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

add logic for differing SLA for order tickets #4274

Open
wants to merge 18 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions cg/clients/freshdesk/models.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from datetime import date
from typing import Tuple, Union

from pydantic import BaseModel, EmailStr, Field
Expand All @@ -16,6 +17,8 @@ class TicketCreate(BaseModel):
priority: int = Priority.LOW
source: int = Source.EMAIL
status: int = Status.PENDING
due_by: date
fr_due_by: date
subject: str
tags: list[str] = []
type: str | None = None
Expand Down
6 changes: 3 additions & 3 deletions cg/constants/priority.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ class PriorityTerms(StrEnum):
class Priority(IntEnum):
research: int = 0
standard: int = 1
priority: int = 2
express: int = 3
clinical_trials: int = 4
clinical_trials: int = 2
priority: int = 3
express: int = 4

@classmethod
def priority_to_slurm_qos(cls) -> dict[int, str]:
Expand Down
17 changes: 17 additions & 0 deletions cg/meta/orders/utils.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
from datetime import date, datetime, timedelta

from cg.clients.freshdesk.constants import Status
from cg.constants.priority import Priority
from cg.models.orders.constants import OrderType
from cg.services.orders.constants import ORDER_TYPE_WORKFLOW_MAP
from cg.services.orders.validation.models.order import Order
from cg.services.orders.validation.models.order_with_cases import OrderWithCases

TIMEDELTA_BY_PRIORITY: dict[Priority, timedelta.days] = {
Priority.express: timedelta(days=7),
Priority.priority: timedelta(days=14),
Priority.standard: timedelta(days=21),
Priority.clinical_trials: timedelta(days=21),
Priority.research: timedelta(days=60),
}


def contains_existing_data(order: OrderWithCases) -> bool:
"""Check if the order contains any existing data"""
Expand Down Expand Up @@ -37,3 +48,9 @@ def get_ticket_status(order: Order) -> Status:
if contains_only_existing_samples(order=order):
return Status.OPEN
return Status.PENDING


def get_due_by_date(priority: Priority) -> date:
"""Get the ticket due by date based on the order priority."""
due_by: datetime = datetime.now() + TIMEDELTA_BY_PRIORITY[priority]
return due_by.date()
4 changes: 2 additions & 2 deletions cg/meta/workflow/analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
WorkflowManager,
)
from cg.constants.gene_panel import GenePanelCombo, GenePanelMasterList
from cg.constants.priority import SlurmQos, TrailblazerPriority
from cg.constants.priority import TrailblazerPriority
from cg.constants.scout import HGNC_ID, ScoutExportFileName
from cg.constants.sequencing import SeqLibraryPrepCategory
from cg.constants.tb import AnalysisStatus, AnalysisType
Expand Down Expand Up @@ -137,7 +137,7 @@ def get_slurm_qos_for_case(self, case_id: str) -> str:
def get_trailblazer_priority(self, case_id: str) -> int:
"""Get the priority for the case in Trailblazer."""
case: Case = self.status_db.get_case_by_internal_id(internal_id=case_id)
priority: int = case.priority
priority: Priority = case.priority
return MAP_TO_TRAILBLAZER_PRIORITY[priority]

def get_workflow_manager(self) -> str:
Expand Down
14 changes: 7 additions & 7 deletions cg/meta/workflow/utils/utils.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from cg.constants.priority import TrailblazerPriority
from cg.constants.priority import Priority, TrailblazerPriority

MAP_TO_TRAILBLAZER_PRIORITY: dict[int, TrailblazerPriority] = {
0: TrailblazerPriority.LOW,
1: TrailblazerPriority.NORMAL,
2: TrailblazerPriority.HIGH,
3: TrailblazerPriority.EXPRESS,
4: TrailblazerPriority.NORMAL,
MAP_TO_TRAILBLAZER_PRIORITY: dict[Priority, TrailblazerPriority] = {
Priority.research: TrailblazerPriority.LOW,
Priority.standard: TrailblazerPriority.NORMAL,
Priority.clinical_trials: TrailblazerPriority.NORMAL,
Priority.priority: TrailblazerPriority.HIGH,
Priority.express: TrailblazerPriority.EXPRESS,
}
30 changes: 27 additions & 3 deletions cg/services/orders/submitter/ticket_handler.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import logging
from datetime import date
from pathlib import Path
from tempfile import TemporaryDirectory
from typing import Any

from cg.clients.freshdesk.freshdesk_client import FreshdeskClient
from cg.clients.freshdesk.models import TicketCreate, TicketResponse
from cg.meta.orders.utils import get_ticket_status, get_ticket_tags
from cg.constants.priority import Priority
from cg.meta.orders.utils import get_due_by_date, get_ticket_status, get_ticket_tags
from cg.models.orders.constants import OrderType
from cg.services.orders.constants import ORDER_TYPE_WORKFLOW_MAP
from cg.services.orders.validation.models.order import Order
from cg.services.orders.validation.models.order_with_cases import OrderWithCases
from cg.services.orders.validation.models.order_with_samples import OrderWithSamples
from cg.store.models import Customer, Sample
from cg.store.models import Case, Customer, Sample
from cg.store.store import Store

LOG = logging.getLogger(__name__)
Expand Down Expand Up @@ -41,6 +42,9 @@ def create_ticket(
tags: list[str] = get_ticket_tags(order=order, order_type=order_type)
status: int = get_ticket_status(order=order)

order_priority: Priority = self._get_max_case_priority(order=order)
deadline_date: date = get_due_by_date(priority=order_priority)

with TemporaryDirectory() as temp_dir:
attachments: Path = self.create_attachment_file(order=order, temp_dir=temp_dir)

Expand All @@ -57,6 +61,8 @@ def create_ticket(
},
attachments=[],
status=status,
due_by=deadline_date,
fr_due_by=deadline_date,
Comment on lines +64 to +65
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did we not get exceptions where they were not allowed equal?

Copy link
Contributor Author

@beatrizsavinhas beatrizsavinhas Mar 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No... It must have been a problem with the test setup at the time. After testing both in postman and in stage, it works fine! See the tests that I executed above - #4274 (comment).

)
ticket_response: TicketResponse = self.client.create_ticket(
ticket=freshdesk_ticket, attachments=[attachments]
Expand Down Expand Up @@ -217,3 +223,21 @@ def create_case_xml_sample_list(self, order, message: str) -> str:
message=message, comment=sample.comment
)
return message

def _get_max_case_priority(self, order: Order) -> Priority:
"""Get max case priority for a given order."""
priority_list: list[Priority] = []

if isinstance(order, OrderWithCases):
for index, new_case in order.enumerated_new_cases:
priority_list.append(Priority[new_case.priority])

for index, case in order.enumerated_existing_cases:
case: Case = self.status_db.get_case_by_internal_id(case.internal_id)
priority_list.append(case.priority)

if isinstance(order, OrderWithSamples):
for sample in order.samples:
priority_list.append(Priority[sample.priority])

return max(priority_list)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given how the Priority IntEnum is set up, I think this will always return clinical trials priority if any such sample/case is present. Is that how we want it to be? (Priority.clinical_trials = 4 > 3 = Priority.express)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are completely right! I'll test changing the priorities and see if it works.

Loading