From abb504d98331a493f4c905326d55aba83bd3c0fb Mon Sep 17 00:00:00 2001 From: Amin <82151354+ahdamin@users.noreply.github.com> Date: Mon, 16 Dec 2024 09:15:28 +0100 Subject: [PATCH 1/4] Remove feature to link order to an existing ticket (#4013) ## Description It was agreed by sysdev and prod to remove the option to link an existing ticket to an order in the order portal. This PR implements the backend changes. ### Changed - Remove the feature to link orders to an existing ticket --------- Co-authored-by: Sebastian Diaz --- cg/exc.py | 4 --- cg/meta/orders/api.py | 20 +++-------- cg/meta/orders/ticket_handler.py | 46 +----------------------- cg/server/endpoints/orders.py | 9 +---- tests/meta/orders/test_ticket_handler.py | 11 ------ 5 files changed, 6 insertions(+), 84 deletions(-) diff --git a/cg/exc.py b/cg/exc.py index 3e6e80ac27..4f5d3b7cbc 100644 --- a/cg/exc.py +++ b/cg/exc.py @@ -298,10 +298,6 @@ class OrderNotFoundError(CgError): """Exception raised when an order is not found.""" -class OrderExistsError(CgError): - """Exception raised when cases and samples are added to a pre-existing order.""" - - class OrderMismatchError(CgError): """Exception raised when cases expected to belong to the same order are not part of the same order.""" diff --git a/cg/meta/orders/api.py b/cg/meta/orders/api.py index 228a9570e0..d62d063119 100644 --- a/cg/meta/orders/api.py +++ b/cg/meta/orders/api.py @@ -12,9 +12,7 @@ from cg.apps.lims import LimsAPI from cg.meta.orders.ticket_handler import TicketHandler from cg.models.orders.order import OrderIn, OrderType -from cg.services.orders.submitters.order_submitter_registry import ( - OrderSubmitterRegistry, -) +from cg.services.orders.submitters.order_submitter_registry import OrderSubmitterRegistry from cg.store.store import Store LOG = logging.getLogger(__name__) @@ -43,18 +41,8 @@ def submit(self, project: OrderType, order_in: OrderIn, user_name: str, user_mai """ submit_handler = self.submitter_registry.get_order_submitter(project) submit_handler.order_validation_service.validate_order(order_in) - # detect manual ticket assignment - ticket_number: str | None = self.ticket_handler.parse_ticket_number(order_in.name) - if not ticket_number: - ticket_number = self.ticket_handler.create_ticket( - order=order_in, user_name=user_name, user_mail=user_mail, project=project - ) - else: - self.ticket_handler.connect_to_ticket( - order=order_in, - user_name=user_name, - project=project, - ticket_number=ticket_number, - ) + ticket_number = self.ticket_handler.create_ticket( + order=order_in, user_name=user_name, user_mail=user_mail, project=project + ) order_in.ticket = ticket_number return submit_handler.submit_order(order_in=order_in) diff --git a/cg/meta/orders/ticket_handler.py b/cg/meta/orders/ticket_handler.py index 91d806fdfa..99ae8693c3 100644 --- a/cg/meta/orders/ticket_handler.py +++ b/cg/meta/orders/ticket_handler.py @@ -1,11 +1,10 @@ import logging -import re 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 ReplyCreate, TicketCreate, TicketResponse +from cg.clients.freshdesk.models import TicketCreate, TicketResponse from cg.models.orders.order import OrderIn from cg.models.orders.samples import Of1508Sample from cg.store.models import Customer, Sample @@ -25,18 +24,6 @@ def __init__(self, db: Store, client: FreshdeskClient, system_email_id: int, env self.system_email_id: int = system_email_id self.env: str = env - @staticmethod - def parse_ticket_number(name: str) -> str | None: - """Try to parse a ticket number from a string""" - # detect manual ticket assignment - ticket_match = re.fullmatch(r"#(\d{6,10})", name) - if ticket_match: - ticket_id = ticket_match.group(1) - LOG.info(f"{ticket_id}: detected ticket in order name") - return ticket_id - LOG.info(f"Could not detected ticket number in name {name}") - return None - def create_ticket( self, order: OrderIn, user_name: str, user_mail: str, project: str ) -> int | None: @@ -105,13 +92,6 @@ def create_xml_sample_list(self, order: OrderIn, user_name: str) -> str: def create_new_ticket_header(message: str, order: OrderIn, project: str) -> str: return f"New order with {len(order.samples)} {project} samples:" + message - @staticmethod - def add_existing_ticket_header(message: str, order: OrderIn, project: str) -> str: - return ( - f"A new order with {len(order.samples)} {project} samples has been connected to this ticket:" - + message - ) - def add_sample_name_to_message(self, message: str, sample_name: str) -> str: message += f"{self.NEW_LINE}{sample_name}" return message @@ -188,27 +168,3 @@ def replace_empty_string_with_none(cls, obj: Any) -> Any: else: obj[key] = cls.replace_empty_string_with_none(item) return obj - - def connect_to_ticket( - self, order: OrderIn, user_name: str, project: str, ticket_number: str - ) -> None: - """Appends a new order message to the ticket selected by the customer""" - LOG.info(f"Connecting order to ticket {ticket_number}") - - message: str = self.add_existing_ticket_header( - message=self.create_xml_sample_list(order=order, user_name=user_name), - order=order, - project=project, - ) - - with TemporaryDirectory() as temp_dir: - attachments: Path = self.create_attachment_file(order=order, temp_dir=temp_dir) - - reply = ReplyCreate(ticket_number=ticket_number, body=message) - - self.client.reply_to_ticket( - reply=reply, - attachments=[attachments], - ) - - LOG.info(f"Connected order to ticket {ticket_number} in Freshdesk") diff --git a/cg/server/endpoints/orders.py b/cg/server/endpoints/orders.py index 3d75a3072e..4d45485872 100644 --- a/cg/server/endpoints/orders.py +++ b/cg/server/endpoints/orders.py @@ -17,7 +17,6 @@ from cg.constants.constants import FileFormat from cg.exc import ( OrderError, - OrderExistsError, OrderFormError, OrderNotDeliverableError, OrderNotFoundError, @@ -27,9 +26,7 @@ from cg.meta.orders import OrdersAPI from cg.models.orders.order import OrderIn, OrderType from cg.models.orders.orderform_schema import Orderform -from cg.server.dto.delivery_message.delivery_message_response import ( - DeliveryMessageResponse, -) +from cg.server.dto.delivery_message.delivery_message_response import DeliveryMessageResponse from cg.server.dto.orders.order_delivery_update_request import OrderOpenUpdateRequest from cg.server.dto.orders.order_patch_request import OrderOpenPatch from cg.server.dto.orders.orders_request import OrdersRequest @@ -170,9 +167,6 @@ def submit_order(order_type): ) project = OrderType(order_type) order_in = OrderIn.parse_obj(request_json, project=project) - existing_ticket: str | None = ticket_handler.parse_ticket_number(order_in.name) - if existing_ticket and order_service.store.get_order_by_ticket_id(existing_ticket): - raise OrderExistsError(f"Order with ticket id {existing_ticket} already exists.") result: dict = api.submit( project=project, @@ -183,7 +177,6 @@ def submit_order(order_type): except ( # user misbehaviour OrderError, - OrderExistsError, OrderFormError, ValidationError, ValueError, diff --git a/tests/meta/orders/test_ticket_handler.py b/tests/meta/orders/test_ticket_handler.py index ef23284aed..6212b75d9d 100644 --- a/tests/meta/orders/test_ticket_handler.py +++ b/tests/meta/orders/test_ticket_handler.py @@ -1,17 +1,6 @@ from cg.meta.orders.ticket_handler import TicketHandler -def test_parse_ticket_number(ticket_id: str): - # GIVEN a string with a ticket number - order_name = f"#{ticket_id}" - - # WHEN parsing the string - result = TicketHandler.parse_ticket_number(order_name) - - # THEN assert that the correct string was parsed - assert result == ticket_id - - def test_add_user_name_message(ticket_handler: TicketHandler): # GIVEN a message string message = "" From eea3e7e965785a5a738e71ab49eda89e389b44d7 Mon Sep 17 00:00:00 2001 From: Clinical Genomics Bot Date: Mon, 16 Dec 2024 08:15:58 +0000 Subject: [PATCH 2/4] =?UTF-8?q?Bump=20version:=2064.5.28=20=E2=86=92=2064.?= =?UTF-8?q?5.29=20[skip=20ci]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .bumpversion.cfg | 2 +- cg/__init__.py | 2 +- pyproject.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 2b700b6731..e7afbf9e94 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 64.5.28 +current_version = 64.5.29 commit = True tag = True tag_name = v{new_version} diff --git a/cg/__init__.py b/cg/__init__.py index ad72faa799..4ee74754c3 100644 --- a/cg/__init__.py +++ b/cg/__init__.py @@ -1,2 +1,2 @@ __title__ = "cg" -__version__ = "64.5.28" +__version__ = "64.5.29" diff --git a/pyproject.toml b/pyproject.toml index 1d747765aa..e550b12649 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api" [tool.poetry] name = "cg" -version = "64.5.28" +version = "64.5.29" description = "Clinical Genomics command center" authors = ["Clinical Genomics "] readme = "README.md" From d1004b4ed6f3924758df507a16b439e8cb317032 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Isak=20Ohlsson=20=C3=85ngnell?= <40887124+islean@users.noreply.github.com> Date: Tue, 17 Dec 2024 09:19:04 +0100 Subject: [PATCH 3/4] Add sample name validation (#4019) (patch) ### Changed - Microbial fastq orders containing samples which the customer has used in a previous order do not pass validation. --- .../validate_microbial_order.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/cg/services/orders/validate_order_services/validate_microbial_order.py b/cg/services/orders/validate_order_services/validate_microbial_order.py index 82b3acff24..1590e6b984 100644 --- a/cg/services/orders/validate_order_services/validate_microbial_order.py +++ b/cg/services/orders/validate_order_services/validate_microbial_order.py @@ -1,7 +1,7 @@ from cg.exc import OrderError from cg.models.orders.constants import OrderType from cg.models.orders.order import OrderIn -from cg.models.orders.samples import SarsCov2Sample +from cg.models.orders.samples import MicrobialFastqSample, SarsCov2Sample from cg.services.orders.submitters.order_submitter import ValidateOrderService from cg.store.models import Customer from cg.store.store import Store @@ -15,18 +15,25 @@ def __init__(self, status_db: Store): def validate_order(self, order: OrderIn) -> None: if order.order_type == OrderType.SARS_COV_2: self._validate_sample_names_are_available( - samples=order.samples, customer_id=order.customer + samples=order.samples, customer_id=order.customer, is_sars_cov_2=True + ) + elif order.order_type == OrderType.MICROBIAL_FASTQ: + self._validate_sample_names_are_available( + samples=order.samples, customer_id=order.customer, is_sars_cov_2=False ) def _validate_sample_names_are_available( - self, samples: list[SarsCov2Sample], customer_id: str + self, + samples: list[SarsCov2Sample] | list[MicrobialFastqSample], + customer_id: str, + is_sars_cov_2: bool, ) -> None: """Validate names of all samples are not already in use.""" customer: Customer = self.status_db.get_customer_by_internal_id( customer_internal_id=customer_id ) for sample in samples: - if sample.control: + if is_sars_cov_2 and sample.control: continue if self.status_db.get_sample_by_customer_and_name( customer_entry_id=[customer.id], sample_name=sample.name From 1fc06557f49e3fce4d26baee1881c9b94fae2d18 Mon Sep 17 00:00:00 2001 From: Clinical Genomics Bot Date: Tue, 17 Dec 2024 08:19:30 +0000 Subject: [PATCH 4/4] =?UTF-8?q?Bump=20version:=2064.5.29=20=E2=86=92=2064.?= =?UTF-8?q?5.30=20[skip=20ci]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .bumpversion.cfg | 2 +- cg/__init__.py | 2 +- pyproject.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index e7afbf9e94..17d722cb10 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 64.5.29 +current_version = 64.5.30 commit = True tag = True tag_name = v{new_version} diff --git a/cg/__init__.py b/cg/__init__.py index 4ee74754c3..e4b5da7c8f 100644 --- a/cg/__init__.py +++ b/cg/__init__.py @@ -1,2 +1,2 @@ __title__ = "cg" -__version__ = "64.5.29" +__version__ = "64.5.30" diff --git a/pyproject.toml b/pyproject.toml index e550b12649..3872eb5223 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api" [tool.poetry] name = "cg" -version = "64.5.29" +version = "64.5.30" description = "Clinical Genomics command center" authors = ["Clinical Genomics "] readme = "README.md"