From bd8f5456bfa84abfc637969e62e242df913eee83 Mon Sep 17 00:00:00 2001 From: Venu-Ajitesh Date: Tue, 29 Apr 2025 12:34:14 +0530 Subject: [PATCH 01/12] FHIR: Renamed medication request full url --- .../converter/OPConsultationConverter.java | 10 +++---- .../dto/compositions/MakeOpComposition.java | 27 ++++++++++--------- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/OPConsultationConverter.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/OPConsultationConverter.java index 7ccc8e39..5e40ee4e 100644 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/OPConsultationConverter.java +++ b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/OPConsultationConverter.java @@ -455,12 +455,10 @@ private List makeMedicalHistoryList( private List makeAllergiesList( Patient patient, List practitionerList, - OPConsultationRequest opConsultationRequest) - throws ParseException { - return Optional.ofNullable(opConsultationRequest.getAllergies()) - .orElse(Collections.emptyList()) - .stream() - .filter(allergy -> allergy.isBlank() && allergy.isEmpty()) + OPConsultationRequest opConsultationRequest) { + + return Optional.ofNullable(opConsultationRequest.getAllergies()).orElse(List.of()).stream() + .filter(allergy -> allergy != null && !allergy.isBlank()) .map( StreamUtils.wrapException( allergy -> diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeOpComposition.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeOpComposition.java index 252510ad..b8646ab2 100644 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeOpComposition.java +++ b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeOpComposition.java @@ -111,7 +111,7 @@ private List makeCompositionSection( List otherObservationList, List documentReferenceList) { List sectionComponentList = new ArrayList<>(); - if (Objects.nonNull(chiefComplaintList)) { + if (chiefComplaintList != null && !chiefComplaintList.isEmpty()) { Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); sectionComponent.setCode( new CodeableConcept() @@ -129,7 +129,7 @@ private List makeCompositionSection( } sectionComponentList.add(sectionComponent); } - if (Objects.nonNull(physicalObservationList)) { + if (Objects.nonNull(physicalObservationList) && !physicalObservationList.isEmpty()) { Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); sectionComponent.setCode( new CodeableConcept() @@ -149,7 +149,7 @@ private List makeCompositionSection( } sectionComponentList.add(sectionComponent); } - if (Objects.nonNull(allergieList)) { + if (Objects.nonNull(allergieList) && !allergieList.isEmpty()) { Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); sectionComponent.setCode( new CodeableConcept() @@ -169,7 +169,7 @@ private List makeCompositionSection( } sectionComponentList.add(sectionComponent); } - if (Objects.nonNull(medicalHistoryList)) { + if (Objects.nonNull(medicalHistoryList) && !medicalHistoryList.isEmpty()) { Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); sectionComponent.setCode( new CodeableConcept() @@ -187,7 +187,7 @@ private List makeCompositionSection( } sectionComponentList.add(sectionComponent); } - if (Objects.nonNull(familyMemberHistoryList)) { + if (Objects.nonNull(familyMemberHistoryList) && !familyMemberHistoryList.isEmpty()) { Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); sectionComponent.setCode( new CodeableConcept() @@ -205,7 +205,7 @@ private List makeCompositionSection( } sectionComponentList.add(sectionComponent); } - if (Objects.nonNull(investigationAdviceList)) { + if (Objects.nonNull(investigationAdviceList) && !investigationAdviceList.isEmpty()) { Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); sectionComponent.setCode( new CodeableConcept() @@ -223,7 +223,7 @@ private List makeCompositionSection( } sectionComponentList.add(sectionComponent); } - if (Objects.nonNull(medicationList)) { + if (Objects.nonNull(medicationList) && !medicationList.isEmpty()) { Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); sectionComponent.setCode( new CodeableConcept() @@ -236,11 +236,12 @@ private List makeCompositionSection( for (MedicationRequest medication : medicationList) { sectionComponent.addEntry( new Reference() - .setReference(BundleResourceIdentifier.FAMILY_HISTORY + "/" + medication.getId())); + .setReference( + BundleResourceIdentifier.MEDICATION_REQUEST + "/" + medication.getId())); } sectionComponentList.add(sectionComponent); } - if (Objects.nonNull(followupList)) { + if (Objects.nonNull(followupList) && !followupList.isEmpty()) { Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); sectionComponent.setCode( new CodeableConcept() @@ -257,7 +258,7 @@ private List makeCompositionSection( } sectionComponentList.add(sectionComponent); } - if (Objects.nonNull(procedureList)) { + if (Objects.nonNull(procedureList) && !procedureList.isEmpty()) { Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); sectionComponent.setCode( new CodeableConcept() @@ -274,7 +275,7 @@ private List makeCompositionSection( } sectionComponentList.add(sectionComponent); } - if (Objects.nonNull(referralList)) { + if (Objects.nonNull(referralList) && !referralList.isEmpty()) { Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); sectionComponent.setCode( new CodeableConcept() @@ -291,7 +292,7 @@ private List makeCompositionSection( } sectionComponentList.add(sectionComponent); } - if (Objects.nonNull(otherObservationList)) { + if (Objects.nonNull(otherObservationList) && !otherObservationList.isEmpty()) { Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); sectionComponent.setCode( new CodeableConcept() @@ -309,7 +310,7 @@ private List makeCompositionSection( } sectionComponentList.add(sectionComponent); } - if (Objects.nonNull(documentReferenceList)) { + if (Objects.nonNull(documentReferenceList) && !documentReferenceList.isEmpty()) { Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); sectionComponent.setCode( new CodeableConcept() From a954b533445c800b4dce595ecc58230bf4635135 Mon Sep 17 00:00:00 2001 From: Venu-Ajitesh Date: Wed, 16 Jul 2025 04:00:30 +0530 Subject: [PATCH 02/12] Fixed linking careContext raceCondition bug and RequestLogV3Service --- .../tables/helpers/FieldIdentifiers.java | 2 + .../mongo/tables/helpers/RequestStatus.java | 10 +- .../mongo/services/RequestLogV3Service.java | 149 +++++++++++------- .../HIPHealthInformationV3Service.java | 90 +++++++---- .../link/hipInitiated/HIPLinkV3Service.java | 18 ++- 5 files changed, 176 insertions(+), 93 deletions(-) diff --git a/src/main/java/in/nha/abdm/wrapper/v1/hip/hrp/database/mongo/tables/helpers/FieldIdentifiers.java b/src/main/java/in/nha/abdm/wrapper/v1/hip/hrp/database/mongo/tables/helpers/FieldIdentifiers.java index 851fff63..e02ccbf5 100644 --- a/src/main/java/in/nha/abdm/wrapper/v1/hip/hrp/database/mongo/tables/helpers/FieldIdentifiers.java +++ b/src/main/java/in/nha/abdm/wrapper/v1/hip/hrp/database/mongo/tables/helpers/FieldIdentifiers.java @@ -23,6 +23,8 @@ public class FieldIdentifiers { public static final String ENTITY = "entity"; public static final String ENTITY_TYPE = "entityType"; public static final String LAST_UPDATED = "lastUpdated"; + public static final String CREATED_ON = "createdOn"; + public static final String MODULE = "module"; public static final String LINK_TOKEN_REQUEST_ID = "linkTokenRequestId"; // Patient table. diff --git a/src/main/java/in/nha/abdm/wrapper/v1/hip/hrp/database/mongo/tables/helpers/RequestStatus.java b/src/main/java/in/nha/abdm/wrapper/v1/hip/hrp/database/mongo/tables/helpers/RequestStatus.java index 351f5d7d..64a7fcc9 100644 --- a/src/main/java/in/nha/abdm/wrapper/v1/hip/hrp/database/mongo/tables/helpers/RequestStatus.java +++ b/src/main/java/in/nha/abdm/wrapper/v1/hip/hrp/database/mongo/tables/helpers/RequestStatus.java @@ -53,7 +53,15 @@ public enum RequestStatus { ENCRYPTED_HEALTH_INFORMATION_RECEIVED("Encrypted Health Information received by HIU from HIP"), ENCRYPTED_HEALTH_INFORMATION_ERROR( "Error while receiving encrypted Health Information by HIU from HIP"), - DECRYPTION_ERROR("Unable to decrypt the data sent by HIP"); + DECRYPTION_ERROR("Unable to decrypt the data sent by HIP"), + FETCHING_BUNDLE("Fetching bundle from HIP"), + FETCHING_BUNDLE_ERROR("Error while fetching bundle from HIP"), + FETCHING_BUNDLE_SUCCESS("Bundle fetched successfully from HIP"), + ENCRYPTION_ERROR("Error while encrypting the data"), + ENCRYPTION_SUCCESS("Data encrypted successfully"), + DATA_TRANSFER_INITIATED("Data transfer initiated successfully"), + DATA_TRANSFER_ERROR("Error while initiating data transfer"), + DATA_TRANSFER_SUCCESS("Data transfer completed successfully"); private String value; diff --git a/src/main/java/in/nha/abdm/wrapper/v3/database/mongo/services/RequestLogV3Service.java b/src/main/java/in/nha/abdm/wrapper/v3/database/mongo/services/RequestLogV3Service.java index c6e8cb25..a16be6b7 100644 --- a/src/main/java/in/nha/abdm/wrapper/v3/database/mongo/services/RequestLogV3Service.java +++ b/src/main/java/in/nha/abdm/wrapper/v3/database/mongo/services/RequestLogV3Service.java @@ -29,12 +29,14 @@ import in.nha.abdm.wrapper.v3.hip.hrp.link.userInitiated.responses.InitV3Response; import in.nha.abdm.wrapper.v3.hip.hrp.share.requests.OnShareV3Request; import in.nha.abdm.wrapper.v3.hip.hrp.share.requests.ProfileShareV3Request; +import java.time.LocalDateTime; import java.util.*; import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.mongodb.core.FindAndModifyOptions; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; @@ -107,6 +109,17 @@ public void updateError(String requestId, Object errors, RequestStatus requestSt mongoTemplate.updateFirst(query, update, RequestLog.class); } + public void updateConsentStatus(String consentId, Object errors, RequestStatus requestStatus) { + Query query = new Query(Criteria.where(FieldIdentifiers.CONSENT_ID).is(consentId)); + Update update = new Update(); + if (errors != null) { + update.set(FieldIdentifiers.ERROR, errors); + } + update.set(FieldIdentifiers.STATUS, requestStatus); + update.set(FieldIdentifiers.LAST_UPDATED, Utils.getCurrentDateTime()); + mongoTemplate.updateFirst(query, update, RequestLog.class); + } + /** * If any error encountered in the generation of LinkToken API this method is used to update in * requestLogs @@ -241,43 +254,44 @@ public RequestLog findRequestLogByTransactionId(String transactionId) { */ public void persistHipLinkRequest( LinkRecordsV3Request linkRecordsV3Request, RequestStatus status, Object errors) { + if (Objects.isNull(linkRecordsV3Request)) { return; } - RequestLog existingLog = logsRepo.findByClientRequestId(linkRecordsV3Request.getRequestId()); - if (Objects.isNull(existingLog)) { - RequestLog requestLog = new RequestLog(); - requestLog.setAbhaAddress(linkRecordsV3Request.getAbhaAddress()); - requestLog.setModule(FieldIdentifiers.HIP_INITIATED_LINKING); - requestLog.setCreatedOn(Utils.getCurrentDateTime()); - requestLog.setLastUpdated(Utils.getCurrentDateTime()); - requestLog.setClientRequestId(linkRecordsV3Request.getRequestId()); - requestLog.setGatewayRequestId(linkRecordsV3Request.getRequestId()); - requestLog.setHipId(linkRecordsV3Request.getRequesterId()); - requestLog.setStatus(status); - HashMap map = new HashMap<>(); - map.put(FieldIdentifiers.LINK_RECORDS_REQUEST, linkRecordsV3Request); - requestLog.setRequestDetails(map); - if (Objects.nonNull(errors)) { - requestLog.setError(errors); - } - mongoTemplate.save(requestLog); - return; + String requestId = linkRecordsV3Request.getRequestId(); + LocalDateTime now = Utils.getCurrentDateTime(); + + RequestLog existingLog = logsRepo.findByClientRequestId(requestId); + + Map requestDetails = + Optional.ofNullable(existingLog != null ? existingLog.getRequestDetails() : null) + .orElse(new HashMap<>()); + + requestDetails.put(FieldIdentifiers.LINK_RECORDS_REQUEST, linkRecordsV3Request); + + Query query = Query.query(Criteria.where(FieldIdentifiers.CLIENT_REQUEST_ID).is(requestId)); + + Update update = + new Update() + .set(FieldIdentifiers.LAST_UPDATED, now) + .set(FieldIdentifiers.STATUS, status) + .set(FieldIdentifiers.REQUEST_DETAILS, requestDetails); + + if (existingLog == null) { + update + .setOnInsert(FieldIdentifiers.ABHA_ADDRESS, linkRecordsV3Request.getAbhaAddress()) + .setOnInsert(FieldIdentifiers.MODULE, FieldIdentifiers.HIP_INITIATED_LINKING) + .setOnInsert(FieldIdentifiers.CREATED_ON, now) + .setOnInsert(FieldIdentifiers.CLIENT_REQUEST_ID, requestId) + .setOnInsert(FieldIdentifiers.GATEWAY_REQUEST_ID, requestId) + .setOnInsert(FieldIdentifiers.HIP_ID, linkRecordsV3Request.getRequesterId()); } - Query query = - new Query( - Criteria.where(FieldIdentifiers.CLIENT_REQUEST_ID) - .is(linkRecordsV3Request.getRequestId())); - Map map = existingLog.getRequestDetails(); - if (Objects.isNull(map)) { - map = new HashMap<>(); + + if (Objects.nonNull(errors)) { + update.set(FieldIdentifiers.ERROR, errors); } - map.replace(FieldIdentifiers.LINK_RECORDS_REQUEST, linkRecordsV3Request); - Update update = new Update(); - update.set(FieldIdentifiers.REQUEST_DETAILS, map); - update.set(FieldIdentifiers.STATUS, status); - update.set(FieldIdentifiers.LAST_UPDATED, Utils.getCurrentDateTime()); - mongoTemplate.updateFirst(query, update, RequestLog.class); + + mongoTemplate.upsert(query, update, RequestLog.class); } /** @@ -602,38 +616,57 @@ public void saveLinkTokenRequest( * *

Adding linkOnAddCareContextsResponse dump into db. * - * @param linkOnAddCareContextsV3Response Acknowledgement from ABDM gateway for HipLinking. + * @param response Acknowledgement from ABDM gateway for HipLinking. */ - public void setHipOnAddCareContextResponse( - LinkOnAddCareContextsV3Response linkOnAddCareContextsV3Response) + public void setHipOnAddCareContextResponse(LinkOnAddCareContextsV3Response response) throws IllegalDataStateException { - RequestLog RequestLog = - logsRepo.findByGatewayRequestId( - linkOnAddCareContextsV3Response.getResponse().getRequestId()); - if (RequestLog == null) { - throw new IllegalDataStateException( - "Request not found in database for: " - + linkOnAddCareContextsV3Response.getResponse().getRequestId()); - } - HashMap map = RequestLog.getRequestDetails(); - map.put(FieldIdentifiers.HIP_ON_ADD_CARE_CONTEXT_RESPONSE, linkOnAddCareContextsV3Response); - Query query = - new Query( - Criteria.where(FieldIdentifiers.GATEWAY_REQUEST_ID) - .is(linkOnAddCareContextsV3Response.getResponse().getRequestId())); - Update update = new Update(); - if ((Objects.nonNull(linkOnAddCareContextsV3Response.getError()))) { - update.set(FieldIdentifiers.ERROR, linkOnAddCareContextsV3Response.getError()); + String requestId = response.getResponse().getRequestId(); + log.info("Processing HIP OnAddCareContext response for requestId: {}", requestId); + + Query query = Query.query(Criteria.where(FieldIdentifiers.GATEWAY_REQUEST_ID).is(requestId)); + Update update = + new Update() + .set( + FieldIdentifiers.REQUEST_DETAILS + + "." + + FieldIdentifiers.HIP_ON_ADD_CARE_CONTEXT_RESPONSE, + response) + .set(FieldIdentifiers.LAST_UPDATED, Utils.getCurrentDateTime()); + + if (response.getError() != null) { + update.set(FieldIdentifiers.ERROR, response.getError()); } else { update.set(FieldIdentifiers.STATUS, RequestStatus.CARE_CONTEXT_LINKED); - LinkRecordsV3Request linkRecordsV3Request = - (LinkRecordsV3Request) - RequestLog.getRequestDetails().get(FieldIdentifiers.LINK_RECORDS_REQUEST); - patientService.addPatientCareContexts(linkRecordsV3Request); } - update.set(FieldIdentifiers.REQUEST_DETAILS, map); - mongoTemplate.updateFirst(query, update, RequestLog.class); + log.info("Querying gatewayRequestId = {}", requestId); + log.info("Query for requestId: {} {}", query, requestId); + log.info("Update for requestId: {} {}", update, requestId); + RequestLog updatedLog = + mongoTemplate.findAndModify( + query, update, FindAndModifyOptions.options().returnNew(true), RequestLog.class); + + if (updatedLog == null) { + log.warn( + "findAndModify returned null, fallback to fetch manually for requestId: {}", requestId); + updatedLog = logsRepo.findByGatewayRequestId(requestId); + + if (updatedLog == null) { + throw new IllegalDataStateException("Request not found in database for: " + requestId); + } + } + + if (response.getError() == null) { + Object raw = updatedLog.getRequestDetails().get(FieldIdentifiers.LINK_RECORDS_REQUEST); + if (raw instanceof LinkRecordsV3Request) { + patientService.addPatientCareContexts((LinkRecordsV3Request) raw); + } else { + log.warn( + "Expected LinkRecordsV3Request but got: {}", + raw == null ? "null" : raw.getClass().getName()); + } + } + log.info("Successfully updated requestId: {}", requestId); } public RequestLog getLogsByAbhaAddress(String abhaAddress, String hipId) { diff --git a/src/main/java/in/nha/abdm/wrapper/v3/hip/hrp/dataTransfer/HIPHealthInformationV3Service.java b/src/main/java/in/nha/abdm/wrapper/v3/hip/hrp/dataTransfer/HIPHealthInformationV3Service.java index ebf522e2..f2fec9d1 100644 --- a/src/main/java/in/nha/abdm/wrapper/v3/hip/hrp/dataTransfer/HIPHealthInformationV3Service.java +++ b/src/main/java/in/nha/abdm/wrapper/v3/hip/hrp/dataTransfer/HIPHealthInformationV3Service.java @@ -7,6 +7,7 @@ import in.nha.abdm.wrapper.v1.common.models.RespRequest; import in.nha.abdm.wrapper.v1.common.requests.*; import in.nha.abdm.wrapper.v1.common.responses.ErrorResponse; +import in.nha.abdm.wrapper.v1.common.responses.ErrorV3Response; import in.nha.abdm.wrapper.v1.common.responses.GenericResponse; import in.nha.abdm.wrapper.v1.hip.hrp.consent.requests.HIPNotifyRequest; import in.nha.abdm.wrapper.v1.hip.hrp.dataTransfer.callback.HIPHealthInformationRequest; @@ -27,6 +28,7 @@ import in.nha.abdm.wrapper.v3.common.RequestV3Manager; import in.nha.abdm.wrapper.v3.common.exceptions.BadRequestHandler; import in.nha.abdm.wrapper.v3.common.models.GenericV3Response; +import in.nha.abdm.wrapper.v3.config.ErrorHandler; import in.nha.abdm.wrapper.v3.database.mongo.services.ConsentPatientV3Service; import in.nha.abdm.wrapper.v3.database.mongo.services.PatientV3Service; import in.nha.abdm.wrapper.v3.database.mongo.services.RequestLogV3Service; @@ -146,20 +148,32 @@ public void healthInformation( // Acknowledge to gateway that health information request has been received. healthInformationAcknowledgementRequest( hipHealthInformationRequest, onHealthInformationRequest, headers); + try { + // Sending the data to HIU only if there is no errors + if (Objects.isNull(onHealthInformationRequest.getError())) { + // Prepare health information bundle request which needs to be sent to HIU. + HealthInformationBundleResponse healthInformationBundleResponse = + fetchHealthInformationBundle(hipHealthInformationRequest, headers); + // Push the health information to HIU. + List> pushHealthInformationResponse = + pushHealthInformation(healthInformationBundleResponse, consentId, headers); + // Notify Gateway that health information was pushed to HIU. + healthInformationPushNotify( + hipHealthInformationRequest, consentId, pushHealthInformationResponse, headers); + } else { + // Sending BAD_REQUEST since there are some errors earlier + healthInformationPushNotify( + hipHealthInformationRequest, + consentId, + Collections.singletonList(new ResponseEntity<>(HttpStatus.BAD_REQUEST)), + headers); + } + } catch (Exception e) { + List errors = ErrorHandler.getErrors(e.getMessage()); + log.debug(errors); + requestLogV3Service.updateConsentStatus(consentId, errors, RequestStatus.DATA_TRANSFER_ERROR); - // Sending the data to HIU only if there is no errors - if (Objects.isNull(onHealthInformationRequest.getError())) { - // Prepare health information bundle request which needs to be sent to HIU. - HealthInformationBundleResponse healthInformationBundleResponse = - fetchHealthInformationBundle(hipHealthInformationRequest, headers); - // Push the health information to HIU. - List> pushHealthInformationResponse = - pushHealthInformation(healthInformationBundleResponse, consentId, headers); - // Notify Gateway that health information was pushed to HIU. - healthInformationPushNotify( - hipHealthInformationRequest, consentId, pushHealthInformationResponse, headers); - } else { - // Sending BAD_REQUEST since there are some errors earlier + // Notify Gateway that health information was pushed to HIU with BAD_REQUEST status. healthInformationPushNotify( hipHealthInformationRequest, consentId, @@ -212,27 +226,30 @@ private void healthInformationAcknowledgementRequest( private HealthInformationBundleResponse fetchHealthInformationBundle( HIPHealthInformationRequest hipHealthInformationRequest, HttpHeaders headers) throws IllegalDataStateException { - ConsentCareContextMapping existingLog = + ConsentCareContextMapping existingConsentLog = consentCareContextsService.findMappingByConsentId( hipHealthInformationRequest.getHiRequest().getConsent().getId()); + RequestLog existingLog = + requestLogV3Service.findByConsentId( + hipHealthInformationRequest.getHiRequest().getConsent().getId(), + GatewayConstants.HIP, + headers.getFirst(GatewayConstants.X_HIP_ID)); + if (existingLog == null) { + throw new IllegalDataStateException("Request log not found for consent id"); + } HIPNotifyRequest hipNotifyRequest = - (HIPNotifyRequest) - requestLogV3Service - .findByConsentId( - hipHealthInformationRequest.getHiRequest().getConsent().getId(), - GatewayConstants.HIP, - headers.getFirst(GatewayConstants.X_HIP_ID)) - .getRequestDetails() - .get(FieldIdentifiers.HIP_NOTIFY_REQUEST); + (HIPNotifyRequest) existingLog.getRequestDetails().get(FieldIdentifiers.HIP_NOTIFY_REQUEST); String hipId = hipNotifyRequest.getNotification().getConsentDetail().getHip().getId(); - if (existingLog == null) { + if (existingConsentLog == null) { throw new IllegalDataStateException("consent id not found in db"); } HealthInformationBundleRequest healthInformationBundleRequest = HealthInformationBundleRequest.builder() .hipId(hipId) - .careContextsWithPatientReferences(existingLog.getCareContexts()) + .careContextsWithPatientReferences(existingConsentLog.getCareContexts()) .build(); + requestLogV3Service.updateConsentStatus( + existingConsentLog.getConsentId(), null, RequestStatus.FETCHING_BUNDLE); log.debug( "Health information bundle request HIP : " + healthInformationBundleRequest.toString()); return hipClient.healthInformationBundleRequest(healthInformationBundleRequest).getBody(); @@ -298,6 +315,9 @@ private List fetchHealthInformationPushRequest( EncryptionResponse encryptedData = encryptionService.encrypt(hipHealthInformationRequest, healthInformationBundleResponse); + requestLogV3Service.updateConsentStatus( + hipNotifyRequest.getNotification().getConsentId(), null, RequestStatus.ENCRYPTION_SUCCESS); + HealthInformationDhPublicKey receiverDhPublicKey = hipHealthInformationRequest.getHiRequest().getKeyMaterial().getDhPublicKey(); @@ -362,7 +382,8 @@ private void healthInformationPushNotify( HIPHealthInformationRequest hipHealthInformationRequest, String consentId, List> pushHealthInformationResponse, - HttpHeaders headers) { + HttpHeaders headers) + throws IllegalDataStateException { boolean allSuccess = pushHealthInformationResponse.stream() .allMatch(response -> response.getStatusCode().is2xxSuccessful()); @@ -370,13 +391,14 @@ private void healthInformationPushNotify( String healthInformationStatus = allSuccess ? "DELIVERED" : "ERRORED"; String sessionStatus = allSuccess ? "TRANSFERRED" : "FAILED"; + RequestLog existingLog = + requestLogV3Service.findByConsentId( + consentId, GatewayConstants.HIP, headers.getFirst(GatewayConstants.X_HIP_ID)); + if (existingLog == null) { + throw new IllegalDataStateException("Request log not found for consent id: " + consentId); + } HIPNotifyRequest hipNotifyRequest = - (HIPNotifyRequest) - requestLogV3Service - .findByConsentId( - consentId, GatewayConstants.HIP, headers.getFirst(GatewayConstants.X_HIP_ID)) - .getRequestDetails() - .get(FieldIdentifiers.HIP_NOTIFY_REQUEST); + (HIPNotifyRequest) existingLog.getRequestDetails().get(FieldIdentifiers.HIP_NOTIFY_REQUEST); List listOfCareContexts = hipNotifyRequest.getNotification().getConsentDetail().getCareContexts(); List healthInformationStatusResponseList = new ArrayList<>(); @@ -415,6 +437,12 @@ private void healthInformationPushNotify( .notification(healthInformationNotificationStatus) .build(); log.info(healthInformationPushNotification.toString()); + if (allSuccess) { + requestLogV3Service.updateConsentStatus(consentId, null, RequestStatus.DATA_TRANSFER_SUCCESS); + } else { + requestLogV3Service.updateConsentStatus(consentId, null, RequestStatus.DATA_TRANSFER_ERROR); + log.error("Data transfer failed for consent id: " + consentId); + } try { ResponseEntity response = requestV3Manager.fetchResponseFromGateway( diff --git a/src/main/java/in/nha/abdm/wrapper/v3/hip/hrp/link/hipInitiated/HIPLinkV3Service.java b/src/main/java/in/nha/abdm/wrapper/v3/hip/hrp/link/hipInitiated/HIPLinkV3Service.java index 336cb991..9c587a20 100644 --- a/src/main/java/in/nha/abdm/wrapper/v3/hip/hrp/link/hipInitiated/HIPLinkV3Service.java +++ b/src/main/java/in/nha/abdm/wrapper/v3/hip/hrp/link/hipInitiated/HIPLinkV3Service.java @@ -99,7 +99,7 @@ public FacadeV3Response addCareContexts(LinkRecordsV3Request linkRecordsV3Reques linkRecordsV3Request.getRequesterId(), linkRecordsV3Request.getCareContexts()); - if (Objects.nonNull(sameCareContexts)) { + if (Objects.nonNull(sameCareContexts) && !sameCareContexts.isEmpty()) { return hipContextNotify(linkRecordsV3Request, patient, sameCareContexts); } @@ -153,6 +153,7 @@ private List buildPatientCareContextHIType( private FacadeV3Response sendAddCareContextsRequest( LinkRecordsV3Request request, AddCareContexts addCareContexts, String linkToken) { try { + requestLogV3Service.persistHipLinkRequest(request, RequestStatus.INITIATING, null); ResponseEntity response = requestV3Manager.fetchResponseFromGateway( addCareContextsPath, @@ -210,6 +211,15 @@ private FacadeV3Response buildErrorResponse( .build(); } + private FacadeV3Response buildErrorResponse( + LinkRecordsV3Request request, List errors) { + return FacadeV3Response.builder() + .clientRequestId(request.getRequestId()) + .httpStatusCode(HttpStatus.BAD_REQUEST) + .errors(errors) + .build(); + } + private FacadeV3Response handleAddCareContextError(LinkRecordsV3Request request) { ErrorResponse errorResponse = ErrorResponse.builder() @@ -228,8 +238,10 @@ private FacadeV3Response handleAddCareContextError(LinkRecordsV3Request request) private FacadeV3Response handleWebClientBadRequest( LinkRecordsV3Request request, WebClientResponseException.BadRequest ex) { Object error = BadRequestHandler.getError(ex); - requestLogV3Service.persistHipLinkRequest(request, RequestStatus.ADD_CARE_CONTEXT_ERROR, error); - return buildErrorResponse(request, "Wrapper-1001", ex.getMessage()); + List errorList = ErrorHandler.getErrors(error); + requestLogV3Service.persistHipLinkRequest( + request, RequestStatus.ADD_CARE_CONTEXT_ERROR, errorList); + return buildErrorResponse(request, errorList); } private FacadeV3Response handleGeneralException(LinkRecordsV3Request request, Exception ex) { From 0e9650155b080c333d4cdc364994e439ff1fa041 Mon Sep 17 00:00:00 2001 From: Venu-Ajitesh Date: Tue, 29 Apr 2025 12:34:14 +0530 Subject: [PATCH 03/12] FHIR: Renamed medication request full url --- .../converter/OPConsultationConverter.java | 10 +++---- .../dto/compositions/MakeOpComposition.java | 27 ++++++++++--------- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/OPConsultationConverter.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/OPConsultationConverter.java index 7ccc8e39..5e40ee4e 100644 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/OPConsultationConverter.java +++ b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/OPConsultationConverter.java @@ -455,12 +455,10 @@ private List makeMedicalHistoryList( private List makeAllergiesList( Patient patient, List practitionerList, - OPConsultationRequest opConsultationRequest) - throws ParseException { - return Optional.ofNullable(opConsultationRequest.getAllergies()) - .orElse(Collections.emptyList()) - .stream() - .filter(allergy -> allergy.isBlank() && allergy.isEmpty()) + OPConsultationRequest opConsultationRequest) { + + return Optional.ofNullable(opConsultationRequest.getAllergies()).orElse(List.of()).stream() + .filter(allergy -> allergy != null && !allergy.isBlank()) .map( StreamUtils.wrapException( allergy -> diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeOpComposition.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeOpComposition.java index 252510ad..b8646ab2 100644 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeOpComposition.java +++ b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeOpComposition.java @@ -111,7 +111,7 @@ private List makeCompositionSection( List otherObservationList, List documentReferenceList) { List sectionComponentList = new ArrayList<>(); - if (Objects.nonNull(chiefComplaintList)) { + if (chiefComplaintList != null && !chiefComplaintList.isEmpty()) { Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); sectionComponent.setCode( new CodeableConcept() @@ -129,7 +129,7 @@ private List makeCompositionSection( } sectionComponentList.add(sectionComponent); } - if (Objects.nonNull(physicalObservationList)) { + if (Objects.nonNull(physicalObservationList) && !physicalObservationList.isEmpty()) { Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); sectionComponent.setCode( new CodeableConcept() @@ -149,7 +149,7 @@ private List makeCompositionSection( } sectionComponentList.add(sectionComponent); } - if (Objects.nonNull(allergieList)) { + if (Objects.nonNull(allergieList) && !allergieList.isEmpty()) { Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); sectionComponent.setCode( new CodeableConcept() @@ -169,7 +169,7 @@ private List makeCompositionSection( } sectionComponentList.add(sectionComponent); } - if (Objects.nonNull(medicalHistoryList)) { + if (Objects.nonNull(medicalHistoryList) && !medicalHistoryList.isEmpty()) { Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); sectionComponent.setCode( new CodeableConcept() @@ -187,7 +187,7 @@ private List makeCompositionSection( } sectionComponentList.add(sectionComponent); } - if (Objects.nonNull(familyMemberHistoryList)) { + if (Objects.nonNull(familyMemberHistoryList) && !familyMemberHistoryList.isEmpty()) { Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); sectionComponent.setCode( new CodeableConcept() @@ -205,7 +205,7 @@ private List makeCompositionSection( } sectionComponentList.add(sectionComponent); } - if (Objects.nonNull(investigationAdviceList)) { + if (Objects.nonNull(investigationAdviceList) && !investigationAdviceList.isEmpty()) { Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); sectionComponent.setCode( new CodeableConcept() @@ -223,7 +223,7 @@ private List makeCompositionSection( } sectionComponentList.add(sectionComponent); } - if (Objects.nonNull(medicationList)) { + if (Objects.nonNull(medicationList) && !medicationList.isEmpty()) { Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); sectionComponent.setCode( new CodeableConcept() @@ -236,11 +236,12 @@ private List makeCompositionSection( for (MedicationRequest medication : medicationList) { sectionComponent.addEntry( new Reference() - .setReference(BundleResourceIdentifier.FAMILY_HISTORY + "/" + medication.getId())); + .setReference( + BundleResourceIdentifier.MEDICATION_REQUEST + "/" + medication.getId())); } sectionComponentList.add(sectionComponent); } - if (Objects.nonNull(followupList)) { + if (Objects.nonNull(followupList) && !followupList.isEmpty()) { Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); sectionComponent.setCode( new CodeableConcept() @@ -257,7 +258,7 @@ private List makeCompositionSection( } sectionComponentList.add(sectionComponent); } - if (Objects.nonNull(procedureList)) { + if (Objects.nonNull(procedureList) && !procedureList.isEmpty()) { Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); sectionComponent.setCode( new CodeableConcept() @@ -274,7 +275,7 @@ private List makeCompositionSection( } sectionComponentList.add(sectionComponent); } - if (Objects.nonNull(referralList)) { + if (Objects.nonNull(referralList) && !referralList.isEmpty()) { Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); sectionComponent.setCode( new CodeableConcept() @@ -291,7 +292,7 @@ private List makeCompositionSection( } sectionComponentList.add(sectionComponent); } - if (Objects.nonNull(otherObservationList)) { + if (Objects.nonNull(otherObservationList) && !otherObservationList.isEmpty()) { Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); sectionComponent.setCode( new CodeableConcept() @@ -309,7 +310,7 @@ private List makeCompositionSection( } sectionComponentList.add(sectionComponent); } - if (Objects.nonNull(documentReferenceList)) { + if (Objects.nonNull(documentReferenceList) && !documentReferenceList.isEmpty()) { Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); sectionComponent.setCode( new CodeableConcept() From 556271269649c68b0ab7d7d27a8288bd2629f38f Mon Sep 17 00:00:00 2001 From: Venu-Ajitesh Date: Wed, 16 Jul 2025 04:00:30 +0530 Subject: [PATCH 04/12] Fixed linking careContext raceCondition bug and RequestLogV3Service --- .../tables/helpers/FieldIdentifiers.java | 2 + .../mongo/tables/helpers/RequestStatus.java | 10 +- .../mongo/services/RequestLogV3Service.java | 149 +++++++++++------- .../HIPHealthInformationV3Service.java | 90 +++++++---- .../link/hipInitiated/HIPLinkV3Service.java | 15 +- 5 files changed, 168 insertions(+), 98 deletions(-) diff --git a/src/main/java/in/nha/abdm/wrapper/v1/hip/hrp/database/mongo/tables/helpers/FieldIdentifiers.java b/src/main/java/in/nha/abdm/wrapper/v1/hip/hrp/database/mongo/tables/helpers/FieldIdentifiers.java index 851fff63..e02ccbf5 100644 --- a/src/main/java/in/nha/abdm/wrapper/v1/hip/hrp/database/mongo/tables/helpers/FieldIdentifiers.java +++ b/src/main/java/in/nha/abdm/wrapper/v1/hip/hrp/database/mongo/tables/helpers/FieldIdentifiers.java @@ -23,6 +23,8 @@ public class FieldIdentifiers { public static final String ENTITY = "entity"; public static final String ENTITY_TYPE = "entityType"; public static final String LAST_UPDATED = "lastUpdated"; + public static final String CREATED_ON = "createdOn"; + public static final String MODULE = "module"; public static final String LINK_TOKEN_REQUEST_ID = "linkTokenRequestId"; // Patient table. diff --git a/src/main/java/in/nha/abdm/wrapper/v1/hip/hrp/database/mongo/tables/helpers/RequestStatus.java b/src/main/java/in/nha/abdm/wrapper/v1/hip/hrp/database/mongo/tables/helpers/RequestStatus.java index 351f5d7d..64a7fcc9 100644 --- a/src/main/java/in/nha/abdm/wrapper/v1/hip/hrp/database/mongo/tables/helpers/RequestStatus.java +++ b/src/main/java/in/nha/abdm/wrapper/v1/hip/hrp/database/mongo/tables/helpers/RequestStatus.java @@ -53,7 +53,15 @@ public enum RequestStatus { ENCRYPTED_HEALTH_INFORMATION_RECEIVED("Encrypted Health Information received by HIU from HIP"), ENCRYPTED_HEALTH_INFORMATION_ERROR( "Error while receiving encrypted Health Information by HIU from HIP"), - DECRYPTION_ERROR("Unable to decrypt the data sent by HIP"); + DECRYPTION_ERROR("Unable to decrypt the data sent by HIP"), + FETCHING_BUNDLE("Fetching bundle from HIP"), + FETCHING_BUNDLE_ERROR("Error while fetching bundle from HIP"), + FETCHING_BUNDLE_SUCCESS("Bundle fetched successfully from HIP"), + ENCRYPTION_ERROR("Error while encrypting the data"), + ENCRYPTION_SUCCESS("Data encrypted successfully"), + DATA_TRANSFER_INITIATED("Data transfer initiated successfully"), + DATA_TRANSFER_ERROR("Error while initiating data transfer"), + DATA_TRANSFER_SUCCESS("Data transfer completed successfully"); private String value; diff --git a/src/main/java/in/nha/abdm/wrapper/v3/database/mongo/services/RequestLogV3Service.java b/src/main/java/in/nha/abdm/wrapper/v3/database/mongo/services/RequestLogV3Service.java index c6e8cb25..a16be6b7 100644 --- a/src/main/java/in/nha/abdm/wrapper/v3/database/mongo/services/RequestLogV3Service.java +++ b/src/main/java/in/nha/abdm/wrapper/v3/database/mongo/services/RequestLogV3Service.java @@ -29,12 +29,14 @@ import in.nha.abdm.wrapper.v3.hip.hrp.link.userInitiated.responses.InitV3Response; import in.nha.abdm.wrapper.v3.hip.hrp.share.requests.OnShareV3Request; import in.nha.abdm.wrapper.v3.hip.hrp.share.requests.ProfileShareV3Request; +import java.time.LocalDateTime; import java.util.*; import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.mongodb.core.FindAndModifyOptions; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; @@ -107,6 +109,17 @@ public void updateError(String requestId, Object errors, RequestStatus requestSt mongoTemplate.updateFirst(query, update, RequestLog.class); } + public void updateConsentStatus(String consentId, Object errors, RequestStatus requestStatus) { + Query query = new Query(Criteria.where(FieldIdentifiers.CONSENT_ID).is(consentId)); + Update update = new Update(); + if (errors != null) { + update.set(FieldIdentifiers.ERROR, errors); + } + update.set(FieldIdentifiers.STATUS, requestStatus); + update.set(FieldIdentifiers.LAST_UPDATED, Utils.getCurrentDateTime()); + mongoTemplate.updateFirst(query, update, RequestLog.class); + } + /** * If any error encountered in the generation of LinkToken API this method is used to update in * requestLogs @@ -241,43 +254,44 @@ public RequestLog findRequestLogByTransactionId(String transactionId) { */ public void persistHipLinkRequest( LinkRecordsV3Request linkRecordsV3Request, RequestStatus status, Object errors) { + if (Objects.isNull(linkRecordsV3Request)) { return; } - RequestLog existingLog = logsRepo.findByClientRequestId(linkRecordsV3Request.getRequestId()); - if (Objects.isNull(existingLog)) { - RequestLog requestLog = new RequestLog(); - requestLog.setAbhaAddress(linkRecordsV3Request.getAbhaAddress()); - requestLog.setModule(FieldIdentifiers.HIP_INITIATED_LINKING); - requestLog.setCreatedOn(Utils.getCurrentDateTime()); - requestLog.setLastUpdated(Utils.getCurrentDateTime()); - requestLog.setClientRequestId(linkRecordsV3Request.getRequestId()); - requestLog.setGatewayRequestId(linkRecordsV3Request.getRequestId()); - requestLog.setHipId(linkRecordsV3Request.getRequesterId()); - requestLog.setStatus(status); - HashMap map = new HashMap<>(); - map.put(FieldIdentifiers.LINK_RECORDS_REQUEST, linkRecordsV3Request); - requestLog.setRequestDetails(map); - if (Objects.nonNull(errors)) { - requestLog.setError(errors); - } - mongoTemplate.save(requestLog); - return; + String requestId = linkRecordsV3Request.getRequestId(); + LocalDateTime now = Utils.getCurrentDateTime(); + + RequestLog existingLog = logsRepo.findByClientRequestId(requestId); + + Map requestDetails = + Optional.ofNullable(existingLog != null ? existingLog.getRequestDetails() : null) + .orElse(new HashMap<>()); + + requestDetails.put(FieldIdentifiers.LINK_RECORDS_REQUEST, linkRecordsV3Request); + + Query query = Query.query(Criteria.where(FieldIdentifiers.CLIENT_REQUEST_ID).is(requestId)); + + Update update = + new Update() + .set(FieldIdentifiers.LAST_UPDATED, now) + .set(FieldIdentifiers.STATUS, status) + .set(FieldIdentifiers.REQUEST_DETAILS, requestDetails); + + if (existingLog == null) { + update + .setOnInsert(FieldIdentifiers.ABHA_ADDRESS, linkRecordsV3Request.getAbhaAddress()) + .setOnInsert(FieldIdentifiers.MODULE, FieldIdentifiers.HIP_INITIATED_LINKING) + .setOnInsert(FieldIdentifiers.CREATED_ON, now) + .setOnInsert(FieldIdentifiers.CLIENT_REQUEST_ID, requestId) + .setOnInsert(FieldIdentifiers.GATEWAY_REQUEST_ID, requestId) + .setOnInsert(FieldIdentifiers.HIP_ID, linkRecordsV3Request.getRequesterId()); } - Query query = - new Query( - Criteria.where(FieldIdentifiers.CLIENT_REQUEST_ID) - .is(linkRecordsV3Request.getRequestId())); - Map map = existingLog.getRequestDetails(); - if (Objects.isNull(map)) { - map = new HashMap<>(); + + if (Objects.nonNull(errors)) { + update.set(FieldIdentifiers.ERROR, errors); } - map.replace(FieldIdentifiers.LINK_RECORDS_REQUEST, linkRecordsV3Request); - Update update = new Update(); - update.set(FieldIdentifiers.REQUEST_DETAILS, map); - update.set(FieldIdentifiers.STATUS, status); - update.set(FieldIdentifiers.LAST_UPDATED, Utils.getCurrentDateTime()); - mongoTemplate.updateFirst(query, update, RequestLog.class); + + mongoTemplate.upsert(query, update, RequestLog.class); } /** @@ -602,38 +616,57 @@ public void saveLinkTokenRequest( * *

Adding linkOnAddCareContextsResponse dump into db. * - * @param linkOnAddCareContextsV3Response Acknowledgement from ABDM gateway for HipLinking. + * @param response Acknowledgement from ABDM gateway for HipLinking. */ - public void setHipOnAddCareContextResponse( - LinkOnAddCareContextsV3Response linkOnAddCareContextsV3Response) + public void setHipOnAddCareContextResponse(LinkOnAddCareContextsV3Response response) throws IllegalDataStateException { - RequestLog RequestLog = - logsRepo.findByGatewayRequestId( - linkOnAddCareContextsV3Response.getResponse().getRequestId()); - if (RequestLog == null) { - throw new IllegalDataStateException( - "Request not found in database for: " - + linkOnAddCareContextsV3Response.getResponse().getRequestId()); - } - HashMap map = RequestLog.getRequestDetails(); - map.put(FieldIdentifiers.HIP_ON_ADD_CARE_CONTEXT_RESPONSE, linkOnAddCareContextsV3Response); - Query query = - new Query( - Criteria.where(FieldIdentifiers.GATEWAY_REQUEST_ID) - .is(linkOnAddCareContextsV3Response.getResponse().getRequestId())); - Update update = new Update(); - if ((Objects.nonNull(linkOnAddCareContextsV3Response.getError()))) { - update.set(FieldIdentifiers.ERROR, linkOnAddCareContextsV3Response.getError()); + String requestId = response.getResponse().getRequestId(); + log.info("Processing HIP OnAddCareContext response for requestId: {}", requestId); + + Query query = Query.query(Criteria.where(FieldIdentifiers.GATEWAY_REQUEST_ID).is(requestId)); + Update update = + new Update() + .set( + FieldIdentifiers.REQUEST_DETAILS + + "." + + FieldIdentifiers.HIP_ON_ADD_CARE_CONTEXT_RESPONSE, + response) + .set(FieldIdentifiers.LAST_UPDATED, Utils.getCurrentDateTime()); + + if (response.getError() != null) { + update.set(FieldIdentifiers.ERROR, response.getError()); } else { update.set(FieldIdentifiers.STATUS, RequestStatus.CARE_CONTEXT_LINKED); - LinkRecordsV3Request linkRecordsV3Request = - (LinkRecordsV3Request) - RequestLog.getRequestDetails().get(FieldIdentifiers.LINK_RECORDS_REQUEST); - patientService.addPatientCareContexts(linkRecordsV3Request); } - update.set(FieldIdentifiers.REQUEST_DETAILS, map); - mongoTemplate.updateFirst(query, update, RequestLog.class); + log.info("Querying gatewayRequestId = {}", requestId); + log.info("Query for requestId: {} {}", query, requestId); + log.info("Update for requestId: {} {}", update, requestId); + RequestLog updatedLog = + mongoTemplate.findAndModify( + query, update, FindAndModifyOptions.options().returnNew(true), RequestLog.class); + + if (updatedLog == null) { + log.warn( + "findAndModify returned null, fallback to fetch manually for requestId: {}", requestId); + updatedLog = logsRepo.findByGatewayRequestId(requestId); + + if (updatedLog == null) { + throw new IllegalDataStateException("Request not found in database for: " + requestId); + } + } + + if (response.getError() == null) { + Object raw = updatedLog.getRequestDetails().get(FieldIdentifiers.LINK_RECORDS_REQUEST); + if (raw instanceof LinkRecordsV3Request) { + patientService.addPatientCareContexts((LinkRecordsV3Request) raw); + } else { + log.warn( + "Expected LinkRecordsV3Request but got: {}", + raw == null ? "null" : raw.getClass().getName()); + } + } + log.info("Successfully updated requestId: {}", requestId); } public RequestLog getLogsByAbhaAddress(String abhaAddress, String hipId) { diff --git a/src/main/java/in/nha/abdm/wrapper/v3/hip/hrp/dataTransfer/HIPHealthInformationV3Service.java b/src/main/java/in/nha/abdm/wrapper/v3/hip/hrp/dataTransfer/HIPHealthInformationV3Service.java index ebf522e2..f2fec9d1 100644 --- a/src/main/java/in/nha/abdm/wrapper/v3/hip/hrp/dataTransfer/HIPHealthInformationV3Service.java +++ b/src/main/java/in/nha/abdm/wrapper/v3/hip/hrp/dataTransfer/HIPHealthInformationV3Service.java @@ -7,6 +7,7 @@ import in.nha.abdm.wrapper.v1.common.models.RespRequest; import in.nha.abdm.wrapper.v1.common.requests.*; import in.nha.abdm.wrapper.v1.common.responses.ErrorResponse; +import in.nha.abdm.wrapper.v1.common.responses.ErrorV3Response; import in.nha.abdm.wrapper.v1.common.responses.GenericResponse; import in.nha.abdm.wrapper.v1.hip.hrp.consent.requests.HIPNotifyRequest; import in.nha.abdm.wrapper.v1.hip.hrp.dataTransfer.callback.HIPHealthInformationRequest; @@ -27,6 +28,7 @@ import in.nha.abdm.wrapper.v3.common.RequestV3Manager; import in.nha.abdm.wrapper.v3.common.exceptions.BadRequestHandler; import in.nha.abdm.wrapper.v3.common.models.GenericV3Response; +import in.nha.abdm.wrapper.v3.config.ErrorHandler; import in.nha.abdm.wrapper.v3.database.mongo.services.ConsentPatientV3Service; import in.nha.abdm.wrapper.v3.database.mongo.services.PatientV3Service; import in.nha.abdm.wrapper.v3.database.mongo.services.RequestLogV3Service; @@ -146,20 +148,32 @@ public void healthInformation( // Acknowledge to gateway that health information request has been received. healthInformationAcknowledgementRequest( hipHealthInformationRequest, onHealthInformationRequest, headers); + try { + // Sending the data to HIU only if there is no errors + if (Objects.isNull(onHealthInformationRequest.getError())) { + // Prepare health information bundle request which needs to be sent to HIU. + HealthInformationBundleResponse healthInformationBundleResponse = + fetchHealthInformationBundle(hipHealthInformationRequest, headers); + // Push the health information to HIU. + List> pushHealthInformationResponse = + pushHealthInformation(healthInformationBundleResponse, consentId, headers); + // Notify Gateway that health information was pushed to HIU. + healthInformationPushNotify( + hipHealthInformationRequest, consentId, pushHealthInformationResponse, headers); + } else { + // Sending BAD_REQUEST since there are some errors earlier + healthInformationPushNotify( + hipHealthInformationRequest, + consentId, + Collections.singletonList(new ResponseEntity<>(HttpStatus.BAD_REQUEST)), + headers); + } + } catch (Exception e) { + List errors = ErrorHandler.getErrors(e.getMessage()); + log.debug(errors); + requestLogV3Service.updateConsentStatus(consentId, errors, RequestStatus.DATA_TRANSFER_ERROR); - // Sending the data to HIU only if there is no errors - if (Objects.isNull(onHealthInformationRequest.getError())) { - // Prepare health information bundle request which needs to be sent to HIU. - HealthInformationBundleResponse healthInformationBundleResponse = - fetchHealthInformationBundle(hipHealthInformationRequest, headers); - // Push the health information to HIU. - List> pushHealthInformationResponse = - pushHealthInformation(healthInformationBundleResponse, consentId, headers); - // Notify Gateway that health information was pushed to HIU. - healthInformationPushNotify( - hipHealthInformationRequest, consentId, pushHealthInformationResponse, headers); - } else { - // Sending BAD_REQUEST since there are some errors earlier + // Notify Gateway that health information was pushed to HIU with BAD_REQUEST status. healthInformationPushNotify( hipHealthInformationRequest, consentId, @@ -212,27 +226,30 @@ private void healthInformationAcknowledgementRequest( private HealthInformationBundleResponse fetchHealthInformationBundle( HIPHealthInformationRequest hipHealthInformationRequest, HttpHeaders headers) throws IllegalDataStateException { - ConsentCareContextMapping existingLog = + ConsentCareContextMapping existingConsentLog = consentCareContextsService.findMappingByConsentId( hipHealthInformationRequest.getHiRequest().getConsent().getId()); + RequestLog existingLog = + requestLogV3Service.findByConsentId( + hipHealthInformationRequest.getHiRequest().getConsent().getId(), + GatewayConstants.HIP, + headers.getFirst(GatewayConstants.X_HIP_ID)); + if (existingLog == null) { + throw new IllegalDataStateException("Request log not found for consent id"); + } HIPNotifyRequest hipNotifyRequest = - (HIPNotifyRequest) - requestLogV3Service - .findByConsentId( - hipHealthInformationRequest.getHiRequest().getConsent().getId(), - GatewayConstants.HIP, - headers.getFirst(GatewayConstants.X_HIP_ID)) - .getRequestDetails() - .get(FieldIdentifiers.HIP_NOTIFY_REQUEST); + (HIPNotifyRequest) existingLog.getRequestDetails().get(FieldIdentifiers.HIP_NOTIFY_REQUEST); String hipId = hipNotifyRequest.getNotification().getConsentDetail().getHip().getId(); - if (existingLog == null) { + if (existingConsentLog == null) { throw new IllegalDataStateException("consent id not found in db"); } HealthInformationBundleRequest healthInformationBundleRequest = HealthInformationBundleRequest.builder() .hipId(hipId) - .careContextsWithPatientReferences(existingLog.getCareContexts()) + .careContextsWithPatientReferences(existingConsentLog.getCareContexts()) .build(); + requestLogV3Service.updateConsentStatus( + existingConsentLog.getConsentId(), null, RequestStatus.FETCHING_BUNDLE); log.debug( "Health information bundle request HIP : " + healthInformationBundleRequest.toString()); return hipClient.healthInformationBundleRequest(healthInformationBundleRequest).getBody(); @@ -298,6 +315,9 @@ private List fetchHealthInformationPushRequest( EncryptionResponse encryptedData = encryptionService.encrypt(hipHealthInformationRequest, healthInformationBundleResponse); + requestLogV3Service.updateConsentStatus( + hipNotifyRequest.getNotification().getConsentId(), null, RequestStatus.ENCRYPTION_SUCCESS); + HealthInformationDhPublicKey receiverDhPublicKey = hipHealthInformationRequest.getHiRequest().getKeyMaterial().getDhPublicKey(); @@ -362,7 +382,8 @@ private void healthInformationPushNotify( HIPHealthInformationRequest hipHealthInformationRequest, String consentId, List> pushHealthInformationResponse, - HttpHeaders headers) { + HttpHeaders headers) + throws IllegalDataStateException { boolean allSuccess = pushHealthInformationResponse.stream() .allMatch(response -> response.getStatusCode().is2xxSuccessful()); @@ -370,13 +391,14 @@ private void healthInformationPushNotify( String healthInformationStatus = allSuccess ? "DELIVERED" : "ERRORED"; String sessionStatus = allSuccess ? "TRANSFERRED" : "FAILED"; + RequestLog existingLog = + requestLogV3Service.findByConsentId( + consentId, GatewayConstants.HIP, headers.getFirst(GatewayConstants.X_HIP_ID)); + if (existingLog == null) { + throw new IllegalDataStateException("Request log not found for consent id: " + consentId); + } HIPNotifyRequest hipNotifyRequest = - (HIPNotifyRequest) - requestLogV3Service - .findByConsentId( - consentId, GatewayConstants.HIP, headers.getFirst(GatewayConstants.X_HIP_ID)) - .getRequestDetails() - .get(FieldIdentifiers.HIP_NOTIFY_REQUEST); + (HIPNotifyRequest) existingLog.getRequestDetails().get(FieldIdentifiers.HIP_NOTIFY_REQUEST); List listOfCareContexts = hipNotifyRequest.getNotification().getConsentDetail().getCareContexts(); List healthInformationStatusResponseList = new ArrayList<>(); @@ -415,6 +437,12 @@ private void healthInformationPushNotify( .notification(healthInformationNotificationStatus) .build(); log.info(healthInformationPushNotification.toString()); + if (allSuccess) { + requestLogV3Service.updateConsentStatus(consentId, null, RequestStatus.DATA_TRANSFER_SUCCESS); + } else { + requestLogV3Service.updateConsentStatus(consentId, null, RequestStatus.DATA_TRANSFER_ERROR); + log.error("Data transfer failed for consent id: " + consentId); + } try { ResponseEntity response = requestV3Manager.fetchResponseFromGateway( diff --git a/src/main/java/in/nha/abdm/wrapper/v3/hip/hrp/link/hipInitiated/HIPLinkV3Service.java b/src/main/java/in/nha/abdm/wrapper/v3/hip/hrp/link/hipInitiated/HIPLinkV3Service.java index 1c7ecc85..66a7eb49 100644 --- a/src/main/java/in/nha/abdm/wrapper/v3/hip/hrp/link/hipInitiated/HIPLinkV3Service.java +++ b/src/main/java/in/nha/abdm/wrapper/v3/hip/hrp/link/hipInitiated/HIPLinkV3Service.java @@ -99,7 +99,7 @@ public FacadeV3Response addCareContexts(LinkRecordsV3Request linkRecordsV3Reques linkRecordsV3Request.getRequesterId(), linkRecordsV3Request.getCareContexts()); - if (sameCareContexts != null && !sameCareContexts.isEmpty()) { + if (Objects.nonNull(sameCareContexts) && !sameCareContexts.isEmpty()) { return hipContextNotify(linkRecordsV3Request, patient, sameCareContexts); } @@ -351,25 +351,24 @@ public void handleAddCareContexts( RequestStatus.LINK_TOKEN_REQUEST_ERROR); return; } + linkTokenService.saveLinkToken( onGenerateTokenResponse.getAbhaAddress(), onGenerateTokenResponse.getLinkToken(), Objects.requireNonNull(headers.getFirst(GatewayConstants.X_HIP_ID))); // Fetching the GenerateLinkToken request - RequestLog requestLog = + RequestLog RequestLog = requestLogV3Service.getLogsByAbhaAddress( onGenerateTokenResponse.getAbhaAddress(), Objects.requireNonNull(headers.get(GatewayConstants.X_HIP_ID)).toString()); - if (Objects.isNull(requestLog)) { - log.error("Request log not found for on-linkToken generation to initiate linking"); + if (Objects.isNull(RequestLog)) { return; } - log.info("RequestLog: " + requestLog); LinkRecordsV3Request linkRecordsV3Request = (LinkRecordsV3Request) - requestLog.getRequestDetails().get(FieldIdentifiers.LINK_RECORDS_REQUEST); - log.info("Initiating careContext Linking"); + RequestLog.getRequestDetails().get(FieldIdentifiers.LINK_RECORDS_REQUEST); + FacadeV3Response facadeV3Response = addCareContexts(linkRecordsV3Request); } catch (WebClientResponseException.BadRequest ex) { Object error = BadRequestHandler.getError(ex); @@ -412,7 +411,7 @@ public FacadeV3Response hipContextNotify( .hip(ConsentHIP.builder().id(linkRecordsV3Request.getRequesterId()).build()) .hiTypes(Collections.singletonList(careContext.getHiType())) .date(Utils.getCurrentTimeStamp()) - .careContext( + .careContexts( ConsentCareContexts.builder() .careContextReference(careContext.getReferenceNumber()) .patientReference(patient.getPatientReference()) From b37894ebb2dff5619a0e3b68d1cca5d3ad39a293 Mon Sep 17 00:00:00 2001 From: Venu-Ajitesh Date: Tue, 12 Aug 2025 01:08:35 +0530 Subject: [PATCH 05/12] Added Fhir-Mapper as a Git submodule --- .gitmodules | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .gitmodules diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..6e5627bc --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "FHIR-Mapper"] + path = FHIR-Mapper + url = https://github.com/VenuAjitesh/FHIR-Mapper.git From ce74b87fadeaf10da30d7b0de8897aa25c339763 Mon Sep 17 00:00:00 2001 From: Venu-Ajitesh Date: Tue, 12 Aug 2025 01:17:07 +0530 Subject: [PATCH 06/12] Remove submodule FHIR-Mapper --- fhir-mapper/.gitignore | 40 - fhir-mapper/Dockerfile | 17 - fhir-mapper/README.md | 581 --- fhir-mapper/build.gradle | 69 - fhir-mapper/docker-compose-fhir.yaml | 17 - fhir-mapper/fhir-mapper.yaml | 1188 ----- fhir-mapper/gradle/wrapper/gradle-wrapper.jar | 0 .../gradle/wrapper/gradle-wrapper.properties | 6 - fhir-mapper/gradlew | 0 fhir-mapper/gradlew.bat | 0 .../FHIR.postman_collection.json | 318 -- fhir-mapper/settings.gradle | 2 - .../nha/abdm/fhir/mapper/FHIRApplication.java | 12 - .../java/com/nha/abdm/fhir/mapper/Utils.java | 40 - .../BundleCompositionIdentifier.java | 72 - .../constants/BundleFieldIdentifier.java | 20 - .../common/constants/BundleIdentifier.java | 12 - .../constants/BundleResourceIdentifier.java | 36 - .../common/constants/BundleUrlIdentifier.java | 11 - .../rest/common/constants/ErrorCode.java | 10 - .../constants/ResourceProfileIdentifier.java | 50 - .../constants/SnomedCodeIdentifier.java | 32 - .../constants/WellnessFieldIdentifiers.java | 119 - .../rest/common/helpers/BundleResponse.java | 17 - .../mapper/rest/common/helpers/DateRange.java | 16 - .../rest/common/helpers/DocumentResource.java | 23 - .../rest/common/helpers/ErrorResponse.java | 16 - .../rest/common/helpers/FacadeError.java | 19 - .../common/helpers/FieldErrorsResponse.java | 16 - .../common/helpers/OrganisationResource.java | 18 - .../rest/common/helpers/PatientResource.java | 31 - .../common/helpers/PractitionerResource.java | 19 - .../rest/common/helpers/SnomedResponse.java | 28 - .../helpers/ValidationErrorResponse.java | 18 - .../rest/controller/BundleController.java | 181 - .../rest/controller/SnomedController.java | 45 - .../converter/DiagnosticReportConverter.java | 211 - .../converter/DischargeSummaryConverter.java | 453 -- .../converter/HealthDocumentConverter.java | 158 - .../rest/converter/ImmunizationConverter.java | 192 - .../converter/OPConsultationConverter.java | 501 --- .../rest/converter/PrescriptionConverter.java | 197 - .../converter/WellnessRecordConverter.java | 304 -- .../rest/database/h2/config/DbLoader.java | 144 - .../SnomedConditionProcedureRepo.java | 19 - .../h2/repositories/SnomedDiagnosticRepo.java | 18 - .../h2/repositories/SnomedEncounterRepo.java | 22 - .../h2/repositories/SnomedMedicineRepo.java | 18 - .../repositories/SnomedMedicineRouteRepo.java | 18 - .../repositories/SnomedObservationRepo.java | 18 - .../h2/repositories/SnomedSpecimenRepo.java | 18 - .../h2/repositories/SnomedVaccineRepo.java | 18 - .../database/h2/services/Displayable.java | 6 - .../database/h2/services/SnomedService.java | 270 -- .../h2/tables/SnomedConditionProcedure.java | 27 - .../database/h2/tables/SnomedDiagnostic.java | 26 - .../database/h2/tables/SnomedEncounter.java | 26 - .../database/h2/tables/SnomedMedicine.java | 26 - .../h2/tables/SnomedMedicineRoute.java | 26 - .../database/h2/tables/SnomedObservation.java | 26 - .../database/h2/tables/SnomedSpecimen.java | 26 - .../database/h2/tables/SnomedVaccine.java | 26 - .../MakeDiagnosticComposition.java | 91 - .../MakeDischargeComposition.java | 302 -- .../MakeHealthDocumentComposition.java | 83 - .../MakeImmunizationComposition.java | 94 - .../dto/compositions/MakeOpComposition.java | 336 -- .../MakePrescriptionComposition.java | 99 - .../compositions/MakeWellnessComposition.java | 185 - .../MakeAllergyToleranceResource.java | 64 - .../dto/resources/MakeBundleMetaResource.java | 27 - .../dto/resources/MakeCarePlanResource.java | 63 - .../dto/resources/MakeConditionResource.java | 55 - .../resources/MakeDiagnosticLabResource.java | 98 - .../dto/resources/MakeDocumentResource.java | 65 - .../dto/resources/MakeEncounterResource.java | 46 - .../resources/MakeFamilyMemberResource.java | 64 - .../resources/MakeImmunizationResource.java | 90 - .../MakeMedicationRequestResource.java | 137 - .../resources/MakeObservationResource.java | 74 - .../resources/MakeOrganisationResource.java | 51 - .../dto/resources/MakePatientResource.java | 49 - .../resources/MakePractitionerResource.java | 44 - .../dto/resources/MakeProcedureResource.java | 68 - .../resources/MakeServiceRequestResource.java | 82 - .../MakeWellnessObservationResource.java | 80 - .../exceptions/GlobalExceptionHandler.java | 124 - .../rest/exceptions/NotBlankFields.java | 20 - .../exceptions/NotBlankFieldsValidator.java | 49 - .../mapper/rest/exceptions/StreamUtils.java | 29 - .../requests/DiagnosticReportRequest.java | 47 - .../requests/DischargeSummaryRequest.java | 58 - .../rest/requests/HealthDocumentRecord.java | 46 - .../rest/requests/ImmunizationRequest.java | 50 - .../rest/requests/OPConsultationRequest.java | 60 - .../rest/requests/PrescriptionRequest.java | 51 - .../rest/requests/WellnessRecordRequest.java | 57 - .../requests/helpers/CarePlanResource.java | 24 - .../helpers/ChiefComplaintResource.java | 23 - .../helpers/DiagnosticPresentedForm.java | 20 - .../requests/helpers/DiagnosticResource.java | 38 - .../helpers/FamilyObservationResource.java | 18 - .../requests/helpers/FollowupResource.java | 19 - .../helpers/ImmunizationResource.java | 28 - .../requests/helpers/ObservationResource.java | 22 - .../helpers/PrescriptionResource.java | 32 - .../requests/helpers/ProcedureResource.java | 29 - .../helpers/ServiceRequestResource.java | 22 - .../helpers/ValueQuantityResource.java | 16 - .../helpers/WellnessObservationResource.java | 22 - .../src/main/resources/application.properties | 24 - fhir-mapper/src/main/resources/banner.txt | 9 - .../snomed/SnomedConditionProcedure.json | 2638 ----------- .../resources/snomed/SnomedDiagnostic.json | 66 - .../resources/snomed/SnomedEncounter.json | 222 - .../main/resources/snomed/SnomedMedicine.json | 418 -- .../resources/snomed/SnomedMedicineRoute.json | 385 -- .../resources/snomed/SnomedObservation.json | 302 -- .../main/resources/snomed/SnomedSpecimen.json | 3998 ----------------- .../main/resources/snomed/SnomedVaccine.json | 754 ---- 120 files changed, 17960 deletions(-) delete mode 100644 fhir-mapper/.gitignore delete mode 100644 fhir-mapper/Dockerfile delete mode 100644 fhir-mapper/README.md delete mode 100644 fhir-mapper/build.gradle delete mode 100644 fhir-mapper/docker-compose-fhir.yaml delete mode 100644 fhir-mapper/fhir-mapper.yaml delete mode 100644 fhir-mapper/gradle/wrapper/gradle-wrapper.jar delete mode 100644 fhir-mapper/gradle/wrapper/gradle-wrapper.properties delete mode 100644 fhir-mapper/gradlew delete mode 100644 fhir-mapper/gradlew.bat delete mode 100644 fhir-mapper/postmanCollection/FHIR.postman_collection.json delete mode 100644 fhir-mapper/settings.gradle delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/FHIRApplication.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/Utils.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/BundleCompositionIdentifier.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/BundleFieldIdentifier.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/BundleIdentifier.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/BundleResourceIdentifier.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/BundleUrlIdentifier.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/ErrorCode.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/ResourceProfileIdentifier.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/SnomedCodeIdentifier.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/WellnessFieldIdentifiers.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/BundleResponse.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/DateRange.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/DocumentResource.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/ErrorResponse.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/FacadeError.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/FieldErrorsResponse.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/OrganisationResource.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/PatientResource.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/PractitionerResource.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/SnomedResponse.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/ValidationErrorResponse.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/controller/BundleController.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/controller/SnomedController.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/DiagnosticReportConverter.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/DischargeSummaryConverter.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/HealthDocumentConverter.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/ImmunizationConverter.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/OPConsultationConverter.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/PrescriptionConverter.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/WellnessRecordConverter.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/config/DbLoader.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedConditionProcedureRepo.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedDiagnosticRepo.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedEncounterRepo.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedMedicineRepo.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedMedicineRouteRepo.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedObservationRepo.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedSpecimenRepo.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedVaccineRepo.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/services/Displayable.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/services/SnomedService.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedConditionProcedure.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedDiagnostic.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedEncounter.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedMedicine.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedMedicineRoute.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedObservation.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedSpecimen.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedVaccine.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeDiagnosticComposition.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeDischargeComposition.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeHealthDocumentComposition.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeImmunizationComposition.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeOpComposition.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakePrescriptionComposition.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeWellnessComposition.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeAllergyToleranceResource.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeBundleMetaResource.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeCarePlanResource.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeConditionResource.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeDiagnosticLabResource.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeDocumentResource.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeEncounterResource.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeFamilyMemberResource.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeImmunizationResource.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeMedicationRequestResource.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeObservationResource.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeOrganisationResource.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakePatientResource.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakePractitionerResource.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeProcedureResource.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeServiceRequestResource.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeWellnessObservationResource.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/exceptions/GlobalExceptionHandler.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/exceptions/NotBlankFields.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/exceptions/NotBlankFieldsValidator.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/exceptions/StreamUtils.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/DiagnosticReportRequest.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/DischargeSummaryRequest.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/HealthDocumentRecord.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/ImmunizationRequest.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/OPConsultationRequest.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/PrescriptionRequest.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/WellnessRecordRequest.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/CarePlanResource.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ChiefComplaintResource.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/DiagnosticPresentedForm.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/DiagnosticResource.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/FamilyObservationResource.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/FollowupResource.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ImmunizationResource.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ObservationResource.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/PrescriptionResource.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ProcedureResource.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ServiceRequestResource.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ValueQuantityResource.java delete mode 100644 fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/WellnessObservationResource.java delete mode 100644 fhir-mapper/src/main/resources/application.properties delete mode 100644 fhir-mapper/src/main/resources/banner.txt delete mode 100644 fhir-mapper/src/main/resources/snomed/SnomedConditionProcedure.json delete mode 100644 fhir-mapper/src/main/resources/snomed/SnomedDiagnostic.json delete mode 100644 fhir-mapper/src/main/resources/snomed/SnomedEncounter.json delete mode 100644 fhir-mapper/src/main/resources/snomed/SnomedMedicine.json delete mode 100644 fhir-mapper/src/main/resources/snomed/SnomedMedicineRoute.json delete mode 100644 fhir-mapper/src/main/resources/snomed/SnomedObservation.json delete mode 100644 fhir-mapper/src/main/resources/snomed/SnomedSpecimen.json delete mode 100644 fhir-mapper/src/main/resources/snomed/SnomedVaccine.json diff --git a/fhir-mapper/.gitignore b/fhir-mapper/.gitignore deleted file mode 100644 index d784edfa..00000000 --- a/fhir-mapper/.gitignore +++ /dev/null @@ -1,40 +0,0 @@ -build -.gradle - -### IntelliJ IDEA ### -.idea/ -.idea/modules.xml -.idea/jarRepositories.xml -.idea/compiler.xml -.idea/libraries/ -*.iws -*.iml -*.ipr -out/ -!**/src/main/**/out/ -!**/src/test/**/out/ - -### Eclipse ### -.apt_generated -.classpath -.factorypath -.project -.settings -.springBeans -.sts4-cache -bin/ -!**/src/main/**/bin/ -!**/src/test/**/bin/ - -### NetBeans ### -/nbproject/private/ -/nbbuild/ -/dist/ -/nbdist/ -/.nb-gradle/ - -### VS Code ### -.vscode/ - -### Mac OS ### -.DS_Store \ No newline at end of file diff --git a/fhir-mapper/Dockerfile b/fhir-mapper/Dockerfile deleted file mode 100644 index 21d72851..00000000 --- a/fhir-mapper/Dockerfile +++ /dev/null @@ -1,17 +0,0 @@ -FROM gradle:8.5-jdk17 AS builder -WORKDIR /app - -COPY build.gradle settings.gradle ./ -RUN gradle dependencies --no-daemon - -COPY . . -RUN gradle build --no-daemon -x test - -FROM eclipse-temurin:17-jdk-focal -WORKDIR /app - -COPY --from=builder /app/build/libs/*-SNAPSHOT.jar fhir.jar - -EXPOSE 8085 - -ENTRYPOINT ["java", "-jar", "fhir.jar"] diff --git a/fhir-mapper/README.md b/fhir-mapper/README.md deleted file mode 100644 index d03090f8..00000000 --- a/fhir-mapper/README.md +++ /dev/null @@ -1,581 +0,0 @@ -# ABDM FHIR Mapper - FHIR (HL7® FHIR® Standard) R4 -- The purpose of this implementation guide is to provide essential and minimum health record artefacts that can be captured and created as per ABDM Health Data Interchange Specifications 1.0. -- This module is built using **hapi fhir library** for generating the fhir resources. -- For better understanding of FHIR, check [here](https://nrces.in/ndhm/fhir/r4/index.html) - -### 1. System Requirements and Installations: -There are two ways to get fhir-mapper application running on your system: -#### 1. Using docker (Preferred): This is an easy way to get wrapper up and running. -Install docker and docker-compose: You can install docker desktop from [here](https://www.docker.com/products/docker-desktop/) to get both. - -System Requirements: -- For Mac, check [here](https://docs.docker.com/desktop/install/mac-install/) -- For Windows, check [here](https://docs.docker.com/desktop/install/windows-install/) -- For Linux, check [here](https://docs.docker.com/desktop/install/linux-install/) - -Using docker-compose-fhir.yaml to bring up the server. - -#### 2. If you are facing issues with installing or running docker, then you can install individual components: -- Install jdk 17. Instructions can be found [here](https://www3.cs.stonybrook.edu/~amione/CSE114_Course/materials/resources/InstallingJava17.pdf) -- Install gradle from [here](https://gradle.org/install/) - -System Requirements: -- For Java17, you can check [here](https://www.oracle.com/java/technologies/javase/products-doc-jdk17certconfig.html) for compatible system configurations. -- Gradle version >= 8.5 should be fine. - -Recommended RAM: Systems with more than 8 GB RAM -### Bringing up the application -- If you have installed docker and docker compose then you can bring the application using: `docker compose -f docker-compose-fhir.yaml up --build` -* If you have chosen to install Java and gradle components, then here is how you can bring the service up: - - Go to root of this repository and start fhir-mapper by running `gradle bootrun` -- Using any of the above approaches the server will be running on port `8085` - -### ABDM PROFILES (HI-Types) -- The HI type is primarily defined based on the data being collected. However the type of interaction should also be considered. -- If the data which is collected is not defined in the structured field for any HI-type you can create a pdf and attach to the particular bundle in the documents. - -| Name | Definition | -|-------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------| -| DiagnosticReportRecord | The Clinical Artifact represents diagnostic reports including Radiology and Laboratory reports that can be shared across the health ecosystem. | -| DischargeSummaryRecord | Clinical document used to represent the discharge summary record for ABDM HDE data set. | -| HealthDocumentRecord | The Clinical Artifact represents the unstructured historical health records as a single or multiple Health Record Documents generally uploaded by the patients through the Health Locker and can be shared across the health ecosystem. | -| ImmunizationRecord | The Clinical Artifact represents the Immunization records with any additional documents such as vaccine certificate, the next immunization recommendations, etc. This can be further shared across the health ecosystem. | -| OPConsultRecord | The Clinical Artifact represents the outpatient visit consultation note which may include clinical information on any OP examinations, procedures along with medication administered, and advice that can be shared across the health ecosystem. | -| PrescriptionRecord | The Clinical Artifact represents the medication advice to the patient in compliance with the Pharmacy Council of India (PCI) guidelines, which can be shared across the health ecosystem. | -| WellnessRecord | The Clinical Artifact represents regular wellness information of patients typically through the Patient Health Record (PHR) application covering clinical information such as vitals, physical examination, general wellness, women wellness, etc., that can be shared across the health ecosystem. | - -### APIs for generating the FHIR bundle -- For Swagger-ui, check [here](https://wrapper-sbx.abdm.gov.in/swagger/fhir) -#### DiagnosticReportRecord -- for the DiagnosticReportRecord bundle you need to - * `POST` Request `/v1/bundle/diagnostic-report` - ``` - { - "bundleType":"DiagnosticReportRecord", //mandatory - "careContextReference":"visist 21-03-2024", //mandatory - "authoredOn":"2006-04-22", //mandatory - "patient":{ //mandatory - "name":"Venu Ajitesh", //mandatory - "patientReference":"ajitesh6x", //mandatory - "gender":"male", - "birthDate":"2001-04-27" - }, - "practitioners":[{ //mandatory - "name":"Dr.Venu Ajitesh", //mandatory - "practitionerId":"Predator" - }], - "organisation":{ - "facilityName":"Predator_HIP", //mandatory - "facilityId":"Predator_HIP" - }, - "encounter":"Ambula", - "diagnostics":[{ - "serviceName":"BloodTest", //mandatory - "serviceCategory":"Hematography", //mandatory - "result":[{ //you can pass either result or valueQuantity not both - "observation":"Height", //mandatory - "result":"Normal", - "valueQuantity": { - "unit": "CM", - "value": 170 - } - }], - "conclusion":"Normal", //mandatory - "presentedForm":{ - "contentType":"application/pdf", - "data":"Base64 data of the pdf" - } - }], - "documents":[{ - "type":"diagnosticReport", //mandatory - "contentType":"application/pdf", //mandatory - "data":"Base64 data of the pdf" //mandatory - }] - } - ``` -#### DischargeSummaryRecord - - for the DischargeSummaryRecord bundle you need to - * `POST` Request `/v1/bundle/discharge-summary` - ``` - { - "bundleType":"DischargeSummaryRecord", //mandatory - "careContextReference":"visist 21-03-2024", //mandatory - "patient":{ //mandatory - "name":"Venu Ajitesh", //mandatory - "patientReference":"ajitesh6x", //mandatory - "gender":"male", - "birthDate":"2001-04-27" - }, - "practitioners":[{ //mandatory - "name":"Dr.Venu Ajitesh", //mandatory - "practitionerId":"Predator" - }], - "organisation":{ //mandatory - "facilityName":"Predator_HIP", //mandatory - "facilityId":"Predator_HIP" - }, - "chiefComplaints":[ - { - "complaint":"Sugar", //mandatory - "recordedDate":"2024-05-20", //mandatory - "dateRange":{ - "from":"2018-04-27", - "to":"2018-05-26" - } - } - ], - "physicalExaminations":[ - { - "observation":"Height", //mandatory - "result":"Normal", //you can pass either result or valueQuantity not both - "valueQuantity": { - "unit": "CM", - "value": 170 - } - } - ], - "allergies":[ - "Walnuts" - ], - "medicalHistories":[ - { - "complaint":"Sugar", //mandatory - "recordedDate":"2024-05-20", //mandatory - "dateRange":{ - "from":"2018-04-27", - "to":"2018-05-26" - } - } - ], - "familyHistories":[ - { - "relationship":"Friend", //mandatory - "observation":"Toxic" //mandatory - } - ], - "authoredOn":"2024-02-03", //mandatory - "medications":[ - { - "medicine":"Aspirin 75 mg oral tablet", //mandatory - "dosage":"1-0-1", //mandatory - "timing":"2-5-d", - "route":"Oral", - "method":"swallow", - "additionalInstructions":"Take them after food", - "reason": "fever" - } - ,{ - "medicine":"Disprin", //mandatory - "dosage":"0-0-1", //mandatory - "timing":"1-2-d", - "route":"Syrup", - "method":"drink", - "additionalInstructions":"Take them before food", - "reason": "Cough" - } - ], - "diagnostics":[{ - "serviceName":"BloodTest", //mandatory - "serviceCategory":"Hematography", //mandatory - "result":[{ - "observation":"Height", //mandatory - "result":"Normal", //you can pass either result or valueQuantity not both - "valueQuantity": { - "unit": "CM", - "value": 170 - } - }], - "conclusion":"Normal", //mandatory - "presentedForm":{ - "contentType":"application/pdf", - "data":"Base64 data of the pdf" - } - }], - - "procedures":[ - { - "date":"2001-04-20", //mandatory - "status":"INPROGRESS", //mandatory - "procedureReason":"Severe", //mandatory - "outcome":"Healthy", - "procedureName":"Operation" //mandatory - } - ], - - "documents":[{ - "type":"Discharge record", //mandatory - "contentType":"application/pdf", //mandatory - "data":"Base64 data of the pdf" //mandatory - }] - } - ``` -#### HealthDocumentRecord -- for the HealthDocumentRecord bundle you need to - * `POST` Request `/v1/bundle/health-document` - ``` - { - "bundleType":"HealthDocumentRecord", //mandatory - "careContextReference":"visist 21-03-2024", //mandatory - "patient":{ //mandatory - "name":"Venu Ajitesh", //mandatory - "patientReference":"ajitesh6x", //mandatory - "gender":"male", - "birthDate":"2001-04-27" - }, - "authoredOn":"2001-04-27", //mandatory - "practitioners":[{ //mandatory - "name":"Dr.Venu Ajitesh", //mandatory - "practitionerId":"Predator" - }], - "organisation":{ - "facilityName":"Predator_HIP", //mandatory - "facilityId":"Predator_HIP" - }, - "encounter":"", - "documents":[{ - "type":"health-document", //mandatory - "contentType":"application/pdf", //mandatory - "data":"Base64 data of the pdf" //mandatory - }] - } - ``` -#### ImmunizationRecord -- for the ImmunizationRecord bundle you need to - * `POST` Request `/v1/bundle/immunization` - ``` - { - "bundleType":"ImmunizationRecord", //mandatory - "careContextReference":"visit-{{$isoTimestamp}}", //mandatory - "authoredOn":"2022-02-14", //mandatory - "patient":{ //mandatory - "name":"Venu Ajitesh", //mandatory - "patientReference":"ajitesh6x", //mandatory - "gender":"male", - "birthDate":"2001-04-27" - }, - "practitioners":[{ //mandatory - "name":"Dr.Venu Ajitesh", //mandatory - "practitionerId":"Predator" - }], - "organisation":{ - "facilityName":"Predator_HIP", //mandatory - "facilityId":"Predator_HIP" - }, - "immunizations":[{ //mandatory - "date":"2024-06-15", //mandatory - "vaccineName":"Covaxin", //mandatory - "lotNumber":"IN00004", - "manufacturer":"NHA", - "doseNumber":"3" - }], - "documents":[{ - "type":"immunization", //mandatory - "contentType":"application/pdf", //mandatory - "data":"Base64 data of the pdf" //mandatory - }] - } - ``` -#### OPConsultRecord -- for the OPConsultRecord bundle you need to - * `POST` Request `/v1/bundle/op-consultation` - ``` - { - "bundleType":"OPConsultRecord", //mandatory - "careContextReference":"visist 21-03-2025", //mandatory - "visitDate":"2000-06-23", //mandatory - "patient":{ //mandatory - "name":"Venu Ajitesh", //mandatory - "patientReference":"ajitesh6x", //mandatory - "gender":"male", - "birthDate":"2001-04-27" - }, - "practitioners":[{ //mandatory - "name":"Dr.Venu Ajitesh", //mandatory - "practitionerId":"Predator" - }], - "organisation":{ - "facilityName":"Predator_HIP", //mandatory - "facilityId":"Predator_HIP" - }, - "chiefComplaints":[ - { - "complaint":"Sugar", //mandatory - "recordedDate":"2024-05-20", //mandatory - "dateRange":{ - "from":"2018-04-27", - "to":"2018-05-26" - } - } - ], - "physicalExaminations":[ - { - "observation":"Height", //mandatory - "result":"Normal", //you can pass either result or valueQuantity not both - "valueQuantity": { - "unit": "CM", - "value": 170 - } - } - ], - "allergies":[ - "Walnuts" - ], - "medicalHistories":[ - { - "complaint":"Sugar", //mandatory - "recordedDate":"2024-05-20", //mandatory - "dateRange":{ - "from":"2018-04-27", - "to":"2018-05-26" - } - } - ], - "familyHistories":[ - { - "relationship":"Friend", //mandatory - "observation":"Toxic" //mandatory - } - ], - "serviceRequests":[ - { - "status":"ACTIVE", //mandatory - "details":"X-RAY", //mandatory - "specimen":"Jhonsons" - } - ], - "medications":[ - { - "medicine":"Aspirin 75 mg oral tablet", //mandatory - "dosage":"1-0-1", //mandatory - "timing":"2-5-d", - "route":"Oral", - "method":"swallow", - "additionalInstructions":"Take them after food", - "reason": "fever" - } - ,{ - "medicine":"Disprin", //mandatory - "dosage":"0-0-1", //mandatory - "timing":"1-2-d", - "route":"Syrup", - "method":"drink", - "additionalInstructions":"Take them before food", - "reason": "Cough" - } - ], - "followups":[ - { - "serviceType":"OPConsultation", //mandatory - "appointmentTime":"2024-05-20", //mandatory - "reason":"General" //mandatory - } - ], - "procedures":[ - { - "date":"2001-04-20", //mandatory - "status":"INPROGRESS", //mandatory - "procedureReason":"Severe", //mandatory - "outcome":"Healthy", - "procedureName":"Operation" //mandatory - } - ], - "referrals":[ - { - "status":"ACTIVE", //mandatory - "details":"Y-RAY", //mandatory - "specimen":"Rock" //mandatory - } - ], - "otherObservations":[ - { - "observation":"weight", //mandatory - "result":"Over weight", //you can pass either result or valueQuantity not both - "valueQuantity": { - "unit": "KG", - "value": 90 - } - } - ], - "documents":[{ - "type":"OP record", //mandatory - "contentType":"application/pdf", //mandatory - "data":"Base64 data of the pdf" //mandatory - }] - } - ``` -#### PrescriptionRecord -- for the PrescriptionRecord bundle you need to - * `POST` Request `/v1/bundle/prescription` - ``` - { - "bundleType":"PrescriptionRecord", //mandatory - "careContextReference":"visit-{{$isoTimestamp}}", //mandatory - "authoredOn":"2001-05-22", //mandatory - "encounter":"", - "patient":{ //mandatory - "name":"Venu Ajitesh", //mandatory - "patientReference":"ajitesh6x", //mandatory - "gender":"male", - "birthDate":"2001-04-27" - }, - "practitioners":[{ //mandatory - "name":"Dr.Venu Ajitesh", //mandatory - "practitionerId":"Predator" - }], - "organisation":{ - "facilityName":"Predator_HIP", //mandatory - "facilityId":"Predator_HIP" - }, - "prescriptions":[ - { - "medicine":"Aspirin 75 mg oral tablet", //mandatory - "dosage":"1-0-1", //mandatory - "timing":"2-5-d", - "route":"Oral", - "method":"swallow", - "additionalInstructions":"Take them after food", - "reason": "fever" - } - ,{ - "medicine":"Disprin", //mandatory - "dosage":"0-0-1", //mandatory - "timing":"1-2-d", - "route":"Syrup", - "method":"drink", - "additionalInstructions":"Take them before food", - "reason": "Cough" - } - ], - "documents":[{ - "type":"Prescription", //mandatory - "contentType":"application/pdf", //mandatory - "data":"Base64 data of the pdf" //mandatory - }] - } - ``` -#### WellnessRecord -- for the WellnessRecord bundle you need to - * `POST` Request `/v1/bundle/wellness-record` - ``` - { - "bundleType":"WellnessRecord", //mandatory - "careContextReference":"visist 21-03-2025", //mandatory - "authoredOn":"2024-02-11", //mandatory - "patient":{ //mandatory - "name":"Venu Ajitesh", //mandatory - "patientReference":"ajitesh6x", //mandatory - "gender":"male", - "birthDate":"2001-04-27" - }, - "practitioners":[{ //mandatory - "name":"Dr.Venu Ajitesh", //mandatory - "practitionerId":"Predator" - }], - "organisation":{ - "facilityName":"Predator_HIP", //mandatory - "facilityId":"Predator_HIP" - }, - "vitalSigns":[ - { - "observation":"Height", //mandatory - "result":"Normal", //you can pass either result or valueQuantity not both - "valueQuantity": { - "unit": "CM", - "value": 170 - } - } - ], - "bodyMeasurements":[ - { - "observation":"Height", //mandatory - "result":"Normal", //you can pass either result or valueQuantity not both - "valueQuantity": { - "unit": "CM", - "value": 170 - } - } - ], - "physicalActivities":[ - { - "observation":"Height", //mandatory - "result":"Normal", //you can pass either result or valueQuantity not both - "valueQuantity": { - "unit": "CM", - "value": 170 - } - } - ], - "generalAssessments":[ - { - "observation":"Height", //mandatory - "result":"Normal", //you can pass either result or valueQuantity not both - "valueQuantity": { - "unit": "CM", - "value": 170 - } - } - ],"womanHealths":[ - { - "observation":"Height", //mandatory - "result":"Normal", //you can pass either result or valueQuantity not both - "valueQuantity": { - "unit": "CM", - "value": 170 - } - } - ], - "lifeStyles":[ - { - "observation":"Height", //mandatory - "result":"Normal", //you can pass either result or valueQuantity not both - "valueQuantity": { - "unit": "CM", - "value": 170 - } - } - ], - "otherObservations":[ - { - "observation":"Height", //mandatory - "result":"Normal", //you can pass either result or valueQuantity not both - "valueQuantity": { - "unit": "CM", - "value": 170 - } - } - ], - "documents":[{ - "type":"Wellness record", //mandatory - "contentType":"application/pdf", //mandatory - "data":"Base64 data of the pdf" //mandatory - }] - } - ``` -#### Error response in 400 BadRequest -- There are two kinds of error - * Validation errors : The errors are thrown when mandatory fields are missing - ``` - { - "validationErrors": { - "code": 1000, - "error": [ - { - "field": "bundleType", - "message": "must match \"WellnessRecord\"" - } - ] - } - } - ``` - * Errors while creating the FHIR bundle - ``` - { - "error":{ - "code":1000, - "message":"Unable to parse date" - } - } - ``` -### Things To Consider -- If the FHIR bundle is generated the HttpStatus will be `201 created` -- The authoredOn will accept date in the format of string in format : `yyyy-MM-dd` or `yyyy-MM-dd'T'HH:mm:ss.SSSX` - UTC iso time format \ No newline at end of file diff --git a/fhir-mapper/build.gradle b/fhir-mapper/build.gradle deleted file mode 100644 index f276331e..00000000 --- a/fhir-mapper/build.gradle +++ /dev/null @@ -1,69 +0,0 @@ -plugins { - id 'java' - id 'org.springframework.boot' version '3.2.0' - id 'io.spring.dependency-management' version '1.0.11.RELEASE' - id 'org.openapi.generator' version '6.6.0' - id 'com.diffplug.spotless' version '6.25.0' -} - -group = 'com.nha.abdm.fhir.wrapper' -version = '1.0-SNAPSHOT' -subprojects { - spotless { - java { - googleJavaFormat('1.15.0') - indentWithTabs(2) - indentWithSpaces(4) - } - } -} -afterEvaluate { - def spotless = tasks.findByName('spotlessApply') - if (spotless) { - tasks.withType(JavaCompile) { - finalizedBy(spotless) - - } - - tasks.withType(GroovyCompile) { - finalizedBy(spotless) - } - } -} - -repositories { - mavenCentral() -} - -dependencies { - implementation 'org.springframework.boot:spring-boot-starter' - implementation 'org.springframework.boot:spring-boot-starter-web' - testImplementation 'org.springframework.boot:spring-boot-starter-test' - implementation 'org.springframework.boot:spring-boot-starter-validation' - compileOnly group: 'org.projectlombok', name: 'lombok', version: '1.18.30' - annotationProcessor 'org.projectlombok:lombok:1.18.30' - implementation 'ca.uhn.hapi.fhir:hapi-fhir-base:5.6.1' - implementation 'ca.uhn.hapi.fhir:hapi-fhir-structures-r4:5.5.0' - testImplementation 'org.mockito:mockito-core:5.13.0' - testImplementation platform('org.junit:junit-bom:5.9.1') - testImplementation 'org.junit.jupiter:junit-jupiter' - implementation 'org.springframework.boot:spring-boot-starter-data-jpa' - implementation 'org.postgresql:postgresql:42.7.2' - implementation 'com.h2database:h2' - implementation 'org.apache.commons:commons-text:1.10.0' -} -spotless { - java { - // Use the default importOrder configuration - importOrder() - - removeUnusedImports() - - // Choose one of these formatters. - googleJavaFormat() // has its own section below - - formatAnnotations() // fixes formatting of type annotations, see below - - licenseHeader '/* (C) $YEAR */' // or licenseHeaderFile - } -} diff --git a/fhir-mapper/docker-compose-fhir.yaml b/fhir-mapper/docker-compose-fhir.yaml deleted file mode 100644 index 150f5982..00000000 --- a/fhir-mapper/docker-compose-fhir.yaml +++ /dev/null @@ -1,17 +0,0 @@ -version: '3.8' -services: - fhir-mapper: - build: - context: . - dockerfile: Dockerfile - image: fhir-mapper - ports: - - '8085:8085' - networks: - - docker_network - extra_hosts: - - "host.docker.internal:host-gateway" - -networks: - docker_network: - driver: bridge \ No newline at end of file diff --git a/fhir-mapper/fhir-mapper.yaml b/fhir-mapper/fhir-mapper.yaml deleted file mode 100644 index bda9b9a0..00000000 --- a/fhir-mapper/fhir-mapper.yaml +++ /dev/null @@ -1,1188 +0,0 @@ -openapi: 3.0.3 -info: - title: FHIR Mapper API's - description: Conversion of simple json to ABDM compliant FHIR Format bundles - version: 1.0.0 -servers: - - url: http://localhost:8085/v1/bundle - -paths: - /op-consultation: - post: - tags: - - HI Types - summary: Create an OP Consultation Record - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/OPConsultRecord' - responses: - '201': - description: Successfully created - '400': - description: Bad Request - content: - application/json: - schema: - oneOf: - - $ref: '#/components/schemas/ValidationErrorResponse' - - $ref: '#/components/schemas/GenericErrorResponse' - '500': - description: Internal server error - content: - application/json: - schema: - $ref: '#/components/schemas/GenericErrorResponse' - /prescription: - post: - tags: - - HI Types - summary: Create a Prescription Record - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/PrescriptionRecord' - responses: - '201': - description: Successfully created - '400': - description: Bad Request - content: - application/json: - schema: - oneOf: - - $ref: '#/components/schemas/ValidationErrorResponse' - - $ref: '#/components/schemas/GenericErrorResponse' - '500': - description: Internal server error - content: - application/json: - schema: - $ref: '#/components/schemas/GenericErrorResponse' - /health-document: - post: - tags: - - HI Types - summary: Create a Health Document Record - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/HealthDocumentRecord' - responses: - '201': - description: Successfully created - '400': - description: Bad Request - content: - application/json: - schema: - oneOf: - - $ref: '#/components/schemas/ValidationErrorResponse' - - $ref: '#/components/schemas/GenericErrorResponse' - '500': - description: Internal server error - content: - application/json: - schema: - $ref: '#/components/schemas/GenericErrorResponse' - /diagnostic-report: - post: - tags: - - HI Types - summary: Create a Diagnostic Report - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/DiagnosticReport' - responses: - '201': - description: Successfully created - '400': - description: Bad Request - content: - application/json: - schema: - oneOf: - - $ref: '#/components/schemas/ValidationErrorResponse' - - $ref: '#/components/schemas/GenericErrorResponse' - '500': - description: Internal server error - content: - application/json: - schema: - $ref: '#/components/schemas/GenericErrorResponse' - /immunization: - post: - tags: - - HI Types - summary: Create an Immunization Record - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/ImmunizationRecord' - responses: - '201': - description: Successfully created - '400': - description: Bad Request - content: - application/json: - schema: - oneOf: - - $ref: '#/components/schemas/ValidationErrorResponse' - - $ref: '#/components/schemas/GenericErrorResponse' - '500': - description: Internal server error - content: - application/json: - schema: - $ref: '#/components/schemas/GenericErrorResponse' - /discharge-summary: - post: - tags: - - HI Types - summary: Create a Discharge Summary - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/DischargeSummary' - responses: - '201': - description: Successfully created - '400': - description: Bad Request - content: - application/json: - schema: - oneOf: - - $ref: '#/components/schemas/ValidationErrorResponse' - - $ref: '#/components/schemas/GenericErrorResponse' - '500': - description: Internal server error - content: - application/json: - schema: - $ref: '#/components/schemas/GenericErrorResponse' - /wellness-record: - post: - tags: - - HI Types - summary: Create a Wellness Record - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/WellnessRecord' - responses: - '201': - description: Successfully created - '400': - description: Bad Request - content: - application/json: - schema: - oneOf: - - $ref: '#/components/schemas/ValidationErrorResponse' - - $ref: '#/components/schemas/GenericErrorResponse' - '500': - description: Internal server error - content: - application/json: - schema: - $ref: '#/components/schemas/GenericErrorResponse' - -components: - schemas: - OPConsultRecord: - type: object - properties: - bundleType: - type: string - enum: - - OPConsultRecord - careContextReference: - type: string - example: visit 21-03-2025 - visitDate: - type: string - format: date - example: 2000-06-23 - patient: - $ref: '#/components/schemas/Patient' - practitioners: - type: array - items: - $ref: '#/components/schemas/Practitioner' - organisation: - $ref: '#/components/schemas/Organisation' - chiefComplaints: - type: array - items: - $ref: '#/components/schemas/ChiefComplaint' - physicalExaminations: - type: array - items: - $ref: '#/components/schemas/PhysicalExamination' - allergies: - type: array - items: - type: string - medicalHistories: - type: array - items: - $ref: '#/components/schemas/ChiefComplaint' - familyHistories: - type: array - items: - $ref: '#/components/schemas/FamilyHistory' - serviceRequests: - type: array - items: - $ref: '#/components/schemas/ServiceRequest' - medications: - type: array - items: - $ref: '#/components/schemas/Medication' - followups: - type: array - items: - $ref: '#/components/schemas/FollowUp' - procedures: - type: array - items: - $ref: '#/components/schemas/Procedure' - referrals: - type: array - items: - $ref: '#/components/schemas/Referral' - otherObservations: - type: array - items: - $ref: '#/components/schemas/OtherObservation' - documents: - type: array - items: - $ref: '#/components/schemas/Document' - required: - - bundleType - - patient - - practitioners - - careContextReference - - authoredOn - PrescriptionRecord: - type: object - properties: - bundleType: - type: string - enum: - - PrescriptionRecord - careContextReference: - type: string - example: visit-{{$isoTimestamp}} - authoredOn: - type: string - format: date - example: 2001-05-22 - encounter: - type: string - example: "" - patient: - $ref: '#/components/schemas/Patient' - practitioners: - type: array - items: - $ref: '#/components/schemas/Practitioner' - organisation: - $ref: '#/components/schemas/Organisation' - prescriptions: - type: array - items: - $ref: '#/components/schemas/Medication' - documents: - type: array - items: - $ref: '#/components/schemas/Document' - required: - - bundleType - - patient - - practitioners - - careContextReference - - authoredOn - - prescriptions - example: - bundleType: PrescriptionRecord - careContextReference: visit-{{$isoTimestamp}} - authoredOn: 2001-05-22 - encounter: "" - patient: - name: Venu Ajitesh - patientReference: ajitesh6x - gender: male - birthDate: 2001-04-27 - practitioners: - - name: Dr.Venu Ajitesh - practitionerId: Predator - organisation: - facilityName: Predator_HIP - facilityId: Predator_HIP - prescriptions: - - medicine: Dolo - dosage: 1-0-1 - timing: 1-1-D - route: Oral - method: swallow - additionalInstructions: Take them after food - reason: Fever - documents: - - type: Prescription - contentType: application/pdf - data: JVBERi0xLjMKJf////8K - HealthDocumentRecord: - type: object - properties: - bundleType: - type: string - enum: - - HealthDocumentRecord - careContextReference: - type: string - example: visist 21-03-2024 - patient: - $ref: '#/components/schemas/Patient' - authoredOn: - type: string - format: date - example: 2001-04-27 - practitioners: - type: array - items: - $ref: '#/components/schemas/Practitioner' - organisation: - $ref: '#/components/schemas/Organisation' - encounter: - type: string - example: "" - documents: - type: array - items: - $ref: '#/components/schemas/Document' - required: - - bundleType - - patient - - practitioners - - careContextReference - - authoredOn - - documents - example: - bundleType: HealthDocumentRecord - careContextReference: visist 21-03-2024 - patient: - name: Venu Ajitesh - patientReference: ajitesh6x - gender: male - birthDate: 2001-04-27 - date: 2001-04-27 - practitioners: - - name: Dr.Venu Ajitesh - practitionerId: Predator - organisation: - facilityName: Predator_HIP - facilityId: Predator_HIP - encounter: "" - documents: - - contentType: application/pdf - data: xyzadybcljbabvlalbfdbvubujzbj - DiagnosticReport: - type: object - properties: - bundleType: - type: string - enum: - - DiagnosticReport - careContextReference: - type: string - example: visist 21-03-2024 - authoredOn: - type: string - format: date - example: 2024-05-20 - patient: - $ref: '#/components/schemas/Patient' - practitioners: - type: array - items: - $ref: '#/components/schemas/Practitioner' - organisation: - $ref: '#/components/schemas/Organisation' - encounter: - type: string - example: Ambula - diagnostics: - type: array - items: - $ref: '#/components/schemas/Diagnostic' - documents: - type: array - items: - $ref: '#/components/schemas/Document' - required: - - bundleType - - patient - - practitioners - - careContextReference - - authoredOn - - diagnostics - example: - bundleType: DiagnosticReport - careContextReference: visist 21-03-2024 - authoredOn: 2024-05-20 - patient: - name: Venu Ajitesh - patientReference: ajitesh6x - gender: male - birthDate: 2001-04-27 - practitioners: - - name: Dr.Venu Ajitesh - practitionerId: Predator - organisation: - facilityName: Predator_HIP - facilityId: Predator_HIP - encounter: Ambula - diagnostics: - - serviceName: BloodTest - serviceCategory: Hematography - result: - - observation: Height - result: Normal - valueQuantity: - unit: CM - value: 170 - conclusion: Normal - presentedForm: - contentType: application/pdf - data: skciybewydcugueducuyeduychidhyuchyedyhcb - documents: - - contentType: pdf - data: xyzadybcljbabvlalbfdbvubujzbj - - ImmunizationRecord: - type: object - properties: - bundleType: - type: string - enum: - - ImmunizationRecord - careContextReference: - type: string - example: visit-{{$isoTimestamp}} - patient: - $ref: '#/components/schemas/Patient' - practitioners: - type: array - items: - $ref: '#/components/schemas/Practitioner' - organisation: - $ref: '#/components/schemas/Organisation' - immunizations: - type: array - items: - $ref: '#/components/schemas/Immunization' - documents: - type: array - items: - $ref: '#/components/schemas/Document' - required: - - bundleType - - patient - - practitioners - - careContextReference - - authoredOn - - immunizations - example: - bundleType: ImmunizationRecord - careContextReference: visit-{{$isoTimestamp}} - patient: - name: Venu Ajitesh - patientReference: ajitesh6x - gender: male - birthDate: 2001-04-27 - practitioners: - - name: Dr.Venu Ajitesh - practitionerId: Predator - organisation: - facilityName: Predator_HIP - facilityId: Predator_HIP - immunizations: - - date: 2024-06-15 - vaccineName: Covaxin - lotNumber: IN00004 - manufacturer: NHA - doseNumber: 3 - documents: - - type: immunization - contentType: application/pdf - data: xyzadybcljbabvlalbfdbvubujzbj - DischargeSummary: - type: object - properties: - bundleType: - type: string - enum: - - discharge-summary - careContextReference: - type: string - example: visist 21-03-2024 - patient: - $ref: '#/components/schemas/Patient' - practitioners: - type: array - items: - $ref: '#/components/schemas/Practitioner' - organisation: - $ref: '#/components/schemas/Organisation' - chiefComplaints: - type: array - items: - $ref: '#/components/schemas/ChiefComplaint' - physicalExaminations: - type: array - items: - $ref: '#/components/schemas/PhysicalExamination' - allergies: - type: array - items: - type: string - medicalHistories: - type: array - items: - $ref: '#/components/schemas/ChiefComplaint' - familyHistories: - type: array - items: - $ref: '#/components/schemas/FamilyHistory' - authoredOn: - type: string - format: date - medications: - type: array - items: - $ref: '#/components/schemas/Medication' - diagnostics: - type: array - items: - $ref: '#/components/schemas/Diagnostic' - procedures: - type: array - items: - $ref: '#/components/schemas/Procedure' - documents: - type: array - items: - $ref: '#/components/schemas/Document' - required: - - bundleType - - patient - - practitioners - - careContextReference - - authoredOn - example: - bundleType: discharge-summary - careContextReference: visist 21-03-2024 - patient: - name: Venu Ajitesh - patientReference: ajitesh6x - gender: male - birthDate: 2001-04-27 - practitioners: - - name: Dr.Venu Ajitesh - practitionerId: Predator - organisation: - facilityName: Predator_HIP - facilityId: Predator_HIP - chiefComplaints: - - complaint: Sugar - recordedDate: 2024-05-20 - dateRange: - from: 2018-04-27 - to: 2018-05-26 - medications: - - medicine: Dolo - dosage: 1-0-1 - timing: 1-1-D - route: Oral - method: swallow - additionalInstructions: Take them after food - physicalExaminations: - - observation: Height - valueQuantity: - unit: CM - value: 170 - allergies: - - Walnuts - medicalHistories: - - complaint: Sugar - recordedDate: 2024-05-20 - dateRange: - from: 2018-04-27 - to: 2018-05-26 - familyHistories: - - relationship: Friend - observation: Toxic - diagnostics: - - serviceName: BloodTest - serviceCategory: Hematography - result: - - observation: Height - result: Normal - valueQuantity: - unit: CM - value: 170 - conclusion: Normal - presentedForm: - contentType: application/pdf - data: skciybewydcugueducuyeduychidhyuchyedyhcb - procedures: - - status: INPROGRESS - condition: Severe - outcome: Healthy - details: Operation - documents: - - type: OP record - contentType: application/pdf - data: xyzadybcljbabvlalbfdbvubujzbj - WellnessRecord: - type: object - properties: - bundleType: - type: string - enum: - - wellness-record - careContextReference: - type: string - example: visist 21-03-2025 - patient: - $ref: '#/components/schemas/Patient' - practitioners: - type: array - items: - $ref: '#/components/schemas/Practitioner' - organisation: - $ref: '#/components/schemas/Organisation' - vitalSigns: - type: array - items: - $ref: '#/components/schemas/Observation' - bodyMeasurements: - type: array - items: - $ref: '#/components/schemas/Observation' - physicalActivities: - type: array - items: - $ref: '#/components/schemas/Observation' - generalAssessments: - type: array - items: - $ref: '#/components/schemas/Observation' - womanHealths: - type: array - items: - $ref: '#/components/schemas/Observation' - lifeStyles: - type: array - items: - $ref: '#/components/schemas/Observation' - otherObservations: - type: array - items: - $ref: '#/components/schemas/Observation' - documents: - type: array - items: - $ref: '#/components/schemas/Document' - required: - - bundleType - - patient - - practitioners - - careContextReference - example: - bundleType: wellness-record - careContextReference: visist 21-03-2025 - patient: - name: Venu Ajitesh - patientReference: ajitesh6x - gender: male - birthDate: 2001-04-27 - practitioner: - - name: Dr.Venu Ajitesh - practitionerId: Predator - organisation: - facilityName: Predator_HIP - facilityId: Predator_HIP - vitalSigns: - - observation: Height - result: Normal - valueQuantity: - unit: CM - value: 170 - bodyMeasurements: - - observation: Height - result: Normal - valueQuantity: - unit: CM - value: 170 - physicalActivities: - - observation: Height - result: Normal - valueQuantity: - unit: CM - value: 170 - generalAssessments: - - observation: Height - result: Normal - valueQuantity: - unit: CM - value: 170 - womanHealths: - - observation: Height - result: Normal - valueQuantity: - unit: CM - value: 170 - lifeStyles: - - observation: Height - result: Normal - valueQuantity: - unit: CM - value: 170 - otherObservations: - - observation: Height - result: Normal - valueQuantity: - unit: CM - value: 170 - documents: - - type: Prescription - contentType: application/pdf - data: JVBERi0xLjMKJf////8KOCAwIG9iago8PAovVHlwZSAvRXh0R1N0YXRlCi9jYSAxCj4 - - Patient: - type: object - properties: - name: - type: string - patientReference: - type: string - gender: - type: string - enum: - - male - - female - birthDate: - type: string - format: date - required: - - name - - patientReference - example: - name: Venu Ajitesh - patientReference: ajitesh6x - gender: male - birthDate: 2001-04-27 - - Practitioner: - type: object - properties: - name: - type: string - practitionerId: - type: string - required: - - name - example: - name: Dr.Venu Ajitesh - practitionerId: Predator - - Organisation: - type: object - properties: - facilityName: - type: string - facilityId: - type: string - required: - - facilityName - example: - facilityName: Predator_HIP - facilityId: Predator_HIP - Diagnostic: - type: object - properties: - serviceName: - type: string - serviceCategory: - type: string - result: - type: array - items: - $ref: '#/components/schemas/Observation' - conclusion: - type: string - presentedForm: - $ref: '#/components/schemas/Document' - required: - - serviceName - - serviceCategory - - result - example: - serviceName: BloodTest - serviceCategory: Hematography - result: - - observation: Height - result: Normal - valueQuantity: - unit: CM - value: 170 - conclusion: Normal - presentedForm: - contentType: application/pdf - data: skciybewydcugueducuyeduychidhyuchyedyhcb - Immunization: - type: object - properties: - date: - type: string - format: date - vaccineName: - type: string - lotNumber: - type: string - manufacturer: - type: string - doseNumber: - type: string - required: - - date - - vaccineName - example: - date: 2024-06-15 - vaccineName: Covaxin - lotNumber: IN00004 - manufacturer: NHA - doseNumber: 3 - - DiagnosticResult: - type: object - properties: - observation: - type: string - result: - type: string - valueQuantity: - $ref: '#/components/schemas/ValueQuantity' - required: - - observation - example: - observation: Height - result: Normal - valueQuantity: - unit: CM - value: 170 - - ChiefComplaint: - type: object - properties: - complaint: - type: string - recordedDate: - type: string - format: date - dateRange: - $ref: '#/components/schemas/DateRange' - required: - - complaint - - recordedDate - example: - complaint: Sugar - recordedDate: 2024-05-20 - dateRange: - from: 2018-04-27 - to: 2018-05-26 - - DateRange: - type: object - properties: - from: - type: string - format: date - to: - type: string - format: date - example: - from: 2018-04-27 - to: 2018-05-26 - - PhysicalExamination: - type: object - properties: - observation: - type: string - result: - type: string - valueQuantity: - $ref: '#/components/schemas/ValueQuantity' - required: - - observation - example: - observation: Height - result: Normal - valueQuantity: - unit: CM - value: 170 - - ValueQuantity: - type: object - properties: - unit: - type: string - value: - type: number - required: - - unit - - value - example: - unit: KG - value: 90 - - FamilyHistory: - type: object - properties: - relationship: - type: string - observation: - type: string - required: - - relationship - - observation - example: - relationship: Friend - observation: Toxic - - ServiceRequest: - type: object - properties: - status: - type: string - details: - type: string - specimen: - type: string - required: - - status - - details - example: - status: ACTIVE - details: X-RAY - specimen: Jhonsons - - Medication: - type: object - properties: - medicine: - type: string - dosage: - type: string - timing: - description: frequency-period-periodUnit - type: string - enum: [S,MIN,H,D,WK,MO] - route: - type: string - method: - type: string - additionalInstructions: - type: string - reason: - type: string - required: - - medicine - - dosage - example: - medicine: Dolo - dosage: 1-0-1 - timing: 1-1-D - route: Oral - method: swallow - additionalInstructions: Take them after food - reason: Fever - - - FollowUp: - type: object - properties: - serviceType: - type: string - appointmentTime: - type: string - format: date - reason: - type: string - required: - - serviceType - - appointmentTime - - reason - example: - serviceType: OPConsultation - appointmentTime: 2024-05-20 - reason: General - - Procedure: - type: object - properties: - date: - type: string - status: - type: string - procedureReason: - type: string - outcome: - type: string - procedureName: - type: string - required: - - date - - status - - procedureName - - procedureReason - example: - date: 2001-04-25 - status: INPROGRESS - procedureReason: Severe - outcome: Healthy - procedureName: Operation - - Referral: - type: object - properties: - status: - type: string - details: - type: string - specimen: - type: string - required: - - status - - details - example: - status: ACTIVE - details: Y-RAY - specimen: Rock - - Observation: - type: object - properties: - observation: - type: string - result: - type: string - valueQuantity: - $ref: '#/components/schemas/ValueQuantity' - required: - - observation - example: - observation: Height - result: Normal - valueQuantity: - unit: CM - value: 170 - - OtherObservation: - type: object - properties: - observation: - type: string - result: - type: string - valueQuantity: - $ref: '#/components/schemas/ValueQuantity' - required: - - observation - example: - observation: weight - result: Over weight - valueQuantity: - unit: KG - value: 90 - # Note: Either result or valueQuantity should be included along with observation. - - Document: - type: object - properties: - type: - type: string - contentType: - type: string - data: - type: string - required: - - type - - contentType - - data - example: - type: OP record - contentType: application/pdf - data: xyzadybcljbabvlalbfdbvubujzbj - - - ValidationErrorResponse: - type: object - properties: - validationErrors: - type: object - properties: - code: - type: integer - example: 1000 - error: - type: array - items: - type: object - properties: - field: - type: string - message: - type: string - example: - validationErrors: - code: 1000 - error: - - field: bundleType - message: must match "PrescriptionRecord" - - GenericErrorResponse: - type: object - properties: - error: - type: object - properties: - code: - type: integer - message: - type: string - example: - error: - code: 1000 - message: "Parsing error must match the date format 2002-05-12" diff --git a/fhir-mapper/gradle/wrapper/gradle-wrapper.jar b/fhir-mapper/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index e69de29b..00000000 diff --git a/fhir-mapper/gradle/wrapper/gradle-wrapper.properties b/fhir-mapper/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 70d416a7..00000000 --- a/fhir-mapper/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -#Mon Mar 11 22:06:57 IST 2024 -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/fhir-mapper/gradlew b/fhir-mapper/gradlew deleted file mode 100644 index e69de29b..00000000 diff --git a/fhir-mapper/gradlew.bat b/fhir-mapper/gradlew.bat deleted file mode 100644 index e69de29b..00000000 diff --git a/fhir-mapper/postmanCollection/FHIR.postman_collection.json b/fhir-mapper/postmanCollection/FHIR.postman_collection.json deleted file mode 100644 index 3cb05d03..00000000 --- a/fhir-mapper/postmanCollection/FHIR.postman_collection.json +++ /dev/null @@ -1,318 +0,0 @@ -{ - "info": { - "_postman_id": "6192a23b-5635-4954-9ba9-903e46159dfd", - "name": "FHIR", - "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", - "_exporter_id": "24014718" - }, - "item": [ - { - "name": "prescription", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var template = `", - "", - "", - "", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " {{#each response.entry}}", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " {{/each}}", - "
IDTypeStatusDateSubjectAuthorTitle
{{resource.id}}{{resource.resourceType}}{{resource.status}}{{resource.date}}{{resource.subject.reference}}{{resource.author.[0].reference}}{{resource.title}}
", - "`;", - "", - "function constructVisualizerPayload() {", - " return { response: pm.response.json() };", - "}", - "", - "pm.visualizer.set(template, constructVisualizerPayload());" - ], - "type": "text/javascript", - "packages": {} - } - }, - { - "listen": "prerequest", - "script": { - "exec": [ - "" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\r\n \"bundleType\": \"PrescriptionRecord\",\r\n \"careContextReference\": \"visit-{{$isoTimestamp}}\",\r\n \"authoredOn\": \"2024-05-01T06:33:37.361Z\",\r\n \"encounter\": \"\",\r\n \"patient\": {\r\n \"name\": \"Venu Ajitesh\",\r\n \"patientReference\": \"ajitesh6x\",\r\n \"gender\": \"male\",\r\n \"birthDate\": \"1940-04-27\"\r\n },\r\n \"practitioners\": [\r\n {\r\n \"name\": \"Dr.Venu Ajitesh\",\r\n \"practitionerId\": \"Predator\"\r\n }\r\n ],\r\n \"organisation\": {\r\n \"facilityName\": \"Predator_HIP\",\r\n \"facilityId\": \"Predator_HIP\"\r\n },\r\n \"prescriptions\": [\r\n {\r\n \"medicine\": \"Glucosamine 1 g oral tablet\",\r\n \"dosage\": \"1-0-1\",\r\n \"timing\": \"1-1-D\",\r\n \"route\": \"Oral\",\r\n \"method\": \"swallow\",\r\n \"additionalInstructions\": \"Take them after food\",\r\n \"reason\": \"fever\"\r\n },\r\n {\r\n \"medicine\": \"Acetaminophen 100 mg/mL oral solution\",\r\n \"dosage\": \"0-0-1\",\r\n \"timing\": \"1-2-MO\",\r\n \"route\": \"Syrup\",\r\n \"method\": \"drink\",\r\n \"additionalInstructions\": \"Take them before food\",\r\n \"reason\": \"Cough\"\r\n }\r\n ],\r\n \"documents\": [\r\n {\r\n \"type\": \"Prescription\",\r\n \"contentType\": \"application/pdf\",\r\n \"data\": \"JVBERi0xLjMKJf////8K\"\r\n }\r\n ]\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "localhost:8085/v1/bundle/prescription", - "host": [ - "localhost" - ], - "port": "8085", - "path": [ - "v1", - "bundle", - "prescription" - ] - } - }, - "response": [] - }, - { - "name": "OPConsultation", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\r\n \"bundleType\":\"OPConsultRecord\",\r\n \"careContextReference\":\"visist 21-03-2025\",\r\n \"visitDate\":\"2024-05-02T06:33:37.361Z\",\r\n \"patient\":{\r\n \"name\":\"Venu Ajitesh\",\r\n \"patientReference\":\"ajitesh6x\",\r\n \"gender\":\"male\",\r\n \"birthDate\":\"1940-04-27\"\r\n },\r\n \"practitioners\":[{\r\n \"name\":\"Dr.Venu Ajitesh\",\r\n \"practitionerId\":\"Predator\"\r\n }],\r\n \"organisation\":{\r\n \"facilityName\":\"Predator_HIP\",\r\n \"facilityId\":\"Predator_HIP\"\r\n },\r\n \"chiefComplaints\":[\r\n {\r\n \"complaint\":\"Dengue\",\r\n \"recordedDate\":\"2024-05-20\",\r\n \"dateRange\":{\r\n \"from\":\"2018-04-27\",\r\n \"to\":\"2018-05-26\"\r\n }\r\n }\r\n ],\r\n \"physicalExaminations\":[\r\n {\r\n \"observation\":\"Heavy drinker\",\r\n \"result\":\"heavy\"\r\n // \"valueQuantity\": {\r\n\t\t\t// \t\t\"unit\": \"CM\",\r\n\t\t\t// \t\t\"value\": 170\r\n\t\t\t// }\r\n }\r\n ],\r\n \"allergies\":[\r\n \"\"\r\n ],\r\n \"medicalHistories\": \r\n [\r\n {\r\n \"complaint\":\"Typhoid fever\",\r\n \"recordedDate\":\"2024-05-20\",\r\n \"dateRange\":{\r\n \"from\":\"2018-04-27\",\r\n \"to\":\"2018-05-26\"\r\n }\r\n }\r\n ],\r\n \"familyHistories\":[\r\n {\r\n \"relationship\":\"Friend\",\r\n \"observation\":\"Toxic\"\r\n }\r\n ],\r\n \"serviceRequests\":[\r\n {\r\n \"status\":\"ACTIVE\",\r\n \"details\":\"X-RAY\",\r\n \"specimen\":\"Lung cytologic material\"\r\n }\r\n ],\r\n \"medications\":\r\n [\r\n {\r\n \"medicine\":\"Nabilone 2 mg oral capsule\",\r\n \"dosage\":\"1-0-1\",\r\n \"timing\":\"2-5-D\",\r\n \"route\":\"Oral route\",\r\n \"method\":\"swallow\",\r\n \"additionalInstructions\":\"Take them after food\"\r\n }\r\n ,{\r\n \"medicine\":\"Nystatin 25000 unit/g vaginal cream\",\r\n \"dosage\":\"0-0-1\",\r\n \"timing\":\"1-2-D\",\r\n \"route\":\"Interstitial route (qualifier value)\",\r\n \"method\":\"drink\",\r\n \"additionalInstructions\":\"Take them before food\"\r\n }\r\n ],\r\n \"followups\":[\r\n {\r\n \"serviceType\":\"OPConsultation\",\r\n \"appointmentTime\":\"2024-05-20\",\r\n \"reason\":\"General\"\r\n }\r\n ],\r\n \"procedures\":[\r\n {\r\n \"date\":\"2001-04-20\",\r\n \"status\":\"INPROGRESS\",\r\n \"procedureReason\":\"Severe\",\r\n \"outcome\":\"Healthy\",\r\n \"procedureName\":\"Endodontic procedure\"\r\n }\r\n ],\r\n \"referrals\":[\r\n {\r\n \"status\":\"ACTIVE\",\r\n \"details\":\"Y-RAY\",\r\n \"specimen\":\"Pleural cytologic material\"\r\n }\r\n ],\r\n \"otherObservations\":[\r\n {\r\n \"observation\":\"Body weight\",\r\n // \"result\":\"Over weight\",\r\n \"valueQuantity\": {\r\n\t\t\t\t\t\"unit\": \"KG\",\r\n\t\t\t\t\t\"value\": 90\r\n\t\t\t\t}\r\n }\r\n ],\r\n \"documents\":[{\r\n \"type\":\"OP record\",\r\n \"contentType\":\"application/pdf\",\r\n \"data\":\"JVBERi0xLjMKJf////8K\"\r\n }]\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "localhost:8085/v1/bundle/op-consultation", - "host": [ - "localhost" - ], - "port": "8085", - "path": [ - "v1", - "bundle", - "op-consultation" - ] - } - }, - "response": [] - }, - { - "name": "health-document", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "" - ], - "type": "text/javascript", - "packages": {} - } - }, - { - "listen": "prerequest", - "script": { - "exec": [ - "" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\r\n \"bundleType\":\"HealthDocumentRecord\",\r\n \"careContextReference\":\"visist 21-03-2024\",\r\n \"patient\":{\r\n \"name\":\"Venu Ajitesh\",\r\n \"patientReference\":\"ajitesh6x\",\r\n \"gender\":\"male\",\r\n \"birthDate\":\"1940-04-27\"\r\n },\r\n \"authoredOn\":\"2024-05-03T06:33:37.361Z\",\r\n \"practitioners\":[{\r\n \"name\":\"Dr.Venu Ajitesh\",\r\n \"practitionerId\":\"Predator\"\r\n }],\r\n \"organisation\":{\r\n \"facilityName\":\"Predator_HIP\",\r\n \"facilityId\":\"Predator_HIP\"\r\n },\r\n \"encounter\":\"\",\r\n \"documents\":[{\r\n \"type\":\"health-document\",\r\n \"contentType\":\"application/pdf\",\r\n \"data\":\"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7Igi2NJ03WIdb8CPaOhwBlKEkoax7E5ZdLjP42F98TiJWKZ1T9XnPz8+/Kc1f/jRS/+d3B19aNHmf3r24eU/ho/Y+4/AKijvgugHu5+K373i9d+++9oPF/X9P6FV1H1lbmRzdHJlYW0gCmVuZG9iaiAKMiAwIG9iaiAKPDwgCi9UeXBlIC9QYWdlcyAKL0tpZHMgWyA4IDAgUiBdIAovQ291bnQgMSAKL01lZGlhQm94IDMgMCBSIAovQ3JvcEJveCA0IDAgUiAKPj4gCmVuZG9iaiAKMyAwIG9iaiAKWyAwIDAgNTk1IDg0MSBdIAplbmRvYmogCjQgMCBvYmogClsgMCAwIDU5NSA4NDEgXSAKZW5kb2JqIAo2IDAgb2JqIAo8PCAKL1Byb2NTZXQgNyAwIFIgCi9Gb250IDw8IAovOSA5IDAgUiAgCi9hIDEwIDAgUiAgCj4+IAovWE9iamVjdCA8PCAKL2ltZzAgMTEgMCBSICAKPj4gCj4+IAplbmRvYmogCjcgMCBvYmogClsgL1BERiAvVGV4dCAvSW1hZ2VCIC9JbWFnZUMgL0ltYWdlSSAgXSAKZW5kb2JqIAo4IDAgb2JqIAo8PCAKL1R5cGUgL1BhZ2UgCi9QYXJlbnQgMiAwIFIgCi9SZXNvdXJjZXMgNiAwIFIgCi9Db250ZW50cyBbIDUgMCBSIF0gCj4+IAplbmRvYmogCjkgMCBvYmogCjw8IAovVHlwZSAvRm9udCAKL1N1YnR5cGUgL1RydWVUeXBlIAovQmFzZUZvbnQgL0FBQUFBQStBcmlhbCxCb2xkIAovRmlyc3RDaGFyIDMyIAovTGFzdENoYXIgMTIxIAovV2lkdGhzIDE0IDAgUiAKL0ZvbnREZXNjcmlwdG9yIDE2IDAgUiAKL1RvVW5pY29kZSAxNSAwIFIgCj4+IAplbmRvYmogCjEwIDAgb2JqIAo8PCAKL1R5cGUgL0ZvbnQgCi9TdWJ0eXBlIC9UcnVlVHlwZSAKL0Jhc2VGb250IC9BQUFBQUIrQXJpYWwgCi9GaXJzdENoYXIgMzIgCi9MYXN0Q2hhciAxMjIgCi9XaWR0aHMgMTkgMCBSIAovRm9udERlc2NyaXB0b3IgMjEgMCBSIAovVG9Vbmljb2RlIDIwIDAgUiAKPj4gCmVuZG9iaiAKMTEgMCBvYmog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CjY2NyAKMCAKNzIyIAo2NjcgCjYxMSAKNzIyIAowIAowIAowIAowIAowIAowIAowIAowIAowIAowIAowIAo1NTYgCjYxMSAKNTU2IAo2MTEgCjU1NiAKMzMzIAo2MTEgCjYxMSAKMjc4IAowIAo1NTYgCjI3OCAKODg5IAo2MTEgCjYxMSAKNjExIAowIAozODkgCjU1NiAKMzMzIAo2MTEgCjU1NiAKMCAKMCAKNTU2IApdIAplbmRvYmogCjE2IDAgb2JqIAo8PCAKL1R5cGUgL0ZvbnREZXNjcmlwdG9yIAovQXNjZW50IDkwNSAKL0NhcEhlaWdodCA1MDAgCi9EZXNjZW50IC0yMTIgCi9GbGFncyA0IAovRm9udEJCb3ggMTcgMCBSIAovRm9udE5hbWUgL0FBQUFBQStBcmlhbCxCb2xkIAovSXRhbGljQW5nbGUgMAovU3RlbVYgMCAKL1N0ZW1IIDAgCi9BdmdXaWR0aCA0NzkgCi9Gb250RmlsZTIgMTggMCBSIAovTGVhZGluZyAwIAovTWF4V2lkdGggMjYyOCAKL01pc3NpbmdXaWR0aCA0NzkgCi9YSGVpZ2h0IDAgCj4+IAplbmRvYmogCjE3IDAgb2JqIApbIC02MjggLTM3NiAyMDAwIDEwNTYgXSAKZW5kb2JqIAoxOSAwIG9iaiAKWyAKMjc4IAowIAowIAowIAowIAowIAowIAowIAowIAowIAowIAowIAoyNzggCjMzMyAKMjc4IAoyNzggCjU1NiAKNTU2IAo1NTYgCjU1NiAKNTU2IAo1NTYgCjU1NiAKNTU2IAo1NTYgCjU1NiAKMjc4IAowIAowIAowIAowIAowIAowIAo2NjcgCjY2NyAKNzIyIAo3MjIgCjY2NyAKMCAKNzc4IAo3MjIgCjI3OCAKMCAKMCAKNTU2IAo4MzMgCjcyMiAKNzc4IAo2NjcgCjAgCjcyMiAKNjY3IAo2MTEgCjcyMiAKMCAKOTQ0IAowIAo2NjcgCjAgCjAgCjAgCjAgCjAgCjAgCjAgCjU1NiAKNTU2IAo1MDAgCjU1NiAKNTU2IAowIAo1NTYgCjU1NiAKMjIyIAoyMjIgCjAgCjIyMiAKODMzIAo1NTYgCjU1NiAKNTU2IAowIAozMzMgCjUwMCAKMjc4IAo1NTYgCjAgCjAgCjAgCjAgCjUwMCAKXSAKZW5kb2JqIAoyMSAwIG9iaiAKPDwgCi9UeXBlIC9Gb250RGVzY3JpcHRvciAKL0FzY2VudCA5MDUgCi9DYXBIZWlnaHQgNTAwIAovRGVzY2VudCAtMjEyIAovRmxhZ3MgNCAKL0ZvbnRCQm94IDIyIDAgUiAKL0ZvbnROYW1lIC9BQUFBQUIrQXJpYWwgCi9JdGFsaWNBbmdsZSAwCi9TdGVtViAwIAovU3RlbUggMCAKL0F2Z1dpZHRoIDQ0MSAKL0ZvbnRGaWxlMiAyMyAwIFIgCi9MZWFkaW5nIDAgCi9NYXhXaWR0aCAyNjY1IAovTWlzc2luZ1dpZHRoIDQ0MSAKL1hIZWlnaHQgMCAKPj4gCmVuZG9iaiAKMjIgMCBvYmogClsgLTY2NSAtMzI1IDIwMDAgMTA0MCBdIAplbmRvYmogCjI0IDAgb2JqIAooUG93ZXJlZCBCeSBDcnlzdGFsKSAKZW5kb2JqIAoyNSAwIG9iaiAKKENyeXN0YWwgUmVwb3J0cykgCmVuZG9iaiAKMjYgMCBvYmogCjw8IAovUHJvZHVjZXIgKFBvd2VyZWQgQnkgQ3J5c3RhbCkgIAovQ3JlYXRvciAoQ3J5c3RhbCBSZXBvcnRzKSAgCj4+IAplbmRvYmogCnhyZWYgCjAgMjcgCjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDAxNyAwMDAwMCBuIAowMDAwMDQyNDE0IDAwMDAwIG4gCjAwMDAwNDI1MTMgMDAwMDAgbiAKMDAwMDA0MjU0NyAwMDAwMCBuIAowMDAwMDAwMTk0IDAwMDAwIG4gCjAwMDAwNDI1ODEgMDAwMDAgbiAKMDAwMDA0MjY5MSAwMDAwMCBuIAowMDAwMDQyNzQ5IDAwMDAwIG4gCjAwMDAwNDI4NDEgMDAwMDAgbiAKMDAwMDA0MzAxOCAwMDAwMCBuIAowMDAwMDQzMTkxIDAwMDAwIG4gCjAwMDAwNTQ3MzUgMDAwMDAgbiAKMDAwMDA1NDc4OSAwMDAwMCBuIAowMDAwMDU1NjA0IDAwMDAwIG4gCjAwMDAwMDE0NzQgMDAwMDAgbiAKMDAwMDA1NTk5MCAwMDAwMCBuIAowMDAwMDU2MjY5IDAwMDAwIG4gCjAwMDAwMDIwOTUgMDAwMDAgbiAKMDAwMDA1NjMxMiAwMDAwMCBuIAowMDAwMDE4MTE3IDAwMDAwIG4gCjAwMDAwNTY3MTcgMDAwMDAgbiAKMDAwMDA1Njk5MSAwMDAwMCBuIAowMDAwMDE4Nzc5IDAwMDAwIG4gCjAwMDAwNTcwMzQgMDAwMDAgbiAKMDAwMDA1NzA3NCAwMDAwMCBuIAowMDAwMDU3MTExIDAwMDAwIG4gCnRyYWlsZXIgCjw8IAovU2l6ZSAyNyAKL1Jvb3QgMSAwIFIgCi9JbmZvIDI2IDAgUiAKPj4gCnN0YXJ0eHJlZiAKNTcxOTkgCiUlRU9GDQo=\"\r\n }]\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "localhost:8085/v1/bundle/health-document", - "host": [ - "localhost" - ], - "port": "8085", - "path": [ - "v1", - "bundle", - "health-document" - ] - } - }, - "response": [] - }, - { - "name": "diagnosticReport", - "protocolProfileBehavior": { - "disabledSystemHeaders": {} - }, - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\r\n \"bundleType\": \"DiagnosticReportRecord\",\r\n \"careContextReference\": \"visist 21-03-2024\",\r\n \"visitDate\": \"2024-05-07T06:33:37.361Z\",\r\n \"patient\": {\r\n \"name\": \"Venu Ajitesh\",\r\n \"patientReference\": \"ajitesh6x\",\r\n \"gender\": \"male\",\r\n \"birthDate\": \"1940-04-27\"\r\n },\r\n \"practitioners\": [\r\n {\r\n \"name\": \"Dr.Venu Ajitesh\",\r\n \"practitionerId\": \"Predator\"\r\n }\r\n ],\r\n \"organisation\": {\r\n \"facilityName\": \"Predator_HIP\",\r\n \"facilityId\": \"Predator_HIP\"\r\n },\r\n \"encounter\": \"Ambula\",\r\n \"diagnostics\": [\r\n {\r\n \"serviceName\": \"BloodTest\",\r\n \"authoredOn\":\"2024-11-23T21:34:38.989Z\",\r\n \"serviceCategory\": \"Hematography\",\r\n \"result\": [\r\n {\r\n \"observation\": \"Height\",\r\n \"result\": \"Normal\",\r\n \"valueQuantity\": {\r\n \"unit\": \"CM\",\r\n \"value\": 170\r\n }\r\n }\r\n ],\r\n \"conclusion\": \"Normal\",\r\n \"presentedForm\":{\r\n \"contentType\": \"application/pdf\",\r\n \"data\": \"JVBERi0xLjMKJf////8K\"\r\n }\r\n }\r\n ],\r\n \"documents\":[{\r\n \"type\": \"diagnosticReport\",\r\n \"contentType\": \"application/pdf\",\r\n \"data\": \"JVBERi0xLjMKJf////8K\"\r\n }]\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "localhost:8085/v1/bundle/diagnostic-report", - "host": [ - "localhost" - ], - "port": "8085", - "path": [ - "v1", - "bundle", - "diagnostic-report" - ] - } - }, - "response": [] - }, - { - "name": "wellness-record", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\r\n \"bundleType\":\"WellnessRecord\",\r\n \"careContextReference\":\"visist 21-03-2025\",\r\n \"authoredOn\":\"2024-05-04T06:33:37.361Z\",\r\n \"patient\":{\r\n \"name\":\"Venu Ajitesh\",\r\n \"patientReference\":\"ajitesh6x\",\r\n \"gender\":\"male\",\r\n \"birthDate\":\"1940-04-27\"\r\n },\r\n \"practitioners\":[{\r\n \"name\":\"Dr.Venu Ajitesh\",\r\n \"practitionerId\":\"Predator\"\r\n }],\r\n \"organisation\":{\r\n \"facilityName\":\"Predator_HIP\",\r\n \"facilityId\":\"Predator_HIP\"\r\n },\r\n \"vitalSigns\":[\r\n {\r\n \"observation\":\"Height\",\r\n \"result\":\"Normal\",\r\n \"valueQuantity\": {\r\n\t\t\t\t\t\"unit\": \"CM\",\r\n\t\t\t\t\t\"value\": 170\r\n\t\t\t}\r\n }\r\n ],\r\n \"bodyMeasurements\":[\r\n {\r\n \"observation\":\"BMI\",\r\n \"result\":\"Normal\",\r\n \"valueQuantity\": {\r\n\t\t\t\t\t\"unit\": \"CM\",\r\n\t\t\t\t\t\"value\": 170\r\n\t\t\t}\r\n }\r\n ],\r\n \"physicalActivities\":[\r\n {\r\n \"observation\":\"Running\",\r\n \"result\":\"Normal\",\r\n \"valueQuantity\": {\r\n\t\t\t\t\t\"unit\": \"CM\",\r\n\t\t\t\t\t\"value\": 170\r\n\t\t\t}\r\n }\r\n ],\r\n \"generalAssessments\":[\r\n {\r\n \"observation\":\"Physico\",\r\n \"result\":\"Normal\",\r\n \"valueQuantity\": {\r\n\t\t\t\t\t\"unit\": \"CM\",\r\n\t\t\t\t\t\"value\": 170\r\n\t\t\t}\r\n }\r\n ],\"womanHealths\":[\r\n {\r\n \"observation\":\"Crazy\",\r\n \"result\":\"Normal\",\r\n \"valueQuantity\": {\r\n\t\t\t\t\t\"unit\": \"CM\",\r\n\t\t\t\t\t\"value\": 170\r\n\t\t\t}\r\n }\r\n ],\r\n \"lifeStyles\":[\r\n {\r\n \"observation\":\"Bad\",\r\n \"result\":\"Normal\",\r\n \"valueQuantity\": {\r\n\t\t\t\t\t\"unit\": \"CM\",\r\n\t\t\t\t\t\"value\": 170\r\n\t\t\t}\r\n }\r\n ],\r\n \"otherObservations\":[\r\n {\r\n \"observation\":\"None\",\r\n \"result\":\"Normal\",\r\n \"valueQuantity\": {\r\n\t\t\t\t\t\"unit\": \"CM\",\r\n\t\t\t\t\t\"value\": 170\r\n\t\t\t}\r\n }\r\n ],\r\n \"documents\":[{\r\n \"type\":\"WellnessRecord\",\r\n \"contentType\":\"application/pdf\",\r\n \"data\": \"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Mzc1Ci9YSGVpZ2h0IDUyOC4zMjAzMTMKL1N0ZW1WIDAKL0ZvbnRGaWxlMiAxNiAwIFIKPj4KZW5kb2JqCjE4IDAgb2JqCjw8Ci9UeXBlIC9Gb250Ci9TdWJ0eXBlIC9DSURGb250VHlwZTIKL0Jhc2VGb250IC9CWlpaWlorUm9ib3RvLVJlZ3VsYXIKL0NJRFN5c3RlbUluZm8gPDwKL1JlZ2lzdHJ5IChBZG9iZSkKL09yZGVyaW5nIChJZGVudGl0eSkKL1N1cHBsZW1lbnQgMAo+PgovRm9udERlc2NyaXB0b3IgMTcgMCBSCi9XIFswIFs5MDggNzEzLjM3ODkwNiA3MTMuMzc4OTA2IDY1Mi4zNDM3NSAyNDguMDQ2ODc1IDI0NC4xNDA2MjUgNTYzLjk2NDg0NCA4NzYuOTUzMTI1IDI0My4xNjQwNjMgNTUyLjI0NjA5NCA2MzYuNzE4NzUgNTcwLjMxMjUgNTUxLjI2OTUzMSA1MjMuNDM3NSA1NTAuNzgxMjUgNTMwLjI3MzQzOCAzMzguODY3MTg4IDI0My4xNjQwNjMgNTQzLjk0NTMxMyAzMjcuMTQ4NDM4IDU5My43NSA1MTYuMTEzMjgxIDU2Mi4wMTE3MTkgNTYyLjAxMTcxOSA1NjIuMDExNzE5IDU2Mi4wMTE3MTkgNDg0LjM3NSA1NjIuMDExNzE5IDU2Mi4wMTE3MTkgNTYyLjAxMTcxOSA1NjIuMDExNzE5IDg3My4wNDY4NzUgNjE2LjIxMDkzOCAyNzYuMzY3MTg4IDI0Mi4xODc1IDYzMC44NTkzNzUgMjYzLjY3MTg3NSAyNzEuOTcyNjU2IDU5Ni42Nzk2ODggNTY4LjM1OTM3NSA2NTYuMjUgNjUwLjg3ODkwNiAzNDcuNjU2MjUgNTYyLjAxMTcxOSA1NjIuMDExNzE5IDU2MS41MjM0MzggNjg3Ljk4ODI4MSA2NDguNDM3NSA1NjEuNTIzNDM4IDYwMC41ODU5MzhdXQovQ0lEVG9HSURNYXAgL0lkZW50aXR5Cj4+CmVuZG9iagoxOSAwIG9iago8PAovTGVuZ3RoIDMzNwovRmlsdGVyIC9GbGF0ZURlY29kZQo+PgpzdHJlYW0KeJxdUstugzAQvPMVe0wPEQFDaCSEVKUXDn2otKeqB2IvEVIxliEH/r7G4yZV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hSaeRYM/OC1xOdwlOx480lpmEZzGvKwIYw3O7ev2dcIFETqTyfRBfUg7ItEpSQGFjhGF/hcOmQnjCmVuZHN0cmVhbQplbmRvYmoKeHJlZgowIDI0CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwNjQ0OSAwMDAwMCBuIAowMDAwMDA2NTA2IDAwMDAwIG4gCjAwMDAwMDYzODcgMDAwMDAgbiAKMDAwMDAwNjM2NiAwMDAwMCBuIAowMDAwMDAwMzU5IDAwMDAwIG4gCjAwMDAwMDAyMTkgMDAwMDAgbiAKMDAwMDAwMDEwOSAwMDAwMCBuIAowMDAwMDAwMDE1IDAwMDAwIG4gCjAwMDAwMDAwNTkgMDAwMDAgbiAKMDAwMDAwNDgxMCAwMDAwMCBuIAowMDAwMDA2MjE4IDAwMDAwIG4gCjAwMDAwMDMzMTcgMDAwMDAgbiAKMDAwMDAwMzIyOSAwMDAwMCBuIAowMDAwMDAzMjU1IDAwMDAwIG4gCjAwMDAwMDMyODEgMDAwMDAgbiAKMDAwMDAwNjU1MyAwMDAwMCBuIAowMDAwMDAzMzkzIDAwMDAwIG4gCjAwMDAwMDM2NjEgMDAwMDAgbiAKMDAwMDAwNDQwMCAwMDAwMCBuIAowMDAwMDE0MjAzIDAwMDAwIG4gCjAwMDAwMDQ5NTkgMDAwMDAgbiAKMDAwMDAwNTIyNiAwMDAwMCBuIAowMDAwMDA1ODM2IDAwMDAwIG4gCnRyYWlsZXIKPDwKL1NpemUgMjQKL1Jvb3QgMyAwIFIKL0luZm8gMTIgMCBSCi9JRCBbPDdiOTliYmRjNzc5ZjAyYjc4MGViNDI1ZWU0ZjdmY2JmPiA8N2I5OWJiZGM3NzlmMDJiNzgwZWI0MjVlZTRmN2ZjYmY+XQo+PgpzdGFydHhyZWYKMjA3NzUKJSVFT0YK\"\r\n }]\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "localhost:8085/v1/bundle/wellness-record", - "host": [ - "localhost" - ], - "port": "8085", - "path": [ - "v1", - "bundle", - "wellness-record" - ] - } - }, - "response": [] - }, - { - "name": "immunization", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\r\n \"bundleType\":\"ImmunizationRecord\",\r\n \"careContextReference\":\"visit-{{$isoTimestamp}}\",\r\n \"authoredOn\":\"{{$isoTimestamp}}\",\r\n \"encounter\":\"\",\r\n \"patient\":{\r\n \"name\":\"Venu Ajitesh\",\r\n \"patientReference\":\"ajitesh6x\",\r\n \"gender\":\"male\",\r\n \"birthDate\":\"1940-04-27\"\r\n },\r\n \"practitioners\":[{\r\n \"name\":\"Dr.Venu Ajitesh\",\r\n \"practitionerId\":\"Predator\"\r\n }],\r\n \"organisation\":{\r\n \"facilityName\":\"Predator_HIP\",\r\n \"facilityId\":\"Predator_HIP\"\r\n },\r\n \"immunizations\":[{\r\n \"date\":\"2024-06-15\",\r\n \"vaccineName\":\"Paratyphoid vaccine\",\r\n \"lotNumber\":\"IN00004\",\r\n \"manufacturer\":\"NHA\",\r\n \"doseNumber\":\"3\"\r\n }],\r\n \"documents\":[{\r\n \"type\":\"immunization\",\r\n \"contentType\":\"application/pdf\",\r\n \"data\": \"JVBERi0xLjMKJf////8K\"\r\n }]\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "localhost:8085/v1/bundle/immunization", - "host": [ - "localhost" - ], - "port": "8085", - "path": [ - "v1", - "bundle", - "immunization" - ] - } - }, - "response": [] - }, - { - "name": "discharge-summary", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\r\n \"bundleType\":\"DischargeSummaryRecord\",\r\n \"careContextReference\":\"visist 21-03-2024\",\r\n \"patient\":{\r\n \"name\":\"Venu Ajitesh\",\r\n \"patientReference\":\"ajitesh6x\",\r\n \"gender\":\"male\",\r\n \"birthDate\":\"1940-04-27\"\r\n },\r\n \"practitioners\":[{\r\n \"name\":\"Dr.Venu Ajitesh\",\r\n \"practitionerId\":\"Predator\"\r\n }],\r\n \"carePlan\":{\r\n \"intent\":\"plan\",\r\n \"type\":\"Regular check up\",\r\n \"goal\":\"Reduce BP\",\r\n \"description\":\"Normal\",\r\n \"notes\":\"The patient has an HIGH BP, recommended to revisit on 29-10-2024\"\r\n },\r\n \"organisation\":{\r\n \"facilityName\":\"Predator_HIP\",\r\n \"facilityId\":\"Predator_HIP\"\r\n },\r\n \"chiefComplaints\":[\r\n {\r\n \"complaint\":\"Sugar\",\r\n \"recordedDate\":\"2024-05-20\",\r\n \"dateRange\":{\r\n \"from\":\"2018-04-27\",\r\n \"to\":\"2018-05-26\"\r\n }\r\n }\r\n ],\r\n \"physicalExaminations\":[\r\n {\r\n \"observation\":\"Height\",\r\n \"result\":\"Normal\",\r\n \"valueQuantity\": {\r\n\t\t\t\t\t\"unit\": \"CM\",\r\n\t\t\t\t\t\"value\": 170\r\n\t\t\t}\r\n }\r\n ],\r\n \"allergies\":[\r\n \"Walnuts\"\r\n ],\r\n \"medicalHistories\":[\r\n {\r\n \"complaint\":\"Sugar\",\r\n \"recordedDate\":\"2024-05-20\",\r\n \"dateRange\":{\r\n \"from\":\"2018-04-27\",\r\n \"to\":\"2018-05-26\"\r\n }\r\n }\r\n ],\r\n \"familyHistories\":[\r\n {\r\n \"relationship\":\"Friend\",\r\n \"observation\":\"Toxic\"\r\n }\r\n ],\r\n \"authoredOn\":\"2024-05-06T06:33:37.361Z\",\r\n \"medications\":[\r\n {\r\n \"medicine\":\"Aspirin 75 mg oral tablet\",\r\n \"dosage\":\"1-0-1\",\r\n \"timing\":\"2-5-D\",\r\n \"route\":\"Oral\",\r\n \"method\":\"swallow\",\r\n \"additionalInstructions\":\"Take them after food\"\r\n }\r\n ,{\r\n \"medicine\":\"Disprin\",\r\n \"dosage\":\"0-0-1\",\r\n \"timing\":\"1-2-D\",\r\n \"route\":\"Syrup\",\r\n \"method\":\"drink\",\r\n \"additionalInstructions\":\"Take them before food\"\r\n }\r\n ],\r\n \"diagnostics\":[{\r\n \"serviceName\":\"BloodTest\",\r\n \"serviceCategory\":\"Hematography\",\r\n \"result\":[{\r\n \"observation\":\"Height\",\r\n \"result\":\"Normal\",\r\n \"valueQuantity\": {\r\n\t\t\t\t\t\"unit\": \"CM\",\r\n\t\t\t\t\t\"value\": 170\r\n\t\t\t}\r\n }],\r\n \"authoredOn\":\"2024-05-08T06:33:37.361Z\",\r\n \"conclusion\":\"Normal\",\r\n \"presentedForm\":{\r\n \"contentType\":\"application/pdf\",\r\n \"data\":\"JVBERi0xLjMKJf////8K\"\r\n }\r\n }],\r\n \"procedures\":[\r\n {\r\n \"date\":\"2001-04-20\",\r\n \"status\":\"INPROGRESS\",\r\n \"procedureReason\":\"Severe\",\r\n \"outcome\":\"Healthy\",\r\n \"procedureName\":\"Operation\"\r\n }\r\n ],\r\n \"documents\":[{\r\n \"type\":\"OP record\",\r\n \"contentType\":\"application/pdf\",\r\n \"data\":\"JVBERi0xLjMKJf////8K\"\r\n }]\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "localhost:8085/v1/bundle/discharge-summary", - "host": [ - "localhost" - ], - "port": "8085", - "path": [ - "v1", - "bundle", - "discharge-summary" - ] - } - }, - "response": [] - }, - { - "name": "Get SnomedCodes", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "localhost:8085/v1/snomed/Medications", - "host": [ - "localhost" - ], - "port": "8085", - "path": [ - "v1", - "snomed", - "Medications" - ] - } - }, - "response": [] - } - ] -} \ No newline at end of file diff --git a/fhir-mapper/settings.gradle b/fhir-mapper/settings.gradle deleted file mode 100644 index b62de251..00000000 --- a/fhir-mapper/settings.gradle +++ /dev/null @@ -1,2 +0,0 @@ -rootProject.name = 'fhir-mapper' - diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/FHIRApplication.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/FHIRApplication.java deleted file mode 100644 index 01471ea0..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/FHIRApplication.java +++ /dev/null @@ -1,12 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -public class FHIRApplication { - public static void main(String[] args) { - SpringApplication.run(FHIRApplication.class, args); - } -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/Utils.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/Utils.java deleted file mode 100644 index a9d679c4..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/Utils.java +++ /dev/null @@ -1,40 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper; - -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Date; -import org.hl7.fhir.r4.model.DateTimeType; -import org.hl7.fhir.r4.model.InstantType; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; - -@Component -public class Utils { - private static final SimpleDateFormat ISO_DATE_TIME_FORMAT = - new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX"); - private static final SimpleDateFormat DATE_ONLY_FORMAT = new SimpleDateFormat("yyyy-MM-dd"); - private static final Logger log = LoggerFactory.getLogger(Utils.class); - - public static InstantType getCurrentTimeStamp() throws ParseException { - InstantType instantType = new InstantType(); - instantType.setToCurrentTimeInLocalTimeZone(); - return (InstantType) InstantType.withCurrentTime().setTimeZoneZulu(true); - } - - public static DateTimeType getFormattedDateTime(String dateTimeString) throws ParseException { - dateTimeString = dateTimeString.trim(); - if (dateTimeString.length() <= 10) { - return new DateTimeType(dateTimeString); - } else { - return (DateTimeType) - new DateTimeType(ISO_DATE_TIME_FORMAT.parse(dateTimeString)).setTimeZoneZulu(true); - } - } - - public static Date getFormattedDate(String dateTimeString) throws ParseException { - dateTimeString = dateTimeString.trim(); - return new DateTimeType(dateTimeString).getValue(); - } -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/BundleCompositionIdentifier.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/BundleCompositionIdentifier.java deleted file mode 100644 index aa426e44..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/BundleCompositionIdentifier.java +++ /dev/null @@ -1,72 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.common.constants; - -public class BundleCompositionIdentifier { - // DISCHARGE SUMMARY - public static final String DISCHARGE_SUMMARY_CODE = "373942005"; - public static final String DISCHARGE_SUMMARY = "Discharge summary"; - public static final String INVESTIGATION_ADVICE = "Discharge summary"; - public static final String CHIEF_COMPLAINTS = "Chief complaint section"; - public static final String CHIEF_COMPLAINTS_CODE = "422843007"; - public static final String PHYSICAL_EXAMINATION_CODE = "425044008"; - public static final String PHYSICAL_EXAMINATION = "Physical exam section"; - public static final String ALLERGY_RECORD = "Allergy record"; - public static final String ALLERGY_RECORD_CODE = "722446000"; - public static final String PAST_MEDICAL_HISTORY = "Past medical history section"; - public static final String PAST_MEDICAL_CODE = "1003642006"; - public static final String FAMILY_HISTORY_SECTION = "Family history section"; - public static final String FAMILY_HISTORY_SECTION_CODE = "422432008"; - public static final String DIAGNOSTIC_STUDIES_REPORT = "Diagnostic studies report"; - public static final String DIAGNOSTIC_STUDIES_REPORT_CODE = "721981007"; - public static final String MEDICAL_HISTORY_SECTION = "Medication history section"; - public static final String MEDICAL_HISTORY_SECTION_CODE = "1003606003"; - public static final String HISTORY_PAST_PROCEDURE = "History of past procedure section"; - public static final String HISTORY_PAST_PROCEDURE_CODE = "1003640003"; - public static final String CARE_PLAN = "Care plan"; - public static final String CARE_PLAN_CODE = "734163000"; - - // HEALTH DOCUMENT RECORD - public static final String RECORD_ARTIFACT = "Record artifact"; - public static final String RECORD_ARTIFACT_CODE = "419891008"; - public static final String HEALTH_DOCUMENT = "Health Document"; - public static final String HEALTH_DOCUMENT_CODE = "423876004"; - - // IMMUNIZATION RECORD - public static final String IMMUNIZATION_RECORD = "Immunization record"; - public static final String IMMUNIZATION_RECORD_CODE = "41000179103"; - - // OP CONSULTATION - public static final String OP_CONSULTATION = "Clinical consultation report"; - public static final String OP_CONSULTATION_CODE = "371530004"; - public static final String HISTORY_PHYSICAL_REPORT = "History and physical report"; - public static final String HISTORY_PHYSICAL_REPORT_CODE = "371529009"; - public static final String ORDER_DOCUMENT = "Order document"; - public static final String ORDER_DOCUMENT_CODE = "721963009"; - public static final String MEDICATION_SUMMARY = "Medication summary document"; - public static final String MEDICATION_SUMMARY_CODE = "721912009"; - public static final String FOLLOW_UP = "Follow-up encounter"; - public static final String FOLLOW_UP_CODE = "390906007"; - public static final String CLINICAL_PROCEDURE = "Clinical procedure report"; - public static final String CLINICAL_PROCEDURE_CODE = "371525003"; - public static final String REFERRAL_TO_SERVICE = "Referral to service"; - public static final String REFERRAL_TO_SERVICE_CODE = "306206005"; - public static final String CLINICAL_FINDING = "Clinical finding"; - public static final String CLINICAL_FINDING_CODE = "404684003"; - public static final String CLINICAL_CONSULTATION_REPORT = "Clinical consultation report"; - public static final String CLINICAL_CONSULTATION_REPORT_CODE = "371530004"; - - // PRESCRIPTION RECORD - public static final String PRESCRIPTION = "Prescription record"; - public static final String PRESCRIPTION_CODE = "440545006"; - - // WELLNESS RECORD - public static final String WELLNESS_RECORD = "Wellness Record"; - public static final String OTHER_OBSERVATIONS = "Other Observations"; - public static final String LIFE_STYLE = "Lifestyle"; - public static final String WOMEN_HEALTH = "Women Health"; - public static final String GENERAL_ASSESSMENT = "General Assessment"; - public static final String PHYSICAL_ACTIVITY = "Physical Activity"; - public static final String BODY_MEASUREMENT = "Body Measurement"; - public static final String VITAL_SIGNS = "Vital Signs"; - public static final String DOCUMENT_REFERENCE = "Document Reference"; -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/BundleFieldIdentifier.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/BundleFieldIdentifier.java deleted file mode 100644 index b8f01958..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/BundleFieldIdentifier.java +++ /dev/null @@ -1,20 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.common.constants; - -public class BundleFieldIdentifier { - public static final String ALLERGY = "Allergy"; - public static final String ACTIVE = "Active"; - public static final String VERY_RESTRICTED = "very restricted"; - public static final String AMBULATORY = "Ambulatory"; - public static final String MEDICAL_RECORD_NUMBER = "Medical record number"; - public static final String LIFE_STYLE = "lifeStyle"; - public static final String WOMAN_HEALTH = "womanHealth"; - public static final String GENERAL_ASSESSMENT = "generalAssessment"; - public static final String PHYSICAL_ACTIVITY = "physicalActivity"; - public static final String BODY_MEASUREMENT = "bodyMeasurement"; - public static final String VITAL_SIGNS = "vitalSigns"; - public static final String SYSTEM = "system"; - public static final String CODE = "code"; - public static final String DISPLAY = "display"; - public static final String MEDICAL_CONDITION = "MedicalCondition"; -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/BundleIdentifier.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/BundleIdentifier.java deleted file mode 100644 index 67718d51..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/BundleIdentifier.java +++ /dev/null @@ -1,12 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.common.constants; - -public class BundleIdentifier { - public static final String WELLNESS_RECORD = "WellnessRecord"; - public static final String DISCHARGE_SUMMARY_RECORD = "DischargeSummaryRecord"; - public static final String DIAGNOSTIC_REPORT = "DiagnosticReportRecord"; - public static final String HEALTH_DOCUMENT = "HealthDocumentRecord"; - public static final String OP_CONSULTATION = "OPConsultRecord"; - public static final String PRESCRIPTION_RECORD = "PrescriptionRecord"; - public static final String IMMUNIZATION_RECORD = "ImmunizationRecord"; -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/BundleResourceIdentifier.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/BundleResourceIdentifier.java deleted file mode 100644 index e1c012b9..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/BundleResourceIdentifier.java +++ /dev/null @@ -1,36 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.common.constants; - -public class BundleResourceIdentifier { - public static final String PATIENT = "Patient"; - public static final String PRACTITIONER = "Practitioner"; - public static final String ORGANISATION = "Organisation"; - public static final String ENCOUNTER = "Encounter"; - public static final String OBSERVATION = "Observation"; - public static final String CONDITION = "Condition"; - public static final String COMPOSITION = "Composition"; - public static final String MEDICATION_REQUEST = "MedicationRequest"; - public static final String BINARY = "Binary"; - public static final String ALLERGY_INTOLERANCE = "AllergyIntolerance"; - public static final String MANUFACTURER = "Manufacturer"; - public static final String DOCUMENT_REFERENCE = "DocumentReference"; - public static final String DIAGNOSTIC_REPORT = "DiagnosticReport"; - public static final String CHIEF_COMPLAINTS = "ChiefComplaints"; - public static final String PHYSICAL_EXAMINATION = "PhysicalExamination"; - public static final String PROCEDURE = "Procedure"; - public static final String FAMILY_HISTORY = "FamilyHistory"; - public static final String MEDICAL_HISTORY = "MedicalHistory"; - public static final String IMMUNIZATION = "Immunization"; - public static final String OTHER_OBSERVATIONS = "OtherObservations"; - public static final String REFERRAL = "Referral"; - public static final String FOLLOW_UP = "FollowUp"; - public static final String INVESTIGATION_ADVICE = "InvestigationAdvice"; - public static final String LIFE_STYLE = "LifeStyle"; - public static final String WOMAN_HEALTH = "WomanHealth"; - public static final String GENERAL_ASSESSMENT = "GeneralAssessment"; - public static final String PHYSICAL_ACTIVITY = "PhysicalActivity"; - public static final String BODY_MEASUREMENT = "BodyMeasurement"; - public static final String VITAL_SIGNS = "VitalSigns"; - public static final String MEDICATIONS = "Medications"; - public static final String CARE_PLAN = "CarePlan"; -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/BundleUrlIdentifier.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/BundleUrlIdentifier.java deleted file mode 100644 index 5db65fe1..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/BundleUrlIdentifier.java +++ /dev/null @@ -1,11 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.common.constants; - -public class BundleUrlIdentifier { - public static final String WRAPPER_URL = "https://ABDM_WRAPPER/bundle"; - public static final String SNOMED_URL = "http://snomed.info/sct"; - public static final String LOINC_URL = "http://loinc.org"; - public static final String FACILITY_URL = "https://facility.abdm.gov.in"; - public static final String HEALTH_ID_URL = "https://healthid.abdm.gov.in"; - public static final String DOCTOR_ID_URL = "https://doctor.abdm.gov.in"; -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/ErrorCode.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/ErrorCode.java deleted file mode 100644 index 7d9e1296..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/ErrorCode.java +++ /dev/null @@ -1,10 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.common.constants; - -public class ErrorCode { - public static String VALIDATION_ERROR = "1001"; - public static String PARSE_ERROR = "1002"; - public static String INCORRECT_BUNDLE_TYPE = "1003"; - public static String DB_SYNTAX_ERROR = "1004"; - public static String DB_ERROR = "1005"; -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/ResourceProfileIdentifier.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/ResourceProfileIdentifier.java deleted file mode 100644 index d8eae526..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/ResourceProfileIdentifier.java +++ /dev/null @@ -1,50 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.common.constants; - -public class ResourceProfileIdentifier { - public static final String PROFILE_BINARY = - "https://nrces.in/ndhm/fhir/r4/StructureDefinition/Binary"; - public static final String PROFILE_ALLERGY_INTOLERANCE = - "https://nrces.in/ndhm/fhir/r4/StructureDefinition/AllergyIntolerance"; - public static final String PROFILE_ALLERGY_INTOLERANCE_SYSTEM = - "http://terminology.hl7.org/CodeSystem/allergyintolerance-clinical"; - public static final String PROFILE_DOCUMENT_BUNDLE = - "https://nrces.in/ndhm/fhir/r4/StructureDefinition/DocumentBundle"; - public static final String PROFILE_BUNDLE_META = - "http://terminology.hl7.org/CodeSystem/v3-Confidentiality"; - public static final String PROFILE_CONDITION = - "https://nrces.in/ndhm/fhir/r4/StructureDefinition/Condition"; - public static final String PROFILE_DIAGNOSTIC_REPORT_LAB = - "https://nrces.in/ndhm/fhir/r4/StructureDefinition/DiagnosticReportLab"; - public static final String PROFILE_DOCUMENT_REFERENCE = - "https://nrces.in/ndhm/fhir/r4/StructureDefinition/DocumentReference"; - public static final String PROFILE_ENCOUNTER = - "https://nrces.in/ndhm/fhir/r4/StructureDefinition/Encounter"; - public static final String PROFILE_FAMILY_MEMBER_HISTORY = - "https://nrces.in/ndhm/fhir/r4/StructureDefinition/FamilyMemberHistory"; - public static final String PROFILE_IMMUNIZATION = - "https://nrces.in/ndhm/fhir/r4/StructureDefinition/Immunization"; - public static final String PROFILE_VACCINE_BRAND_NAME = - "https://nrces.in/ndhm/fhir/r4/StructureDefinition/BrandName"; - public static final String PROFILE_MEDICATION_REQUEST = - "https://nrces.in/ndhm/fhir/r4/StructureDefinition/MedicationRequest"; - public static final String PROFILE_OBSERVATION = - "https://nrces.in/ndhm/fhir/r4/StructureDefinition/Observation"; - public static final String PROFILE_PROVIDER = "http://terminology.hl7.org/CodeSystem/v2-0203"; - public static final String PROFILE_ORGANISATION = - "https://nrces.in/ndhm/fhir/r4/StructureDefinition/Organization"; - public static final String PROFILE_PATIENT = - "https://nrces.in/ndhm/fhir/r4/StructureDefinition/Patient"; - public static final String PROFILE_PRACTITIONER = - "https://nrces.in/ndhm/fhir/r4/StructureDefinition/Practitioner"; - public static final String PROFILE_PROCEDURE = - "https://nrces.in/ndhm/fhir/r4/StructureDefinition/Procedure"; - public static final String PROFILE_SERVICE_REQUEST = - "https://nrces.in/ndhm/fhir/r4/StructureDefinition/ServiceRequest"; - public static final String PROFILE_DIAGNOSTIC_REPORT = - "https://nrces.in/ndhm/fhir/r4/StructureDefinition/DiagnosticReportRecord"; - public static final String PROFILE_HEALTH_DOCUMENT_RECORD = - "https://nrces.in/ndhm/fhir/r4/StructureDefinition/HealthDocumentRecord"; - public static final String PROFILE_PRESCRIPTION_RECORD = - "https://nrces.in/ndhm/fhir/r4/StructureDefinition/PrescriptionRecord"; -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/SnomedCodeIdentifier.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/SnomedCodeIdentifier.java deleted file mode 100644 index 7a28e61f..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/SnomedCodeIdentifier.java +++ /dev/null @@ -1,32 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.common.constants; - -import java.util.*; - -public class SnomedCodeIdentifier { - public static final String SNOMED_ALLERGY_INTOLERANCE = "609328004"; - public static final String SNOMED_DIAGNOSTIC_LAB = "261665006"; - public static final String SNOMED_UNKNOWN = "261665006"; - public static final String LOINC_UNKNOWN = "LL3865-4"; - public static final String SNOMED_MEDICATIONS = "Medications"; - public static final String SNOMED_DIAGNOSTICS = "Diagnostics"; - public static final String SNOMED_VACCINES = "Vaccines"; - public static final String SNOMED_OBSERVATIONS = "Observations"; - public static final String SNOMED_SPECIMEN = "Specimen"; - public static final String SNOMED_CONDITION = "Condition"; - public static final String SNOMED_PROCEDURE = "Procedure"; - public static final String SNOMED_MEDICATION_ROUTE = "Medication-Route"; - public static final String SNOMED_ENCOUNTER_AMBULATORY = "AMB"; - public static final String SNOMED_ENCOUNTER = "Encounter"; - public static final String CATEGORY = "Category"; - public static final List availableSnomed = - Arrays.asList( - SNOMED_CONDITION, - SNOMED_PROCEDURE, - SNOMED_ENCOUNTER, - SNOMED_MEDICATION_ROUTE, - SNOMED_MEDICATIONS, - SNOMED_OBSERVATIONS, - SNOMED_SPECIMEN, - SNOMED_VACCINES); -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/WellnessFieldIdentifiers.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/WellnessFieldIdentifiers.java deleted file mode 100644 index 134cd630..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/WellnessFieldIdentifiers.java +++ /dev/null @@ -1,119 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.common.constants; - -import java.util.HashMap; -import java.util.Map; - -public class WellnessFieldIdentifiers { - private static final HashMap vitalSigns = new HashMap<>(); - private static final HashMap bodyMeasurement = new HashMap<>(); - private static final HashMap physicalActivity = new HashMap<>(); - private static final HashMap generalAssessment = new HashMap<>(); - private static final HashMap womanHealth = new HashMap<>(); - private static final HashMap lifeStyle = new HashMap<>(); - - private static final Map> categoryMap = new HashMap<>(); - - static { - categoryMap.put(BundleFieldIdentifier.VITAL_SIGNS, vitalSigns); - categoryMap.put(BundleFieldIdentifier.BODY_MEASUREMENT, bodyMeasurement); - categoryMap.put(BundleFieldIdentifier.PHYSICAL_ACTIVITY, physicalActivity); - categoryMap.put(BundleFieldIdentifier.GENERAL_ASSESSMENT, generalAssessment); - categoryMap.put(BundleFieldIdentifier.WOMAN_HEALTH, womanHealth); - categoryMap.put(BundleFieldIdentifier.LIFE_STYLE, lifeStyle); - // VitalSigns - HashMap vitals = new HashMap<>(); - vitalSigns.put("system", BundleUrlIdentifier.LOINC_URL); - vitals.put("Body surface temperature", "61008-9"); - vitals.put("Respiratory rate", "9279-1"); - vitals.put("Heart rate", "8867-4"); - vitals.put("Oxygen saturation in Arterial blood", "2708-6"); - vitals.put("Blood pressure panel with all children optional", "85354-9"); - vitalSigns.putAll(vitals); - - // Body Measurement - HashMap measurement = new HashMap<>(); - measurement.put("system", BundleUrlIdentifier.LOINC_URL); - measurement.put("Body mass index (BMI) [Ratio]", "39156-5"); - measurement.put("Body weight", "29463-7"); - measurement.put("Body height", "8302-2"); - measurement.put("Circumference Neck", "56074-8"); - measurement.put("Waist Circumference at umbilicus by Tape measure", "8280-0"); - measurement.put("Circumference Mid upper arm - right", "56072-2"); - bodyMeasurement.putAll(measurement); - - // Physical Activity - HashMap pActivity = new HashMap<>(); - pActivity.put("system", BundleUrlIdentifier.LOINC_URL); - pActivity.put("Number of steps in unspecified time Pedometer", "55423-8"); - pActivity.put("Sleep duration", "93832-4"); - pActivity.put("Calories burned", "41981-2"); - pActivity.put("Activity level [Acceleration]", "80493-0"); - physicalActivity.putAll(pActivity); - - // General Assessment - HashMap assessment = new HashMap<>(); - assessment.put("system", BundleUrlIdentifier.LOINC_URL); - assessment.put("Glucose [Mass/volume] in Blood", "2339-0"); - assessment.put("Fasting glucose [Mass/volume] in Capillary blood by Glucometer", "41604-0"); - assessment.put("Glucose [Moles/volume] in Capillary blood by Glucometer", "14743-9"); - assessment.put("Glucose [Moles/volume] in Capillary blood --2 hours post meal", "14760-3"); - assessment.put("Body fat [Mass] Calculated", "73708-0"); - assessment.put("12 lead EKG panel", "34534-8"); - assessment.put("Fluid intake oral Estimated", "8999-5"); - assessment.put("Calorie intake total", "9052-2"); - assessment.put("Metabolic rate --resting", "69429-9"); - assessment.put( - "Oxygen consumption (VO2)/Body weight [Volume Rate Content] --peak during exercise", - "94122-9"); - assessment.put("Mental status", "8693-4"); - generalAssessment.putAll(assessment); - - // Woman Health - HashMap wHealth = new HashMap<>(); - wHealth.put("system", BundleUrlIdentifier.LOINC_URL); - wHealth.put("Ovulation date", "11976-8"); - wHealth.put("Number of menstrual periods per year", "92656-8"); - wHealth.put("Age at menarche", "42798-9"); - wHealth.put("Age at menopause", "42802-9"); - wHealth.put("Last menstrual period start date", "8665-2"); - womanHealth.putAll(wHealth); - - // LifeStyle - HashMap observationLifeStyle = new HashMap<>(); - observationLifeStyle.put("system", BundleUrlIdentifier.SNOMED_URL); - observationLifeStyle.put("Finding relating to alcohol drinking behavior", "228273003"); - observationLifeStyle.put("Tobacco smoking behavior - finding", "365981007"); - observationLifeStyle.put("Finding relating to tobacco chewing", "228509002"); - observationLifeStyle.put("Diet", "41829006"); - lifeStyle.putAll(observationLifeStyle); - } - - public static String getVitals(String type) { - return vitalSigns.get(type) != null ? vitalSigns.get(type) : "LL3865-4"; - } - - public static String getBodyMeasurement(String type) { - return bodyMeasurement.get(type) != null ? bodyMeasurement.get(type) : "LL3865-4"; - } - - public static String getPhysicalActivity(String type) { - return physicalActivity.get(type) != null ? physicalActivity.get(type) : "LL3865-4"; - } - - public static String getGeneralAssessment(String type) { - return generalAssessment.get(type) != null ? generalAssessment.get(type) : "LL3865-4"; - } - - public static String getWomanHealth(String type) { - return womanHealth.get(type) != null ? womanHealth.get(type) : "LL3865-4"; - } - - public static String getLifeStyle(String type) { - return lifeStyle.get(type) != null ? lifeStyle.get(type) : "261665006"; - } - - public static String getSystem(String type) { - return categoryMap.get(type).get(BundleFieldIdentifier.SYSTEM); - } -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/BundleResponse.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/BundleResponse.java deleted file mode 100644 index cd511512..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/BundleResponse.java +++ /dev/null @@ -1,17 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.common.helpers; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.hl7.fhir.r4.model.Bundle; - -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class BundleResponse { - private ErrorResponse error; - private Bundle bundle; -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/DateRange.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/DateRange.java deleted file mode 100644 index cac6a968..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/DateRange.java +++ /dev/null @@ -1,16 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.common.helpers; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class DateRange { - private String from; - private String to; -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/DocumentResource.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/DocumentResource.java deleted file mode 100644 index 88f03ae5..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/DocumentResource.java +++ /dev/null @@ -1,23 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.common.helpers; - -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@NoArgsConstructor -@AllArgsConstructor -@Data -@Builder -public class DocumentResource { - @NotBlank(message = "contentType is mandatory") - private String contentType; - - @NotBlank(message = "type is mandatory") - private String type; - - @NotNull(message = "data is mandatory") private byte[] data; -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/ErrorResponse.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/ErrorResponse.java deleted file mode 100644 index da6c07ef..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/ErrorResponse.java +++ /dev/null @@ -1,16 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.common.helpers; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class ErrorResponse { - public String code; - public String message; -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/FacadeError.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/FacadeError.java deleted file mode 100644 index 24f61797..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/FacadeError.java +++ /dev/null @@ -1,19 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.common.helpers; - -import com.fasterxml.jackson.annotation.JsonInclude; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -@JsonInclude(JsonInclude.Include.NON_NULL) -public class FacadeError { - private String description; - private ErrorResponse error; - private ValidationErrorResponse validationErrors; -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/FieldErrorsResponse.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/FieldErrorsResponse.java deleted file mode 100644 index 203126ac..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/FieldErrorsResponse.java +++ /dev/null @@ -1,16 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.common.helpers; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class FieldErrorsResponse { - private String field; - private String message; -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/OrganisationResource.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/OrganisationResource.java deleted file mode 100644 index b2b78b54..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/OrganisationResource.java +++ /dev/null @@ -1,18 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.common.helpers; - -import com.nha.abdm.fhir.mapper.rest.exceptions.NotBlankFields; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@NoArgsConstructor -@AllArgsConstructor -@Data -@Builder -@NotBlankFields -public class OrganisationResource { - private String facilityName; - private String facilityId; -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/PatientResource.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/PatientResource.java deleted file mode 100644 index a446eae3..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/PatientResource.java +++ /dev/null @@ -1,31 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.common.helpers; - -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.Pattern; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@NoArgsConstructor -@AllArgsConstructor -@Data -@Builder -public class PatientResource { - @NotBlank(message = "name of the patient is mandatory") - private String name; - - @NotBlank(message = "patientReference of the patient is mandatory") - private String patientReference; - - @Pattern( - regexp = "^(?i)(male|female|other|unknown)$", - message = "gender must be male, female, other, unknown") - private String gender; - - @Pattern( - regexp = "^\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])$", - message = "birthDate must be in format YYYY-MM-DD.") - private String birthDate; -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/PractitionerResource.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/PractitionerResource.java deleted file mode 100644 index b57440cb..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/PractitionerResource.java +++ /dev/null @@ -1,19 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.common.helpers; - -import jakarta.validation.constraints.NotBlank; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@NoArgsConstructor -@AllArgsConstructor -@Data -@Builder -public class PractitionerResource { - @NotBlank(message = "Name of the practitioner is mandatory") - private String name; - - private String practitionerId; -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/SnomedResponse.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/SnomedResponse.java deleted file mode 100644 index ae8c941e..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/SnomedResponse.java +++ /dev/null @@ -1,28 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.common.helpers; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.nha.abdm.fhir.mapper.rest.database.h2.tables.*; -import java.util.List; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -@JsonInclude(JsonInclude.Include.NON_NULL) -public class SnomedResponse { - public String message; - public List snomedConditionProcedureCodes; - public List snomedDiagnosticCodes; - public List snomedEncounterCodes; - public List snomedMedicineRouteCodes; - public List snomedMedicineCodes; - public List snomedObservationCodes; - public List snomedSpecimenCodes; - public List snomedVaccineCodes; - public List availableSnomed; -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/ValidationErrorResponse.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/ValidationErrorResponse.java deleted file mode 100644 index d5f81057..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/ValidationErrorResponse.java +++ /dev/null @@ -1,18 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.common.helpers; - -import java.util.ArrayList; -import java.util.List; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class ValidationErrorResponse { - public String code; - @Builder.Default private List error = new ArrayList<>(); -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/controller/BundleController.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/controller/BundleController.java deleted file mode 100644 index f6b36a2a..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/controller/BundleController.java +++ /dev/null @@ -1,181 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.controller; - -import ca.uhn.fhir.context.FhirContext; -import com.nha.abdm.fhir.mapper.rest.common.helpers.BundleResponse; -import com.nha.abdm.fhir.mapper.rest.common.helpers.FacadeError; -import com.nha.abdm.fhir.mapper.rest.converter.*; -import com.nha.abdm.fhir.mapper.rest.database.h2.services.SnomedService; -import com.nha.abdm.fhir.mapper.rest.requests.*; -import jakarta.validation.Valid; -import java.text.ParseException; -import java.util.Objects; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -@RestController -@RequestMapping(path = "/v1/bundle") -@Validated -public class BundleController { - @Autowired ImmunizationConverter immunizationConverter; - @Autowired PrescriptionConverter prescriptionConverter; - @Autowired HealthDocumentConverter healthDocumentConverter; - @Autowired OPConsultationConverter opConsultationConverter; - @Autowired DiagnosticReportConverter diagnosticReportConverter; - @Autowired DischargeSummaryConverter dischargeSummaryConverter; - @Autowired WellnessRecordConverter wellnessRecordConverter; - @Autowired SnomedService snomedService; - FhirContext ctx = FhirContext.forR4(); - - /** - * @param immunizationRequest which has immunization details like vaccine and type of vaccine - * @return FHIR bundle if no error found - * @throws ParseException while parsing the string into date - */ - @PostMapping("/immunization") - public Object createImmunizationBundle( - @Valid @RequestBody ImmunizationRequest immunizationRequest) throws ParseException { - - BundleResponse bundleResponse = - immunizationConverter.makeImmunizationBundle(immunizationRequest); - - if (Objects.nonNull(bundleResponse.getError())) - return ResponseEntity.badRequest() - .contentType(MediaType.APPLICATION_JSON) - .body(FacadeError.builder().error(bundleResponse.getError()).build()); - return ResponseEntity.status(HttpStatus.CREATED) - .contentType(MediaType.APPLICATION_JSON) - .body(ctx.newJsonParser().encodeResourceToString(bundleResponse.getBundle())); - } - - /** - * @param prescriptionRequest which has prescription details like medicine and dosage - * @return FHIR bundle if no error found - * @throws ParseException while parsing the string into date - */ - @PostMapping("/prescription") - public ResponseEntity createPrescriptionBundle( - @Valid @RequestBody PrescriptionRequest prescriptionRequest) throws ParseException { - - BundleResponse bundleResponse = - prescriptionConverter.convertToPrescriptionBundle(prescriptionRequest); - - if (Objects.nonNull(bundleResponse.getError())) - return ResponseEntity.badRequest() - .contentType(MediaType.APPLICATION_JSON) - .body(FacadeError.builder().error(bundleResponse.getError()).build()); - return ResponseEntity.status(HttpStatus.CREATED) - .contentType(MediaType.APPLICATION_JSON) - .body(ctx.newJsonParser().encodeResourceToString(bundleResponse.getBundle())); - } - - /** - * @param opConsultationRequest which has all basic details of the visit - * @return FHIR bundle if no error found - * @throws ParseException while parsing the string into date - */ - @PostMapping("/op-consultation") - public ResponseEntity createOPConsultationBundle( - @Valid @RequestBody OPConsultationRequest opConsultationRequest) throws ParseException { - - BundleResponse bundleResponse = - opConsultationConverter.convertToOPConsultationBundle(opConsultationRequest); - - if (Objects.nonNull(bundleResponse.getError())) - return ResponseEntity.badRequest() - .contentType(MediaType.APPLICATION_JSON) - .body(FacadeError.builder().error(bundleResponse.getError()).build()); - return ResponseEntity.status(HttpStatus.CREATED) - .contentType(MediaType.APPLICATION_JSON) - .body(ctx.newJsonParser().encodeResourceToString(bundleResponse.getBundle())); - } - - /** - * @param healthDocumentRecord which has document as an attachment - * @return FHIR bundle if no error found - * @throws ParseException while parsing the string into date - */ - @PostMapping("/health-document") - public ResponseEntity createHealthDocumentBundle( - @Valid @RequestBody HealthDocumentRecord healthDocumentRecord) throws ParseException { - - BundleResponse bundleResponse = - healthDocumentConverter.convertToHealthDocumentBundle(healthDocumentRecord); - - if (Objects.nonNull(bundleResponse.getError())) - return ResponseEntity.badRequest() - .contentType(MediaType.APPLICATION_JSON) - .body(FacadeError.builder().error(bundleResponse.getError()).build()); - return ResponseEntity.status(HttpStatus.CREATED) - .contentType(MediaType.APPLICATION_JSON) - .body(ctx.newJsonParser().encodeResourceToString(bundleResponse.getBundle())); - } - - /** - * @param diagnosticReportRequest which has diagnostic details like the result and type of - * diagnosis - * @return FHIR bundle if no error found - * @throws ParseException while parsing the string into date - */ - @PostMapping(value = "/diagnostic-report") - public ResponseEntity createDiagnosticReportBundle( - @Valid @RequestBody DiagnosticReportRequest diagnosticReportRequest) throws ParseException { - - BundleResponse bundleResponse = - diagnosticReportConverter.convertToDiagnosticBundle(diagnosticReportRequest); - - if (Objects.nonNull(bundleResponse.getError())) - return ResponseEntity.badRequest() - .contentType(MediaType.APPLICATION_JSON) - .body(FacadeError.builder().error(bundleResponse.getError()).build()); - return ResponseEntity.status(HttpStatus.CREATED) - .contentType(MediaType.APPLICATION_JSON) - .body(ctx.newJsonParser().encodeResourceToString(bundleResponse.getBundle())); - } - - /** - * @param dischargeSummaryRequest which has discharge details like the findings and observations - * @return FHIR bundle if no error found - * @throws ParseException while parsing the string into date - */ - @PostMapping("/discharge-summary") - public ResponseEntity createDischargeSummaryBundle( - @Valid @RequestBody DischargeSummaryRequest dischargeSummaryRequest) throws ParseException { - - BundleResponse bundleResponse = - dischargeSummaryConverter.convertToDischargeSummary(dischargeSummaryRequest); - - if (Objects.nonNull(bundleResponse.getError())) - return ResponseEntity.badRequest() - .contentType(MediaType.APPLICATION_JSON) - .body(FacadeError.builder().error(bundleResponse.getError()).build()); - return ResponseEntity.status(HttpStatus.CREATED) - .contentType(MediaType.APPLICATION_JSON) - .body(ctx.newJsonParser().encodeResourceToString(bundleResponse.getBundle())); - } - - /** - * @param wellnessRecordRequest which has all the physical observations - * @return FHIR bundle if no error found - * @throws ParseException while parsing the string into date - */ - @PostMapping("/wellness-record") - public ResponseEntity createWellnessBundle( - @Valid @RequestBody WellnessRecordRequest wellnessRecordRequest) { - - BundleResponse bundleResponse = - wellnessRecordConverter.getWellnessBundle(wellnessRecordRequest); - - if (Objects.nonNull(bundleResponse.getError())) - return ResponseEntity.badRequest() - .contentType(MediaType.APPLICATION_JSON) - .body(FacadeError.builder().error(bundleResponse.getError()).build()); - return ResponseEntity.status(HttpStatus.CREATED) - .contentType(MediaType.APPLICATION_JSON) - .body(ctx.newJsonParser().encodeResourceToString(bundleResponse.getBundle())); - } -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/controller/SnomedController.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/controller/SnomedController.java deleted file mode 100644 index 9f24eaf3..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/controller/SnomedController.java +++ /dev/null @@ -1,45 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.controller; - -import com.nha.abdm.fhir.mapper.rest.common.constants.SnomedCodeIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.helpers.SnomedResponse; -import com.nha.abdm.fhir.mapper.rest.database.h2.services.SnomedService; -import java.util.Objects; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -@RequestMapping(path = "/v1/snomed") -public class SnomedController { - @Autowired SnomedService snomedService; - - /** - * Returns all the available snomed codes - * - * @param resource - * @return - */ - @GetMapping({"/{resource}"}) - public ResponseEntity getSnomedCodes(@PathVariable("resource") String resource) { - if (SnomedCodeIdentifier.availableSnomed.contains(resource)) { - SnomedResponse snomedResponse = snomedService.getSnomedCodes(resource); - if (Objects.nonNull(snomedResponse)) { - snomedResponse.setMessage("Retrieved"); - return ResponseEntity.ok().body(snomedResponse); - } else { - snomedResponse.setMessage("Empty Codes"); - return ResponseEntity.badRequest().body(snomedResponse); - } - } else - return ResponseEntity.badRequest() - .body( - SnomedResponse.builder() - .message("Invalid Resource") - .availableSnomed(SnomedCodeIdentifier.availableSnomed) - .build()); - } -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/DiagnosticReportConverter.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/DiagnosticReportConverter.java deleted file mode 100644 index 42a7a08a..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/DiagnosticReportConverter.java +++ /dev/null @@ -1,211 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.converter; - -import com.nha.abdm.fhir.mapper.Utils; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleCompositionIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.ErrorCode; -import com.nha.abdm.fhir.mapper.rest.common.helpers.BundleResponse; -import com.nha.abdm.fhir.mapper.rest.common.helpers.ErrorResponse; -import com.nha.abdm.fhir.mapper.rest.dto.compositions.MakeDiagnosticComposition; -import com.nha.abdm.fhir.mapper.rest.dto.resources.*; -import com.nha.abdm.fhir.mapper.rest.exceptions.StreamUtils; -import com.nha.abdm.fhir.mapper.rest.requests.DiagnosticReportRequest; -import java.text.ParseException; -import java.util.*; -import org.hl7.fhir.r4.model.*; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.dao.InvalidDataAccessResourceUsageException; -import org.springframework.stereotype.Service; - -@Service -public class DiagnosticReportConverter { - private static final Logger log = LoggerFactory.getLogger(DiagnosticReportConverter.class); - private final MakeOrganisationResource makeOrganisationResource; - private final MakeBundleMetaResource makeBundleMetaResource; - - private final MakePatientResource makePatientResource; - - private final MakePractitionerResource makePractitionerResource; - private final MakeDocumentResource makeDocumentResource; - private final MakeObservationResource makeObservationResource; - private final MakeDiagnosticLabResource makeDiagnosticLabResource; - private final MakeEncounterResource makeEncounterResource; - private final MakeDiagnosticComposition makeDiagnosticComposition; - - public DiagnosticReportConverter( - MakeOrganisationResource makeOrganisationResource, - MakeBundleMetaResource makeBundleMetaResource, - MakePatientResource makePatientResource, - MakePractitionerResource makePractitionerResource, - MakeDocumentResource makeDocumentResource, - MakeObservationResource makeObservationResource, - MakeDiagnosticLabResource makeDiagnosticLabResource, - MakeEncounterResource makeEncounterResource, - MakeDiagnosticComposition makeDiagnosticComposition) { - this.makeOrganisationResource = makeOrganisationResource; - this.makeBundleMetaResource = makeBundleMetaResource; - this.makePatientResource = makePatientResource; - this.makePractitionerResource = makePractitionerResource; - this.makeDocumentResource = makeDocumentResource; - this.makeObservationResource = makeObservationResource; - this.makeDiagnosticLabResource = makeDiagnosticLabResource; - this.makeEncounterResource = makeEncounterResource; - this.makeDiagnosticComposition = makeDiagnosticComposition; - } - - public BundleResponse convertToDiagnosticBundle(DiagnosticReportRequest diagnosticReportRequest) - throws ParseException { - try { - if (diagnosticReportRequest == null) { - return BundleResponse.builder() - .error(ErrorResponse.builder().code("1001").message("Request is null").build()) - .build(); - } - - // Initialize bundle entries - List entries = new ArrayList<>(); - - // Organization resource - Organization organization = - makeOrganisationResource.getOrganization(diagnosticReportRequest.getOrganisation()); - - // Patient resource - Patient patient = makePatientResource.getPatient(diagnosticReportRequest.getPatient()); - - // Practitioners - List practitionerList = - Optional.ofNullable(diagnosticReportRequest.getPractitioners()) - .orElse(Collections.emptyList()) - .stream() - .map(StreamUtils.wrapException(makePractitionerResource::getPractitioner)) - .toList(); - - // Encounter resource - Encounter encounter = - makeEncounterResource.getEncounter( - patient, - diagnosticReportRequest.getEncounter(), - diagnosticReportRequest.getVisitDate()); - - // Diagnostic Reports and Observations - List diagnosticReportList = new ArrayList<>(); - List diagnosticObservationList = new ArrayList<>(); - Optional.ofNullable(diagnosticReportRequest.getDiagnostics()) - .orElse(Collections.emptyList()) - .forEach( - diagnosticResource -> { - List observationList = - Optional.ofNullable(diagnosticResource.getResult()) - .orElse(Collections.emptyList()) - .stream() - .map( - StreamUtils.wrapException( - observationResource -> { - return makeObservationResource.getObservation( - patient, practitionerList, observationResource); - })) - .peek(diagnosticObservationList::add) - .toList(); - - try { - diagnosticReportList.add( - makeDiagnosticLabResource.getDiagnosticReport( - patient, - practitionerList, - observationList, - encounter, - diagnosticResource)); - } catch (ParseException e) { - throw new RuntimeException(e); - } - }); - - // Document References - List documentReferenceList = - Optional.ofNullable(diagnosticReportRequest.getDocuments()) - .orElse(Collections.emptyList()) - .stream() - .map( - StreamUtils.wrapException( - documentResource -> { - return makeDocumentResource.getDocument( - patient, - organization, - documentResource, - BundleCompositionIdentifier.DIAGNOSTIC_STUDIES_REPORT_CODE, - documentResource.getType()); - })) - .toList(); - - // Composition resource - Composition composition = - makeDiagnosticComposition.makeCompositionResource( - patient, - diagnosticReportRequest.getVisitDate(), - practitionerList, - organization, - encounter, - diagnosticReportList, - documentReferenceList); - - // Build the bundle - Bundle bundle = new Bundle(); - bundle.setId(UUID.randomUUID().toString()); - bundle.setType(Bundle.BundleType.DOCUMENT); - bundle.setTimestampElement(Utils.getCurrentTimeStamp()); - bundle.setMeta(makeBundleMetaResource.getMeta()); - bundle.setIdentifier( - new Identifier() - .setSystem(BundleUrlIdentifier.WRAPPER_URL) - .setValue(diagnosticReportRequest.getCareContextReference())); - - // Add entries to the bundle - addBundleEntry(entries, composition, BundleResourceIdentifier.COMPOSITION); - addBundleEntry(entries, patient, BundleResourceIdentifier.PATIENT); - practitionerList.forEach( - practitioner -> - addBundleEntry(entries, practitioner, BundleResourceIdentifier.PRACTITIONER)); - addBundleEntry(entries, organization, BundleResourceIdentifier.ORGANISATION); - addBundleEntry(entries, encounter, BundleResourceIdentifier.ENCOUNTER); - diagnosticReportList.forEach( - report -> addBundleEntry(entries, report, BundleResourceIdentifier.DIAGNOSTIC_REPORT)); - diagnosticObservationList.forEach( - observation -> - addBundleEntry(entries, observation, BundleResourceIdentifier.OBSERVATION)); - documentReferenceList.forEach( - document -> - addBundleEntry(entries, document, BundleResourceIdentifier.DOCUMENT_REFERENCE)); - - bundle.setEntry(entries); - - return BundleResponse.builder().bundle(bundle).build(); - - } catch (Exception e) { - if (e instanceof InvalidDataAccessResourceUsageException) { - log.error(e.getMessage()); - return BundleResponse.builder() - .error( - new ErrorResponse( - ErrorCode.DB_ERROR, - " JDBCException Generic SQL Related Error, kindly check logs.")) - .build(); - } - return BundleResponse.builder() - .error(ErrorResponse.builder().code("1000").message(e.getMessage()).build()) - .build(); - } - } - - private void addBundleEntry( - List entries, Resource resource, String resourceIdentifier) { - if (resource != null && resource.getId() != null) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(resourceIdentifier + "/" + resource.getId()) - .setResource(resource)); - } - } -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/DischargeSummaryConverter.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/DischargeSummaryConverter.java deleted file mode 100644 index 7b47f43d..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/DischargeSummaryConverter.java +++ /dev/null @@ -1,453 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.converter; - -import com.nha.abdm.fhir.mapper.Utils; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleCompositionIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.ErrorCode; -import com.nha.abdm.fhir.mapper.rest.common.helpers.BundleResponse; -import com.nha.abdm.fhir.mapper.rest.common.helpers.DocumentResource; -import com.nha.abdm.fhir.mapper.rest.common.helpers.ErrorResponse; -import com.nha.abdm.fhir.mapper.rest.dto.compositions.MakeDischargeComposition; -import com.nha.abdm.fhir.mapper.rest.dto.resources.*; -import com.nha.abdm.fhir.mapper.rest.exceptions.StreamUtils; -import com.nha.abdm.fhir.mapper.rest.requests.DischargeSummaryRequest; -import com.nha.abdm.fhir.mapper.rest.requests.helpers.*; -import java.text.ParseException; -import java.util.*; -import java.util.stream.Collectors; -import org.hl7.fhir.r4.model.*; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.dao.InvalidDataAccessResourceUsageException; -import org.springframework.stereotype.Service; - -@Service -public class DischargeSummaryConverter { - private static final Logger log = LoggerFactory.getLogger(DischargeSummaryConverter.class); - private final MakeOrganisationResource makeOrganisationResource; - private final MakeBundleMetaResource makeBundleMetaResource; - - private final MakePatientResource makePatientResource; - - private final MakePractitionerResource makePractitionerResource; - private final MakeConditionResource makeConditionResource; - private final MakeObservationResource makeObservationResource; - private final MakeAllergyToleranceResource makeAllergyToleranceResource; - private final MakeFamilyMemberResource makeFamilyMemberResource; - private final MakeDocumentResource makeDocumentResource; - private final MakeEncounterResource makeEncounterResource; - private final MakeMedicationRequestResource makeMedicationRequestResource; - private final MakeDiagnosticLabResource makeDiagnosticLabResource; - private final MakeProcedureResource makeProcedureResource; - private final MakeDischargeComposition makeDischargeComposition; - private final MakeCarePlanResource makeCarePlanResource; - - public DischargeSummaryConverter( - MakeOrganisationResource makeOrganisationResource, - MakeBundleMetaResource makeBundleMetaResource, - MakePatientResource makePatientResource, - MakePractitionerResource makePractitionerResource, - MakeConditionResource makeConditionResource, - MakeObservationResource makeObservationResource, - MakeServiceRequestResource makeServiceRequestResource, - MakeAllergyToleranceResource makeAllergyToleranceResource, - MakeFamilyMemberResource makeFamilyMemberResource, - MakeDocumentResource makeDocumentResource, - MakeEncounterResource makeEncounterResource, - MakeMedicationRequestResource makeMedicationRequestResource, - MakeDiagnosticLabResource makeDiagnosticLabResource, - MakeProcedureResource makeProcedureResource, - MakeDischargeComposition makeDischargeComposition, - MakeCarePlanResource makeCarePlanResource) { - this.makeOrganisationResource = makeOrganisationResource; - this.makeBundleMetaResource = makeBundleMetaResource; - this.makePatientResource = makePatientResource; - this.makePractitionerResource = makePractitionerResource; - this.makeConditionResource = makeConditionResource; - this.makeObservationResource = makeObservationResource; - this.makeAllergyToleranceResource = makeAllergyToleranceResource; - this.makeFamilyMemberResource = makeFamilyMemberResource; - this.makeDocumentResource = makeDocumentResource; - this.makeEncounterResource = makeEncounterResource; - this.makeMedicationRequestResource = makeMedicationRequestResource; - this.makeDiagnosticLabResource = makeDiagnosticLabResource; - this.makeProcedureResource = makeProcedureResource; - this.makeDischargeComposition = makeDischargeComposition; - this.makeCarePlanResource = makeCarePlanResource; - } - - public BundleResponse convertToDischargeSummary(DischargeSummaryRequest dischargeSummaryRequest) - throws ParseException { - try { - - List entries = new ArrayList<>(); - - Organization organization = - makeOrganisationResource.getOrganization(dischargeSummaryRequest.getOrganisation()); - - Patient patient = makePatientResource.getPatient(dischargeSummaryRequest.getPatient()); - - List practitionerList = - Optional.ofNullable(dischargeSummaryRequest.getPractitioners()) - .orElse(Collections.emptyList()) - .stream() - .map(StreamUtils.wrapException(makePractitionerResource::getPractitioner)) - .collect(Collectors.toList()); - - Encounter encounter = - makeEncounterResource.getEncounter( - patient, - dischargeSummaryRequest.getEncounter() != null - ? dischargeSummaryRequest.getEncounter() - : null, - dischargeSummaryRequest.getAuthoredOn()); - List chiefComplaintList = - dischargeSummaryRequest.getChiefComplaints() != null - ? makeCheifComplaintsList(dischargeSummaryRequest, patient) - : new ArrayList<>(); - List physicalObservationList = - dischargeSummaryRequest.getPhysicalExaminations() != null - ? makePhysicalObservations(dischargeSummaryRequest, patient, practitionerList) - : new ArrayList<>(); - List allergieList = - dischargeSummaryRequest.getAllergies() != null - ? makeAllergiesList(patient, practitionerList, dischargeSummaryRequest) - : new ArrayList<>(); - List medicalHistoryList = - dischargeSummaryRequest.getMedicalHistories() != null - ? makeMedicalHistoryList(dischargeSummaryRequest, patient) - : new ArrayList<>(); - List familyMemberHistoryList = - dischargeSummaryRequest.getFamilyHistories() != null - ? makeFamilyMemberHistory(patient, dischargeSummaryRequest) - : new ArrayList<>(); - List medicationList = new ArrayList<>(); - List medicationConditionList = new ArrayList<>(); - for (PrescriptionResource prescriptionResource : dischargeSummaryRequest.getMedications()) { - Condition medicationCondition = - prescriptionResource.getReason() != null - ? makeConditionResource.getCondition( - prescriptionResource.getReason(), - patient, - dischargeSummaryRequest.getAuthoredOn(), - null) - : null; - medicationList.add( - makeMedicationRequestResource.getMedicationResource( - dischargeSummaryRequest.getAuthoredOn(), - prescriptionResource, - medicationCondition, - organization, - practitionerList, - patient)); - if (medicationCondition != null) { - medicationConditionList.add(medicationCondition); - } - } - // Diagnostic Reports and Observations - List diagnosticReportList = new ArrayList<>(); - List diagnosticObservationList = new ArrayList<>(); - Optional.ofNullable(dischargeSummaryRequest.getDiagnostics()) - .orElse(Collections.emptyList()) - .forEach( - diagnosticResource -> { - List observationList = - Optional.ofNullable(diagnosticResource.getResult()) - .orElse(Collections.emptyList()) - .stream() - .map( - StreamUtils.wrapException( - observationResource -> { - return makeObservationResource.getObservation( - patient, practitionerList, observationResource); - })) - .peek(diagnosticObservationList::add) - .toList(); - - try { - diagnosticReportList.add( - makeDiagnosticLabResource.getDiagnosticReport( - patient, - practitionerList, - observationList, - encounter, - diagnosticResource)); - } catch (ParseException e) { - throw new RuntimeException(e); - } - }); - - List procedureList = - dischargeSummaryRequest.getProcedures() != null - ? makeProcedureList(dischargeSummaryRequest, patient) - : new ArrayList<>(); - List documentReferenceList = - Optional.ofNullable(dischargeSummaryRequest.getDocuments()) - .orElse(Collections.emptyList()) - .stream() - .map( - StreamUtils.wrapException( - documentResource -> - makeDocumentReference(patient, organization, documentResource))) - .toList(); - - CarePlan carePlan = - makeCarePlanResource.getCarePlan(dischargeSummaryRequest.getCarePlan(), patient); - - Composition composition = - makeDischargeComposition.makeDischargeCompositionResource( - patient, - dischargeSummaryRequest.getAuthoredOn(), - encounter, - practitionerList, - organization, - chiefComplaintList, - physicalObservationList, - allergieList, - medicationList, - diagnosticReportList, - medicalHistoryList, - familyMemberHistoryList, - carePlan, - procedureList, - documentReferenceList, - BundleCompositionIdentifier.DISCHARGE_SUMMARY_CODE, - BundleCompositionIdentifier.DISCHARGE_SUMMARY); - - Bundle bundle = new Bundle(); - bundle.setId(UUID.randomUUID().toString()); - bundle.setType(Bundle.BundleType.DOCUMENT); - bundle.setTimestampElement(Utils.getCurrentTimeStamp()); - bundle.setMeta(makeBundleMetaResource.getMeta()); - bundle.setIdentifier( - new Identifier() - .setSystem(BundleUrlIdentifier.WRAPPER_URL) - .setValue(dischargeSummaryRequest.getCareContextReference())); - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.COMPOSITION + "/" + composition.getId()) - .setResource(composition)); - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.PATIENT + "/" + patient.getId()) - .setResource(patient)); - for (Practitioner practitioner : practitionerList) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.PRACTITIONER + "/" + practitioner.getId()) - .setResource(practitioner)); - } - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.ENCOUNTER + "/" + encounter.getId()) - .setResource(encounter)); - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.ORGANISATION + "/" + organization.getId()) - .setResource(organization)); - - for (Condition complaint : chiefComplaintList) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.CHIEF_COMPLAINTS + "/" + complaint.getId()) - .setResource(complaint)); - } - for (Observation physicalObservation : physicalObservationList) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl( - BundleResourceIdentifier.PHYSICAL_EXAMINATION - + "/" - + physicalObservation.getId()) - .setResource(physicalObservation)); - } - for (AllergyIntolerance allergyIntolerance : allergieList) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl( - BundleResourceIdentifier.ALLERGY_INTOLERANCE + "/" + allergyIntolerance.getId()) - .setResource(allergyIntolerance)); - } - for (Condition medicalHistory : medicalHistoryList) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.MEDICAL_HISTORY + "/" + medicalHistory.getId()) - .setResource(medicalHistory)); - } - for (Condition medicationCondition : medicationConditionList) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.CONDITION + "/" + medicationCondition.getId()) - .setResource(medicationCondition)); - } - for (FamilyMemberHistory familyMemberHistory : familyMemberHistoryList) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl( - BundleResourceIdentifier.FAMILY_HISTORY + "/" + familyMemberHistory.getId()) - .setResource(familyMemberHistory)); - } - if (Objects.nonNull(carePlan)) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.CARE_PLAN + "/" + carePlan.getId()) - .setResource(carePlan)); - } - for (MedicationRequest medicationRequest : medicationList) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl( - BundleResourceIdentifier.FAMILY_HISTORY + "/" + medicationRequest.getId()) - .setResource(medicationRequest)); - } - - for (DiagnosticReport diagnosticReport : diagnosticReportList) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl( - BundleResourceIdentifier.DIAGNOSTIC_REPORT + "/" + diagnosticReport.getId()) - .setResource(diagnosticReport)); - } - - for (Procedure procedure : procedureList) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.PROCEDURE + "/" + procedure.getId()) - .setResource(procedure)); - } - for (Observation observation : diagnosticObservationList) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.OBSERVATION + "/" + observation.getId()) - .setResource(observation)); - } - for (DocumentReference documentReference : documentReferenceList) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl( - BundleResourceIdentifier.DOCUMENT_REFERENCE + "/" + documentReference.getId()) - .setResource(documentReference)); - } - bundle.setEntry(entries); - return BundleResponse.builder().bundle(bundle).build(); - } catch (Exception e) { - if (e instanceof InvalidDataAccessResourceUsageException) { - log.error(e.getMessage()); - return BundleResponse.builder() - .error( - new ErrorResponse( - ErrorCode.DB_ERROR, - " JDBCException Generic SQL Related Error, kindly check logs.")) - .build(); - } - return BundleResponse.builder() - .error(ErrorResponse.builder().code("1000").message(e.getMessage()).build()) - .build(); - } - } - - private DocumentReference makeDocumentReference( - Patient patient, Organization organization, DocumentResource documentResource) - throws ParseException { - return makeDocumentResource.getDocument( - patient, - organization, - documentResource, - BundleCompositionIdentifier.DISCHARGE_SUMMARY_CODE, - BundleCompositionIdentifier.DISCHARGE_SUMMARY); - } - - private List makeProcedureList( - DischargeSummaryRequest dischargeSummaryRequest, Patient patient) throws ParseException { - - return Optional.ofNullable(dischargeSummaryRequest.getProcedures()) - .orElse(Collections.emptyList()) - .stream() - .map( - StreamUtils.wrapException( - procedureResource -> - makeProcedureResource.getProcedure(patient, procedureResource))) - .toList(); - } - - private List makeFamilyMemberHistory( - Patient patient, DischargeSummaryRequest dischargeSummaryRequest) throws ParseException { - return Optional.ofNullable(dischargeSummaryRequest.getFamilyHistories()) - .orElse(Collections.emptyList()) - .stream() - .map( - StreamUtils.wrapException( - familyObservationResource -> - makeFamilyMemberResource.getFamilyHistory(patient, familyObservationResource))) - .toList(); - } - - private List makeMedicalHistoryList( - DischargeSummaryRequest dischargeSummaryRequest, Patient patient) throws ParseException { - return Optional.ofNullable(dischargeSummaryRequest.getMedicalHistories()) - .orElse(Collections.emptyList()) - .stream() - .map( - StreamUtils.wrapException( - chiefComplaintResource -> - makeConditionResource.getCondition( - chiefComplaintResource.getComplaint(), - patient, - chiefComplaintResource.getRecordedDate(), - chiefComplaintResource.getDateRange()))) - .toList(); - } - - private List makeAllergiesList( - Patient patient, - List practitionerList, - DischargeSummaryRequest dischargeSummaryRequest) - throws ParseException { - return Optional.ofNullable(dischargeSummaryRequest.getAllergies()) - .orElse(Collections.emptyList()) - .stream() - .map( - StreamUtils.wrapException( - allergy -> - makeAllergyToleranceResource.getAllergy( - patient, - practitionerList, - allergy, - dischargeSummaryRequest.getAuthoredOn()))) - .toList(); - } - - private List makePhysicalObservations( - DischargeSummaryRequest dischargeSummaryRequest, - Patient patient, - List practitionerList) - throws ParseException { - return Optional.ofNullable(dischargeSummaryRequest.getPhysicalExaminations()) - .orElse(Collections.emptyList()) - .stream() - .map( - StreamUtils.wrapException( - observationResource -> - makeObservationResource.getObservation( - patient, practitionerList, observationResource))) - .toList(); - } - - private List makeCheifComplaintsList( - DischargeSummaryRequest dischargeSummaryRequest, Patient patient) throws ParseException { - return Optional.ofNullable(dischargeSummaryRequest.getChiefComplaints()) - .orElse(Collections.emptyList()) - .stream() - .map( - StreamUtils.wrapException( - chiefComplaint -> - makeConditionResource.getCondition( - chiefComplaint.getComplaint(), - patient, - chiefComplaint.getRecordedDate(), - chiefComplaint.getDateRange()))) - .toList(); - } -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/HealthDocumentConverter.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/HealthDocumentConverter.java deleted file mode 100644 index 3672a205..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/HealthDocumentConverter.java +++ /dev/null @@ -1,158 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.converter; - -import com.nha.abdm.fhir.mapper.Utils; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleCompositionIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.ErrorCode; -import com.nha.abdm.fhir.mapper.rest.common.helpers.BundleResponse; -import com.nha.abdm.fhir.mapper.rest.common.helpers.ErrorResponse; -import com.nha.abdm.fhir.mapper.rest.dto.compositions.MakeHealthDocumentComposition; -import com.nha.abdm.fhir.mapper.rest.dto.resources.*; -import com.nha.abdm.fhir.mapper.rest.exceptions.StreamUtils; -import com.nha.abdm.fhir.mapper.rest.requests.HealthDocumentRecord; -import java.text.ParseException; -import java.util.*; -import org.hl7.fhir.r4.model.*; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.dao.InvalidDataAccessResourceUsageException; -import org.springframework.stereotype.Service; - -@Service -public class HealthDocumentConverter { - private static final Logger log = LoggerFactory.getLogger(HealthDocumentConverter.class); - private final MakeOrganisationResource makeOrganisationResource; - private final MakeBundleMetaResource makeBundleMetaResource; - - private final MakePatientResource makePatientResource; - - private final MakePractitionerResource makePractitionerResource; - private final MakeDocumentResource makeDocumentResource; - private final MakeEncounterResource makeEncounterResource; - private final MakeHealthDocumentComposition makeHealthDocumentComposition; - - public HealthDocumentConverter( - MakeOrganisationResource makeOrganisationResource, - MakeBundleMetaResource makeBundleMetaResource, - MakePatientResource makePatientResource, - MakePractitionerResource makePractitionerResource, - MakeDocumentResource makeDocumentResource, - MakeEncounterResource makeEncounterResource, - MakeHealthDocumentComposition makeHealthDocumentComposition) { - this.makeOrganisationResource = makeOrganisationResource; - this.makeBundleMetaResource = makeBundleMetaResource; - this.makePatientResource = makePatientResource; - this.makePractitionerResource = makePractitionerResource; - this.makeDocumentResource = makeDocumentResource; - this.makeEncounterResource = makeEncounterResource; - this.makeHealthDocumentComposition = makeHealthDocumentComposition; - } - - public BundleResponse convertToHealthDocumentBundle(HealthDocumentRecord healthDocumentRecord) - throws ParseException { - try { - Organization organization = - Objects.nonNull(healthDocumentRecord.getOrganisation()) - ? makeOrganisationResource.getOrganization(healthDocumentRecord.getOrganisation()) - : null; - Patient patient = makePatientResource.getPatient(healthDocumentRecord.getPatient()); - List practitionerList = - Optional.ofNullable(healthDocumentRecord.getPractitioners()) - .orElse(Collections.emptyList()) - .stream() - .map(StreamUtils.wrapException(makePractitionerResource::getPractitioner)) - .toList(); - - List documentReferenceList = - Optional.ofNullable(healthDocumentRecord.getDocuments()) - .orElse(Collections.emptyList()) - .stream() - .map( - StreamUtils.wrapException( - documentResource -> - makeDocumentResource.getDocument( - patient, - organization, - documentResource, - BundleCompositionIdentifier.HEALTH_DOCUMENT_CODE, - BundleCompositionIdentifier.HEALTH_DOCUMENT))) - .toList(); - - Encounter encounter = - makeEncounterResource.getEncounter( - patient, - healthDocumentRecord.getEncounter() != null - ? healthDocumentRecord.getEncounter() - : null, - healthDocumentRecord.getAuthoredOn()); - Composition composition = - makeHealthDocumentComposition.makeCompositionResource( - patient, - healthDocumentRecord.getAuthoredOn(), - practitionerList, - organization, - encounter, - documentReferenceList); - Bundle bundle = new Bundle(); - bundle.setId(UUID.randomUUID().toString()); - bundle.setType(Bundle.BundleType.DOCUMENT); - bundle.setTimestampElement(Utils.getCurrentTimeStamp()); - bundle.setMeta(makeBundleMetaResource.getMeta()); - bundle.setIdentifier( - new Identifier() - .setSystem(BundleUrlIdentifier.WRAPPER_URL) - .setValue(healthDocumentRecord.getCareContextReference())); - List entries = new ArrayList<>(); - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.COMPOSITION + "/" + composition.getId()) - .setResource(composition)); - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.PATIENT + "/" + patient.getId()) - .setResource(patient)); - for (Practitioner practitioner : practitionerList) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.PRACTITIONER + "/" + practitioner.getId()) - .setResource(practitioner)); - } - if (Objects.nonNull(organization)) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.ORGANISATION + "/" + organization.getId()) - .setResource(organization)); - } - if (Objects.nonNull(encounter)) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.ENCOUNTER + "/" + encounter.getId()) - .setResource(encounter)); - } - for (DocumentReference documentReference : documentReferenceList) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl( - BundleResourceIdentifier.DOCUMENT_REFERENCE + "/" + documentReference.getId()) - .setResource(documentReference)); - } - bundle.setEntry(entries); - return BundleResponse.builder().bundle(bundle).build(); - } catch (Exception e) { - if (e instanceof InvalidDataAccessResourceUsageException) { - log.error(e.getMessage()); - return BundleResponse.builder() - .error( - new ErrorResponse( - ErrorCode.DB_ERROR, - " JDBCException Generic SQL Related Error, kindly check logs.")) - .build(); - } - return BundleResponse.builder() - .error(ErrorResponse.builder().code("1000").message(e.getMessage()).build()) - .build(); - } - } -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/ImmunizationConverter.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/ImmunizationConverter.java deleted file mode 100644 index 0cbd03b1..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/ImmunizationConverter.java +++ /dev/null @@ -1,192 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.converter; - -import com.nha.abdm.fhir.mapper.Utils; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleCompositionIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.ErrorCode; -import com.nha.abdm.fhir.mapper.rest.common.helpers.BundleResponse; -import com.nha.abdm.fhir.mapper.rest.common.helpers.ErrorResponse; -import com.nha.abdm.fhir.mapper.rest.common.helpers.OrganisationResource; -import com.nha.abdm.fhir.mapper.rest.dto.compositions.MakeImmunizationComposition; -import com.nha.abdm.fhir.mapper.rest.dto.resources.*; -import com.nha.abdm.fhir.mapper.rest.exceptions.StreamUtils; -import com.nha.abdm.fhir.mapper.rest.requests.ImmunizationRequest; -import java.text.ParseException; -import java.util.*; -import org.hl7.fhir.r4.model.*; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.dao.InvalidDataAccessResourceUsageException; -import org.springframework.stereotype.Service; - -@Service -public class ImmunizationConverter { - private static final Logger log = LoggerFactory.getLogger(ImmunizationConverter.class); - private final MakeDocumentResource makeDocumentReference; - private final MakePatientResource makePatientResource; - private final MakePractitionerResource makePractitionerResource; - private final MakeOrganisationResource makeOrganisationResource; - private final MakeImmunizationResource makeImmunizationResource; - private final MakeBundleMetaResource makeBundleMetaResource; - private final MakeEncounterResource makeEncounterResource; - private final MakeImmunizationComposition makeImmunizationComposition; - - public ImmunizationConverter( - MakeDocumentResource makeDocumentReference, - MakePatientResource makePatientResource, - MakePractitionerResource makePractitionerResource, - MakeOrganisationResource makeOrganisationResource, - MakeImmunizationResource makeImmunizationResource, - MakeBundleMetaResource makeBundleMetaResource, - MakeEncounterResource makeEncounterResource, - MakeImmunizationComposition makeImmunizationComposition) { - this.makeDocumentReference = makeDocumentReference; - this.makePatientResource = makePatientResource; - this.makePractitionerResource = makePractitionerResource; - this.makeOrganisationResource = makeOrganisationResource; - this.makeImmunizationResource = makeImmunizationResource; - this.makeBundleMetaResource = makeBundleMetaResource; - this.makeEncounterResource = makeEncounterResource; - this.makeImmunizationComposition = makeImmunizationComposition; - } - - public BundleResponse makeImmunizationBundle(ImmunizationRequest immunizationRequest) - throws ParseException { - try { - Bundle bundle = new Bundle(); - Patient patient = makePatientResource.getPatient(immunizationRequest.getPatient()); - List practitionerList = - Optional.ofNullable(immunizationRequest.getPractitioners()) - .orElse(Collections.emptyList()) - .stream() - .map(StreamUtils.wrapException(makePractitionerResource::getPractitioner)) - .toList(); - - Organization organization = - makeOrganisationResource.getOrganization(immunizationRequest.getOrganisation()); - Encounter encounter = - makeEncounterResource.getEncounter( - patient, - immunizationRequest.getEncounter() != null - ? immunizationRequest.getEncounter() - : null, - immunizationRequest.getAuthoredOn()); - List manufactureList = new ArrayList<>(); - List immunizationList = - Optional.ofNullable(immunizationRequest.getImmunizations()) - .orElse(Collections.emptyList()) - .stream() - .filter(Objects::nonNull) - .map( - StreamUtils.wrapException( - immunizationResource -> { - Organization manufacturer = - makeOrganisationResource.getOrganization( - OrganisationResource.builder() - .facilityId(immunizationResource.getManufacturer()) - .facilityName(immunizationResource.getManufacturer()) - .build()); - manufactureList.add(manufacturer); - return makeImmunizationResource.getImmunization( - patient, practitionerList, manufacturer, immunizationResource); - })) - .toList(); - - List documentList = - Optional.ofNullable(immunizationRequest.getDocuments()) - .orElse(Collections.emptyList()) - .stream() - .map( - StreamUtils.wrapException( - documentResource -> - makeDocumentReference.getDocument( - patient, - organization, - documentResource, - BundleCompositionIdentifier.IMMUNIZATION_RECORD_CODE, - BundleCompositionIdentifier.IMMUNIZATION_RECORD))) - .toList(); - - Composition composition = - makeImmunizationComposition.makeCompositionResource( - patient, - practitionerList, - organization, - immunizationRequest.getAuthoredOn(), - immunizationList, - documentList); - - bundle.setId(UUID.randomUUID().toString()); - bundle.setType(Bundle.BundleType.DOCUMENT); - bundle.setTimestampElement(Utils.getCurrentTimeStamp()); - bundle.setMeta(makeBundleMetaResource.getMeta()); - List entries = new ArrayList<>(); - bundle.setIdentifier( - new Identifier() - .setSystem(BundleUrlIdentifier.WRAPPER_URL) - .setValue(immunizationRequest.getCareContextReference())); - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.COMPOSITION + "/" + composition.getId()) - .setResource(composition)); - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.PATIENT + "/" + patient.getId()) - .setResource(patient)); - for (Practitioner practitioner : practitionerList) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.PRACTITIONER + "/" + practitioner.getId()) - .setResource(practitioner)); - } - if (Objects.nonNull(organization)) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.ORGANISATION + "/" + organization.getId()) - .setResource(organization)); - } - if (Objects.nonNull(encounter)) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.ENCOUNTER + "/" + encounter.getId()) - .setResource(encounter)); - } - for (Organization manufacturer : manufactureList) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.MANUFACTURER + "/" + manufacturer.getId()) - .setResource(manufacturer)); - } - for (Immunization immunization : immunizationList) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.IMMUNIZATION + "/" + immunization.getId()) - .setResource(immunization)); - } - for (DocumentReference documentReference : documentList) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl( - BundleResourceIdentifier.DOCUMENT_REFERENCE + "/" + documentReference.getId()) - .setResource(documentReference)); - } - bundle.setEntry(entries); - return BundleResponse.builder().bundle(bundle).build(); - } catch (Exception e) { - if (e instanceof InvalidDataAccessResourceUsageException) { - log.error(e.getMessage()); - return BundleResponse.builder() - .error( - new ErrorResponse( - ErrorCode.DB_ERROR, - " JDBCException Generic SQL Related Error, kindly check logs.")) - .build(); - } - return BundleResponse.builder() - .error(ErrorResponse.builder().code("1000").message(e.getMessage()).build()) - .build(); - } - } -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/OPConsultationConverter.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/OPConsultationConverter.java deleted file mode 100644 index 5e40ee4e..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/OPConsultationConverter.java +++ /dev/null @@ -1,501 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.converter; - -import com.nha.abdm.fhir.mapper.Utils; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleCompositionIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.ErrorCode; -import com.nha.abdm.fhir.mapper.rest.common.helpers.BundleResponse; -import com.nha.abdm.fhir.mapper.rest.common.helpers.DocumentResource; -import com.nha.abdm.fhir.mapper.rest.common.helpers.ErrorResponse; -import com.nha.abdm.fhir.mapper.rest.dto.compositions.MakeOpComposition; -import com.nha.abdm.fhir.mapper.rest.dto.resources.*; -import com.nha.abdm.fhir.mapper.rest.exceptions.StreamUtils; -import com.nha.abdm.fhir.mapper.rest.requests.OPConsultationRequest; -import com.nha.abdm.fhir.mapper.rest.requests.helpers.*; -import java.text.ParseException; -import java.util.*; -import org.hl7.fhir.r4.model.*; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.dao.InvalidDataAccessResourceUsageException; -import org.springframework.stereotype.Service; - -@Service -public class OPConsultationConverter { - private static final Logger log = LoggerFactory.getLogger(OPConsultationConverter.class); - private final MakeOrganisationResource makeOrganisationResource; - private final MakeBundleMetaResource makeBundleMetaResource; - - private final MakePatientResource makePatientResource; - - private final MakePractitionerResource makePractitionerResource; - private final MakeConditionResource makeConditionResource; - private final MakeObservationResource makeObservationResource; - private final MakeServiceRequestResource makeServiceRequestResource; - private final MakeAllergyToleranceResource makeAllergyToleranceResource; - private final MakeFamilyMemberResource makeFamilyMemberResource; - private final MakeDocumentResource makeDocumentResource; - private final MakeEncounterResource makeEncounterResource; - private final MakeMedicationRequestResource makeMedicationRequestResource; - private final MakeProcedureResource makeProcedureResource; - private final MakeOpComposition makeOpComposition; - - public OPConsultationConverter( - MakeOrganisationResource makeOrganisationResource, - MakeBundleMetaResource makeBundleMetaResource, - MakePatientResource makePatientResource, - MakePractitionerResource makePractitionerResource, - MakeConditionResource makeConditionResource, - MakeObservationResource makeObservationResource, - MakeServiceRequestResource makeServiceRequestResource, - MakeAllergyToleranceResource makeAllergyToleranceResource, - MakeFamilyMemberResource makeFamilyMemberResource, - MakeDocumentResource makeDocumentResource, - MakeEncounterResource makeEncounterResource, - MakeMedicationRequestResource makeMedicationRequestResource, - MakeProcedureResource makeProcedureResource, - MakeOpComposition makeOpComposition) { - this.makeOrganisationResource = makeOrganisationResource; - this.makeBundleMetaResource = makeBundleMetaResource; - this.makePatientResource = makePatientResource; - this.makePractitionerResource = makePractitionerResource; - this.makeConditionResource = makeConditionResource; - this.makeObservationResource = makeObservationResource; - this.makeServiceRequestResource = makeServiceRequestResource; - this.makeAllergyToleranceResource = makeAllergyToleranceResource; - this.makeFamilyMemberResource = makeFamilyMemberResource; - this.makeDocumentResource = makeDocumentResource; - this.makeEncounterResource = makeEncounterResource; - this.makeMedicationRequestResource = makeMedicationRequestResource; - this.makeProcedureResource = makeProcedureResource; - this.makeOpComposition = makeOpComposition; - } - - public BundleResponse convertToOPConsultationBundle(OPConsultationRequest opConsultationRequest) - throws ParseException { - try { - Organization organization = - makeOrganisationResource.getOrganization(opConsultationRequest.getOrganisation()); - Patient patient = makePatientResource.getPatient(opConsultationRequest.getPatient()); - List practitionerList = - Optional.ofNullable(opConsultationRequest.getPractitioners()) - .orElse(Collections.emptyList()) - .stream() - .map(StreamUtils.wrapException(makePractitionerResource::getPractitioner)) - .toList(); - Encounter encounter = - makeEncounterResource.getEncounter( - patient, - opConsultationRequest.getEncounter() != null - ? opConsultationRequest.getEncounter() - : null, - opConsultationRequest.getVisitDate()); - List chiefComplaintList = - opConsultationRequest.getChiefComplaints() != null - ? makeCheifComplaintsList(opConsultationRequest, patient) - : new ArrayList<>(); - List physicalObservationList = - opConsultationRequest.getPhysicalExaminations() != null - ? makePhysicalObservations(opConsultationRequest, patient, practitionerList) - : new ArrayList<>(); - List allergieList = - opConsultationRequest.getAllergies() != null - ? makeAllergiesList(patient, practitionerList, opConsultationRequest) - : new ArrayList<>(); - List medicalHistoryList = - opConsultationRequest.getMedicalHistories() != null - ? makeMedicalHistoryList(opConsultationRequest, patient) - : new ArrayList<>(); - List familyMemberHistoryList = - opConsultationRequest.getFamilyHistories() != null - ? makeFamilyMemberHistory(patient, opConsultationRequest) - : new ArrayList<>(); - List investigationAdviceList = - opConsultationRequest.getServiceRequests() != null - ? makeInvestigationAdviceList(opConsultationRequest, patient, practitionerList) - : new ArrayList<>(); - HashMap medicationRequestMap = new HashMap<>(); - List medicationList = new ArrayList<>(); - List medicationConditionList = new ArrayList<>(); - if (Objects.nonNull(opConsultationRequest.getMedications())) { - for (PrescriptionResource prescriptionResource : opConsultationRequest.getMedications()) { - Condition medicationCondition = - prescriptionResource.getReason() != null - ? makeConditionResource.getCondition( - prescriptionResource.getReason(), - patient, - opConsultationRequest.getVisitDate(), - null) - : null; - medicationList.add( - makeMedicationRequestResource.getMedicationResource( - opConsultationRequest.getVisitDate(), - prescriptionResource, - medicationCondition, - organization, - practitionerList, - patient)); - if (medicationCondition != null) { - medicationConditionList.add(medicationCondition); - } - } // TODO - } - List followupList = - opConsultationRequest.getFollowups() != null - ? makeFollowupList(patient, opConsultationRequest) - : new ArrayList<>(); - List procedureList = - opConsultationRequest.getProcedures() != null - ? makeProcedureList(opConsultationRequest, patient) - : new ArrayList<>(); - List referralList = - opConsultationRequest.getReferrals() != null - ? makeReferralList(opConsultationRequest, patient, practitionerList) - : new ArrayList<>(); - List otherObservationList = - opConsultationRequest.getOtherObservations() != null - ? makeOtherObservations(patient, practitionerList, opConsultationRequest) - : new ArrayList<>(); - List documentReferenceList = new ArrayList<>(); - if (Objects.nonNull(opConsultationRequest.getDocuments())) { - for (DocumentResource documentResource : opConsultationRequest.getDocuments()) { - documentReferenceList.add(makeDocumentReference(patient, organization, documentResource)); - } - } - - Composition composition = - makeOpComposition.makeOPCompositionResource( - patient, - opConsultationRequest.getVisitDate(), - encounter, - practitionerList, - organization, - chiefComplaintList, - physicalObservationList, - allergieList, - medicationList, - medicalHistoryList, - familyMemberHistoryList, - investigationAdviceList, - followupList, - procedureList, - referralList, - otherObservationList, - documentReferenceList); - - Bundle bundle = new Bundle(); - bundle.setId(UUID.randomUUID().toString()); - bundle.setType(Bundle.BundleType.DOCUMENT); - bundle.setTimestampElement(Utils.getCurrentTimeStamp()); - bundle.setMeta(makeBundleMetaResource.getMeta()); - bundle.setIdentifier( - new Identifier() - .setSystem(BundleUrlIdentifier.WRAPPER_URL) - .setValue(opConsultationRequest.getCareContextReference())); - List entries = new ArrayList<>(); - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.COMPOSITION + "/" + composition.getId()) - .setResource(composition)); - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.PATIENT + "/" + patient.getId()) - .setResource(patient)); - for (Practitioner practitioner : practitionerList) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.PRACTITIONER + "/" + practitioner.getId()) - .setResource(practitioner)); - } - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.ENCOUNTER + "/" + encounter.getId()) - .setResource(encounter)); - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.ORGANISATION + "/" + organization.getId()) - .setResource(organization)); - - for (Condition complaint : chiefComplaintList) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.CHIEF_COMPLAINTS + "/" + complaint.getId()) - .setResource(complaint)); - } - for (Observation physicalObservation : physicalObservationList) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl( - BundleResourceIdentifier.PHYSICAL_EXAMINATION - + "/" - + physicalObservation.getId()) - .setResource(physicalObservation)); - } - for (AllergyIntolerance allergyIntolerance : allergieList) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl( - BundleResourceIdentifier.ALLERGY_INTOLERANCE + "/" + allergyIntolerance.getId()) - .setResource(allergyIntolerance)); - } - for (Condition medicalHistory : medicalHistoryList) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.MEDICAL_HISTORY + "/" + medicalHistory.getId()) - .setResource(medicalHistory)); - } - for (FamilyMemberHistory familyMemberHistory : familyMemberHistoryList) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl( - BundleResourceIdentifier.FAMILY_HISTORY + "/" + familyMemberHistory.getId()) - .setResource(familyMemberHistory)); - } - for (ServiceRequest investigation : investigationAdviceList) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl( - BundleResourceIdentifier.INVESTIGATION_ADVICE + "/" + investigation.getId()) - .setResource(investigation)); - } - for (MedicationRequest medicationRequest : medicationList) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl( - BundleResourceIdentifier.MEDICATION_REQUEST + "/" + medicationRequest.getId()) - .setResource(medicationRequest)); - } - for (Condition medicationCondition : medicationConditionList) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.CONDITION + "/" + medicationCondition.getId()) - .setResource(medicationCondition)); - } - for (Appointment followUp : followupList) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.FOLLOW_UP + "/" + followUp.getId()) - .setResource(followUp)); - } - for (Procedure procedure : procedureList) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.PROCEDURE + "/" + procedure.getId()) - .setResource(procedure)); - } - for (ServiceRequest referral : referralList) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.REFERRAL + "/" + referral.getId()) - .setResource(referral)); - } - for (Observation observation : otherObservationList) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.OTHER_OBSERVATIONS + "/" + observation.getId()) - .setResource(observation)); - } - for (DocumentReference documentReference : documentReferenceList) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl( - BundleResourceIdentifier.DOCUMENT_REFERENCE + "/" + documentReference.getId()) - .setResource(documentReference)); - } - bundle.setEntry(entries); - return BundleResponse.builder().bundle(bundle).build(); - } catch (Exception e) { - if (e instanceof InvalidDataAccessResourceUsageException) { - log.error(e.getMessage()); - return BundleResponse.builder() - .error( - new ErrorResponse( - ErrorCode.DB_ERROR, - " JDBCException Generic SQL Related Error, kindly check logs.")) - .build(); - } - return BundleResponse.builder() - .error(ErrorResponse.builder().code("1000").message(e.getMessage()).build()) - .build(); - } - } - - private DocumentReference makeDocumentReference( - Patient patient, Organization organization, DocumentResource documentResource) - throws ParseException { - return makeDocumentResource.getDocument( - patient, - organization, - documentResource, - BundleCompositionIdentifier.RECORD_ARTIFACT_CODE, - BundleCompositionIdentifier.RECORD_ARTIFACT); - } - - private List makeOtherObservations( - Patient patient, - List practitionerList, - OPConsultationRequest opConsultationRequest) - throws ParseException { - return Optional.ofNullable(opConsultationRequest.getOtherObservations()) - .orElse(Collections.emptyList()) - .stream() - .map( - StreamUtils.wrapException( - observation -> - makeObservationResource.getObservation(patient, practitionerList, observation))) - .toList(); - } - - private List makeReferralList( - OPConsultationRequest opConsultationRequest, - Patient patient, - List practitionerList) - throws ParseException { - return Optional.ofNullable(opConsultationRequest.getReferrals()) - .orElse(Collections.emptyList()) - .stream() - .map( - StreamUtils.wrapException( - referral -> - makeServiceRequestResource.getServiceRequest( - patient, practitionerList, referral, opConsultationRequest.getVisitDate()))) - .toList(); - } - - private List makeProcedureList( - OPConsultationRequest opConsultationRequest, Patient patient) throws ParseException { - return Optional.ofNullable(opConsultationRequest.getProcedures()) - .orElse(Collections.emptyList()) - .stream() - .map( - StreamUtils.wrapException( - procedure -> makeProcedureResource.getProcedure(patient, procedure))) - .toList(); - } - - private List makeFollowupList( - Patient patient, OPConsultationRequest opConsultationRequest) throws ParseException { - return Optional.ofNullable(opConsultationRequest.getFollowups()) - .orElse(Collections.emptyList()) - .stream() - .map( - StreamUtils.wrapException( - item -> { - Appointment appointment = new Appointment(); - appointment.setId(UUID.randomUUID().toString()); - appointment.setStatus(Appointment.AppointmentStatus.PROPOSED); - appointment.setParticipant( - Collections.singletonList( - new Appointment.AppointmentParticipantComponent() - .setActor( - new Reference() - .setReference( - BundleResourceIdentifier.PATIENT + "/" + patient.getId())) - .setStatus(Appointment.ParticipationStatus.ACCEPTED))); - appointment.setStart( - Utils.getFormattedDateTime(item.getAppointmentTime()) - .getValue()); // TODO in UTC format - appointment.addReasonCode(new CodeableConcept().setText(item.getReason())); - appointment.setServiceType( - Collections.singletonList( - new CodeableConcept().setText(item.getServiceType()))); - return appointment; - })) - .toList(); - } - - private List makeInvestigationAdviceList( - OPConsultationRequest opConsultationRequest, - Patient patient, - List practitionerList) - throws ParseException { - return Optional.ofNullable(opConsultationRequest.getServiceRequests()) - .orElse(Collections.emptyList()) - .stream() - .map( - StreamUtils.wrapException( - investigation -> - makeServiceRequestResource.getServiceRequest( - patient, - practitionerList, - investigation, - opConsultationRequest.getVisitDate()))) - .toList(); - } - - private List makeFamilyMemberHistory( - Patient patient, OPConsultationRequest opConsultationRequest) throws ParseException { - return Optional.ofNullable(opConsultationRequest.getFamilyHistories()) - .orElse(Collections.emptyList()) - .stream() - .map( - StreamUtils.wrapException( - family -> makeFamilyMemberResource.getFamilyHistory(patient, family))) - .toList(); - } - - private List makeMedicalHistoryList( - OPConsultationRequest opConsultationRequest, Patient patient) throws ParseException { - return Optional.ofNullable(opConsultationRequest.getMedicalHistories()) - .orElse(Collections.emptyList()) - .stream() - .map( - StreamUtils.wrapException( - medicalHistory -> - makeConditionResource.getCondition( - medicalHistory.getComplaint(), - patient, - medicalHistory.getRecordedDate(), - medicalHistory.getDateRange()))) - .toList(); - } - - private List makeAllergiesList( - Patient patient, - List practitionerList, - OPConsultationRequest opConsultationRequest) { - - return Optional.ofNullable(opConsultationRequest.getAllergies()).orElse(List.of()).stream() - .filter(allergy -> allergy != null && !allergy.isBlank()) - .map( - StreamUtils.wrapException( - allergy -> - makeAllergyToleranceResource.getAllergy( - patient, practitionerList, allergy, opConsultationRequest.getVisitDate()))) - .toList(); - } - - private List makePhysicalObservations( - OPConsultationRequest opConsultationRequest, - Patient patient, - List practitionerList) - throws ParseException { - return Optional.ofNullable(opConsultationRequest.getPhysicalExaminations()) - .orElse(Collections.emptyList()) - .stream() - .map( - StreamUtils.wrapException( - physicalObservation -> - makeObservationResource.getObservation( - patient, practitionerList, physicalObservation))) - .toList(); - } - - private List makeCheifComplaintsList( - OPConsultationRequest opConsultationRequest, Patient patient) throws ParseException { - return Optional.ofNullable(opConsultationRequest.getChiefComplaints()) - .orElse(Collections.emptyList()) - .stream() - .map( - StreamUtils.wrapException( - complaint -> - makeConditionResource.getCondition( - complaint.getComplaint(), - patient, - complaint.getRecordedDate(), - complaint.getDateRange()))) - .toList(); - } -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/PrescriptionConverter.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/PrescriptionConverter.java deleted file mode 100644 index 25a0107c..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/PrescriptionConverter.java +++ /dev/null @@ -1,197 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.converter; - -import com.nha.abdm.fhir.mapper.Utils; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.ErrorCode; -import com.nha.abdm.fhir.mapper.rest.common.constants.ResourceProfileIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.helpers.BundleResponse; -import com.nha.abdm.fhir.mapper.rest.common.helpers.DocumentResource; -import com.nha.abdm.fhir.mapper.rest.common.helpers.ErrorResponse; -import com.nha.abdm.fhir.mapper.rest.dto.compositions.MakePrescriptionComposition; -import com.nha.abdm.fhir.mapper.rest.dto.resources.*; -import com.nha.abdm.fhir.mapper.rest.exceptions.StreamUtils; -import com.nha.abdm.fhir.mapper.rest.requests.PrescriptionRequest; -import com.nha.abdm.fhir.mapper.rest.requests.helpers.PrescriptionResource; -import java.text.ParseException; -import java.util.*; -import org.hl7.fhir.r4.model.*; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.dao.InvalidDataAccessResourceUsageException; -import org.springframework.stereotype.Service; - -@Service -public class PrescriptionConverter { - private static final Logger log = LoggerFactory.getLogger(PrescriptionConverter.class); - private final MakeOrganisationResource makeOrganisationResource; - - private final MakePatientResource makePatientResource; - - private final MakePractitionerResource makePractitionerResource; - private final MakeBundleMetaResource makeBundleMetaResource; - private final MakeMedicationRequestResource makeMedicationRequestResource; - private final MakeEncounterResource makeEncounterResource; - private final MakePrescriptionComposition makePrescriptionComposition; - private final MakeConditionResource makeConditionResource; - - public PrescriptionConverter( - MakeOrganisationResource makeOrganisationResource, - MakePatientResource makePatientResource, - MakePractitionerResource makePractitionerResource, - MakeBundleMetaResource makeBundleMetaResource, - MakeMedicationRequestResource makeMedicationRequestResource, - MakeEncounterResource makeEncounterResource, - MakePrescriptionComposition makePrescriptionComposition, - MakeConditionResource makeConditionResource) { - this.makeOrganisationResource = makeOrganisationResource; - this.makePatientResource = makePatientResource; - this.makePractitionerResource = makePractitionerResource; - this.makeBundleMetaResource = makeBundleMetaResource; - this.makeMedicationRequestResource = makeMedicationRequestResource; - this.makeEncounterResource = makeEncounterResource; - this.makePrescriptionComposition = makePrescriptionComposition; - this.makeConditionResource = makeConditionResource; - } - - public BundleResponse convertToPrescriptionBundle(PrescriptionRequest prescriptionRequest) - throws ParseException { - try { - Organization organization = - Objects.nonNull(prescriptionRequest.getOrganisation()) - ? makeOrganisationResource.getOrganization(prescriptionRequest.getOrganisation()) - : null; - - Patient patient = makePatientResource.getPatient(prescriptionRequest.getPatient()); - - List practitionerList = - Optional.ofNullable(prescriptionRequest.getPractitioners()) - .orElse(Collections.emptyList()) - .stream() - .map(StreamUtils.wrapException(makePractitionerResource::getPractitioner)) - .toList(); - List medicationRequestList = new ArrayList<>(); - List medicationConditionList = new ArrayList<>(); - for (PrescriptionResource item : prescriptionRequest.getPrescriptions()) { - Condition condition = - item.getReason() != null - ? makeConditionResource.getCondition( - item.getReason(), patient, prescriptionRequest.getAuthoredOn(), null) - : null; - medicationRequestList.add( - makeMedicationRequestResource.getMedicationResource( - prescriptionRequest.getAuthoredOn(), - item, - condition, - organization, - practitionerList, - patient)); - if (condition != null) { - medicationConditionList.add(condition); - } - } - Encounter encounter = - makeEncounterResource.getEncounter( - patient, - prescriptionRequest.getEncounter() != null - ? prescriptionRequest.getEncounter() - : null, - prescriptionRequest.getAuthoredOn()); - List documentList = new ArrayList<>(); - if (prescriptionRequest.getDocuments() != null) { - for (DocumentResource documentResource : prescriptionRequest.getDocuments()) { - Binary binary = new Binary(); - binary.setMeta( - new Meta() - .setLastUpdatedElement(Utils.getCurrentTimeStamp()) - .addProfile(ResourceProfileIdentifier.PROFILE_BINARY)); - binary.setContent(documentResource.getData()); - binary.setContentType(documentResource.getContentType()); - binary.setId(UUID.randomUUID().toString()); - documentList.add(binary); - } - } - Composition composition = - makePrescriptionComposition.makeCompositionResource( - patient, - practitionerList, - organization, - prescriptionRequest.getAuthoredOn(), - encounter, - medicationRequestList, - documentList); - - Bundle bundle = new Bundle(); - bundle.setId(UUID.randomUUID().toString()); - bundle.setType(Bundle.BundleType.DOCUMENT); - bundle.setTimestampElement(Utils.getCurrentTimeStamp()); - bundle.setMeta(makeBundleMetaResource.getMeta()); - bundle.setIdentifier( - new Identifier() - .setSystem(BundleUrlIdentifier.WRAPPER_URL) - .setValue(prescriptionRequest.getCareContextReference())); - List entries = new ArrayList<>(); - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.COMPOSITION + "/" + composition.getId()) - .setResource(composition)); - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.PATIENT + "/" + patient.getId()) - .setResource(patient)); - for (Practitioner practitioner : practitionerList) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.PRACTITIONER + "/" + practitioner.getId()) - .setResource(practitioner)); - } - if (Objects.nonNull(organization)) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.ORGANISATION + "/" + organization.getId()) - .setResource(organization)); - } - if (Objects.nonNull(encounter)) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.ENCOUNTER + "/" + encounter.getId()) - .setResource(encounter)); - } - for (MedicationRequest medicationRequest : medicationRequestList) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl( - BundleResourceIdentifier.MEDICATION_REQUEST + "/" + medicationRequest.getId()) - .setResource(medicationRequest)); - } - for (Condition medicationCondition : medicationConditionList) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.CONDITION + "/" + medicationCondition.getId()) - .setResource(medicationCondition)); - } - for (Binary binary : documentList) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.BINARY + "/" + binary.getId()) - .setResource(binary)); - } - bundle.setEntry(entries); - return BundleResponse.builder().bundle(bundle).build(); - } catch (Exception e) { - if (e instanceof InvalidDataAccessResourceUsageException) { - log.error(e.getMessage()); - return BundleResponse.builder() - .error( - new ErrorResponse( - ErrorCode.DB_ERROR, - " JDBCException Generic SQL Related Error, kindly check logs.")) - .build(); - } - return BundleResponse.builder() - .error(ErrorResponse.builder().code("1000").message(e.getMessage()).build()) - .build(); - } - } -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/WellnessRecordConverter.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/WellnessRecordConverter.java deleted file mode 100644 index 709839fb..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/WellnessRecordConverter.java +++ /dev/null @@ -1,304 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.converter; - -import com.nha.abdm.fhir.mapper.Utils; -import com.nha.abdm.fhir.mapper.rest.common.constants.*; -import com.nha.abdm.fhir.mapper.rest.common.helpers.BundleResponse; -import com.nha.abdm.fhir.mapper.rest.common.helpers.ErrorResponse; -import com.nha.abdm.fhir.mapper.rest.dto.compositions.MakeWellnessComposition; -import com.nha.abdm.fhir.mapper.rest.dto.resources.*; -import com.nha.abdm.fhir.mapper.rest.exceptions.StreamUtils; -import com.nha.abdm.fhir.mapper.rest.requests.WellnessRecordRequest; -import java.util.*; -import org.hl7.fhir.r4.model.*; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.dao.InvalidDataAccessResourceUsageException; -import org.springframework.stereotype.Service; - -@Service -public class WellnessRecordConverter { - private static final Logger log = LoggerFactory.getLogger(WellnessRecordConverter.class); - private final MakeOrganisationResource makeOrganisationResource; - private final MakeBundleMetaResource makeBundleMetaResource; - - private final MakePatientResource makePatientResource; - - private final MakePractitionerResource makePractitionerResource; - private final MakeDocumentResource makeDocumentResource; - private final MakeEncounterResource makeEncounterResource; - private final MakeObservationResource makeObservationResource; - private final MakeWellnessObservationResource makeWellnessObservationResource; - private final MakeWellnessComposition makeWellnessComposition; - - public WellnessRecordConverter( - MakeOrganisationResource makeOrganisationResource, - MakeBundleMetaResource makeBundleMetaResource, - MakePatientResource makePatientResource, - MakePractitionerResource makePractitionerResource, - MakeDocumentResource makeDocumentResource, - MakeEncounterResource makeEncounterResource, - MakeObservationResource makeObservationResource, - MakeWellnessObservationResource makeWellnessObservationResource, - MakeWellnessComposition makeWellnessComposition) { - this.makeOrganisationResource = makeOrganisationResource; - this.makeBundleMetaResource = makeBundleMetaResource; - this.makePatientResource = makePatientResource; - this.makePractitionerResource = makePractitionerResource; - this.makeDocumentResource = makeDocumentResource; - this.makeEncounterResource = makeEncounterResource; - this.makeObservationResource = makeObservationResource; - this.makeWellnessObservationResource = makeWellnessObservationResource; - this.makeWellnessComposition = makeWellnessComposition; - } - - public BundleResponse getWellnessBundle(WellnessRecordRequest wellnessRecordRequest) { - try { - Organization organization = - makeOrganisationResource.getOrganization(wellnessRecordRequest.getOrganisation()); - - Patient patient = makePatientResource.getPatient(wellnessRecordRequest.getPatient()); - - List practitionerList = - Optional.ofNullable(wellnessRecordRequest.getPractitioners()) - .orElse(Collections.emptyList()) - .stream() - .map(StreamUtils.wrapException(makePractitionerResource::getPractitioner)) - .toList(); - - Encounter encounter = - makeEncounterResource.getEncounter( - patient, - wellnessRecordRequest.getEncounter() != null - ? wellnessRecordRequest.getEncounter() - : null, - wellnessRecordRequest.getAuthoredOn()); - - List vitalSignsList = - Optional.ofNullable(wellnessRecordRequest.getVitalSigns()) - .orElse(Collections.emptyList()) - .stream() - .map( - StreamUtils.wrapException( - vitalSign -> - makeWellnessObservationResource.getObservation( - patient, - practitionerList, - vitalSign, - BundleFieldIdentifier.VITAL_SIGNS))) - .toList(); - - List bodyMeasurementList = - Optional.ofNullable(wellnessRecordRequest.getBodyMeasurements()) - .filter(Objects::nonNull) - .orElse(Collections.emptyList()) - .stream() - .map( - StreamUtils.wrapException( - bodyMeasurement -> - makeWellnessObservationResource.getObservation( - patient, - practitionerList, - bodyMeasurement, - BundleFieldIdentifier.BODY_MEASUREMENT))) - .toList(); - - List physicalActivityList = - Optional.ofNullable(wellnessRecordRequest.getPhysicalActivities()) - .orElse(Collections.emptyList()) - .stream() - .map( - StreamUtils.wrapException( - physicalActivity -> - makeWellnessObservationResource.getObservation( - patient, - practitionerList, - physicalActivity, - BundleFieldIdentifier.PHYSICAL_ACTIVITY))) - .toList(); - - List generalAssessmentList = - Optional.ofNullable(wellnessRecordRequest.getGeneralAssessments()) - .orElse(Collections.emptyList()) - .stream() - .map( - StreamUtils.wrapException( - generalAssessment -> - makeWellnessObservationResource.getObservation( - patient, - practitionerList, - generalAssessment, - BundleFieldIdentifier.GENERAL_ASSESSMENT))) - .toList(); - - List womanHealthList = - Optional.ofNullable(wellnessRecordRequest.getWomanHealths()) - .orElse(Collections.emptyList()) - .stream() - .map( - StreamUtils.wrapException( - womanHealth -> - makeWellnessObservationResource.getObservation( - patient, - practitionerList, - womanHealth, - BundleFieldIdentifier.WOMAN_HEALTH))) - .toList(); - - List lifeStyleList = - Optional.ofNullable(wellnessRecordRequest.getLifeStyles()) - .orElse(Collections.emptyList()) - .stream() - .map( - StreamUtils.wrapException( - lifeStyle -> - makeWellnessObservationResource.getObservation( - patient, - practitionerList, - lifeStyle, - BundleFieldIdentifier.LIFE_STYLE))) - .toList(); - - List otherObservationList = - Optional.ofNullable(wellnessRecordRequest.getOtherObservations()) - .orElse(Collections.emptyList()) - .stream() - .map( - StreamUtils.wrapException( - otherObservation -> - makeObservationResource.getObservation( - patient, practitionerList, otherObservation))) - .toList(); - - List documentReferenceList = - Optional.ofNullable(wellnessRecordRequest.getDocuments()) - .orElse(Collections.emptyList()) - .stream() - .map( - StreamUtils.wrapException( - documentResource -> { - return makeDocumentResource.getDocument( - patient, - organization, - documentResource, - BundleCompositionIdentifier.HEALTH_DOCUMENT_CODE, - BundleCompositionIdentifier.HEALTH_DOCUMENT); - })) - .toList(); - - Composition composition = - makeWellnessComposition.makeWellnessComposition( - patient, - wellnessRecordRequest.getAuthoredOn(), - encounter, - practitionerList, - organization, - vitalSignsList, - bodyMeasurementList, - physicalActivityList, - generalAssessmentList, - womanHealthList, - lifeStyleList, - otherObservationList, - documentReferenceList); - - Bundle bundle = new Bundle(); - bundle.setId(UUID.randomUUID().toString()); - bundle.setType(Bundle.BundleType.DOCUMENT); - bundle.setTimestampElement(Utils.getCurrentTimeStamp()); - bundle.setMeta(makeBundleMetaResource.getMeta()); - bundle.setIdentifier( - new Identifier() - .setSystem(BundleUrlIdentifier.WRAPPER_URL) - .setValue(wellnessRecordRequest.getCareContextReference())); - List entries = new ArrayList<>(); - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.COMPOSITION + "/" + composition.getId()) - .setResource(composition)); - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.PATIENT + "/" + patient.getId()) - .setResource(patient)); - for (Practitioner practitioner : practitionerList) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.PRACTITIONER + "/" + practitioner.getId()) - .setResource(practitioner)); - } - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.ENCOUNTER + "/" + encounter.getId()) - .setResource(encounter)); - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.ORGANISATION + "/" + organization.getId()) - .setResource(organization)); - - for (Observation observation : vitalSignsList) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.VITAL_SIGNS + "/" + observation.getId()) - .setResource(observation)); - } - for (Observation observation : bodyMeasurementList) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.BODY_MEASUREMENT + "/" + observation.getId()) - .setResource(observation)); - } - for (Observation observation : physicalActivityList) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.PHYSICAL_ACTIVITY + "/" + observation.getId()) - .setResource(observation)); - } - for (Observation observation : generalAssessmentList) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.GENERAL_ASSESSMENT + "/" + observation.getId()) - .setResource(observation)); - } - for (Observation observation : womanHealthList) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.WOMAN_HEALTH + "/" + observation.getId()) - .setResource(observation)); - } - for (Observation observation : lifeStyleList) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.LIFE_STYLE + "/" + observation.getId()) - .setResource(observation)); - } - for (Observation observation : otherObservationList) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl(BundleResourceIdentifier.OTHER_OBSERVATIONS + "/" + observation.getId()) - .setResource(observation)); - } - for (DocumentReference documentReference : documentReferenceList) { - entries.add( - new Bundle.BundleEntryComponent() - .setFullUrl( - BundleResourceIdentifier.DOCUMENT_REFERENCE + "/" + documentReference.getId()) - .setResource(documentReference)); - } - bundle.setEntry(entries); - return BundleResponse.builder().bundle(bundle).build(); - } catch (Exception e) { - if (e instanceof InvalidDataAccessResourceUsageException) { - log.error(e.getMessage()); - return BundleResponse.builder() - .error( - new ErrorResponse( - ErrorCode.DB_ERROR, - " JDBCException Generic SQL Related Error, kindly check logs.")) - .build(); - } - return BundleResponse.builder() - .error(ErrorResponse.builder().code("1000").message(e.getMessage()).build()) - .build(); - } - } -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/config/DbLoader.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/config/DbLoader.java deleted file mode 100644 index 5e7816ae..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/config/DbLoader.java +++ /dev/null @@ -1,144 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.database.h2.config; - -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.nha.abdm.fhir.mapper.rest.database.h2.tables.*; -import jakarta.annotation.PostConstruct; -import jakarta.persistence.EntityManager; -import jakarta.transaction.Transactional; -import java.io.IOException; -import java.io.InputStream; -import java.util.List; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.core.io.Resource; -import org.springframework.core.io.support.PathMatchingResourcePatternResolver; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Component; -import org.springframework.transaction.PlatformTransactionManager; -import org.springframework.transaction.support.TransactionTemplate; - -@Component -public class DbLoader { - private final ApplicationContext applicationContext; - private final ObjectMapper dbMapper; - private static final Logger log = LoggerFactory.getLogger(DbLoader.class); - - @Autowired private PlatformTransactionManager transactionManager; - - public DbLoader(ApplicationContext applicationContext) { - this.applicationContext = applicationContext; - this.dbMapper = new ObjectMapper(); - } - - @PostConstruct - public void loadData() throws IOException { - PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); - Resource[] resources = resolver.getResources("classpath:/snomed/*.json"); - - if (resources == null || resources.length == 0) { - throw new IllegalStateException( - "No JSON files found in the 'snomed' folder on the classpath."); - } - - TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager); - - transactionTemplate.execute( - status -> { - try { - for (Resource resource : resources) { - processResource(resource); - } - } catch (Exception e) { - status.setRollbackOnly(); - throw new RuntimeException("Error loading data", e); - } - return null; - }); - } - - private void processResource(Resource resource) { - try (InputStream inputStream = resource.getInputStream()) { - String fileName = resource.getFilename(); - if (fileName == null || !fileName.endsWith(".json")) { - log.warn("Skipping invalid resource: {}", fileName); - return; - } - - String entityName = fileName.replace(".json", ""); - String beanName = entityName.substring(0, 1).toLowerCase() + entityName.substring(1) + "Repo"; - - if (applicationContext.containsBean(beanName)) { - - JpaRepository repository = - (JpaRepository) applicationContext.getBean(beanName); - - List entities = - (List) dbMapper.readValue(inputStream, getTypeReference(entityName)); - repository.saveAll(entities); - - log.info("Loaded {} records into {}", entities.size(), entityName); - - addIndexesTransactional(entityName); - } else { - log.info("No repository bean found for {}", entityName); - } - } catch (Exception e) { - log.error("Error processing resource: {}", resource.getFilename(), e); - throw new RuntimeException(e); - } - } - - private TypeReference getTypeReference(String entityName) { - return switch (entityName) { - case "SnomedConditionProcedure" -> new TypeReference>() {}; - case "SnomedDiagnostic" -> new TypeReference>() {}; - case "SnomedEncounter" -> new TypeReference>() {}; - case "SnomedMedicineRoute" -> new TypeReference>() {}; - case "SnomedMedicine" -> new TypeReference>() {}; - case "SnomedObservation" -> new TypeReference>() {}; - case "SnomedSpecimen" -> new TypeReference>() {}; - case "SnomedVaccine" -> new TypeReference>() {}; - default -> throw new IllegalArgumentException("Unknown entity name: " + entityName); - }; - } - - @Transactional - public void addIndexesTransactional(String entityName) { - - String tableName = "\"" + convertToSnakeCase(entityName) + "\""; - String indexName = "idx_" + convertToSnakeCase(entityName) + "_display_code"; - String sql = - switch (entityName) { - case "SnomedEncounter" -> - "CREATE INDEX " + indexName + " ON " + tableName + " (\"code\", \"display\");"; - case "SnomedDiagnostic" -> - "CREATE INDEX " + indexName + " ON " + tableName + " (\"code\", \"display\");"; - case "SnomedConditionProcedure" -> - "CREATE INDEX " + indexName + " ON " + tableName + " (\"code\", \"display\");"; - case "SnomedMedicineRoute" -> - "CREATE INDEX " + indexName + " ON " + tableName + " (\"code\", \"display\");"; - case "SnomedMedicine" -> - "CREATE INDEX " + indexName + " ON " + tableName + " (\"code\", \"display\");"; - case "SnomedObservation" -> - "CREATE INDEX " + indexName + " ON " + tableName + " (\"code\", \"display\");"; - case "SnomedSpecimen" -> - "CREATE INDEX " + indexName + " ON " + tableName + " (\"code\", \"display\");"; - case "SnomedVaccine" -> - "CREATE INDEX " + indexName + " ON " + tableName + " (\"code\", \"display\");"; - default -> null; - }; - - if (sql != null) { - EntityManager em = applicationContext.getBean(EntityManager.class); - em.createNativeQuery(sql).executeUpdate(); - } - } - - private String convertToSnakeCase(String className) { - return className.replaceAll("([a-z])([A-Z])", "$1_$2").toLowerCase(); - } -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedConditionProcedureRepo.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedConditionProcedureRepo.java deleted file mode 100644 index 91c47415..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedConditionProcedureRepo.java +++ /dev/null @@ -1,19 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.database.h2.repositories; - -import com.nha.abdm.fhir.mapper.rest.database.h2.tables.SnomedConditionProcedure; -import java.util.List; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; -import org.springframework.stereotype.Repository; - -@Repository -public interface SnomedConditionProcedureRepo - extends JpaRepository { - @Query( - value = - "SELECT * FROM \"snomed_condition_procedure\" sp WHERE sp.\"display\" ILIKE CONCAT('%', :display, '%') LIMIT 20", - nativeQuery = true) - List findByDisplay(@Param("display") String display); -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedDiagnosticRepo.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedDiagnosticRepo.java deleted file mode 100644 index 8ef691f7..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedDiagnosticRepo.java +++ /dev/null @@ -1,18 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.database.h2.repositories; - -import com.nha.abdm.fhir.mapper.rest.database.h2.tables.SnomedDiagnostic; -import java.util.List; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; -import org.springframework.stereotype.Repository; - -@Repository -public interface SnomedDiagnosticRepo extends JpaRepository { - @Query( - value = - "SELECT * FROM \"snomed_diagnostic\" sp WHERE sp.\"display\" ILIKE CONCAT('%', :display, '%') LIMIT 20 ", - nativeQuery = true) - List findByDisplay(@Param("display") String display); -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedEncounterRepo.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedEncounterRepo.java deleted file mode 100644 index f74b634c..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedEncounterRepo.java +++ /dev/null @@ -1,22 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.database.h2.repositories; - -import com.nha.abdm.fhir.mapper.rest.database.h2.tables.SnomedEncounter; -import java.util.List; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; -import org.springframework.stereotype.Repository; - -@Repository -public interface SnomedEncounterRepo extends JpaRepository { - // @Query( - // value = "SELECT sp.code FROM snomed_encounter sp WHERE sp.display LIKE %:display% LIMIT - // 1", - // nativeQuery = true) - @Query( - value = - "SELECT * FROM \"snomed_encounter\" sp WHERE sp.\"display\" ILIKE CONCAT('%', :display, '%') LIMIT 20", - nativeQuery = true) - List findByDisplay(@Param("display") String display); -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedMedicineRepo.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedMedicineRepo.java deleted file mode 100644 index 735d8026..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedMedicineRepo.java +++ /dev/null @@ -1,18 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.database.h2.repositories; - -import com.nha.abdm.fhir.mapper.rest.database.h2.tables.SnomedMedicine; -import java.util.List; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; -import org.springframework.stereotype.Repository; - -@Repository -public interface SnomedMedicineRepo extends JpaRepository { - @Query( - value = - "SELECT * FROM \"snomed_medicine\" sp WHERE sp.\"display\" ILIKE CONCAT('%', :display, '%') LIMIT 20", - nativeQuery = true) - List findByDisplay(@Param("display") String display); -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedMedicineRouteRepo.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedMedicineRouteRepo.java deleted file mode 100644 index 94204511..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedMedicineRouteRepo.java +++ /dev/null @@ -1,18 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.database.h2.repositories; - -import com.nha.abdm.fhir.mapper.rest.database.h2.tables.SnomedMedicineRoute; -import java.util.List; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; -import org.springframework.stereotype.Repository; - -@Repository -public interface SnomedMedicineRouteRepo extends JpaRepository { - @Query( - value = - "SELECT * FROM \"snomed_medicine_route\" sp WHERE sp.\"display\" ILIKE CONCAT('%', :display, '%') LIMIT 20", - nativeQuery = true) - List findByDisplay(@Param("display") String display); -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedObservationRepo.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedObservationRepo.java deleted file mode 100644 index 4c35d81d..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedObservationRepo.java +++ /dev/null @@ -1,18 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.database.h2.repositories; - -import com.nha.abdm.fhir.mapper.rest.database.h2.tables.SnomedObservation; -import java.util.List; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; -import org.springframework.stereotype.Repository; - -@Repository -public interface SnomedObservationRepo extends JpaRepository { - @Query( - value = - "SELECT * FROM \"snomed_observation\" sp WHERE sp.\"display\" ILIKE CONCAT('%', :display, '%') LIMIT 20", - nativeQuery = true) - List findByDisplay(@Param("display") String display); -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedSpecimenRepo.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedSpecimenRepo.java deleted file mode 100644 index 42fde9c5..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedSpecimenRepo.java +++ /dev/null @@ -1,18 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.database.h2.repositories; - -import com.nha.abdm.fhir.mapper.rest.database.h2.tables.SnomedSpecimen; -import java.util.List; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; -import org.springframework.stereotype.Repository; - -@Repository -public interface SnomedSpecimenRepo extends JpaRepository { - @Query( - value = - "SELECT * FROM \"snomed_specimen\" sp WHERE sp.\"display\" ILIKE CONCAT('%', :display, '%') LIMIT 20", - nativeQuery = true) - List findByDisplay(@Param("display") String display); -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedVaccineRepo.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedVaccineRepo.java deleted file mode 100644 index fa95765f..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedVaccineRepo.java +++ /dev/null @@ -1,18 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.database.h2.repositories; - -import com.nha.abdm.fhir.mapper.rest.database.h2.tables.SnomedVaccine; -import java.util.List; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; -import org.springframework.stereotype.Repository; - -@Repository -public interface SnomedVaccineRepo extends JpaRepository { - @Query( - value = - "SELECT * FROM \"snomed_vaccine\" sp WHERE sp.\"display\" ILIKE CONCAT('%', :display, '%') LIMIT 20", - nativeQuery = true) - List findByDisplay(@Param("display") String display); -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/services/Displayable.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/services/Displayable.java deleted file mode 100644 index 081f9ca4..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/services/Displayable.java +++ /dev/null @@ -1,6 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.database.h2.services; - -public interface Displayable { - String getDisplay(); -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/services/SnomedService.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/services/SnomedService.java deleted file mode 100644 index f8a87f01..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/services/SnomedService.java +++ /dev/null @@ -1,270 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.database.h2.services; - -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleFieldIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.SnomedCodeIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.helpers.SnomedResponse; -import com.nha.abdm.fhir.mapper.rest.database.h2.repositories.*; -import com.nha.abdm.fhir.mapper.rest.database.h2.tables.*; -import java.util.*; -import java.util.stream.Collectors; -import org.apache.commons.text.similarity.CosineSimilarity; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -@Service -public class SnomedService { - @Autowired private final SnomedMedicineRepo snomedMedicineRepo; - @Autowired private final SnomedConditionProcedureRepo snomedConditionProcedureRepo; - @Autowired private final SnomedEncounterRepo snomedEncounterRepo; - @Autowired private final SnomedSpecimenRepo snomedSpecimenRepo; - @Autowired private final SnomedObservationRepo snomedObservationRepo; - @Autowired private final SnomedVaccineRepo snomedVaccineRepo; - @Autowired private final SnomedDiagnosticRepo snomedDiagnosticRepo; - @Autowired private final SnomedMedicineRouteRepo snomedMedicineRouteRepo; - - public SnomedService( - SnomedMedicineRepo snomedMedicineRepo, - SnomedConditionProcedureRepo snomedConditionProcedureRepo, - SnomedEncounterRepo snomedEncounterRepo, - SnomedSpecimenRepo snomedSpecimenRepo, - SnomedObservationRepo snomedObservationRepo, - SnomedVaccineRepo snomedVaccineRepo, - SnomedDiagnosticRepo snomedDiagnosticRepo, - SnomedMedicineRouteRepo snomedMedicineRouteRepo) { - this.snomedMedicineRepo = snomedMedicineRepo; - this.snomedConditionProcedureRepo = snomedConditionProcedureRepo; - this.snomedEncounterRepo = snomedEncounterRepo; - this.snomedSpecimenRepo = snomedSpecimenRepo; - this.snomedObservationRepo = snomedObservationRepo; - this.snomedVaccineRepo = snomedVaccineRepo; - this.snomedDiagnosticRepo = snomedDiagnosticRepo; - this.snomedMedicineRouteRepo = snomedMedicineRouteRepo; - } - - public SnomedConditionProcedure getConditionProcedureCode(String display) { - SnomedConditionProcedure snomedCode = - (SnomedConditionProcedure) - fuzzyMatch( - snomedConditionProcedureRepo.findByDisplay(display), - display, - SnomedConditionProcedure.class); - return snomedCode == null - ? SnomedConditionProcedure.builder() - .code(SnomedCodeIdentifier.SNOMED_UNKNOWN) - .display(display) - .build() - : snomedCode; - } - - public List getAllConditionProcedureCode() { - return snomedConditionProcedureRepo.findAll(); - } - - public SnomedDiagnostic getSnomedDiagnosticCode(String display) { - SnomedDiagnostic snomedCode = - (SnomedDiagnostic) - fuzzyMatch( - snomedDiagnosticRepo.findByDisplay(display), display, SnomedDiagnostic.class); - return snomedCode != null - ? snomedCode - : SnomedDiagnostic.builder() - .code(SnomedCodeIdentifier.SNOMED_UNKNOWN) - .display(display) - .build(); - } - - public List getAllSnomedDiagnosticCode() { - return snomedDiagnosticRepo.findAll(); - } - - public SnomedEncounter getSnomedEncounterCode(String display) { - if (display == null) { - return SnomedEncounter.builder() - .code(SnomedCodeIdentifier.SNOMED_ENCOUNTER_AMBULATORY) - .display(BundleFieldIdentifier.AMBULATORY) - .build(); - } - SnomedEncounter snomedCode = - (SnomedEncounter) - fuzzyMatch(snomedEncounterRepo.findByDisplay(display), display, SnomedEncounter.class); - return snomedCode != null - ? snomedCode - : SnomedEncounter.builder() - .code(SnomedCodeIdentifier.SNOMED_ENCOUNTER_AMBULATORY) - .display(display) - .build(); - } - - public List getAllSnomedEncounterCode() { - return snomedEncounterRepo.findAll(); - } - - public SnomedMedicine getSnomedMedicineCode(String display) { - SnomedMedicine snomedCode = - (SnomedMedicine) - fuzzyMatch(snomedMedicineRepo.findByDisplay(display), display, SnomedMedicine.class); - return snomedCode != null - ? snomedCode - : SnomedMedicine.builder() - .code(SnomedCodeIdentifier.SNOMED_UNKNOWN) - .display(display) - .build(); - } - - public List getAllSnomedMedicineCode() { - return snomedMedicineRepo.findAll(); - } - - public SnomedObservation getSnomedObservationCode(String display) { - SnomedObservation snomedObservation = - (SnomedObservation) - fuzzyMatch( - snomedObservationRepo.findByDisplay(display), display, SnomedObservation.class); - return snomedObservation != null - ? snomedObservation - : SnomedObservation.builder() - .code(SnomedCodeIdentifier.SNOMED_UNKNOWN) - .display(display) - .build(); - } - - public List getAllSnomedObservationCode() { - return snomedObservationRepo.findAll(); - } - - public SnomedSpecimen getSnomedSpecimenCode(String display) { - SnomedSpecimen snomedCode = - (SnomedSpecimen) - fuzzyMatch(snomedSpecimenRepo.findByDisplay(display), display, SnomedSpecimen.class); - return snomedCode != null - ? snomedCode - : SnomedSpecimen.builder() - .code(SnomedCodeIdentifier.SNOMED_UNKNOWN) - .display(display) - .build(); - } - - public List getAllSnomedSpecimenCode() { - return snomedSpecimenRepo.findAll(); - } - - public SnomedVaccine getSnomedVaccineCode(String display) { - SnomedVaccine snomedCode = - (SnomedVaccine) - fuzzyMatch(snomedVaccineRepo.findByDisplay(display), display, SnomedVaccine.class); - return snomedCode != null - ? snomedCode - : SnomedVaccine.builder() - .code(SnomedCodeIdentifier.SNOMED_UNKNOWN) - .display(display) - .build(); - } - - public List getAllSnomedVaccineCode() { - return snomedVaccineRepo.findAll(); - } - - public SnomedMedicineRoute getSnomedMedicineRouteCode(String display) { - SnomedMedicineRoute snomedCode = - (SnomedMedicineRoute) - fuzzyMatch( - snomedMedicineRouteRepo.findByDisplay(display), display, SnomedMedicineRoute.class); - return snomedCode != null - ? snomedCode - : SnomedMedicineRoute.builder() - .code(SnomedCodeIdentifier.SNOMED_UNKNOWN) - .display(display) - .build(); - } - - public List getAllSnomedMedicineRouteCode() { - return snomedMedicineRouteRepo.findAll(); - } - - public SnomedResponse getSnomedCodes(String resource) { - if (resource.equalsIgnoreCase(SnomedCodeIdentifier.SNOMED_CONDITION) - || resource.equalsIgnoreCase(SnomedCodeIdentifier.SNOMED_PROCEDURE)) { - return SnomedResponse.builder() - .snomedConditionProcedureCodes(getAllConditionProcedureCode()) - .build(); - } - if (resource.equalsIgnoreCase(SnomedCodeIdentifier.SNOMED_DIAGNOSTICS)) { - return SnomedResponse.builder().snomedDiagnosticCodes(getAllSnomedDiagnosticCode()).build(); - } - if (resource.equalsIgnoreCase(SnomedCodeIdentifier.SNOMED_ENCOUNTER)) { - return SnomedResponse.builder().snomedEncounterCodes(getAllSnomedEncounterCode()).build(); - } - if (resource.equalsIgnoreCase(SnomedCodeIdentifier.SNOMED_MEDICATION_ROUTE)) { - return SnomedResponse.builder() - .snomedMedicineRouteCodes(getAllSnomedMedicineRouteCode()) - .build(); - } - if (resource.equalsIgnoreCase(SnomedCodeIdentifier.SNOMED_MEDICATIONS)) { - return SnomedResponse.builder().snomedMedicineCodes(getAllSnomedMedicineCode()).build(); - } - if (resource.equalsIgnoreCase(SnomedCodeIdentifier.SNOMED_OBSERVATIONS)) { - return SnomedResponse.builder().snomedObservationCodes(getAllSnomedObservationCode()).build(); - } - if (resource.equalsIgnoreCase(SnomedCodeIdentifier.SNOMED_SPECIMEN)) { - return SnomedResponse.builder().snomedSpecimenCodes(getAllSnomedSpecimenCode()).build(); - } - if (resource.equalsIgnoreCase(SnomedCodeIdentifier.SNOMED_VACCINES)) { - return SnomedResponse.builder().snomedVaccineCodes(getAllSnomedVaccineCode()).build(); - } - return null; - } - - private static boolean hasValidWordDifference(String input, String display) { - if (input == null || display == null) return false; - int inputWordCount = countWords(input); - int displayWordCount = countWords(display); - - return inputWordCount >= 1 && displayWordCount <= inputWordCount + 2; - } - - // Count words in a string - private static int countWords(String text) { - if (text == null || text.trim().isEmpty()) return 0; - return text.trim().split("\\s+").length; - } - - private static Map createFrequencyMap(String text) { - String[] tokens = text.toLowerCase().split("\\s+"); - Map frequencyMap = new HashMap<>(); - - for (String token : tokens) { - frequencyMap.put(token, frequencyMap.getOrDefault(token, 0) + 1); - } - return frequencyMap; - } - - public static Object fuzzyMatch( - List list, String input, Class type) { - CosineSimilarity cosineSimilarity = new CosineSimilarity(); - - Map scoreMap = - list.stream() - .filter(type::isInstance) - .map(type::cast) - .filter( - obj -> - hasValidWordDifference( - input, - obj.getDisplay())) // filtering the difference in words not more the input - // +=2 - .collect( - Collectors.toMap( - obj -> obj, - obj -> { - Map inputMap = createFrequencyMap(input); - Map displayMap = createFrequencyMap(obj.getDisplay()); - return cosineSimilarity.cosineSimilarity(inputMap, displayMap); - })); - - return scoreMap.entrySet().stream() - .max(Map.Entry.comparingByValue()) - .map(Map.Entry::getKey) - .orElse(null); - } -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedConditionProcedure.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedConditionProcedure.java deleted file mode 100644 index 64320638..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedConditionProcedure.java +++ /dev/null @@ -1,27 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.database.h2.tables; - -import com.nha.abdm.fhir.mapper.rest.common.constants.SnomedCodeIdentifier; -import com.nha.abdm.fhir.mapper.rest.database.h2.services.Displayable; -import jakarta.persistence.Entity; -import jakarta.persistence.Id; -import jakarta.persistence.Table; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@Entity -@Builder -@NoArgsConstructor -@AllArgsConstructor -@Table(name = "snomed_condition_procedure") -public class SnomedConditionProcedure implements Displayable { - @Id public String code; - - public String display; - - public final String type = - SnomedCodeIdentifier.SNOMED_CONDITION + "/" + SnomedCodeIdentifier.SNOMED_PROCEDURE; -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedDiagnostic.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedDiagnostic.java deleted file mode 100644 index a653bd3a..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedDiagnostic.java +++ /dev/null @@ -1,26 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.database.h2.tables; - -import com.nha.abdm.fhir.mapper.rest.common.constants.SnomedCodeIdentifier; -import com.nha.abdm.fhir.mapper.rest.database.h2.services.Displayable; -import jakarta.persistence.Entity; -import jakarta.persistence.Id; -import jakarta.persistence.Table; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@Entity -@AllArgsConstructor -@NoArgsConstructor -@Table(name = "snomed_diagnostic") -@Builder -public class SnomedDiagnostic implements Displayable { - @Id public String code; - - public String display; - - public final String type = SnomedCodeIdentifier.SNOMED_DIAGNOSTICS; -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedEncounter.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedEncounter.java deleted file mode 100644 index a921b4ee..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedEncounter.java +++ /dev/null @@ -1,26 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.database.h2.tables; - -import com.nha.abdm.fhir.mapper.rest.common.constants.SnomedCodeIdentifier; -import com.nha.abdm.fhir.mapper.rest.database.h2.services.Displayable; -import jakarta.persistence.Entity; -import jakarta.persistence.Id; -import jakarta.persistence.Table; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@Entity -@Builder -@AllArgsConstructor -@NoArgsConstructor -@Table(name = "snomed_encounter") -public class SnomedEncounter implements Displayable { - @Id public String code; - - public String display; - - public final String type = SnomedCodeIdentifier.SNOMED_ENCOUNTER; -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedMedicine.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedMedicine.java deleted file mode 100644 index 9408f5b2..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedMedicine.java +++ /dev/null @@ -1,26 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.database.h2.tables; - -import com.nha.abdm.fhir.mapper.rest.common.constants.SnomedCodeIdentifier; -import com.nha.abdm.fhir.mapper.rest.database.h2.services.Displayable; -import jakarta.persistence.Entity; -import jakarta.persistence.Id; -import jakarta.persistence.Table; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@Entity -@Builder -@AllArgsConstructor -@NoArgsConstructor -@Table(name = "snomed_medicine") -public class SnomedMedicine implements Displayable { - @Id public String code; - - public String display; - - public final String type = SnomedCodeIdentifier.SNOMED_MEDICATIONS; -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedMedicineRoute.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedMedicineRoute.java deleted file mode 100644 index ccb71ae5..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedMedicineRoute.java +++ /dev/null @@ -1,26 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.database.h2.tables; - -import com.nha.abdm.fhir.mapper.rest.common.constants.SnomedCodeIdentifier; -import com.nha.abdm.fhir.mapper.rest.database.h2.services.Displayable; -import jakarta.persistence.Entity; -import jakarta.persistence.Id; -import jakarta.persistence.Table; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@Entity -@Builder -@AllArgsConstructor -@NoArgsConstructor -@Table(name = "snomed_medicine_route") -public class SnomedMedicineRoute implements Displayable { - @Id public String code; - - public String display; - - public final String type = SnomedCodeIdentifier.SNOMED_MEDICATION_ROUTE; -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedObservation.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedObservation.java deleted file mode 100644 index 2bf3409a..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedObservation.java +++ /dev/null @@ -1,26 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.database.h2.tables; - -import com.nha.abdm.fhir.mapper.rest.common.constants.SnomedCodeIdentifier; -import com.nha.abdm.fhir.mapper.rest.database.h2.services.Displayable; -import jakarta.persistence.Entity; -import jakarta.persistence.Id; -import jakarta.persistence.Table; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@Entity -@Builder -@AllArgsConstructor -@NoArgsConstructor -@Table(name = "snomed_observation") -public class SnomedObservation implements Displayable { - @Id public String code; - - public String display; - - public final String type = SnomedCodeIdentifier.SNOMED_OBSERVATIONS; -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedSpecimen.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedSpecimen.java deleted file mode 100644 index a154787c..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedSpecimen.java +++ /dev/null @@ -1,26 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.database.h2.tables; - -import com.nha.abdm.fhir.mapper.rest.common.constants.SnomedCodeIdentifier; -import com.nha.abdm.fhir.mapper.rest.database.h2.services.Displayable; -import jakarta.persistence.Entity; -import jakarta.persistence.Id; -import jakarta.persistence.Table; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@Entity -@AllArgsConstructor -@NoArgsConstructor -@Table(name = "snomed_specimen") -@Builder -public class SnomedSpecimen implements Displayable { - @Id public String code; - - public String display; - - public final String type = SnomedCodeIdentifier.SNOMED_SPECIMEN; -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedVaccine.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedVaccine.java deleted file mode 100644 index f053055f..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedVaccine.java +++ /dev/null @@ -1,26 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.database.h2.tables; - -import com.nha.abdm.fhir.mapper.rest.common.constants.SnomedCodeIdentifier; -import com.nha.abdm.fhir.mapper.rest.database.h2.services.Displayable; -import jakarta.persistence.Entity; -import jakarta.persistence.Id; -import jakarta.persistence.Table; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@Entity -@AllArgsConstructor -@NoArgsConstructor -@Table(name = "snomed_vaccine") -@Builder -public class SnomedVaccine implements Displayable { - @Id public String code; - - public String display; - - public final String type = SnomedCodeIdentifier.SNOMED_VACCINES; -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeDiagnosticComposition.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeDiagnosticComposition.java deleted file mode 100644 index 4c87e3ae..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeDiagnosticComposition.java +++ /dev/null @@ -1,91 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.dto.compositions; - -import com.nha.abdm.fhir.mapper.Utils; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleCompositionIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.ResourceProfileIdentifier; -import java.text.ParseException; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.UUID; -import org.hl7.fhir.r4.model.*; -import org.springframework.stereotype.Service; - -@Service -public class MakeDiagnosticComposition { - public Composition makeCompositionResource( - Patient patient, - String authoredOn, - List practitionerList, - Organization organization, - Encounter encounter, - List diagnosticReportList, - List documentReferenceList) - throws ParseException { - Composition composition = new Composition(); - Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); - Meta meta = new Meta(); - meta.setVersionId("1"); - meta.setLastUpdatedElement(Utils.getCurrentTimeStamp()); - meta.addProfile(ResourceProfileIdentifier.PROFILE_DIAGNOSTIC_REPORT); - composition.setMeta(meta); - CodeableConcept sectionCode = new CodeableConcept(); - Coding typeCoding = new Coding(); - typeCoding.setSystem(BundleUrlIdentifier.SNOMED_URL); - typeCoding.setCode(BundleCompositionIdentifier.DIAGNOSTIC_STUDIES_REPORT_CODE); - typeCoding.setDisplay(BundleCompositionIdentifier.DIAGNOSTIC_STUDIES_REPORT); - sectionCode.addCoding(typeCoding); - composition.setType(sectionCode); - composition.setTitle(BundleCompositionIdentifier.DIAGNOSTIC_STUDIES_REPORT); - sectionComponent.setCode( - new CodeableConcept() - .addCoding(typeCoding) - .setText(BundleCompositionIdentifier.DIAGNOSTIC_STUDIES_REPORT)); - for (DiagnosticReport diagnosticReport : diagnosticReportList) { - sectionComponent.addEntry( - new Reference() - .setReference( - BundleResourceIdentifier.DIAGNOSTIC_REPORT + "/" + diagnosticReport.getId())); - } - for (DocumentReference documentReference : documentReferenceList) { - sectionComponent.addEntry( - new Reference() - .setReference( - BundleResourceIdentifier.DOCUMENT_REFERENCE + "/" + documentReference.getId())); - } - composition.addSection(sectionComponent); - List authorList = new ArrayList<>(); - for (Practitioner practitioner : practitionerList) { - HumanName practionerName = practitioner.getName().get(0); - authorList.add( - new Reference() - .setDisplay(practionerName.getText()) - .setReference(BundleResourceIdentifier.PRACTITIONER + "/" + practitioner.getId())); - } - composition.setCustodian( - new Reference() - .setDisplay(organization.getName()) - .setReference(BundleResourceIdentifier.ORGANISATION + "/" + organization.getId())); - composition.setAuthor(authorList); - if (Objects.nonNull(encounter)) - composition.setEncounter( - new Reference() - .setReference(BundleResourceIdentifier.ENCOUNTER + "/" + encounter.getId())); - HumanName patientName = patient.getName().get(0); - composition.setSubject( - new Reference() - .setDisplay(patientName.getText()) - .setReference(BundleResourceIdentifier.PATIENT + "/" + patient.getId())); - composition.setDateElement(Utils.getFormattedDateTime(authoredOn)); - composition.setStatus(Composition.CompositionStatus.FINAL); - Identifier identifier = new Identifier(); - identifier.setSystem(BundleUrlIdentifier.WRAPPER_URL); - identifier.setValue(UUID.randomUUID().toString()); - composition.setIdentifier(identifier); - composition.setId(UUID.randomUUID().toString()); - return composition; - } -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeDischargeComposition.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeDischargeComposition.java deleted file mode 100644 index fe2a8f99..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeDischargeComposition.java +++ /dev/null @@ -1,302 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.dto.compositions; - -import com.nha.abdm.fhir.mapper.Utils; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleCompositionIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; -import java.text.ParseException; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.UUID; -import org.hl7.fhir.r4.model.*; -import org.springframework.stereotype.Service; - -@Service -public class MakeDischargeComposition { - public Composition makeDischargeCompositionResource( - Patient patient, - String authoredOn, - Encounter encounter, - List practitionerList, - Organization organization, - List chiefComplaintList, - List physicalObservationList, - List allergieList, - List medicationRequestList, - List diagnosticReportList, - List medicalHistoryList, - List familyMemberHistoryList, - CarePlan carePlan, - List procedureList, - List documentReferenceList, - String docCode, - String docName) - throws ParseException { - HumanName patientName = patient.getName().get(0); - HumanName practitionerName = null; - Composition composition = new Composition(); - CodeableConcept typeCode = new CodeableConcept(); - Coding typeCoding = new Coding(); - typeCoding.setSystem(BundleUrlIdentifier.SNOMED_URL); - typeCoding.setCode(BundleCompositionIdentifier.DISCHARGE_SUMMARY_CODE); - typeCoding.setDisplay(BundleCompositionIdentifier.DISCHARGE_SUMMARY); - typeCode.addCoding(typeCoding); - composition.setType(typeCode); - composition.setTitle(BundleCompositionIdentifier.DISCHARGE_SUMMARY); - List authorList = new ArrayList<>(); - for (Practitioner practitioner : practitionerList) { - practitionerName = practitioner.getName().get(0); - authorList.add( - new Reference() - .setReference(BundleResourceIdentifier.PRACTITIONER + "/" + practitioner.getId()) - .setDisplay(practitionerName != null ? practitionerName.getText() : null)); - } - composition.setEncounter( - new Reference().setReference(BundleResourceIdentifier.ENCOUNTER + "/" + encounter.getId())); - composition.setCustodian( - new Reference() - .setReference(BundleResourceIdentifier.ORGANISATION + "/" + organization.getId()) - .setDisplay(organization.getName())); - composition.setAuthor(authorList); - composition.setSubject( - new Reference() - .setReference(BundleResourceIdentifier.PATIENT + "/" + patient.getId()) - .setDisplay(patientName.getText())); - composition.setDateElement(Utils.getFormattedDateTime(authoredOn)); - composition.setStatus(Composition.CompositionStatus.FINAL); - List sectionComponentList = - makeCompositionSection( - patient, - practitionerList, - organization, - chiefComplaintList, - physicalObservationList, - allergieList, - medicationRequestList, - diagnosticReportList, - medicalHistoryList, - familyMemberHistoryList, - carePlan, - procedureList, - documentReferenceList, - docCode, - docName); - if (Objects.nonNull(sectionComponentList)) - for (Composition.SectionComponent sectionComponent : sectionComponentList) - composition.addSection(sectionComponent); - Identifier identifier = new Identifier(); - identifier.setSystem(BundleUrlIdentifier.WRAPPER_URL); - identifier.setValue(UUID.randomUUID().toString()); - composition.setIdentifier(identifier); - composition.setId(UUID.randomUUID().toString()); - return composition; - } - - private List makeCompositionSection( - Patient patient, - List practitionerList, - Organization organization, - List chiefComplaintList, - List physicalObservationList, - List allergieList, - List medicationRequestList, - List diagnosticReportList, - List medicalHistoryList, - List familyMemberHistoryList, - CarePlan carePlan, - List procedureList, - List documentReferenceList, - String docCode, - String docName) { - List sectionComponentList = new ArrayList<>(); - if (!(chiefComplaintList.isEmpty())) { - Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); - sectionComponent.setCode( - new CodeableConcept() - .setText(BundleResourceIdentifier.CHIEF_COMPLAINTS) - .addCoding( - new Coding() - .setSystem(BundleUrlIdentifier.SNOMED_URL) - .setCode(BundleCompositionIdentifier.CHIEF_COMPLAINTS_CODE) - .setDisplay(BundleCompositionIdentifier.CHIEF_COMPLAINTS))); - for (Condition chiefComplaint : chiefComplaintList) { - sectionComponent.addEntry( - new Reference() - .setReference( - BundleResourceIdentifier.CHIEF_COMPLAINTS + "/" + chiefComplaint.getId())); - } - sectionComponentList.add(sectionComponent); - } - if (!(physicalObservationList.isEmpty())) { - Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); - sectionComponent.setCode( - new CodeableConcept() - .setText(BundleResourceIdentifier.PHYSICAL_EXAMINATION) - .addCoding( - new Coding() - .setSystem(BundleUrlIdentifier.SNOMED_URL) - .setCode(BundleCompositionIdentifier.PHYSICAL_EXAMINATION_CODE) - .setDisplay(BundleCompositionIdentifier.PHYSICAL_EXAMINATION))); - for (Observation physicalObservation : physicalObservationList) { - sectionComponent.addEntry( - new Reference() - .setReference( - BundleResourceIdentifier.PHYSICAL_EXAMINATION - + "/" - + physicalObservation.getId())); - } - sectionComponentList.add(sectionComponent); - } - if (!(allergieList.isEmpty())) { - Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); - sectionComponent.setCode( - new CodeableConcept() - .setText(BundleCompositionIdentifier.ALLERGY_RECORD) - .addCoding( - new Coding() - .setSystem(BundleUrlIdentifier.SNOMED_URL) - .setCode(BundleCompositionIdentifier.ALLERGY_RECORD_CODE) - .setDisplay(BundleCompositionIdentifier.ALLERGY_RECORD))); - for (AllergyIntolerance allergyIntolerance : allergieList) { - sectionComponent.addEntry( - new Reference() - .setReference( - BundleResourceIdentifier.ALLERGY_INTOLERANCE - + "/" - + allergyIntolerance.getId())); - } - sectionComponentList.add(sectionComponent); - } - if (!medicalHistoryList.isEmpty()) { - Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); - sectionComponent.setCode( - new CodeableConcept() - .setText(BundleCompositionIdentifier.PAST_MEDICAL_HISTORY) - .addCoding( - new Coding() - .setSystem(BundleUrlIdentifier.SNOMED_URL) - .setCode(BundleCompositionIdentifier.PAST_MEDICAL_CODE) - .setDisplay(BundleCompositionIdentifier.PAST_MEDICAL_HISTORY))); - for (Condition medicalHistory : medicalHistoryList) { - sectionComponent.addEntry( - new Reference() - .setReference( - BundleResourceIdentifier.MEDICAL_HISTORY + "/" + medicalHistory.getId())); - } - sectionComponentList.add(sectionComponent); - } - if (!(familyMemberHistoryList.isEmpty())) { - Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); - sectionComponent.setCode( - new CodeableConcept() - .setText(BundleResourceIdentifier.FAMILY_HISTORY) - .addCoding( - new Coding() - .setSystem(BundleUrlIdentifier.SNOMED_URL) - .setCode(BundleCompositionIdentifier.FAMILY_HISTORY_SECTION_CODE) - .setDisplay(BundleCompositionIdentifier.FAMILY_HISTORY_SECTION))); - for (FamilyMemberHistory familyMemberHistory : familyMemberHistoryList) { - sectionComponent.addEntry( - new Reference() - .setReference( - BundleResourceIdentifier.FAMILY_HISTORY + "/" + familyMemberHistory.getId())); - } - sectionComponentList.add(sectionComponent); - } - if (Objects.nonNull(carePlan)) { - Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); - sectionComponent.setCode( - new CodeableConcept() - .setText(BundleResourceIdentifier.CARE_PLAN) - .addCoding( - new Coding() - .setSystem(BundleUrlIdentifier.SNOMED_URL) - .setCode(BundleCompositionIdentifier.CARE_PLAN_CODE) - .setDisplay(BundleCompositionIdentifier.CARE_PLAN))); - sectionComponent.addEntry( - new Reference() - .setReference(BundleResourceIdentifier.CARE_PLAN + "/" + carePlan.getId())); - sectionComponentList.add(sectionComponent); - } - if (!(medicationRequestList.isEmpty())) { - Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); - sectionComponent.setCode( - new CodeableConcept() - .setText(BundleResourceIdentifier.MEDICAL_HISTORY) - .addCoding( - new Coding() - .setSystem(BundleUrlIdentifier.SNOMED_URL) - .setCode(BundleCompositionIdentifier.MEDICAL_HISTORY_SECTION_CODE) - .setDisplay(BundleCompositionIdentifier.MEDICAL_HISTORY_SECTION))); - for (MedicationRequest medicationRequest : medicationRequestList) { - sectionComponent.addEntry( - new Reference() - .setReference( - BundleResourceIdentifier.MEDICATION_REQUEST - + BundleResourceIdentifier.FAMILY_HISTORY - + "/" - + medicationRequest.getId())); - } - sectionComponentList.add(sectionComponent); - } - if (!(diagnosticReportList.isEmpty())) { - Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); - sectionComponent.setCode( - new CodeableConcept() - .setText(BundleCompositionIdentifier.DIAGNOSTIC_STUDIES_REPORT) - .addCoding( - new Coding() - .setSystem(BundleUrlIdentifier.SNOMED_URL) - .setCode(BundleCompositionIdentifier.DIAGNOSTIC_STUDIES_REPORT_CODE) - .setDisplay(BundleCompositionIdentifier.DIAGNOSTIC_STUDIES_REPORT))); - for (DiagnosticReport diagnosticReport : diagnosticReportList) { - sectionComponent.addEntry( - new Reference() - .setReference( - BundleResourceIdentifier.DIAGNOSTIC_REPORT + "/" + diagnosticReport.getId())); - } - sectionComponentList.add(sectionComponent); - } - if (!(procedureList.isEmpty())) { - Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); - sectionComponent.setCode( - new CodeableConcept() - .setText(BundleCompositionIdentifier.HISTORY_PAST_PROCEDURE) - .addCoding( - new Coding() - .setSystem(BundleUrlIdentifier.SNOMED_URL) - .setCode(BundleCompositionIdentifier.HISTORY_PAST_PROCEDURE_CODE) - .setDisplay(BundleCompositionIdentifier.HISTORY_PAST_PROCEDURE))); - for (Procedure procedure : procedureList) { - sectionComponent.addEntry( - new Reference() - .setReference(BundleResourceIdentifier.PROCEDURE + "/" + procedure.getId())); - } - sectionComponentList.add(sectionComponent); - } - if (!(documentReferenceList.isEmpty())) { - Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); - sectionComponent.setCode( - new CodeableConcept() - .setText(BundleResourceIdentifier.DOCUMENT_REFERENCE) - .addCoding( - new Coding() - .setSystem(BundleUrlIdentifier.SNOMED_URL) - .setCode(docCode) - .setDisplay(docName))); - for (DocumentReference documentReferenceItem : documentReferenceList) { - sectionComponent.addEntry( - new Reference() - .setReference( - BundleResourceIdentifier.DOCUMENT_REFERENCE - + "/" - + documentReferenceItem.getId())); - } - sectionComponentList.add(sectionComponent); - } - - return sectionComponentList; - } -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeHealthDocumentComposition.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeHealthDocumentComposition.java deleted file mode 100644 index cb460938..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeHealthDocumentComposition.java +++ /dev/null @@ -1,83 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.dto.compositions; - -import com.nha.abdm.fhir.mapper.Utils; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleCompositionIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.ResourceProfileIdentifier; -import java.text.ParseException; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.UUID; -import org.hl7.fhir.r4.model.*; -import org.springframework.stereotype.Service; - -@Service -public class MakeHealthDocumentComposition { - public Composition makeCompositionResource( - Patient patient, - String authoredOn, - List practitionerList, - Organization organization, - Encounter encounter, - List documentReferenceList) - throws ParseException { - Composition composition = new Composition(); - Meta meta = new Meta(); - meta.setVersionId("1"); - meta.setLastUpdatedElement(Utils.getCurrentTimeStamp()); - meta.addProfile(ResourceProfileIdentifier.PROFILE_HEALTH_DOCUMENT_RECORD); - composition.setMeta(meta); - Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); - sectionComponent.setTitle(BundleCompositionIdentifier.RECORD_ARTIFACT); - CodeableConcept typeCode = new CodeableConcept(); - Coding typeCoding = new Coding(); - typeCoding.setSystem(BundleUrlIdentifier.SNOMED_URL); - typeCoding.setCode(BundleCompositionIdentifier.RECORD_ARTIFACT_CODE); - typeCoding.setDisplay(BundleCompositionIdentifier.RECORD_ARTIFACT); - typeCode.addCoding(typeCoding); - typeCode.setText(BundleCompositionIdentifier.RECORD_ARTIFACT); - composition.setType(typeCode); - sectionComponent.setCode(typeCode); - for (DocumentReference documentReference : documentReferenceList) { - sectionComponent.addEntry( - new Reference() - .setReference( - BundleResourceIdentifier.DOCUMENT_REFERENCE + "/" + documentReference.getId())); - } - composition.addSection(sectionComponent); - composition.setTitle(BundleCompositionIdentifier.HEALTH_DOCUMENT); - composition.setEncounter( - new Reference().setReference(BundleResourceIdentifier.ENCOUNTER + "/" + encounter.getId())); - List authorList = new ArrayList<>(); - for (Practitioner practitioner : practitionerList) { - HumanName practionerName = practitioner.getName().get(0); - authorList.add( - new Reference() - .setDisplay(practionerName.getText()) - .setReference(BundleResourceIdentifier.PRACTITIONER + "/" + practitioner.getId())); - } - if (Objects.nonNull(organization)) { - composition.setCustodian( - new Reference() - .setDisplay(organization.getName()) - .setReference(BundleResourceIdentifier.ORGANISATION + "/" + organization.getId())); - } - composition.setAuthor(authorList); - HumanName patientName = patient.getName().get(0); - composition.setSubject( - new Reference() - .setDisplay(patientName.getText()) - .setReference(BundleResourceIdentifier.PATIENT + "/" + patient.getId())); - composition.setDateElement(Utils.getFormattedDateTime(authoredOn)); - composition.setStatus(Composition.CompositionStatus.FINAL); - Identifier identifier = new Identifier(); - identifier.setSystem(BundleUrlIdentifier.WRAPPER_URL); - identifier.setValue(UUID.randomUUID().toString()); - composition.setIdentifier(identifier); - composition.setId(UUID.randomUUID().toString()); - return composition; - } -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeImmunizationComposition.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeImmunizationComposition.java deleted file mode 100644 index a6580f99..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeImmunizationComposition.java +++ /dev/null @@ -1,94 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.dto.compositions; - -import com.nha.abdm.fhir.mapper.Utils; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleCompositionIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.ResourceProfileIdentifier; -import java.text.ParseException; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.UUID; -import org.hl7.fhir.r4.model.*; -import org.springframework.stereotype.Service; - -@Service -public class MakeImmunizationComposition { - - public Composition makeCompositionResource( - Patient patient, - List practitionerList, - Organization organization, - String authoredOn, - List immunizationList, - List documentList) - throws ParseException { - Composition composition = new Composition(); - Meta meta = new Meta(); - meta.setVersionId("1"); - meta.setLastUpdatedElement(Utils.getCurrentTimeStamp()); - meta.addProfile(ResourceProfileIdentifier.PROFILE_IMMUNIZATION); - composition.setMeta(meta); - CodeableConcept typeCode = new CodeableConcept(); - Coding typeCoding = new Coding(); - typeCoding.setSystem(BundleUrlIdentifier.SNOMED_URL); - typeCoding.setCode(BundleCompositionIdentifier.IMMUNIZATION_RECORD_CODE); - typeCoding.setDisplay(BundleCompositionIdentifier.IMMUNIZATION_RECORD); - typeCode.addCoding(typeCoding); - composition.setType(typeCode); - composition.setTitle(BundleCompositionIdentifier.IMMUNIZATION_RECORD); - if (Objects.nonNull(organization)) - composition.setCustodian( - new Reference() - .setReference(BundleResourceIdentifier.ORGANISATION + "/" + organization.getId())); - List authorList = new ArrayList<>(); - HumanName practitionerName = null; - for (Practitioner author : practitionerList) { - practitionerName = author.getName().get(0); - authorList.add( - new Reference() - .setReference(BundleResourceIdentifier.PRACTITIONER + "/" + author.getId()) - .setDisplay(practitionerName.getText())); - } - composition.setAuthor(authorList); - HumanName patientName = patient.getName().get(0); - composition.setSubject( - new Reference() - .setReference(BundleResourceIdentifier.PATIENT + "/" + patient.getId()) - .setDisplay(patientName.getText())); - composition.setDateElement(Utils.getFormattedDateTime(authoredOn)); - Composition.SectionComponent immunizationSection = new Composition.SectionComponent(); - immunizationSection.setTitle(BundleResourceIdentifier.IMMUNIZATION); - immunizationSection.setCode( - new CodeableConcept() - .setText(BundleCompositionIdentifier.IMMUNIZATION_RECORD) - .addCoding( - new Coding() - .setCode(BundleCompositionIdentifier.IMMUNIZATION_RECORD_CODE) - .setDisplay(BundleCompositionIdentifier.IMMUNIZATION_RECORD) - .setSystem(BundleUrlIdentifier.SNOMED_URL))); - for (Immunization immunization : immunizationList) { - Reference entryReference = - new Reference() - .setReference(BundleResourceIdentifier.IMMUNIZATION + "/" + immunization.getId()) - .setType(BundleResourceIdentifier.IMMUNIZATION); - immunizationSection.addEntry(entryReference); - } - composition.addSection(immunizationSection); - for (DocumentReference documentReference : documentList) - immunizationSection.addEntry( - new Reference() - .setReference( - BundleResourceIdentifier.DOCUMENT_REFERENCE + "/" + documentReference.getId()) - .setType(BundleResourceIdentifier.DOCUMENT_REFERENCE)); - composition.setStatus(Composition.CompositionStatus.FINAL); - Identifier identifier = new Identifier(); - identifier.setSystem(BundleUrlIdentifier.WRAPPER_URL); - identifier.setValue(UUID.randomUUID().toString()); - composition.setIdentifier(identifier); - composition.setId(UUID.randomUUID().toString()); - return composition; - } -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeOpComposition.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeOpComposition.java deleted file mode 100644 index b8646ab2..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeOpComposition.java +++ /dev/null @@ -1,336 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.dto.compositions; - -import com.nha.abdm.fhir.mapper.Utils; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleCompositionIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; -import java.text.ParseException; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.UUID; -import org.hl7.fhir.r4.model.*; -import org.springframework.stereotype.Service; - -@Service -public class MakeOpComposition { - public Composition makeOPCompositionResource( - Patient patient, - String visitDate, - Encounter encounter, - List practitionerList, - Organization organization, - List chiefComplaintList, - List physicalObservationList, - List allergieList, - List medicationList, - List medicalHistoryList, - List familyMemberHistoryList, - List investigationAdviceList, - List followupList, - List procedureList, - List referralList, - List otherObservationList, - List documentReferenceList) - throws ParseException { - HumanName patientName = patient.getName().get(0); - HumanName practitionerName = null; - Composition composition = new Composition(); - CodeableConcept typeCode = new CodeableConcept(); - Coding typeCoding = new Coding(); - typeCoding.setSystem(BundleUrlIdentifier.SNOMED_URL); - typeCoding.setCode(BundleCompositionIdentifier.CLINICAL_CONSULTATION_REPORT_CODE); - typeCoding.setDisplay(BundleCompositionIdentifier.CLINICAL_CONSULTATION_REPORT); - typeCode.addCoding(typeCoding); - composition.setType(typeCode); - composition.setTitle(BundleCompositionIdentifier.CLINICAL_CONSULTATION_REPORT); - List authorList = new ArrayList<>(); - for (Practitioner practitioner : practitionerList) { - practitionerName = practitioner.getName().get(0); - authorList.add( - new Reference() - .setReference(BundleResourceIdentifier.PRACTITIONER + "/" + practitioner.getId()) - .setDisplay(practitionerName != null ? practitionerName.getText() : null)); - } - composition.setEncounter( - new Reference().setReference(BundleResourceIdentifier.ENCOUNTER + "/" + encounter.getId())); - composition.setCustodian( - new Reference() - .setReference(BundleResourceIdentifier.ORGANISATION + "/" + organization.getId()) - .setDisplay(organization.getName())); - composition.setAuthor(authorList); - composition.setSubject( - new Reference() - .setReference(BundleResourceIdentifier.PATIENT + "/" + patient.getId()) - .setDisplay(patientName.getText())); - composition.setDateElement(Utils.getFormattedDateTime(visitDate)); - composition.setStatus(Composition.CompositionStatus.FINAL); - List sectionComponentList = - makeCompositionSection( - patient, - practitionerList, - organization, - chiefComplaintList, - physicalObservationList, - allergieList, - medicationList, - medicalHistoryList, - familyMemberHistoryList, - investigationAdviceList, - followupList, - procedureList, - referralList, - otherObservationList, - documentReferenceList); - if (Objects.nonNull(sectionComponentList)) - for (Composition.SectionComponent sectionComponent : sectionComponentList) - composition.addSection(sectionComponent); - Identifier identifier = new Identifier(); - identifier.setSystem(BundleUrlIdentifier.WRAPPER_URL); - identifier.setValue(UUID.randomUUID().toString()); - composition.setIdentifier(identifier); - composition.setId(UUID.randomUUID().toString()); - return composition; - } - - private List makeCompositionSection( - Patient patient, - List practitionerList, - Organization organization, - List chiefComplaintList, - List physicalObservationList, - List allergieList, - List medicationList, - List medicalHistoryList, - List familyMemberHistoryList, - List investigationAdviceList, - List followupList, - List procedureList, - List referralList, - List otherObservationList, - List documentReferenceList) { - List sectionComponentList = new ArrayList<>(); - if (chiefComplaintList != null && !chiefComplaintList.isEmpty()) { - Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); - sectionComponent.setCode( - new CodeableConcept() - .setText(BundleCompositionIdentifier.CHIEF_COMPLAINTS) - .addCoding( - new Coding() - .setSystem(BundleUrlIdentifier.SNOMED_URL) - .setCode(BundleCompositionIdentifier.CHIEF_COMPLAINTS_CODE) - .setDisplay(BundleCompositionIdentifier.CHIEF_COMPLAINTS))); - for (Condition chiefComplaint : chiefComplaintList) { - sectionComponent.addEntry( - new Reference() - .setReference( - BundleResourceIdentifier.CHIEF_COMPLAINTS + "/" + chiefComplaint.getId())); - } - sectionComponentList.add(sectionComponent); - } - if (Objects.nonNull(physicalObservationList) && !physicalObservationList.isEmpty()) { - Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); - sectionComponent.setCode( - new CodeableConcept() - .setText(BundleCompositionIdentifier.PHYSICAL_EXAMINATION) - .addCoding( - new Coding() - .setSystem(BundleUrlIdentifier.SNOMED_URL) - .setCode(BundleCompositionIdentifier.PHYSICAL_EXAMINATION_CODE) - .setDisplay(BundleCompositionIdentifier.PHYSICAL_EXAMINATION))); - for (Observation physicalObservation : physicalObservationList) { - sectionComponent.addEntry( - new Reference() - .setReference( - BundleResourceIdentifier.PHYSICAL_EXAMINATION - + "/" - + physicalObservation.getId())); - } - sectionComponentList.add(sectionComponent); - } - if (Objects.nonNull(allergieList) && !allergieList.isEmpty()) { - Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); - sectionComponent.setCode( - new CodeableConcept() - .setText(BundleCompositionIdentifier.ALLERGY_RECORD) - .addCoding( - new Coding() - .setSystem(BundleUrlIdentifier.SNOMED_URL) - .setCode(BundleCompositionIdentifier.ALLERGY_RECORD) - .setDisplay(BundleCompositionIdentifier.ALLERGY_RECORD))); - for (AllergyIntolerance allergyIntolerance : allergieList) { - sectionComponent.addEntry( - new Reference() - .setReference( - BundleResourceIdentifier.ALLERGY_INTOLERANCE - + "/" - + allergyIntolerance.getId())); - } - sectionComponentList.add(sectionComponent); - } - if (Objects.nonNull(medicalHistoryList) && !medicalHistoryList.isEmpty()) { - Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); - sectionComponent.setCode( - new CodeableConcept() - .setText(BundleCompositionIdentifier.MEDICAL_HISTORY_SECTION) - .addCoding( - new Coding() - .setSystem(BundleUrlIdentifier.SNOMED_URL) - .setCode(BundleCompositionIdentifier.MEDICAL_HISTORY_SECTION) - .setDisplay(BundleCompositionIdentifier.MEDICAL_HISTORY_SECTION))); - for (Condition medicalHistory : medicalHistoryList) { - sectionComponent.addEntry( - new Reference() - .setReference( - BundleResourceIdentifier.MEDICAL_HISTORY + "/" + medicalHistory.getId())); - } - sectionComponentList.add(sectionComponent); - } - if (Objects.nonNull(familyMemberHistoryList) && !familyMemberHistoryList.isEmpty()) { - Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); - sectionComponent.setCode( - new CodeableConcept() - .setText(BundleCompositionIdentifier.FAMILY_HISTORY_SECTION) - .addCoding( - new Coding() - .setSystem(BundleUrlIdentifier.SNOMED_URL) - .setCode(BundleCompositionIdentifier.FAMILY_HISTORY_SECTION_CODE) - .setDisplay(BundleCompositionIdentifier.FAMILY_HISTORY_SECTION))); - for (FamilyMemberHistory familyMemberHistory : familyMemberHistoryList) { - sectionComponent.addEntry( - new Reference() - .setReference( - BundleResourceIdentifier.FAMILY_HISTORY + "/" + familyMemberHistory.getId())); - } - sectionComponentList.add(sectionComponent); - } - if (Objects.nonNull(investigationAdviceList) && !investigationAdviceList.isEmpty()) { - Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); - sectionComponent.setCode( - new CodeableConcept() - .setText(BundleCompositionIdentifier.ORDER_DOCUMENT) - .addCoding( - new Coding() - .setSystem(BundleUrlIdentifier.SNOMED_URL) - .setCode(BundleCompositionIdentifier.ORDER_DOCUMENT_CODE) - .setDisplay(BundleCompositionIdentifier.ORDER_DOCUMENT))); - for (ServiceRequest investigation : investigationAdviceList) { - sectionComponent.addEntry( - new Reference() - .setReference( - BundleResourceIdentifier.INVESTIGATION_ADVICE + "/" + investigation.getId())); - } - sectionComponentList.add(sectionComponent); - } - if (Objects.nonNull(medicationList) && !medicationList.isEmpty()) { - Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); - sectionComponent.setCode( - new CodeableConcept() - .setText(BundleCompositionIdentifier.MEDICATION_SUMMARY) - .addCoding( - new Coding() - .setSystem(BundleUrlIdentifier.SNOMED_URL) - .setCode(BundleCompositionIdentifier.MEDICATION_SUMMARY_CODE) - .setDisplay(BundleCompositionIdentifier.MEDICATION_SUMMARY))); - for (MedicationRequest medication : medicationList) { - sectionComponent.addEntry( - new Reference() - .setReference( - BundleResourceIdentifier.MEDICATION_REQUEST + "/" + medication.getId())); - } - sectionComponentList.add(sectionComponent); - } - if (Objects.nonNull(followupList) && !followupList.isEmpty()) { - Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); - sectionComponent.setCode( - new CodeableConcept() - .setText(BundleCompositionIdentifier.FOLLOW_UP) - .addCoding( - new Coding() - .setSystem(BundleUrlIdentifier.SNOMED_URL) - .setCode(BundleCompositionIdentifier.FOLLOW_UP_CODE) - .setDisplay(BundleCompositionIdentifier.FOLLOW_UP))); - for (Appointment followUp : followupList) { - sectionComponent.addEntry( - new Reference() - .setReference(BundleResourceIdentifier.FOLLOW_UP + "/" + followUp.getId())); - } - sectionComponentList.add(sectionComponent); - } - if (Objects.nonNull(procedureList) && !procedureList.isEmpty()) { - Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); - sectionComponent.setCode( - new CodeableConcept() - .setText(BundleCompositionIdentifier.CLINICAL_PROCEDURE) - .addCoding( - new Coding() - .setSystem(BundleUrlIdentifier.SNOMED_URL) - .setCode(BundleCompositionIdentifier.CLINICAL_PROCEDURE_CODE) - .setDisplay(BundleCompositionIdentifier.CLINICAL_PROCEDURE))); - for (Procedure procedure : procedureList) { - sectionComponent.addEntry( - new Reference() - .setReference(BundleResourceIdentifier.PROCEDURE + "/" + procedure.getId())); - } - sectionComponentList.add(sectionComponent); - } - if (Objects.nonNull(referralList) && !referralList.isEmpty()) { - Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); - sectionComponent.setCode( - new CodeableConcept() - .setText(BundleCompositionIdentifier.REFERRAL_TO_SERVICE) - .addCoding( - new Coding() - .setSystem(BundleUrlIdentifier.SNOMED_URL) - .setCode(BundleCompositionIdentifier.REFERRAL_TO_SERVICE_CODE) - .setDisplay(BundleCompositionIdentifier.REFERRAL_TO_SERVICE))); - for (ServiceRequest referral : referralList) { - sectionComponent.addEntry( - new Reference() - .setReference(BundleResourceIdentifier.REFERRAL + "/" + referral.getId())); - } - sectionComponentList.add(sectionComponent); - } - if (Objects.nonNull(otherObservationList) && !otherObservationList.isEmpty()) { - Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); - sectionComponent.setCode( - new CodeableConcept() - .setText(BundleCompositionIdentifier.CLINICAL_FINDING) - .addCoding( - new Coding() - .setSystem(BundleUrlIdentifier.SNOMED_URL) - .setCode(BundleCompositionIdentifier.CLINICAL_FINDING_CODE) - .setDisplay(BundleCompositionIdentifier.CLINICAL_FINDING))); - for (Observation otherObservation : otherObservationList) { - sectionComponent.addEntry( - new Reference() - .setReference( - BundleResourceIdentifier.OTHER_OBSERVATIONS + "/" + otherObservation.getId())); - } - sectionComponentList.add(sectionComponent); - } - if (Objects.nonNull(documentReferenceList) && !documentReferenceList.isEmpty()) { - Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); - sectionComponent.setCode( - new CodeableConcept() - .setText(BundleCompositionIdentifier.CLINICAL_CONSULTATION_REPORT) - .addCoding( - new Coding() - .setSystem(BundleUrlIdentifier.SNOMED_URL) - .setCode(BundleCompositionIdentifier.CLINICAL_CONSULTATION_REPORT_CODE) - .setDisplay(BundleCompositionIdentifier.CLINICAL_CONSULTATION_REPORT))); - for (DocumentReference documentReferenceItem : documentReferenceList) { - sectionComponent.addEntry( - new Reference() - .setReference( - BundleResourceIdentifier.DOCUMENT_REFERENCE - + "/" - + documentReferenceItem.getId())); - } - sectionComponentList.add(sectionComponent); - } - - return sectionComponentList; - } -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakePrescriptionComposition.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakePrescriptionComposition.java deleted file mode 100644 index 1fddb14c..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakePrescriptionComposition.java +++ /dev/null @@ -1,99 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.dto.compositions; - -import com.nha.abdm.fhir.mapper.Utils; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleCompositionIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.ResourceProfileIdentifier; -import java.text.ParseException; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.UUID; -import org.hl7.fhir.r4.model.*; -import org.springframework.stereotype.Service; - -@Service -public class MakePrescriptionComposition { - public Composition makeCompositionResource( - Patient patient, - List practitionerList, - Organization organization, - String authoredOn, - Encounter encounter, - List medicationRequestList, - List documentList) - throws ParseException { - Composition composition = new Composition(); - Meta meta = new Meta(); - meta.setVersionId("1"); - meta.setLastUpdatedElement(Utils.getCurrentTimeStamp()); - meta.addProfile(ResourceProfileIdentifier.PROFILE_PRESCRIPTION_RECORD); - composition.setMeta(meta); - CodeableConcept typeCode = new CodeableConcept(); - Coding typeCoding = new Coding(); - typeCoding.setSystem(BundleUrlIdentifier.SNOMED_URL); - typeCoding.setCode(BundleCompositionIdentifier.PRESCRIPTION_CODE); - typeCoding.setDisplay(BundleCompositionIdentifier.PRESCRIPTION); - typeCode.addCoding(typeCoding); - composition.setType(typeCode); - composition.setTitle(BundleCompositionIdentifier.PRESCRIPTION); - if (Objects.nonNull(organization)) - composition.setCustodian( - new Reference() - .setReference(BundleResourceIdentifier.ORGANISATION + "/" + organization.getId())); - if (Objects.nonNull(encounter)) - composition.setEncounter( - new Reference() - .setReference(BundleResourceIdentifier.ENCOUNTER + "/" + encounter.getId()) - .setDisplay(encounter.getClass_().getDisplay())); - List authorList = new ArrayList<>(); - HumanName practitionerName = null; - for (Practitioner author : practitionerList) { - practitionerName = author.getName().get(0); - authorList.add( - new Reference() - .setReference(BundleResourceIdentifier.PRACTITIONER + "/" + author.getId()) - .setDisplay(practitionerName.getText())); - } - composition.setAuthor(authorList); - HumanName patientName = patient.getName().get(0); - composition.setSubject( - new Reference() - .setReference(BundleResourceIdentifier.PATIENT + "/" + patient.getId()) - .setDisplay(patientName.getText())); - composition.setDateElement(Utils.getFormattedDateTime(authoredOn)); - Composition.SectionComponent medicationComponent = new Composition.SectionComponent(); - medicationComponent.setTitle(BundleResourceIdentifier.MEDICATIONS); - medicationComponent.setCode( - new CodeableConcept() - .setText(BundleCompositionIdentifier.PRESCRIPTION) - .addCoding( - new Coding() - .setCode(BundleCompositionIdentifier.PRESCRIPTION_CODE) - .setDisplay(BundleCompositionIdentifier.PRESCRIPTION) - .setSystem(BundleUrlIdentifier.SNOMED_URL))); - for (MedicationRequest medicationRequest : medicationRequestList) { - Reference entryReference = - new Reference() - .setReference( - BundleResourceIdentifier.MEDICATION_REQUEST + "/" + medicationRequest.getId()) - .setType(BundleResourceIdentifier.MEDICATION_REQUEST); - medicationComponent.addEntry(entryReference); - } - composition.addSection(medicationComponent); - for (Binary binary : documentList) - medicationComponent.addEntry( - new Reference() - .setReference(BundleResourceIdentifier.BINARY + "/" + binary.getId()) - .setType(BundleResourceIdentifier.BINARY)); - composition.setStatus(Composition.CompositionStatus.FINAL); - Identifier identifier = new Identifier(); - identifier.setSystem(BundleUrlIdentifier.WRAPPER_URL); - identifier.setValue(UUID.randomUUID().toString()); - composition.setIdentifier(identifier); - composition.setId(UUID.randomUUID().toString()); - return composition; - } -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeWellnessComposition.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeWellnessComposition.java deleted file mode 100644 index f1eb3343..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeWellnessComposition.java +++ /dev/null @@ -1,185 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.dto.compositions; - -import com.nha.abdm.fhir.mapper.Utils; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleCompositionIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; -import java.text.ParseException; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.UUID; -import org.hl7.fhir.r4.model.*; -import org.springframework.stereotype.Service; - -@Service -public class MakeWellnessComposition { - public Composition makeWellnessComposition( - Patient patient, - String authoredOn, - Encounter encounter, - List practitionerList, - Organization organization, - List vitalSignsList, - List bodyMeasurementList, - List physicalActivityList, - List generalAssessmentList, - List womanHealthList, - List lifeStyleList, - List otherObservationList, - List documentReferenceList) - throws ParseException { - HumanName patientName = patient.getName().get(0); - HumanName practitionerName = null; - Composition composition = new Composition(); - composition.setStatus(Composition.CompositionStatus.FINAL); - composition.setType(new CodeableConcept().setText(BundleCompositionIdentifier.WELLNESS_RECORD)); - composition.setTitle(BundleCompositionIdentifier.WELLNESS_RECORD); - List authorList = new ArrayList<>(); - for (Practitioner practitioner : practitionerList) { - practitionerName = practitioner.getName().get(0); - authorList.add( - new Reference() - .setReference(BundleResourceIdentifier.PRACTITIONER + "/" + practitioner.getId()) - .setDisplay(practitionerName != null ? practitionerName.getText() : null)); - } - composition.setEncounter( - new Reference().setReference(BundleResourceIdentifier.ENCOUNTER + "/" + encounter.getId())); - composition.setCustodian( - new Reference() - .setReference(BundleResourceIdentifier.ORGANISATION + "/" + organization.getId()) - .setDisplay(organization.getName())); - composition.setAuthor(authorList); - composition.setSubject( - new Reference() - .setReference(BundleResourceIdentifier.PATIENT + "/" + patient.getId()) - .setDisplay(patientName.getText())); - composition.setDateElement(Utils.getFormattedDateTime(authoredOn)); - List sectionComponentList = - makeCompositionSection( - patient, - encounter, - practitionerList, - organization, - vitalSignsList, - bodyMeasurementList, - physicalActivityList, - generalAssessmentList, - womanHealthList, - lifeStyleList, - otherObservationList, - documentReferenceList); - if (Objects.nonNull(sectionComponentList)) - for (Composition.SectionComponent sectionComponent : sectionComponentList) - composition.addSection(sectionComponent); - Identifier identifier = new Identifier(); - identifier.setSystem(BundleUrlIdentifier.WRAPPER_URL); - identifier.setValue(UUID.randomUUID().toString()); - composition.setIdentifier(identifier); - composition.setId(UUID.randomUUID().toString()); - return composition; - } - - private List makeCompositionSection( - Patient patient, - Encounter encounter, - List practitionerList, - Organization organization, - List vitalSignsList, - List bodyMeasurementList, - List physicalActivityList, - List generalAssessmentList, - List womanHealthList, - List lifeStyleList, - List otherObservationList, - List documentReferenceList) { - List sectionComponentList = new ArrayList<>(); - if (Objects.nonNull(vitalSignsList)) { - Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); - sectionComponent.setTitle(BundleCompositionIdentifier.VITAL_SIGNS); - for (Observation observation : vitalSignsList) { - sectionComponent.addEntry( - new Reference() - .setReference(BundleResourceIdentifier.VITAL_SIGNS + "/" + observation.getId())); - } - sectionComponentList.add(sectionComponent); - } - if (Objects.nonNull(bodyMeasurementList)) { - Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); - sectionComponent.setTitle(BundleCompositionIdentifier.BODY_MEASUREMENT); - for (Observation observation : bodyMeasurementList) { - sectionComponent.addEntry( - new Reference() - .setReference( - BundleResourceIdentifier.BODY_MEASUREMENT + "/" + observation.getId())); - } - sectionComponentList.add(sectionComponent); - } - if (Objects.nonNull(physicalActivityList)) { - Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); - sectionComponent.setTitle(BundleCompositionIdentifier.PHYSICAL_ACTIVITY); - for (Observation observation : physicalActivityList) { - sectionComponent.addEntry( - new Reference() - .setReference( - BundleResourceIdentifier.PHYSICAL_ACTIVITY + "/" + observation.getId())); - } - sectionComponentList.add(sectionComponent); - } - if (Objects.nonNull(generalAssessmentList)) { - Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); - sectionComponent.setTitle(BundleCompositionIdentifier.GENERAL_ASSESSMENT); - for (Observation observation : generalAssessmentList) { - sectionComponent.addEntry( - new Reference() - .setReference( - BundleResourceIdentifier.GENERAL_ASSESSMENT + "/" + observation.getId())); - } - sectionComponentList.add(sectionComponent); - } - if (Objects.nonNull(womanHealthList)) { - Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); - sectionComponent.setTitle(BundleCompositionIdentifier.WOMEN_HEALTH); - for (Observation observation : womanHealthList) { - sectionComponent.addEntry( - new Reference() - .setReference(BundleResourceIdentifier.WOMAN_HEALTH + "/" + observation.getId())); - } - sectionComponentList.add(sectionComponent); - } - if (Objects.nonNull(lifeStyleList)) { - Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); - sectionComponent.setTitle(BundleCompositionIdentifier.LIFE_STYLE); - for (Observation observation : lifeStyleList) { - sectionComponent.addEntry( - new Reference() - .setReference(BundleResourceIdentifier.LIFE_STYLE + "/" + observation.getId())); - } - sectionComponentList.add(sectionComponent); - } - if (Objects.nonNull(otherObservationList)) { - Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); - sectionComponent.setTitle(BundleCompositionIdentifier.OTHER_OBSERVATIONS); - for (Observation observation : otherObservationList) { - sectionComponent.addEntry( - new Reference() - .setReference( - BundleResourceIdentifier.OTHER_OBSERVATIONS + "/" + observation.getId())); - } - sectionComponentList.add(sectionComponent); - } - if (Objects.nonNull(documentReferenceList)) { - Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); - sectionComponent.setTitle(BundleCompositionIdentifier.DOCUMENT_REFERENCE); - for (DocumentReference documentReference : documentReferenceList) { - sectionComponent.addEntry( - new Reference() - .setReference( - BundleResourceIdentifier.DOCUMENT_REFERENCE + "/" + documentReference.getId())); - } - sectionComponentList.add(sectionComponent); - } - return sectionComponentList; - } -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeAllergyToleranceResource.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeAllergyToleranceResource.java deleted file mode 100644 index f36881e4..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeAllergyToleranceResource.java +++ /dev/null @@ -1,64 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.dto.resources; - -import com.nha.abdm.fhir.mapper.Utils; -import com.nha.abdm.fhir.mapper.rest.common.constants.*; -import com.nha.abdm.fhir.mapper.rest.database.h2.services.SnomedService; -import com.nha.abdm.fhir.mapper.rest.database.h2.tables.SnomedConditionProcedure; -import java.text.ParseException; -import java.util.List; -import java.util.UUID; -import org.hl7.fhir.r4.model.*; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -@Component -public class MakeAllergyToleranceResource { - @Autowired SnomedService snomedService; - - public AllergyIntolerance getAllergy( - Patient patient, List practitionerList, String allergy, String authoredOn) - throws ParseException { - HumanName patientName = patient.getName().get(0); - AllergyIntolerance allergyIntolerance = new AllergyIntolerance(); - allergyIntolerance.setId(UUID.randomUUID().toString()); - allergyIntolerance.setMeta( - new Meta() - .setLastUpdatedElement(Utils.getCurrentTimeStamp()) - .addProfile(ResourceProfileIdentifier.PROFILE_ALLERGY_INTOLERANCE)); - - Coding coding = new Coding(); - SnomedConditionProcedure snomed = snomedService.getConditionProcedureCode(allergy); - coding.setSystem(BundleUrlIdentifier.SNOMED_URL); - coding.setCode(snomed.getCode()); - coding.setDisplay(snomed.getDisplay()); - CodeableConcept code = new CodeableConcept(); - code.addCoding(coding); - code.setText(snomed.getDisplay()); - - allergyIntolerance.setCode(code); - Coding clinicalStatusCoding = new Coding(); - clinicalStatusCoding.setSystem(ResourceProfileIdentifier.PROFILE_ALLERGY_INTOLERANCE_SYSTEM); - clinicalStatusCoding.setCode(BundleFieldIdentifier.ACTIVE); - clinicalStatusCoding.setDisplay(BundleFieldIdentifier.ACTIVE); - - CodeableConcept clinicalStatus = new CodeableConcept(); - clinicalStatus.addCoding(clinicalStatusCoding); - allergyIntolerance.setClinicalStatus(clinicalStatus); - if (authoredOn != null) - allergyIntolerance.setRecordedDateElement(Utils.getFormattedDateTime(authoredOn)); - allergyIntolerance.setType(AllergyIntolerance.AllergyIntoleranceType.ALLERGY); - allergyIntolerance.setPatient( - new Reference() - .setReference(BundleResourceIdentifier.PATIENT + "/" + patient.getId()) - .setDisplay(patientName.getText())); - if (!(practitionerList.isEmpty())) { - allergyIntolerance.setRecorder( - new Reference() - .setReference( - BundleResourceIdentifier.PRACTITIONER + "/" + practitionerList.get(0).getId()) - .setDisplay(patientName.getText())); - } - return allergyIntolerance; - } -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeBundleMetaResource.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeBundleMetaResource.java deleted file mode 100644 index 14be3a1a..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeBundleMetaResource.java +++ /dev/null @@ -1,27 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.dto.resources; - -import com.nha.abdm.fhir.mapper.Utils; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleFieldIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.ResourceProfileIdentifier; -import java.text.ParseException; -import org.hl7.fhir.r4.model.Coding; -import org.hl7.fhir.r4.model.Meta; -import org.springframework.stereotype.Component; - -@Component -public class MakeBundleMetaResource { - public Meta getMeta() throws ParseException { - Meta meta = new Meta(); - meta.setVersionId("1"); - // meta.setLastUpdated(Utils.getCurrentTimeStamp()); - meta.setLastUpdatedElement(Utils.getCurrentTimeStamp()); - meta.addProfile(ResourceProfileIdentifier.PROFILE_DOCUMENT_BUNDLE); - meta.addSecurity( - new Coding() - .setSystem(ResourceProfileIdentifier.PROFILE_BUNDLE_META) - .setCode("V") - .setDisplay(BundleFieldIdentifier.VERY_RESTRICTED)); - return meta; - } -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeCarePlanResource.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeCarePlanResource.java deleted file mode 100644 index bdddf0e7..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeCarePlanResource.java +++ /dev/null @@ -1,63 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.dto.resources; - -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; -import com.nha.abdm.fhir.mapper.rest.database.h2.services.SnomedService; -import com.nha.abdm.fhir.mapper.rest.database.h2.tables.SnomedEncounter; -import com.nha.abdm.fhir.mapper.rest.requests.helpers.CarePlanResource; -import java.util.Collections; -import java.util.UUID; -import java.util.stream.Collectors; -import org.hl7.fhir.r4.model.*; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -@Component -public class MakeCarePlanResource { - - @Autowired SnomedService snomedService; - - public CarePlan getCarePlan(CarePlanResource carePlanResource, Patient patient) { - CarePlan carePlan = new CarePlan(); - carePlan.setId(UUID.randomUUID().toString()); - carePlan.setStatus(CarePlan.CarePlanStatus.ACTIVE); - carePlan.setIntent(CarePlan.CarePlanIntent.fromCode(carePlanResource.getIntent())); - if (carePlanResource.getDescription() != null) { - carePlan.setDescription(carePlanResource.getDescription()); - } - carePlan.setTitle(carePlanResource.getType()); - carePlan.setSubject( - new Reference() - .setReference(BundleResourceIdentifier.PATIENT + "/" + patient.getId()) - .setDisplay( - patient.getName().stream() - .map(HumanName::getText) - .collect(Collectors.joining(" ")))); - - CodeableConcept codeableConcept = new CodeableConcept(); - Coding carePlanCoding = new Coding(); - SnomedEncounter snomed = snomedService.getSnomedEncounterCode(carePlanResource.getType()); - carePlanCoding.setDisplay(snomed.getDisplay()); - carePlanCoding.setSystem(BundleUrlIdentifier.SNOMED_URL); - carePlanCoding.setCode(snomed.getCode()); - codeableConcept.addCoding(carePlanCoding); - carePlan.setCategory(Collections.singletonList(codeableConcept)); - - if (carePlanResource.getNotes() != null) { - // Detail - CarePlan.CarePlanActivityDetailComponent activityDetailComponent = - new CarePlan.CarePlanActivityDetailComponent(); - activityDetailComponent.setDescription(carePlanResource.getNotes()); - // activityDetailComponent.setScheduled(new - // Period().setStartElement(carePlanResource.getPeriod().getFrom()).setEndElement(carePlanResource.getPeriod().getTo())) - carePlan.setActivity( - Collections.singletonList( - new CarePlan.CarePlanActivityComponent().setDetail(activityDetailComponent))); - Annotation annotation = new Annotation(); - annotation.setText(carePlanResource.getNotes()); - carePlan.setNote(Collections.singletonList(annotation)); - } - return carePlan; - } -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeConditionResource.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeConditionResource.java deleted file mode 100644 index 33ff2f98..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeConditionResource.java +++ /dev/null @@ -1,55 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.dto.resources; - -import com.nha.abdm.fhir.mapper.Utils; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.ResourceProfileIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.helpers.DateRange; -import com.nha.abdm.fhir.mapper.rest.database.h2.services.SnomedService; -import com.nha.abdm.fhir.mapper.rest.database.h2.tables.SnomedConditionProcedure; -import java.text.ParseException; -import java.util.UUID; -import org.hl7.fhir.r4.model.*; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -@Component -public class MakeConditionResource { - @Autowired SnomedService snomedService; - - public Condition getCondition( - String conditionDetails, Patient patient, String recordedDate, DateRange dateRange) - throws ParseException { - HumanName patientName = patient.getName().get(0); - Condition condition = new Condition(); - condition.setId(UUID.randomUUID().toString()); - - SnomedConditionProcedure snomed = snomedService.getConditionProcedureCode(conditionDetails); - condition.setCode( - new CodeableConcept() - .addCoding( - new Coding() - .setDisplay(snomed.getDisplay()) - .setCode(snomed.getCode()) - .setSystem(BundleUrlIdentifier.SNOMED_URL)) - .setText(snomed.getDisplay())); - condition.setMeta( - new Meta() - .setLastUpdatedElement(Utils.getCurrentTimeStamp()) - .addProfile(ResourceProfileIdentifier.PROFILE_CONDITION)); - condition.setSubject( - new Reference() - .setReference(BundleResourceIdentifier.PATIENT + "/" + patient.getId()) - .setDisplay(patientName.getText())); - if (recordedDate != null) - condition.setRecordedDateElement(Utils.getFormattedDateTime(recordedDate)); - if (dateRange != null) { - condition.setOnset( - new Period() - .setStartElement(Utils.getFormattedDateTime(dateRange.getFrom())) - .setEndElement(Utils.getFormattedDateTime(dateRange.getTo()))); - } - return condition; - } -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeDiagnosticLabResource.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeDiagnosticLabResource.java deleted file mode 100644 index b6c573da..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeDiagnosticLabResource.java +++ /dev/null @@ -1,98 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.dto.resources; - -import com.nha.abdm.fhir.mapper.Utils; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.ResourceProfileIdentifier; -import com.nha.abdm.fhir.mapper.rest.database.h2.services.SnomedService; -import com.nha.abdm.fhir.mapper.rest.database.h2.tables.SnomedDiagnostic; -import com.nha.abdm.fhir.mapper.rest.database.h2.tables.SnomedObservation; -import com.nha.abdm.fhir.mapper.rest.requests.helpers.DiagnosticResource; -import java.text.ParseException; -import java.util.List; -import java.util.Objects; -import java.util.UUID; -import org.hl7.fhir.r4.model.*; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -@Component -public class MakeDiagnosticLabResource { - @Autowired SnomedService snomedService; - - public DiagnosticReport getDiagnosticReport( - Patient patient, - List practitionerList, - List observationList, - Encounter encounter, - DiagnosticResource diagnosticResource) - throws ParseException { - HumanName patientName = patient.getName().get(0); - DiagnosticReport diagnosticReport = new DiagnosticReport(); - diagnosticReport.setId(UUID.randomUUID().toString()); - diagnosticReport.setMeta( - new Meta() - .setLastUpdatedElement(Utils.getCurrentTimeStamp()) - .addProfile(ResourceProfileIdentifier.PROFILE_DIAGNOSTIC_REPORT_LAB)); - diagnosticReport.setStatus(DiagnosticReport.DiagnosticReportStatus.FINAL); - SnomedDiagnostic snomed = - snomedService.getSnomedDiagnosticCode(diagnosticResource.getServiceName()); - diagnosticReport.setCode( - new CodeableConcept() - .setText(diagnosticResource.getServiceName()) - .addCoding( - new Coding() - .setSystem(BundleUrlIdentifier.LOINC_URL) - .setCode(snomed.getCode()) - .setDisplay(snomed.getDisplay()))); - diagnosticReport.setSubject( - new Reference() - .setReference(BundleResourceIdentifier.PATIENT + "/" + patient.getId()) - .setDisplay(patientName.getText())); - if (Objects.nonNull(encounter)) - diagnosticReport.setEncounter(new Reference().setReference("/" + encounter.getId())); - for (Practitioner practitioner : practitionerList) { - diagnosticReport.addPerformer( - new Reference() - .setReference(BundleResourceIdentifier.PRACTITIONER + "/" + practitioner.getId())); - diagnosticReport.addResultsInterpreter( - new Reference() - .setReference(BundleResourceIdentifier.PRACTITIONER + "/" + practitioner.getId())); - } - SnomedDiagnostic snomedDiagnostic = - snomedService.getSnomedDiagnosticCode(diagnosticResource.getServiceCategory()); - diagnosticReport.addCategory( - new CodeableConcept() - .setText(diagnosticResource.getServiceCategory()) - .addCoding( - new Coding() - .setSystem(BundleUrlIdentifier.SNOMED_URL) - .setCode(snomedDiagnostic.getCode()) - .setDisplay(snomed.getDisplay()))); - for (Observation observation : observationList) { - diagnosticReport.addResult( - new Reference() - .setReference(BundleResourceIdentifier.OBSERVATION + "/" + observation.getId())); - } - diagnosticReport.setIssued(encounter.getPeriod().getStart()); // TODO Conversion of UTC - diagnosticReport.setConclusion(diagnosticResource.getConclusion()); - SnomedObservation snomedObservation = - snomedService.getSnomedObservationCode(diagnosticResource.getConclusion()); - diagnosticReport.addConclusionCode( - new CodeableConcept() - .setText(diagnosticResource.getConclusion()) - .addCoding( - new Coding() - .setSystem(BundleUrlIdentifier.SNOMED_URL) - .setCode(snomedObservation.getCode()) - .setDisplay(snomedObservation.getDisplay()))); - if (Objects.nonNull(diagnosticResource.getPresentedForm())) { - Attachment attachment = new Attachment(); - attachment.setContentType(diagnosticResource.getPresentedForm().getContentType()); - attachment.setData(diagnosticResource.getPresentedForm().getData()); - diagnosticReport.addPresentedForm(attachment); - } - return diagnosticReport; - } -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeDocumentResource.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeDocumentResource.java deleted file mode 100644 index baba1b56..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeDocumentResource.java +++ /dev/null @@ -1,65 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.dto.resources; - -import com.nha.abdm.fhir.mapper.Utils; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.ResourceProfileIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.helpers.DocumentResource; -import java.text.ParseException; -import java.util.Objects; -import java.util.UUID; -import org.hl7.fhir.r4.model.*; -import org.springframework.stereotype.Component; - -@Component -public class MakeDocumentResource { - public DocumentReference getDocument( - Patient patient, - Organization organization, - DocumentResource documentResource, - String docCode, - String docName) - throws ParseException { - HumanName patientName = patient.getName().get(0); - Coding coding = new Coding(); - coding.setCode(docCode); - coding.setSystem(BundleUrlIdentifier.SNOMED_URL); - coding.setDisplay(docName); - CodeableConcept codeableConcept = new CodeableConcept(); - codeableConcept.addCoding(coding); - codeableConcept.setText(documentResource.getType()); - Identifier identifier = new Identifier(); - identifier.setType(codeableConcept); - identifier.setSystem(BundleUrlIdentifier.FACILITY_URL); - if (Objects.nonNull(organization)) { - identifier.setValue( - organization.getId() == null ? UUID.randomUUID().toString() : organization.getId()); - } else { - identifier.setValue(UUID.randomUUID().toString()); - } - Attachment attachment = new Attachment(); - attachment.setContentType(documentResource.getContentType()); - attachment.setData(documentResource.getData()); - attachment.setTitle(documentResource.getType()); - attachment.setCreationElement(new DateTimeType(Utils.getCurrentTimeStamp().getValueAsString())); - DocumentReference.DocumentReferenceContentComponent documentReferenceContentComponent = - new DocumentReference.DocumentReferenceContentComponent().setAttachment(attachment); - DocumentReference documentReference = new DocumentReference(); - documentReference.setId(UUID.randomUUID().toString()); - documentReference.setMeta( - new Meta() - .setLastUpdatedElement(Utils.getCurrentTimeStamp()) - .addProfile(ResourceProfileIdentifier.PROFILE_DOCUMENT_REFERENCE)); - documentReference.addIdentifier(identifier); - documentReference.addContent(documentReferenceContentComponent); - documentReference.setStatus(Enumerations.DocumentReferenceStatus.CURRENT); - documentReference.setDocStatus(DocumentReference.ReferredDocumentStatus.FINAL); - Reference documentSubject = new Reference(); - documentReference.setSubject( - documentSubject - .setReference(BundleResourceIdentifier.PATIENT + "/" + patient.getId()) - .setDisplay(patientName.getText())); - return documentReference; - } -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeEncounterResource.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeEncounterResource.java deleted file mode 100644 index 741d24a9..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeEncounterResource.java +++ /dev/null @@ -1,46 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.dto.resources; - -import com.nha.abdm.fhir.mapper.Utils; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleFieldIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.ResourceProfileIdentifier; -import com.nha.abdm.fhir.mapper.rest.database.h2.services.SnomedService; -import com.nha.abdm.fhir.mapper.rest.database.h2.tables.SnomedEncounter; -import java.text.ParseException; -import java.util.UUID; -import org.hl7.fhir.r4.model.*; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -@Component -public class MakeEncounterResource { - @Autowired SnomedService snomedService; - - public Encounter getEncounter(Patient patient, String encounterName, String visitDate) - throws ParseException { - HumanName patientName = patient.getName().get(0); - Encounter encounter = new Encounter(); - encounter.setId(UUID.randomUUID().toString()); - encounter.setStatus(Encounter.EncounterStatus.INPROGRESS); - encounter.setMeta( - new Meta() - .setLastUpdatedElement(Utils.getCurrentTimeStamp()) - .addProfile(ResourceProfileIdentifier.PROFILE_ENCOUNTER)); - SnomedEncounter snomedEncounter = snomedService.getSnomedEncounterCode(encounterName); - encounter.setClass_( - new Coding() - .setSystem(ResourceProfileIdentifier.PROFILE_BUNDLE_META) - .setCode(snomedEncounter.getCode()) - .setDisplay( - (encounterName != null && !encounterName.isEmpty()) - ? encounterName - : BundleFieldIdentifier.AMBULATORY)); - encounter.setSubject( - new Reference() - .setReference(BundleResourceIdentifier.PATIENT + "/" + patient.getId()) - .setDisplay(patientName.getText())); - encounter.setPeriod(new Period().setStartElement(Utils.getFormattedDateTime(visitDate))); - return encounter; - } -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeFamilyMemberResource.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeFamilyMemberResource.java deleted file mode 100644 index 00c79402..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeFamilyMemberResource.java +++ /dev/null @@ -1,64 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.dto.resources; - -import com.nha.abdm.fhir.mapper.Utils; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.ResourceProfileIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.SnomedCodeIdentifier; -import com.nha.abdm.fhir.mapper.rest.database.h2.services.SnomedService; -import com.nha.abdm.fhir.mapper.rest.database.h2.tables.SnomedObservation; -import com.nha.abdm.fhir.mapper.rest.requests.helpers.FamilyObservationResource; -import java.text.ParseException; -import java.util.Objects; -import java.util.UUID; -import org.hl7.fhir.r4.model.*; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -@Component -public class MakeFamilyMemberResource { - - @Autowired SnomedService snomedService; - - public FamilyMemberHistory getFamilyHistory( - Patient patient, FamilyObservationResource familyObservationResource) throws ParseException { - HumanName patientName = patient.getName().get(0); - FamilyMemberHistory familyMemberHistory = new FamilyMemberHistory(); - familyMemberHistory.setId(UUID.randomUUID().toString()); - familyMemberHistory.setStatus(FamilyMemberHistory.FamilyHistoryStatus.COMPLETED); - familyMemberHistory.setMeta( - new Meta() - .setLastUpdatedElement(Utils.getCurrentTimeStamp()) - .addProfile(ResourceProfileIdentifier.PROFILE_FAMILY_MEMBER_HISTORY)); - familyMemberHistory.setPatient( - new Reference() - .setReference(BundleResourceIdentifier.PATIENT + "/" + patient.getId()) - .setDisplay(patientName.getText())); - if (Objects.nonNull(familyObservationResource.getRelationship())) { - familyMemberHistory.setRelationship( - new CodeableConcept() - .addCoding( - new Coding() - .setSystem(BundleUrlIdentifier.SNOMED_URL) - .setCode(SnomedCodeIdentifier.SNOMED_UNKNOWN) - .setDisplay(familyObservationResource.getRelationship())) - .setText(familyObservationResource.getRelationship())); - } - if (Objects.nonNull(familyObservationResource.getObservation())) { - SnomedObservation snomedCondition = - snomedService.getSnomedObservationCode(familyObservationResource.getObservation()); - familyMemberHistory.addCondition( - new FamilyMemberHistory.FamilyMemberHistoryConditionComponent() - .setCode( - new CodeableConcept() - .addCoding( - new Coding() - .setSystem(BundleUrlIdentifier.SNOMED_URL) - .setCode(snomedCondition.getCode()) - .setDisplay(snomedCondition.getDisplay())) - .setText(snomedCondition.getDisplay()))); - } - return familyMemberHistory; - } -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeImmunizationResource.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeImmunizationResource.java deleted file mode 100644 index 7870a0be..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeImmunizationResource.java +++ /dev/null @@ -1,90 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.dto.resources; - -import com.nha.abdm.fhir.mapper.Utils; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.ResourceProfileIdentifier; -import com.nha.abdm.fhir.mapper.rest.database.h2.services.SnomedService; -import com.nha.abdm.fhir.mapper.rest.database.h2.tables.SnomedVaccine; -import com.nha.abdm.fhir.mapper.rest.requests.helpers.ImmunizationResource; -import java.text.ParseException; -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.UUID; -import org.hl7.fhir.r4.model.*; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -@Component -public class MakeImmunizationResource { - @Autowired SnomedService snomedService; - - public Immunization getImmunization( - Patient patient, - List practitionerList, - Organization organization, - ImmunizationResource immunizationResource) - throws ParseException { - Immunization immunization = new Immunization(); - immunization.setId(UUID.randomUUID().toString()); - Meta meta = new Meta(); - meta.setVersionId("1"); - meta.setLastUpdatedElement(Utils.getCurrentTimeStamp()); - meta.addProfile(ResourceProfileIdentifier.PROFILE_IMMUNIZATION); - immunization.setMeta(meta); - immunization.setStatus(Immunization.ImmunizationStatus.COMPLETED); - - immunization.setPatient( - new Reference().setReference(BundleResourceIdentifier.PATIENT + "/" + patient.getId())); - if (Objects.nonNull(immunizationResource.getDate())) { - immunization.setOccurrence((Utils.getFormattedDateTime(immunizationResource.getDate()))); - } - if (Objects.nonNull(immunizationResource.getVaccineName())) { - immunization.addExtension( - new Extension() - .setValue(new StringType().setValue(immunizationResource.getVaccineName())) - .setUrl(ResourceProfileIdentifier.PROFILE_VACCINE_BRAND_NAME)); - - SnomedVaccine snomedVaccine = - snomedService.getSnomedVaccineCode(immunizationResource.getVaccineName()); - immunization.setVaccineCode( - new CodeableConcept() - .setText(immunizationResource.getVaccineName()) - .addCoding( - new Coding() - .setSystem(BundleUrlIdentifier.SNOMED_URL) - .setCode(snomedVaccine.getCode()) - .setDisplay(snomedVaccine.getDisplay()))); - } - immunization.setPrimarySource(true); - if (Objects.nonNull(immunizationResource.getManufacturer())) { - immunization.setManufacturer( - new Reference() - .setReference(BundleResourceIdentifier.MANUFACTURER + "/" + organization.getId()) - .setDisplay(organization.getName())); - } - if (Objects.nonNull(immunizationResource.getLotNumber())) { - immunization.setLotNumber(immunizationResource.getLotNumber()); - } - if (Objects.nonNull(immunizationResource.getDoseNumber())) { - immunization.setDoseQuantity(new Quantity().setValue(immunizationResource.getDoseNumber())); - immunization.setProtocolApplied( - Collections.singletonList( - new Immunization.ImmunizationProtocolAppliedComponent() - .setDoseNumber( - new PositiveIntType().setValue(immunizationResource.getDoseNumber())))); - } - - for (Practitioner practitioner : practitionerList) { - immunization.addPerformer( - new Immunization.ImmunizationPerformerComponent() - .setActor( - new Reference() - .setReference( - BundleResourceIdentifier.PRACTITIONER + "/" + practitioner.getId()))); - } - return immunization; - } -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeMedicationRequestResource.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeMedicationRequestResource.java deleted file mode 100644 index d29445e0..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeMedicationRequestResource.java +++ /dev/null @@ -1,137 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.dto.resources; - -import com.nha.abdm.fhir.mapper.Utils; -import com.nha.abdm.fhir.mapper.rest.common.constants.*; -import com.nha.abdm.fhir.mapper.rest.database.h2.services.SnomedService; -import com.nha.abdm.fhir.mapper.rest.database.h2.tables.SnomedMedicine; -import com.nha.abdm.fhir.mapper.rest.database.h2.tables.SnomedMedicineRoute; -import com.nha.abdm.fhir.mapper.rest.requests.helpers.PrescriptionResource; -import java.text.ParseException; -import java.util.*; -import org.hl7.fhir.r4.model.*; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -@Component -public class MakeMedicationRequestResource { - @Autowired SnomedService snomedService; - - public MedicationRequest getMedicationResource( - String authoredOn, - PrescriptionResource prescriptionResource, - Condition medicationCondition, - Organization organization, - List practitioners, - Patient patient) - throws ParseException { - HumanName patientName = patient.getName().get(0); - MedicationRequest medicationRequest = new MedicationRequest(); - - // Setting Meta of the Medication Resource - medicationRequest.setMeta( - new Meta() - .addProfile(ResourceProfileIdentifier.PROFILE_MEDICATION_REQUEST) - .setLastUpdatedElement(Utils.getCurrentTimeStamp())); - - // Setting Medications - SnomedMedicine snomedMedicine = - snomedService.getSnomedMedicineCode(prescriptionResource.getMedicine()); - medicationRequest.setMedication( - new CodeableConcept() - .setText(prescriptionResource.getMedicine()) - .addCoding( - new Coding() - .setSystem(BundleUrlIdentifier.SNOMED_URL) - .setCode(snomedMedicine.getCode()) - .setDisplay(snomedMedicine.getDisplay()))); - if (prescriptionResource.getDosage() != null) { - Dosage dosage = new Dosage(); - dosage.setText(prescriptionResource.getDosage()); - if (prescriptionResource.getAdditionalInstructions() != null) { - dosage.addAdditionalInstruction( - new CodeableConcept() - .setText(prescriptionResource.getAdditionalInstructions()) - .addCoding( - new Coding() - .setSystem(BundleUrlIdentifier.SNOMED_URL) - .setCode(SnomedCodeIdentifier.SNOMED_UNKNOWN) - .setDisplay(prescriptionResource.getAdditionalInstructions()))); - } - if (prescriptionResource.getRoute() != null) { - SnomedMedicineRoute snomedMedicineRoute = - snomedService.getSnomedMedicineRouteCode(prescriptionResource.getRoute()); - dosage.setRoute( - new CodeableConcept() - .setText(prescriptionResource.getRoute()) - .addCoding( - new Coding() - .setSystem(BundleUrlIdentifier.SNOMED_URL) - .setCode(snomedMedicineRoute.getCode()) - .setDisplay(snomedMedicine.getDisplay()))); - } - if (prescriptionResource.getMethod() != null) { - SnomedMedicineRoute snomedMethod = - snomedService.getSnomedMedicineRouteCode(prescriptionResource.getRoute()); - dosage.setMethod( - new CodeableConcept() - .setText(prescriptionResource.getMethod()) - .addCoding( - new Coding() - .setSystem(BundleUrlIdentifier.SNOMED_URL) - .setCode(snomedMethod.getCode()) - .setDisplay(snomedMethod.getDisplay()))); - } - if (prescriptionResource.getTiming() != null) { - String[] parts = prescriptionResource.getTiming().split("-"); - dosage.setTiming( - new Timing() - .setRepeat( - new Timing.TimingRepeatComponent() - .setFrequency(Integer.parseInt(parts[0])) - .setPeriod(Integer.parseInt(parts[1])) - .setPeriodUnit(Timing.UnitsOfTime.valueOf(parts[2])))); - } - medicationRequest.setDosageInstruction(Collections.singletonList(dosage)); - } - if (medicationCondition != null) { - medicationRequest.setReasonCode( - Collections.singletonList( - new CodeableConcept() - .addCoding( - new Coding() - .setSystem(BundleUrlIdentifier.SNOMED_URL) - .setCode( - snomedService - .getConditionProcedureCode( - medicationCondition.getCode().getText()) - .getCode()) - .setDisplay(medicationCondition.getCode().getText())) - .setText(medicationCondition.getCode().getText()))); - medicationRequest.setReasonReference( - Collections.singletonList( - new Reference() - .setReference( - BundleResourceIdentifier.CONDITION + "/" + medicationCondition.getId()) - .setDisplay(BundleFieldIdentifier.MEDICAL_CONDITION))); - } - if (!practitioners.isEmpty()) { - Practitioner practitioner = practitioners.get(0); - HumanName practitionerName = practitioner.getName().get(0); - medicationRequest.setRequester( - new Reference() - .setReference(BundleResourceIdentifier.PRACTITIONER + "/" + practitioner.getId()) - .setDisplay(practitionerName.getText())); - } - medicationRequest.setSubject( - new Reference() - .setReference(BundleResourceIdentifier.PATIENT + "/" + patient.getId()) - .setDisplay(patientName.getText())); - if (authoredOn != null) - medicationRequest.setAuthoredOnElement(Utils.getFormattedDateTime(authoredOn)); - medicationRequest.setStatus(MedicationRequest.MedicationRequestStatus.COMPLETED); - medicationRequest.setIntent(MedicationRequest.MedicationRequestIntent.ORDER); - medicationRequest.setId(UUID.randomUUID().toString()); - return medicationRequest; - } -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeObservationResource.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeObservationResource.java deleted file mode 100644 index 954dc899..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeObservationResource.java +++ /dev/null @@ -1,74 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.dto.resources; - -import com.nha.abdm.fhir.mapper.Utils; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.ResourceProfileIdentifier; -import com.nha.abdm.fhir.mapper.rest.database.h2.services.SnomedService; -import com.nha.abdm.fhir.mapper.rest.database.h2.tables.SnomedObservation; -import com.nha.abdm.fhir.mapper.rest.requests.helpers.ObservationResource; -import java.text.ParseException; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.UUID; -import org.hl7.fhir.r4.model.*; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -@Component -public class MakeObservationResource { - @Autowired SnomedService snomedService; - private static final Logger log = LoggerFactory.getLogger(MakeObservationResource.class); - - public Observation getObservation( - Patient patient, List practitionerList, ObservationResource observationResource) - throws ParseException { - HumanName patientName = patient.getName().get(0); - Observation observation = new Observation(); - observation.setStatus(Observation.ObservationStatus.FINAL); - SnomedObservation snomed = - snomedService.getSnomedObservationCode(observationResource.getObservation()); - observation.setCode( - new CodeableConcept() - .setText(observationResource.getObservation()) - .addCoding( - new Coding() - .setSystem(BundleUrlIdentifier.SNOMED_URL) - .setCode(snomed.getCode()) - .setDisplay(snomed.getDisplay()))); - observation.setSubject( - new Reference() - .setReference(BundleResourceIdentifier.PATIENT + "/" + patient.getId()) - .setDisplay(patientName.getText())); - List performerList = new ArrayList<>(); - HumanName practitionerName = null; - for (Practitioner practitioner : practitionerList) { - practitionerName = practitioner.getName().get(0); - performerList.add( - new Reference() - .setReference(BundleResourceIdentifier.PRACTITIONER + "/" + practitioner.getId()) - .setDisplay(practitionerName.getText())); - } - observation.setPerformer(performerList); - if (Objects.nonNull(observationResource.getValueQuantity())) { - observation.setValue( - new Quantity() - .setValue(observationResource.getValueQuantity().getValue()) - .setUnit(observationResource.getValueQuantity().getUnit())); - } - if (Objects.nonNull(observation.getValueQuantity()) - && observationResource.getResult() != null) { - observation.setValue(new CodeableConcept().setText(observationResource.getResult())); - } - observation.setId(UUID.randomUUID().toString()); - observation.setMeta( - new Meta() - .setLastUpdatedElement(Utils.getCurrentTimeStamp()) - .addProfile(ResourceProfileIdentifier.PROFILE_OBSERVATION)); - return observation; - } -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeOrganisationResource.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeOrganisationResource.java deleted file mode 100644 index a8aecfe5..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeOrganisationResource.java +++ /dev/null @@ -1,51 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.dto.resources; - -import com.nha.abdm.fhir.mapper.Utils; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.ResourceProfileIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.helpers.OrganisationResource; -import java.text.ParseException; -import java.util.Objects; -import java.util.UUID; -import org.hl7.fhir.r4.model.*; -import org.springframework.stereotype.Component; - -@Component -public class MakeOrganisationResource { - public Organization getOrganization(OrganisationResource organisationResource) - throws ParseException { - Coding coding = new Coding(); - coding.setCode("PRN"); - coding.setSystem(ResourceProfileIdentifier.PROFILE_PROVIDER); - coding.setDisplay("Provider number"); - CodeableConcept codeableConcept = new CodeableConcept(); - codeableConcept.addCoding(coding); - Identifier identifier = new Identifier(); - identifier.setType(codeableConcept); - identifier.setSystem(BundleUrlIdentifier.FACILITY_URL); - if (Objects.nonNull(organisationResource)) { - identifier.setValue( - organisationResource.getFacilityId() == null - ? UUID.randomUUID().toString() - : organisationResource.getFacilityId()); - } else { - identifier.setValue(UUID.randomUUID().toString()); - } - - Meta meta = new Meta(); - meta.setVersionId("1"); - meta.setLastUpdatedElement(Utils.getCurrentTimeStamp()); - meta.addProfile(ResourceProfileIdentifier.PROFILE_ORGANISATION); - - Organization organization = new Organization(); - organization.setName( - organisationResource.getFacilityName() != null - ? organisationResource.getFacilityName() - : organisationResource.getFacilityId()); - organization.setMeta(meta); - organization.addIdentifier(identifier); - organization.setId(UUID.randomUUID().toString()); - return organization; - } -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakePatientResource.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakePatientResource.java deleted file mode 100644 index 92e6e780..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakePatientResource.java +++ /dev/null @@ -1,49 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.dto.resources; - -import com.nha.abdm.fhir.mapper.Utils; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.ResourceProfileIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.helpers.PatientResource; -import java.text.ParseException; -import java.util.Locale; -import java.util.UUID; -import org.hl7.fhir.r4.model.*; -import org.springframework.stereotype.Component; - -@Component -public class MakePatientResource { - - public Patient getPatient(PatientResource patientResource) throws ParseException { - Coding coding = new Coding(); - coding.setCode("MR"); - coding.setSystem(ResourceProfileIdentifier.PROFILE_PROVIDER); - coding.setDisplay("Medical record number"); - CodeableConcept codeableConcept = new CodeableConcept(); - codeableConcept.addCoding(coding); - Identifier identifier = new Identifier(); - identifier.setType(codeableConcept); - identifier.setSystem(BundleUrlIdentifier.HEALTH_ID_URL); - identifier.setValue(patientResource.getPatientReference()); - - Meta meta = new Meta(); - meta.setVersionId("1"); - meta.setLastUpdatedElement(Utils.getCurrentTimeStamp()); - meta.addProfile(ResourceProfileIdentifier.PROFILE_PATIENT); - - Patient patient = new Patient(); - patient.addName(new HumanName().setText(patientResource.getName())); - if (patientResource.getGender() != null) { - patient.setGender( - Enumerations.AdministrativeGender.fromCode( - patientResource.getGender().toLowerCase(Locale.ROOT))); - } - if (patientResource.getBirthDate() != null) { - patient.setBirthDate(Utils.getFormattedDateTime(patientResource.getBirthDate()).getValue()); - } - patient.setMeta(meta); - patient.addIdentifier(identifier); - patient.setId(UUID.randomUUID().toString()); - return patient; - } -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakePractitionerResource.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakePractitionerResource.java deleted file mode 100644 index 753021e0..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakePractitionerResource.java +++ /dev/null @@ -1,44 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.dto.resources; - -import com.nha.abdm.fhir.mapper.Utils; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleFieldIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.ResourceProfileIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.helpers.PractitionerResource; -import java.text.ParseException; -import java.util.UUID; -import org.hl7.fhir.r4.model.*; -import org.springframework.stereotype.Component; - -@Component -public class MakePractitionerResource { - public Practitioner getPractitioner(PractitionerResource practitionerResource) - throws ParseException { - Coding coding = new Coding(); - coding.setCode("MR"); - coding.setSystem(ResourceProfileIdentifier.PROFILE_PROVIDER); - coding.setDisplay(BundleFieldIdentifier.MEDICAL_RECORD_NUMBER); - CodeableConcept codeableConcept = new CodeableConcept(); - codeableConcept.addCoding(coding); - Identifier identifier = new Identifier(); - identifier.setType(codeableConcept); - identifier.setSystem(BundleUrlIdentifier.DOCTOR_ID_URL); - identifier.setValue(practitionerResource.getPractitionerId()); - - Meta meta = new Meta(); - meta.setVersionId("1"); - meta.setLastUpdatedElement(Utils.getCurrentTimeStamp()); - meta.addProfile(ResourceProfileIdentifier.PROFILE_PRACTITIONER); - - Practitioner practitioner = new Practitioner(); - practitioner.addName(new HumanName().setText(practitionerResource.getName())); - practitioner.setMeta(meta); - practitioner.addIdentifier(identifier); - practitioner.setId( - practitionerResource.getPractitionerId() != null - ? practitionerResource.getPractitionerId() - : UUID.randomUUID().toString()); - return practitioner; - } -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeProcedureResource.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeProcedureResource.java deleted file mode 100644 index f632cb9d..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeProcedureResource.java +++ /dev/null @@ -1,68 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.dto.resources; - -import com.nha.abdm.fhir.mapper.Utils; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.ResourceProfileIdentifier; -import com.nha.abdm.fhir.mapper.rest.database.h2.services.SnomedService; -import com.nha.abdm.fhir.mapper.rest.database.h2.tables.SnomedConditionProcedure; -import com.nha.abdm.fhir.mapper.rest.requests.helpers.ProcedureResource; -import java.text.ParseException; -import java.util.UUID; -import org.hl7.fhir.r4.model.*; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -@Component -public class MakeProcedureResource { - @Autowired SnomedService snomedService; - - public Procedure getProcedure(Patient patient, ProcedureResource procedureResource) - throws ParseException { - Procedure procedure = new Procedure(); - procedure.setId(UUID.randomUUID().toString()); - procedure.setMeta(new Meta().addProfile(ResourceProfileIdentifier.PROFILE_PROCEDURE)); - if (procedureResource.getStatus() != null) { - procedure.setStatus(Procedure.ProcedureStatus.valueOf(procedureResource.getStatus())); - } else { - procedure.setStatus(Procedure.ProcedureStatus.COMPLETED); - } - procedure.setSubject( - new Reference().setReference(BundleResourceIdentifier.PATIENT + "/" + patient.getId())); - SnomedConditionProcedure snomedProcedure = - snomedService.getConditionProcedureCode(procedureResource.getProcedureName()); - procedure.setCode( - new CodeableConcept() - .setText(procedureResource.getProcedureName()) - .addCoding( - new Coding() - .setDisplay(snomedProcedure.getDisplay()) - .setCode(snomedProcedure.getCode()) - .setSystem(BundleUrlIdentifier.SNOMED_URL))); - if (procedureResource.getOutcome() != null) { - SnomedConditionProcedure snomedOutcome = - snomedService.getConditionProcedureCode(procedureResource.getOutcome()); - procedure.setOutcome( - new CodeableConcept() - .setText(procedureResource.getOutcome()) - .addCoding( - new Coding() - .setSystem(BundleUrlIdentifier.SNOMED_URL) - .setCode(snomedOutcome.getCode()) - .setDisplay(snomedOutcome.getDisplay()))); - } - SnomedConditionProcedure snomedCondition = - snomedService.getConditionProcedureCode(procedureResource.getProcedureReason()); - procedure.addReasonCode( - new CodeableConcept() - .setText(procedureResource.getProcedureReason()) - .addCoding( - new Coding() - .setSystem(BundleUrlIdentifier.SNOMED_URL) - .setCode(snomedCondition.getCode()) - .setDisplay(snomedCondition.getDisplay()))); - procedure.setPerformed((Utils.getFormattedDateTime(procedureResource.getDate()))); - return procedure; - } -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeServiceRequestResource.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeServiceRequestResource.java deleted file mode 100644 index 7fad8571..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeServiceRequestResource.java +++ /dev/null @@ -1,82 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.dto.resources; - -import com.nha.abdm.fhir.mapper.Utils; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.ResourceProfileIdentifier; -import com.nha.abdm.fhir.mapper.rest.database.h2.services.SnomedService; -import com.nha.abdm.fhir.mapper.rest.database.h2.tables.SnomedDiagnostic; -import com.nha.abdm.fhir.mapper.rest.requests.helpers.ServiceRequestResource; -import java.text.ParseException; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; -import org.hl7.fhir.r4.model.*; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -@Component -public class MakeServiceRequestResource { - @Autowired SnomedService snomedService; - - public ServiceRequest getServiceRequest( - Patient patient, - List practitionerList, - ServiceRequestResource serviceRequestResource, - String authoredOn) - throws ParseException { - HumanName patientName = patient.getName().get(0); - ServiceRequest serviceRequest = new ServiceRequest(); - serviceRequest.setId(UUID.randomUUID().toString()); - serviceRequest.setStatus( - ServiceRequest.ServiceRequestStatus.valueOf(serviceRequestResource.getStatus())); - serviceRequest.setIntent(ServiceRequest.ServiceRequestIntent.PROPOSAL); - serviceRequest.setStatus(ServiceRequest.ServiceRequestStatus.ACTIVE); - serviceRequest.setAuthoredOnElement(Utils.getFormattedDateTime(authoredOn)); - serviceRequest.setMeta( - new Meta() - .setLastUpdatedElement(Utils.getCurrentTimeStamp()) - .addProfile(ResourceProfileIdentifier.PROFILE_SERVICE_REQUEST)); - SnomedDiagnostic snomedDiagnostic = - snomedService.getSnomedDiagnosticCode(serviceRequestResource.getDetails()); - serviceRequest.setCode( - new CodeableConcept() - .addCoding( - new Coding() - .setDisplay(snomedDiagnostic.getDisplay()) - .setCode(snomedDiagnostic.getCode()) - .setSystem(BundleUrlIdentifier.SNOMED_URL)) - .setText(serviceRequestResource.getDetails())); - serviceRequest.setSubject( - new Reference() - .setReference(BundleResourceIdentifier.PATIENT + "/" + patient.getId()) - .setDisplay(patientName.getText())); - List performerList = new ArrayList<>(); - HumanName practitionerName = null; - for (Practitioner practitioner : practitionerList) { - practitionerName = practitioner.getName().get(0); - performerList.add( - new Reference() - .setReference(BundleResourceIdentifier.PRACTITIONER + "/" + practitioner.getId()) - .setDisplay(practitionerName.getText())); - } - if (!performerList.isEmpty()) { - Practitioner practitioner = practitionerList.get(0); - practitionerName = practitioner.getName().get(0); - serviceRequest.setRequester( - new Reference() - .setReference(BundleResourceIdentifier.PRACTITIONER + "/" + practitioner.getId()) - .setDisplay(practitionerName.getText())); - } - serviceRequest.setPerformer(performerList); - if (serviceRequestResource.getSpecimen() != null) - serviceRequest.addSpecimen( - new Reference() - .setDisplay( - snomedService - .getSnomedSpecimenCode(serviceRequestResource.getSpecimen()) - .getDisplay())); - return serviceRequest; - } -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeWellnessObservationResource.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeWellnessObservationResource.java deleted file mode 100644 index 71800e6f..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeWellnessObservationResource.java +++ /dev/null @@ -1,80 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.dto.resources; - -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.SnomedCodeIdentifier; -import com.nha.abdm.fhir.mapper.rest.common.constants.WellnessFieldIdentifiers; -import com.nha.abdm.fhir.mapper.rest.database.h2.services.SnomedService; -import com.nha.abdm.fhir.mapper.rest.database.h2.tables.SnomedObservation; -import com.nha.abdm.fhir.mapper.rest.requests.helpers.WellnessObservationResource; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.UUID; -import org.hl7.fhir.r4.model.*; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -@Component -public class MakeWellnessObservationResource { - @Autowired SnomedService snomedService; - - public Observation getObservation( - Patient patient, - List practitionerList, - WellnessObservationResource observationResource, - String type) { - HumanName patientName = patient.getName().get(0); - Observation observation = new Observation(); - observation.setStatus(Observation.ObservationStatus.FINAL); - CodeableConcept typeCode = new CodeableConcept(); - Coding coding = new Coding(); - SnomedObservation snomed = - snomedService.getSnomedObservationCode(observationResource.getObservation()); - coding.setSystem(WellnessFieldIdentifiers.getSystem(type)); - if (Objects.nonNull(snomed)) { - coding.setCode(snomed.getCode()); - coding.setDisplay(snomed.getDisplay()); - typeCode.addCoding(coding); - } else { - coding.setCode( - coding.getSystem().equalsIgnoreCase(BundleUrlIdentifier.LOINC_URL) - ? SnomedCodeIdentifier.LOINC_UNKNOWN - : SnomedCodeIdentifier.SNOMED_UNKNOWN); - coding.setDisplay(observationResource.getObservation()); - typeCode.addCoding(coding); - } - - typeCode.setText(snomed == null ? observationResource.getObservation() : snomed.getDisplay()); - - observation.setCode(typeCode); - observation.setSubject( - new Reference() - .setReference(BundleResourceIdentifier.PATIENT + "/" + patient.getId()) - .setDisplay(patientName.getText())); - List performerList = new ArrayList<>(); - HumanName practitionerName = null; - for (Practitioner practitioner : practitionerList) { - practitionerName = practitioner.getName().get(0); - performerList.add( - new Reference() - .setReference(BundleResourceIdentifier.PRACTITIONER + "/" + practitioner.getId()) - .setDisplay(practitionerName.getText())); - } - observation.setPerformer(performerList); - if (observationResource.getValueQuantity() != null) { - observation.setValue( - new Quantity() - .setValue(observationResource.getValueQuantity().getValue()) - .setUnit(observationResource.getValueQuantity().getUnit())); - } - if (observationResource.getResult() != null) { - observation.setValue(new CodeableConcept().setText(observationResource.getResult())); - observation.setValue(new StringType(observationResource.getResult())); - } - - observation.setId(UUID.randomUUID().toString()); - return observation; - } -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/exceptions/GlobalExceptionHandler.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/exceptions/GlobalExceptionHandler.java deleted file mode 100644 index 8275079f..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/exceptions/GlobalExceptionHandler.java +++ /dev/null @@ -1,124 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.exceptions; - -import com.fasterxml.jackson.databind.JsonMappingException; -import com.fasterxml.jackson.databind.exc.InvalidFormatException; -import com.nha.abdm.fhir.mapper.rest.common.constants.ErrorCode; -import com.nha.abdm.fhir.mapper.rest.common.helpers.ErrorResponse; -import com.nha.abdm.fhir.mapper.rest.common.helpers.FacadeError; -import com.nha.abdm.fhir.mapper.rest.common.helpers.FieldErrorsResponse; -import com.nha.abdm.fhir.mapper.rest.common.helpers.ValidationErrorResponse; -import java.text.ParseException; -import java.util.ArrayList; -import java.util.List; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.boot.json.JsonParseException; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.http.converter.HttpMessageNotReadableException; -import org.springframework.validation.FieldError; -import org.springframework.validation.ObjectError; -import org.springframework.web.HttpMediaTypeNotAcceptableException; -import org.springframework.web.bind.MethodArgumentNotValidException; -import org.springframework.web.bind.annotation.ControllerAdvice; -import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.bind.annotation.ResponseStatus; - -@ControllerAdvice -public class GlobalExceptionHandler { - private static Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class); - - @ResponseStatus(HttpStatus.BAD_REQUEST) - @ExceptionHandler(MethodArgumentNotValidException.class) - public ResponseEntity handleValidationExceptions( - MethodArgumentNotValidException ex) { - List fieldErrorResponses = new ArrayList<>(); - for (ObjectError error : ex.getBindingResult().getAllErrors()) { - if (error instanceof FieldError) { - FieldError fieldError = (FieldError) error; - fieldErrorResponses.add( - new FieldErrorsResponse(fieldError.getField(), fieldError.getDefaultMessage())); - } - } - - ValidationErrorResponse errorResponse = - new ValidationErrorResponse(ErrorCode.VALIDATION_ERROR, fieldErrorResponses); - return new ResponseEntity<>( - FacadeError.builder().validationErrors(errorResponse).build(), HttpStatus.BAD_REQUEST); - } - - @ExceptionHandler(HttpMessageNotReadableException.class) - public ResponseEntity handleHttpMessageNotReadable(HttpMessageNotReadableException ex) { - Throwable cause = ex.getCause(); - String errorMessage = "Invalid request. Please check the JSON format."; - - if (cause instanceof InvalidFormatException) { - InvalidFormatException invalidFormatException = (InvalidFormatException) cause; - Class targetType = invalidFormatException.getTargetType(); - errorMessage = - "Invalid input: Unable to map value to " - + targetType.getSimpleName() - + ", Kindly check base64 data"; - } else if (cause instanceof JsonMappingException) { - errorMessage = "Invalid JSON structure. " + getParseExceptionMessage(cause); - } else if (cause instanceof JsonParseException) { - errorMessage = "JSON parse error: " + cause.getMessage(); - } else if (cause != null) { - errorMessage += " Error: " + cause.getMessage(); - } - - FacadeError response = - FacadeError.builder() - .description("Invalid request. Please check the JSON format.") - .error( - ErrorResponse.builder().message(errorMessage).code(ErrorCode.PARSE_ERROR).build()) - .build(); - - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(response); - } - - @ExceptionHandler(HttpMediaTypeNotAcceptableException.class) - public ResponseEntity handleNotAcceptable(HttpMediaTypeNotAcceptableException ex) { - log.error("406 Not Acceptable: " + ex.getMessage()); - - ErrorResponse errorResponse = - new ErrorResponse( - ErrorCode.PARSE_ERROR, - "The requested media type is not supported. Please check the 'Accept' header and base64 data if present"); - return new ResponseEntity<>( - FacadeError.builder() - .description("Issue with base64 data or contentType/accept") - .error(errorResponse) - .build(), - HttpStatus.BAD_REQUEST); - } - - @ExceptionHandler(ParseException.class) - public ResponseEntity handleParseException(ParseException ex) { - String errorMessage = "ParseError: " + ex.getMessage(); - - log.error("Parse error: " + ex.getMessage()); - ErrorResponse errorResponse = new ErrorResponse(ErrorCode.PARSE_ERROR, errorMessage); - return new ResponseEntity<>(errorResponse, HttpStatus.BAD_REQUEST); - } - - private String getParseExceptionMessage(Throwable cause) { - JsonMappingException jsonMappingException = (JsonMappingException) cause; - - StringBuilder fieldPath = new StringBuilder(); - for (JsonMappingException.Reference ref : jsonMappingException.getPath()) { - if (ref.getIndex() != -1) { - fieldPath.append("[").append(ref.getIndex()).append("]"); - } else if (ref.getFieldName() != null) { - if (fieldPath.length() > 0) fieldPath.append("."); - fieldPath.append(ref.getFieldName()); - } - } - - return "JSON parse error in field '" - + fieldPath - + "': " - + jsonMappingException.getOriginalMessage(); - } -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/exceptions/NotBlankFields.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/exceptions/NotBlankFields.java deleted file mode 100644 index b503eb87..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/exceptions/NotBlankFields.java +++ /dev/null @@ -1,20 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.exceptions; - -import jakarta.validation.Constraint; -import jakarta.validation.Payload; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Constraint(validatedBy = NotBlankFieldsValidator.class) -@Target({ElementType.TYPE}) -@Retention(RetentionPolicy.RUNTIME) -public @interface NotBlankFields { - String message() default "{field} is mandatory"; - - Class[] groups() default {}; - - Class[] payload() default {}; -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/exceptions/NotBlankFieldsValidator.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/exceptions/NotBlankFieldsValidator.java deleted file mode 100644 index e6da7bde..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/exceptions/NotBlankFieldsValidator.java +++ /dev/null @@ -1,49 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.exceptions; - -import jakarta.validation.ConstraintValidator; -import jakarta.validation.ConstraintValidatorContext; -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.List; -import org.apache.commons.lang3.StringUtils; - -public class NotBlankFieldsValidator implements ConstraintValidator { - - private String message; - - @Override - public void initialize(NotBlankFields constraintAnnotation) { - this.message = constraintAnnotation.message(); - } - - @Override - public boolean isValid(Object obj, ConstraintValidatorContext context) { - List nullFields = new ArrayList<>(); - - for (Field field : obj.getClass().getDeclaredFields()) { - field.setAccessible(true); - try { - Object value = field.get(obj); - if (value == null || StringUtils.isBlank(value.toString())) { - nullFields.add(field.getName()); - } - } catch (IllegalAccessException e) { - e.printStackTrace(); - } - } - - if (!nullFields.isEmpty()) { - context.disableDefaultConstraintViolation(); - for (String nullField : nullFields) { - context - .buildConstraintViolationWithTemplate(nullField + " is mandatory") - .addPropertyNode(nullField) - .addConstraintViolation(); - } - return false; - } - - return true; - } -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/exceptions/StreamUtils.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/exceptions/StreamUtils.java deleted file mode 100644 index 92f6c911..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/exceptions/StreamUtils.java +++ /dev/null @@ -1,29 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.exceptions; - -import java.util.function.Function; - -public class StreamUtils { - - @FunctionalInterface - public interface CheckedFunction { - R apply(T t) throws Exception; - } - - public static Function wrapException(CheckedFunction function) { - return t -> { - try { - return function.apply(t); - } catch (Exception e) { - throw new RuntimeException( - "Exception in stream processing" - + e.getMessage() - + " " - + e.getCause() - + " " - + e.getLocalizedMessage(), - e); - } - }; - } -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/DiagnosticReportRequest.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/DiagnosticReportRequest.java deleted file mode 100644 index 1b4d7d73..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/DiagnosticReportRequest.java +++ /dev/null @@ -1,47 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.requests; - -import com.nha.abdm.fhir.mapper.rest.common.helpers.DocumentResource; -import com.nha.abdm.fhir.mapper.rest.common.helpers.OrganisationResource; -import com.nha.abdm.fhir.mapper.rest.common.helpers.PatientResource; -import com.nha.abdm.fhir.mapper.rest.common.helpers.PractitionerResource; -import com.nha.abdm.fhir.mapper.rest.requests.helpers.DiagnosticResource; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Pattern; -import java.util.List; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@NoArgsConstructor -@AllArgsConstructor -@Data -@Builder -public class DiagnosticReportRequest { - @Pattern(regexp = "DiagnosticReportRecord") - @NotBlank(message = "BundleType is mandatory and must not be empty : 'DiagnosticReportRecord'") - private String bundleType; - - @NotBlank(message = "careContextReference is mandatory and must not be empty") - private String careContextReference; - - @Valid - @NotNull(message = "Patient demographic details are mandatory and must not be empty") private PatientResource patient; - - @Pattern( - regexp = "^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z)?$", - message = "Value must match either yyyy-MM-dd or yyyy-MM-dd'T'HH:mm:ss.SSSZ") - @NotBlank(message = "visitDate is mandatory timestamp") - @NotNull private String visitDate; - - @Valid - @NotNull(message = "practitioners are mandatory and must not be empty") private List practitioners; - - private OrganisationResource organisation; - private String encounter; - @Valid private List diagnostics; - @Valid private List documents; -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/DischargeSummaryRequest.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/DischargeSummaryRequest.java deleted file mode 100644 index c5cc13d9..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/DischargeSummaryRequest.java +++ /dev/null @@ -1,58 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.requests; - -import com.nha.abdm.fhir.mapper.rest.common.helpers.DocumentResource; -import com.nha.abdm.fhir.mapper.rest.common.helpers.OrganisationResource; -import com.nha.abdm.fhir.mapper.rest.common.helpers.PatientResource; -import com.nha.abdm.fhir.mapper.rest.common.helpers.PractitionerResource; -import com.nha.abdm.fhir.mapper.rest.requests.helpers.*; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Pattern; -import java.util.List; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@NoArgsConstructor -@AllArgsConstructor -@Data -@Builder -public class DischargeSummaryRequest { - @Pattern(regexp = "DischargeSummaryRecord") - @NotBlank(message = "BundleType is mandatory and must not be empty : 'DischargeSummaryRecord'") - private String bundleType; - - @NotBlank(message = "careContextReference is mandatory and must not be empty") - private String careContextReference; - - @Valid - @NotNull(message = "Patient demographic details are mandatory and must not be empty") private PatientResource patient; - - private String encounter; - - @Valid - @NotNull(message = "practitioners are mandatory and must not be empty") private List practitioners; - - @Valid - @NotNull(message = "organisation is mandatory") private OrganisationResource organisation; - - @Valid private List chiefComplaints; - @Valid private List physicalExaminations; - private List allergies; - @Valid private List medicalHistories; - @Valid private List familyHistories; - @Valid private List diagnostics; - @Valid private CarePlanResource carePlan; - - @Pattern( - regexp = "^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z)?$", - message = "Value must match either yyyy-MM-dd or yyyy-MM-dd'T'HH:mm:ss.SSSZ") - @NotNull(message = "authoredOn is mandatory timestamp") @NotNull private String authoredOn; - - @Valid private List medications; - @Valid private List procedures; - @Valid private List documents; -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/HealthDocumentRecord.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/HealthDocumentRecord.java deleted file mode 100644 index e8bff7d3..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/HealthDocumentRecord.java +++ /dev/null @@ -1,46 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.requests; - -import com.nha.abdm.fhir.mapper.rest.common.helpers.DocumentResource; -import com.nha.abdm.fhir.mapper.rest.common.helpers.OrganisationResource; -import com.nha.abdm.fhir.mapper.rest.common.helpers.PatientResource; -import com.nha.abdm.fhir.mapper.rest.common.helpers.PractitionerResource; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Pattern; -import java.util.List; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@NoArgsConstructor -@AllArgsConstructor -@Data -@Builder -public class HealthDocumentRecord { - @Pattern(regexp = "HealthDocumentRecord") - @NotBlank(message = "BundleType is mandatory and must not be empty : 'HealthDocumentRecord'") - private String bundleType; - - @NotBlank(message = "careContextReference is mandatory and must not be empty") - private String careContextReference; - - @Valid - @NotNull(message = "Patient demographic details are mandatory and must not be empty") private PatientResource patient; - - @Pattern( - regexp = "^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z)?$", - message = "Value must match either yyyy-MM-dd or yyyy-MM-dd'T'HH:mm:ss.SSSZ") - private String authoredOn; - - @Valid - @NotNull(message = "practitioners are mandatory and must not be empty") private List practitioners; - - private OrganisationResource organisation; - private String encounter; - - @NotNull(message = "documents are mandatory") @Valid - private List documents; -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/ImmunizationRequest.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/ImmunizationRequest.java deleted file mode 100644 index a40d1882..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/ImmunizationRequest.java +++ /dev/null @@ -1,50 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.requests; - -import com.nha.abdm.fhir.mapper.rest.common.helpers.DocumentResource; -import com.nha.abdm.fhir.mapper.rest.common.helpers.OrganisationResource; -import com.nha.abdm.fhir.mapper.rest.common.helpers.PatientResource; -import com.nha.abdm.fhir.mapper.rest.common.helpers.PractitionerResource; -import com.nha.abdm.fhir.mapper.rest.requests.helpers.ImmunizationResource; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Pattern; -import java.util.List; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@NoArgsConstructor -@AllArgsConstructor -@Data -@Builder -public class ImmunizationRequest { - @Pattern(regexp = "ImmunizationRecord") - @NotBlank(message = "BundleType is mandatory and must not be empty : 'ImmunizationRecord'") - private String bundleType; - - @NotBlank(message = "careContextReference is mandatory and must not be empty") - private String careContextReference; - - @Valid - @NotNull(message = "Patient demographic details are mandatory and must not be empty") private PatientResource patient; - - @Valid - @NotNull(message = "practitioners are mandatory and must not be empty") private List practitioners; - - private OrganisationResource organisation; - private String encounter; - - @Pattern( - regexp = "^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z)?$", - message = "Value must match either yyyy-MM-dd or yyyy-MM-dd'T'HH:mm:ss.SSSZ") - @NotBlank(message = "authoredOn is mandatory timestamp") - private String authoredOn; - - @Valid - @NotNull(message = "Immunizations are mandatory") private List immunizations; - - @Valid private List documents; -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/OPConsultationRequest.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/OPConsultationRequest.java deleted file mode 100644 index 2bd6f501..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/OPConsultationRequest.java +++ /dev/null @@ -1,60 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.requests; - -import com.nha.abdm.fhir.mapper.rest.common.helpers.DocumentResource; -import com.nha.abdm.fhir.mapper.rest.common.helpers.OrganisationResource; -import com.nha.abdm.fhir.mapper.rest.common.helpers.PatientResource; -import com.nha.abdm.fhir.mapper.rest.common.helpers.PractitionerResource; -import com.nha.abdm.fhir.mapper.rest.requests.helpers.*; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Pattern; -import java.util.List; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@NoArgsConstructor -@AllArgsConstructor -@Data -@Builder -public class OPConsultationRequest { - @Pattern(regexp = "OPConsultRecord") - @NotBlank(message = "BundleType is mandatory and must not be empty : 'OPConsultRecord'") - private String bundleType; - - @NotBlank(message = "careContextReference is mandatory and must not be empty") - private String careContextReference; - - @Valid - @NotNull(message = "Patient demographic details are mandatory and must not be empty") private PatientResource patient; - - private String encounter; - - @Valid - @NotNull(message = "practitioners are mandatory and must not be empty") private List practitioners; - - @Valid - @NotNull(message = "organisation is mandatory") private OrganisationResource organisation; - - @Valid private List chiefComplaints; - @Valid private List physicalExaminations; - private List allergies; - @Valid private List medicalHistories; - @Valid private List familyHistories; - @Valid private List serviceRequests; - - @Pattern( - regexp = "^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z)?$", - message = "Value must match either yyyy-MM-dd or yyyy-MM-dd'T'HH:mm:ss.SSSZ") - @NotNull(message = "authoredOn is mandatory timestamp") @NotNull private String visitDate; - - @Valid private List medications; - @Valid private List followups; - @Valid private List procedures; - @Valid private List referrals; - @Valid private List otherObservations; - @Valid private List documents; -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/PrescriptionRequest.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/PrescriptionRequest.java deleted file mode 100644 index a37f78a4..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/PrescriptionRequest.java +++ /dev/null @@ -1,51 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.requests; - -import com.nha.abdm.fhir.mapper.rest.common.helpers.DocumentResource; -import com.nha.abdm.fhir.mapper.rest.common.helpers.OrganisationResource; -import com.nha.abdm.fhir.mapper.rest.common.helpers.PatientResource; -import com.nha.abdm.fhir.mapper.rest.common.helpers.PractitionerResource; -import com.nha.abdm.fhir.mapper.rest.requests.helpers.PrescriptionResource; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Pattern; -import java.util.List; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@NoArgsConstructor -@AllArgsConstructor -@Data -@Builder -public class PrescriptionRequest { - @Pattern(regexp = "PrescriptionRecord") - @NotBlank(message = "BundleType is mandatory and must not be empty : 'PrescriptionRecord'") - private String bundleType; - - @NotBlank(message = "careContextReference is mandatory and must not be empty") - private String careContextReference; - - @Valid - @NotNull(message = "Patient demographic details are mandatory and must not be empty") private PatientResource patient; - - @Pattern( - regexp = "^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z)?$", - message = "Value must match either yyyy-MM-dd or yyyy-MM-dd'T'HH:mm:ss.SSSZ") - @NotBlank(message = "authoredOn is mandatory timestamp") - private String authoredOn; - - private String encounter; - - @Valid - @NotNull(message = "practitioners are mandatory and must not be empty") private List practitioners; - - private OrganisationResource organisation; - - @Valid - @NotNull(message = "prescription is mandatory and must not be empty") private List prescriptions; - - @Valid private List documents; -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/WellnessRecordRequest.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/WellnessRecordRequest.java deleted file mode 100644 index 6a10714a..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/WellnessRecordRequest.java +++ /dev/null @@ -1,57 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.requests; - -import com.nha.abdm.fhir.mapper.rest.common.helpers.DocumentResource; -import com.nha.abdm.fhir.mapper.rest.common.helpers.OrganisationResource; -import com.nha.abdm.fhir.mapper.rest.common.helpers.PatientResource; -import com.nha.abdm.fhir.mapper.rest.common.helpers.PractitionerResource; -import com.nha.abdm.fhir.mapper.rest.requests.helpers.ObservationResource; -import com.nha.abdm.fhir.mapper.rest.requests.helpers.WellnessObservationResource; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Pattern; -import java.util.List; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@NoArgsConstructor -@AllArgsConstructor -@Data -@Builder -public class WellnessRecordRequest { - @Pattern(regexp = "WellnessRecord") - @NotBlank(message = "BundleType is mandatory and must not be empty : 'WellnessRecord'") - private String bundleType; - - @NotBlank(message = "careContextReference is mandatory and must not be empty") - private String careContextReference; - - @Valid - @NotNull(message = "Patient demographic details are mandatory and must not be empty") private PatientResource patient; - - private String encounter; - - @Pattern( - regexp = "^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z)?$", - message = "Value must match either yyyy-MM-dd or yyyy-MM-dd'T'HH:mm:ss.SSSZ") - @NotBlank(message = "authoredOn is mandatory timestamp") - private String authoredOn; - - @Valid - @NotNull(message = "practitioners are mandatory and must not be empty") private List practitioners; - - @Valid - @NotNull(message = "organisation is mandatory") private OrganisationResource organisation; - - @Valid private List vitalSigns; - @Valid private List bodyMeasurements; - @Valid private List physicalActivities; - @Valid private List generalAssessments; - @Valid private List womanHealths; - @Valid private List lifeStyles; - @Valid private List otherObservations; - @Valid private List documents; -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/CarePlanResource.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/CarePlanResource.java deleted file mode 100644 index bdd895ed..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/CarePlanResource.java +++ /dev/null @@ -1,24 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.requests.helpers; - -import com.nha.abdm.fhir.mapper.rest.common.helpers.DateRange; -import jakarta.validation.constraints.Pattern; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@NoArgsConstructor -@AllArgsConstructor -@Data -@Builder -public class CarePlanResource { - @Pattern(regexp = "^(proposal|plan|order|option)$") - private String intent; - - private DateRange period; - private String type; - private String description; - private String notes; - private String goal; -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ChiefComplaintResource.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ChiefComplaintResource.java deleted file mode 100644 index 6e2a3fd2..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ChiefComplaintResource.java +++ /dev/null @@ -1,23 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.requests.helpers; - -import com.nha.abdm.fhir.mapper.rest.common.helpers.DateRange; -import jakarta.validation.constraints.NotBlank; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@NoArgsConstructor -@AllArgsConstructor -@Data -@Builder -public class ChiefComplaintResource { - @NotBlank(message = "complaint is mandatory") - private String complaint; - - @NotBlank(message = "recordedDate is mandatory") - private String recordedDate; - - private DateRange dateRange; -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/DiagnosticPresentedForm.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/DiagnosticPresentedForm.java deleted file mode 100644 index 247c7717..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/DiagnosticPresentedForm.java +++ /dev/null @@ -1,20 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.requests.helpers; - -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class DiagnosticPresentedForm { - @NotBlank(message = "presentedForm contentType is mandatory") - private String contentType; - - @NotNull(message = "presentedForm data is mandatory") private byte[] data; -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/DiagnosticResource.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/DiagnosticResource.java deleted file mode 100644 index 71da6842..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/DiagnosticResource.java +++ /dev/null @@ -1,38 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.requests.helpers; - -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Pattern; -import java.util.List; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class DiagnosticResource { - @NotBlank(message = "serviceName is mandatory") - private String serviceName; - - @NotBlank(message = "serviceCategory is mandatory") - private String serviceCategory; - - @Pattern( - regexp = "^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z)?$", - message = "Value must match either yyyy-MM-dd or yyyy-MM-dd'T'HH:mm:ss.SSSZ") - @NotBlank(message = "authoredOn is mandatory timestamp") - @NotNull private String authoredOn; - - @Valid - @NotNull(message = "results of the report is mandatory") private List result; - - @NotBlank(message = "conclusion is mandatory") - private String conclusion; - - @Valid private DiagnosticPresentedForm presentedForm; -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/FamilyObservationResource.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/FamilyObservationResource.java deleted file mode 100644 index f40d3a67..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/FamilyObservationResource.java +++ /dev/null @@ -1,18 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.requests.helpers; - -import com.nha.abdm.fhir.mapper.rest.exceptions.NotBlankFields; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@NoArgsConstructor -@AllArgsConstructor -@Data -@Builder -@NotBlankFields -public class FamilyObservationResource { - private String relationship; - private String observation; -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/FollowupResource.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/FollowupResource.java deleted file mode 100644 index 49874c5a..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/FollowupResource.java +++ /dev/null @@ -1,19 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.requests.helpers; - -import com.nha.abdm.fhir.mapper.rest.exceptions.NotBlankFields; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@NoArgsConstructor -@AllArgsConstructor -@Data -@Builder -@NotBlankFields -public class FollowupResource { - private String serviceType; - private String appointmentTime; - private String reason; -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ImmunizationResource.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ImmunizationResource.java deleted file mode 100644 index 5f257540..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ImmunizationResource.java +++ /dev/null @@ -1,28 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.requests.helpers; - -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.Pattern; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@NoArgsConstructor -@AllArgsConstructor -@Data -@Builder -public class ImmunizationResource { - @Pattern( - regexp = "^\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])$", - message = "Date must be in the format yyyy-MM-dd") - @NotBlank(message = "date of vaccine is mandatory") - private String date; - - @NotBlank(message = "vaccineName is mandatory") - private String vaccineName; - - private String lotNumber; - private String manufacturer; - private int doseNumber; -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ObservationResource.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ObservationResource.java deleted file mode 100644 index 3729b31e..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ObservationResource.java +++ /dev/null @@ -1,22 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.requests.helpers; - -import jakarta.validation.constraints.NotBlank; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@NoArgsConstructor -@AllArgsConstructor -@Data -@Builder -public class ObservationResource { - @NotBlank(message = "observation is mandatory") - private String observation; - - // @NotNull(message = "result is mandatory") - private String result; - - private ValueQuantityResource valueQuantity; -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/PrescriptionResource.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/PrescriptionResource.java deleted file mode 100644 index eceaa256..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/PrescriptionResource.java +++ /dev/null @@ -1,32 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.requests.helpers; - -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.Pattern; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@NoArgsConstructor -@AllArgsConstructor -@Data -@Builder -public class PrescriptionResource { - @NotBlank(message = "medicine is mandatory") - private String medicine; - - @NotBlank(message = "dosage is mandatory") - private String dosage; - - @Pattern( - regexp = "^\\d{1,2}-\\d{1,2}-(S|MIN|H|D|WK|MO)$", - message = - "timing should have frequency-period-periodUnit '(0-99)-(0-99)-(S ~ seconds | MIN ~ minutes | H ~ hours | D ~ days| WK ~ week| MO ~ month' ex: 1-2-D") - private String timing; - - private String route; - private String method; - private String additionalInstructions; - private String reason; -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ProcedureResource.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ProcedureResource.java deleted file mode 100644 index 9a0be909..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ProcedureResource.java +++ /dev/null @@ -1,29 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.requests.helpers; - -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.Pattern; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@NoArgsConstructor -@AllArgsConstructor -@Data -@Builder -public class ProcedureResource { - @NotBlank(message = "date of the procedure is mandatory") - private String date; - - @Pattern(regexp = "COMPLETED|INPROGRESS") - private String status; - - @NotBlank(message = "procedureReason is mandatory") - private String procedureReason; - - private String outcome; - - @NotBlank(message = "procedureName is mandatory") - private String procedureName; -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ServiceRequestResource.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ServiceRequestResource.java deleted file mode 100644 index 3137813d..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ServiceRequestResource.java +++ /dev/null @@ -1,22 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.requests.helpers; - -import jakarta.validation.constraints.NotBlank; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@NoArgsConstructor -@AllArgsConstructor -@Data -@Builder -public class ServiceRequestResource { - @NotBlank(message = "status is mandatory") - private String status; - - @NotBlank(message = "details of service is mandatory") - private String details; - - private String specimen; -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ValueQuantityResource.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ValueQuantityResource.java deleted file mode 100644 index 343c934c..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ValueQuantityResource.java +++ /dev/null @@ -1,16 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.requests.helpers; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@NoArgsConstructor -@AllArgsConstructor -@Data -@Builder -public class ValueQuantityResource { - private String unit; - private double value; -} diff --git a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/WellnessObservationResource.java b/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/WellnessObservationResource.java deleted file mode 100644 index 3e62bb0a..00000000 --- a/fhir-mapper/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/WellnessObservationResource.java +++ /dev/null @@ -1,22 +0,0 @@ -/* (C) 2024 */ -package com.nha.abdm.fhir.mapper.rest.requests.helpers; - -import jakarta.validation.constraints.NotBlank; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@NoArgsConstructor -@AllArgsConstructor -@Data -@Builder -public class WellnessObservationResource { - @NotBlank(message = "observation is mandatory") - private String observation; - - // @NotNull(message = "result is mandatory") - private String result; - - private ValueQuantityResource valueQuantity; -} diff --git a/fhir-mapper/src/main/resources/application.properties b/fhir-mapper/src/main/resources/application.properties deleted file mode 100644 index 3fda537d..00000000 --- a/fhir-mapper/src/main/resources/application.properties +++ /dev/null @@ -1,24 +0,0 @@ -server.port=8085 - - -spring.banner.location=classpath:banner.txt - -spring.datasource.url=jdbc:h2:mem:fhir_mapper;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE -spring.datasource.driver-class-name=org.h2.Driver -spring.datasource.username=abdm -spring.datasource.password= -spring.jpa.database-platform=org.hibernate.dialect.H2Dialect -spring.h2.console.enabled=true -spring.h2.console.path=/h2-console -spring.jpa.properties.hibernate.globally_quoted_identifiers=true -spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl - - - -# LOGGER -# You can disable the logs by commenting the below lines. -logging.level.com.nha.abdm.wrapper=DEBUG -logging.level.org.springframework.web=DEBUG -logging.level.org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor=TRACE -logging.level.org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor=TRACE -logging.level.org.springframework.web.HttpLogging=TRACE \ No newline at end of file diff --git a/fhir-mapper/src/main/resources/banner.txt b/fhir-mapper/src/main/resources/banner.txt deleted file mode 100644 index fe481d87..00000000 --- a/fhir-mapper/src/main/resources/banner.txt +++ /dev/null @@ -1,9 +0,0 @@ - _______ __ __ __ .______ .___ ___. ___ .______ .______ _______ .______ -| ____|| | | | | | | _ \ | \/ | / \ | _ \ | _ \ | ____|| _ \ -| |__ | |__| | | | | |_) | ______| \ / | / ^ \ | |_) | | |_) | | |__ | |_) | -| __| | __ | | | | / |______| |\/| | / /_\ \ | ___/ | ___/ | __| | / -| | | | | | | | | |\ \----. | | | | / _____ \ | | | | | |____ | |\ \----. -|__| |__| |__| |__| | _| `._____| |__| |__| /__/ \__\ | _| | _| |_______|| _| `._____| - -${application.title} ${application.version} -NHA-VenuAjitesh \ No newline at end of file diff --git a/fhir-mapper/src/main/resources/snomed/SnomedConditionProcedure.json b/fhir-mapper/src/main/resources/snomed/SnomedConditionProcedure.json deleted file mode 100644 index 960e3919..00000000 --- a/fhir-mapper/src/main/resources/snomed/SnomedConditionProcedure.json +++ /dev/null @@ -1,2638 +0,0 @@ -[ - { - "code": "781087000", - "display": "Medical care" - }, - { - "code": "133898004", - "display": "Preoperative care" - }, - { - "code": "11429006", - "display": "Consultation" - }, - { - "code": "363680008", - "display": "Radiographic imaging procedure" - }, - { - "code": "53115007", - "display": "Diagnostic dental procedure" - }, - { - "code": "32150000", - "display": "Periodontic procedure" - }, - { - "code": "55670007", - "display": "Endodontic procedure" - }, - { - "code": "281171009", - "display": "Maxillofacial technical (device) procedure" - }, - { - "code": "79076007", - "display": "Prosthetic readjustment" - }, - { - "code": "110461004", - "display": "Adjunctive care" - }, - { - "code": "225362009", - "display": "Dental care" - }, - { - "code": "103697008", - "display": "Patient referral for dental care" - }, - { - "code": "384762007", - "display": "Transportation procedure" - }, - { - "code": "52637005", - "display": "Test tube ovum fertilization" - }, - { - "code": "113091000", - "display": "Magnetic resonance imaging" - }, - { - "code": "53958007", - "display": "Harvesting of donor material" - }, - { - "code": "271298009", - "display": "Organ retrieval operation" - }, - { - "code": "265764009", - "display": "Renal dialysis" - }, - { - "code": "717278002", - "display": "Burn care management" - }, - { - "code": "50849002", - "display": "Emergency room admission" - }, - { - "code": "310054005", - "display": "Infectious diseases service" - }, - { - "code": "240917005", - "display": "Interventional radiology" - }, - { - "code": "64915003", - "display": "Cardiac surgery procedure" - }, - { - "code": "305367005", - "display": "Admission to gastroenterology department" - }, - { - "code": "310056007", - "display": "Nephrology service" - }, - { - "code": "310057003", - "display": "Neurology service" - }, - { - "code": "310036006", - "display": "Cardiology service" - }, - { - "code": "305366001", - "display": "Admission to endocrinology department" - }, - { - "code": "700415000", - "display": "Pediatric surgery care management" - }, - { - "code": "305434007", - "display": "Admission to urology department" - }, - { - "code": "830077005", - "display": "Admission to neonatal intensive care unit" - }, - { - "code": "310039004", - "display": "Pulmonary medicine service" - }, - { - "code": "108290001", - "display": "Radiation oncology AND/OR radiotherapy" - }, - { - "code": "399097000", - "display": "Administration of anesthesia" - }, - { - "code": "224886008", - "display": "Treatment room (environment)" - }, - { - "code": "9632001", - "display": "Nursing procedure (procedure)" - }, - { - "code": "13288007", - "display": "Monitor, device (physical object)" - }, - { - "code": "309904001", - "display": "Intensive care unit (environment)" - }, - { - "code": "182998008", - "display": "Intensive nursing care (regime/therapy)" - }, - { - "code": "272181003", - "display": "Clinical equipment and/or device (physical object)" - }, - { - "code": "225738002", - "display": "Operating room (environment)" - }, - { - "code": "63653004", - "display": "Biomedical device (physical object)" - }, - { - "code": "3895009", - "display": "Application of dressing (procedure)" - }, - { - "code": "289122001", - "display": "Cosmetic material (substance)" - }, - { - "code": "16349000", - "display": "Orthopedic device (physical object)" - }, - { - "code": "6919005", - "display": "Protective clothing material, device (physical object)" - }, - { - "code": "430033006", - "display": "Infusion pump (physical object)" - }, - { - "code": "11429006", - "display": "Consultation (procedure)" - }, - { - "code": "387713003", - "display": "Surgical procedure (procedure)" - }, - { - "code": "398228004", - "display": "Anesthesia consultation (procedure)" - }, - { - "code": "878786001", - "display": "Operating room technician (occupation)" - }, - { - "code": "91251008", - "display": "Physical therapy procedure (regime/therapy)" - }, - { - "code": "71388002", - "display": "Procedure (procedure)" - }, - { - "code": "367336001", - "display": "Chemotherapy (procedure)" - }, - { - "code": "278414003", - "display": "Pain management (procedure)" - }, - { - "code": "127801007", - "display": "Body fluid analysis (procedure)" - }, - { - "code": "276341003", - "display": "Cardiovascular investigation (procedure)" - }, - { - "code": "252275004", - "display": "Hematology test (procedure)" - }, - { - "code": "19851009", - "display": "Microbiology procedure (procedure)" - }, - { - "code": "118678004", - "display": "Procedure on nervous system (procedure)" - }, - { - "code": "371572003", - "display": "Nuclear medicine procedure (procedure)" - }, - { - "code": "15220000", - "display": "Laboratory test (procedure)" - }, - { - "code": "363679005", - "display": "Imaging (procedure)" - }, - { - "code": "396550006", - "display": "Blood test (procedure)" - }, - { - "code": "43782000", - "display": "Organ or system related test (procedure)" - }, - { - "code": "252416005", - "display": "Histopathology test (procedure)" - }, - { - "code": "415564008", - "display": "Specimen sent to reference laboratory for testing (situation)" - }, - { - "code": "715544005", - "display": "Transportation by ambulance with assistance of one person (procedure)" - }, - { - "code": "305056002", - "display": "Admission procedure (procedure)" - }, - { - "code": "184047000", - "display": "Patient registration (procedure)" - }, - { - "code": "107727007", - "display": "Chart related administrative procedure (procedure)" - }, - { - "code": "14734007", - "display": "Administrative procedure (procedure)" - }, - { - "code": "312635000", - "display": "Provision of telephone (procedure)" - }, - { - "code": "303607000", - "display": "Biomedical equipment (physical object)" - }, - { - "code": "225737007", - "display": "Mortuary (environment)" - }, - { - "code": "33022008", - "display": "Hospital-based outpatient department (environment)" - }, - { - "code": "171324002", - "display": "New patient screening (procedure)" - }, - { - "code": "112802009", - "display": "Cardiovascular operative procedure (procedure)" - }, - { - "code": "118672003", - "display": "Procedure on cardiovascular system (procedure)" - }, - { - "code": "118797008", - "display": "Procedure on heart (procedure)" - }, - { - "code": "81733005", - "display": "Dental surgical procedure (procedure)" - }, - { - "code": "118683007", - "display": "Procedure on ear and related structures (procedure)" - }, - { - "code": "118673008", - "display": "Procedure on digestive system (procedure)" - }, - { - "code": "118675001", - "display": "Procedure on female genital system (procedure)" - }, - { - "code": "118677009", - "display": "Procedure on urinary system (procedure)" - }, - { - "code": "89901005", - "display": "Operative procedure on head (procedure)" - }, - { - "code": "118897002", - "display": "Procedure on eye proper (procedure)" - }, - { - "code": "118666003", - "display": "Procedure on musculoskeletal system (procedure)" - }, - { - "code": "225746001", - "display": "Ward (environment)" - }, - { - "code": "705333009", - "display": "Toileting assistive device (physical object)" - }, - { - "code": "105789008", - "display": "Cannula/tube/catheter, device (physical object)" - }, - { - "code": "108290001", - "display": "Radiation oncology AND/OR radiotherapy (procedure)" - }, - { - "code": "23745001", - "display": "Documentation procedure (procedure)" - }, - { - "code": "468046005", - "display": "Cardiac catheterization laboratory computer (physical object)" - }, - { - "code": "118781003", - "display": "Procedure on nose (procedure)" - }, - { - "code": "118670006", - "display": "Procedure on upper respiratory tract (procedure)" - }, - { - "code": "763158003", - "display": "Medicinal product (product)" - }, - { - "code": "310000008", - "display": "Accident and Emergency service (qualifier value)" - }, - { - "code": "737481003", - "display": "Inpatient care management (procedure)" - }, - { - "code": "11429006", - "display": "Consultation (procedure)" - }, - { - "code": "737850002", - "display": "Day care case management (procedure)" - }, - { - "code": "410345004", - "display": "Medical/dental care case management (procedure)" - }, - { - "code": "387713003", - "display": "Surgical procedure (procedure)" - }, - { - "code": "73957001", - "display": "Air transport ambulance, device (physical object)" - }, - { - "code": "465341007", - "display": "Automobile ambulance (physical object)" - }, - { - "code": "568291000005106", - "display": "Hospital unit (environment)" - }, - { - "code": "272181003", - "display": "Clinical equipment and/or device (physical object)" - }, - { - "code": "77343006", - "display": "Angiography (procedure)" - }, - { - "code": "439533007", - "display": "Endoscopic balloon dilatation of ostium of paranasal sinus (procedure)" - }, - { - "code": "711364006", - "display": "Surgery using robotic assistance (procedure)" - }, - { - "code": "266719004", - "display": "Oral chemotherapy (procedure)" - }, - { - "code": "713348007", - "display": "Thermoplasty of bronchus (procedure)" - }, - { - "code": "1269349006", - "display": "Transplantation of stem cell (procedure)" - }, - { - "code": "76334006", - "display": "Immunotherapy (procedure)" - }, - { - "code": "763158003", - "display": "Medicinal product (product)" - }, - { - "code": "75516001", - "display": "Psychotherapy (regime/therapy)" - }, - { - "code": "91251008", - "display": "Physical therapy procedure (regime/therapy)" - }, - { - "code": "15220000", - "display": "Laboratory test (procedure)" - }, - { - "code": "51032003", - "display": "Hospital admission, donor for transplant organ (procedure)" - }, - { - "code": "9632001", - "display": "Nursing procedure (procedure)" - }, - { - "code": "5880005", - "display": "Physical examination procedure (procedure)" - }, - { - "code": "29303009", - "display": "Electrocardiographic procedure (procedure)" - }, - { - "code": "16310003", - "display": "Ultrasonography (procedure)" - }, - { - "code": "49083007", - "display": "Administration of vaccine product containing virus antigen (procedure)" - }, - { - "code": "108241001", - "display": "Dialysis procedure (procedure)" - }, - { - "code": "367336001", - "display": "Chemotherapy (procedure)" - }, - { - "code": "713603004", - "display": "Advance care planning (procedure)" - }, - { - "code": "710967003", - "display": "Management of health status after discharge from hospital (procedure)" - }, - { - "code": "49122002", - "display": "Ambulance, device (physical object)" - }, - { - "code": "275926002", - "display": "Screening - health check (procedure)" - }, - { - "code": "33879002", - "display": "Administration of vaccine to produce active immunity (procedure)" - }, - { - "code": "60689008", - "display": "Home care of patient (regime/therapy)" - }, - { - "code": "410225009", - "display": "Mental health care management (procedure)" - }, - { - "code": "410083007", - "display": "Rehabilitation therapy management (procedure)" - }, - { - "code": "737492002", - "display": "Outpatient care management (procedure)" - }, - { - "code": "385907003", - "display": "Eye care management (procedure)" - }, - { - "code": "409972000", - "display": "Pre-hospital care (situation)" - }, - { - "code": "1259939000", - "display": "Ayurveda medicine (qualifier value)" - }, - { - "code": "1259938008", - "display": "Homeopathic medicine (qualifier value)" - }, - { - "code": "1259940003", - "display": "Yoga medicine (qualifier value)" - }, - { - "code": "1259218001", - "display": "Unani medicine (qualifier value)" - }, - { - "code": "1259219009", - "display": "Siddha medicine (qualifier value)" - }, - { - "code": "416113008", - "display": "Febrile disorder" - }, - { - "code": "91302008", - "display": "Sepsis" - }, - { - "code": "76571007", - "display": "Septic shock" - }, - { - "code": "61462000", - "display": "Malaria" - }, - { - "code": "38362002", - "display": "Dengue" - }, - { - "code": "20927009", - "display": "Dengue hemorrhagic fever" - }, - { - "code": "409671005", - "display": "Dengue shock syndrome" - }, - { - "code": "111864006", - "display": "Chikungunya fever" - }, - { - "code": "4834000", - "display": "Typhoid fever" - }, - { - "code": "81000119104", - "display": "Symptomatic human immunodeficiency virus infection" - }, - { - "code": "77377001", - "display": "Leptospirosis" - }, - { - "code": "236071009", - "display": "Chronic diarrhea" - }, - { - "code": "409966000", - "display": "Acute diarrhea" - }, - { - "code": "46799006", - "display": "Dysenteric diarrhea" - }, - { - "code": "57412004", - "display": "Acute viral hepatitis" - }, - { - "code": "76783007", - "display": "Chronic hepatitis" - }, - { - "code": "27916005", - "display": "Abscess of liver" - }, - { - "code": "186803007", - "display": "Visceral leishmaniasis" - }, - { - "code": "233604007", - "display": "Pneumonia" - }, - { - "code": "312682007", - "display": "Empyema" - }, - { - "code": "67256000", - "display": "Tuberculosis of pericardium" - }, - { - "code": "186182003", - "display": "Tuberculosis of pleura" - }, - { - "code": "68566005", - "display": "Urinary tract infectious disease" - }, - { - "code": "34476008", - "display": "Viral encephalitis" - }, - { - "code": "48245008", - "display": "Bacterial arthritis" - }, - { - "code": "19824006", - "display": "Infection of skin and/or subcutaneous tissue" - }, - { - "code": "7520000", - "display": "Pyrexia of unknown origin" - }, - { - "code": "12295008", - "display": "Bronchiectasis" - }, - { - "code": "10509002", - "display": "Acute bronchitis" - }, - { - "code": "195951007", - "display": "Acute exacerbation of chronic obstructive airways disease" - }, - { - "code": "233703007", - "display": "Interstitial lung disease" - }, - { - "code": "301183007", - "display": "Bacterial endocarditis" - }, - { - "code": "86348002", - "display": "Mycotic endocarditis" - }, - { - "code": "31996006", - "display": "Vasculitis" - }, - { - "code": "197456007", - "display": "Acute pancreatitis" - }, - { - "code": "235494005", - "display": "Chronic pancreatitis" - }, - { - "code": "389026000", - "display": "Ascites" - }, - { - "code": "47000000", - "display": "Acute transverse myelitis" - }, - { - "code": "49436004", - "display": "Atrial fibrillation" - }, - { - "code": "35304003", - "display": "Cardiac tamponade" - }, - { - "code": "42343007", - "display": "Congestive heart failure" - }, - { - "code": "708038006", - "display": "Acute exacerbation of asthma" - }, - { - "code": "733858005", - "display": "Acute severe refractory exacerbation of asthma" - }, - { - "code": "233765002", - "display": "Respiratory failure without hypercapnia" - }, - { - "code": "709109004", - "display": "Hypercapnic respiratory failure" - }, - { - "code": "409622000", - "display": "Respiratory failure" - }, - { - "code": "363732003", - "display": "Addison's disease" - }, - { - "code": "7093002", - "display": "Renal colic" - }, - { - "code": "42399005", - "display": "Renal failure syndrome" - }, - { - "code": "128613002", - "display": "Seizure disorder" - }, - { - "code": "230456007", - "display": "Status epilepticus" - }, - { - "code": "230690007", - "display": "Cerebrovascular accident" - }, - { - "code": "192759008", - "display": "Cerebral venous sinus thrombosis" - }, - { - "code": "422504002", - "display": "Ischemic stroke" - }, - { - "code": "274100004", - "display": "Cerebral hemorrhage" - }, - { - "code": "24700007", - "display": "Multiple sclerosis" - }, - { - "code": "74772000", - "display": "Meningomyelitis" - }, - { - "code": "25044007", - "display": "Neuromyelitis optica" - }, - { - "code": "16631009", - "display": "Transverse myelopathy syndrome" - }, - { - "code": "230745008", - "display": "Hydrocephalus" - }, - { - "code": "21263006", - "display": "Myxedema coma" - }, - { - "code": "29028009", - "display": "Thyrotoxic crisis" - }, - { - "code": "90560007", - "display": "Inflammatory disorder due to increased blood urate level" - }, - { - "code": "36118008", - "display": "Pneumothorax" - }, - { - "code": "257277002", - "display": "Combined disorder of muscle AND peripheral nerve" - }, - { - "code": "302866003", - "display": "Hypoglycemia" - }, - { - "code": "280137006", - "display": "Diabetic foot" - }, - { - "code": "420422005", - "display": "Ketoacidosis due to diabetes mellitus" - }, - { - "code": "66931009", - "display": "Hypercalcemia" - }, - { - "code": "5291005", - "display": "Hypocalcemia" - }, - { - "code": "89627008", - "display": "Hyponatremia" - }, - { - "code": "771115008", - "display": "Hypernatremia" - }, - { - "code": "421966007", - "display": "Non-ketotic non-hyperosmolar coma due to diabetes mellitus" - }, - { - "code": "78975002", - "display": "Malignant essential hypertension" - }, - { - "code": "132721000119104", - "display": "Hypertensive emergency" - }, - { - "code": "127040003", - "display": "Sickle cell-hemoglobin SS disease" - }, - { - "code": "39579001", - "display": "Anaphylaxis" - }, - { - "code": "52072009", - "display": "Heat stroke" - }, - { - "code": "55464009", - "display": "Systemic lupus erythematosus" - }, - { - "code": "40956001", - "display": "Guillain-Barré syndrome" - }, - { - "code": "61288004", - "display": "Poisoning caused by venomous snake" - }, - { - "code": "8260003", - "display": "Organophosphate poisoning" - }, - { - "code": "75478009", - "display": "Poisoning" - }, - { - "code": "302497006", - "display": "Hemodialysis" - }, - { - "code": "71192002", - "display": "Peritoneal dialysis" - }, - { - "code": "20720000", - "display": "Plasmapheresis" - }, - { - "code": "33389009", - "display": "Transfusion of whole blood" - }, - { - "code": "54790000", - "display": "Transfusion of blood component" - }, - { - "code": "363679005", - "display": "Imaging" - }, - { - "code": "252416005", - "display": "Histopathology test" - }, - { - "code": "86273004", - "display": "Biopsy" - }, - { - "code": "45900003", - "display": "Esophagectomy" - }, - { - "code": "307332009", - "display": "Esophagectomy and colonic interposition" - }, - { - "code": "708987006", - "display": "Laparoscopic total gastrectomy" - }, - { - "code": "26452005", - "display": "Total gastrectomy" - }, - { - "code": "54956002", - "display": "Gastrostomy" - }, - { - "code": "72971003", - "display": "Gastrojejunostomy with vagotomy" - }, - { - "code": "46381000", - "display": "Truncal vagotomy with pyloroplasty" - }, - { - "code": "287811008", - "display": "Perforated peptic ulcer closure" - }, - { - "code": "235674005", - "display": "Perforation of stomach" - }, - { - "code": "270909006", - "display": "Duodenal perforation" - }, - { - "code": "363742001", - "display": "Pyloroplasty" - }, - { - "code": "173788005", - "display": "Pyloromyotomy" - }, - { - "code": "49245001", - "display": "Bypass gastrojejunostomy" - }, - { - "code": "238280007", - "display": "Drainage of peritoneal pseudocyst" - }, - { - "code": "238275003", - "display": "Drainage of peritoneal cyst" - }, - { - "code": "75389003", - "display": "Pancreaticocystogastrostomy" - }, - { - "code": "234321000", - "display": "Splenic cystogastrostomy" - }, - { - "code": "234322007", - "display": "Splenic cystojejunostomy" - }, - { - "code": "238278001", - "display": "Peritoneal cystojejunostomy" - }, - { - "code": "238279009", - "display": "Peritoneal cystogastrostomy" - }, - { - "code": "174740002", - "display": "Open cystogastrotomy of pancreas" - }, - { - "code": "62937006", - "display": "Feeding enterostomy of jejunum" - }, - { - "code": "301784005", - "display": "Ileostomy operation" - }, - { - "code": "67389003", - "display": "Diverticulectomy of duodenum" - }, - { - "code": "61218006", - "display": "Excision of Meckel's diverticulum" - }, - { - "code": "80146002", - "display": "Excision of appendix" - }, - { - "code": "6025007", - "display": "Laparoscopic appendectomy" - }, - { - "code": "47693006", - "display": "Rupture of appendix" - }, - { - "code": "174052001", - "display": "Drainage of appendix abscess" - }, - { - "code": "26390003", - "display": "Total colectomy" - }, - { - "code": "787874000", - "display": "Laparoscopic total colectomy" - }, - { - "code": "359571009", - "display": "Right colectomy" - }, - { - "code": "50774009", - "display": "Laparoscopic-assisted right colectomy" - }, - { - "code": "82619000", - "display": "Left colectomy" - }, - { - "code": "41330009", - "display": "Laparoscopic-assisted left colectomy" - }, - { - "code": "398740003", - "display": "Colostomy" - }, - { - "code": "1805005", - "display": "Surgical closure of stoma" - }, - { - "code": "84604002", - "display": "Sigmoid colectomy" - }, - { - "code": "174286001", - "display": "Perineal operations for rectal prolapse" - }, - { - "code": "73921006", - "display": "Repair of rectal prolapse by abdominal approach" - }, - { - "code": "440032004", - "display": "Laparoscopic fixation of prolapse of rectum" - }, - { - "code": "274031008", - "display": "Rectal polypectomy" - }, - { - "code": "4558008", - "display": "Anterior resection of rectum" - }, - { - "code": "90527009", - "display": "Laparoscopic-assisted anterior resection of rectum" - }, - { - "code": "315328007", - "display": "Anterior resection of rectum with anastomosis" - }, - { - "code": "392027008", - "display": "Anal fissurectomy" - }, - { - "code": "24496007", - "display": "Hemorrhoidectomy" - }, - { - "code": "412737002", - "display": "Stapling of hemorrhoid" - }, - { - "code": "174396007", - "display": "Pilonidal sinus operation" - }, - { - "code": "107808005", - "display": "Accessory sinus excision" - }, - { - "code": "302392001", - "display": "Curettage of sinus" - }, - { - "code": "74770008", - "display": "Exploratory laparotomy" - }, - { - "code": "177916006", - "display": "Resuture of burst abdomen" - }, - { - "code": "107963000", - "display": "Liver excision" - }, - { - "code": "708590009", - "display": "Laparoscopic wedge resection of liver" - }, - { - "code": "708589000", - "display": "Laparoscopic resection of segment of liver" - }, - { - "code": "38102005", - "display": "Cholecystectomy" - }, - { - "code": "45993005", - "display": "Cholecystectomy with exploration of common duct" - }, - { - "code": "45595009", - "display": "Laparoscopic cholecystectomy" - }, - { - "code": "67557008", - "display": "Laparoscopic cholecystectomy with exploration of common duct" - }, - { - "code": "66361005", - "display": "Excision of choledochal cyst" - }, - { - "code": "234319005", - "display": "Splenectomy" - }, - { - "code": "174776001", - "display": "Total splenectomy" - }, - { - "code": "314118002", - "display": "Laparoscopic total splenectomy" - }, - { - "code": "446408009", - "display": "Laparoscopic excision of part of spleen" - }, - { - "code": "173747005", - "display": "Roux-en-Y gastrojejunostomy" - }, - { - "code": "91516004", - "display": "Distal subtotal pancreatectomy with pancreaticojejunostomy" - }, - { - "code": "116241004", - "display": "Pancreaticoduodenectomy" - }, - { - "code": "20767001", - "display": "Shunt of portal vein to vena cava" - }, - { - "code": "175793006", - "display": "Mesocaval shunt" - }, - { - "code": "238299003", - "display": "Excision of mesenteric cyst" - }, - { - "code": "92433007", - "display": "Benign neoplasm of retroperitoneum" - }, - { - "code": "608797008", - "display": "Open repair of inguinal hernia" - }, - { - "code": "15018006", - "display": "Laparoscopic repair of inguinal hernia" - }, - { - "code": "608796004", - "display": "Open repair of femoral hernia" - }, - { - "code": "608789001", - "display": "Laparoscopic repair of femoral hernia" - }, - { - "code": "608790005", - "display": "Laparoscopic repair of obturator hernia" - }, - { - "code": "238184006", - "display": "Repair of epigastric hernia" - }, - { - "code": "44946007", - "display": "Repair of umbilical hernia" - }, - { - "code": "9877001", - "display": "Repair of paraumbilical hernia" - }, - { - "code": "15694008", - "display": "Repair of spigelian hernia" - }, - { - "code": "238187004", - "display": "Repair of incisional hernia" - }, - { - "code": "9292007", - "display": "Esophageal hiatus hernia repair" - }, - { - "code": "413181005", - "display": "Laparoscopic repair of hiatus hernia" - }, - { - "code": "359890009", - "display": "Fundoplication" - }, - { - "code": "359893006", - "display": "Total fundoplication" - }, - { - "code": "78656005", - "display": "Laparoscopic fundoplication" - }, - { - "code": "21810005", - "display": "Excision of lesion of scrotum" - }, - { - "code": "236326007", - "display": "Excision of multiple scrotal sebaceous cysts" - }, - { - "code": "236347006", - "display": "Hydrocele operation" - }, - { - "code": "176481007", - "display": "Excision of cyst of epididymis" - }, - { - "code": "176490000", - "display": "Reversal of vasectomy" - }, - { - "code": "236334001", - "display": "Total orchidectomy" - }, - { - "code": "178286005", - "display": "Block dissection of inguinal lymph nodes" - }, - { - "code": "112851007", - "display": "Full thickness excision of lip, reconstruction with local flap" - }, - { - "code": "20418004", - "display": "Wedge resection" - }, - { - "code": "173225009", - "display": "Wedge excision of lip" - }, - { - "code": "39562007", - "display": "Vermilionectomy" - }, - { - "code": "173218002", - "display": "Excision of vermilion border and advancement of lip mucosa" - }, - { - "code": "359703006", - "display": "Total glossectomy" - }, - { - "code": "177124000", - "display": "Biopsy of tongue" - }, - { - "code": "173357008", - "display": "Removal of lesion of tongue" - }, - { - "code": "234246002", - "display": "Selective neck dissection of cervical lymph nodes" - }, - { - "code": "59687004", - "display": "Excision of laryngeal polyp" - }, - { - "code": "308030005", - "display": "Microlaryngoscopic vocal cord polypectomy" - }, - { - "code": "173490007", - "display": "Excision of lesion of submandibular gland" - }, - { - "code": "45685007", - "display": "Radical neck dissection" - }, - { - "code": "178347009", - "display": "Excision of branchial cyst" - }, - { - "code": "233401008", - "display": "Excision of carotid body tumor" - }, - { - "code": "302338000", - "display": "Lobectomy of thyroid gland" - }, - { - "code": "24443003", - "display": "Total thyroidectomy" - }, - { - "code": "237486002", - "display": "Total thyroidectomy with cervical lymph node dissection" - }, - { - "code": "287258006", - "display": "Parathyroid adenoma excision" - }, - { - "code": "399750009", - "display": "Excision of thymus" - }, - { - "code": "57071006", - "display": "Sympathectomy" - }, - { - "code": "392021009", - "display": "Lumpectomy of breast" - }, - { - "code": "172043006", - "display": "Simple mastectomy" - }, - { - "code": "406505007", - "display": "Modified radical mastectomy" - }, - { - "code": "384723003", - "display": "Radical mastectomy" - }, - { - "code": "172106007", - "display": "Excision of fistula of mammary duct" - }, - { - "code": "238356005", - "display": "Intercostal drain removal" - }, - { - "code": "177789001", - "display": "Excision of rib and open drainage of pleural cavity" - }, - { - "code": "238332006", - "display": "Total thoracoplasty" - }, - { - "code": "26411001", - "display": "Decortication of lung and parietal pleurectomy" - }, - { - "code": "75935006", - "display": "Thoracoscopic lobectomy of lung" - }, - { - "code": "173171007", - "display": "Lobectomy of lung" - }, - { - "code": "444188003", - "display": "Thoracoscopic wedge resection of lung" - }, - { - "code": "284181007", - "display": "Incision and drainage of abscess" - }, - { - "code": "274068006", - "display": "Excision of lipoma" - }, - { - "code": "428297005", - "display": "Excision of cyst" - }, - { - "code": "440258006", - "display": "Excision of skin" - }, - { - "code": "312775003", - "display": "Debridement of ulcer" - }, - { - "code": "771225007", - "display": "Reconstruction using free flap" - }, - { - "code": "119561005", - "display": "Grafting procedure" - }, - { - "code": "265675003", - "display": "Split thickness graft of skin to skin" - }, - { - "code": "304039000", - "display": "Skin flap operation" - }, - { - "code": "264983002", - "display": "Transfer of tendon" - }, - { - "code": "107996003", - "display": "Lymphatic system excision" - }, - { - "code": "27929005", - "display": "Arteriovenous fistulization" - }, - { - "code": "717285003", - "display": "Vascular system care" - }, - { - "code": "21911005", - "display": "Biopsy of lymph node" - }, - { - "code": "447338009", - "display": "Aspiration of endometrium" - }, - { - "code": "171149006", - "display": "Screening for malignant neoplasm of cervix" - }, - { - "code": "50796003", - "display": "Cervical biopsy" - }, - { - "code": "274942001", - "display": "Biopsy of vulva" - }, - { - "code": "87515005", - "display": "Ileostomy management and care" - }, - { - "code": "25953003", - "display": "Colostomy management and care" - }, - { - "code": "10849003", - "display": "Removal of foreign body" - }, - { - "code": "225746001", - "display": "Ward (environment)" - }, - { - "code": "224663004", - "display": "Single room (environment)" - }, - { - "code": "67604003", - "display": "Household appliance (physical object)" - }, - { - "code": "5679009", - "display": "Bed sheet, device (physical object)" - }, - { - "code": "47448006", - "display": "Hot water (substance)" - }, - { - "code": "182591009", - "display": "Water bed (physical object)" - }, - { - "code": "229772003", - "display": "Bed (physical object)" - }, - { - "code": "1348009", - "display": "Day care center (environment)" - }, - { - "code": "25721000087108", - "display": "Emergency shelter (environment)" - }, - { - "code": "9632001", - "display": "Nursing procedure (procedure)" - }, - { - "code": "3895009", - "display": "Application of dressing (procedure)" - }, - { - "code": "401304009", - "display": "Service of nebulizer (procedure)" - }, - { - "code": "59108006", - "display": "Injection (procedure)" - }, - { - "code": "430033006", - "display": "Infusion pump (physical object)" - }, - { - "code": "159753002", - "display": "General caretaker (occupation)" - }, - { - "code": "116859006", - "display": "Transfusion of blood product (procedure)" - }, - { - "code": "11429006", - "display": "Consultation (procedure)" - }, - { - "code": "252465000", - "display": "Pulse oximetry (procedure)" - }, - { - "code": "309906004", - "display": "Burns unit (environment)" - }, - { - "code": "397771005", - "display": "High dependency unit (environment)" - }, - { - "code": "309907008", - "display": "Cardiac intensive care unit (environment)" - }, - { - "code": "409688003", - "display": "Hospital isolation room (environment)" - }, - { - "code": "309909006", - "display": "Neurological intensive care unit (environment)" - }, - { - "code": "398161000", - "display": "Postoperative anesthesia care unit (environment)" - }, - { - "code": "387713003", - "display": "Surgical procedure (procedure)" - }, - { - "code": "309904001", - "display": "Intensive care unit (environment)" - }, - { - "code": "182998008", - "display": "Intensive nursing care (regime/therapy)" - }, - { - "code": "61968008", - "display": "Syringe, device (physical object)" - }, - { - "code": "13288007", - "display": "Monitor, device (physical object)" - }, - { - "code": "23852006", - "display": "Cardiac monitoring (regime/therapy)" - }, - { - "code": "399217008", - "display": "Cardioassist by aortic balloon pump (procedure)" - }, - { - "code": "31394004", - "display": "Light therapy (procedure)" - }, - { - "code": "24099007", - "display": "Oxygen (substance)" - }, - { - "code": "706172005", - "display": "Ventilator (physical object)" - }, - { - "code": "424172009", - "display": "Dual pressure spontaneous ventilation support weaning protocol (regime/therapy)" - }, - { - "code": "225738002", - "display": "Operating room (environment)" - }, - { - "code": "257715004", - "display": "Theater (environment)" - }, - { - "code": "1255635002", - "display": "Birth room (environment)" - }, - { - "code": "122456005", - "display": "Laser device (physical object)" - }, - { - "code": "701418007", - "display": "C-arm drape (physical object)" - }, - { - "code": "423827005", - "display": "Endoscopy (procedure)" - }, - { - "code": "51316009", - "display": "Laparoscopic procedure (procedure)" - }, - { - "code": "272181003", - "display": "Clinical equipment and/or device (physical object)" - }, - { - "code": "462524004", - "display": "Neurosurgical ultrasonic navigation system (physical object)" - }, - { - "code": "80557002", - "display": "Drilling of bone (procedure)" - }, - { - "code": "118299005", - "display": "Semiconductor laser device (physical object)" - }, - { - "code": "310801006", - "display": "Ureteroscope (physical object)" - }, - { - "code": "312077001", - "display": "Flexible ureteroscope (physical object)" - }, - { - "code": "6012004", - "display": "Hearing aid, device (physical object)" - }, - { - "code": "63653004", - "display": "Biomedical device (physical object)" - }, - { - "code": "5776009", - "display": "Medicinal product acting as anesthetic agent (product)" - }, - { - "code": "86174004", - "display": "Laparoscope, device (physical object)" - }, - { - "code": "14106009", - "display": "Cardiac pacemaker, device (physical object)" - }, - { - "code": "704722004", - "display": "Dual chamber rate responsive implantable cardiac pacemaker (physical object)" - }, - { - "code": "705637003", - "display": "Drug-eluting coronary artery stent (physical object)" - }, - { - "code": "464052002", - "display": "Bare metal coronary artery stent (physical object)" - }, - { - "code": "356497001", - "display": "Bone cements (product)" - }, - { - "code": "303533002", - "display": "Hip joint implant (physical object)" - }, - { - "code": "63995005", - "display": "Bandage, device (physical object)" - }, - { - "code": "256246007", - "display": "Cotton - textile (physical object)" - }, - { - "code": "350785008", - "display": "Gauzes (physical object)" - }, - { - "code": "52291003", - "display": "Glove, device (physical object)" - }, - { - "code": "261382003", - "display": "Mask (physical object)" - }, - { - "code": "994005", - "display": "Brush, device (physical object)" - }, - { - "code": "48741003", - "display": "Toothpaste (substance)" - }, - { - "code": "25780000", - "display": "Soap (substance)" - }, - { - "code": "739000003", - "display": "Lotion (basic dose form)" - }, - { - "code": "255698008", - "display": "Shampoo (substance)" - }, - { - "code": "52065008", - "display": "Diaper, device (physical object)" - }, - { - "code": "40519001", - "display": "Binder, device (physical object)" - }, - { - "code": "74094004", - "display": "Belt, device (physical object)" - }, - { - "code": "228184002", - "display": "Stocking (physical object)" - }, - { - "code": "16650009", - "display": "Splint, device (physical object)" - }, - { - "code": "9096001", - "display": "Support, device (physical object)" - }, - { - "code": "51883004", - "display": "Sling, device (physical object)" - }, - { - "code": "272363005", - "display": "Fixed orthodontic appliance (physical object)" - }, - { - "code": "12150006", - "display": "Cannula, device (physical object)" - }, - { - "code": "255560000", - "display": "Intravenous (qualifier value)" - }, - { - "code": "19923001", - "display": "Catheter, device (physical object)" - }, - { - "code": "83059008", - "display": "Tube, device (physical object)" - }, - { - "code": "57134006", - "display": "Instrument, device (physical object)" - }, - { - "code": "408097009", - "display": "Strip (physical object)" - }, - { - "code": "369443003", - "display": "Bedpan (physical object)" - }, - { - "code": "91251008", - "display": "Physiotherapy (regime/therapy)" - }, - { - "code": "81375008", - "display": "Physical assessment (procedure)" - }, - { - "code": "386053000", - "display": "Evaluation procedure (procedure)" - }, - { - "code": "45900003", - "display": "Esophagectomy (procedure)" - }, - { - "code": "235162005", - "display": "Trans-hiatal esophagectomy (procedure)" - }, - { - "code": "90410003", - "display": "Wedge resection of stomach (procedure)" - }, - { - "code": "50774009", - "display": "Laparoscopic-assisted right colectomy (procedure)" - }, - { - "code": "174071004", - "display": "Extended right hemicolectomy (procedure)" - }, - { - "code": "41330009", - "display": "Laparoscopic-assisted left colectomy (procedure)" - }, - { - "code": "82619000", - "display": "Left colectomy (procedure)" - }, - { - "code": "235325001", - "display": "Extended left hemicolectomy (procedure)" - }, - { - "code": "26925005", - "display": "Transverse colectomy (procedure)" - }, - { - "code": "84604002", - "display": "Sigmoid colectomy (procedure)" - }, - { - "code": "1390003", - "display": "Laparoscopic-assisted sigmoid colectomy (procedure)" - }, - { - "code": "708913004", - "display": "Laparoscopic abdominoperineal resection using robotic assistance (procedure)" - }, - { - "code": "180056004", - "display": "Posterior exenteration of pelvis (procedure)" - }, - { - "code": "180055000", - "display": "Anterior exenteration of pelvis (procedure)" - }, - { - "code": "69036001", - "display": "Total pancreaticoduodenectomy (procedure)" - }, - { - "code": "61326000", - "display": "Hepatectomy, total right lobectomy (procedure)" - }, - { - "code": "63816008", - "display": "Hepatectomy, total left lobectomy (procedure)" - }, - { - "code": "281255004", - "display": "Small bowel obstruction (disorder)" - }, - { - "code": "281254000", - "display": "Large bowel obstruction (disorder)" - }, - { - "code": "39270003", - "display": "Lysis of adhesions (procedure)" - }, - { - "code": "63185002", - "display": "Laparoscopy with biopsy (procedure)" - }, - { - "code": "81516001", - "display": "Partial nephrectomy (procedure)" - }, - { - "code": "236335000", - "display": "Subcapsular orchidectomy (procedure)" - }, - { - "code": "116171002", - "display": "Radical inguinal orchiectomy (procedure)" - }, - { - "code": "176599002", - "display": "Partial vulvectomy (procedure)" - }, - { - "code": "234250009", - "display": "Block dissection of pelvic lymph nodes (procedure)" - }, - { - "code": "116142003", - "display": "Radical hysterectomy (procedure)" - }, - { - "code": "116141005", - "display": "Abdominal hysterectomy (procedure)" - }, - { - "code": "83152002", - "display": "Oophorectomy (procedure)" - }, - { - "code": "61174009", - "display": "Transposition of ovary (procedure)" - }, - { - "code": "236940003", - "display": "Second look laparoscopy (procedure)" - }, - { - "code": "122460008", - "display": "Reexploration procedure (procedure)" - }, - { - "code": "237370008", - "display": "Segmentectomy of breast (procedure)" - }, - { - "code": "120146008", - "display": "Chest wall excision (procedure)" - }, - { - "code": "1115001", - "display": "Decortication (procedure)" - }, - { - "code": "234272006", - "display": "Biopsy of mediastinal lymph node (procedure)" - }, - { - "code": "261531000", - "display": "Excision of rib (procedure)" - }, - { - "code": "65651000", - "display": "Ligation of thoracic duct (procedure)" - }, - { - "code": "40583006", - "display": "Resection of trachea (procedure)" - }, - { - "code": "177754003", - "display": "Excision of lesion of chest wall (procedure)" - }, - { - "code": "234270003", - "display": "Biopsy of cervical lymph node (procedure)" - }, - { - "code": "75935006", - "display": "Thoracoscopic lobectomy of lung (procedure)" - }, - { - "code": "235155001", - "display": "Endoscopic Congo Red Test (procedure)" - }, - { - "code": "65808002", - "display": "Excision of presacral tumor (procedure)" - }, - { - "code": "231552001", - "display": "Anterior orbitotomy (procedure)" - }, - { - "code": "29513000", - "display": "Irrigation with syringe (procedure)" - }, - { - "code": "76508002", - "display": "Rhytidoplasty of eyelid (procedure)" - }, - { - "code": "75489002", - "display": "Blepharoplasty of bilateral upper and lower eyelids (procedure)" - }, - { - "code": "371394007", - "display": "Removal of scleral buckle (procedure)" - }, - { - "code": "59077004", - "display": "Canthotomy (procedure)" - }, - { - "code": "397537003", - "display": "Laser cycloablation (procedure)" - }, - { - "code": "258485006", - "display": "Corneal scraping specimen (specimen)" - }, - { - "code": "231728005", - "display": "Repair of prolapsed iris (procedure)" - }, - { - "code": "231607009", - "display": "Correction of entropion of lower eyelid (procedure)" - }, - { - "code": "231612005", - "display": "Correction of entropion of upper eyelid (procedure)" - }, - { - "code": "69769008", - "display": "Repair of blepharoptosis (procedure)" - }, - { - "code": "50489001", - "display": "Repair of telecanthus (procedure)" - }, - { - "code": "87539000", - "display": "Cryotherapy of eyelid (procedure)" - }, - { - "code": "172214005", - "display": "Cryotherapy to lesion of eyelid (procedure)" - }, - { - "code": "71091006", - "display": "Cryotherapy of ciliary body (procedure)" - }, - { - "code": "231631004", - "display": "Dacryocystorhinostomy and insertion of tube (procedure)" - }, - { - "code": "75745001", - "display": "Dacryocystotomy (procedure)" - }, - { - "code": "55272009", - "display": "Dacryocystectomy (procedure)" - }, - { - "code": "172261006", - "display": "Drainage of lesion of eyelid (procedure)" - }, - { - "code": "172172005", - "display": "Drainage of orbit (procedure)" - }, - { - "code": "48957009", - "display": "Epilation by electrolysis (procedure)" - }, - { - "code": "39250009", - "display": "Enucleation (procedure)" - }, - { - "code": "14509009", - "display": "Evisceration (procedure)" - }, - { - "code": "75588007", - "display": "Excision of lesion of cornea (procedure)" - }, - { - "code": "36436000", - "display": "Excision of lesion of eyebrow (procedure)" - }, - { - "code": "172212009", - "display": "Excision of lesion of eyelid (procedure)" - }, - { - "code": "47487006", - "display": "Excision of lesion of iris (procedure)" - }, - { - "code": "60712003", - "display": "Excision of lesion of sclera (procedure)" - }, - { - "code": "172196000", - "display": "Excision of lesion of canthus (procedure)" - }, - { - "code": "397112000", - "display": "Simple excision of pterygium (procedure)" - }, - { - "code": "2242005", - "display": "Reconstruction of eyelid (procedure)" - }, - { - "code": "1004085005", - "display": "Injection of filling material into eyelid (procedure)" - }, - { - "code": "240988007", - "display": "Division of flap (procedure)" - }, - { - "code": "400929002", - "display": "Forced duction test (procedure)" - }, - { - "code": "783539008", - "display": "Full thickness graft of skin to skin (procedure)" - }, - { - "code": "265292003", - "display": "Goniotomy (procedure)" - }, - { - "code": "4143006", - "display": "Injection of anterior chamber of eye (procedure)" - }, - { - "code": "310557005", - "display": "Partial thickness corneal graft (substance)" - }, - { - "code": "83694000", - "display": "Lamellar keratoplasty (procedure)" - }, - { - "code": "46082001", - "display": "Lateral orbitotomy (procedure)" - }, - { - "code": "419767009", - "display": "Bimanual microincisional phacoemulsification of cataract with intraocular lens implantation (procedure)" - }, - { - "code": "92829008", - "display": "Glaucoma due to combination of mechanisms (disorder)" - }, - { - "code": "172389006", - "display": "Mucosal graft to conjunctiva (procedure)" - }, - { - "code": "86088003", - "display": "Centesis (procedure)" - }, - { - "code": "42101009", - "display": "Penetrating keratoplasty (procedure)" - }, - { - "code": "231724007", - "display": "Peripheral iridectomy (procedure)" - }, - { - "code": "84149000", - "display": "Aspiration of cataract by phacoemulsification (procedure)" - }, - { - "code": "172426003", - "display": "Removal of foreign body from cornea (procedure)" - }, - { - "code": "172498005", - "display": "Removal of foreign body from iris (procedure)" - }, - { - "code": "172173000", - "display": "Removal of foreign body from orbit (procedure)" - }, - { - "code": "36884001", - "display": "Repair of recurrent dislocation of patella (procedure)" - }, - { - "code": "58992007", - "display": "Complete patellectomy (procedure)" - }, - { - "code": "52050007", - "display": "Pelvic osteotomy (procedure)" - }, - { - "code": "178677007", - "display": "Posterior decompression of fracture of spine (procedure)" - }, - { - "code": "52734007", - "display": "Total replacement of hip (procedure)" - }, - { - "code": "785850002", - "display": "Reverse prosthetic total arthroplasty of shoulder (procedure)" - }, - { - "code": "56060000", - "display": "Repair of musculotendinous cuff of shoulder (procedure)" - }, - { - "code": "18557009", - "display": "Closure by suture (procedure)" - }, - { - "code": "80469007", - "display": "Arthroplasty of shoulder for recurrent dislocation (procedure)" - }, - { - "code": "239468007", - "display": "Arthroplasty of shoulder (procedure)" - }, - { - "code": "69446009", - "display": "Skeletal traction (procedure)" - }, - { - "code": "304040003", - "display": "Grafting to skin (procedure)" - }, - { - "code": "6779009", - "display": "Open treatment of slipped femoral epiphysis (procedure)" - }, - { - "code": "55705006", - "display": "Spinal arthrodesis (procedure)" - }, - { - "code": "35443000", - "display": "Diagnostic radiography supine and erect of thoracic and lumbar spine for scoliosis (procedure)" - }, - { - "code": "122478003", - "display": "Synovial biopsy (procedure)" - }, - { - "code": "45247004", - "display": "Lengthening of tendon (procedure)" - }, - { - "code": "281758003", - "display": "Repair of tendon (procedure)" - }, - { - "code": "178156005", - "display": "Repair of tendo achilles (procedure)" - }, - { - "code": "264983002", - "display": "Transfer of tendon (procedure)" - }, - { - "code": "179836002", - "display": "Release of torticollis (procedure)" - }, - { - "code": "609588000", - "display": "Total knee replacement (procedure)" - }, - { - "code": "27813003", - "display": "Intra-articular injection (procedure)" - }, - { - "code": "13714004", - "display": "Arthroscopy (procedure)" - }, - { - "code": "239430005", - "display": "Ligament reconstruction (procedure)" - }, - { - "code": "179353004", - "display": "Revision uncemented total knee replacement (procedure)" - }, - { - "code": "86052008", - "display": "Closed reduction of fracture (procedure)" - }, - { - "code": "302489004", - "display": "Removal of complete external fixator (procedure)" - }, - { - "code": "180293003", - "display": "Change of plaster jacket (procedure)" - }, - { - "code": "90131007", - "display": "Arthrocentesis (procedure)" - }, - { - "code": "239667008", - "display": "Application of above elbow plaster cast (procedure)" - }, - { - "code": "239676001", - "display": "Application of below knee plaster cast (procedure)" - }, - { - "code": "63097004", - "display": "Application of long leg cast (procedure)" - }, - { - "code": "180289009", - "display": "Application of plaster cast (procedure)" - }, - { - "code": "37354008", - "display": "Application of shoulder spica (procedure)" - }, - { - "code": "127599007", - "display": "Application of hip spica cast (procedure)" - }, - { - "code": "81666003", - "display": "Strapping of ankle (procedure)" - }, - { - "code": "85046002", - "display": "Strapping of elbow (procedure)" - }, - { - "code": "24459003", - "display": "Strapping of finger (procedure)" - }, - { - "code": "21288003", - "display": "Strapping of knee (procedure)" - }, - { - "code": "229535006", - "display": "Shoulder strapping (procedure)" - }, - { - "code": "41029007", - "display": "Strapping of toes (procedure)" - }, - { - "code": "21411002", - "display": "Strapping of wrist (procedure)" - }, - { - "code": "30549001", - "display": "Removal of suture (procedure)" - }, - { - "code": "58825001", - "display": "Closed reduction of dislocation (procedure)" - }, - { - "code": "70163005", - "display": "Excision of ganglion cyst (procedure)" - }, - { - "code": "284101009", - "display": "Removal of implant (procedure)" - }, - { - "code": "76699006", - "display": "Ligamentous reconstruction of knee, intra-articular and extra-articular (procedure)" - }, - { - "code": "387731002", - "display": "Excision of lamina of vertebra (procedure)" - }, - { - "code": "78918006", - "display": "Open reduction of dislocation (procedure)" - }, - { - "code": "178668000", - "display": "Percutaneous discectomy (procedure)" - }, - { - "code": "311479006", - "display": "Spinal instrumentation (procedure)" - }, - { - "code": "439303004", - "display": "Application of rigid total contact leg cast (procedure)" - }, - { - "code": "2337004", - "display": "Adductor tenotomy of hip (procedure)" - }, - { - "code": "239267000", - "display": "Release of trigger finger (procedure)" - }, - { - "code": "239644006", - "display": "Application of pelvic traction (procedure)" - }, - { - "code": "178789004", - "display": "Manipulation of spine using traction (procedure)" - }, - { - "code": "450671005", - "display": "Debridement of soft tissue (procedure)" - }, - { - "code": "179709006", - "display": "Total synovectomy of joint (procedure)" - }, - { - "code": "387821004", - "display": "Spinal deformity correction (procedure)" - }, - { - "code": "428845007", - "display": "Intramedullary fixation with cementing of bone (procedure)" - }, - { - "code": "179892002", - "display": "Arthroscopic reattachment glenoid labrum (procedure)" - }, - { - "code": "699120002", - "display": "Arthroscopic repair of rotator cuff (procedure)" - }, - { - "code": "301761003", - "display": "Arthroscopic synovial biopsy (procedure)" - }, - { - "code": "265106004", - "display": "Insertion of Austin-Moore prosthesis (procedure)" - }, - { - "code": "439756000", - "display": "Open reduction of bimalleolar fracture of lateral and medial malleoli with internal fixation (procedure)" - }, - { - "code": "61916001", - "display": "Injection into bone marrow (procedure)" - }, - { - "code": "239690003", - "display": "Application of buttress strapping (procedure)" - }, - { - "code": "239329001", - "display": "Excision of bone (procedure)" - }, - { - "code": "699119008", - "display": "Repair of medial ligament of talocrural joint (procedure)" - }, - { - "code": "708899000", - "display": "Closed reduction of fracture of femur and internal fixation using dynamic condylar screw plate (procedure)" - }, - { - "code": "239619003", - "display": "Dynamization of external fixator (procedure)" - }, - { - "code": "239259008", - "display": "Lengthening of tendons or muscles of the flexor compartment of the forearm (procedure)" - }, - { - "code": "179537001", - "display": "Excision arthroplasty (procedure)" - }, - { - "code": "385523005", - "display": "External fixator using Ilizarov system (physical object)" - }, - { - "code": "440418007", - "display": "Open reduction of fracture of medial malleolus with internal fixation (procedure)" - }, - { - "code": "239432002", - "display": "Reconstruction of posterior cruciate ligament of knee joint (procedure)" - }, - { - "code": "69171004", - "display": "Excision of radial head (procedure)" - }, - { - "code": "56153009", - "display": "Reconstruction of radial head (procedure)" - }, - { - "code": "112694000", - "display": "Saucerization (procedure)" - }, - { - "code": "313295000", - "display": "Fixation of fracture using Herbert screw (procedure)" - }, - { - "code": "257949002", - "display": "Tension band wiring of fracture (procedure)" - }, - { - "code": "178493006", - "display": "Alveolar bone graft (procedure)" - }, - { - "code": "180673001", - "display": "Cross finger flap (substance)" - }, - { - "code": "384686000", - "display": "Reattachment of lower extremity (procedure)" - }, - { - "code": "307554005", - "display": "Reconstruction of nose with flap (procedure)" - }, - { - "code": "782787005", - "display": "Split thickness graft of skin (substance)" - }, - { - "code": "284079008", - "display": "Revision of scar (procedure)" - }, - { - "code": "405444008", - "display": "Revision of amputation of foot (procedure)" - }, - { - "code": "240995003", - "display": "Release of burns contracture (procedure)" - }, - { - "code": "231619001", - "display": "Surgical dehiscence of the aponeurotic insertion of Muller's muscle (procedure)" - }, - { - "code": "52781008", - "display": "Congenital hip dysplasia (disorder)" - }, - { - "code": "367411006", - "display": "Hamstring tendon transfer (procedure)" - }, - { - "code": "32492002", - "display": "Excision of accessory navicular bone (procedure)" - }, - { - "code": "308446007", - "display": "Excision of distal end of ulna (procedure)" - }, - { - "code": "158965000", - "display": "Medical practitioner (occupation)" - }, - { - "code": "303133007", - "display": "Responsible medical officer (occupation)" - } -] \ No newline at end of file diff --git a/fhir-mapper/src/main/resources/snomed/SnomedDiagnostic.json b/fhir-mapper/src/main/resources/snomed/SnomedDiagnostic.json deleted file mode 100644 index ffe994c6..00000000 --- a/fhir-mapper/src/main/resources/snomed/SnomedDiagnostic.json +++ /dev/null @@ -1,66 +0,0 @@ -[ - { - "code": "B53.0", - "display": "Plasmodium ovale malaria" - }, - { - "code": "E11.9", - "display": "Type 2 diabetes mellitus : Without complications" - }, - { - "code": "I46.9", - "display": "Cardiac arrest, unspecified" - }, - { - "code": "S82.1", - "display": "Fracture of upper end of tibia" - }, - { - "code": "K70.3", - "display": "Alcoholic cirrhosis of liver" - }, - { - "code": "K35.8", - "display": "Acute appendicitis, other and unspecified" - }, - { - "code": "A08.4", - "display": "Viral intestinal infection, unspecified" - }, - { - "code": "770573007", - "display": "Airway endoscopy report" - }, - { - "code": "782659005", - "display": "Cystoscopy report" - }, - { - "code": "725870000", - "display": "Diagnostic coronary angiography report" - }, - { - "code": "721981007", - "display": "Diagnostic studies report" - }, - { - "code": "722143004", - "display": "Infectious disease diagnostic study note" - }, - { - "code": "720449003", - "display": "Pulmonary function report" - }, - { - "code": "371528001", - "display": "Pathology report" - }, - { - "code": "721631001", - "display": "Bone marrow pathology biopsy report" - }, - { - "code": "4311000179106", - "display": "Chemical pathology report" - } -] \ No newline at end of file diff --git a/fhir-mapper/src/main/resources/snomed/SnomedEncounter.json b/fhir-mapper/src/main/resources/snomed/SnomedEncounter.json deleted file mode 100644 index d8225a79..00000000 --- a/fhir-mapper/src/main/resources/snomed/SnomedEncounter.json +++ /dev/null @@ -1,222 +0,0 @@ -[ - { - "code": "AMB", - "display": "Ambulatory" - }, - { - "code": "171238007", - "display": "Arthritis screening" - }, - { - "code": "171242005", - "display": "Chromosome abnormality screening" - }, - { - "code": "171183004", - "display": "Diabetes mellitus screening" - }, - { - "code": "391277002", - "display": "Digestive system disease screening" - }, - { - "code": "171219003", - "display": "Ear disorder screening" - }, - { - "code": "473200002", - "display": "Genetic screening for disorder" - }, - { - "code": "171233003", - "display": "Genitourinary disease screening" - }, - { - "code": "243790003", - "display": "Infection screening" - }, - { - "code": "60151004", - "display": "Neonatal screening" - }, - { - "code": "171214008", - "display": "Neurological screening" - }, - { - "code": "171228002", - "display": "Respiratory disease screening" - }, - { - "code": "300007000", - "display": "Screening for cardiovascular system disease" - }, - { - "code": "866150003", - "display": "Screening for developmental disorder" - }, - { - "code": "300005008", - "display": "Screening for mental disorders" - }, - { - "code": "15886004", - "display": "Screening for cancer" - }, - { - "code": "370854007", - "display": "Screening for substance abuse" - }, - { - "code": "171237002", - "display": "Skin disease screening" - }, - { - "code": "408760009", - "display": "Vision screening" - }, - { - "code": "274412005", - "display": "Eye disorder screening" - }, - { - "code": "171126009", - "display": "Tuberculosis screening" - }, - { - "code": "171121004", - "display": "HIV screening" - }, - { - "code": "243787009", - "display": "Antenatal screening" - }, - { - "code": "103735009", - "display": "Palliative care" - }, - { - "code": "112802009", - "display": "Cardiovascular surgical procedure" - }, - { - "code": "71025006", - "display": "Dilation procedure" - }, - { - "code": "122459003", - "display": "Dissection procedure" - }, - { - "code": "34896006", - "display": "Incision" - }, - { - "code": "287391004", - "display": "Nose, mouth or pharynx operations" - }, - { - "code": "386638009", - "display": "Obstetric operation" - }, - { - "code": "112697007", - "display": "Operation on musculoskeletal system" - }, - { - "code": "16545005", - "display": "Operation on nervous system" - }, - { - "code": "387661001", - "display": "Operation on respiratory tract" - }, - { - "code": "74943008", - "display": "Operation on trunk" - }, - { - "code": "107907001", - "display": "Operative procedure on digestive system" - }, - { - "code": "89901005", - "display": "Operative procedure on head" - }, - { - "code": "107994000", - "display": "Operative procedure on hematopoietic system" - }, - { - "code": "107876005", - "display": "Operative procedure on integumentary system" - }, - { - "code": "392236004", - "display": "Operative procedure on spinal structure" - }, - { - "code": "410771003", - "display": "Surgical procedure for clinical finding and/or disorder" - }, - { - "code": "313071005", - "display": "Substance abuse counselling" - }, - { - "code": "79841006", - "display": "Genetic counseling" - }, - { - "code": "171022008", - "display": "Psychological counseling" - }, - { - "code": "24165007", - "display": "Alcoholism counselling" - }, - { - "code": "228557008", - "display": "Cognitive and behavioral therapy" - }, - { - "code": "75516001", - "display": "Psychotherapy" - }, - { - "code": "266739000", - "display": "Physiotherapy/remedial therapy" - }, - { - "code": "5154007", - "display": "Speech therapy" - }, - { - "code": "773412008", - "display": "Traditional medicine" - }, - { - "code": "385804009", - "display": "Diabetic care" - }, - { - "code": "367336001", - "display": "Chemotherapy" - }, - { - "code": "18629005", - "display": "Administration of medication" - }, - { - "code": "86273004", - "display": "Biopsy" - }, - { - "code": "23835007", - "display": "Electroconvulsive therapy" - }, - { - "code": "397619005", - "display": "Family planning education" - } -] \ No newline at end of file diff --git a/fhir-mapper/src/main/resources/snomed/SnomedMedicine.json b/fhir-mapper/src/main/resources/snomed/SnomedMedicine.json deleted file mode 100644 index 4920779a..00000000 --- a/fhir-mapper/src/main/resources/snomed/SnomedMedicine.json +++ /dev/null @@ -1,418 +0,0 @@ -[ - { - "code": "319775004", - "display": "Aspirin 75 mg oral tablet" - }, - { - "code": "370166004", - "display": "Aspirin 325 mg oral tablet" - }, - { - "code": "374744009", - "display": "Aspirin 800 mg oral tablet" - }, - { - "code": "370164001", - "display": "Aspirin 81 mg chewable tablet" - }, - { - "code": "785018008", - "display": "Aspirin 2.5 mg/mL oral solution" - }, - { - "code": "412575004", - "display": "Aspirin 325 mg and codeine 30 mg oral tablet" - }, - { - "code": "347070003", - "display": "Aspirin 500 mg and glycine 133 mg orodispersible tablet" - }, - { - "code": "413586006", - "display": "Acetaminophen 250 mg and aspirin 250 mg and caffeine 65 mg oral tablet" - }, - { - "code": "412647005", - "display": "Aspirin 389 mg and caffeine 32.4 mg and propoxyphene hydrochloride 32 mg oral capsule" - }, - { - "code": "322784004", - "display": "Aspirin DL-lysine 900 mg and metoclopramide hydrochloride 10 mg oral powder sachet" - }, - { - "code": "322236009", - "display": "Acetaminophen 500 mg oral tablet" - }, - { - "code": "322246006", - "display": "Acetaminophen 100 mg/mL oral solution" - }, - { - "code": "426061004", - "display": "Mesalamine 1.2 g gastro-resistant oral tablet" - }, - { - "code": "324409009", - "display": "Sulfalene 2 g oral tablet" - }, - { - "code": "376693009", - "display": "Cefadroxil 1 g oral tablet" - }, - { - "code": "329838002", - "display": "Naproxen 250 mg gastro-resistant oral tablet" - }, - { - "code": "416272002", - "display": "Zinc 50 mg oral capsule" - }, - { - "code": "418197002", - "display": "Glucosamine 1 g oral tablet" - }, - { - "code": "426863002", - "display": "Melatonin 2 mg prolonged-release oral tablet" - }, - { - "code": "765963000", - "display": "Budesonide 3 mg gastro-resistant oral capsule" - }, - { - "code": "765590000", - "display": "Felodipine 5 mg prolonged-release oral tablet" - }, - { - "code": "765699007", - "display": "Ibuprofen 800 mg prolonged-release oral tablet" - }, - { - "code": "766432002", - "display": "Fusidic acid 10 mg/g prolonged-release eye drops" - }, - { - "code": "324682007", - "display": "Miconazole 25 mg/g oral gel" - }, - { - "code": "765651007", - "display": "Axitinib 5 mg oral tablet" - }, - { - "code": "408068006", - "display": "Nabilone 2 mg oral capsule" - }, - { - "code": "326272004", - "display": "Nystatin 25000 unit/g vaginal cream" - }, - { - "code": "408597001", - "display": "Ganciclovir 1.5 mg/g eye gel" - }, - { - "code": "321573006", - "display": "Clozapine 25 mg oral tablet" - }, - { - "code": "375833002", - "display": "Ofloxacin 3 mg/mL ear solution" - }, - { - "code": "785252002", - "display": "Glycerin 10 mg/mL eye solution" - }, - { - "code": "321203006", - "display": "Diazepam 1 mg/mL oral solution" - }, - { - "code": "784911007", - "display": "Carbachol 15 mg/mL eye solution" - }, - { - "code": "407773006", - "display": "Sulpiride 40 mg/mL oral solution" - }, - { - "code": "407836002", - "display": "Efavirenz 30 mg/mL oral solution" - }, - { - "code": "323074003", - "display": "Diazepam 4 mg/mL rectal solution" - }, - { - "code": "410840000", - "display": "Ribavirin 40 mg/mL oral solution" - }, - { - "code": "348336006", - "display": "Phenol 10 mg/mL cutaneous solution" - }, - { - "code": "784960002", - "display": "Epinephrine 1 mg/mL nasal solution" - }, - { - "code": "781971000", - "display": "Linezolid 2 mg/mL solution for infusion" - }, - { - "code": "781781009", - "display": "Baclofen 2 mg/mL solution for injection" - }, - { - "code": "781829000", - "display": "Diazepam 5 mg/mL solution for injection" - }, - { - "code": "785204007", - "display": "Glucose 200 mg/mL solution for injection" - }, - { - "code": "446347007", - "display": "Denosumab 60 mg/mL solution for injection" - }, - { - "code": "782062009", - "display": "Piroxicam 20 mg/mL solution for injection" - }, - { - "code": "784839007", - "display": "Tobramycin 60 mg/mL solution for inhalation" - }, - { - "code": "784910008", - "display": "Enflurane 999 mg/mL solution for inhalation" - }, - { - "code": "781996002", - "display": "Metronidazole 5 mg/mL solution for infusion" - }, - { - "code": "782021003", - "display": "Nitroglycerin 5 mg/mL solution for injection" - }, - { - "code": "348190007", - "display": "Tolnaftate 10 mg/g cutaneous powder" - }, - { - "code": "766284006", - "display": "Clotrimazole 10 mg/g cutaneous powder" - }, - { - "code": "324867004", - "display": "Nelfinavir 50 microgram/mg oral powder" - }, - { - "code": "766429000", - "display": "Povidone iodine 25 mg/g cutaneous powder spray" - }, - { - "code": "322979001", - "display": "Vigabatrin 500 mg powder for oral solution sachet" - }, - { - "code": "375854009", - "display": "Hemin 313 mg powder for solution for injection vial" - }, - { - "code": "323961007", - "display": "Aztreonam 1 g powder for solution for injection vial" - }, - { - "code": "319948000", - "display": "Cholestyramine 4 g powder for oral suspension sachet" - }, - { - "code": "785962002", - "display": "Cromolyn sodium 20 mg/actuation powder for inhalation" - }, - { - "code": "785973009", - "display": "Noxythiolin 2.5 g powder for solution for injection vial" - }, - { - "code": "782053007", - "display": "Phenol 50 mg/mL oil for injection" - }, - { - "code": "781828008", - "display": "Diazepam 5 mg/mL emulsion for injection" - }, - { - "code": "782035001", - "display": "Oxytocin 5 unit/mL solution for injection" - }, - { - "code": "785006004", - "display": "Propofol 10 mg/mL suspension for injection" - }, - { - "code": "769129007", - "display": "Triptorelin (as triptorelin acetate) 3.75 mg powder for suspension for injection syringe" - }, - { - "code": "766169007", - "display": "Somatropin(rbe) 600 microgram powder for solution for injection syringe" - }, - { - "code": "871797008", - "display": "Ozanimod (as ozanimod hydrochloride) 920 microgram oral capsule" - }, - { - "code": "386086001", - "display": "Tacrine 40 mg oral capsule" - }, - { - "code": "415163005", - "display": "Pregabalin 200 mg oral capsule" - }, - { - "code": "430273009", - "display": "Temazepam 22.5 mg oral capsule" - }, - { - "code": "423454000", - "display": "Vorinostat 100 mg oral capsule" - }, - { - "code": "370149001", - "display": "Acetaminophen 160 mg oral tablet" - }, - { - "code": "377441009", - "display": "Acetaminophen 325 mg and tramadol 37.5 mg oral tablet" - }, - { - "code": "377594002", - "display": "Acetaminophen 325 mg and butalbital 50 mg oral tablet" - }, - { - "code": "322341003", - "display": "Acetaminophen 500 mg and codeine phosphate 30 mg oral tablet" - }, - { - "code": "783660005", - "display": "Paroxetine (as paroxetine hydrochloride) 10 mg oral tablet" - }, - { - "code": "421386002", - "display": "Acetaminophen 300 mg and oxycodone hydrochloride 5 mg oral tablet" - }, - { - "code": "377343008", - "display": "Acetaminophen 325 mg and oxycodone hydrochloride 5 mg oral tablet" - }, - { - "code": "370148009", - "display": "Acetaminophen 80 mg chewable tablet" - }, - { - "code": "785926003", - "display": "Mucin 35 mg/mL oral spray" - }, - { - "code": "703958008", - "display": "Avanafil 50 mg oral tablet" - }, - { - "code": "324682007", - "display": "Miconazole 25 mg/g oral gel" - }, - { - "code": "442888004", - "display": "Iloperidone 8 mg oral tablet" - }, - { - "code": "445522003", - "display": "Rifaximin 550 mg oral tablet" - }, - { - "code": "332248004", - "display": "Anthralin 1 mg/g cutaneous cream" - }, - { - "code": "332246000", - "display": "Anthralin 5 mg/g cutaneous cream" - }, - { - "code": "333020002", - "display": "Acyclovir 50 mg/g cutaneous cream" - }, - { - "code": "331624002", - "display": "Benzocaine 30 mg/g cutaneous cream" - }, - { - "code": "332199003", - "display": "Calcipotriol 50 microgram/mL cutaneous cream" - }, - { - "code": "413872001", - "display": "Clocortolone pivalate 1 mg/mL cutaneous cream" - }, - { - "code": "330588001", - "display": "Tropicamide 5 mg/mL eye drops" - }, - { - "code": "409490006", - "display": "Hydroxyamphetamine hydrobromide 10 mg/mL and tropicamide 2.5 mg/mL eye solution" - }, - { - "code": "783373002", - "display": "Tropisetron (as tropisetron hydrochloride) 5 mg oral capsule" - }, - { - "code": "324682007", - "display": "Miconazole 25 mg/g oral gel" - }, - { - "code": "408597001", - "display": "Ganciclovir 1.5 mg/g eye gel" - }, - { - "code": "332378006", - "display": "Adapalene 1 mg/g cutaneous gel" - }, - { - "code": "135588001", - "display": "Benzocaine 100 mg/g dental gel" - }, - { - "code": "330229006", - "display": "Felbinac 30 mg/g transdermal gel" - }, - { - "code": "414272004", - "display": "Fluocinolone acetonide 100 microgram/mL cutaneous oil" - }, - { - "code": "331469001", - "display": "Cod liver oil 114 mg/g and zinc oxide 380 mg/g cutaneous ointment" - }, - { - "code": "781919008", - "display": "Haloperidol (as haloperidol decanoate) 50 mg/mL oil for injection" - }, - { - "code": "781828008", - "display": "Diazepam 5 mg/mL emulsion for injection" - }, - { - "code": "781752008", - "display": "Adenosine 3 mg/mL solution for injection" - }, - { - "code": "784932004", - "display": "Diazepam 5 mg/mL suspension for injection" - }, - { - "code": "376105006", - "display": "Estrone 15 mg/mL suspension for injection" - } -] \ No newline at end of file diff --git a/fhir-mapper/src/main/resources/snomed/SnomedMedicineRoute.json b/fhir-mapper/src/main/resources/snomed/SnomedMedicineRoute.json deleted file mode 100644 index 7757e521..00000000 --- a/fhir-mapper/src/main/resources/snomed/SnomedMedicineRoute.json +++ /dev/null @@ -1,385 +0,0 @@ - -[ - { "code": "6064005", "display": "Topical route" }, - { "code": "10547007", "display": "Otic route" }, - { "code": "12130007", "display": "Intra-articular route" }, - { "code": "16857009", "display": "Per vagina" }, - { "code": "26643006", "display": "Oral route" }, - { "code": "34206005", "display": "Subcutaneous route" }, - { "code": "37161004", "display": "Per rectum" }, - { "code": "37737002", "display": "Intraluminal route" }, - { "code": "37839007", "display": "Sublingual route" }, - { "code": "38239002", "display": "Intraperitoneal route" }, - { "code": "45890007", "display": "Transdermal route" }, - { "code": "46713006", "display": "Nasal route" }, - { "code": "47625008", "display": "Intravenous route" }, - { "code": "54471007", "display": "Buccal route" }, - { "code": "54485002", "display": "Ophthalmic route" }, - { "code": "58100008", "display": "Intra-arterial route" }, - { "code": "60213007", "display": "Intramedullary route" }, - { "code": "62226000", "display": "Intrauterine route" }, - { "code": "72607000", "display": "Intrathecal route" }, - { "code": "78421000", "display": "Intramuscular route" }, - { "code": "90028008", "display": "Urethral route" }, - { "code": "127490009", "display": "Gastrostomy route" }, - { "code": "127491008", "display": "Jejunostomy route" }, - { "code": "127492001", "display": "Nasogastric route" }, - { "code": "372449004", "display": "Dental use" }, - { "code": "372450004", "display": "Endocervical use" }, - { "code": "372451000", "display": "Endosinusial use" }, - { "code": "372452007", "display": "Endotracheopulmonary use" }, - { "code": "372453002", "display": "Extra-amniotic use" }, - { "code": "372454008", "display": "Gastroenteral use" }, - { "code": "372457001", "display": "Gingival use" }, - { "code": "372458006", "display": "Intraamniotic use" }, - { "code": "372459003", "display": "Intrabursal use" }, - { "code": "372460008", "display": "Intracardiac use" }, - { "code": "372461007", "display": "Intracavernous use" }, - { "code": "372462000", "display": "Intracervical route (qualifier value)" }, - { "code": "372463005", "display": "Intracoronary use" }, - { "code": "372464004", "display": "Intradermal use" }, - { "code": "372465003", "display": "Intradiscal use" }, - { "code": "372466002", "display": "Intralesional use" }, - { "code": "372467006", "display": "Intralymphatic use" }, - { "code": "372468001", "display": "Intraocular use" }, - { "code": "372469009", "display": "Intrapleural use" }, - { "code": "372470005", "display": "Intrasternal use" }, - { "code": "372471009", "display": "Intravesical use" }, - { "code": "372472002", "display": "Ocular route (qualifier value)" }, - { "code": "372473007", "display": "Oromucosal use" }, - { "code": "372474001", "display": "Periarticular use" }, - { "code": "372475000", "display": "Perineural use" }, - { "code": "372476004", "display": "Subconjunctival use" }, - { "code": "404815008", "display": "Transmucosal route (qualifier value)" }, - { "code": "404818005", "display": "Intratracheal route (qualifier value)" }, - { "code": "404819002", "display": "Intrabiliary route (qualifier value)" }, - { "code": "404820008", "display": "Epidural route (qualifier value)" }, - { "code": "416174007", "display": "Suborbital route (qualifier value)" }, - { "code": "417070009", "display": "Caudal route (qualifier value)" }, - { "code": "417255000", "display": "Intraosseous route (qualifier value)" }, - { "code": "417950001", "display": "Intrathoracic route (qualifier value)" }, - { "code": "417985001", "display": "Enteral route (qualifier value)" }, - { "code": "417989007", "display": "Intraductal route (qualifier value)" }, - { "code": "418091004", "display": "Intratympanic route (qualifier value)" }, - { "code": "418114005", "display": "Intravenous central route (qualifier value)" }, - { "code": "418133000", "display": "Intramyometrial route (qualifier value)" }, - { "code": "418136008", "display": "Gastro-intestinal stoma route (qualifier value)" }, - { "code": "418162004", "display": "Colostomy route (qualifier value)" }, - { "code": "418204005", "display": "Periurethral route (qualifier value)" }, - { "code": "418287000", "display": "Intracoronal route (qualifier value)" }, - { "code": "418321004", "display": "Retrobulbar route (qualifier value)" }, - { "code": "418331006", "display": "Intracartilaginous route (qualifier value)" }, - { "code": "418401004", "display": "Intravitreal route (qualifier value)" }, - { "code": "418418000", "display": "Intraspinal route (qualifier value)" }, - { "code": "418441008", "display": "Orogastric route (qualifier value)" }, - { "code": "418511008", "display": "Transurethral route (qualifier value)" }, - { "code": "418586008", "display": "Intratendinous route (qualifier value)" }, - { "code": "418608002", "display": "Intracorneal route (qualifier value)" }, - { "code": "418664002", "display": "Oropharyngeal route (qualifier value)" }, - { "code": "418722009", "display": "Peribulbar route (qualifier value)" }, - { "code": "418730005", "display": "Nasojejunal route (qualifier value)" }, - { "code": "418743005", "display": "Fistula route (qualifier value)" }, - { "code": "418813001", "display": "Surgical drain route (qualifier value)" }, - { "code": "418821007", "display": "Intracameral route (qualifier value)" }, - { "code": "418851001", "display": "Paracervical route (qualifier value)" }, - { "code": "418877009", "display": "Intrasynovial route (qualifier value)" }, - { "code": "418887008", "display": "Intraduodenal route (qualifier value)" }, - { "code": "418892005", "display": "Intracisternal route (qualifier value)" }, - { "code": "418947002", "display": "Intratesticular route (qualifier value)" }, - { "code": "418987007", "display": "Intracranial route (qualifier value)" }, - { "code": "419021003", "display": "Tumour cavity route" }, - { "code": "419165009", "display": "Paravertebral route (qualifier value)" }, - { "code": "419231003", "display": "Intrasinal route (qualifier value)" }, - { - "code": "419243002", - "display": "Transcervical route (qualifier value)" - }, - { - "code": "419320008", - "display": "Subtendinous route (qualifier value)" - }, - { - "code": "419396008", - "display": "Intraabdominal route (qualifier value)" - }, - { - "code": "419601003", - "display": "Subgingival route (qualifier value)" - }, - { - "code": "419631009", - "display": "Intraovarian route (qualifier value)" - }, - { - "code": "419684008", - "display": "Ureteral route (qualifier value)" - }, - { - "code": "419762003", - "display": "Peritendinous route (qualifier value)" - }, - { - "code": "419778001", - "display": "Intrabronchial route (qualifier value)" - }, - { - "code": "419810008", - "display": "Intraprostatic route (qualifier value)" - }, - { - "code": "419874009", - "display": "Submucosal route (qualifier value)" - }, - { - "code": "419894000", - "display": "Surgical cavity route (qualifier value)" - }, - { - "code": "419954003", - "display": "Ileostomy route (qualifier value)" - }, - { - "code": "419993007", - "display": "Intravenous peripheral route (qualifier value)" - }, - { - "code": "420047004", - "display": "Periosteal route (qualifier value)" - }, - { - "code": "420163009", - "display": "Esophagostomy route" - }, - { - "code": "420168000", - "display": "Urostomy route (qualifier value)" - }, - { - "code": "420185003", - "display": "Laryngeal route (qualifier value)" - }, - { - "code": "420201002", - "display": "Intrapulmonary route (qualifier value)" - }, - { - "code": "420204005", - "display": "Mucous fistula route (qualifier value)" - }, - { - "code": "420218003", - "display": "Nasoduodenal route (qualifier value)" - }, - { - "code": "420254004", - "display": "Body cavity route (qualifier value)" - }, - { - "code": "420287000", - "display": "Intraventricular route - cardiac (qualifier value)" - }, - { - "code": "420719007", - "display": "Intracerebroventricular route (qualifier value)" - }, - { - "code": "428191002", - "display": "Percutaneous route (qualifier value)" - }, - { - "code": "429817007", - "display": "Interstitial route (qualifier value)" - }, - { - "code": "445752009", - "display": "Intraesophageal route (qualifier value)" - }, - { - "code": "445754005", - "display": "Intragingival route (qualifier value)" - }, - { - "code": "445755006", - "display": "Intravascular route (qualifier value)" - }, - { - "code": "445756007", - "display": "Intradural route (qualifier value)" - }, - { - "code": "445767008", - "display": "Intrameningeal route (qualifier value)" - }, - { - "code": "445768003", - "display": "Intragastric route (qualifier value)" - }, - { - "code": "445771006", - "display": "Intrapericardial route (qualifier value)" - }, - { - "code": "445913005", - "display": "Intralingual route (qualifier value)" - }, - { - "code": "445941009", - "display": "Intrahepatic route (qualifier value)" - }, - { - "code": "446105004", - "display": "Conjunctival route (qualifier value)" - }, - { - "code": "446407004", - "display": "Intraepicardial route (qualifier value)" - }, - { - "code": "446435000", - "display": "Transendocardial route (qualifier value)" - }, - { - "code": "446442000", - "display": "Transplacental route (qualifier value)" - }, - { - "code": "446540005", - "display": "Intracerebral route (qualifier value)" - }, - { - "code": "447026006", - "display": "Intraileal route (qualifier value)" - }, - { - "code": "447052000", - "display": "Periodontal route (qualifier value)" - }, - { - "code": "447080003", - "display": "Peridural route (qualifier value)" - }, - { - "code": "447081004", - "display": "Lower respiratory tract route (qualifier value)" - }, - { - "code": "447121004", - "display": "Intramammary route (qualifier value)" - }, - { - "code": "447122006", - "display": "Intratumor route (qualifier value)" - }, - { - "code": "447227007", - "display": "Transtympanic route (qualifier value)" - }, - { - "code": "447229005", - "display": "Transtracheal route (qualifier value)" - }, - { - "code": "447694001", - "display": "Respiratory tract route (qualifier value)" - }, - { - "code": "447964005", - "display": "Digestive tract route (qualifier value)" - }, - { - "code": "448077001", - "display": "Intraepidermal route (qualifier value)" - }, - { - "code": "448491004", - "display": "Intrajejunal route (qualifier value)" - }, - { - "code": "448492006", - "display": "Intracolonic route (qualifier value)" - }, - { - "code": "448598008", - "display": "Cutaneous route (qualifier value)" - }, - { - "code": "697971008", - "display": "Arteriovenous fistula route (qualifier value)" - }, - { - "code": "711360002", - "display": "Intraneural route (qualifier value)" - }, - { - "code": "711378007", - "display": "Intramural route (qualifier value)" - }, - { - "code": "714743009", - "display": "Extracorporeal route (qualifier value)" - }, - { - "code": "718329006", - "display": "Infiltration route (qualifier value)" - }, - { - "code": "764723001", - "display": "Epilesional route (qualifier value)" - }, - { - "code": "766790006", - "display": "Extracorporeal hemodialysis route (qualifier value)" - }, - { - "code": "876824003", - "display": "Intradialytic route" - }, - { - "code": "1078280005", - "display": "Intracatheter instillation route (qualifier value)" - }, - { - "code": "1254769004", - "display": "Suprachoroidal route" - }, - { - "code": "1259221004", - "display": "Intracorporus cavernosum route (qualifier value)" - }, - { - "code": "1611000175109", - "display": "Sublesional route (qualifier value)" - }, - { - "code": "58731000052100", - "display": "Intestinal route (qualifier value)" - }, - { - "code": "58751000052109", - "display": "Intraglandular route (qualifier value)" - }, - { - "code": "58761000052107", - "display": "Intracholangiopancreatic route" - }, - { - "code": "58771000052103", - "display": "Intraportal route" - }, - { - "code": "58811000052103", - "display": "Peritumoral route (qualifier value)" - }, - { - "code": "58821000052106", - "display": "Posterior juxtascleral route (qualifier value)" - }, - { - "code": "58831000052108", - "display": "Subretinal route (qualifier value)" - }, - { - "code": "666210000521", - "display": "Subretinal route (qualifier value)" - } -] \ No newline at end of file diff --git a/fhir-mapper/src/main/resources/snomed/SnomedObservation.json b/fhir-mapper/src/main/resources/snomed/SnomedObservation.json deleted file mode 100644 index 33e64c12..00000000 --- a/fhir-mapper/src/main/resources/snomed/SnomedObservation.json +++ /dev/null @@ -1,302 +0,0 @@ -[ - { - "code": "219006", - "display": "Current drinker" - }, - { - "code": "105542008", - "display": "Non - drinker" - }, - { - "code": "82581004", - "display": "Ex-drinker" - }, - { - "code": "86933000", - "display": "Heavy drinker" - }, - { - "code": "228277002", - "display": "Light drinker" - }, - { - "code": "43783005", - "display": "Moderate drinker" - }, - { - "code": "28127009", - "display": "Social drinker" - }, - { - "code": "39156-5", - "display": "Body mass index (BMI) [Ratio]" - }, - { - "code": "29463-7", - "display": "Body weight" - }, - { - "code": "8302-2", - "display": "Body height" - }, - { - "code": "56074-8", - "display": "Circumference Neck" - }, - { - "code": "8280-0", - "display": "Waist Circumference at umbilicus by Tape measure" - }, - { - "code": "56072-2", - "display": "Circumference Mid upper arm - right" - }, - { - "code": "2339-0", - "display": "Glucose [Mass/volume] in Blood" - }, - { - "code": "41604-0", - "display": "Fasting glucose [Mass/volume] in Capillary blood by Glucometer" - }, - { - "code": "14743-9", - "display": "Glucose [Moles/volume] in Capillary blood by Glucometer" - }, - { - "code": "14760-3", - "display": "Glucose [Moles/volume] in Capillary blood --2 hours post meal" - }, - { - "code": "73708-0", - "display": "Body fat [Mass] Calculated" - }, - { - "code": "34534-8", - "display": "12 lead EKG panel" - }, - { - "code": "8999-5", - "display": "Fluid intake oral Estimated" - }, - { - "code": "9052-2", - "display": "Calorie intake total" - }, - { - "code": "69429-9", - "display": "Metabolic rate --resting" - }, - { - "code": "94122-9", - "display": "Oxygen consumption (VO2)/Body weight [Volume Rate Content] --peak during exercise" - }, - { - "code": "8693-4", - "display": "Mental status" - }, - { - "code": "228273003", - "display": "Finding relating to alcohol drinking behavior" - }, - { - "code": "365981007", - "display": "Finding of tobacco smoking behavior" - }, - { - "code": "228509002", - "display": "Finding relating to tobacco chewing" - }, - { - "code": "41829006", - "display": "Finding relating to tobacco chewing" - }, - { - "code": "83765003", - "display": "Boredom" - }, - { - "code": "45763006", - "display": "Demoralization" - }, - { - "code": "708891002", - "display": "Emotionally stable" - }, - { - "code": "28669007", - "display": "Anhedonia" - }, - { - "code": "48694002", - "display": "Anxiety" - }, - { - "code": "102893002", - "display": "Excitability" - }, - { - "code": "225012006", - "display": "Feeling ashamed" - }, - { - "code": "224973000", - "display": "Feeling frustrated" - }, - { - "code": "224973000", - "display": "Feeling frustrated" - }, - { - "code": "267076002", - "display": "Feeling lonely" - }, - { - "code": "307048004", - "display": "Feeling isolated" - }, - { - "code": "162190005", - "display": "No nervous symptoms" - }, - { - "code": "225457007", - "display": "Feeling suicidal" - }, - { - "code": "224977004", - "display": "Feeling upset" - }, - { - "code": "271596009", - "display": "Mental distress" - }, - { - "code": "366979004", - "display": "Depressed mood" - }, - { - "code": "1402001", - "display": "Fear" - }, - { - "code": "75408008", - "display": "Feeling angry" - }, - { - "code": "55929007", - "display": "Feeling irritable" - }, - { - "code": "112080002", - "display": "Cheerful mood" - }, - { - "code": "225658008", - "display": "Mood stable" - }, - { - "code": "102894008", - "display": "Feeling calm" - }, - { - "code": "425363002", - "display": "Smiling" - }, - { - "code": "79015004", - "display": "Worried" - }, - { - "code": "53489000", - "display": "Tension" - }, - { - "code": "55423-8", - "display": "Number of steps in unspecified time Pedometer" - }, - { - "code": "93832-4", - "display": "Sleep duration" - }, - { - "code": "41981-2", - "display": "Calories burned" - }, - { - "code": "80493-0", - "display": "Activity level [Acceleration]" - }, - { - "code": "77176002", - "display": "Smoker" - }, - { - "code": "160618006", - "display": "Current non-smoker" - }, - { - "code": "8517006", - "display": "Ex-smoker" - }, - { - "code": "230065006", - "display": "Chain smoker" - }, - { - "code": "230063004", - "display": "Heavy cigarette smoker" - }, - { - "code": "230060001", - "display": "Light cigarette smoker" - }, - { - "code": "230062009", - "display": "Moderate cigarette smoker" - }, - { - "code": "230059006", - "display": "Occasional cigarette smoker" - }, - { - "code": "61008-9", - "display": "Body surface temperature" - }, - { - "code": "9279-1", - "display": "Respiratory rate" - }, - { - "code": "8867-4", - "display": "Heart rate" - }, - { - "code": "2708-6", - "display": "Oxygen saturation in Arterial blood" - }, - { - "code": "85354-9", - "display": "Blood pressure panel with all children optional" - }, - { - "code": "11976-8", - "display": "Ovulation date" - }, - { - "code": "92656-8", - "display": "Number of menstrual periods per year" - }, - { - "code": "42798-9", - "display": "Age at menarche" - }, - { - "code": "42802-9", - "display": "Age at menopause" - }, - { - "code": "8665-2", - "display": "Last menstrual period start date" - } -] \ No newline at end of file diff --git a/fhir-mapper/src/main/resources/snomed/SnomedSpecimen.json b/fhir-mapper/src/main/resources/snomed/SnomedSpecimen.json deleted file mode 100644 index ccb64567..00000000 --- a/fhir-mapper/src/main/resources/snomed/SnomedSpecimen.json +++ /dev/null @@ -1,3998 +0,0 @@ -[ - { - "code": "40511003", - "display": "Eluate" - }, - { - "code": "48469005", - "display": "Cytologic material" - }, - { - "code": "110893002", - "display": "Cutaneous cytologic material" - }, - { - "code": "110894008", - "display": "Mammary cytologic material" - }, - { - "code": "110896005", - "display": "Subcutaneous cytologic material" - }, - { - "code": "110897001", - "display": "Bone marrow cytological material" - }, - { - "code": "110898006", - "display": "Lymph node cytologic material" - }, - { - "code": "110899003", - "display": "Breast nipple cytologic material" - }, - { - "code": "110900008", - "display": "Skeletal muscle cytologic material" - }, - { - "code": "110901007", - "display": "Bone cytologic material" - }, - { - "code": "110902000", - "display": "Upper respiratory tract cytologic material" - }, - { - "code": "110903005", - "display": "Nasal cytologic material" - }, - { - "code": "110904004", - "display": "Accessory sinus cytologic material" - }, - { - "code": "110905003", - "display": "Nasopharyngeal cytologic material" - }, - { - "code": "110906002", - "display": "Lower respiratory tract cytologic material" - }, - { - "code": "110907006", - "display": "Epiglottic cytologic material" - }, - { - "code": "110908001", - "display": "Laryngeal cytologic material" - }, - { - "code": "110909009", - "display": "Vocal cord cytologic material" - }, - { - "code": "110910004", - "display": "Lung cytologic material" - }, - { - "code": "110912007", - "display": "Bronchial cytologic material" - }, - { - "code": "110913002", - "display": "Pleural cytologic material" - }, - { - "code": "110914008", - "display": "Right upper lobe bronchus cytologic material" - }, - { - "code": "110915009", - "display": "Right pleural cytologic material" - }, - { - "code": "110916005", - "display": "Right lower lobe bronchus cytologic material" - }, - { - "code": "110917001", - "display": "Left pleural cytologic material" - }, - { - "code": "110918006", - "display": "Left upper lobe bronchus cytologic material" - }, - { - "code": "110919003", - "display": "Pericardial cytologic material" - }, - { - "code": "110920009", - "display": "Tracheal cytologic material" - }, - { - "code": "110921008", - "display": "Right middle lobe bronchus cytologic material" - }, - { - "code": "110922001", - "display": "Left bronchial cytologic material" - }, - { - "code": "110923006", - "display": "Left lower lobe bronchus cytologic material" - }, - { - "code": "110924000", - "display": "Right bronchial cytologic material" - }, - { - "code": "110925004", - "display": "Cytologic material of mouth" - }, - { - "code": "110926003", - "display": "Gallbladder cytologic material" - }, - { - "code": "110927007", - "display": "Liver cytologic material" - }, - { - "code": "110928002", - "display": "Bile duct cytologic material" - }, - { - "code": "110929005", - "display": "Pancreatic cytologic material" - }, - { - "code": "110930000", - "display": "Salivary gland cytologic material" - }, - { - "code": "110931001", - "display": "Penis cytologic material" - }, - { - "code": "110932008", - "display": "Parotid gland cytologic material" - }, - { - "code": "110933003", - "display": "Prostate cytologic material" - }, - { - "code": "110934009", - "display": "Pharyngeal cytologic material" - }, - { - "code": "110935005", - "display": "Testis cytologic material" - }, - { - "code": "110936006", - "display": "Gastric cytologic material" - }, - { - "code": "110937002", - "display": "Seminal vesicle cytologic material" - }, - { - "code": "110938007", - "display": "Duodenal cytologic material" - }, - { - "code": "110939004", - "display": "Vas deferens cytologic material" - }, - { - "code": "110940002", - "display": "Ileal cytologic material" - }, - { - "code": "110941003", - "display": "Epididymis cytologic material" - }, - { - "code": "110942005", - "display": "Rectal cytologic material" - }, - { - "code": "110943000", - "display": "Renal pelvis cytologic material" - }, - { - "code": "110944006", - "display": "Peritoneal cytologic material" - }, - { - "code": "110945007", - "display": "Vulva cytologic material" - }, - { - "code": "110946008", - "display": "Upper urinary tract cytologic material" - }, - { - "code": "110947004", - "display": "Vagina cytologic material" - }, - { - "code": "110948009", - "display": "Kidney cytologic material" - }, - { - "code": "110949001", - "display": "Cervix cytologic material" - }, - { - "code": "110950001", - "display": "Urinary bladder cytologic material" - }, - { - "code": "110951002", - "display": "Endocervical cytologic material" - }, - { - "code": "110952009", - "display": "Submaxillary gland cytologic material" - }, - { - "code": "110953004", - "display": "Vaginal and cervical cytologic material (specimen)" - }, - { - "code": "110954005", - "display": "Small intestine cytologic material" - }, - { - "code": "110955006", - "display": "Endometrium cytologic material" - }, - { - "code": "110956007", - "display": "Colonic cytologic material" - }, - { - "code": "110957003", - "display": "Fallopian tube cytologic material" - }, - { - "code": "110958008", - "display": "Urinary tract cytologic material" - }, - { - "code": "110959000", - "display": "Placenta cytologic material" - }, - { - "code": "110960005", - "display": "Ureter cytologic material" - }, - { - "code": "110961009", - "display": "Chorion cytologic material" - }, - { - "code": "110962002", - "display": "Esophageal cytologic material" - }, - { - "code": "110963007", - "display": "Anal cytologic material" - }, - { - "code": "110964001", - "display": "Lower urinary tract cytologic material" - }, - { - "code": "110965000", - "display": "Urethra cytologic material" - }, - { - "code": "110966004", - "display": "Jejunal cytologic material" - }, - { - "code": "110967008", - "display": "Amnion cytologic material" - }, - { - "code": "110968003", - "display": "Fetal cytologic material" - }, - { - "code": "110969006", - "display": "Cerebrospinal fluid cytologic material" - }, - { - "code": "110970007", - "display": "Cerebroventricular fluid cytologic material" - }, - { - "code": "116155002", - "display": "Ampulla of Vater cytologic material" - }, - { - "code": "116156001", - "display": "Gastrointestinal tract cytologic material" - }, - { - "code": "116157005", - "display": "Heart cytologic material" - }, - { - "code": "116158000", - "display": "Large intestine cytologic material" - }, - { - "code": "116159008", - "display": "Upper aerodigestive tract cytologic material" - }, - { - "code": "116160003", - "display": "Thyroid cytologic material" - }, - { - "code": "116161004", - "display": "Fine needle aspirate of thyroid, cytologic material" - }, - { - "code": "116162006", - "display": "Thyroid cytologic material, processed intraoperatively" - }, - { - "code": "116213003", - "display": "Ovary cytologic material" - }, - { - "code": "119294007", - "display": "Dried blood specimen" - }, - { - "code": "119295008", - "display": "Specimen obtained by aspiration" - }, - { - "code": "119297000", - "display": "Blood specimen" - }, - { - "code": "119298005", - "display": "Mixed venous blood specimen" - }, - { - "code": "119299002", - "display": "Specimen from patient" - }, - { - "code": "119300005", - "display": "Specimen from blood product" - }, - { - "code": "119301009", - "display": "Plant specimen" - }, - { - "code": "119302002", - "display": "Mushroom specimen" - }, - { - "code": "119303007", - "display": "Microbial isolate specimen" - }, - { - "code": "119304001", - "display": "Specimen from blood bag" - }, - { - "code": "119305000", - "display": "Specimen from plasma bag (specimen)" - }, - { - "code": "119307008", - "display": "Endotracheal tube specimen" - }, - { - "code": "119308003", - "display": "Cannula submitted as specimen" - }, - { - "code": "119309006", - "display": "Arterial line submitted as specimen" - }, - { - "code": "119311002", - "display": "Catheter submitted as specimen (specimen)" - }, - { - "code": "119312009", - "display": "Catheter tip submitted as specimen" - }, - { - "code": "119313004", - "display": "Implantable venous catheter submitted as specimen" - }, - { - "code": "119314005", - "display": "Electrode submitted as specimen (specimen)" - }, - { - "code": "119316007", - "display": "Non-biological fluid specimen" - }, - { - "code": "119317003", - "display": "Gaseous material specimen" - }, - { - "code": "119318008", - "display": "Water specimen" - }, - { - "code": "119319000", - "display": "Drug specimen" - }, - { - "code": "119320006", - "display": "Food specimen" - }, - { - "code": "119321005", - "display": "Milk specimen" - }, - { - "code": "119323008", - "display": "Pus specimen" - }, - { - "code": "119324002", - "display": "Specimen of unknown material" - }, - { - "code": "119325001", - "display": "Skin specimen" - }, - { - "code": "119326000", - "display": "Hair specimen" - }, - { - "code": "119327009", - "display": "Nail specimen" - }, - { - "code": "119328004", - "display": "Mother's milk specimen" - }, - { - "code": "119329007", - "display": "Colostrum specimen" - }, - { - "code": "119331003", - "display": "Skeletal muscle specimen" - }, - { - "code": "119332005", - "display": "Synovial fluid specimen" - }, - { - "code": "119333000", - "display": "Fibroblast specimen" - }, - { - "code": "119334006", - "display": "Sputum specimen" - }, - { - "code": "119335007", - "display": "Coughed sputum specimen" - }, - { - "code": "119336008", - "display": "Exhaled air specimen" - }, - { - "code": "119337004", - "display": "Inhaled gas specimen" - }, - { - "code": "119338009", - "display": "Dentin specimen" - }, - { - "code": "119339001", - "display": "Stool specimen" - }, - { - "code": "119340004", - "display": "Meconium specimen" - }, - { - "code": "119341000", - "display": "Bile specimen" - }, - { - "code": "119342007", - "display": "Saliva specimen" - }, - { - "code": "119343002", - "display": "Pancreatic fluid specimen" - }, - { - "code": "119344008", - "display": "Specimen from genital system" - }, - { - "code": "119345009", - "display": "Menstrual blood specimen" - }, - { - "code": "119346005", - "display": "Egg yolk specimen" - }, - { - "code": "119347001", - "display": "Seminal fluid specimen" - }, - { - "code": "119348006", - "display": "Seminal plasma specimen" - }, - { - "code": "119349003", - "display": "Spermatozoa specimen" - }, - { - "code": "119350003", - "display": "Calculus specimen" - }, - { - "code": "119351004", - "display": "Erythrocyte specimen" - }, - { - "code": "119352006", - "display": "Macrophage specimen" - }, - { - "code": "119353001", - "display": "Lymphocyte specimen" - }, - { - "code": "119355008", - "display": "Polymorphonuclear neutrophil specimen" - }, - { - "code": "119356009", - "display": "Eosinophil specimen" - }, - { - "code": "119357000", - "display": "Basophil specimen" - }, - { - "code": "119358005", - "display": "Platelet specimen" - }, - { - "code": "119359002", - "display": "Bone marrow specimen" - }, - { - "code": "119361006", - "display": "Plasma specimen" - }, - { - "code": "119362004", - "display": "Platelet poor plasma specimen" - }, - { - "code": "119363009", - "display": "Platelet rich plasma specimen" - }, - { - "code": "119364003", - "display": "Serum specimen" - }, - { - "code": "119365002", - "display": "Specimen from wound" - }, - { - "code": "119366001", - "display": "Specimen from wound abscess" - }, - { - "code": "119367005", - "display": "Specimen from burn injury" - }, - { - "code": "119368000", - "display": "Specimen from cyst" - }, - { - "code": "119369008", - "display": "Specimen from ulcer" - }, - { - "code": "119370009", - "display": "Specimen from fistula" - }, - { - "code": "119371008", - "display": "Specimen from abscess" - }, - { - "code": "119373006", - "display": "Amniotic fluid specimen" - }, - { - "code": "119376003", - "display": "Tissue specimen" - }, - { - "code": "119377007", - "display": "Myocardial specimen" - }, - { - "code": "119378002", - "display": "Endocardial specimen" - }, - { - "code": "119379005", - "display": "Specimen from stomach" - }, - { - "code": "119380008", - "display": "Specimen from small intestine" - }, - { - "code": "119381007", - "display": "Specimen from large intestine" - }, - { - "code": "119382000", - "display": "Specimen from colon" - }, - { - "code": "119383005", - "display": "Specimen from liver" - }, - { - "code": "119384004", - "display": "Specimen from right fallopian tube" - }, - { - "code": "119385003", - "display": "Specimen from left fallopian tube" - }, - { - "code": "119386002", - "display": "Specimen from prostate" - }, - { - "code": "119388001", - "display": "Specimen from internal nose" - }, - { - "code": "119389009", - "display": "Specimen from throat" - }, - { - "code": "119390000", - "display": "Specimen from trachea" - }, - { - "code": "119391001", - "display": "Specimen from bronchus" - }, - { - "code": "119392008", - "display": "Specimen from anus" - }, - { - "code": "119393003", - "display": "Specimen from urethra" - }, - { - "code": "119394009", - "display": "Specimen from vagina" - }, - { - "code": "119395005", - "display": "Specimen from uterine cervix" - }, - { - "code": "119396006", - "display": "Specimen from endometrium" - }, - { - "code": "119397002", - "display": "Specimen from penis" - }, - { - "code": "119398007", - "display": "Specimen from brain" - }, - { - "code": "119399004", - "display": "Specimen from eye" - }, - { - "code": "119400006", - "display": "Specimen from cornea" - }, - { - "code": "119401005", - "display": "Specimen from conjunctiva" - }, - { - "code": "119403008", - "display": "Specimen from placenta" - }, - { - "code": "122550002", - "display": "Specimen obtained by fine needle aspiration procedure" - }, - { - "code": "122551003", - "display": "Peripheral blood specimen" - }, - { - "code": "122552005", - "display": "Arterial blood specimen" - }, - { - "code": "122553000", - "display": "Blood specimen obtained from umbilicus" - }, - { - "code": "122554006", - "display": "Capillary blood specimen" - }, - { - "code": "122555007", - "display": "Venous blood specimen" - }, - { - "code": "122556008", - "display": "Cord blood specimen" - }, - { - "code": "122557004", - "display": "Cord blood specimen from fetus" - }, - { - "code": "122558009", - "display": "Blood specimen from blood product" - }, - { - "code": "122559001", - "display": "Blood specimen from control" - }, - { - "code": "122560006", - "display": "Blood specimen from donor" - }, - { - "code": "122561005", - "display": "Blood specimen from patient" - }, - { - "code": "122562003", - "display": "Blood specimen from newborn" - }, - { - "code": "122563008", - "display": "Specimen from blood bag from patient (specimen)" - }, - { - "code": "122564002", - "display": "Specimen from blood bag from blood product (specimen)" - }, - { - "code": "122565001", - "display": "Urinary catheter specimen" - }, - { - "code": "122566000", - "display": "Fluid specimen from wound" - }, - { - "code": "122567009", - "display": "Urine sediment specimen" - }, - { - "code": "122568004", - "display": "Exudate specimen from wound" - }, - { - "code": "122569007", - "display": "Sweat specimen" - }, - { - "code": "122571007", - "display": "Pericardial fluid specimen" - }, - { - "code": "122572000", - "display": "Vomitus specimen" - }, - { - "code": "122573005", - "display": "Gastric contents specimen" - }, - { - "code": "122574004", - "display": "Duodenal fluid specimen" - }, - { - "code": "122575003", - "display": "Urine specimen" - }, - { - "code": "122576002", - "display": "Genital mucus specimen" - }, - { - "code": "122577006", - "display": "Cervical mucus specimen" - }, - { - "code": "122578001", - "display": "Female genital fluid specimen" - }, - { - "code": "122579009", - "display": "Genital lochia specimen" - }, - { - "code": "122580007", - "display": "Cerumen specimen" - }, - { - "code": "122581006", - "display": "Erythrocyte specimen from blood donor" - }, - { - "code": "122582004", - "display": "Erythrocyte specimen from blood product" - }, - { - "code": "122583009", - "display": "Erythrocyte specimen from patient" - }, - { - "code": "122584003", - "display": "Leukocyte specimen from patient" - }, - { - "code": "122585002", - "display": "Leukocyte specimen from control" - }, - { - "code": "122587005", - "display": "Platelet poor plasma specimen from control" - }, - { - "code": "122588000", - "display": "Platelet poor plasma specimen from patient" - }, - { - "code": "122589008", - "display": "Serum specimen from donor" - }, - { - "code": "122590004", - "display": "Serum specimen from patient" - }, - { - "code": "122591000", - "display": "Serum specimen from blood product" - }, - { - "code": "122592007", - "display": "Acellular blood (serum or plasma) specimen" - }, - { - "code": "122593002", - "display": "Tissue specimen obtained from ulcer" - }, - { - "code": "122594008", - "display": "Tears specimen" - }, - { - "code": "122595009", - "display": "Specimen from breast obtained by total mastectomy" - }, - { - "code": "122596005", - "display": "Specimen from breast obtained by complete excision of lesion, less than total mastectomy" - }, - { - "code": "122597001", - "display": "Specimen from breast obtained by complete excision, less than total mastectomy, with axillary contents" - }, - { - "code": "122598006", - "display": "Specimen from breast obtained by complete excision, less than total mastectomy, without axillary contents" - }, - { - "code": "122599003", - "display": "Specimen from breast obtained by radical mastectomy" - }, - { - "code": "122600000", - "display": "Specimen from breast obtained by modified radical mastectomy" - }, - { - "code": "122601001", - "display": "Specimen from breast obtained by biopsy" - }, - { - "code": "122602008", - "display": "Tissue specimen from biopsy of upper aerodigestive tract" - }, - { - "code": "122604009", - "display": "Specimen from lung obtained by wedge resection" - }, - { - "code": "122605005", - "display": "Specimen from lung obtained by segmentectomy" - }, - { - "code": "122606006", - "display": "Specimen from lung obtained by lobectomy" - }, - { - "code": "122607002", - "display": "Specimen from lung obtained by pneumonectomy" - }, - { - "code": "122608007", - "display": "Specimen from lung obtained by major airway resection" - }, - { - "code": "122609004", - "display": "Specimen from lung obtained by bronchial washing procedure" - }, - { - "code": "122610009", - "display": "Specimen from lung obtained by biopsy" - }, - { - "code": "122611008", - "display": "Specimen from lung obtained by fiberoptic bronchoscopic biopsy" - }, - { - "code": "122613006", - "display": "Specimen from lung obtained by mediastinoscopic biopsy" - }, - { - "code": "122614000", - "display": "Specimen from lung obtained by fine needle aspiration procedure" - }, - { - "code": "122616003", - "display": "Specimen from pleura obtained by open thoracotomy and biopsy" - }, - { - "code": "122617007", - "display": "Specimen from pleura obtained by percutaneous needle biopsy" - }, - { - "code": "122618002", - "display": "Specimen from pleura obtained by fine needle aspiration procedure" - }, - { - "code": "122619005", - "display": "Specimen from pleura obtained by thoracentesis" - }, - { - "code": "122620004", - "display": "Specimen from pleura obtained by thoracoscopic procedure" - }, - { - "code": "122621000", - "display": "Specimen from pleura obtained by thoracoscopic biopsy" - }, - { - "code": "122622007", - "display": "Specimen from pleura obtained by lymph node biopsy" - }, - { - "code": "122623002", - "display": "Specimen from heart obtained by biopsy" - }, - { - "code": "122624008", - "display": "Specimen from heart obtained by excisional biopsy of lesion" - }, - { - "code": "122625009", - "display": "Specimen from heart obtained by incisional biopsy" - }, - { - "code": "122626005", - "display": "Specimen from heart obtained by fine needle aspiration procedure" - }, - { - "code": "122627001", - "display": "Specimen from gastrointestinal tract obtained by incisional biopsy" - }, - { - "code": "122628006", - "display": "Specimen from esophagus obtained by incisional biopsy" - }, - { - "code": "122629003", - "display": "Specimen from esophagus obtained by excisional biopsy of lesion" - }, - { - "code": "122630008", - "display": "Specimen from esophagus obtained by esophageal resection" - }, - { - "code": "122631007", - "display": "Specimen from esophagus obtained by esophagogastrectomy" - }, - { - "code": "122632000", - "display": "Specimen from stomach obtained by incisional biopsy" - }, - { - "code": "122633005", - "display": "Specimen from stomach obtained by excisional biopsy (polypectomy) of lesion" - }, - { - "code": "122634004", - "display": "Specimen from stomach obtained by total gastrectomy" - }, - { - "code": "122635003", - "display": "Specimen from stomach obtained by partial gastrectomy" - }, - { - "code": "122636002", - "display": "Specimen from proximal stomach obtained by partial gastrectomy" - }, - { - "code": "122637006", - "display": "Specimen from distal stomach obtained by partial gastrectomy" - }, - { - "code": "122638001", - "display": "Tissue specimen from small intestine" - }, - { - "code": "122639009", - "display": "Specimen from duodenum obtained by Whipple resection" - }, - { - "code": "122640006", - "display": "Specimen from jejunum obtained by segmental resection" - }, - { - "code": "122641005", - "display": "Specimen from ileum obtained by segmental resection" - }, - { - "code": "122642003", - "display": "Specimen from distal ileum obtained by right hemicolectomy" - }, - { - "code": "122643008", - "display": "Tissue specimen from large intestine" - }, - { - "code": "122644002", - "display": "Specimen from large intestine obtained by incisional biopsy" - }, - { - "code": "122645001", - "display": "Specimen from large intestine obtained by excisional biopsy (polypectomy) of lesion" - }, - { - "code": "122646000", - "display": "Specimen from large intestine obtained by abdominoperineal resection" - }, - { - "code": "122647009", - "display": "Specimen from large intestine obtained by total abdominal colectomy" - }, - { - "code": "122648004", - "display": "Specimen from colon obtained by right hemicolectomy" - }, - { - "code": "122649007", - "display": "Specimen from colon obtained by transverse colectomy" - }, - { - "code": "122650007", - "display": "Specimen from colon obtained by left hemicolectomy" - }, - { - "code": "122651006", - "display": "Specimen from colon obtained by sigmoidectomy" - }, - { - "code": "122652004", - "display": "Specimen from colon obtained by rectal (low anterior) resection" - }, - { - "code": "122653009", - "display": "Specimen from rectum obtained by transanal disk excision" - }, - { - "code": "122654003", - "display": "Specimen from rectum obtained by transanal disk excision, intact" - }, - { - "code": "122655002", - "display": "Specimen from rectum obtained by transanal disk excision, fragmented" - }, - { - "code": "122656001", - "display": "Tissue specimen from gall bladder" - }, - { - "code": "122657005", - "display": "Specimen from ampulla of Vater obtained by incisional biopsy" - }, - { - "code": "122658000", - "display": "Specimen from ampulla of Vater obtained by ampullectomy" - }, - { - "code": "122659008", - "display": "Specimen from ampulla of Vater obtained by pancreaticoduodenectomy" - }, - { - "code": "122660003", - "display": "Specimen from ampulla of Vater obtained by pylorus-sparing pancreaticoduodenectomy" - }, - { - "code": "122661004", - "display": "Specimen from pancreas obtained by partial pancreatectomy" - }, - { - "code": "122662006", - "display": "Specimen from pancreatic body obtained by partial resection" - }, - { - "code": "122663001", - "display": "Specimen from pancreatic tail obtained by partial resection" - }, - { - "code": "122664007", - "display": "Specimen from pancreas obtained by total pancreatectomy" - }, - { - "code": "122665008", - "display": "Specimen from pancreas obtained by pancreaticoduodenectomy (Whipple resection)" - }, - { - "code": "122666009", - "display": "Specimen from pancreas obtained by pylorus sparing pancreaticoduodenectomy" - }, - { - "code": "122667000", - "display": "Specimen from pancreas obtained by incisional biopsy" - }, - { - "code": "122668005", - "display": "Specimen from urinary tract obtained by transurethral excision" - }, - { - "code": "122669002", - "display": "Specimen from urinary bladder obtained by anterior exenteration (specimen)" - }, - { - "code": "122670001", - "display": "Specimen from kidney obtained by (core) needle biopsy" - }, - { - "code": "122671002", - "display": "Specimen from kidney obtained by fine needle aspiration procedure" - }, - { - "code": "122672009", - "display": "Specimen from kidney obtained by incisional biopsy" - }, - { - "code": "122673004", - "display": "Specimen from kidney obtained by wedge biopsy" - }, - { - "code": "122674005", - "display": "Specimen from right kidney obtained by radical nephrectomy" - }, - { - "code": "122675006", - "display": "Specimen from right kidney obtained by radical nephrectomy, without adrenal" - }, - { - "code": "122676007", - "display": "Specimen from right kidney obtained by partial nephrectomy" - }, - { - "code": "122677003", - "display": "Specimen from right kidney, inferior pole obtained by partial nephrectomy" - }, - { - "code": "122678008", - "display": "Specimen from right kidney, middle pole obtained by partial nephrectomy" - }, - { - "code": "122679000", - "display": "Specimen from right kidney, superior pole obtained by partial nephrectomy" - }, - { - "code": "122680002", - "display": "Specimen from left kidney obtained by radical nephrectomy" - }, - { - "code": "122681003", - "display": "Specimen from left kidney obtained by radical nephrectomy, without adrenal" - }, - { - "code": "122682005", - "display": "Specimen from left kidney obtained by partial nephrectomy" - }, - { - "code": "122683000", - "display": "Specimen from left kidney, inferior pole obtained by partial nephrectomy" - }, - { - "code": "122684006", - "display": "Specimen from left kidney, middle pole obtained by partial nephrectomy" - }, - { - "code": "122685007", - "display": "Specimen from left kidney, superior pole obtained by partial nephrectomy" - }, - { - "code": "122686008", - "display": "Specimen from urinary bladder obtained by partial cystectomy (specimen)" - }, - { - "code": "122687004", - "display": "Specimen from urinary bladder obtained by total cystectomy (specimen)" - }, - { - "code": "122688009", - "display": "Specimen from urinary bladder obtained by radical cystoprostatectomy (specimen)" - }, - { - "code": "122689001", - "display": "Specimen from right kidney obtained by radical nephrectomy and adrenalectomy" - }, - { - "code": "122690005", - "display": "Specimen from left kidney obtained by radical nephrectomy and adrenalectomy" - }, - { - "code": "122691009", - "display": "Specimen from vagina obtained by incisional biopsy" - }, - { - "code": "122692002", - "display": "Specimen from vagina obtained by excisional biopsy of lesion" - }, - { - "code": "122693007", - "display": "Specimen from vagina obtained by vaginectomy" - }, - { - "code": "122694001", - "display": "Specimen from vagina obtained by radical vaginectomy" - }, - { - "code": "122696004", - "display": "Specimen from uterus obtained by radical hysterectomy" - }, - { - "code": "122697008", - "display": "Specimen from uterus obtained by pelvic exenteration" - }, - { - "code": "122698003", - "display": "Specimen from uterine cervix obtained by incisional biopsy" - }, - { - "code": "122699006", - "display": "Specimen from uterine cervix obtained by excisional biopsy (cone biopsy) of lesion" - }, - { - "code": "122700007", - "display": "Specimen from uterine cervix obtained by hysterectomy" - }, - { - "code": "122701006", - "display": "Specimen from uterine cervix obtained by radical hysterectomy" - }, - { - "code": "122702004", - "display": "Specimen from uterine cervix obtained by pelvic exenteration" - }, - { - "code": "122703009", - "display": "Specimen from endometrium obtained by curettage" - }, - { - "code": "122704003", - "display": "Specimen from endometrium obtained by biopsy" - }, - { - "code": "122705002", - "display": "Specimen from endometrium obtained by hysterectomy" - }, - { - "code": "122706001", - "display": "Specimen from endometrium obtained by radical hysterectomy" - }, - { - "code": "122707005", - "display": "Specimen from endometrium obtained by pelvic exenteration" - }, - { - "code": "122708000", - "display": "Specimen from ovary obtained by biopsy" - }, - { - "code": "122709008", - "display": "Specimen from ovary obtained by incisional biopsy" - }, - { - "code": "122710003", - "display": "Specimen from ovary obtained by resection" - }, - { - "code": "122711004", - "display": "Specimen from ovary obtained by removal of tumor in fragments" - }, - { - "code": "122712006", - "display": "Specimen from ovary obtained by hysterectomy with salpingo-oophorectomy" - }, - { - "code": "122713001", - "display": "Specimen from ovary obtained by subtotal right oophorectomy" - }, - { - "code": "122714007", - "display": "Specimen from right ovary obtained by oophorectomy" - }, - { - "code": "122715008", - "display": "Specimen from right ovary obtained by salpingo-oophorectomy" - }, - { - "code": "122716009", - "display": "Specimen from left ovary obtained by oophorectomy" - }, - { - "code": "122717000", - "display": "Specimen from ovary obtained by subtotal left oophorectomy" - }, - { - "code": "122718005", - "display": "Specimen from left ovary obtained by salpingo-oophorectomy" - }, - { - "code": "122719002", - "display": "Specimen from fallopian tube obtained by hysterectomy with salpingo-oophorectomy" - }, - { - "code": "122720008", - "display": "Specimen from fallopian tube obtained by excision of tubal fragments" - }, - { - "code": "122721007", - "display": "Specimen from fallopian tube obtained by pelvic exenteration" - }, - { - "code": "122722000", - "display": "Specimen from right fallopian tube obtained by salpingo-oophorectomy" - }, - { - "code": "122723005", - "display": "Specimen from left fallopian tube obtained by salpingo-oophorectomy" - }, - { - "code": "122724004", - "display": "Specimen from prostate obtained by enucleation" - }, - { - "code": "122725003", - "display": "Specimen from prostate obtained by radical prostatectomy" - }, - { - "code": "122726002", - "display": "Specimen from prostate obtained by retropubic resection" - }, - { - "code": "122727006", - "display": "Specimen from prostate obtained by suprapubic resection" - }, - { - "code": "122728001", - "display": "Specimen from testis obtained by inguinal exposure with testicular isolation and biopsy" - }, - { - "code": "122729009", - "display": "Specimen from testis obtained by transscrotal needle biopsy" - }, - { - "code": "122730004", - "display": "Specimen from testis obtained by transcrotal open biopsy" - }, - { - "code": "122732007", - "display": "Specimen from thyroid obtained by lobectomy" - }, - { - "code": "122733002", - "display": "Specimen from right lobe of thyroid obtained by lobe resection" - }, - { - "code": "122734008", - "display": "Specimen from left lobe of thyroid obtained by lobe resection" - }, - { - "code": "122735009", - "display": "Specimen from thyroid obtained by isthmectomy" - }, - { - "code": "122736005", - "display": "Tissue specimen from placenta" - }, - { - "code": "122737001", - "display": "Specimen from breast obtained by core needle biopsy" - }, - { - "code": "122738006", - "display": "Specimen obtained from breast by stereotactically guided core needle biopsy" - }, - { - "code": "122739003", - "display": "Specimen from breast obtained by incisional biopsy of breast mass" - }, - { - "code": "122877000", - "display": "Upper respiratory fluid specimen obtained by tracheal aspiration" - }, - { - "code": "122879002", - "display": "Upper gastrointestinal contents specimen" - }, - { - "code": "122880004", - "display": "Urine specimen obtained by clean catch procedure" - }, - { - "code": "127456000", - "display": "Specimen from breast" - }, - { - "code": "127457009", - "display": "Tissue specimen from breast" - }, - { - "code": "127458004", - "display": "Specimen from lung" - }, - { - "code": "127459007", - "display": "Specimen from pleura" - }, - { - "code": "127460002", - "display": "Tissue specimen from pleura" - }, - { - "code": "127461003", - "display": "Specimen from pleura obtained by pleurectomy" - }, - { - "code": "127462005", - "display": "Specimen from heart" - }, - { - "code": "127463000", - "display": "Specimen from esophagus" - }, - { - "code": "127464006", - "display": "Tissue specimen from esophagus" - }, - { - "code": "127465007", - "display": "Specimen from gastrointestinal tract" - }, - { - "code": "127466008", - "display": "Tissue specimen from gastrointestinal tract" - }, - { - "code": "127467004", - "display": "Specimen from ampulla of Vater" - }, - { - "code": "127468009", - "display": "Tissue specimen from ampulla of Vater" - }, - { - "code": "127469001", - "display": "Specimen from pancreas" - }, - { - "code": "127470000", - "display": "Tissue specimen from pancreas" - }, - { - "code": "127471001", - "display": "Specimen from urinary tract" - }, - { - "code": "127472008", - "display": "Tissue specimen from urinary tract" - }, - { - "code": "127473003", - "display": "Specimen from kidney" - }, - { - "code": "127474009", - "display": "Tissue specimen from kidney" - }, - { - "code": "127475005", - "display": "Tissue specimen from testis" - }, - { - "code": "127476006", - "display": "Specimen from fallopian tube" - }, - { - "code": "127478007", - "display": "Tissue specimen from thyroid gland" - }, - { - "code": "127479004", - "display": "Specimen from uterus" - }, - { - "code": "127480001", - "display": "Tissue specimen from uterus" - }, - { - "code": "127481002", - "display": "Tissue specimen from uterine cervix" - }, - { - "code": "127482009", - "display": "Tissue specimen from ovary" - }, - { - "code": "127483004", - "display": "Tissue specimen from fallopian tube" - }, - { - "code": "128154006", - "display": "Specimen from testis" - }, - { - "code": "128155007", - "display": "Specimen from ovary" - }, - { - "code": "128156008", - "display": "Tissue specimen from anus" - }, - { - "code": "128157004", - "display": "Tissue specimen from brain" - }, - { - "code": "128158009", - "display": "Tissue specimen from bronchus" - }, - { - "code": "128159001", - "display": "Tissue specimen from colon" - }, - { - "code": "128160006", - "display": "Tissue specimen from conjunctiva" - }, - { - "code": "128161005", - "display": "Tissue specimen from cornea" - }, - { - "code": "128162003", - "display": "Tissue specimen from ear" - }, - { - "code": "128163008", - "display": "Tissue specimen from endometrium" - }, - { - "code": "128164002", - "display": "Tissue specimen from eye" - }, - { - "code": "128165001", - "display": "Tissue specimen from genital system" - }, - { - "code": "128166000", - "display": "Tissue specimen from heart" - }, - { - "code": "128167009", - "display": "Tissue specimen from internal nose" - }, - { - "code": "128168004", - "display": "Tissue specimen from liver" - }, - { - "code": "128169007", - "display": "Tissue specimen from penis" - }, - { - "code": "128170008", - "display": "Tissue specimen from prostate" - }, - { - "code": "128171007", - "display": "Tissue specimen from stomach" - }, - { - "code": "128172000", - "display": "Tissue specimen from throat" - }, - { - "code": "128173005", - "display": "Tissue specimen from trachea" - }, - { - "code": "128174004", - "display": "Tissue specimen from urethra" - }, - { - "code": "128175003", - "display": "Tissue specimen from vagina" - }, - { - "code": "167867009", - "display": "Multiple joint synovial fluid" - }, - { - "code": "167868004", - "display": "Shoulder joint synovial fluid" - }, - { - "code": "167869007", - "display": "Elbow joint synovial fluid" - }, - { - "code": "167870008", - "display": "Wrist joint synovial fluid" - }, - { - "code": "167871007", - "display": "Hand joint synovial fluid" - }, - { - "code": "167872000", - "display": "Finger joint synovial fluid" - }, - { - "code": "167873005", - "display": "Hip joint synovial fluid" - }, - { - "code": "167874004", - "display": "Knee joint synovial fluid" - }, - { - "code": "167875003", - "display": "Ankle joint synovial fluid" - }, - { - "code": "167876002", - "display": "Foot joint synovial fluid" - }, - { - "code": "167877006", - "display": "Toe joint synovial fluid" - }, - { - "code": "167913002", - "display": "Bone marrow source" - }, - { - "code": "168136008", - "display": "Colostomy fluid sample" - }, - { - "code": "168137004", - "display": "Gastric aspirate sample" - }, - { - "code": "168138009", - "display": "Gastric lavage aspirate sample" - }, - { - "code": "168139001", - "display": "Peritoneal fluid sample" - }, - { - "code": "168140004", - "display": "Peritoneal dialysis sample" - }, - { - "code": "168141000", - "display": "Nasal fluid sample" - }, - { - "code": "168145009", - "display": "Lymph sample" - }, - { - "code": "256889002", - "display": "Breast cyst fluid sample" - }, - { - "code": "256912003", - "display": "Red blood cell fluid sample" - }, - { - "code": "257261003", - "display": "Swab" - }, - { - "code": "258407001", - "display": "Abscess tissue" - }, - { - "code": "258411007", - "display": "Nasopharyngeal aspirate" - }, - { - "code": "258412000", - "display": "Oropharyngeal aspirate" - }, - { - "code": "258414004", - "display": "Adipose tissue sample" - }, - { - "code": "258415003", - "display": "Biopsy sample" - }, - { - "code": "258417006", - "display": "Bone tissue sample" - }, - { - "code": "258418001", - "display": "Burn tissue" - }, - { - "code": "258419009", - "display": "Curettings" - }, - { - "code": "258420003", - "display": "Cyst tissue" - }, - { - "code": "258421004", - "display": "Embryo biopsy sample" - }, - { - "code": "258422006", - "display": "Gonad tissue" - }, - { - "code": "258423001", - "display": "Hair bulb sample" - }, - { - "code": "258424007", - "display": "Heart valve tissue" - }, - { - "code": "258425008", - "display": "Natural lens tissue" - }, - { - "code": "258426009", - "display": "Placental membrane tissue sample" - }, - { - "code": "258428005", - "display": "Products of conception tissue sample" - }, - { - "code": "258429002", - "display": "Rectal scrape sample" - }, - { - "code": "258430007", - "display": "Rectal snip sample" - }, - { - "code": "258431006", - "display": "Scrapings" - }, - { - "code": "258432004", - "display": "Sebum sample" - }, - { - "code": "258433009", - "display": "Smear sample" - }, - { - "code": "258434003", - "display": "Spun urinary sediment" - }, - { - "code": "258435002", - "display": "Tumour tissue" - }, - { - "code": "258436001", - "display": "Umbilical cord tissue" - }, - { - "code": "258437005", - "display": "Vegetation from heart valve" - }, - { - "code": "258438000", - "display": "Vitreous humor sample" - }, - { - "code": "258439008", - "display": "Discharge" - }, - { - "code": "258440005", - "display": "Effusion sample" - }, - { - "code": "258441009", - "display": "Exudate sample" - }, - { - "code": "258442002", - "display": "Fluid sample" - }, - { - "code": "258444001", - "display": "Aqueous humour sample" - }, - { - "code": "258446004", - "display": "Bronchial fluid sample" - }, - { - "code": "258448003", - "display": "Bursa fluid sample" - }, - { - "code": "258450006", - "display": "Cerebrospinal fluid sample" - }, - { - "code": "258452003", - "display": "Chylous fluid sample" - }, - { - "code": "258453008", - "display": "Cyst fluid sample" - }, - { - "code": "258454002", - "display": "Dialysate sample" - }, - { - "code": "258455001", - "display": "Drainage fluid sample" - }, - { - "code": "258456000", - "display": "Empyema fluid sample" - }, - { - "code": "258457009", - "display": "Faecal fluid sample" - }, - { - "code": "258458004", - "display": "Fistula fluid sample" - }, - { - "code": "258459007", - "display": "Gastric fluid sample" - }, - { - "code": "258461003", - "display": "Hydrocele fluid sample" - }, - { - "code": "258462005", - "display": "Ileostomy fluid sample" - }, - { - "code": "258463000", - "display": "Jejunal fluid sample" - }, - { - "code": "258465007", - "display": "Lacrimal fluid sample" - }, - { - "code": "258466008", - "display": "Middle ear fluid sample" - }, - { - "code": "258467004", - "display": "Nasopharyngeal washings" - }, - { - "code": "258468009", - "display": "Oedema fluid sample" - }, - { - "code": "258469001", - "display": "Pharyngeal washings" - }, - { - "code": "258470000", - "display": "Prostatic fluid sample" - }, - { - "code": "258471001", - "display": "Prostatic massage fluid sample" - }, - { - "code": "258472008", - "display": "Renal pelvis fluid sample" - }, - { - "code": "258474009", - "display": "Sinus fluid sample" - }, - { - "code": "258475005", - "display": "Sinus washings" - }, - { - "code": "258476006", - "display": "Subretinal fluid sample" - }, - { - "code": "258479004", - "display": "Tissue fluid sample" - }, - { - "code": "258480001", - "display": "Transtracheal aspirate sample" - }, - { - "code": "258481002", - "display": "Vaginal washout fluid sample" - }, - { - "code": "258482009", - "display": "Vesicle fluid sample" - }, - { - "code": "258483004", - "display": "Mucus sample" - }, - { - "code": "258484005", - "display": "Postmortem tissue sample" - }, - { - "code": "258485006", - "display": "Corneal scrapings" - }, - { - "code": "258487003", - "display": "Faecal smear" - }, - { - "code": "258488008", - "display": "Lymph node smear" - }, - { - "code": "258489000", - "display": "Slit skin smear" - }, - { - "code": "258490009", - "display": "Biliary stone sample" - }, - { - "code": "258492001", - "display": "Gallstone sample" - }, - { - "code": "258493006", - "display": "Bladder stone sample" - }, - { - "code": "258494000", - "display": "Pancreatic stone sample" - }, - { - "code": "258495004", - "display": "Renal stone sample" - }, - { - "code": "258496003", - "display": "Ureteric stone sample" - }, - { - "code": "258497007", - "display": "Abscess swab" - }, - { - "code": "258498002", - "display": "Conjunctival swab" - }, - { - "code": "258499005", - "display": "Cough swab" - }, - { - "code": "258500001", - "display": "Nasopharyngeal swab" - }, - { - "code": "258502009", - "display": "Pus swab" - }, - { - "code": "258503004", - "display": "Skin swab" - }, - { - "code": "258504005", - "display": "BCG site swab" - }, - { - "code": "258505006", - "display": "Skin ulcer swab" - }, - { - "code": "258506007", - "display": "Swab of drain insertion site" - }, - { - "code": "258507003", - "display": "Swab of line insertion site" - }, - { - "code": "258508008", - "display": "Genital swab" - }, - { - "code": "258509000", - "display": "Male genital swab" - }, - { - "code": "258510005", - "display": "Penis swab" - }, - { - "code": "258511009", - "display": "Penile urethral swab" - }, - { - "code": "258512002", - "display": "Glans penis swab" - }, - { - "code": "258513007", - "display": "Prepuce swab" - }, - { - "code": "258514001", - "display": "Subpreputial swab" - }, - { - "code": "258515000", - "display": "Coronal sulcus of penis swab" - }, - { - "code": "258516004", - "display": "Frenulum of penis swab" - }, - { - "code": "258517008", - "display": "Shaft of penis swab" - }, - { - "code": "258518003", - "display": "Scrotal swab" - }, - { - "code": "258519006", - "display": "Female genital swab" - }, - { - "code": "258520000", - "display": "Vaginal swab" - }, - { - "code": "258521001", - "display": "HVS - High vaginal swab" - }, - { - "code": "258522008", - "display": "Low vaginal swab" - }, - { - "code": "258523003", - "display": "Vulval swab" - }, - { - "code": "258524009", - "display": "Cervical swab" - }, - { - "code": "258525005", - "display": "Perineal swab" - }, - { - "code": "258526006", - "display": "Perianal swab" - }, - { - "code": "258527002", - "display": "Anal swab" - }, - { - "code": "258528007", - "display": "Rectal swab" - }, - { - "code": "258529004", - "display": "TS - Throat swab" - }, - { - "code": "258530009", - "display": "Urethral swab" - }, - { - "code": "258531008", - "display": "Wound swab" - }, - { - "code": "258532001", - "display": "Swab of inanimate object" - }, - { - "code": "258535004", - "display": "Floor swab" - }, - { - "code": "258536003", - "display": "Incubator swab" - }, - { - "code": "258537007", - "display": "Surface swab" - }, - { - "code": "258538002", - "display": "Transudate sample" - }, - { - "code": "258539005", - "display": "Bone and joint sample" - }, - { - "code": "258541006", - "display": "Cardiovascular sample" - }, - { - "code": "258542004", - "display": "Heart valve sample" - }, - { - "code": "258544003", - "display": "Natural heart valve sample" - }, - { - "code": "258545002", - "display": "Vegetation from prosthetic heart valve" - }, - { - "code": "258546001", - "display": "Vegetation from natural heart valve" - }, - { - "code": "258547005", - "display": "Cardiopulmonary bypass pump fluid sample" - }, - { - "code": "258548000", - "display": "Dermatological sample" - }, - { - "code": "258549008", - "display": "Skin scale sample" - }, - { - "code": "258553005", - "display": "Duodenal string" - }, - { - "code": "258554004", - "display": "Faecal concretion sample" - }, - { - "code": "258555003", - "display": "Hot stool sample" - }, - { - "code": "258558001", - "display": "Oral secretion sample" - }, - { - "code": "258559009", - "display": "Gingivocrevicular fluid sample" - }, - { - "code": "258560004", - "display": "Oral saliva sample" - }, - { - "code": "258561000", - "display": "Parotid gland saliva sample" - }, - { - "code": "258562007", - "display": "Genetic sample" - }, - { - "code": "258563002", - "display": "Amniotic cell sample" - }, - { - "code": "258564008", - "display": "Buccal smear sample" - }, - { - "code": "258565009", - "display": "Chorionic villi sample" - }, - { - "code": "258566005", - "display": "Deoxyribonucleic acid sample" - }, - { - "code": "258567001", - "display": "Gonad sample" - }, - { - "code": "258568006", - "display": "Polar body sample" - }, - { - "code": "258569003", - "display": "Skin fibroblast sample" - }, - { - "code": "258570002", - "display": "Genitourinary sample" - }, - { - "code": "258571003", - "display": "Machine hemodialysate sample" - }, - { - "code": "258572005", - "display": "Ultrafiltrate sample" - }, - { - "code": "258574006", - "display": "Mid-stream urine sample" - }, - { - "code": "258575007", - "display": "EMU-Early morning urine sample" - }, - { - "code": "258576008", - "display": "Suprapubic aspirate sample" - }, - { - "code": "258577004", - "display": "Vaginal secretion sample" - }, - { - "code": "258580003", - "display": "Whole blood sample" - }, - { - "code": "258581004", - "display": "Clotted blood sample" - }, - { - "code": "258582006", - "display": "Blood clot sample" - }, - { - "code": "258583001", - "display": "Bone marrow clot sample" - }, - { - "code": "258584007", - "display": "Bone marrow fragment sample" - }, - { - "code": "258585008", - "display": "Bone marrow trephine sample" - }, - { - "code": "258587000", - "display": "Buffy coat" - }, - { - "code": "258588005", - "display": "Hematoma sample" - }, - { - "code": "258589002", - "display": "Lymph node sample" - }, - { - "code": "258590006", - "display": "Acidified serum sample" - }, - { - "code": "258591005", - "display": "White blood cell sample" - }, - { - "code": "258599007", - "display": "Contact lens solution sample" - }, - { - "code": "258601009", - "display": "Lens sample" - }, - { - "code": "258602002", - "display": "Intraocular lens sample" - }, - { - "code": "258603007", - "display": "Respiratory sample" - }, - { - "code": "258604001", - "display": "Upper respiratory sample" - }, - { - "code": "258606004", - "display": "Lower respiratory sample" - }, - { - "code": "258607008", - "display": "Bronchoalveolar lavage fluid sample" - }, - { - "code": "258608003", - "display": "Sputum specimen obtained by aspiration (specimen)" - }, - { - "code": "258609006", - "display": "Sputum specimen obtained by aspiration from trachea (specimen)" - }, - { - "code": "258610001", - "display": "Sputum specimen obtained by sputum induction (specimen)" - }, - { - "code": "258611002", - "display": "Sputum specimen obtained from sputum suction trap (specimen)" - }, - { - "code": "258613004", - "display": "Living sample" - }, - { - "code": "258614005", - "display": "Insect sample" - }, - { - "code": "258615006", - "display": "Larva sample" - }, - { - "code": "258616007", - "display": "Maggot sample" - }, - { - "code": "258617003", - "display": "Parasite sample" - }, - { - "code": "258618008", - "display": "Helminth sample" - }, - { - "code": "258627009", - "display": "Cannula tip submitted as specimen (specimen)" - }, - { - "code": "258628004", - "display": "Vascular cannula tip submitted as specimen" - }, - { - "code": "258629007", - "display": "Arterial cannula tip submitted as specimen (specimen)" - }, - { - "code": "258630002", - "display": "Venous cannula tip submitted as specimen (specimen)" - }, - { - "code": "258631003", - "display": "Arteriovenous shunt tip submitted as specimen (specimen)" - }, - { - "code": "258649003", - "display": "Intravenous infusion fluid sample" - }, - { - "code": "258650003", - "display": "Intravenous lipid infusion fluid sample" - }, - { - "code": "258651004", - "display": "Cream sample" - }, - { - "code": "258652006", - "display": "Ice-cream sample" - }, - { - "code": "258653001", - "display": "Formula milk sample" - }, - { - "code": "258654007", - "display": "Soya milk sample" - }, - { - "code": "258655008", - "display": "Cow's milk sample" - }, - { - "code": "258656009", - "display": "Whole milk sample" - }, - { - "code": "258657000", - "display": "Semi-skimmed milk sample" - }, - { - "code": "258658005", - "display": "Skimmed milk sample" - }, - { - "code": "258659002", - "display": "Sheep's milk sample" - }, - { - "code": "258660007", - "display": "Goat's milk sample" - }, - { - "code": "258662004", - "display": "Adhesive slide specimen (specimen)" - }, - { - "code": "258663009", - "display": "Sellotape slide specimen" - }, - { - "code": "258664003", - "display": "Scotch tape slide specimen" - }, - { - "code": "264380007", - "display": "Synovial fluid cells" - }, - { - "code": "271514008", - "display": "Sternal bone marrow sample" - }, - { - "code": "271515009", - "display": "Iliac crest bone marrow sample" - }, - { - "code": "271516005", - "display": "Vertebral spinous process bone marrow sample" - }, - { - "code": "271518006", - "display": "Rib bone marrow sample" - }, - { - "code": "276446009", - "display": "Cervical smear sample" - }, - { - "code": "276833005", - "display": "24 hour urine sample" - }, - { - "code": "278020009", - "display": "Spot urine sample" - }, - { - "code": "302794003", - "display": "Nasogastric aspirate" - }, - { - "code": "302795002", - "display": "Lymph node aspirate" - }, - { - "code": "303247002", - "display": "Adrenal tissue" - }, - { - "code": "303248007", - "display": "Blood film sample" - }, - { - "code": "309048008", - "display": "Endocrine sample" - }, - { - "code": "309049000", - "display": "Lesion sample" - }, - { - "code": "309050000", - "display": "Body substance sample" - }, - { - "code": "309051001", - "display": "Body fluid sample" - }, - { - "code": "309052008", - "display": "Male genital sample" - }, - { - "code": "309053003", - "display": "Female genital sample" - }, - { - "code": "309055005", - "display": "Breast fluid sample" - }, - { - "code": "309057002", - "display": "Breast direct smear sample" - }, - { - "code": "309058007", - "display": "Breast tru-cut biopsy sample" - }, - { - "code": "309059004", - "display": "Frozen section breast sample" - }, - { - "code": "309061008", - "display": "Breast fine needle aspirate sample" - }, - { - "code": "309066003", - "display": "Skin biopsy sample" - }, - { - "code": "309067007", - "display": "Skin curettings sample" - }, - { - "code": "309068002", - "display": "Skin lesion sample" - }, - { - "code": "309070006", - "display": "Vulval skin biopsy sample" - }, - { - "code": "309071005", - "display": "Penis skin biopsy sample" - }, - { - "code": "309072003", - "display": "Soft tissue sample" - }, - { - "code": "309073008", - "display": "Lipoma biopsy sample" - }, - { - "code": "309074002", - "display": "Soft tissue biopsy sample" - }, - { - "code": "309075001", - "display": "Skin cyst sample" - }, - { - "code": "309077009", - "display": "Spleen resection sample" - }, - { - "code": "309078004", - "display": "Lymph node tissue sample" - }, - { - "code": "309079007", - "display": "Lymph node biopsy sample" - }, - { - "code": "309101008", - "display": "Cartilage sample" - }, - { - "code": "309102001", - "display": "Cartilage biopsy sample" - }, - { - "code": "309103006", - "display": "Excised cartilage sample" - }, - { - "code": "309104000", - "display": "Musculoskeletal sample" - }, - { - "code": "309105004", - "display": "Bone biopsy sample" - }, - { - "code": "309107007", - "display": "Tendon sample" - }, - { - "code": "309108002", - "display": "Excised tendon sample" - }, - { - "code": "309109005", - "display": "Bursa sample" - }, - { - "code": "309110000", - "display": "Bursa tissue sample" - }, - { - "code": "309111001", - "display": "Bursa biopsy sample" - }, - { - "code": "309112008", - "display": "Excised bursa sample" - }, - { - "code": "309113003", - "display": "Tendon biopsy sample" - }, - { - "code": "309114009", - "display": "Ligament sample" - }, - { - "code": "309115005", - "display": "Ligament biopsy sample" - }, - { - "code": "309116006", - "display": "Excised ligament sample" - }, - { - "code": "309117002", - "display": "Fascia sample" - }, - { - "code": "309118007", - "display": "Fascia biopsy sample" - }, - { - "code": "309119004", - "display": "Excised fascia sample" - }, - { - "code": "309120005", - "display": "Head of femur sample" - }, - { - "code": "309121009", - "display": "Synovial tissue sample" - }, - { - "code": "309122002", - "display": "Synovium biopsy sample" - }, - { - "code": "309123007", - "display": "Synovial sample" - }, - { - "code": "309124001", - "display": "Joint biopsy sample" - }, - { - "code": "309125000", - "display": "Joint sample" - }, - { - "code": "309126004", - "display": "Articular tissue sample" - }, - { - "code": "309127008", - "display": "Resected articular tissue sample" - }, - { - "code": "309128003", - "display": "Eye fluid sample" - }, - { - "code": "309129006", - "display": "Nerve tissue sample" - }, - { - "code": "309130001", - "display": "Nerve biopsy sample" - }, - { - "code": "309131002", - "display": "Neuroma sample" - }, - { - "code": "309132009", - "display": "Prostate biopsy sample" - }, - { - "code": "309133004", - "display": "Resected prostate sample" - }, - { - "code": "309134005", - "display": "Prostate tru-cut biopsy sample" - }, - { - "code": "309135006", - "display": "Hydrocele sample" - }, - { - "code": "309137003", - "display": "Testes biopsy sample" - }, - { - "code": "309138008", - "display": "Orchidectomy sample" - }, - { - "code": "309139000", - "display": "Vas deferens sample" - }, - { - "code": "309140003", - "display": "Epididymis sample" - }, - { - "code": "309141004", - "display": "Adrenal gland sample" - }, - { - "code": "309142006", - "display": "Adrenal biopsy sample" - }, - { - "code": "309143001", - "display": "Excised adrenal gland sample" - }, - { - "code": "309144007", - "display": "Thyroid lobe sample" - }, - { - "code": "309145008", - "display": "Thyroid fluid sample" - }, - { - "code": "309146009", - "display": "Thyroid fine needle aspirate sample" - }, - { - "code": "309147000", - "display": "Thyroid cyst fluid sample" - }, - { - "code": "309148005", - "display": "Thyroid direct smear sample" - }, - { - "code": "309149002", - "display": "Parathyroid sample" - }, - { - "code": "309150002", - "display": "Parathyroid tissue sample" - }, - { - "code": "309151003", - "display": "Parathyroid biopsy sample" - }, - { - "code": "309153000", - "display": "Excised parathyroid sample" - }, - { - "code": "309154006", - "display": "Pituitary sample" - }, - { - "code": "309164002", - "display": "Upper respiratory swab sample" - }, - { - "code": "309165001", - "display": "Ear sample" - }, - { - "code": "309166000", - "display": "Ear swab sample" - }, - { - "code": "309167009", - "display": "Middle ear biopsy sample" - }, - { - "code": "309168004", - "display": "Upper respiratory tissue sample" - }, - { - "code": "309169007", - "display": "Tracheal biopsy sample" - }, - { - "code": "309170008", - "display": "Lower respiratory tissue sample" - }, - { - "code": "309171007", - "display": "Lower respiratory fluid sample" - }, - { - "code": "309172000", - "display": "Pleura biopsy sample" - }, - { - "code": "309173005", - "display": "Transbronchial lung biopsy sample" - }, - { - "code": "309174004", - "display": "Bronchial biopsy sample" - }, - { - "code": "309175003", - "display": "Resected lung sample" - }, - { - "code": "309176002", - "display": "Bronchial brushings sample" - }, - { - "code": "309177006", - "display": "Lung direct smear sample" - }, - { - "code": "309178001", - "display": "Nasal biopsy sample" - }, - { - "code": "309179009", - "display": "Nasal polyp sample" - }, - { - "code": "309180007", - "display": "Nasopharyngeal biopsy sample" - }, - { - "code": "309181006", - "display": "Mastoid biopsy sample" - }, - { - "code": "309182004", - "display": "Larynx biopsy sample" - }, - { - "code": "309183009", - "display": "Laryngectomy sample" - }, - { - "code": "309184003", - "display": "Vocal cord biopsy sample" - }, - { - "code": "309185002", - "display": "Oral cavity sample" - }, - { - "code": "309186001", - "display": "Oral tissue sample" - }, - { - "code": "309187005", - "display": "Dental tissue sample" - }, - { - "code": "309188000", - "display": "Mouth biopsy sample" - }, - { - "code": "309189008", - "display": "Tongue biopsy sample" - }, - { - "code": "309190004", - "display": "Excised salivary gland sample" - }, - { - "code": "309191000", - "display": "Tonsil biopsy sample" - }, - { - "code": "309192007", - "display": "Tonsillectomy sample" - }, - { - "code": "309193002", - "display": "Pharyngeal biopsy sample" - }, - { - "code": "309199003", - "display": "Gastrointestinal fluid sample" - }, - { - "code": "309200000", - "display": "Rectal tissue sample" - }, - { - "code": "309201001", - "display": "Ascitic fluid sample" - }, - { - "code": "309202008", - "display": "Gastrointestinal direct smear" - }, - { - "code": "309203003", - "display": "Liver biopsy sample" - }, - { - "code": "309204009", - "display": "Liver direct smear sample" - }, - { - "code": "309205005", - "display": "Cholecystectomy sample" - }, - { - "code": "309206006", - "display": "Pancreas biopsy sample" - }, - { - "code": "309207002", - "display": "Peritoneal biopsy sample" - }, - { - "code": "309208007", - "display": "Omentum biopsy sample" - }, - { - "code": "309209004", - "display": "Esophageal biopsy sample" - }, - { - "code": "309210009", - "display": "Oesophageal brushings sample" - }, - { - "code": "309211008", - "display": "Gastric biopsy sample" - }, - { - "code": "309212001", - "display": "Gastric antral biopsy sample" - }, - { - "code": "309213006", - "display": "Gastric brushings sample" - }, - { - "code": "309214000", - "display": "Gastric fundus biopsy sample" - }, - { - "code": "309215004", - "display": "Gastric ulcer sample" - }, - { - "code": "309216003", - "display": "Duodenal biopsy sample" - }, - { - "code": "309217007", - "display": "Ileal biopsy sample" - }, - { - "code": "309218002", - "display": "Ileal resection sample" - }, - { - "code": "309219005", - "display": "Jejunal biopsy sample" - }, - { - "code": "309220004", - "display": "Small bowel resection sample" - }, - { - "code": "309221000", - "display": "Terminal ileum resection sample" - }, - { - "code": "309222007", - "display": "Appendix sample" - }, - { - "code": "309223002", - "display": "Colectomy sample" - }, - { - "code": "309224008", - "display": "Colon strip sample" - }, - { - "code": "309225009", - "display": "Colonic biopsy sample" - }, - { - "code": "309226005", - "display": "Colonic polyp sample" - }, - { - "code": "309227001", - "display": "Sigmoid colonic polyp sample" - }, - { - "code": "309260003", - "display": "Sigmoid colon biopsy sample" - }, - { - "code": "309261004", - "display": "Sigmoid colon brushings sample" - }, - { - "code": "309262006", - "display": "Rectal biopsy sample" - }, - { - "code": "309263001", - "display": "Rectal polyp sample" - }, - { - "code": "309264007", - "display": "Excised rectum sample" - }, - { - "code": "309265008", - "display": "Anal biopsy sample" - }, - { - "code": "309266009", - "display": "Anal polyp sample" - }, - { - "code": "309267000", - "display": "Anal resection sample" - }, - { - "code": "309268005", - "display": "Urological fluid sample" - }, - { - "code": "309269002", - "display": "Kidney biopsy sample" - }, - { - "code": "309270001", - "display": "Nephrectomy sample" - }, - { - "code": "309271002", - "display": "Ureter biopsy sample" - }, - { - "code": "309272009", - "display": "Urinary bladder tissue sample" - }, - { - "code": "309273004", - "display": "Bladder biopsy sample" - }, - { - "code": "309274005", - "display": "Bladder curettings sample" - }, - { - "code": "309275006", - "display": "Cystectomy sample" - }, - { - "code": "309276007", - "display": "Frozen section bladder sample" - }, - { - "code": "309277003", - "display": "Urethra biopsy sample" - }, - { - "code": "309278008", - "display": "Female genital tissue sample" - }, - { - "code": "309280002", - "display": "Vaginal biopsy sample" - }, - { - "code": "309281003", - "display": "Vaginal vault biopsy sample" - }, - { - "code": "309283000", - "display": "Cervical biopsy sample" - }, - { - "code": "309285007", - "display": "Cervical loop excision sample" - }, - { - "code": "309286008", - "display": "Cervical polyp sample" - }, - { - "code": "309287004", - "display": "Excised uterus, fallopian tubes and ovaries sample" - }, - { - "code": "309288009", - "display": "Endometrial polyp sample" - }, - { - "code": "309289001", - "display": "Endometrial resection sample" - }, - { - "code": "309290005", - "display": "Fallopian tube biopsy sample" - }, - { - "code": "309291009", - "display": "Ovarian cyst sample" - }, - { - "code": "309292002", - "display": "Ovarian fluid sample" - }, - { - "code": "309293007", - "display": "Placenta biopsy sample" - }, - { - "code": "309476009", - "display": "Neck block dissection sample" - }, - { - "code": "309478005", - "display": "Thrombus sample" - }, - { - "code": "309479002", - "display": "Artery sample" - }, - { - "code": "309480004", - "display": "Vein sample" - }, - { - "code": "309481000", - "display": "Temporal artery sample" - }, - { - "code": "309482007", - "display": "Frozen section lymph node sample" - }, - { - "code": "309483002", - "display": "Lip biopsy sample" - }, - { - "code": "309484008", - "display": "Parotidectomy sample" - }, - { - "code": "309485009", - "display": "Excised sublingual gland sample" - }, - { - "code": "309486005", - "display": "Excised submandibular gland sample" - }, - { - "code": "309487001", - "display": "Total colectomy sample" - }, - { - "code": "309488006", - "display": "Partial colectomy sample" - }, - { - "code": "309489003", - "display": "Anterior resection of rectum sample" - }, - { - "code": "309490007", - "display": "Pancreatectomy sample" - }, - { - "code": "309491006", - "display": "Biliary tract tissue sample" - }, - { - "code": "309493009", - "display": "Bile duct biopsy sample" - }, - { - "code": "309494003", - "display": "Ampulla of Vater biopsy sample" - }, - { - "code": "309495002", - "display": "Omentum tissue sample" - }, - { - "code": "309496001", - "display": "Omentectomy sample" - }, - { - "code": "309497005", - "display": "Total nephrectomy sample" - }, - { - "code": "309498000", - "display": "Partial nephrectomy sample" - }, - { - "code": "309499008", - "display": "Foreskin biopsy sample" - }, - { - "code": "309501000", - "display": "Excised uterus sample" - }, - { - "code": "309502007", - "display": "Fetus specimen" - }, - { - "code": "309503002", - "display": "Breast nipple discharge sample" - }, - { - "code": "309504008", - "display": "Skin punch biopsy sample" - }, - { - "code": "309505009", - "display": "Skin incision biopsy sample" - }, - { - "code": "309506005", - "display": "Skin excision biopsy sample" - }, - { - "code": "309507001", - "display": "Muscle biopsy sample" - }, - { - "code": "309508006", - "display": "Soft tissue lesion fine needle aspirate sample" - }, - { - "code": "309546004", - "display": "Lumpectomy breast sample" - }, - { - "code": "309547008", - "display": "Segmentectomy breast sample" - }, - { - "code": "309548003", - "display": "Breast duct sample" - }, - { - "code": "309549006", - "display": "Minor salivary gland sample" - }, - { - "code": "312494007", - "display": "Vaginal vault smear sample" - }, - { - "code": "363311008", - "display": "Specimen from digestive system" - }, - { - "code": "363328006", - "display": "Tissue specimen from digestive system" - }, - { - "code": "363329003", - "display": "Tissue specimen from respiratory system" - }, - { - "code": "369611008", - "display": "Tissue specimen obtained from small intestine by biopsy" - }, - { - "code": "369613006", - "display": "Tissue specimen obtained for Hodgkin's disease by biopsy" - }, - { - "code": "369614000", - "display": "Tissue specimen obtained from extrahepatic bile ducts by biopsy" - }, - { - "code": "369615004", - "display": "Tissue specimen obtained from extrahepatic bile ducts by choledochal cyst resection" - }, - { - "code": "369616003", - "display": "Tissue specimen obtained from gallbladder by biopsy" - }, - { - "code": "369617007", - "display": "Tissue specimen obtained from gallbladder by cholecystectomy with partial hepatectomy" - }, - { - "code": "369618002", - "display": "Tissue specimen obtained from vulva by biopsy (specimen)" - }, - { - "code": "370108001", - "display": "Extrahepatic bile duct cytologic material" - }, - { - "code": "371780008", - "display": "Specimen for identification (specimen)" - }, - { - "code": "371782000", - "display": "Human bone for identification (specimen)" - }, - { - "code": "371783005", - "display": "Human tissue for identification (specimen)" - }, - { - "code": "371784004", - "display": "Body parts for identification (specimen)" - }, - { - "code": "373101006", - "display": "Breast cytologic material obtained by percutaneous core biopsy (specimen)" - }, - { - "code": "373102004", - "display": "Breast tissue obtained by image guided core biopsy" - }, - { - "code": "373103009", - "display": "Breast cytologic material obtained by incisional biopsy (specimen)" - }, - { - "code": "373192005", - "display": "Lymph node from axillary dissection (specimen)" - }, - { - "code": "373193000", - "display": "Lymph node from sentinel lymph node dissection (specimen)" - }, - { - "code": "373826004", - "display": "Surgical excision sample" - }, - { - "code": "384744003", - "display": "Lymph node from sentinel lymph node dissection and axillary dissection (specimen)" - }, - { - "code": "384746001", - "display": "Specimen from lung obtained by wedge biopsy (specimen)" - }, - { - "code": "384747005", - "display": "Specimen from lung obtained by CT guided needle biopsy" - }, - { - "code": "384819001", - "display": "Specimen from prostate obtained by needle biopsy (specimen)" - }, - { - "code": "384820007", - "display": "Specimen from prostate obtained by transurethral resection (specimen)" - }, - { - "code": "385338007", - "display": "Specimen from anus obtained by transanal disk excision (specimen)" - }, - { - "code": "385339004", - "display": "Specimen from anus obtained by transanal disk excision, intact (specimen)" - }, - { - "code": "385340002", - "display": "Specimen from anus obtained by transanal disk excision, fragmented (specimen)" - }, - { - "code": "396273004", - "display": "Specimen from uterine cervix obtained by excision of cervix (specimen)" - }, - { - "code": "396353007", - "display": "Specimen from skin obtained by elliptical excision (specimen)" - }, - { - "code": "396354001", - "display": "Specimen from skin obtained by wide excision (specimen)" - }, - { - "code": "396355000", - "display": "Specimen from skin obtained by excision (specimen)" - }, - { - "code": "396356004", - "display": "Specimen from skin obtained by re-excision (specimen)" - }, - { - "code": "396357008", - "display": "Specimen from skin obtained by elliptical re-excision (specimen)" - }, - { - "code": "396358003", - "display": "Specimen from skin obtained by wide re-excision (specimen)" - }, - { - "code": "396359006", - "display": "Lymph node from regional lymph node dissection (specimen)" - }, - { - "code": "396476009", - "display": "Specimen from liver obtained by right lobectomy (specimen)" - }, - { - "code": "396477000", - "display": "Specimen from liver obtained by extended right lobectomy (specimen)" - }, - { - "code": "396478005", - "display": "Specimen from liver obtained by medial segmentectomy (specimen)" - }, - { - "code": "396479002", - "display": "Specimen from liver obtained by left lateral segmentectomy (specimen)" - }, - { - "code": "396480004", - "display": "Specimen from liver obtained by total left lobectomy (specimen)" - }, - { - "code": "396481000", - "display": "Specimen from explanted liver (specimen)" - }, - { - "code": "396483002", - "display": "Specimen from skin obtained by shave excision (specimen)" - }, - { - "code": "396525008", - "display": "Specimen from adrenal gland obtained by needle biopsy (specimen)" - }, - { - "code": "396526009", - "display": "Specimen from adrenal gland obtained by partial adrenalectomy (specimen)" - }, - { - "code": "396527000", - "display": "Specimen from adrenal gland obtained by total adrenalectomy (specimen)" - }, - { - "code": "396685001", - "display": "Specimen from urinary bladder obtained by radical cystectomy (specimen)" - }, - { - "code": "396804002", - "display": "Specimen from pancreas obtained by pylorus sparing pancreaticoduodenectomy, partial pancreatectomy (specimen)" - }, - { - "code": "396805001", - "display": "Specimen from pancreas obtained by pylorus sparing pancreaticoduodenectomy, total pancreatectomy (specimen)" - }, - { - "code": "396806000", - "display": "Specimen from pancreas obtained by pancreaticoduodenectomy, partial pancreatectomy (specimen)" - }, - { - "code": "396807009", - "display": "Specimen from pancreas obtained by pancreaticoduodenectomy, total pancreatectomy (specimen)" - }, - { - "code": "396896007", - "display": "Specimen from thymus gland (specimen)" - }, - { - "code": "396897003", - "display": "Specimen from thymus gland obtained by transcervical thymectomy (specimen)" - }, - { - "code": "396898008", - "display": "Specimen from thymus gland obtained by thoracotomy (specimen)" - }, - { - "code": "396899000", - "display": "Specimen from thymus gland obtained by fine needle aspiration biopsy (specimen)" - }, - { - "code": "396900005", - "display": "Specimen from thymus gland obtained by CT guided needle biopsy" - }, - { - "code": "396902002", - "display": "Specimen from thymus gland obtained by transthoracic needle biopsy (specimen)" - }, - { - "code": "396904001", - "display": "Specimen from thymus gland obtained by limited thoracotomy (specimen)" - }, - { - "code": "396906004", - "display": "Specimen from thymus gland obtained by video assisted thoracotomy (specimen)" - }, - { - "code": "396928004", - "display": "Specimen from eye obtained by enucleation (specimen)" - }, - { - "code": "396997002", - "display": "Specimen from bone marrow obtained by aspiration (specimen)" - }, - { - "code": "396998007", - "display": "Specimen from bone marrow obtained by aspiration and biopsy (specimen)" - }, - { - "code": "396999004", - "display": "Specimen from bone marrow obtained by biopsy (specimen)" - }, - { - "code": "397053005", - "display": "Specimen from small intestine obtained by polypectomy (specimen)" - }, - { - "code": "397055003", - "display": "Specimen from small intestine obtained by segmental resection (specimen)" - }, - { - "code": "397056002", - "display": "Specimen from small intestine obtained by Whipple procedure" - }, - { - "code": "397077004", - "display": "Specimen obtained by incisional biopsy (specimen)" - }, - { - "code": "397078009", - "display": "Specimen obtained by excisional biopsy (specimen)" - }, - { - "code": "397111007", - "display": "Specimen from vagina obtained by partial vaginectomy (specimen)" - }, - { - "code": "397129002", - "display": "Specimen from vulva (specimen)" - }, - { - "code": "397130007", - "display": "Specimen from vulva obtained by local excision (specimen)" - }, - { - "code": "397131006", - "display": "Specimen from vulva obtained by wide excision (specimen)" - }, - { - "code": "397132004", - "display": "Specimen from vulva obtained by partial vulvectomy (specimen)" - }, - { - "code": "397133009", - "display": "Specimen from vulva obtained by total vulvectomy (specimen)" - }, - { - "code": "397134003", - "display": "Specimen from vulva obtained by radical vulvectomy (specimen)" - }, - { - "code": "397135002", - "display": "Specimen from pelvic lymph node (specimen)" - }, - { - "code": "397136001", - "display": "Specimen from inguinofemoral lymphadenectomy (specimen)" - }, - { - "code": "397199005", - "display": "Specimen from breast obtained by excision (specimen)" - }, - { - "code": "397221008", - "display": "Specimen from renal pelvis obtained by biopsy (specimen)" - }, - { - "code": "397232008", - "display": "Specimen from renal pelvis obtained by nephroureterectomy (specimen)" - }, - { - "code": "397233003", - "display": "Specimen from renal pelvis (specimen)" - }, - { - "code": "397234009", - "display": "Specimen from renal pelvis obtained by partial nephroureterectomy (specimen)" - }, - { - "code": "397235005", - "display": "Specimen from renal pelvis obtained by complete nephroureterectomy (specimen)" - }, - { - "code": "397245007", - "display": "Specimen from ovary obtained by hysterectomy with right salpingo-oophorectomy (specimen)" - }, - { - "code": "397246008", - "display": "Specimen from ovary obtained by hysterectomy with left salpingo-oophorectomy (specimen)" - }, - { - "code": "397326000", - "display": "Specimen from right fallopian tube obtained by hysterectomy with salpingo-oophorectomy (specimen)" - }, - { - "code": "397333000", - "display": "Specimen from right fallopian tube obtained by salpingectomy (specimen)" - }, - { - "code": "397334006", - "display": "Specimen from left fallopian tube obtained by salpingectomy (specimen)" - }, - { - "code": "397436009", - "display": "Specimen obtained by lymphadenectomy (specimen)" - }, - { - "code": "397438005", - "display": "Specimen from lymph node obtained by staging laparotomy (specimen)" - }, - { - "code": "397455009", - "display": "Specimen from thoracic mesothelium obtained by percutaneous needle biopsy (specimen)" - }, - { - "code": "397456005", - "display": "Specimen from thoracic mesothelium obtained by thoracoscopic biopsy (specimen)" - }, - { - "code": "397457001", - "display": "Specimen from thoracic mesothelium (specimen)" - }, - { - "code": "397458006", - "display": "Specimen from thoracic mesothelium obtained by open thoracotomy (specimen)" - }, - { - "code": "397462000", - "display": "Specimen from pericardium obtained by pericardial resection (specimen)" - }, - { - "code": "397482001", - "display": "Specimen from extrahepatic bile duct obtained by pancreaticoduodenectomy (specimen)" - }, - { - "code": "397483006", - "display": "Specimen from extrahepatic bile duct obtained by segmental resection of bile ducts (specimen)" - }, - { - "code": "399388008", - "display": "Specimen from left fallopian tube obtained by hysterectomy with salpingo-oophorectomy (specimen)" - }, - { - "code": "399396003", - "display": "Trophoblastic tissue obtained from uterus by dilation and curettage (specimen)" - }, - { - "code": "399402006", - "display": "Specimen from ureter (specimen)" - }, - { - "code": "399407000", - "display": "Specimen from ureter obtained by ureterectomy (specimen)" - }, - { - "code": "399411006", - "display": "Specimen from trophoblast (specimen)" - }, - { - "code": "399436000", - "display": "Specimen from central nervous system (specimen)" - }, - { - "code": "399440009", - "display": "Specimen from ureter obtained by nephroureterectomy (specimen)" - }, - { - "code": "399443006", - "display": "Specimen from eye obtained by complete exenteration (specimen)" - }, - { - "code": "399447007", - "display": "Trophoblastic tissue obtained by radical hysterectomy (specimen)" - }, - { - "code": "399451009", - "display": "Tissue specimen from retina (specimen)" - }, - { - "code": "399460001", - "display": "Specimen from extrahepatic bile duct (specimen)" - }, - { - "code": "399467003", - "display": "Specimen from uvea obtained by limited exenteration of eye (specimen)" - }, - { - "code": "399484009", - "display": "Superficial parotidectomy sample" - }, - { - "code": "399486006", - "display": "Tissue specimen from vulva (specimen)" - }, - { - "code": "399492000", - "display": "Tissue specimen from lung (specimen)" - }, - { - "code": "399499009", - "display": "Specimen from uvea obtained by complete exenteration of eye (specimen)" - }, - { - "code": "399502008", - "display": "Trophoblastic tissue obtained by pelvic exenteration (specimen)" - }, - { - "code": "399512001", - "display": "Specimen from retina obtained by enucleation of eye (specimen)" - }, - { - "code": "399526005", - "display": "Specimen from major salivary gland (specimen)" - }, - { - "code": "399532000", - "display": "Tissue specimen from renal pelvis (specimen)" - }, - { - "code": "399541005", - "display": "Tissue specimen from extrahepatic bile duct (specimen)" - }, - { - "code": "399542003", - "display": "Tissue specimen from central nervous system (specimen)" - }, - { - "code": "399551006", - "display": "Specimen from central nervous system obtained by open biopsy (specimen)" - }, - { - "code": "399559008", - "display": "Specimen from uvea obtained by enucleation of eye (specimen)" - }, - { - "code": "399572009", - "display": "Tissue specimen from thymus gland (specimen)" - }, - { - "code": "399603006", - "display": "Specimen from retina obtained by complete exenteration of eye (specimen)" - }, - { - "code": "399614009", - "display": "Specimen from central nervous system obtained by total resection of tumor (specimen)" - }, - { - "code": "399619004", - "display": "Tissue specimen from uvea (specimen)" - }, - { - "code": "399622002", - "display": "Specimen from thyroid obtained by total thyroidectomy (specimen)" - }, - { - "code": "399624001", - "display": "Tissue specimen from ureter (specimen)" - }, - { - "code": "399629006", - "display": "Specimen from stomach obtained by gastrectomy (specimen)" - }, - { - "code": "399633004", - "display": "Specimen from thymus gland obtained by biopsy (specimen)" - }, - { - "code": "399640003", - "display": "Specimen from retina obtained by limited exenteration of eye (specimen)" - }, - { - "code": "399645008", - "display": "Tissue specimen from major salivary gland (specimen)" - }, - { - "code": "399649002", - "display": "Specimen from regional lymph node obtained by lymphadenectomy (specimen)" - }, - { - "code": "399657004", - "display": "Tissue specimen from trophoblast (specimen)" - }, - { - "code": "399658009", - "display": "Trophoblastic tissue obtained by hysterectomy (specimen)" - }, - { - "code": "399661005", - "display": "Specimen from pelvic lymphadenectomy (specimen)" - }, - { - "code": "399672000", - "display": "Tissue specimen from thoracic mesothelium (specimen)" - }, - { - "code": "399680007", - "display": "Specimen from thyroid (specimen)" - }, - { - "code": "399689008", - "display": "Specimen from thyroid obtained by thyroidectomy (specimen)" - }, - { - "code": "399693002", - "display": "Total parotidectomy sample" - }, - { - "code": "399713008", - "display": "Specimen from uterine cervix obtained by cone biopsy (specimen)" - }, - { - "code": "399728008", - "display": "Specimen from central nervous system obtained by stereotactically guided core needle biopsy (specimen)" - }, - { - "code": "399731009", - "display": "Specimen from anus obtained by excision of anal polyp (specimen)" - }, - { - "code": "399732002", - "display": "Specimen from central nervous system obtained by partial excision of tumor (specimen)" - }, - { - "code": "399735000", - "display": "Specimen from eye obtained by limited exenteration (specimen)" - }, - { - "code": "399741007", - "display": "Specimen from kidney obtained by radical nephrectomy (specimen)" - }, - { - "code": "399747006", - "display": "Specimen from salivary gland (specimen)" - }, - { - "code": "399751008", - "display": "Specimen from uterus obtained by dilation and curettage (specimen)" - }, - { - "code": "399752001", - "display": "Specimen from anus obtained by abdominoperineal resection (specimen)" - }, - { - "code": "404643001", - "display": "Sputum smear specimen (specimen)" - }, - { - "code": "405902005", - "display": "Specimen obtained by radical excision (specimen)" - }, - { - "code": "406101006", - "display": "Tissue specimen from axilla (specimen)" - }, - { - "code": "408654003", - "display": "Specimen obtained by amputation (specimen)" - }, - { - "code": "409821005", - "display": "Timed urine specimen" - }, - { - "code": "409876003", - "display": "Oral mucosal transudate sample" - }, - { - "code": "410580001", - "display": "Respiratory fluid specimen (specimen)" - }, - { - "code": "410581002", - "display": "Upper respiratory fluid sample" - } -] \ No newline at end of file diff --git a/fhir-mapper/src/main/resources/snomed/SnomedVaccine.json b/fhir-mapper/src/main/resources/snomed/SnomedVaccine.json deleted file mode 100644 index 795b77be..00000000 --- a/fhir-mapper/src/main/resources/snomed/SnomedVaccine.json +++ /dev/null @@ -1,754 +0,0 @@ -[ - { - "code": "1119305005", - "display": "COVID-19 antigen vaccine" - }, - { - "code": "1119349007", - "display": "COVID-19 mRNA vaccine" - }, - { - "code": "871761004", - "display": "Rotavirus vaccine" - }, - { - "code": "318351000221106", - "display": "Diphtheria toxoid and acellular pertussis and inactivated poliomyelitis type 1,2, and 3 and tetanus toxoid pediatric vaccine" - }, - { - "code": "1052330009", - "display": "Pneumococcal 10-valent conjugate vaccine" - }, - { - "code": "836498007", - "display": "Mumps orthorubulavirus antigen-containing vaccine product" - }, - { - "code": "871929006", - "display": "Diphtheria and hepatitis B and tetanus vaccine" - }, - { - "code": "2261000221104", - "display": "Influenza A virus subtypes H1N1 and H3N2 and Influenza B virus Victoria and Yamagata lineage antigens only vaccine product" - }, - { - "code": "428601009", - "display": "Paratyphoid vaccine" - }, - { - "code": "836389008", - "display": "Vaccinia virus antigen-containing vaccine product" - }, - { - "code": "871755002", - "display": "Typhoid Vi capsular polysaccharide vaccine" - }, - { - "code": "871732000", - "display": "Rubella vaccine" - }, - { - "code": "836400005", - "display": "Adenovirus antigen-containing vaccine product" - }, - { - "code": "871893003", - "display": "Diphtheria and acellular pertussis and inactivated poliomyelitis and tetanus vaccine" - }, - { - "code": "971000221109", - "display": "Live attenuated typhoid vaccine in oral dose form" - }, - { - "code": "601000221108", - "display": "Bordetella pertussis antigen-containing vaccine product" - }, - { - "code": "1181000221105", - "display": "Influenza vaccine" - }, - { - "code": "871878002", - "display": "Diphtheria and pertussis and poliomyelitis and tetanus vaccine" - }, - { - "code": "2031000221103", - "display": "Adult diphtheria and tetanus toxoids vaccine" - }, - { - "code": "871723002", - "display": "Q fever vaccine" - }, - { - "code": "871826000", - "display": "Diphtheria and tetanus vaccine" - }, - { - "code": "871921009", - "display": "Staphylococcus toxoid vaccine" - }, - { - "code": "836375003", - "display": "Hepatitis A virus antigen-containing vaccine product" - }, - { - "code": "836398006", - "display": "Streptococcus pneumoniae antigen-containing vaccine product" - }, - { - "code": "2181000221101", - "display": "Cholera vaccine in oral dose form" - }, - { - "code": "1031000221108", - "display": "Human poliovirus antigen-containing vaccine product" - }, - { - "code": "860818003", - "display": "Anthrax vaccine" - }, - { - "code": "871887006", - "display": "Diphtheria and Haemophilus influenzae type B and pertussis and poliomyelitis and tetanus vaccine" - }, - { - "code": "871803007", - "display": "Hepatitis A and B vaccine" - }, - { - "code": "836495005", - "display": "Varicella-zoster virus antigen-containing vaccine product" - }, - { - "code": "871717007", - "display": "Yellow fever vaccine" - }, - { - "code": "1111000221101", - "display": "Live attenuated Argentinian haemorrhagic fever vaccine" - }, - { - "code": "1111000221101", - "display": "Live attenuated Argentinian hemorrhagic fever vaccine" - }, - { - "code": "871737006", - "display": "Mumps vaccine" - }, - { - "code": "871890000", - "display": "Diphtheria and Haemophilus influenzae type B and poliomyelitis and tetanus vaccine" - }, - { - "code": "871758000", - "display": "Pertussis vaccine" - }, - { - "code": "871764007", - "display": "Haemophilus influenzae type B vaccine" - }, - { - "code": "2251000221101", - "display": "Live attenuated measles and mumps and rubella and varicella-zoster vaccine" - }, - { - "code": "836403007", - "display": "Tick-borne encephalitis virus antigen-containing vaccine product" - }, - { - "code": "91000221102", - "display": "Inactivated hepatitis A vaccine" - }, - { - "code": "836384003", - "display": "Bacillus anthracis antigen-containing vaccine product" - }, - { - "code": "1121000221106", - "display": "Live attenuated yellow fever vaccine" - }, - { - "code": "1119220001", - "display": "Pneumococcal 23-valent conjugate vaccine" - }, - { - "code": "2191000221103", - "display": "Inactivated rabies vaccine grown in cellular line" - }, - { - "code": "1861000221106", - "display": "BCG (Bacillus Calmette-Guerin) vaccine" - }, - { - "code": "871873006", - "display": "Meningitis A, C, W135 and Y vaccine" - }, - { - "code": "462321000124107", - "display": "Tdap - Low dose diphtheria and low dose acellular pertussis and tetanus vaccine" - }, - { - "code": "319941000221104", - "display": "BCG (Bacillus Calmette-Guerin) vaccine in parenteral dose form" - }, - { - "code": "871750007", - "display": "Hepatitis A pediatric vaccine" - }, - { - "code": "871750007", - "display": "Hepatitis A paediatric vaccine" - }, - { - "code": "871726005", - "display": "Rabies vaccine" - }, - { - "code": "836378001", - "display": "Japanese encephalitis virus antigen-containing vaccine product" - }, - { - "code": "2021000221101", - "display": "Tetanus toxoid vaccine" - }, - { - "code": "840564009", - "display": "Leptospira antigen-containing vaccine product" - }, - { - "code": "840599008", - "display": "Borrelia burgdorferi antigen-containing vaccine product" - }, - { - "code": "1010308001", - "display": "Inactivated whole Hepatitis A HM-175 strain vaccine" - }, - { - "code": "2091000221104", - "display": "Diphtheria and Haemophilus influenza B and acellular pertussis and poliomyelitis and tetanus pediatric vaccine" - }, - { - "code": "836381006", - "display": "Corynebacterium diphtheriae antigen-containing vaccine product" - }, - { - "code": "871891001", - "display": "Diphtheria and hepatitis B and acellular pertussis and inactivated poliomyelitis and tetanus vaccine" - }, - { - "code": "836387005", - "display": "Rotavirus antigen-containing vaccine product" - }, - { - "code": "836368004", - "display": "Bacteria antigen-containing vaccine product" - }, - { - "code": "774618008", - "display": "Diphtheria toxoid and whole cell pertussis and tetanus toxoid adsorbed vaccine" - }, - { - "code": "836393002", - "display": "Rabies lyssavirus antigen-containing vaccine product" - }, - { - "code": "871837004", - "display": "Diphtheria and poliomyelitis and tetanus vaccine" - }, - { - "code": "871738001", - "display": "Live attenuated mumps vaccine" - }, - { - "code": "836402002", - "display": "Live attenuated Mycobacterium bovis antigen-containing vaccine product" - }, - { - "code": "871908002", - "display": "Measles and mumps and rubella and varicella virus vaccine" - }, - { - "code": "991000221105", - "display": "Cholera vaccine" - }, - { - "code": "871721000", - "display": "Ebolavirus antigen only vaccine product" - }, - { - "code": "871876003", - "display": "Diphtheria and acellular pertussis and tetanus vaccine" - }, - { - "code": "2241000221103", - "display": "Live attenuated measles, mumps, and rubella vaccine" - }, - { - "code": "871772009", - "display": "Influenza H1N1 vaccine" - }, - { - "code": "871730008", - "display": "Low dose diphtheria vaccine" - }, - { - "code": "1119254000", - "display": "Pneumococcal 13-valent conjugate vaccine" - }, - { - "code": "911000221103", - "display": "Human papillomavirus vaccine" - }, - { - "code": "318341000221109", - "display": "Diphtheria toxoid and Haemophilus influenzae type B and acellular pertussis and tetanus toxoid pediatric vaccine" - }, - { - "code": "318341000221109", - "display": "Diphtheria toxoid and Haemophilus influenzae type B and acellular pertussis and tetanus toxoid paediatric vaccine" - }, - { - "code": "836390004", - "display": "Salmonella enterica subspecies enterica serovar Typhi antigen-containing vaccine product" - }, - { - "code": "961000221100", - "display": "Typhoid vaccine" - }, - { - "code": "871817003", - "display": "Measles and rubella vaccine" - }, - { - "code": "871766009", - "display": "Live attenuated measles vaccine" - }, - { - "code": "1010689004", - "display": "Haemophilus influenzae type B capsular polysaccharide polyribosylribitol phosphate conjugated to Clostridium tetani toxoid vaccine" - }, - { - "code": "871729003", - "display": "Diphtheria vaccine" - }, - { - "code": "1011000221100", - "display": "Live attenuated cholera vaccine in oral dose form" - }, - { - "code": "871724008", - "display": "Japanese encephalitis virus vaccine" - }, - { - "code": "871871008", - "display": "Meningitis A and C vaccine" - }, - { - "code": "775641005", - "display": "Diphtheria toxoid and tetanus toxoid adsorbed vaccine" - }, - { - "code": "1801000221105", - "display": "Pneumococcal polysaccharide vaccine" - }, - { - "code": "2171000221104", - "display": "Typhoid polysaccharide vaccine in parenteral dose form" - }, - { - "code": "777725002", - "display": "Tetanus toxoid adsorbed vaccine" - }, - { - "code": "2041000221105", - "display": "Haemophilus influenzae type B capsular polysaccharide conjugated vaccine" - }, - { - "code": "871718002", - "display": "Plague vaccine" - }, - { - "code": "409568008", - "display": "Pentavalent (ABCDE) botulinum toxoid vaccine" - }, - { - "code": "121000221105", - "display": "Inactivated hepatitis A and hepatitis B surface antigen vaccine" - }, - { - "code": "840549009", - "display": "Yersinia pestis antigen-containing vaccine product" - }, - { - "code": "871911001", - "display": "Lyme disease vaccine" - }, - { - "code": "871919004", - "display": "Varicella-zoster vaccine" - }, - { - "code": "871806004", - "display": "Haemophilus influenzae type B and Hepatitis B virus antigens only vaccine product" - }, - { - "code": "2001000221108", - "display": "Human papillomavirus 6, 11, 16 and 18 vaccine" - }, - { - "code": "871925000", - "display": "Hepatitis B surface antigen vaccine" - }, - { - "code": "2071000221100", - "display": "Diphtheria toxoid and Haemophilus influenzae type B and whole cell pertussis and tetanus toxoid paediatric vaccine" - }, - { - "code": "2071000221100", - "display": "Diphtheria toxoid and Haemophilus influenzae type B and whole cell pertussis and tetanus toxoid pediatric vaccine" - }, - { - "code": "1052328007", - "display": "Pneumococcal 7-valent conjugate vaccine" - }, - { - "code": "1010313002", - "display": "Live attenuated influenza vaccine" - }, - { - "code": "871765008", - "display": "Measles vaccine" - }, - { - "code": "1119351006", - "display": "Haemophilus influenzae type B and meningitis C and Y vaccine" - }, - { - "code": "836385002", - "display": "Yellow fever virus antigen-containing vaccine product" - }, - { - "code": "871759008", - "display": "Acellular pertussis vaccine" - }, - { - "code": "1001000221103", - "display": "Inactivated cholera vaccine in oral dose form" - }, - { - "code": "871839001", - "display": "Diphtheria and Haemophilus influenzae B and pertussis and tetanus vaccine" - }, - { - "code": "871816007", - "display": "Poliomyelitis and tetanus vaccine" - }, - { - "code": "871742003", - "display": "Tetanus vaccine" - }, - { - "code": "1981000221108", - "display": "Meningococcus serogroup B vaccine" - }, - { - "code": "871916006", - "display": "Meningococcus A, C, W135 and Y capsular oligosaccharide conjugated vaccine" - }, - { - "code": "871883005", - "display": "Diphtheria and acellular pertussis and poliomyelitis and tetanus paediatric vaccine" - }, - { - "code": "871883005", - "display": "Diphtheria and acellular pertussis and poliomyelitis and tetanus pediatric vaccine" - }, - { - "code": "836379009", - "display": "Human papillomavirus antigen-containing vaccine product" - }, - { - "code": "871751006", - "display": "Hepatitis A vaccine" - }, - { - "code": "840563003", - "display": "Dengue virus antigen-containing vaccine product" - }, - { - "code": "871727001", - "display": "Vaccinia virus antigen only vaccine product" - }, - { - "code": "1010310004", - "display": "Live attenuated Oka-Merck strain varicella vaccine" - }, - { - "code": "871897002", - "display": "Rocky Mountain spotted fever vaccine" - }, - { - "code": "1081000221109", - "display": "Live attenuated rotavirus vaccine" - }, - { - "code": "836382004", - "display": "Measles morbillivirus antigen-containing product" - }, - { - "code": "1010322001", - "display": "Live attenuated Oka strain varicella vaccine" - }, - { - "code": "871822003", - "display": "Hepatitis B vaccine" - }, - { - "code": "2221000221107", - "display": "Live attenuated Varicella-zoster vaccine" - }, - { - "code": "1119279002", - "display": "Inactivated whole Influenza H5N1 vaccine" - }, - { - "code": "836388000", - "display": "Rubella virus antigen-containing vaccine product" - }, - { - "code": "871888001", - "display": "Diphtheria and Haemophilus influenza B and acellular pertussis and inactivated poliomyelitis and tetanus vaccine" - }, - { - "code": "1010318006", - "display": "Inactivated whole Hepatitis A GBM strain vaccine" - }, - { - "code": "37146000", - "display": "Typhus vaccine" - }, - { - "code": "1991000221106", - "display": "Human papillomavirus 16 and 18 vaccine" - }, - { - "code": "1061000221102", - "display": "Meningitis polysaccharide vaccine" - }, - { - "code": "871894009", - "display": "Low dose diphtheria and acellular pertussis and inactivated poliomyelitis and tetanus vaccine" - }, - { - "code": "871722007", - "display": "Adenovirus antigen only vaccine product" - }, - { - "code": "871928003", - "display": "Diphtheria and measles and pertussis and poliomyelitis and tetanus vaccine" - }, - { - "code": "871831003", - "display": "Measles and mumps and rubella vaccine" - }, - { - "code": "871804001", - "display": "Hepatitis A and typhoid vaccine" - }, - { - "code": "2211000221102", - "display": "Influenza A virus subtypes H1N1 and H3N2 and influenza B virus Victoria lineage antigens only vaccine product" - }, - { - "code": "1003499009", - "display": "Influenza H5N1 vaccine" - }, - { - "code": "836374004", - "display": "Hepatitis B virus antigen-containing vaccine product" - }, - { - "code": "871768005", - "display": "Influenza vaccine in nasal dose form" - }, - { - "code": "871716003", - "display": "Tularemia vaccine" - }, - { - "code": "871716003", - "display": "Tularaemia vaccine" - }, - { - "code": "871825001", - "display": "Inactivated Japanese encephalitis virus adsorbed vaccine" - }, - { - "code": "871866001", - "display": "Meningitis C vaccine" - }, - { - "code": "836421005", - "display": "Ebolavirus antigen-containing vaccine product" - }, - { - "code": "871895005", - "display": "Diphtheria and Haemophilus influenzae type B and hepatitis B and pertussis and poliomyelitis and tetanus" - }, - { - "code": "921000221108", - "display": "Meningococcus vaccine" - }, - { - "code": "951000221102", - "display": "Meningococcus group C capsular polysaccharide conjugate vaccine" - }, - { - "code": "863950005", - "display": "Bacteria and virus antigens-containing vaccine product" - }, - { - "code": "871740006", - "display": "Inactivated polio vaccine" - }, - { - "code": "2051000221107", - "display": "Adult diphtheria toxoid and acellular pertussis and tetanus toxoid vaccine" - }, - { - "code": "1131000221109", - "display": "Inactivated rabies vaccine" - }, - { - "code": "871725009", - "display": "Inactivated Japanese encephalitis virus vaccine" - }, - { - "code": "836380007", - "display": "Haemophilus influenzae type B antigen-containing vaccine product" - }, - { - "code": "863911006", - "display": "Clostridium tetani antigen-containing vaccine product" - }, - { - "code": "836377006", - "display": "Influenza virus antigen-containing vaccine product" - }, - { - "code": "871918007", - "display": "Rickettsia antigen-containing vaccine product" - }, - { - "code": "1051000221104", - "display": "Live attenuated poliovirus serotypes 1 and 3 vaccine in oral dose form" - }, - { - "code": "2061000221109", - "display": "Diphtheria toxoid and whole cell pertussis and tetanus toxoid paediatric vaccine" - }, - { - "code": "2061000221109", - "display": "Diphtheria toxoid and whole cell pertussis and tetanus toxoid pediatric vaccine" - }, - { - "code": "871719005", - "display": "Tick-borne encephalitis vaccine" - }, - { - "code": "860722004", - "display": "Junin virus antigen-containing product" - }, - { - "code": "871889009", - "display": "Diphtheria and hepatitis B and inactivated poliomyelitis and acellular pertussis vaccine" - }, - { - "code": "865997008", - "display": "Hepatitis A adult vaccine" - }, - { - "code": "871767000", - "display": "Human papillomavirus 9 vaccine" - }, - { - "code": "871739009", - "display": "Human poliovirus antigen only vaccine product" - }, - { - "code": "981000221107", - "display": "Pneumococcal vaccine" - }, - { - "code": "836369007", - "display": "Virus antigen-containing vaccine product" - }, - { - "code": "836401009", - "display": "Neisseria meningitidis antigen-containing vaccine product" - }, - { - "code": "2081000221102", - "display": "Diphtheria toxoid, Haemophilus influenzae B, hepatitis B surface antigen, acellular pertussis and tetanus toxoid paediatric vaccine" - }, - { - "code": "2081000221102", - "display": "Diphtheria toxoid, Haemophilus influenzae B, hepatitis B surface antigen, acellular pertussis and tetanus toxoid pediatric vaccine" - }, - { - "code": "871886002", - "display": "Diphtheria and Haemophilus influenzae type B and hepatitis B and pertussis and tetanus vaccine" - }, - { - "code": "1971000221105", - "display": "Meningococcus A, C, W135 and Y capsular polysaccharide conjugated vaccine" - }, - { - "code": "840551008", - "display": "Francisella tularensis antigen-containing vaccine product" - }, - { - "code": "871875004", - "display": "Diphtheria and pertussis and tetanus vaccine" - }, - { - "code": "871720004", - "display": "Dengue vaccine" - }, - { - "code": "871838009", - "display": "Low dose diphtheria and inactivated poliomyelitis and tetanus vaccine" - }, - { - "code": "836500008", - "display": "Haemophilus influenzae type B and meningitis C vaccine" - }, - { - "code": "836397001", - "display": "Coxiella burnetii antigen-containing vaccine product" - }, - { - "code": "2201000221100", - "display": "Inactivated rabies virus vaccine grown in brain tissue" - }, - { - "code": "2231000221105", - "display": "Live attenuated measles and rubella vaccine" - }, - { - "code": "2101000221107", - "display": "Diphtheria and acellular pertussis and Haemophilus influenzae type B and hepatitis B and poliomyelitis and tetanus pediatric vaccine" - }, - { - "code": "2101000221107", - "display": "Diphtheria and acellular pertussis and Haemophilus influenzae type B and hepatitis B and poliomyelitis and tetanus paediatric vaccine" - }, - { - "code": "871827009", - "display": "Low dose diphtheria and tetanus vaccine" - }, - { - "code": "836383009", - "display": "Vibrio cholerae antigen-containing vaccine product" - } -] \ No newline at end of file From 7d1b425c35ad85d53bdcd5dac1f1c113677b921a Mon Sep 17 00:00:00 2001 From: Venu-Ajitesh Date: Tue, 12 Aug 2025 01:20:23 +0530 Subject: [PATCH 07/12] Remove FHIR submodule --- .gitmodules | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 .gitmodules diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 6e5627bc..00000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "FHIR-Mapper"] - path = FHIR-Mapper - url = https://github.com/VenuAjitesh/FHIR-Mapper.git From 0d5327c9bfbf05f16cf7591270837d9427ee790e Mon Sep 17 00:00:00 2001 From: Venu-Ajitesh Date: Tue, 12 Aug 2025 01:22:47 +0530 Subject: [PATCH 08/12] Squashed 'FHIR-Mapper/' content from commit 805518f git-subtree-dir: FHIR-Mapper git-subtree-split: 805518fbcc3856e57a66f83d1f97b089f1cb9ee5 --- .gitignore | 40 + Dockerfile | 17 + README.md | 581 +++ build.gradle | 69 + docker-compose-fhir.yaml | 17 + fhir-mapper.yaml | 1188 +++++ gradle/wrapper/gradle-wrapper.jar | 0 gradle/wrapper/gradle-wrapper.properties | 6 + gradlew | 0 gradlew.bat | 0 .../FHIR.postman_collection.json | 318 ++ settings.gradle | 2 + .../nha/abdm/fhir/mapper/FHIRApplication.java | 12 + .../java/com/nha/abdm/fhir/mapper/Utils.java | 40 + .../BundleCompositionIdentifier.java | 72 + .../constants/BundleFieldIdentifier.java | 20 + .../common/constants/BundleIdentifier.java | 12 + .../constants/BundleResourceIdentifier.java | 36 + .../common/constants/BundleUrlIdentifier.java | 11 + .../rest/common/constants/ErrorCode.java | 10 + .../constants/ResourceProfileIdentifier.java | 50 + .../constants/SnomedCodeIdentifier.java | 32 + .../constants/WellnessFieldIdentifiers.java | 119 + .../rest/common/helpers/BundleResponse.java | 17 + .../mapper/rest/common/helpers/DateRange.java | 16 + .../rest/common/helpers/DocumentResource.java | 23 + .../rest/common/helpers/ErrorResponse.java | 16 + .../rest/common/helpers/FacadeError.java | 19 + .../common/helpers/FieldErrorsResponse.java | 16 + .../common/helpers/OrganisationResource.java | 18 + .../rest/common/helpers/PatientResource.java | 31 + .../common/helpers/PractitionerResource.java | 19 + .../rest/common/helpers/SnomedResponse.java | 28 + .../helpers/ValidationErrorResponse.java | 18 + .../rest/controller/BundleController.java | 181 + .../rest/controller/SnomedController.java | 45 + .../converter/DiagnosticReportConverter.java | 211 + .../converter/DischargeSummaryConverter.java | 453 ++ .../converter/HealthDocumentConverter.java | 158 + .../rest/converter/ImmunizationConverter.java | 192 + .../converter/OPConsultationConverter.java | 501 +++ .../rest/converter/PrescriptionConverter.java | 197 + .../converter/WellnessRecordConverter.java | 304 ++ .../rest/database/h2/config/DbLoader.java | 144 + .../SnomedConditionProcedureRepo.java | 19 + .../h2/repositories/SnomedDiagnosticRepo.java | 18 + .../h2/repositories/SnomedEncounterRepo.java | 22 + .../h2/repositories/SnomedMedicineRepo.java | 18 + .../repositories/SnomedMedicineRouteRepo.java | 18 + .../repositories/SnomedObservationRepo.java | 18 + .../h2/repositories/SnomedSpecimenRepo.java | 18 + .../h2/repositories/SnomedVaccineRepo.java | 18 + .../database/h2/services/Displayable.java | 6 + .../database/h2/services/SnomedService.java | 270 ++ .../h2/tables/SnomedConditionProcedure.java | 27 + .../database/h2/tables/SnomedDiagnostic.java | 26 + .../database/h2/tables/SnomedEncounter.java | 26 + .../database/h2/tables/SnomedMedicine.java | 26 + .../h2/tables/SnomedMedicineRoute.java | 26 + .../database/h2/tables/SnomedObservation.java | 26 + .../database/h2/tables/SnomedSpecimen.java | 26 + .../database/h2/tables/SnomedVaccine.java | 26 + .../MakeDiagnosticComposition.java | 91 + .../MakeDischargeComposition.java | 302 ++ .../MakeHealthDocumentComposition.java | 83 + .../MakeImmunizationComposition.java | 94 + .../dto/compositions/MakeOpComposition.java | 336 ++ .../MakePrescriptionComposition.java | 99 + .../compositions/MakeWellnessComposition.java | 185 + .../MakeAllergyToleranceResource.java | 64 + .../dto/resources/MakeBundleMetaResource.java | 27 + .../dto/resources/MakeCarePlanResource.java | 63 + .../dto/resources/MakeConditionResource.java | 55 + .../resources/MakeDiagnosticLabResource.java | 98 + .../dto/resources/MakeDocumentResource.java | 65 + .../dto/resources/MakeEncounterResource.java | 46 + .../resources/MakeFamilyMemberResource.java | 64 + .../resources/MakeImmunizationResource.java | 90 + .../MakeMedicationRequestResource.java | 137 + .../resources/MakeObservationResource.java | 74 + .../resources/MakeOrganisationResource.java | 51 + .../dto/resources/MakePatientResource.java | 49 + .../resources/MakePractitionerResource.java | 44 + .../dto/resources/MakeProcedureResource.java | 68 + .../resources/MakeServiceRequestResource.java | 82 + .../MakeWellnessObservationResource.java | 80 + .../exceptions/GlobalExceptionHandler.java | 124 + .../rest/exceptions/NotBlankFields.java | 20 + .../exceptions/NotBlankFieldsValidator.java | 49 + .../mapper/rest/exceptions/StreamUtils.java | 29 + .../requests/DiagnosticReportRequest.java | 47 + .../requests/DischargeSummaryRequest.java | 58 + .../rest/requests/HealthDocumentRecord.java | 46 + .../rest/requests/ImmunizationRequest.java | 50 + .../rest/requests/OPConsultationRequest.java | 60 + .../rest/requests/PrescriptionRequest.java | 51 + .../rest/requests/WellnessRecordRequest.java | 57 + .../requests/helpers/CarePlanResource.java | 24 + .../helpers/ChiefComplaintResource.java | 23 + .../helpers/DiagnosticPresentedForm.java | 20 + .../requests/helpers/DiagnosticResource.java | 38 + .../helpers/FamilyObservationResource.java | 18 + .../requests/helpers/FollowupResource.java | 19 + .../helpers/ImmunizationResource.java | 28 + .../requests/helpers/ObservationResource.java | 22 + .../helpers/PrescriptionResource.java | 32 + .../requests/helpers/ProcedureResource.java | 29 + .../helpers/ServiceRequestResource.java | 22 + .../helpers/ValueQuantityResource.java | 16 + .../helpers/WellnessObservationResource.java | 22 + src/main/resources/application.properties | 24 + src/main/resources/banner.txt | 9 + .../snomed/SnomedConditionProcedure.json | 2638 +++++++++++ .../resources/snomed/SnomedDiagnostic.json | 66 + .../resources/snomed/SnomedEncounter.json | 222 + src/main/resources/snomed/SnomedMedicine.json | 418 ++ .../resources/snomed/SnomedMedicineRoute.json | 385 ++ .../resources/snomed/SnomedObservation.json | 302 ++ src/main/resources/snomed/SnomedSpecimen.json | 3998 +++++++++++++++++ src/main/resources/snomed/SnomedVaccine.json | 754 ++++ 120 files changed, 17960 insertions(+) create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 README.md create mode 100644 build.gradle create mode 100644 docker-compose-fhir.yaml create mode 100644 fhir-mapper.yaml create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100644 gradlew create mode 100644 gradlew.bat create mode 100644 postmanCollection/FHIR.postman_collection.json create mode 100644 settings.gradle create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/FHIRApplication.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/Utils.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/BundleCompositionIdentifier.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/BundleFieldIdentifier.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/BundleIdentifier.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/BundleResourceIdentifier.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/BundleUrlIdentifier.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/ErrorCode.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/ResourceProfileIdentifier.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/SnomedCodeIdentifier.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/WellnessFieldIdentifiers.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/BundleResponse.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/DateRange.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/DocumentResource.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/ErrorResponse.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/FacadeError.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/FieldErrorsResponse.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/OrganisationResource.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/PatientResource.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/PractitionerResource.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/SnomedResponse.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/ValidationErrorResponse.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/controller/BundleController.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/controller/SnomedController.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/converter/DiagnosticReportConverter.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/converter/DischargeSummaryConverter.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/converter/HealthDocumentConverter.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/converter/ImmunizationConverter.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/converter/OPConsultationConverter.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/converter/PrescriptionConverter.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/converter/WellnessRecordConverter.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/config/DbLoader.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedConditionProcedureRepo.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedDiagnosticRepo.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedEncounterRepo.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedMedicineRepo.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedMedicineRouteRepo.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedObservationRepo.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedSpecimenRepo.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedVaccineRepo.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/services/Displayable.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/services/SnomedService.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedConditionProcedure.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedDiagnostic.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedEncounter.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedMedicine.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedMedicineRoute.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedObservation.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedSpecimen.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedVaccine.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeDiagnosticComposition.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeDischargeComposition.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeHealthDocumentComposition.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeImmunizationComposition.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeOpComposition.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakePrescriptionComposition.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeWellnessComposition.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeAllergyToleranceResource.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeBundleMetaResource.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeCarePlanResource.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeConditionResource.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeDiagnosticLabResource.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeDocumentResource.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeEncounterResource.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeFamilyMemberResource.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeImmunizationResource.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeMedicationRequestResource.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeObservationResource.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeOrganisationResource.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakePatientResource.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakePractitionerResource.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeProcedureResource.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeServiceRequestResource.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeWellnessObservationResource.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/exceptions/GlobalExceptionHandler.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/exceptions/NotBlankFields.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/exceptions/NotBlankFieldsValidator.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/exceptions/StreamUtils.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/requests/DiagnosticReportRequest.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/requests/DischargeSummaryRequest.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/requests/HealthDocumentRecord.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/requests/ImmunizationRequest.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/requests/OPConsultationRequest.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/requests/PrescriptionRequest.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/requests/WellnessRecordRequest.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/CarePlanResource.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ChiefComplaintResource.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/DiagnosticPresentedForm.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/DiagnosticResource.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/FamilyObservationResource.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/FollowupResource.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ImmunizationResource.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ObservationResource.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/PrescriptionResource.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ProcedureResource.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ServiceRequestResource.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ValueQuantityResource.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/WellnessObservationResource.java create mode 100644 src/main/resources/application.properties create mode 100644 src/main/resources/banner.txt create mode 100644 src/main/resources/snomed/SnomedConditionProcedure.json create mode 100644 src/main/resources/snomed/SnomedDiagnostic.json create mode 100644 src/main/resources/snomed/SnomedEncounter.json create mode 100644 src/main/resources/snomed/SnomedMedicine.json create mode 100644 src/main/resources/snomed/SnomedMedicineRoute.json create mode 100644 src/main/resources/snomed/SnomedObservation.json create mode 100644 src/main/resources/snomed/SnomedSpecimen.json create mode 100644 src/main/resources/snomed/SnomedVaccine.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..d784edfa --- /dev/null +++ b/.gitignore @@ -0,0 +1,40 @@ +build +.gradle + +### IntelliJ IDEA ### +.idea/ +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..21d72851 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,17 @@ +FROM gradle:8.5-jdk17 AS builder +WORKDIR /app + +COPY build.gradle settings.gradle ./ +RUN gradle dependencies --no-daemon + +COPY . . +RUN gradle build --no-daemon -x test + +FROM eclipse-temurin:17-jdk-focal +WORKDIR /app + +COPY --from=builder /app/build/libs/*-SNAPSHOT.jar fhir.jar + +EXPOSE 8085 + +ENTRYPOINT ["java", "-jar", "fhir.jar"] diff --git a/README.md b/README.md new file mode 100644 index 00000000..d03090f8 --- /dev/null +++ b/README.md @@ -0,0 +1,581 @@ +# ABDM FHIR Mapper - FHIR (HL7® FHIR® Standard) R4 +- The purpose of this implementation guide is to provide essential and minimum health record artefacts that can be captured and created as per ABDM Health Data Interchange Specifications 1.0. +- This module is built using **hapi fhir library** for generating the fhir resources. +- For better understanding of FHIR, check [here](https://nrces.in/ndhm/fhir/r4/index.html) + +### 1. System Requirements and Installations: +There are two ways to get fhir-mapper application running on your system: +#### 1. Using docker (Preferred): This is an easy way to get wrapper up and running. +Install docker and docker-compose: You can install docker desktop from [here](https://www.docker.com/products/docker-desktop/) to get both. + +System Requirements: +- For Mac, check [here](https://docs.docker.com/desktop/install/mac-install/) +- For Windows, check [here](https://docs.docker.com/desktop/install/windows-install/) +- For Linux, check [here](https://docs.docker.com/desktop/install/linux-install/) + +Using docker-compose-fhir.yaml to bring up the server. + +#### 2. If you are facing issues with installing or running docker, then you can install individual components: +- Install jdk 17. Instructions can be found [here](https://www3.cs.stonybrook.edu/~amione/CSE114_Course/materials/resources/InstallingJava17.pdf) +- Install gradle from [here](https://gradle.org/install/) + +System Requirements: +- For Java17, you can check [here](https://www.oracle.com/java/technologies/javase/products-doc-jdk17certconfig.html) for compatible system configurations. +- Gradle version >= 8.5 should be fine. + +Recommended RAM: Systems with more than 8 GB RAM +### Bringing up the application +- If you have installed docker and docker compose then you can bring the application using: `docker compose -f docker-compose-fhir.yaml up --build` +* If you have chosen to install Java and gradle components, then here is how you can bring the service up: + - Go to root of this repository and start fhir-mapper by running `gradle bootrun` +- Using any of the above approaches the server will be running on port `8085` + +### ABDM PROFILES (HI-Types) +- The HI type is primarily defined based on the data being collected. However the type of interaction should also be considered. +- If the data which is collected is not defined in the structured field for any HI-type you can create a pdf and attach to the particular bundle in the documents. + +| Name | Definition | +|-------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------| +| DiagnosticReportRecord | The Clinical Artifact represents diagnostic reports including Radiology and Laboratory reports that can be shared across the health ecosystem. | +| DischargeSummaryRecord | Clinical document used to represent the discharge summary record for ABDM HDE data set. | +| HealthDocumentRecord | The Clinical Artifact represents the unstructured historical health records as a single or multiple Health Record Documents generally uploaded by the patients through the Health Locker and can be shared across the health ecosystem. | +| ImmunizationRecord | The Clinical Artifact represents the Immunization records with any additional documents such as vaccine certificate, the next immunization recommendations, etc. This can be further shared across the health ecosystem. | +| OPConsultRecord | The Clinical Artifact represents the outpatient visit consultation note which may include clinical information on any OP examinations, procedures along with medication administered, and advice that can be shared across the health ecosystem. | +| PrescriptionRecord | The Clinical Artifact represents the medication advice to the patient in compliance with the Pharmacy Council of India (PCI) guidelines, which can be shared across the health ecosystem. | +| WellnessRecord | The Clinical Artifact represents regular wellness information of patients typically through the Patient Health Record (PHR) application covering clinical information such as vitals, physical examination, general wellness, women wellness, etc., that can be shared across the health ecosystem. | + +### APIs for generating the FHIR bundle +- For Swagger-ui, check [here](https://wrapper-sbx.abdm.gov.in/swagger/fhir) +#### DiagnosticReportRecord +- for the DiagnosticReportRecord bundle you need to + * `POST` Request `/v1/bundle/diagnostic-report` + ``` + { + "bundleType":"DiagnosticReportRecord", //mandatory + "careContextReference":"visist 21-03-2024", //mandatory + "authoredOn":"2006-04-22", //mandatory + "patient":{ //mandatory + "name":"Venu Ajitesh", //mandatory + "patientReference":"ajitesh6x", //mandatory + "gender":"male", + "birthDate":"2001-04-27" + }, + "practitioners":[{ //mandatory + "name":"Dr.Venu Ajitesh", //mandatory + "practitionerId":"Predator" + }], + "organisation":{ + "facilityName":"Predator_HIP", //mandatory + "facilityId":"Predator_HIP" + }, + "encounter":"Ambula", + "diagnostics":[{ + "serviceName":"BloodTest", //mandatory + "serviceCategory":"Hematography", //mandatory + "result":[{ //you can pass either result or valueQuantity not both + "observation":"Height", //mandatory + "result":"Normal", + "valueQuantity": { + "unit": "CM", + "value": 170 + } + }], + "conclusion":"Normal", //mandatory + "presentedForm":{ + "contentType":"application/pdf", + "data":"Base64 data of the pdf" + } + }], + "documents":[{ + "type":"diagnosticReport", //mandatory + "contentType":"application/pdf", //mandatory + "data":"Base64 data of the pdf" //mandatory + }] + } + ``` +#### DischargeSummaryRecord + - for the DischargeSummaryRecord bundle you need to + * `POST` Request `/v1/bundle/discharge-summary` + ``` + { + "bundleType":"DischargeSummaryRecord", //mandatory + "careContextReference":"visist 21-03-2024", //mandatory + "patient":{ //mandatory + "name":"Venu Ajitesh", //mandatory + "patientReference":"ajitesh6x", //mandatory + "gender":"male", + "birthDate":"2001-04-27" + }, + "practitioners":[{ //mandatory + "name":"Dr.Venu Ajitesh", //mandatory + "practitionerId":"Predator" + }], + "organisation":{ //mandatory + "facilityName":"Predator_HIP", //mandatory + "facilityId":"Predator_HIP" + }, + "chiefComplaints":[ + { + "complaint":"Sugar", //mandatory + "recordedDate":"2024-05-20", //mandatory + "dateRange":{ + "from":"2018-04-27", + "to":"2018-05-26" + } + } + ], + "physicalExaminations":[ + { + "observation":"Height", //mandatory + "result":"Normal", //you can pass either result or valueQuantity not both + "valueQuantity": { + "unit": "CM", + "value": 170 + } + } + ], + "allergies":[ + "Walnuts" + ], + "medicalHistories":[ + { + "complaint":"Sugar", //mandatory + "recordedDate":"2024-05-20", //mandatory + "dateRange":{ + "from":"2018-04-27", + "to":"2018-05-26" + } + } + ], + "familyHistories":[ + { + "relationship":"Friend", //mandatory + "observation":"Toxic" //mandatory + } + ], + "authoredOn":"2024-02-03", //mandatory + "medications":[ + { + "medicine":"Aspirin 75 mg oral tablet", //mandatory + "dosage":"1-0-1", //mandatory + "timing":"2-5-d", + "route":"Oral", + "method":"swallow", + "additionalInstructions":"Take them after food", + "reason": "fever" + } + ,{ + "medicine":"Disprin", //mandatory + "dosage":"0-0-1", //mandatory + "timing":"1-2-d", + "route":"Syrup", + "method":"drink", + "additionalInstructions":"Take them before food", + "reason": "Cough" + } + ], + "diagnostics":[{ + "serviceName":"BloodTest", //mandatory + "serviceCategory":"Hematography", //mandatory + "result":[{ + "observation":"Height", //mandatory + "result":"Normal", //you can pass either result or valueQuantity not both + "valueQuantity": { + "unit": "CM", + "value": 170 + } + }], + "conclusion":"Normal", //mandatory + "presentedForm":{ + "contentType":"application/pdf", + "data":"Base64 data of the pdf" + } + }], + + "procedures":[ + { + "date":"2001-04-20", //mandatory + "status":"INPROGRESS", //mandatory + "procedureReason":"Severe", //mandatory + "outcome":"Healthy", + "procedureName":"Operation" //mandatory + } + ], + + "documents":[{ + "type":"Discharge record", //mandatory + "contentType":"application/pdf", //mandatory + "data":"Base64 data of the pdf" //mandatory + }] + } + ``` +#### HealthDocumentRecord +- for the HealthDocumentRecord bundle you need to + * `POST` Request `/v1/bundle/health-document` + ``` + { + "bundleType":"HealthDocumentRecord", //mandatory + "careContextReference":"visist 21-03-2024", //mandatory + "patient":{ //mandatory + "name":"Venu Ajitesh", //mandatory + "patientReference":"ajitesh6x", //mandatory + "gender":"male", + "birthDate":"2001-04-27" + }, + "authoredOn":"2001-04-27", //mandatory + "practitioners":[{ //mandatory + "name":"Dr.Venu Ajitesh", //mandatory + "practitionerId":"Predator" + }], + "organisation":{ + "facilityName":"Predator_HIP", //mandatory + "facilityId":"Predator_HIP" + }, + "encounter":"", + "documents":[{ + "type":"health-document", //mandatory + "contentType":"application/pdf", //mandatory + "data":"Base64 data of the pdf" //mandatory + }] + } + ``` +#### ImmunizationRecord +- for the ImmunizationRecord bundle you need to + * `POST` Request `/v1/bundle/immunization` + ``` + { + "bundleType":"ImmunizationRecord", //mandatory + "careContextReference":"visit-{{$isoTimestamp}}", //mandatory + "authoredOn":"2022-02-14", //mandatory + "patient":{ //mandatory + "name":"Venu Ajitesh", //mandatory + "patientReference":"ajitesh6x", //mandatory + "gender":"male", + "birthDate":"2001-04-27" + }, + "practitioners":[{ //mandatory + "name":"Dr.Venu Ajitesh", //mandatory + "practitionerId":"Predator" + }], + "organisation":{ + "facilityName":"Predator_HIP", //mandatory + "facilityId":"Predator_HIP" + }, + "immunizations":[{ //mandatory + "date":"2024-06-15", //mandatory + "vaccineName":"Covaxin", //mandatory + "lotNumber":"IN00004", + "manufacturer":"NHA", + "doseNumber":"3" + }], + "documents":[{ + "type":"immunization", //mandatory + "contentType":"application/pdf", //mandatory + "data":"Base64 data of the pdf" //mandatory + }] + } + ``` +#### OPConsultRecord +- for the OPConsultRecord bundle you need to + * `POST` Request `/v1/bundle/op-consultation` + ``` + { + "bundleType":"OPConsultRecord", //mandatory + "careContextReference":"visist 21-03-2025", //mandatory + "visitDate":"2000-06-23", //mandatory + "patient":{ //mandatory + "name":"Venu Ajitesh", //mandatory + "patientReference":"ajitesh6x", //mandatory + "gender":"male", + "birthDate":"2001-04-27" + }, + "practitioners":[{ //mandatory + "name":"Dr.Venu Ajitesh", //mandatory + "practitionerId":"Predator" + }], + "organisation":{ + "facilityName":"Predator_HIP", //mandatory + "facilityId":"Predator_HIP" + }, + "chiefComplaints":[ + { + "complaint":"Sugar", //mandatory + "recordedDate":"2024-05-20", //mandatory + "dateRange":{ + "from":"2018-04-27", + "to":"2018-05-26" + } + } + ], + "physicalExaminations":[ + { + "observation":"Height", //mandatory + "result":"Normal", //you can pass either result or valueQuantity not both + "valueQuantity": { + "unit": "CM", + "value": 170 + } + } + ], + "allergies":[ + "Walnuts" + ], + "medicalHistories":[ + { + "complaint":"Sugar", //mandatory + "recordedDate":"2024-05-20", //mandatory + "dateRange":{ + "from":"2018-04-27", + "to":"2018-05-26" + } + } + ], + "familyHistories":[ + { + "relationship":"Friend", //mandatory + "observation":"Toxic" //mandatory + } + ], + "serviceRequests":[ + { + "status":"ACTIVE", //mandatory + "details":"X-RAY", //mandatory + "specimen":"Jhonsons" + } + ], + "medications":[ + { + "medicine":"Aspirin 75 mg oral tablet", //mandatory + "dosage":"1-0-1", //mandatory + "timing":"2-5-d", + "route":"Oral", + "method":"swallow", + "additionalInstructions":"Take them after food", + "reason": "fever" + } + ,{ + "medicine":"Disprin", //mandatory + "dosage":"0-0-1", //mandatory + "timing":"1-2-d", + "route":"Syrup", + "method":"drink", + "additionalInstructions":"Take them before food", + "reason": "Cough" + } + ], + "followups":[ + { + "serviceType":"OPConsultation", //mandatory + "appointmentTime":"2024-05-20", //mandatory + "reason":"General" //mandatory + } + ], + "procedures":[ + { + "date":"2001-04-20", //mandatory + "status":"INPROGRESS", //mandatory + "procedureReason":"Severe", //mandatory + "outcome":"Healthy", + "procedureName":"Operation" //mandatory + } + ], + "referrals":[ + { + "status":"ACTIVE", //mandatory + "details":"Y-RAY", //mandatory + "specimen":"Rock" //mandatory + } + ], + "otherObservations":[ + { + "observation":"weight", //mandatory + "result":"Over weight", //you can pass either result or valueQuantity not both + "valueQuantity": { + "unit": "KG", + "value": 90 + } + } + ], + "documents":[{ + "type":"OP record", //mandatory + "contentType":"application/pdf", //mandatory + "data":"Base64 data of the pdf" //mandatory + }] + } + ``` +#### PrescriptionRecord +- for the PrescriptionRecord bundle you need to + * `POST` Request `/v1/bundle/prescription` + ``` + { + "bundleType":"PrescriptionRecord", //mandatory + "careContextReference":"visit-{{$isoTimestamp}}", //mandatory + "authoredOn":"2001-05-22", //mandatory + "encounter":"", + "patient":{ //mandatory + "name":"Venu Ajitesh", //mandatory + "patientReference":"ajitesh6x", //mandatory + "gender":"male", + "birthDate":"2001-04-27" + }, + "practitioners":[{ //mandatory + "name":"Dr.Venu Ajitesh", //mandatory + "practitionerId":"Predator" + }], + "organisation":{ + "facilityName":"Predator_HIP", //mandatory + "facilityId":"Predator_HIP" + }, + "prescriptions":[ + { + "medicine":"Aspirin 75 mg oral tablet", //mandatory + "dosage":"1-0-1", //mandatory + "timing":"2-5-d", + "route":"Oral", + "method":"swallow", + "additionalInstructions":"Take them after food", + "reason": "fever" + } + ,{ + "medicine":"Disprin", //mandatory + "dosage":"0-0-1", //mandatory + "timing":"1-2-d", + "route":"Syrup", + "method":"drink", + "additionalInstructions":"Take them before food", + "reason": "Cough" + } + ], + "documents":[{ + "type":"Prescription", //mandatory + "contentType":"application/pdf", //mandatory + "data":"Base64 data of the pdf" //mandatory + }] + } + ``` +#### WellnessRecord +- for the WellnessRecord bundle you need to + * `POST` Request `/v1/bundle/wellness-record` + ``` + { + "bundleType":"WellnessRecord", //mandatory + "careContextReference":"visist 21-03-2025", //mandatory + "authoredOn":"2024-02-11", //mandatory + "patient":{ //mandatory + "name":"Venu Ajitesh", //mandatory + "patientReference":"ajitesh6x", //mandatory + "gender":"male", + "birthDate":"2001-04-27" + }, + "practitioners":[{ //mandatory + "name":"Dr.Venu Ajitesh", //mandatory + "practitionerId":"Predator" + }], + "organisation":{ + "facilityName":"Predator_HIP", //mandatory + "facilityId":"Predator_HIP" + }, + "vitalSigns":[ + { + "observation":"Height", //mandatory + "result":"Normal", //you can pass either result or valueQuantity not both + "valueQuantity": { + "unit": "CM", + "value": 170 + } + } + ], + "bodyMeasurements":[ + { + "observation":"Height", //mandatory + "result":"Normal", //you can pass either result or valueQuantity not both + "valueQuantity": { + "unit": "CM", + "value": 170 + } + } + ], + "physicalActivities":[ + { + "observation":"Height", //mandatory + "result":"Normal", //you can pass either result or valueQuantity not both + "valueQuantity": { + "unit": "CM", + "value": 170 + } + } + ], + "generalAssessments":[ + { + "observation":"Height", //mandatory + "result":"Normal", //you can pass either result or valueQuantity not both + "valueQuantity": { + "unit": "CM", + "value": 170 + } + } + ],"womanHealths":[ + { + "observation":"Height", //mandatory + "result":"Normal", //you can pass either result or valueQuantity not both + "valueQuantity": { + "unit": "CM", + "value": 170 + } + } + ], + "lifeStyles":[ + { + "observation":"Height", //mandatory + "result":"Normal", //you can pass either result or valueQuantity not both + "valueQuantity": { + "unit": "CM", + "value": 170 + } + } + ], + "otherObservations":[ + { + "observation":"Height", //mandatory + "result":"Normal", //you can pass either result or valueQuantity not both + "valueQuantity": { + "unit": "CM", + "value": 170 + } + } + ], + "documents":[{ + "type":"Wellness record", //mandatory + "contentType":"application/pdf", //mandatory + "data":"Base64 data of the pdf" //mandatory + }] + } + ``` +#### Error response in 400 BadRequest +- There are two kinds of error + * Validation errors : The errors are thrown when mandatory fields are missing + ``` + { + "validationErrors": { + "code": 1000, + "error": [ + { + "field": "bundleType", + "message": "must match \"WellnessRecord\"" + } + ] + } + } + ``` + * Errors while creating the FHIR bundle + ``` + { + "error":{ + "code":1000, + "message":"Unable to parse date" + } + } + ``` +### Things To Consider +- If the FHIR bundle is generated the HttpStatus will be `201 created` +- The authoredOn will accept date in the format of string in format : `yyyy-MM-dd` or `yyyy-MM-dd'T'HH:mm:ss.SSSX` - UTC iso time format \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 00000000..f276331e --- /dev/null +++ b/build.gradle @@ -0,0 +1,69 @@ +plugins { + id 'java' + id 'org.springframework.boot' version '3.2.0' + id 'io.spring.dependency-management' version '1.0.11.RELEASE' + id 'org.openapi.generator' version '6.6.0' + id 'com.diffplug.spotless' version '6.25.0' +} + +group = 'com.nha.abdm.fhir.wrapper' +version = '1.0-SNAPSHOT' +subprojects { + spotless { + java { + googleJavaFormat('1.15.0') + indentWithTabs(2) + indentWithSpaces(4) + } + } +} +afterEvaluate { + def spotless = tasks.findByName('spotlessApply') + if (spotless) { + tasks.withType(JavaCompile) { + finalizedBy(spotless) + + } + + tasks.withType(GroovyCompile) { + finalizedBy(spotless) + } + } +} + +repositories { + mavenCentral() +} + +dependencies { + implementation 'org.springframework.boot:spring-boot-starter' + implementation 'org.springframework.boot:spring-boot-starter-web' + testImplementation 'org.springframework.boot:spring-boot-starter-test' + implementation 'org.springframework.boot:spring-boot-starter-validation' + compileOnly group: 'org.projectlombok', name: 'lombok', version: '1.18.30' + annotationProcessor 'org.projectlombok:lombok:1.18.30' + implementation 'ca.uhn.hapi.fhir:hapi-fhir-base:5.6.1' + implementation 'ca.uhn.hapi.fhir:hapi-fhir-structures-r4:5.5.0' + testImplementation 'org.mockito:mockito-core:5.13.0' + testImplementation platform('org.junit:junit-bom:5.9.1') + testImplementation 'org.junit.jupiter:junit-jupiter' + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + implementation 'org.postgresql:postgresql:42.7.2' + implementation 'com.h2database:h2' + implementation 'org.apache.commons:commons-text:1.10.0' +} +spotless { + java { + // Use the default importOrder configuration + importOrder() + + removeUnusedImports() + + // Choose one of these formatters. + googleJavaFormat() // has its own section below + + formatAnnotations() // fixes formatting of type annotations, see below + + licenseHeader '/* (C) $YEAR */' // or licenseHeaderFile + } +} diff --git a/docker-compose-fhir.yaml b/docker-compose-fhir.yaml new file mode 100644 index 00000000..150f5982 --- /dev/null +++ b/docker-compose-fhir.yaml @@ -0,0 +1,17 @@ +version: '3.8' +services: + fhir-mapper: + build: + context: . + dockerfile: Dockerfile + image: fhir-mapper + ports: + - '8085:8085' + networks: + - docker_network + extra_hosts: + - "host.docker.internal:host-gateway" + +networks: + docker_network: + driver: bridge \ No newline at end of file diff --git a/fhir-mapper.yaml b/fhir-mapper.yaml new file mode 100644 index 00000000..bda9b9a0 --- /dev/null +++ b/fhir-mapper.yaml @@ -0,0 +1,1188 @@ +openapi: 3.0.3 +info: + title: FHIR Mapper API's + description: Conversion of simple json to ABDM compliant FHIR Format bundles + version: 1.0.0 +servers: + - url: http://localhost:8085/v1/bundle + +paths: + /op-consultation: + post: + tags: + - HI Types + summary: Create an OP Consultation Record + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/OPConsultRecord' + responses: + '201': + description: Successfully created + '400': + description: Bad Request + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/ValidationErrorResponse' + - $ref: '#/components/schemas/GenericErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericErrorResponse' + /prescription: + post: + tags: + - HI Types + summary: Create a Prescription Record + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/PrescriptionRecord' + responses: + '201': + description: Successfully created + '400': + description: Bad Request + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/ValidationErrorResponse' + - $ref: '#/components/schemas/GenericErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericErrorResponse' + /health-document: + post: + tags: + - HI Types + summary: Create a Health Document Record + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/HealthDocumentRecord' + responses: + '201': + description: Successfully created + '400': + description: Bad Request + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/ValidationErrorResponse' + - $ref: '#/components/schemas/GenericErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericErrorResponse' + /diagnostic-report: + post: + tags: + - HI Types + summary: Create a Diagnostic Report + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/DiagnosticReport' + responses: + '201': + description: Successfully created + '400': + description: Bad Request + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/ValidationErrorResponse' + - $ref: '#/components/schemas/GenericErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericErrorResponse' + /immunization: + post: + tags: + - HI Types + summary: Create an Immunization Record + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ImmunizationRecord' + responses: + '201': + description: Successfully created + '400': + description: Bad Request + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/ValidationErrorResponse' + - $ref: '#/components/schemas/GenericErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericErrorResponse' + /discharge-summary: + post: + tags: + - HI Types + summary: Create a Discharge Summary + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/DischargeSummary' + responses: + '201': + description: Successfully created + '400': + description: Bad Request + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/ValidationErrorResponse' + - $ref: '#/components/schemas/GenericErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericErrorResponse' + /wellness-record: + post: + tags: + - HI Types + summary: Create a Wellness Record + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/WellnessRecord' + responses: + '201': + description: Successfully created + '400': + description: Bad Request + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/ValidationErrorResponse' + - $ref: '#/components/schemas/GenericErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericErrorResponse' + +components: + schemas: + OPConsultRecord: + type: object + properties: + bundleType: + type: string + enum: + - OPConsultRecord + careContextReference: + type: string + example: visit 21-03-2025 + visitDate: + type: string + format: date + example: 2000-06-23 + patient: + $ref: '#/components/schemas/Patient' + practitioners: + type: array + items: + $ref: '#/components/schemas/Practitioner' + organisation: + $ref: '#/components/schemas/Organisation' + chiefComplaints: + type: array + items: + $ref: '#/components/schemas/ChiefComplaint' + physicalExaminations: + type: array + items: + $ref: '#/components/schemas/PhysicalExamination' + allergies: + type: array + items: + type: string + medicalHistories: + type: array + items: + $ref: '#/components/schemas/ChiefComplaint' + familyHistories: + type: array + items: + $ref: '#/components/schemas/FamilyHistory' + serviceRequests: + type: array + items: + $ref: '#/components/schemas/ServiceRequest' + medications: + type: array + items: + $ref: '#/components/schemas/Medication' + followups: + type: array + items: + $ref: '#/components/schemas/FollowUp' + procedures: + type: array + items: + $ref: '#/components/schemas/Procedure' + referrals: + type: array + items: + $ref: '#/components/schemas/Referral' + otherObservations: + type: array + items: + $ref: '#/components/schemas/OtherObservation' + documents: + type: array + items: + $ref: '#/components/schemas/Document' + required: + - bundleType + - patient + - practitioners + - careContextReference + - authoredOn + PrescriptionRecord: + type: object + properties: + bundleType: + type: string + enum: + - PrescriptionRecord + careContextReference: + type: string + example: visit-{{$isoTimestamp}} + authoredOn: + type: string + format: date + example: 2001-05-22 + encounter: + type: string + example: "" + patient: + $ref: '#/components/schemas/Patient' + practitioners: + type: array + items: + $ref: '#/components/schemas/Practitioner' + organisation: + $ref: '#/components/schemas/Organisation' + prescriptions: + type: array + items: + $ref: '#/components/schemas/Medication' + documents: + type: array + items: + $ref: '#/components/schemas/Document' + required: + - bundleType + - patient + - practitioners + - careContextReference + - authoredOn + - prescriptions + example: + bundleType: PrescriptionRecord + careContextReference: visit-{{$isoTimestamp}} + authoredOn: 2001-05-22 + encounter: "" + patient: + name: Venu Ajitesh + patientReference: ajitesh6x + gender: male + birthDate: 2001-04-27 + practitioners: + - name: Dr.Venu Ajitesh + practitionerId: Predator + organisation: + facilityName: Predator_HIP + facilityId: Predator_HIP + prescriptions: + - medicine: Dolo + dosage: 1-0-1 + timing: 1-1-D + route: Oral + method: swallow + additionalInstructions: Take them after food + reason: Fever + documents: + - type: Prescription + contentType: application/pdf + data: JVBERi0xLjMKJf////8K + HealthDocumentRecord: + type: object + properties: + bundleType: + type: string + enum: + - HealthDocumentRecord + careContextReference: + type: string + example: visist 21-03-2024 + patient: + $ref: '#/components/schemas/Patient' + authoredOn: + type: string + format: date + example: 2001-04-27 + practitioners: + type: array + items: + $ref: '#/components/schemas/Practitioner' + organisation: + $ref: '#/components/schemas/Organisation' + encounter: + type: string + example: "" + documents: + type: array + items: + $ref: '#/components/schemas/Document' + required: + - bundleType + - patient + - practitioners + - careContextReference + - authoredOn + - documents + example: + bundleType: HealthDocumentRecord + careContextReference: visist 21-03-2024 + patient: + name: Venu Ajitesh + patientReference: ajitesh6x + gender: male + birthDate: 2001-04-27 + date: 2001-04-27 + practitioners: + - name: Dr.Venu Ajitesh + practitionerId: Predator + organisation: + facilityName: Predator_HIP + facilityId: Predator_HIP + encounter: "" + documents: + - contentType: application/pdf + data: xyzadybcljbabvlalbfdbvubujzbj + DiagnosticReport: + type: object + properties: + bundleType: + type: string + enum: + - DiagnosticReport + careContextReference: + type: string + example: visist 21-03-2024 + authoredOn: + type: string + format: date + example: 2024-05-20 + patient: + $ref: '#/components/schemas/Patient' + practitioners: + type: array + items: + $ref: '#/components/schemas/Practitioner' + organisation: + $ref: '#/components/schemas/Organisation' + encounter: + type: string + example: Ambula + diagnostics: + type: array + items: + $ref: '#/components/schemas/Diagnostic' + documents: + type: array + items: + $ref: '#/components/schemas/Document' + required: + - bundleType + - patient + - practitioners + - careContextReference + - authoredOn + - diagnostics + example: + bundleType: DiagnosticReport + careContextReference: visist 21-03-2024 + authoredOn: 2024-05-20 + patient: + name: Venu Ajitesh + patientReference: ajitesh6x + gender: male + birthDate: 2001-04-27 + practitioners: + - name: Dr.Venu Ajitesh + practitionerId: Predator + organisation: + facilityName: Predator_HIP + facilityId: Predator_HIP + encounter: Ambula + diagnostics: + - serviceName: BloodTest + serviceCategory: Hematography + result: + - observation: Height + result: Normal + valueQuantity: + unit: CM + value: 170 + conclusion: Normal + presentedForm: + contentType: application/pdf + data: skciybewydcugueducuyeduychidhyuchyedyhcb + documents: + - contentType: pdf + data: xyzadybcljbabvlalbfdbvubujzbj + + ImmunizationRecord: + type: object + properties: + bundleType: + type: string + enum: + - ImmunizationRecord + careContextReference: + type: string + example: visit-{{$isoTimestamp}} + patient: + $ref: '#/components/schemas/Patient' + practitioners: + type: array + items: + $ref: '#/components/schemas/Practitioner' + organisation: + $ref: '#/components/schemas/Organisation' + immunizations: + type: array + items: + $ref: '#/components/schemas/Immunization' + documents: + type: array + items: + $ref: '#/components/schemas/Document' + required: + - bundleType + - patient + - practitioners + - careContextReference + - authoredOn + - immunizations + example: + bundleType: ImmunizationRecord + careContextReference: visit-{{$isoTimestamp}} + patient: + name: Venu Ajitesh + patientReference: ajitesh6x + gender: male + birthDate: 2001-04-27 + practitioners: + - name: Dr.Venu Ajitesh + practitionerId: Predator + organisation: + facilityName: Predator_HIP + facilityId: Predator_HIP + immunizations: + - date: 2024-06-15 + vaccineName: Covaxin + lotNumber: IN00004 + manufacturer: NHA + doseNumber: 3 + documents: + - type: immunization + contentType: application/pdf + data: xyzadybcljbabvlalbfdbvubujzbj + DischargeSummary: + type: object + properties: + bundleType: + type: string + enum: + - discharge-summary + careContextReference: + type: string + example: visist 21-03-2024 + patient: + $ref: '#/components/schemas/Patient' + practitioners: + type: array + items: + $ref: '#/components/schemas/Practitioner' + organisation: + $ref: '#/components/schemas/Organisation' + chiefComplaints: + type: array + items: + $ref: '#/components/schemas/ChiefComplaint' + physicalExaminations: + type: array + items: + $ref: '#/components/schemas/PhysicalExamination' + allergies: + type: array + items: + type: string + medicalHistories: + type: array + items: + $ref: '#/components/schemas/ChiefComplaint' + familyHistories: + type: array + items: + $ref: '#/components/schemas/FamilyHistory' + authoredOn: + type: string + format: date + medications: + type: array + items: + $ref: '#/components/schemas/Medication' + diagnostics: + type: array + items: + $ref: '#/components/schemas/Diagnostic' + procedures: + type: array + items: + $ref: '#/components/schemas/Procedure' + documents: + type: array + items: + $ref: '#/components/schemas/Document' + required: + - bundleType + - patient + - practitioners + - careContextReference + - authoredOn + example: + bundleType: discharge-summary + careContextReference: visist 21-03-2024 + patient: + name: Venu Ajitesh + patientReference: ajitesh6x + gender: male + birthDate: 2001-04-27 + practitioners: + - name: Dr.Venu Ajitesh + practitionerId: Predator + organisation: + facilityName: Predator_HIP + facilityId: Predator_HIP + chiefComplaints: + - complaint: Sugar + recordedDate: 2024-05-20 + dateRange: + from: 2018-04-27 + to: 2018-05-26 + medications: + - medicine: Dolo + dosage: 1-0-1 + timing: 1-1-D + route: Oral + method: swallow + additionalInstructions: Take them after food + physicalExaminations: + - observation: Height + valueQuantity: + unit: CM + value: 170 + allergies: + - Walnuts + medicalHistories: + - complaint: Sugar + recordedDate: 2024-05-20 + dateRange: + from: 2018-04-27 + to: 2018-05-26 + familyHistories: + - relationship: Friend + observation: Toxic + diagnostics: + - serviceName: BloodTest + serviceCategory: Hematography + result: + - observation: Height + result: Normal + valueQuantity: + unit: CM + value: 170 + conclusion: Normal + presentedForm: + contentType: application/pdf + data: skciybewydcugueducuyeduychidhyuchyedyhcb + procedures: + - status: INPROGRESS + condition: Severe + outcome: Healthy + details: Operation + documents: + - type: OP record + contentType: application/pdf + data: xyzadybcljbabvlalbfdbvubujzbj + WellnessRecord: + type: object + properties: + bundleType: + type: string + enum: + - wellness-record + careContextReference: + type: string + example: visist 21-03-2025 + patient: + $ref: '#/components/schemas/Patient' + practitioners: + type: array + items: + $ref: '#/components/schemas/Practitioner' + organisation: + $ref: '#/components/schemas/Organisation' + vitalSigns: + type: array + items: + $ref: '#/components/schemas/Observation' + bodyMeasurements: + type: array + items: + $ref: '#/components/schemas/Observation' + physicalActivities: + type: array + items: + $ref: '#/components/schemas/Observation' + generalAssessments: + type: array + items: + $ref: '#/components/schemas/Observation' + womanHealths: + type: array + items: + $ref: '#/components/schemas/Observation' + lifeStyles: + type: array + items: + $ref: '#/components/schemas/Observation' + otherObservations: + type: array + items: + $ref: '#/components/schemas/Observation' + documents: + type: array + items: + $ref: '#/components/schemas/Document' + required: + - bundleType + - patient + - practitioners + - careContextReference + example: + bundleType: wellness-record + careContextReference: visist 21-03-2025 + patient: + name: Venu Ajitesh + patientReference: ajitesh6x + gender: male + birthDate: 2001-04-27 + practitioner: + - name: Dr.Venu Ajitesh + practitionerId: Predator + organisation: + facilityName: Predator_HIP + facilityId: Predator_HIP + vitalSigns: + - observation: Height + result: Normal + valueQuantity: + unit: CM + value: 170 + bodyMeasurements: + - observation: Height + result: Normal + valueQuantity: + unit: CM + value: 170 + physicalActivities: + - observation: Height + result: Normal + valueQuantity: + unit: CM + value: 170 + generalAssessments: + - observation: Height + result: Normal + valueQuantity: + unit: CM + value: 170 + womanHealths: + - observation: Height + result: Normal + valueQuantity: + unit: CM + value: 170 + lifeStyles: + - observation: Height + result: Normal + valueQuantity: + unit: CM + value: 170 + otherObservations: + - observation: Height + result: Normal + valueQuantity: + unit: CM + value: 170 + documents: + - type: Prescription + contentType: application/pdf + data: JVBERi0xLjMKJf////8KOCAwIG9iago8PAovVHlwZSAvRXh0R1N0YXRlCi9jYSAxCj4 + + Patient: + type: object + properties: + name: + type: string + patientReference: + type: string + gender: + type: string + enum: + - male + - female + birthDate: + type: string + format: date + required: + - name + - patientReference + example: + name: Venu Ajitesh + patientReference: ajitesh6x + gender: male + birthDate: 2001-04-27 + + Practitioner: + type: object + properties: + name: + type: string + practitionerId: + type: string + required: + - name + example: + name: Dr.Venu Ajitesh + practitionerId: Predator + + Organisation: + type: object + properties: + facilityName: + type: string + facilityId: + type: string + required: + - facilityName + example: + facilityName: Predator_HIP + facilityId: Predator_HIP + Diagnostic: + type: object + properties: + serviceName: + type: string + serviceCategory: + type: string + result: + type: array + items: + $ref: '#/components/schemas/Observation' + conclusion: + type: string + presentedForm: + $ref: '#/components/schemas/Document' + required: + - serviceName + - serviceCategory + - result + example: + serviceName: BloodTest + serviceCategory: Hematography + result: + - observation: Height + result: Normal + valueQuantity: + unit: CM + value: 170 + conclusion: Normal + presentedForm: + contentType: application/pdf + data: skciybewydcugueducuyeduychidhyuchyedyhcb + Immunization: + type: object + properties: + date: + type: string + format: date + vaccineName: + type: string + lotNumber: + type: string + manufacturer: + type: string + doseNumber: + type: string + required: + - date + - vaccineName + example: + date: 2024-06-15 + vaccineName: Covaxin + lotNumber: IN00004 + manufacturer: NHA + doseNumber: 3 + + DiagnosticResult: + type: object + properties: + observation: + type: string + result: + type: string + valueQuantity: + $ref: '#/components/schemas/ValueQuantity' + required: + - observation + example: + observation: Height + result: Normal + valueQuantity: + unit: CM + value: 170 + + ChiefComplaint: + type: object + properties: + complaint: + type: string + recordedDate: + type: string + format: date + dateRange: + $ref: '#/components/schemas/DateRange' + required: + - complaint + - recordedDate + example: + complaint: Sugar + recordedDate: 2024-05-20 + dateRange: + from: 2018-04-27 + to: 2018-05-26 + + DateRange: + type: object + properties: + from: + type: string + format: date + to: + type: string + format: date + example: + from: 2018-04-27 + to: 2018-05-26 + + PhysicalExamination: + type: object + properties: + observation: + type: string + result: + type: string + valueQuantity: + $ref: '#/components/schemas/ValueQuantity' + required: + - observation + example: + observation: Height + result: Normal + valueQuantity: + unit: CM + value: 170 + + ValueQuantity: + type: object + properties: + unit: + type: string + value: + type: number + required: + - unit + - value + example: + unit: KG + value: 90 + + FamilyHistory: + type: object + properties: + relationship: + type: string + observation: + type: string + required: + - relationship + - observation + example: + relationship: Friend + observation: Toxic + + ServiceRequest: + type: object + properties: + status: + type: string + details: + type: string + specimen: + type: string + required: + - status + - details + example: + status: ACTIVE + details: X-RAY + specimen: Jhonsons + + Medication: + type: object + properties: + medicine: + type: string + dosage: + type: string + timing: + description: frequency-period-periodUnit + type: string + enum: [S,MIN,H,D,WK,MO] + route: + type: string + method: + type: string + additionalInstructions: + type: string + reason: + type: string + required: + - medicine + - dosage + example: + medicine: Dolo + dosage: 1-0-1 + timing: 1-1-D + route: Oral + method: swallow + additionalInstructions: Take them after food + reason: Fever + + + FollowUp: + type: object + properties: + serviceType: + type: string + appointmentTime: + type: string + format: date + reason: + type: string + required: + - serviceType + - appointmentTime + - reason + example: + serviceType: OPConsultation + appointmentTime: 2024-05-20 + reason: General + + Procedure: + type: object + properties: + date: + type: string + status: + type: string + procedureReason: + type: string + outcome: + type: string + procedureName: + type: string + required: + - date + - status + - procedureName + - procedureReason + example: + date: 2001-04-25 + status: INPROGRESS + procedureReason: Severe + outcome: Healthy + procedureName: Operation + + Referral: + type: object + properties: + status: + type: string + details: + type: string + specimen: + type: string + required: + - status + - details + example: + status: ACTIVE + details: Y-RAY + specimen: Rock + + Observation: + type: object + properties: + observation: + type: string + result: + type: string + valueQuantity: + $ref: '#/components/schemas/ValueQuantity' + required: + - observation + example: + observation: Height + result: Normal + valueQuantity: + unit: CM + value: 170 + + OtherObservation: + type: object + properties: + observation: + type: string + result: + type: string + valueQuantity: + $ref: '#/components/schemas/ValueQuantity' + required: + - observation + example: + observation: weight + result: Over weight + valueQuantity: + unit: KG + value: 90 + # Note: Either result or valueQuantity should be included along with observation. + + Document: + type: object + properties: + type: + type: string + contentType: + type: string + data: + type: string + required: + - type + - contentType + - data + example: + type: OP record + contentType: application/pdf + data: xyzadybcljbabvlalbfdbvubujzbj + + + ValidationErrorResponse: + type: object + properties: + validationErrors: + type: object + properties: + code: + type: integer + example: 1000 + error: + type: array + items: + type: object + properties: + field: + type: string + message: + type: string + example: + validationErrors: + code: 1000 + error: + - field: bundleType + message: must match "PrescriptionRecord" + + GenericErrorResponse: + type: object + properties: + error: + type: object + properties: + code: + type: integer + message: + type: string + example: + error: + code: 1000 + message: "Parsing error must match the date format 2002-05-12" diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 00000000..e69de29b diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..70d416a7 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Mon Mar 11 22:06:57 IST 2024 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100644 index 00000000..e69de29b diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 00000000..e69de29b diff --git a/postmanCollection/FHIR.postman_collection.json b/postmanCollection/FHIR.postman_collection.json new file mode 100644 index 00000000..3cb05d03 --- /dev/null +++ b/postmanCollection/FHIR.postman_collection.json @@ -0,0 +1,318 @@ +{ + "info": { + "_postman_id": "6192a23b-5635-4954-9ba9-903e46159dfd", + "name": "FHIR", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", + "_exporter_id": "24014718" + }, + "item": [ + { + "name": "prescription", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var template = `", + "", + "", + "", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " {{#each response.entry}}", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " {{/each}}", + "
IDTypeStatusDateSubjectAuthorTitle
{{resource.id}}{{resource.resourceType}}{{resource.status}}{{resource.date}}{{resource.subject.reference}}{{resource.author.[0].reference}}{{resource.title}}
", + "`;", + "", + "function constructVisualizerPayload() {", + " return { response: pm.response.json() };", + "}", + "", + "pm.visualizer.set(template, constructVisualizerPayload());" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"bundleType\": \"PrescriptionRecord\",\r\n \"careContextReference\": \"visit-{{$isoTimestamp}}\",\r\n \"authoredOn\": \"2024-05-01T06:33:37.361Z\",\r\n \"encounter\": \"\",\r\n \"patient\": {\r\n \"name\": \"Venu Ajitesh\",\r\n \"patientReference\": \"ajitesh6x\",\r\n \"gender\": \"male\",\r\n \"birthDate\": \"1940-04-27\"\r\n },\r\n \"practitioners\": [\r\n {\r\n \"name\": \"Dr.Venu Ajitesh\",\r\n \"practitionerId\": \"Predator\"\r\n }\r\n ],\r\n \"organisation\": {\r\n \"facilityName\": \"Predator_HIP\",\r\n \"facilityId\": \"Predator_HIP\"\r\n },\r\n \"prescriptions\": [\r\n {\r\n \"medicine\": \"Glucosamine 1 g oral tablet\",\r\n \"dosage\": \"1-0-1\",\r\n \"timing\": \"1-1-D\",\r\n \"route\": \"Oral\",\r\n \"method\": \"swallow\",\r\n \"additionalInstructions\": \"Take them after food\",\r\n \"reason\": \"fever\"\r\n },\r\n {\r\n \"medicine\": \"Acetaminophen 100 mg/mL oral solution\",\r\n \"dosage\": \"0-0-1\",\r\n \"timing\": \"1-2-MO\",\r\n \"route\": \"Syrup\",\r\n \"method\": \"drink\",\r\n \"additionalInstructions\": \"Take them before food\",\r\n \"reason\": \"Cough\"\r\n }\r\n ],\r\n \"documents\": [\r\n {\r\n \"type\": \"Prescription\",\r\n \"contentType\": \"application/pdf\",\r\n \"data\": \"JVBERi0xLjMKJf////8K\"\r\n }\r\n ]\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "localhost:8085/v1/bundle/prescription", + "host": [ + "localhost" + ], + "port": "8085", + "path": [ + "v1", + "bundle", + "prescription" + ] + } + }, + "response": [] + }, + { + "name": "OPConsultation", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"bundleType\":\"OPConsultRecord\",\r\n \"careContextReference\":\"visist 21-03-2025\",\r\n \"visitDate\":\"2024-05-02T06:33:37.361Z\",\r\n \"patient\":{\r\n \"name\":\"Venu Ajitesh\",\r\n \"patientReference\":\"ajitesh6x\",\r\n \"gender\":\"male\",\r\n \"birthDate\":\"1940-04-27\"\r\n },\r\n \"practitioners\":[{\r\n \"name\":\"Dr.Venu Ajitesh\",\r\n \"practitionerId\":\"Predator\"\r\n }],\r\n \"organisation\":{\r\n \"facilityName\":\"Predator_HIP\",\r\n \"facilityId\":\"Predator_HIP\"\r\n },\r\n \"chiefComplaints\":[\r\n {\r\n \"complaint\":\"Dengue\",\r\n \"recordedDate\":\"2024-05-20\",\r\n \"dateRange\":{\r\n \"from\":\"2018-04-27\",\r\n \"to\":\"2018-05-26\"\r\n }\r\n }\r\n ],\r\n \"physicalExaminations\":[\r\n {\r\n \"observation\":\"Heavy drinker\",\r\n \"result\":\"heavy\"\r\n // \"valueQuantity\": {\r\n\t\t\t// \t\t\"unit\": \"CM\",\r\n\t\t\t// \t\t\"value\": 170\r\n\t\t\t// }\r\n }\r\n ],\r\n \"allergies\":[\r\n \"\"\r\n ],\r\n \"medicalHistories\": \r\n [\r\n {\r\n \"complaint\":\"Typhoid fever\",\r\n \"recordedDate\":\"2024-05-20\",\r\n \"dateRange\":{\r\n \"from\":\"2018-04-27\",\r\n \"to\":\"2018-05-26\"\r\n }\r\n }\r\n ],\r\n \"familyHistories\":[\r\n {\r\n \"relationship\":\"Friend\",\r\n \"observation\":\"Toxic\"\r\n }\r\n ],\r\n \"serviceRequests\":[\r\n {\r\n \"status\":\"ACTIVE\",\r\n \"details\":\"X-RAY\",\r\n \"specimen\":\"Lung cytologic material\"\r\n }\r\n ],\r\n \"medications\":\r\n [\r\n {\r\n \"medicine\":\"Nabilone 2 mg oral capsule\",\r\n \"dosage\":\"1-0-1\",\r\n \"timing\":\"2-5-D\",\r\n \"route\":\"Oral route\",\r\n \"method\":\"swallow\",\r\n \"additionalInstructions\":\"Take them after food\"\r\n }\r\n ,{\r\n \"medicine\":\"Nystatin 25000 unit/g vaginal cream\",\r\n \"dosage\":\"0-0-1\",\r\n \"timing\":\"1-2-D\",\r\n \"route\":\"Interstitial route (qualifier value)\",\r\n \"method\":\"drink\",\r\n \"additionalInstructions\":\"Take them before food\"\r\n }\r\n ],\r\n \"followups\":[\r\n {\r\n \"serviceType\":\"OPConsultation\",\r\n \"appointmentTime\":\"2024-05-20\",\r\n \"reason\":\"General\"\r\n }\r\n ],\r\n \"procedures\":[\r\n {\r\n \"date\":\"2001-04-20\",\r\n \"status\":\"INPROGRESS\",\r\n \"procedureReason\":\"Severe\",\r\n \"outcome\":\"Healthy\",\r\n \"procedureName\":\"Endodontic procedure\"\r\n }\r\n ],\r\n \"referrals\":[\r\n {\r\n \"status\":\"ACTIVE\",\r\n \"details\":\"Y-RAY\",\r\n \"specimen\":\"Pleural cytologic material\"\r\n }\r\n ],\r\n \"otherObservations\":[\r\n {\r\n \"observation\":\"Body weight\",\r\n // \"result\":\"Over weight\",\r\n \"valueQuantity\": {\r\n\t\t\t\t\t\"unit\": \"KG\",\r\n\t\t\t\t\t\"value\": 90\r\n\t\t\t\t}\r\n }\r\n ],\r\n \"documents\":[{\r\n \"type\":\"OP record\",\r\n \"contentType\":\"application/pdf\",\r\n \"data\":\"JVBERi0xLjMKJf////8K\"\r\n }]\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "localhost:8085/v1/bundle/op-consultation", + "host": [ + "localhost" + ], + "port": "8085", + "path": [ + "v1", + "bundle", + "op-consultation" + ] + } + }, + "response": [] + }, + { + "name": "health-document", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"bundleType\":\"HealthDocumentRecord\",\r\n \"careContextReference\":\"visist 21-03-2024\",\r\n \"patient\":{\r\n \"name\":\"Venu Ajitesh\",\r\n \"patientReference\":\"ajitesh6x\",\r\n \"gender\":\"male\",\r\n \"birthDate\":\"1940-04-27\"\r\n },\r\n \"authoredOn\":\"2024-05-03T06:33:37.361Z\",\r\n \"practitioners\":[{\r\n \"name\":\"Dr.Venu Ajitesh\",\r\n \"practitionerId\":\"Predator\"\r\n }],\r\n \"organisation\":{\r\n \"facilityName\":\"Predator_HIP\",\r\n \"facilityId\":\"Predator_HIP\"\r\n },\r\n \"encounter\":\"\",\r\n \"documents\":[{\r\n \"type\":\"health-document\",\r\n \"contentType\":\"application/pdf\",\r\n \"data\":\"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7Igi2NJ03WIdb8CPaOhwBlKEkoax7E5ZdLjP42F98TiJWKZ1T9XnPz8+/Kc1f/jRS/+d3B19aNHmf3r24eU/ho/Y+4/AKijvgugHu5+K373i9d+++9oPF/X9P6FV1H1lbmRzdHJlYW0gCmVuZG9iaiAKMiAwIG9iaiAKPDwgCi9UeXBlIC9QYWdlcyAKL0tpZHMgWyA4IDAgUiBdIAovQ291bnQgMSAKL01lZGlhQm94IDMgMCBSIAovQ3JvcEJveCA0IDAgUiAKPj4gCmVuZG9iaiAKMyAwIG9iaiAKWyAwIDAgNTk1IDg0MSBdIAplbmRvYmogCjQgMCBvYmogClsgMCAwIDU5NSA4NDEgXSAKZW5kb2JqIAo2IDAgb2JqIAo8PCAKL1Byb2NTZXQgNyAwIFIgCi9Gb250IDw8IAovOSA5IDAgUiAgCi9hIDEwIDAgUiAgCj4+IAovWE9iamVjdCA8PCAKL2ltZzAgMTEgMCBSICAKPj4gCj4+IAplbmRvYmogCjcgMCBvYmogClsgL1BERiAvVGV4dCAvSW1hZ2VCIC9JbWFnZUMgL0ltYWdlSSAgXSAKZW5kb2JqIAo4IDAgb2JqIAo8PCAKL1R5cGUgL1BhZ2UgCi9QYXJlbnQgMiAwIFIgCi9SZXNvdXJjZXMgNiAwIFIgCi9Db250ZW50cyBbIDUgMCBSIF0gCj4+IAplbmRvYmogCjkgMCBvYmogCjw8IAovVHlwZSAvRm9udCAKL1N1YnR5cGUgL1RydWVUeXBlIAovQmFzZUZvbnQgL0FBQUFBQStBcmlhbCxCb2xkIAovRmlyc3RDaGFyIDMyIAovTGFzdENoYXIgMTIxIAovV2lkdGhzIDE0IDAgUiAKL0ZvbnREZXNjcmlwdG9yIDE2IDAgUiAKL1RvVW5pY29kZSAxNSAwIFIgCj4+IAplbmRvYmogCjEwIDAgb2JqIAo8PCAKL1R5cGUgL0ZvbnQgCi9TdWJ0eXBlIC9UcnVlVHlwZSAKL0Jhc2VGb250IC9BQUFBQUIrQXJpYWwgCi9GaXJzdENoYXIgMzIgCi9MYXN0Q2hhciAxMjIgCi9XaWR0aHMgMTkgMCBSIAovRm9udERlc2NyaXB0b3IgMjEgMCBSIAovVG9Vbmljb2RlIDIwIDAgUiAKPj4gCmVuZG9iaiAKMTEgMCBvYmog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CjY2NyAKMCAKNzIyIAo2NjcgCjYxMSAKNzIyIAowIAowIAowIAowIAowIAowIAowIAowIAowIAowIAowIAo1NTYgCjYxMSAKNTU2IAo2MTEgCjU1NiAKMzMzIAo2MTEgCjYxMSAKMjc4IAowIAo1NTYgCjI3OCAKODg5IAo2MTEgCjYxMSAKNjExIAowIAozODkgCjU1NiAKMzMzIAo2MTEgCjU1NiAKMCAKMCAKNTU2IApdIAplbmRvYmogCjE2IDAgb2JqIAo8PCAKL1R5cGUgL0ZvbnREZXNjcmlwdG9yIAovQXNjZW50IDkwNSAKL0NhcEhlaWdodCA1MDAgCi9EZXNjZW50IC0yMTIgCi9GbGFncyA0IAovRm9udEJCb3ggMTcgMCBSIAovRm9udE5hbWUgL0FBQUFBQStBcmlhbCxCb2xkIAovSXRhbGljQW5nbGUgMAovU3RlbVYgMCAKL1N0ZW1IIDAgCi9BdmdXaWR0aCA0NzkgCi9Gb250RmlsZTIgMTggMCBSIAovTGVhZGluZyAwIAovTWF4V2lkdGggMjYyOCAKL01pc3NpbmdXaWR0aCA0NzkgCi9YSGVpZ2h0IDAgCj4+IAplbmRvYmogCjE3IDAgb2JqIApbIC02MjggLTM3NiAyMDAwIDEwNTYgXSAKZW5kb2JqIAoxOSAwIG9iaiAKWyAKMjc4IAowIAowIAowIAowIAowIAowIAowIAowIAowIAowIAowIAoyNzggCjMzMyAKMjc4IAoyNzggCjU1NiAKNTU2IAo1NTYgCjU1NiAKNTU2IAo1NTYgCjU1NiAKNTU2IAo1NTYgCjU1NiAKMjc4IAowIAowIAowIAowIAowIAowIAo2NjcgCjY2NyAKNzIyIAo3MjIgCjY2NyAKMCAKNzc4IAo3MjIgCjI3OCAKMCAKMCAKNTU2IAo4MzMgCjcyMiAKNzc4IAo2NjcgCjAgCjcyMiAKNjY3IAo2MTEgCjcyMiAKMCAKOTQ0IAowIAo2NjcgCjAgCjAgCjAgCjAgCjAgCjAgCjAgCjU1NiAKNTU2IAo1MDAgCjU1NiAKNTU2IAowIAo1NTYgCjU1NiAKMjIyIAoyMjIgCjAgCjIyMiAKODMzIAo1NTYgCjU1NiAKNTU2IAowIAozMzMgCjUwMCAKMjc4IAo1NTYgCjAgCjAgCjAgCjAgCjUwMCAKXSAKZW5kb2JqIAoyMSAwIG9iaiAKPDwgCi9UeXBlIC9Gb250RGVzY3JpcHRvciAKL0FzY2VudCA5MDUgCi9DYXBIZWlnaHQgNTAwIAovRGVzY2VudCAtMjEyIAovRmxhZ3MgNCAKL0ZvbnRCQm94IDIyIDAgUiAKL0ZvbnROYW1lIC9BQUFBQUIrQXJpYWwgCi9JdGFsaWNBbmdsZSAwCi9TdGVtViAwIAovU3RlbUggMCAKL0F2Z1dpZHRoIDQ0MSAKL0ZvbnRGaWxlMiAyMyAwIFIgCi9MZWFkaW5nIDAgCi9NYXhXaWR0aCAyNjY1IAovTWlzc2luZ1dpZHRoIDQ0MSAKL1hIZWlnaHQgMCAKPj4gCmVuZG9iaiAKMjIgMCBvYmogClsgLTY2NSAtMzI1IDIwMDAgMTA0MCBdIAplbmRvYmogCjI0IDAgb2JqIAooUG93ZXJlZCBCeSBDcnlzdGFsKSAKZW5kb2JqIAoyNSAwIG9iaiAKKENyeXN0YWwgUmVwb3J0cykgCmVuZG9iaiAKMjYgMCBvYmogCjw8IAovUHJvZHVjZXIgKFBvd2VyZWQgQnkgQ3J5c3RhbCkgIAovQ3JlYXRvciAoQ3J5c3RhbCBSZXBvcnRzKSAgCj4+IAplbmRvYmogCnhyZWYgCjAgMjcgCjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDAxNyAwMDAwMCBuIAowMDAwMDQyNDE0IDAwMDAwIG4gCjAwMDAwNDI1MTMgMDAwMDAgbiAKMDAwMDA0MjU0NyAwMDAwMCBuIAowMDAwMDAwMTk0IDAwMDAwIG4gCjAwMDAwNDI1ODEgMDAwMDAgbiAKMDAwMDA0MjY5MSAwMDAwMCBuIAowMDAwMDQyNzQ5IDAwMDAwIG4gCjAwMDAwNDI4NDEgMDAwMDAgbiAKMDAwMDA0MzAxOCAwMDAwMCBuIAowMDAwMDQzMTkxIDAwMDAwIG4gCjAwMDAwNTQ3MzUgMDAwMDAgbiAKMDAwMDA1NDc4OSAwMDAwMCBuIAowMDAwMDU1NjA0IDAwMDAwIG4gCjAwMDAwMDE0NzQgMDAwMDAgbiAKMDAwMDA1NTk5MCAwMDAwMCBuIAowMDAwMDU2MjY5IDAwMDAwIG4gCjAwMDAwMDIwOTUgMDAwMDAgbiAKMDAwMDA1NjMxMiAwMDAwMCBuIAowMDAwMDE4MTE3IDAwMDAwIG4gCjAwMDAwNTY3MTcgMDAwMDAgbiAKMDAwMDA1Njk5MSAwMDAwMCBuIAowMDAwMDE4Nzc5IDAwMDAwIG4gCjAwMDAwNTcwMzQgMDAwMDAgbiAKMDAwMDA1NzA3NCAwMDAwMCBuIAowMDAwMDU3MTExIDAwMDAwIG4gCnRyYWlsZXIgCjw8IAovU2l6ZSAyNyAKL1Jvb3QgMSAwIFIgCi9JbmZvIDI2IDAgUiAKPj4gCnN0YXJ0eHJlZiAKNTcxOTkgCiUlRU9GDQo=\"\r\n }]\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "localhost:8085/v1/bundle/health-document", + "host": [ + "localhost" + ], + "port": "8085", + "path": [ + "v1", + "bundle", + "health-document" + ] + } + }, + "response": [] + }, + { + "name": "diagnosticReport", + "protocolProfileBehavior": { + "disabledSystemHeaders": {} + }, + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"bundleType\": \"DiagnosticReportRecord\",\r\n \"careContextReference\": \"visist 21-03-2024\",\r\n \"visitDate\": \"2024-05-07T06:33:37.361Z\",\r\n \"patient\": {\r\n \"name\": \"Venu Ajitesh\",\r\n \"patientReference\": \"ajitesh6x\",\r\n \"gender\": \"male\",\r\n \"birthDate\": \"1940-04-27\"\r\n },\r\n \"practitioners\": [\r\n {\r\n \"name\": \"Dr.Venu Ajitesh\",\r\n \"practitionerId\": \"Predator\"\r\n }\r\n ],\r\n \"organisation\": {\r\n \"facilityName\": \"Predator_HIP\",\r\n \"facilityId\": \"Predator_HIP\"\r\n },\r\n \"encounter\": \"Ambula\",\r\n \"diagnostics\": [\r\n {\r\n \"serviceName\": \"BloodTest\",\r\n \"authoredOn\":\"2024-11-23T21:34:38.989Z\",\r\n \"serviceCategory\": \"Hematography\",\r\n \"result\": [\r\n {\r\n \"observation\": \"Height\",\r\n \"result\": \"Normal\",\r\n \"valueQuantity\": {\r\n \"unit\": \"CM\",\r\n \"value\": 170\r\n }\r\n }\r\n ],\r\n \"conclusion\": \"Normal\",\r\n \"presentedForm\":{\r\n \"contentType\": \"application/pdf\",\r\n \"data\": \"JVBERi0xLjMKJf////8K\"\r\n }\r\n }\r\n ],\r\n \"documents\":[{\r\n \"type\": \"diagnosticReport\",\r\n \"contentType\": \"application/pdf\",\r\n \"data\": \"JVBERi0xLjMKJf////8K\"\r\n }]\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "localhost:8085/v1/bundle/diagnostic-report", + "host": [ + "localhost" + ], + "port": "8085", + "path": [ + "v1", + "bundle", + "diagnostic-report" + ] + } + }, + "response": [] + }, + { + "name": "wellness-record", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"bundleType\":\"WellnessRecord\",\r\n \"careContextReference\":\"visist 21-03-2025\",\r\n \"authoredOn\":\"2024-05-04T06:33:37.361Z\",\r\n \"patient\":{\r\n \"name\":\"Venu Ajitesh\",\r\n \"patientReference\":\"ajitesh6x\",\r\n \"gender\":\"male\",\r\n \"birthDate\":\"1940-04-27\"\r\n },\r\n \"practitioners\":[{\r\n \"name\":\"Dr.Venu Ajitesh\",\r\n \"practitionerId\":\"Predator\"\r\n }],\r\n \"organisation\":{\r\n \"facilityName\":\"Predator_HIP\",\r\n \"facilityId\":\"Predator_HIP\"\r\n },\r\n \"vitalSigns\":[\r\n {\r\n \"observation\":\"Height\",\r\n \"result\":\"Normal\",\r\n \"valueQuantity\": {\r\n\t\t\t\t\t\"unit\": \"CM\",\r\n\t\t\t\t\t\"value\": 170\r\n\t\t\t}\r\n }\r\n ],\r\n \"bodyMeasurements\":[\r\n {\r\n \"observation\":\"BMI\",\r\n \"result\":\"Normal\",\r\n \"valueQuantity\": {\r\n\t\t\t\t\t\"unit\": \"CM\",\r\n\t\t\t\t\t\"value\": 170\r\n\t\t\t}\r\n }\r\n ],\r\n \"physicalActivities\":[\r\n {\r\n \"observation\":\"Running\",\r\n \"result\":\"Normal\",\r\n \"valueQuantity\": {\r\n\t\t\t\t\t\"unit\": \"CM\",\r\n\t\t\t\t\t\"value\": 170\r\n\t\t\t}\r\n }\r\n ],\r\n \"generalAssessments\":[\r\n {\r\n \"observation\":\"Physico\",\r\n \"result\":\"Normal\",\r\n \"valueQuantity\": {\r\n\t\t\t\t\t\"unit\": \"CM\",\r\n\t\t\t\t\t\"value\": 170\r\n\t\t\t}\r\n }\r\n ],\"womanHealths\":[\r\n {\r\n \"observation\":\"Crazy\",\r\n \"result\":\"Normal\",\r\n \"valueQuantity\": {\r\n\t\t\t\t\t\"unit\": \"CM\",\r\n\t\t\t\t\t\"value\": 170\r\n\t\t\t}\r\n }\r\n ],\r\n \"lifeStyles\":[\r\n {\r\n \"observation\":\"Bad\",\r\n \"result\":\"Normal\",\r\n \"valueQuantity\": {\r\n\t\t\t\t\t\"unit\": \"CM\",\r\n\t\t\t\t\t\"value\": 170\r\n\t\t\t}\r\n }\r\n ],\r\n \"otherObservations\":[\r\n {\r\n \"observation\":\"None\",\r\n \"result\":\"Normal\",\r\n \"valueQuantity\": {\r\n\t\t\t\t\t\"unit\": \"CM\",\r\n\t\t\t\t\t\"value\": 170\r\n\t\t\t}\r\n }\r\n ],\r\n \"documents\":[{\r\n \"type\":\"WellnessRecord\",\r\n \"contentType\":\"application/pdf\",\r\n \"data\": \"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Mzc1Ci9YSGVpZ2h0IDUyOC4zMjAzMTMKL1N0ZW1WIDAKL0ZvbnRGaWxlMiAxNiAwIFIKPj4KZW5kb2JqCjE4IDAgb2JqCjw8Ci9UeXBlIC9Gb250Ci9TdWJ0eXBlIC9DSURGb250VHlwZTIKL0Jhc2VGb250IC9CWlpaWlorUm9ib3RvLVJlZ3VsYXIKL0NJRFN5c3RlbUluZm8gPDwKL1JlZ2lzdHJ5IChBZG9iZSkKL09yZGVyaW5nIChJZGVudGl0eSkKL1N1cHBsZW1lbnQgMAo+PgovRm9udERlc2NyaXB0b3IgMTcgMCBSCi9XIFswIFs5MDggNzEzLjM3ODkwNiA3MTMuMzc4OTA2IDY1Mi4zNDM3NSAyNDguMDQ2ODc1IDI0NC4xNDA2MjUgNTYzLjk2NDg0NCA4NzYuOTUzMTI1IDI0My4xNjQwNjMgNTUyLjI0NjA5NCA2MzYuNzE4NzUgNTcwLjMxMjUgNTUxLjI2OTUzMSA1MjMuNDM3NSA1NTAuNzgxMjUgNTMwLjI3MzQzOCAzMzguODY3MTg4IDI0My4xNjQwNjMgNTQzLjk0NTMxMyAzMjcuMTQ4NDM4IDU5My43NSA1MTYuMTEzMjgxIDU2Mi4wMTE3MTkgNTYyLjAxMTcxOSA1NjIuMDExNzE5IDU2Mi4wMTE3MTkgNDg0LjM3NSA1NjIuMDExNzE5IDU2Mi4wMTE3MTkgNTYyLjAxMTcxOSA1NjIuMDExNzE5IDg3My4wNDY4NzUgNjE2LjIxMDkzOCAyNzYuMzY3MTg4IDI0Mi4xODc1IDYzMC44NTkzNzUgMjYzLjY3MTg3NSAyNzEuOTcyNjU2IDU5Ni42Nzk2ODggNTY4LjM1OTM3NSA2NTYuMjUgNjUwLjg3ODkwNiAzNDcuNjU2MjUgNTYyLjAxMTcxOSA1NjIuMDExNzE5IDU2MS41MjM0MzggNjg3Ljk4ODI4MSA2NDguNDM3NSA1NjEuNTIzNDM4IDYwMC41ODU5MzhdXQovQ0lEVG9HSURNYXAgL0lkZW50aXR5Cj4+CmVuZG9iagoxOSAwIG9iago8PAovTGVuZ3RoIDMzNwovRmlsdGVyIC9GbGF0ZURlY29kZQo+PgpzdHJlYW0KeJxdUstugzAQvPMVe0wPEQFDaCSEVKUXDn2otKeqB2IvEVIxliEH/r7G4yZV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hSaeRYM/OC1xOdwlOx480lpmEZzGvKwIYw3O7ev2dcIFETqTyfRBfUg7ItEpSQGFjhGF/hcOmQnjCmVuZHN0cmVhbQplbmRvYmoKeHJlZgowIDI0CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwNjQ0OSAwMDAwMCBuIAowMDAwMDA2NTA2IDAwMDAwIG4gCjAwMDAwMDYzODcgMDAwMDAgbiAKMDAwMDAwNjM2NiAwMDAwMCBuIAowMDAwMDAwMzU5IDAwMDAwIG4gCjAwMDAwMDAyMTkgMDAwMDAgbiAKMDAwMDAwMDEwOSAwMDAwMCBuIAowMDAwMDAwMDE1IDAwMDAwIG4gCjAwMDAwMDAwNTkgMDAwMDAgbiAKMDAwMDAwNDgxMCAwMDAwMCBuIAowMDAwMDA2MjE4IDAwMDAwIG4gCjAwMDAwMDMzMTcgMDAwMDAgbiAKMDAwMDAwMzIyOSAwMDAwMCBuIAowMDAwMDAzMjU1IDAwMDAwIG4gCjAwMDAwMDMyODEgMDAwMDAgbiAKMDAwMDAwNjU1MyAwMDAwMCBuIAowMDAwMDAzMzkzIDAwMDAwIG4gCjAwMDAwMDM2NjEgMDAwMDAgbiAKMDAwMDAwNDQwMCAwMDAwMCBuIAowMDAwMDE0MjAzIDAwMDAwIG4gCjAwMDAwMDQ5NTkgMDAwMDAgbiAKMDAwMDAwNTIyNiAwMDAwMCBuIAowMDAwMDA1ODM2IDAwMDAwIG4gCnRyYWlsZXIKPDwKL1NpemUgMjQKL1Jvb3QgMyAwIFIKL0luZm8gMTIgMCBSCi9JRCBbPDdiOTliYmRjNzc5ZjAyYjc4MGViNDI1ZWU0ZjdmY2JmPiA8N2I5OWJiZGM3NzlmMDJiNzgwZWI0MjVlZTRmN2ZjYmY+XQo+PgpzdGFydHhyZWYKMjA3NzUKJSVFT0YK\"\r\n }]\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "localhost:8085/v1/bundle/wellness-record", + "host": [ + "localhost" + ], + "port": "8085", + "path": [ + "v1", + "bundle", + "wellness-record" + ] + } + }, + "response": [] + }, + { + "name": "immunization", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"bundleType\":\"ImmunizationRecord\",\r\n \"careContextReference\":\"visit-{{$isoTimestamp}}\",\r\n \"authoredOn\":\"{{$isoTimestamp}}\",\r\n \"encounter\":\"\",\r\n \"patient\":{\r\n \"name\":\"Venu Ajitesh\",\r\n \"patientReference\":\"ajitesh6x\",\r\n \"gender\":\"male\",\r\n \"birthDate\":\"1940-04-27\"\r\n },\r\n \"practitioners\":[{\r\n \"name\":\"Dr.Venu Ajitesh\",\r\n \"practitionerId\":\"Predator\"\r\n }],\r\n \"organisation\":{\r\n \"facilityName\":\"Predator_HIP\",\r\n \"facilityId\":\"Predator_HIP\"\r\n },\r\n \"immunizations\":[{\r\n \"date\":\"2024-06-15\",\r\n \"vaccineName\":\"Paratyphoid vaccine\",\r\n \"lotNumber\":\"IN00004\",\r\n \"manufacturer\":\"NHA\",\r\n \"doseNumber\":\"3\"\r\n }],\r\n \"documents\":[{\r\n \"type\":\"immunization\",\r\n \"contentType\":\"application/pdf\",\r\n \"data\": \"JVBERi0xLjMKJf////8K\"\r\n }]\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "localhost:8085/v1/bundle/immunization", + "host": [ + "localhost" + ], + "port": "8085", + "path": [ + "v1", + "bundle", + "immunization" + ] + } + }, + "response": [] + }, + { + "name": "discharge-summary", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"bundleType\":\"DischargeSummaryRecord\",\r\n \"careContextReference\":\"visist 21-03-2024\",\r\n \"patient\":{\r\n \"name\":\"Venu Ajitesh\",\r\n \"patientReference\":\"ajitesh6x\",\r\n \"gender\":\"male\",\r\n \"birthDate\":\"1940-04-27\"\r\n },\r\n \"practitioners\":[{\r\n \"name\":\"Dr.Venu Ajitesh\",\r\n \"practitionerId\":\"Predator\"\r\n }],\r\n \"carePlan\":{\r\n \"intent\":\"plan\",\r\n \"type\":\"Regular check up\",\r\n \"goal\":\"Reduce BP\",\r\n \"description\":\"Normal\",\r\n \"notes\":\"The patient has an HIGH BP, recommended to revisit on 29-10-2024\"\r\n },\r\n \"organisation\":{\r\n \"facilityName\":\"Predator_HIP\",\r\n \"facilityId\":\"Predator_HIP\"\r\n },\r\n \"chiefComplaints\":[\r\n {\r\n \"complaint\":\"Sugar\",\r\n \"recordedDate\":\"2024-05-20\",\r\n \"dateRange\":{\r\n \"from\":\"2018-04-27\",\r\n \"to\":\"2018-05-26\"\r\n }\r\n }\r\n ],\r\n \"physicalExaminations\":[\r\n {\r\n \"observation\":\"Height\",\r\n \"result\":\"Normal\",\r\n \"valueQuantity\": {\r\n\t\t\t\t\t\"unit\": \"CM\",\r\n\t\t\t\t\t\"value\": 170\r\n\t\t\t}\r\n }\r\n ],\r\n \"allergies\":[\r\n \"Walnuts\"\r\n ],\r\n \"medicalHistories\":[\r\n {\r\n \"complaint\":\"Sugar\",\r\n \"recordedDate\":\"2024-05-20\",\r\n \"dateRange\":{\r\n \"from\":\"2018-04-27\",\r\n \"to\":\"2018-05-26\"\r\n }\r\n }\r\n ],\r\n \"familyHistories\":[\r\n {\r\n \"relationship\":\"Friend\",\r\n \"observation\":\"Toxic\"\r\n }\r\n ],\r\n \"authoredOn\":\"2024-05-06T06:33:37.361Z\",\r\n \"medications\":[\r\n {\r\n \"medicine\":\"Aspirin 75 mg oral tablet\",\r\n \"dosage\":\"1-0-1\",\r\n \"timing\":\"2-5-D\",\r\n \"route\":\"Oral\",\r\n \"method\":\"swallow\",\r\n \"additionalInstructions\":\"Take them after food\"\r\n }\r\n ,{\r\n \"medicine\":\"Disprin\",\r\n \"dosage\":\"0-0-1\",\r\n \"timing\":\"1-2-D\",\r\n \"route\":\"Syrup\",\r\n \"method\":\"drink\",\r\n \"additionalInstructions\":\"Take them before food\"\r\n }\r\n ],\r\n \"diagnostics\":[{\r\n \"serviceName\":\"BloodTest\",\r\n \"serviceCategory\":\"Hematography\",\r\n \"result\":[{\r\n \"observation\":\"Height\",\r\n \"result\":\"Normal\",\r\n \"valueQuantity\": {\r\n\t\t\t\t\t\"unit\": \"CM\",\r\n\t\t\t\t\t\"value\": 170\r\n\t\t\t}\r\n }],\r\n \"authoredOn\":\"2024-05-08T06:33:37.361Z\",\r\n \"conclusion\":\"Normal\",\r\n \"presentedForm\":{\r\n \"contentType\":\"application/pdf\",\r\n \"data\":\"JVBERi0xLjMKJf////8K\"\r\n }\r\n }],\r\n \"procedures\":[\r\n {\r\n \"date\":\"2001-04-20\",\r\n \"status\":\"INPROGRESS\",\r\n \"procedureReason\":\"Severe\",\r\n \"outcome\":\"Healthy\",\r\n \"procedureName\":\"Operation\"\r\n }\r\n ],\r\n \"documents\":[{\r\n \"type\":\"OP record\",\r\n \"contentType\":\"application/pdf\",\r\n \"data\":\"JVBERi0xLjMKJf////8K\"\r\n }]\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "localhost:8085/v1/bundle/discharge-summary", + "host": [ + "localhost" + ], + "port": "8085", + "path": [ + "v1", + "bundle", + "discharge-summary" + ] + } + }, + "response": [] + }, + { + "name": "Get SnomedCodes", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "localhost:8085/v1/snomed/Medications", + "host": [ + "localhost" + ], + "port": "8085", + "path": [ + "v1", + "snomed", + "Medications" + ] + } + }, + "response": [] + } + ] +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 00000000..b62de251 --- /dev/null +++ b/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = 'fhir-mapper' + diff --git a/src/main/java/com/nha/abdm/fhir/mapper/FHIRApplication.java b/src/main/java/com/nha/abdm/fhir/mapper/FHIRApplication.java new file mode 100644 index 00000000..01471ea0 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/FHIRApplication.java @@ -0,0 +1,12 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class FHIRApplication { + public static void main(String[] args) { + SpringApplication.run(FHIRApplication.class, args); + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/Utils.java b/src/main/java/com/nha/abdm/fhir/mapper/Utils.java new file mode 100644 index 00000000..a9d679c4 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/Utils.java @@ -0,0 +1,40 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import org.hl7.fhir.r4.model.DateTimeType; +import org.hl7.fhir.r4.model.InstantType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +@Component +public class Utils { + private static final SimpleDateFormat ISO_DATE_TIME_FORMAT = + new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX"); + private static final SimpleDateFormat DATE_ONLY_FORMAT = new SimpleDateFormat("yyyy-MM-dd"); + private static final Logger log = LoggerFactory.getLogger(Utils.class); + + public static InstantType getCurrentTimeStamp() throws ParseException { + InstantType instantType = new InstantType(); + instantType.setToCurrentTimeInLocalTimeZone(); + return (InstantType) InstantType.withCurrentTime().setTimeZoneZulu(true); + } + + public static DateTimeType getFormattedDateTime(String dateTimeString) throws ParseException { + dateTimeString = dateTimeString.trim(); + if (dateTimeString.length() <= 10) { + return new DateTimeType(dateTimeString); + } else { + return (DateTimeType) + new DateTimeType(ISO_DATE_TIME_FORMAT.parse(dateTimeString)).setTimeZoneZulu(true); + } + } + + public static Date getFormattedDate(String dateTimeString) throws ParseException { + dateTimeString = dateTimeString.trim(); + return new DateTimeType(dateTimeString).getValue(); + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/BundleCompositionIdentifier.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/BundleCompositionIdentifier.java new file mode 100644 index 00000000..aa426e44 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/BundleCompositionIdentifier.java @@ -0,0 +1,72 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.common.constants; + +public class BundleCompositionIdentifier { + // DISCHARGE SUMMARY + public static final String DISCHARGE_SUMMARY_CODE = "373942005"; + public static final String DISCHARGE_SUMMARY = "Discharge summary"; + public static final String INVESTIGATION_ADVICE = "Discharge summary"; + public static final String CHIEF_COMPLAINTS = "Chief complaint section"; + public static final String CHIEF_COMPLAINTS_CODE = "422843007"; + public static final String PHYSICAL_EXAMINATION_CODE = "425044008"; + public static final String PHYSICAL_EXAMINATION = "Physical exam section"; + public static final String ALLERGY_RECORD = "Allergy record"; + public static final String ALLERGY_RECORD_CODE = "722446000"; + public static final String PAST_MEDICAL_HISTORY = "Past medical history section"; + public static final String PAST_MEDICAL_CODE = "1003642006"; + public static final String FAMILY_HISTORY_SECTION = "Family history section"; + public static final String FAMILY_HISTORY_SECTION_CODE = "422432008"; + public static final String DIAGNOSTIC_STUDIES_REPORT = "Diagnostic studies report"; + public static final String DIAGNOSTIC_STUDIES_REPORT_CODE = "721981007"; + public static final String MEDICAL_HISTORY_SECTION = "Medication history section"; + public static final String MEDICAL_HISTORY_SECTION_CODE = "1003606003"; + public static final String HISTORY_PAST_PROCEDURE = "History of past procedure section"; + public static final String HISTORY_PAST_PROCEDURE_CODE = "1003640003"; + public static final String CARE_PLAN = "Care plan"; + public static final String CARE_PLAN_CODE = "734163000"; + + // HEALTH DOCUMENT RECORD + public static final String RECORD_ARTIFACT = "Record artifact"; + public static final String RECORD_ARTIFACT_CODE = "419891008"; + public static final String HEALTH_DOCUMENT = "Health Document"; + public static final String HEALTH_DOCUMENT_CODE = "423876004"; + + // IMMUNIZATION RECORD + public static final String IMMUNIZATION_RECORD = "Immunization record"; + public static final String IMMUNIZATION_RECORD_CODE = "41000179103"; + + // OP CONSULTATION + public static final String OP_CONSULTATION = "Clinical consultation report"; + public static final String OP_CONSULTATION_CODE = "371530004"; + public static final String HISTORY_PHYSICAL_REPORT = "History and physical report"; + public static final String HISTORY_PHYSICAL_REPORT_CODE = "371529009"; + public static final String ORDER_DOCUMENT = "Order document"; + public static final String ORDER_DOCUMENT_CODE = "721963009"; + public static final String MEDICATION_SUMMARY = "Medication summary document"; + public static final String MEDICATION_SUMMARY_CODE = "721912009"; + public static final String FOLLOW_UP = "Follow-up encounter"; + public static final String FOLLOW_UP_CODE = "390906007"; + public static final String CLINICAL_PROCEDURE = "Clinical procedure report"; + public static final String CLINICAL_PROCEDURE_CODE = "371525003"; + public static final String REFERRAL_TO_SERVICE = "Referral to service"; + public static final String REFERRAL_TO_SERVICE_CODE = "306206005"; + public static final String CLINICAL_FINDING = "Clinical finding"; + public static final String CLINICAL_FINDING_CODE = "404684003"; + public static final String CLINICAL_CONSULTATION_REPORT = "Clinical consultation report"; + public static final String CLINICAL_CONSULTATION_REPORT_CODE = "371530004"; + + // PRESCRIPTION RECORD + public static final String PRESCRIPTION = "Prescription record"; + public static final String PRESCRIPTION_CODE = "440545006"; + + // WELLNESS RECORD + public static final String WELLNESS_RECORD = "Wellness Record"; + public static final String OTHER_OBSERVATIONS = "Other Observations"; + public static final String LIFE_STYLE = "Lifestyle"; + public static final String WOMEN_HEALTH = "Women Health"; + public static final String GENERAL_ASSESSMENT = "General Assessment"; + public static final String PHYSICAL_ACTIVITY = "Physical Activity"; + public static final String BODY_MEASUREMENT = "Body Measurement"; + public static final String VITAL_SIGNS = "Vital Signs"; + public static final String DOCUMENT_REFERENCE = "Document Reference"; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/BundleFieldIdentifier.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/BundleFieldIdentifier.java new file mode 100644 index 00000000..b8f01958 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/BundleFieldIdentifier.java @@ -0,0 +1,20 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.common.constants; + +public class BundleFieldIdentifier { + public static final String ALLERGY = "Allergy"; + public static final String ACTIVE = "Active"; + public static final String VERY_RESTRICTED = "very restricted"; + public static final String AMBULATORY = "Ambulatory"; + public static final String MEDICAL_RECORD_NUMBER = "Medical record number"; + public static final String LIFE_STYLE = "lifeStyle"; + public static final String WOMAN_HEALTH = "womanHealth"; + public static final String GENERAL_ASSESSMENT = "generalAssessment"; + public static final String PHYSICAL_ACTIVITY = "physicalActivity"; + public static final String BODY_MEASUREMENT = "bodyMeasurement"; + public static final String VITAL_SIGNS = "vitalSigns"; + public static final String SYSTEM = "system"; + public static final String CODE = "code"; + public static final String DISPLAY = "display"; + public static final String MEDICAL_CONDITION = "MedicalCondition"; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/BundleIdentifier.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/BundleIdentifier.java new file mode 100644 index 00000000..67718d51 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/BundleIdentifier.java @@ -0,0 +1,12 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.common.constants; + +public class BundleIdentifier { + public static final String WELLNESS_RECORD = "WellnessRecord"; + public static final String DISCHARGE_SUMMARY_RECORD = "DischargeSummaryRecord"; + public static final String DIAGNOSTIC_REPORT = "DiagnosticReportRecord"; + public static final String HEALTH_DOCUMENT = "HealthDocumentRecord"; + public static final String OP_CONSULTATION = "OPConsultRecord"; + public static final String PRESCRIPTION_RECORD = "PrescriptionRecord"; + public static final String IMMUNIZATION_RECORD = "ImmunizationRecord"; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/BundleResourceIdentifier.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/BundleResourceIdentifier.java new file mode 100644 index 00000000..e1c012b9 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/BundleResourceIdentifier.java @@ -0,0 +1,36 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.common.constants; + +public class BundleResourceIdentifier { + public static final String PATIENT = "Patient"; + public static final String PRACTITIONER = "Practitioner"; + public static final String ORGANISATION = "Organisation"; + public static final String ENCOUNTER = "Encounter"; + public static final String OBSERVATION = "Observation"; + public static final String CONDITION = "Condition"; + public static final String COMPOSITION = "Composition"; + public static final String MEDICATION_REQUEST = "MedicationRequest"; + public static final String BINARY = "Binary"; + public static final String ALLERGY_INTOLERANCE = "AllergyIntolerance"; + public static final String MANUFACTURER = "Manufacturer"; + public static final String DOCUMENT_REFERENCE = "DocumentReference"; + public static final String DIAGNOSTIC_REPORT = "DiagnosticReport"; + public static final String CHIEF_COMPLAINTS = "ChiefComplaints"; + public static final String PHYSICAL_EXAMINATION = "PhysicalExamination"; + public static final String PROCEDURE = "Procedure"; + public static final String FAMILY_HISTORY = "FamilyHistory"; + public static final String MEDICAL_HISTORY = "MedicalHistory"; + public static final String IMMUNIZATION = "Immunization"; + public static final String OTHER_OBSERVATIONS = "OtherObservations"; + public static final String REFERRAL = "Referral"; + public static final String FOLLOW_UP = "FollowUp"; + public static final String INVESTIGATION_ADVICE = "InvestigationAdvice"; + public static final String LIFE_STYLE = "LifeStyle"; + public static final String WOMAN_HEALTH = "WomanHealth"; + public static final String GENERAL_ASSESSMENT = "GeneralAssessment"; + public static final String PHYSICAL_ACTIVITY = "PhysicalActivity"; + public static final String BODY_MEASUREMENT = "BodyMeasurement"; + public static final String VITAL_SIGNS = "VitalSigns"; + public static final String MEDICATIONS = "Medications"; + public static final String CARE_PLAN = "CarePlan"; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/BundleUrlIdentifier.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/BundleUrlIdentifier.java new file mode 100644 index 00000000..5db65fe1 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/BundleUrlIdentifier.java @@ -0,0 +1,11 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.common.constants; + +public class BundleUrlIdentifier { + public static final String WRAPPER_URL = "https://ABDM_WRAPPER/bundle"; + public static final String SNOMED_URL = "http://snomed.info/sct"; + public static final String LOINC_URL = "http://loinc.org"; + public static final String FACILITY_URL = "https://facility.abdm.gov.in"; + public static final String HEALTH_ID_URL = "https://healthid.abdm.gov.in"; + public static final String DOCTOR_ID_URL = "https://doctor.abdm.gov.in"; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/ErrorCode.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/ErrorCode.java new file mode 100644 index 00000000..7d9e1296 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/ErrorCode.java @@ -0,0 +1,10 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.common.constants; + +public class ErrorCode { + public static String VALIDATION_ERROR = "1001"; + public static String PARSE_ERROR = "1002"; + public static String INCORRECT_BUNDLE_TYPE = "1003"; + public static String DB_SYNTAX_ERROR = "1004"; + public static String DB_ERROR = "1005"; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/ResourceProfileIdentifier.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/ResourceProfileIdentifier.java new file mode 100644 index 00000000..d8eae526 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/ResourceProfileIdentifier.java @@ -0,0 +1,50 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.common.constants; + +public class ResourceProfileIdentifier { + public static final String PROFILE_BINARY = + "https://nrces.in/ndhm/fhir/r4/StructureDefinition/Binary"; + public static final String PROFILE_ALLERGY_INTOLERANCE = + "https://nrces.in/ndhm/fhir/r4/StructureDefinition/AllergyIntolerance"; + public static final String PROFILE_ALLERGY_INTOLERANCE_SYSTEM = + "http://terminology.hl7.org/CodeSystem/allergyintolerance-clinical"; + public static final String PROFILE_DOCUMENT_BUNDLE = + "https://nrces.in/ndhm/fhir/r4/StructureDefinition/DocumentBundle"; + public static final String PROFILE_BUNDLE_META = + "http://terminology.hl7.org/CodeSystem/v3-Confidentiality"; + public static final String PROFILE_CONDITION = + "https://nrces.in/ndhm/fhir/r4/StructureDefinition/Condition"; + public static final String PROFILE_DIAGNOSTIC_REPORT_LAB = + "https://nrces.in/ndhm/fhir/r4/StructureDefinition/DiagnosticReportLab"; + public static final String PROFILE_DOCUMENT_REFERENCE = + "https://nrces.in/ndhm/fhir/r4/StructureDefinition/DocumentReference"; + public static final String PROFILE_ENCOUNTER = + "https://nrces.in/ndhm/fhir/r4/StructureDefinition/Encounter"; + public static final String PROFILE_FAMILY_MEMBER_HISTORY = + "https://nrces.in/ndhm/fhir/r4/StructureDefinition/FamilyMemberHistory"; + public static final String PROFILE_IMMUNIZATION = + "https://nrces.in/ndhm/fhir/r4/StructureDefinition/Immunization"; + public static final String PROFILE_VACCINE_BRAND_NAME = + "https://nrces.in/ndhm/fhir/r4/StructureDefinition/BrandName"; + public static final String PROFILE_MEDICATION_REQUEST = + "https://nrces.in/ndhm/fhir/r4/StructureDefinition/MedicationRequest"; + public static final String PROFILE_OBSERVATION = + "https://nrces.in/ndhm/fhir/r4/StructureDefinition/Observation"; + public static final String PROFILE_PROVIDER = "http://terminology.hl7.org/CodeSystem/v2-0203"; + public static final String PROFILE_ORGANISATION = + "https://nrces.in/ndhm/fhir/r4/StructureDefinition/Organization"; + public static final String PROFILE_PATIENT = + "https://nrces.in/ndhm/fhir/r4/StructureDefinition/Patient"; + public static final String PROFILE_PRACTITIONER = + "https://nrces.in/ndhm/fhir/r4/StructureDefinition/Practitioner"; + public static final String PROFILE_PROCEDURE = + "https://nrces.in/ndhm/fhir/r4/StructureDefinition/Procedure"; + public static final String PROFILE_SERVICE_REQUEST = + "https://nrces.in/ndhm/fhir/r4/StructureDefinition/ServiceRequest"; + public static final String PROFILE_DIAGNOSTIC_REPORT = + "https://nrces.in/ndhm/fhir/r4/StructureDefinition/DiagnosticReportRecord"; + public static final String PROFILE_HEALTH_DOCUMENT_RECORD = + "https://nrces.in/ndhm/fhir/r4/StructureDefinition/HealthDocumentRecord"; + public static final String PROFILE_PRESCRIPTION_RECORD = + "https://nrces.in/ndhm/fhir/r4/StructureDefinition/PrescriptionRecord"; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/SnomedCodeIdentifier.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/SnomedCodeIdentifier.java new file mode 100644 index 00000000..7a28e61f --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/SnomedCodeIdentifier.java @@ -0,0 +1,32 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.common.constants; + +import java.util.*; + +public class SnomedCodeIdentifier { + public static final String SNOMED_ALLERGY_INTOLERANCE = "609328004"; + public static final String SNOMED_DIAGNOSTIC_LAB = "261665006"; + public static final String SNOMED_UNKNOWN = "261665006"; + public static final String LOINC_UNKNOWN = "LL3865-4"; + public static final String SNOMED_MEDICATIONS = "Medications"; + public static final String SNOMED_DIAGNOSTICS = "Diagnostics"; + public static final String SNOMED_VACCINES = "Vaccines"; + public static final String SNOMED_OBSERVATIONS = "Observations"; + public static final String SNOMED_SPECIMEN = "Specimen"; + public static final String SNOMED_CONDITION = "Condition"; + public static final String SNOMED_PROCEDURE = "Procedure"; + public static final String SNOMED_MEDICATION_ROUTE = "Medication-Route"; + public static final String SNOMED_ENCOUNTER_AMBULATORY = "AMB"; + public static final String SNOMED_ENCOUNTER = "Encounter"; + public static final String CATEGORY = "Category"; + public static final List availableSnomed = + Arrays.asList( + SNOMED_CONDITION, + SNOMED_PROCEDURE, + SNOMED_ENCOUNTER, + SNOMED_MEDICATION_ROUTE, + SNOMED_MEDICATIONS, + SNOMED_OBSERVATIONS, + SNOMED_SPECIMEN, + SNOMED_VACCINES); +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/WellnessFieldIdentifiers.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/WellnessFieldIdentifiers.java new file mode 100644 index 00000000..134cd630 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/WellnessFieldIdentifiers.java @@ -0,0 +1,119 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.common.constants; + +import java.util.HashMap; +import java.util.Map; + +public class WellnessFieldIdentifiers { + private static final HashMap vitalSigns = new HashMap<>(); + private static final HashMap bodyMeasurement = new HashMap<>(); + private static final HashMap physicalActivity = new HashMap<>(); + private static final HashMap generalAssessment = new HashMap<>(); + private static final HashMap womanHealth = new HashMap<>(); + private static final HashMap lifeStyle = new HashMap<>(); + + private static final Map> categoryMap = new HashMap<>(); + + static { + categoryMap.put(BundleFieldIdentifier.VITAL_SIGNS, vitalSigns); + categoryMap.put(BundleFieldIdentifier.BODY_MEASUREMENT, bodyMeasurement); + categoryMap.put(BundleFieldIdentifier.PHYSICAL_ACTIVITY, physicalActivity); + categoryMap.put(BundleFieldIdentifier.GENERAL_ASSESSMENT, generalAssessment); + categoryMap.put(BundleFieldIdentifier.WOMAN_HEALTH, womanHealth); + categoryMap.put(BundleFieldIdentifier.LIFE_STYLE, lifeStyle); + // VitalSigns + HashMap vitals = new HashMap<>(); + vitalSigns.put("system", BundleUrlIdentifier.LOINC_URL); + vitals.put("Body surface temperature", "61008-9"); + vitals.put("Respiratory rate", "9279-1"); + vitals.put("Heart rate", "8867-4"); + vitals.put("Oxygen saturation in Arterial blood", "2708-6"); + vitals.put("Blood pressure panel with all children optional", "85354-9"); + vitalSigns.putAll(vitals); + + // Body Measurement + HashMap measurement = new HashMap<>(); + measurement.put("system", BundleUrlIdentifier.LOINC_URL); + measurement.put("Body mass index (BMI) [Ratio]", "39156-5"); + measurement.put("Body weight", "29463-7"); + measurement.put("Body height", "8302-2"); + measurement.put("Circumference Neck", "56074-8"); + measurement.put("Waist Circumference at umbilicus by Tape measure", "8280-0"); + measurement.put("Circumference Mid upper arm - right", "56072-2"); + bodyMeasurement.putAll(measurement); + + // Physical Activity + HashMap pActivity = new HashMap<>(); + pActivity.put("system", BundleUrlIdentifier.LOINC_URL); + pActivity.put("Number of steps in unspecified time Pedometer", "55423-8"); + pActivity.put("Sleep duration", "93832-4"); + pActivity.put("Calories burned", "41981-2"); + pActivity.put("Activity level [Acceleration]", "80493-0"); + physicalActivity.putAll(pActivity); + + // General Assessment + HashMap assessment = new HashMap<>(); + assessment.put("system", BundleUrlIdentifier.LOINC_URL); + assessment.put("Glucose [Mass/volume] in Blood", "2339-0"); + assessment.put("Fasting glucose [Mass/volume] in Capillary blood by Glucometer", "41604-0"); + assessment.put("Glucose [Moles/volume] in Capillary blood by Glucometer", "14743-9"); + assessment.put("Glucose [Moles/volume] in Capillary blood --2 hours post meal", "14760-3"); + assessment.put("Body fat [Mass] Calculated", "73708-0"); + assessment.put("12 lead EKG panel", "34534-8"); + assessment.put("Fluid intake oral Estimated", "8999-5"); + assessment.put("Calorie intake total", "9052-2"); + assessment.put("Metabolic rate --resting", "69429-9"); + assessment.put( + "Oxygen consumption (VO2)/Body weight [Volume Rate Content] --peak during exercise", + "94122-9"); + assessment.put("Mental status", "8693-4"); + generalAssessment.putAll(assessment); + + // Woman Health + HashMap wHealth = new HashMap<>(); + wHealth.put("system", BundleUrlIdentifier.LOINC_URL); + wHealth.put("Ovulation date", "11976-8"); + wHealth.put("Number of menstrual periods per year", "92656-8"); + wHealth.put("Age at menarche", "42798-9"); + wHealth.put("Age at menopause", "42802-9"); + wHealth.put("Last menstrual period start date", "8665-2"); + womanHealth.putAll(wHealth); + + // LifeStyle + HashMap observationLifeStyle = new HashMap<>(); + observationLifeStyle.put("system", BundleUrlIdentifier.SNOMED_URL); + observationLifeStyle.put("Finding relating to alcohol drinking behavior", "228273003"); + observationLifeStyle.put("Tobacco smoking behavior - finding", "365981007"); + observationLifeStyle.put("Finding relating to tobacco chewing", "228509002"); + observationLifeStyle.put("Diet", "41829006"); + lifeStyle.putAll(observationLifeStyle); + } + + public static String getVitals(String type) { + return vitalSigns.get(type) != null ? vitalSigns.get(type) : "LL3865-4"; + } + + public static String getBodyMeasurement(String type) { + return bodyMeasurement.get(type) != null ? bodyMeasurement.get(type) : "LL3865-4"; + } + + public static String getPhysicalActivity(String type) { + return physicalActivity.get(type) != null ? physicalActivity.get(type) : "LL3865-4"; + } + + public static String getGeneralAssessment(String type) { + return generalAssessment.get(type) != null ? generalAssessment.get(type) : "LL3865-4"; + } + + public static String getWomanHealth(String type) { + return womanHealth.get(type) != null ? womanHealth.get(type) : "LL3865-4"; + } + + public static String getLifeStyle(String type) { + return lifeStyle.get(type) != null ? lifeStyle.get(type) : "261665006"; + } + + public static String getSystem(String type) { + return categoryMap.get(type).get(BundleFieldIdentifier.SYSTEM); + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/BundleResponse.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/BundleResponse.java new file mode 100644 index 00000000..cd511512 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/BundleResponse.java @@ -0,0 +1,17 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.common.helpers; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.hl7.fhir.r4.model.Bundle; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class BundleResponse { + private ErrorResponse error; + private Bundle bundle; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/DateRange.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/DateRange.java new file mode 100644 index 00000000..cac6a968 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/DateRange.java @@ -0,0 +1,16 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.common.helpers; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class DateRange { + private String from; + private String to; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/DocumentResource.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/DocumentResource.java new file mode 100644 index 00000000..88f03ae5 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/DocumentResource.java @@ -0,0 +1,23 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.common.helpers; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@AllArgsConstructor +@Data +@Builder +public class DocumentResource { + @NotBlank(message = "contentType is mandatory") + private String contentType; + + @NotBlank(message = "type is mandatory") + private String type; + + @NotNull(message = "data is mandatory") private byte[] data; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/ErrorResponse.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/ErrorResponse.java new file mode 100644 index 00000000..da6c07ef --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/ErrorResponse.java @@ -0,0 +1,16 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.common.helpers; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ErrorResponse { + public String code; + public String message; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/FacadeError.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/FacadeError.java new file mode 100644 index 00000000..24f61797 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/FacadeError.java @@ -0,0 +1,19 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.common.helpers; + +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +public class FacadeError { + private String description; + private ErrorResponse error; + private ValidationErrorResponse validationErrors; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/FieldErrorsResponse.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/FieldErrorsResponse.java new file mode 100644 index 00000000..203126ac --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/FieldErrorsResponse.java @@ -0,0 +1,16 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.common.helpers; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class FieldErrorsResponse { + private String field; + private String message; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/OrganisationResource.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/OrganisationResource.java new file mode 100644 index 00000000..b2b78b54 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/OrganisationResource.java @@ -0,0 +1,18 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.common.helpers; + +import com.nha.abdm.fhir.mapper.rest.exceptions.NotBlankFields; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@AllArgsConstructor +@Data +@Builder +@NotBlankFields +public class OrganisationResource { + private String facilityName; + private String facilityId; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/PatientResource.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/PatientResource.java new file mode 100644 index 00000000..a446eae3 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/PatientResource.java @@ -0,0 +1,31 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.common.helpers; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Pattern; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@AllArgsConstructor +@Data +@Builder +public class PatientResource { + @NotBlank(message = "name of the patient is mandatory") + private String name; + + @NotBlank(message = "patientReference of the patient is mandatory") + private String patientReference; + + @Pattern( + regexp = "^(?i)(male|female|other|unknown)$", + message = "gender must be male, female, other, unknown") + private String gender; + + @Pattern( + regexp = "^\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])$", + message = "birthDate must be in format YYYY-MM-DD.") + private String birthDate; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/PractitionerResource.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/PractitionerResource.java new file mode 100644 index 00000000..b57440cb --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/PractitionerResource.java @@ -0,0 +1,19 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.common.helpers; + +import jakarta.validation.constraints.NotBlank; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@AllArgsConstructor +@Data +@Builder +public class PractitionerResource { + @NotBlank(message = "Name of the practitioner is mandatory") + private String name; + + private String practitionerId; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/SnomedResponse.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/SnomedResponse.java new file mode 100644 index 00000000..ae8c941e --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/SnomedResponse.java @@ -0,0 +1,28 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.common.helpers; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.nha.abdm.fhir.mapper.rest.database.h2.tables.*; +import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +public class SnomedResponse { + public String message; + public List snomedConditionProcedureCodes; + public List snomedDiagnosticCodes; + public List snomedEncounterCodes; + public List snomedMedicineRouteCodes; + public List snomedMedicineCodes; + public List snomedObservationCodes; + public List snomedSpecimenCodes; + public List snomedVaccineCodes; + public List availableSnomed; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/ValidationErrorResponse.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/ValidationErrorResponse.java new file mode 100644 index 00000000..d5f81057 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/helpers/ValidationErrorResponse.java @@ -0,0 +1,18 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.common.helpers; + +import java.util.ArrayList; +import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ValidationErrorResponse { + public String code; + @Builder.Default private List error = new ArrayList<>(); +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/controller/BundleController.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/controller/BundleController.java new file mode 100644 index 00000000..f6b36a2a --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/controller/BundleController.java @@ -0,0 +1,181 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.controller; + +import ca.uhn.fhir.context.FhirContext; +import com.nha.abdm.fhir.mapper.rest.common.helpers.BundleResponse; +import com.nha.abdm.fhir.mapper.rest.common.helpers.FacadeError; +import com.nha.abdm.fhir.mapper.rest.converter.*; +import com.nha.abdm.fhir.mapper.rest.database.h2.services.SnomedService; +import com.nha.abdm.fhir.mapper.rest.requests.*; +import jakarta.validation.Valid; +import java.text.ParseException; +import java.util.Objects; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping(path = "/v1/bundle") +@Validated +public class BundleController { + @Autowired ImmunizationConverter immunizationConverter; + @Autowired PrescriptionConverter prescriptionConverter; + @Autowired HealthDocumentConverter healthDocumentConverter; + @Autowired OPConsultationConverter opConsultationConverter; + @Autowired DiagnosticReportConverter diagnosticReportConverter; + @Autowired DischargeSummaryConverter dischargeSummaryConverter; + @Autowired WellnessRecordConverter wellnessRecordConverter; + @Autowired SnomedService snomedService; + FhirContext ctx = FhirContext.forR4(); + + /** + * @param immunizationRequest which has immunization details like vaccine and type of vaccine + * @return FHIR bundle if no error found + * @throws ParseException while parsing the string into date + */ + @PostMapping("/immunization") + public Object createImmunizationBundle( + @Valid @RequestBody ImmunizationRequest immunizationRequest) throws ParseException { + + BundleResponse bundleResponse = + immunizationConverter.makeImmunizationBundle(immunizationRequest); + + if (Objects.nonNull(bundleResponse.getError())) + return ResponseEntity.badRequest() + .contentType(MediaType.APPLICATION_JSON) + .body(FacadeError.builder().error(bundleResponse.getError()).build()); + return ResponseEntity.status(HttpStatus.CREATED) + .contentType(MediaType.APPLICATION_JSON) + .body(ctx.newJsonParser().encodeResourceToString(bundleResponse.getBundle())); + } + + /** + * @param prescriptionRequest which has prescription details like medicine and dosage + * @return FHIR bundle if no error found + * @throws ParseException while parsing the string into date + */ + @PostMapping("/prescription") + public ResponseEntity createPrescriptionBundle( + @Valid @RequestBody PrescriptionRequest prescriptionRequest) throws ParseException { + + BundleResponse bundleResponse = + prescriptionConverter.convertToPrescriptionBundle(prescriptionRequest); + + if (Objects.nonNull(bundleResponse.getError())) + return ResponseEntity.badRequest() + .contentType(MediaType.APPLICATION_JSON) + .body(FacadeError.builder().error(bundleResponse.getError()).build()); + return ResponseEntity.status(HttpStatus.CREATED) + .contentType(MediaType.APPLICATION_JSON) + .body(ctx.newJsonParser().encodeResourceToString(bundleResponse.getBundle())); + } + + /** + * @param opConsultationRequest which has all basic details of the visit + * @return FHIR bundle if no error found + * @throws ParseException while parsing the string into date + */ + @PostMapping("/op-consultation") + public ResponseEntity createOPConsultationBundle( + @Valid @RequestBody OPConsultationRequest opConsultationRequest) throws ParseException { + + BundleResponse bundleResponse = + opConsultationConverter.convertToOPConsultationBundle(opConsultationRequest); + + if (Objects.nonNull(bundleResponse.getError())) + return ResponseEntity.badRequest() + .contentType(MediaType.APPLICATION_JSON) + .body(FacadeError.builder().error(bundleResponse.getError()).build()); + return ResponseEntity.status(HttpStatus.CREATED) + .contentType(MediaType.APPLICATION_JSON) + .body(ctx.newJsonParser().encodeResourceToString(bundleResponse.getBundle())); + } + + /** + * @param healthDocumentRecord which has document as an attachment + * @return FHIR bundle if no error found + * @throws ParseException while parsing the string into date + */ + @PostMapping("/health-document") + public ResponseEntity createHealthDocumentBundle( + @Valid @RequestBody HealthDocumentRecord healthDocumentRecord) throws ParseException { + + BundleResponse bundleResponse = + healthDocumentConverter.convertToHealthDocumentBundle(healthDocumentRecord); + + if (Objects.nonNull(bundleResponse.getError())) + return ResponseEntity.badRequest() + .contentType(MediaType.APPLICATION_JSON) + .body(FacadeError.builder().error(bundleResponse.getError()).build()); + return ResponseEntity.status(HttpStatus.CREATED) + .contentType(MediaType.APPLICATION_JSON) + .body(ctx.newJsonParser().encodeResourceToString(bundleResponse.getBundle())); + } + + /** + * @param diagnosticReportRequest which has diagnostic details like the result and type of + * diagnosis + * @return FHIR bundle if no error found + * @throws ParseException while parsing the string into date + */ + @PostMapping(value = "/diagnostic-report") + public ResponseEntity createDiagnosticReportBundle( + @Valid @RequestBody DiagnosticReportRequest diagnosticReportRequest) throws ParseException { + + BundleResponse bundleResponse = + diagnosticReportConverter.convertToDiagnosticBundle(diagnosticReportRequest); + + if (Objects.nonNull(bundleResponse.getError())) + return ResponseEntity.badRequest() + .contentType(MediaType.APPLICATION_JSON) + .body(FacadeError.builder().error(bundleResponse.getError()).build()); + return ResponseEntity.status(HttpStatus.CREATED) + .contentType(MediaType.APPLICATION_JSON) + .body(ctx.newJsonParser().encodeResourceToString(bundleResponse.getBundle())); + } + + /** + * @param dischargeSummaryRequest which has discharge details like the findings and observations + * @return FHIR bundle if no error found + * @throws ParseException while parsing the string into date + */ + @PostMapping("/discharge-summary") + public ResponseEntity createDischargeSummaryBundle( + @Valid @RequestBody DischargeSummaryRequest dischargeSummaryRequest) throws ParseException { + + BundleResponse bundleResponse = + dischargeSummaryConverter.convertToDischargeSummary(dischargeSummaryRequest); + + if (Objects.nonNull(bundleResponse.getError())) + return ResponseEntity.badRequest() + .contentType(MediaType.APPLICATION_JSON) + .body(FacadeError.builder().error(bundleResponse.getError()).build()); + return ResponseEntity.status(HttpStatus.CREATED) + .contentType(MediaType.APPLICATION_JSON) + .body(ctx.newJsonParser().encodeResourceToString(bundleResponse.getBundle())); + } + + /** + * @param wellnessRecordRequest which has all the physical observations + * @return FHIR bundle if no error found + * @throws ParseException while parsing the string into date + */ + @PostMapping("/wellness-record") + public ResponseEntity createWellnessBundle( + @Valid @RequestBody WellnessRecordRequest wellnessRecordRequest) { + + BundleResponse bundleResponse = + wellnessRecordConverter.getWellnessBundle(wellnessRecordRequest); + + if (Objects.nonNull(bundleResponse.getError())) + return ResponseEntity.badRequest() + .contentType(MediaType.APPLICATION_JSON) + .body(FacadeError.builder().error(bundleResponse.getError()).build()); + return ResponseEntity.status(HttpStatus.CREATED) + .contentType(MediaType.APPLICATION_JSON) + .body(ctx.newJsonParser().encodeResourceToString(bundleResponse.getBundle())); + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/controller/SnomedController.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/controller/SnomedController.java new file mode 100644 index 00000000..9f24eaf3 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/controller/SnomedController.java @@ -0,0 +1,45 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.controller; + +import com.nha.abdm.fhir.mapper.rest.common.constants.SnomedCodeIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.helpers.SnomedResponse; +import com.nha.abdm.fhir.mapper.rest.database.h2.services.SnomedService; +import java.util.Objects; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping(path = "/v1/snomed") +public class SnomedController { + @Autowired SnomedService snomedService; + + /** + * Returns all the available snomed codes + * + * @param resource + * @return + */ + @GetMapping({"/{resource}"}) + public ResponseEntity getSnomedCodes(@PathVariable("resource") String resource) { + if (SnomedCodeIdentifier.availableSnomed.contains(resource)) { + SnomedResponse snomedResponse = snomedService.getSnomedCodes(resource); + if (Objects.nonNull(snomedResponse)) { + snomedResponse.setMessage("Retrieved"); + return ResponseEntity.ok().body(snomedResponse); + } else { + snomedResponse.setMessage("Empty Codes"); + return ResponseEntity.badRequest().body(snomedResponse); + } + } else + return ResponseEntity.badRequest() + .body( + SnomedResponse.builder() + .message("Invalid Resource") + .availableSnomed(SnomedCodeIdentifier.availableSnomed) + .build()); + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/DiagnosticReportConverter.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/DiagnosticReportConverter.java new file mode 100644 index 00000000..42a7a08a --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/DiagnosticReportConverter.java @@ -0,0 +1,211 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.converter; + +import com.nha.abdm.fhir.mapper.Utils; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleCompositionIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.ErrorCode; +import com.nha.abdm.fhir.mapper.rest.common.helpers.BundleResponse; +import com.nha.abdm.fhir.mapper.rest.common.helpers.ErrorResponse; +import com.nha.abdm.fhir.mapper.rest.dto.compositions.MakeDiagnosticComposition; +import com.nha.abdm.fhir.mapper.rest.dto.resources.*; +import com.nha.abdm.fhir.mapper.rest.exceptions.StreamUtils; +import com.nha.abdm.fhir.mapper.rest.requests.DiagnosticReportRequest; +import java.text.ParseException; +import java.util.*; +import org.hl7.fhir.r4.model.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.dao.InvalidDataAccessResourceUsageException; +import org.springframework.stereotype.Service; + +@Service +public class DiagnosticReportConverter { + private static final Logger log = LoggerFactory.getLogger(DiagnosticReportConverter.class); + private final MakeOrganisationResource makeOrganisationResource; + private final MakeBundleMetaResource makeBundleMetaResource; + + private final MakePatientResource makePatientResource; + + private final MakePractitionerResource makePractitionerResource; + private final MakeDocumentResource makeDocumentResource; + private final MakeObservationResource makeObservationResource; + private final MakeDiagnosticLabResource makeDiagnosticLabResource; + private final MakeEncounterResource makeEncounterResource; + private final MakeDiagnosticComposition makeDiagnosticComposition; + + public DiagnosticReportConverter( + MakeOrganisationResource makeOrganisationResource, + MakeBundleMetaResource makeBundleMetaResource, + MakePatientResource makePatientResource, + MakePractitionerResource makePractitionerResource, + MakeDocumentResource makeDocumentResource, + MakeObservationResource makeObservationResource, + MakeDiagnosticLabResource makeDiagnosticLabResource, + MakeEncounterResource makeEncounterResource, + MakeDiagnosticComposition makeDiagnosticComposition) { + this.makeOrganisationResource = makeOrganisationResource; + this.makeBundleMetaResource = makeBundleMetaResource; + this.makePatientResource = makePatientResource; + this.makePractitionerResource = makePractitionerResource; + this.makeDocumentResource = makeDocumentResource; + this.makeObservationResource = makeObservationResource; + this.makeDiagnosticLabResource = makeDiagnosticLabResource; + this.makeEncounterResource = makeEncounterResource; + this.makeDiagnosticComposition = makeDiagnosticComposition; + } + + public BundleResponse convertToDiagnosticBundle(DiagnosticReportRequest diagnosticReportRequest) + throws ParseException { + try { + if (diagnosticReportRequest == null) { + return BundleResponse.builder() + .error(ErrorResponse.builder().code("1001").message("Request is null").build()) + .build(); + } + + // Initialize bundle entries + List entries = new ArrayList<>(); + + // Organization resource + Organization organization = + makeOrganisationResource.getOrganization(diagnosticReportRequest.getOrganisation()); + + // Patient resource + Patient patient = makePatientResource.getPatient(diagnosticReportRequest.getPatient()); + + // Practitioners + List practitionerList = + Optional.ofNullable(diagnosticReportRequest.getPractitioners()) + .orElse(Collections.emptyList()) + .stream() + .map(StreamUtils.wrapException(makePractitionerResource::getPractitioner)) + .toList(); + + // Encounter resource + Encounter encounter = + makeEncounterResource.getEncounter( + patient, + diagnosticReportRequest.getEncounter(), + diagnosticReportRequest.getVisitDate()); + + // Diagnostic Reports and Observations + List diagnosticReportList = new ArrayList<>(); + List diagnosticObservationList = new ArrayList<>(); + Optional.ofNullable(diagnosticReportRequest.getDiagnostics()) + .orElse(Collections.emptyList()) + .forEach( + diagnosticResource -> { + List observationList = + Optional.ofNullable(diagnosticResource.getResult()) + .orElse(Collections.emptyList()) + .stream() + .map( + StreamUtils.wrapException( + observationResource -> { + return makeObservationResource.getObservation( + patient, practitionerList, observationResource); + })) + .peek(diagnosticObservationList::add) + .toList(); + + try { + diagnosticReportList.add( + makeDiagnosticLabResource.getDiagnosticReport( + patient, + practitionerList, + observationList, + encounter, + diagnosticResource)); + } catch (ParseException e) { + throw new RuntimeException(e); + } + }); + + // Document References + List documentReferenceList = + Optional.ofNullable(diagnosticReportRequest.getDocuments()) + .orElse(Collections.emptyList()) + .stream() + .map( + StreamUtils.wrapException( + documentResource -> { + return makeDocumentResource.getDocument( + patient, + organization, + documentResource, + BundleCompositionIdentifier.DIAGNOSTIC_STUDIES_REPORT_CODE, + documentResource.getType()); + })) + .toList(); + + // Composition resource + Composition composition = + makeDiagnosticComposition.makeCompositionResource( + patient, + diagnosticReportRequest.getVisitDate(), + practitionerList, + organization, + encounter, + diagnosticReportList, + documentReferenceList); + + // Build the bundle + Bundle bundle = new Bundle(); + bundle.setId(UUID.randomUUID().toString()); + bundle.setType(Bundle.BundleType.DOCUMENT); + bundle.setTimestampElement(Utils.getCurrentTimeStamp()); + bundle.setMeta(makeBundleMetaResource.getMeta()); + bundle.setIdentifier( + new Identifier() + .setSystem(BundleUrlIdentifier.WRAPPER_URL) + .setValue(diagnosticReportRequest.getCareContextReference())); + + // Add entries to the bundle + addBundleEntry(entries, composition, BundleResourceIdentifier.COMPOSITION); + addBundleEntry(entries, patient, BundleResourceIdentifier.PATIENT); + practitionerList.forEach( + practitioner -> + addBundleEntry(entries, practitioner, BundleResourceIdentifier.PRACTITIONER)); + addBundleEntry(entries, organization, BundleResourceIdentifier.ORGANISATION); + addBundleEntry(entries, encounter, BundleResourceIdentifier.ENCOUNTER); + diagnosticReportList.forEach( + report -> addBundleEntry(entries, report, BundleResourceIdentifier.DIAGNOSTIC_REPORT)); + diagnosticObservationList.forEach( + observation -> + addBundleEntry(entries, observation, BundleResourceIdentifier.OBSERVATION)); + documentReferenceList.forEach( + document -> + addBundleEntry(entries, document, BundleResourceIdentifier.DOCUMENT_REFERENCE)); + + bundle.setEntry(entries); + + return BundleResponse.builder().bundle(bundle).build(); + + } catch (Exception e) { + if (e instanceof InvalidDataAccessResourceUsageException) { + log.error(e.getMessage()); + return BundleResponse.builder() + .error( + new ErrorResponse( + ErrorCode.DB_ERROR, + " JDBCException Generic SQL Related Error, kindly check logs.")) + .build(); + } + return BundleResponse.builder() + .error(ErrorResponse.builder().code("1000").message(e.getMessage()).build()) + .build(); + } + } + + private void addBundleEntry( + List entries, Resource resource, String resourceIdentifier) { + if (resource != null && resource.getId() != null) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(resourceIdentifier + "/" + resource.getId()) + .setResource(resource)); + } + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/DischargeSummaryConverter.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/DischargeSummaryConverter.java new file mode 100644 index 00000000..7b47f43d --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/DischargeSummaryConverter.java @@ -0,0 +1,453 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.converter; + +import com.nha.abdm.fhir.mapper.Utils; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleCompositionIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.ErrorCode; +import com.nha.abdm.fhir.mapper.rest.common.helpers.BundleResponse; +import com.nha.abdm.fhir.mapper.rest.common.helpers.DocumentResource; +import com.nha.abdm.fhir.mapper.rest.common.helpers.ErrorResponse; +import com.nha.abdm.fhir.mapper.rest.dto.compositions.MakeDischargeComposition; +import com.nha.abdm.fhir.mapper.rest.dto.resources.*; +import com.nha.abdm.fhir.mapper.rest.exceptions.StreamUtils; +import com.nha.abdm.fhir.mapper.rest.requests.DischargeSummaryRequest; +import com.nha.abdm.fhir.mapper.rest.requests.helpers.*; +import java.text.ParseException; +import java.util.*; +import java.util.stream.Collectors; +import org.hl7.fhir.r4.model.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.dao.InvalidDataAccessResourceUsageException; +import org.springframework.stereotype.Service; + +@Service +public class DischargeSummaryConverter { + private static final Logger log = LoggerFactory.getLogger(DischargeSummaryConverter.class); + private final MakeOrganisationResource makeOrganisationResource; + private final MakeBundleMetaResource makeBundleMetaResource; + + private final MakePatientResource makePatientResource; + + private final MakePractitionerResource makePractitionerResource; + private final MakeConditionResource makeConditionResource; + private final MakeObservationResource makeObservationResource; + private final MakeAllergyToleranceResource makeAllergyToleranceResource; + private final MakeFamilyMemberResource makeFamilyMemberResource; + private final MakeDocumentResource makeDocumentResource; + private final MakeEncounterResource makeEncounterResource; + private final MakeMedicationRequestResource makeMedicationRequestResource; + private final MakeDiagnosticLabResource makeDiagnosticLabResource; + private final MakeProcedureResource makeProcedureResource; + private final MakeDischargeComposition makeDischargeComposition; + private final MakeCarePlanResource makeCarePlanResource; + + public DischargeSummaryConverter( + MakeOrganisationResource makeOrganisationResource, + MakeBundleMetaResource makeBundleMetaResource, + MakePatientResource makePatientResource, + MakePractitionerResource makePractitionerResource, + MakeConditionResource makeConditionResource, + MakeObservationResource makeObservationResource, + MakeServiceRequestResource makeServiceRequestResource, + MakeAllergyToleranceResource makeAllergyToleranceResource, + MakeFamilyMemberResource makeFamilyMemberResource, + MakeDocumentResource makeDocumentResource, + MakeEncounterResource makeEncounterResource, + MakeMedicationRequestResource makeMedicationRequestResource, + MakeDiagnosticLabResource makeDiagnosticLabResource, + MakeProcedureResource makeProcedureResource, + MakeDischargeComposition makeDischargeComposition, + MakeCarePlanResource makeCarePlanResource) { + this.makeOrganisationResource = makeOrganisationResource; + this.makeBundleMetaResource = makeBundleMetaResource; + this.makePatientResource = makePatientResource; + this.makePractitionerResource = makePractitionerResource; + this.makeConditionResource = makeConditionResource; + this.makeObservationResource = makeObservationResource; + this.makeAllergyToleranceResource = makeAllergyToleranceResource; + this.makeFamilyMemberResource = makeFamilyMemberResource; + this.makeDocumentResource = makeDocumentResource; + this.makeEncounterResource = makeEncounterResource; + this.makeMedicationRequestResource = makeMedicationRequestResource; + this.makeDiagnosticLabResource = makeDiagnosticLabResource; + this.makeProcedureResource = makeProcedureResource; + this.makeDischargeComposition = makeDischargeComposition; + this.makeCarePlanResource = makeCarePlanResource; + } + + public BundleResponse convertToDischargeSummary(DischargeSummaryRequest dischargeSummaryRequest) + throws ParseException { + try { + + List entries = new ArrayList<>(); + + Organization organization = + makeOrganisationResource.getOrganization(dischargeSummaryRequest.getOrganisation()); + + Patient patient = makePatientResource.getPatient(dischargeSummaryRequest.getPatient()); + + List practitionerList = + Optional.ofNullable(dischargeSummaryRequest.getPractitioners()) + .orElse(Collections.emptyList()) + .stream() + .map(StreamUtils.wrapException(makePractitionerResource::getPractitioner)) + .collect(Collectors.toList()); + + Encounter encounter = + makeEncounterResource.getEncounter( + patient, + dischargeSummaryRequest.getEncounter() != null + ? dischargeSummaryRequest.getEncounter() + : null, + dischargeSummaryRequest.getAuthoredOn()); + List chiefComplaintList = + dischargeSummaryRequest.getChiefComplaints() != null + ? makeCheifComplaintsList(dischargeSummaryRequest, patient) + : new ArrayList<>(); + List physicalObservationList = + dischargeSummaryRequest.getPhysicalExaminations() != null + ? makePhysicalObservations(dischargeSummaryRequest, patient, practitionerList) + : new ArrayList<>(); + List allergieList = + dischargeSummaryRequest.getAllergies() != null + ? makeAllergiesList(patient, practitionerList, dischargeSummaryRequest) + : new ArrayList<>(); + List medicalHistoryList = + dischargeSummaryRequest.getMedicalHistories() != null + ? makeMedicalHistoryList(dischargeSummaryRequest, patient) + : new ArrayList<>(); + List familyMemberHistoryList = + dischargeSummaryRequest.getFamilyHistories() != null + ? makeFamilyMemberHistory(patient, dischargeSummaryRequest) + : new ArrayList<>(); + List medicationList = new ArrayList<>(); + List medicationConditionList = new ArrayList<>(); + for (PrescriptionResource prescriptionResource : dischargeSummaryRequest.getMedications()) { + Condition medicationCondition = + prescriptionResource.getReason() != null + ? makeConditionResource.getCondition( + prescriptionResource.getReason(), + patient, + dischargeSummaryRequest.getAuthoredOn(), + null) + : null; + medicationList.add( + makeMedicationRequestResource.getMedicationResource( + dischargeSummaryRequest.getAuthoredOn(), + prescriptionResource, + medicationCondition, + organization, + practitionerList, + patient)); + if (medicationCondition != null) { + medicationConditionList.add(medicationCondition); + } + } + // Diagnostic Reports and Observations + List diagnosticReportList = new ArrayList<>(); + List diagnosticObservationList = new ArrayList<>(); + Optional.ofNullable(dischargeSummaryRequest.getDiagnostics()) + .orElse(Collections.emptyList()) + .forEach( + diagnosticResource -> { + List observationList = + Optional.ofNullable(diagnosticResource.getResult()) + .orElse(Collections.emptyList()) + .stream() + .map( + StreamUtils.wrapException( + observationResource -> { + return makeObservationResource.getObservation( + patient, practitionerList, observationResource); + })) + .peek(diagnosticObservationList::add) + .toList(); + + try { + diagnosticReportList.add( + makeDiagnosticLabResource.getDiagnosticReport( + patient, + practitionerList, + observationList, + encounter, + diagnosticResource)); + } catch (ParseException e) { + throw new RuntimeException(e); + } + }); + + List procedureList = + dischargeSummaryRequest.getProcedures() != null + ? makeProcedureList(dischargeSummaryRequest, patient) + : new ArrayList<>(); + List documentReferenceList = + Optional.ofNullable(dischargeSummaryRequest.getDocuments()) + .orElse(Collections.emptyList()) + .stream() + .map( + StreamUtils.wrapException( + documentResource -> + makeDocumentReference(patient, organization, documentResource))) + .toList(); + + CarePlan carePlan = + makeCarePlanResource.getCarePlan(dischargeSummaryRequest.getCarePlan(), patient); + + Composition composition = + makeDischargeComposition.makeDischargeCompositionResource( + patient, + dischargeSummaryRequest.getAuthoredOn(), + encounter, + practitionerList, + organization, + chiefComplaintList, + physicalObservationList, + allergieList, + medicationList, + diagnosticReportList, + medicalHistoryList, + familyMemberHistoryList, + carePlan, + procedureList, + documentReferenceList, + BundleCompositionIdentifier.DISCHARGE_SUMMARY_CODE, + BundleCompositionIdentifier.DISCHARGE_SUMMARY); + + Bundle bundle = new Bundle(); + bundle.setId(UUID.randomUUID().toString()); + bundle.setType(Bundle.BundleType.DOCUMENT); + bundle.setTimestampElement(Utils.getCurrentTimeStamp()); + bundle.setMeta(makeBundleMetaResource.getMeta()); + bundle.setIdentifier( + new Identifier() + .setSystem(BundleUrlIdentifier.WRAPPER_URL) + .setValue(dischargeSummaryRequest.getCareContextReference())); + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.COMPOSITION + "/" + composition.getId()) + .setResource(composition)); + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.PATIENT + "/" + patient.getId()) + .setResource(patient)); + for (Practitioner practitioner : practitionerList) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.PRACTITIONER + "/" + practitioner.getId()) + .setResource(practitioner)); + } + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.ENCOUNTER + "/" + encounter.getId()) + .setResource(encounter)); + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.ORGANISATION + "/" + organization.getId()) + .setResource(organization)); + + for (Condition complaint : chiefComplaintList) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.CHIEF_COMPLAINTS + "/" + complaint.getId()) + .setResource(complaint)); + } + for (Observation physicalObservation : physicalObservationList) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl( + BundleResourceIdentifier.PHYSICAL_EXAMINATION + + "/" + + physicalObservation.getId()) + .setResource(physicalObservation)); + } + for (AllergyIntolerance allergyIntolerance : allergieList) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl( + BundleResourceIdentifier.ALLERGY_INTOLERANCE + "/" + allergyIntolerance.getId()) + .setResource(allergyIntolerance)); + } + for (Condition medicalHistory : medicalHistoryList) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.MEDICAL_HISTORY + "/" + medicalHistory.getId()) + .setResource(medicalHistory)); + } + for (Condition medicationCondition : medicationConditionList) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.CONDITION + "/" + medicationCondition.getId()) + .setResource(medicationCondition)); + } + for (FamilyMemberHistory familyMemberHistory : familyMemberHistoryList) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl( + BundleResourceIdentifier.FAMILY_HISTORY + "/" + familyMemberHistory.getId()) + .setResource(familyMemberHistory)); + } + if (Objects.nonNull(carePlan)) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.CARE_PLAN + "/" + carePlan.getId()) + .setResource(carePlan)); + } + for (MedicationRequest medicationRequest : medicationList) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl( + BundleResourceIdentifier.FAMILY_HISTORY + "/" + medicationRequest.getId()) + .setResource(medicationRequest)); + } + + for (DiagnosticReport diagnosticReport : diagnosticReportList) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl( + BundleResourceIdentifier.DIAGNOSTIC_REPORT + "/" + diagnosticReport.getId()) + .setResource(diagnosticReport)); + } + + for (Procedure procedure : procedureList) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.PROCEDURE + "/" + procedure.getId()) + .setResource(procedure)); + } + for (Observation observation : diagnosticObservationList) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.OBSERVATION + "/" + observation.getId()) + .setResource(observation)); + } + for (DocumentReference documentReference : documentReferenceList) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl( + BundleResourceIdentifier.DOCUMENT_REFERENCE + "/" + documentReference.getId()) + .setResource(documentReference)); + } + bundle.setEntry(entries); + return BundleResponse.builder().bundle(bundle).build(); + } catch (Exception e) { + if (e instanceof InvalidDataAccessResourceUsageException) { + log.error(e.getMessage()); + return BundleResponse.builder() + .error( + new ErrorResponse( + ErrorCode.DB_ERROR, + " JDBCException Generic SQL Related Error, kindly check logs.")) + .build(); + } + return BundleResponse.builder() + .error(ErrorResponse.builder().code("1000").message(e.getMessage()).build()) + .build(); + } + } + + private DocumentReference makeDocumentReference( + Patient patient, Organization organization, DocumentResource documentResource) + throws ParseException { + return makeDocumentResource.getDocument( + patient, + organization, + documentResource, + BundleCompositionIdentifier.DISCHARGE_SUMMARY_CODE, + BundleCompositionIdentifier.DISCHARGE_SUMMARY); + } + + private List makeProcedureList( + DischargeSummaryRequest dischargeSummaryRequest, Patient patient) throws ParseException { + + return Optional.ofNullable(dischargeSummaryRequest.getProcedures()) + .orElse(Collections.emptyList()) + .stream() + .map( + StreamUtils.wrapException( + procedureResource -> + makeProcedureResource.getProcedure(patient, procedureResource))) + .toList(); + } + + private List makeFamilyMemberHistory( + Patient patient, DischargeSummaryRequest dischargeSummaryRequest) throws ParseException { + return Optional.ofNullable(dischargeSummaryRequest.getFamilyHistories()) + .orElse(Collections.emptyList()) + .stream() + .map( + StreamUtils.wrapException( + familyObservationResource -> + makeFamilyMemberResource.getFamilyHistory(patient, familyObservationResource))) + .toList(); + } + + private List makeMedicalHistoryList( + DischargeSummaryRequest dischargeSummaryRequest, Patient patient) throws ParseException { + return Optional.ofNullable(dischargeSummaryRequest.getMedicalHistories()) + .orElse(Collections.emptyList()) + .stream() + .map( + StreamUtils.wrapException( + chiefComplaintResource -> + makeConditionResource.getCondition( + chiefComplaintResource.getComplaint(), + patient, + chiefComplaintResource.getRecordedDate(), + chiefComplaintResource.getDateRange()))) + .toList(); + } + + private List makeAllergiesList( + Patient patient, + List practitionerList, + DischargeSummaryRequest dischargeSummaryRequest) + throws ParseException { + return Optional.ofNullable(dischargeSummaryRequest.getAllergies()) + .orElse(Collections.emptyList()) + .stream() + .map( + StreamUtils.wrapException( + allergy -> + makeAllergyToleranceResource.getAllergy( + patient, + practitionerList, + allergy, + dischargeSummaryRequest.getAuthoredOn()))) + .toList(); + } + + private List makePhysicalObservations( + DischargeSummaryRequest dischargeSummaryRequest, + Patient patient, + List practitionerList) + throws ParseException { + return Optional.ofNullable(dischargeSummaryRequest.getPhysicalExaminations()) + .orElse(Collections.emptyList()) + .stream() + .map( + StreamUtils.wrapException( + observationResource -> + makeObservationResource.getObservation( + patient, practitionerList, observationResource))) + .toList(); + } + + private List makeCheifComplaintsList( + DischargeSummaryRequest dischargeSummaryRequest, Patient patient) throws ParseException { + return Optional.ofNullable(dischargeSummaryRequest.getChiefComplaints()) + .orElse(Collections.emptyList()) + .stream() + .map( + StreamUtils.wrapException( + chiefComplaint -> + makeConditionResource.getCondition( + chiefComplaint.getComplaint(), + patient, + chiefComplaint.getRecordedDate(), + chiefComplaint.getDateRange()))) + .toList(); + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/HealthDocumentConverter.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/HealthDocumentConverter.java new file mode 100644 index 00000000..3672a205 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/HealthDocumentConverter.java @@ -0,0 +1,158 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.converter; + +import com.nha.abdm.fhir.mapper.Utils; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleCompositionIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.ErrorCode; +import com.nha.abdm.fhir.mapper.rest.common.helpers.BundleResponse; +import com.nha.abdm.fhir.mapper.rest.common.helpers.ErrorResponse; +import com.nha.abdm.fhir.mapper.rest.dto.compositions.MakeHealthDocumentComposition; +import com.nha.abdm.fhir.mapper.rest.dto.resources.*; +import com.nha.abdm.fhir.mapper.rest.exceptions.StreamUtils; +import com.nha.abdm.fhir.mapper.rest.requests.HealthDocumentRecord; +import java.text.ParseException; +import java.util.*; +import org.hl7.fhir.r4.model.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.dao.InvalidDataAccessResourceUsageException; +import org.springframework.stereotype.Service; + +@Service +public class HealthDocumentConverter { + private static final Logger log = LoggerFactory.getLogger(HealthDocumentConverter.class); + private final MakeOrganisationResource makeOrganisationResource; + private final MakeBundleMetaResource makeBundleMetaResource; + + private final MakePatientResource makePatientResource; + + private final MakePractitionerResource makePractitionerResource; + private final MakeDocumentResource makeDocumentResource; + private final MakeEncounterResource makeEncounterResource; + private final MakeHealthDocumentComposition makeHealthDocumentComposition; + + public HealthDocumentConverter( + MakeOrganisationResource makeOrganisationResource, + MakeBundleMetaResource makeBundleMetaResource, + MakePatientResource makePatientResource, + MakePractitionerResource makePractitionerResource, + MakeDocumentResource makeDocumentResource, + MakeEncounterResource makeEncounterResource, + MakeHealthDocumentComposition makeHealthDocumentComposition) { + this.makeOrganisationResource = makeOrganisationResource; + this.makeBundleMetaResource = makeBundleMetaResource; + this.makePatientResource = makePatientResource; + this.makePractitionerResource = makePractitionerResource; + this.makeDocumentResource = makeDocumentResource; + this.makeEncounterResource = makeEncounterResource; + this.makeHealthDocumentComposition = makeHealthDocumentComposition; + } + + public BundleResponse convertToHealthDocumentBundle(HealthDocumentRecord healthDocumentRecord) + throws ParseException { + try { + Organization organization = + Objects.nonNull(healthDocumentRecord.getOrganisation()) + ? makeOrganisationResource.getOrganization(healthDocumentRecord.getOrganisation()) + : null; + Patient patient = makePatientResource.getPatient(healthDocumentRecord.getPatient()); + List practitionerList = + Optional.ofNullable(healthDocumentRecord.getPractitioners()) + .orElse(Collections.emptyList()) + .stream() + .map(StreamUtils.wrapException(makePractitionerResource::getPractitioner)) + .toList(); + + List documentReferenceList = + Optional.ofNullable(healthDocumentRecord.getDocuments()) + .orElse(Collections.emptyList()) + .stream() + .map( + StreamUtils.wrapException( + documentResource -> + makeDocumentResource.getDocument( + patient, + organization, + documentResource, + BundleCompositionIdentifier.HEALTH_DOCUMENT_CODE, + BundleCompositionIdentifier.HEALTH_DOCUMENT))) + .toList(); + + Encounter encounter = + makeEncounterResource.getEncounter( + patient, + healthDocumentRecord.getEncounter() != null + ? healthDocumentRecord.getEncounter() + : null, + healthDocumentRecord.getAuthoredOn()); + Composition composition = + makeHealthDocumentComposition.makeCompositionResource( + patient, + healthDocumentRecord.getAuthoredOn(), + practitionerList, + organization, + encounter, + documentReferenceList); + Bundle bundle = new Bundle(); + bundle.setId(UUID.randomUUID().toString()); + bundle.setType(Bundle.BundleType.DOCUMENT); + bundle.setTimestampElement(Utils.getCurrentTimeStamp()); + bundle.setMeta(makeBundleMetaResource.getMeta()); + bundle.setIdentifier( + new Identifier() + .setSystem(BundleUrlIdentifier.WRAPPER_URL) + .setValue(healthDocumentRecord.getCareContextReference())); + List entries = new ArrayList<>(); + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.COMPOSITION + "/" + composition.getId()) + .setResource(composition)); + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.PATIENT + "/" + patient.getId()) + .setResource(patient)); + for (Practitioner practitioner : practitionerList) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.PRACTITIONER + "/" + practitioner.getId()) + .setResource(practitioner)); + } + if (Objects.nonNull(organization)) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.ORGANISATION + "/" + organization.getId()) + .setResource(organization)); + } + if (Objects.nonNull(encounter)) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.ENCOUNTER + "/" + encounter.getId()) + .setResource(encounter)); + } + for (DocumentReference documentReference : documentReferenceList) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl( + BundleResourceIdentifier.DOCUMENT_REFERENCE + "/" + documentReference.getId()) + .setResource(documentReference)); + } + bundle.setEntry(entries); + return BundleResponse.builder().bundle(bundle).build(); + } catch (Exception e) { + if (e instanceof InvalidDataAccessResourceUsageException) { + log.error(e.getMessage()); + return BundleResponse.builder() + .error( + new ErrorResponse( + ErrorCode.DB_ERROR, + " JDBCException Generic SQL Related Error, kindly check logs.")) + .build(); + } + return BundleResponse.builder() + .error(ErrorResponse.builder().code("1000").message(e.getMessage()).build()) + .build(); + } + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/ImmunizationConverter.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/ImmunizationConverter.java new file mode 100644 index 00000000..0cbd03b1 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/ImmunizationConverter.java @@ -0,0 +1,192 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.converter; + +import com.nha.abdm.fhir.mapper.Utils; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleCompositionIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.ErrorCode; +import com.nha.abdm.fhir.mapper.rest.common.helpers.BundleResponse; +import com.nha.abdm.fhir.mapper.rest.common.helpers.ErrorResponse; +import com.nha.abdm.fhir.mapper.rest.common.helpers.OrganisationResource; +import com.nha.abdm.fhir.mapper.rest.dto.compositions.MakeImmunizationComposition; +import com.nha.abdm.fhir.mapper.rest.dto.resources.*; +import com.nha.abdm.fhir.mapper.rest.exceptions.StreamUtils; +import com.nha.abdm.fhir.mapper.rest.requests.ImmunizationRequest; +import java.text.ParseException; +import java.util.*; +import org.hl7.fhir.r4.model.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.dao.InvalidDataAccessResourceUsageException; +import org.springframework.stereotype.Service; + +@Service +public class ImmunizationConverter { + private static final Logger log = LoggerFactory.getLogger(ImmunizationConverter.class); + private final MakeDocumentResource makeDocumentReference; + private final MakePatientResource makePatientResource; + private final MakePractitionerResource makePractitionerResource; + private final MakeOrganisationResource makeOrganisationResource; + private final MakeImmunizationResource makeImmunizationResource; + private final MakeBundleMetaResource makeBundleMetaResource; + private final MakeEncounterResource makeEncounterResource; + private final MakeImmunizationComposition makeImmunizationComposition; + + public ImmunizationConverter( + MakeDocumentResource makeDocumentReference, + MakePatientResource makePatientResource, + MakePractitionerResource makePractitionerResource, + MakeOrganisationResource makeOrganisationResource, + MakeImmunizationResource makeImmunizationResource, + MakeBundleMetaResource makeBundleMetaResource, + MakeEncounterResource makeEncounterResource, + MakeImmunizationComposition makeImmunizationComposition) { + this.makeDocumentReference = makeDocumentReference; + this.makePatientResource = makePatientResource; + this.makePractitionerResource = makePractitionerResource; + this.makeOrganisationResource = makeOrganisationResource; + this.makeImmunizationResource = makeImmunizationResource; + this.makeBundleMetaResource = makeBundleMetaResource; + this.makeEncounterResource = makeEncounterResource; + this.makeImmunizationComposition = makeImmunizationComposition; + } + + public BundleResponse makeImmunizationBundle(ImmunizationRequest immunizationRequest) + throws ParseException { + try { + Bundle bundle = new Bundle(); + Patient patient = makePatientResource.getPatient(immunizationRequest.getPatient()); + List practitionerList = + Optional.ofNullable(immunizationRequest.getPractitioners()) + .orElse(Collections.emptyList()) + .stream() + .map(StreamUtils.wrapException(makePractitionerResource::getPractitioner)) + .toList(); + + Organization organization = + makeOrganisationResource.getOrganization(immunizationRequest.getOrganisation()); + Encounter encounter = + makeEncounterResource.getEncounter( + patient, + immunizationRequest.getEncounter() != null + ? immunizationRequest.getEncounter() + : null, + immunizationRequest.getAuthoredOn()); + List manufactureList = new ArrayList<>(); + List immunizationList = + Optional.ofNullable(immunizationRequest.getImmunizations()) + .orElse(Collections.emptyList()) + .stream() + .filter(Objects::nonNull) + .map( + StreamUtils.wrapException( + immunizationResource -> { + Organization manufacturer = + makeOrganisationResource.getOrganization( + OrganisationResource.builder() + .facilityId(immunizationResource.getManufacturer()) + .facilityName(immunizationResource.getManufacturer()) + .build()); + manufactureList.add(manufacturer); + return makeImmunizationResource.getImmunization( + patient, practitionerList, manufacturer, immunizationResource); + })) + .toList(); + + List documentList = + Optional.ofNullable(immunizationRequest.getDocuments()) + .orElse(Collections.emptyList()) + .stream() + .map( + StreamUtils.wrapException( + documentResource -> + makeDocumentReference.getDocument( + patient, + organization, + documentResource, + BundleCompositionIdentifier.IMMUNIZATION_RECORD_CODE, + BundleCompositionIdentifier.IMMUNIZATION_RECORD))) + .toList(); + + Composition composition = + makeImmunizationComposition.makeCompositionResource( + patient, + practitionerList, + organization, + immunizationRequest.getAuthoredOn(), + immunizationList, + documentList); + + bundle.setId(UUID.randomUUID().toString()); + bundle.setType(Bundle.BundleType.DOCUMENT); + bundle.setTimestampElement(Utils.getCurrentTimeStamp()); + bundle.setMeta(makeBundleMetaResource.getMeta()); + List entries = new ArrayList<>(); + bundle.setIdentifier( + new Identifier() + .setSystem(BundleUrlIdentifier.WRAPPER_URL) + .setValue(immunizationRequest.getCareContextReference())); + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.COMPOSITION + "/" + composition.getId()) + .setResource(composition)); + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.PATIENT + "/" + patient.getId()) + .setResource(patient)); + for (Practitioner practitioner : practitionerList) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.PRACTITIONER + "/" + practitioner.getId()) + .setResource(practitioner)); + } + if (Objects.nonNull(organization)) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.ORGANISATION + "/" + organization.getId()) + .setResource(organization)); + } + if (Objects.nonNull(encounter)) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.ENCOUNTER + "/" + encounter.getId()) + .setResource(encounter)); + } + for (Organization manufacturer : manufactureList) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.MANUFACTURER + "/" + manufacturer.getId()) + .setResource(manufacturer)); + } + for (Immunization immunization : immunizationList) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.IMMUNIZATION + "/" + immunization.getId()) + .setResource(immunization)); + } + for (DocumentReference documentReference : documentList) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl( + BundleResourceIdentifier.DOCUMENT_REFERENCE + "/" + documentReference.getId()) + .setResource(documentReference)); + } + bundle.setEntry(entries); + return BundleResponse.builder().bundle(bundle).build(); + } catch (Exception e) { + if (e instanceof InvalidDataAccessResourceUsageException) { + log.error(e.getMessage()); + return BundleResponse.builder() + .error( + new ErrorResponse( + ErrorCode.DB_ERROR, + " JDBCException Generic SQL Related Error, kindly check logs.")) + .build(); + } + return BundleResponse.builder() + .error(ErrorResponse.builder().code("1000").message(e.getMessage()).build()) + .build(); + } + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/OPConsultationConverter.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/OPConsultationConverter.java new file mode 100644 index 00000000..5e40ee4e --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/OPConsultationConverter.java @@ -0,0 +1,501 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.converter; + +import com.nha.abdm.fhir.mapper.Utils; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleCompositionIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.ErrorCode; +import com.nha.abdm.fhir.mapper.rest.common.helpers.BundleResponse; +import com.nha.abdm.fhir.mapper.rest.common.helpers.DocumentResource; +import com.nha.abdm.fhir.mapper.rest.common.helpers.ErrorResponse; +import com.nha.abdm.fhir.mapper.rest.dto.compositions.MakeOpComposition; +import com.nha.abdm.fhir.mapper.rest.dto.resources.*; +import com.nha.abdm.fhir.mapper.rest.exceptions.StreamUtils; +import com.nha.abdm.fhir.mapper.rest.requests.OPConsultationRequest; +import com.nha.abdm.fhir.mapper.rest.requests.helpers.*; +import java.text.ParseException; +import java.util.*; +import org.hl7.fhir.r4.model.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.dao.InvalidDataAccessResourceUsageException; +import org.springframework.stereotype.Service; + +@Service +public class OPConsultationConverter { + private static final Logger log = LoggerFactory.getLogger(OPConsultationConverter.class); + private final MakeOrganisationResource makeOrganisationResource; + private final MakeBundleMetaResource makeBundleMetaResource; + + private final MakePatientResource makePatientResource; + + private final MakePractitionerResource makePractitionerResource; + private final MakeConditionResource makeConditionResource; + private final MakeObservationResource makeObservationResource; + private final MakeServiceRequestResource makeServiceRequestResource; + private final MakeAllergyToleranceResource makeAllergyToleranceResource; + private final MakeFamilyMemberResource makeFamilyMemberResource; + private final MakeDocumentResource makeDocumentResource; + private final MakeEncounterResource makeEncounterResource; + private final MakeMedicationRequestResource makeMedicationRequestResource; + private final MakeProcedureResource makeProcedureResource; + private final MakeOpComposition makeOpComposition; + + public OPConsultationConverter( + MakeOrganisationResource makeOrganisationResource, + MakeBundleMetaResource makeBundleMetaResource, + MakePatientResource makePatientResource, + MakePractitionerResource makePractitionerResource, + MakeConditionResource makeConditionResource, + MakeObservationResource makeObservationResource, + MakeServiceRequestResource makeServiceRequestResource, + MakeAllergyToleranceResource makeAllergyToleranceResource, + MakeFamilyMemberResource makeFamilyMemberResource, + MakeDocumentResource makeDocumentResource, + MakeEncounterResource makeEncounterResource, + MakeMedicationRequestResource makeMedicationRequestResource, + MakeProcedureResource makeProcedureResource, + MakeOpComposition makeOpComposition) { + this.makeOrganisationResource = makeOrganisationResource; + this.makeBundleMetaResource = makeBundleMetaResource; + this.makePatientResource = makePatientResource; + this.makePractitionerResource = makePractitionerResource; + this.makeConditionResource = makeConditionResource; + this.makeObservationResource = makeObservationResource; + this.makeServiceRequestResource = makeServiceRequestResource; + this.makeAllergyToleranceResource = makeAllergyToleranceResource; + this.makeFamilyMemberResource = makeFamilyMemberResource; + this.makeDocumentResource = makeDocumentResource; + this.makeEncounterResource = makeEncounterResource; + this.makeMedicationRequestResource = makeMedicationRequestResource; + this.makeProcedureResource = makeProcedureResource; + this.makeOpComposition = makeOpComposition; + } + + public BundleResponse convertToOPConsultationBundle(OPConsultationRequest opConsultationRequest) + throws ParseException { + try { + Organization organization = + makeOrganisationResource.getOrganization(opConsultationRequest.getOrganisation()); + Patient patient = makePatientResource.getPatient(opConsultationRequest.getPatient()); + List practitionerList = + Optional.ofNullable(opConsultationRequest.getPractitioners()) + .orElse(Collections.emptyList()) + .stream() + .map(StreamUtils.wrapException(makePractitionerResource::getPractitioner)) + .toList(); + Encounter encounter = + makeEncounterResource.getEncounter( + patient, + opConsultationRequest.getEncounter() != null + ? opConsultationRequest.getEncounter() + : null, + opConsultationRequest.getVisitDate()); + List chiefComplaintList = + opConsultationRequest.getChiefComplaints() != null + ? makeCheifComplaintsList(opConsultationRequest, patient) + : new ArrayList<>(); + List physicalObservationList = + opConsultationRequest.getPhysicalExaminations() != null + ? makePhysicalObservations(opConsultationRequest, patient, practitionerList) + : new ArrayList<>(); + List allergieList = + opConsultationRequest.getAllergies() != null + ? makeAllergiesList(patient, practitionerList, opConsultationRequest) + : new ArrayList<>(); + List medicalHistoryList = + opConsultationRequest.getMedicalHistories() != null + ? makeMedicalHistoryList(opConsultationRequest, patient) + : new ArrayList<>(); + List familyMemberHistoryList = + opConsultationRequest.getFamilyHistories() != null + ? makeFamilyMemberHistory(patient, opConsultationRequest) + : new ArrayList<>(); + List investigationAdviceList = + opConsultationRequest.getServiceRequests() != null + ? makeInvestigationAdviceList(opConsultationRequest, patient, practitionerList) + : new ArrayList<>(); + HashMap medicationRequestMap = new HashMap<>(); + List medicationList = new ArrayList<>(); + List medicationConditionList = new ArrayList<>(); + if (Objects.nonNull(opConsultationRequest.getMedications())) { + for (PrescriptionResource prescriptionResource : opConsultationRequest.getMedications()) { + Condition medicationCondition = + prescriptionResource.getReason() != null + ? makeConditionResource.getCondition( + prescriptionResource.getReason(), + patient, + opConsultationRequest.getVisitDate(), + null) + : null; + medicationList.add( + makeMedicationRequestResource.getMedicationResource( + opConsultationRequest.getVisitDate(), + prescriptionResource, + medicationCondition, + organization, + practitionerList, + patient)); + if (medicationCondition != null) { + medicationConditionList.add(medicationCondition); + } + } // TODO + } + List followupList = + opConsultationRequest.getFollowups() != null + ? makeFollowupList(patient, opConsultationRequest) + : new ArrayList<>(); + List procedureList = + opConsultationRequest.getProcedures() != null + ? makeProcedureList(opConsultationRequest, patient) + : new ArrayList<>(); + List referralList = + opConsultationRequest.getReferrals() != null + ? makeReferralList(opConsultationRequest, patient, practitionerList) + : new ArrayList<>(); + List otherObservationList = + opConsultationRequest.getOtherObservations() != null + ? makeOtherObservations(patient, practitionerList, opConsultationRequest) + : new ArrayList<>(); + List documentReferenceList = new ArrayList<>(); + if (Objects.nonNull(opConsultationRequest.getDocuments())) { + for (DocumentResource documentResource : opConsultationRequest.getDocuments()) { + documentReferenceList.add(makeDocumentReference(patient, organization, documentResource)); + } + } + + Composition composition = + makeOpComposition.makeOPCompositionResource( + patient, + opConsultationRequest.getVisitDate(), + encounter, + practitionerList, + organization, + chiefComplaintList, + physicalObservationList, + allergieList, + medicationList, + medicalHistoryList, + familyMemberHistoryList, + investigationAdviceList, + followupList, + procedureList, + referralList, + otherObservationList, + documentReferenceList); + + Bundle bundle = new Bundle(); + bundle.setId(UUID.randomUUID().toString()); + bundle.setType(Bundle.BundleType.DOCUMENT); + bundle.setTimestampElement(Utils.getCurrentTimeStamp()); + bundle.setMeta(makeBundleMetaResource.getMeta()); + bundle.setIdentifier( + new Identifier() + .setSystem(BundleUrlIdentifier.WRAPPER_URL) + .setValue(opConsultationRequest.getCareContextReference())); + List entries = new ArrayList<>(); + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.COMPOSITION + "/" + composition.getId()) + .setResource(composition)); + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.PATIENT + "/" + patient.getId()) + .setResource(patient)); + for (Practitioner practitioner : practitionerList) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.PRACTITIONER + "/" + practitioner.getId()) + .setResource(practitioner)); + } + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.ENCOUNTER + "/" + encounter.getId()) + .setResource(encounter)); + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.ORGANISATION + "/" + organization.getId()) + .setResource(organization)); + + for (Condition complaint : chiefComplaintList) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.CHIEF_COMPLAINTS + "/" + complaint.getId()) + .setResource(complaint)); + } + for (Observation physicalObservation : physicalObservationList) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl( + BundleResourceIdentifier.PHYSICAL_EXAMINATION + + "/" + + physicalObservation.getId()) + .setResource(physicalObservation)); + } + for (AllergyIntolerance allergyIntolerance : allergieList) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl( + BundleResourceIdentifier.ALLERGY_INTOLERANCE + "/" + allergyIntolerance.getId()) + .setResource(allergyIntolerance)); + } + for (Condition medicalHistory : medicalHistoryList) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.MEDICAL_HISTORY + "/" + medicalHistory.getId()) + .setResource(medicalHistory)); + } + for (FamilyMemberHistory familyMemberHistory : familyMemberHistoryList) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl( + BundleResourceIdentifier.FAMILY_HISTORY + "/" + familyMemberHistory.getId()) + .setResource(familyMemberHistory)); + } + for (ServiceRequest investigation : investigationAdviceList) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl( + BundleResourceIdentifier.INVESTIGATION_ADVICE + "/" + investigation.getId()) + .setResource(investigation)); + } + for (MedicationRequest medicationRequest : medicationList) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl( + BundleResourceIdentifier.MEDICATION_REQUEST + "/" + medicationRequest.getId()) + .setResource(medicationRequest)); + } + for (Condition medicationCondition : medicationConditionList) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.CONDITION + "/" + medicationCondition.getId()) + .setResource(medicationCondition)); + } + for (Appointment followUp : followupList) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.FOLLOW_UP + "/" + followUp.getId()) + .setResource(followUp)); + } + for (Procedure procedure : procedureList) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.PROCEDURE + "/" + procedure.getId()) + .setResource(procedure)); + } + for (ServiceRequest referral : referralList) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.REFERRAL + "/" + referral.getId()) + .setResource(referral)); + } + for (Observation observation : otherObservationList) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.OTHER_OBSERVATIONS + "/" + observation.getId()) + .setResource(observation)); + } + for (DocumentReference documentReference : documentReferenceList) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl( + BundleResourceIdentifier.DOCUMENT_REFERENCE + "/" + documentReference.getId()) + .setResource(documentReference)); + } + bundle.setEntry(entries); + return BundleResponse.builder().bundle(bundle).build(); + } catch (Exception e) { + if (e instanceof InvalidDataAccessResourceUsageException) { + log.error(e.getMessage()); + return BundleResponse.builder() + .error( + new ErrorResponse( + ErrorCode.DB_ERROR, + " JDBCException Generic SQL Related Error, kindly check logs.")) + .build(); + } + return BundleResponse.builder() + .error(ErrorResponse.builder().code("1000").message(e.getMessage()).build()) + .build(); + } + } + + private DocumentReference makeDocumentReference( + Patient patient, Organization organization, DocumentResource documentResource) + throws ParseException { + return makeDocumentResource.getDocument( + patient, + organization, + documentResource, + BundleCompositionIdentifier.RECORD_ARTIFACT_CODE, + BundleCompositionIdentifier.RECORD_ARTIFACT); + } + + private List makeOtherObservations( + Patient patient, + List practitionerList, + OPConsultationRequest opConsultationRequest) + throws ParseException { + return Optional.ofNullable(opConsultationRequest.getOtherObservations()) + .orElse(Collections.emptyList()) + .stream() + .map( + StreamUtils.wrapException( + observation -> + makeObservationResource.getObservation(patient, practitionerList, observation))) + .toList(); + } + + private List makeReferralList( + OPConsultationRequest opConsultationRequest, + Patient patient, + List practitionerList) + throws ParseException { + return Optional.ofNullable(opConsultationRequest.getReferrals()) + .orElse(Collections.emptyList()) + .stream() + .map( + StreamUtils.wrapException( + referral -> + makeServiceRequestResource.getServiceRequest( + patient, practitionerList, referral, opConsultationRequest.getVisitDate()))) + .toList(); + } + + private List makeProcedureList( + OPConsultationRequest opConsultationRequest, Patient patient) throws ParseException { + return Optional.ofNullable(opConsultationRequest.getProcedures()) + .orElse(Collections.emptyList()) + .stream() + .map( + StreamUtils.wrapException( + procedure -> makeProcedureResource.getProcedure(patient, procedure))) + .toList(); + } + + private List makeFollowupList( + Patient patient, OPConsultationRequest opConsultationRequest) throws ParseException { + return Optional.ofNullable(opConsultationRequest.getFollowups()) + .orElse(Collections.emptyList()) + .stream() + .map( + StreamUtils.wrapException( + item -> { + Appointment appointment = new Appointment(); + appointment.setId(UUID.randomUUID().toString()); + appointment.setStatus(Appointment.AppointmentStatus.PROPOSED); + appointment.setParticipant( + Collections.singletonList( + new Appointment.AppointmentParticipantComponent() + .setActor( + new Reference() + .setReference( + BundleResourceIdentifier.PATIENT + "/" + patient.getId())) + .setStatus(Appointment.ParticipationStatus.ACCEPTED))); + appointment.setStart( + Utils.getFormattedDateTime(item.getAppointmentTime()) + .getValue()); // TODO in UTC format + appointment.addReasonCode(new CodeableConcept().setText(item.getReason())); + appointment.setServiceType( + Collections.singletonList( + new CodeableConcept().setText(item.getServiceType()))); + return appointment; + })) + .toList(); + } + + private List makeInvestigationAdviceList( + OPConsultationRequest opConsultationRequest, + Patient patient, + List practitionerList) + throws ParseException { + return Optional.ofNullable(opConsultationRequest.getServiceRequests()) + .orElse(Collections.emptyList()) + .stream() + .map( + StreamUtils.wrapException( + investigation -> + makeServiceRequestResource.getServiceRequest( + patient, + practitionerList, + investigation, + opConsultationRequest.getVisitDate()))) + .toList(); + } + + private List makeFamilyMemberHistory( + Patient patient, OPConsultationRequest opConsultationRequest) throws ParseException { + return Optional.ofNullable(opConsultationRequest.getFamilyHistories()) + .orElse(Collections.emptyList()) + .stream() + .map( + StreamUtils.wrapException( + family -> makeFamilyMemberResource.getFamilyHistory(patient, family))) + .toList(); + } + + private List makeMedicalHistoryList( + OPConsultationRequest opConsultationRequest, Patient patient) throws ParseException { + return Optional.ofNullable(opConsultationRequest.getMedicalHistories()) + .orElse(Collections.emptyList()) + .stream() + .map( + StreamUtils.wrapException( + medicalHistory -> + makeConditionResource.getCondition( + medicalHistory.getComplaint(), + patient, + medicalHistory.getRecordedDate(), + medicalHistory.getDateRange()))) + .toList(); + } + + private List makeAllergiesList( + Patient patient, + List practitionerList, + OPConsultationRequest opConsultationRequest) { + + return Optional.ofNullable(opConsultationRequest.getAllergies()).orElse(List.of()).stream() + .filter(allergy -> allergy != null && !allergy.isBlank()) + .map( + StreamUtils.wrapException( + allergy -> + makeAllergyToleranceResource.getAllergy( + patient, practitionerList, allergy, opConsultationRequest.getVisitDate()))) + .toList(); + } + + private List makePhysicalObservations( + OPConsultationRequest opConsultationRequest, + Patient patient, + List practitionerList) + throws ParseException { + return Optional.ofNullable(opConsultationRequest.getPhysicalExaminations()) + .orElse(Collections.emptyList()) + .stream() + .map( + StreamUtils.wrapException( + physicalObservation -> + makeObservationResource.getObservation( + patient, practitionerList, physicalObservation))) + .toList(); + } + + private List makeCheifComplaintsList( + OPConsultationRequest opConsultationRequest, Patient patient) throws ParseException { + return Optional.ofNullable(opConsultationRequest.getChiefComplaints()) + .orElse(Collections.emptyList()) + .stream() + .map( + StreamUtils.wrapException( + complaint -> + makeConditionResource.getCondition( + complaint.getComplaint(), + patient, + complaint.getRecordedDate(), + complaint.getDateRange()))) + .toList(); + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/PrescriptionConverter.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/PrescriptionConverter.java new file mode 100644 index 00000000..25a0107c --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/PrescriptionConverter.java @@ -0,0 +1,197 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.converter; + +import com.nha.abdm.fhir.mapper.Utils; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.ErrorCode; +import com.nha.abdm.fhir.mapper.rest.common.constants.ResourceProfileIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.helpers.BundleResponse; +import com.nha.abdm.fhir.mapper.rest.common.helpers.DocumentResource; +import com.nha.abdm.fhir.mapper.rest.common.helpers.ErrorResponse; +import com.nha.abdm.fhir.mapper.rest.dto.compositions.MakePrescriptionComposition; +import com.nha.abdm.fhir.mapper.rest.dto.resources.*; +import com.nha.abdm.fhir.mapper.rest.exceptions.StreamUtils; +import com.nha.abdm.fhir.mapper.rest.requests.PrescriptionRequest; +import com.nha.abdm.fhir.mapper.rest.requests.helpers.PrescriptionResource; +import java.text.ParseException; +import java.util.*; +import org.hl7.fhir.r4.model.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.dao.InvalidDataAccessResourceUsageException; +import org.springframework.stereotype.Service; + +@Service +public class PrescriptionConverter { + private static final Logger log = LoggerFactory.getLogger(PrescriptionConverter.class); + private final MakeOrganisationResource makeOrganisationResource; + + private final MakePatientResource makePatientResource; + + private final MakePractitionerResource makePractitionerResource; + private final MakeBundleMetaResource makeBundleMetaResource; + private final MakeMedicationRequestResource makeMedicationRequestResource; + private final MakeEncounterResource makeEncounterResource; + private final MakePrescriptionComposition makePrescriptionComposition; + private final MakeConditionResource makeConditionResource; + + public PrescriptionConverter( + MakeOrganisationResource makeOrganisationResource, + MakePatientResource makePatientResource, + MakePractitionerResource makePractitionerResource, + MakeBundleMetaResource makeBundleMetaResource, + MakeMedicationRequestResource makeMedicationRequestResource, + MakeEncounterResource makeEncounterResource, + MakePrescriptionComposition makePrescriptionComposition, + MakeConditionResource makeConditionResource) { + this.makeOrganisationResource = makeOrganisationResource; + this.makePatientResource = makePatientResource; + this.makePractitionerResource = makePractitionerResource; + this.makeBundleMetaResource = makeBundleMetaResource; + this.makeMedicationRequestResource = makeMedicationRequestResource; + this.makeEncounterResource = makeEncounterResource; + this.makePrescriptionComposition = makePrescriptionComposition; + this.makeConditionResource = makeConditionResource; + } + + public BundleResponse convertToPrescriptionBundle(PrescriptionRequest prescriptionRequest) + throws ParseException { + try { + Organization organization = + Objects.nonNull(prescriptionRequest.getOrganisation()) + ? makeOrganisationResource.getOrganization(prescriptionRequest.getOrganisation()) + : null; + + Patient patient = makePatientResource.getPatient(prescriptionRequest.getPatient()); + + List practitionerList = + Optional.ofNullable(prescriptionRequest.getPractitioners()) + .orElse(Collections.emptyList()) + .stream() + .map(StreamUtils.wrapException(makePractitionerResource::getPractitioner)) + .toList(); + List medicationRequestList = new ArrayList<>(); + List medicationConditionList = new ArrayList<>(); + for (PrescriptionResource item : prescriptionRequest.getPrescriptions()) { + Condition condition = + item.getReason() != null + ? makeConditionResource.getCondition( + item.getReason(), patient, prescriptionRequest.getAuthoredOn(), null) + : null; + medicationRequestList.add( + makeMedicationRequestResource.getMedicationResource( + prescriptionRequest.getAuthoredOn(), + item, + condition, + organization, + practitionerList, + patient)); + if (condition != null) { + medicationConditionList.add(condition); + } + } + Encounter encounter = + makeEncounterResource.getEncounter( + patient, + prescriptionRequest.getEncounter() != null + ? prescriptionRequest.getEncounter() + : null, + prescriptionRequest.getAuthoredOn()); + List documentList = new ArrayList<>(); + if (prescriptionRequest.getDocuments() != null) { + for (DocumentResource documentResource : prescriptionRequest.getDocuments()) { + Binary binary = new Binary(); + binary.setMeta( + new Meta() + .setLastUpdatedElement(Utils.getCurrentTimeStamp()) + .addProfile(ResourceProfileIdentifier.PROFILE_BINARY)); + binary.setContent(documentResource.getData()); + binary.setContentType(documentResource.getContentType()); + binary.setId(UUID.randomUUID().toString()); + documentList.add(binary); + } + } + Composition composition = + makePrescriptionComposition.makeCompositionResource( + patient, + practitionerList, + organization, + prescriptionRequest.getAuthoredOn(), + encounter, + medicationRequestList, + documentList); + + Bundle bundle = new Bundle(); + bundle.setId(UUID.randomUUID().toString()); + bundle.setType(Bundle.BundleType.DOCUMENT); + bundle.setTimestampElement(Utils.getCurrentTimeStamp()); + bundle.setMeta(makeBundleMetaResource.getMeta()); + bundle.setIdentifier( + new Identifier() + .setSystem(BundleUrlIdentifier.WRAPPER_URL) + .setValue(prescriptionRequest.getCareContextReference())); + List entries = new ArrayList<>(); + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.COMPOSITION + "/" + composition.getId()) + .setResource(composition)); + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.PATIENT + "/" + patient.getId()) + .setResource(patient)); + for (Practitioner practitioner : practitionerList) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.PRACTITIONER + "/" + practitioner.getId()) + .setResource(practitioner)); + } + if (Objects.nonNull(organization)) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.ORGANISATION + "/" + organization.getId()) + .setResource(organization)); + } + if (Objects.nonNull(encounter)) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.ENCOUNTER + "/" + encounter.getId()) + .setResource(encounter)); + } + for (MedicationRequest medicationRequest : medicationRequestList) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl( + BundleResourceIdentifier.MEDICATION_REQUEST + "/" + medicationRequest.getId()) + .setResource(medicationRequest)); + } + for (Condition medicationCondition : medicationConditionList) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.CONDITION + "/" + medicationCondition.getId()) + .setResource(medicationCondition)); + } + for (Binary binary : documentList) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.BINARY + "/" + binary.getId()) + .setResource(binary)); + } + bundle.setEntry(entries); + return BundleResponse.builder().bundle(bundle).build(); + } catch (Exception e) { + if (e instanceof InvalidDataAccessResourceUsageException) { + log.error(e.getMessage()); + return BundleResponse.builder() + .error( + new ErrorResponse( + ErrorCode.DB_ERROR, + " JDBCException Generic SQL Related Error, kindly check logs.")) + .build(); + } + return BundleResponse.builder() + .error(ErrorResponse.builder().code("1000").message(e.getMessage()).build()) + .build(); + } + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/WellnessRecordConverter.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/WellnessRecordConverter.java new file mode 100644 index 00000000..709839fb --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/WellnessRecordConverter.java @@ -0,0 +1,304 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.converter; + +import com.nha.abdm.fhir.mapper.Utils; +import com.nha.abdm.fhir.mapper.rest.common.constants.*; +import com.nha.abdm.fhir.mapper.rest.common.helpers.BundleResponse; +import com.nha.abdm.fhir.mapper.rest.common.helpers.ErrorResponse; +import com.nha.abdm.fhir.mapper.rest.dto.compositions.MakeWellnessComposition; +import com.nha.abdm.fhir.mapper.rest.dto.resources.*; +import com.nha.abdm.fhir.mapper.rest.exceptions.StreamUtils; +import com.nha.abdm.fhir.mapper.rest.requests.WellnessRecordRequest; +import java.util.*; +import org.hl7.fhir.r4.model.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.dao.InvalidDataAccessResourceUsageException; +import org.springframework.stereotype.Service; + +@Service +public class WellnessRecordConverter { + private static final Logger log = LoggerFactory.getLogger(WellnessRecordConverter.class); + private final MakeOrganisationResource makeOrganisationResource; + private final MakeBundleMetaResource makeBundleMetaResource; + + private final MakePatientResource makePatientResource; + + private final MakePractitionerResource makePractitionerResource; + private final MakeDocumentResource makeDocumentResource; + private final MakeEncounterResource makeEncounterResource; + private final MakeObservationResource makeObservationResource; + private final MakeWellnessObservationResource makeWellnessObservationResource; + private final MakeWellnessComposition makeWellnessComposition; + + public WellnessRecordConverter( + MakeOrganisationResource makeOrganisationResource, + MakeBundleMetaResource makeBundleMetaResource, + MakePatientResource makePatientResource, + MakePractitionerResource makePractitionerResource, + MakeDocumentResource makeDocumentResource, + MakeEncounterResource makeEncounterResource, + MakeObservationResource makeObservationResource, + MakeWellnessObservationResource makeWellnessObservationResource, + MakeWellnessComposition makeWellnessComposition) { + this.makeOrganisationResource = makeOrganisationResource; + this.makeBundleMetaResource = makeBundleMetaResource; + this.makePatientResource = makePatientResource; + this.makePractitionerResource = makePractitionerResource; + this.makeDocumentResource = makeDocumentResource; + this.makeEncounterResource = makeEncounterResource; + this.makeObservationResource = makeObservationResource; + this.makeWellnessObservationResource = makeWellnessObservationResource; + this.makeWellnessComposition = makeWellnessComposition; + } + + public BundleResponse getWellnessBundle(WellnessRecordRequest wellnessRecordRequest) { + try { + Organization organization = + makeOrganisationResource.getOrganization(wellnessRecordRequest.getOrganisation()); + + Patient patient = makePatientResource.getPatient(wellnessRecordRequest.getPatient()); + + List practitionerList = + Optional.ofNullable(wellnessRecordRequest.getPractitioners()) + .orElse(Collections.emptyList()) + .stream() + .map(StreamUtils.wrapException(makePractitionerResource::getPractitioner)) + .toList(); + + Encounter encounter = + makeEncounterResource.getEncounter( + patient, + wellnessRecordRequest.getEncounter() != null + ? wellnessRecordRequest.getEncounter() + : null, + wellnessRecordRequest.getAuthoredOn()); + + List vitalSignsList = + Optional.ofNullable(wellnessRecordRequest.getVitalSigns()) + .orElse(Collections.emptyList()) + .stream() + .map( + StreamUtils.wrapException( + vitalSign -> + makeWellnessObservationResource.getObservation( + patient, + practitionerList, + vitalSign, + BundleFieldIdentifier.VITAL_SIGNS))) + .toList(); + + List bodyMeasurementList = + Optional.ofNullable(wellnessRecordRequest.getBodyMeasurements()) + .filter(Objects::nonNull) + .orElse(Collections.emptyList()) + .stream() + .map( + StreamUtils.wrapException( + bodyMeasurement -> + makeWellnessObservationResource.getObservation( + patient, + practitionerList, + bodyMeasurement, + BundleFieldIdentifier.BODY_MEASUREMENT))) + .toList(); + + List physicalActivityList = + Optional.ofNullable(wellnessRecordRequest.getPhysicalActivities()) + .orElse(Collections.emptyList()) + .stream() + .map( + StreamUtils.wrapException( + physicalActivity -> + makeWellnessObservationResource.getObservation( + patient, + practitionerList, + physicalActivity, + BundleFieldIdentifier.PHYSICAL_ACTIVITY))) + .toList(); + + List generalAssessmentList = + Optional.ofNullable(wellnessRecordRequest.getGeneralAssessments()) + .orElse(Collections.emptyList()) + .stream() + .map( + StreamUtils.wrapException( + generalAssessment -> + makeWellnessObservationResource.getObservation( + patient, + practitionerList, + generalAssessment, + BundleFieldIdentifier.GENERAL_ASSESSMENT))) + .toList(); + + List womanHealthList = + Optional.ofNullable(wellnessRecordRequest.getWomanHealths()) + .orElse(Collections.emptyList()) + .stream() + .map( + StreamUtils.wrapException( + womanHealth -> + makeWellnessObservationResource.getObservation( + patient, + practitionerList, + womanHealth, + BundleFieldIdentifier.WOMAN_HEALTH))) + .toList(); + + List lifeStyleList = + Optional.ofNullable(wellnessRecordRequest.getLifeStyles()) + .orElse(Collections.emptyList()) + .stream() + .map( + StreamUtils.wrapException( + lifeStyle -> + makeWellnessObservationResource.getObservation( + patient, + practitionerList, + lifeStyle, + BundleFieldIdentifier.LIFE_STYLE))) + .toList(); + + List otherObservationList = + Optional.ofNullable(wellnessRecordRequest.getOtherObservations()) + .orElse(Collections.emptyList()) + .stream() + .map( + StreamUtils.wrapException( + otherObservation -> + makeObservationResource.getObservation( + patient, practitionerList, otherObservation))) + .toList(); + + List documentReferenceList = + Optional.ofNullable(wellnessRecordRequest.getDocuments()) + .orElse(Collections.emptyList()) + .stream() + .map( + StreamUtils.wrapException( + documentResource -> { + return makeDocumentResource.getDocument( + patient, + organization, + documentResource, + BundleCompositionIdentifier.HEALTH_DOCUMENT_CODE, + BundleCompositionIdentifier.HEALTH_DOCUMENT); + })) + .toList(); + + Composition composition = + makeWellnessComposition.makeWellnessComposition( + patient, + wellnessRecordRequest.getAuthoredOn(), + encounter, + practitionerList, + organization, + vitalSignsList, + bodyMeasurementList, + physicalActivityList, + generalAssessmentList, + womanHealthList, + lifeStyleList, + otherObservationList, + documentReferenceList); + + Bundle bundle = new Bundle(); + bundle.setId(UUID.randomUUID().toString()); + bundle.setType(Bundle.BundleType.DOCUMENT); + bundle.setTimestampElement(Utils.getCurrentTimeStamp()); + bundle.setMeta(makeBundleMetaResource.getMeta()); + bundle.setIdentifier( + new Identifier() + .setSystem(BundleUrlIdentifier.WRAPPER_URL) + .setValue(wellnessRecordRequest.getCareContextReference())); + List entries = new ArrayList<>(); + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.COMPOSITION + "/" + composition.getId()) + .setResource(composition)); + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.PATIENT + "/" + patient.getId()) + .setResource(patient)); + for (Practitioner practitioner : practitionerList) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.PRACTITIONER + "/" + practitioner.getId()) + .setResource(practitioner)); + } + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.ENCOUNTER + "/" + encounter.getId()) + .setResource(encounter)); + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.ORGANISATION + "/" + organization.getId()) + .setResource(organization)); + + for (Observation observation : vitalSignsList) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.VITAL_SIGNS + "/" + observation.getId()) + .setResource(observation)); + } + for (Observation observation : bodyMeasurementList) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.BODY_MEASUREMENT + "/" + observation.getId()) + .setResource(observation)); + } + for (Observation observation : physicalActivityList) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.PHYSICAL_ACTIVITY + "/" + observation.getId()) + .setResource(observation)); + } + for (Observation observation : generalAssessmentList) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.GENERAL_ASSESSMENT + "/" + observation.getId()) + .setResource(observation)); + } + for (Observation observation : womanHealthList) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.WOMAN_HEALTH + "/" + observation.getId()) + .setResource(observation)); + } + for (Observation observation : lifeStyleList) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.LIFE_STYLE + "/" + observation.getId()) + .setResource(observation)); + } + for (Observation observation : otherObservationList) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(BundleResourceIdentifier.OTHER_OBSERVATIONS + "/" + observation.getId()) + .setResource(observation)); + } + for (DocumentReference documentReference : documentReferenceList) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl( + BundleResourceIdentifier.DOCUMENT_REFERENCE + "/" + documentReference.getId()) + .setResource(documentReference)); + } + bundle.setEntry(entries); + return BundleResponse.builder().bundle(bundle).build(); + } catch (Exception e) { + if (e instanceof InvalidDataAccessResourceUsageException) { + log.error(e.getMessage()); + return BundleResponse.builder() + .error( + new ErrorResponse( + ErrorCode.DB_ERROR, + " JDBCException Generic SQL Related Error, kindly check logs.")) + .build(); + } + return BundleResponse.builder() + .error(ErrorResponse.builder().code("1000").message(e.getMessage()).build()) + .build(); + } + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/config/DbLoader.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/config/DbLoader.java new file mode 100644 index 00000000..5e7816ae --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/config/DbLoader.java @@ -0,0 +1,144 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.database.h2.config; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.nha.abdm.fhir.mapper.rest.database.h2.tables.*; +import jakarta.annotation.PostConstruct; +import jakarta.persistence.EntityManager; +import jakarta.transaction.Transactional; +import java.io.IOException; +import java.io.InputStream; +import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Component; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.support.TransactionTemplate; + +@Component +public class DbLoader { + private final ApplicationContext applicationContext; + private final ObjectMapper dbMapper; + private static final Logger log = LoggerFactory.getLogger(DbLoader.class); + + @Autowired private PlatformTransactionManager transactionManager; + + public DbLoader(ApplicationContext applicationContext) { + this.applicationContext = applicationContext; + this.dbMapper = new ObjectMapper(); + } + + @PostConstruct + public void loadData() throws IOException { + PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); + Resource[] resources = resolver.getResources("classpath:/snomed/*.json"); + + if (resources == null || resources.length == 0) { + throw new IllegalStateException( + "No JSON files found in the 'snomed' folder on the classpath."); + } + + TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager); + + transactionTemplate.execute( + status -> { + try { + for (Resource resource : resources) { + processResource(resource); + } + } catch (Exception e) { + status.setRollbackOnly(); + throw new RuntimeException("Error loading data", e); + } + return null; + }); + } + + private void processResource(Resource resource) { + try (InputStream inputStream = resource.getInputStream()) { + String fileName = resource.getFilename(); + if (fileName == null || !fileName.endsWith(".json")) { + log.warn("Skipping invalid resource: {}", fileName); + return; + } + + String entityName = fileName.replace(".json", ""); + String beanName = entityName.substring(0, 1).toLowerCase() + entityName.substring(1) + "Repo"; + + if (applicationContext.containsBean(beanName)) { + + JpaRepository repository = + (JpaRepository) applicationContext.getBean(beanName); + + List entities = + (List) dbMapper.readValue(inputStream, getTypeReference(entityName)); + repository.saveAll(entities); + + log.info("Loaded {} records into {}", entities.size(), entityName); + + addIndexesTransactional(entityName); + } else { + log.info("No repository bean found for {}", entityName); + } + } catch (Exception e) { + log.error("Error processing resource: {}", resource.getFilename(), e); + throw new RuntimeException(e); + } + } + + private TypeReference getTypeReference(String entityName) { + return switch (entityName) { + case "SnomedConditionProcedure" -> new TypeReference>() {}; + case "SnomedDiagnostic" -> new TypeReference>() {}; + case "SnomedEncounter" -> new TypeReference>() {}; + case "SnomedMedicineRoute" -> new TypeReference>() {}; + case "SnomedMedicine" -> new TypeReference>() {}; + case "SnomedObservation" -> new TypeReference>() {}; + case "SnomedSpecimen" -> new TypeReference>() {}; + case "SnomedVaccine" -> new TypeReference>() {}; + default -> throw new IllegalArgumentException("Unknown entity name: " + entityName); + }; + } + + @Transactional + public void addIndexesTransactional(String entityName) { + + String tableName = "\"" + convertToSnakeCase(entityName) + "\""; + String indexName = "idx_" + convertToSnakeCase(entityName) + "_display_code"; + String sql = + switch (entityName) { + case "SnomedEncounter" -> + "CREATE INDEX " + indexName + " ON " + tableName + " (\"code\", \"display\");"; + case "SnomedDiagnostic" -> + "CREATE INDEX " + indexName + " ON " + tableName + " (\"code\", \"display\");"; + case "SnomedConditionProcedure" -> + "CREATE INDEX " + indexName + " ON " + tableName + " (\"code\", \"display\");"; + case "SnomedMedicineRoute" -> + "CREATE INDEX " + indexName + " ON " + tableName + " (\"code\", \"display\");"; + case "SnomedMedicine" -> + "CREATE INDEX " + indexName + " ON " + tableName + " (\"code\", \"display\");"; + case "SnomedObservation" -> + "CREATE INDEX " + indexName + " ON " + tableName + " (\"code\", \"display\");"; + case "SnomedSpecimen" -> + "CREATE INDEX " + indexName + " ON " + tableName + " (\"code\", \"display\");"; + case "SnomedVaccine" -> + "CREATE INDEX " + indexName + " ON " + tableName + " (\"code\", \"display\");"; + default -> null; + }; + + if (sql != null) { + EntityManager em = applicationContext.getBean(EntityManager.class); + em.createNativeQuery(sql).executeUpdate(); + } + } + + private String convertToSnakeCase(String className) { + return className.replaceAll("([a-z])([A-Z])", "$1_$2").toLowerCase(); + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedConditionProcedureRepo.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedConditionProcedureRepo.java new file mode 100644 index 00000000..91c47415 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedConditionProcedureRepo.java @@ -0,0 +1,19 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.database.h2.repositories; + +import com.nha.abdm.fhir.mapper.rest.database.h2.tables.SnomedConditionProcedure; +import java.util.List; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +@Repository +public interface SnomedConditionProcedureRepo + extends JpaRepository { + @Query( + value = + "SELECT * FROM \"snomed_condition_procedure\" sp WHERE sp.\"display\" ILIKE CONCAT('%', :display, '%') LIMIT 20", + nativeQuery = true) + List findByDisplay(@Param("display") String display); +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedDiagnosticRepo.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedDiagnosticRepo.java new file mode 100644 index 00000000..8ef691f7 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedDiagnosticRepo.java @@ -0,0 +1,18 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.database.h2.repositories; + +import com.nha.abdm.fhir.mapper.rest.database.h2.tables.SnomedDiagnostic; +import java.util.List; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +@Repository +public interface SnomedDiagnosticRepo extends JpaRepository { + @Query( + value = + "SELECT * FROM \"snomed_diagnostic\" sp WHERE sp.\"display\" ILIKE CONCAT('%', :display, '%') LIMIT 20 ", + nativeQuery = true) + List findByDisplay(@Param("display") String display); +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedEncounterRepo.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedEncounterRepo.java new file mode 100644 index 00000000..f74b634c --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedEncounterRepo.java @@ -0,0 +1,22 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.database.h2.repositories; + +import com.nha.abdm.fhir.mapper.rest.database.h2.tables.SnomedEncounter; +import java.util.List; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +@Repository +public interface SnomedEncounterRepo extends JpaRepository { + // @Query( + // value = "SELECT sp.code FROM snomed_encounter sp WHERE sp.display LIKE %:display% LIMIT + // 1", + // nativeQuery = true) + @Query( + value = + "SELECT * FROM \"snomed_encounter\" sp WHERE sp.\"display\" ILIKE CONCAT('%', :display, '%') LIMIT 20", + nativeQuery = true) + List findByDisplay(@Param("display") String display); +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedMedicineRepo.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedMedicineRepo.java new file mode 100644 index 00000000..735d8026 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedMedicineRepo.java @@ -0,0 +1,18 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.database.h2.repositories; + +import com.nha.abdm.fhir.mapper.rest.database.h2.tables.SnomedMedicine; +import java.util.List; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +@Repository +public interface SnomedMedicineRepo extends JpaRepository { + @Query( + value = + "SELECT * FROM \"snomed_medicine\" sp WHERE sp.\"display\" ILIKE CONCAT('%', :display, '%') LIMIT 20", + nativeQuery = true) + List findByDisplay(@Param("display") String display); +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedMedicineRouteRepo.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedMedicineRouteRepo.java new file mode 100644 index 00000000..94204511 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedMedicineRouteRepo.java @@ -0,0 +1,18 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.database.h2.repositories; + +import com.nha.abdm.fhir.mapper.rest.database.h2.tables.SnomedMedicineRoute; +import java.util.List; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +@Repository +public interface SnomedMedicineRouteRepo extends JpaRepository { + @Query( + value = + "SELECT * FROM \"snomed_medicine_route\" sp WHERE sp.\"display\" ILIKE CONCAT('%', :display, '%') LIMIT 20", + nativeQuery = true) + List findByDisplay(@Param("display") String display); +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedObservationRepo.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedObservationRepo.java new file mode 100644 index 00000000..4c35d81d --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedObservationRepo.java @@ -0,0 +1,18 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.database.h2.repositories; + +import com.nha.abdm.fhir.mapper.rest.database.h2.tables.SnomedObservation; +import java.util.List; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +@Repository +public interface SnomedObservationRepo extends JpaRepository { + @Query( + value = + "SELECT * FROM \"snomed_observation\" sp WHERE sp.\"display\" ILIKE CONCAT('%', :display, '%') LIMIT 20", + nativeQuery = true) + List findByDisplay(@Param("display") String display); +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedSpecimenRepo.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedSpecimenRepo.java new file mode 100644 index 00000000..42fde9c5 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedSpecimenRepo.java @@ -0,0 +1,18 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.database.h2.repositories; + +import com.nha.abdm.fhir.mapper.rest.database.h2.tables.SnomedSpecimen; +import java.util.List; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +@Repository +public interface SnomedSpecimenRepo extends JpaRepository { + @Query( + value = + "SELECT * FROM \"snomed_specimen\" sp WHERE sp.\"display\" ILIKE CONCAT('%', :display, '%') LIMIT 20", + nativeQuery = true) + List findByDisplay(@Param("display") String display); +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedVaccineRepo.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedVaccineRepo.java new file mode 100644 index 00000000..fa95765f --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/SnomedVaccineRepo.java @@ -0,0 +1,18 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.database.h2.repositories; + +import com.nha.abdm.fhir.mapper.rest.database.h2.tables.SnomedVaccine; +import java.util.List; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +@Repository +public interface SnomedVaccineRepo extends JpaRepository { + @Query( + value = + "SELECT * FROM \"snomed_vaccine\" sp WHERE sp.\"display\" ILIKE CONCAT('%', :display, '%') LIMIT 20", + nativeQuery = true) + List findByDisplay(@Param("display") String display); +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/services/Displayable.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/services/Displayable.java new file mode 100644 index 00000000..081f9ca4 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/services/Displayable.java @@ -0,0 +1,6 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.database.h2.services; + +public interface Displayable { + String getDisplay(); +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/services/SnomedService.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/services/SnomedService.java new file mode 100644 index 00000000..f8a87f01 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/services/SnomedService.java @@ -0,0 +1,270 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.database.h2.services; + +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleFieldIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.SnomedCodeIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.helpers.SnomedResponse; +import com.nha.abdm.fhir.mapper.rest.database.h2.repositories.*; +import com.nha.abdm.fhir.mapper.rest.database.h2.tables.*; +import java.util.*; +import java.util.stream.Collectors; +import org.apache.commons.text.similarity.CosineSimilarity; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class SnomedService { + @Autowired private final SnomedMedicineRepo snomedMedicineRepo; + @Autowired private final SnomedConditionProcedureRepo snomedConditionProcedureRepo; + @Autowired private final SnomedEncounterRepo snomedEncounterRepo; + @Autowired private final SnomedSpecimenRepo snomedSpecimenRepo; + @Autowired private final SnomedObservationRepo snomedObservationRepo; + @Autowired private final SnomedVaccineRepo snomedVaccineRepo; + @Autowired private final SnomedDiagnosticRepo snomedDiagnosticRepo; + @Autowired private final SnomedMedicineRouteRepo snomedMedicineRouteRepo; + + public SnomedService( + SnomedMedicineRepo snomedMedicineRepo, + SnomedConditionProcedureRepo snomedConditionProcedureRepo, + SnomedEncounterRepo snomedEncounterRepo, + SnomedSpecimenRepo snomedSpecimenRepo, + SnomedObservationRepo snomedObservationRepo, + SnomedVaccineRepo snomedVaccineRepo, + SnomedDiagnosticRepo snomedDiagnosticRepo, + SnomedMedicineRouteRepo snomedMedicineRouteRepo) { + this.snomedMedicineRepo = snomedMedicineRepo; + this.snomedConditionProcedureRepo = snomedConditionProcedureRepo; + this.snomedEncounterRepo = snomedEncounterRepo; + this.snomedSpecimenRepo = snomedSpecimenRepo; + this.snomedObservationRepo = snomedObservationRepo; + this.snomedVaccineRepo = snomedVaccineRepo; + this.snomedDiagnosticRepo = snomedDiagnosticRepo; + this.snomedMedicineRouteRepo = snomedMedicineRouteRepo; + } + + public SnomedConditionProcedure getConditionProcedureCode(String display) { + SnomedConditionProcedure snomedCode = + (SnomedConditionProcedure) + fuzzyMatch( + snomedConditionProcedureRepo.findByDisplay(display), + display, + SnomedConditionProcedure.class); + return snomedCode == null + ? SnomedConditionProcedure.builder() + .code(SnomedCodeIdentifier.SNOMED_UNKNOWN) + .display(display) + .build() + : snomedCode; + } + + public List getAllConditionProcedureCode() { + return snomedConditionProcedureRepo.findAll(); + } + + public SnomedDiagnostic getSnomedDiagnosticCode(String display) { + SnomedDiagnostic snomedCode = + (SnomedDiagnostic) + fuzzyMatch( + snomedDiagnosticRepo.findByDisplay(display), display, SnomedDiagnostic.class); + return snomedCode != null + ? snomedCode + : SnomedDiagnostic.builder() + .code(SnomedCodeIdentifier.SNOMED_UNKNOWN) + .display(display) + .build(); + } + + public List getAllSnomedDiagnosticCode() { + return snomedDiagnosticRepo.findAll(); + } + + public SnomedEncounter getSnomedEncounterCode(String display) { + if (display == null) { + return SnomedEncounter.builder() + .code(SnomedCodeIdentifier.SNOMED_ENCOUNTER_AMBULATORY) + .display(BundleFieldIdentifier.AMBULATORY) + .build(); + } + SnomedEncounter snomedCode = + (SnomedEncounter) + fuzzyMatch(snomedEncounterRepo.findByDisplay(display), display, SnomedEncounter.class); + return snomedCode != null + ? snomedCode + : SnomedEncounter.builder() + .code(SnomedCodeIdentifier.SNOMED_ENCOUNTER_AMBULATORY) + .display(display) + .build(); + } + + public List getAllSnomedEncounterCode() { + return snomedEncounterRepo.findAll(); + } + + public SnomedMedicine getSnomedMedicineCode(String display) { + SnomedMedicine snomedCode = + (SnomedMedicine) + fuzzyMatch(snomedMedicineRepo.findByDisplay(display), display, SnomedMedicine.class); + return snomedCode != null + ? snomedCode + : SnomedMedicine.builder() + .code(SnomedCodeIdentifier.SNOMED_UNKNOWN) + .display(display) + .build(); + } + + public List getAllSnomedMedicineCode() { + return snomedMedicineRepo.findAll(); + } + + public SnomedObservation getSnomedObservationCode(String display) { + SnomedObservation snomedObservation = + (SnomedObservation) + fuzzyMatch( + snomedObservationRepo.findByDisplay(display), display, SnomedObservation.class); + return snomedObservation != null + ? snomedObservation + : SnomedObservation.builder() + .code(SnomedCodeIdentifier.SNOMED_UNKNOWN) + .display(display) + .build(); + } + + public List getAllSnomedObservationCode() { + return snomedObservationRepo.findAll(); + } + + public SnomedSpecimen getSnomedSpecimenCode(String display) { + SnomedSpecimen snomedCode = + (SnomedSpecimen) + fuzzyMatch(snomedSpecimenRepo.findByDisplay(display), display, SnomedSpecimen.class); + return snomedCode != null + ? snomedCode + : SnomedSpecimen.builder() + .code(SnomedCodeIdentifier.SNOMED_UNKNOWN) + .display(display) + .build(); + } + + public List getAllSnomedSpecimenCode() { + return snomedSpecimenRepo.findAll(); + } + + public SnomedVaccine getSnomedVaccineCode(String display) { + SnomedVaccine snomedCode = + (SnomedVaccine) + fuzzyMatch(snomedVaccineRepo.findByDisplay(display), display, SnomedVaccine.class); + return snomedCode != null + ? snomedCode + : SnomedVaccine.builder() + .code(SnomedCodeIdentifier.SNOMED_UNKNOWN) + .display(display) + .build(); + } + + public List getAllSnomedVaccineCode() { + return snomedVaccineRepo.findAll(); + } + + public SnomedMedicineRoute getSnomedMedicineRouteCode(String display) { + SnomedMedicineRoute snomedCode = + (SnomedMedicineRoute) + fuzzyMatch( + snomedMedicineRouteRepo.findByDisplay(display), display, SnomedMedicineRoute.class); + return snomedCode != null + ? snomedCode + : SnomedMedicineRoute.builder() + .code(SnomedCodeIdentifier.SNOMED_UNKNOWN) + .display(display) + .build(); + } + + public List getAllSnomedMedicineRouteCode() { + return snomedMedicineRouteRepo.findAll(); + } + + public SnomedResponse getSnomedCodes(String resource) { + if (resource.equalsIgnoreCase(SnomedCodeIdentifier.SNOMED_CONDITION) + || resource.equalsIgnoreCase(SnomedCodeIdentifier.SNOMED_PROCEDURE)) { + return SnomedResponse.builder() + .snomedConditionProcedureCodes(getAllConditionProcedureCode()) + .build(); + } + if (resource.equalsIgnoreCase(SnomedCodeIdentifier.SNOMED_DIAGNOSTICS)) { + return SnomedResponse.builder().snomedDiagnosticCodes(getAllSnomedDiagnosticCode()).build(); + } + if (resource.equalsIgnoreCase(SnomedCodeIdentifier.SNOMED_ENCOUNTER)) { + return SnomedResponse.builder().snomedEncounterCodes(getAllSnomedEncounterCode()).build(); + } + if (resource.equalsIgnoreCase(SnomedCodeIdentifier.SNOMED_MEDICATION_ROUTE)) { + return SnomedResponse.builder() + .snomedMedicineRouteCodes(getAllSnomedMedicineRouteCode()) + .build(); + } + if (resource.equalsIgnoreCase(SnomedCodeIdentifier.SNOMED_MEDICATIONS)) { + return SnomedResponse.builder().snomedMedicineCodes(getAllSnomedMedicineCode()).build(); + } + if (resource.equalsIgnoreCase(SnomedCodeIdentifier.SNOMED_OBSERVATIONS)) { + return SnomedResponse.builder().snomedObservationCodes(getAllSnomedObservationCode()).build(); + } + if (resource.equalsIgnoreCase(SnomedCodeIdentifier.SNOMED_SPECIMEN)) { + return SnomedResponse.builder().snomedSpecimenCodes(getAllSnomedSpecimenCode()).build(); + } + if (resource.equalsIgnoreCase(SnomedCodeIdentifier.SNOMED_VACCINES)) { + return SnomedResponse.builder().snomedVaccineCodes(getAllSnomedVaccineCode()).build(); + } + return null; + } + + private static boolean hasValidWordDifference(String input, String display) { + if (input == null || display == null) return false; + int inputWordCount = countWords(input); + int displayWordCount = countWords(display); + + return inputWordCount >= 1 && displayWordCount <= inputWordCount + 2; + } + + // Count words in a string + private static int countWords(String text) { + if (text == null || text.trim().isEmpty()) return 0; + return text.trim().split("\\s+").length; + } + + private static Map createFrequencyMap(String text) { + String[] tokens = text.toLowerCase().split("\\s+"); + Map frequencyMap = new HashMap<>(); + + for (String token : tokens) { + frequencyMap.put(token, frequencyMap.getOrDefault(token, 0) + 1); + } + return frequencyMap; + } + + public static Object fuzzyMatch( + List list, String input, Class type) { + CosineSimilarity cosineSimilarity = new CosineSimilarity(); + + Map scoreMap = + list.stream() + .filter(type::isInstance) + .map(type::cast) + .filter( + obj -> + hasValidWordDifference( + input, + obj.getDisplay())) // filtering the difference in words not more the input + // +=2 + .collect( + Collectors.toMap( + obj -> obj, + obj -> { + Map inputMap = createFrequencyMap(input); + Map displayMap = createFrequencyMap(obj.getDisplay()); + return cosineSimilarity.cosineSimilarity(inputMap, displayMap); + })); + + return scoreMap.entrySet().stream() + .max(Map.Entry.comparingByValue()) + .map(Map.Entry::getKey) + .orElse(null); + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedConditionProcedure.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedConditionProcedure.java new file mode 100644 index 00000000..64320638 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedConditionProcedure.java @@ -0,0 +1,27 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.database.h2.tables; + +import com.nha.abdm.fhir.mapper.rest.common.constants.SnomedCodeIdentifier; +import com.nha.abdm.fhir.mapper.rest.database.h2.services.Displayable; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Entity +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Table(name = "snomed_condition_procedure") +public class SnomedConditionProcedure implements Displayable { + @Id public String code; + + public String display; + + public final String type = + SnomedCodeIdentifier.SNOMED_CONDITION + "/" + SnomedCodeIdentifier.SNOMED_PROCEDURE; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedDiagnostic.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedDiagnostic.java new file mode 100644 index 00000000..a653bd3a --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedDiagnostic.java @@ -0,0 +1,26 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.database.h2.tables; + +import com.nha.abdm.fhir.mapper.rest.common.constants.SnomedCodeIdentifier; +import com.nha.abdm.fhir.mapper.rest.database.h2.services.Displayable; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Entity +@AllArgsConstructor +@NoArgsConstructor +@Table(name = "snomed_diagnostic") +@Builder +public class SnomedDiagnostic implements Displayable { + @Id public String code; + + public String display; + + public final String type = SnomedCodeIdentifier.SNOMED_DIAGNOSTICS; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedEncounter.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedEncounter.java new file mode 100644 index 00000000..a921b4ee --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedEncounter.java @@ -0,0 +1,26 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.database.h2.tables; + +import com.nha.abdm.fhir.mapper.rest.common.constants.SnomedCodeIdentifier; +import com.nha.abdm.fhir.mapper.rest.database.h2.services.Displayable; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Entity +@Builder +@AllArgsConstructor +@NoArgsConstructor +@Table(name = "snomed_encounter") +public class SnomedEncounter implements Displayable { + @Id public String code; + + public String display; + + public final String type = SnomedCodeIdentifier.SNOMED_ENCOUNTER; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedMedicine.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedMedicine.java new file mode 100644 index 00000000..9408f5b2 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedMedicine.java @@ -0,0 +1,26 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.database.h2.tables; + +import com.nha.abdm.fhir.mapper.rest.common.constants.SnomedCodeIdentifier; +import com.nha.abdm.fhir.mapper.rest.database.h2.services.Displayable; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Entity +@Builder +@AllArgsConstructor +@NoArgsConstructor +@Table(name = "snomed_medicine") +public class SnomedMedicine implements Displayable { + @Id public String code; + + public String display; + + public final String type = SnomedCodeIdentifier.SNOMED_MEDICATIONS; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedMedicineRoute.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedMedicineRoute.java new file mode 100644 index 00000000..ccb71ae5 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedMedicineRoute.java @@ -0,0 +1,26 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.database.h2.tables; + +import com.nha.abdm.fhir.mapper.rest.common.constants.SnomedCodeIdentifier; +import com.nha.abdm.fhir.mapper.rest.database.h2.services.Displayable; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Entity +@Builder +@AllArgsConstructor +@NoArgsConstructor +@Table(name = "snomed_medicine_route") +public class SnomedMedicineRoute implements Displayable { + @Id public String code; + + public String display; + + public final String type = SnomedCodeIdentifier.SNOMED_MEDICATION_ROUTE; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedObservation.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedObservation.java new file mode 100644 index 00000000..2bf3409a --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedObservation.java @@ -0,0 +1,26 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.database.h2.tables; + +import com.nha.abdm.fhir.mapper.rest.common.constants.SnomedCodeIdentifier; +import com.nha.abdm.fhir.mapper.rest.database.h2.services.Displayable; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Entity +@Builder +@AllArgsConstructor +@NoArgsConstructor +@Table(name = "snomed_observation") +public class SnomedObservation implements Displayable { + @Id public String code; + + public String display; + + public final String type = SnomedCodeIdentifier.SNOMED_OBSERVATIONS; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedSpecimen.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedSpecimen.java new file mode 100644 index 00000000..a154787c --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedSpecimen.java @@ -0,0 +1,26 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.database.h2.tables; + +import com.nha.abdm.fhir.mapper.rest.common.constants.SnomedCodeIdentifier; +import com.nha.abdm.fhir.mapper.rest.database.h2.services.Displayable; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Entity +@AllArgsConstructor +@NoArgsConstructor +@Table(name = "snomed_specimen") +@Builder +public class SnomedSpecimen implements Displayable { + @Id public String code; + + public String display; + + public final String type = SnomedCodeIdentifier.SNOMED_SPECIMEN; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedVaccine.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedVaccine.java new file mode 100644 index 00000000..f053055f --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/SnomedVaccine.java @@ -0,0 +1,26 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.database.h2.tables; + +import com.nha.abdm.fhir.mapper.rest.common.constants.SnomedCodeIdentifier; +import com.nha.abdm.fhir.mapper.rest.database.h2.services.Displayable; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Entity +@AllArgsConstructor +@NoArgsConstructor +@Table(name = "snomed_vaccine") +@Builder +public class SnomedVaccine implements Displayable { + @Id public String code; + + public String display; + + public final String type = SnomedCodeIdentifier.SNOMED_VACCINES; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeDiagnosticComposition.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeDiagnosticComposition.java new file mode 100644 index 00000000..4c87e3ae --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeDiagnosticComposition.java @@ -0,0 +1,91 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.dto.compositions; + +import com.nha.abdm.fhir.mapper.Utils; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleCompositionIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.ResourceProfileIdentifier; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.UUID; +import org.hl7.fhir.r4.model.*; +import org.springframework.stereotype.Service; + +@Service +public class MakeDiagnosticComposition { + public Composition makeCompositionResource( + Patient patient, + String authoredOn, + List practitionerList, + Organization organization, + Encounter encounter, + List diagnosticReportList, + List documentReferenceList) + throws ParseException { + Composition composition = new Composition(); + Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); + Meta meta = new Meta(); + meta.setVersionId("1"); + meta.setLastUpdatedElement(Utils.getCurrentTimeStamp()); + meta.addProfile(ResourceProfileIdentifier.PROFILE_DIAGNOSTIC_REPORT); + composition.setMeta(meta); + CodeableConcept sectionCode = new CodeableConcept(); + Coding typeCoding = new Coding(); + typeCoding.setSystem(BundleUrlIdentifier.SNOMED_URL); + typeCoding.setCode(BundleCompositionIdentifier.DIAGNOSTIC_STUDIES_REPORT_CODE); + typeCoding.setDisplay(BundleCompositionIdentifier.DIAGNOSTIC_STUDIES_REPORT); + sectionCode.addCoding(typeCoding); + composition.setType(sectionCode); + composition.setTitle(BundleCompositionIdentifier.DIAGNOSTIC_STUDIES_REPORT); + sectionComponent.setCode( + new CodeableConcept() + .addCoding(typeCoding) + .setText(BundleCompositionIdentifier.DIAGNOSTIC_STUDIES_REPORT)); + for (DiagnosticReport diagnosticReport : diagnosticReportList) { + sectionComponent.addEntry( + new Reference() + .setReference( + BundleResourceIdentifier.DIAGNOSTIC_REPORT + "/" + diagnosticReport.getId())); + } + for (DocumentReference documentReference : documentReferenceList) { + sectionComponent.addEntry( + new Reference() + .setReference( + BundleResourceIdentifier.DOCUMENT_REFERENCE + "/" + documentReference.getId())); + } + composition.addSection(sectionComponent); + List authorList = new ArrayList<>(); + for (Practitioner practitioner : practitionerList) { + HumanName practionerName = practitioner.getName().get(0); + authorList.add( + new Reference() + .setDisplay(practionerName.getText()) + .setReference(BundleResourceIdentifier.PRACTITIONER + "/" + practitioner.getId())); + } + composition.setCustodian( + new Reference() + .setDisplay(organization.getName()) + .setReference(BundleResourceIdentifier.ORGANISATION + "/" + organization.getId())); + composition.setAuthor(authorList); + if (Objects.nonNull(encounter)) + composition.setEncounter( + new Reference() + .setReference(BundleResourceIdentifier.ENCOUNTER + "/" + encounter.getId())); + HumanName patientName = patient.getName().get(0); + composition.setSubject( + new Reference() + .setDisplay(patientName.getText()) + .setReference(BundleResourceIdentifier.PATIENT + "/" + patient.getId())); + composition.setDateElement(Utils.getFormattedDateTime(authoredOn)); + composition.setStatus(Composition.CompositionStatus.FINAL); + Identifier identifier = new Identifier(); + identifier.setSystem(BundleUrlIdentifier.WRAPPER_URL); + identifier.setValue(UUID.randomUUID().toString()); + composition.setIdentifier(identifier); + composition.setId(UUID.randomUUID().toString()); + return composition; + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeDischargeComposition.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeDischargeComposition.java new file mode 100644 index 00000000..fe2a8f99 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeDischargeComposition.java @@ -0,0 +1,302 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.dto.compositions; + +import com.nha.abdm.fhir.mapper.Utils; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleCompositionIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.UUID; +import org.hl7.fhir.r4.model.*; +import org.springframework.stereotype.Service; + +@Service +public class MakeDischargeComposition { + public Composition makeDischargeCompositionResource( + Patient patient, + String authoredOn, + Encounter encounter, + List practitionerList, + Organization organization, + List chiefComplaintList, + List physicalObservationList, + List allergieList, + List medicationRequestList, + List diagnosticReportList, + List medicalHistoryList, + List familyMemberHistoryList, + CarePlan carePlan, + List procedureList, + List documentReferenceList, + String docCode, + String docName) + throws ParseException { + HumanName patientName = patient.getName().get(0); + HumanName practitionerName = null; + Composition composition = new Composition(); + CodeableConcept typeCode = new CodeableConcept(); + Coding typeCoding = new Coding(); + typeCoding.setSystem(BundleUrlIdentifier.SNOMED_URL); + typeCoding.setCode(BundleCompositionIdentifier.DISCHARGE_SUMMARY_CODE); + typeCoding.setDisplay(BundleCompositionIdentifier.DISCHARGE_SUMMARY); + typeCode.addCoding(typeCoding); + composition.setType(typeCode); + composition.setTitle(BundleCompositionIdentifier.DISCHARGE_SUMMARY); + List authorList = new ArrayList<>(); + for (Practitioner practitioner : practitionerList) { + practitionerName = practitioner.getName().get(0); + authorList.add( + new Reference() + .setReference(BundleResourceIdentifier.PRACTITIONER + "/" + practitioner.getId()) + .setDisplay(practitionerName != null ? practitionerName.getText() : null)); + } + composition.setEncounter( + new Reference().setReference(BundleResourceIdentifier.ENCOUNTER + "/" + encounter.getId())); + composition.setCustodian( + new Reference() + .setReference(BundleResourceIdentifier.ORGANISATION + "/" + organization.getId()) + .setDisplay(organization.getName())); + composition.setAuthor(authorList); + composition.setSubject( + new Reference() + .setReference(BundleResourceIdentifier.PATIENT + "/" + patient.getId()) + .setDisplay(patientName.getText())); + composition.setDateElement(Utils.getFormattedDateTime(authoredOn)); + composition.setStatus(Composition.CompositionStatus.FINAL); + List sectionComponentList = + makeCompositionSection( + patient, + practitionerList, + organization, + chiefComplaintList, + physicalObservationList, + allergieList, + medicationRequestList, + diagnosticReportList, + medicalHistoryList, + familyMemberHistoryList, + carePlan, + procedureList, + documentReferenceList, + docCode, + docName); + if (Objects.nonNull(sectionComponentList)) + for (Composition.SectionComponent sectionComponent : sectionComponentList) + composition.addSection(sectionComponent); + Identifier identifier = new Identifier(); + identifier.setSystem(BundleUrlIdentifier.WRAPPER_URL); + identifier.setValue(UUID.randomUUID().toString()); + composition.setIdentifier(identifier); + composition.setId(UUID.randomUUID().toString()); + return composition; + } + + private List makeCompositionSection( + Patient patient, + List practitionerList, + Organization organization, + List chiefComplaintList, + List physicalObservationList, + List allergieList, + List medicationRequestList, + List diagnosticReportList, + List medicalHistoryList, + List familyMemberHistoryList, + CarePlan carePlan, + List procedureList, + List documentReferenceList, + String docCode, + String docName) { + List sectionComponentList = new ArrayList<>(); + if (!(chiefComplaintList.isEmpty())) { + Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); + sectionComponent.setCode( + new CodeableConcept() + .setText(BundleResourceIdentifier.CHIEF_COMPLAINTS) + .addCoding( + new Coding() + .setSystem(BundleUrlIdentifier.SNOMED_URL) + .setCode(BundleCompositionIdentifier.CHIEF_COMPLAINTS_CODE) + .setDisplay(BundleCompositionIdentifier.CHIEF_COMPLAINTS))); + for (Condition chiefComplaint : chiefComplaintList) { + sectionComponent.addEntry( + new Reference() + .setReference( + BundleResourceIdentifier.CHIEF_COMPLAINTS + "/" + chiefComplaint.getId())); + } + sectionComponentList.add(sectionComponent); + } + if (!(physicalObservationList.isEmpty())) { + Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); + sectionComponent.setCode( + new CodeableConcept() + .setText(BundleResourceIdentifier.PHYSICAL_EXAMINATION) + .addCoding( + new Coding() + .setSystem(BundleUrlIdentifier.SNOMED_URL) + .setCode(BundleCompositionIdentifier.PHYSICAL_EXAMINATION_CODE) + .setDisplay(BundleCompositionIdentifier.PHYSICAL_EXAMINATION))); + for (Observation physicalObservation : physicalObservationList) { + sectionComponent.addEntry( + new Reference() + .setReference( + BundleResourceIdentifier.PHYSICAL_EXAMINATION + + "/" + + physicalObservation.getId())); + } + sectionComponentList.add(sectionComponent); + } + if (!(allergieList.isEmpty())) { + Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); + sectionComponent.setCode( + new CodeableConcept() + .setText(BundleCompositionIdentifier.ALLERGY_RECORD) + .addCoding( + new Coding() + .setSystem(BundleUrlIdentifier.SNOMED_URL) + .setCode(BundleCompositionIdentifier.ALLERGY_RECORD_CODE) + .setDisplay(BundleCompositionIdentifier.ALLERGY_RECORD))); + for (AllergyIntolerance allergyIntolerance : allergieList) { + sectionComponent.addEntry( + new Reference() + .setReference( + BundleResourceIdentifier.ALLERGY_INTOLERANCE + + "/" + + allergyIntolerance.getId())); + } + sectionComponentList.add(sectionComponent); + } + if (!medicalHistoryList.isEmpty()) { + Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); + sectionComponent.setCode( + new CodeableConcept() + .setText(BundleCompositionIdentifier.PAST_MEDICAL_HISTORY) + .addCoding( + new Coding() + .setSystem(BundleUrlIdentifier.SNOMED_URL) + .setCode(BundleCompositionIdentifier.PAST_MEDICAL_CODE) + .setDisplay(BundleCompositionIdentifier.PAST_MEDICAL_HISTORY))); + for (Condition medicalHistory : medicalHistoryList) { + sectionComponent.addEntry( + new Reference() + .setReference( + BundleResourceIdentifier.MEDICAL_HISTORY + "/" + medicalHistory.getId())); + } + sectionComponentList.add(sectionComponent); + } + if (!(familyMemberHistoryList.isEmpty())) { + Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); + sectionComponent.setCode( + new CodeableConcept() + .setText(BundleResourceIdentifier.FAMILY_HISTORY) + .addCoding( + new Coding() + .setSystem(BundleUrlIdentifier.SNOMED_URL) + .setCode(BundleCompositionIdentifier.FAMILY_HISTORY_SECTION_CODE) + .setDisplay(BundleCompositionIdentifier.FAMILY_HISTORY_SECTION))); + for (FamilyMemberHistory familyMemberHistory : familyMemberHistoryList) { + sectionComponent.addEntry( + new Reference() + .setReference( + BundleResourceIdentifier.FAMILY_HISTORY + "/" + familyMemberHistory.getId())); + } + sectionComponentList.add(sectionComponent); + } + if (Objects.nonNull(carePlan)) { + Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); + sectionComponent.setCode( + new CodeableConcept() + .setText(BundleResourceIdentifier.CARE_PLAN) + .addCoding( + new Coding() + .setSystem(BundleUrlIdentifier.SNOMED_URL) + .setCode(BundleCompositionIdentifier.CARE_PLAN_CODE) + .setDisplay(BundleCompositionIdentifier.CARE_PLAN))); + sectionComponent.addEntry( + new Reference() + .setReference(BundleResourceIdentifier.CARE_PLAN + "/" + carePlan.getId())); + sectionComponentList.add(sectionComponent); + } + if (!(medicationRequestList.isEmpty())) { + Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); + sectionComponent.setCode( + new CodeableConcept() + .setText(BundleResourceIdentifier.MEDICAL_HISTORY) + .addCoding( + new Coding() + .setSystem(BundleUrlIdentifier.SNOMED_URL) + .setCode(BundleCompositionIdentifier.MEDICAL_HISTORY_SECTION_CODE) + .setDisplay(BundleCompositionIdentifier.MEDICAL_HISTORY_SECTION))); + for (MedicationRequest medicationRequest : medicationRequestList) { + sectionComponent.addEntry( + new Reference() + .setReference( + BundleResourceIdentifier.MEDICATION_REQUEST + + BundleResourceIdentifier.FAMILY_HISTORY + + "/" + + medicationRequest.getId())); + } + sectionComponentList.add(sectionComponent); + } + if (!(diagnosticReportList.isEmpty())) { + Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); + sectionComponent.setCode( + new CodeableConcept() + .setText(BundleCompositionIdentifier.DIAGNOSTIC_STUDIES_REPORT) + .addCoding( + new Coding() + .setSystem(BundleUrlIdentifier.SNOMED_URL) + .setCode(BundleCompositionIdentifier.DIAGNOSTIC_STUDIES_REPORT_CODE) + .setDisplay(BundleCompositionIdentifier.DIAGNOSTIC_STUDIES_REPORT))); + for (DiagnosticReport diagnosticReport : diagnosticReportList) { + sectionComponent.addEntry( + new Reference() + .setReference( + BundleResourceIdentifier.DIAGNOSTIC_REPORT + "/" + diagnosticReport.getId())); + } + sectionComponentList.add(sectionComponent); + } + if (!(procedureList.isEmpty())) { + Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); + sectionComponent.setCode( + new CodeableConcept() + .setText(BundleCompositionIdentifier.HISTORY_PAST_PROCEDURE) + .addCoding( + new Coding() + .setSystem(BundleUrlIdentifier.SNOMED_URL) + .setCode(BundleCompositionIdentifier.HISTORY_PAST_PROCEDURE_CODE) + .setDisplay(BundleCompositionIdentifier.HISTORY_PAST_PROCEDURE))); + for (Procedure procedure : procedureList) { + sectionComponent.addEntry( + new Reference() + .setReference(BundleResourceIdentifier.PROCEDURE + "/" + procedure.getId())); + } + sectionComponentList.add(sectionComponent); + } + if (!(documentReferenceList.isEmpty())) { + Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); + sectionComponent.setCode( + new CodeableConcept() + .setText(BundleResourceIdentifier.DOCUMENT_REFERENCE) + .addCoding( + new Coding() + .setSystem(BundleUrlIdentifier.SNOMED_URL) + .setCode(docCode) + .setDisplay(docName))); + for (DocumentReference documentReferenceItem : documentReferenceList) { + sectionComponent.addEntry( + new Reference() + .setReference( + BundleResourceIdentifier.DOCUMENT_REFERENCE + + "/" + + documentReferenceItem.getId())); + } + sectionComponentList.add(sectionComponent); + } + + return sectionComponentList; + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeHealthDocumentComposition.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeHealthDocumentComposition.java new file mode 100644 index 00000000..cb460938 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeHealthDocumentComposition.java @@ -0,0 +1,83 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.dto.compositions; + +import com.nha.abdm.fhir.mapper.Utils; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleCompositionIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.ResourceProfileIdentifier; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.UUID; +import org.hl7.fhir.r4.model.*; +import org.springframework.stereotype.Service; + +@Service +public class MakeHealthDocumentComposition { + public Composition makeCompositionResource( + Patient patient, + String authoredOn, + List practitionerList, + Organization organization, + Encounter encounter, + List documentReferenceList) + throws ParseException { + Composition composition = new Composition(); + Meta meta = new Meta(); + meta.setVersionId("1"); + meta.setLastUpdatedElement(Utils.getCurrentTimeStamp()); + meta.addProfile(ResourceProfileIdentifier.PROFILE_HEALTH_DOCUMENT_RECORD); + composition.setMeta(meta); + Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); + sectionComponent.setTitle(BundleCompositionIdentifier.RECORD_ARTIFACT); + CodeableConcept typeCode = new CodeableConcept(); + Coding typeCoding = new Coding(); + typeCoding.setSystem(BundleUrlIdentifier.SNOMED_URL); + typeCoding.setCode(BundleCompositionIdentifier.RECORD_ARTIFACT_CODE); + typeCoding.setDisplay(BundleCompositionIdentifier.RECORD_ARTIFACT); + typeCode.addCoding(typeCoding); + typeCode.setText(BundleCompositionIdentifier.RECORD_ARTIFACT); + composition.setType(typeCode); + sectionComponent.setCode(typeCode); + for (DocumentReference documentReference : documentReferenceList) { + sectionComponent.addEntry( + new Reference() + .setReference( + BundleResourceIdentifier.DOCUMENT_REFERENCE + "/" + documentReference.getId())); + } + composition.addSection(sectionComponent); + composition.setTitle(BundleCompositionIdentifier.HEALTH_DOCUMENT); + composition.setEncounter( + new Reference().setReference(BundleResourceIdentifier.ENCOUNTER + "/" + encounter.getId())); + List authorList = new ArrayList<>(); + for (Practitioner practitioner : practitionerList) { + HumanName practionerName = practitioner.getName().get(0); + authorList.add( + new Reference() + .setDisplay(practionerName.getText()) + .setReference(BundleResourceIdentifier.PRACTITIONER + "/" + practitioner.getId())); + } + if (Objects.nonNull(organization)) { + composition.setCustodian( + new Reference() + .setDisplay(organization.getName()) + .setReference(BundleResourceIdentifier.ORGANISATION + "/" + organization.getId())); + } + composition.setAuthor(authorList); + HumanName patientName = patient.getName().get(0); + composition.setSubject( + new Reference() + .setDisplay(patientName.getText()) + .setReference(BundleResourceIdentifier.PATIENT + "/" + patient.getId())); + composition.setDateElement(Utils.getFormattedDateTime(authoredOn)); + composition.setStatus(Composition.CompositionStatus.FINAL); + Identifier identifier = new Identifier(); + identifier.setSystem(BundleUrlIdentifier.WRAPPER_URL); + identifier.setValue(UUID.randomUUID().toString()); + composition.setIdentifier(identifier); + composition.setId(UUID.randomUUID().toString()); + return composition; + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeImmunizationComposition.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeImmunizationComposition.java new file mode 100644 index 00000000..a6580f99 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeImmunizationComposition.java @@ -0,0 +1,94 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.dto.compositions; + +import com.nha.abdm.fhir.mapper.Utils; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleCompositionIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.ResourceProfileIdentifier; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.UUID; +import org.hl7.fhir.r4.model.*; +import org.springframework.stereotype.Service; + +@Service +public class MakeImmunizationComposition { + + public Composition makeCompositionResource( + Patient patient, + List practitionerList, + Organization organization, + String authoredOn, + List immunizationList, + List documentList) + throws ParseException { + Composition composition = new Composition(); + Meta meta = new Meta(); + meta.setVersionId("1"); + meta.setLastUpdatedElement(Utils.getCurrentTimeStamp()); + meta.addProfile(ResourceProfileIdentifier.PROFILE_IMMUNIZATION); + composition.setMeta(meta); + CodeableConcept typeCode = new CodeableConcept(); + Coding typeCoding = new Coding(); + typeCoding.setSystem(BundleUrlIdentifier.SNOMED_URL); + typeCoding.setCode(BundleCompositionIdentifier.IMMUNIZATION_RECORD_CODE); + typeCoding.setDisplay(BundleCompositionIdentifier.IMMUNIZATION_RECORD); + typeCode.addCoding(typeCoding); + composition.setType(typeCode); + composition.setTitle(BundleCompositionIdentifier.IMMUNIZATION_RECORD); + if (Objects.nonNull(organization)) + composition.setCustodian( + new Reference() + .setReference(BundleResourceIdentifier.ORGANISATION + "/" + organization.getId())); + List authorList = new ArrayList<>(); + HumanName practitionerName = null; + for (Practitioner author : practitionerList) { + practitionerName = author.getName().get(0); + authorList.add( + new Reference() + .setReference(BundleResourceIdentifier.PRACTITIONER + "/" + author.getId()) + .setDisplay(practitionerName.getText())); + } + composition.setAuthor(authorList); + HumanName patientName = patient.getName().get(0); + composition.setSubject( + new Reference() + .setReference(BundleResourceIdentifier.PATIENT + "/" + patient.getId()) + .setDisplay(patientName.getText())); + composition.setDateElement(Utils.getFormattedDateTime(authoredOn)); + Composition.SectionComponent immunizationSection = new Composition.SectionComponent(); + immunizationSection.setTitle(BundleResourceIdentifier.IMMUNIZATION); + immunizationSection.setCode( + new CodeableConcept() + .setText(BundleCompositionIdentifier.IMMUNIZATION_RECORD) + .addCoding( + new Coding() + .setCode(BundleCompositionIdentifier.IMMUNIZATION_RECORD_CODE) + .setDisplay(BundleCompositionIdentifier.IMMUNIZATION_RECORD) + .setSystem(BundleUrlIdentifier.SNOMED_URL))); + for (Immunization immunization : immunizationList) { + Reference entryReference = + new Reference() + .setReference(BundleResourceIdentifier.IMMUNIZATION + "/" + immunization.getId()) + .setType(BundleResourceIdentifier.IMMUNIZATION); + immunizationSection.addEntry(entryReference); + } + composition.addSection(immunizationSection); + for (DocumentReference documentReference : documentList) + immunizationSection.addEntry( + new Reference() + .setReference( + BundleResourceIdentifier.DOCUMENT_REFERENCE + "/" + documentReference.getId()) + .setType(BundleResourceIdentifier.DOCUMENT_REFERENCE)); + composition.setStatus(Composition.CompositionStatus.FINAL); + Identifier identifier = new Identifier(); + identifier.setSystem(BundleUrlIdentifier.WRAPPER_URL); + identifier.setValue(UUID.randomUUID().toString()); + composition.setIdentifier(identifier); + composition.setId(UUID.randomUUID().toString()); + return composition; + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeOpComposition.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeOpComposition.java new file mode 100644 index 00000000..b8646ab2 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeOpComposition.java @@ -0,0 +1,336 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.dto.compositions; + +import com.nha.abdm.fhir.mapper.Utils; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleCompositionIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.UUID; +import org.hl7.fhir.r4.model.*; +import org.springframework.stereotype.Service; + +@Service +public class MakeOpComposition { + public Composition makeOPCompositionResource( + Patient patient, + String visitDate, + Encounter encounter, + List practitionerList, + Organization organization, + List chiefComplaintList, + List physicalObservationList, + List allergieList, + List medicationList, + List medicalHistoryList, + List familyMemberHistoryList, + List investigationAdviceList, + List followupList, + List procedureList, + List referralList, + List otherObservationList, + List documentReferenceList) + throws ParseException { + HumanName patientName = patient.getName().get(0); + HumanName practitionerName = null; + Composition composition = new Composition(); + CodeableConcept typeCode = new CodeableConcept(); + Coding typeCoding = new Coding(); + typeCoding.setSystem(BundleUrlIdentifier.SNOMED_URL); + typeCoding.setCode(BundleCompositionIdentifier.CLINICAL_CONSULTATION_REPORT_CODE); + typeCoding.setDisplay(BundleCompositionIdentifier.CLINICAL_CONSULTATION_REPORT); + typeCode.addCoding(typeCoding); + composition.setType(typeCode); + composition.setTitle(BundleCompositionIdentifier.CLINICAL_CONSULTATION_REPORT); + List authorList = new ArrayList<>(); + for (Practitioner practitioner : practitionerList) { + practitionerName = practitioner.getName().get(0); + authorList.add( + new Reference() + .setReference(BundleResourceIdentifier.PRACTITIONER + "/" + practitioner.getId()) + .setDisplay(practitionerName != null ? practitionerName.getText() : null)); + } + composition.setEncounter( + new Reference().setReference(BundleResourceIdentifier.ENCOUNTER + "/" + encounter.getId())); + composition.setCustodian( + new Reference() + .setReference(BundleResourceIdentifier.ORGANISATION + "/" + organization.getId()) + .setDisplay(organization.getName())); + composition.setAuthor(authorList); + composition.setSubject( + new Reference() + .setReference(BundleResourceIdentifier.PATIENT + "/" + patient.getId()) + .setDisplay(patientName.getText())); + composition.setDateElement(Utils.getFormattedDateTime(visitDate)); + composition.setStatus(Composition.CompositionStatus.FINAL); + List sectionComponentList = + makeCompositionSection( + patient, + practitionerList, + organization, + chiefComplaintList, + physicalObservationList, + allergieList, + medicationList, + medicalHistoryList, + familyMemberHistoryList, + investigationAdviceList, + followupList, + procedureList, + referralList, + otherObservationList, + documentReferenceList); + if (Objects.nonNull(sectionComponentList)) + for (Composition.SectionComponent sectionComponent : sectionComponentList) + composition.addSection(sectionComponent); + Identifier identifier = new Identifier(); + identifier.setSystem(BundleUrlIdentifier.WRAPPER_URL); + identifier.setValue(UUID.randomUUID().toString()); + composition.setIdentifier(identifier); + composition.setId(UUID.randomUUID().toString()); + return composition; + } + + private List makeCompositionSection( + Patient patient, + List practitionerList, + Organization organization, + List chiefComplaintList, + List physicalObservationList, + List allergieList, + List medicationList, + List medicalHistoryList, + List familyMemberHistoryList, + List investigationAdviceList, + List followupList, + List procedureList, + List referralList, + List otherObservationList, + List documentReferenceList) { + List sectionComponentList = new ArrayList<>(); + if (chiefComplaintList != null && !chiefComplaintList.isEmpty()) { + Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); + sectionComponent.setCode( + new CodeableConcept() + .setText(BundleCompositionIdentifier.CHIEF_COMPLAINTS) + .addCoding( + new Coding() + .setSystem(BundleUrlIdentifier.SNOMED_URL) + .setCode(BundleCompositionIdentifier.CHIEF_COMPLAINTS_CODE) + .setDisplay(BundleCompositionIdentifier.CHIEF_COMPLAINTS))); + for (Condition chiefComplaint : chiefComplaintList) { + sectionComponent.addEntry( + new Reference() + .setReference( + BundleResourceIdentifier.CHIEF_COMPLAINTS + "/" + chiefComplaint.getId())); + } + sectionComponentList.add(sectionComponent); + } + if (Objects.nonNull(physicalObservationList) && !physicalObservationList.isEmpty()) { + Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); + sectionComponent.setCode( + new CodeableConcept() + .setText(BundleCompositionIdentifier.PHYSICAL_EXAMINATION) + .addCoding( + new Coding() + .setSystem(BundleUrlIdentifier.SNOMED_URL) + .setCode(BundleCompositionIdentifier.PHYSICAL_EXAMINATION_CODE) + .setDisplay(BundleCompositionIdentifier.PHYSICAL_EXAMINATION))); + for (Observation physicalObservation : physicalObservationList) { + sectionComponent.addEntry( + new Reference() + .setReference( + BundleResourceIdentifier.PHYSICAL_EXAMINATION + + "/" + + physicalObservation.getId())); + } + sectionComponentList.add(sectionComponent); + } + if (Objects.nonNull(allergieList) && !allergieList.isEmpty()) { + Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); + sectionComponent.setCode( + new CodeableConcept() + .setText(BundleCompositionIdentifier.ALLERGY_RECORD) + .addCoding( + new Coding() + .setSystem(BundleUrlIdentifier.SNOMED_URL) + .setCode(BundleCompositionIdentifier.ALLERGY_RECORD) + .setDisplay(BundleCompositionIdentifier.ALLERGY_RECORD))); + for (AllergyIntolerance allergyIntolerance : allergieList) { + sectionComponent.addEntry( + new Reference() + .setReference( + BundleResourceIdentifier.ALLERGY_INTOLERANCE + + "/" + + allergyIntolerance.getId())); + } + sectionComponentList.add(sectionComponent); + } + if (Objects.nonNull(medicalHistoryList) && !medicalHistoryList.isEmpty()) { + Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); + sectionComponent.setCode( + new CodeableConcept() + .setText(BundleCompositionIdentifier.MEDICAL_HISTORY_SECTION) + .addCoding( + new Coding() + .setSystem(BundleUrlIdentifier.SNOMED_URL) + .setCode(BundleCompositionIdentifier.MEDICAL_HISTORY_SECTION) + .setDisplay(BundleCompositionIdentifier.MEDICAL_HISTORY_SECTION))); + for (Condition medicalHistory : medicalHistoryList) { + sectionComponent.addEntry( + new Reference() + .setReference( + BundleResourceIdentifier.MEDICAL_HISTORY + "/" + medicalHistory.getId())); + } + sectionComponentList.add(sectionComponent); + } + if (Objects.nonNull(familyMemberHistoryList) && !familyMemberHistoryList.isEmpty()) { + Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); + sectionComponent.setCode( + new CodeableConcept() + .setText(BundleCompositionIdentifier.FAMILY_HISTORY_SECTION) + .addCoding( + new Coding() + .setSystem(BundleUrlIdentifier.SNOMED_URL) + .setCode(BundleCompositionIdentifier.FAMILY_HISTORY_SECTION_CODE) + .setDisplay(BundleCompositionIdentifier.FAMILY_HISTORY_SECTION))); + for (FamilyMemberHistory familyMemberHistory : familyMemberHistoryList) { + sectionComponent.addEntry( + new Reference() + .setReference( + BundleResourceIdentifier.FAMILY_HISTORY + "/" + familyMemberHistory.getId())); + } + sectionComponentList.add(sectionComponent); + } + if (Objects.nonNull(investigationAdviceList) && !investigationAdviceList.isEmpty()) { + Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); + sectionComponent.setCode( + new CodeableConcept() + .setText(BundleCompositionIdentifier.ORDER_DOCUMENT) + .addCoding( + new Coding() + .setSystem(BundleUrlIdentifier.SNOMED_URL) + .setCode(BundleCompositionIdentifier.ORDER_DOCUMENT_CODE) + .setDisplay(BundleCompositionIdentifier.ORDER_DOCUMENT))); + for (ServiceRequest investigation : investigationAdviceList) { + sectionComponent.addEntry( + new Reference() + .setReference( + BundleResourceIdentifier.INVESTIGATION_ADVICE + "/" + investigation.getId())); + } + sectionComponentList.add(sectionComponent); + } + if (Objects.nonNull(medicationList) && !medicationList.isEmpty()) { + Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); + sectionComponent.setCode( + new CodeableConcept() + .setText(BundleCompositionIdentifier.MEDICATION_SUMMARY) + .addCoding( + new Coding() + .setSystem(BundleUrlIdentifier.SNOMED_URL) + .setCode(BundleCompositionIdentifier.MEDICATION_SUMMARY_CODE) + .setDisplay(BundleCompositionIdentifier.MEDICATION_SUMMARY))); + for (MedicationRequest medication : medicationList) { + sectionComponent.addEntry( + new Reference() + .setReference( + BundleResourceIdentifier.MEDICATION_REQUEST + "/" + medication.getId())); + } + sectionComponentList.add(sectionComponent); + } + if (Objects.nonNull(followupList) && !followupList.isEmpty()) { + Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); + sectionComponent.setCode( + new CodeableConcept() + .setText(BundleCompositionIdentifier.FOLLOW_UP) + .addCoding( + new Coding() + .setSystem(BundleUrlIdentifier.SNOMED_URL) + .setCode(BundleCompositionIdentifier.FOLLOW_UP_CODE) + .setDisplay(BundleCompositionIdentifier.FOLLOW_UP))); + for (Appointment followUp : followupList) { + sectionComponent.addEntry( + new Reference() + .setReference(BundleResourceIdentifier.FOLLOW_UP + "/" + followUp.getId())); + } + sectionComponentList.add(sectionComponent); + } + if (Objects.nonNull(procedureList) && !procedureList.isEmpty()) { + Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); + sectionComponent.setCode( + new CodeableConcept() + .setText(BundleCompositionIdentifier.CLINICAL_PROCEDURE) + .addCoding( + new Coding() + .setSystem(BundleUrlIdentifier.SNOMED_URL) + .setCode(BundleCompositionIdentifier.CLINICAL_PROCEDURE_CODE) + .setDisplay(BundleCompositionIdentifier.CLINICAL_PROCEDURE))); + for (Procedure procedure : procedureList) { + sectionComponent.addEntry( + new Reference() + .setReference(BundleResourceIdentifier.PROCEDURE + "/" + procedure.getId())); + } + sectionComponentList.add(sectionComponent); + } + if (Objects.nonNull(referralList) && !referralList.isEmpty()) { + Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); + sectionComponent.setCode( + new CodeableConcept() + .setText(BundleCompositionIdentifier.REFERRAL_TO_SERVICE) + .addCoding( + new Coding() + .setSystem(BundleUrlIdentifier.SNOMED_URL) + .setCode(BundleCompositionIdentifier.REFERRAL_TO_SERVICE_CODE) + .setDisplay(BundleCompositionIdentifier.REFERRAL_TO_SERVICE))); + for (ServiceRequest referral : referralList) { + sectionComponent.addEntry( + new Reference() + .setReference(BundleResourceIdentifier.REFERRAL + "/" + referral.getId())); + } + sectionComponentList.add(sectionComponent); + } + if (Objects.nonNull(otherObservationList) && !otherObservationList.isEmpty()) { + Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); + sectionComponent.setCode( + new CodeableConcept() + .setText(BundleCompositionIdentifier.CLINICAL_FINDING) + .addCoding( + new Coding() + .setSystem(BundleUrlIdentifier.SNOMED_URL) + .setCode(BundleCompositionIdentifier.CLINICAL_FINDING_CODE) + .setDisplay(BundleCompositionIdentifier.CLINICAL_FINDING))); + for (Observation otherObservation : otherObservationList) { + sectionComponent.addEntry( + new Reference() + .setReference( + BundleResourceIdentifier.OTHER_OBSERVATIONS + "/" + otherObservation.getId())); + } + sectionComponentList.add(sectionComponent); + } + if (Objects.nonNull(documentReferenceList) && !documentReferenceList.isEmpty()) { + Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); + sectionComponent.setCode( + new CodeableConcept() + .setText(BundleCompositionIdentifier.CLINICAL_CONSULTATION_REPORT) + .addCoding( + new Coding() + .setSystem(BundleUrlIdentifier.SNOMED_URL) + .setCode(BundleCompositionIdentifier.CLINICAL_CONSULTATION_REPORT_CODE) + .setDisplay(BundleCompositionIdentifier.CLINICAL_CONSULTATION_REPORT))); + for (DocumentReference documentReferenceItem : documentReferenceList) { + sectionComponent.addEntry( + new Reference() + .setReference( + BundleResourceIdentifier.DOCUMENT_REFERENCE + + "/" + + documentReferenceItem.getId())); + } + sectionComponentList.add(sectionComponent); + } + + return sectionComponentList; + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakePrescriptionComposition.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakePrescriptionComposition.java new file mode 100644 index 00000000..1fddb14c --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakePrescriptionComposition.java @@ -0,0 +1,99 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.dto.compositions; + +import com.nha.abdm.fhir.mapper.Utils; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleCompositionIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.ResourceProfileIdentifier; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.UUID; +import org.hl7.fhir.r4.model.*; +import org.springframework.stereotype.Service; + +@Service +public class MakePrescriptionComposition { + public Composition makeCompositionResource( + Patient patient, + List practitionerList, + Organization organization, + String authoredOn, + Encounter encounter, + List medicationRequestList, + List documentList) + throws ParseException { + Composition composition = new Composition(); + Meta meta = new Meta(); + meta.setVersionId("1"); + meta.setLastUpdatedElement(Utils.getCurrentTimeStamp()); + meta.addProfile(ResourceProfileIdentifier.PROFILE_PRESCRIPTION_RECORD); + composition.setMeta(meta); + CodeableConcept typeCode = new CodeableConcept(); + Coding typeCoding = new Coding(); + typeCoding.setSystem(BundleUrlIdentifier.SNOMED_URL); + typeCoding.setCode(BundleCompositionIdentifier.PRESCRIPTION_CODE); + typeCoding.setDisplay(BundleCompositionIdentifier.PRESCRIPTION); + typeCode.addCoding(typeCoding); + composition.setType(typeCode); + composition.setTitle(BundleCompositionIdentifier.PRESCRIPTION); + if (Objects.nonNull(organization)) + composition.setCustodian( + new Reference() + .setReference(BundleResourceIdentifier.ORGANISATION + "/" + organization.getId())); + if (Objects.nonNull(encounter)) + composition.setEncounter( + new Reference() + .setReference(BundleResourceIdentifier.ENCOUNTER + "/" + encounter.getId()) + .setDisplay(encounter.getClass_().getDisplay())); + List authorList = new ArrayList<>(); + HumanName practitionerName = null; + for (Practitioner author : practitionerList) { + practitionerName = author.getName().get(0); + authorList.add( + new Reference() + .setReference(BundleResourceIdentifier.PRACTITIONER + "/" + author.getId()) + .setDisplay(practitionerName.getText())); + } + composition.setAuthor(authorList); + HumanName patientName = patient.getName().get(0); + composition.setSubject( + new Reference() + .setReference(BundleResourceIdentifier.PATIENT + "/" + patient.getId()) + .setDisplay(patientName.getText())); + composition.setDateElement(Utils.getFormattedDateTime(authoredOn)); + Composition.SectionComponent medicationComponent = new Composition.SectionComponent(); + medicationComponent.setTitle(BundleResourceIdentifier.MEDICATIONS); + medicationComponent.setCode( + new CodeableConcept() + .setText(BundleCompositionIdentifier.PRESCRIPTION) + .addCoding( + new Coding() + .setCode(BundleCompositionIdentifier.PRESCRIPTION_CODE) + .setDisplay(BundleCompositionIdentifier.PRESCRIPTION) + .setSystem(BundleUrlIdentifier.SNOMED_URL))); + for (MedicationRequest medicationRequest : medicationRequestList) { + Reference entryReference = + new Reference() + .setReference( + BundleResourceIdentifier.MEDICATION_REQUEST + "/" + medicationRequest.getId()) + .setType(BundleResourceIdentifier.MEDICATION_REQUEST); + medicationComponent.addEntry(entryReference); + } + composition.addSection(medicationComponent); + for (Binary binary : documentList) + medicationComponent.addEntry( + new Reference() + .setReference(BundleResourceIdentifier.BINARY + "/" + binary.getId()) + .setType(BundleResourceIdentifier.BINARY)); + composition.setStatus(Composition.CompositionStatus.FINAL); + Identifier identifier = new Identifier(); + identifier.setSystem(BundleUrlIdentifier.WRAPPER_URL); + identifier.setValue(UUID.randomUUID().toString()); + composition.setIdentifier(identifier); + composition.setId(UUID.randomUUID().toString()); + return composition; + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeWellnessComposition.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeWellnessComposition.java new file mode 100644 index 00000000..f1eb3343 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeWellnessComposition.java @@ -0,0 +1,185 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.dto.compositions; + +import com.nha.abdm.fhir.mapper.Utils; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleCompositionIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.UUID; +import org.hl7.fhir.r4.model.*; +import org.springframework.stereotype.Service; + +@Service +public class MakeWellnessComposition { + public Composition makeWellnessComposition( + Patient patient, + String authoredOn, + Encounter encounter, + List practitionerList, + Organization organization, + List vitalSignsList, + List bodyMeasurementList, + List physicalActivityList, + List generalAssessmentList, + List womanHealthList, + List lifeStyleList, + List otherObservationList, + List documentReferenceList) + throws ParseException { + HumanName patientName = patient.getName().get(0); + HumanName practitionerName = null; + Composition composition = new Composition(); + composition.setStatus(Composition.CompositionStatus.FINAL); + composition.setType(new CodeableConcept().setText(BundleCompositionIdentifier.WELLNESS_RECORD)); + composition.setTitle(BundleCompositionIdentifier.WELLNESS_RECORD); + List authorList = new ArrayList<>(); + for (Practitioner practitioner : practitionerList) { + practitionerName = practitioner.getName().get(0); + authorList.add( + new Reference() + .setReference(BundleResourceIdentifier.PRACTITIONER + "/" + practitioner.getId()) + .setDisplay(practitionerName != null ? practitionerName.getText() : null)); + } + composition.setEncounter( + new Reference().setReference(BundleResourceIdentifier.ENCOUNTER + "/" + encounter.getId())); + composition.setCustodian( + new Reference() + .setReference(BundleResourceIdentifier.ORGANISATION + "/" + organization.getId()) + .setDisplay(organization.getName())); + composition.setAuthor(authorList); + composition.setSubject( + new Reference() + .setReference(BundleResourceIdentifier.PATIENT + "/" + patient.getId()) + .setDisplay(patientName.getText())); + composition.setDateElement(Utils.getFormattedDateTime(authoredOn)); + List sectionComponentList = + makeCompositionSection( + patient, + encounter, + practitionerList, + organization, + vitalSignsList, + bodyMeasurementList, + physicalActivityList, + generalAssessmentList, + womanHealthList, + lifeStyleList, + otherObservationList, + documentReferenceList); + if (Objects.nonNull(sectionComponentList)) + for (Composition.SectionComponent sectionComponent : sectionComponentList) + composition.addSection(sectionComponent); + Identifier identifier = new Identifier(); + identifier.setSystem(BundleUrlIdentifier.WRAPPER_URL); + identifier.setValue(UUID.randomUUID().toString()); + composition.setIdentifier(identifier); + composition.setId(UUID.randomUUID().toString()); + return composition; + } + + private List makeCompositionSection( + Patient patient, + Encounter encounter, + List practitionerList, + Organization organization, + List vitalSignsList, + List bodyMeasurementList, + List physicalActivityList, + List generalAssessmentList, + List womanHealthList, + List lifeStyleList, + List otherObservationList, + List documentReferenceList) { + List sectionComponentList = new ArrayList<>(); + if (Objects.nonNull(vitalSignsList)) { + Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); + sectionComponent.setTitle(BundleCompositionIdentifier.VITAL_SIGNS); + for (Observation observation : vitalSignsList) { + sectionComponent.addEntry( + new Reference() + .setReference(BundleResourceIdentifier.VITAL_SIGNS + "/" + observation.getId())); + } + sectionComponentList.add(sectionComponent); + } + if (Objects.nonNull(bodyMeasurementList)) { + Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); + sectionComponent.setTitle(BundleCompositionIdentifier.BODY_MEASUREMENT); + for (Observation observation : bodyMeasurementList) { + sectionComponent.addEntry( + new Reference() + .setReference( + BundleResourceIdentifier.BODY_MEASUREMENT + "/" + observation.getId())); + } + sectionComponentList.add(sectionComponent); + } + if (Objects.nonNull(physicalActivityList)) { + Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); + sectionComponent.setTitle(BundleCompositionIdentifier.PHYSICAL_ACTIVITY); + for (Observation observation : physicalActivityList) { + sectionComponent.addEntry( + new Reference() + .setReference( + BundleResourceIdentifier.PHYSICAL_ACTIVITY + "/" + observation.getId())); + } + sectionComponentList.add(sectionComponent); + } + if (Objects.nonNull(generalAssessmentList)) { + Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); + sectionComponent.setTitle(BundleCompositionIdentifier.GENERAL_ASSESSMENT); + for (Observation observation : generalAssessmentList) { + sectionComponent.addEntry( + new Reference() + .setReference( + BundleResourceIdentifier.GENERAL_ASSESSMENT + "/" + observation.getId())); + } + sectionComponentList.add(sectionComponent); + } + if (Objects.nonNull(womanHealthList)) { + Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); + sectionComponent.setTitle(BundleCompositionIdentifier.WOMEN_HEALTH); + for (Observation observation : womanHealthList) { + sectionComponent.addEntry( + new Reference() + .setReference(BundleResourceIdentifier.WOMAN_HEALTH + "/" + observation.getId())); + } + sectionComponentList.add(sectionComponent); + } + if (Objects.nonNull(lifeStyleList)) { + Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); + sectionComponent.setTitle(BundleCompositionIdentifier.LIFE_STYLE); + for (Observation observation : lifeStyleList) { + sectionComponent.addEntry( + new Reference() + .setReference(BundleResourceIdentifier.LIFE_STYLE + "/" + observation.getId())); + } + sectionComponentList.add(sectionComponent); + } + if (Objects.nonNull(otherObservationList)) { + Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); + sectionComponent.setTitle(BundleCompositionIdentifier.OTHER_OBSERVATIONS); + for (Observation observation : otherObservationList) { + sectionComponent.addEntry( + new Reference() + .setReference( + BundleResourceIdentifier.OTHER_OBSERVATIONS + "/" + observation.getId())); + } + sectionComponentList.add(sectionComponent); + } + if (Objects.nonNull(documentReferenceList)) { + Composition.SectionComponent sectionComponent = new Composition.SectionComponent(); + sectionComponent.setTitle(BundleCompositionIdentifier.DOCUMENT_REFERENCE); + for (DocumentReference documentReference : documentReferenceList) { + sectionComponent.addEntry( + new Reference() + .setReference( + BundleResourceIdentifier.DOCUMENT_REFERENCE + "/" + documentReference.getId())); + } + sectionComponentList.add(sectionComponent); + } + return sectionComponentList; + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeAllergyToleranceResource.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeAllergyToleranceResource.java new file mode 100644 index 00000000..f36881e4 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeAllergyToleranceResource.java @@ -0,0 +1,64 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.dto.resources; + +import com.nha.abdm.fhir.mapper.Utils; +import com.nha.abdm.fhir.mapper.rest.common.constants.*; +import com.nha.abdm.fhir.mapper.rest.database.h2.services.SnomedService; +import com.nha.abdm.fhir.mapper.rest.database.h2.tables.SnomedConditionProcedure; +import java.text.ParseException; +import java.util.List; +import java.util.UUID; +import org.hl7.fhir.r4.model.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class MakeAllergyToleranceResource { + @Autowired SnomedService snomedService; + + public AllergyIntolerance getAllergy( + Patient patient, List practitionerList, String allergy, String authoredOn) + throws ParseException { + HumanName patientName = patient.getName().get(0); + AllergyIntolerance allergyIntolerance = new AllergyIntolerance(); + allergyIntolerance.setId(UUID.randomUUID().toString()); + allergyIntolerance.setMeta( + new Meta() + .setLastUpdatedElement(Utils.getCurrentTimeStamp()) + .addProfile(ResourceProfileIdentifier.PROFILE_ALLERGY_INTOLERANCE)); + + Coding coding = new Coding(); + SnomedConditionProcedure snomed = snomedService.getConditionProcedureCode(allergy); + coding.setSystem(BundleUrlIdentifier.SNOMED_URL); + coding.setCode(snomed.getCode()); + coding.setDisplay(snomed.getDisplay()); + CodeableConcept code = new CodeableConcept(); + code.addCoding(coding); + code.setText(snomed.getDisplay()); + + allergyIntolerance.setCode(code); + Coding clinicalStatusCoding = new Coding(); + clinicalStatusCoding.setSystem(ResourceProfileIdentifier.PROFILE_ALLERGY_INTOLERANCE_SYSTEM); + clinicalStatusCoding.setCode(BundleFieldIdentifier.ACTIVE); + clinicalStatusCoding.setDisplay(BundleFieldIdentifier.ACTIVE); + + CodeableConcept clinicalStatus = new CodeableConcept(); + clinicalStatus.addCoding(clinicalStatusCoding); + allergyIntolerance.setClinicalStatus(clinicalStatus); + if (authoredOn != null) + allergyIntolerance.setRecordedDateElement(Utils.getFormattedDateTime(authoredOn)); + allergyIntolerance.setType(AllergyIntolerance.AllergyIntoleranceType.ALLERGY); + allergyIntolerance.setPatient( + new Reference() + .setReference(BundleResourceIdentifier.PATIENT + "/" + patient.getId()) + .setDisplay(patientName.getText())); + if (!(practitionerList.isEmpty())) { + allergyIntolerance.setRecorder( + new Reference() + .setReference( + BundleResourceIdentifier.PRACTITIONER + "/" + practitionerList.get(0).getId()) + .setDisplay(patientName.getText())); + } + return allergyIntolerance; + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeBundleMetaResource.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeBundleMetaResource.java new file mode 100644 index 00000000..14be3a1a --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeBundleMetaResource.java @@ -0,0 +1,27 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.dto.resources; + +import com.nha.abdm.fhir.mapper.Utils; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleFieldIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.ResourceProfileIdentifier; +import java.text.ParseException; +import org.hl7.fhir.r4.model.Coding; +import org.hl7.fhir.r4.model.Meta; +import org.springframework.stereotype.Component; + +@Component +public class MakeBundleMetaResource { + public Meta getMeta() throws ParseException { + Meta meta = new Meta(); + meta.setVersionId("1"); + // meta.setLastUpdated(Utils.getCurrentTimeStamp()); + meta.setLastUpdatedElement(Utils.getCurrentTimeStamp()); + meta.addProfile(ResourceProfileIdentifier.PROFILE_DOCUMENT_BUNDLE); + meta.addSecurity( + new Coding() + .setSystem(ResourceProfileIdentifier.PROFILE_BUNDLE_META) + .setCode("V") + .setDisplay(BundleFieldIdentifier.VERY_RESTRICTED)); + return meta; + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeCarePlanResource.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeCarePlanResource.java new file mode 100644 index 00000000..bdddf0e7 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeCarePlanResource.java @@ -0,0 +1,63 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.dto.resources; + +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; +import com.nha.abdm.fhir.mapper.rest.database.h2.services.SnomedService; +import com.nha.abdm.fhir.mapper.rest.database.h2.tables.SnomedEncounter; +import com.nha.abdm.fhir.mapper.rest.requests.helpers.CarePlanResource; +import java.util.Collections; +import java.util.UUID; +import java.util.stream.Collectors; +import org.hl7.fhir.r4.model.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class MakeCarePlanResource { + + @Autowired SnomedService snomedService; + + public CarePlan getCarePlan(CarePlanResource carePlanResource, Patient patient) { + CarePlan carePlan = new CarePlan(); + carePlan.setId(UUID.randomUUID().toString()); + carePlan.setStatus(CarePlan.CarePlanStatus.ACTIVE); + carePlan.setIntent(CarePlan.CarePlanIntent.fromCode(carePlanResource.getIntent())); + if (carePlanResource.getDescription() != null) { + carePlan.setDescription(carePlanResource.getDescription()); + } + carePlan.setTitle(carePlanResource.getType()); + carePlan.setSubject( + new Reference() + .setReference(BundleResourceIdentifier.PATIENT + "/" + patient.getId()) + .setDisplay( + patient.getName().stream() + .map(HumanName::getText) + .collect(Collectors.joining(" ")))); + + CodeableConcept codeableConcept = new CodeableConcept(); + Coding carePlanCoding = new Coding(); + SnomedEncounter snomed = snomedService.getSnomedEncounterCode(carePlanResource.getType()); + carePlanCoding.setDisplay(snomed.getDisplay()); + carePlanCoding.setSystem(BundleUrlIdentifier.SNOMED_URL); + carePlanCoding.setCode(snomed.getCode()); + codeableConcept.addCoding(carePlanCoding); + carePlan.setCategory(Collections.singletonList(codeableConcept)); + + if (carePlanResource.getNotes() != null) { + // Detail + CarePlan.CarePlanActivityDetailComponent activityDetailComponent = + new CarePlan.CarePlanActivityDetailComponent(); + activityDetailComponent.setDescription(carePlanResource.getNotes()); + // activityDetailComponent.setScheduled(new + // Period().setStartElement(carePlanResource.getPeriod().getFrom()).setEndElement(carePlanResource.getPeriod().getTo())) + carePlan.setActivity( + Collections.singletonList( + new CarePlan.CarePlanActivityComponent().setDetail(activityDetailComponent))); + Annotation annotation = new Annotation(); + annotation.setText(carePlanResource.getNotes()); + carePlan.setNote(Collections.singletonList(annotation)); + } + return carePlan; + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeConditionResource.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeConditionResource.java new file mode 100644 index 00000000..33ff2f98 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeConditionResource.java @@ -0,0 +1,55 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.dto.resources; + +import com.nha.abdm.fhir.mapper.Utils; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.ResourceProfileIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.helpers.DateRange; +import com.nha.abdm.fhir.mapper.rest.database.h2.services.SnomedService; +import com.nha.abdm.fhir.mapper.rest.database.h2.tables.SnomedConditionProcedure; +import java.text.ParseException; +import java.util.UUID; +import org.hl7.fhir.r4.model.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class MakeConditionResource { + @Autowired SnomedService snomedService; + + public Condition getCondition( + String conditionDetails, Patient patient, String recordedDate, DateRange dateRange) + throws ParseException { + HumanName patientName = patient.getName().get(0); + Condition condition = new Condition(); + condition.setId(UUID.randomUUID().toString()); + + SnomedConditionProcedure snomed = snomedService.getConditionProcedureCode(conditionDetails); + condition.setCode( + new CodeableConcept() + .addCoding( + new Coding() + .setDisplay(snomed.getDisplay()) + .setCode(snomed.getCode()) + .setSystem(BundleUrlIdentifier.SNOMED_URL)) + .setText(snomed.getDisplay())); + condition.setMeta( + new Meta() + .setLastUpdatedElement(Utils.getCurrentTimeStamp()) + .addProfile(ResourceProfileIdentifier.PROFILE_CONDITION)); + condition.setSubject( + new Reference() + .setReference(BundleResourceIdentifier.PATIENT + "/" + patient.getId()) + .setDisplay(patientName.getText())); + if (recordedDate != null) + condition.setRecordedDateElement(Utils.getFormattedDateTime(recordedDate)); + if (dateRange != null) { + condition.setOnset( + new Period() + .setStartElement(Utils.getFormattedDateTime(dateRange.getFrom())) + .setEndElement(Utils.getFormattedDateTime(dateRange.getTo()))); + } + return condition; + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeDiagnosticLabResource.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeDiagnosticLabResource.java new file mode 100644 index 00000000..b6c573da --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeDiagnosticLabResource.java @@ -0,0 +1,98 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.dto.resources; + +import com.nha.abdm.fhir.mapper.Utils; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.ResourceProfileIdentifier; +import com.nha.abdm.fhir.mapper.rest.database.h2.services.SnomedService; +import com.nha.abdm.fhir.mapper.rest.database.h2.tables.SnomedDiagnostic; +import com.nha.abdm.fhir.mapper.rest.database.h2.tables.SnomedObservation; +import com.nha.abdm.fhir.mapper.rest.requests.helpers.DiagnosticResource; +import java.text.ParseException; +import java.util.List; +import java.util.Objects; +import java.util.UUID; +import org.hl7.fhir.r4.model.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class MakeDiagnosticLabResource { + @Autowired SnomedService snomedService; + + public DiagnosticReport getDiagnosticReport( + Patient patient, + List practitionerList, + List observationList, + Encounter encounter, + DiagnosticResource diagnosticResource) + throws ParseException { + HumanName patientName = patient.getName().get(0); + DiagnosticReport diagnosticReport = new DiagnosticReport(); + diagnosticReport.setId(UUID.randomUUID().toString()); + diagnosticReport.setMeta( + new Meta() + .setLastUpdatedElement(Utils.getCurrentTimeStamp()) + .addProfile(ResourceProfileIdentifier.PROFILE_DIAGNOSTIC_REPORT_LAB)); + diagnosticReport.setStatus(DiagnosticReport.DiagnosticReportStatus.FINAL); + SnomedDiagnostic snomed = + snomedService.getSnomedDiagnosticCode(diagnosticResource.getServiceName()); + diagnosticReport.setCode( + new CodeableConcept() + .setText(diagnosticResource.getServiceName()) + .addCoding( + new Coding() + .setSystem(BundleUrlIdentifier.LOINC_URL) + .setCode(snomed.getCode()) + .setDisplay(snomed.getDisplay()))); + diagnosticReport.setSubject( + new Reference() + .setReference(BundleResourceIdentifier.PATIENT + "/" + patient.getId()) + .setDisplay(patientName.getText())); + if (Objects.nonNull(encounter)) + diagnosticReport.setEncounter(new Reference().setReference("/" + encounter.getId())); + for (Practitioner practitioner : practitionerList) { + diagnosticReport.addPerformer( + new Reference() + .setReference(BundleResourceIdentifier.PRACTITIONER + "/" + practitioner.getId())); + diagnosticReport.addResultsInterpreter( + new Reference() + .setReference(BundleResourceIdentifier.PRACTITIONER + "/" + practitioner.getId())); + } + SnomedDiagnostic snomedDiagnostic = + snomedService.getSnomedDiagnosticCode(diagnosticResource.getServiceCategory()); + diagnosticReport.addCategory( + new CodeableConcept() + .setText(diagnosticResource.getServiceCategory()) + .addCoding( + new Coding() + .setSystem(BundleUrlIdentifier.SNOMED_URL) + .setCode(snomedDiagnostic.getCode()) + .setDisplay(snomed.getDisplay()))); + for (Observation observation : observationList) { + diagnosticReport.addResult( + new Reference() + .setReference(BundleResourceIdentifier.OBSERVATION + "/" + observation.getId())); + } + diagnosticReport.setIssued(encounter.getPeriod().getStart()); // TODO Conversion of UTC + diagnosticReport.setConclusion(diagnosticResource.getConclusion()); + SnomedObservation snomedObservation = + snomedService.getSnomedObservationCode(diagnosticResource.getConclusion()); + diagnosticReport.addConclusionCode( + new CodeableConcept() + .setText(diagnosticResource.getConclusion()) + .addCoding( + new Coding() + .setSystem(BundleUrlIdentifier.SNOMED_URL) + .setCode(snomedObservation.getCode()) + .setDisplay(snomedObservation.getDisplay()))); + if (Objects.nonNull(diagnosticResource.getPresentedForm())) { + Attachment attachment = new Attachment(); + attachment.setContentType(diagnosticResource.getPresentedForm().getContentType()); + attachment.setData(diagnosticResource.getPresentedForm().getData()); + diagnosticReport.addPresentedForm(attachment); + } + return diagnosticReport; + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeDocumentResource.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeDocumentResource.java new file mode 100644 index 00000000..baba1b56 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeDocumentResource.java @@ -0,0 +1,65 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.dto.resources; + +import com.nha.abdm.fhir.mapper.Utils; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.ResourceProfileIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.helpers.DocumentResource; +import java.text.ParseException; +import java.util.Objects; +import java.util.UUID; +import org.hl7.fhir.r4.model.*; +import org.springframework.stereotype.Component; + +@Component +public class MakeDocumentResource { + public DocumentReference getDocument( + Patient patient, + Organization organization, + DocumentResource documentResource, + String docCode, + String docName) + throws ParseException { + HumanName patientName = patient.getName().get(0); + Coding coding = new Coding(); + coding.setCode(docCode); + coding.setSystem(BundleUrlIdentifier.SNOMED_URL); + coding.setDisplay(docName); + CodeableConcept codeableConcept = new CodeableConcept(); + codeableConcept.addCoding(coding); + codeableConcept.setText(documentResource.getType()); + Identifier identifier = new Identifier(); + identifier.setType(codeableConcept); + identifier.setSystem(BundleUrlIdentifier.FACILITY_URL); + if (Objects.nonNull(organization)) { + identifier.setValue( + organization.getId() == null ? UUID.randomUUID().toString() : organization.getId()); + } else { + identifier.setValue(UUID.randomUUID().toString()); + } + Attachment attachment = new Attachment(); + attachment.setContentType(documentResource.getContentType()); + attachment.setData(documentResource.getData()); + attachment.setTitle(documentResource.getType()); + attachment.setCreationElement(new DateTimeType(Utils.getCurrentTimeStamp().getValueAsString())); + DocumentReference.DocumentReferenceContentComponent documentReferenceContentComponent = + new DocumentReference.DocumentReferenceContentComponent().setAttachment(attachment); + DocumentReference documentReference = new DocumentReference(); + documentReference.setId(UUID.randomUUID().toString()); + documentReference.setMeta( + new Meta() + .setLastUpdatedElement(Utils.getCurrentTimeStamp()) + .addProfile(ResourceProfileIdentifier.PROFILE_DOCUMENT_REFERENCE)); + documentReference.addIdentifier(identifier); + documentReference.addContent(documentReferenceContentComponent); + documentReference.setStatus(Enumerations.DocumentReferenceStatus.CURRENT); + documentReference.setDocStatus(DocumentReference.ReferredDocumentStatus.FINAL); + Reference documentSubject = new Reference(); + documentReference.setSubject( + documentSubject + .setReference(BundleResourceIdentifier.PATIENT + "/" + patient.getId()) + .setDisplay(patientName.getText())); + return documentReference; + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeEncounterResource.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeEncounterResource.java new file mode 100644 index 00000000..741d24a9 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeEncounterResource.java @@ -0,0 +1,46 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.dto.resources; + +import com.nha.abdm.fhir.mapper.Utils; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleFieldIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.ResourceProfileIdentifier; +import com.nha.abdm.fhir.mapper.rest.database.h2.services.SnomedService; +import com.nha.abdm.fhir.mapper.rest.database.h2.tables.SnomedEncounter; +import java.text.ParseException; +import java.util.UUID; +import org.hl7.fhir.r4.model.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class MakeEncounterResource { + @Autowired SnomedService snomedService; + + public Encounter getEncounter(Patient patient, String encounterName, String visitDate) + throws ParseException { + HumanName patientName = patient.getName().get(0); + Encounter encounter = new Encounter(); + encounter.setId(UUID.randomUUID().toString()); + encounter.setStatus(Encounter.EncounterStatus.INPROGRESS); + encounter.setMeta( + new Meta() + .setLastUpdatedElement(Utils.getCurrentTimeStamp()) + .addProfile(ResourceProfileIdentifier.PROFILE_ENCOUNTER)); + SnomedEncounter snomedEncounter = snomedService.getSnomedEncounterCode(encounterName); + encounter.setClass_( + new Coding() + .setSystem(ResourceProfileIdentifier.PROFILE_BUNDLE_META) + .setCode(snomedEncounter.getCode()) + .setDisplay( + (encounterName != null && !encounterName.isEmpty()) + ? encounterName + : BundleFieldIdentifier.AMBULATORY)); + encounter.setSubject( + new Reference() + .setReference(BundleResourceIdentifier.PATIENT + "/" + patient.getId()) + .setDisplay(patientName.getText())); + encounter.setPeriod(new Period().setStartElement(Utils.getFormattedDateTime(visitDate))); + return encounter; + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeFamilyMemberResource.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeFamilyMemberResource.java new file mode 100644 index 00000000..00c79402 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeFamilyMemberResource.java @@ -0,0 +1,64 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.dto.resources; + +import com.nha.abdm.fhir.mapper.Utils; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.ResourceProfileIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.SnomedCodeIdentifier; +import com.nha.abdm.fhir.mapper.rest.database.h2.services.SnomedService; +import com.nha.abdm.fhir.mapper.rest.database.h2.tables.SnomedObservation; +import com.nha.abdm.fhir.mapper.rest.requests.helpers.FamilyObservationResource; +import java.text.ParseException; +import java.util.Objects; +import java.util.UUID; +import org.hl7.fhir.r4.model.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class MakeFamilyMemberResource { + + @Autowired SnomedService snomedService; + + public FamilyMemberHistory getFamilyHistory( + Patient patient, FamilyObservationResource familyObservationResource) throws ParseException { + HumanName patientName = patient.getName().get(0); + FamilyMemberHistory familyMemberHistory = new FamilyMemberHistory(); + familyMemberHistory.setId(UUID.randomUUID().toString()); + familyMemberHistory.setStatus(FamilyMemberHistory.FamilyHistoryStatus.COMPLETED); + familyMemberHistory.setMeta( + new Meta() + .setLastUpdatedElement(Utils.getCurrentTimeStamp()) + .addProfile(ResourceProfileIdentifier.PROFILE_FAMILY_MEMBER_HISTORY)); + familyMemberHistory.setPatient( + new Reference() + .setReference(BundleResourceIdentifier.PATIENT + "/" + patient.getId()) + .setDisplay(patientName.getText())); + if (Objects.nonNull(familyObservationResource.getRelationship())) { + familyMemberHistory.setRelationship( + new CodeableConcept() + .addCoding( + new Coding() + .setSystem(BundleUrlIdentifier.SNOMED_URL) + .setCode(SnomedCodeIdentifier.SNOMED_UNKNOWN) + .setDisplay(familyObservationResource.getRelationship())) + .setText(familyObservationResource.getRelationship())); + } + if (Objects.nonNull(familyObservationResource.getObservation())) { + SnomedObservation snomedCondition = + snomedService.getSnomedObservationCode(familyObservationResource.getObservation()); + familyMemberHistory.addCondition( + new FamilyMemberHistory.FamilyMemberHistoryConditionComponent() + .setCode( + new CodeableConcept() + .addCoding( + new Coding() + .setSystem(BundleUrlIdentifier.SNOMED_URL) + .setCode(snomedCondition.getCode()) + .setDisplay(snomedCondition.getDisplay())) + .setText(snomedCondition.getDisplay()))); + } + return familyMemberHistory; + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeImmunizationResource.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeImmunizationResource.java new file mode 100644 index 00000000..7870a0be --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeImmunizationResource.java @@ -0,0 +1,90 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.dto.resources; + +import com.nha.abdm.fhir.mapper.Utils; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.ResourceProfileIdentifier; +import com.nha.abdm.fhir.mapper.rest.database.h2.services.SnomedService; +import com.nha.abdm.fhir.mapper.rest.database.h2.tables.SnomedVaccine; +import com.nha.abdm.fhir.mapper.rest.requests.helpers.ImmunizationResource; +import java.text.ParseException; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.UUID; +import org.hl7.fhir.r4.model.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class MakeImmunizationResource { + @Autowired SnomedService snomedService; + + public Immunization getImmunization( + Patient patient, + List practitionerList, + Organization organization, + ImmunizationResource immunizationResource) + throws ParseException { + Immunization immunization = new Immunization(); + immunization.setId(UUID.randomUUID().toString()); + Meta meta = new Meta(); + meta.setVersionId("1"); + meta.setLastUpdatedElement(Utils.getCurrentTimeStamp()); + meta.addProfile(ResourceProfileIdentifier.PROFILE_IMMUNIZATION); + immunization.setMeta(meta); + immunization.setStatus(Immunization.ImmunizationStatus.COMPLETED); + + immunization.setPatient( + new Reference().setReference(BundleResourceIdentifier.PATIENT + "/" + patient.getId())); + if (Objects.nonNull(immunizationResource.getDate())) { + immunization.setOccurrence((Utils.getFormattedDateTime(immunizationResource.getDate()))); + } + if (Objects.nonNull(immunizationResource.getVaccineName())) { + immunization.addExtension( + new Extension() + .setValue(new StringType().setValue(immunizationResource.getVaccineName())) + .setUrl(ResourceProfileIdentifier.PROFILE_VACCINE_BRAND_NAME)); + + SnomedVaccine snomedVaccine = + snomedService.getSnomedVaccineCode(immunizationResource.getVaccineName()); + immunization.setVaccineCode( + new CodeableConcept() + .setText(immunizationResource.getVaccineName()) + .addCoding( + new Coding() + .setSystem(BundleUrlIdentifier.SNOMED_URL) + .setCode(snomedVaccine.getCode()) + .setDisplay(snomedVaccine.getDisplay()))); + } + immunization.setPrimarySource(true); + if (Objects.nonNull(immunizationResource.getManufacturer())) { + immunization.setManufacturer( + new Reference() + .setReference(BundleResourceIdentifier.MANUFACTURER + "/" + organization.getId()) + .setDisplay(organization.getName())); + } + if (Objects.nonNull(immunizationResource.getLotNumber())) { + immunization.setLotNumber(immunizationResource.getLotNumber()); + } + if (Objects.nonNull(immunizationResource.getDoseNumber())) { + immunization.setDoseQuantity(new Quantity().setValue(immunizationResource.getDoseNumber())); + immunization.setProtocolApplied( + Collections.singletonList( + new Immunization.ImmunizationProtocolAppliedComponent() + .setDoseNumber( + new PositiveIntType().setValue(immunizationResource.getDoseNumber())))); + } + + for (Practitioner practitioner : practitionerList) { + immunization.addPerformer( + new Immunization.ImmunizationPerformerComponent() + .setActor( + new Reference() + .setReference( + BundleResourceIdentifier.PRACTITIONER + "/" + practitioner.getId()))); + } + return immunization; + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeMedicationRequestResource.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeMedicationRequestResource.java new file mode 100644 index 00000000..d29445e0 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeMedicationRequestResource.java @@ -0,0 +1,137 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.dto.resources; + +import com.nha.abdm.fhir.mapper.Utils; +import com.nha.abdm.fhir.mapper.rest.common.constants.*; +import com.nha.abdm.fhir.mapper.rest.database.h2.services.SnomedService; +import com.nha.abdm.fhir.mapper.rest.database.h2.tables.SnomedMedicine; +import com.nha.abdm.fhir.mapper.rest.database.h2.tables.SnomedMedicineRoute; +import com.nha.abdm.fhir.mapper.rest.requests.helpers.PrescriptionResource; +import java.text.ParseException; +import java.util.*; +import org.hl7.fhir.r4.model.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class MakeMedicationRequestResource { + @Autowired SnomedService snomedService; + + public MedicationRequest getMedicationResource( + String authoredOn, + PrescriptionResource prescriptionResource, + Condition medicationCondition, + Organization organization, + List practitioners, + Patient patient) + throws ParseException { + HumanName patientName = patient.getName().get(0); + MedicationRequest medicationRequest = new MedicationRequest(); + + // Setting Meta of the Medication Resource + medicationRequest.setMeta( + new Meta() + .addProfile(ResourceProfileIdentifier.PROFILE_MEDICATION_REQUEST) + .setLastUpdatedElement(Utils.getCurrentTimeStamp())); + + // Setting Medications + SnomedMedicine snomedMedicine = + snomedService.getSnomedMedicineCode(prescriptionResource.getMedicine()); + medicationRequest.setMedication( + new CodeableConcept() + .setText(prescriptionResource.getMedicine()) + .addCoding( + new Coding() + .setSystem(BundleUrlIdentifier.SNOMED_URL) + .setCode(snomedMedicine.getCode()) + .setDisplay(snomedMedicine.getDisplay()))); + if (prescriptionResource.getDosage() != null) { + Dosage dosage = new Dosage(); + dosage.setText(prescriptionResource.getDosage()); + if (prescriptionResource.getAdditionalInstructions() != null) { + dosage.addAdditionalInstruction( + new CodeableConcept() + .setText(prescriptionResource.getAdditionalInstructions()) + .addCoding( + new Coding() + .setSystem(BundleUrlIdentifier.SNOMED_URL) + .setCode(SnomedCodeIdentifier.SNOMED_UNKNOWN) + .setDisplay(prescriptionResource.getAdditionalInstructions()))); + } + if (prescriptionResource.getRoute() != null) { + SnomedMedicineRoute snomedMedicineRoute = + snomedService.getSnomedMedicineRouteCode(prescriptionResource.getRoute()); + dosage.setRoute( + new CodeableConcept() + .setText(prescriptionResource.getRoute()) + .addCoding( + new Coding() + .setSystem(BundleUrlIdentifier.SNOMED_URL) + .setCode(snomedMedicineRoute.getCode()) + .setDisplay(snomedMedicine.getDisplay()))); + } + if (prescriptionResource.getMethod() != null) { + SnomedMedicineRoute snomedMethod = + snomedService.getSnomedMedicineRouteCode(prescriptionResource.getRoute()); + dosage.setMethod( + new CodeableConcept() + .setText(prescriptionResource.getMethod()) + .addCoding( + new Coding() + .setSystem(BundleUrlIdentifier.SNOMED_URL) + .setCode(snomedMethod.getCode()) + .setDisplay(snomedMethod.getDisplay()))); + } + if (prescriptionResource.getTiming() != null) { + String[] parts = prescriptionResource.getTiming().split("-"); + dosage.setTiming( + new Timing() + .setRepeat( + new Timing.TimingRepeatComponent() + .setFrequency(Integer.parseInt(parts[0])) + .setPeriod(Integer.parseInt(parts[1])) + .setPeriodUnit(Timing.UnitsOfTime.valueOf(parts[2])))); + } + medicationRequest.setDosageInstruction(Collections.singletonList(dosage)); + } + if (medicationCondition != null) { + medicationRequest.setReasonCode( + Collections.singletonList( + new CodeableConcept() + .addCoding( + new Coding() + .setSystem(BundleUrlIdentifier.SNOMED_URL) + .setCode( + snomedService + .getConditionProcedureCode( + medicationCondition.getCode().getText()) + .getCode()) + .setDisplay(medicationCondition.getCode().getText())) + .setText(medicationCondition.getCode().getText()))); + medicationRequest.setReasonReference( + Collections.singletonList( + new Reference() + .setReference( + BundleResourceIdentifier.CONDITION + "/" + medicationCondition.getId()) + .setDisplay(BundleFieldIdentifier.MEDICAL_CONDITION))); + } + if (!practitioners.isEmpty()) { + Practitioner practitioner = practitioners.get(0); + HumanName practitionerName = practitioner.getName().get(0); + medicationRequest.setRequester( + new Reference() + .setReference(BundleResourceIdentifier.PRACTITIONER + "/" + practitioner.getId()) + .setDisplay(practitionerName.getText())); + } + medicationRequest.setSubject( + new Reference() + .setReference(BundleResourceIdentifier.PATIENT + "/" + patient.getId()) + .setDisplay(patientName.getText())); + if (authoredOn != null) + medicationRequest.setAuthoredOnElement(Utils.getFormattedDateTime(authoredOn)); + medicationRequest.setStatus(MedicationRequest.MedicationRequestStatus.COMPLETED); + medicationRequest.setIntent(MedicationRequest.MedicationRequestIntent.ORDER); + medicationRequest.setId(UUID.randomUUID().toString()); + return medicationRequest; + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeObservationResource.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeObservationResource.java new file mode 100644 index 00000000..954dc899 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeObservationResource.java @@ -0,0 +1,74 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.dto.resources; + +import com.nha.abdm.fhir.mapper.Utils; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.ResourceProfileIdentifier; +import com.nha.abdm.fhir.mapper.rest.database.h2.services.SnomedService; +import com.nha.abdm.fhir.mapper.rest.database.h2.tables.SnomedObservation; +import com.nha.abdm.fhir.mapper.rest.requests.helpers.ObservationResource; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.UUID; +import org.hl7.fhir.r4.model.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class MakeObservationResource { + @Autowired SnomedService snomedService; + private static final Logger log = LoggerFactory.getLogger(MakeObservationResource.class); + + public Observation getObservation( + Patient patient, List practitionerList, ObservationResource observationResource) + throws ParseException { + HumanName patientName = patient.getName().get(0); + Observation observation = new Observation(); + observation.setStatus(Observation.ObservationStatus.FINAL); + SnomedObservation snomed = + snomedService.getSnomedObservationCode(observationResource.getObservation()); + observation.setCode( + new CodeableConcept() + .setText(observationResource.getObservation()) + .addCoding( + new Coding() + .setSystem(BundleUrlIdentifier.SNOMED_URL) + .setCode(snomed.getCode()) + .setDisplay(snomed.getDisplay()))); + observation.setSubject( + new Reference() + .setReference(BundleResourceIdentifier.PATIENT + "/" + patient.getId()) + .setDisplay(patientName.getText())); + List performerList = new ArrayList<>(); + HumanName practitionerName = null; + for (Practitioner practitioner : practitionerList) { + practitionerName = practitioner.getName().get(0); + performerList.add( + new Reference() + .setReference(BundleResourceIdentifier.PRACTITIONER + "/" + practitioner.getId()) + .setDisplay(practitionerName.getText())); + } + observation.setPerformer(performerList); + if (Objects.nonNull(observationResource.getValueQuantity())) { + observation.setValue( + new Quantity() + .setValue(observationResource.getValueQuantity().getValue()) + .setUnit(observationResource.getValueQuantity().getUnit())); + } + if (Objects.nonNull(observation.getValueQuantity()) + && observationResource.getResult() != null) { + observation.setValue(new CodeableConcept().setText(observationResource.getResult())); + } + observation.setId(UUID.randomUUID().toString()); + observation.setMeta( + new Meta() + .setLastUpdatedElement(Utils.getCurrentTimeStamp()) + .addProfile(ResourceProfileIdentifier.PROFILE_OBSERVATION)); + return observation; + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeOrganisationResource.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeOrganisationResource.java new file mode 100644 index 00000000..a8aecfe5 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeOrganisationResource.java @@ -0,0 +1,51 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.dto.resources; + +import com.nha.abdm.fhir.mapper.Utils; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.ResourceProfileIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.helpers.OrganisationResource; +import java.text.ParseException; +import java.util.Objects; +import java.util.UUID; +import org.hl7.fhir.r4.model.*; +import org.springframework.stereotype.Component; + +@Component +public class MakeOrganisationResource { + public Organization getOrganization(OrganisationResource organisationResource) + throws ParseException { + Coding coding = new Coding(); + coding.setCode("PRN"); + coding.setSystem(ResourceProfileIdentifier.PROFILE_PROVIDER); + coding.setDisplay("Provider number"); + CodeableConcept codeableConcept = new CodeableConcept(); + codeableConcept.addCoding(coding); + Identifier identifier = new Identifier(); + identifier.setType(codeableConcept); + identifier.setSystem(BundleUrlIdentifier.FACILITY_URL); + if (Objects.nonNull(organisationResource)) { + identifier.setValue( + organisationResource.getFacilityId() == null + ? UUID.randomUUID().toString() + : organisationResource.getFacilityId()); + } else { + identifier.setValue(UUID.randomUUID().toString()); + } + + Meta meta = new Meta(); + meta.setVersionId("1"); + meta.setLastUpdatedElement(Utils.getCurrentTimeStamp()); + meta.addProfile(ResourceProfileIdentifier.PROFILE_ORGANISATION); + + Organization organization = new Organization(); + organization.setName( + organisationResource.getFacilityName() != null + ? organisationResource.getFacilityName() + : organisationResource.getFacilityId()); + organization.setMeta(meta); + organization.addIdentifier(identifier); + organization.setId(UUID.randomUUID().toString()); + return organization; + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakePatientResource.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakePatientResource.java new file mode 100644 index 00000000..92e6e780 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakePatientResource.java @@ -0,0 +1,49 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.dto.resources; + +import com.nha.abdm.fhir.mapper.Utils; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.ResourceProfileIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.helpers.PatientResource; +import java.text.ParseException; +import java.util.Locale; +import java.util.UUID; +import org.hl7.fhir.r4.model.*; +import org.springframework.stereotype.Component; + +@Component +public class MakePatientResource { + + public Patient getPatient(PatientResource patientResource) throws ParseException { + Coding coding = new Coding(); + coding.setCode("MR"); + coding.setSystem(ResourceProfileIdentifier.PROFILE_PROVIDER); + coding.setDisplay("Medical record number"); + CodeableConcept codeableConcept = new CodeableConcept(); + codeableConcept.addCoding(coding); + Identifier identifier = new Identifier(); + identifier.setType(codeableConcept); + identifier.setSystem(BundleUrlIdentifier.HEALTH_ID_URL); + identifier.setValue(patientResource.getPatientReference()); + + Meta meta = new Meta(); + meta.setVersionId("1"); + meta.setLastUpdatedElement(Utils.getCurrentTimeStamp()); + meta.addProfile(ResourceProfileIdentifier.PROFILE_PATIENT); + + Patient patient = new Patient(); + patient.addName(new HumanName().setText(patientResource.getName())); + if (patientResource.getGender() != null) { + patient.setGender( + Enumerations.AdministrativeGender.fromCode( + patientResource.getGender().toLowerCase(Locale.ROOT))); + } + if (patientResource.getBirthDate() != null) { + patient.setBirthDate(Utils.getFormattedDateTime(patientResource.getBirthDate()).getValue()); + } + patient.setMeta(meta); + patient.addIdentifier(identifier); + patient.setId(UUID.randomUUID().toString()); + return patient; + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakePractitionerResource.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakePractitionerResource.java new file mode 100644 index 00000000..753021e0 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakePractitionerResource.java @@ -0,0 +1,44 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.dto.resources; + +import com.nha.abdm.fhir.mapper.Utils; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleFieldIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.ResourceProfileIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.helpers.PractitionerResource; +import java.text.ParseException; +import java.util.UUID; +import org.hl7.fhir.r4.model.*; +import org.springframework.stereotype.Component; + +@Component +public class MakePractitionerResource { + public Practitioner getPractitioner(PractitionerResource practitionerResource) + throws ParseException { + Coding coding = new Coding(); + coding.setCode("MR"); + coding.setSystem(ResourceProfileIdentifier.PROFILE_PROVIDER); + coding.setDisplay(BundleFieldIdentifier.MEDICAL_RECORD_NUMBER); + CodeableConcept codeableConcept = new CodeableConcept(); + codeableConcept.addCoding(coding); + Identifier identifier = new Identifier(); + identifier.setType(codeableConcept); + identifier.setSystem(BundleUrlIdentifier.DOCTOR_ID_URL); + identifier.setValue(practitionerResource.getPractitionerId()); + + Meta meta = new Meta(); + meta.setVersionId("1"); + meta.setLastUpdatedElement(Utils.getCurrentTimeStamp()); + meta.addProfile(ResourceProfileIdentifier.PROFILE_PRACTITIONER); + + Practitioner practitioner = new Practitioner(); + practitioner.addName(new HumanName().setText(practitionerResource.getName())); + practitioner.setMeta(meta); + practitioner.addIdentifier(identifier); + practitioner.setId( + practitionerResource.getPractitionerId() != null + ? practitionerResource.getPractitionerId() + : UUID.randomUUID().toString()); + return practitioner; + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeProcedureResource.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeProcedureResource.java new file mode 100644 index 00000000..f632cb9d --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeProcedureResource.java @@ -0,0 +1,68 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.dto.resources; + +import com.nha.abdm.fhir.mapper.Utils; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.ResourceProfileIdentifier; +import com.nha.abdm.fhir.mapper.rest.database.h2.services.SnomedService; +import com.nha.abdm.fhir.mapper.rest.database.h2.tables.SnomedConditionProcedure; +import com.nha.abdm.fhir.mapper.rest.requests.helpers.ProcedureResource; +import java.text.ParseException; +import java.util.UUID; +import org.hl7.fhir.r4.model.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class MakeProcedureResource { + @Autowired SnomedService snomedService; + + public Procedure getProcedure(Patient patient, ProcedureResource procedureResource) + throws ParseException { + Procedure procedure = new Procedure(); + procedure.setId(UUID.randomUUID().toString()); + procedure.setMeta(new Meta().addProfile(ResourceProfileIdentifier.PROFILE_PROCEDURE)); + if (procedureResource.getStatus() != null) { + procedure.setStatus(Procedure.ProcedureStatus.valueOf(procedureResource.getStatus())); + } else { + procedure.setStatus(Procedure.ProcedureStatus.COMPLETED); + } + procedure.setSubject( + new Reference().setReference(BundleResourceIdentifier.PATIENT + "/" + patient.getId())); + SnomedConditionProcedure snomedProcedure = + snomedService.getConditionProcedureCode(procedureResource.getProcedureName()); + procedure.setCode( + new CodeableConcept() + .setText(procedureResource.getProcedureName()) + .addCoding( + new Coding() + .setDisplay(snomedProcedure.getDisplay()) + .setCode(snomedProcedure.getCode()) + .setSystem(BundleUrlIdentifier.SNOMED_URL))); + if (procedureResource.getOutcome() != null) { + SnomedConditionProcedure snomedOutcome = + snomedService.getConditionProcedureCode(procedureResource.getOutcome()); + procedure.setOutcome( + new CodeableConcept() + .setText(procedureResource.getOutcome()) + .addCoding( + new Coding() + .setSystem(BundleUrlIdentifier.SNOMED_URL) + .setCode(snomedOutcome.getCode()) + .setDisplay(snomedOutcome.getDisplay()))); + } + SnomedConditionProcedure snomedCondition = + snomedService.getConditionProcedureCode(procedureResource.getProcedureReason()); + procedure.addReasonCode( + new CodeableConcept() + .setText(procedureResource.getProcedureReason()) + .addCoding( + new Coding() + .setSystem(BundleUrlIdentifier.SNOMED_URL) + .setCode(snomedCondition.getCode()) + .setDisplay(snomedCondition.getDisplay()))); + procedure.setPerformed((Utils.getFormattedDateTime(procedureResource.getDate()))); + return procedure; + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeServiceRequestResource.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeServiceRequestResource.java new file mode 100644 index 00000000..7fad8571 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeServiceRequestResource.java @@ -0,0 +1,82 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.dto.resources; + +import com.nha.abdm.fhir.mapper.Utils; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.ResourceProfileIdentifier; +import com.nha.abdm.fhir.mapper.rest.database.h2.services.SnomedService; +import com.nha.abdm.fhir.mapper.rest.database.h2.tables.SnomedDiagnostic; +import com.nha.abdm.fhir.mapper.rest.requests.helpers.ServiceRequestResource; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import org.hl7.fhir.r4.model.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class MakeServiceRequestResource { + @Autowired SnomedService snomedService; + + public ServiceRequest getServiceRequest( + Patient patient, + List practitionerList, + ServiceRequestResource serviceRequestResource, + String authoredOn) + throws ParseException { + HumanName patientName = patient.getName().get(0); + ServiceRequest serviceRequest = new ServiceRequest(); + serviceRequest.setId(UUID.randomUUID().toString()); + serviceRequest.setStatus( + ServiceRequest.ServiceRequestStatus.valueOf(serviceRequestResource.getStatus())); + serviceRequest.setIntent(ServiceRequest.ServiceRequestIntent.PROPOSAL); + serviceRequest.setStatus(ServiceRequest.ServiceRequestStatus.ACTIVE); + serviceRequest.setAuthoredOnElement(Utils.getFormattedDateTime(authoredOn)); + serviceRequest.setMeta( + new Meta() + .setLastUpdatedElement(Utils.getCurrentTimeStamp()) + .addProfile(ResourceProfileIdentifier.PROFILE_SERVICE_REQUEST)); + SnomedDiagnostic snomedDiagnostic = + snomedService.getSnomedDiagnosticCode(serviceRequestResource.getDetails()); + serviceRequest.setCode( + new CodeableConcept() + .addCoding( + new Coding() + .setDisplay(snomedDiagnostic.getDisplay()) + .setCode(snomedDiagnostic.getCode()) + .setSystem(BundleUrlIdentifier.SNOMED_URL)) + .setText(serviceRequestResource.getDetails())); + serviceRequest.setSubject( + new Reference() + .setReference(BundleResourceIdentifier.PATIENT + "/" + patient.getId()) + .setDisplay(patientName.getText())); + List performerList = new ArrayList<>(); + HumanName practitionerName = null; + for (Practitioner practitioner : practitionerList) { + practitionerName = practitioner.getName().get(0); + performerList.add( + new Reference() + .setReference(BundleResourceIdentifier.PRACTITIONER + "/" + practitioner.getId()) + .setDisplay(practitionerName.getText())); + } + if (!performerList.isEmpty()) { + Practitioner practitioner = practitionerList.get(0); + practitionerName = practitioner.getName().get(0); + serviceRequest.setRequester( + new Reference() + .setReference(BundleResourceIdentifier.PRACTITIONER + "/" + practitioner.getId()) + .setDisplay(practitionerName.getText())); + } + serviceRequest.setPerformer(performerList); + if (serviceRequestResource.getSpecimen() != null) + serviceRequest.addSpecimen( + new Reference() + .setDisplay( + snomedService + .getSnomedSpecimenCode(serviceRequestResource.getSpecimen()) + .getDisplay())); + return serviceRequest; + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeWellnessObservationResource.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeWellnessObservationResource.java new file mode 100644 index 00000000..71800e6f --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/MakeWellnessObservationResource.java @@ -0,0 +1,80 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.dto.resources; + +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.SnomedCodeIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.WellnessFieldIdentifiers; +import com.nha.abdm.fhir.mapper.rest.database.h2.services.SnomedService; +import com.nha.abdm.fhir.mapper.rest.database.h2.tables.SnomedObservation; +import com.nha.abdm.fhir.mapper.rest.requests.helpers.WellnessObservationResource; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.UUID; +import org.hl7.fhir.r4.model.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class MakeWellnessObservationResource { + @Autowired SnomedService snomedService; + + public Observation getObservation( + Patient patient, + List practitionerList, + WellnessObservationResource observationResource, + String type) { + HumanName patientName = patient.getName().get(0); + Observation observation = new Observation(); + observation.setStatus(Observation.ObservationStatus.FINAL); + CodeableConcept typeCode = new CodeableConcept(); + Coding coding = new Coding(); + SnomedObservation snomed = + snomedService.getSnomedObservationCode(observationResource.getObservation()); + coding.setSystem(WellnessFieldIdentifiers.getSystem(type)); + if (Objects.nonNull(snomed)) { + coding.setCode(snomed.getCode()); + coding.setDisplay(snomed.getDisplay()); + typeCode.addCoding(coding); + } else { + coding.setCode( + coding.getSystem().equalsIgnoreCase(BundleUrlIdentifier.LOINC_URL) + ? SnomedCodeIdentifier.LOINC_UNKNOWN + : SnomedCodeIdentifier.SNOMED_UNKNOWN); + coding.setDisplay(observationResource.getObservation()); + typeCode.addCoding(coding); + } + + typeCode.setText(snomed == null ? observationResource.getObservation() : snomed.getDisplay()); + + observation.setCode(typeCode); + observation.setSubject( + new Reference() + .setReference(BundleResourceIdentifier.PATIENT + "/" + patient.getId()) + .setDisplay(patientName.getText())); + List performerList = new ArrayList<>(); + HumanName practitionerName = null; + for (Practitioner practitioner : practitionerList) { + practitionerName = practitioner.getName().get(0); + performerList.add( + new Reference() + .setReference(BundleResourceIdentifier.PRACTITIONER + "/" + practitioner.getId()) + .setDisplay(practitionerName.getText())); + } + observation.setPerformer(performerList); + if (observationResource.getValueQuantity() != null) { + observation.setValue( + new Quantity() + .setValue(observationResource.getValueQuantity().getValue()) + .setUnit(observationResource.getValueQuantity().getUnit())); + } + if (observationResource.getResult() != null) { + observation.setValue(new CodeableConcept().setText(observationResource.getResult())); + observation.setValue(new StringType(observationResource.getResult())); + } + + observation.setId(UUID.randomUUID().toString()); + return observation; + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/exceptions/GlobalExceptionHandler.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/exceptions/GlobalExceptionHandler.java new file mode 100644 index 00000000..8275079f --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/exceptions/GlobalExceptionHandler.java @@ -0,0 +1,124 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.exceptions; + +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.exc.InvalidFormatException; +import com.nha.abdm.fhir.mapper.rest.common.constants.ErrorCode; +import com.nha.abdm.fhir.mapper.rest.common.helpers.ErrorResponse; +import com.nha.abdm.fhir.mapper.rest.common.helpers.FacadeError; +import com.nha.abdm.fhir.mapper.rest.common.helpers.FieldErrorsResponse; +import com.nha.abdm.fhir.mapper.rest.common.helpers.ValidationErrorResponse; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.json.JsonParseException; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.http.converter.HttpMessageNotReadableException; +import org.springframework.validation.FieldError; +import org.springframework.validation.ObjectError; +import org.springframework.web.HttpMediaTypeNotAcceptableException; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseStatus; + +@ControllerAdvice +public class GlobalExceptionHandler { + private static Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class); + + @ResponseStatus(HttpStatus.BAD_REQUEST) + @ExceptionHandler(MethodArgumentNotValidException.class) + public ResponseEntity handleValidationExceptions( + MethodArgumentNotValidException ex) { + List fieldErrorResponses = new ArrayList<>(); + for (ObjectError error : ex.getBindingResult().getAllErrors()) { + if (error instanceof FieldError) { + FieldError fieldError = (FieldError) error; + fieldErrorResponses.add( + new FieldErrorsResponse(fieldError.getField(), fieldError.getDefaultMessage())); + } + } + + ValidationErrorResponse errorResponse = + new ValidationErrorResponse(ErrorCode.VALIDATION_ERROR, fieldErrorResponses); + return new ResponseEntity<>( + FacadeError.builder().validationErrors(errorResponse).build(), HttpStatus.BAD_REQUEST); + } + + @ExceptionHandler(HttpMessageNotReadableException.class) + public ResponseEntity handleHttpMessageNotReadable(HttpMessageNotReadableException ex) { + Throwable cause = ex.getCause(); + String errorMessage = "Invalid request. Please check the JSON format."; + + if (cause instanceof InvalidFormatException) { + InvalidFormatException invalidFormatException = (InvalidFormatException) cause; + Class targetType = invalidFormatException.getTargetType(); + errorMessage = + "Invalid input: Unable to map value to " + + targetType.getSimpleName() + + ", Kindly check base64 data"; + } else if (cause instanceof JsonMappingException) { + errorMessage = "Invalid JSON structure. " + getParseExceptionMessage(cause); + } else if (cause instanceof JsonParseException) { + errorMessage = "JSON parse error: " + cause.getMessage(); + } else if (cause != null) { + errorMessage += " Error: " + cause.getMessage(); + } + + FacadeError response = + FacadeError.builder() + .description("Invalid request. Please check the JSON format.") + .error( + ErrorResponse.builder().message(errorMessage).code(ErrorCode.PARSE_ERROR).build()) + .build(); + + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(response); + } + + @ExceptionHandler(HttpMediaTypeNotAcceptableException.class) + public ResponseEntity handleNotAcceptable(HttpMediaTypeNotAcceptableException ex) { + log.error("406 Not Acceptable: " + ex.getMessage()); + + ErrorResponse errorResponse = + new ErrorResponse( + ErrorCode.PARSE_ERROR, + "The requested media type is not supported. Please check the 'Accept' header and base64 data if present"); + return new ResponseEntity<>( + FacadeError.builder() + .description("Issue with base64 data or contentType/accept") + .error(errorResponse) + .build(), + HttpStatus.BAD_REQUEST); + } + + @ExceptionHandler(ParseException.class) + public ResponseEntity handleParseException(ParseException ex) { + String errorMessage = "ParseError: " + ex.getMessage(); + + log.error("Parse error: " + ex.getMessage()); + ErrorResponse errorResponse = new ErrorResponse(ErrorCode.PARSE_ERROR, errorMessage); + return new ResponseEntity<>(errorResponse, HttpStatus.BAD_REQUEST); + } + + private String getParseExceptionMessage(Throwable cause) { + JsonMappingException jsonMappingException = (JsonMappingException) cause; + + StringBuilder fieldPath = new StringBuilder(); + for (JsonMappingException.Reference ref : jsonMappingException.getPath()) { + if (ref.getIndex() != -1) { + fieldPath.append("[").append(ref.getIndex()).append("]"); + } else if (ref.getFieldName() != null) { + if (fieldPath.length() > 0) fieldPath.append("."); + fieldPath.append(ref.getFieldName()); + } + } + + return "JSON parse error in field '" + + fieldPath + + "': " + + jsonMappingException.getOriginalMessage(); + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/exceptions/NotBlankFields.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/exceptions/NotBlankFields.java new file mode 100644 index 00000000..b503eb87 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/exceptions/NotBlankFields.java @@ -0,0 +1,20 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.exceptions; + +import jakarta.validation.Constraint; +import jakarta.validation.Payload; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Constraint(validatedBy = NotBlankFieldsValidator.class) +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +public @interface NotBlankFields { + String message() default "{field} is mandatory"; + + Class[] groups() default {}; + + Class[] payload() default {}; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/exceptions/NotBlankFieldsValidator.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/exceptions/NotBlankFieldsValidator.java new file mode 100644 index 00000000..e6da7bde --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/exceptions/NotBlankFieldsValidator.java @@ -0,0 +1,49 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.exceptions; + +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; +import org.apache.commons.lang3.StringUtils; + +public class NotBlankFieldsValidator implements ConstraintValidator { + + private String message; + + @Override + public void initialize(NotBlankFields constraintAnnotation) { + this.message = constraintAnnotation.message(); + } + + @Override + public boolean isValid(Object obj, ConstraintValidatorContext context) { + List nullFields = new ArrayList<>(); + + for (Field field : obj.getClass().getDeclaredFields()) { + field.setAccessible(true); + try { + Object value = field.get(obj); + if (value == null || StringUtils.isBlank(value.toString())) { + nullFields.add(field.getName()); + } + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + + if (!nullFields.isEmpty()) { + context.disableDefaultConstraintViolation(); + for (String nullField : nullFields) { + context + .buildConstraintViolationWithTemplate(nullField + " is mandatory") + .addPropertyNode(nullField) + .addConstraintViolation(); + } + return false; + } + + return true; + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/exceptions/StreamUtils.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/exceptions/StreamUtils.java new file mode 100644 index 00000000..92f6c911 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/exceptions/StreamUtils.java @@ -0,0 +1,29 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.exceptions; + +import java.util.function.Function; + +public class StreamUtils { + + @FunctionalInterface + public interface CheckedFunction { + R apply(T t) throws Exception; + } + + public static Function wrapException(CheckedFunction function) { + return t -> { + try { + return function.apply(t); + } catch (Exception e) { + throw new RuntimeException( + "Exception in stream processing" + + e.getMessage() + + " " + + e.getCause() + + " " + + e.getLocalizedMessage(), + e); + } + }; + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/DiagnosticReportRequest.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/DiagnosticReportRequest.java new file mode 100644 index 00000000..1b4d7d73 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/DiagnosticReportRequest.java @@ -0,0 +1,47 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.requests; + +import com.nha.abdm.fhir.mapper.rest.common.helpers.DocumentResource; +import com.nha.abdm.fhir.mapper.rest.common.helpers.OrganisationResource; +import com.nha.abdm.fhir.mapper.rest.common.helpers.PatientResource; +import com.nha.abdm.fhir.mapper.rest.common.helpers.PractitionerResource; +import com.nha.abdm.fhir.mapper.rest.requests.helpers.DiagnosticResource; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; +import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@AllArgsConstructor +@Data +@Builder +public class DiagnosticReportRequest { + @Pattern(regexp = "DiagnosticReportRecord") + @NotBlank(message = "BundleType is mandatory and must not be empty : 'DiagnosticReportRecord'") + private String bundleType; + + @NotBlank(message = "careContextReference is mandatory and must not be empty") + private String careContextReference; + + @Valid + @NotNull(message = "Patient demographic details are mandatory and must not be empty") private PatientResource patient; + + @Pattern( + regexp = "^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z)?$", + message = "Value must match either yyyy-MM-dd or yyyy-MM-dd'T'HH:mm:ss.SSSZ") + @NotBlank(message = "visitDate is mandatory timestamp") + @NotNull private String visitDate; + + @Valid + @NotNull(message = "practitioners are mandatory and must not be empty") private List practitioners; + + private OrganisationResource organisation; + private String encounter; + @Valid private List diagnostics; + @Valid private List documents; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/DischargeSummaryRequest.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/DischargeSummaryRequest.java new file mode 100644 index 00000000..c5cc13d9 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/DischargeSummaryRequest.java @@ -0,0 +1,58 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.requests; + +import com.nha.abdm.fhir.mapper.rest.common.helpers.DocumentResource; +import com.nha.abdm.fhir.mapper.rest.common.helpers.OrganisationResource; +import com.nha.abdm.fhir.mapper.rest.common.helpers.PatientResource; +import com.nha.abdm.fhir.mapper.rest.common.helpers.PractitionerResource; +import com.nha.abdm.fhir.mapper.rest.requests.helpers.*; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; +import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@AllArgsConstructor +@Data +@Builder +public class DischargeSummaryRequest { + @Pattern(regexp = "DischargeSummaryRecord") + @NotBlank(message = "BundleType is mandatory and must not be empty : 'DischargeSummaryRecord'") + private String bundleType; + + @NotBlank(message = "careContextReference is mandatory and must not be empty") + private String careContextReference; + + @Valid + @NotNull(message = "Patient demographic details are mandatory and must not be empty") private PatientResource patient; + + private String encounter; + + @Valid + @NotNull(message = "practitioners are mandatory and must not be empty") private List practitioners; + + @Valid + @NotNull(message = "organisation is mandatory") private OrganisationResource organisation; + + @Valid private List chiefComplaints; + @Valid private List physicalExaminations; + private List allergies; + @Valid private List medicalHistories; + @Valid private List familyHistories; + @Valid private List diagnostics; + @Valid private CarePlanResource carePlan; + + @Pattern( + regexp = "^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z)?$", + message = "Value must match either yyyy-MM-dd or yyyy-MM-dd'T'HH:mm:ss.SSSZ") + @NotNull(message = "authoredOn is mandatory timestamp") @NotNull private String authoredOn; + + @Valid private List medications; + @Valid private List procedures; + @Valid private List documents; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/HealthDocumentRecord.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/HealthDocumentRecord.java new file mode 100644 index 00000000..e8bff7d3 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/HealthDocumentRecord.java @@ -0,0 +1,46 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.requests; + +import com.nha.abdm.fhir.mapper.rest.common.helpers.DocumentResource; +import com.nha.abdm.fhir.mapper.rest.common.helpers.OrganisationResource; +import com.nha.abdm.fhir.mapper.rest.common.helpers.PatientResource; +import com.nha.abdm.fhir.mapper.rest.common.helpers.PractitionerResource; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; +import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@AllArgsConstructor +@Data +@Builder +public class HealthDocumentRecord { + @Pattern(regexp = "HealthDocumentRecord") + @NotBlank(message = "BundleType is mandatory and must not be empty : 'HealthDocumentRecord'") + private String bundleType; + + @NotBlank(message = "careContextReference is mandatory and must not be empty") + private String careContextReference; + + @Valid + @NotNull(message = "Patient demographic details are mandatory and must not be empty") private PatientResource patient; + + @Pattern( + regexp = "^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z)?$", + message = "Value must match either yyyy-MM-dd or yyyy-MM-dd'T'HH:mm:ss.SSSZ") + private String authoredOn; + + @Valid + @NotNull(message = "practitioners are mandatory and must not be empty") private List practitioners; + + private OrganisationResource organisation; + private String encounter; + + @NotNull(message = "documents are mandatory") @Valid + private List documents; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/ImmunizationRequest.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/ImmunizationRequest.java new file mode 100644 index 00000000..a40d1882 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/ImmunizationRequest.java @@ -0,0 +1,50 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.requests; + +import com.nha.abdm.fhir.mapper.rest.common.helpers.DocumentResource; +import com.nha.abdm.fhir.mapper.rest.common.helpers.OrganisationResource; +import com.nha.abdm.fhir.mapper.rest.common.helpers.PatientResource; +import com.nha.abdm.fhir.mapper.rest.common.helpers.PractitionerResource; +import com.nha.abdm.fhir.mapper.rest.requests.helpers.ImmunizationResource; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; +import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@AllArgsConstructor +@Data +@Builder +public class ImmunizationRequest { + @Pattern(regexp = "ImmunizationRecord") + @NotBlank(message = "BundleType is mandatory and must not be empty : 'ImmunizationRecord'") + private String bundleType; + + @NotBlank(message = "careContextReference is mandatory and must not be empty") + private String careContextReference; + + @Valid + @NotNull(message = "Patient demographic details are mandatory and must not be empty") private PatientResource patient; + + @Valid + @NotNull(message = "practitioners are mandatory and must not be empty") private List practitioners; + + private OrganisationResource organisation; + private String encounter; + + @Pattern( + regexp = "^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z)?$", + message = "Value must match either yyyy-MM-dd or yyyy-MM-dd'T'HH:mm:ss.SSSZ") + @NotBlank(message = "authoredOn is mandatory timestamp") + private String authoredOn; + + @Valid + @NotNull(message = "Immunizations are mandatory") private List immunizations; + + @Valid private List documents; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/OPConsultationRequest.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/OPConsultationRequest.java new file mode 100644 index 00000000..2bd6f501 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/OPConsultationRequest.java @@ -0,0 +1,60 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.requests; + +import com.nha.abdm.fhir.mapper.rest.common.helpers.DocumentResource; +import com.nha.abdm.fhir.mapper.rest.common.helpers.OrganisationResource; +import com.nha.abdm.fhir.mapper.rest.common.helpers.PatientResource; +import com.nha.abdm.fhir.mapper.rest.common.helpers.PractitionerResource; +import com.nha.abdm.fhir.mapper.rest.requests.helpers.*; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; +import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@AllArgsConstructor +@Data +@Builder +public class OPConsultationRequest { + @Pattern(regexp = "OPConsultRecord") + @NotBlank(message = "BundleType is mandatory and must not be empty : 'OPConsultRecord'") + private String bundleType; + + @NotBlank(message = "careContextReference is mandatory and must not be empty") + private String careContextReference; + + @Valid + @NotNull(message = "Patient demographic details are mandatory and must not be empty") private PatientResource patient; + + private String encounter; + + @Valid + @NotNull(message = "practitioners are mandatory and must not be empty") private List practitioners; + + @Valid + @NotNull(message = "organisation is mandatory") private OrganisationResource organisation; + + @Valid private List chiefComplaints; + @Valid private List physicalExaminations; + private List allergies; + @Valid private List medicalHistories; + @Valid private List familyHistories; + @Valid private List serviceRequests; + + @Pattern( + regexp = "^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z)?$", + message = "Value must match either yyyy-MM-dd or yyyy-MM-dd'T'HH:mm:ss.SSSZ") + @NotNull(message = "authoredOn is mandatory timestamp") @NotNull private String visitDate; + + @Valid private List medications; + @Valid private List followups; + @Valid private List procedures; + @Valid private List referrals; + @Valid private List otherObservations; + @Valid private List documents; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/PrescriptionRequest.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/PrescriptionRequest.java new file mode 100644 index 00000000..a37f78a4 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/PrescriptionRequest.java @@ -0,0 +1,51 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.requests; + +import com.nha.abdm.fhir.mapper.rest.common.helpers.DocumentResource; +import com.nha.abdm.fhir.mapper.rest.common.helpers.OrganisationResource; +import com.nha.abdm.fhir.mapper.rest.common.helpers.PatientResource; +import com.nha.abdm.fhir.mapper.rest.common.helpers.PractitionerResource; +import com.nha.abdm.fhir.mapper.rest.requests.helpers.PrescriptionResource; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; +import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@AllArgsConstructor +@Data +@Builder +public class PrescriptionRequest { + @Pattern(regexp = "PrescriptionRecord") + @NotBlank(message = "BundleType is mandatory and must not be empty : 'PrescriptionRecord'") + private String bundleType; + + @NotBlank(message = "careContextReference is mandatory and must not be empty") + private String careContextReference; + + @Valid + @NotNull(message = "Patient demographic details are mandatory and must not be empty") private PatientResource patient; + + @Pattern( + regexp = "^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z)?$", + message = "Value must match either yyyy-MM-dd or yyyy-MM-dd'T'HH:mm:ss.SSSZ") + @NotBlank(message = "authoredOn is mandatory timestamp") + private String authoredOn; + + private String encounter; + + @Valid + @NotNull(message = "practitioners are mandatory and must not be empty") private List practitioners; + + private OrganisationResource organisation; + + @Valid + @NotNull(message = "prescription is mandatory and must not be empty") private List prescriptions; + + @Valid private List documents; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/WellnessRecordRequest.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/WellnessRecordRequest.java new file mode 100644 index 00000000..6a10714a --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/WellnessRecordRequest.java @@ -0,0 +1,57 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.requests; + +import com.nha.abdm.fhir.mapper.rest.common.helpers.DocumentResource; +import com.nha.abdm.fhir.mapper.rest.common.helpers.OrganisationResource; +import com.nha.abdm.fhir.mapper.rest.common.helpers.PatientResource; +import com.nha.abdm.fhir.mapper.rest.common.helpers.PractitionerResource; +import com.nha.abdm.fhir.mapper.rest.requests.helpers.ObservationResource; +import com.nha.abdm.fhir.mapper.rest.requests.helpers.WellnessObservationResource; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; +import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@AllArgsConstructor +@Data +@Builder +public class WellnessRecordRequest { + @Pattern(regexp = "WellnessRecord") + @NotBlank(message = "BundleType is mandatory and must not be empty : 'WellnessRecord'") + private String bundleType; + + @NotBlank(message = "careContextReference is mandatory and must not be empty") + private String careContextReference; + + @Valid + @NotNull(message = "Patient demographic details are mandatory and must not be empty") private PatientResource patient; + + private String encounter; + + @Pattern( + regexp = "^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z)?$", + message = "Value must match either yyyy-MM-dd or yyyy-MM-dd'T'HH:mm:ss.SSSZ") + @NotBlank(message = "authoredOn is mandatory timestamp") + private String authoredOn; + + @Valid + @NotNull(message = "practitioners are mandatory and must not be empty") private List practitioners; + + @Valid + @NotNull(message = "organisation is mandatory") private OrganisationResource organisation; + + @Valid private List vitalSigns; + @Valid private List bodyMeasurements; + @Valid private List physicalActivities; + @Valid private List generalAssessments; + @Valid private List womanHealths; + @Valid private List lifeStyles; + @Valid private List otherObservations; + @Valid private List documents; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/CarePlanResource.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/CarePlanResource.java new file mode 100644 index 00000000..bdd895ed --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/CarePlanResource.java @@ -0,0 +1,24 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.requests.helpers; + +import com.nha.abdm.fhir.mapper.rest.common.helpers.DateRange; +import jakarta.validation.constraints.Pattern; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@AllArgsConstructor +@Data +@Builder +public class CarePlanResource { + @Pattern(regexp = "^(proposal|plan|order|option)$") + private String intent; + + private DateRange period; + private String type; + private String description; + private String notes; + private String goal; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ChiefComplaintResource.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ChiefComplaintResource.java new file mode 100644 index 00000000..6e2a3fd2 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ChiefComplaintResource.java @@ -0,0 +1,23 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.requests.helpers; + +import com.nha.abdm.fhir.mapper.rest.common.helpers.DateRange; +import jakarta.validation.constraints.NotBlank; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@AllArgsConstructor +@Data +@Builder +public class ChiefComplaintResource { + @NotBlank(message = "complaint is mandatory") + private String complaint; + + @NotBlank(message = "recordedDate is mandatory") + private String recordedDate; + + private DateRange dateRange; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/DiagnosticPresentedForm.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/DiagnosticPresentedForm.java new file mode 100644 index 00000000..247c7717 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/DiagnosticPresentedForm.java @@ -0,0 +1,20 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.requests.helpers; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class DiagnosticPresentedForm { + @NotBlank(message = "presentedForm contentType is mandatory") + private String contentType; + + @NotNull(message = "presentedForm data is mandatory") private byte[] data; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/DiagnosticResource.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/DiagnosticResource.java new file mode 100644 index 00000000..71da6842 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/DiagnosticResource.java @@ -0,0 +1,38 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.requests.helpers; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; +import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class DiagnosticResource { + @NotBlank(message = "serviceName is mandatory") + private String serviceName; + + @NotBlank(message = "serviceCategory is mandatory") + private String serviceCategory; + + @Pattern( + regexp = "^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z)?$", + message = "Value must match either yyyy-MM-dd or yyyy-MM-dd'T'HH:mm:ss.SSSZ") + @NotBlank(message = "authoredOn is mandatory timestamp") + @NotNull private String authoredOn; + + @Valid + @NotNull(message = "results of the report is mandatory") private List result; + + @NotBlank(message = "conclusion is mandatory") + private String conclusion; + + @Valid private DiagnosticPresentedForm presentedForm; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/FamilyObservationResource.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/FamilyObservationResource.java new file mode 100644 index 00000000..f40d3a67 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/FamilyObservationResource.java @@ -0,0 +1,18 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.requests.helpers; + +import com.nha.abdm.fhir.mapper.rest.exceptions.NotBlankFields; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@AllArgsConstructor +@Data +@Builder +@NotBlankFields +public class FamilyObservationResource { + private String relationship; + private String observation; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/FollowupResource.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/FollowupResource.java new file mode 100644 index 00000000..49874c5a --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/FollowupResource.java @@ -0,0 +1,19 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.requests.helpers; + +import com.nha.abdm.fhir.mapper.rest.exceptions.NotBlankFields; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@AllArgsConstructor +@Data +@Builder +@NotBlankFields +public class FollowupResource { + private String serviceType; + private String appointmentTime; + private String reason; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ImmunizationResource.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ImmunizationResource.java new file mode 100644 index 00000000..5f257540 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ImmunizationResource.java @@ -0,0 +1,28 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.requests.helpers; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Pattern; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@AllArgsConstructor +@Data +@Builder +public class ImmunizationResource { + @Pattern( + regexp = "^\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])$", + message = "Date must be in the format yyyy-MM-dd") + @NotBlank(message = "date of vaccine is mandatory") + private String date; + + @NotBlank(message = "vaccineName is mandatory") + private String vaccineName; + + private String lotNumber; + private String manufacturer; + private int doseNumber; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ObservationResource.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ObservationResource.java new file mode 100644 index 00000000..3729b31e --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ObservationResource.java @@ -0,0 +1,22 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.requests.helpers; + +import jakarta.validation.constraints.NotBlank; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@AllArgsConstructor +@Data +@Builder +public class ObservationResource { + @NotBlank(message = "observation is mandatory") + private String observation; + + // @NotNull(message = "result is mandatory") + private String result; + + private ValueQuantityResource valueQuantity; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/PrescriptionResource.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/PrescriptionResource.java new file mode 100644 index 00000000..eceaa256 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/PrescriptionResource.java @@ -0,0 +1,32 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.requests.helpers; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Pattern; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@AllArgsConstructor +@Data +@Builder +public class PrescriptionResource { + @NotBlank(message = "medicine is mandatory") + private String medicine; + + @NotBlank(message = "dosage is mandatory") + private String dosage; + + @Pattern( + regexp = "^\\d{1,2}-\\d{1,2}-(S|MIN|H|D|WK|MO)$", + message = + "timing should have frequency-period-periodUnit '(0-99)-(0-99)-(S ~ seconds | MIN ~ minutes | H ~ hours | D ~ days| WK ~ week| MO ~ month' ex: 1-2-D") + private String timing; + + private String route; + private String method; + private String additionalInstructions; + private String reason; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ProcedureResource.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ProcedureResource.java new file mode 100644 index 00000000..9a0be909 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ProcedureResource.java @@ -0,0 +1,29 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.requests.helpers; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Pattern; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@AllArgsConstructor +@Data +@Builder +public class ProcedureResource { + @NotBlank(message = "date of the procedure is mandatory") + private String date; + + @Pattern(regexp = "COMPLETED|INPROGRESS") + private String status; + + @NotBlank(message = "procedureReason is mandatory") + private String procedureReason; + + private String outcome; + + @NotBlank(message = "procedureName is mandatory") + private String procedureName; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ServiceRequestResource.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ServiceRequestResource.java new file mode 100644 index 00000000..3137813d --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ServiceRequestResource.java @@ -0,0 +1,22 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.requests.helpers; + +import jakarta.validation.constraints.NotBlank; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@AllArgsConstructor +@Data +@Builder +public class ServiceRequestResource { + @NotBlank(message = "status is mandatory") + private String status; + + @NotBlank(message = "details of service is mandatory") + private String details; + + private String specimen; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ValueQuantityResource.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ValueQuantityResource.java new file mode 100644 index 00000000..343c934c --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ValueQuantityResource.java @@ -0,0 +1,16 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.requests.helpers; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@AllArgsConstructor +@Data +@Builder +public class ValueQuantityResource { + private String unit; + private double value; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/WellnessObservationResource.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/WellnessObservationResource.java new file mode 100644 index 00000000..3e62bb0a --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/WellnessObservationResource.java @@ -0,0 +1,22 @@ +/* (C) 2024 */ +package com.nha.abdm.fhir.mapper.rest.requests.helpers; + +import jakarta.validation.constraints.NotBlank; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@AllArgsConstructor +@Data +@Builder +public class WellnessObservationResource { + @NotBlank(message = "observation is mandatory") + private String observation; + + // @NotNull(message = "result is mandatory") + private String result; + + private ValueQuantityResource valueQuantity; +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties new file mode 100644 index 00000000..3fda537d --- /dev/null +++ b/src/main/resources/application.properties @@ -0,0 +1,24 @@ +server.port=8085 + + +spring.banner.location=classpath:banner.txt + +spring.datasource.url=jdbc:h2:mem:fhir_mapper;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE +spring.datasource.driver-class-name=org.h2.Driver +spring.datasource.username=abdm +spring.datasource.password= +spring.jpa.database-platform=org.hibernate.dialect.H2Dialect +spring.h2.console.enabled=true +spring.h2.console.path=/h2-console +spring.jpa.properties.hibernate.globally_quoted_identifiers=true +spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl + + + +# LOGGER +# You can disable the logs by commenting the below lines. +logging.level.com.nha.abdm.wrapper=DEBUG +logging.level.org.springframework.web=DEBUG +logging.level.org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor=TRACE +logging.level.org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor=TRACE +logging.level.org.springframework.web.HttpLogging=TRACE \ No newline at end of file diff --git a/src/main/resources/banner.txt b/src/main/resources/banner.txt new file mode 100644 index 00000000..fe481d87 --- /dev/null +++ b/src/main/resources/banner.txt @@ -0,0 +1,9 @@ + _______ __ __ __ .______ .___ ___. ___ .______ .______ _______ .______ +| ____|| | | | | | | _ \ | \/ | / \ | _ \ | _ \ | ____|| _ \ +| |__ | |__| | | | | |_) | ______| \ / | / ^ \ | |_) | | |_) | | |__ | |_) | +| __| | __ | | | | / |______| |\/| | / /_\ \ | ___/ | ___/ | __| | / +| | | | | | | | | |\ \----. | | | | / _____ \ | | | | | |____ | |\ \----. +|__| |__| |__| |__| | _| `._____| |__| |__| /__/ \__\ | _| | _| |_______|| _| `._____| + +${application.title} ${application.version} +NHA-VenuAjitesh \ No newline at end of file diff --git a/src/main/resources/snomed/SnomedConditionProcedure.json b/src/main/resources/snomed/SnomedConditionProcedure.json new file mode 100644 index 00000000..960e3919 --- /dev/null +++ b/src/main/resources/snomed/SnomedConditionProcedure.json @@ -0,0 +1,2638 @@ +[ + { + "code": "781087000", + "display": "Medical care" + }, + { + "code": "133898004", + "display": "Preoperative care" + }, + { + "code": "11429006", + "display": "Consultation" + }, + { + "code": "363680008", + "display": "Radiographic imaging procedure" + }, + { + "code": "53115007", + "display": "Diagnostic dental procedure" + }, + { + "code": "32150000", + "display": "Periodontic procedure" + }, + { + "code": "55670007", + "display": "Endodontic procedure" + }, + { + "code": "281171009", + "display": "Maxillofacial technical (device) procedure" + }, + { + "code": "79076007", + "display": "Prosthetic readjustment" + }, + { + "code": "110461004", + "display": "Adjunctive care" + }, + { + "code": "225362009", + "display": "Dental care" + }, + { + "code": "103697008", + "display": "Patient referral for dental care" + }, + { + "code": "384762007", + "display": "Transportation procedure" + }, + { + "code": "52637005", + "display": "Test tube ovum fertilization" + }, + { + "code": "113091000", + "display": "Magnetic resonance imaging" + }, + { + "code": "53958007", + "display": "Harvesting of donor material" + }, + { + "code": "271298009", + "display": "Organ retrieval operation" + }, + { + "code": "265764009", + "display": "Renal dialysis" + }, + { + "code": "717278002", + "display": "Burn care management" + }, + { + "code": "50849002", + "display": "Emergency room admission" + }, + { + "code": "310054005", + "display": "Infectious diseases service" + }, + { + "code": "240917005", + "display": "Interventional radiology" + }, + { + "code": "64915003", + "display": "Cardiac surgery procedure" + }, + { + "code": "305367005", + "display": "Admission to gastroenterology department" + }, + { + "code": "310056007", + "display": "Nephrology service" + }, + { + "code": "310057003", + "display": "Neurology service" + }, + { + "code": "310036006", + "display": "Cardiology service" + }, + { + "code": "305366001", + "display": "Admission to endocrinology department" + }, + { + "code": "700415000", + "display": "Pediatric surgery care management" + }, + { + "code": "305434007", + "display": "Admission to urology department" + }, + { + "code": "830077005", + "display": "Admission to neonatal intensive care unit" + }, + { + "code": "310039004", + "display": "Pulmonary medicine service" + }, + { + "code": "108290001", + "display": "Radiation oncology AND/OR radiotherapy" + }, + { + "code": "399097000", + "display": "Administration of anesthesia" + }, + { + "code": "224886008", + "display": "Treatment room (environment)" + }, + { + "code": "9632001", + "display": "Nursing procedure (procedure)" + }, + { + "code": "13288007", + "display": "Monitor, device (physical object)" + }, + { + "code": "309904001", + "display": "Intensive care unit (environment)" + }, + { + "code": "182998008", + "display": "Intensive nursing care (regime/therapy)" + }, + { + "code": "272181003", + "display": "Clinical equipment and/or device (physical object)" + }, + { + "code": "225738002", + "display": "Operating room (environment)" + }, + { + "code": "63653004", + "display": "Biomedical device (physical object)" + }, + { + "code": "3895009", + "display": "Application of dressing (procedure)" + }, + { + "code": "289122001", + "display": "Cosmetic material (substance)" + }, + { + "code": "16349000", + "display": "Orthopedic device (physical object)" + }, + { + "code": "6919005", + "display": "Protective clothing material, device (physical object)" + }, + { + "code": "430033006", + "display": "Infusion pump (physical object)" + }, + { + "code": "11429006", + "display": "Consultation (procedure)" + }, + { + "code": "387713003", + "display": "Surgical procedure (procedure)" + }, + { + "code": "398228004", + "display": "Anesthesia consultation (procedure)" + }, + { + "code": "878786001", + "display": "Operating room technician (occupation)" + }, + { + "code": "91251008", + "display": "Physical therapy procedure (regime/therapy)" + }, + { + "code": "71388002", + "display": "Procedure (procedure)" + }, + { + "code": "367336001", + "display": "Chemotherapy (procedure)" + }, + { + "code": "278414003", + "display": "Pain management (procedure)" + }, + { + "code": "127801007", + "display": "Body fluid analysis (procedure)" + }, + { + "code": "276341003", + "display": "Cardiovascular investigation (procedure)" + }, + { + "code": "252275004", + "display": "Hematology test (procedure)" + }, + { + "code": "19851009", + "display": "Microbiology procedure (procedure)" + }, + { + "code": "118678004", + "display": "Procedure on nervous system (procedure)" + }, + { + "code": "371572003", + "display": "Nuclear medicine procedure (procedure)" + }, + { + "code": "15220000", + "display": "Laboratory test (procedure)" + }, + { + "code": "363679005", + "display": "Imaging (procedure)" + }, + { + "code": "396550006", + "display": "Blood test (procedure)" + }, + { + "code": "43782000", + "display": "Organ or system related test (procedure)" + }, + { + "code": "252416005", + "display": "Histopathology test (procedure)" + }, + { + "code": "415564008", + "display": "Specimen sent to reference laboratory for testing (situation)" + }, + { + "code": "715544005", + "display": "Transportation by ambulance with assistance of one person (procedure)" + }, + { + "code": "305056002", + "display": "Admission procedure (procedure)" + }, + { + "code": "184047000", + "display": "Patient registration (procedure)" + }, + { + "code": "107727007", + "display": "Chart related administrative procedure (procedure)" + }, + { + "code": "14734007", + "display": "Administrative procedure (procedure)" + }, + { + "code": "312635000", + "display": "Provision of telephone (procedure)" + }, + { + "code": "303607000", + "display": "Biomedical equipment (physical object)" + }, + { + "code": "225737007", + "display": "Mortuary (environment)" + }, + { + "code": "33022008", + "display": "Hospital-based outpatient department (environment)" + }, + { + "code": "171324002", + "display": "New patient screening (procedure)" + }, + { + "code": "112802009", + "display": "Cardiovascular operative procedure (procedure)" + }, + { + "code": "118672003", + "display": "Procedure on cardiovascular system (procedure)" + }, + { + "code": "118797008", + "display": "Procedure on heart (procedure)" + }, + { + "code": "81733005", + "display": "Dental surgical procedure (procedure)" + }, + { + "code": "118683007", + "display": "Procedure on ear and related structures (procedure)" + }, + { + "code": "118673008", + "display": "Procedure on digestive system (procedure)" + }, + { + "code": "118675001", + "display": "Procedure on female genital system (procedure)" + }, + { + "code": "118677009", + "display": "Procedure on urinary system (procedure)" + }, + { + "code": "89901005", + "display": "Operative procedure on head (procedure)" + }, + { + "code": "118897002", + "display": "Procedure on eye proper (procedure)" + }, + { + "code": "118666003", + "display": "Procedure on musculoskeletal system (procedure)" + }, + { + "code": "225746001", + "display": "Ward (environment)" + }, + { + "code": "705333009", + "display": "Toileting assistive device (physical object)" + }, + { + "code": "105789008", + "display": "Cannula/tube/catheter, device (physical object)" + }, + { + "code": "108290001", + "display": "Radiation oncology AND/OR radiotherapy (procedure)" + }, + { + "code": "23745001", + "display": "Documentation procedure (procedure)" + }, + { + "code": "468046005", + "display": "Cardiac catheterization laboratory computer (physical object)" + }, + { + "code": "118781003", + "display": "Procedure on nose (procedure)" + }, + { + "code": "118670006", + "display": "Procedure on upper respiratory tract (procedure)" + }, + { + "code": "763158003", + "display": "Medicinal product (product)" + }, + { + "code": "310000008", + "display": "Accident and Emergency service (qualifier value)" + }, + { + "code": "737481003", + "display": "Inpatient care management (procedure)" + }, + { + "code": "11429006", + "display": "Consultation (procedure)" + }, + { + "code": "737850002", + "display": "Day care case management (procedure)" + }, + { + "code": "410345004", + "display": "Medical/dental care case management (procedure)" + }, + { + "code": "387713003", + "display": "Surgical procedure (procedure)" + }, + { + "code": "73957001", + "display": "Air transport ambulance, device (physical object)" + }, + { + "code": "465341007", + "display": "Automobile ambulance (physical object)" + }, + { + "code": "568291000005106", + "display": "Hospital unit (environment)" + }, + { + "code": "272181003", + "display": "Clinical equipment and/or device (physical object)" + }, + { + "code": "77343006", + "display": "Angiography (procedure)" + }, + { + "code": "439533007", + "display": "Endoscopic balloon dilatation of ostium of paranasal sinus (procedure)" + }, + { + "code": "711364006", + "display": "Surgery using robotic assistance (procedure)" + }, + { + "code": "266719004", + "display": "Oral chemotherapy (procedure)" + }, + { + "code": "713348007", + "display": "Thermoplasty of bronchus (procedure)" + }, + { + "code": "1269349006", + "display": "Transplantation of stem cell (procedure)" + }, + { + "code": "76334006", + "display": "Immunotherapy (procedure)" + }, + { + "code": "763158003", + "display": "Medicinal product (product)" + }, + { + "code": "75516001", + "display": "Psychotherapy (regime/therapy)" + }, + { + "code": "91251008", + "display": "Physical therapy procedure (regime/therapy)" + }, + { + "code": "15220000", + "display": "Laboratory test (procedure)" + }, + { + "code": "51032003", + "display": "Hospital admission, donor for transplant organ (procedure)" + }, + { + "code": "9632001", + "display": "Nursing procedure (procedure)" + }, + { + "code": "5880005", + "display": "Physical examination procedure (procedure)" + }, + { + "code": "29303009", + "display": "Electrocardiographic procedure (procedure)" + }, + { + "code": "16310003", + "display": "Ultrasonography (procedure)" + }, + { + "code": "49083007", + "display": "Administration of vaccine product containing virus antigen (procedure)" + }, + { + "code": "108241001", + "display": "Dialysis procedure (procedure)" + }, + { + "code": "367336001", + "display": "Chemotherapy (procedure)" + }, + { + "code": "713603004", + "display": "Advance care planning (procedure)" + }, + { + "code": "710967003", + "display": "Management of health status after discharge from hospital (procedure)" + }, + { + "code": "49122002", + "display": "Ambulance, device (physical object)" + }, + { + "code": "275926002", + "display": "Screening - health check (procedure)" + }, + { + "code": "33879002", + "display": "Administration of vaccine to produce active immunity (procedure)" + }, + { + "code": "60689008", + "display": "Home care of patient (regime/therapy)" + }, + { + "code": "410225009", + "display": "Mental health care management (procedure)" + }, + { + "code": "410083007", + "display": "Rehabilitation therapy management (procedure)" + }, + { + "code": "737492002", + "display": "Outpatient care management (procedure)" + }, + { + "code": "385907003", + "display": "Eye care management (procedure)" + }, + { + "code": "409972000", + "display": "Pre-hospital care (situation)" + }, + { + "code": "1259939000", + "display": "Ayurveda medicine (qualifier value)" + }, + { + "code": "1259938008", + "display": "Homeopathic medicine (qualifier value)" + }, + { + "code": "1259940003", + "display": "Yoga medicine (qualifier value)" + }, + { + "code": "1259218001", + "display": "Unani medicine (qualifier value)" + }, + { + "code": "1259219009", + "display": "Siddha medicine (qualifier value)" + }, + { + "code": "416113008", + "display": "Febrile disorder" + }, + { + "code": "91302008", + "display": "Sepsis" + }, + { + "code": "76571007", + "display": "Septic shock" + }, + { + "code": "61462000", + "display": "Malaria" + }, + { + "code": "38362002", + "display": "Dengue" + }, + { + "code": "20927009", + "display": "Dengue hemorrhagic fever" + }, + { + "code": "409671005", + "display": "Dengue shock syndrome" + }, + { + "code": "111864006", + "display": "Chikungunya fever" + }, + { + "code": "4834000", + "display": "Typhoid fever" + }, + { + "code": "81000119104", + "display": "Symptomatic human immunodeficiency virus infection" + }, + { + "code": "77377001", + "display": "Leptospirosis" + }, + { + "code": "236071009", + "display": "Chronic diarrhea" + }, + { + "code": "409966000", + "display": "Acute diarrhea" + }, + { + "code": "46799006", + "display": "Dysenteric diarrhea" + }, + { + "code": "57412004", + "display": "Acute viral hepatitis" + }, + { + "code": "76783007", + "display": "Chronic hepatitis" + }, + { + "code": "27916005", + "display": "Abscess of liver" + }, + { + "code": "186803007", + "display": "Visceral leishmaniasis" + }, + { + "code": "233604007", + "display": "Pneumonia" + }, + { + "code": "312682007", + "display": "Empyema" + }, + { + "code": "67256000", + "display": "Tuberculosis of pericardium" + }, + { + "code": "186182003", + "display": "Tuberculosis of pleura" + }, + { + "code": "68566005", + "display": "Urinary tract infectious disease" + }, + { + "code": "34476008", + "display": "Viral encephalitis" + }, + { + "code": "48245008", + "display": "Bacterial arthritis" + }, + { + "code": "19824006", + "display": "Infection of skin and/or subcutaneous tissue" + }, + { + "code": "7520000", + "display": "Pyrexia of unknown origin" + }, + { + "code": "12295008", + "display": "Bronchiectasis" + }, + { + "code": "10509002", + "display": "Acute bronchitis" + }, + { + "code": "195951007", + "display": "Acute exacerbation of chronic obstructive airways disease" + }, + { + "code": "233703007", + "display": "Interstitial lung disease" + }, + { + "code": "301183007", + "display": "Bacterial endocarditis" + }, + { + "code": "86348002", + "display": "Mycotic endocarditis" + }, + { + "code": "31996006", + "display": "Vasculitis" + }, + { + "code": "197456007", + "display": "Acute pancreatitis" + }, + { + "code": "235494005", + "display": "Chronic pancreatitis" + }, + { + "code": "389026000", + "display": "Ascites" + }, + { + "code": "47000000", + "display": "Acute transverse myelitis" + }, + { + "code": "49436004", + "display": "Atrial fibrillation" + }, + { + "code": "35304003", + "display": "Cardiac tamponade" + }, + { + "code": "42343007", + "display": "Congestive heart failure" + }, + { + "code": "708038006", + "display": "Acute exacerbation of asthma" + }, + { + "code": "733858005", + "display": "Acute severe refractory exacerbation of asthma" + }, + { + "code": "233765002", + "display": "Respiratory failure without hypercapnia" + }, + { + "code": "709109004", + "display": "Hypercapnic respiratory failure" + }, + { + "code": "409622000", + "display": "Respiratory failure" + }, + { + "code": "363732003", + "display": "Addison's disease" + }, + { + "code": "7093002", + "display": "Renal colic" + }, + { + "code": "42399005", + "display": "Renal failure syndrome" + }, + { + "code": "128613002", + "display": "Seizure disorder" + }, + { + "code": "230456007", + "display": "Status epilepticus" + }, + { + "code": "230690007", + "display": "Cerebrovascular accident" + }, + { + "code": "192759008", + "display": "Cerebral venous sinus thrombosis" + }, + { + "code": "422504002", + "display": "Ischemic stroke" + }, + { + "code": "274100004", + "display": "Cerebral hemorrhage" + }, + { + "code": "24700007", + "display": "Multiple sclerosis" + }, + { + "code": "74772000", + "display": "Meningomyelitis" + }, + { + "code": "25044007", + "display": "Neuromyelitis optica" + }, + { + "code": "16631009", + "display": "Transverse myelopathy syndrome" + }, + { + "code": "230745008", + "display": "Hydrocephalus" + }, + { + "code": "21263006", + "display": "Myxedema coma" + }, + { + "code": "29028009", + "display": "Thyrotoxic crisis" + }, + { + "code": "90560007", + "display": "Inflammatory disorder due to increased blood urate level" + }, + { + "code": "36118008", + "display": "Pneumothorax" + }, + { + "code": "257277002", + "display": "Combined disorder of muscle AND peripheral nerve" + }, + { + "code": "302866003", + "display": "Hypoglycemia" + }, + { + "code": "280137006", + "display": "Diabetic foot" + }, + { + "code": "420422005", + "display": "Ketoacidosis due to diabetes mellitus" + }, + { + "code": "66931009", + "display": "Hypercalcemia" + }, + { + "code": "5291005", + "display": "Hypocalcemia" + }, + { + "code": "89627008", + "display": "Hyponatremia" + }, + { + "code": "771115008", + "display": "Hypernatremia" + }, + { + "code": "421966007", + "display": "Non-ketotic non-hyperosmolar coma due to diabetes mellitus" + }, + { + "code": "78975002", + "display": "Malignant essential hypertension" + }, + { + "code": "132721000119104", + "display": "Hypertensive emergency" + }, + { + "code": "127040003", + "display": "Sickle cell-hemoglobin SS disease" + }, + { + "code": "39579001", + "display": "Anaphylaxis" + }, + { + "code": "52072009", + "display": "Heat stroke" + }, + { + "code": "55464009", + "display": "Systemic lupus erythematosus" + }, + { + "code": "40956001", + "display": "Guillain-Barré syndrome" + }, + { + "code": "61288004", + "display": "Poisoning caused by venomous snake" + }, + { + "code": "8260003", + "display": "Organophosphate poisoning" + }, + { + "code": "75478009", + "display": "Poisoning" + }, + { + "code": "302497006", + "display": "Hemodialysis" + }, + { + "code": "71192002", + "display": "Peritoneal dialysis" + }, + { + "code": "20720000", + "display": "Plasmapheresis" + }, + { + "code": "33389009", + "display": "Transfusion of whole blood" + }, + { + "code": "54790000", + "display": "Transfusion of blood component" + }, + { + "code": "363679005", + "display": "Imaging" + }, + { + "code": "252416005", + "display": "Histopathology test" + }, + { + "code": "86273004", + "display": "Biopsy" + }, + { + "code": "45900003", + "display": "Esophagectomy" + }, + { + "code": "307332009", + "display": "Esophagectomy and colonic interposition" + }, + { + "code": "708987006", + "display": "Laparoscopic total gastrectomy" + }, + { + "code": "26452005", + "display": "Total gastrectomy" + }, + { + "code": "54956002", + "display": "Gastrostomy" + }, + { + "code": "72971003", + "display": "Gastrojejunostomy with vagotomy" + }, + { + "code": "46381000", + "display": "Truncal vagotomy with pyloroplasty" + }, + { + "code": "287811008", + "display": "Perforated peptic ulcer closure" + }, + { + "code": "235674005", + "display": "Perforation of stomach" + }, + { + "code": "270909006", + "display": "Duodenal perforation" + }, + { + "code": "363742001", + "display": "Pyloroplasty" + }, + { + "code": "173788005", + "display": "Pyloromyotomy" + }, + { + "code": "49245001", + "display": "Bypass gastrojejunostomy" + }, + { + "code": "238280007", + "display": "Drainage of peritoneal pseudocyst" + }, + { + "code": "238275003", + "display": "Drainage of peritoneal cyst" + }, + { + "code": "75389003", + "display": "Pancreaticocystogastrostomy" + }, + { + "code": "234321000", + "display": "Splenic cystogastrostomy" + }, + { + "code": "234322007", + "display": "Splenic cystojejunostomy" + }, + { + "code": "238278001", + "display": "Peritoneal cystojejunostomy" + }, + { + "code": "238279009", + "display": "Peritoneal cystogastrostomy" + }, + { + "code": "174740002", + "display": "Open cystogastrotomy of pancreas" + }, + { + "code": "62937006", + "display": "Feeding enterostomy of jejunum" + }, + { + "code": "301784005", + "display": "Ileostomy operation" + }, + { + "code": "67389003", + "display": "Diverticulectomy of duodenum" + }, + { + "code": "61218006", + "display": "Excision of Meckel's diverticulum" + }, + { + "code": "80146002", + "display": "Excision of appendix" + }, + { + "code": "6025007", + "display": "Laparoscopic appendectomy" + }, + { + "code": "47693006", + "display": "Rupture of appendix" + }, + { + "code": "174052001", + "display": "Drainage of appendix abscess" + }, + { + "code": "26390003", + "display": "Total colectomy" + }, + { + "code": "787874000", + "display": "Laparoscopic total colectomy" + }, + { + "code": "359571009", + "display": "Right colectomy" + }, + { + "code": "50774009", + "display": "Laparoscopic-assisted right colectomy" + }, + { + "code": "82619000", + "display": "Left colectomy" + }, + { + "code": "41330009", + "display": "Laparoscopic-assisted left colectomy" + }, + { + "code": "398740003", + "display": "Colostomy" + }, + { + "code": "1805005", + "display": "Surgical closure of stoma" + }, + { + "code": "84604002", + "display": "Sigmoid colectomy" + }, + { + "code": "174286001", + "display": "Perineal operations for rectal prolapse" + }, + { + "code": "73921006", + "display": "Repair of rectal prolapse by abdominal approach" + }, + { + "code": "440032004", + "display": "Laparoscopic fixation of prolapse of rectum" + }, + { + "code": "274031008", + "display": "Rectal polypectomy" + }, + { + "code": "4558008", + "display": "Anterior resection of rectum" + }, + { + "code": "90527009", + "display": "Laparoscopic-assisted anterior resection of rectum" + }, + { + "code": "315328007", + "display": "Anterior resection of rectum with anastomosis" + }, + { + "code": "392027008", + "display": "Anal fissurectomy" + }, + { + "code": "24496007", + "display": "Hemorrhoidectomy" + }, + { + "code": "412737002", + "display": "Stapling of hemorrhoid" + }, + { + "code": "174396007", + "display": "Pilonidal sinus operation" + }, + { + "code": "107808005", + "display": "Accessory sinus excision" + }, + { + "code": "302392001", + "display": "Curettage of sinus" + }, + { + "code": "74770008", + "display": "Exploratory laparotomy" + }, + { + "code": "177916006", + "display": "Resuture of burst abdomen" + }, + { + "code": "107963000", + "display": "Liver excision" + }, + { + "code": "708590009", + "display": "Laparoscopic wedge resection of liver" + }, + { + "code": "708589000", + "display": "Laparoscopic resection of segment of liver" + }, + { + "code": "38102005", + "display": "Cholecystectomy" + }, + { + "code": "45993005", + "display": "Cholecystectomy with exploration of common duct" + }, + { + "code": "45595009", + "display": "Laparoscopic cholecystectomy" + }, + { + "code": "67557008", + "display": "Laparoscopic cholecystectomy with exploration of common duct" + }, + { + "code": "66361005", + "display": "Excision of choledochal cyst" + }, + { + "code": "234319005", + "display": "Splenectomy" + }, + { + "code": "174776001", + "display": "Total splenectomy" + }, + { + "code": "314118002", + "display": "Laparoscopic total splenectomy" + }, + { + "code": "446408009", + "display": "Laparoscopic excision of part of spleen" + }, + { + "code": "173747005", + "display": "Roux-en-Y gastrojejunostomy" + }, + { + "code": "91516004", + "display": "Distal subtotal pancreatectomy with pancreaticojejunostomy" + }, + { + "code": "116241004", + "display": "Pancreaticoduodenectomy" + }, + { + "code": "20767001", + "display": "Shunt of portal vein to vena cava" + }, + { + "code": "175793006", + "display": "Mesocaval shunt" + }, + { + "code": "238299003", + "display": "Excision of mesenteric cyst" + }, + { + "code": "92433007", + "display": "Benign neoplasm of retroperitoneum" + }, + { + "code": "608797008", + "display": "Open repair of inguinal hernia" + }, + { + "code": "15018006", + "display": "Laparoscopic repair of inguinal hernia" + }, + { + "code": "608796004", + "display": "Open repair of femoral hernia" + }, + { + "code": "608789001", + "display": "Laparoscopic repair of femoral hernia" + }, + { + "code": "608790005", + "display": "Laparoscopic repair of obturator hernia" + }, + { + "code": "238184006", + "display": "Repair of epigastric hernia" + }, + { + "code": "44946007", + "display": "Repair of umbilical hernia" + }, + { + "code": "9877001", + "display": "Repair of paraumbilical hernia" + }, + { + "code": "15694008", + "display": "Repair of spigelian hernia" + }, + { + "code": "238187004", + "display": "Repair of incisional hernia" + }, + { + "code": "9292007", + "display": "Esophageal hiatus hernia repair" + }, + { + "code": "413181005", + "display": "Laparoscopic repair of hiatus hernia" + }, + { + "code": "359890009", + "display": "Fundoplication" + }, + { + "code": "359893006", + "display": "Total fundoplication" + }, + { + "code": "78656005", + "display": "Laparoscopic fundoplication" + }, + { + "code": "21810005", + "display": "Excision of lesion of scrotum" + }, + { + "code": "236326007", + "display": "Excision of multiple scrotal sebaceous cysts" + }, + { + "code": "236347006", + "display": "Hydrocele operation" + }, + { + "code": "176481007", + "display": "Excision of cyst of epididymis" + }, + { + "code": "176490000", + "display": "Reversal of vasectomy" + }, + { + "code": "236334001", + "display": "Total orchidectomy" + }, + { + "code": "178286005", + "display": "Block dissection of inguinal lymph nodes" + }, + { + "code": "112851007", + "display": "Full thickness excision of lip, reconstruction with local flap" + }, + { + "code": "20418004", + "display": "Wedge resection" + }, + { + "code": "173225009", + "display": "Wedge excision of lip" + }, + { + "code": "39562007", + "display": "Vermilionectomy" + }, + { + "code": "173218002", + "display": "Excision of vermilion border and advancement of lip mucosa" + }, + { + "code": "359703006", + "display": "Total glossectomy" + }, + { + "code": "177124000", + "display": "Biopsy of tongue" + }, + { + "code": "173357008", + "display": "Removal of lesion of tongue" + }, + { + "code": "234246002", + "display": "Selective neck dissection of cervical lymph nodes" + }, + { + "code": "59687004", + "display": "Excision of laryngeal polyp" + }, + { + "code": "308030005", + "display": "Microlaryngoscopic vocal cord polypectomy" + }, + { + "code": "173490007", + "display": "Excision of lesion of submandibular gland" + }, + { + "code": "45685007", + "display": "Radical neck dissection" + }, + { + "code": "178347009", + "display": "Excision of branchial cyst" + }, + { + "code": "233401008", + "display": "Excision of carotid body tumor" + }, + { + "code": "302338000", + "display": "Lobectomy of thyroid gland" + }, + { + "code": "24443003", + "display": "Total thyroidectomy" + }, + { + "code": "237486002", + "display": "Total thyroidectomy with cervical lymph node dissection" + }, + { + "code": "287258006", + "display": "Parathyroid adenoma excision" + }, + { + "code": "399750009", + "display": "Excision of thymus" + }, + { + "code": "57071006", + "display": "Sympathectomy" + }, + { + "code": "392021009", + "display": "Lumpectomy of breast" + }, + { + "code": "172043006", + "display": "Simple mastectomy" + }, + { + "code": "406505007", + "display": "Modified radical mastectomy" + }, + { + "code": "384723003", + "display": "Radical mastectomy" + }, + { + "code": "172106007", + "display": "Excision of fistula of mammary duct" + }, + { + "code": "238356005", + "display": "Intercostal drain removal" + }, + { + "code": "177789001", + "display": "Excision of rib and open drainage of pleural cavity" + }, + { + "code": "238332006", + "display": "Total thoracoplasty" + }, + { + "code": "26411001", + "display": "Decortication of lung and parietal pleurectomy" + }, + { + "code": "75935006", + "display": "Thoracoscopic lobectomy of lung" + }, + { + "code": "173171007", + "display": "Lobectomy of lung" + }, + { + "code": "444188003", + "display": "Thoracoscopic wedge resection of lung" + }, + { + "code": "284181007", + "display": "Incision and drainage of abscess" + }, + { + "code": "274068006", + "display": "Excision of lipoma" + }, + { + "code": "428297005", + "display": "Excision of cyst" + }, + { + "code": "440258006", + "display": "Excision of skin" + }, + { + "code": "312775003", + "display": "Debridement of ulcer" + }, + { + "code": "771225007", + "display": "Reconstruction using free flap" + }, + { + "code": "119561005", + "display": "Grafting procedure" + }, + { + "code": "265675003", + "display": "Split thickness graft of skin to skin" + }, + { + "code": "304039000", + "display": "Skin flap operation" + }, + { + "code": "264983002", + "display": "Transfer of tendon" + }, + { + "code": "107996003", + "display": "Lymphatic system excision" + }, + { + "code": "27929005", + "display": "Arteriovenous fistulization" + }, + { + "code": "717285003", + "display": "Vascular system care" + }, + { + "code": "21911005", + "display": "Biopsy of lymph node" + }, + { + "code": "447338009", + "display": "Aspiration of endometrium" + }, + { + "code": "171149006", + "display": "Screening for malignant neoplasm of cervix" + }, + { + "code": "50796003", + "display": "Cervical biopsy" + }, + { + "code": "274942001", + "display": "Biopsy of vulva" + }, + { + "code": "87515005", + "display": "Ileostomy management and care" + }, + { + "code": "25953003", + "display": "Colostomy management and care" + }, + { + "code": "10849003", + "display": "Removal of foreign body" + }, + { + "code": "225746001", + "display": "Ward (environment)" + }, + { + "code": "224663004", + "display": "Single room (environment)" + }, + { + "code": "67604003", + "display": "Household appliance (physical object)" + }, + { + "code": "5679009", + "display": "Bed sheet, device (physical object)" + }, + { + "code": "47448006", + "display": "Hot water (substance)" + }, + { + "code": "182591009", + "display": "Water bed (physical object)" + }, + { + "code": "229772003", + "display": "Bed (physical object)" + }, + { + "code": "1348009", + "display": "Day care center (environment)" + }, + { + "code": "25721000087108", + "display": "Emergency shelter (environment)" + }, + { + "code": "9632001", + "display": "Nursing procedure (procedure)" + }, + { + "code": "3895009", + "display": "Application of dressing (procedure)" + }, + { + "code": "401304009", + "display": "Service of nebulizer (procedure)" + }, + { + "code": "59108006", + "display": "Injection (procedure)" + }, + { + "code": "430033006", + "display": "Infusion pump (physical object)" + }, + { + "code": "159753002", + "display": "General caretaker (occupation)" + }, + { + "code": "116859006", + "display": "Transfusion of blood product (procedure)" + }, + { + "code": "11429006", + "display": "Consultation (procedure)" + }, + { + "code": "252465000", + "display": "Pulse oximetry (procedure)" + }, + { + "code": "309906004", + "display": "Burns unit (environment)" + }, + { + "code": "397771005", + "display": "High dependency unit (environment)" + }, + { + "code": "309907008", + "display": "Cardiac intensive care unit (environment)" + }, + { + "code": "409688003", + "display": "Hospital isolation room (environment)" + }, + { + "code": "309909006", + "display": "Neurological intensive care unit (environment)" + }, + { + "code": "398161000", + "display": "Postoperative anesthesia care unit (environment)" + }, + { + "code": "387713003", + "display": "Surgical procedure (procedure)" + }, + { + "code": "309904001", + "display": "Intensive care unit (environment)" + }, + { + "code": "182998008", + "display": "Intensive nursing care (regime/therapy)" + }, + { + "code": "61968008", + "display": "Syringe, device (physical object)" + }, + { + "code": "13288007", + "display": "Monitor, device (physical object)" + }, + { + "code": "23852006", + "display": "Cardiac monitoring (regime/therapy)" + }, + { + "code": "399217008", + "display": "Cardioassist by aortic balloon pump (procedure)" + }, + { + "code": "31394004", + "display": "Light therapy (procedure)" + }, + { + "code": "24099007", + "display": "Oxygen (substance)" + }, + { + "code": "706172005", + "display": "Ventilator (physical object)" + }, + { + "code": "424172009", + "display": "Dual pressure spontaneous ventilation support weaning protocol (regime/therapy)" + }, + { + "code": "225738002", + "display": "Operating room (environment)" + }, + { + "code": "257715004", + "display": "Theater (environment)" + }, + { + "code": "1255635002", + "display": "Birth room (environment)" + }, + { + "code": "122456005", + "display": "Laser device (physical object)" + }, + { + "code": "701418007", + "display": "C-arm drape (physical object)" + }, + { + "code": "423827005", + "display": "Endoscopy (procedure)" + }, + { + "code": "51316009", + "display": "Laparoscopic procedure (procedure)" + }, + { + "code": "272181003", + "display": "Clinical equipment and/or device (physical object)" + }, + { + "code": "462524004", + "display": "Neurosurgical ultrasonic navigation system (physical object)" + }, + { + "code": "80557002", + "display": "Drilling of bone (procedure)" + }, + { + "code": "118299005", + "display": "Semiconductor laser device (physical object)" + }, + { + "code": "310801006", + "display": "Ureteroscope (physical object)" + }, + { + "code": "312077001", + "display": "Flexible ureteroscope (physical object)" + }, + { + "code": "6012004", + "display": "Hearing aid, device (physical object)" + }, + { + "code": "63653004", + "display": "Biomedical device (physical object)" + }, + { + "code": "5776009", + "display": "Medicinal product acting as anesthetic agent (product)" + }, + { + "code": "86174004", + "display": "Laparoscope, device (physical object)" + }, + { + "code": "14106009", + "display": "Cardiac pacemaker, device (physical object)" + }, + { + "code": "704722004", + "display": "Dual chamber rate responsive implantable cardiac pacemaker (physical object)" + }, + { + "code": "705637003", + "display": "Drug-eluting coronary artery stent (physical object)" + }, + { + "code": "464052002", + "display": "Bare metal coronary artery stent (physical object)" + }, + { + "code": "356497001", + "display": "Bone cements (product)" + }, + { + "code": "303533002", + "display": "Hip joint implant (physical object)" + }, + { + "code": "63995005", + "display": "Bandage, device (physical object)" + }, + { + "code": "256246007", + "display": "Cotton - textile (physical object)" + }, + { + "code": "350785008", + "display": "Gauzes (physical object)" + }, + { + "code": "52291003", + "display": "Glove, device (physical object)" + }, + { + "code": "261382003", + "display": "Mask (physical object)" + }, + { + "code": "994005", + "display": "Brush, device (physical object)" + }, + { + "code": "48741003", + "display": "Toothpaste (substance)" + }, + { + "code": "25780000", + "display": "Soap (substance)" + }, + { + "code": "739000003", + "display": "Lotion (basic dose form)" + }, + { + "code": "255698008", + "display": "Shampoo (substance)" + }, + { + "code": "52065008", + "display": "Diaper, device (physical object)" + }, + { + "code": "40519001", + "display": "Binder, device (physical object)" + }, + { + "code": "74094004", + "display": "Belt, device (physical object)" + }, + { + "code": "228184002", + "display": "Stocking (physical object)" + }, + { + "code": "16650009", + "display": "Splint, device (physical object)" + }, + { + "code": "9096001", + "display": "Support, device (physical object)" + }, + { + "code": "51883004", + "display": "Sling, device (physical object)" + }, + { + "code": "272363005", + "display": "Fixed orthodontic appliance (physical object)" + }, + { + "code": "12150006", + "display": "Cannula, device (physical object)" + }, + { + "code": "255560000", + "display": "Intravenous (qualifier value)" + }, + { + "code": "19923001", + "display": "Catheter, device (physical object)" + }, + { + "code": "83059008", + "display": "Tube, device (physical object)" + }, + { + "code": "57134006", + "display": "Instrument, device (physical object)" + }, + { + "code": "408097009", + "display": "Strip (physical object)" + }, + { + "code": "369443003", + "display": "Bedpan (physical object)" + }, + { + "code": "91251008", + "display": "Physiotherapy (regime/therapy)" + }, + { + "code": "81375008", + "display": "Physical assessment (procedure)" + }, + { + "code": "386053000", + "display": "Evaluation procedure (procedure)" + }, + { + "code": "45900003", + "display": "Esophagectomy (procedure)" + }, + { + "code": "235162005", + "display": "Trans-hiatal esophagectomy (procedure)" + }, + { + "code": "90410003", + "display": "Wedge resection of stomach (procedure)" + }, + { + "code": "50774009", + "display": "Laparoscopic-assisted right colectomy (procedure)" + }, + { + "code": "174071004", + "display": "Extended right hemicolectomy (procedure)" + }, + { + "code": "41330009", + "display": "Laparoscopic-assisted left colectomy (procedure)" + }, + { + "code": "82619000", + "display": "Left colectomy (procedure)" + }, + { + "code": "235325001", + "display": "Extended left hemicolectomy (procedure)" + }, + { + "code": "26925005", + "display": "Transverse colectomy (procedure)" + }, + { + "code": "84604002", + "display": "Sigmoid colectomy (procedure)" + }, + { + "code": "1390003", + "display": "Laparoscopic-assisted sigmoid colectomy (procedure)" + }, + { + "code": "708913004", + "display": "Laparoscopic abdominoperineal resection using robotic assistance (procedure)" + }, + { + "code": "180056004", + "display": "Posterior exenteration of pelvis (procedure)" + }, + { + "code": "180055000", + "display": "Anterior exenteration of pelvis (procedure)" + }, + { + "code": "69036001", + "display": "Total pancreaticoduodenectomy (procedure)" + }, + { + "code": "61326000", + "display": "Hepatectomy, total right lobectomy (procedure)" + }, + { + "code": "63816008", + "display": "Hepatectomy, total left lobectomy (procedure)" + }, + { + "code": "281255004", + "display": "Small bowel obstruction (disorder)" + }, + { + "code": "281254000", + "display": "Large bowel obstruction (disorder)" + }, + { + "code": "39270003", + "display": "Lysis of adhesions (procedure)" + }, + { + "code": "63185002", + "display": "Laparoscopy with biopsy (procedure)" + }, + { + "code": "81516001", + "display": "Partial nephrectomy (procedure)" + }, + { + "code": "236335000", + "display": "Subcapsular orchidectomy (procedure)" + }, + { + "code": "116171002", + "display": "Radical inguinal orchiectomy (procedure)" + }, + { + "code": "176599002", + "display": "Partial vulvectomy (procedure)" + }, + { + "code": "234250009", + "display": "Block dissection of pelvic lymph nodes (procedure)" + }, + { + "code": "116142003", + "display": "Radical hysterectomy (procedure)" + }, + { + "code": "116141005", + "display": "Abdominal hysterectomy (procedure)" + }, + { + "code": "83152002", + "display": "Oophorectomy (procedure)" + }, + { + "code": "61174009", + "display": "Transposition of ovary (procedure)" + }, + { + "code": "236940003", + "display": "Second look laparoscopy (procedure)" + }, + { + "code": "122460008", + "display": "Reexploration procedure (procedure)" + }, + { + "code": "237370008", + "display": "Segmentectomy of breast (procedure)" + }, + { + "code": "120146008", + "display": "Chest wall excision (procedure)" + }, + { + "code": "1115001", + "display": "Decortication (procedure)" + }, + { + "code": "234272006", + "display": "Biopsy of mediastinal lymph node (procedure)" + }, + { + "code": "261531000", + "display": "Excision of rib (procedure)" + }, + { + "code": "65651000", + "display": "Ligation of thoracic duct (procedure)" + }, + { + "code": "40583006", + "display": "Resection of trachea (procedure)" + }, + { + "code": "177754003", + "display": "Excision of lesion of chest wall (procedure)" + }, + { + "code": "234270003", + "display": "Biopsy of cervical lymph node (procedure)" + }, + { + "code": "75935006", + "display": "Thoracoscopic lobectomy of lung (procedure)" + }, + { + "code": "235155001", + "display": "Endoscopic Congo Red Test (procedure)" + }, + { + "code": "65808002", + "display": "Excision of presacral tumor (procedure)" + }, + { + "code": "231552001", + "display": "Anterior orbitotomy (procedure)" + }, + { + "code": "29513000", + "display": "Irrigation with syringe (procedure)" + }, + { + "code": "76508002", + "display": "Rhytidoplasty of eyelid (procedure)" + }, + { + "code": "75489002", + "display": "Blepharoplasty of bilateral upper and lower eyelids (procedure)" + }, + { + "code": "371394007", + "display": "Removal of scleral buckle (procedure)" + }, + { + "code": "59077004", + "display": "Canthotomy (procedure)" + }, + { + "code": "397537003", + "display": "Laser cycloablation (procedure)" + }, + { + "code": "258485006", + "display": "Corneal scraping specimen (specimen)" + }, + { + "code": "231728005", + "display": "Repair of prolapsed iris (procedure)" + }, + { + "code": "231607009", + "display": "Correction of entropion of lower eyelid (procedure)" + }, + { + "code": "231612005", + "display": "Correction of entropion of upper eyelid (procedure)" + }, + { + "code": "69769008", + "display": "Repair of blepharoptosis (procedure)" + }, + { + "code": "50489001", + "display": "Repair of telecanthus (procedure)" + }, + { + "code": "87539000", + "display": "Cryotherapy of eyelid (procedure)" + }, + { + "code": "172214005", + "display": "Cryotherapy to lesion of eyelid (procedure)" + }, + { + "code": "71091006", + "display": "Cryotherapy of ciliary body (procedure)" + }, + { + "code": "231631004", + "display": "Dacryocystorhinostomy and insertion of tube (procedure)" + }, + { + "code": "75745001", + "display": "Dacryocystotomy (procedure)" + }, + { + "code": "55272009", + "display": "Dacryocystectomy (procedure)" + }, + { + "code": "172261006", + "display": "Drainage of lesion of eyelid (procedure)" + }, + { + "code": "172172005", + "display": "Drainage of orbit (procedure)" + }, + { + "code": "48957009", + "display": "Epilation by electrolysis (procedure)" + }, + { + "code": "39250009", + "display": "Enucleation (procedure)" + }, + { + "code": "14509009", + "display": "Evisceration (procedure)" + }, + { + "code": "75588007", + "display": "Excision of lesion of cornea (procedure)" + }, + { + "code": "36436000", + "display": "Excision of lesion of eyebrow (procedure)" + }, + { + "code": "172212009", + "display": "Excision of lesion of eyelid (procedure)" + }, + { + "code": "47487006", + "display": "Excision of lesion of iris (procedure)" + }, + { + "code": "60712003", + "display": "Excision of lesion of sclera (procedure)" + }, + { + "code": "172196000", + "display": "Excision of lesion of canthus (procedure)" + }, + { + "code": "397112000", + "display": "Simple excision of pterygium (procedure)" + }, + { + "code": "2242005", + "display": "Reconstruction of eyelid (procedure)" + }, + { + "code": "1004085005", + "display": "Injection of filling material into eyelid (procedure)" + }, + { + "code": "240988007", + "display": "Division of flap (procedure)" + }, + { + "code": "400929002", + "display": "Forced duction test (procedure)" + }, + { + "code": "783539008", + "display": "Full thickness graft of skin to skin (procedure)" + }, + { + "code": "265292003", + "display": "Goniotomy (procedure)" + }, + { + "code": "4143006", + "display": "Injection of anterior chamber of eye (procedure)" + }, + { + "code": "310557005", + "display": "Partial thickness corneal graft (substance)" + }, + { + "code": "83694000", + "display": "Lamellar keratoplasty (procedure)" + }, + { + "code": "46082001", + "display": "Lateral orbitotomy (procedure)" + }, + { + "code": "419767009", + "display": "Bimanual microincisional phacoemulsification of cataract with intraocular lens implantation (procedure)" + }, + { + "code": "92829008", + "display": "Glaucoma due to combination of mechanisms (disorder)" + }, + { + "code": "172389006", + "display": "Mucosal graft to conjunctiva (procedure)" + }, + { + "code": "86088003", + "display": "Centesis (procedure)" + }, + { + "code": "42101009", + "display": "Penetrating keratoplasty (procedure)" + }, + { + "code": "231724007", + "display": "Peripheral iridectomy (procedure)" + }, + { + "code": "84149000", + "display": "Aspiration of cataract by phacoemulsification (procedure)" + }, + { + "code": "172426003", + "display": "Removal of foreign body from cornea (procedure)" + }, + { + "code": "172498005", + "display": "Removal of foreign body from iris (procedure)" + }, + { + "code": "172173000", + "display": "Removal of foreign body from orbit (procedure)" + }, + { + "code": "36884001", + "display": "Repair of recurrent dislocation of patella (procedure)" + }, + { + "code": "58992007", + "display": "Complete patellectomy (procedure)" + }, + { + "code": "52050007", + "display": "Pelvic osteotomy (procedure)" + }, + { + "code": "178677007", + "display": "Posterior decompression of fracture of spine (procedure)" + }, + { + "code": "52734007", + "display": "Total replacement of hip (procedure)" + }, + { + "code": "785850002", + "display": "Reverse prosthetic total arthroplasty of shoulder (procedure)" + }, + { + "code": "56060000", + "display": "Repair of musculotendinous cuff of shoulder (procedure)" + }, + { + "code": "18557009", + "display": "Closure by suture (procedure)" + }, + { + "code": "80469007", + "display": "Arthroplasty of shoulder for recurrent dislocation (procedure)" + }, + { + "code": "239468007", + "display": "Arthroplasty of shoulder (procedure)" + }, + { + "code": "69446009", + "display": "Skeletal traction (procedure)" + }, + { + "code": "304040003", + "display": "Grafting to skin (procedure)" + }, + { + "code": "6779009", + "display": "Open treatment of slipped femoral epiphysis (procedure)" + }, + { + "code": "55705006", + "display": "Spinal arthrodesis (procedure)" + }, + { + "code": "35443000", + "display": "Diagnostic radiography supine and erect of thoracic and lumbar spine for scoliosis (procedure)" + }, + { + "code": "122478003", + "display": "Synovial biopsy (procedure)" + }, + { + "code": "45247004", + "display": "Lengthening of tendon (procedure)" + }, + { + "code": "281758003", + "display": "Repair of tendon (procedure)" + }, + { + "code": "178156005", + "display": "Repair of tendo achilles (procedure)" + }, + { + "code": "264983002", + "display": "Transfer of tendon (procedure)" + }, + { + "code": "179836002", + "display": "Release of torticollis (procedure)" + }, + { + "code": "609588000", + "display": "Total knee replacement (procedure)" + }, + { + "code": "27813003", + "display": "Intra-articular injection (procedure)" + }, + { + "code": "13714004", + "display": "Arthroscopy (procedure)" + }, + { + "code": "239430005", + "display": "Ligament reconstruction (procedure)" + }, + { + "code": "179353004", + "display": "Revision uncemented total knee replacement (procedure)" + }, + { + "code": "86052008", + "display": "Closed reduction of fracture (procedure)" + }, + { + "code": "302489004", + "display": "Removal of complete external fixator (procedure)" + }, + { + "code": "180293003", + "display": "Change of plaster jacket (procedure)" + }, + { + "code": "90131007", + "display": "Arthrocentesis (procedure)" + }, + { + "code": "239667008", + "display": "Application of above elbow plaster cast (procedure)" + }, + { + "code": "239676001", + "display": "Application of below knee plaster cast (procedure)" + }, + { + "code": "63097004", + "display": "Application of long leg cast (procedure)" + }, + { + "code": "180289009", + "display": "Application of plaster cast (procedure)" + }, + { + "code": "37354008", + "display": "Application of shoulder spica (procedure)" + }, + { + "code": "127599007", + "display": "Application of hip spica cast (procedure)" + }, + { + "code": "81666003", + "display": "Strapping of ankle (procedure)" + }, + { + "code": "85046002", + "display": "Strapping of elbow (procedure)" + }, + { + "code": "24459003", + "display": "Strapping of finger (procedure)" + }, + { + "code": "21288003", + "display": "Strapping of knee (procedure)" + }, + { + "code": "229535006", + "display": "Shoulder strapping (procedure)" + }, + { + "code": "41029007", + "display": "Strapping of toes (procedure)" + }, + { + "code": "21411002", + "display": "Strapping of wrist (procedure)" + }, + { + "code": "30549001", + "display": "Removal of suture (procedure)" + }, + { + "code": "58825001", + "display": "Closed reduction of dislocation (procedure)" + }, + { + "code": "70163005", + "display": "Excision of ganglion cyst (procedure)" + }, + { + "code": "284101009", + "display": "Removal of implant (procedure)" + }, + { + "code": "76699006", + "display": "Ligamentous reconstruction of knee, intra-articular and extra-articular (procedure)" + }, + { + "code": "387731002", + "display": "Excision of lamina of vertebra (procedure)" + }, + { + "code": "78918006", + "display": "Open reduction of dislocation (procedure)" + }, + { + "code": "178668000", + "display": "Percutaneous discectomy (procedure)" + }, + { + "code": "311479006", + "display": "Spinal instrumentation (procedure)" + }, + { + "code": "439303004", + "display": "Application of rigid total contact leg cast (procedure)" + }, + { + "code": "2337004", + "display": "Adductor tenotomy of hip (procedure)" + }, + { + "code": "239267000", + "display": "Release of trigger finger (procedure)" + }, + { + "code": "239644006", + "display": "Application of pelvic traction (procedure)" + }, + { + "code": "178789004", + "display": "Manipulation of spine using traction (procedure)" + }, + { + "code": "450671005", + "display": "Debridement of soft tissue (procedure)" + }, + { + "code": "179709006", + "display": "Total synovectomy of joint (procedure)" + }, + { + "code": "387821004", + "display": "Spinal deformity correction (procedure)" + }, + { + "code": "428845007", + "display": "Intramedullary fixation with cementing of bone (procedure)" + }, + { + "code": "179892002", + "display": "Arthroscopic reattachment glenoid labrum (procedure)" + }, + { + "code": "699120002", + "display": "Arthroscopic repair of rotator cuff (procedure)" + }, + { + "code": "301761003", + "display": "Arthroscopic synovial biopsy (procedure)" + }, + { + "code": "265106004", + "display": "Insertion of Austin-Moore prosthesis (procedure)" + }, + { + "code": "439756000", + "display": "Open reduction of bimalleolar fracture of lateral and medial malleoli with internal fixation (procedure)" + }, + { + "code": "61916001", + "display": "Injection into bone marrow (procedure)" + }, + { + "code": "239690003", + "display": "Application of buttress strapping (procedure)" + }, + { + "code": "239329001", + "display": "Excision of bone (procedure)" + }, + { + "code": "699119008", + "display": "Repair of medial ligament of talocrural joint (procedure)" + }, + { + "code": "708899000", + "display": "Closed reduction of fracture of femur and internal fixation using dynamic condylar screw plate (procedure)" + }, + { + "code": "239619003", + "display": "Dynamization of external fixator (procedure)" + }, + { + "code": "239259008", + "display": "Lengthening of tendons or muscles of the flexor compartment of the forearm (procedure)" + }, + { + "code": "179537001", + "display": "Excision arthroplasty (procedure)" + }, + { + "code": "385523005", + "display": "External fixator using Ilizarov system (physical object)" + }, + { + "code": "440418007", + "display": "Open reduction of fracture of medial malleolus with internal fixation (procedure)" + }, + { + "code": "239432002", + "display": "Reconstruction of posterior cruciate ligament of knee joint (procedure)" + }, + { + "code": "69171004", + "display": "Excision of radial head (procedure)" + }, + { + "code": "56153009", + "display": "Reconstruction of radial head (procedure)" + }, + { + "code": "112694000", + "display": "Saucerization (procedure)" + }, + { + "code": "313295000", + "display": "Fixation of fracture using Herbert screw (procedure)" + }, + { + "code": "257949002", + "display": "Tension band wiring of fracture (procedure)" + }, + { + "code": "178493006", + "display": "Alveolar bone graft (procedure)" + }, + { + "code": "180673001", + "display": "Cross finger flap (substance)" + }, + { + "code": "384686000", + "display": "Reattachment of lower extremity (procedure)" + }, + { + "code": "307554005", + "display": "Reconstruction of nose with flap (procedure)" + }, + { + "code": "782787005", + "display": "Split thickness graft of skin (substance)" + }, + { + "code": "284079008", + "display": "Revision of scar (procedure)" + }, + { + "code": "405444008", + "display": "Revision of amputation of foot (procedure)" + }, + { + "code": "240995003", + "display": "Release of burns contracture (procedure)" + }, + { + "code": "231619001", + "display": "Surgical dehiscence of the aponeurotic insertion of Muller's muscle (procedure)" + }, + { + "code": "52781008", + "display": "Congenital hip dysplasia (disorder)" + }, + { + "code": "367411006", + "display": "Hamstring tendon transfer (procedure)" + }, + { + "code": "32492002", + "display": "Excision of accessory navicular bone (procedure)" + }, + { + "code": "308446007", + "display": "Excision of distal end of ulna (procedure)" + }, + { + "code": "158965000", + "display": "Medical practitioner (occupation)" + }, + { + "code": "303133007", + "display": "Responsible medical officer (occupation)" + } +] \ No newline at end of file diff --git a/src/main/resources/snomed/SnomedDiagnostic.json b/src/main/resources/snomed/SnomedDiagnostic.json new file mode 100644 index 00000000..ffe994c6 --- /dev/null +++ b/src/main/resources/snomed/SnomedDiagnostic.json @@ -0,0 +1,66 @@ +[ + { + "code": "B53.0", + "display": "Plasmodium ovale malaria" + }, + { + "code": "E11.9", + "display": "Type 2 diabetes mellitus : Without complications" + }, + { + "code": "I46.9", + "display": "Cardiac arrest, unspecified" + }, + { + "code": "S82.1", + "display": "Fracture of upper end of tibia" + }, + { + "code": "K70.3", + "display": "Alcoholic cirrhosis of liver" + }, + { + "code": "K35.8", + "display": "Acute appendicitis, other and unspecified" + }, + { + "code": "A08.4", + "display": "Viral intestinal infection, unspecified" + }, + { + "code": "770573007", + "display": "Airway endoscopy report" + }, + { + "code": "782659005", + "display": "Cystoscopy report" + }, + { + "code": "725870000", + "display": "Diagnostic coronary angiography report" + }, + { + "code": "721981007", + "display": "Diagnostic studies report" + }, + { + "code": "722143004", + "display": "Infectious disease diagnostic study note" + }, + { + "code": "720449003", + "display": "Pulmonary function report" + }, + { + "code": "371528001", + "display": "Pathology report" + }, + { + "code": "721631001", + "display": "Bone marrow pathology biopsy report" + }, + { + "code": "4311000179106", + "display": "Chemical pathology report" + } +] \ No newline at end of file diff --git a/src/main/resources/snomed/SnomedEncounter.json b/src/main/resources/snomed/SnomedEncounter.json new file mode 100644 index 00000000..d8225a79 --- /dev/null +++ b/src/main/resources/snomed/SnomedEncounter.json @@ -0,0 +1,222 @@ +[ + { + "code": "AMB", + "display": "Ambulatory" + }, + { + "code": "171238007", + "display": "Arthritis screening" + }, + { + "code": "171242005", + "display": "Chromosome abnormality screening" + }, + { + "code": "171183004", + "display": "Diabetes mellitus screening" + }, + { + "code": "391277002", + "display": "Digestive system disease screening" + }, + { + "code": "171219003", + "display": "Ear disorder screening" + }, + { + "code": "473200002", + "display": "Genetic screening for disorder" + }, + { + "code": "171233003", + "display": "Genitourinary disease screening" + }, + { + "code": "243790003", + "display": "Infection screening" + }, + { + "code": "60151004", + "display": "Neonatal screening" + }, + { + "code": "171214008", + "display": "Neurological screening" + }, + { + "code": "171228002", + "display": "Respiratory disease screening" + }, + { + "code": "300007000", + "display": "Screening for cardiovascular system disease" + }, + { + "code": "866150003", + "display": "Screening for developmental disorder" + }, + { + "code": "300005008", + "display": "Screening for mental disorders" + }, + { + "code": "15886004", + "display": "Screening for cancer" + }, + { + "code": "370854007", + "display": "Screening for substance abuse" + }, + { + "code": "171237002", + "display": "Skin disease screening" + }, + { + "code": "408760009", + "display": "Vision screening" + }, + { + "code": "274412005", + "display": "Eye disorder screening" + }, + { + "code": "171126009", + "display": "Tuberculosis screening" + }, + { + "code": "171121004", + "display": "HIV screening" + }, + { + "code": "243787009", + "display": "Antenatal screening" + }, + { + "code": "103735009", + "display": "Palliative care" + }, + { + "code": "112802009", + "display": "Cardiovascular surgical procedure" + }, + { + "code": "71025006", + "display": "Dilation procedure" + }, + { + "code": "122459003", + "display": "Dissection procedure" + }, + { + "code": "34896006", + "display": "Incision" + }, + { + "code": "287391004", + "display": "Nose, mouth or pharynx operations" + }, + { + "code": "386638009", + "display": "Obstetric operation" + }, + { + "code": "112697007", + "display": "Operation on musculoskeletal system" + }, + { + "code": "16545005", + "display": "Operation on nervous system" + }, + { + "code": "387661001", + "display": "Operation on respiratory tract" + }, + { + "code": "74943008", + "display": "Operation on trunk" + }, + { + "code": "107907001", + "display": "Operative procedure on digestive system" + }, + { + "code": "89901005", + "display": "Operative procedure on head" + }, + { + "code": "107994000", + "display": "Operative procedure on hematopoietic system" + }, + { + "code": "107876005", + "display": "Operative procedure on integumentary system" + }, + { + "code": "392236004", + "display": "Operative procedure on spinal structure" + }, + { + "code": "410771003", + "display": "Surgical procedure for clinical finding and/or disorder" + }, + { + "code": "313071005", + "display": "Substance abuse counselling" + }, + { + "code": "79841006", + "display": "Genetic counseling" + }, + { + "code": "171022008", + "display": "Psychological counseling" + }, + { + "code": "24165007", + "display": "Alcoholism counselling" + }, + { + "code": "228557008", + "display": "Cognitive and behavioral therapy" + }, + { + "code": "75516001", + "display": "Psychotherapy" + }, + { + "code": "266739000", + "display": "Physiotherapy/remedial therapy" + }, + { + "code": "5154007", + "display": "Speech therapy" + }, + { + "code": "773412008", + "display": "Traditional medicine" + }, + { + "code": "385804009", + "display": "Diabetic care" + }, + { + "code": "367336001", + "display": "Chemotherapy" + }, + { + "code": "18629005", + "display": "Administration of medication" + }, + { + "code": "86273004", + "display": "Biopsy" + }, + { + "code": "23835007", + "display": "Electroconvulsive therapy" + }, + { + "code": "397619005", + "display": "Family planning education" + } +] \ No newline at end of file diff --git a/src/main/resources/snomed/SnomedMedicine.json b/src/main/resources/snomed/SnomedMedicine.json new file mode 100644 index 00000000..4920779a --- /dev/null +++ b/src/main/resources/snomed/SnomedMedicine.json @@ -0,0 +1,418 @@ +[ + { + "code": "319775004", + "display": "Aspirin 75 mg oral tablet" + }, + { + "code": "370166004", + "display": "Aspirin 325 mg oral tablet" + }, + { + "code": "374744009", + "display": "Aspirin 800 mg oral tablet" + }, + { + "code": "370164001", + "display": "Aspirin 81 mg chewable tablet" + }, + { + "code": "785018008", + "display": "Aspirin 2.5 mg/mL oral solution" + }, + { + "code": "412575004", + "display": "Aspirin 325 mg and codeine 30 mg oral tablet" + }, + { + "code": "347070003", + "display": "Aspirin 500 mg and glycine 133 mg orodispersible tablet" + }, + { + "code": "413586006", + "display": "Acetaminophen 250 mg and aspirin 250 mg and caffeine 65 mg oral tablet" + }, + { + "code": "412647005", + "display": "Aspirin 389 mg and caffeine 32.4 mg and propoxyphene hydrochloride 32 mg oral capsule" + }, + { + "code": "322784004", + "display": "Aspirin DL-lysine 900 mg and metoclopramide hydrochloride 10 mg oral powder sachet" + }, + { + "code": "322236009", + "display": "Acetaminophen 500 mg oral tablet" + }, + { + "code": "322246006", + "display": "Acetaminophen 100 mg/mL oral solution" + }, + { + "code": "426061004", + "display": "Mesalamine 1.2 g gastro-resistant oral tablet" + }, + { + "code": "324409009", + "display": "Sulfalene 2 g oral tablet" + }, + { + "code": "376693009", + "display": "Cefadroxil 1 g oral tablet" + }, + { + "code": "329838002", + "display": "Naproxen 250 mg gastro-resistant oral tablet" + }, + { + "code": "416272002", + "display": "Zinc 50 mg oral capsule" + }, + { + "code": "418197002", + "display": "Glucosamine 1 g oral tablet" + }, + { + "code": "426863002", + "display": "Melatonin 2 mg prolonged-release oral tablet" + }, + { + "code": "765963000", + "display": "Budesonide 3 mg gastro-resistant oral capsule" + }, + { + "code": "765590000", + "display": "Felodipine 5 mg prolonged-release oral tablet" + }, + { + "code": "765699007", + "display": "Ibuprofen 800 mg prolonged-release oral tablet" + }, + { + "code": "766432002", + "display": "Fusidic acid 10 mg/g prolonged-release eye drops" + }, + { + "code": "324682007", + "display": "Miconazole 25 mg/g oral gel" + }, + { + "code": "765651007", + "display": "Axitinib 5 mg oral tablet" + }, + { + "code": "408068006", + "display": "Nabilone 2 mg oral capsule" + }, + { + "code": "326272004", + "display": "Nystatin 25000 unit/g vaginal cream" + }, + { + "code": "408597001", + "display": "Ganciclovir 1.5 mg/g eye gel" + }, + { + "code": "321573006", + "display": "Clozapine 25 mg oral tablet" + }, + { + "code": "375833002", + "display": "Ofloxacin 3 mg/mL ear solution" + }, + { + "code": "785252002", + "display": "Glycerin 10 mg/mL eye solution" + }, + { + "code": "321203006", + "display": "Diazepam 1 mg/mL oral solution" + }, + { + "code": "784911007", + "display": "Carbachol 15 mg/mL eye solution" + }, + { + "code": "407773006", + "display": "Sulpiride 40 mg/mL oral solution" + }, + { + "code": "407836002", + "display": "Efavirenz 30 mg/mL oral solution" + }, + { + "code": "323074003", + "display": "Diazepam 4 mg/mL rectal solution" + }, + { + "code": "410840000", + "display": "Ribavirin 40 mg/mL oral solution" + }, + { + "code": "348336006", + "display": "Phenol 10 mg/mL cutaneous solution" + }, + { + "code": "784960002", + "display": "Epinephrine 1 mg/mL nasal solution" + }, + { + "code": "781971000", + "display": "Linezolid 2 mg/mL solution for infusion" + }, + { + "code": "781781009", + "display": "Baclofen 2 mg/mL solution for injection" + }, + { + "code": "781829000", + "display": "Diazepam 5 mg/mL solution for injection" + }, + { + "code": "785204007", + "display": "Glucose 200 mg/mL solution for injection" + }, + { + "code": "446347007", + "display": "Denosumab 60 mg/mL solution for injection" + }, + { + "code": "782062009", + "display": "Piroxicam 20 mg/mL solution for injection" + }, + { + "code": "784839007", + "display": "Tobramycin 60 mg/mL solution for inhalation" + }, + { + "code": "784910008", + "display": "Enflurane 999 mg/mL solution for inhalation" + }, + { + "code": "781996002", + "display": "Metronidazole 5 mg/mL solution for infusion" + }, + { + "code": "782021003", + "display": "Nitroglycerin 5 mg/mL solution for injection" + }, + { + "code": "348190007", + "display": "Tolnaftate 10 mg/g cutaneous powder" + }, + { + "code": "766284006", + "display": "Clotrimazole 10 mg/g cutaneous powder" + }, + { + "code": "324867004", + "display": "Nelfinavir 50 microgram/mg oral powder" + }, + { + "code": "766429000", + "display": "Povidone iodine 25 mg/g cutaneous powder spray" + }, + { + "code": "322979001", + "display": "Vigabatrin 500 mg powder for oral solution sachet" + }, + { + "code": "375854009", + "display": "Hemin 313 mg powder for solution for injection vial" + }, + { + "code": "323961007", + "display": "Aztreonam 1 g powder for solution for injection vial" + }, + { + "code": "319948000", + "display": "Cholestyramine 4 g powder for oral suspension sachet" + }, + { + "code": "785962002", + "display": "Cromolyn sodium 20 mg/actuation powder for inhalation" + }, + { + "code": "785973009", + "display": "Noxythiolin 2.5 g powder for solution for injection vial" + }, + { + "code": "782053007", + "display": "Phenol 50 mg/mL oil for injection" + }, + { + "code": "781828008", + "display": "Diazepam 5 mg/mL emulsion for injection" + }, + { + "code": "782035001", + "display": "Oxytocin 5 unit/mL solution for injection" + }, + { + "code": "785006004", + "display": "Propofol 10 mg/mL suspension for injection" + }, + { + "code": "769129007", + "display": "Triptorelin (as triptorelin acetate) 3.75 mg powder for suspension for injection syringe" + }, + { + "code": "766169007", + "display": "Somatropin(rbe) 600 microgram powder for solution for injection syringe" + }, + { + "code": "871797008", + "display": "Ozanimod (as ozanimod hydrochloride) 920 microgram oral capsule" + }, + { + "code": "386086001", + "display": "Tacrine 40 mg oral capsule" + }, + { + "code": "415163005", + "display": "Pregabalin 200 mg oral capsule" + }, + { + "code": "430273009", + "display": "Temazepam 22.5 mg oral capsule" + }, + { + "code": "423454000", + "display": "Vorinostat 100 mg oral capsule" + }, + { + "code": "370149001", + "display": "Acetaminophen 160 mg oral tablet" + }, + { + "code": "377441009", + "display": "Acetaminophen 325 mg and tramadol 37.5 mg oral tablet" + }, + { + "code": "377594002", + "display": "Acetaminophen 325 mg and butalbital 50 mg oral tablet" + }, + { + "code": "322341003", + "display": "Acetaminophen 500 mg and codeine phosphate 30 mg oral tablet" + }, + { + "code": "783660005", + "display": "Paroxetine (as paroxetine hydrochloride) 10 mg oral tablet" + }, + { + "code": "421386002", + "display": "Acetaminophen 300 mg and oxycodone hydrochloride 5 mg oral tablet" + }, + { + "code": "377343008", + "display": "Acetaminophen 325 mg and oxycodone hydrochloride 5 mg oral tablet" + }, + { + "code": "370148009", + "display": "Acetaminophen 80 mg chewable tablet" + }, + { + "code": "785926003", + "display": "Mucin 35 mg/mL oral spray" + }, + { + "code": "703958008", + "display": "Avanafil 50 mg oral tablet" + }, + { + "code": "324682007", + "display": "Miconazole 25 mg/g oral gel" + }, + { + "code": "442888004", + "display": "Iloperidone 8 mg oral tablet" + }, + { + "code": "445522003", + "display": "Rifaximin 550 mg oral tablet" + }, + { + "code": "332248004", + "display": "Anthralin 1 mg/g cutaneous cream" + }, + { + "code": "332246000", + "display": "Anthralin 5 mg/g cutaneous cream" + }, + { + "code": "333020002", + "display": "Acyclovir 50 mg/g cutaneous cream" + }, + { + "code": "331624002", + "display": "Benzocaine 30 mg/g cutaneous cream" + }, + { + "code": "332199003", + "display": "Calcipotriol 50 microgram/mL cutaneous cream" + }, + { + "code": "413872001", + "display": "Clocortolone pivalate 1 mg/mL cutaneous cream" + }, + { + "code": "330588001", + "display": "Tropicamide 5 mg/mL eye drops" + }, + { + "code": "409490006", + "display": "Hydroxyamphetamine hydrobromide 10 mg/mL and tropicamide 2.5 mg/mL eye solution" + }, + { + "code": "783373002", + "display": "Tropisetron (as tropisetron hydrochloride) 5 mg oral capsule" + }, + { + "code": "324682007", + "display": "Miconazole 25 mg/g oral gel" + }, + { + "code": "408597001", + "display": "Ganciclovir 1.5 mg/g eye gel" + }, + { + "code": "332378006", + "display": "Adapalene 1 mg/g cutaneous gel" + }, + { + "code": "135588001", + "display": "Benzocaine 100 mg/g dental gel" + }, + { + "code": "330229006", + "display": "Felbinac 30 mg/g transdermal gel" + }, + { + "code": "414272004", + "display": "Fluocinolone acetonide 100 microgram/mL cutaneous oil" + }, + { + "code": "331469001", + "display": "Cod liver oil 114 mg/g and zinc oxide 380 mg/g cutaneous ointment" + }, + { + "code": "781919008", + "display": "Haloperidol (as haloperidol decanoate) 50 mg/mL oil for injection" + }, + { + "code": "781828008", + "display": "Diazepam 5 mg/mL emulsion for injection" + }, + { + "code": "781752008", + "display": "Adenosine 3 mg/mL solution for injection" + }, + { + "code": "784932004", + "display": "Diazepam 5 mg/mL suspension for injection" + }, + { + "code": "376105006", + "display": "Estrone 15 mg/mL suspension for injection" + } +] \ No newline at end of file diff --git a/src/main/resources/snomed/SnomedMedicineRoute.json b/src/main/resources/snomed/SnomedMedicineRoute.json new file mode 100644 index 00000000..7757e521 --- /dev/null +++ b/src/main/resources/snomed/SnomedMedicineRoute.json @@ -0,0 +1,385 @@ + +[ + { "code": "6064005", "display": "Topical route" }, + { "code": "10547007", "display": "Otic route" }, + { "code": "12130007", "display": "Intra-articular route" }, + { "code": "16857009", "display": "Per vagina" }, + { "code": "26643006", "display": "Oral route" }, + { "code": "34206005", "display": "Subcutaneous route" }, + { "code": "37161004", "display": "Per rectum" }, + { "code": "37737002", "display": "Intraluminal route" }, + { "code": "37839007", "display": "Sublingual route" }, + { "code": "38239002", "display": "Intraperitoneal route" }, + { "code": "45890007", "display": "Transdermal route" }, + { "code": "46713006", "display": "Nasal route" }, + { "code": "47625008", "display": "Intravenous route" }, + { "code": "54471007", "display": "Buccal route" }, + { "code": "54485002", "display": "Ophthalmic route" }, + { "code": "58100008", "display": "Intra-arterial route" }, + { "code": "60213007", "display": "Intramedullary route" }, + { "code": "62226000", "display": "Intrauterine route" }, + { "code": "72607000", "display": "Intrathecal route" }, + { "code": "78421000", "display": "Intramuscular route" }, + { "code": "90028008", "display": "Urethral route" }, + { "code": "127490009", "display": "Gastrostomy route" }, + { "code": "127491008", "display": "Jejunostomy route" }, + { "code": "127492001", "display": "Nasogastric route" }, + { "code": "372449004", "display": "Dental use" }, + { "code": "372450004", "display": "Endocervical use" }, + { "code": "372451000", "display": "Endosinusial use" }, + { "code": "372452007", "display": "Endotracheopulmonary use" }, + { "code": "372453002", "display": "Extra-amniotic use" }, + { "code": "372454008", "display": "Gastroenteral use" }, + { "code": "372457001", "display": "Gingival use" }, + { "code": "372458006", "display": "Intraamniotic use" }, + { "code": "372459003", "display": "Intrabursal use" }, + { "code": "372460008", "display": "Intracardiac use" }, + { "code": "372461007", "display": "Intracavernous use" }, + { "code": "372462000", "display": "Intracervical route (qualifier value)" }, + { "code": "372463005", "display": "Intracoronary use" }, + { "code": "372464004", "display": "Intradermal use" }, + { "code": "372465003", "display": "Intradiscal use" }, + { "code": "372466002", "display": "Intralesional use" }, + { "code": "372467006", "display": "Intralymphatic use" }, + { "code": "372468001", "display": "Intraocular use" }, + { "code": "372469009", "display": "Intrapleural use" }, + { "code": "372470005", "display": "Intrasternal use" }, + { "code": "372471009", "display": "Intravesical use" }, + { "code": "372472002", "display": "Ocular route (qualifier value)" }, + { "code": "372473007", "display": "Oromucosal use" }, + { "code": "372474001", "display": "Periarticular use" }, + { "code": "372475000", "display": "Perineural use" }, + { "code": "372476004", "display": "Subconjunctival use" }, + { "code": "404815008", "display": "Transmucosal route (qualifier value)" }, + { "code": "404818005", "display": "Intratracheal route (qualifier value)" }, + { "code": "404819002", "display": "Intrabiliary route (qualifier value)" }, + { "code": "404820008", "display": "Epidural route (qualifier value)" }, + { "code": "416174007", "display": "Suborbital route (qualifier value)" }, + { "code": "417070009", "display": "Caudal route (qualifier value)" }, + { "code": "417255000", "display": "Intraosseous route (qualifier value)" }, + { "code": "417950001", "display": "Intrathoracic route (qualifier value)" }, + { "code": "417985001", "display": "Enteral route (qualifier value)" }, + { "code": "417989007", "display": "Intraductal route (qualifier value)" }, + { "code": "418091004", "display": "Intratympanic route (qualifier value)" }, + { "code": "418114005", "display": "Intravenous central route (qualifier value)" }, + { "code": "418133000", "display": "Intramyometrial route (qualifier value)" }, + { "code": "418136008", "display": "Gastro-intestinal stoma route (qualifier value)" }, + { "code": "418162004", "display": "Colostomy route (qualifier value)" }, + { "code": "418204005", "display": "Periurethral route (qualifier value)" }, + { "code": "418287000", "display": "Intracoronal route (qualifier value)" }, + { "code": "418321004", "display": "Retrobulbar route (qualifier value)" }, + { "code": "418331006", "display": "Intracartilaginous route (qualifier value)" }, + { "code": "418401004", "display": "Intravitreal route (qualifier value)" }, + { "code": "418418000", "display": "Intraspinal route (qualifier value)" }, + { "code": "418441008", "display": "Orogastric route (qualifier value)" }, + { "code": "418511008", "display": "Transurethral route (qualifier value)" }, + { "code": "418586008", "display": "Intratendinous route (qualifier value)" }, + { "code": "418608002", "display": "Intracorneal route (qualifier value)" }, + { "code": "418664002", "display": "Oropharyngeal route (qualifier value)" }, + { "code": "418722009", "display": "Peribulbar route (qualifier value)" }, + { "code": "418730005", "display": "Nasojejunal route (qualifier value)" }, + { "code": "418743005", "display": "Fistula route (qualifier value)" }, + { "code": "418813001", "display": "Surgical drain route (qualifier value)" }, + { "code": "418821007", "display": "Intracameral route (qualifier value)" }, + { "code": "418851001", "display": "Paracervical route (qualifier value)" }, + { "code": "418877009", "display": "Intrasynovial route (qualifier value)" }, + { "code": "418887008", "display": "Intraduodenal route (qualifier value)" }, + { "code": "418892005", "display": "Intracisternal route (qualifier value)" }, + { "code": "418947002", "display": "Intratesticular route (qualifier value)" }, + { "code": "418987007", "display": "Intracranial route (qualifier value)" }, + { "code": "419021003", "display": "Tumour cavity route" }, + { "code": "419165009", "display": "Paravertebral route (qualifier value)" }, + { "code": "419231003", "display": "Intrasinal route (qualifier value)" }, + { + "code": "419243002", + "display": "Transcervical route (qualifier value)" + }, + { + "code": "419320008", + "display": "Subtendinous route (qualifier value)" + }, + { + "code": "419396008", + "display": "Intraabdominal route (qualifier value)" + }, + { + "code": "419601003", + "display": "Subgingival route (qualifier value)" + }, + { + "code": "419631009", + "display": "Intraovarian route (qualifier value)" + }, + { + "code": "419684008", + "display": "Ureteral route (qualifier value)" + }, + { + "code": "419762003", + "display": "Peritendinous route (qualifier value)" + }, + { + "code": "419778001", + "display": "Intrabronchial route (qualifier value)" + }, + { + "code": "419810008", + "display": "Intraprostatic route (qualifier value)" + }, + { + "code": "419874009", + "display": "Submucosal route (qualifier value)" + }, + { + "code": "419894000", + "display": "Surgical cavity route (qualifier value)" + }, + { + "code": "419954003", + "display": "Ileostomy route (qualifier value)" + }, + { + "code": "419993007", + "display": "Intravenous peripheral route (qualifier value)" + }, + { + "code": "420047004", + "display": "Periosteal route (qualifier value)" + }, + { + "code": "420163009", + "display": "Esophagostomy route" + }, + { + "code": "420168000", + "display": "Urostomy route (qualifier value)" + }, + { + "code": "420185003", + "display": "Laryngeal route (qualifier value)" + }, + { + "code": "420201002", + "display": "Intrapulmonary route (qualifier value)" + }, + { + "code": "420204005", + "display": "Mucous fistula route (qualifier value)" + }, + { + "code": "420218003", + "display": "Nasoduodenal route (qualifier value)" + }, + { + "code": "420254004", + "display": "Body cavity route (qualifier value)" + }, + { + "code": "420287000", + "display": "Intraventricular route - cardiac (qualifier value)" + }, + { + "code": "420719007", + "display": "Intracerebroventricular route (qualifier value)" + }, + { + "code": "428191002", + "display": "Percutaneous route (qualifier value)" + }, + { + "code": "429817007", + "display": "Interstitial route (qualifier value)" + }, + { + "code": "445752009", + "display": "Intraesophageal route (qualifier value)" + }, + { + "code": "445754005", + "display": "Intragingival route (qualifier value)" + }, + { + "code": "445755006", + "display": "Intravascular route (qualifier value)" + }, + { + "code": "445756007", + "display": "Intradural route (qualifier value)" + }, + { + "code": "445767008", + "display": "Intrameningeal route (qualifier value)" + }, + { + "code": "445768003", + "display": "Intragastric route (qualifier value)" + }, + { + "code": "445771006", + "display": "Intrapericardial route (qualifier value)" + }, + { + "code": "445913005", + "display": "Intralingual route (qualifier value)" + }, + { + "code": "445941009", + "display": "Intrahepatic route (qualifier value)" + }, + { + "code": "446105004", + "display": "Conjunctival route (qualifier value)" + }, + { + "code": "446407004", + "display": "Intraepicardial route (qualifier value)" + }, + { + "code": "446435000", + "display": "Transendocardial route (qualifier value)" + }, + { + "code": "446442000", + "display": "Transplacental route (qualifier value)" + }, + { + "code": "446540005", + "display": "Intracerebral route (qualifier value)" + }, + { + "code": "447026006", + "display": "Intraileal route (qualifier value)" + }, + { + "code": "447052000", + "display": "Periodontal route (qualifier value)" + }, + { + "code": "447080003", + "display": "Peridural route (qualifier value)" + }, + { + "code": "447081004", + "display": "Lower respiratory tract route (qualifier value)" + }, + { + "code": "447121004", + "display": "Intramammary route (qualifier value)" + }, + { + "code": "447122006", + "display": "Intratumor route (qualifier value)" + }, + { + "code": "447227007", + "display": "Transtympanic route (qualifier value)" + }, + { + "code": "447229005", + "display": "Transtracheal route (qualifier value)" + }, + { + "code": "447694001", + "display": "Respiratory tract route (qualifier value)" + }, + { + "code": "447964005", + "display": "Digestive tract route (qualifier value)" + }, + { + "code": "448077001", + "display": "Intraepidermal route (qualifier value)" + }, + { + "code": "448491004", + "display": "Intrajejunal route (qualifier value)" + }, + { + "code": "448492006", + "display": "Intracolonic route (qualifier value)" + }, + { + "code": "448598008", + "display": "Cutaneous route (qualifier value)" + }, + { + "code": "697971008", + "display": "Arteriovenous fistula route (qualifier value)" + }, + { + "code": "711360002", + "display": "Intraneural route (qualifier value)" + }, + { + "code": "711378007", + "display": "Intramural route (qualifier value)" + }, + { + "code": "714743009", + "display": "Extracorporeal route (qualifier value)" + }, + { + "code": "718329006", + "display": "Infiltration route (qualifier value)" + }, + { + "code": "764723001", + "display": "Epilesional route (qualifier value)" + }, + { + "code": "766790006", + "display": "Extracorporeal hemodialysis route (qualifier value)" + }, + { + "code": "876824003", + "display": "Intradialytic route" + }, + { + "code": "1078280005", + "display": "Intracatheter instillation route (qualifier value)" + }, + { + "code": "1254769004", + "display": "Suprachoroidal route" + }, + { + "code": "1259221004", + "display": "Intracorporus cavernosum route (qualifier value)" + }, + { + "code": "1611000175109", + "display": "Sublesional route (qualifier value)" + }, + { + "code": "58731000052100", + "display": "Intestinal route (qualifier value)" + }, + { + "code": "58751000052109", + "display": "Intraglandular route (qualifier value)" + }, + { + "code": "58761000052107", + "display": "Intracholangiopancreatic route" + }, + { + "code": "58771000052103", + "display": "Intraportal route" + }, + { + "code": "58811000052103", + "display": "Peritumoral route (qualifier value)" + }, + { + "code": "58821000052106", + "display": "Posterior juxtascleral route (qualifier value)" + }, + { + "code": "58831000052108", + "display": "Subretinal route (qualifier value)" + }, + { + "code": "666210000521", + "display": "Subretinal route (qualifier value)" + } +] \ No newline at end of file diff --git a/src/main/resources/snomed/SnomedObservation.json b/src/main/resources/snomed/SnomedObservation.json new file mode 100644 index 00000000..33e64c12 --- /dev/null +++ b/src/main/resources/snomed/SnomedObservation.json @@ -0,0 +1,302 @@ +[ + { + "code": "219006", + "display": "Current drinker" + }, + { + "code": "105542008", + "display": "Non - drinker" + }, + { + "code": "82581004", + "display": "Ex-drinker" + }, + { + "code": "86933000", + "display": "Heavy drinker" + }, + { + "code": "228277002", + "display": "Light drinker" + }, + { + "code": "43783005", + "display": "Moderate drinker" + }, + { + "code": "28127009", + "display": "Social drinker" + }, + { + "code": "39156-5", + "display": "Body mass index (BMI) [Ratio]" + }, + { + "code": "29463-7", + "display": "Body weight" + }, + { + "code": "8302-2", + "display": "Body height" + }, + { + "code": "56074-8", + "display": "Circumference Neck" + }, + { + "code": "8280-0", + "display": "Waist Circumference at umbilicus by Tape measure" + }, + { + "code": "56072-2", + "display": "Circumference Mid upper arm - right" + }, + { + "code": "2339-0", + "display": "Glucose [Mass/volume] in Blood" + }, + { + "code": "41604-0", + "display": "Fasting glucose [Mass/volume] in Capillary blood by Glucometer" + }, + { + "code": "14743-9", + "display": "Glucose [Moles/volume] in Capillary blood by Glucometer" + }, + { + "code": "14760-3", + "display": "Glucose [Moles/volume] in Capillary blood --2 hours post meal" + }, + { + "code": "73708-0", + "display": "Body fat [Mass] Calculated" + }, + { + "code": "34534-8", + "display": "12 lead EKG panel" + }, + { + "code": "8999-5", + "display": "Fluid intake oral Estimated" + }, + { + "code": "9052-2", + "display": "Calorie intake total" + }, + { + "code": "69429-9", + "display": "Metabolic rate --resting" + }, + { + "code": "94122-9", + "display": "Oxygen consumption (VO2)/Body weight [Volume Rate Content] --peak during exercise" + }, + { + "code": "8693-4", + "display": "Mental status" + }, + { + "code": "228273003", + "display": "Finding relating to alcohol drinking behavior" + }, + { + "code": "365981007", + "display": "Finding of tobacco smoking behavior" + }, + { + "code": "228509002", + "display": "Finding relating to tobacco chewing" + }, + { + "code": "41829006", + "display": "Finding relating to tobacco chewing" + }, + { + "code": "83765003", + "display": "Boredom" + }, + { + "code": "45763006", + "display": "Demoralization" + }, + { + "code": "708891002", + "display": "Emotionally stable" + }, + { + "code": "28669007", + "display": "Anhedonia" + }, + { + "code": "48694002", + "display": "Anxiety" + }, + { + "code": "102893002", + "display": "Excitability" + }, + { + "code": "225012006", + "display": "Feeling ashamed" + }, + { + "code": "224973000", + "display": "Feeling frustrated" + }, + { + "code": "224973000", + "display": "Feeling frustrated" + }, + { + "code": "267076002", + "display": "Feeling lonely" + }, + { + "code": "307048004", + "display": "Feeling isolated" + }, + { + "code": "162190005", + "display": "No nervous symptoms" + }, + { + "code": "225457007", + "display": "Feeling suicidal" + }, + { + "code": "224977004", + "display": "Feeling upset" + }, + { + "code": "271596009", + "display": "Mental distress" + }, + { + "code": "366979004", + "display": "Depressed mood" + }, + { + "code": "1402001", + "display": "Fear" + }, + { + "code": "75408008", + "display": "Feeling angry" + }, + { + "code": "55929007", + "display": "Feeling irritable" + }, + { + "code": "112080002", + "display": "Cheerful mood" + }, + { + "code": "225658008", + "display": "Mood stable" + }, + { + "code": "102894008", + "display": "Feeling calm" + }, + { + "code": "425363002", + "display": "Smiling" + }, + { + "code": "79015004", + "display": "Worried" + }, + { + "code": "53489000", + "display": "Tension" + }, + { + "code": "55423-8", + "display": "Number of steps in unspecified time Pedometer" + }, + { + "code": "93832-4", + "display": "Sleep duration" + }, + { + "code": "41981-2", + "display": "Calories burned" + }, + { + "code": "80493-0", + "display": "Activity level [Acceleration]" + }, + { + "code": "77176002", + "display": "Smoker" + }, + { + "code": "160618006", + "display": "Current non-smoker" + }, + { + "code": "8517006", + "display": "Ex-smoker" + }, + { + "code": "230065006", + "display": "Chain smoker" + }, + { + "code": "230063004", + "display": "Heavy cigarette smoker" + }, + { + "code": "230060001", + "display": "Light cigarette smoker" + }, + { + "code": "230062009", + "display": "Moderate cigarette smoker" + }, + { + "code": "230059006", + "display": "Occasional cigarette smoker" + }, + { + "code": "61008-9", + "display": "Body surface temperature" + }, + { + "code": "9279-1", + "display": "Respiratory rate" + }, + { + "code": "8867-4", + "display": "Heart rate" + }, + { + "code": "2708-6", + "display": "Oxygen saturation in Arterial blood" + }, + { + "code": "85354-9", + "display": "Blood pressure panel with all children optional" + }, + { + "code": "11976-8", + "display": "Ovulation date" + }, + { + "code": "92656-8", + "display": "Number of menstrual periods per year" + }, + { + "code": "42798-9", + "display": "Age at menarche" + }, + { + "code": "42802-9", + "display": "Age at menopause" + }, + { + "code": "8665-2", + "display": "Last menstrual period start date" + } +] \ No newline at end of file diff --git a/src/main/resources/snomed/SnomedSpecimen.json b/src/main/resources/snomed/SnomedSpecimen.json new file mode 100644 index 00000000..ccb64567 --- /dev/null +++ b/src/main/resources/snomed/SnomedSpecimen.json @@ -0,0 +1,3998 @@ +[ + { + "code": "40511003", + "display": "Eluate" + }, + { + "code": "48469005", + "display": "Cytologic material" + }, + { + "code": "110893002", + "display": "Cutaneous cytologic material" + }, + { + "code": "110894008", + "display": "Mammary cytologic material" + }, + { + "code": "110896005", + "display": "Subcutaneous cytologic material" + }, + { + "code": "110897001", + "display": "Bone marrow cytological material" + }, + { + "code": "110898006", + "display": "Lymph node cytologic material" + }, + { + "code": "110899003", + "display": "Breast nipple cytologic material" + }, + { + "code": "110900008", + "display": "Skeletal muscle cytologic material" + }, + { + "code": "110901007", + "display": "Bone cytologic material" + }, + { + "code": "110902000", + "display": "Upper respiratory tract cytologic material" + }, + { + "code": "110903005", + "display": "Nasal cytologic material" + }, + { + "code": "110904004", + "display": "Accessory sinus cytologic material" + }, + { + "code": "110905003", + "display": "Nasopharyngeal cytologic material" + }, + { + "code": "110906002", + "display": "Lower respiratory tract cytologic material" + }, + { + "code": "110907006", + "display": "Epiglottic cytologic material" + }, + { + "code": "110908001", + "display": "Laryngeal cytologic material" + }, + { + "code": "110909009", + "display": "Vocal cord cytologic material" + }, + { + "code": "110910004", + "display": "Lung cytologic material" + }, + { + "code": "110912007", + "display": "Bronchial cytologic material" + }, + { + "code": "110913002", + "display": "Pleural cytologic material" + }, + { + "code": "110914008", + "display": "Right upper lobe bronchus cytologic material" + }, + { + "code": "110915009", + "display": "Right pleural cytologic material" + }, + { + "code": "110916005", + "display": "Right lower lobe bronchus cytologic material" + }, + { + "code": "110917001", + "display": "Left pleural cytologic material" + }, + { + "code": "110918006", + "display": "Left upper lobe bronchus cytologic material" + }, + { + "code": "110919003", + "display": "Pericardial cytologic material" + }, + { + "code": "110920009", + "display": "Tracheal cytologic material" + }, + { + "code": "110921008", + "display": "Right middle lobe bronchus cytologic material" + }, + { + "code": "110922001", + "display": "Left bronchial cytologic material" + }, + { + "code": "110923006", + "display": "Left lower lobe bronchus cytologic material" + }, + { + "code": "110924000", + "display": "Right bronchial cytologic material" + }, + { + "code": "110925004", + "display": "Cytologic material of mouth" + }, + { + "code": "110926003", + "display": "Gallbladder cytologic material" + }, + { + "code": "110927007", + "display": "Liver cytologic material" + }, + { + "code": "110928002", + "display": "Bile duct cytologic material" + }, + { + "code": "110929005", + "display": "Pancreatic cytologic material" + }, + { + "code": "110930000", + "display": "Salivary gland cytologic material" + }, + { + "code": "110931001", + "display": "Penis cytologic material" + }, + { + "code": "110932008", + "display": "Parotid gland cytologic material" + }, + { + "code": "110933003", + "display": "Prostate cytologic material" + }, + { + "code": "110934009", + "display": "Pharyngeal cytologic material" + }, + { + "code": "110935005", + "display": "Testis cytologic material" + }, + { + "code": "110936006", + "display": "Gastric cytologic material" + }, + { + "code": "110937002", + "display": "Seminal vesicle cytologic material" + }, + { + "code": "110938007", + "display": "Duodenal cytologic material" + }, + { + "code": "110939004", + "display": "Vas deferens cytologic material" + }, + { + "code": "110940002", + "display": "Ileal cytologic material" + }, + { + "code": "110941003", + "display": "Epididymis cytologic material" + }, + { + "code": "110942005", + "display": "Rectal cytologic material" + }, + { + "code": "110943000", + "display": "Renal pelvis cytologic material" + }, + { + "code": "110944006", + "display": "Peritoneal cytologic material" + }, + { + "code": "110945007", + "display": "Vulva cytologic material" + }, + { + "code": "110946008", + "display": "Upper urinary tract cytologic material" + }, + { + "code": "110947004", + "display": "Vagina cytologic material" + }, + { + "code": "110948009", + "display": "Kidney cytologic material" + }, + { + "code": "110949001", + "display": "Cervix cytologic material" + }, + { + "code": "110950001", + "display": "Urinary bladder cytologic material" + }, + { + "code": "110951002", + "display": "Endocervical cytologic material" + }, + { + "code": "110952009", + "display": "Submaxillary gland cytologic material" + }, + { + "code": "110953004", + "display": "Vaginal and cervical cytologic material (specimen)" + }, + { + "code": "110954005", + "display": "Small intestine cytologic material" + }, + { + "code": "110955006", + "display": "Endometrium cytologic material" + }, + { + "code": "110956007", + "display": "Colonic cytologic material" + }, + { + "code": "110957003", + "display": "Fallopian tube cytologic material" + }, + { + "code": "110958008", + "display": "Urinary tract cytologic material" + }, + { + "code": "110959000", + "display": "Placenta cytologic material" + }, + { + "code": "110960005", + "display": "Ureter cytologic material" + }, + { + "code": "110961009", + "display": "Chorion cytologic material" + }, + { + "code": "110962002", + "display": "Esophageal cytologic material" + }, + { + "code": "110963007", + "display": "Anal cytologic material" + }, + { + "code": "110964001", + "display": "Lower urinary tract cytologic material" + }, + { + "code": "110965000", + "display": "Urethra cytologic material" + }, + { + "code": "110966004", + "display": "Jejunal cytologic material" + }, + { + "code": "110967008", + "display": "Amnion cytologic material" + }, + { + "code": "110968003", + "display": "Fetal cytologic material" + }, + { + "code": "110969006", + "display": "Cerebrospinal fluid cytologic material" + }, + { + "code": "110970007", + "display": "Cerebroventricular fluid cytologic material" + }, + { + "code": "116155002", + "display": "Ampulla of Vater cytologic material" + }, + { + "code": "116156001", + "display": "Gastrointestinal tract cytologic material" + }, + { + "code": "116157005", + "display": "Heart cytologic material" + }, + { + "code": "116158000", + "display": "Large intestine cytologic material" + }, + { + "code": "116159008", + "display": "Upper aerodigestive tract cytologic material" + }, + { + "code": "116160003", + "display": "Thyroid cytologic material" + }, + { + "code": "116161004", + "display": "Fine needle aspirate of thyroid, cytologic material" + }, + { + "code": "116162006", + "display": "Thyroid cytologic material, processed intraoperatively" + }, + { + "code": "116213003", + "display": "Ovary cytologic material" + }, + { + "code": "119294007", + "display": "Dried blood specimen" + }, + { + "code": "119295008", + "display": "Specimen obtained by aspiration" + }, + { + "code": "119297000", + "display": "Blood specimen" + }, + { + "code": "119298005", + "display": "Mixed venous blood specimen" + }, + { + "code": "119299002", + "display": "Specimen from patient" + }, + { + "code": "119300005", + "display": "Specimen from blood product" + }, + { + "code": "119301009", + "display": "Plant specimen" + }, + { + "code": "119302002", + "display": "Mushroom specimen" + }, + { + "code": "119303007", + "display": "Microbial isolate specimen" + }, + { + "code": "119304001", + "display": "Specimen from blood bag" + }, + { + "code": "119305000", + "display": "Specimen from plasma bag (specimen)" + }, + { + "code": "119307008", + "display": "Endotracheal tube specimen" + }, + { + "code": "119308003", + "display": "Cannula submitted as specimen" + }, + { + "code": "119309006", + "display": "Arterial line submitted as specimen" + }, + { + "code": "119311002", + "display": "Catheter submitted as specimen (specimen)" + }, + { + "code": "119312009", + "display": "Catheter tip submitted as specimen" + }, + { + "code": "119313004", + "display": "Implantable venous catheter submitted as specimen" + }, + { + "code": "119314005", + "display": "Electrode submitted as specimen (specimen)" + }, + { + "code": "119316007", + "display": "Non-biological fluid specimen" + }, + { + "code": "119317003", + "display": "Gaseous material specimen" + }, + { + "code": "119318008", + "display": "Water specimen" + }, + { + "code": "119319000", + "display": "Drug specimen" + }, + { + "code": "119320006", + "display": "Food specimen" + }, + { + "code": "119321005", + "display": "Milk specimen" + }, + { + "code": "119323008", + "display": "Pus specimen" + }, + { + "code": "119324002", + "display": "Specimen of unknown material" + }, + { + "code": "119325001", + "display": "Skin specimen" + }, + { + "code": "119326000", + "display": "Hair specimen" + }, + { + "code": "119327009", + "display": "Nail specimen" + }, + { + "code": "119328004", + "display": "Mother's milk specimen" + }, + { + "code": "119329007", + "display": "Colostrum specimen" + }, + { + "code": "119331003", + "display": "Skeletal muscle specimen" + }, + { + "code": "119332005", + "display": "Synovial fluid specimen" + }, + { + "code": "119333000", + "display": "Fibroblast specimen" + }, + { + "code": "119334006", + "display": "Sputum specimen" + }, + { + "code": "119335007", + "display": "Coughed sputum specimen" + }, + { + "code": "119336008", + "display": "Exhaled air specimen" + }, + { + "code": "119337004", + "display": "Inhaled gas specimen" + }, + { + "code": "119338009", + "display": "Dentin specimen" + }, + { + "code": "119339001", + "display": "Stool specimen" + }, + { + "code": "119340004", + "display": "Meconium specimen" + }, + { + "code": "119341000", + "display": "Bile specimen" + }, + { + "code": "119342007", + "display": "Saliva specimen" + }, + { + "code": "119343002", + "display": "Pancreatic fluid specimen" + }, + { + "code": "119344008", + "display": "Specimen from genital system" + }, + { + "code": "119345009", + "display": "Menstrual blood specimen" + }, + { + "code": "119346005", + "display": "Egg yolk specimen" + }, + { + "code": "119347001", + "display": "Seminal fluid specimen" + }, + { + "code": "119348006", + "display": "Seminal plasma specimen" + }, + { + "code": "119349003", + "display": "Spermatozoa specimen" + }, + { + "code": "119350003", + "display": "Calculus specimen" + }, + { + "code": "119351004", + "display": "Erythrocyte specimen" + }, + { + "code": "119352006", + "display": "Macrophage specimen" + }, + { + "code": "119353001", + "display": "Lymphocyte specimen" + }, + { + "code": "119355008", + "display": "Polymorphonuclear neutrophil specimen" + }, + { + "code": "119356009", + "display": "Eosinophil specimen" + }, + { + "code": "119357000", + "display": "Basophil specimen" + }, + { + "code": "119358005", + "display": "Platelet specimen" + }, + { + "code": "119359002", + "display": "Bone marrow specimen" + }, + { + "code": "119361006", + "display": "Plasma specimen" + }, + { + "code": "119362004", + "display": "Platelet poor plasma specimen" + }, + { + "code": "119363009", + "display": "Platelet rich plasma specimen" + }, + { + "code": "119364003", + "display": "Serum specimen" + }, + { + "code": "119365002", + "display": "Specimen from wound" + }, + { + "code": "119366001", + "display": "Specimen from wound abscess" + }, + { + "code": "119367005", + "display": "Specimen from burn injury" + }, + { + "code": "119368000", + "display": "Specimen from cyst" + }, + { + "code": "119369008", + "display": "Specimen from ulcer" + }, + { + "code": "119370009", + "display": "Specimen from fistula" + }, + { + "code": "119371008", + "display": "Specimen from abscess" + }, + { + "code": "119373006", + "display": "Amniotic fluid specimen" + }, + { + "code": "119376003", + "display": "Tissue specimen" + }, + { + "code": "119377007", + "display": "Myocardial specimen" + }, + { + "code": "119378002", + "display": "Endocardial specimen" + }, + { + "code": "119379005", + "display": "Specimen from stomach" + }, + { + "code": "119380008", + "display": "Specimen from small intestine" + }, + { + "code": "119381007", + "display": "Specimen from large intestine" + }, + { + "code": "119382000", + "display": "Specimen from colon" + }, + { + "code": "119383005", + "display": "Specimen from liver" + }, + { + "code": "119384004", + "display": "Specimen from right fallopian tube" + }, + { + "code": "119385003", + "display": "Specimen from left fallopian tube" + }, + { + "code": "119386002", + "display": "Specimen from prostate" + }, + { + "code": "119388001", + "display": "Specimen from internal nose" + }, + { + "code": "119389009", + "display": "Specimen from throat" + }, + { + "code": "119390000", + "display": "Specimen from trachea" + }, + { + "code": "119391001", + "display": "Specimen from bronchus" + }, + { + "code": "119392008", + "display": "Specimen from anus" + }, + { + "code": "119393003", + "display": "Specimen from urethra" + }, + { + "code": "119394009", + "display": "Specimen from vagina" + }, + { + "code": "119395005", + "display": "Specimen from uterine cervix" + }, + { + "code": "119396006", + "display": "Specimen from endometrium" + }, + { + "code": "119397002", + "display": "Specimen from penis" + }, + { + "code": "119398007", + "display": "Specimen from brain" + }, + { + "code": "119399004", + "display": "Specimen from eye" + }, + { + "code": "119400006", + "display": "Specimen from cornea" + }, + { + "code": "119401005", + "display": "Specimen from conjunctiva" + }, + { + "code": "119403008", + "display": "Specimen from placenta" + }, + { + "code": "122550002", + "display": "Specimen obtained by fine needle aspiration procedure" + }, + { + "code": "122551003", + "display": "Peripheral blood specimen" + }, + { + "code": "122552005", + "display": "Arterial blood specimen" + }, + { + "code": "122553000", + "display": "Blood specimen obtained from umbilicus" + }, + { + "code": "122554006", + "display": "Capillary blood specimen" + }, + { + "code": "122555007", + "display": "Venous blood specimen" + }, + { + "code": "122556008", + "display": "Cord blood specimen" + }, + { + "code": "122557004", + "display": "Cord blood specimen from fetus" + }, + { + "code": "122558009", + "display": "Blood specimen from blood product" + }, + { + "code": "122559001", + "display": "Blood specimen from control" + }, + { + "code": "122560006", + "display": "Blood specimen from donor" + }, + { + "code": "122561005", + "display": "Blood specimen from patient" + }, + { + "code": "122562003", + "display": "Blood specimen from newborn" + }, + { + "code": "122563008", + "display": "Specimen from blood bag from patient (specimen)" + }, + { + "code": "122564002", + "display": "Specimen from blood bag from blood product (specimen)" + }, + { + "code": "122565001", + "display": "Urinary catheter specimen" + }, + { + "code": "122566000", + "display": "Fluid specimen from wound" + }, + { + "code": "122567009", + "display": "Urine sediment specimen" + }, + { + "code": "122568004", + "display": "Exudate specimen from wound" + }, + { + "code": "122569007", + "display": "Sweat specimen" + }, + { + "code": "122571007", + "display": "Pericardial fluid specimen" + }, + { + "code": "122572000", + "display": "Vomitus specimen" + }, + { + "code": "122573005", + "display": "Gastric contents specimen" + }, + { + "code": "122574004", + "display": "Duodenal fluid specimen" + }, + { + "code": "122575003", + "display": "Urine specimen" + }, + { + "code": "122576002", + "display": "Genital mucus specimen" + }, + { + "code": "122577006", + "display": "Cervical mucus specimen" + }, + { + "code": "122578001", + "display": "Female genital fluid specimen" + }, + { + "code": "122579009", + "display": "Genital lochia specimen" + }, + { + "code": "122580007", + "display": "Cerumen specimen" + }, + { + "code": "122581006", + "display": "Erythrocyte specimen from blood donor" + }, + { + "code": "122582004", + "display": "Erythrocyte specimen from blood product" + }, + { + "code": "122583009", + "display": "Erythrocyte specimen from patient" + }, + { + "code": "122584003", + "display": "Leukocyte specimen from patient" + }, + { + "code": "122585002", + "display": "Leukocyte specimen from control" + }, + { + "code": "122587005", + "display": "Platelet poor plasma specimen from control" + }, + { + "code": "122588000", + "display": "Platelet poor plasma specimen from patient" + }, + { + "code": "122589008", + "display": "Serum specimen from donor" + }, + { + "code": "122590004", + "display": "Serum specimen from patient" + }, + { + "code": "122591000", + "display": "Serum specimen from blood product" + }, + { + "code": "122592007", + "display": "Acellular blood (serum or plasma) specimen" + }, + { + "code": "122593002", + "display": "Tissue specimen obtained from ulcer" + }, + { + "code": "122594008", + "display": "Tears specimen" + }, + { + "code": "122595009", + "display": "Specimen from breast obtained by total mastectomy" + }, + { + "code": "122596005", + "display": "Specimen from breast obtained by complete excision of lesion, less than total mastectomy" + }, + { + "code": "122597001", + "display": "Specimen from breast obtained by complete excision, less than total mastectomy, with axillary contents" + }, + { + "code": "122598006", + "display": "Specimen from breast obtained by complete excision, less than total mastectomy, without axillary contents" + }, + { + "code": "122599003", + "display": "Specimen from breast obtained by radical mastectomy" + }, + { + "code": "122600000", + "display": "Specimen from breast obtained by modified radical mastectomy" + }, + { + "code": "122601001", + "display": "Specimen from breast obtained by biopsy" + }, + { + "code": "122602008", + "display": "Tissue specimen from biopsy of upper aerodigestive tract" + }, + { + "code": "122604009", + "display": "Specimen from lung obtained by wedge resection" + }, + { + "code": "122605005", + "display": "Specimen from lung obtained by segmentectomy" + }, + { + "code": "122606006", + "display": "Specimen from lung obtained by lobectomy" + }, + { + "code": "122607002", + "display": "Specimen from lung obtained by pneumonectomy" + }, + { + "code": "122608007", + "display": "Specimen from lung obtained by major airway resection" + }, + { + "code": "122609004", + "display": "Specimen from lung obtained by bronchial washing procedure" + }, + { + "code": "122610009", + "display": "Specimen from lung obtained by biopsy" + }, + { + "code": "122611008", + "display": "Specimen from lung obtained by fiberoptic bronchoscopic biopsy" + }, + { + "code": "122613006", + "display": "Specimen from lung obtained by mediastinoscopic biopsy" + }, + { + "code": "122614000", + "display": "Specimen from lung obtained by fine needle aspiration procedure" + }, + { + "code": "122616003", + "display": "Specimen from pleura obtained by open thoracotomy and biopsy" + }, + { + "code": "122617007", + "display": "Specimen from pleura obtained by percutaneous needle biopsy" + }, + { + "code": "122618002", + "display": "Specimen from pleura obtained by fine needle aspiration procedure" + }, + { + "code": "122619005", + "display": "Specimen from pleura obtained by thoracentesis" + }, + { + "code": "122620004", + "display": "Specimen from pleura obtained by thoracoscopic procedure" + }, + { + "code": "122621000", + "display": "Specimen from pleura obtained by thoracoscopic biopsy" + }, + { + "code": "122622007", + "display": "Specimen from pleura obtained by lymph node biopsy" + }, + { + "code": "122623002", + "display": "Specimen from heart obtained by biopsy" + }, + { + "code": "122624008", + "display": "Specimen from heart obtained by excisional biopsy of lesion" + }, + { + "code": "122625009", + "display": "Specimen from heart obtained by incisional biopsy" + }, + { + "code": "122626005", + "display": "Specimen from heart obtained by fine needle aspiration procedure" + }, + { + "code": "122627001", + "display": "Specimen from gastrointestinal tract obtained by incisional biopsy" + }, + { + "code": "122628006", + "display": "Specimen from esophagus obtained by incisional biopsy" + }, + { + "code": "122629003", + "display": "Specimen from esophagus obtained by excisional biopsy of lesion" + }, + { + "code": "122630008", + "display": "Specimen from esophagus obtained by esophageal resection" + }, + { + "code": "122631007", + "display": "Specimen from esophagus obtained by esophagogastrectomy" + }, + { + "code": "122632000", + "display": "Specimen from stomach obtained by incisional biopsy" + }, + { + "code": "122633005", + "display": "Specimen from stomach obtained by excisional biopsy (polypectomy) of lesion" + }, + { + "code": "122634004", + "display": "Specimen from stomach obtained by total gastrectomy" + }, + { + "code": "122635003", + "display": "Specimen from stomach obtained by partial gastrectomy" + }, + { + "code": "122636002", + "display": "Specimen from proximal stomach obtained by partial gastrectomy" + }, + { + "code": "122637006", + "display": "Specimen from distal stomach obtained by partial gastrectomy" + }, + { + "code": "122638001", + "display": "Tissue specimen from small intestine" + }, + { + "code": "122639009", + "display": "Specimen from duodenum obtained by Whipple resection" + }, + { + "code": "122640006", + "display": "Specimen from jejunum obtained by segmental resection" + }, + { + "code": "122641005", + "display": "Specimen from ileum obtained by segmental resection" + }, + { + "code": "122642003", + "display": "Specimen from distal ileum obtained by right hemicolectomy" + }, + { + "code": "122643008", + "display": "Tissue specimen from large intestine" + }, + { + "code": "122644002", + "display": "Specimen from large intestine obtained by incisional biopsy" + }, + { + "code": "122645001", + "display": "Specimen from large intestine obtained by excisional biopsy (polypectomy) of lesion" + }, + { + "code": "122646000", + "display": "Specimen from large intestine obtained by abdominoperineal resection" + }, + { + "code": "122647009", + "display": "Specimen from large intestine obtained by total abdominal colectomy" + }, + { + "code": "122648004", + "display": "Specimen from colon obtained by right hemicolectomy" + }, + { + "code": "122649007", + "display": "Specimen from colon obtained by transverse colectomy" + }, + { + "code": "122650007", + "display": "Specimen from colon obtained by left hemicolectomy" + }, + { + "code": "122651006", + "display": "Specimen from colon obtained by sigmoidectomy" + }, + { + "code": "122652004", + "display": "Specimen from colon obtained by rectal (low anterior) resection" + }, + { + "code": "122653009", + "display": "Specimen from rectum obtained by transanal disk excision" + }, + { + "code": "122654003", + "display": "Specimen from rectum obtained by transanal disk excision, intact" + }, + { + "code": "122655002", + "display": "Specimen from rectum obtained by transanal disk excision, fragmented" + }, + { + "code": "122656001", + "display": "Tissue specimen from gall bladder" + }, + { + "code": "122657005", + "display": "Specimen from ampulla of Vater obtained by incisional biopsy" + }, + { + "code": "122658000", + "display": "Specimen from ampulla of Vater obtained by ampullectomy" + }, + { + "code": "122659008", + "display": "Specimen from ampulla of Vater obtained by pancreaticoduodenectomy" + }, + { + "code": "122660003", + "display": "Specimen from ampulla of Vater obtained by pylorus-sparing pancreaticoduodenectomy" + }, + { + "code": "122661004", + "display": "Specimen from pancreas obtained by partial pancreatectomy" + }, + { + "code": "122662006", + "display": "Specimen from pancreatic body obtained by partial resection" + }, + { + "code": "122663001", + "display": "Specimen from pancreatic tail obtained by partial resection" + }, + { + "code": "122664007", + "display": "Specimen from pancreas obtained by total pancreatectomy" + }, + { + "code": "122665008", + "display": "Specimen from pancreas obtained by pancreaticoduodenectomy (Whipple resection)" + }, + { + "code": "122666009", + "display": "Specimen from pancreas obtained by pylorus sparing pancreaticoduodenectomy" + }, + { + "code": "122667000", + "display": "Specimen from pancreas obtained by incisional biopsy" + }, + { + "code": "122668005", + "display": "Specimen from urinary tract obtained by transurethral excision" + }, + { + "code": "122669002", + "display": "Specimen from urinary bladder obtained by anterior exenteration (specimen)" + }, + { + "code": "122670001", + "display": "Specimen from kidney obtained by (core) needle biopsy" + }, + { + "code": "122671002", + "display": "Specimen from kidney obtained by fine needle aspiration procedure" + }, + { + "code": "122672009", + "display": "Specimen from kidney obtained by incisional biopsy" + }, + { + "code": "122673004", + "display": "Specimen from kidney obtained by wedge biopsy" + }, + { + "code": "122674005", + "display": "Specimen from right kidney obtained by radical nephrectomy" + }, + { + "code": "122675006", + "display": "Specimen from right kidney obtained by radical nephrectomy, without adrenal" + }, + { + "code": "122676007", + "display": "Specimen from right kidney obtained by partial nephrectomy" + }, + { + "code": "122677003", + "display": "Specimen from right kidney, inferior pole obtained by partial nephrectomy" + }, + { + "code": "122678008", + "display": "Specimen from right kidney, middle pole obtained by partial nephrectomy" + }, + { + "code": "122679000", + "display": "Specimen from right kidney, superior pole obtained by partial nephrectomy" + }, + { + "code": "122680002", + "display": "Specimen from left kidney obtained by radical nephrectomy" + }, + { + "code": "122681003", + "display": "Specimen from left kidney obtained by radical nephrectomy, without adrenal" + }, + { + "code": "122682005", + "display": "Specimen from left kidney obtained by partial nephrectomy" + }, + { + "code": "122683000", + "display": "Specimen from left kidney, inferior pole obtained by partial nephrectomy" + }, + { + "code": "122684006", + "display": "Specimen from left kidney, middle pole obtained by partial nephrectomy" + }, + { + "code": "122685007", + "display": "Specimen from left kidney, superior pole obtained by partial nephrectomy" + }, + { + "code": "122686008", + "display": "Specimen from urinary bladder obtained by partial cystectomy (specimen)" + }, + { + "code": "122687004", + "display": "Specimen from urinary bladder obtained by total cystectomy (specimen)" + }, + { + "code": "122688009", + "display": "Specimen from urinary bladder obtained by radical cystoprostatectomy (specimen)" + }, + { + "code": "122689001", + "display": "Specimen from right kidney obtained by radical nephrectomy and adrenalectomy" + }, + { + "code": "122690005", + "display": "Specimen from left kidney obtained by radical nephrectomy and adrenalectomy" + }, + { + "code": "122691009", + "display": "Specimen from vagina obtained by incisional biopsy" + }, + { + "code": "122692002", + "display": "Specimen from vagina obtained by excisional biopsy of lesion" + }, + { + "code": "122693007", + "display": "Specimen from vagina obtained by vaginectomy" + }, + { + "code": "122694001", + "display": "Specimen from vagina obtained by radical vaginectomy" + }, + { + "code": "122696004", + "display": "Specimen from uterus obtained by radical hysterectomy" + }, + { + "code": "122697008", + "display": "Specimen from uterus obtained by pelvic exenteration" + }, + { + "code": "122698003", + "display": "Specimen from uterine cervix obtained by incisional biopsy" + }, + { + "code": "122699006", + "display": "Specimen from uterine cervix obtained by excisional biopsy (cone biopsy) of lesion" + }, + { + "code": "122700007", + "display": "Specimen from uterine cervix obtained by hysterectomy" + }, + { + "code": "122701006", + "display": "Specimen from uterine cervix obtained by radical hysterectomy" + }, + { + "code": "122702004", + "display": "Specimen from uterine cervix obtained by pelvic exenteration" + }, + { + "code": "122703009", + "display": "Specimen from endometrium obtained by curettage" + }, + { + "code": "122704003", + "display": "Specimen from endometrium obtained by biopsy" + }, + { + "code": "122705002", + "display": "Specimen from endometrium obtained by hysterectomy" + }, + { + "code": "122706001", + "display": "Specimen from endometrium obtained by radical hysterectomy" + }, + { + "code": "122707005", + "display": "Specimen from endometrium obtained by pelvic exenteration" + }, + { + "code": "122708000", + "display": "Specimen from ovary obtained by biopsy" + }, + { + "code": "122709008", + "display": "Specimen from ovary obtained by incisional biopsy" + }, + { + "code": "122710003", + "display": "Specimen from ovary obtained by resection" + }, + { + "code": "122711004", + "display": "Specimen from ovary obtained by removal of tumor in fragments" + }, + { + "code": "122712006", + "display": "Specimen from ovary obtained by hysterectomy with salpingo-oophorectomy" + }, + { + "code": "122713001", + "display": "Specimen from ovary obtained by subtotal right oophorectomy" + }, + { + "code": "122714007", + "display": "Specimen from right ovary obtained by oophorectomy" + }, + { + "code": "122715008", + "display": "Specimen from right ovary obtained by salpingo-oophorectomy" + }, + { + "code": "122716009", + "display": "Specimen from left ovary obtained by oophorectomy" + }, + { + "code": "122717000", + "display": "Specimen from ovary obtained by subtotal left oophorectomy" + }, + { + "code": "122718005", + "display": "Specimen from left ovary obtained by salpingo-oophorectomy" + }, + { + "code": "122719002", + "display": "Specimen from fallopian tube obtained by hysterectomy with salpingo-oophorectomy" + }, + { + "code": "122720008", + "display": "Specimen from fallopian tube obtained by excision of tubal fragments" + }, + { + "code": "122721007", + "display": "Specimen from fallopian tube obtained by pelvic exenteration" + }, + { + "code": "122722000", + "display": "Specimen from right fallopian tube obtained by salpingo-oophorectomy" + }, + { + "code": "122723005", + "display": "Specimen from left fallopian tube obtained by salpingo-oophorectomy" + }, + { + "code": "122724004", + "display": "Specimen from prostate obtained by enucleation" + }, + { + "code": "122725003", + "display": "Specimen from prostate obtained by radical prostatectomy" + }, + { + "code": "122726002", + "display": "Specimen from prostate obtained by retropubic resection" + }, + { + "code": "122727006", + "display": "Specimen from prostate obtained by suprapubic resection" + }, + { + "code": "122728001", + "display": "Specimen from testis obtained by inguinal exposure with testicular isolation and biopsy" + }, + { + "code": "122729009", + "display": "Specimen from testis obtained by transscrotal needle biopsy" + }, + { + "code": "122730004", + "display": "Specimen from testis obtained by transcrotal open biopsy" + }, + { + "code": "122732007", + "display": "Specimen from thyroid obtained by lobectomy" + }, + { + "code": "122733002", + "display": "Specimen from right lobe of thyroid obtained by lobe resection" + }, + { + "code": "122734008", + "display": "Specimen from left lobe of thyroid obtained by lobe resection" + }, + { + "code": "122735009", + "display": "Specimen from thyroid obtained by isthmectomy" + }, + { + "code": "122736005", + "display": "Tissue specimen from placenta" + }, + { + "code": "122737001", + "display": "Specimen from breast obtained by core needle biopsy" + }, + { + "code": "122738006", + "display": "Specimen obtained from breast by stereotactically guided core needle biopsy" + }, + { + "code": "122739003", + "display": "Specimen from breast obtained by incisional biopsy of breast mass" + }, + { + "code": "122877000", + "display": "Upper respiratory fluid specimen obtained by tracheal aspiration" + }, + { + "code": "122879002", + "display": "Upper gastrointestinal contents specimen" + }, + { + "code": "122880004", + "display": "Urine specimen obtained by clean catch procedure" + }, + { + "code": "127456000", + "display": "Specimen from breast" + }, + { + "code": "127457009", + "display": "Tissue specimen from breast" + }, + { + "code": "127458004", + "display": "Specimen from lung" + }, + { + "code": "127459007", + "display": "Specimen from pleura" + }, + { + "code": "127460002", + "display": "Tissue specimen from pleura" + }, + { + "code": "127461003", + "display": "Specimen from pleura obtained by pleurectomy" + }, + { + "code": "127462005", + "display": "Specimen from heart" + }, + { + "code": "127463000", + "display": "Specimen from esophagus" + }, + { + "code": "127464006", + "display": "Tissue specimen from esophagus" + }, + { + "code": "127465007", + "display": "Specimen from gastrointestinal tract" + }, + { + "code": "127466008", + "display": "Tissue specimen from gastrointestinal tract" + }, + { + "code": "127467004", + "display": "Specimen from ampulla of Vater" + }, + { + "code": "127468009", + "display": "Tissue specimen from ampulla of Vater" + }, + { + "code": "127469001", + "display": "Specimen from pancreas" + }, + { + "code": "127470000", + "display": "Tissue specimen from pancreas" + }, + { + "code": "127471001", + "display": "Specimen from urinary tract" + }, + { + "code": "127472008", + "display": "Tissue specimen from urinary tract" + }, + { + "code": "127473003", + "display": "Specimen from kidney" + }, + { + "code": "127474009", + "display": "Tissue specimen from kidney" + }, + { + "code": "127475005", + "display": "Tissue specimen from testis" + }, + { + "code": "127476006", + "display": "Specimen from fallopian tube" + }, + { + "code": "127478007", + "display": "Tissue specimen from thyroid gland" + }, + { + "code": "127479004", + "display": "Specimen from uterus" + }, + { + "code": "127480001", + "display": "Tissue specimen from uterus" + }, + { + "code": "127481002", + "display": "Tissue specimen from uterine cervix" + }, + { + "code": "127482009", + "display": "Tissue specimen from ovary" + }, + { + "code": "127483004", + "display": "Tissue specimen from fallopian tube" + }, + { + "code": "128154006", + "display": "Specimen from testis" + }, + { + "code": "128155007", + "display": "Specimen from ovary" + }, + { + "code": "128156008", + "display": "Tissue specimen from anus" + }, + { + "code": "128157004", + "display": "Tissue specimen from brain" + }, + { + "code": "128158009", + "display": "Tissue specimen from bronchus" + }, + { + "code": "128159001", + "display": "Tissue specimen from colon" + }, + { + "code": "128160006", + "display": "Tissue specimen from conjunctiva" + }, + { + "code": "128161005", + "display": "Tissue specimen from cornea" + }, + { + "code": "128162003", + "display": "Tissue specimen from ear" + }, + { + "code": "128163008", + "display": "Tissue specimen from endometrium" + }, + { + "code": "128164002", + "display": "Tissue specimen from eye" + }, + { + "code": "128165001", + "display": "Tissue specimen from genital system" + }, + { + "code": "128166000", + "display": "Tissue specimen from heart" + }, + { + "code": "128167009", + "display": "Tissue specimen from internal nose" + }, + { + "code": "128168004", + "display": "Tissue specimen from liver" + }, + { + "code": "128169007", + "display": "Tissue specimen from penis" + }, + { + "code": "128170008", + "display": "Tissue specimen from prostate" + }, + { + "code": "128171007", + "display": "Tissue specimen from stomach" + }, + { + "code": "128172000", + "display": "Tissue specimen from throat" + }, + { + "code": "128173005", + "display": "Tissue specimen from trachea" + }, + { + "code": "128174004", + "display": "Tissue specimen from urethra" + }, + { + "code": "128175003", + "display": "Tissue specimen from vagina" + }, + { + "code": "167867009", + "display": "Multiple joint synovial fluid" + }, + { + "code": "167868004", + "display": "Shoulder joint synovial fluid" + }, + { + "code": "167869007", + "display": "Elbow joint synovial fluid" + }, + { + "code": "167870008", + "display": "Wrist joint synovial fluid" + }, + { + "code": "167871007", + "display": "Hand joint synovial fluid" + }, + { + "code": "167872000", + "display": "Finger joint synovial fluid" + }, + { + "code": "167873005", + "display": "Hip joint synovial fluid" + }, + { + "code": "167874004", + "display": "Knee joint synovial fluid" + }, + { + "code": "167875003", + "display": "Ankle joint synovial fluid" + }, + { + "code": "167876002", + "display": "Foot joint synovial fluid" + }, + { + "code": "167877006", + "display": "Toe joint synovial fluid" + }, + { + "code": "167913002", + "display": "Bone marrow source" + }, + { + "code": "168136008", + "display": "Colostomy fluid sample" + }, + { + "code": "168137004", + "display": "Gastric aspirate sample" + }, + { + "code": "168138009", + "display": "Gastric lavage aspirate sample" + }, + { + "code": "168139001", + "display": "Peritoneal fluid sample" + }, + { + "code": "168140004", + "display": "Peritoneal dialysis sample" + }, + { + "code": "168141000", + "display": "Nasal fluid sample" + }, + { + "code": "168145009", + "display": "Lymph sample" + }, + { + "code": "256889002", + "display": "Breast cyst fluid sample" + }, + { + "code": "256912003", + "display": "Red blood cell fluid sample" + }, + { + "code": "257261003", + "display": "Swab" + }, + { + "code": "258407001", + "display": "Abscess tissue" + }, + { + "code": "258411007", + "display": "Nasopharyngeal aspirate" + }, + { + "code": "258412000", + "display": "Oropharyngeal aspirate" + }, + { + "code": "258414004", + "display": "Adipose tissue sample" + }, + { + "code": "258415003", + "display": "Biopsy sample" + }, + { + "code": "258417006", + "display": "Bone tissue sample" + }, + { + "code": "258418001", + "display": "Burn tissue" + }, + { + "code": "258419009", + "display": "Curettings" + }, + { + "code": "258420003", + "display": "Cyst tissue" + }, + { + "code": "258421004", + "display": "Embryo biopsy sample" + }, + { + "code": "258422006", + "display": "Gonad tissue" + }, + { + "code": "258423001", + "display": "Hair bulb sample" + }, + { + "code": "258424007", + "display": "Heart valve tissue" + }, + { + "code": "258425008", + "display": "Natural lens tissue" + }, + { + "code": "258426009", + "display": "Placental membrane tissue sample" + }, + { + "code": "258428005", + "display": "Products of conception tissue sample" + }, + { + "code": "258429002", + "display": "Rectal scrape sample" + }, + { + "code": "258430007", + "display": "Rectal snip sample" + }, + { + "code": "258431006", + "display": "Scrapings" + }, + { + "code": "258432004", + "display": "Sebum sample" + }, + { + "code": "258433009", + "display": "Smear sample" + }, + { + "code": "258434003", + "display": "Spun urinary sediment" + }, + { + "code": "258435002", + "display": "Tumour tissue" + }, + { + "code": "258436001", + "display": "Umbilical cord tissue" + }, + { + "code": "258437005", + "display": "Vegetation from heart valve" + }, + { + "code": "258438000", + "display": "Vitreous humor sample" + }, + { + "code": "258439008", + "display": "Discharge" + }, + { + "code": "258440005", + "display": "Effusion sample" + }, + { + "code": "258441009", + "display": "Exudate sample" + }, + { + "code": "258442002", + "display": "Fluid sample" + }, + { + "code": "258444001", + "display": "Aqueous humour sample" + }, + { + "code": "258446004", + "display": "Bronchial fluid sample" + }, + { + "code": "258448003", + "display": "Bursa fluid sample" + }, + { + "code": "258450006", + "display": "Cerebrospinal fluid sample" + }, + { + "code": "258452003", + "display": "Chylous fluid sample" + }, + { + "code": "258453008", + "display": "Cyst fluid sample" + }, + { + "code": "258454002", + "display": "Dialysate sample" + }, + { + "code": "258455001", + "display": "Drainage fluid sample" + }, + { + "code": "258456000", + "display": "Empyema fluid sample" + }, + { + "code": "258457009", + "display": "Faecal fluid sample" + }, + { + "code": "258458004", + "display": "Fistula fluid sample" + }, + { + "code": "258459007", + "display": "Gastric fluid sample" + }, + { + "code": "258461003", + "display": "Hydrocele fluid sample" + }, + { + "code": "258462005", + "display": "Ileostomy fluid sample" + }, + { + "code": "258463000", + "display": "Jejunal fluid sample" + }, + { + "code": "258465007", + "display": "Lacrimal fluid sample" + }, + { + "code": "258466008", + "display": "Middle ear fluid sample" + }, + { + "code": "258467004", + "display": "Nasopharyngeal washings" + }, + { + "code": "258468009", + "display": "Oedema fluid sample" + }, + { + "code": "258469001", + "display": "Pharyngeal washings" + }, + { + "code": "258470000", + "display": "Prostatic fluid sample" + }, + { + "code": "258471001", + "display": "Prostatic massage fluid sample" + }, + { + "code": "258472008", + "display": "Renal pelvis fluid sample" + }, + { + "code": "258474009", + "display": "Sinus fluid sample" + }, + { + "code": "258475005", + "display": "Sinus washings" + }, + { + "code": "258476006", + "display": "Subretinal fluid sample" + }, + { + "code": "258479004", + "display": "Tissue fluid sample" + }, + { + "code": "258480001", + "display": "Transtracheal aspirate sample" + }, + { + "code": "258481002", + "display": "Vaginal washout fluid sample" + }, + { + "code": "258482009", + "display": "Vesicle fluid sample" + }, + { + "code": "258483004", + "display": "Mucus sample" + }, + { + "code": "258484005", + "display": "Postmortem tissue sample" + }, + { + "code": "258485006", + "display": "Corneal scrapings" + }, + { + "code": "258487003", + "display": "Faecal smear" + }, + { + "code": "258488008", + "display": "Lymph node smear" + }, + { + "code": "258489000", + "display": "Slit skin smear" + }, + { + "code": "258490009", + "display": "Biliary stone sample" + }, + { + "code": "258492001", + "display": "Gallstone sample" + }, + { + "code": "258493006", + "display": "Bladder stone sample" + }, + { + "code": "258494000", + "display": "Pancreatic stone sample" + }, + { + "code": "258495004", + "display": "Renal stone sample" + }, + { + "code": "258496003", + "display": "Ureteric stone sample" + }, + { + "code": "258497007", + "display": "Abscess swab" + }, + { + "code": "258498002", + "display": "Conjunctival swab" + }, + { + "code": "258499005", + "display": "Cough swab" + }, + { + "code": "258500001", + "display": "Nasopharyngeal swab" + }, + { + "code": "258502009", + "display": "Pus swab" + }, + { + "code": "258503004", + "display": "Skin swab" + }, + { + "code": "258504005", + "display": "BCG site swab" + }, + { + "code": "258505006", + "display": "Skin ulcer swab" + }, + { + "code": "258506007", + "display": "Swab of drain insertion site" + }, + { + "code": "258507003", + "display": "Swab of line insertion site" + }, + { + "code": "258508008", + "display": "Genital swab" + }, + { + "code": "258509000", + "display": "Male genital swab" + }, + { + "code": "258510005", + "display": "Penis swab" + }, + { + "code": "258511009", + "display": "Penile urethral swab" + }, + { + "code": "258512002", + "display": "Glans penis swab" + }, + { + "code": "258513007", + "display": "Prepuce swab" + }, + { + "code": "258514001", + "display": "Subpreputial swab" + }, + { + "code": "258515000", + "display": "Coronal sulcus of penis swab" + }, + { + "code": "258516004", + "display": "Frenulum of penis swab" + }, + { + "code": "258517008", + "display": "Shaft of penis swab" + }, + { + "code": "258518003", + "display": "Scrotal swab" + }, + { + "code": "258519006", + "display": "Female genital swab" + }, + { + "code": "258520000", + "display": "Vaginal swab" + }, + { + "code": "258521001", + "display": "HVS - High vaginal swab" + }, + { + "code": "258522008", + "display": "Low vaginal swab" + }, + { + "code": "258523003", + "display": "Vulval swab" + }, + { + "code": "258524009", + "display": "Cervical swab" + }, + { + "code": "258525005", + "display": "Perineal swab" + }, + { + "code": "258526006", + "display": "Perianal swab" + }, + { + "code": "258527002", + "display": "Anal swab" + }, + { + "code": "258528007", + "display": "Rectal swab" + }, + { + "code": "258529004", + "display": "TS - Throat swab" + }, + { + "code": "258530009", + "display": "Urethral swab" + }, + { + "code": "258531008", + "display": "Wound swab" + }, + { + "code": "258532001", + "display": "Swab of inanimate object" + }, + { + "code": "258535004", + "display": "Floor swab" + }, + { + "code": "258536003", + "display": "Incubator swab" + }, + { + "code": "258537007", + "display": "Surface swab" + }, + { + "code": "258538002", + "display": "Transudate sample" + }, + { + "code": "258539005", + "display": "Bone and joint sample" + }, + { + "code": "258541006", + "display": "Cardiovascular sample" + }, + { + "code": "258542004", + "display": "Heart valve sample" + }, + { + "code": "258544003", + "display": "Natural heart valve sample" + }, + { + "code": "258545002", + "display": "Vegetation from prosthetic heart valve" + }, + { + "code": "258546001", + "display": "Vegetation from natural heart valve" + }, + { + "code": "258547005", + "display": "Cardiopulmonary bypass pump fluid sample" + }, + { + "code": "258548000", + "display": "Dermatological sample" + }, + { + "code": "258549008", + "display": "Skin scale sample" + }, + { + "code": "258553005", + "display": "Duodenal string" + }, + { + "code": "258554004", + "display": "Faecal concretion sample" + }, + { + "code": "258555003", + "display": "Hot stool sample" + }, + { + "code": "258558001", + "display": "Oral secretion sample" + }, + { + "code": "258559009", + "display": "Gingivocrevicular fluid sample" + }, + { + "code": "258560004", + "display": "Oral saliva sample" + }, + { + "code": "258561000", + "display": "Parotid gland saliva sample" + }, + { + "code": "258562007", + "display": "Genetic sample" + }, + { + "code": "258563002", + "display": "Amniotic cell sample" + }, + { + "code": "258564008", + "display": "Buccal smear sample" + }, + { + "code": "258565009", + "display": "Chorionic villi sample" + }, + { + "code": "258566005", + "display": "Deoxyribonucleic acid sample" + }, + { + "code": "258567001", + "display": "Gonad sample" + }, + { + "code": "258568006", + "display": "Polar body sample" + }, + { + "code": "258569003", + "display": "Skin fibroblast sample" + }, + { + "code": "258570002", + "display": "Genitourinary sample" + }, + { + "code": "258571003", + "display": "Machine hemodialysate sample" + }, + { + "code": "258572005", + "display": "Ultrafiltrate sample" + }, + { + "code": "258574006", + "display": "Mid-stream urine sample" + }, + { + "code": "258575007", + "display": "EMU-Early morning urine sample" + }, + { + "code": "258576008", + "display": "Suprapubic aspirate sample" + }, + { + "code": "258577004", + "display": "Vaginal secretion sample" + }, + { + "code": "258580003", + "display": "Whole blood sample" + }, + { + "code": "258581004", + "display": "Clotted blood sample" + }, + { + "code": "258582006", + "display": "Blood clot sample" + }, + { + "code": "258583001", + "display": "Bone marrow clot sample" + }, + { + "code": "258584007", + "display": "Bone marrow fragment sample" + }, + { + "code": "258585008", + "display": "Bone marrow trephine sample" + }, + { + "code": "258587000", + "display": "Buffy coat" + }, + { + "code": "258588005", + "display": "Hematoma sample" + }, + { + "code": "258589002", + "display": "Lymph node sample" + }, + { + "code": "258590006", + "display": "Acidified serum sample" + }, + { + "code": "258591005", + "display": "White blood cell sample" + }, + { + "code": "258599007", + "display": "Contact lens solution sample" + }, + { + "code": "258601009", + "display": "Lens sample" + }, + { + "code": "258602002", + "display": "Intraocular lens sample" + }, + { + "code": "258603007", + "display": "Respiratory sample" + }, + { + "code": "258604001", + "display": "Upper respiratory sample" + }, + { + "code": "258606004", + "display": "Lower respiratory sample" + }, + { + "code": "258607008", + "display": "Bronchoalveolar lavage fluid sample" + }, + { + "code": "258608003", + "display": "Sputum specimen obtained by aspiration (specimen)" + }, + { + "code": "258609006", + "display": "Sputum specimen obtained by aspiration from trachea (specimen)" + }, + { + "code": "258610001", + "display": "Sputum specimen obtained by sputum induction (specimen)" + }, + { + "code": "258611002", + "display": "Sputum specimen obtained from sputum suction trap (specimen)" + }, + { + "code": "258613004", + "display": "Living sample" + }, + { + "code": "258614005", + "display": "Insect sample" + }, + { + "code": "258615006", + "display": "Larva sample" + }, + { + "code": "258616007", + "display": "Maggot sample" + }, + { + "code": "258617003", + "display": "Parasite sample" + }, + { + "code": "258618008", + "display": "Helminth sample" + }, + { + "code": "258627009", + "display": "Cannula tip submitted as specimen (specimen)" + }, + { + "code": "258628004", + "display": "Vascular cannula tip submitted as specimen" + }, + { + "code": "258629007", + "display": "Arterial cannula tip submitted as specimen (specimen)" + }, + { + "code": "258630002", + "display": "Venous cannula tip submitted as specimen (specimen)" + }, + { + "code": "258631003", + "display": "Arteriovenous shunt tip submitted as specimen (specimen)" + }, + { + "code": "258649003", + "display": "Intravenous infusion fluid sample" + }, + { + "code": "258650003", + "display": "Intravenous lipid infusion fluid sample" + }, + { + "code": "258651004", + "display": "Cream sample" + }, + { + "code": "258652006", + "display": "Ice-cream sample" + }, + { + "code": "258653001", + "display": "Formula milk sample" + }, + { + "code": "258654007", + "display": "Soya milk sample" + }, + { + "code": "258655008", + "display": "Cow's milk sample" + }, + { + "code": "258656009", + "display": "Whole milk sample" + }, + { + "code": "258657000", + "display": "Semi-skimmed milk sample" + }, + { + "code": "258658005", + "display": "Skimmed milk sample" + }, + { + "code": "258659002", + "display": "Sheep's milk sample" + }, + { + "code": "258660007", + "display": "Goat's milk sample" + }, + { + "code": "258662004", + "display": "Adhesive slide specimen (specimen)" + }, + { + "code": "258663009", + "display": "Sellotape slide specimen" + }, + { + "code": "258664003", + "display": "Scotch tape slide specimen" + }, + { + "code": "264380007", + "display": "Synovial fluid cells" + }, + { + "code": "271514008", + "display": "Sternal bone marrow sample" + }, + { + "code": "271515009", + "display": "Iliac crest bone marrow sample" + }, + { + "code": "271516005", + "display": "Vertebral spinous process bone marrow sample" + }, + { + "code": "271518006", + "display": "Rib bone marrow sample" + }, + { + "code": "276446009", + "display": "Cervical smear sample" + }, + { + "code": "276833005", + "display": "24 hour urine sample" + }, + { + "code": "278020009", + "display": "Spot urine sample" + }, + { + "code": "302794003", + "display": "Nasogastric aspirate" + }, + { + "code": "302795002", + "display": "Lymph node aspirate" + }, + { + "code": "303247002", + "display": "Adrenal tissue" + }, + { + "code": "303248007", + "display": "Blood film sample" + }, + { + "code": "309048008", + "display": "Endocrine sample" + }, + { + "code": "309049000", + "display": "Lesion sample" + }, + { + "code": "309050000", + "display": "Body substance sample" + }, + { + "code": "309051001", + "display": "Body fluid sample" + }, + { + "code": "309052008", + "display": "Male genital sample" + }, + { + "code": "309053003", + "display": "Female genital sample" + }, + { + "code": "309055005", + "display": "Breast fluid sample" + }, + { + "code": "309057002", + "display": "Breast direct smear sample" + }, + { + "code": "309058007", + "display": "Breast tru-cut biopsy sample" + }, + { + "code": "309059004", + "display": "Frozen section breast sample" + }, + { + "code": "309061008", + "display": "Breast fine needle aspirate sample" + }, + { + "code": "309066003", + "display": "Skin biopsy sample" + }, + { + "code": "309067007", + "display": "Skin curettings sample" + }, + { + "code": "309068002", + "display": "Skin lesion sample" + }, + { + "code": "309070006", + "display": "Vulval skin biopsy sample" + }, + { + "code": "309071005", + "display": "Penis skin biopsy sample" + }, + { + "code": "309072003", + "display": "Soft tissue sample" + }, + { + "code": "309073008", + "display": "Lipoma biopsy sample" + }, + { + "code": "309074002", + "display": "Soft tissue biopsy sample" + }, + { + "code": "309075001", + "display": "Skin cyst sample" + }, + { + "code": "309077009", + "display": "Spleen resection sample" + }, + { + "code": "309078004", + "display": "Lymph node tissue sample" + }, + { + "code": "309079007", + "display": "Lymph node biopsy sample" + }, + { + "code": "309101008", + "display": "Cartilage sample" + }, + { + "code": "309102001", + "display": "Cartilage biopsy sample" + }, + { + "code": "309103006", + "display": "Excised cartilage sample" + }, + { + "code": "309104000", + "display": "Musculoskeletal sample" + }, + { + "code": "309105004", + "display": "Bone biopsy sample" + }, + { + "code": "309107007", + "display": "Tendon sample" + }, + { + "code": "309108002", + "display": "Excised tendon sample" + }, + { + "code": "309109005", + "display": "Bursa sample" + }, + { + "code": "309110000", + "display": "Bursa tissue sample" + }, + { + "code": "309111001", + "display": "Bursa biopsy sample" + }, + { + "code": "309112008", + "display": "Excised bursa sample" + }, + { + "code": "309113003", + "display": "Tendon biopsy sample" + }, + { + "code": "309114009", + "display": "Ligament sample" + }, + { + "code": "309115005", + "display": "Ligament biopsy sample" + }, + { + "code": "309116006", + "display": "Excised ligament sample" + }, + { + "code": "309117002", + "display": "Fascia sample" + }, + { + "code": "309118007", + "display": "Fascia biopsy sample" + }, + { + "code": "309119004", + "display": "Excised fascia sample" + }, + { + "code": "309120005", + "display": "Head of femur sample" + }, + { + "code": "309121009", + "display": "Synovial tissue sample" + }, + { + "code": "309122002", + "display": "Synovium biopsy sample" + }, + { + "code": "309123007", + "display": "Synovial sample" + }, + { + "code": "309124001", + "display": "Joint biopsy sample" + }, + { + "code": "309125000", + "display": "Joint sample" + }, + { + "code": "309126004", + "display": "Articular tissue sample" + }, + { + "code": "309127008", + "display": "Resected articular tissue sample" + }, + { + "code": "309128003", + "display": "Eye fluid sample" + }, + { + "code": "309129006", + "display": "Nerve tissue sample" + }, + { + "code": "309130001", + "display": "Nerve biopsy sample" + }, + { + "code": "309131002", + "display": "Neuroma sample" + }, + { + "code": "309132009", + "display": "Prostate biopsy sample" + }, + { + "code": "309133004", + "display": "Resected prostate sample" + }, + { + "code": "309134005", + "display": "Prostate tru-cut biopsy sample" + }, + { + "code": "309135006", + "display": "Hydrocele sample" + }, + { + "code": "309137003", + "display": "Testes biopsy sample" + }, + { + "code": "309138008", + "display": "Orchidectomy sample" + }, + { + "code": "309139000", + "display": "Vas deferens sample" + }, + { + "code": "309140003", + "display": "Epididymis sample" + }, + { + "code": "309141004", + "display": "Adrenal gland sample" + }, + { + "code": "309142006", + "display": "Adrenal biopsy sample" + }, + { + "code": "309143001", + "display": "Excised adrenal gland sample" + }, + { + "code": "309144007", + "display": "Thyroid lobe sample" + }, + { + "code": "309145008", + "display": "Thyroid fluid sample" + }, + { + "code": "309146009", + "display": "Thyroid fine needle aspirate sample" + }, + { + "code": "309147000", + "display": "Thyroid cyst fluid sample" + }, + { + "code": "309148005", + "display": "Thyroid direct smear sample" + }, + { + "code": "309149002", + "display": "Parathyroid sample" + }, + { + "code": "309150002", + "display": "Parathyroid tissue sample" + }, + { + "code": "309151003", + "display": "Parathyroid biopsy sample" + }, + { + "code": "309153000", + "display": "Excised parathyroid sample" + }, + { + "code": "309154006", + "display": "Pituitary sample" + }, + { + "code": "309164002", + "display": "Upper respiratory swab sample" + }, + { + "code": "309165001", + "display": "Ear sample" + }, + { + "code": "309166000", + "display": "Ear swab sample" + }, + { + "code": "309167009", + "display": "Middle ear biopsy sample" + }, + { + "code": "309168004", + "display": "Upper respiratory tissue sample" + }, + { + "code": "309169007", + "display": "Tracheal biopsy sample" + }, + { + "code": "309170008", + "display": "Lower respiratory tissue sample" + }, + { + "code": "309171007", + "display": "Lower respiratory fluid sample" + }, + { + "code": "309172000", + "display": "Pleura biopsy sample" + }, + { + "code": "309173005", + "display": "Transbronchial lung biopsy sample" + }, + { + "code": "309174004", + "display": "Bronchial biopsy sample" + }, + { + "code": "309175003", + "display": "Resected lung sample" + }, + { + "code": "309176002", + "display": "Bronchial brushings sample" + }, + { + "code": "309177006", + "display": "Lung direct smear sample" + }, + { + "code": "309178001", + "display": "Nasal biopsy sample" + }, + { + "code": "309179009", + "display": "Nasal polyp sample" + }, + { + "code": "309180007", + "display": "Nasopharyngeal biopsy sample" + }, + { + "code": "309181006", + "display": "Mastoid biopsy sample" + }, + { + "code": "309182004", + "display": "Larynx biopsy sample" + }, + { + "code": "309183009", + "display": "Laryngectomy sample" + }, + { + "code": "309184003", + "display": "Vocal cord biopsy sample" + }, + { + "code": "309185002", + "display": "Oral cavity sample" + }, + { + "code": "309186001", + "display": "Oral tissue sample" + }, + { + "code": "309187005", + "display": "Dental tissue sample" + }, + { + "code": "309188000", + "display": "Mouth biopsy sample" + }, + { + "code": "309189008", + "display": "Tongue biopsy sample" + }, + { + "code": "309190004", + "display": "Excised salivary gland sample" + }, + { + "code": "309191000", + "display": "Tonsil biopsy sample" + }, + { + "code": "309192007", + "display": "Tonsillectomy sample" + }, + { + "code": "309193002", + "display": "Pharyngeal biopsy sample" + }, + { + "code": "309199003", + "display": "Gastrointestinal fluid sample" + }, + { + "code": "309200000", + "display": "Rectal tissue sample" + }, + { + "code": "309201001", + "display": "Ascitic fluid sample" + }, + { + "code": "309202008", + "display": "Gastrointestinal direct smear" + }, + { + "code": "309203003", + "display": "Liver biopsy sample" + }, + { + "code": "309204009", + "display": "Liver direct smear sample" + }, + { + "code": "309205005", + "display": "Cholecystectomy sample" + }, + { + "code": "309206006", + "display": "Pancreas biopsy sample" + }, + { + "code": "309207002", + "display": "Peritoneal biopsy sample" + }, + { + "code": "309208007", + "display": "Omentum biopsy sample" + }, + { + "code": "309209004", + "display": "Esophageal biopsy sample" + }, + { + "code": "309210009", + "display": "Oesophageal brushings sample" + }, + { + "code": "309211008", + "display": "Gastric biopsy sample" + }, + { + "code": "309212001", + "display": "Gastric antral biopsy sample" + }, + { + "code": "309213006", + "display": "Gastric brushings sample" + }, + { + "code": "309214000", + "display": "Gastric fundus biopsy sample" + }, + { + "code": "309215004", + "display": "Gastric ulcer sample" + }, + { + "code": "309216003", + "display": "Duodenal biopsy sample" + }, + { + "code": "309217007", + "display": "Ileal biopsy sample" + }, + { + "code": "309218002", + "display": "Ileal resection sample" + }, + { + "code": "309219005", + "display": "Jejunal biopsy sample" + }, + { + "code": "309220004", + "display": "Small bowel resection sample" + }, + { + "code": "309221000", + "display": "Terminal ileum resection sample" + }, + { + "code": "309222007", + "display": "Appendix sample" + }, + { + "code": "309223002", + "display": "Colectomy sample" + }, + { + "code": "309224008", + "display": "Colon strip sample" + }, + { + "code": "309225009", + "display": "Colonic biopsy sample" + }, + { + "code": "309226005", + "display": "Colonic polyp sample" + }, + { + "code": "309227001", + "display": "Sigmoid colonic polyp sample" + }, + { + "code": "309260003", + "display": "Sigmoid colon biopsy sample" + }, + { + "code": "309261004", + "display": "Sigmoid colon brushings sample" + }, + { + "code": "309262006", + "display": "Rectal biopsy sample" + }, + { + "code": "309263001", + "display": "Rectal polyp sample" + }, + { + "code": "309264007", + "display": "Excised rectum sample" + }, + { + "code": "309265008", + "display": "Anal biopsy sample" + }, + { + "code": "309266009", + "display": "Anal polyp sample" + }, + { + "code": "309267000", + "display": "Anal resection sample" + }, + { + "code": "309268005", + "display": "Urological fluid sample" + }, + { + "code": "309269002", + "display": "Kidney biopsy sample" + }, + { + "code": "309270001", + "display": "Nephrectomy sample" + }, + { + "code": "309271002", + "display": "Ureter biopsy sample" + }, + { + "code": "309272009", + "display": "Urinary bladder tissue sample" + }, + { + "code": "309273004", + "display": "Bladder biopsy sample" + }, + { + "code": "309274005", + "display": "Bladder curettings sample" + }, + { + "code": "309275006", + "display": "Cystectomy sample" + }, + { + "code": "309276007", + "display": "Frozen section bladder sample" + }, + { + "code": "309277003", + "display": "Urethra biopsy sample" + }, + { + "code": "309278008", + "display": "Female genital tissue sample" + }, + { + "code": "309280002", + "display": "Vaginal biopsy sample" + }, + { + "code": "309281003", + "display": "Vaginal vault biopsy sample" + }, + { + "code": "309283000", + "display": "Cervical biopsy sample" + }, + { + "code": "309285007", + "display": "Cervical loop excision sample" + }, + { + "code": "309286008", + "display": "Cervical polyp sample" + }, + { + "code": "309287004", + "display": "Excised uterus, fallopian tubes and ovaries sample" + }, + { + "code": "309288009", + "display": "Endometrial polyp sample" + }, + { + "code": "309289001", + "display": "Endometrial resection sample" + }, + { + "code": "309290005", + "display": "Fallopian tube biopsy sample" + }, + { + "code": "309291009", + "display": "Ovarian cyst sample" + }, + { + "code": "309292002", + "display": "Ovarian fluid sample" + }, + { + "code": "309293007", + "display": "Placenta biopsy sample" + }, + { + "code": "309476009", + "display": "Neck block dissection sample" + }, + { + "code": "309478005", + "display": "Thrombus sample" + }, + { + "code": "309479002", + "display": "Artery sample" + }, + { + "code": "309480004", + "display": "Vein sample" + }, + { + "code": "309481000", + "display": "Temporal artery sample" + }, + { + "code": "309482007", + "display": "Frozen section lymph node sample" + }, + { + "code": "309483002", + "display": "Lip biopsy sample" + }, + { + "code": "309484008", + "display": "Parotidectomy sample" + }, + { + "code": "309485009", + "display": "Excised sublingual gland sample" + }, + { + "code": "309486005", + "display": "Excised submandibular gland sample" + }, + { + "code": "309487001", + "display": "Total colectomy sample" + }, + { + "code": "309488006", + "display": "Partial colectomy sample" + }, + { + "code": "309489003", + "display": "Anterior resection of rectum sample" + }, + { + "code": "309490007", + "display": "Pancreatectomy sample" + }, + { + "code": "309491006", + "display": "Biliary tract tissue sample" + }, + { + "code": "309493009", + "display": "Bile duct biopsy sample" + }, + { + "code": "309494003", + "display": "Ampulla of Vater biopsy sample" + }, + { + "code": "309495002", + "display": "Omentum tissue sample" + }, + { + "code": "309496001", + "display": "Omentectomy sample" + }, + { + "code": "309497005", + "display": "Total nephrectomy sample" + }, + { + "code": "309498000", + "display": "Partial nephrectomy sample" + }, + { + "code": "309499008", + "display": "Foreskin biopsy sample" + }, + { + "code": "309501000", + "display": "Excised uterus sample" + }, + { + "code": "309502007", + "display": "Fetus specimen" + }, + { + "code": "309503002", + "display": "Breast nipple discharge sample" + }, + { + "code": "309504008", + "display": "Skin punch biopsy sample" + }, + { + "code": "309505009", + "display": "Skin incision biopsy sample" + }, + { + "code": "309506005", + "display": "Skin excision biopsy sample" + }, + { + "code": "309507001", + "display": "Muscle biopsy sample" + }, + { + "code": "309508006", + "display": "Soft tissue lesion fine needle aspirate sample" + }, + { + "code": "309546004", + "display": "Lumpectomy breast sample" + }, + { + "code": "309547008", + "display": "Segmentectomy breast sample" + }, + { + "code": "309548003", + "display": "Breast duct sample" + }, + { + "code": "309549006", + "display": "Minor salivary gland sample" + }, + { + "code": "312494007", + "display": "Vaginal vault smear sample" + }, + { + "code": "363311008", + "display": "Specimen from digestive system" + }, + { + "code": "363328006", + "display": "Tissue specimen from digestive system" + }, + { + "code": "363329003", + "display": "Tissue specimen from respiratory system" + }, + { + "code": "369611008", + "display": "Tissue specimen obtained from small intestine by biopsy" + }, + { + "code": "369613006", + "display": "Tissue specimen obtained for Hodgkin's disease by biopsy" + }, + { + "code": "369614000", + "display": "Tissue specimen obtained from extrahepatic bile ducts by biopsy" + }, + { + "code": "369615004", + "display": "Tissue specimen obtained from extrahepatic bile ducts by choledochal cyst resection" + }, + { + "code": "369616003", + "display": "Tissue specimen obtained from gallbladder by biopsy" + }, + { + "code": "369617007", + "display": "Tissue specimen obtained from gallbladder by cholecystectomy with partial hepatectomy" + }, + { + "code": "369618002", + "display": "Tissue specimen obtained from vulva by biopsy (specimen)" + }, + { + "code": "370108001", + "display": "Extrahepatic bile duct cytologic material" + }, + { + "code": "371780008", + "display": "Specimen for identification (specimen)" + }, + { + "code": "371782000", + "display": "Human bone for identification (specimen)" + }, + { + "code": "371783005", + "display": "Human tissue for identification (specimen)" + }, + { + "code": "371784004", + "display": "Body parts for identification (specimen)" + }, + { + "code": "373101006", + "display": "Breast cytologic material obtained by percutaneous core biopsy (specimen)" + }, + { + "code": "373102004", + "display": "Breast tissue obtained by image guided core biopsy" + }, + { + "code": "373103009", + "display": "Breast cytologic material obtained by incisional biopsy (specimen)" + }, + { + "code": "373192005", + "display": "Lymph node from axillary dissection (specimen)" + }, + { + "code": "373193000", + "display": "Lymph node from sentinel lymph node dissection (specimen)" + }, + { + "code": "373826004", + "display": "Surgical excision sample" + }, + { + "code": "384744003", + "display": "Lymph node from sentinel lymph node dissection and axillary dissection (specimen)" + }, + { + "code": "384746001", + "display": "Specimen from lung obtained by wedge biopsy (specimen)" + }, + { + "code": "384747005", + "display": "Specimen from lung obtained by CT guided needle biopsy" + }, + { + "code": "384819001", + "display": "Specimen from prostate obtained by needle biopsy (specimen)" + }, + { + "code": "384820007", + "display": "Specimen from prostate obtained by transurethral resection (specimen)" + }, + { + "code": "385338007", + "display": "Specimen from anus obtained by transanal disk excision (specimen)" + }, + { + "code": "385339004", + "display": "Specimen from anus obtained by transanal disk excision, intact (specimen)" + }, + { + "code": "385340002", + "display": "Specimen from anus obtained by transanal disk excision, fragmented (specimen)" + }, + { + "code": "396273004", + "display": "Specimen from uterine cervix obtained by excision of cervix (specimen)" + }, + { + "code": "396353007", + "display": "Specimen from skin obtained by elliptical excision (specimen)" + }, + { + "code": "396354001", + "display": "Specimen from skin obtained by wide excision (specimen)" + }, + { + "code": "396355000", + "display": "Specimen from skin obtained by excision (specimen)" + }, + { + "code": "396356004", + "display": "Specimen from skin obtained by re-excision (specimen)" + }, + { + "code": "396357008", + "display": "Specimen from skin obtained by elliptical re-excision (specimen)" + }, + { + "code": "396358003", + "display": "Specimen from skin obtained by wide re-excision (specimen)" + }, + { + "code": "396359006", + "display": "Lymph node from regional lymph node dissection (specimen)" + }, + { + "code": "396476009", + "display": "Specimen from liver obtained by right lobectomy (specimen)" + }, + { + "code": "396477000", + "display": "Specimen from liver obtained by extended right lobectomy (specimen)" + }, + { + "code": "396478005", + "display": "Specimen from liver obtained by medial segmentectomy (specimen)" + }, + { + "code": "396479002", + "display": "Specimen from liver obtained by left lateral segmentectomy (specimen)" + }, + { + "code": "396480004", + "display": "Specimen from liver obtained by total left lobectomy (specimen)" + }, + { + "code": "396481000", + "display": "Specimen from explanted liver (specimen)" + }, + { + "code": "396483002", + "display": "Specimen from skin obtained by shave excision (specimen)" + }, + { + "code": "396525008", + "display": "Specimen from adrenal gland obtained by needle biopsy (specimen)" + }, + { + "code": "396526009", + "display": "Specimen from adrenal gland obtained by partial adrenalectomy (specimen)" + }, + { + "code": "396527000", + "display": "Specimen from adrenal gland obtained by total adrenalectomy (specimen)" + }, + { + "code": "396685001", + "display": "Specimen from urinary bladder obtained by radical cystectomy (specimen)" + }, + { + "code": "396804002", + "display": "Specimen from pancreas obtained by pylorus sparing pancreaticoduodenectomy, partial pancreatectomy (specimen)" + }, + { + "code": "396805001", + "display": "Specimen from pancreas obtained by pylorus sparing pancreaticoduodenectomy, total pancreatectomy (specimen)" + }, + { + "code": "396806000", + "display": "Specimen from pancreas obtained by pancreaticoduodenectomy, partial pancreatectomy (specimen)" + }, + { + "code": "396807009", + "display": "Specimen from pancreas obtained by pancreaticoduodenectomy, total pancreatectomy (specimen)" + }, + { + "code": "396896007", + "display": "Specimen from thymus gland (specimen)" + }, + { + "code": "396897003", + "display": "Specimen from thymus gland obtained by transcervical thymectomy (specimen)" + }, + { + "code": "396898008", + "display": "Specimen from thymus gland obtained by thoracotomy (specimen)" + }, + { + "code": "396899000", + "display": "Specimen from thymus gland obtained by fine needle aspiration biopsy (specimen)" + }, + { + "code": "396900005", + "display": "Specimen from thymus gland obtained by CT guided needle biopsy" + }, + { + "code": "396902002", + "display": "Specimen from thymus gland obtained by transthoracic needle biopsy (specimen)" + }, + { + "code": "396904001", + "display": "Specimen from thymus gland obtained by limited thoracotomy (specimen)" + }, + { + "code": "396906004", + "display": "Specimen from thymus gland obtained by video assisted thoracotomy (specimen)" + }, + { + "code": "396928004", + "display": "Specimen from eye obtained by enucleation (specimen)" + }, + { + "code": "396997002", + "display": "Specimen from bone marrow obtained by aspiration (specimen)" + }, + { + "code": "396998007", + "display": "Specimen from bone marrow obtained by aspiration and biopsy (specimen)" + }, + { + "code": "396999004", + "display": "Specimen from bone marrow obtained by biopsy (specimen)" + }, + { + "code": "397053005", + "display": "Specimen from small intestine obtained by polypectomy (specimen)" + }, + { + "code": "397055003", + "display": "Specimen from small intestine obtained by segmental resection (specimen)" + }, + { + "code": "397056002", + "display": "Specimen from small intestine obtained by Whipple procedure" + }, + { + "code": "397077004", + "display": "Specimen obtained by incisional biopsy (specimen)" + }, + { + "code": "397078009", + "display": "Specimen obtained by excisional biopsy (specimen)" + }, + { + "code": "397111007", + "display": "Specimen from vagina obtained by partial vaginectomy (specimen)" + }, + { + "code": "397129002", + "display": "Specimen from vulva (specimen)" + }, + { + "code": "397130007", + "display": "Specimen from vulva obtained by local excision (specimen)" + }, + { + "code": "397131006", + "display": "Specimen from vulva obtained by wide excision (specimen)" + }, + { + "code": "397132004", + "display": "Specimen from vulva obtained by partial vulvectomy (specimen)" + }, + { + "code": "397133009", + "display": "Specimen from vulva obtained by total vulvectomy (specimen)" + }, + { + "code": "397134003", + "display": "Specimen from vulva obtained by radical vulvectomy (specimen)" + }, + { + "code": "397135002", + "display": "Specimen from pelvic lymph node (specimen)" + }, + { + "code": "397136001", + "display": "Specimen from inguinofemoral lymphadenectomy (specimen)" + }, + { + "code": "397199005", + "display": "Specimen from breast obtained by excision (specimen)" + }, + { + "code": "397221008", + "display": "Specimen from renal pelvis obtained by biopsy (specimen)" + }, + { + "code": "397232008", + "display": "Specimen from renal pelvis obtained by nephroureterectomy (specimen)" + }, + { + "code": "397233003", + "display": "Specimen from renal pelvis (specimen)" + }, + { + "code": "397234009", + "display": "Specimen from renal pelvis obtained by partial nephroureterectomy (specimen)" + }, + { + "code": "397235005", + "display": "Specimen from renal pelvis obtained by complete nephroureterectomy (specimen)" + }, + { + "code": "397245007", + "display": "Specimen from ovary obtained by hysterectomy with right salpingo-oophorectomy (specimen)" + }, + { + "code": "397246008", + "display": "Specimen from ovary obtained by hysterectomy with left salpingo-oophorectomy (specimen)" + }, + { + "code": "397326000", + "display": "Specimen from right fallopian tube obtained by hysterectomy with salpingo-oophorectomy (specimen)" + }, + { + "code": "397333000", + "display": "Specimen from right fallopian tube obtained by salpingectomy (specimen)" + }, + { + "code": "397334006", + "display": "Specimen from left fallopian tube obtained by salpingectomy (specimen)" + }, + { + "code": "397436009", + "display": "Specimen obtained by lymphadenectomy (specimen)" + }, + { + "code": "397438005", + "display": "Specimen from lymph node obtained by staging laparotomy (specimen)" + }, + { + "code": "397455009", + "display": "Specimen from thoracic mesothelium obtained by percutaneous needle biopsy (specimen)" + }, + { + "code": "397456005", + "display": "Specimen from thoracic mesothelium obtained by thoracoscopic biopsy (specimen)" + }, + { + "code": "397457001", + "display": "Specimen from thoracic mesothelium (specimen)" + }, + { + "code": "397458006", + "display": "Specimen from thoracic mesothelium obtained by open thoracotomy (specimen)" + }, + { + "code": "397462000", + "display": "Specimen from pericardium obtained by pericardial resection (specimen)" + }, + { + "code": "397482001", + "display": "Specimen from extrahepatic bile duct obtained by pancreaticoduodenectomy (specimen)" + }, + { + "code": "397483006", + "display": "Specimen from extrahepatic bile duct obtained by segmental resection of bile ducts (specimen)" + }, + { + "code": "399388008", + "display": "Specimen from left fallopian tube obtained by hysterectomy with salpingo-oophorectomy (specimen)" + }, + { + "code": "399396003", + "display": "Trophoblastic tissue obtained from uterus by dilation and curettage (specimen)" + }, + { + "code": "399402006", + "display": "Specimen from ureter (specimen)" + }, + { + "code": "399407000", + "display": "Specimen from ureter obtained by ureterectomy (specimen)" + }, + { + "code": "399411006", + "display": "Specimen from trophoblast (specimen)" + }, + { + "code": "399436000", + "display": "Specimen from central nervous system (specimen)" + }, + { + "code": "399440009", + "display": "Specimen from ureter obtained by nephroureterectomy (specimen)" + }, + { + "code": "399443006", + "display": "Specimen from eye obtained by complete exenteration (specimen)" + }, + { + "code": "399447007", + "display": "Trophoblastic tissue obtained by radical hysterectomy (specimen)" + }, + { + "code": "399451009", + "display": "Tissue specimen from retina (specimen)" + }, + { + "code": "399460001", + "display": "Specimen from extrahepatic bile duct (specimen)" + }, + { + "code": "399467003", + "display": "Specimen from uvea obtained by limited exenteration of eye (specimen)" + }, + { + "code": "399484009", + "display": "Superficial parotidectomy sample" + }, + { + "code": "399486006", + "display": "Tissue specimen from vulva (specimen)" + }, + { + "code": "399492000", + "display": "Tissue specimen from lung (specimen)" + }, + { + "code": "399499009", + "display": "Specimen from uvea obtained by complete exenteration of eye (specimen)" + }, + { + "code": "399502008", + "display": "Trophoblastic tissue obtained by pelvic exenteration (specimen)" + }, + { + "code": "399512001", + "display": "Specimen from retina obtained by enucleation of eye (specimen)" + }, + { + "code": "399526005", + "display": "Specimen from major salivary gland (specimen)" + }, + { + "code": "399532000", + "display": "Tissue specimen from renal pelvis (specimen)" + }, + { + "code": "399541005", + "display": "Tissue specimen from extrahepatic bile duct (specimen)" + }, + { + "code": "399542003", + "display": "Tissue specimen from central nervous system (specimen)" + }, + { + "code": "399551006", + "display": "Specimen from central nervous system obtained by open biopsy (specimen)" + }, + { + "code": "399559008", + "display": "Specimen from uvea obtained by enucleation of eye (specimen)" + }, + { + "code": "399572009", + "display": "Tissue specimen from thymus gland (specimen)" + }, + { + "code": "399603006", + "display": "Specimen from retina obtained by complete exenteration of eye (specimen)" + }, + { + "code": "399614009", + "display": "Specimen from central nervous system obtained by total resection of tumor (specimen)" + }, + { + "code": "399619004", + "display": "Tissue specimen from uvea (specimen)" + }, + { + "code": "399622002", + "display": "Specimen from thyroid obtained by total thyroidectomy (specimen)" + }, + { + "code": "399624001", + "display": "Tissue specimen from ureter (specimen)" + }, + { + "code": "399629006", + "display": "Specimen from stomach obtained by gastrectomy (specimen)" + }, + { + "code": "399633004", + "display": "Specimen from thymus gland obtained by biopsy (specimen)" + }, + { + "code": "399640003", + "display": "Specimen from retina obtained by limited exenteration of eye (specimen)" + }, + { + "code": "399645008", + "display": "Tissue specimen from major salivary gland (specimen)" + }, + { + "code": "399649002", + "display": "Specimen from regional lymph node obtained by lymphadenectomy (specimen)" + }, + { + "code": "399657004", + "display": "Tissue specimen from trophoblast (specimen)" + }, + { + "code": "399658009", + "display": "Trophoblastic tissue obtained by hysterectomy (specimen)" + }, + { + "code": "399661005", + "display": "Specimen from pelvic lymphadenectomy (specimen)" + }, + { + "code": "399672000", + "display": "Tissue specimen from thoracic mesothelium (specimen)" + }, + { + "code": "399680007", + "display": "Specimen from thyroid (specimen)" + }, + { + "code": "399689008", + "display": "Specimen from thyroid obtained by thyroidectomy (specimen)" + }, + { + "code": "399693002", + "display": "Total parotidectomy sample" + }, + { + "code": "399713008", + "display": "Specimen from uterine cervix obtained by cone biopsy (specimen)" + }, + { + "code": "399728008", + "display": "Specimen from central nervous system obtained by stereotactically guided core needle biopsy (specimen)" + }, + { + "code": "399731009", + "display": "Specimen from anus obtained by excision of anal polyp (specimen)" + }, + { + "code": "399732002", + "display": "Specimen from central nervous system obtained by partial excision of tumor (specimen)" + }, + { + "code": "399735000", + "display": "Specimen from eye obtained by limited exenteration (specimen)" + }, + { + "code": "399741007", + "display": "Specimen from kidney obtained by radical nephrectomy (specimen)" + }, + { + "code": "399747006", + "display": "Specimen from salivary gland (specimen)" + }, + { + "code": "399751008", + "display": "Specimen from uterus obtained by dilation and curettage (specimen)" + }, + { + "code": "399752001", + "display": "Specimen from anus obtained by abdominoperineal resection (specimen)" + }, + { + "code": "404643001", + "display": "Sputum smear specimen (specimen)" + }, + { + "code": "405902005", + "display": "Specimen obtained by radical excision (specimen)" + }, + { + "code": "406101006", + "display": "Tissue specimen from axilla (specimen)" + }, + { + "code": "408654003", + "display": "Specimen obtained by amputation (specimen)" + }, + { + "code": "409821005", + "display": "Timed urine specimen" + }, + { + "code": "409876003", + "display": "Oral mucosal transudate sample" + }, + { + "code": "410580001", + "display": "Respiratory fluid specimen (specimen)" + }, + { + "code": "410581002", + "display": "Upper respiratory fluid sample" + } +] \ No newline at end of file diff --git a/src/main/resources/snomed/SnomedVaccine.json b/src/main/resources/snomed/SnomedVaccine.json new file mode 100644 index 00000000..795b77be --- /dev/null +++ b/src/main/resources/snomed/SnomedVaccine.json @@ -0,0 +1,754 @@ +[ + { + "code": "1119305005", + "display": "COVID-19 antigen vaccine" + }, + { + "code": "1119349007", + "display": "COVID-19 mRNA vaccine" + }, + { + "code": "871761004", + "display": "Rotavirus vaccine" + }, + { + "code": "318351000221106", + "display": "Diphtheria toxoid and acellular pertussis and inactivated poliomyelitis type 1,2, and 3 and tetanus toxoid pediatric vaccine" + }, + { + "code": "1052330009", + "display": "Pneumococcal 10-valent conjugate vaccine" + }, + { + "code": "836498007", + "display": "Mumps orthorubulavirus antigen-containing vaccine product" + }, + { + "code": "871929006", + "display": "Diphtheria and hepatitis B and tetanus vaccine" + }, + { + "code": "2261000221104", + "display": "Influenza A virus subtypes H1N1 and H3N2 and Influenza B virus Victoria and Yamagata lineage antigens only vaccine product" + }, + { + "code": "428601009", + "display": "Paratyphoid vaccine" + }, + { + "code": "836389008", + "display": "Vaccinia virus antigen-containing vaccine product" + }, + { + "code": "871755002", + "display": "Typhoid Vi capsular polysaccharide vaccine" + }, + { + "code": "871732000", + "display": "Rubella vaccine" + }, + { + "code": "836400005", + "display": "Adenovirus antigen-containing vaccine product" + }, + { + "code": "871893003", + "display": "Diphtheria and acellular pertussis and inactivated poliomyelitis and tetanus vaccine" + }, + { + "code": "971000221109", + "display": "Live attenuated typhoid vaccine in oral dose form" + }, + { + "code": "601000221108", + "display": "Bordetella pertussis antigen-containing vaccine product" + }, + { + "code": "1181000221105", + "display": "Influenza vaccine" + }, + { + "code": "871878002", + "display": "Diphtheria and pertussis and poliomyelitis and tetanus vaccine" + }, + { + "code": "2031000221103", + "display": "Adult diphtheria and tetanus toxoids vaccine" + }, + { + "code": "871723002", + "display": "Q fever vaccine" + }, + { + "code": "871826000", + "display": "Diphtheria and tetanus vaccine" + }, + { + "code": "871921009", + "display": "Staphylococcus toxoid vaccine" + }, + { + "code": "836375003", + "display": "Hepatitis A virus antigen-containing vaccine product" + }, + { + "code": "836398006", + "display": "Streptococcus pneumoniae antigen-containing vaccine product" + }, + { + "code": "2181000221101", + "display": "Cholera vaccine in oral dose form" + }, + { + "code": "1031000221108", + "display": "Human poliovirus antigen-containing vaccine product" + }, + { + "code": "860818003", + "display": "Anthrax vaccine" + }, + { + "code": "871887006", + "display": "Diphtheria and Haemophilus influenzae type B and pertussis and poliomyelitis and tetanus vaccine" + }, + { + "code": "871803007", + "display": "Hepatitis A and B vaccine" + }, + { + "code": "836495005", + "display": "Varicella-zoster virus antigen-containing vaccine product" + }, + { + "code": "871717007", + "display": "Yellow fever vaccine" + }, + { + "code": "1111000221101", + "display": "Live attenuated Argentinian haemorrhagic fever vaccine" + }, + { + "code": "1111000221101", + "display": "Live attenuated Argentinian hemorrhagic fever vaccine" + }, + { + "code": "871737006", + "display": "Mumps vaccine" + }, + { + "code": "871890000", + "display": "Diphtheria and Haemophilus influenzae type B and poliomyelitis and tetanus vaccine" + }, + { + "code": "871758000", + "display": "Pertussis vaccine" + }, + { + "code": "871764007", + "display": "Haemophilus influenzae type B vaccine" + }, + { + "code": "2251000221101", + "display": "Live attenuated measles and mumps and rubella and varicella-zoster vaccine" + }, + { + "code": "836403007", + "display": "Tick-borne encephalitis virus antigen-containing vaccine product" + }, + { + "code": "91000221102", + "display": "Inactivated hepatitis A vaccine" + }, + { + "code": "836384003", + "display": "Bacillus anthracis antigen-containing vaccine product" + }, + { + "code": "1121000221106", + "display": "Live attenuated yellow fever vaccine" + }, + { + "code": "1119220001", + "display": "Pneumococcal 23-valent conjugate vaccine" + }, + { + "code": "2191000221103", + "display": "Inactivated rabies vaccine grown in cellular line" + }, + { + "code": "1861000221106", + "display": "BCG (Bacillus Calmette-Guerin) vaccine" + }, + { + "code": "871873006", + "display": "Meningitis A, C, W135 and Y vaccine" + }, + { + "code": "462321000124107", + "display": "Tdap - Low dose diphtheria and low dose acellular pertussis and tetanus vaccine" + }, + { + "code": "319941000221104", + "display": "BCG (Bacillus Calmette-Guerin) vaccine in parenteral dose form" + }, + { + "code": "871750007", + "display": "Hepatitis A pediatric vaccine" + }, + { + "code": "871750007", + "display": "Hepatitis A paediatric vaccine" + }, + { + "code": "871726005", + "display": "Rabies vaccine" + }, + { + "code": "836378001", + "display": "Japanese encephalitis virus antigen-containing vaccine product" + }, + { + "code": "2021000221101", + "display": "Tetanus toxoid vaccine" + }, + { + "code": "840564009", + "display": "Leptospira antigen-containing vaccine product" + }, + { + "code": "840599008", + "display": "Borrelia burgdorferi antigen-containing vaccine product" + }, + { + "code": "1010308001", + "display": "Inactivated whole Hepatitis A HM-175 strain vaccine" + }, + { + "code": "2091000221104", + "display": "Diphtheria and Haemophilus influenza B and acellular pertussis and poliomyelitis and tetanus pediatric vaccine" + }, + { + "code": "836381006", + "display": "Corynebacterium diphtheriae antigen-containing vaccine product" + }, + { + "code": "871891001", + "display": "Diphtheria and hepatitis B and acellular pertussis and inactivated poliomyelitis and tetanus vaccine" + }, + { + "code": "836387005", + "display": "Rotavirus antigen-containing vaccine product" + }, + { + "code": "836368004", + "display": "Bacteria antigen-containing vaccine product" + }, + { + "code": "774618008", + "display": "Diphtheria toxoid and whole cell pertussis and tetanus toxoid adsorbed vaccine" + }, + { + "code": "836393002", + "display": "Rabies lyssavirus antigen-containing vaccine product" + }, + { + "code": "871837004", + "display": "Diphtheria and poliomyelitis and tetanus vaccine" + }, + { + "code": "871738001", + "display": "Live attenuated mumps vaccine" + }, + { + "code": "836402002", + "display": "Live attenuated Mycobacterium bovis antigen-containing vaccine product" + }, + { + "code": "871908002", + "display": "Measles and mumps and rubella and varicella virus vaccine" + }, + { + "code": "991000221105", + "display": "Cholera vaccine" + }, + { + "code": "871721000", + "display": "Ebolavirus antigen only vaccine product" + }, + { + "code": "871876003", + "display": "Diphtheria and acellular pertussis and tetanus vaccine" + }, + { + "code": "2241000221103", + "display": "Live attenuated measles, mumps, and rubella vaccine" + }, + { + "code": "871772009", + "display": "Influenza H1N1 vaccine" + }, + { + "code": "871730008", + "display": "Low dose diphtheria vaccine" + }, + { + "code": "1119254000", + "display": "Pneumococcal 13-valent conjugate vaccine" + }, + { + "code": "911000221103", + "display": "Human papillomavirus vaccine" + }, + { + "code": "318341000221109", + "display": "Diphtheria toxoid and Haemophilus influenzae type B and acellular pertussis and tetanus toxoid pediatric vaccine" + }, + { + "code": "318341000221109", + "display": "Diphtheria toxoid and Haemophilus influenzae type B and acellular pertussis and tetanus toxoid paediatric vaccine" + }, + { + "code": "836390004", + "display": "Salmonella enterica subspecies enterica serovar Typhi antigen-containing vaccine product" + }, + { + "code": "961000221100", + "display": "Typhoid vaccine" + }, + { + "code": "871817003", + "display": "Measles and rubella vaccine" + }, + { + "code": "871766009", + "display": "Live attenuated measles vaccine" + }, + { + "code": "1010689004", + "display": "Haemophilus influenzae type B capsular polysaccharide polyribosylribitol phosphate conjugated to Clostridium tetani toxoid vaccine" + }, + { + "code": "871729003", + "display": "Diphtheria vaccine" + }, + { + "code": "1011000221100", + "display": "Live attenuated cholera vaccine in oral dose form" + }, + { + "code": "871724008", + "display": "Japanese encephalitis virus vaccine" + }, + { + "code": "871871008", + "display": "Meningitis A and C vaccine" + }, + { + "code": "775641005", + "display": "Diphtheria toxoid and tetanus toxoid adsorbed vaccine" + }, + { + "code": "1801000221105", + "display": "Pneumococcal polysaccharide vaccine" + }, + { + "code": "2171000221104", + "display": "Typhoid polysaccharide vaccine in parenteral dose form" + }, + { + "code": "777725002", + "display": "Tetanus toxoid adsorbed vaccine" + }, + { + "code": "2041000221105", + "display": "Haemophilus influenzae type B capsular polysaccharide conjugated vaccine" + }, + { + "code": "871718002", + "display": "Plague vaccine" + }, + { + "code": "409568008", + "display": "Pentavalent (ABCDE) botulinum toxoid vaccine" + }, + { + "code": "121000221105", + "display": "Inactivated hepatitis A and hepatitis B surface antigen vaccine" + }, + { + "code": "840549009", + "display": "Yersinia pestis antigen-containing vaccine product" + }, + { + "code": "871911001", + "display": "Lyme disease vaccine" + }, + { + "code": "871919004", + "display": "Varicella-zoster vaccine" + }, + { + "code": "871806004", + "display": "Haemophilus influenzae type B and Hepatitis B virus antigens only vaccine product" + }, + { + "code": "2001000221108", + "display": "Human papillomavirus 6, 11, 16 and 18 vaccine" + }, + { + "code": "871925000", + "display": "Hepatitis B surface antigen vaccine" + }, + { + "code": "2071000221100", + "display": "Diphtheria toxoid and Haemophilus influenzae type B and whole cell pertussis and tetanus toxoid paediatric vaccine" + }, + { + "code": "2071000221100", + "display": "Diphtheria toxoid and Haemophilus influenzae type B and whole cell pertussis and tetanus toxoid pediatric vaccine" + }, + { + "code": "1052328007", + "display": "Pneumococcal 7-valent conjugate vaccine" + }, + { + "code": "1010313002", + "display": "Live attenuated influenza vaccine" + }, + { + "code": "871765008", + "display": "Measles vaccine" + }, + { + "code": "1119351006", + "display": "Haemophilus influenzae type B and meningitis C and Y vaccine" + }, + { + "code": "836385002", + "display": "Yellow fever virus antigen-containing vaccine product" + }, + { + "code": "871759008", + "display": "Acellular pertussis vaccine" + }, + { + "code": "1001000221103", + "display": "Inactivated cholera vaccine in oral dose form" + }, + { + "code": "871839001", + "display": "Diphtheria and Haemophilus influenzae B and pertussis and tetanus vaccine" + }, + { + "code": "871816007", + "display": "Poliomyelitis and tetanus vaccine" + }, + { + "code": "871742003", + "display": "Tetanus vaccine" + }, + { + "code": "1981000221108", + "display": "Meningococcus serogroup B vaccine" + }, + { + "code": "871916006", + "display": "Meningococcus A, C, W135 and Y capsular oligosaccharide conjugated vaccine" + }, + { + "code": "871883005", + "display": "Diphtheria and acellular pertussis and poliomyelitis and tetanus paediatric vaccine" + }, + { + "code": "871883005", + "display": "Diphtheria and acellular pertussis and poliomyelitis and tetanus pediatric vaccine" + }, + { + "code": "836379009", + "display": "Human papillomavirus antigen-containing vaccine product" + }, + { + "code": "871751006", + "display": "Hepatitis A vaccine" + }, + { + "code": "840563003", + "display": "Dengue virus antigen-containing vaccine product" + }, + { + "code": "871727001", + "display": "Vaccinia virus antigen only vaccine product" + }, + { + "code": "1010310004", + "display": "Live attenuated Oka-Merck strain varicella vaccine" + }, + { + "code": "871897002", + "display": "Rocky Mountain spotted fever vaccine" + }, + { + "code": "1081000221109", + "display": "Live attenuated rotavirus vaccine" + }, + { + "code": "836382004", + "display": "Measles morbillivirus antigen-containing product" + }, + { + "code": "1010322001", + "display": "Live attenuated Oka strain varicella vaccine" + }, + { + "code": "871822003", + "display": "Hepatitis B vaccine" + }, + { + "code": "2221000221107", + "display": "Live attenuated Varicella-zoster vaccine" + }, + { + "code": "1119279002", + "display": "Inactivated whole Influenza H5N1 vaccine" + }, + { + "code": "836388000", + "display": "Rubella virus antigen-containing vaccine product" + }, + { + "code": "871888001", + "display": "Diphtheria and Haemophilus influenza B and acellular pertussis and inactivated poliomyelitis and tetanus vaccine" + }, + { + "code": "1010318006", + "display": "Inactivated whole Hepatitis A GBM strain vaccine" + }, + { + "code": "37146000", + "display": "Typhus vaccine" + }, + { + "code": "1991000221106", + "display": "Human papillomavirus 16 and 18 vaccine" + }, + { + "code": "1061000221102", + "display": "Meningitis polysaccharide vaccine" + }, + { + "code": "871894009", + "display": "Low dose diphtheria and acellular pertussis and inactivated poliomyelitis and tetanus vaccine" + }, + { + "code": "871722007", + "display": "Adenovirus antigen only vaccine product" + }, + { + "code": "871928003", + "display": "Diphtheria and measles and pertussis and poliomyelitis and tetanus vaccine" + }, + { + "code": "871831003", + "display": "Measles and mumps and rubella vaccine" + }, + { + "code": "871804001", + "display": "Hepatitis A and typhoid vaccine" + }, + { + "code": "2211000221102", + "display": "Influenza A virus subtypes H1N1 and H3N2 and influenza B virus Victoria lineage antigens only vaccine product" + }, + { + "code": "1003499009", + "display": "Influenza H5N1 vaccine" + }, + { + "code": "836374004", + "display": "Hepatitis B virus antigen-containing vaccine product" + }, + { + "code": "871768005", + "display": "Influenza vaccine in nasal dose form" + }, + { + "code": "871716003", + "display": "Tularemia vaccine" + }, + { + "code": "871716003", + "display": "Tularaemia vaccine" + }, + { + "code": "871825001", + "display": "Inactivated Japanese encephalitis virus adsorbed vaccine" + }, + { + "code": "871866001", + "display": "Meningitis C vaccine" + }, + { + "code": "836421005", + "display": "Ebolavirus antigen-containing vaccine product" + }, + { + "code": "871895005", + "display": "Diphtheria and Haemophilus influenzae type B and hepatitis B and pertussis and poliomyelitis and tetanus" + }, + { + "code": "921000221108", + "display": "Meningococcus vaccine" + }, + { + "code": "951000221102", + "display": "Meningococcus group C capsular polysaccharide conjugate vaccine" + }, + { + "code": "863950005", + "display": "Bacteria and virus antigens-containing vaccine product" + }, + { + "code": "871740006", + "display": "Inactivated polio vaccine" + }, + { + "code": "2051000221107", + "display": "Adult diphtheria toxoid and acellular pertussis and tetanus toxoid vaccine" + }, + { + "code": "1131000221109", + "display": "Inactivated rabies vaccine" + }, + { + "code": "871725009", + "display": "Inactivated Japanese encephalitis virus vaccine" + }, + { + "code": "836380007", + "display": "Haemophilus influenzae type B antigen-containing vaccine product" + }, + { + "code": "863911006", + "display": "Clostridium tetani antigen-containing vaccine product" + }, + { + "code": "836377006", + "display": "Influenza virus antigen-containing vaccine product" + }, + { + "code": "871918007", + "display": "Rickettsia antigen-containing vaccine product" + }, + { + "code": "1051000221104", + "display": "Live attenuated poliovirus serotypes 1 and 3 vaccine in oral dose form" + }, + { + "code": "2061000221109", + "display": "Diphtheria toxoid and whole cell pertussis and tetanus toxoid paediatric vaccine" + }, + { + "code": "2061000221109", + "display": "Diphtheria toxoid and whole cell pertussis and tetanus toxoid pediatric vaccine" + }, + { + "code": "871719005", + "display": "Tick-borne encephalitis vaccine" + }, + { + "code": "860722004", + "display": "Junin virus antigen-containing product" + }, + { + "code": "871889009", + "display": "Diphtheria and hepatitis B and inactivated poliomyelitis and acellular pertussis vaccine" + }, + { + "code": "865997008", + "display": "Hepatitis A adult vaccine" + }, + { + "code": "871767000", + "display": "Human papillomavirus 9 vaccine" + }, + { + "code": "871739009", + "display": "Human poliovirus antigen only vaccine product" + }, + { + "code": "981000221107", + "display": "Pneumococcal vaccine" + }, + { + "code": "836369007", + "display": "Virus antigen-containing vaccine product" + }, + { + "code": "836401009", + "display": "Neisseria meningitidis antigen-containing vaccine product" + }, + { + "code": "2081000221102", + "display": "Diphtheria toxoid, Haemophilus influenzae B, hepatitis B surface antigen, acellular pertussis and tetanus toxoid paediatric vaccine" + }, + { + "code": "2081000221102", + "display": "Diphtheria toxoid, Haemophilus influenzae B, hepatitis B surface antigen, acellular pertussis and tetanus toxoid pediatric vaccine" + }, + { + "code": "871886002", + "display": "Diphtheria and Haemophilus influenzae type B and hepatitis B and pertussis and tetanus vaccine" + }, + { + "code": "1971000221105", + "display": "Meningococcus A, C, W135 and Y capsular polysaccharide conjugated vaccine" + }, + { + "code": "840551008", + "display": "Francisella tularensis antigen-containing vaccine product" + }, + { + "code": "871875004", + "display": "Diphtheria and pertussis and tetanus vaccine" + }, + { + "code": "871720004", + "display": "Dengue vaccine" + }, + { + "code": "871838009", + "display": "Low dose diphtheria and inactivated poliomyelitis and tetanus vaccine" + }, + { + "code": "836500008", + "display": "Haemophilus influenzae type B and meningitis C vaccine" + }, + { + "code": "836397001", + "display": "Coxiella burnetii antigen-containing vaccine product" + }, + { + "code": "2201000221100", + "display": "Inactivated rabies virus vaccine grown in brain tissue" + }, + { + "code": "2231000221105", + "display": "Live attenuated measles and rubella vaccine" + }, + { + "code": "2101000221107", + "display": "Diphtheria and acellular pertussis and Haemophilus influenzae type B and hepatitis B and poliomyelitis and tetanus pediatric vaccine" + }, + { + "code": "2101000221107", + "display": "Diphtheria and acellular pertussis and Haemophilus influenzae type B and hepatitis B and poliomyelitis and tetanus paediatric vaccine" + }, + { + "code": "871827009", + "display": "Low dose diphtheria and tetanus vaccine" + }, + { + "code": "836383009", + "display": "Vibrio cholerae antigen-containing vaccine product" + } +] \ No newline at end of file From 3710e72ddc12796224b48374394fc9bc4dfabe48 Mon Sep 17 00:00:00 2001 From: Venu-Ajitesh Date: Thu, 28 Aug 2025 15:03:11 +0530 Subject: [PATCH 09/12] Added sample-hip files into gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index d784edfa..d1928c30 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,8 @@ build .gradle +logs/ +sample-hip/generated/ +src/main/resources/Predator_HIP.png ### IntelliJ IDEA ### .idea/ From 6c5cecd4a19f3969b1bc324d4d47f793fc8da954 Mon Sep 17 00:00:00 2001 From: Venu-Ajitesh Date: Thu, 28 Aug 2025 15:03:49 +0530 Subject: [PATCH 10/12] Squashed 'FHIR-Mapper/' changes from 805518f..2cb8737 2cb8737 Merge pull request #5 from VenuAjitesh/implementation/invoice-bundle 19516f9 Updated README.md for clean look of APIs 559e2e0 Merge pull request #4 from VenuAjitesh/implementation/invoice-bundle d400e74 Invoice: Updated InvoicePriceType 24a48e6 Merge pull request #3 from VenuAjitesh/implementation/invoice-bundle d0b7748 Updated postman collection and disabled logs 6b02df7 Merge pull request #2 from VenuAjitesh/implementation/invoice-bundle 9042d82 Corrected Swagger URL in README.md 6295084 Merge pull request #1 from VenuAjitesh/implementation/invoice-bundle 730c1dd Updated Swagger URL in README.md 5d50dc9 Updated Swagger UI 3b9f31e Optimised docker imager size by using light jre 8449101 invoice: updated swagger yaml 1dd8073 invoice: Added enum for api schema e2a3cac invoice: Added null checks for all invoice resources 525dd6d Added few more attributes in chargeItems of invoiceBundle cc3e080 Added few more attributes in device,medication of invoiceBundle c628db1 Working invoice bundle with broken values 71b6d59 Initial commit of invoice bundle git-subtree-dir: FHIR-Mapper git-subtree-split: 2cb8737a6026618711570672d55da03fa5291665 --- Dockerfile | 4 +- README.md | 490 +++++++----- docker-compose-fhir.yaml | 5 +- fhir-mapper.yaml => docs/fhir-mapper.yaml | 707 ++++++++++++++++++ docs/index.html | 257 +++++++ .../FHIR.postman_collection.json | 684 +++++++++-------- .../java/com/nha/abdm/fhir/mapper/Utils.java | 8 + .../BundleCompositionIdentifier.java | 2 + .../constants/BundleResourceIdentifier.java | 6 + .../common/constants/ChargeItemStatus.java | 36 + .../rest/common/constants/DeviceStatus.java | 33 + .../constants/InvoicePaymentStatus.java | 34 + .../common/constants/InvoicePriceType.java | 52 ++ .../common/constants/InvoiceProductType.java | 32 + .../rest/common/constants/InvoiceStatus.java | 32 + .../constants/ResourceProfileIdentifier.java | 6 + .../common/constants/TypeIdentifiers.java | 7 + .../rest/controller/BundleController.java | 22 + .../converter/InvoiceRequestConverter.java | 242 ++++++ .../rest/database/h2/config/DbLoader.java | 6 + .../h2/repositories/TypeChargeItemRepo.java | 18 + .../h2/repositories/TypeInvoiceRepo.java | 18 + .../database/h2/tables/TypeChargeItem.java | 26 + .../rest/database/h2/tables/TypeInvoice.java | 26 + .../compositions/MakeInvoiceComposition.java | 136 ++++ .../invoice/MakeChargeItemResource.java | 82 ++ .../invoice/MakeInvoiceDeviceResource.java | 97 +++ .../MakeInvoiceMedicationResource.java | 62 ++ .../invoice/MakeInvoicePaymentResource.java | 63 ++ .../invoice/MakeInvoicePriceComponent.java | 72 ++ .../invoice/MakeInvoiceResource.java | 160 ++++ .../invoice/MakeInvoiceSubstanceResource.java | 54 ++ .../rest/requests/InvoiceBundleRequest.java | 57 ++ .../requests/helpers/ChargeItemResource.java | 33 + .../helpers/InvoiceDeviceResource.java | 30 + .../helpers/InvoiceMedicationResource.java | 21 + .../helpers/InvoicePaymentResource.java | 27 + .../rest/requests/helpers/InvoicePrice.java | 19 + .../requests/helpers/InvoiceResource.java | 24 + .../helpers/InvoiceSubstanceResource.java | 24 + src/main/resources/application.properties | 10 +- .../resources/snomed/SnomedMedicineRoute.json | 1 + src/main/resources/snomed/TypeChargeItem.json | 42 ++ src/main/resources/snomed/TypeInvoice.json | 22 + 44 files changed, 3297 insertions(+), 492 deletions(-) rename fhir-mapper.yaml => docs/fhir-mapper.yaml (53%) create mode 100644 docs/index.html create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/ChargeItemStatus.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/DeviceStatus.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/InvoicePaymentStatus.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/InvoicePriceType.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/InvoiceProductType.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/InvoiceStatus.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/TypeIdentifiers.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/converter/InvoiceRequestConverter.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/TypeChargeItemRepo.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/TypeInvoiceRepo.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/TypeChargeItem.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/TypeInvoice.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeInvoiceComposition.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/invoice/MakeChargeItemResource.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/invoice/MakeInvoiceDeviceResource.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/invoice/MakeInvoiceMedicationResource.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/invoice/MakeInvoicePaymentResource.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/invoice/MakeInvoicePriceComponent.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/invoice/MakeInvoiceResource.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/invoice/MakeInvoiceSubstanceResource.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/requests/InvoiceBundleRequest.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ChargeItemResource.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/InvoiceDeviceResource.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/InvoiceMedicationResource.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/InvoicePaymentResource.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/InvoicePrice.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/InvoiceResource.java create mode 100644 src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/InvoiceSubstanceResource.java create mode 100644 src/main/resources/snomed/TypeChargeItem.json create mode 100644 src/main/resources/snomed/TypeInvoice.json diff --git a/Dockerfile b/Dockerfile index 21d72851..ee977c34 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,12 +2,12 @@ FROM gradle:8.5-jdk17 AS builder WORKDIR /app COPY build.gradle settings.gradle ./ -RUN gradle dependencies --no-daemon +RUN gradle buildEnvironment --no-daemon COPY . . RUN gradle build --no-daemon -x test -FROM eclipse-temurin:17-jdk-focal +FROM eclipse-temurin:17-jre-focal WORKDIR /app COPY --from=builder /app/build/libs/*-SNAPSHOT.jar fhir.jar diff --git a/README.md b/README.md index d03090f8..3574fb14 100644 --- a/README.md +++ b/README.md @@ -34,182 +34,196 @@ Recommended RAM: Systems with more than 8 GB RAM - The HI type is primarily defined based on the data being collected. However the type of interaction should also be considered. - If the data which is collected is not defined in the structured field for any HI-type you can create a pdf and attach to the particular bundle in the documents. -| Name | Definition | -|-------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------| -| DiagnosticReportRecord | The Clinical Artifact represents diagnostic reports including Radiology and Laboratory reports that can be shared across the health ecosystem. | -| DischargeSummaryRecord | Clinical document used to represent the discharge summary record for ABDM HDE data set. | -| HealthDocumentRecord | The Clinical Artifact represents the unstructured historical health records as a single or multiple Health Record Documents generally uploaded by the patients through the Health Locker and can be shared across the health ecosystem. | -| ImmunizationRecord | The Clinical Artifact represents the Immunization records with any additional documents such as vaccine certificate, the next immunization recommendations, etc. This can be further shared across the health ecosystem. | -| OPConsultRecord | The Clinical Artifact represents the outpatient visit consultation note which may include clinical information on any OP examinations, procedures along with medication administered, and advice that can be shared across the health ecosystem. | -| PrescriptionRecord | The Clinical Artifact represents the medication advice to the patient in compliance with the Pharmacy Council of India (PCI) guidelines, which can be shared across the health ecosystem. | -| WellnessRecord | The Clinical Artifact represents regular wellness information of patients typically through the Patient Health Record (PHR) application covering clinical information such as vitals, physical examination, general wellness, women wellness, etc., that can be shared across the health ecosystem. | +| Name | Definition | +|------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------| +| DiagnosticReportRecord | The Clinical Artifact represents diagnostic reports including Radiology and Laboratory reports that can be shared across the health ecosystem. | +| DischargeSummaryRecord | Clinical document used to represent the discharge summary record for ABDM HDE data set. | +| HealthDocumentRecord | The Clinical Artifact represents the unstructured historical health records as a single or multiple Health Record Documents generally uploaded by the patients through the Health Locker and can be shared across the health ecosystem. | +| ImmunizationRecord | The Clinical Artifact represents the Immunization records with any additional documents such as vaccine certificate, the next immunization recommendations, etc. This can be further shared across the health ecosystem. | +| OPConsultRecord | The Clinical Artifact represents the outpatient visit consultation note which may include clinical information on any OP examinations, procedures along with medication administered, and advice that can be shared across the health ecosystem. | +| PrescriptionRecord | The Clinical Artifact represents the medication advice to the patient in compliance with the Pharmacy Council of India (PCI) guidelines, which can be shared across the health ecosystem. | +| WellnessRecord | The Clinical Artifact represents regular wellness information of patients typically through the Patient Health Record (PHR) application covering clinical information such as vitals, physical examination, general wellness, women wellness, etc., that can be shared across the health ecosystem. | +| InvoiceRecord | The billing artifact represents the invoice details such as pharmacy invoice, consultation invoice etc. along with the support for scanned documents attached for the patient which can be shared across the health ecosystem. | +--- ### APIs for generating the FHIR bundle -- For Swagger-ui, check [here](https://wrapper-sbx.abdm.gov.in/swagger/fhir) -#### DiagnosticReportRecord +- For Swagger-ui, check [here](https://venuajitesh.github.io/FHIR-Mapper/) + +
+ 📄 DiagnosticReportRecord + - for the DiagnosticReportRecord bundle you need to - * `POST` Request `/v1/bundle/diagnostic-report` - ``` - { - "bundleType":"DiagnosticReportRecord", //mandatory - "careContextReference":"visist 21-03-2024", //mandatory - "authoredOn":"2006-04-22", //mandatory - "patient":{ //mandatory - "name":"Venu Ajitesh", //mandatory - "patientReference":"ajitesh6x", //mandatory - "gender":"male", - "birthDate":"2001-04-27" - }, - "practitioners":[{ //mandatory - "name":"Dr.Venu Ajitesh", //mandatory - "practitionerId":"Predator" - }], - "organisation":{ - "facilityName":"Predator_HIP", //mandatory - "facilityId":"Predator_HIP" - }, - "encounter":"Ambula", - "diagnostics":[{ - "serviceName":"BloodTest", //mandatory - "serviceCategory":"Hematography", //mandatory - "result":[{ //you can pass either result or valueQuantity not both - "observation":"Height", //mandatory - "result":"Normal", - "valueQuantity": { - "unit": "CM", - "value": 170 - } - }], - "conclusion":"Normal", //mandatory - "presentedForm":{ - "contentType":"application/pdf", - "data":"Base64 data of the pdf" - } - }], - "documents":[{ - "type":"diagnosticReport", //mandatory - "contentType":"application/pdf", //mandatory - "data":"Base64 data of the pdf" //mandatory - }] - } - ``` -#### DischargeSummaryRecord - - for the DischargeSummaryRecord bundle you need to - * `POST` Request `/v1/bundle/discharge-summary` - ``` + * `POST` Request `/v1/bundle/diagnostic-report` + + ``` { - "bundleType":"DischargeSummaryRecord", //mandatory - "careContextReference":"visist 21-03-2024", //mandatory - "patient":{ //mandatory - "name":"Venu Ajitesh", //mandatory - "patientReference":"ajitesh6x", //mandatory - "gender":"male", - "birthDate":"2001-04-27" + "bundleType": "DiagnosticReportRecord", + "careContextReference": "visist 21-03-2024", + "authoredOn": "2006-04-22", + "patient": { + "name": "Venu Ajitesh", + "patientReference": "ajitesh6x", + "gender": "male", + "birthDate": "2001-04-27" }, - "practitioners":[{ //mandatory - "name":"Dr.Venu Ajitesh", //mandatory - "practitionerId":"Predator" + "practitioners": [{ + "name": "Dr.Venu Ajitesh", + "practitionerId": "Predator" }], - "organisation":{ //mandatory - "facilityName":"Predator_HIP", //mandatory - "facilityId":"Predator_HIP" + "organisation": { + "facilityName": "Predator_HIP", + "facilityId": "Predator_HIP" }, - "chiefComplaints":[ - { - "complaint":"Sugar", //mandatory - "recordedDate":"2024-05-20", //mandatory - "dateRange":{ - "from":"2018-04-27", - "to":"2018-05-26" - } - } - ], - "physicalExaminations":[ - { - "observation":"Height", //mandatory - "result":"Normal", //you can pass either result or valueQuantity not both - "valueQuantity": { - "unit": "CM", - "value": 170 - } - } - ], - "allergies":[ - "Walnuts" - ], - "medicalHistories":[ - { - "complaint":"Sugar", //mandatory - "recordedDate":"2024-05-20", //mandatory - "dateRange":{ - "from":"2018-04-27", - "to":"2018-05-26" - } - } - ], - "familyHistories":[ - { - "relationship":"Friend", //mandatory - "observation":"Toxic" //mandatory + "encounter": "Ambula", + "diagnostics": [{ + "serviceName": "BloodTest", + "serviceCategory": "Hematography", + "result": [{ + "observation": "Height", + "result": "Normal", + "valueQuantity": { + "unit": "CM", + "value": 170 } - ], - "authoredOn":"2024-02-03", //mandatory - "medications":[ - { - "medicine":"Aspirin 75 mg oral tablet", //mandatory - "dosage":"1-0-1", //mandatory - "timing":"2-5-d", - "route":"Oral", - "method":"swallow", - "additionalInstructions":"Take them after food", - "reason": "fever" + }], + "conclusion": "Normal", + "presentedForm": { + "contentType": "application/pdf", + "data": "Base64 data of the pdf" } - ,{ - "medicine":"Disprin", //mandatory - "dosage":"0-0-1", //mandatory - "timing":"1-2-d", - "route":"Syrup", - "method":"drink", - "additionalInstructions":"Take them before food", - "reason": "Cough" + }], + "documents": [{ + "type": "diagnosticReport", + "contentType": "application/pdf", + "data": "Base64 data of the pdf" + }] + } ``` +
+ +
+ 🏥 DischargeSummaryRecord + +- For the DischargeSummaryRecord bundle you need to + * `POST` Request `/v1/bundle/discharge-summary` + + ``` + { + "bundleType":"DischargeSummaryRecord", //mandatory + "careContextReference":"visist 21-03-2024", //mandatory + "patient":{ //mandatory + "name":"Venu Ajitesh", //mandatory + "patientReference":"ajitesh6x", //mandatory + "gender":"male", + "birthDate":"2001-04-27" + }, + "practitioners":[{ //mandatory + "name":"Dr.Venu Ajitesh", //mandatory + "practitionerId":"Predator" + }], + "organisation":{ //mandatory + "facilityName":"Predator_HIP", //mandatory + "facilityId":"Predator_HIP" + }, + "chiefComplaints":[ + { + "complaint":"Sugar", //mandatory + "recordedDate":"2024-05-20", //mandatory + "dateRange":{ + "from":"2018-04-27", + "to":"2018-05-26" + } } - ], - "diagnostics":[{ - "serviceName":"BloodTest", //mandatory - "serviceCategory":"Hematography", //mandatory - "result":[{ - "observation":"Height", //mandatory - "result":"Normal", //you can pass either result or valueQuantity not both - "valueQuantity": { - "unit": "CM", - "value": 170 - } - }], - "conclusion":"Normal", //mandatory - "presentedForm":{ - "contentType":"application/pdf", - "data":"Base64 data of the pdf" + ], + "physicalExaminations":[ + { + "observation":"Height", //mandatory + "result":"Normal", //you can pass either result or valueQuantity not both + "valueQuantity": { + "unit": "CM", + "value": 170 } - }], - - "procedures":[ - { - "date":"2001-04-20", //mandatory - "status":"INPROGRESS", //mandatory - "procedureReason":"Severe", //mandatory - "outcome":"Healthy", - "procedureName":"Operation" //mandatory + } + ], + "allergies":[ + "Walnuts" + ], + "medicalHistories":[ + { + "complaint":"Sugar", //mandatory + "recordedDate":"2024-05-20", //mandatory + "dateRange":{ + "from":"2018-04-27", + "to":"2018-05-26" + } + } + ], + "familyHistories":[ + { + "relationship":"Friend", //mandatory + "observation":"Toxic" //mandatory + } + ], + "authoredOn":"2024-02-03", //mandatory + "medications":[ + { + "medicine":"Aspirin 75 mg oral tablet", //mandatory + "dosage":"1-0-1", //mandatory + "timing":"2-5-d", + "route":"Oral", + "method":"swallow", + "additionalInstructions":"Take them after food", + "reason": "fever" + } + ,{ + "medicine":"Disprin", //mandatory + "dosage":"0-0-1", //mandatory + "timing":"1-2-d", + "route":"Syrup", + "method":"drink", + "additionalInstructions":"Take them before food", + "reason": "Cough" + } + ], + "diagnostics":[{ + "serviceName":"BloodTest", //mandatory + "serviceCategory":"Hematography", //mandatory + "result":[{ + "observation":"Height", //mandatory + "result":"Normal", //you can pass either result or valueQuantity not both + "valueQuantity": { + "unit": "CM", + "value": 170 + } + }], + "conclusion":"Normal", //mandatory + "presentedForm":{ + "contentType":"application/pdf", + "data":"Base64 data of the pdf" } - ], + }], + + "procedures":[ + { + "date":"2001-04-20", //mandatory + "status":"INPROGRESS", //mandatory + "procedureReason":"Severe", //mandatory + "outcome":"Healthy", + "procedureName":"Operation" //mandatory + } + ], + + "documents":[{ + "type":"Discharge record", //mandatory + "contentType":"application/pdf", //mandatory + "data":"Base64 data of the pdf" //mandatory + }] + } + ``` +
+ +
+ 📑 HealthDocumentRecord - "documents":[{ - "type":"Discharge record", //mandatory - "contentType":"application/pdf", //mandatory - "data":"Base64 data of the pdf" //mandatory - }] - } - ``` -#### HealthDocumentRecord - for the HealthDocumentRecord bundle you need to * `POST` Request `/v1/bundle/health-document` ``` @@ -239,7 +253,10 @@ Recommended RAM: Systems with more than 8 GB RAM }] } ``` -#### ImmunizationRecord +
+
+ 💉 ImmunizationRecord + - for the ImmunizationRecord bundle you need to * `POST` Request `/v1/bundle/immunization` ``` @@ -275,7 +292,10 @@ Recommended RAM: Systems with more than 8 GB RAM }] } ``` -#### OPConsultRecord +
+
+ 👨‍⚕️ OPConsultRecord + - for the OPConsultRecord bundle you need to * `POST` Request `/v1/bundle/op-consultation` ``` @@ -403,7 +423,10 @@ Recommended RAM: Systems with more than 8 GB RAM }] } ``` -#### PrescriptionRecord +
+
+ 💊 PrescriptionRecord + - for the PrescriptionRecord bundle you need to * `POST` Request `/v1/bundle/prescription` ``` @@ -453,7 +476,10 @@ Recommended RAM: Systems with more than 8 GB RAM }] } ``` -#### WellnessRecord +
+
+ 🌿 WellnessRecord + - for the WellnessRecord bundle you need to * `POST` Request `/v1/bundle/wellness-record` ``` @@ -551,7 +577,134 @@ Recommended RAM: Systems with more than 8 GB RAM }] } ``` -#### Error response in 400 BadRequest +
+
+ 🧾 InvoiceRecord + + - for the InvoiceRecord bundle you need to + * `POST` Request `/v1/bundle/invoice` + ``` + { + "bundleType": "Invoice", + "careContextReference": "visit-{{$isoTimestamp}}", + "invoiceDate": "2024-05-01T06:33:37.361Z", + "status": "issued", + "encounter": "", + "patient": { + "name": "Venu Ajitesh", + "patientReference": "ajitesh6x", + "gender": "male", + "birthDate": "1940-04-27" + }, + "practitioners": [ + { + "name": "Dr.Venu Ajitesh", + "practitionerId": "Predator" + } + ], + "organisation": { + "facilityName": "Predator_HIP", + "facilityId": "Predator_HIP" + }, + "invoice": { + "id": "INV-12345", // Required + "status": "issued", // Required - issued | balanced | cancelled | draft | entered-in-error + "type": "Pharmacy", // Required - Consultation | Pharmacy | IPD | OPD | Others + "date": "2025-08-12T10:30:00+05:30", // Required + "totalNet": 2000.00, // Required + "totalGross": 2200.00, // Required + "currency": "INR", // Required + "paymentTerms": "Due in 15 days", // Optional + "note": "Surgery + post-op medicines" // Optional + }, + "chargeItems": [ // Required - at least one + { + "id": "CHG-002", + "productType": "medication", // medication | device | substance + "chargeType": "Pharmacy", + "status": "billed", // planned | billable | not-billable | aborted | billed | entered-in-error | unknown + "description": "Amoxicillin 500mg", + "quantity": 14, + "price": [ + { + "priceType": "base", // base | surcharge | deduction | discount | SGST | CGST | informational + "amount": "100" + } + ], + "medication": { // Only for type=medication + "medicineName": "AMOX500", + "manufacturer": "ABC Pharma", + "medicationForm": "tablet", + "lotNumber": "ABC123", + "expiryDate": "{{$isoTimestamp}}" + } + }, + { + "id": "CHG-003", + "productType": "device", // medication | device | substance + "chargeType": "OPD", + "status": "billed", + "description": "Surgical Gloves", + "quantity": 5, + "price": [ + { + "priceType": "base", // base | surcharge | deduction | discount | SGST | CGST | informational + "amount": "200" + } + ], + "device": { // Only for type=device + "udiCarrier": "UDI-GLV-001", + "manufacturer": "MedGlove Inc.", + "modelNumber": "MG-GLV-SRG", + "lotNumber": "194847-0", + "serialNumber": "SN-98347", + "manufactureDate": "2025-01-10", + "expirationDate": "2028-01-10", + "status": "active", + "safety": [ + "Latex Free", + "Sterile" + ], + "deviceName": "Surgical Gloves", + "note": "Used for major surgery" + } + }, + { + "id": "CHG-004", + "productType": "substance", // medication | device | substance + "chargeType": "IPD", + "status": "billed", + "description": "Lab Reagent Kit", + "quantity": 1, + "price": [ + { + "priceType": "base", // base | surcharge | deduction | discount | SGST | CGST | informational + "amount": "300" + } + ], + "substance": { // Only for type=substance + "id": "", + "code": "LAB-REAGENT-001", + "category": "chemical", + "description": "Used to treat infections", + "expiry": "{{$isoTimestamp}}", + "quantity": "2.0" + } + } + ], + "payment": { + "method": "upi", // Optional + "status":"active", // Optional + "paymentDate":"", /// Optional + "paidAmount": 2200.00, // Optional + "transactionId": "TXN-98765" // Optional + }, + } + ``` +
+ +--- +### Error response in 400 BadRequest - There are two kinds of error * Validation errors : The errors are thrown when mandatory fields are missing ``` @@ -576,6 +729,7 @@ Recommended RAM: Systems with more than 8 GB RAM } } ``` +--- ### Things To Consider - If the FHIR bundle is generated the HttpStatus will be `201 created` - The authoredOn will accept date in the format of string in format : `yyyy-MM-dd` or `yyyy-MM-dd'T'HH:mm:ss.SSSX` - UTC iso time format \ No newline at end of file diff --git a/docker-compose-fhir.yaml b/docker-compose-fhir.yaml index 150f5982..981ca379 100644 --- a/docker-compose-fhir.yaml +++ b/docker-compose-fhir.yaml @@ -4,13 +4,16 @@ services: build: context: . dockerfile: Dockerfile - image: fhir-mapper + image: fhir-mapper:latest ports: - '8085:8085' networks: - docker_network extra_hosts: - "host.docker.internal:host-gateway" + restart: unless-stopped + environment: + JAVA_OPTS: "-Xms256m -Xmx512m" networks: docker_network: diff --git a/fhir-mapper.yaml b/docs/fhir-mapper.yaml similarity index 53% rename from fhir-mapper.yaml rename to docs/fhir-mapper.yaml index bda9b9a0..7c5a640b 100644 --- a/fhir-mapper.yaml +++ b/docs/fhir-mapper.yaml @@ -189,6 +189,491 @@ paths: responses: '201': description: Successfully created + '400': + description: Bad Request + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/ValidationErrorResponse' + - $ref: '#/components/schemas/GenericErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericErrorResponse' + /invoice: + post: + tags: + - Billing + summary: Create an Invoice Bundle + description: Submits an invoice bundle containing patient, practitioner, organization, charge items, and payment details. + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/InvoiceBundleRequest' + example: + bundleType: Invoice + careContextReference: visit-2025-08-20T10:00:00Z + invoiceDate: 2025-08-12T10:30:00+05:30 + status: issued + encounter: "" + patient: + name: Venu Ajitesh + patientReference: ajitesh6x + gender: male + birthDate: 1940-04-27 + practitioners: + - name: Dr.Venu Ajitesh + practitionerId: Predator + organisation: + facilityName: Predator_HIP + facilityId: Predator_HIP + invoice: + id: INV-12345 + status: issued + type: Pharmacy + date: 2025-08-12T10:30:00+05:30 + totalNet: 2000.00 + totalGross: 2200.00 + currency: INR + paymentTerms: Due in 15 days + note: Surgery + post-op medicines + chargeItems: + - id: CHG-002 + productType: medication + chargeType: Pharmacy + status: billed + description: Amoxicillin 500mg + quantity: 14 + price: + - priceType: base + amount: 100 + medication: + medicineName: AMOX500 + manufacturer: ABC Pharma + medicationForm: tablet + lotNumber: ABC123 + expiryDate: 2026-05-01 + - id: CHG-003 + productType: device + chargeType: OPD + status: billed + description: Surgical Gloves + quantity: 5 + price: + - priceType: base + amount: 200 + device: + udiCarrier: UDI-GLV-001 + manufacturer: MedGlove Inc. + modelNumber: MG-GLV-SRG + lotNumber: 194847-0 + serialNumber: SN-98347 + manufactureDate: 2025-01-10 + expirationDate: 2028-01-10 + status: active + safety: + - Latex Free + - Sterile + deviceName: Surgical Gloves + note: Used for major surgery + - id: CHG-004 + productType: substance + chargeType: IPD + status: billed + description: Lab Reagent Kit + quantity: 1 + price: + - priceType: base + amount: 300 + substance: + id: SUB-001 + code: LAB-REAGENT-001 + category: chemical + description: Used to treat infections + expiry: 2026-05-01 + quantity: 2.0 + payment: + method: upi + status: active + paymentDate: 2025-08-12T11:00:00+05:30 + paidAmount: 2200.00 + transactionId: TXN-98765 + responses: + '201': + description: Successfully created + content: + application/json: + example: + resourceType: Bundle + id: 81ab25d0-82a0-41b5-b3a6-bff89356bce0 + meta: + versionId: '1' + lastUpdated: '2025-08-19T22:19:11.777Z' + profile: + - 'https://nrces.in/ndhm/fhir/r4/StructureDefinition/DocumentBundle' + security: + - system: 'http://terminology.hl7.org/CodeSystem/v3-Confidentiality' + code: V + display: very restricted + identifier: + system: 'https://ABDM_WRAPPER/bundle' + value: 'visit-2025-08-19T22:19:11.395Z' + type: document + timestamp: '2025-08-19T22:19:11.774Z' + entry: + - fullUrl: Composition/0f545f1a-64b5-437a-824e-ebb22b1bf720 + resource: + resourceType: Composition + id: 0f545f1a-64b5-437a-824e-ebb22b1bf720 + meta: + versionId: '1' + lastUpdated: '2025-08-19T22:19:11.921Z' + identifier: + system: 'https://ABDM_WRAPPER/bundle' + value: 0f545f1a-64b5-437a-824e-ebb22b1bf720 + status: final + type: + coding: + - system: 'http://snomed.info/sct' + code: Invoice Record + display: Invoice Record + subject: + reference: Patient/94ecc23e-c798-4023-bcb2-15cd687166c4 + type: Patient + display: Venu Ajitesh + date: '2024-05-01T12:03:37+05:30' + author: + - reference: Practitioner/Predator + type: Practitioner + display: Dr.Venu Ajitesh + title: Invoice Record + custodian: + reference: Organisation/ec12d2da-22f2-4b05-9cd6-5c66efa0853f + type: Organisation + section: + - title: Invoice + code: + coding: + - system: 'http://snomed.info/sct' + code: Invoice Record + display: Invoice Record + text: Invoice Record + entry: + - reference: Invoice/INV-12345 + type: Invoice + - reference: ChargeItem/CHG-002 + type: ChargeItem + - reference: ChargeItem/CHG-003 + type: ChargeItem + - reference: ChargeItem/CHG-004 + type: ChargeItem + - reference: Device/UDI-GLV-001 + type: Device + - reference: Substance/a54eb8ca-a9bd-4147-90d5-51eb953b2965 + type: Substance + - reference: Medication/1882f644-ee31-497d-b9ab-3c8350584659 + type: Medication + - reference: PaymentReconciliation/b2fb26bb-b286-4487-bc9c-512f564220f0 + type: PaymentReconciliation + - fullUrl: Patient/94ecc23e-c798-4023-bcb2-15cd687166c4 + resource: + resourceType: Patient + id: 94ecc23e-c798-4023-bcb2-15cd687166c4 + meta: + versionId: '1' + lastUpdated: '2025-08-19T22:19:11.778Z' + profile: + - 'https://nrces.in/ndhm/fhir/r4/StructureDefinition/Patient' + identifier: + - type: + coding: + - system: 'http://terminology.hl7.org/CodeSystem/v2-0203' + code: MR + display: Medical record number + system: 'https://healthid.abdm.gov.in' + value: ajitesh6x + name: + - text: Venu Ajitesh + gender: male + birthDate: '1940-04-27' + - fullUrl: Practitioner/Predator + resource: + resourceType: Practitioner + id: Predator + meta: + versionId: '1' + lastUpdated: '2025-08-19T22:19:11.795Z' + profile: + - 'https://nrces.in/ndhm/fhir/r4/StructureDefinition/Practitioner' + identifier: + - type: + coding: + - system: 'http://terminology.hl7.org/CodeSystem/v2-0203' + code: MR + display: Medical record number + system: 'https://doctor.abdm.gov.in' + value: Predator + name: + - text: Dr.Venu Ajitesh + - fullUrl: Organisation/ec12d2da-22f2-4b05-9cd6-5c66efa0853f + resource: + resourceType: Organization + id: ec12d2da-22f2-4b05-9cd6-5c66efa0853f + meta: + versionId: '1' + lastUpdated: '2025-08-19T22:19:11.797Z' + profile: + - 'https://nrces.in/ndhm/fhir/r4/StructureDefinition/Organization' + identifier: + - type: + coding: + - system: 'http://terminology.hl7.org/CodeSystem/v2-0203' + code: PRN + display: Provider number + system: 'https://facility.abdm.gov.in' + value: Predator_HIP + name: Predator_HIP + - fullUrl: Encounter/871368c4-1701-4ea6-bef1-aa590218eba5 + resource: + resourceType: Encounter + id: 871368c4-1701-4ea6-bef1-aa590218eba5 + meta: + lastUpdated: '2025-08-19T22:19:11.808Z' + profile: + - 'https://nrces.in/ndhm/fhir/r4/StructureDefinition/Encounter' + status: in-progress + class: + system: 'http://terminology.hl7.org/CodeSystem/v3-Confidentiality' + code: AMB + display: Ambulatory + subject: + reference: Patient/94ecc23e-c798-4023-bcb2-15cd687166c4 + display: Venu Ajitesh + period: + start: '2024-05-01T06:33:37Z' + - fullUrl: Manufacturer/e9f1c715-19a3-463b-ae5b-cafe2d1466ab + resource: + resourceType: Organization + id: e9f1c715-19a3-463b-ae5b-cafe2d1466ab + meta: + versionId: '1' + lastUpdated: '2025-08-19T22:19:11.873Z' + profile: + - 'https://nrces.in/ndhm/fhir/r4/StructureDefinition/Organization' + identifier: + - type: + coding: + - system: 'http://terminology.hl7.org/CodeSystem/v2-0203' + code: PRN + display: Provider number + system: 'https://facility.abdm.gov.in' + value: 3ac2e25a-490c-424d-a19c-e541114f8f7e + name: ABC Pharma + - fullUrl: Invoice/INV-12345 + resource: + resourceType: Invoice + id: INV-12345 + status: issued + type: + text: Pharmacy + subject: + reference: Patient/94ecc23e-c798-4023-bcb2-15cd687166c4 + display: Venu Ajitesh + date: '2024-05-01T12:03:37+05:30' + issuer: + reference: Organisation/ec12d2da-22f2-4b05-9cd6-5c66efa0853f + display: Predator_HIP + lineItem: + - chargeItemReference: + reference: ChargeItem/CHG-002 + priceComponent: + - type: base + code: + coding: + - system: 'http://hl7.org/fhir/invoice-priceComponentType' + code: base + display: base + text: base + amount: + value: 100 + currency: INR + - chargeItemReference: + reference: ChargeItem/CHG-003 + priceComponent: + - type: base + code: + coding: + - system: 'http://hl7.org/fhir/invoice-priceComponentType' + code: base + display: base + text: base + amount: + value: 200 + currency: INR + - chargeItemReference: + reference: ChargeItem/CHG-004 + priceComponent: + - type: base + code: + coding: + - system: 'http://hl7.org/fhir/invoice-priceComponentType' + code: base + display: base + text: base + amount: + value: 300 + currency: INR + totalNet: + value: 2000 + currency: INR + totalGross: + value: 2200 + currency: INR + paymentTerms: Due in 15 days + note: + - text: Surgery + post-op medicines + - fullUrl: ChargeItem/CHG-002 + resource: + resourceType: ChargeItem + id: CHG-002 + identifier: + - value: medication + status: billed + code: + coding: + - system: 'https://nrces.in/ndhm/fhir/r4/CodeSystem/ndhm-billing-codes' + code: '01' + display: Pharmacy + text: Pharmacy + quantity: + value: 14 + unit: pcs + productReference: + reference: Medication/1882f644-ee31-497d-b9ab-3c8350584659 + note: + - text: Amoxicillin 500mg + - fullUrl: ChargeItem/CHG-003 + resource: + resourceType: ChargeItem + id: CHG-003 + identifier: + - value: device + status: billed + code: + coding: + - system: 'https://nrces.in/ndhm/fhir/r4/CodeSystem/ndhm-billing-codes' + code: '03' + display: OPD + text: OPD + quantity: + value: 5 + unit: pcs + productReference: + reference: Device/UDI-GLV-001 + note: + - text: Surgical Gloves + - fullUrl: ChargeItem/CHG-004 + resource: + resourceType: ChargeItem + id: CHG-004 + identifier: + - value: substance + status: billed + code: + coding: + - system: 'https://nrces.in/ndhm/fhir/r4/CodeSystem/ndhm-billing-codes' + code: '02' + display: IPD + text: IPD + quantity: + value: 1 + unit: pcs + productReference: + reference: Substance/a54eb8ca-a9bd-4147-90d5-51eb953b2965 + note: + - text: Lab Reagent Kit + - fullUrl: Device/UDI-GLV-001 + resource: + resourceType: Device + id: UDI-GLV-001 + udiCarrier: + - deviceIdentifier: UDI-GLV-001 + status: active + manufacturer: MedGlove Inc. + manufactureDate: '2025-01-10T00:00:00+05:30' + expirationDate: '2028-01-10T00:00:00+05:30' + lotNumber: 194847-0 + serialNumber: SN-98347 + deviceName: + - name: Surgical Gloves + type: user-friendly-name + modelNumber: MG-GLV-SRG + note: + - text: Used for major surgery + safety: + - text: Latex Free + - text: Sterile + - fullUrl: Substance/a54eb8ca-a9bd-4147-90d5-51eb953b2965 + resource: + resourceType: Substance + id: a54eb8ca-a9bd-4147-90d5-51eb953b2965 + category: + - text: chemical + code: + text: LAB-REAGENT-001 + description: Used to treat infections + instance: + - expiry: '2025-08-20T03:49:11+05:30' + quantity: + value: 2 + - fullUrl: Medication/1882f644-ee31-497d-b9ab-3c8350584659 + resource: + resourceType: Medication + id: 1882f644-ee31-497d-b9ab-3c8350584659 + meta: + versionId: '1' + lastUpdated: '2025-08-19T22:19:11.878Z' + code: + coding: + - system: 'http://snomed.info/sct' + code: '261665006' + display: AMOX500 + text: AMOX500 + manufacturer: + reference: Manufacturer/e9f1c715-19a3-463b-ae5b-cafe2d1466ab + form: + coding: + - system: 'http://snomed.info/sct' + code: '385055001' + display: tablet + text: tablet + batch: + lotNumber: ABC123 + expirationDate: '2025-08-20T03:49:11+05:30' + - fullUrl: PaymentReconciliation/b2fb26bb-b286-4487-bc9c-512f564220f0 + resource: + resourceType: PaymentReconciliation + id: b2fb26bb-b286-4487-bc9c-512f564220f0 + status: active + paymentAmount: + value: 2200 + currency: INR + paymentIdentifier: + value: TXN-98765 + detail: + - type: + coding: + - system: 'http://terminology.hl7.org/CodeSystem/payment-type' + code: upi + display: upi + + + '400': description: Bad Request content: @@ -1145,6 +1630,228 @@ components: type: OP record contentType: application/pdf data: xyzadybcljbabvlalbfdbvubujzbj + InvoiceBundleRequest: + type: object + required: + - bundleType + - careContextReference + - invoiceDate + - status + - patient + - organisation + - invoice + - chargeItems + properties: + bundleType: + type: string + example: Invoice + careContextReference: + type: string + invoiceDate: + type: string + format: date-time + status: + type: string + enum: [issued, balanced, cancelled, draft, entered-in-error] + encounter: + type: string + patient: + $ref: '#/components/schemas/Patient' + practitioners: + type: array + items: + $ref: '#/components/schemas/Practitioner' + organisation: + $ref: '#/components/schemas/Organisation' + invoice: + $ref: '#/components/schemas/Invoice' + chargeItems: + type: array + items: + $ref: '#/components/schemas/ChargeItem' + payment: + $ref: '#/components/schemas/Payment' + + + + Invoice: + type: object + required: + - status + - type + - totalNet + - totalGross + - currency + - date + properties: + id: + type: string + status: + type: string + enum: [issued, balanced, cancelled, draft, entered-in-error] + type: + type: string + enum: [Consultation, Pharmacy, IPD, OPD, Others] + date: + type: string + format: date-time + totalNet: + type: number + format: double + totalGross: + type: number + format: double + currency: + type: string + paymentTerms: + type: string + note: + type: string + + ChargeItem: + type: object + required: + - productType + - chargeType + - status + - quantity + - price + - description + properties: + id: + type: string + productType: + type: string + enum: [medication, device, substance] + chargeType: + type: string + status: + type: string + enum: [planned, billable, not-billable, aborted, billed, entered-in-error, unknown] + description: + type: string + quantity: + type: integer + price: + type: array + items: + $ref: '#/components/schemas/Price' + medication: + $ref: '#/components/schemas/InvoiceMedication' + device: + $ref: '#/components/schemas/Device' + substance: + $ref: '#/components/schemas/Substance' + + Price: + type: object + required: + - proceType + - amount + properties: + priceType: + type: string + enum: [base, surcharge, deduction, discount, SGST, CGST, informational] + amount: + type: number + format: double + + InvoiceMedication: + type: object + required: + - medicineName + properties: + medicineName: + type: string + manufacturer: + type: string + medicationForm: + type: string + lotNumber: + type: string + expiryDate: + type: string + format: date-time + + Device: + type: object + required: + - status + - deviceName + properties: + udiCarrier: + type: string + manufacturer: + type: string + modelNumber: + type: string + lotNumber: + type: string + serialNumber: + type: string + manufactureDate: + type: string + format: date + expirationDate: + type: string + format: date + status: + type: string + enum: [active, inactive, entered-in-error, unknown] + safety: + type: array + items: + type: string + deviceName: + type: string + note: + type: string + + Substance: + type: object + required: + - code + - category + - description + - quantity + properties: + id: + type: string + code: + type: string + category: + type: string + description: + type: string + expiry: + type: string + format: date-time + quantity: + type: number + format: double + + Payment: + type: object + required: + - method + - status + - paymentAmount + properties: + method: + type: string + example: upi + status: + type: string + enum: [active, cancelled, draft, entered-in-error, null] + paymentDate: + type: string + format: date-time + paidAmount: + type: number + format: double + transactionId: + type: string + ValidationErrorResponse: diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 00000000..10b180f2 --- /dev/null +++ b/docs/index.html @@ -0,0 +1,257 @@ + + + + + + Swagger + + + + + +
+ + + + + + diff --git a/postmanCollection/FHIR.postman_collection.json b/postmanCollection/FHIR.postman_collection.json index 3cb05d03..a0d31870 100644 --- a/postmanCollection/FHIR.postman_collection.json +++ b/postmanCollection/FHIR.postman_collection.json @@ -1,318 +1,370 @@ { - "info": { - "_postman_id": "6192a23b-5635-4954-9ba9-903e46159dfd", - "name": "FHIR", - "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", - "_exporter_id": "24014718" - }, - "item": [ - { - "name": "prescription", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var template = `", - "", - "", - "", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " {{#each response.entry}}", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " {{/each}}", - "
IDTypeStatusDateSubjectAuthorTitle
{{resource.id}}{{resource.resourceType}}{{resource.status}}{{resource.date}}{{resource.subject.reference}}{{resource.author.[0].reference}}{{resource.title}}
", - "`;", - "", - "function constructVisualizerPayload() {", - " return { response: pm.response.json() };", - "}", - "", - "pm.visualizer.set(template, constructVisualizerPayload());" - ], - "type": "text/javascript", - "packages": {} - } - }, - { - "listen": "prerequest", - "script": { - "exec": [ - "" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\r\n \"bundleType\": \"PrescriptionRecord\",\r\n \"careContextReference\": \"visit-{{$isoTimestamp}}\",\r\n \"authoredOn\": \"2024-05-01T06:33:37.361Z\",\r\n \"encounter\": \"\",\r\n \"patient\": {\r\n \"name\": \"Venu Ajitesh\",\r\n \"patientReference\": \"ajitesh6x\",\r\n \"gender\": \"male\",\r\n \"birthDate\": \"1940-04-27\"\r\n },\r\n \"practitioners\": [\r\n {\r\n \"name\": \"Dr.Venu Ajitesh\",\r\n \"practitionerId\": \"Predator\"\r\n }\r\n ],\r\n \"organisation\": {\r\n \"facilityName\": \"Predator_HIP\",\r\n \"facilityId\": \"Predator_HIP\"\r\n },\r\n \"prescriptions\": [\r\n {\r\n \"medicine\": \"Glucosamine 1 g oral tablet\",\r\n \"dosage\": \"1-0-1\",\r\n \"timing\": \"1-1-D\",\r\n \"route\": \"Oral\",\r\n \"method\": \"swallow\",\r\n \"additionalInstructions\": \"Take them after food\",\r\n \"reason\": \"fever\"\r\n },\r\n {\r\n \"medicine\": \"Acetaminophen 100 mg/mL oral solution\",\r\n \"dosage\": \"0-0-1\",\r\n \"timing\": \"1-2-MO\",\r\n \"route\": \"Syrup\",\r\n \"method\": \"drink\",\r\n \"additionalInstructions\": \"Take them before food\",\r\n \"reason\": \"Cough\"\r\n }\r\n ],\r\n \"documents\": [\r\n {\r\n \"type\": \"Prescription\",\r\n \"contentType\": \"application/pdf\",\r\n \"data\": \"JVBERi0xLjMKJf////8K\"\r\n }\r\n ]\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "localhost:8085/v1/bundle/prescription", - "host": [ - "localhost" - ], - "port": "8085", - "path": [ - "v1", - "bundle", - "prescription" - ] - } - }, - "response": [] - }, - { - "name": "OPConsultation", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\r\n \"bundleType\":\"OPConsultRecord\",\r\n \"careContextReference\":\"visist 21-03-2025\",\r\n \"visitDate\":\"2024-05-02T06:33:37.361Z\",\r\n \"patient\":{\r\n \"name\":\"Venu Ajitesh\",\r\n \"patientReference\":\"ajitesh6x\",\r\n \"gender\":\"male\",\r\n \"birthDate\":\"1940-04-27\"\r\n },\r\n \"practitioners\":[{\r\n \"name\":\"Dr.Venu Ajitesh\",\r\n \"practitionerId\":\"Predator\"\r\n }],\r\n \"organisation\":{\r\n \"facilityName\":\"Predator_HIP\",\r\n \"facilityId\":\"Predator_HIP\"\r\n },\r\n \"chiefComplaints\":[\r\n {\r\n \"complaint\":\"Dengue\",\r\n \"recordedDate\":\"2024-05-20\",\r\n \"dateRange\":{\r\n \"from\":\"2018-04-27\",\r\n \"to\":\"2018-05-26\"\r\n }\r\n }\r\n ],\r\n \"physicalExaminations\":[\r\n {\r\n \"observation\":\"Heavy drinker\",\r\n \"result\":\"heavy\"\r\n // \"valueQuantity\": {\r\n\t\t\t// \t\t\"unit\": \"CM\",\r\n\t\t\t// \t\t\"value\": 170\r\n\t\t\t// }\r\n }\r\n ],\r\n \"allergies\":[\r\n \"\"\r\n ],\r\n \"medicalHistories\": \r\n [\r\n {\r\n \"complaint\":\"Typhoid fever\",\r\n \"recordedDate\":\"2024-05-20\",\r\n \"dateRange\":{\r\n \"from\":\"2018-04-27\",\r\n \"to\":\"2018-05-26\"\r\n }\r\n }\r\n ],\r\n \"familyHistories\":[\r\n {\r\n \"relationship\":\"Friend\",\r\n \"observation\":\"Toxic\"\r\n }\r\n ],\r\n \"serviceRequests\":[\r\n {\r\n \"status\":\"ACTIVE\",\r\n \"details\":\"X-RAY\",\r\n \"specimen\":\"Lung cytologic material\"\r\n }\r\n ],\r\n \"medications\":\r\n [\r\n {\r\n \"medicine\":\"Nabilone 2 mg oral capsule\",\r\n \"dosage\":\"1-0-1\",\r\n \"timing\":\"2-5-D\",\r\n \"route\":\"Oral route\",\r\n \"method\":\"swallow\",\r\n \"additionalInstructions\":\"Take them after food\"\r\n }\r\n ,{\r\n \"medicine\":\"Nystatin 25000 unit/g vaginal cream\",\r\n \"dosage\":\"0-0-1\",\r\n \"timing\":\"1-2-D\",\r\n \"route\":\"Interstitial route (qualifier value)\",\r\n \"method\":\"drink\",\r\n \"additionalInstructions\":\"Take them before food\"\r\n }\r\n ],\r\n \"followups\":[\r\n {\r\n \"serviceType\":\"OPConsultation\",\r\n \"appointmentTime\":\"2024-05-20\",\r\n \"reason\":\"General\"\r\n }\r\n ],\r\n \"procedures\":[\r\n {\r\n \"date\":\"2001-04-20\",\r\n \"status\":\"INPROGRESS\",\r\n \"procedureReason\":\"Severe\",\r\n \"outcome\":\"Healthy\",\r\n \"procedureName\":\"Endodontic procedure\"\r\n }\r\n ],\r\n \"referrals\":[\r\n {\r\n \"status\":\"ACTIVE\",\r\n \"details\":\"Y-RAY\",\r\n \"specimen\":\"Pleural cytologic material\"\r\n }\r\n ],\r\n \"otherObservations\":[\r\n {\r\n \"observation\":\"Body weight\",\r\n // \"result\":\"Over weight\",\r\n \"valueQuantity\": {\r\n\t\t\t\t\t\"unit\": \"KG\",\r\n\t\t\t\t\t\"value\": 90\r\n\t\t\t\t}\r\n }\r\n ],\r\n \"documents\":[{\r\n \"type\":\"OP record\",\r\n \"contentType\":\"application/pdf\",\r\n \"data\":\"JVBERi0xLjMKJf////8K\"\r\n }]\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "localhost:8085/v1/bundle/op-consultation", - "host": [ - "localhost" - ], - "port": "8085", - "path": [ - "v1", - "bundle", - "op-consultation" - ] - } - }, - "response": [] - }, - { - "name": "health-document", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "" - ], - "type": "text/javascript", - "packages": {} - } - }, - { - "listen": "prerequest", - "script": { - "exec": [ - "" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\r\n \"bundleType\":\"HealthDocumentRecord\",\r\n \"careContextReference\":\"visist 21-03-2024\",\r\n \"patient\":{\r\n \"name\":\"Venu Ajitesh\",\r\n \"patientReference\":\"ajitesh6x\",\r\n \"gender\":\"male\",\r\n \"birthDate\":\"1940-04-27\"\r\n },\r\n \"authoredOn\":\"2024-05-03T06:33:37.361Z\",\r\n \"practitioners\":[{\r\n \"name\":\"Dr.Venu Ajitesh\",\r\n \"practitionerId\":\"Predator\"\r\n }],\r\n \"organisation\":{\r\n \"facilityName\":\"Predator_HIP\",\r\n \"facilityId\":\"Predator_HIP\"\r\n },\r\n \"encounter\":\"\",\r\n \"documents\":[{\r\n \"type\":\"health-document\",\r\n \"contentType\":\"application/pdf\",\r\n \"data\":\"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7Igi2NJ03WIdb8CPaOhwBlKEkoax7E5ZdLjP42F98TiJWKZ1T9XnPz8+/Kc1f/jRS/+d3B19aNHmf3r24eU/ho/Y+4/AKijvgugHu5+K373i9d+++9oPF/X9P6FV1H1lbmRzdHJlYW0gCmVuZG9iaiAKMiAwIG9iaiAKPDwgCi9UeXBlIC9QYWdlcyAKL0tpZHMgWyA4IDAgUiBdIAovQ291bnQgMSAKL01lZGlhQm94IDMgMCBSIAovQ3JvcEJveCA0IDAgUiAKPj4gCmVuZG9iaiAKMyAwIG9iaiAKWyAwIDAgNTk1IDg0MSBdIAplbmRvYmogCjQgMCBvYmogClsgMCAwIDU5NSA4NDEgXSAKZW5kb2JqIAo2IDAgb2JqIAo8PCAKL1Byb2NTZXQgNyAwIFIgCi9Gb250IDw8IAovOSA5IDAgUiAgCi9hIDEwIDAgUiAgCj4+IAovWE9iamVjdCA8PCAKL2ltZzAgMTEgMCBSICAKPj4gCj4+IAplbmRvYmogCjcgMCBvYmogClsgL1BERiAvVGV4dCAvSW1hZ2VCIC9JbWFnZUMgL0ltYWdlSSAgXSAKZW5kb2JqIAo4IDAgb2JqIAo8PCAKL1R5cGUgL1BhZ2UgCi9QYXJlbnQgMiAwIFIgCi9SZXNvdXJjZXMgNiAwIFIgCi9Db250ZW50cyBbIDUgMCBSIF0gCj4+IAplbmRvYmogCjkgMCBvYmogCjw8IAovVHlwZSAvRm9udCAKL1N1YnR5cGUgL1RydWVUeXBlIAovQmFzZUZvbnQgL0FBQUFBQStBcmlhbCxCb2xkIAovRmlyc3RDaGFyIDMyIAovTGFzdENoYXIgMTIxIAovV2lkdGhzIDE0IDAgUiAKL0ZvbnREZXNjcmlwdG9yIDE2IDAgUiAKL1RvVW5pY29kZSAxNSAwIFIgCj4+IAplbmRvYmogCjEwIDAgb2JqIAo8PCAKL1R5cGUgL0ZvbnQgCi9TdWJ0eXBlIC9UcnVlVHlwZSAKL0Jhc2VGb250IC9BQUFBQUIrQXJpYWwgCi9GaXJzdENoYXIgMzIgCi9MYXN0Q2hhciAxMjIgCi9XaWR0aHMgMTkgMCBSIAovRm9udERlc2NyaXB0b3IgMjEgMCBSIAovVG9Vbmljb2RlIDIwIDAgUiAKPj4gCmVuZG9iaiAKMTEgMCBvYmog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CjY2NyAKMCAKNzIyIAo2NjcgCjYxMSAKNzIyIAowIAowIAowIAowIAowIAowIAowIAowIAowIAowIAowIAo1NTYgCjYxMSAKNTU2IAo2MTEgCjU1NiAKMzMzIAo2MTEgCjYxMSAKMjc4IAowIAo1NTYgCjI3OCAKODg5IAo2MTEgCjYxMSAKNjExIAowIAozODkgCjU1NiAKMzMzIAo2MTEgCjU1NiAKMCAKMCAKNTU2IApdIAplbmRvYmogCjE2IDAgb2JqIAo8PCAKL1R5cGUgL0ZvbnREZXNjcmlwdG9yIAovQXNjZW50IDkwNSAKL0NhcEhlaWdodCA1MDAgCi9EZXNjZW50IC0yMTIgCi9GbGFncyA0IAovRm9udEJCb3ggMTcgMCBSIAovRm9udE5hbWUgL0FBQUFBQStBcmlhbCxCb2xkIAovSXRhbGljQW5nbGUgMAovU3RlbVYgMCAKL1N0ZW1IIDAgCi9BdmdXaWR0aCA0NzkgCi9Gb250RmlsZTIgMTggMCBSIAovTGVhZGluZyAwIAovTWF4V2lkdGggMjYyOCAKL01pc3NpbmdXaWR0aCA0NzkgCi9YSGVpZ2h0IDAgCj4+IAplbmRvYmogCjE3IDAgb2JqIApbIC02MjggLTM3NiAyMDAwIDEwNTYgXSAKZW5kb2JqIAoxOSAwIG9iaiAKWyAKMjc4IAowIAowIAowIAowIAowIAowIAowIAowIAowIAowIAowIAoyNzggCjMzMyAKMjc4IAoyNzggCjU1NiAKNTU2IAo1NTYgCjU1NiAKNTU2IAo1NTYgCjU1NiAKNTU2IAo1NTYgCjU1NiAKMjc4IAowIAowIAowIAowIAowIAowIAo2NjcgCjY2NyAKNzIyIAo3MjIgCjY2NyAKMCAKNzc4IAo3MjIgCjI3OCAKMCAKMCAKNTU2IAo4MzMgCjcyMiAKNzc4IAo2NjcgCjAgCjcyMiAKNjY3IAo2MTEgCjcyMiAKMCAKOTQ0IAowIAo2NjcgCjAgCjAgCjAgCjAgCjAgCjAgCjAgCjU1NiAKNTU2IAo1MDAgCjU1NiAKNTU2IAowIAo1NTYgCjU1NiAKMjIyIAoyMjIgCjAgCjIyMiAKODMzIAo1NTYgCjU1NiAKNTU2IAowIAozMzMgCjUwMCAKMjc4IAo1NTYgCjAgCjAgCjAgCjAgCjUwMCAKXSAKZW5kb2JqIAoyMSAwIG9iaiAKPDwgCi9UeXBlIC9Gb250RGVzY3JpcHRvciAKL0FzY2VudCA5MDUgCi9DYXBIZWlnaHQgNTAwIAovRGVzY2VudCAtMjEyIAovRmxhZ3MgNCAKL0ZvbnRCQm94IDIyIDAgUiAKL0ZvbnROYW1lIC9BQUFBQUIrQXJpYWwgCi9JdGFsaWNBbmdsZSAwCi9TdGVtViAwIAovU3RlbUggMCAKL0F2Z1dpZHRoIDQ0MSAKL0ZvbnRGaWxlMiAyMyAwIFIgCi9MZWFkaW5nIDAgCi9NYXhXaWR0aCAyNjY1IAovTWlzc2luZ1dpZHRoIDQ0MSAKL1hIZWlnaHQgMCAKPj4gCmVuZG9iaiAKMjIgMCBvYmogClsgLTY2NSAtMzI1IDIwMDAgMTA0MCBdIAplbmRvYmogCjI0IDAgb2JqIAooUG93ZXJlZCBCeSBDcnlzdGFsKSAKZW5kb2JqIAoyNSAwIG9iaiAKKENyeXN0YWwgUmVwb3J0cykgCmVuZG9iaiAKMjYgMCBvYmogCjw8IAovUHJvZHVjZXIgKFBvd2VyZWQgQnkgQ3J5c3RhbCkgIAovQ3JlYXRvciAoQ3J5c3RhbCBSZXBvcnRzKSAgCj4+IAplbmRvYmogCnhyZWYgCjAgMjcgCjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDAxNyAwMDAwMCBuIAowMDAwMDQyNDE0IDAwMDAwIG4gCjAwMDAwNDI1MTMgMDAwMDAgbiAKMDAwMDA0MjU0NyAwMDAwMCBuIAowMDAwMDAwMTk0IDAwMDAwIG4gCjAwMDAwNDI1ODEgMDAwMDAgbiAKMDAwMDA0MjY5MSAwMDAwMCBuIAowMDAwMDQyNzQ5IDAwMDAwIG4gCjAwMDAwNDI4NDEgMDAwMDAgbiAKMDAwMDA0MzAxOCAwMDAwMCBuIAowMDAwMDQzMTkxIDAwMDAwIG4gCjAwMDAwNTQ3MzUgMDAwMDAgbiAKMDAwMDA1NDc4OSAwMDAwMCBuIAowMDAwMDU1NjA0IDAwMDAwIG4gCjAwMDAwMDE0NzQgMDAwMDAgbiAKMDAwMDA1NTk5MCAwMDAwMCBuIAowMDAwMDU2MjY5IDAwMDAwIG4gCjAwMDAwMDIwOTUgMDAwMDAgbiAKMDAwMDA1NjMxMiAwMDAwMCBuIAowMDAwMDE4MTE3IDAwMDAwIG4gCjAwMDAwNTY3MTcgMDAwMDAgbiAKMDAwMDA1Njk5MSAwMDAwMCBuIAowMDAwMDE4Nzc5IDAwMDAwIG4gCjAwMDAwNTcwMzQgMDAwMDAgbiAKMDAwMDA1NzA3NCAwMDAwMCBuIAowMDAwMDU3MTExIDAwMDAwIG4gCnRyYWlsZXIgCjw8IAovU2l6ZSAyNyAKL1Jvb3QgMSAwIFIgCi9JbmZvIDI2IDAgUiAKPj4gCnN0YXJ0eHJlZiAKNTcxOTkgCiUlRU9GDQo=\"\r\n }]\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "localhost:8085/v1/bundle/health-document", - "host": [ - "localhost" - ], - "port": "8085", - "path": [ - "v1", - "bundle", - "health-document" - ] - } - }, - "response": [] - }, - { - "name": "diagnosticReport", - "protocolProfileBehavior": { - "disabledSystemHeaders": {} - }, - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\r\n \"bundleType\": \"DiagnosticReportRecord\",\r\n \"careContextReference\": \"visist 21-03-2024\",\r\n \"visitDate\": \"2024-05-07T06:33:37.361Z\",\r\n \"patient\": {\r\n \"name\": \"Venu Ajitesh\",\r\n \"patientReference\": \"ajitesh6x\",\r\n \"gender\": \"male\",\r\n \"birthDate\": \"1940-04-27\"\r\n },\r\n \"practitioners\": [\r\n {\r\n \"name\": \"Dr.Venu Ajitesh\",\r\n \"practitionerId\": \"Predator\"\r\n }\r\n ],\r\n \"organisation\": {\r\n \"facilityName\": \"Predator_HIP\",\r\n \"facilityId\": \"Predator_HIP\"\r\n },\r\n \"encounter\": \"Ambula\",\r\n \"diagnostics\": [\r\n {\r\n \"serviceName\": \"BloodTest\",\r\n \"authoredOn\":\"2024-11-23T21:34:38.989Z\",\r\n \"serviceCategory\": \"Hematography\",\r\n \"result\": [\r\n {\r\n \"observation\": \"Height\",\r\n \"result\": \"Normal\",\r\n \"valueQuantity\": {\r\n \"unit\": \"CM\",\r\n \"value\": 170\r\n }\r\n }\r\n ],\r\n \"conclusion\": \"Normal\",\r\n \"presentedForm\":{\r\n \"contentType\": \"application/pdf\",\r\n \"data\": \"JVBERi0xLjMKJf////8K\"\r\n }\r\n }\r\n ],\r\n \"documents\":[{\r\n \"type\": \"diagnosticReport\",\r\n \"contentType\": \"application/pdf\",\r\n \"data\": \"JVBERi0xLjMKJf////8K\"\r\n }]\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "localhost:8085/v1/bundle/diagnostic-report", - "host": [ - "localhost" - ], - "port": "8085", - "path": [ - "v1", - "bundle", - "diagnostic-report" - ] - } - }, - "response": [] - }, - { - "name": "wellness-record", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\r\n \"bundleType\":\"WellnessRecord\",\r\n \"careContextReference\":\"visist 21-03-2025\",\r\n \"authoredOn\":\"2024-05-04T06:33:37.361Z\",\r\n \"patient\":{\r\n \"name\":\"Venu Ajitesh\",\r\n \"patientReference\":\"ajitesh6x\",\r\n \"gender\":\"male\",\r\n \"birthDate\":\"1940-04-27\"\r\n },\r\n \"practitioners\":[{\r\n \"name\":\"Dr.Venu Ajitesh\",\r\n \"practitionerId\":\"Predator\"\r\n }],\r\n \"organisation\":{\r\n \"facilityName\":\"Predator_HIP\",\r\n \"facilityId\":\"Predator_HIP\"\r\n },\r\n \"vitalSigns\":[\r\n {\r\n \"observation\":\"Height\",\r\n \"result\":\"Normal\",\r\n \"valueQuantity\": {\r\n\t\t\t\t\t\"unit\": \"CM\",\r\n\t\t\t\t\t\"value\": 170\r\n\t\t\t}\r\n }\r\n ],\r\n \"bodyMeasurements\":[\r\n {\r\n \"observation\":\"BMI\",\r\n \"result\":\"Normal\",\r\n \"valueQuantity\": {\r\n\t\t\t\t\t\"unit\": \"CM\",\r\n\t\t\t\t\t\"value\": 170\r\n\t\t\t}\r\n }\r\n ],\r\n \"physicalActivities\":[\r\n {\r\n \"observation\":\"Running\",\r\n \"result\":\"Normal\",\r\n \"valueQuantity\": {\r\n\t\t\t\t\t\"unit\": \"CM\",\r\n\t\t\t\t\t\"value\": 170\r\n\t\t\t}\r\n }\r\n ],\r\n \"generalAssessments\":[\r\n {\r\n \"observation\":\"Physico\",\r\n \"result\":\"Normal\",\r\n \"valueQuantity\": {\r\n\t\t\t\t\t\"unit\": \"CM\",\r\n\t\t\t\t\t\"value\": 170\r\n\t\t\t}\r\n }\r\n ],\"womanHealths\":[\r\n {\r\n \"observation\":\"Crazy\",\r\n \"result\":\"Normal\",\r\n \"valueQuantity\": {\r\n\t\t\t\t\t\"unit\": \"CM\",\r\n\t\t\t\t\t\"value\": 170\r\n\t\t\t}\r\n }\r\n ],\r\n \"lifeStyles\":[\r\n {\r\n \"observation\":\"Bad\",\r\n \"result\":\"Normal\",\r\n \"valueQuantity\": {\r\n\t\t\t\t\t\"unit\": \"CM\",\r\n\t\t\t\t\t\"value\": 170\r\n\t\t\t}\r\n }\r\n ],\r\n \"otherObservations\":[\r\n {\r\n \"observation\":\"None\",\r\n \"result\":\"Normal\",\r\n \"valueQuantity\": {\r\n\t\t\t\t\t\"unit\": \"CM\",\r\n\t\t\t\t\t\"value\": 170\r\n\t\t\t}\r\n }\r\n ],\r\n \"documents\":[{\r\n \"type\":\"WellnessRecord\",\r\n \"contentType\":\"application/pdf\",\r\n \"data\": \"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Mzc1Ci9YSGVpZ2h0IDUyOC4zMjAzMTMKL1N0ZW1WIDAKL0ZvbnRGaWxlMiAxNiAwIFIKPj4KZW5kb2JqCjE4IDAgb2JqCjw8Ci9UeXBlIC9Gb250Ci9TdWJ0eXBlIC9DSURGb250VHlwZTIKL0Jhc2VGb250IC9CWlpaWlorUm9ib3RvLVJlZ3VsYXIKL0NJRFN5c3RlbUluZm8gPDwKL1JlZ2lzdHJ5IChBZG9iZSkKL09yZGVyaW5nIChJZGVudGl0eSkKL1N1cHBsZW1lbnQgMAo+PgovRm9udERlc2NyaXB0b3IgMTcgMCBSCi9XIFswIFs5MDggNzEzLjM3ODkwNiA3MTMuMzc4OTA2IDY1Mi4zNDM3NSAyNDguMDQ2ODc1IDI0NC4xNDA2MjUgNTYzLjk2NDg0NCA4NzYuOTUzMTI1IDI0My4xNjQwNjMgNTUyLjI0NjA5NCA2MzYuNzE4NzUgNTcwLjMxMjUgNTUxLjI2OTUzMSA1MjMuNDM3NSA1NTAuNzgxMjUgNTMwLjI3MzQzOCAzMzguODY3MTg4IDI0My4xNjQwNjMgNTQzLjk0NTMxMyAzMjcuMTQ4NDM4IDU5My43NSA1MTYuMTEzMjgxIDU2Mi4wMTE3MTkgNTYyLjAxMTcxOSA1NjIuMDExNzE5IDU2Mi4wMTE3MTkgNDg0LjM3NSA1NjIuMDExNzE5IDU2Mi4wMTE3MTkgNTYyLjAxMTcxOSA1NjIuMDExNzE5IDg3My4wNDY4NzUgNjE2LjIxMDkzOCAyNzYuMzY3MTg4IDI0Mi4xODc1IDYzMC44NTkzNzUgMjYzLjY3MTg3NSAyNzEuOTcyNjU2IDU5Ni42Nzk2ODggNTY4LjM1OTM3NSA2NTYuMjUgNjUwLjg3ODkwNiAzNDcuNjU2MjUgNTYyLjAxMTcxOSA1NjIuMDExNzE5IDU2MS41MjM0MzggNjg3Ljk4ODI4MSA2NDguNDM3NSA1NjEuNTIzNDM4IDYwMC41ODU5MzhdXQovQ0lEVG9HSURNYXAgL0lkZW50aXR5Cj4+CmVuZG9iagoxOSAwIG9iago8PAovTGVuZ3RoIDMzNwovRmlsdGVyIC9GbGF0ZURlY29kZQo+PgpzdHJlYW0KeJxdUstugzAQvPMVe0wPEQFDaCSEVKUXDn2otKeqB2IvEVIxliEH/r7G4yZV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hSaeRYM/OC1xOdwlOx480lpmEZzGvKwIYw3O7ev2dcIFETqTyfRBfUg7ItEpSQGFjhGF/hcOmQnjCmVuZHN0cmVhbQplbmRvYmoKeHJlZgowIDI0CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwNjQ0OSAwMDAwMCBuIAowMDAwMDA2NTA2IDAwMDAwIG4gCjAwMDAwMDYzODcgMDAwMDAgbiAKMDAwMDAwNjM2NiAwMDAwMCBuIAowMDAwMDAwMzU5IDAwMDAwIG4gCjAwMDAwMDAyMTkgMDAwMDAgbiAKMDAwMDAwMDEwOSAwMDAwMCBuIAowMDAwMDAwMDE1IDAwMDAwIG4gCjAwMDAwMDAwNTkgMDAwMDAgbiAKMDAwMDAwNDgxMCAwMDAwMCBuIAowMDAwMDA2MjE4IDAwMDAwIG4gCjAwMDAwMDMzMTcgMDAwMDAgbiAKMDAwMDAwMzIyOSAwMDAwMCBuIAowMDAwMDAzMjU1IDAwMDAwIG4gCjAwMDAwMDMyODEgMDAwMDAgbiAKMDAwMDAwNjU1MyAwMDAwMCBuIAowMDAwMDAzMzkzIDAwMDAwIG4gCjAwMDAwMDM2NjEgMDAwMDAgbiAKMDAwMDAwNDQwMCAwMDAwMCBuIAowMDAwMDE0MjAzIDAwMDAwIG4gCjAwMDAwMDQ5NTkgMDAwMDAgbiAKMDAwMDAwNTIyNiAwMDAwMCBuIAowMDAwMDA1ODM2IDAwMDAwIG4gCnRyYWlsZXIKPDwKL1NpemUgMjQKL1Jvb3QgMyAwIFIKL0luZm8gMTIgMCBSCi9JRCBbPDdiOTliYmRjNzc5ZjAyYjc4MGViNDI1ZWU0ZjdmY2JmPiA8N2I5OWJiZGM3NzlmMDJiNzgwZWI0MjVlZTRmN2ZjYmY+XQo+PgpzdGFydHhyZWYKMjA3NzUKJSVFT0YK\"\r\n }]\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "localhost:8085/v1/bundle/wellness-record", - "host": [ - "localhost" - ], - "port": "8085", - "path": [ - "v1", - "bundle", - "wellness-record" - ] - } - }, - "response": [] - }, - { - "name": "immunization", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\r\n \"bundleType\":\"ImmunizationRecord\",\r\n \"careContextReference\":\"visit-{{$isoTimestamp}}\",\r\n \"authoredOn\":\"{{$isoTimestamp}}\",\r\n \"encounter\":\"\",\r\n \"patient\":{\r\n \"name\":\"Venu Ajitesh\",\r\n \"patientReference\":\"ajitesh6x\",\r\n \"gender\":\"male\",\r\n \"birthDate\":\"1940-04-27\"\r\n },\r\n \"practitioners\":[{\r\n \"name\":\"Dr.Venu Ajitesh\",\r\n \"practitionerId\":\"Predator\"\r\n }],\r\n \"organisation\":{\r\n \"facilityName\":\"Predator_HIP\",\r\n \"facilityId\":\"Predator_HIP\"\r\n },\r\n \"immunizations\":[{\r\n \"date\":\"2024-06-15\",\r\n \"vaccineName\":\"Paratyphoid vaccine\",\r\n \"lotNumber\":\"IN00004\",\r\n \"manufacturer\":\"NHA\",\r\n \"doseNumber\":\"3\"\r\n }],\r\n \"documents\":[{\r\n \"type\":\"immunization\",\r\n \"contentType\":\"application/pdf\",\r\n \"data\": \"JVBERi0xLjMKJf////8K\"\r\n }]\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "localhost:8085/v1/bundle/immunization", - "host": [ - "localhost" - ], - "port": "8085", - "path": [ - "v1", - "bundle", - "immunization" - ] - } - }, - "response": [] - }, - { - "name": "discharge-summary", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\r\n \"bundleType\":\"DischargeSummaryRecord\",\r\n \"careContextReference\":\"visist 21-03-2024\",\r\n \"patient\":{\r\n \"name\":\"Venu Ajitesh\",\r\n \"patientReference\":\"ajitesh6x\",\r\n \"gender\":\"male\",\r\n \"birthDate\":\"1940-04-27\"\r\n },\r\n \"practitioners\":[{\r\n \"name\":\"Dr.Venu Ajitesh\",\r\n \"practitionerId\":\"Predator\"\r\n }],\r\n \"carePlan\":{\r\n \"intent\":\"plan\",\r\n \"type\":\"Regular check up\",\r\n \"goal\":\"Reduce BP\",\r\n \"description\":\"Normal\",\r\n \"notes\":\"The patient has an HIGH BP, recommended to revisit on 29-10-2024\"\r\n },\r\n \"organisation\":{\r\n \"facilityName\":\"Predator_HIP\",\r\n \"facilityId\":\"Predator_HIP\"\r\n },\r\n \"chiefComplaints\":[\r\n {\r\n \"complaint\":\"Sugar\",\r\n \"recordedDate\":\"2024-05-20\",\r\n \"dateRange\":{\r\n \"from\":\"2018-04-27\",\r\n \"to\":\"2018-05-26\"\r\n }\r\n }\r\n ],\r\n \"physicalExaminations\":[\r\n {\r\n \"observation\":\"Height\",\r\n \"result\":\"Normal\",\r\n \"valueQuantity\": {\r\n\t\t\t\t\t\"unit\": \"CM\",\r\n\t\t\t\t\t\"value\": 170\r\n\t\t\t}\r\n }\r\n ],\r\n \"allergies\":[\r\n \"Walnuts\"\r\n ],\r\n \"medicalHistories\":[\r\n {\r\n \"complaint\":\"Sugar\",\r\n \"recordedDate\":\"2024-05-20\",\r\n \"dateRange\":{\r\n \"from\":\"2018-04-27\",\r\n \"to\":\"2018-05-26\"\r\n }\r\n }\r\n ],\r\n \"familyHistories\":[\r\n {\r\n \"relationship\":\"Friend\",\r\n \"observation\":\"Toxic\"\r\n }\r\n ],\r\n \"authoredOn\":\"2024-05-06T06:33:37.361Z\",\r\n \"medications\":[\r\n {\r\n \"medicine\":\"Aspirin 75 mg oral tablet\",\r\n \"dosage\":\"1-0-1\",\r\n \"timing\":\"2-5-D\",\r\n \"route\":\"Oral\",\r\n \"method\":\"swallow\",\r\n \"additionalInstructions\":\"Take them after food\"\r\n }\r\n ,{\r\n \"medicine\":\"Disprin\",\r\n \"dosage\":\"0-0-1\",\r\n \"timing\":\"1-2-D\",\r\n \"route\":\"Syrup\",\r\n \"method\":\"drink\",\r\n \"additionalInstructions\":\"Take them before food\"\r\n }\r\n ],\r\n \"diagnostics\":[{\r\n \"serviceName\":\"BloodTest\",\r\n \"serviceCategory\":\"Hematography\",\r\n \"result\":[{\r\n \"observation\":\"Height\",\r\n \"result\":\"Normal\",\r\n \"valueQuantity\": {\r\n\t\t\t\t\t\"unit\": \"CM\",\r\n\t\t\t\t\t\"value\": 170\r\n\t\t\t}\r\n }],\r\n \"authoredOn\":\"2024-05-08T06:33:37.361Z\",\r\n \"conclusion\":\"Normal\",\r\n \"presentedForm\":{\r\n \"contentType\":\"application/pdf\",\r\n \"data\":\"JVBERi0xLjMKJf////8K\"\r\n }\r\n }],\r\n \"procedures\":[\r\n {\r\n \"date\":\"2001-04-20\",\r\n \"status\":\"INPROGRESS\",\r\n \"procedureReason\":\"Severe\",\r\n \"outcome\":\"Healthy\",\r\n \"procedureName\":\"Operation\"\r\n }\r\n ],\r\n \"documents\":[{\r\n \"type\":\"OP record\",\r\n \"contentType\":\"application/pdf\",\r\n \"data\":\"JVBERi0xLjMKJf////8K\"\r\n }]\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "localhost:8085/v1/bundle/discharge-summary", - "host": [ - "localhost" - ], - "port": "8085", - "path": [ - "v1", - "bundle", - "discharge-summary" - ] - } - }, - "response": [] - }, - { - "name": "Get SnomedCodes", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "localhost:8085/v1/snomed/Medications", - "host": [ - "localhost" - ], - "port": "8085", - "path": [ - "v1", - "snomed", - "Medications" - ] - } - }, - "response": [] - } - ] + "info": { + "_postman_id": "6192a23b-5635-4954-9ba9-903e46159dfd", + "name": "FHIR", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", + "_exporter_id": "24014718" + }, + "item": [ + { + "name": "prescription", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var template = `", + "", + "", + "", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " {{#each response.entry}}", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " {{/each}}", + "
IDTypeStatusDateSubjectAuthorTitle
{{resource.id}}{{resource.resourceType}}{{resource.status}}{{resource.date}}{{resource.subject.reference}}{{resource.author.[0].reference}}{{resource.title}}
", + "`;", + "", + "function constructVisualizerPayload() {", + " return { response: pm.response.json() };", + "}", + "", + "pm.visualizer.set(template, constructVisualizerPayload());" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"bundleType\": \"PrescriptionRecord\",\r\n \"careContextReference\": \"visit-{{$isoTimestamp}}\",\r\n \"authoredOn\": \"2024-05-01T06:33:37.361Z\",\r\n \"encounter\": \"\",\r\n \"patient\": {\r\n \"name\": \"Venu Ajitesh\",\r\n \"patientReference\": \"ajitesh6x\",\r\n \"gender\": \"male\",\r\n \"birthDate\": \"1940-04-27\"\r\n },\r\n \"practitioners\": [\r\n {\r\n \"name\": \"Dr.Venu Ajitesh\",\r\n \"practitionerId\": \"Predator\"\r\n }\r\n ],\r\n \"organisation\": {\r\n \"facilityName\": \"Predator_HIP\",\r\n \"facilityId\": \"Predator_HIP\"\r\n },\r\n \"prescriptions\": [\r\n {\r\n \"medicine\": \"Glucosamine 1 g oral tablet\",\r\n \"dosage\": \"1-0-1\",\r\n \"timing\": \"1-1-D\",\r\n \"route\": \"Oral\",\r\n \"method\": \"swallow\",\r\n \"additionalInstructions\": \"Take them after food\",\r\n \"reason\": \"fever\"\r\n },\r\n {\r\n \"medicine\": \"Acetaminophen 100 mg/mL oral solution\",\r\n \"dosage\": \"0-0-1\",\r\n \"timing\": \"1-2-MO\",\r\n \"route\": \"Syrup\",\r\n \"method\": \"drink\",\r\n \"additionalInstructions\": \"Take them before food\",\r\n \"reason\": \"Cough\"\r\n }\r\n ],\r\n \"documents\": [\r\n {\r\n \"type\": \"Prescription\",\r\n \"contentType\": \"application/pdf\",\r\n \"data\": \"JVBERi0xLjMKJf////8K\"\r\n }\r\n ]\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "localhost:8085/v1/bundle/prescription", + "host": [ + "localhost" + ], + "port": "8085", + "path": [ + "v1", + "bundle", + "prescription" + ] + } + }, + "response": [] + }, + { + "name": "OPConsultation", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"bundleType\":\"OPConsultRecord\",\r\n \"careContextReference\":\"visist 21-03-2025\",\r\n \"visitDate\":\"2024-05-02T06:33:37.361Z\",\r\n \"patient\":{\r\n \"name\":\"Venu Ajitesh\",\r\n \"patientReference\":\"ajitesh6x\",\r\n \"gender\":\"male\",\r\n \"birthDate\":\"1940-04-27\"\r\n },\r\n \"practitioners\":[{\r\n \"name\":\"Dr.Venu Ajitesh\",\r\n \"practitionerId\":\"Predator\"\r\n }],\r\n \"organisation\":{\r\n \"facilityName\":\"Predator_HIP\",\r\n \"facilityId\":\"Predator_HIP\"\r\n },\r\n \"chiefComplaints\":[\r\n {\r\n \"complaint\":\"Dengue\",\r\n \"recordedDate\":\"2024-05-20\",\r\n \"dateRange\":{\r\n \"from\":\"2018-04-27\",\r\n \"to\":\"2018-05-26\"\r\n }\r\n }\r\n ],\r\n \"physicalExaminations\":[\r\n {\r\n \"observation\":\"Heavy drinker\",\r\n \"result\":\"heavy\"\r\n // \"valueQuantity\": {\r\n\t\t\t// \t\t\"unit\": \"CM\",\r\n\t\t\t// \t\t\"value\": 170\r\n\t\t\t// }\r\n }\r\n ],\r\n \"allergies\":[\r\n \"\"\r\n ],\r\n \"medicalHistories\": \r\n [\r\n {\r\n \"complaint\":\"Typhoid fever\",\r\n \"recordedDate\":\"2024-05-20\",\r\n \"dateRange\":{\r\n \"from\":\"2018-04-27\",\r\n \"to\":\"2018-05-26\"\r\n }\r\n }\r\n ],\r\n \"familyHistories\":[\r\n {\r\n \"relationship\":\"Friend\",\r\n \"observation\":\"Toxic\"\r\n }\r\n ],\r\n \"serviceRequests\":[\r\n {\r\n \"status\":\"ACTIVE\",\r\n \"details\":\"X-RAY\",\r\n \"specimen\":\"Lung cytologic material\"\r\n }\r\n ],\r\n \"medications\":\r\n [\r\n {\r\n \"medicine\":\"Nabilone 2 mg oral capsule\",\r\n \"dosage\":\"1-0-1\",\r\n \"timing\":\"2-5-D\",\r\n \"route\":\"Oral route\",\r\n \"method\":\"swallow\",\r\n \"additionalInstructions\":\"Take them after food\"\r\n }\r\n ,{\r\n \"medicine\":\"Nystatin 25000 unit/g vaginal cream\",\r\n \"dosage\":\"0-0-1\",\r\n \"timing\":\"1-2-D\",\r\n \"route\":\"Interstitial route (qualifier value)\",\r\n \"method\":\"drink\",\r\n \"additionalInstructions\":\"Take them before food\"\r\n }\r\n ],\r\n \"followups\":[\r\n {\r\n \"serviceType\":\"OPConsultation\",\r\n \"appointmentTime\":\"2024-05-20\",\r\n \"reason\":\"General\"\r\n }\r\n ],\r\n \"procedures\":[\r\n {\r\n \"date\":\"2001-04-20\",\r\n \"status\":\"INPROGRESS\",\r\n \"procedureReason\":\"Severe\",\r\n \"outcome\":\"Healthy\",\r\n \"procedureName\":\"Endodontic procedure\"\r\n }\r\n ],\r\n \"referrals\":[\r\n {\r\n \"status\":\"ACTIVE\",\r\n \"details\":\"Y-RAY\",\r\n \"specimen\":\"Pleural cytologic material\"\r\n }\r\n ],\r\n \"otherObservations\":[\r\n {\r\n \"observation\":\"Body weight\",\r\n // \"result\":\"Over weight\",\r\n \"valueQuantity\": {\r\n\t\t\t\t\t\"unit\": \"KG\",\r\n\t\t\t\t\t\"value\": 90\r\n\t\t\t\t}\r\n }\r\n ],\r\n \"documents\":[{\r\n \"type\":\"OP record\",\r\n \"contentType\":\"application/pdf\",\r\n \"data\":\"JVBERi0xLjMKJf////8K\"\r\n }]\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "localhost:8085/v1/bundle/op-consultation", + "host": [ + "localhost" + ], + "port": "8085", + "path": [ + "v1", + "bundle", + "op-consultation" + ] + } + }, + "response": [] + }, + { + "name": "health-document", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"bundleType\":\"HealthDocumentRecord\",\r\n \"careContextReference\":\"visist 21-03-2024\",\r\n \"patient\":{\r\n \"name\":\"Venu Ajitesh\",\r\n \"patientReference\":\"ajitesh6x\",\r\n \"gender\":\"male\",\r\n \"birthDate\":\"1940-04-27\"\r\n },\r\n \"authoredOn\":\"2024-05-03T06:33:37.361Z\",\r\n \"practitioners\":[{\r\n \"name\":\"Dr.Venu Ajitesh\",\r\n \"practitionerId\":\"Predator\"\r\n }],\r\n \"organisation\":{\r\n \"facilityName\":\"Predator_HIP\",\r\n \"facilityId\":\"Predator_HIP\"\r\n },\r\n \"encounter\":\"\",\r\n \"documents\":[{\r\n \"type\":\"health-document\",\r\n \"contentType\":\"application/pdf\",\r\n \"data\":\"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7Igi2NJ03WIdb8CPaOhwBlKEkoax7E5ZdLjP42F98TiJWKZ1T9XnPz8+/Kc1f/jRS/+d3B19aNHmf3r24eU/ho/Y+4/AKijvgugHu5+K373i9d+++9oPF/X9P6FV1H1lbmRzdHJlYW0gCmVuZG9iaiAKMiAwIG9iaiAKPDwgCi9UeXBlIC9QYWdlcyAKL0tpZHMgWyA4IDAgUiBdIAovQ291bnQgMSAKL01lZGlhQm94IDMgMCBSIAovQ3JvcEJveCA0IDAgUiAKPj4gCmVuZG9iaiAKMyAwIG9iaiAKWyAwIDAgNTk1IDg0MSBdIAplbmRvYmogCjQgMCBvYmogClsgMCAwIDU5NSA4NDEgXSAKZW5kb2JqIAo2IDAgb2JqIAo8PCAKL1Byb2NTZXQgNyAwIFIgCi9Gb250IDw8IAovOSA5IDAgUiAgCi9hIDEwIDAgUiAgCj4+IAovWE9iamVjdCA8PCAKL2ltZzAgMTEgMCBSICAKPj4gCj4+IAplbmRvYmogCjcgMCBvYmogClsgL1BERiAvVGV4dCAvSW1hZ2VCIC9JbWFnZUMgL0ltYWdlSSAgXSAKZW5kb2JqIAo4IDAgb2JqIAo8PCAKL1R5cGUgL1BhZ2UgCi9QYXJlbnQgMiAwIFIgCi9SZXNvdXJjZXMgNiAwIFIgCi9Db250ZW50cyBbIDUgMCBSIF0gCj4+IAplbmRvYmogCjkgMCBvYmogCjw8IAovVHlwZSAvRm9udCAKL1N1YnR5cGUgL1RydWVUeXBlIAovQmFzZUZvbnQgL0FBQUFBQStBcmlhbCxCb2xkIAovRmlyc3RDaGFyIDMyIAovTGFzdENoYXIgMTIxIAovV2lkdGhzIDE0IDAgUiAKL0ZvbnREZXNjcmlwdG9yIDE2IDAgUiAKL1RvVW5pY29kZSAxNSAwIFIgCj4+IAplbmRvYmogCjEwIDAgb2JqIAo8PCAKL1R5cGUgL0ZvbnQgCi9TdWJ0eXBlIC9UcnVlVHlwZSAKL0Jhc2VGb250IC9BQUFBQUIrQXJpYWwgCi9GaXJzdENoYXIgMzIgCi9MYXN0Q2hhciAxMjIgCi9XaWR0aHMgMTkgMCBSIAovRm9udERlc2NyaXB0b3IgMjEgMCBSIAovVG9Vbmljb2RlIDIwIDAgUiAKPj4gCmVuZG9iaiAKMTEgMCBvYmog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CjY2NyAKMCAKNzIyIAo2NjcgCjYxMSAKNzIyIAowIAowIAowIAowIAowIAowIAowIAowIAowIAowIAowIAo1NTYgCjYxMSAKNTU2IAo2MTEgCjU1NiAKMzMzIAo2MTEgCjYxMSAKMjc4IAowIAo1NTYgCjI3OCAKODg5IAo2MTEgCjYxMSAKNjExIAowIAozODkgCjU1NiAKMzMzIAo2MTEgCjU1NiAKMCAKMCAKNTU2IApdIAplbmRvYmogCjE2IDAgb2JqIAo8PCAKL1R5cGUgL0ZvbnREZXNjcmlwdG9yIAovQXNjZW50IDkwNSAKL0NhcEhlaWdodCA1MDAgCi9EZXNjZW50IC0yMTIgCi9GbGFncyA0IAovRm9udEJCb3ggMTcgMCBSIAovRm9udE5hbWUgL0FBQUFBQStBcmlhbCxCb2xkIAovSXRhbGljQW5nbGUgMAovU3RlbVYgMCAKL1N0ZW1IIDAgCi9BdmdXaWR0aCA0NzkgCi9Gb250RmlsZTIgMTggMCBSIAovTGVhZGluZyAwIAovTWF4V2lkdGggMjYyOCAKL01pc3NpbmdXaWR0aCA0NzkgCi9YSGVpZ2h0IDAgCj4+IAplbmRvYmogCjE3IDAgb2JqIApbIC02MjggLTM3NiAyMDAwIDEwNTYgXSAKZW5kb2JqIAoxOSAwIG9iaiAKWyAKMjc4IAowIAowIAowIAowIAowIAowIAowIAowIAowIAowIAowIAoyNzggCjMzMyAKMjc4IAoyNzggCjU1NiAKNTU2IAo1NTYgCjU1NiAKNTU2IAo1NTYgCjU1NiAKNTU2IAo1NTYgCjU1NiAKMjc4IAowIAowIAowIAowIAowIAowIAo2NjcgCjY2NyAKNzIyIAo3MjIgCjY2NyAKMCAKNzc4IAo3MjIgCjI3OCAKMCAKMCAKNTU2IAo4MzMgCjcyMiAKNzc4IAo2NjcgCjAgCjcyMiAKNjY3IAo2MTEgCjcyMiAKMCAKOTQ0IAowIAo2NjcgCjAgCjAgCjAgCjAgCjAgCjAgCjAgCjU1NiAKNTU2IAo1MDAgCjU1NiAKNTU2IAowIAo1NTYgCjU1NiAKMjIyIAoyMjIgCjAgCjIyMiAKODMzIAo1NTYgCjU1NiAKNTU2IAowIAozMzMgCjUwMCAKMjc4IAo1NTYgCjAgCjAgCjAgCjAgCjUwMCAKXSAKZW5kb2JqIAoyMSAwIG9iaiAKPDwgCi9UeXBlIC9Gb250RGVzY3JpcHRvciAKL0FzY2VudCA5MDUgCi9DYXBIZWlnaHQgNTAwIAovRGVzY2VudCAtMjEyIAovRmxhZ3MgNCAKL0ZvbnRCQm94IDIyIDAgUiAKL0ZvbnROYW1lIC9BQUFBQUIrQXJpYWwgCi9JdGFsaWNBbmdsZSAwCi9TdGVtViAwIAovU3RlbUggMCAKL0F2Z1dpZHRoIDQ0MSAKL0ZvbnRGaWxlMiAyMyAwIFIgCi9MZWFkaW5nIDAgCi9NYXhXaWR0aCAyNjY1IAovTWlzc2luZ1dpZHRoIDQ0MSAKL1hIZWlnaHQgMCAKPj4gCmVuZG9iaiAKMjIgMCBvYmogClsgLTY2NSAtMzI1IDIwMDAgMTA0MCBdIAplbmRvYmogCjI0IDAgb2JqIAooUG93ZXJlZCBCeSBDcnlzdGFsKSAKZW5kb2JqIAoyNSAwIG9iaiAKKENyeXN0YWwgUmVwb3J0cykgCmVuZG9iaiAKMjYgMCBvYmogCjw8IAovUHJvZHVjZXIgKFBvd2VyZWQgQnkgQ3J5c3RhbCkgIAovQ3JlYXRvciAoQ3J5c3RhbCBSZXBvcnRzKSAgCj4+IAplbmRvYmogCnhyZWYgCjAgMjcgCjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDAxNyAwMDAwMCBuIAowMDAwMDQyNDE0IDAwMDAwIG4gCjAwMDAwNDI1MTMgMDAwMDAgbiAKMDAwMDA0MjU0NyAwMDAwMCBuIAowMDAwMDAwMTk0IDAwMDAwIG4gCjAwMDAwNDI1ODEgMDAwMDAgbiAKMDAwMDA0MjY5MSAwMDAwMCBuIAowMDAwMDQyNzQ5IDAwMDAwIG4gCjAwMDAwNDI4NDEgMDAwMDAgbiAKMDAwMDA0MzAxOCAwMDAwMCBuIAowMDAwMDQzMTkxIDAwMDAwIG4gCjAwMDAwNTQ3MzUgMDAwMDAgbiAKMDAwMDA1NDc4OSAwMDAwMCBuIAowMDAwMDU1NjA0IDAwMDAwIG4gCjAwMDAwMDE0NzQgMDAwMDAgbiAKMDAwMDA1NTk5MCAwMDAwMCBuIAowMDAwMDU2MjY5IDAwMDAwIG4gCjAwMDAwMDIwOTUgMDAwMDAgbiAKMDAwMDA1NjMxMiAwMDAwMCBuIAowMDAwMDE4MTE3IDAwMDAwIG4gCjAwMDAwNTY3MTcgMDAwMDAgbiAKMDAwMDA1Njk5MSAwMDAwMCBuIAowMDAwMDE4Nzc5IDAwMDAwIG4gCjAwMDAwNTcwMzQgMDAwMDAgbiAKMDAwMDA1NzA3NCAwMDAwMCBuIAowMDAwMDU3MTExIDAwMDAwIG4gCnRyYWlsZXIgCjw8IAovU2l6ZSAyNyAKL1Jvb3QgMSAwIFIgCi9JbmZvIDI2IDAgUiAKPj4gCnN0YXJ0eHJlZiAKNTcxOTkgCiUlRU9GDQo=\"\r\n }]\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "localhost:8085/v1/bundle/health-document", + "host": [ + "localhost" + ], + "port": "8085", + "path": [ + "v1", + "bundle", + "health-document" + ] + } + }, + "response": [] + }, + { + "name": "diagnosticReport", + "protocolProfileBehavior": { + "disabledSystemHeaders": {} + }, + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + }, + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "// {\r\n// \"bundleType\": \"DiagnosticReportRecord\",\r\n// \"careContextReference\": \"visist 21-03-2024\",\r\n// \"visitDate\": \"2024-05-07T06:33:37.361Z\",\r\n// \"patient\": {\r\n// \"name\": \"Venu Ajitesh\",\r\n// \"patientReference\": \"ajitesh6x\",\r\n// \"gender\": \"male\",\r\n// \"birthDate\": \"1940-04-27\"\r\n// },\r\n// \"practitioners\": [\r\n// {\r\n// \"name\": \"Dr.Venu Ajitesh\",\r\n// \"practitionerId\": \"Predator\"\r\n// }\r\n// ],\r\n// \"organisation\": {\r\n// \"facilityName\": \"Predator_HIP\",\r\n// \"facilityId\": \"Predator_HIP\"\r\n// },\r\n// \"encounter\": \"Ambula\",\r\n// \"diagnostics\": [\r\n// {\r\n// \"serviceName\": \"BloodTest\",\r\n// \"authoredOn\":\"2024-11-23T21:34:38.989Z\",\r\n// \"serviceCategory\": \"Hematography\",\r\n// \"result\": [\r\n// {\r\n// \"observation\": \"Height\",\r\n// \"result\": \"Normal\",\r\n// \"valueQuantity\": {\r\n// \"unit\": \"CM\",\r\n// \"value\": 170\r\n// }\r\n// }\r\n// ],\r\n// \"conclusion\": \"Normal\",\r\n// \"presentedForm\":{\r\n// \"contentType\": \"application/pdf\",\r\n// \"data\": \"JVBERi0xLjMKJf////8K\"\r\n// }\r\n// }\r\n// ],\r\n// \"documents\":[{\r\n// \"type\": \"diagnosticReport\",\r\n// \"contentType\": \"application/pdf\",\r\n// \"data\": \"JVBERi0xLjMKJf////8K\"\r\n// }]\r\n// }\r\n{\r\n \"bundleType\": \"DiagnosticReportRecord\",\r\n \"careContextReference\": \"329998-1-1-1\",\r\n \"visitDate\": \"2024-05-28T17:04:50.539Z\",\r\n \"patient\": {\r\n \"name\": \"Himani Gupta\",\r\n \"patientReference\": \"329998\",\r\n \"gender\": \"Female\",\r\n \"birthDate\": \"1996-11-15\"\r\n },\r\n \"practitioners\": [\r\n {\r\n \"name\": \"xyz\",\r\n \"practitionerId\": \"8770092714\"\r\n }\r\n ],\r\n \"organisation\": {\r\n \"facilityName\": \"Ayela\",\r\n \"facilityId\": \"378608\"\r\n },\r\n \"encounter\": \"SICKLE\",\r\n \"diagnostics\": [\r\n {\r\n \"serviceName\": \"SICKLE\",\r\n \"authoredOn\": \"2024-05-28T17:04:50.539Z\",\r\n \"serviceCategory\": \"SICKLE\",\r\n \"result\": [\r\n {\r\n \"observation\": \"SICKLE\",\r\n \"result\": \"carrier\"\r\n }\r\n ],\r\n \"conclusion\": \"carrier\"\r\n }\r\n ]\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "localhost:8085/v1/bundle/diagnostic-report", + "host": [ + "localhost" + ], + "port": "8085", + "path": [ + "v1", + "bundle", + "diagnostic-report" + ] + } + }, + "response": [] + }, + { + "name": "wellness-record", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"bundleType\":\"WellnessRecord\",\r\n \"careContextReference\":\"visist 21-03-2025\",\r\n \"authoredOn\":\"2024-05-04T06:33:37.361Z\",\r\n \"patient\":{\r\n \"name\":\"Venu Ajitesh\",\r\n \"patientReference\":\"ajitesh6x\",\r\n \"gender\":\"male\",\r\n \"birthDate\":\"1940-04-27\"\r\n },\r\n \"practitioners\":[{\r\n \"name\":\"Dr.Venu Ajitesh\",\r\n \"practitionerId\":\"Predator\"\r\n }],\r\n \"organisation\":{\r\n \"facilityName\":\"Predator_HIP\",\r\n \"facilityId\":\"Predator_HIP\"\r\n },\r\n \"vitalSigns\":[\r\n {\r\n \"observation\":\"Height\",\r\n \"result\":\"Normal\",\r\n \"valueQuantity\": {\r\n\t\t\t\t\t\"unit\": \"CM\",\r\n\t\t\t\t\t\"value\": 170\r\n\t\t\t}\r\n }\r\n ],\r\n \"bodyMeasurements\":[\r\n {\r\n \"observation\":\"BMI\",\r\n \"result\":\"Normal\",\r\n \"valueQuantity\": {\r\n\t\t\t\t\t\"unit\": \"CM\",\r\n\t\t\t\t\t\"value\": 170\r\n\t\t\t}\r\n }\r\n ],\r\n \"physicalActivities\":[\r\n {\r\n \"observation\":\"Running\",\r\n \"result\":\"Normal\",\r\n \"valueQuantity\": {\r\n\t\t\t\t\t\"unit\": \"CM\",\r\n\t\t\t\t\t\"value\": 170\r\n\t\t\t}\r\n }\r\n ],\r\n \"generalAssessments\":[\r\n {\r\n \"observation\":\"Physico\",\r\n \"result\":\"Normal\",\r\n \"valueQuantity\": {\r\n\t\t\t\t\t\"unit\": \"CM\",\r\n\t\t\t\t\t\"value\": 170\r\n\t\t\t}\r\n }\r\n ],\"womanHealths\":[\r\n {\r\n \"observation\":\"Crazy\",\r\n \"result\":\"Normal\",\r\n \"valueQuantity\": {\r\n\t\t\t\t\t\"unit\": \"CM\",\r\n\t\t\t\t\t\"value\": 170\r\n\t\t\t}\r\n }\r\n ],\r\n \"lifeStyles\":[\r\n {\r\n \"observation\":\"Bad\",\r\n \"result\":\"Normal\",\r\n \"valueQuantity\": {\r\n\t\t\t\t\t\"unit\": \"CM\",\r\n\t\t\t\t\t\"value\": 170\r\n\t\t\t}\r\n }\r\n ],\r\n \"otherObservations\":[\r\n {\r\n \"observation\":\"None\",\r\n \"result\":\"Normal\",\r\n \"valueQuantity\": {\r\n\t\t\t\t\t\"unit\": \"CM\",\r\n\t\t\t\t\t\"value\": 170\r\n\t\t\t}\r\n }\r\n ],\r\n \"documents\":[{\r\n \"type\":\"WellnessRecord\",\r\n \"contentType\":\"application/pdf\",\r\n \"data\": \"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Mzc1Ci9YSGVpZ2h0IDUyOC4zMjAzMTMKL1N0ZW1WIDAKL0ZvbnRGaWxlMiAxNiAwIFIKPj4KZW5kb2JqCjE4IDAgb2JqCjw8Ci9UeXBlIC9Gb250Ci9TdWJ0eXBlIC9DSURGb250VHlwZTIKL0Jhc2VGb250IC9CWlpaWlorUm9ib3RvLVJlZ3VsYXIKL0NJRFN5c3RlbUluZm8gPDwKL1JlZ2lzdHJ5IChBZG9iZSkKL09yZGVyaW5nIChJZGVudGl0eSkKL1N1cHBsZW1lbnQgMAo+PgovRm9udERlc2NyaXB0b3IgMTcgMCBSCi9XIFswIFs5MDggNzEzLjM3ODkwNiA3MTMuMzc4OTA2IDY1Mi4zNDM3NSAyNDguMDQ2ODc1IDI0NC4xNDA2MjUgNTYzLjk2NDg0NCA4NzYuOTUzMTI1IDI0My4xNjQwNjMgNTUyLjI0NjA5NCA2MzYuNzE4NzUgNTcwLjMxMjUgNTUxLjI2OTUzMSA1MjMuNDM3NSA1NTAuNzgxMjUgNTMwLjI3MzQzOCAzMzguODY3MTg4IDI0My4xNjQwNjMgNTQzLjk0NTMxMyAzMjcuMTQ4NDM4IDU5My43NSA1MTYuMTEzMjgxIDU2Mi4wMTE3MTkgNTYyLjAxMTcxOSA1NjIuMDExNzE5IDU2Mi4wMTE3MTkgNDg0LjM3NSA1NjIuMDExNzE5IDU2Mi4wMTE3MTkgNTYyLjAxMTcxOSA1NjIuMDExNzE5IDg3My4wNDY4NzUgNjE2LjIxMDkzOCAyNzYuMzY3MTg4IDI0Mi4xODc1IDYzMC44NTkzNzUgMjYzLjY3MTg3NSAyNzEuOTcyNjU2IDU5Ni42Nzk2ODggNTY4LjM1OTM3NSA2NTYuMjUgNjUwLjg3ODkwNiAzNDcuNjU2MjUgNTYyLjAxMTcxOSA1NjIuMDExNzE5IDU2MS41MjM0MzggNjg3Ljk4ODI4MSA2NDguNDM3NSA1NjEuNTIzNDM4IDYwMC41ODU5MzhdXQovQ0lEVG9HSURNYXAgL0lkZW50aXR5Cj4+CmVuZG9iagoxOSAwIG9iago8PAovTGVuZ3RoIDMzNwovRmlsdGVyIC9GbGF0ZURlY29kZQo+PgpzdHJlYW0KeJxdUstugzAQvPMVe0wPEQFDaCSEVKUXDn2otKeqB2IvEVIxliEH/r7G4yZV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hSaeRYM/OC1xOdwlOx480lpmEZzGvKwIYw3O7ev2dcIFETqTyfRBfUg7ItEpSQGFjhGF/hcOmQnjCmVuZHN0cmVhbQplbmRvYmoKeHJlZgowIDI0CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwNjQ0OSAwMDAwMCBuIAowMDAwMDA2NTA2IDAwMDAwIG4gCjAwMDAwMDYzODcgMDAwMDAgbiAKMDAwMDAwNjM2NiAwMDAwMCBuIAowMDAwMDAwMzU5IDAwMDAwIG4gCjAwMDAwMDAyMTkgMDAwMDAgbiAKMDAwMDAwMDEwOSAwMDAwMCBuIAowMDAwMDAwMDE1IDAwMDAwIG4gCjAwMDAwMDAwNTkgMDAwMDAgbiAKMDAwMDAwNDgxMCAwMDAwMCBuIAowMDAwMDA2MjE4IDAwMDAwIG4gCjAwMDAwMDMzMTcgMDAwMDAgbiAKMDAwMDAwMzIyOSAwMDAwMCBuIAowMDAwMDAzMjU1IDAwMDAwIG4gCjAwMDAwMDMyODEgMDAwMDAgbiAKMDAwMDAwNjU1MyAwMDAwMCBuIAowMDAwMDAzMzkzIDAwMDAwIG4gCjAwMDAwMDM2NjEgMDAwMDAgbiAKMDAwMDAwNDQwMCAwMDAwMCBuIAowMDAwMDE0MjAzIDAwMDAwIG4gCjAwMDAwMDQ5NTkgMDAwMDAgbiAKMDAwMDAwNTIyNiAwMDAwMCBuIAowMDAwMDA1ODM2IDAwMDAwIG4gCnRyYWlsZXIKPDwKL1NpemUgMjQKL1Jvb3QgMyAwIFIKL0luZm8gMTIgMCBSCi9JRCBbPDdiOTliYmRjNzc5ZjAyYjc4MGViNDI1ZWU0ZjdmY2JmPiA8N2I5OWJiZGM3NzlmMDJiNzgwZWI0MjVlZTRmN2ZjYmY+XQo+PgpzdGFydHhyZWYKMjA3NzUKJSVFT0YK\"\r\n }]\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "localhost:8085/v1/bundle/wellness-record", + "host": [ + "localhost" + ], + "port": "8085", + "path": [ + "v1", + "bundle", + "wellness-record" + ] + } + }, + "response": [] + }, + { + "name": "immunization", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"bundleType\":\"ImmunizationRecord\",\r\n \"careContextReference\":\"visit-{{$isoTimestamp}}\",\r\n \"authoredOn\":\"{{$isoTimestamp}}\",\r\n \"encounter\":\"\",\r\n \"patient\":{\r\n \"name\":\"Venu Ajitesh\",\r\n \"patientReference\":\"ajitesh6x\",\r\n \"gender\":\"male\",\r\n \"birthDate\":\"1940-04-27\"\r\n },\r\n \"practitioners\":[{\r\n \"name\":\"Dr.Venu Ajitesh\",\r\n \"practitionerId\":\"Predator\"\r\n }],\r\n \"organisation\":{\r\n \"facilityName\":\"Predator_HIP\",\r\n \"facilityId\":\"Predator_HIP\"\r\n },\r\n \"immunizations\":[{\r\n \"date\":\"2024-06-15\",\r\n \"vaccineName\":\"Paratyphoid vaccine\",\r\n \"lotNumber\":\"IN00004\",\r\n \"manufacturer\":\"NHA\",\r\n \"doseNumber\":\"3\"\r\n }],\r\n \"documents\":[{\r\n \"type\":\"immunization\",\r\n \"contentType\":\"application/pdf\",\r\n \"data\": \"JVBERi0xLjMKJf////8K\"\r\n }]\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "localhost:8085/v1/bundle/immunization", + "host": [ + "localhost" + ], + "port": "8085", + "path": [ + "v1", + "bundle", + "immunization" + ] + } + }, + "response": [] + }, + { + "name": "discharge-summary", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"bundleType\":\"DischargeSummaryRecord\",\r\n \"careContextReference\":\"visist 21-03-2024\",\r\n \"patient\":{\r\n \"name\":\"Venu Ajitesh\",\r\n \"patientReference\":\"ajitesh6x\",\r\n \"gender\":\"male\",\r\n \"birthDate\":\"1940-04-27\"\r\n },\r\n \"practitioners\":[{\r\n \"name\":\"Dr.Venu Ajitesh\",\r\n \"practitionerId\":\"Predator\"\r\n }],\r\n \"carePlan\":{\r\n \"intent\":\"plan\",\r\n \"type\":\"Regular check up\",\r\n \"goal\":\"Reduce BP\",\r\n \"description\":\"Normal\",\r\n \"notes\":\"The patient has an HIGH BP, recommended to revisit on 29-10-2024\"\r\n },\r\n \"organisation\":{\r\n \"facilityName\":\"Predator_HIP\",\r\n \"facilityId\":\"Predator_HIP\"\r\n },\r\n \"chiefComplaints\":[\r\n {\r\n \"complaint\":\"Sugar\",\r\n \"recordedDate\":\"2024-05-20\",\r\n \"dateRange\":{\r\n \"from\":\"2018-04-27\",\r\n \"to\":\"2018-05-26\"\r\n }\r\n }\r\n ],\r\n \"physicalExaminations\":[\r\n {\r\n \"observation\":\"Height\",\r\n \"result\":\"Normal\",\r\n \"valueQuantity\": {\r\n\t\t\t\t\t\"unit\": \"CM\",\r\n\t\t\t\t\t\"value\": 170\r\n\t\t\t}\r\n }\r\n ],\r\n \"allergies\":[\r\n \"Walnuts\"\r\n ],\r\n \"medicalHistories\":[\r\n {\r\n \"complaint\":\"Sugar\",\r\n \"recordedDate\":\"2024-05-20\",\r\n \"dateRange\":{\r\n \"from\":\"2018-04-27\",\r\n \"to\":\"2018-05-26\"\r\n }\r\n }\r\n ],\r\n \"familyHistories\":[\r\n {\r\n \"relationship\":\"Friend\",\r\n \"observation\":\"Toxic\"\r\n }\r\n ],\r\n \"authoredOn\":\"2024-05-06T06:33:37.361Z\",\r\n \"medications\":[\r\n {\r\n \"medicine\":\"Aspirin 75 mg oral tablet\",\r\n \"dosage\":\"1-0-1\",\r\n \"timing\":\"2-5-D\",\r\n \"route\":\"Oral\",\r\n \"method\":\"swallow\",\r\n \"additionalInstructions\":\"Take them after food\"\r\n }\r\n ,{\r\n \"medicine\":\"Disprin\",\r\n \"dosage\":\"0-0-1\",\r\n \"timing\":\"1-2-D\",\r\n \"route\":\"Syrup\",\r\n \"method\":\"drink\",\r\n \"additionalInstructions\":\"Take them before food\"\r\n }\r\n ],\r\n \"diagnostics\":[{\r\n \"serviceName\":\"BloodTest\",\r\n \"serviceCategory\":\"Hematography\",\r\n \"result\":[{\r\n \"observation\":\"Height\",\r\n \"result\":\"Normal\",\r\n \"valueQuantity\": {\r\n\t\t\t\t\t\"unit\": \"CM\",\r\n\t\t\t\t\t\"value\": 170\r\n\t\t\t}\r\n }],\r\n \"authoredOn\":\"2024-05-08T06:33:37.361Z\",\r\n \"conclusion\":\"Normal\",\r\n \"presentedForm\":{\r\n \"contentType\":\"application/pdf\",\r\n \"data\":\"JVBERi0xLjMKJf////8K\"\r\n }\r\n }],\r\n \"procedures\":[\r\n {\r\n \"date\":\"2001-04-20\",\r\n \"status\":\"INPROGRESS\",\r\n \"procedureReason\":\"Severe\",\r\n \"outcome\":\"Healthy\",\r\n \"procedureName\":\"Operation\"\r\n }\r\n ],\r\n \"documents\":[{\r\n \"type\":\"OP record\",\r\n \"contentType\":\"application/pdf\",\r\n \"data\":\"JVBERi0xLjMKJf////8K\"\r\n }]\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "localhost:8085/v1/bundle/discharge-summary", + "host": [ + "localhost" + ], + "port": "8085", + "path": [ + "v1", + "bundle", + "discharge-summary" + ] + } + }, + "response": [] + }, + { + "name": "Get SnomedCodes", + "protocolProfileBehavior": { + "disableBodyPruning": true + }, + "request": { + "method": "GET", + "header": [], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "localhost:8085/v1/snomed/Medications", + "host": [ + "localhost" + ], + "port": "8085", + "path": [ + "v1", + "snomed", + "Medications" + ] + } + }, + "response": [] + }, + { + "name": "Invoice", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"bundleType\": \"Invoice\",\r\n \"careContextReference\": \"visit-{{$isoTimestamp}}\",\r\n \"invoiceDate\": \"2024-05-01T06:33:37.361Z\",\r\n \"status\": \"issued\",\r\n \"encounter\": \"\",\r\n \"patient\": {\r\n \"name\": \"Venu Ajitesh\",\r\n \"patientReference\": \"ajitesh6x\",\r\n \"gender\": \"male\",\r\n \"birthDate\": \"1940-04-27\"\r\n },\r\n \"practitioners\": [\r\n {\r\n \"name\": \"Dr.Venu Ajitesh\",\r\n \"practitionerId\": \"Predator\"\r\n }\r\n ],\r\n \"organisation\": {\r\n \"facilityName\": \"Predator_HIP\",\r\n \"facilityId\": \"Predator_HIP\"\r\n },\r\n \"invoice\": {\r\n \"id\": \"INV-12345\", // Required\r\n \"status\": \"issued\", // Required - issued | balanced | cancelled\r\n \"type\": \"Pharmacy\", // Consultation | Pharmacy | IPD | OPD | Others\r\n \"date\": \"2025-08-12T10:30:00+05:30\", // Required\r\n \"totalNet\": 2000.00, // Required\r\n \"totalGross\": 2200.00, // Required\r\n \"currency\": \"INR\", // Required\r\n \"paymentTerms\": \"Due in 15 days\", // Optional\r\n \"note\": \"Surgery + post-op medicines\" // Optional\r\n },\r\n \"chargeItems\": [ // Required - at least one\r\n {\r\n \"id\": \"CHG-002\",\r\n \"productType\": \"medication\", // medication | device | substance\r\n \"chargeType\": \"Pharmacy\",\r\n \"status\": \"billed\",\r\n \"description\": \"Amoxicillin 500mg\",\r\n \"quantity\": 14,\r\n \"price\": [\r\n {\r\n \"priceType\": \"base\", // base | surcharge | deduction | discount | SGST | CGST | informational\r\n \"amount\": \"100\"\r\n }\r\n ],\r\n \"medication\": { // Only for type=medication\r\n \"medicineName\": \"AMOX500\",\r\n \"manufacturer\": \"ABC Pharma\",\r\n \"medicationForm\": \"tablet\",\r\n \"lotNumber\": \"ABC123\",\r\n \"expiryDate\": \"{{$isoTimestamp}}\"\r\n }\r\n },\r\n {\r\n \"id\": \"CHG-003\",\r\n \"productType\": \"device\", // medication | device | substance\r\n \"chargeType\": \"OPD\",\r\n \"status\": \"billed\",\r\n \"description\": \"Surgical Gloves\",\r\n \"quantity\": 5,\r\n \"price\": [\r\n {\r\n \"priceType\": \"base\", // base | surcharge | deduction | discount | SGST | CGST | informational\r\n \"amount\": \"200\"\r\n }\r\n ],\r\n \"device\": { // Only for type=device\r\n \"udiCarrier\": \"UDI-GLV-001\",\r\n \"manufacturer\": \"MedGlove Inc.\",\r\n \"modelNumber\": \"MG-GLV-SRG\",\r\n \"lotNumber\": \"194847-0\",\r\n \"serialNumber\": \"SN-98347\",\r\n \"manufactureDate\": \"2025-01-10\",\r\n \"expirationDate\": \"2028-01-10\",\r\n \"status\": \"active\",\r\n \"safety\": [\r\n \"Latex Free\",\r\n \"Sterile\"\r\n ],\r\n \"deviceName\": \"Surgical Gloves\",\r\n \"note\": \"Used for major surgery\"\r\n }\r\n },\r\n {\r\n \"id\": \"CHG-004\",\r\n \"productType\": \"substance\", // medication | device | substance\r\n \"chargeType\": \"IPD\",\r\n \"status\": \"billed\",\r\n \"description\": \"Lab Reagent Kit\",\r\n \"quantity\": 1,\r\n \"price\": [\r\n {\r\n \"priceType\": \"base\", // base | surcharge | deduction | discount | SGST | CGST | informational\r\n \"amount\": \"300\"\r\n }\r\n ],\r\n \"substance\": { // Only for type=substance\r\n \"id\": \"\",\r\n \"code\": \"LAB-REAGENT-001\",\r\n \"category\": \"chemical\",\r\n \"description\": \"Used to treat infections\",\r\n \"expiry\": \"{{$isoTimestamp}}\",\r\n \"quantity\": \"2.0\"\r\n }\r\n }\r\n ],\r\n \"payment\": {\r\n \"method\": \"upi\", // Optional\r\n \"status\":\"active\", // Optional\r\n \"paymentDate\":\"\", /// Optional\r\n \"paidAmount\": 2200.00, // Optional\r\n \"transactionId\": \"TXN-98765\" // Optional\r\n }\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "localhost:8085/v1/bundle/invoice", + "host": [ + "localhost" + ], + "port": "8085", + "path": [ + "v1", + "bundle", + "invoice" + ] + } + }, + "response": [] + } + ] } \ No newline at end of file diff --git a/src/main/java/com/nha/abdm/fhir/mapper/Utils.java b/src/main/java/com/nha/abdm/fhir/mapper/Utils.java index a9d679c4..62ecfc14 100644 --- a/src/main/java/com/nha/abdm/fhir/mapper/Utils.java +++ b/src/main/java/com/nha/abdm/fhir/mapper/Utils.java @@ -24,6 +24,10 @@ public static InstantType getCurrentTimeStamp() throws ParseException { } public static DateTimeType getFormattedDateTime(String dateTimeString) throws ParseException { + if (dateTimeString == null || dateTimeString.isEmpty()) { + log.error("DateTime string is null or empty"); + return null; + } dateTimeString = dateTimeString.trim(); if (dateTimeString.length() <= 10) { return new DateTimeType(dateTimeString); @@ -34,6 +38,10 @@ public static DateTimeType getFormattedDateTime(String dateTimeString) throws Pa } public static Date getFormattedDate(String dateTimeString) throws ParseException { + if (dateTimeString == null || dateTimeString.isEmpty()) { + log.error("DateTime string is null or empty"); + return null; + } dateTimeString = dateTimeString.trim(); return new DateTimeType(dateTimeString).getValue(); } diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/BundleCompositionIdentifier.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/BundleCompositionIdentifier.java index aa426e44..97a28368 100644 --- a/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/BundleCompositionIdentifier.java +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/BundleCompositionIdentifier.java @@ -69,4 +69,6 @@ public class BundleCompositionIdentifier { public static final String BODY_MEASUREMENT = "Body Measurement"; public static final String VITAL_SIGNS = "Vital Signs"; public static final String DOCUMENT_REFERENCE = "Document Reference"; + + public static final String INVOICE_RECORD = "Invoice Record"; } diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/BundleResourceIdentifier.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/BundleResourceIdentifier.java index e1c012b9..3c114b19 100644 --- a/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/BundleResourceIdentifier.java +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/BundleResourceIdentifier.java @@ -33,4 +33,10 @@ public class BundleResourceIdentifier { public static final String VITAL_SIGNS = "VitalSigns"; public static final String MEDICATIONS = "Medications"; public static final String CARE_PLAN = "CarePlan"; + public static final String INVOICE = "Invoice"; + public static final String CHARGE_ITEM = "ChargeItem"; + public static final String SUBSTANCE = "Substance"; + public static final String DEVICE = "Device"; + public static final String MEDICATION = "Medication"; + public static final String INVOICE_PAYMENT_RECONCILIATION = "PaymentReconciliation"; } diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/ChargeItemStatus.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/ChargeItemStatus.java new file mode 100644 index 00000000..d86c2602 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/ChargeItemStatus.java @@ -0,0 +1,36 @@ +/* (C) 2025 */ +package com.nha.abdm.fhir.mapper.rest.common.constants; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +public enum ChargeItemStatus { + PLANNED("planned"), + BILLABLE("billable"), + NOT_BILLABLE("not-billable"), + ABORTED("aborted"), + BILLED("billed"), + ENTERED_IN_ERROR("entered-in-error"), + UNKNOWN("unknown"); + + private final String value; + + ChargeItemStatus(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @JsonCreator + public static ChargeItemStatus fromValue(String value) { + for (ChargeItemStatus status : ChargeItemStatus.values()) { + if (status.value.equalsIgnoreCase(value)) { + return status; + } + } + throw new IllegalArgumentException("Unknown enum value: " + value); + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/DeviceStatus.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/DeviceStatus.java new file mode 100644 index 00000000..717dceb6 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/DeviceStatus.java @@ -0,0 +1,33 @@ +/* (C) 2025 */ +package com.nha.abdm.fhir.mapper.rest.common.constants; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +@Getter +public enum DeviceStatus { + ACTIVE("active"), + INACTIVE("inactive"), + ENTERED_IN_ERROR("entered-in-error"), + UNKNOWN("unknown"); + + private final String value; + + @JsonValue + public String getValue() { + return value; + } + + @JsonCreator + public static DeviceStatus fromValue(String value) { + for (DeviceStatus status : DeviceStatus.values()) { + if (status.value.equalsIgnoreCase(value)) { + return status; + } + } + throw new IllegalArgumentException("Unknown DeviceStatus: " + value); + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/InvoicePaymentStatus.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/InvoicePaymentStatus.java new file mode 100644 index 00000000..d35e724e --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/InvoicePaymentStatus.java @@ -0,0 +1,34 @@ +/* (C) 2025 */ +package com.nha.abdm.fhir.mapper.rest.common.constants; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +@Getter +public enum InvoicePaymentStatus { + ACTIVE("active"), + CANCELLED("cancelled"), + DRAFT("draft"), + ENTERED_IN_ERROR("entered-in-error"), + NULL("null"); + + private final String value; + + @JsonValue + public String getValue() { + return value; + } + + @JsonCreator + public static InvoicePaymentStatus fromValue(String value) { + for (InvoicePaymentStatus status : InvoicePaymentStatus.values()) { + if (status.value.equalsIgnoreCase(value)) { + return status; + } + } + throw new IllegalArgumentException("Unknown value: " + value); + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/InvoicePriceType.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/InvoicePriceType.java new file mode 100644 index 00000000..2b75e922 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/InvoicePriceType.java @@ -0,0 +1,52 @@ +/* (C) 2025 */ +package com.nha.abdm.fhir.mapper.rest.common.constants; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +@Getter +public enum InvoicePriceType { + BASE("base", "00", "https://nrces.in/ndhm/fhir/r4/CodeSystem/ndhm-price-components", "MRP"), + SURCHARGE( + "surcharge", "01", "https://nrces.in/ndhm/fhir/r4/CodeSystem/ndhm-price-components", "Rate"), + DEDUCTION( + "deduction", + "02", + "https://nrces.in/ndhm/fhir/r4/CodeSystem/ndhm-price-components", + "Discount"), + DISCOUNT( + "discount", + "02", + "https://nrces.in/ndhm/fhir/r4/CodeSystem/ndhm-price-components", + "Discount"), + CGST("CGST", "03", "https://nrces.in/ndhm/fhir/r4/CodeSystem/ndhm-price-components", "Tax"), + SGST("SGST", "04", "https://nrces.in/ndhm/fhir/r4/CodeSystem/ndhm-price-components", "Tax"), + INFORMATIONAL( + "informational", + "informational", + "https://nrces.in/ndhm/fhir/r4/CodeSystem/ndhm-price-components", + "informational"); + + private final String value; + private final String code; + private final String system; + private final String display; + + @JsonValue + public String getValue() { + return value; + } + + @JsonCreator + public static InvoicePriceType fromValue(String value) { + for (InvoicePriceType type : values()) { + if (type.value.equalsIgnoreCase(value)) { + return type; + } + } + throw new IllegalArgumentException("Unknown value: " + value); + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/InvoiceProductType.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/InvoiceProductType.java new file mode 100644 index 00000000..0fec6d49 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/InvoiceProductType.java @@ -0,0 +1,32 @@ +/* (C) 2025 */ +package com.nha.abdm.fhir.mapper.rest.common.constants; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum InvoiceProductType { + MEDICATION("medication"), + DEVICE("device"), + SUBSTANCE("substance"); + + private final String value; + + @JsonValue + public String getValue() { + return this.value; + } + + @JsonCreator + public static InvoiceProductType fromValue(String value) { + for (InvoiceProductType type : InvoiceProductType.values()) { + if (type.value.equalsIgnoreCase(value)) { + return type; + } + } + throw new IllegalArgumentException("Invalid InvoiceProductType: " + value); + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/InvoiceStatus.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/InvoiceStatus.java new file mode 100644 index 00000000..c35c663d --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/InvoiceStatus.java @@ -0,0 +1,32 @@ +/* (C) 2025 */ +package com.nha.abdm.fhir.mapper.rest.common.constants; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import lombok.AllArgsConstructor; + +@AllArgsConstructor +public enum InvoiceStatus { + ISSUED("issued"), + BALANCED("balanced"), + CANCELLED("cancelled"), + DRAFT("draft"), + ENTERED_IN_ERROR("entered-in-error"); + + private final String value; + + @JsonCreator + public static InvoiceStatus fromValue(String value) { + for (InvoiceStatus status : InvoiceStatus.values()) { + if (status.value.equalsIgnoreCase(value)) { + return status; + } + } + throw new IllegalArgumentException("Unknown InvoiceStatus: " + value); + } + + @JsonValue + public String getValue() { + return value; + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/ResourceProfileIdentifier.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/ResourceProfileIdentifier.java index d8eae526..5519a3ad 100644 --- a/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/ResourceProfileIdentifier.java +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/ResourceProfileIdentifier.java @@ -47,4 +47,10 @@ public class ResourceProfileIdentifier { "https://nrces.in/ndhm/fhir/r4/StructureDefinition/HealthDocumentRecord"; public static final String PROFILE_PRESCRIPTION_RECORD = "https://nrces.in/ndhm/fhir/r4/StructureDefinition/PrescriptionRecord"; + public static final String PROFILE_CHARGE_ITEM_BILLING_CODES = + "https://nrces.in/ndhm/fhir/r4/CodeSystem/ndhm-billing-codes"; + public static final String PROFILE_PRICE_COMPONENT_TYPE = + "http://hl7.org/fhir/invoice-priceComponentType"; + public static final String PROFILE_INVOICE_PAYMENT_TYPE = + "http://terminology.hl7.org/CodeSystem/payment-type"; } diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/TypeIdentifiers.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/TypeIdentifiers.java new file mode 100644 index 00000000..15768fda --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/common/constants/TypeIdentifiers.java @@ -0,0 +1,7 @@ +/* (C) 2025 */ +package com.nha.abdm.fhir.mapper.rest.common.constants; + +public class TypeIdentifiers { + public static final String TYPE_CHARGE_ITEM = "ChargeItem"; + public static final String TYPE_INVOICE = "Invoice"; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/controller/BundleController.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/controller/BundleController.java index f6b36a2a..00d013fa 100644 --- a/src/main/java/com/nha/abdm/fhir/mapper/rest/controller/BundleController.java +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/controller/BundleController.java @@ -28,6 +28,7 @@ public class BundleController { @Autowired DiagnosticReportConverter diagnosticReportConverter; @Autowired DischargeSummaryConverter dischargeSummaryConverter; @Autowired WellnessRecordConverter wellnessRecordConverter; + @Autowired InvoiceRequestConverter invoiceRequestConverter; @Autowired SnomedService snomedService; FhirContext ctx = FhirContext.forR4(); @@ -178,4 +179,25 @@ public ResponseEntity createWellnessBundle( .contentType(MediaType.APPLICATION_JSON) .body(ctx.newJsonParser().encodeResourceToString(bundleResponse.getBundle())); } + + /** + * @param invoiceBundleRequest which has all the invoice details like charge items, total amount, + * tax, etc. + * @return FHIR bundle if no error found + * @throws ParseException while parsing the string into date + */ + @PostMapping("/invoice") + public ResponseEntity createInvoiceBundle( + @Valid @RequestBody InvoiceBundleRequest invoiceBundleRequest) { + + BundleResponse bundleResponse = invoiceRequestConverter.makeInvoiceBundle(invoiceBundleRequest); + + if (Objects.nonNull(bundleResponse.getError())) + return ResponseEntity.badRequest() + .contentType(MediaType.APPLICATION_JSON) + .body(FacadeError.builder().error(bundleResponse.getError()).build()); + return ResponseEntity.status(HttpStatus.CREATED) + .contentType(MediaType.APPLICATION_JSON) + .body(ctx.newJsonParser().encodeResourceToString(bundleResponse.getBundle())); + } } diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/InvoiceRequestConverter.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/InvoiceRequestConverter.java new file mode 100644 index 00000000..55eb2d44 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/converter/InvoiceRequestConverter.java @@ -0,0 +1,242 @@ +/* (C) 2025 */ +package com.nha.abdm.fhir.mapper.rest.converter; + +import com.nha.abdm.fhir.mapper.Utils; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.ErrorCode; +import com.nha.abdm.fhir.mapper.rest.common.helpers.BundleResponse; +import com.nha.abdm.fhir.mapper.rest.common.helpers.ErrorResponse; +import com.nha.abdm.fhir.mapper.rest.common.helpers.OrganisationResource; +import com.nha.abdm.fhir.mapper.rest.dto.compositions.MakeInvoiceComposition; +import com.nha.abdm.fhir.mapper.rest.dto.resources.*; +import com.nha.abdm.fhir.mapper.rest.dto.resources.invoice.*; +import com.nha.abdm.fhir.mapper.rest.exceptions.StreamUtils; +import com.nha.abdm.fhir.mapper.rest.requests.InvoiceBundleRequest; +import com.nha.abdm.fhir.mapper.rest.requests.helpers.ChargeItemResource; +import java.text.ParseException; +import java.util.*; +import org.hl7.fhir.r4.model.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.InvalidDataAccessResourceUsageException; +import org.springframework.stereotype.Service; + +@Service +public class InvoiceRequestConverter { + private static final Logger log = LoggerFactory.getLogger(InvoiceRequestConverter.class); + private final MakePatientResource makePatientResource; + private final MakePractitionerResource makePractitionerResource; + private final MakeOrganisationResource makeOrganisationResource; + private final MakeBundleMetaResource makeBundleMetaResource; + private final MakeEncounterResource makeEncounterResource; + private final MakeInvoiceComposition makeInvoiceComposition; + private final MakeChargeItemResource makeChargeItemResource; + private final MakeInvoiceResource makeInvoiceResource; + private final MakeInvoiceDeviceResource makeInvoiceDeviceResource; + private final MakeInvoiceSubstanceResource makeInvoiceSubstanceResource; + private final MakeInvoiceMedicationResource makeInvoiceMedicationResource; + private final MakeInvoicePaymentResource makeInvoicePaymentResource; + + @Autowired + public InvoiceRequestConverter( + MakePatientResource makePatientResource, + MakePractitionerResource makePractitionerResource, + MakeOrganisationResource makeOrganisationResource, + MakeBundleMetaResource makeBundleMetaResource, + MakeEncounterResource makeEncounterResource, + MakeInvoiceComposition makeInvoiceComposition, + MakeChargeItemResource makeChargeItemResource, + MakeInvoiceResource makeInvoiceResource, + MakeInvoiceDeviceResource makeInvoiceDeviceResource, + MakeInvoiceSubstanceResource makeInvoiceSubstanceResource, + MakeInvoiceMedicationResource makeInvoiceMedicationResource, + MakeInvoicePaymentResource makeInvoicePaymentResource) { + this.makePatientResource = makePatientResource; + this.makePractitionerResource = makePractitionerResource; + this.makeOrganisationResource = makeOrganisationResource; + this.makeBundleMetaResource = makeBundleMetaResource; + this.makeEncounterResource = makeEncounterResource; + this.makeInvoiceComposition = makeInvoiceComposition; + this.makeChargeItemResource = makeChargeItemResource; + this.makeInvoiceResource = makeInvoiceResource; + this.makeInvoiceDeviceResource = makeInvoiceDeviceResource; + this.makeInvoiceSubstanceResource = makeInvoiceSubstanceResource; + this.makeInvoiceMedicationResource = makeInvoiceMedicationResource; + this.makeInvoicePaymentResource = makeInvoicePaymentResource; + } + + public BundleResponse makeInvoiceBundle(InvoiceBundleRequest invoiceBundleRequest) { + try { + Bundle bundle = new Bundle(); + bundle.setId(UUID.randomUUID().toString()); + bundle.setType(Bundle.BundleType.DOCUMENT); + bundle.setTimestampElement(Utils.getCurrentTimeStamp()); + bundle.setMeta(makeBundleMetaResource.getMeta()); + bundle.setIdentifier( + new Identifier() + .setSystem(BundleUrlIdentifier.WRAPPER_URL) + .setValue(invoiceBundleRequest.getCareContextReference())); + + Patient patient = makePatientResource.getPatient(invoiceBundleRequest.getPatient()); + + List practitionerList = + Optional.ofNullable(invoiceBundleRequest.getPractitioners()) + .orElse(Collections.emptyList()) + .stream() + .map(StreamUtils.wrapException(makePractitionerResource::getPractitioner)) + .toList(); + + Organization organization = + makeOrganisationResource.getOrganization(invoiceBundleRequest.getOrganisation()); + + Encounter encounter = + makeEncounterResource.getEncounter( + patient, + invoiceBundleRequest.getEncounter() != null + ? invoiceBundleRequest.getEncounter() + : null, + invoiceBundleRequest.getInvoiceDate()); + + List manufactureList = new ArrayList<>(); + List deviceList = new ArrayList<>(); + List substanceList = new ArrayList<>(); + List medicationList = new ArrayList<>(); + + List chargeItemList = + Optional.ofNullable(invoiceBundleRequest.getChargeItems()) + .orElse(Collections.emptyList()) + .stream() + .map( + item -> { + try { + return generateProductAndChargeItem( + item, + deviceList, + substanceList, + medicationList, + manufactureList, + invoiceBundleRequest); + } catch (ParseException e) { + throw new RuntimeException(e); + } + }) + .toList(); + + Invoice invoice = + makeInvoiceResource.buildInvoice( + invoiceBundleRequest, chargeItemList, patient, organization); + + PaymentReconciliation paymentReconciliation = null; + if (Objects.nonNull(invoiceBundleRequest.getPayment())) { + paymentReconciliation = + makeInvoicePaymentResource.buildInvoicePayment(invoiceBundleRequest); + } + + Composition composition = + makeInvoiceComposition.makeCompositionResource( + patient, + practitionerList, + organization, + invoice, + chargeItemList, + deviceList, + substanceList, + medicationList, + paymentReconciliation); + + List entries = new ArrayList<>(); + + addEntry(entries, BundleResourceIdentifier.COMPOSITION, composition); + addEntry(entries, BundleResourceIdentifier.PATIENT, patient); + practitionerList.forEach( + practitioner -> addEntry(entries, BundleResourceIdentifier.PRACTITIONER, practitioner)); + if (organization != null) + addEntry(entries, BundleResourceIdentifier.ORGANISATION, organization); + if (encounter != null) addEntry(entries, BundleResourceIdentifier.ENCOUNTER, encounter); + manufactureList.forEach( + manufacturer -> addEntry(entries, BundleResourceIdentifier.MANUFACTURER, manufacturer)); + addEntry(entries, BundleResourceIdentifier.INVOICE, invoice); + + chargeItemList.forEach( + chargeItem -> addEntry(entries, BundleResourceIdentifier.CHARGE_ITEM, chargeItem)); + deviceList.forEach(device -> addEntry(entries, BundleResourceIdentifier.DEVICE, device)); + substanceList.forEach( + substance -> addEntry(entries, BundleResourceIdentifier.SUBSTANCE, substance)); + medicationList.forEach( + medication -> addEntry(entries, BundleResourceIdentifier.MEDICATION, medication)); + if (paymentReconciliation != null) { + addEntry( + entries, + BundleResourceIdentifier.INVOICE_PAYMENT_RECONCILIATION, + paymentReconciliation); + } + + bundle.setEntry(entries); + + return BundleResponse.builder().bundle(bundle).build(); + + } catch (Exception e) { + if (e instanceof InvalidDataAccessResourceUsageException) { + log.error(e.getMessage()); + return BundleResponse.builder() + .error( + new ErrorResponse( + ErrorCode.DB_ERROR, + " JDBCException Generic SQL Related Error, kindly check logs.")) + .build(); + } + return BundleResponse.builder() + .error(ErrorResponse.builder().code("1000").message(e.getMessage()).build()) + .build(); + } + } + + private void addEntry( + List entries, String resourceType, Resource resource) { + entries.add( + new Bundle.BundleEntryComponent() + .setFullUrl(resourceType + "/" + resource.getId()) + .setResource(resource)); + } + + private ChargeItem generateProductAndChargeItem( + ChargeItemResource item, + List deviceList, + List substanceList, + List medicationList, + List manufactureList, + InvoiceBundleRequest invoiceBundleRequest) + throws ParseException { + if (item.getProductType().getValue().equalsIgnoreCase(BundleResourceIdentifier.DEVICE)) { + Device device = makeInvoiceDeviceResource.getDevice(item.getDevice()); + deviceList.add(device); + return makeChargeItemResource.getChargeItems(item, device.getId()); + } else if (item.getProductType() + .getValue() + .equalsIgnoreCase(BundleResourceIdentifier.SUBSTANCE)) { + Substance substance = makeInvoiceSubstanceResource.getSubstance(item.getSubstance()); + substanceList.add(substance); + return makeChargeItemResource.getChargeItems(item, substance.getId()); + } else if (item.getProductType() + .getValue() + .equalsIgnoreCase(BundleResourceIdentifier.MEDICATION)) { + Organization manufacturer = new Organization(); + if (Objects.nonNull(item.getMedication().getManufacturer())) { + manufacturer = + makeOrganisationResource.getOrganization( + OrganisationResource.builder() + .facilityName(item.getMedication().getManufacturer()) + .build()); + manufactureList.add(manufacturer); + } + Medication medication = + makeInvoiceMedicationResource.getMedication(item.getMedication(), manufacturer); + medicationList.add(medication); + return makeChargeItemResource.getChargeItems(item, medication.getId()); + } else { + throw new IllegalArgumentException("Unknown product type: " + item.getProductType()); + } + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/config/DbLoader.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/config/DbLoader.java index 5e7816ae..d6a3cfd9 100644 --- a/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/config/DbLoader.java +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/config/DbLoader.java @@ -102,6 +102,8 @@ private TypeReference getTypeReference(String entityName) { case "SnomedObservation" -> new TypeReference>() {}; case "SnomedSpecimen" -> new TypeReference>() {}; case "SnomedVaccine" -> new TypeReference>() {}; + case "TypeChargeItem" -> new TypeReference>() {}; + case "TypeInvoice" -> new TypeReference>() {}; default -> throw new IllegalArgumentException("Unknown entity name: " + entityName); }; } @@ -129,6 +131,10 @@ public void addIndexesTransactional(String entityName) { "CREATE INDEX " + indexName + " ON " + tableName + " (\"code\", \"display\");"; case "SnomedVaccine" -> "CREATE INDEX " + indexName + " ON " + tableName + " (\"code\", \"display\");"; + case "TypeChargeItem" -> + "CREATE INDEX " + indexName + " ON " + tableName + " (\"code\", \"display\");"; + case "TypeInvoice" -> + "CREATE INDEX " + indexName + " ON " + tableName + " (\"code\", \"display\");"; default -> null; }; diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/TypeChargeItemRepo.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/TypeChargeItemRepo.java new file mode 100644 index 00000000..1a8a356b --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/TypeChargeItemRepo.java @@ -0,0 +1,18 @@ +/* (C) 2025 */ +package com.nha.abdm.fhir.mapper.rest.database.h2.repositories; + +import com.nha.abdm.fhir.mapper.rest.database.h2.tables.TypeChargeItem; +import java.util.List; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +@Repository +public interface TypeChargeItemRepo extends JpaRepository { + @Query( + value = + "SELECT * FROM \"type_charge_item\" sp WHERE sp.\"display\" ILIKE CONCAT('%', :display, '%') LIMIT 20", + nativeQuery = true) + List findByDisplay(@Param("display") String display); +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/TypeInvoiceRepo.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/TypeInvoiceRepo.java new file mode 100644 index 00000000..8bc3272c --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/repositories/TypeInvoiceRepo.java @@ -0,0 +1,18 @@ +/* (C) 2025 */ +package com.nha.abdm.fhir.mapper.rest.database.h2.repositories; + +import com.nha.abdm.fhir.mapper.rest.database.h2.tables.TypeInvoice; +import java.util.List; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +@Repository +public interface TypeInvoiceRepo extends JpaRepository { + @Query( + value = + "SELECT * FROM \"type_invoice\" sp WHERE sp.\"display\" ILIKE CONCAT('%', :display, '%') LIMIT 20", + nativeQuery = true) + List findByDisplay(@Param("display") String display); +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/TypeChargeItem.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/TypeChargeItem.java new file mode 100644 index 00000000..696a1f7e --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/TypeChargeItem.java @@ -0,0 +1,26 @@ +/* (C) 2025 */ +package com.nha.abdm.fhir.mapper.rest.database.h2.tables; + +import com.nha.abdm.fhir.mapper.rest.common.constants.TypeIdentifiers; +import com.nha.abdm.fhir.mapper.rest.database.h2.services.Displayable; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Entity +@AllArgsConstructor +@NoArgsConstructor +@Table(name = "type_charge_item") +@Builder +public class TypeChargeItem implements Displayable { + @Id public String code; + + public String display; + + public final String type = TypeIdentifiers.TYPE_CHARGE_ITEM; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/TypeInvoice.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/TypeInvoice.java new file mode 100644 index 00000000..3d7e5060 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/database/h2/tables/TypeInvoice.java @@ -0,0 +1,26 @@ +/* (C) 2025 */ +package com.nha.abdm.fhir.mapper.rest.database.h2.tables; + +import com.nha.abdm.fhir.mapper.rest.common.constants.TypeIdentifiers; +import com.nha.abdm.fhir.mapper.rest.database.h2.services.Displayable; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Entity +@AllArgsConstructor +@NoArgsConstructor +@Table(name = "type_invoice") +@Builder +public class TypeInvoice implements Displayable { + @Id public String code; + + public String display; + + public final String type = TypeIdentifiers.TYPE_INVOICE; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeInvoiceComposition.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeInvoiceComposition.java new file mode 100644 index 00000000..4ef92ea6 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/compositions/MakeInvoiceComposition.java @@ -0,0 +1,136 @@ +/* (C) 2025 */ +package com.nha.abdm.fhir.mapper.rest.dto.compositions; + +import com.nha.abdm.fhir.mapper.Utils; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleCompositionIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; +import java.text.ParseException; +import java.util.List; +import java.util.UUID; +import org.hl7.fhir.r4.model.*; +import org.springframework.stereotype.Service; + +@Service +public class MakeInvoiceComposition { + + public Composition makeCompositionResource( + Patient patient, + List practitionerList, + Organization organization, + Invoice invoice, + List chargeItemList, + List deviceList, + List substanceList, + List medicationList, + PaymentReconciliation paymentReconciliation) + throws ParseException { + + Composition composition = new Composition(); + + composition.setMeta( + new Meta().setVersionId("1").setLastUpdatedElement(Utils.getCurrentTimeStamp())); + + composition + .setType( + new CodeableConcept() + .addCoding( + new Coding() + .setSystem(BundleUrlIdentifier.SNOMED_URL) + .setCode(BundleCompositionIdentifier.INVOICE_RECORD) + .setDisplay(BundleCompositionIdentifier.INVOICE_RECORD))) + .setTitle(BundleCompositionIdentifier.INVOICE_RECORD); + + if (organization != null) { + composition.setCustodian(ref(BundleResourceIdentifier.ORGANISATION, organization.getId())); + } + + if (practitionerList != null && !practitionerList.isEmpty()) { + composition.setAuthor( + practitionerList.stream() + .map( + p -> + ref( + BundleResourceIdentifier.PRACTITIONER, + p.getId(), + p.getName().get(0).getText())) + .toList()); + } + + if (patient != null) { + composition.setSubject( + ref( + BundleResourceIdentifier.PATIENT, + patient.getId(), + patient.getName().get(0).getText())); + } + + if (invoice != null) { + composition.setDateElement(invoice.getDateElement()); + } + + Composition.SectionComponent invoiceSection = + new Composition.SectionComponent() + .setTitle(BundleResourceIdentifier.INVOICE) + .setCode( + new CodeableConcept() + .setText(BundleCompositionIdentifier.INVOICE_RECORD) + .addCoding( + new Coding() + .setCode(BundleCompositionIdentifier.INVOICE_RECORD) + .setDisplay(BundleCompositionIdentifier.INVOICE_RECORD) + .setSystem(BundleUrlIdentifier.SNOMED_URL))); + + if (invoice != null) { + invoiceSection.addEntry(ref(BundleResourceIdentifier.INVOICE, invoice.getId())); + } + + if (chargeItemList != null && !chargeItemList.isEmpty()) { + chargeItemList.forEach( + item -> invoiceSection.addEntry(ref(BundleResourceIdentifier.CHARGE_ITEM, item.getId()))); + } + + if (deviceList != null && !deviceList.isEmpty()) { + deviceList.forEach( + device -> invoiceSection.addEntry(ref(BundleResourceIdentifier.DEVICE, device.getId()))); + } + + if (substanceList != null && !substanceList.isEmpty()) { + substanceList.forEach( + substance -> + invoiceSection.addEntry(ref(BundleResourceIdentifier.SUBSTANCE, substance.getId()))); + } + + if (medicationList != null && !medicationList.isEmpty()) { + medicationList.forEach( + medication -> + invoiceSection.addEntry( + ref(BundleResourceIdentifier.MEDICATION, medication.getId()))); + } + + if (paymentReconciliation != null) { + invoiceSection.addEntry( + ref( + BundleResourceIdentifier.INVOICE_PAYMENT_RECONCILIATION, + paymentReconciliation.getId())); + } + + composition.addSection(invoiceSection); + + composition.setStatus(Composition.CompositionStatus.FINAL); + String compositionId = UUID.randomUUID().toString(); + composition.setIdentifier( + new Identifier().setSystem(BundleUrlIdentifier.WRAPPER_URL).setValue(compositionId)); + composition.setId(compositionId); + + return composition; + } + + private Reference ref(String resourceType, String id) { + return new Reference().setReference(resourceType + "/" + id).setType(resourceType); + } + + private Reference ref(String resourceType, String id, String display) { + return ref(resourceType, id).setDisplay(display); + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/invoice/MakeChargeItemResource.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/invoice/MakeChargeItemResource.java new file mode 100644 index 00000000..2d344d85 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/invoice/MakeChargeItemResource.java @@ -0,0 +1,82 @@ +/* (C) 2025 */ +package com.nha.abdm.fhir.mapper.rest.dto.resources.invoice; + +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.ResourceProfileIdentifier; +import com.nha.abdm.fhir.mapper.rest.database.h2.repositories.TypeChargeItemRepo; +import com.nha.abdm.fhir.mapper.rest.database.h2.tables.TypeChargeItem; +import com.nha.abdm.fhir.mapper.rest.requests.helpers.ChargeItemResource; +import java.util.Objects; +import java.util.UUID; +import org.apache.commons.lang3.StringUtils; +import org.hl7.fhir.r4.model.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class MakeChargeItemResource { + @Autowired private TypeChargeItemRepo typeChargeItemRepo; + + public ChargeItem getChargeItems(ChargeItemResource resource, String baseUrl) { + if (resource == null) { + return null; + } + + ChargeItem chargeItem = new ChargeItem(); + + if (StringUtils.isNotBlank(resource.getId())) { + chargeItem.setId(resource.getId()); + } else { + chargeItem.setId(UUID.randomUUID().toString()); + } + + if (StringUtils.isNotBlank(resource.getStatus().getValue())) { + try { + chargeItem.setStatus( + ChargeItem.ChargeItemStatus.valueOf(resource.getStatus().getValue().toUpperCase())); + } catch (IllegalArgumentException e) { + chargeItem.setStatus(ChargeItem.ChargeItemStatus.NULL); + } + } + + if (StringUtils.isNotBlank(resource.getProductType().getValue())) { + chargeItem.addIdentifier(new Identifier().setValue(resource.getProductType().getValue())); + } + + if (StringUtils.isNotBlank(resource.getChargeType())) { + CodeableConcept codeConcept = new CodeableConcept().setText(resource.getChargeType()); + + TypeChargeItem typeChargeItem = + typeChargeItemRepo.findByDisplay(resource.getChargeType()).stream() + .findFirst() + .orElse(null); + + if (typeChargeItem != null) { + codeConcept.addCoding( + new Coding() + .setCode(typeChargeItem.getCode()) + .setSystem(ResourceProfileIdentifier.PROFILE_CHARGE_ITEM_BILLING_CODES) + .setDisplay(typeChargeItem.getDisplay())); + } + chargeItem.setCode(codeConcept); + } + + if (StringUtils.isNotBlank(resource.getDescription())) { + chargeItem.addNote(new Annotation().setText(resource.getDescription())); + } + + if (resource.getQuantity() != null && resource.getQuantity() > 0) { + chargeItem.setQuantity(new Quantity().setValue(resource.getQuantity()).setUnit("pcs")); + } + + if (Objects.nonNull(resource.getMedication())) { + chargeItem.setProduct(new Reference(BundleResourceIdentifier.MEDICATION + "/" + baseUrl)); + } else if (Objects.nonNull(resource.getDevice())) { + chargeItem.setProduct(new Reference(BundleResourceIdentifier.DEVICE + "/" + baseUrl)); + } else if (Objects.nonNull(resource.getSubstance())) { + chargeItem.setProduct(new Reference(BundleResourceIdentifier.SUBSTANCE + "/" + baseUrl)); + } + + return chargeItem; + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/invoice/MakeInvoiceDeviceResource.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/invoice/MakeInvoiceDeviceResource.java new file mode 100644 index 00000000..87049631 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/invoice/MakeInvoiceDeviceResource.java @@ -0,0 +1,97 @@ +/* (C) 2025 */ +package com.nha.abdm.fhir.mapper.rest.dto.resources.invoice; + +import com.nha.abdm.fhir.mapper.Utils; +import com.nha.abdm.fhir.mapper.rest.requests.helpers.InvoiceDeviceResource; +import java.text.ParseException; +import java.util.List; +import java.util.UUID; +import org.apache.commons.lang3.StringUtils; +import org.hl7.fhir.r4.model.Annotation; +import org.hl7.fhir.r4.model.CodeableConcept; +import org.hl7.fhir.r4.model.Device; +import org.hl7.fhir.r4.model.Identifier; +import org.springframework.stereotype.Service; + +@Service +public class MakeInvoiceDeviceResource { + + public Device getDevice(InvoiceDeviceResource deviceResource) throws ParseException { + if (deviceResource == null) { + return null; + } + + Device device = new Device(); + + device.setId( + StringUtils.isNotBlank(deviceResource.getUdiCarrier()) + ? deviceResource.getUdiCarrier() + : UUID.randomUUID().toString()); + + if (StringUtils.isNotBlank(deviceResource.getDeviceName())) { + device.setDeviceName( + List.of( + new Device.DeviceDeviceNameComponent() + .setName(deviceResource.getDeviceName()) + .setType(Device.DeviceNameType.USERFRIENDLYNAME))); + } + + if (StringUtils.isNotBlank(deviceResource.getUdiCarrier())) { + device.setUdiCarrier( + List.of( + new Device.DeviceUdiCarrierComponent() + .setDeviceIdentifier(deviceResource.getUdiCarrier()))); + } + + if (StringUtils.isNotBlank(deviceResource.getManufacturer())) { + device.setManufacturer(deviceResource.getManufacturer()); + } + + if (StringUtils.isNotBlank(deviceResource.getSerialNumber())) { + device.setSerialNumber(deviceResource.getSerialNumber()); + } + if (StringUtils.isNotBlank(deviceResource.getLotNumber())) { + device.setLotNumber(deviceResource.getLotNumber()); + } + if (StringUtils.isNotBlank(deviceResource.getModelNumber())) { + device.setModelNumber(deviceResource.getModelNumber()); + } + + if (StringUtils.isNotBlank(deviceResource.getType())) { + device.setType(new CodeableConcept().setText(deviceResource.getType())); + } + + device.setManufactureDate(Utils.getFormattedDate(deviceResource.getManufactureDate())); + device.setExpirationDate(Utils.getFormattedDate(deviceResource.getExpirationDate())); + + if (StringUtils.isNotBlank(deviceResource.getStatus().getValue())) { + try { + device.setStatus(Device.FHIRDeviceStatus.fromCode(deviceResource.getStatus().getValue())); + } catch (Exception e) { + device.setStatus(Device.FHIRDeviceStatus.UNKNOWN); + } + } + + if (deviceResource.getSafety() != null && !deviceResource.getSafety().isEmpty()) { + List safetyConcepts = + deviceResource.getSafety().stream() + .filter(StringUtils::isNotBlank) + .map(s -> new CodeableConcept().setText(s)) + .toList(); + device.setSafety(safetyConcepts); + } + + if (StringUtils.isNotBlank(deviceResource.getNote())) { + device.setNote(List.of(new Annotation().setText(deviceResource.getNote()))); + } + + return device; + } + + /** Helper to safely add identifiers */ + private void addIdentifierIfPresent(Device device, String system, String value) { + if (StringUtils.isNotBlank(value)) { + device.addIdentifier(new Identifier().setSystem(system).setValue(value)); + } + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/invoice/MakeInvoiceMedicationResource.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/invoice/MakeInvoiceMedicationResource.java new file mode 100644 index 00000000..9084b918 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/invoice/MakeInvoiceMedicationResource.java @@ -0,0 +1,62 @@ +/* (C) 2025 */ +package com.nha.abdm.fhir.mapper.rest.dto.resources.invoice; + +import com.nha.abdm.fhir.mapper.Utils; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleUrlIdentifier; +import com.nha.abdm.fhir.mapper.rest.database.h2.services.SnomedService; +import com.nha.abdm.fhir.mapper.rest.requests.helpers.InvoiceMedicationResource; +import java.text.ParseException; +import java.util.Collections; +import java.util.UUID; +import lombok.extern.slf4j.Slf4j; +import org.hl7.fhir.r4.model.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +@Slf4j +public class MakeInvoiceMedicationResource { + @Autowired SnomedService snomedService; + + public Medication getMedication( + InvoiceMedicationResource medicationResource, Organization manufacturer) + throws ParseException { + + Medication medication = new Medication(); + medication.setId(UUID.randomUUID().toString()); + medication.setMeta( + new Meta().setVersionId("1").setLastUpdatedElement(Utils.getCurrentTimeStamp())); + + medication.setCode( + createCodeableConcept( + snomedService.getSnomedMedicineCode(medicationResource.getMedicineName()).getCode(), + medicationResource.getMedicineName())); + + medication.setForm( + createCodeableConcept( + snomedService + .getSnomedMedicineRouteCode(medicationResource.getMedicationForm()) + .getCode(), + medicationResource.getMedicationForm())); + + medication.setManufacturer( + new Reference() + .setReference(BundleResourceIdentifier.MANUFACTURER + "/" + manufacturer.getId())); + + medication.setBatch( + new Medication.MedicationBatchComponent() + .setLotNumber(medicationResource.getLotNumber()) + .setExpirationDate(Utils.getFormattedDate(medicationResource.getExpiryDate()))); + + return medication; + } + + /** Utility method to create CodeableConcept with SNOMED coding. */ + private CodeableConcept createCodeableConcept(String code, String display) { + return new CodeableConcept() + .setCoding( + Collections.singletonList(new Coding(BundleUrlIdentifier.SNOMED_URL, code, display))) + .setText(display); + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/invoice/MakeInvoicePaymentResource.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/invoice/MakeInvoicePaymentResource.java new file mode 100644 index 00000000..9aeaa151 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/invoice/MakeInvoicePaymentResource.java @@ -0,0 +1,63 @@ +/* (C) 2025 */ +package com.nha.abdm.fhir.mapper.rest.dto.resources.invoice; + +import com.nha.abdm.fhir.mapper.Utils; +import com.nha.abdm.fhir.mapper.rest.common.constants.ResourceProfileIdentifier; +import com.nha.abdm.fhir.mapper.rest.requests.InvoiceBundleRequest; +import java.text.ParseException; +import java.util.UUID; +import org.hl7.fhir.r4.model.*; +import org.springframework.stereotype.Service; + +@Service +public class MakeInvoicePaymentResource { + public PaymentReconciliation buildInvoicePayment(InvoiceBundleRequest invoiceBundleRequest) + throws ParseException { + + if (invoiceBundleRequest == null || invoiceBundleRequest.getPayment() == null) { + return null; + } + + var paymentReq = invoiceBundleRequest.getPayment(); + var invoiceReq = invoiceBundleRequest.getInvoice(); + + PaymentReconciliation paymentReconciliation = new PaymentReconciliation(); + paymentReconciliation.setId(UUID.randomUUID().toString()); + + if (paymentReq.getStatus() != null) { + paymentReconciliation.setStatus( + PaymentReconciliation.PaymentReconciliationStatus.fromCode( + paymentReq.getStatus().getValue())); + } + + if (paymentReq.getPaymentDate() != null) { + paymentReconciliation.setPaymentDate(Utils.getFormattedDate(paymentReq.getPaymentDate())); + } + + if (paymentReq.getPaidAmount() != null && paymentReq.getPaidAmount().doubleValue() > 0) { + paymentReconciliation.setPaymentAmount( + new Money() + .setValue(paymentReq.getPaidAmount()) + .setCurrency(invoiceReq != null ? invoiceReq.getCurrency() : "INR")); + } + + if (paymentReq.getTransactionId() != null && !paymentReq.getTransactionId().isBlank()) { + paymentReconciliation.setPaymentIdentifier( + new Identifier().setValue(paymentReq.getTransactionId())); + } + if (paymentReq.getMethod() != null && !paymentReq.getMethod().isBlank()) { + PaymentReconciliation.DetailsComponent detail = new PaymentReconciliation.DetailsComponent(); + detail.setType( + new CodeableConcept() + .addCoding( + new Coding() + .setSystem(ResourceProfileIdentifier.PROFILE_INVOICE_PAYMENT_TYPE) + .setCode(paymentReq.getMethod()) + .setDisplay(paymentReq.getMethod()))); + + paymentReconciliation.addDetail(detail); + } + + return paymentReconciliation; + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/invoice/MakeInvoicePriceComponent.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/invoice/MakeInvoicePriceComponent.java new file mode 100644 index 00000000..97385703 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/invoice/MakeInvoicePriceComponent.java @@ -0,0 +1,72 @@ +/* (C) 2025 */ +package com.nha.abdm.fhir.mapper.rest.dto.resources.invoice; + +import com.nha.abdm.fhir.mapper.rest.common.constants.ResourceProfileIdentifier; +import com.nha.abdm.fhir.mapper.rest.requests.InvoiceBundleRequest; +import com.nha.abdm.fhir.mapper.rest.requests.helpers.ChargeItemResource; +import com.nha.abdm.fhir.mapper.rest.requests.helpers.InvoicePrice; +import java.math.BigDecimal; +import java.util.List; +import java.util.Objects; +import org.hl7.fhir.r4.model.*; +import org.springframework.stereotype.Service; + +@Service +public class MakeInvoicePriceComponent { + + public List makeInvoicePriceComponents( + ChargeItemResource chargeItemResource, InvoiceBundleRequest invoiceBundleRequest) { + + if (chargeItemResource == null + || chargeItemResource.getPrice() == null + || chargeItemResource.getPrice().isEmpty() + || invoiceBundleRequest == null + || invoiceBundleRequest.getInvoice() == null + || invoiceBundleRequest.getInvoice().getCurrency() == null) { + return List.of(); + } + + String currency = invoiceBundleRequest.getInvoice().getCurrency(); + + return chargeItemResource.getPrice().stream() + .filter(Objects::nonNull) + .map(price -> buildPriceComponent(price, currency)) + .toList(); + } + + private Invoice.InvoiceLineItemPriceComponentComponent buildPriceComponent( + InvoicePrice price, String currency) { + + Invoice.InvoiceLineItemPriceComponentComponent priceComponent = + new Invoice.InvoiceLineItemPriceComponentComponent(); + + Invoice.InvoicePriceComponentType type = Invoice.InvoicePriceComponentType.INFORMATIONAL; + if (price.getPriceType() != null && !price.getPriceType().getValue().isBlank()) { + try { + type = Invoice.InvoicePriceComponentType.fromCode(price.getPriceType().getValue()); + } catch (Exception ignored) { + + } + } + priceComponent.setType(type); + + if (price.getPriceType() != null && !price.getPriceType().getValue().isBlank()) { + CodeableConcept codeConcept = + new CodeableConcept() + .addCoding( + new Coding() + .setSystem(ResourceProfileIdentifier.PROFILE_PRICE_COMPONENT_TYPE) + .setCode(price.getPriceType().getCode()) + .setDisplay(price.getPriceType().getDisplay())) + .setText(price.getPriceType().getValue()); + priceComponent.setCode(codeConcept); + } + + if (Objects.nonNull(price.getAmount()) && price.getAmount() > 0) { + Money money = + new Money().setCurrency(currency).setValue(BigDecimal.valueOf(price.getAmount())); + priceComponent.setAmount(money); + } + return priceComponent; + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/invoice/MakeInvoiceResource.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/invoice/MakeInvoiceResource.java new file mode 100644 index 00000000..09ce426b --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/invoice/MakeInvoiceResource.java @@ -0,0 +1,160 @@ +/* (C) 2025 */ +package com.nha.abdm.fhir.mapper.rest.dto.resources.invoice; + +import com.nha.abdm.fhir.mapper.Utils; +import com.nha.abdm.fhir.mapper.rest.common.constants.BundleResourceIdentifier; +import com.nha.abdm.fhir.mapper.rest.common.constants.ResourceProfileIdentifier; +import com.nha.abdm.fhir.mapper.rest.database.h2.repositories.TypeInvoiceRepo; +import com.nha.abdm.fhir.mapper.rest.database.h2.tables.TypeInvoice; +import com.nha.abdm.fhir.mapper.rest.requests.InvoiceBundleRequest; +import java.text.ParseException; +import java.util.*; +import java.util.stream.Collectors; +import org.apache.commons.lang3.StringUtils; +import org.hl7.fhir.r4.model.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class MakeInvoiceResource { + + private final MakeInvoicePriceComponent makeInvoicePriceComponent; + private final TypeInvoiceRepo typeInvoiceRepo; + + @Autowired + public MakeInvoiceResource( + MakeInvoicePriceComponent makeInvoicePriceComponent, TypeInvoiceRepo typeInvoiceRepo) { + this.makeInvoicePriceComponent = makeInvoicePriceComponent; + this.typeInvoiceRepo = typeInvoiceRepo; + } + + public Invoice buildInvoice( + InvoiceBundleRequest invoiceBundleRequest, + List chargeItems, + Patient patient, + Organization organisation) + throws ParseException { + + Invoice invoice = new Invoice(); + + if (invoiceBundleRequest.getInvoice() != null + && StringUtils.isNotBlank(invoiceBundleRequest.getInvoice().getId())) { + invoice.setId(invoiceBundleRequest.getInvoice().getId()); + } else { + invoice.setId(UUID.randomUUID().toString()); + } + + if (StringUtils.isNotBlank(invoiceBundleRequest.getStatus().getValue())) { + invoice.setStatus( + Invoice.InvoiceStatus.fromCode(invoiceBundleRequest.getStatus().getValue())); + } + + if (StringUtils.isNotBlank(invoiceBundleRequest.getInvoiceDate())) { + invoice.setDate(Utils.getFormattedDate(invoiceBundleRequest.getInvoiceDate())); + } + + if (patient != null && patient.hasId()) { + Reference patientRef = + new Reference(BundleResourceIdentifier.PATIENT + "/" + patient.getId()); + if (patient.hasName() && patient.getNameFirstRep().hasText()) { + patientRef.setDisplay(patient.getNameFirstRep().getText()); + } + invoice.setSubject(patientRef); + } + + if (organisation != null && organisation.hasId()) { + Reference orgRef = + new Reference(BundleResourceIdentifier.ORGANISATION + "/" + organisation.getId()); + if (StringUtils.isNotBlank(organisation.getName())) { + orgRef.setDisplay(organisation.getName()); + } + invoice.setIssuer(orgRef); + } + + if (invoiceBundleRequest.getInvoice() != null + && StringUtils.isNotBlank(invoiceBundleRequest.getInvoice().getType())) { + CodeableConcept codeConcept = new CodeableConcept(); + codeConcept.setText(invoiceBundleRequest.getInvoice().getType()); + + TypeInvoice typeInvoice = + typeInvoiceRepo.findByDisplay(invoiceBundleRequest.getInvoice().getType()).stream() + .findFirst() + .orElse(null); + + if (typeInvoice != null && StringUtils.isNotBlank(typeInvoice.getCode())) { + codeConcept.addCoding( + new Coding() + .setCode(typeInvoice.getCode()) + .setSystem(ResourceProfileIdentifier.PROFILE_CHARGE_ITEM_BILLING_CODES) + .setDisplay(typeInvoice.getDisplay())); + } + invoice.setType(codeConcept); + } + + if (invoiceBundleRequest.getInvoice() != null + && StringUtils.isNotBlank(invoiceBundleRequest.getInvoice().getPaymentTerms())) { + invoice.setPaymentTerms(invoiceBundleRequest.getInvoice().getPaymentTerms()); + } + + Map chargeItemMap = + chargeItems == null + ? Collections.emptyMap() + : chargeItems.stream() + .filter(Objects::nonNull) + .filter( + item -> + item.getIdElement() != null + && StringUtils.isNotBlank(item.getIdElement().getIdPart())) + .collect(Collectors.toMap(item -> item.getIdElement().getIdPart(), item -> item)); + + List lineItems = + invoiceBundleRequest.getChargeItems() == null + ? List.of() + : invoiceBundleRequest.getChargeItems().stream() + .filter(Objects::nonNull) + .filter( + item -> + StringUtils.isNotBlank(item.getId()) + && chargeItemMap.containsKey(item.getId())) + .map( + item -> { + Invoice.InvoiceLineItemComponent lineItem = + new Invoice.InvoiceLineItemComponent(); + lineItem.setChargeItem( + new Reference(BundleResourceIdentifier.CHARGE_ITEM + "/" + item.getId())); + makeInvoicePriceComponent + .makeInvoicePriceComponents(item, invoiceBundleRequest) + .forEach(lineItem::addPriceComponent); + return lineItem; + }) + .toList(); + + if (!lineItems.isEmpty()) { + invoice.setLineItem(lineItems); + } + + if (invoiceBundleRequest.getInvoice() != null) { + if (invoiceBundleRequest.getInvoice().getTotalGross() != null) { + invoice.setTotalGross( + new Money() + .setValue(invoiceBundleRequest.getInvoice().getTotalGross()) + .setCurrency(invoiceBundleRequest.getInvoice().getCurrency())); + } + + if (invoiceBundleRequest.getInvoice().getTotalNet() != null) { + invoice.setTotalNet( + new Money() + .setValue(invoiceBundleRequest.getInvoice().getTotalNet()) + .setCurrency(invoiceBundleRequest.getInvoice().getCurrency())); + } + + if (StringUtils.isNotBlank(invoiceBundleRequest.getInvoice().getNote())) { + invoice.setNote( + Collections.singletonList( + new Annotation().setText(invoiceBundleRequest.getInvoice().getNote()))); + } + } + + return invoice; + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/invoice/MakeInvoiceSubstanceResource.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/invoice/MakeInvoiceSubstanceResource.java new file mode 100644 index 00000000..6fca2ca2 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/dto/resources/invoice/MakeInvoiceSubstanceResource.java @@ -0,0 +1,54 @@ +/* (C) 2025 */ +package com.nha.abdm.fhir.mapper.rest.dto.resources.invoice; + +import com.nha.abdm.fhir.mapper.Utils; +import com.nha.abdm.fhir.mapper.rest.requests.helpers.InvoiceSubstanceResource; +import java.text.ParseException; +import java.util.Collections; +import java.util.UUID; +import org.apache.commons.lang3.StringUtils; +import org.hl7.fhir.r4.model.CodeableConcept; +import org.hl7.fhir.r4.model.Quantity; +import org.hl7.fhir.r4.model.Substance; +import org.springframework.stereotype.Service; + +@Service +public class MakeInvoiceSubstanceResource { + + public Substance getSubstance(InvoiceSubstanceResource substanceResource) throws ParseException { + Substance substance = new Substance(); + + String id = StringUtils.defaultIfBlank(substanceResource.getId(), UUID.randomUUID().toString()); + substance.setId(id); + + if (StringUtils.isNotBlank(substanceResource.getCode())) { + substance.setCode(new CodeableConcept().setText(substanceResource.getCode())); + } + + if (StringUtils.isNotBlank(substanceResource.getDescription())) { + substance.setDescription(substanceResource.getDescription()); + } + + if (StringUtils.isNotBlank(substanceResource.getCategory())) { + substance.setCategory( + Collections.singletonList( + new CodeableConcept().setText(substanceResource.getCategory()))); + } + + Substance.SubstanceInstanceComponent instance = new Substance.SubstanceInstanceComponent(); + + if (substanceResource.getQuantity() > 0) { + instance.setQuantity(new Quantity().setValue(substanceResource.getQuantity())); + } + + if (StringUtils.isNotBlank(substanceResource.getExpiry())) { + instance.setExpiry(Utils.getFormattedDate(substanceResource.getExpiry())); + } + + if (instance.hasQuantity() || instance.hasExpiry()) { + substance.setInstance(Collections.singletonList(instance)); + } + + return substance; + } +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/InvoiceBundleRequest.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/InvoiceBundleRequest.java new file mode 100644 index 00000000..0a27dfcb --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/InvoiceBundleRequest.java @@ -0,0 +1,57 @@ +/* (C) 2025 */ +package com.nha.abdm.fhir.mapper.rest.requests; + +import com.nha.abdm.fhir.mapper.rest.common.constants.InvoiceStatus; +import com.nha.abdm.fhir.mapper.rest.common.helpers.OrganisationResource; +import com.nha.abdm.fhir.mapper.rest.common.helpers.PatientResource; +import com.nha.abdm.fhir.mapper.rest.common.helpers.PractitionerResource; +import com.nha.abdm.fhir.mapper.rest.requests.helpers.ChargeItemResource; +import com.nha.abdm.fhir.mapper.rest.requests.helpers.InvoicePaymentResource; +import com.nha.abdm.fhir.mapper.rest.requests.helpers.InvoiceResource; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; +import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class InvoiceBundleRequest { + @Pattern(regexp = "Invoice") + @NotBlank(message = "BundleType is mandatory and must not be empty : 'Invoice'") + private String bundleType; + + @NotBlank(message = "careContextReference is mandatory and must not be empty") + private String careContextReference; + + @Pattern( + regexp = "^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z)?$", + message = "Value must match either yyyy-MM-dd or yyyy-MM-dd'T'HH:mm:ss.SSSZ") + @NotNull(message = "authoredOn is mandatory timestamp") private String invoiceDate; + + private String encounter; + + @Valid + @NotNull(message = "Patient demographic details are mandatory and must not be empty") private PatientResource patient; + + @Valid + @NotNull(message = "practitioners are mandatory and must not be empty") private List practitioners; + + @Valid + @NotNull(message = "organisation is mandatory") private OrganisationResource organisation; + + @NotNull(message = "invoice is mandatory") private InvoiceResource invoice; + + @NotNull(message = "status is mandatory") private InvoiceStatus status; + + @Valid + @NotNull(message = "chargeItems are mandatory and must not be empty") private List chargeItems; + + @Valid private InvoicePaymentResource payment; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ChargeItemResource.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ChargeItemResource.java new file mode 100644 index 00000000..af8dd7c2 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/ChargeItemResource.java @@ -0,0 +1,33 @@ +/* (C) 2025 */ +package com.nha.abdm.fhir.mapper.rest.requests.helpers; + +import com.nha.abdm.fhir.mapper.rest.common.constants.ChargeItemStatus; +import com.nha.abdm.fhir.mapper.rest.common.constants.InvoiceProductType; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ChargeItemResource { + private String id; + + @NotNull(message = "productType is mandatory and must not be empty") private InvoiceProductType productType; + + private String chargeType; + private ChargeItemStatus status; + private String description; + + @NotNull(message = "chargeItem quantity is mandatory and must not be empty") private Integer quantity; + + @Valid private List price; + @Valid private InvoiceMedicationResource medication; + @Valid private InvoiceDeviceResource device; + @Valid private InvoiceSubstanceResource substance; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/InvoiceDeviceResource.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/InvoiceDeviceResource.java new file mode 100644 index 00000000..17ade7f7 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/InvoiceDeviceResource.java @@ -0,0 +1,30 @@ +/* (C) 2025 */ +package com.nha.abdm.fhir.mapper.rest.requests.helpers; + +import com.nha.abdm.fhir.mapper.rest.common.constants.DeviceStatus; +import jakarta.validation.constraints.NotNull; +import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class InvoiceDeviceResource { + @NotNull(message = "deviceName is mandatory and must not be empty") private String deviceName; + + private String udiCarrier; + private String manufacturer; + private String lotNumber; + private String serialNumber; + private String modelNumber; + private String type; + private String manufactureDate; + private String expirationDate; + private DeviceStatus status; + private String note; + private List safety; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/InvoiceMedicationResource.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/InvoiceMedicationResource.java new file mode 100644 index 00000000..95cff0db --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/InvoiceMedicationResource.java @@ -0,0 +1,21 @@ +/* (C) 2025 */ +package com.nha.abdm.fhir.mapper.rest.requests.helpers; + +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class InvoiceMedicationResource { + @NotNull(message = "medicineName is mandatory and must not be empty") private String medicineName; + + private String manufacturer; + private String medicationForm; + private String lotNumber; + private String expiryDate; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/InvoicePaymentResource.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/InvoicePaymentResource.java new file mode 100644 index 00000000..2c236668 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/InvoicePaymentResource.java @@ -0,0 +1,27 @@ +/* (C) 2025 */ +package com.nha.abdm.fhir.mapper.rest.requests.helpers; + +import com.nha.abdm.fhir.mapper.rest.common.constants.InvoicePaymentStatus; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import java.math.BigDecimal; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class InvoicePaymentResource { + @NotBlank(message = "method is mandatory and must not be empty") + private String method; + + private String paymentDate; + private InvoicePaymentStatus status; + + @NotNull(message = "paidAmount is mandatory and must not be empty") private BigDecimal paidAmount; + + private String transactionId; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/InvoicePrice.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/InvoicePrice.java new file mode 100644 index 00000000..f637c9f9 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/InvoicePrice.java @@ -0,0 +1,19 @@ +/* (C) 2025 */ +package com.nha.abdm.fhir.mapper.rest.requests.helpers; + +import com.nha.abdm.fhir.mapper.rest.common.constants.InvoicePriceType; +import com.nha.abdm.fhir.mapper.rest.exceptions.NotBlankFields; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +@NotBlankFields +public class InvoicePrice { + private InvoicePriceType priceType; + private double amount; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/InvoiceResource.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/InvoiceResource.java new file mode 100644 index 00000000..7542841c --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/InvoiceResource.java @@ -0,0 +1,24 @@ +/* (C) 2025 */ +package com.nha.abdm.fhir.mapper.rest.requests.helpers; + +import java.math.BigDecimal; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class InvoiceResource { + private String id; + private String status; + private String type; + private String date; + private BigDecimal totalNet; + private BigDecimal totalGross; + private String currency; + private String paymentTerms; + private String note; +} diff --git a/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/InvoiceSubstanceResource.java b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/InvoiceSubstanceResource.java new file mode 100644 index 00000000..374c5824 --- /dev/null +++ b/src/main/java/com/nha/abdm/fhir/mapper/rest/requests/helpers/InvoiceSubstanceResource.java @@ -0,0 +1,24 @@ +/* (C) 2025 */ +package com.nha.abdm.fhir.mapper.rest.requests.helpers; + +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class InvoiceSubstanceResource { + private String id; + + @NotNull(message = "code is mandatory and must not be empty, ex: LAB-REAGENT-001") private String code; + + @NotNull(message = "category is mandatory and must not be empty, ex: Chemical") private String category; + + private String description; + private String expiry; + private double quantity; +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 3fda537d..f1ab1d77 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -16,9 +16,9 @@ spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.Ph # LOGGER -# You can disable the logs by commenting the below lines. +# You can enable the logs by commenting the below lines. logging.level.com.nha.abdm.wrapper=DEBUG -logging.level.org.springframework.web=DEBUG -logging.level.org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor=TRACE -logging.level.org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor=TRACE -logging.level.org.springframework.web.HttpLogging=TRACE \ No newline at end of file +#logging.level.org.springframework.web=DEBUG +#logging.level.org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor=TRACE +#logging.level.org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor=TRACE +#logging.level.org.springframework.web.HttpLogging=TRACE \ No newline at end of file diff --git a/src/main/resources/snomed/SnomedMedicineRoute.json b/src/main/resources/snomed/SnomedMedicineRoute.json index 7757e521..b9b1f65b 100644 --- a/src/main/resources/snomed/SnomedMedicineRoute.json +++ b/src/main/resources/snomed/SnomedMedicineRoute.json @@ -90,6 +90,7 @@ { "code": "419021003", "display": "Tumour cavity route" }, { "code": "419165009", "display": "Paravertebral route (qualifier value)" }, { "code": "419231003", "display": "Intrasinal route (qualifier value)" }, + { "code": "385055001", "display": "Tablet" }, { "code": "419243002", "display": "Transcervical route (qualifier value)" diff --git a/src/main/resources/snomed/TypeChargeItem.json b/src/main/resources/snomed/TypeChargeItem.json new file mode 100644 index 00000000..81b45e37 --- /dev/null +++ b/src/main/resources/snomed/TypeChargeItem.json @@ -0,0 +1,42 @@ +[ + { + "code" : "00", + "display" : "Consultation" + }, + { + "code" : "01", + "display" : "Pharmacy" + }, + { + "code" : "02", + "display" : "IPD" + }, + { + "code" : "03", + "display" : "OPD" + }, + { + "code" : "04", + "display" : "Pathology" + }, + { + "code" : "05", + "display" : "Medicines" + }, + { + "code" : "06", + "display" : "Nursing Charges" + }, + { + "code" : "07", + "display" : "Handling Charges" + }, + { + "code" : "08", + "display" : "Delivery Charges" + }, + { + "code" : "99", + "display" : "Others" + } +] \ No newline at end of file diff --git a/src/main/resources/snomed/TypeInvoice.json b/src/main/resources/snomed/TypeInvoice.json new file mode 100644 index 00000000..94212ce4 --- /dev/null +++ b/src/main/resources/snomed/TypeInvoice.json @@ -0,0 +1,22 @@ +[ + { + "code" : "00", + "display" : "Consultation" + }, + { + "code" : "01", + "display" : "Pharmacy" + }, + { + "code" : "02", + "display" : "IPD" + }, + { + "code" : "03", + "display" : "OPD" + }, + { + "code" : "99", + "display" : "Others" + } +] \ No newline at end of file From 1b3b5f36d1874a259df2d05516849c452ca34eb0 Mon Sep 17 00:00:00 2001 From: Venu-Ajitesh Date: Thu, 28 Aug 2025 15:17:28 +0530 Subject: [PATCH 11/12] Using gradle:8.5-jdk17 for docker --- Dockerfile | 23 +++++++++---------- docker-compose.yaml | 14 +++++++---- .../link/hipInitiated/HIPLinkV3Service.java | 2 +- 3 files changed, 22 insertions(+), 17 deletions(-) diff --git a/Dockerfile b/Dockerfile index 01831530..62388fd2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,17 +1,16 @@ -FROM maven:3.8.7-eclipse-temurin-17-focal -VOLUME /tmp +FROM gradle:8.5-jdk17 AS build WORKDIR /app -RUN apt-get install -y curl -RUN curl -L https://services.gradle.org/distributions/gradle-8.5-bin.zip -o gradle-8.6-bin.zip -RUN apt-get update -RUN apt-get install -y unzip -RUN unzip gradle-8.6-bin.zip -ENV GRADLE_HOME=/app/gradle-8.5 -ENV PATH=$PATH:$GRADLE_HOME/bin +COPY build.gradle settings.gradle gradlew gradle/ ./ +RUN gradle dependencies --no-daemon || true + COPY . . -RUN gradle build -x test +RUN gradle build -x test --no-daemon -EXPOSE 8082 +FROM eclipse-temurin:17-jdk-jammy +WORKDIR /app -ENTRYPOINT java -jar /app/build/libs/*-SNAPSHOT.jar --spring.data.mongodb.host=mongodb \ No newline at end of file +COPY --from=build /app/build/libs/*-SNAPSHOT.jar app.jar + +EXPOSE 8082 +ENTRYPOINT ["java", "-jar", "app.jar", "--spring.data.mongodb.host=mongodb"] \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml index 0ca3d792..cb35f25d 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -2,12 +2,17 @@ version: '3.8' services: abdm-wrapper: - build: . - image: abdm-wrapper + build: + context: . + dockerfile: Dockerfile + image: abdm-wrapper:latest ports: - '8082:8082' depends_on: - mongodb + environment: + SPRING_DATA_MONGODB_HOST: mongodb + SPRING_DATA_MONGODB_PORT: 27017 networks: - docker_network extra_hosts: @@ -20,15 +25,16 @@ services: mongodb: image: mongodb/mongodb-community-server:latest + restart: always ports: - '27017:27017' volumes: - - mongodb_vol:/data/db + - mongodb_data:/data/db networks: - docker_network volumes: - mongodb_vol: + mongodb_data: networks: docker_network: diff --git a/src/main/java/in/nha/abdm/wrapper/v3/hip/hrp/link/hipInitiated/HIPLinkV3Service.java b/src/main/java/in/nha/abdm/wrapper/v3/hip/hrp/link/hipInitiated/HIPLinkV3Service.java index 9c587a20..889bfcad 100644 --- a/src/main/java/in/nha/abdm/wrapper/v3/hip/hrp/link/hipInitiated/HIPLinkV3Service.java +++ b/src/main/java/in/nha/abdm/wrapper/v3/hip/hrp/link/hipInitiated/HIPLinkV3Service.java @@ -423,7 +423,7 @@ public FacadeV3Response hipContextNotify( .hip(ConsentHIP.builder().id(linkRecordsV3Request.getRequesterId()).build()) .hiTypes(Collections.singletonList(careContext.getHiType())) .date(Utils.getCurrentTimeStamp()) - .careContexts( + .careContext( ConsentCareContexts.builder() .careContextReference(careContext.getReferenceNumber()) .patientReference(patient.getPatientReference()) From 85961c1e8d3c974a96d54de7f5fe8bfa1c291bd0 Mon Sep 17 00:00:00 2001 From: Venu-Ajitesh Date: Thu, 28 Aug 2025 16:57:07 +0530 Subject: [PATCH 12/12] Added patient careContext serialization in add-patient api --- .../database/mongo/services/PatientV3Service.java | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/main/java/in/nha/abdm/wrapper/v3/database/mongo/services/PatientV3Service.java b/src/main/java/in/nha/abdm/wrapper/v3/database/mongo/services/PatientV3Service.java index 6f42bad8..2d729c4e 100644 --- a/src/main/java/in/nha/abdm/wrapper/v3/database/mongo/services/PatientV3Service.java +++ b/src/main/java/in/nha/abdm/wrapper/v3/database/mongo/services/PatientV3Service.java @@ -353,10 +353,20 @@ public FacadeV3Response upsertPatients(List patients) { } if (patient.getCareContexts() != null && !patient.getCareContexts().isEmpty()) { + List careContextDocs = + patient.getCareContexts().stream() + .map( + careContext -> + new Document() + .append("referenceNumber", careContext.getReferenceNumber()) + .append("display", careContext.getDisplay()) + .append("isLinked", Boolean.FALSE) + .append("hiType", careContext.getHiType())) + .collect(Collectors.toList()); + update.append( "$addToSet", - new Document( - FieldIdentifiers.CARE_CONTEXTS, new Document("$each", patient.getCareContexts()))); + new Document(FieldIdentifiers.CARE_CONTEXTS, new Document("$each", careContextDocs))); } if (!update.isEmpty()) { updates.add(new UpdateOneModel<>(filter, update, new UpdateOptions().upsert(true)));