Example #1
0
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
Example #2
0
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()