Skip to content

Commit

Permalink
(Improve order flow) Remove submitters (#4062) (minor)
Browse files Browse the repository at this point in the history
### Changed

- The OrderSubmitterRegistry is a StoringServiceRegistry
- The OrderSubmitters are removed
- The OrdersAPI needs no Store in its init
- The OrdersAPI needs a StoringServiceRegistry instead of a SubmitterRegistry
- The OrdersAPI needs an OrderValidationService
  • Loading branch information
islean authored Jan 10, 2025
1 parent 50f447f commit 653377f
Show file tree
Hide file tree
Showing 40 changed files with 235 additions and 434 deletions.
20 changes: 10 additions & 10 deletions cg/meta/orders/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
from cg.meta.orders.ticket_handler import TicketHandler
from cg.models.orders.order import OrderType
from cg.services.order_validation_service.models.order import Order
from cg.services.orders.submitters.order_submitter import OrderSubmitter
from cg.services.orders.submitters.order_submitter_registry import OrderSubmitterRegistry
from cg.services.order_validation_service.order_validation_service import OrderValidationService
from cg.services.orders.store_order_services.store_order_service import StoreOrderService
from cg.services.orders.store_order_services.storing_service_registry import StoringServiceRegistry
from cg.store.models import User
from cg.store.store import Store

LOG = logging.getLogger(__name__)

Expand All @@ -27,27 +27,27 @@ class OrdersAPI:
def __init__(
self,
lims: LimsAPI,
status: Store,
ticket_handler: TicketHandler,
submitter_registry: OrderSubmitterRegistry,
storing_registry: StoringServiceRegistry,
validation_service: OrderValidationService,
):
super().__init__()
self.lims = lims
self.status = status
self.ticket_handler = ticket_handler
self.submitter_registry = submitter_registry
self.storing_registry = storing_registry
self.validation_service = validation_service

def submit(self, order_type: OrderType, raw_order: dict, user: User) -> dict:
"""Submit a batch of samples.
Main entry point for the class towards interfaces that implements it.
"""
submit_handler: OrderSubmitter = self.submitter_registry.get_order_submitter(order_type)
order: Order = submit_handler.order_validation_service.parse_and_validate(
storing_service: StoreOrderService = self.storing_registry.get_storing_service(order_type)
order: Order = self.validation_service.parse_and_validate(
raw_order=raw_order, order_type=order_type
)
ticket_number: int = self.ticket_handler.create_ticket(
order=order, user_name=user.name, user_mail=user.email, order_type=order_type
)
order._generated_ticket_id = ticket_number
return submit_handler.submit_order(order)
return storing_service.store_order(order)
6 changes: 3 additions & 3 deletions cg/server/endpoints/orders.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@
delivery_message_service,
lims,
order_service,
order_submitter_registry,
order_validation_service,
storing_service_registry,
ticket_handler,
)
from cg.store.models import Application, Customer
Expand Down Expand Up @@ -153,9 +153,9 @@ def submit_order(order_type: OrderType):
"""Submit an order for samples."""
api = OrdersAPI(
lims=lims,
status=db,
ticket_handler=ticket_handler,
submitter_registry=order_submitter_registry,
storing_registry=storing_service_registry,
validation_service=order_validation_service,
)
error_message: str
try:
Expand Down
8 changes: 4 additions & 4 deletions cg/server/ext.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
from cg.services.order_validation_service.order_validation_service import OrderValidationService
from cg.services.orders.order_service.order_service import OrderService
from cg.services.orders.order_summary_service.order_summary_service import OrderSummaryService
from cg.services.orders.submitters.order_submitter_registry import (
OrderSubmitterRegistry,
setup_order_submitter_registry,
from cg.services.orders.store_order_services.storing_service_registry import (
StoringServiceRegistry,
setup_storing_service_registry,
)
from cg.services.sample_run_metrics_service.sample_run_metrics_service import (
SampleRunMetricsService,
Expand Down Expand Up @@ -95,7 +95,7 @@ def init_app(self, app):
order_service = OrderService(store=db, status_service=summary_service)
sample_service = SampleService(db)
flow_cell_service = SampleRunMetricsService(db)
order_submitter_registry: OrderSubmitterRegistry = setup_order_submitter_registry(
storing_service_registry: StoringServiceRegistry = setup_storing_service_registry(
lims=lims,
status_db=db,
)
Expand Down
File renamed without changes.
19 changes: 8 additions & 11 deletions cg/services/orders/order_service/order_service.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,19 @@
from cg.server.dto.orders.orders_request import OrdersRequest
from cg.server.dto.orders.orders_response import Order as OrderResponse, Order
from cg.server.dto.orders.orders_response import OrdersResponse
from cg.server.dto.orders.orders_response import Order, OrdersResponse
from cg.services.orders.order_service.models import OrderQueryParams
from cg.services.orders.order_summary_service.dto.order_summary import OrderSummary
from cg.services.orders.order_summary_service.order_summary_service import (
OrderSummaryService,
)
from cg.store.store import Store
from cg.services.orders.order_summary_service.order_summary_service import OrderSummaryService
from cg.store.models import Order as DatabaseOrder
from cg.store.store import Store


class OrderService:
def __init__(self, store: Store, status_service: OrderSummaryService) -> None:
self.store = store
self.summary_service = status_service

def get_order(self, order_id: int) -> OrderResponse:
order: Order = self.store.get_order_by_id(order_id)
def get_order(self, order_id: int) -> Order:
order: DatabaseOrder = self.store.get_order_by_id(order_id)
summary: OrderSummary = self.summary_service.get_summary(order_id)
return self._create_order_response(order=order, summary=summary)

Expand All @@ -29,13 +26,13 @@ def get_orders(self, orders_request: OrdersRequest) -> OrdersResponse:
summaries: list[OrderSummary] = self.summary_service.get_summaries(order_ids)
return self._create_orders_response(orders=orders, summaries=summaries, total=total_count)

def set_open(self, order_id: int, open: bool) -> OrderResponse:
order: Order = self.store.update_order_status(order_id=order_id, open=open)
def set_open(self, order_id: int, open: bool) -> Order:
order: DatabaseOrder = self.store.update_order_status(order_id=order_id, open=open)
return self._create_order_response(order)

def update_is_open(self, order_id: int, delivered_analyses: int) -> None:
"""Update the is_open parameter of an order based on the number of delivered analyses."""
order: Order = self.store.get_order_by_id(order_id)
order: DatabaseOrder = self.store.get_order_by_id(order_id)
case_count: int = len(order.cases)
if self._is_order_closed(case_count=case_count, delivered_analyses=delivered_analyses):
self.set_open(order_id=order_id, open=False)
Expand Down
Empty file.
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from cg.services.order_validation_service.models.sample_aliases import SampleInCase
from cg.services.orders.constants import ORDER_TYPE_WORKFLOW_MAP
from cg.services.orders.order_lims_service.order_lims_service import OrderLimsService
from cg.services.orders.submitters.order_submitter import StoreOrderService
from cg.services.orders.store_order_services.store_order_service import StoreOrderService
from cg.store.models import ApplicationVersion
from cg.store.models import Case as DbCase
from cg.store.models import CaseSample, Customer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from cg.services.order_validation_service.workflows.fastq.models.order import FastqOrder
from cg.services.order_validation_service.workflows.fastq.models.sample import FastqSample
from cg.services.orders.order_lims_service.order_lims_service import OrderLimsService
from cg.services.orders.submitters.order_submitter import StoreOrderService
from cg.services.orders.store_order_services.store_order_service import StoreOrderService
from cg.store.models import ApplicationVersion, Case, CaseSample, Customer, Order, Sample
from cg.store.store import Store

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
)
from cg.services.orders.constants import ORDER_TYPE_WORKFLOW_MAP
from cg.services.orders.order_lims_service.order_lims_service import OrderLimsService
from cg.services.orders.submitters.order_submitter import StoreOrderService
from cg.services.orders.store_order_services.store_order_service import StoreOrderService
from cg.store.models import ApplicationVersion
from cg.store.models import Case as DbCase
from cg.store.models import CaseSample, Customer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
MicrobialFastqSample,
)
from cg.services.orders.order_lims_service.order_lims_service import OrderLimsService
from cg.services.orders.submitters.order_submitter import StoreOrderService
from cg.services.orders.store_order_services.store_order_service import StoreOrderService
from cg.store.models import ApplicationVersion, Case, CaseSample, Customer, Order, Sample
from cg.store.store import Store

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from cg.services.order_validation_service.workflows.mutant.models.sample import MutantSample
from cg.services.orders.constants import ORDER_TYPE_WORKFLOW_MAP
from cg.services.orders.order_lims_service.order_lims_service import OrderLimsService
from cg.services.orders.submitters.order_submitter import StoreOrderService
from cg.services.orders.store_order_services.store_order_service import StoreOrderService
from cg.store.models import ApplicationVersion
from cg.store.models import Case as DbCase
from cg.store.models import CaseSample, Customer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@
from datetime import datetime

from cg.constants import DataDelivery, Workflow
from cg.models.orders.order import OrderIn
from cg.models.orders.sample_base import StatusEnum
from cg.services.order_validation_service.workflows.pacbio_long_read.models.order import PacbioOrder
from cg.services.order_validation_service.workflows.pacbio_long_read.models.sample import (
PacbioSample,
)
from cg.services.orders.order_lims_service.order_lims_service import OrderLimsService
from cg.services.orders.submitters.order_submitter import StoreOrderService
from cg.services.orders.store_order_services.store_order_service import StoreOrderService
from cg.store.models import ApplicationVersion, Case, CaseSample, Customer, Order, Sample
from cg.store.store import Store

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
)
from cg.services.orders.constants import ORDER_TYPE_WORKFLOW_MAP
from cg.services.orders.order_lims_service.order_lims_service import OrderLimsService
from cg.services.orders.submitters.order_submitter import StoreOrderService
from cg.services.orders.store_order_services.store_order_service import StoreOrderService
from cg.store.models import ApplicationVersion, Case, CaseSample, Customer, Order, Pool, Sample
from cg.store.store import Store

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
from abc import ABC, abstractmethod

from cg.models.orders.order import OrderIn
from cg.services.order_validation_service.models.order import Order
from cg.services.order_validation_service.models.sample import Sample
from cg.services.order_validation_service.order_validation_service import OrderValidationService
from cg.services.orders.order_lims_service.order_lims_service import OrderLimsService
from cg.store.store import Store

Expand All @@ -29,7 +29,7 @@ def __init__(self, status_db: Store, lims_service: OrderLimsService):
self.lims = lims_service

@abstractmethod
def store_order(self, order_in: OrderIn):
def store_order(self, order: Order):
pass

@staticmethod
Expand All @@ -40,18 +40,3 @@ def _fill_in_sample_ids(samples: list[Sample], lims_map: dict):
internal_id = lims_map[sample.name]
LOG.info(f"{sample.name} -> {internal_id}: connect sample to LIMS")
sample._generated_lims_id = internal_id


class OrderSubmitter(ABC):
@abstractmethod
def __init__(
self,
validate_order_service: OrderValidationService,
store_order_service: StoreOrderService,
):
self.order_validation_service = validate_order_service
self.order_store_service = store_order_service

@abstractmethod
def submit_order(self, order_in: OrderIn) -> dict:
pass
134 changes: 134 additions & 0 deletions cg/services/orders/store_order_services/storing_service_registry.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
from cg.apps.lims import LimsAPI
from cg.models.orders.constants import OrderType
from cg.services.orders.order_lims_service.order_lims_service import OrderLimsService
from cg.services.orders.store_order_services.implementations.store_case_order import (
StoreCaseOrderService,
)
from cg.services.orders.store_order_services.implementations.store_fastq_order_service import (
StoreFastqOrderService,
)
from cg.services.orders.store_order_services.implementations.store_metagenome_order import (
StoreMetagenomeOrderService,
)
from cg.services.orders.store_order_services.implementations.store_microbial_fastq_order_service import (
StoreMicrobialFastqOrderService,
)
from cg.services.orders.store_order_services.implementations.store_microbial_order import (
StoreMicrobialOrderService,
)
from cg.services.orders.store_order_services.implementations.store_pacbio_order_service import (
StorePacBioOrderService,
)
from cg.services.orders.store_order_services.implementations.store_pool_order import (
StorePoolOrderService,
)
from cg.services.orders.store_order_services.store_order_service import StoreOrderService
from cg.store.store import Store


class StoringServiceRegistry:
"""
A registry for StoreOrderService instances, keyed by OrderType.
"""

def __init__(self):
self._registry = {}

def register(self, order_type: OrderType, storing_service: StoreOrderService):
"""Register a StoreOrderService instance for a given OrderType."""
self._registry[order_type] = storing_service

def get_storing_service(self, order_type: OrderType) -> StoreOrderService:
"""Fetch the registered StoreOrderService for the given OrderType."""
if storing_service := self._registry.get(order_type):
return storing_service
raise ValueError(f"No StoreOrderService registered for order type: {order_type}")


order_service_mapping = {
OrderType.BALSAMIC: (
OrderLimsService,
StoreCaseOrderService,
),
OrderType.BALSAMIC_QC: (
OrderLimsService,
StoreCaseOrderService,
),
OrderType.BALSAMIC_UMI: (
OrderLimsService,
StoreCaseOrderService,
),
OrderType.FASTQ: (
OrderLimsService,
StoreFastqOrderService,
),
OrderType.FLUFFY: (
OrderLimsService,
StorePoolOrderService,
),
OrderType.METAGENOME: (
OrderLimsService,
StoreMetagenomeOrderService,
),
OrderType.MICROBIAL_FASTQ: (
OrderLimsService,
StoreMicrobialFastqOrderService,
),
OrderType.MICROSALT: (
OrderLimsService,
StoreMicrobialOrderService,
),
OrderType.MIP_DNA: (
OrderLimsService,
StoreCaseOrderService,
),
OrderType.MIP_RNA: (
OrderLimsService,
StoreCaseOrderService,
),
OrderType.PACBIO_LONG_READ: (
OrderLimsService,
StorePacBioOrderService,
),
OrderType.RML: (
OrderLimsService,
StorePoolOrderService,
),
OrderType.RNAFUSION: (
OrderLimsService,
StoreCaseOrderService,
),
OrderType.SARS_COV_2: (
OrderLimsService,
StoreMicrobialOrderService,
),
OrderType.TAXPROFILER: (
OrderLimsService,
StoreMetagenomeOrderService,
),
OrderType.TOMTE: (
OrderLimsService,
StoreCaseOrderService,
),
}


def build_storing_service(
lims: LimsAPI, status_db: Store, order_type: OrderType
) -> StoreOrderService:
"""Build a StoreOrderService instance for the given OrderType."""
lims_service, store_service = order_service_mapping[order_type]
return store_service(status_db, lims_service(lims))


def setup_storing_service_registry(lims: LimsAPI, status_db: Store) -> StoringServiceRegistry:
"""Set up the StoringServiceRegistry with all StoreOrderService instances."""
registry = StoringServiceRegistry()
for order_type in order_service_mapping.keys():
registry.register(
order_type=order_type,
storing_service=build_storing_service(
lims=lims, status_db=status_db, order_type=order_type
),
)
return registry
Loading

0 comments on commit 653377f

Please sign in to comment.