33from enums .document_review_status import DocumentReviewStatus
44from enums .metadata_field_names import DocumentReferenceMetadataFields
55from enums .snomed_codes import SnomedCodes
6- from pydantic import BaseModel , ConfigDict , Field
7- from pydantic .alias_generators import to_pascal , to_camel
6+ from pydantic import BaseModel , ConfigDict , Field , model_validator
7+ from pydantic .alias_generators import to_camel , to_pascal
8+ from utils .exceptions import InvalidNhsNumberException
9+ from utils .utilities import validate_nhs_number
810
911
1012class DocumentReviewFileDetails (BaseModel ):
@@ -41,10 +43,8 @@ class DocumentUploadReviewReference(BaseModel):
4143 upload_date : int
4244 files : list [DocumentReviewFileDetails ] = Field (min_length = 1 )
4345 nhs_number : str
44- ttl : int | None = Field (
45- alias = str (DocumentReferenceMetadataFields .TTL .value ), default = None
46- )
47- document_reference_id : str | None = Field (default = None )
46+ version : int = Field (default = 1 )
47+ document_reference_id : str = Field (default = None )
4848 document_snomed_code_type : str = Field (default = SnomedCodes .LLOYD_GEORGE .value .code )
4949
5050 def model_dump_camel_case (self , * args , ** kwargs ):
@@ -66,4 +66,63 @@ def camelize(self, model: dict) -> dict:
6666 value = result
6767 camel_case_dict [to_camel (key )] = value
6868
69- return camel_case_dict
69+ return camel_case_dict
70+
71+ class PatchDocumentReviewRequest (BaseModel ):
72+ model_config = ConfigDict (
73+ validate_by_alias = True ,
74+ populate_by_name = True ,
75+ alias_generator = to_camel ,
76+ use_enum_values = True ,
77+ )
78+
79+ review_status : DocumentReviewStatus = Field (..., description = "Review outcome" )
80+ document_reference_id : str | None = Field (
81+ default = None ,
82+ description = "Document reference ID (required when status is APPROVED)" ,
83+ )
84+ nhs_number : str | None = Field (
85+ default = None ,
86+ description = "New NHS number (required when status is REASSIGNED)" ,
87+ )
88+
89+ @model_validator (mode = "after" )
90+ def validate_document_reference_id (self ):
91+ """Ensure document_reference_id is provided when review_status is APPROVED."""
92+ if (
93+ self .review_status == DocumentReviewStatus .APPROVED
94+ and not self .document_reference_id
95+ ):
96+ raise ValueError (
97+ "document_reference_id is required when review_status is APPROVED"
98+ )
99+ elif (
100+ self .review_status != DocumentReviewStatus .APPROVED
101+ and self .document_reference_id
102+ ):
103+ raise ValueError (
104+ "document_reference_id is not required when review_status is not APPROVED"
105+ )
106+ return self
107+
108+ @model_validator (mode = "after" )
109+ def validate_reassign_nhs_number (self ):
110+ """
111+ Validate the reassignment of the NHS number after the input data model has been populated.
112+
113+ Checks whether the `reassigned_nhs_number` field has been provided and is valid when the
114+ `review_status` reflects a reassigned state. Raises an error if validation fails.
115+ """
116+ if (
117+ self .review_status == DocumentReviewStatus .REASSIGNED
118+ and not self .nhs_number
119+ ):
120+ raise ValueError (
121+ "reassigned_nhs_number is required when review_status is REASSIGNED or REASSIGNED_PATIENT_UNKNOWN"
122+ )
123+ elif self .review_status == DocumentReviewStatus .REASSIGNED and self .nhs_number :
124+ try :
125+ validate_nhs_number (self .nhs_number )
126+ except InvalidNhsNumberException :
127+ raise ValueError ("Invalid NHS number" )
128+ return self
0 commit comments