Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Enhancement] - Case participant slack functions, ephemeral message, and escalate bug fix #4708

Merged
merged 7 commits into from
May 11, 2024
59 changes: 53 additions & 6 deletions src/dispatch/case/flows.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
from dispatch.incident.enums import IncidentStatus
from dispatch.incident.messaging import send_participant_announcement_message
from dispatch.incident.models import IncidentCreate, Incident
from dispatch.incident.type.models import IncidentType
from dispatch.incident.priority.models import IncidentPriority
from dispatch.individual.models import IndividualContactRead
from dispatch.models import OrganizationSlug, PrimaryKey
from dispatch.participant import flows as participant_flows
Expand Down Expand Up @@ -125,6 +127,38 @@ def case_add_or_reactivate_participant_flow(
return participant


@background_task
def case_remove_participant_flow(
user_email: str,
case_id: int,
db_session: Session,
):
"""Runs the remove participant flow."""
case = case_service.get(db_session=db_session, case_id=case_id)

if not case:
log.warn(
f"Unable to remove participant from case with id {case_id}. An case with this id does not exist."
)
return

# we remove the participant from the incident
participant_flows.remove_case_participant(
user_email=user_email,
case=case,
db_session=db_session,
)

# we remove the participant from the tactical group
group_flows.update_group(
subject=case,
group=case.tactical_group,
group_action=GroupAction.remove_member,
group_member=user_email,
db_session=db_session,
)


def update_conversation(case: Case, db_session: Session) -> None:
"""Updates external communication conversation."""

Expand Down Expand Up @@ -362,7 +396,13 @@ def case_triage_status_flow(case: Case, db_session=None):
db_session.commit()


def case_escalated_status_flow(case: Case, organization_slug: OrganizationSlug, db_session=None):
def case_escalated_status_flow(
case: Case,
organization_slug: OrganizationSlug,
db_session: Session,
incident_priority: IncidentType | None,
incident_type: IncidentPriority | None,
):
"""Runs the case escalated transition flow."""
# we set the escalated_at time
case.escalated_at = datetime.utcnow()
Expand All @@ -373,6 +413,8 @@ def case_escalated_status_flow(case: Case, organization_slug: OrganizationSlug,
case=case,
organization_slug=organization_slug,
db_session=db_session,
incident_priority=incident_priority,
incident_type=incident_type,
)


Expand Down Expand Up @@ -634,9 +676,11 @@ def common_escalate_flow(
def case_to_incident_escalate_flow(
case: Case,
organization_slug: OrganizationSlug,
db_session: Session = None,
db_session: Session,
incident_priority: IncidentType | None,
incident_type: IncidentPriority | None,
):
if case.incidents or not case.case_type.incident_type:
if case.incidents:
return

reporter = ParticipantUpdate(
Expand All @@ -649,13 +693,16 @@ def case_to_incident_escalate_flow(
f"in the {case.project.name} project. Check out the case in the Dispatch Web UI for additional context."
)

incident_type = case.case_type.incident_type if case.case_type.incident_type else incident_type
incident_priority = case.case_priority if not incident_priority else incident_priority

incident_in = IncidentCreate(
title=case.title,
description=description,
status=IncidentStatus.active,
incident_type=case.case_type.incident_type,
incident_priority=case.case_priority,
project=case.case_type.incident_type.project,
incident_type=incident_type,
incident_priority=incident_priority,
project=case.project,
reporter=reporter,
)
incident = incident_service.create(db_session=db_session, incident_in=incident_in)
Expand Down
3 changes: 2 additions & 1 deletion src/dispatch/event/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ def log_case_event(
started_at: datetime = None,
ended_at: datetime = None,
details: dict = None,
type: str = EventType.other,
) -> Event:
"""Logs an event in the case timeline."""
uuid = uuid4()
Expand All @@ -165,7 +166,7 @@ def log_case_event(
source=source,
description=description,
details=details,
type=EventType.other,
type=type,
)
event = create(db_session=db_session, event_in=event_in)

Expand Down
49 changes: 40 additions & 9 deletions src/dispatch/participant/flows.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,19 +117,51 @@ def remove_participant(user_email: str, incident: Incident, db_session: SessionL
)


def inactivate_participant(user_email: str, incident: Incident, db_session: SessionLocal):
def remove_case_participant(user_email: str, case: Case, db_session: SessionLocal):
"""Removes a participant."""
inactivated = inactivate_participant(user_email, case, db_session)

if inactivated:
participant = participant_service.get_by_case_id_and_email(
db_session=db_session, case_id=case.id, email=user_email
)

log.debug(f"Removing {participant.individual.name} from {case.name} case...")

participant.service = None

db_session.add(participant)
db_session.commit()

event_service.log_subject_event(
subject=case,
db_session=db_session,
source="Dispatch Core App",
description=f"{participant.individual.name} has been removed",
type=EventType.participant_updated,
)


def inactivate_participant(user_email: str, subject: Subject, db_session: SessionLocal):
"""Inactivates a participant."""
participant = participant_service.get_by_incident_id_and_email(
db_session=db_session, incident_id=incident.id, email=user_email
)
subject_type = get_table_name_by_class_instance(subject)

if subject_type == "case":
participant = participant_service.get_by_case_id_and_email(
db_session=db_session, case_id=subject.id, email=user_email
)
else:
participant = participant_service.get_by_incident_id_and_email(
db_session=db_session, incident_id=subject.id, email=user_email
)

if not participant:
log.debug(
f"Can't inactivate participant with {user_email} email. They're not a participant of {incident.name} incident."
f"Can't inactivate participant with {user_email} email. They're not a participant of {subject.name} {subject_type}."
)
return False

log.debug(f"Inactivating {participant.individual.name} from {incident.name} incident...")
log.debug(f"Inactivating {participant.individual.name} from {subject.name} {subject_type}...")

participant_active_roles = participant_role_service.get_all_active_roles(
db_session=db_session, participant_id=participant.id
Expand All @@ -139,14 +171,13 @@ def inactivate_participant(user_email: str, incident: Incident, db_session: Sess
db_session=db_session, participant_role=participant_active_role
)

event_service.log_incident_event(
event_service.log_subject_event(
subject=subject,
db_session=db_session,
source="Dispatch Core App",
description=f"{participant.individual.name} has been inactivated",
incident_id=incident.id,
type=EventType.participant_updated,
)

return True


Expand Down
Loading
Loading