Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 44 additions & 32 deletions lambdas/services/create_document_reference_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@
from models.fhir.R4.fhir_document_reference import Attachment, DocumentReferenceInfo
from pydantic import ValidationError
from services.base.ssm_service import SSMService
from services.feature_flags_service import FeatureFlagService
from services.post_fhir_document_reference_service import (
PostFhirDocumentReferenceService,
)
from utils import upload_file_configs
from utils.audit_logging_setup import LoggingService
from utils.common_query_filters import get_document_type_filter
from utils.constants.ssm import UPLOAD_PILOT_ODS_ALLOWED_LIST
from utils.dynamo_query_filter_builder import DynamoQueryFilterBuilder
from utils.exceptions import (
ConfigNotFoundException,
Expand Down Expand Up @@ -49,13 +49,16 @@ class CreateDocumentReferenceService:
def __init__(self):
self.post_fhir_doc_ref_service = PostFhirDocumentReferenceService()
self.ssm_service = SSMService()
self.feature_flag_service = FeatureFlagService()

self.lg_dynamo_table = os.getenv("LLOYD_GEORGE_DYNAMODB_NAME")
self.staging_bucket_name = os.getenv("STAGING_STORE_BUCKET_NAME")
self.upload_sub_folder = "user_upload"

def create_document_reference_request(
self, nhs_number: str, documents_list: list[dict]
self,
nhs_number: str,
documents_list: list[dict],
):
upload_document_names = []
url_responses = {}
Expand All @@ -73,18 +76,19 @@ def create_document_reference_request(

for validated_doc in upload_request_documents:
snomed_code = validated_doc.doc_type
config = upload_file_configs.get_config_by_snomed_code(
snomed_code
)
config = upload_file_configs.get_config_by_snomed_code(snomed_code)

if config.single_file_only:
self.check_existing_records_and_remove_failed_upload(
nhs_number,
snomed_code
snomed_code,
)

document_reference = self.create_document_reference(
nhs_number, user_ods_code, validated_doc, snomed_code
nhs_number,
user_ods_code,
validated_doc,
snomed_code,
)

self.validate_document_file_type(validated_doc, config)
Expand Down Expand Up @@ -126,13 +130,21 @@ def create_document_reference_request(
raise DocumentRefException(400, LambdaError.DocRefInvalidFiles)

def validate_document_file_type(self, validated_doc, document_config):
if not is_file_type_allowed(validated_doc.file_name, document_config.accepted_file_types):
if not is_file_type_allowed(
validated_doc.file_name,
document_config.accepted_file_types,
):
raise LGInvalidFilesException(
f"Unsupported file type for file: {validated_doc.file_name}"
f"Unsupported file type for file: {validated_doc.file_name}",
)

def build_and_process_fhir_doc_ref(
self, nhs_number, user_ods_code, validated_doc, snomed_code, document_reference
self,
nhs_number,
user_ods_code,
validated_doc,
snomed_code,
document_reference,
):
doc_ref_info = self.build_doc_ref_info(
validated_doc,
Expand All @@ -142,11 +154,11 @@ def build_and_process_fhir_doc_ref(
)

fhir_doc_ref = doc_ref_info.create_fhir_document_reference_object(
document_reference
document_reference,
)

fhir_response = self.post_fhir_doc_ref_service.process_fhir_document_reference(
fhir_doc_ref.model_dump_json()
fhir_doc_ref.model_dump_json(),
)

return fhir_response
Expand All @@ -159,7 +171,11 @@ def validate_patient_user_ods_codes_match(self, user_ods_code, patient_ods_code)
raise DocumentRefException(401, LambdaError.DocRefUnauthorizedOdsCode)

def build_doc_ref_info(
self, validated_doc, nhs_number, snomed_code, user_ods_code
self,
validated_doc,
nhs_number,
snomed_code,
user_ods_code,
) -> DocumentReferenceInfo:
attachment_details = Attachment(
title=validated_doc.file_name,
Expand All @@ -176,14 +192,17 @@ def build_doc_ref_info(
return doc_ref_info

def check_if_user_ods_code_is_in_pilot(self, ods_code) -> bool:
pilot_ods_codes = self.get_allowed_list_of_ods_codes_for_upload_pilot()
if ods_code in pilot_ods_codes:
pilot_ods_codes = (
self.feature_flag_service.get_allowed_list_of_ods_codes_for_upload_pilot()
)
if ods_code in pilot_ods_codes or pilot_ods_codes == []:
return True
else:
raise OdsErrorException()

def parse_documents_list(
self, document_list: list[dict]
self,
document_list: list[dict],
) -> list[UploadRequestDocument]:
upload_request_document_list = []
for document in document_list:
Expand Down Expand Up @@ -250,7 +269,7 @@ def check_existing_records_and_remove_failed_upload(
)
if not previous_records:
logger.info(
"No record was found for this patient. Will continue to create doc ref."
"No record was found for this patient. Will continue to create doc ref.",
)
return

Expand All @@ -261,7 +280,7 @@ def check_existing_records_and_remove_failed_upload(
def stop_if_upload_is_in_process(self, previous_records: list[DocumentReference]):
if any(
self.post_fhir_doc_ref_service.document_service.is_upload_in_process(
document
document,
)
for document in previous_records
):
Expand All @@ -276,7 +295,7 @@ def stop_if_all_records_uploaded(self, previous_records: list[DocumentReference]
if all_records_uploaded:
logger.info(
"The patient already has a full set of record. "
"We should not be processing the new Lloyd George record upload."
"We should not be processing the new Lloyd George record upload.",
)
logger.error(
f"{LambdaError.DocRefRecordAlreadyInPlace.to_str()}",
Expand All @@ -291,30 +310,23 @@ def remove_records_of_failed_upload(
):
logger.info(
"Found previous records of failed upload. "
"Will delete those records before creating new document references."
"Will delete those records before creating new document references.",
)

logger.info("Deleting files from s3...")
for record in failed_upload_records:
s3_bucket_name, s3_file_key = record._parse_s3_location(
record.file_location
record.file_location,
)
self.post_fhir_doc_ref_service.s3_service.delete_object(
s3_bucket_name, s3_file_key
s3_bucket_name,
s3_file_key,
)

logger.info("Deleting dynamodb record...")
self.post_fhir_doc_ref_service.document_service.hard_delete_metadata_records(
table_name=table_name, document_references=failed_upload_records
table_name=table_name,
document_references=failed_upload_records,
)

logger.info("Previous failed records are deleted.")

def get_allowed_list_of_ods_codes_for_upload_pilot(self) -> list[str]:
logger.info(
"Starting ssm request to retrieve allowed list of ODS codes for Upload Pilot"
)
response = self.ssm_service.get_ssm_parameter(UPLOAD_PILOT_ODS_ALLOWED_LIST)
if not response:
logger.warning("No ODS codes found in allowed list for Upload Pilot")
return response
17 changes: 10 additions & 7 deletions lambdas/services/feature_flags_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,33 +130,36 @@ def get_feature_flags_by_flag(self, flag: str):

def get_allowed_list_of_ods_codes_for_upload_pilot(self) -> list[str]:
logger.info(
"Starting ssm request to retrieve allowed list of ODS codes for Upload Pilot"
"Starting ssm request to retrieve allowed list of ODS codes for Upload Pilot",
)
response = self.ssm_service.get_ssm_parameter(UPLOAD_PILOT_ODS_ALLOWED_LIST)
if not response:
response = self.ssm_service.get_ssm_parameter(
UPLOAD_PILOT_ODS_ALLOWED_LIST,
).split(",")
if not response or response == ["*"]:
logger.warning("No ODS codes found in allowed list for Upload Pilot")
return []
return response.split(",")
return response

def check_if_ods_code_is_in_pilot(self) -> bool:
ods_code = ""

if isinstance(request_context.authorization, dict):
ods_code = request_context.authorization.get(
"selected_organisation", {}
"selected_organisation",
{},
).get("org_ods_code", "")

if not ods_code:
return False
pilot_ods_codes = self.get_allowed_list_of_ods_codes_for_upload_pilot()

return ods_code in pilot_ods_codes
return ods_code in pilot_ods_codes or pilot_ods_codes == []

def validate_feature_flag(self, flag_name: str):
flag_object = self.get_feature_flags_by_flag(flag_name)

if not flag_object.get(flag_name, False):
logger.info(
f"Feature flag '{flag_name}' not enabled, event will not be processed"
f"Feature flag '{flag_name}' not enabled, event will not be processed",
)
raise FeatureFlagsException(404, LambdaError.FeatureFlagDisabled)
55 changes: 34 additions & 21 deletions lambdas/services/update_document_reference_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
from pydantic import ValidationError
from services.base.ssm_service import SSMService
from services.document_service import DocumentService
from services.feature_flags_service import FeatureFlagService
from services.put_fhir_document_reference_service import PutFhirDocumentReferenceService
from utils.audit_logging_setup import LoggingService
from utils.common_query_filters import CurrentStatusFile, NotDeleted
from utils.constants.ssm import UPLOAD_PILOT_ODS_ALLOWED_LIST
from utils.dynamo_utils import DocTypeTableRouter
from utils.exceptions import (
InvalidNhsNumberException,
Expand All @@ -38,10 +38,14 @@ def __init__(self):
self.fhir_doc_ref_service = PutFhirDocumentReferenceService()
self.document_service = DocumentService()
self.ssm_service = SSMService()
self.feature_flag_service = FeatureFlagService()
self.doctype_table_router = DocTypeTableRouter()

def update_document_reference_request(
self, nhs_number: str, document: dict, doc_ref_id: str
self,
nhs_number: str,
document: dict,
doc_ref_id: str,
):
self.validate_doc_ref_exists(doc_ref_id)

Expand All @@ -64,12 +68,16 @@ def update_document_reference_request(
self.validate_user_patient_ods_match(patient_ods_code, user_ods_code)

validate_files_for_access_and_store(
[update_request_document], pds_patient_details
[update_request_document],
pds_patient_details,
)
self.stop_if_upload_is_in_progress(nhs_number)

fhir_response = self.build_and_process_fhir_doc_ref(
nhs_number, doc_ref_id, update_request_document, user_ods_code
nhs_number,
doc_ref_id,
update_request_document,
user_ods_code,
)

fhir_response_data = json.loads(fhir_response)
Expand Down Expand Up @@ -97,24 +105,32 @@ def update_document_reference_request(
raise DocumentRefException(400, LambdaError.DocRefInvalidFiles)

def build_and_process_fhir_doc_ref(
self, nhs_number, doc_ref_id, update_request_document, user_ods_code
self,
nhs_number,
doc_ref_id,
update_request_document,
user_ods_code,
):
snomed_code_type = self.get_snomed_code_from_doc(update_request_document)

doc_ref_info = self.build_doc_ref_info(
nhs_number, update_request_document, snomed_code_type, user_ods_code
nhs_number,
update_request_document,
snomed_code_type,
user_ods_code,
)

logger.info(f"Updating document reference for client id: {doc_ref_id}")

validate_doc_version = update_request_document.version_id

fhir_doc_ref = doc_ref_info.create_fhir_document_reference_object_basic(
doc_ref_id, validate_doc_version
doc_ref_id,
validate_doc_version,
)

fhir_response = self.fhir_doc_ref_service.process_fhir_document_reference(
fhir_doc_ref.model_dump_json()
fhir_doc_ref.model_dump_json(),
)

return fhir_response
Expand Down Expand Up @@ -153,7 +169,11 @@ def get_snomed_code_from_doc(self, update_request_document):
return snomed_code_type

def build_doc_ref_info(
self, nhs_number, update_request_document, snomed_code_type, user_ods_code
self,
nhs_number,
update_request_document,
snomed_code_type,
user_ods_code,
):
attachment_details = Attachment(
title=update_request_document.file_name,
Expand All @@ -169,16 +189,18 @@ def build_doc_ref_info(
return doc_ref_info

def check_if_ods_code_is_in_pilot(self, ods_code) -> bool:
pilot_ods_codes = self.get_allowed_list_of_ods_codes_for_upload_pilot()
if ods_code in pilot_ods_codes:
pilot_ods_codes = (
self.feature_flag_service.get_allowed_list_of_ods_codes_for_upload_pilot()
)
if ods_code in pilot_ods_codes or pilot_ods_codes == []:
return True
else:
raise OdsErrorException()

def parse_document(self, document: dict) -> UploadRequestDocument:
try:
validated_doc: UploadRequestDocument = UploadRequestDocument.model_validate(
document
document,
)
except ValidationError as e:
logger.error(
Expand Down Expand Up @@ -207,12 +229,3 @@ def stop_if_upload_is_in_progress(self, nhs_number: str):
{"Result": UPDATE_REFERENCE_FAILED_MESSAGE},
)
raise DocumentRefException(423, LambdaError.UploadInProgressError)

def get_allowed_list_of_ods_codes_for_upload_pilot(self) -> list[str]:
logger.info(
"Starting ssm request to retrieve allowed list of ODS codes for Upload Pilot"
)
response = self.ssm_service.get_ssm_parameter(UPLOAD_PILOT_ODS_ALLOWED_LIST)
if not response:
logger.warning("No ODS codes found in allowed list for Upload Pilot")
return response
Loading
Loading