Skip to content

Commit 160beaf

Browse files
authored
Fix clashing ticket ids (#3833) (patch)
### Changed - Filtering on ticket id is done in the Order table
1 parent d6422d3 commit 160beaf

File tree

6 files changed

+83
-52
lines changed

6 files changed

+83
-52
lines changed

cg/store/base.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,12 @@
66
from sqlalchemy import and_, func
77
from sqlalchemy.orm import Query, Session
88

9-
from cg.store.models import Analysis, Application, ApplicationLimitations, ApplicationVersion
9+
from cg.store.models import (
10+
Analysis,
11+
Application,
12+
ApplicationLimitations,
13+
ApplicationVersion,
14+
)
1015
from cg.store.models import Base as ModelBase
1116
from cg.store.models import (
1217
Case,
@@ -74,6 +79,12 @@ def _get_join_sample_family_query(self) -> Query:
7479
"""Return a join sample case relationship query."""
7580
return self._get_query(table=Sample).join(Case.links).join(CaseSample.sample)
7681

82+
def _get_join_sample_case_order_query(self) -> Query:
83+
"""Return a query joining sample, cases_sample, case and order. Selects from sample."""
84+
return (
85+
self._get_query(table=Sample).join(Case.links).join(CaseSample.sample).join(Case.orders)
86+
)
87+
7788
def _get_join_sample_application_version_query(self) -> Query:
7889
"""Return join sample to application version query."""
7990
return (

cg/store/crud/read.py

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -313,25 +313,26 @@ def filter_cases_with_samples(self, case_ids: list[str]) -> list[str]:
313313

314314
def get_cases_by_ticket_id(self, ticket_id: str) -> list[Case]:
315315
"""Return cases associated with a given ticket id."""
316-
return apply_case_filter(
317-
cases=self._get_query(table=Case),
318-
filter_functions=[CaseFilter.BY_TICKET],
319-
ticket_id=ticket_id,
320-
).all()
316+
if order := apply_order_filters(
317+
orders=self._get_query(table=Order),
318+
filters=[OrderFilter.BY_TICKET_ID],
319+
ticket_id=int(ticket_id),
320+
).first():
321+
return order.cases
322+
return []
321323

322324
def get_customer_id_from_ticket(self, ticket: str) -> str:
323325
"""Returns the customer related to given ticket."""
324-
cases: list[Case] = self.get_cases_by_ticket_id(ticket_id=ticket)
325-
if not cases:
326-
raise ValueError(f"No case found for ticket {ticket}")
327-
return cases[0].customer.internal_id
326+
if order := self.get_order_by_ticket_id(int(ticket)):
327+
return order.customer.internal_id
328+
raise ValueError(f"No order found for ticket {ticket}")
328329

329330
def get_samples_from_ticket(self, ticket: str) -> list[Sample]:
330331
"""Returns the samples related to given ticket."""
331-
return apply_case_filter(
332-
cases=self._get_join_sample_family_query(),
333-
filter_functions=[CaseFilter.BY_TICKET],
334-
ticket_id=ticket,
332+
return apply_order_filters(
333+
orders=self._get_join_sample_case_order_query(),
334+
filters=[OrderFilter.BY_TICKET_ID],
335+
ticket_id=int(ticket),
335336
).all()
336337

337338
def get_latest_ticket_from_case(self, case_id: str) -> str:

cg/store/filters/status_case_filters.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -96,11 +96,6 @@ def filter_cases_by_priority(cases: Query, priority: str, **kwargs) -> Query:
9696
return cases.filter(Case.priority == priority)
9797

9898

99-
def filter_cases_by_ticket_id(cases: Query, ticket_id: str, **kwargs) -> Query:
100-
"""Filter cases with matching ticket id."""
101-
return cases.filter(Case.tickets.contains(ticket_id))
102-
103-
10499
def filter_cases_for_analysis(cases: Query, **kwargs) -> Query:
105100
"""Filter cases in need of analysis by:
106101
1. Action set to analyze or
@@ -289,7 +284,6 @@ class CaseFilter(Enum):
289284
BY_WORKFLOWS: Callable = filter_cases_by_workflows
290285
BY_WORKFLOW_SEARCH: Callable = filter_cases_by_workflow_search
291286
BY_PRIORITY: Callable = filter_cases_by_priority
292-
BY_TICKET: Callable = filter_cases_by_ticket_id
293287
FOR_ANALYSIS: Callable = filter_cases_for_analysis
294288
HAS_INACTIVE_ANALYSIS: Callable = filter_inactive_analysis_cases
295289
HAS_SEQUENCE: Callable = filter_cases_has_sequence

tests/store/filters/test_status_cases_filters.py

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
filter_cases_by_entry_id,
1313
filter_cases_by_name,
1414
filter_cases_by_priority,
15-
filter_cases_by_ticket_id,
1615
filter_cases_by_workflow_search,
1716
filter_cases_for_analysis,
1817
filter_cases_has_sequence,
@@ -704,36 +703,6 @@ def test_filter_running_cases_only_running_cases(store_with_multiple_cases_and_s
704703
assert active_cases.count() == cases_query.count()
705704

706705

707-
def test_filter_cases_by_ticket_no_matching_ticket(
708-
store_with_multiple_cases_and_samples: Store, non_existent_id: str
709-
):
710-
"""Test that no cases are returned when filtering by a non-existent ticket."""
711-
# GIVEN a store containing cases with no matching ticket id
712-
cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Case)
713-
714-
# WHEN filtering cases by a non-existent ticket
715-
filtered_cases: Query = filter_cases_by_ticket_id(cases=cases_query, ticket_id=non_existent_id)
716-
717-
# THEN the query should return no cases
718-
assert filtered_cases.count() == 0
719-
720-
721-
def test_filter_cases_by_ticket_matching_ticket(
722-
store_with_multiple_cases_and_samples: Store, ticket_id: str
723-
):
724-
"""Test that cases are returned when filtering by an existing ticket id."""
725-
# GIVEN a store containing cases with a matching ticket id
726-
cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Case)
727-
728-
# WHEN filtering cases by an existing ticket id
729-
filtered_cases: Query = filter_cases_by_ticket_id(cases=cases_query, ticket_id=ticket_id)
730-
731-
# THEN the query should return cases with the matching ticket
732-
assert filtered_cases.count() > 0
733-
for case in filtered_cases:
734-
assert ticket_id in case.tickets
735-
736-
737706
def test_filter_cases_by_customer_entry_ids(store_with_multiple_cases_and_samples: Store):
738707
"""Test that cases are returned when filtering by customer entry ids."""
739708
# GIVEN a store containing cases with customer ids
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
from sqlalchemy.orm import Query
2+
3+
from cg.constants import Workflow
4+
from cg.store.filters.status_order_filters import filter_orders_by_ticket_id
5+
from cg.store.models import Order
6+
from cg.store.store import Store
7+
8+
9+
def test_filter_orders_by_ticket_no_matching_ticket(base_store: Store, non_existent_id: str):
10+
"""Test that no cases are returned when filtering by a non-existent ticket."""
11+
# GIVEN a store containing orders with no matching ticket id
12+
order = Order(
13+
id=1,
14+
customer_id=1,
15+
ticket_id=1,
16+
workflow=Workflow.MIP_DNA,
17+
)
18+
base_store.session.add(order)
19+
base_store.session.commit()
20+
order_query: Query = base_store._get_query(table=Order)
21+
22+
# WHEN filtering orders by a non-existent ticket
23+
filtered_orders: Query = filter_orders_by_ticket_id(orders=order_query, ticket_id=2)
24+
25+
# THEN the query should return no order
26+
assert filtered_orders.count() == 0
27+
28+
29+
def test_filter_orders_by_ticket_id_matching_ticket(base_store: Store, ticket_id: str):
30+
"""Test that the order is returned when filtering by an existing ticket id."""
31+
32+
order = Order(
33+
id=1,
34+
customer_id=1,
35+
ticket_id=int(ticket_id),
36+
workflow=Workflow.MIP_DNA,
37+
)
38+
base_store.session.add(order)
39+
base_store.session.commit()
40+
41+
# GIVEN a store containing an order with a matching ticket id
42+
order_query: Query = base_store._get_query(table=Order)
43+
44+
# WHEN filtering orders by an existing ticket id
45+
filtered_orders: Query = filter_orders_by_ticket_id(
46+
orders=order_query, ticket_id=int(ticket_id)
47+
)
48+
49+
# THEN the query should return cases with the matching ticket
50+
assert filtered_orders.count() == 1
51+
assert filtered_orders.first().ticket_id == int(ticket_id)

tests/store_helpers.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,11 @@ def ensure_case_from_dict(
552552
):
553553
"""Load a case with samples and link relations from a dictionary."""
554554
customer_obj = StoreHelpers.ensure_customer(store)
555+
order = store.get_order_by_ticket_id(ticket_id=int(case_info["tickets"])) or Order(
556+
ticket_id=int(case_info["tickets"]),
557+
customer_id=customer_obj.id,
558+
workflow=case_info.get("data_analysis", Workflow.MIP_DNA),
559+
)
555560
case = Case(
556561
name=case_info["name"],
557562
panels=case_info["panels"],
@@ -563,7 +568,7 @@ def ensure_case_from_dict(
563568
action=case_info.get("action"),
564569
tickets=case_info["tickets"],
565570
)
566-
571+
case.orders.append(order)
567572
case = StoreHelpers.add_case(store, case_obj=case, customer_id=customer_obj.internal_id)
568573

569574
app_tag = app_tag or "WGSPCFC030"

0 commit comments

Comments
 (0)