Skip to content

Commit 6c1a224

Browse files
authored
Add sample error mapping (#3840) (patch)
### Changed - Sample errors are mapped to their field in the response
1 parent 55ecceb commit 6c1a224

File tree

6 files changed

+56
-18
lines changed

6 files changed

+56
-18
lines changed

cg/services/order_validation_service/models/sample.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ class Sample(BaseModel):
99
container: ContainerEnum
1010
container_name: str | None = None
1111
name: str = Field(pattern=NAME_PATTERN, min_length=2, max_length=128)
12-
require_qc_ok: bool
1312
volume: int | None = None
1413
well_position: str | None = None
1514

cg/services/order_validation_service/response_mapper.py

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
from typing import Any
22

33
from cg.services.order_validation_service.errors.case_errors import CaseError
4-
from cg.services.order_validation_service.errors.case_sample_errors import CaseSampleError
4+
from cg.services.order_validation_service.errors.case_sample_errors import (
5+
CaseSampleError,
6+
)
57
from cg.services.order_validation_service.errors.order_errors import OrderError
6-
from cg.services.order_validation_service.errors.validation_errors import ValidationErrors
8+
from cg.services.order_validation_service.errors.sample_errors import SampleError
9+
from cg.services.order_validation_service.errors.validation_errors import (
10+
ValidationErrors,
11+
)
712

813

914
def create_order_validation_response(raw_order: dict, errors: ValidationErrors) -> dict:
@@ -17,6 +22,7 @@ def map_errors_to_order(order: dict, errors: ValidationErrors) -> None:
1722
map_order_errors(order=order, errors=errors.order_errors)
1823
map_case_errors(order=order, errors=errors.case_errors)
1924
map_case_sample_errors(order=order, errors=errors.case_sample_errors)
25+
map_sample_errors(order=order, errors=errors.sample_errors)
2026

2127

2228
def map_order_errors(order: dict, errors: list[OrderError]) -> None:
@@ -33,7 +39,13 @@ def map_case_errors(order: dict, errors: list[CaseError]) -> None:
3339
def map_case_sample_errors(order: dict, errors: list[CaseSampleError]) -> None:
3440
for error in errors:
3541
case: dict = get_case(order=order, index=error.case_index)
36-
sample: dict = get_sample(case=case, index=error.sample_index)
42+
sample: dict = get_case_sample(case=case, index=error.sample_index)
43+
add_error(entity=sample, field=error.field, message=error.message)
44+
45+
46+
def map_sample_errors(order: dict, errors: list[SampleError]) -> None:
47+
for error in errors:
48+
sample: dict = get_sample(order=order, index=error.sample_index)
3749
add_error(entity=sample, field=error.field, message=error.message)
3850

3951

@@ -47,13 +59,20 @@ def get_case(order: dict, index: int) -> dict:
4759
return order["cases"][index]
4860

4961

50-
def get_sample(case: dict, index: int) -> dict:
62+
def get_case_sample(case: dict, index: int) -> dict:
5163
return case["samples"][index]
5264

5365

66+
def get_sample(order: dict, index: int) -> dict:
67+
return order["samples"][index]
68+
69+
5470
def wrap_fields(raw_order: dict) -> None:
5571
wrap_order_fields(raw_order)
56-
wrap_case_and_sample_fields(raw_order)
72+
if raw_order.get("cases"):
73+
wrap_case_and_sample_fields(raw_order)
74+
else:
75+
wrap_sample_fields(raw_order["samples"])
5776

5877

5978
def wrap_order_fields(raw_order: dict) -> None:
@@ -65,7 +84,7 @@ def wrap_order_fields(raw_order: dict) -> None:
6584
def wrap_case_and_sample_fields(raw_order: dict) -> None:
6685
for case in raw_order["cases"]:
6786
wrap_case_fields(case)
68-
wrap_sample_fields(case)
87+
wrap_sample_fields(case["samples"])
6988

7089

7190
def wrap_case_fields(case: dict) -> None:
@@ -74,8 +93,7 @@ def wrap_case_fields(case: dict) -> None:
7493
set_field(entity=case, field=field, value=value)
7594

7695

77-
def wrap_sample_fields(case: dict) -> None:
78-
samples: list[dict] = case.get("samples", [])
96+
def wrap_sample_fields(samples: list[dict]) -> None:
7997
for sample in samples:
8098
for field, value in sample.items():
8199
set_field(entity=sample, field=field, value=value)

cg/services/order_validation_service/workflows/balsamic/models/sample.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
from pydantic import Field
2+
23
from cg.constants.constants import GenomeVersion
34
from cg.models.orders.sample_base import NAME_PATTERN, ControlEnum, SexEnum, StatusEnum
4-
from cg.services.order_validation_service.constants import ElutionBuffer, TissueBlockEnum
5+
from cg.services.order_validation_service.constants import (
6+
ElutionBuffer,
7+
TissueBlockEnum,
8+
)
59
from cg.services.order_validation_service.models.sample import Sample
610

711

@@ -18,6 +22,7 @@ class BalsamicSample(Sample):
1822
phenotype_terms: list[str] | None = None
1923
post_formalin_fixation_time: int | None = None
2024
reference_genome: GenomeVersion
25+
require_qc_ok: bool
2126
sex: SexEnum
2227
source: str
2328
status: StatusEnum | None = None

cg/services/order_validation_service/workflows/microsalt/validation_service.py

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,30 @@
11
from cg.services.order_validation_service.errors.order_errors import OrderError
22
from cg.services.order_validation_service.errors.sample_errors import SampleError
3-
from cg.services.order_validation_service.errors.validation_errors import ValidationErrors
4-
from cg.services.order_validation_service.model_validator.model_validator import ModelValidator
5-
from cg.services.order_validation_service.order_validation_service import OrderValidationService
3+
from cg.services.order_validation_service.errors.validation_errors import (
4+
ValidationErrors,
5+
)
6+
from cg.services.order_validation_service.model_validator.model_validator import (
7+
ModelValidator,
8+
)
9+
from cg.services.order_validation_service.order_validation_service import (
10+
OrderValidationService,
11+
)
12+
from cg.services.order_validation_service.response_mapper import (
13+
create_order_validation_response,
14+
)
615
from cg.services.order_validation_service.utils import (
716
apply_order_validation,
817
apply_sample_validation,
918
)
10-
from cg.services.order_validation_service.workflows.microsalt.models.order import MicrosaltOrder
11-
from cg.services.order_validation_service.workflows.microsalt.validation_rules import SAMPLE_RULES
12-
from cg.services.order_validation_service.response_mapper import create_order_validation_response
13-
from cg.services.order_validation_service.workflows.order_validation_rules import ORDER_RULES
19+
from cg.services.order_validation_service.workflows.microsalt.models.order import (
20+
MicrosaltOrder,
21+
)
22+
from cg.services.order_validation_service.workflows.microsalt.validation_rules import (
23+
SAMPLE_RULES,
24+
)
25+
from cg.services.order_validation_service.workflows.order_validation_rules import (
26+
ORDER_RULES,
27+
)
1428
from cg.store.store import Store
1529

1630

@@ -26,7 +40,7 @@ def validate(self, raw_order: dict) -> dict:
2640
def _get_errors(self, raw_order: dict) -> ValidationErrors:
2741
order, field_errors = ModelValidator.validate(order=raw_order, model=MicrosaltOrder)
2842

29-
if field_errors:
43+
if not order:
3044
return field_errors
3145

3246
order_errors: list[OrderError] = apply_order_validation(

cg/services/order_validation_service/workflows/mip_dna/models/sample.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ class MipDnaSample(Sample):
1515
phenotype_groups: list[str] | None = None
1616
phenotype_terms: list[str] | None = None
1717
post_formalin_fixation_time: int | None = None
18+
require_qc_ok: bool
1819
sex: SexEnum
1920
source: str
2021
status: StatusEnum

cg/services/order_validation_service/workflows/tomte/models/sample.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class TomteSample(Sample):
1717
phenotype_terms: list[str] | None = None
1818
post_formalin_fixation_time: int | None = None
1919
reference_genome: GenomeVersion
20+
require_qc_ok: bool
2021
sex: SexEnum
2122
source: str
2223
status: StatusEnum

0 commit comments

Comments
 (0)