def create(*, db_session, task_in: TaskCreate) -> Task: """Create a new task.""" incident = incident_service.get(db_session=db_session, incident_id=task_in.incident.id) tickets = [ ticket_service.get_or_create_by_weblink(db_session=db_session, weblink=t.weblink, resource_type="task-ticket") for t in task_in.tickets ] assignees = [] for i in task_in.assignees: assignee = incident_flows.incident_add_or_reactivate_participant_flow( db_session=db_session, incident_id=incident.id, user_email=i.individual.email, ) # due to the freeform nature of task assignment, we can sometimes pick up other emails # e.g. a google group that we cannot resolve to an individual assignee if assignee: assignees.append(assignee) creator_email = None if not task_in.creator: creator_email = task_in.owner.individual.email else: creator_email = task_in.creator.individual.email # add creator as a participant if they are not one already creator = incident_flows.incident_add_or_reactivate_participant_flow( db_session=db_session, incident_id=incident.id, user_email=creator_email, ) # if we cannot find any assignees, the creator becomes the default assignee if not assignees: assignees.append(creator) # we add owner as a participant if they are not one already if task_in.owner: owner = incident_flows.incident_add_or_reactivate_participant_flow( db_session=db_session, incident_id=incident.id, user_email=task_in.owner.individual.email, ) else: owner = incident.commander task = Task( **task_in.dict( exclude={"assignees", "owner", "incident", "creator", "tickets"}), creator=creator, owner=owner, assignees=assignees, incident=incident, tickets=tickets, ) event_service.log( db_session=db_session, source="Dispatch Core App", description="New incident task created", details={"weblink": task.weblink}, incident_id=incident.id, ) db_session.add(task) db_session.commit() return task
def create_or_update_task(db_session, incident, task: dict, notify: bool = False): """Creates a new task in the database or updates an existing one.""" incident_task = task_service.get_by_resource_id(db_session=db_session, resource_id=task["id"]) assignees = [] for a in task["assignees"]: assignees.append( db_session.merge( incident_add_or_reactivate_participant_flow( a, incident_id=incident.id, db_session=db_session))) description = task["description"][0] status = TaskStatus.open if not task["status"] else TaskStatus.resolved resource_id = task["id"] weblink = task["web_link"] # TODO we can build this out as our scraping gets more advanced tickets = [ ticket_service.get_or_create_by_weblink(db_session=db_session, weblink=t["web_link"]) for t in task["tickets"] ] if incident_task: # allways update tickets and assignees incident_task.assignees = assignees incident_task.tickets = tickets # only notify if it's newly resolved if status == TaskStatus.resolved: if incident_task.status != TaskStatus.resolved: incident_task.status = status if notify: send_task_notification( incident.conversation.channel_id, INCIDENT_TASK_RESOLVED_NOTIFICATION, assignees, description, weblink, ) else: # we add the task to the incident creator = db_session.merge( incident_add_or_reactivate_participant_flow( task["owner"], incident_id=incident.id, db_session=db_session)) task = task_service.create( db_session=db_session, creator=creator, assignees=assignees, description=description, status=status, tickets=tickets, resource_id=resource_id, resource_type=INCIDENT_RESOURCE_INCIDENT_TASK, weblink=weblink, ) incident.tasks.append(task) if notify: send_task_notification( incident.conversation.channel_id, INCIDENT_TASK_NEW_NOTIFICATION, assignees, description, weblink, ) db_session.commit()