/// <summary> /// Gets the start dateTime from OBR22 in the HL7 V2 message. /// </summary> /// <param name="genericMessage">The HL7 V2 message.</param> /// <returns></returns> internal static ISO8601DateTime GetQuantityTimingStartDateTime(HL7GenericMessage genericMessage) { DateTime dateTime = genericMessage.Order.First().Observation.First() .ObservationsReportID.QuantityTiming.startdatetime.TimestampValue.Value; return(new ISO8601DateTime(dateTime)); }
/// <summary> /// Validates the patient identification. /// </summary> /// <param name="hl7GenericMessage">The HL7 generic message.</param> /// <exception cref="MessageValidationException">PatientIdentification</exception> internal static void ValidatePatientIdentification(HL7GenericMessage hl7GenericMessage) { if (hl7GenericMessage.PatientIdentification == null) { throw new MessageValidationException(nameof(hl7GenericMessage.PatientIdentification)); } }
/// <summary> /// Gets the document creation time. /// </summary> /// <param name="genericMessage">The HL7 V2 message.</param> /// <returns></returns> internal static ISO8601DateTime GetReportDate(HL7GenericMessage genericMessage) { IList <DateTime> testResultDateTimes = new List <DateTime>(); foreach (var orderGroup in genericMessage.Order) { foreach (var observationGroup in orderGroup.Observation) { OBR obrSegment = observationGroup.ObservationsReportID; if (obrSegment.UniversalServiceID.identifier != TransformerConstants.ReportText) { testResultDateTimes.Add(obrSegment.ResultsRptStatusChngDateTime.Where(r => r.TimestampValue.HasValue) .OrderBy(r => r.TimestampValue.Value) .Single() .TimestampValue.Value); } } } DateTime reportDate = testResultDateTimes.Max(); return(reportDate.TimeOfDay.TotalSeconds == 0 ? new ISO8601DateTime(reportDate, ISO8601DateTime.Precision.Day) : new ISO8601DateTime(reportDate)); }
/// <summary> /// Gets the WhenResultsRptStatusChange time from OBR22 in the HL7 V2 message. /// </summary> /// <param name="genericMessage">The HL7 V2 message.</param> /// <returns></returns> internal static ISO8601DateTime GetResultsReportStatusChange(HL7GenericMessage genericMessage) { DateTime dateTime = genericMessage.Order.First().Observation.First() .ObservationsReportID.ResultsRptStatusChngDateTime.First().TimestampValue.Value; return(new ISO8601DateTime(dateTime)); }
/// <summary> /// Transforms the HL7 v2 diagnostic imaging message into a MHR compliant CDA document. /// </summary> /// <param name="message">HL7 message model.</param> /// <param name="metadata">Additional data required from the source system.</param> /// <param name="reportData"></param> /// <returns>Transformed diagnostic imaging report model</returns> public DiagnosticImagingTransformResult Transform(HL7GenericMessage message, DiagnosticImagingMetadata metadata, byte[] reportData = null) { _diagnosticImagingMessageValidator.Validate(message, metadata, reportData); return(_diagnosticImagingMessageTransformer.Transform(message, metadata, reportData)); }
/// <summary> /// Gets the report attachment. /// </summary> /// <param name="genericMessage">The HL7 V2 message.</param> /// <param name="reportData">Report data.</param> /// <returns></returns> internal static ReportAttachment GetReportAttachment(HL7GenericMessage genericMessage, byte[] reportData) { if (reportData != null) { OBX attachmentObx = genericMessage.Order.Last().Observation.Last().Result.SingleOrDefault(s => s.ValueType == "RP" && s.ObservationIdentifier.identifier.ToUpper() == TransformerConstants.PdfType); return(new ReportAttachment { Data = reportData, Filename = attachmentObx.ObservationValue.First() }); } else { OBX attachmentObx = genericMessage.Order.Last().Observation.Last().Result.Single(s => s.ValueType == "ED" && s.ObservationIdentifier.identifier.ToUpper() == TransformerConstants.PdfType); return(new ReportAttachment { Data = Convert.FromBase64String(attachmentObx.ObservationValue[4]), Filename = TransformerConstants.DefaultFilename }); } }
/// <summary> /// Create the order details from information in the HL7 V2 message. /// </summary> /// <param name="message">The HL7 V2 message.</param> /// <returns></returns> internal static OrderDetails CreateOrderDetails(HL7GenericMessage message) { // Order Details var orderDetails = DiagnosticImagingReport.CreateOrderDetails(); // Requester orderDetails.Requester = CreateRequester(message); return(orderDetails); }
/// <summary> /// Get the related document status. /// </summary> /// <param name="genericMessage">The HL7 V2 message.</param> /// <returns>Status</returns> internal static string GetRelatedDocumentStatus(HL7GenericMessage genericMessage) { string relatedDocumentStatus = null; foreach (OrderGroup orderGroup in genericMessage.Order) { relatedDocumentStatus = orderGroup.Observation.Any(i => i.ObservationsReportID.ResultStatus == "P" || i.ObservationsReportID.ResultStatus == "C") ? (orderGroup.Observation.Any(i => i.ObservationsReportID.ResultStatus == "P") ? "P" : "C") : "F"; } return(relatedDocumentStatus); }
/// <summary> /// Validates the attachment. /// </summary> /// <param name="hl7GenericMessage">The HL7 generic message.</param> /// <param name="reportData">The report attachment data.</param> /// <exception cref="MessageValidationException">Message does not contain an embedded PDF report</exception> internal static void ValidateAttachment(HL7GenericMessage hl7GenericMessage, byte[] reportData) { var hasRpObx = hl7GenericMessage.Order.Last().Observation.Last().Result.SingleOrDefault(s => s.ValueType == "RP" && s.ObservationIdentifier.identifier.ToUpper() == "PDF") != null; var hasEdObx = hl7GenericMessage.Order.Last().Observation.Last().Result.SingleOrDefault(s => s.ValueType == "ED" && s.ObservationIdentifier.identifier.ToUpper() == "PDF") != null; if (hasRpObx && reportData == null) { throw new MessageValidationException("reportData must be provided for messages containing an RP type attachment"); } if (hasEdObx && reportData != null) { throw new MessageValidationException("reportData cannot be provided for messages containing an ED type attachment"); } }
/// <summary> /// Create the legal authenticator from information in the HL7 V2 message. /// </summary> /// <param name="message">The HL7 V2 message.</param> /// <returns></returns> internal static IParticipationLegalAuthenticator CreateLegalAuthenticator(HL7GenericMessage message) { IParticipationLegalAuthenticator authenticator = BaseCDAModel.CreateAuthenticator(); // LegalAuthenticator/assignedEntity authenticator.Participant = BaseCDAModel.CreateParticipantForLegalAuthenticator(); // LegalAuthenticator/assignedEntity/assignedPerson // authenticator.Participant.Person = MapAssignedPerson(message); authenticator.Participant.Person = GetPrincipalResultInterpreter(message); // LegalAuthenticator/time/@value // V2 MAP : OBR-22 authenticator.Participant.DateTimeAuthenticated = GetResultsReportStatusChange(message); return(authenticator); }
/// <summary> /// Parses a pipe delimetered HL7 v2 pathology into a message model. /// </summary> /// <param name="payload">HL7 message.</param> /// <returns>HL7 pathology message model.</returns> /// <exception cref="ArgumentNullException">payload</exception> /// <exception cref="ArgumentException">Message is not a HL7 result message (ORU_R01)</exception> public HL7GenericMessage ParseHl7Message(string payload) { if (string.IsNullOrWhiteSpace(payload)) { throw new ArgumentNullException(nameof(payload)); } HL7GenericMessage message = (HL7GenericMessage)HL7Message.Parse(payload); if (!(message.MessageHeader.MessageType.messagetype == TransformerConstants.Hl7PathologyMessage && message.MessageHeader.MessageType.triggerevent == TransformerConstants.Hl7PathologyMessageType)) { throw new ArgumentException("Message is not a HL7 result message (ORU_R01)"); } return(message); }
/// <summary> /// Gets the PrincipalResultInterpreter from OBR32 in the HL7 V2 message. /// </summary> /// <param name="message">The HL7 V2 message.</param> /// <returns></returns> internal static IPerson GetPrincipalResultInterpreter(HL7GenericMessage message) { var person = BaseCDAModel.CreatePerson(); var nameCn = message.Order.First().Observation.First().ObservationsReportID.PrincipalResultInterpreter.name; person.PersonNames = new List <IPersonName> { GetPersonNameFromCn(nameCn) }; person.Identifiers = new List <Identifier> { BaseCDAModel.CreateHealthIdentifier(HealthIdentifierType.HPII, nameCn.IDnumberST) }; return(person); }
/// <summary> /// Gets the report name. /// </summary> /// <param name="genericMessage">The HL7 V2 message.</param> /// <returns>Report name.</returns> internal static string GetReportName(HL7GenericMessage genericMessage) { IList <string> resultName = new List <string>(); foreach (var orderGroup in genericMessage.Order) { foreach (var observationGroup in orderGroup.Observation) { OBR obrSegment = observationGroup.ObservationsReportID; if (obrSegment.UniversalServiceID.identifier != TransformerConstants.ReportText) { resultName.Add($"{obrSegment.UniversalServiceID.alternatetext ?? obrSegment.UniversalServiceID.text}"); } } } return(string.Join(",", resultName)); }
/// <summary> /// Create the pathology test results from information in the HL7 V2 message. /// </summary> /// <param name="genericMessage">The HL7 V2 message.</param> /// <returns>List of PathologyTestResult</returns> internal static IList <PathologyTestResult> CreatePathologyTestResults(HL7GenericMessage genericMessage) { IList <PathologyTestResult> pathologyTestResults = new List <PathologyTestResult>(); foreach (var orderGroup in genericMessage.Order) { foreach (var observationGroup in orderGroup.Observation) { OBR obrSegment = observationGroup.ObservationsReportID; if (obrSegment.UniversalServiceID.identifier != TransformerConstants.ReportText) { PathologyTestResult testResult = CreatePathologyTestResult(obrSegment); pathologyTestResults.Add(testResult); } } } return(pathologyTestResults); }
/// <summary> /// Validates the specified HL7 generic diagnostic imaging message. /// </summary> /// <param name="hl7GenericMessage">The HL7 generic diagnostic imaging message.</param> /// <param name="metadata">The metadata instance providing required information.</param> /// <param name="reportData">The diagnostic imaging report data, if not included in the path message.</param> /// <exception cref="MessageValidationException">hl7GenericMessage</exception> public void Validate(HL7GenericMessage hl7GenericMessage, DiagnosticImagingMetadata metadata, byte[] reportData) { if (hl7GenericMessage == null) { throw new MessageValidationException(nameof(hl7GenericMessage)); } if (metadata == null) { throw new MessageValidationException(nameof(metadata)); } ValidatePatientIdentification(hl7GenericMessage); ValidateOrder(hl7GenericMessage, metadata); ValidateAttachment(hl7GenericMessage, reportData); ValidateMetadata(metadata); }
/// <summary> /// Create the author from information in the HL7 V2 message. /// </summary> /// <param name="message">The HL7 V2 message.</param> /// <returns></returns> internal static IParticipationAuthorHealthcareProvider CreateAuthor(HL7GenericMessage message) { IParticipationAuthorHealthcareProvider author = BaseCDAModel.CreateAuthorHealthcareProvider(); // Document Author > Participant author.Participant = BaseCDAModel.CreateParticipantForAuthorHealthcareProvider(); // V2 MAP : OBR-22 author.AuthorParticipationPeriodOrDateTimeAuthored = BaseCDAModel.CreateParticipationPeriod(GetResultsReportStatusChange(message)); // Document Author > Role = AddressPurpose.Residential author.Role = BaseCDAModel.CreateRole(Occupation.Pathologist, CodingSystem.ANZSCORevision1); // Document Author > Participant > Person or Organisation or Device > Person > Person Name (Note: 1..* in ACI) var person = GetPrincipalResultInterpreter(message); author.Participant.Person = (IPersonHealthcareProvider)person; return(author); }
/// <summary> /// Sample code showing how an HL7 V2 diagnostic imaging message is transformed into a CDA document. /// </summary> public static void TransformHL7V2DiagnosticImagingToCdaDocumentSample() { // Obtain HL7 V2 report in a string. var v2DiagnosticImagingText = File.ReadAllText($"{AppContext.BaseDirectory}/Sample/imagingreport.hl7"); // Create an instance of the DiagnosticImagingTransformer. IDiagnosticImagingTransformer cdaImagingTransformer = new DiagnosticImagingTransformer(); // Parse the HL7 V2 string into an object model of the diagnostic imaging message. HL7GenericMessage hl7Message = cdaImagingTransformer.ParseHl7Message(v2DiagnosticImagingText); // Create a DiagnosticImagingMetadata instance (to provide additional information required for CDA document generation, that is not // available from the HL7 V2 report). DiagnosticImagingMetadata requiredMetadata = CreateRequiredMetadataForDiagnosticImagingCdaTransform(); // Transform the diagnostic imaging message into a DiagnosticImagingTransformResult. DiagnosticImagingTransformResult contains two // properties: // 1) DiagnosticImagingReport - This is the object model of the diagnostic imaging report CDA document. Prior to CDA document generation, // you can modify this instance to include more information for the CDA document. // 2) Attachment - This contains the byte array of the extracted report attachment // Note: reportData argument must not be supplied if the report attachment is found within the HL7 V2 report. Otherwise, reportData // has to be provided in this function. DiagnosticImagingTransformResult imagingTransformResult = cdaImagingTransformer.Transform(hl7Message, requiredMetadata); // This would be how you insert and external report not embedded in the OBX ED segment // byte[] reportdata = File.ReadAllBytes($"{AppContext.BaseDirectory}/Sample/prdfreport.pdf"); // DiagnosticImagingTransformResult imagingTransformResult = cdaImagingTransformer.Transform(hl7Message, requiredMetadata, reportdata); // An example of how you can modify DiagnosticImagingReport instance to include more information for the CDA document. // For more examples, please view the CDA.R5Samples project. imagingTransformResult.DiagnosticImagingReport.SCSContext.Author.Participant.Person.Organisation.Name = "Sample Organisation Name"; // Generates the CDA document XML XmlDocument cdaDocument = cdaImagingTransformer.Generate(imagingTransformResult.DiagnosticImagingReport); // Save the CDA document XML to file cdaDocument.Save($"{AppContext.BaseDirectory}/cdadocument.xml"); // Save the report attachment to file File.WriteAllBytes($"{AppContext.BaseDirectory}/{imagingTransformResult.Attachment.Filename}", imagingTransformResult.Attachment.Data); }
/// <summary> /// Gets the report status. /// </summary> /// <param name="message">The HL7 V2 message.</param> /// <returns>DocumentStatus</returns> internal static DocumentStatus GetReportStatus(HL7GenericMessage message) { string reportStatus = null; foreach (OrderGroup orderGroup in message.Order) { reportStatus = orderGroup.Observation.Any(i => i.ObservationsReportID.ResultStatus == "P") ? "I" : "F"; } switch (reportStatus) { case "I": return(DocumentStatus.Interim); case "F": return(DocumentStatus.Final); default: return(DocumentStatus.Final); } }
/// <summary> /// Create the requester from information in the HL7 V2 message. /// </summary> /// <param name="message">The HL7 V2 message.</param> /// <returns></returns> internal static IParticipationRequester CreateRequester(HL7GenericMessage message) { OBR obrSegment = message.Order.First().Observation.First().ObservationsReportID; XCN orderingProvider = obrSegment.OrderingProvider; var requester = BaseCDAModel.CreateRequester(); // Document Requester> Participant requester.Participant = BaseCDAModel.CreateParticipantForRequester(); var person = BaseCDAModel.CreatePersonWithOrganisation(); // Participation Period requester.ParticipationEndTime = GetQuantityTimingStartDateTime(message); // Document Requester > Role requester.Role = BaseCDAModel.CreateRole(Occupation.GeneralMedicalPractitioner, CodingSystem.ANZSCO); // Document Requester > Participant > Person or Organisation or Device > Person > Person Name var name1 = BaseCDAModel.CreatePersonName(); name1.FamilyName = orderingProvider.familylastname.familyname; name1.GivenNames = new List <string> { orderingProvider.givenname }; name1.Titles = new List <string> { orderingProvider.prefix }; person.PersonNames = new List <IPersonName> { name1 }; person.Organisation = BaseCDAModel.CreateEmploymentOrganisation(); requester.Participant.Person = person; return(requester); }
/// <summary> /// Create the related document from information in the HL7 V2 message. /// </summary> /// <param name="message">The HL7 V2 message.</param> /// <param name="reportAttachment">Report attachment.</param> /// <returns>RelatedDocument</returns> internal static RelatedDocument CreateRelatedDocument(HL7GenericMessage message, ReportAttachment reportAttachment) { RelatedDocument relatedDocument = PathologyResultReport.CreateRelatedDocument(); // Pathology PDF var attachmentPdf = BaseCDAModel.CreateExternalData(); attachmentPdf.ExternalDataMediaType = reportAttachment.MediaType; attachmentPdf.ByteArrayInput = new ByteArrayInput { ByteArray = reportAttachment.Data, FileName = reportAttachment.Filename }; relatedDocument.ExaminationResultRepresentation = attachmentPdf; DocumentDetails documentDetails = BaseCDAModel.CreateDocumentDetails(); // Report Date documentDetails.ReportDate = GetReportDate(message); // Result Status string status = GetRelatedDocumentStatus(message); Hl7V3ResultStatus resultStatus; if (!EnumHelper.TryGetEnumValue <Hl7V3ResultStatus, NameAttribute>(attribute => attribute.Code == status, out resultStatus)) { throw new ArgumentException("No matching Hl7V3ResultStatus value found"); } documentDetails.ReportStatus = BaseCDAModel.CreateResultStatus(resultStatus); // Report Name documentDetails.ReportDescription = GetReportName(message); relatedDocument.DocumentDetails = documentDetails; return(relatedDocument); }
/// <summary> /// Create a PathologyTransformResult instance (containing a PathologyResultReport and a ReportAttachment instance) from a HL7 V2 pathology message. /// The PathologyTransformResult instance is then used to generate a CDA document. /// </summary> /// <param name="hl7GenericMessage">The HL7 V2 message to transform.</param> /// <param name="metadata">Mandatory information to supplement the transform.</param> /// <param name="reportData">Report data.</param> /// <returns></returns> internal PathologyTransformResult Transform(HL7GenericMessage hl7GenericMessage, PathologyMetadata metadata, byte[] reportData = null) { PathologyResultReport pathologyResultReport = PathologyResultReport.CreatePathologyResultReport(); // Include Logo pathologyResultReport.IncludeLogo = false; // Set Creation Time pathologyResultReport.DocumentCreationTime = GetResultsReportStatusChange(hl7GenericMessage); // Document Status pathologyResultReport.DocumentStatus = GetReportStatus(hl7GenericMessage); #region Setup and populate the CDA context model // CDA Context model var cdaContext = PathologyResultReport.CreateCDAContext(); // Document Id cdaContext.DocumentId = BaseCDAModel.CreateIdentifier(BaseCDAModel.CreateOid(), null); // Set Id cdaContext.SetId = BaseCDAModel.CreateIdentifier(BaseCDAModel.CreateGuid(), null); // CDA Context Version cdaContext.Version = "1"; // Legal Authenticator cdaContext.LegalAuthenticator = CreateLegalAuthenticator(hl7GenericMessage); // Custodian cdaContext.Custodian = BaseCDAModel.CreateCustodian(); ICustodian custodian = BaseCDAModel.CreateParticipantCustodian(); cdaContext.Custodian.Participant = custodian; pathologyResultReport.CDAContext = cdaContext; #endregion #region Setup and Populate the SCS Context model // SCS Context model pathologyResultReport.SCSContext = PathologyResultReport.CreateSCSContext(); // Author Health Care Provider pathologyResultReport.SCSContext.Author = CreateAuthor(hl7GenericMessage); // The Reporting Pathologist pathologyResultReport.SCSContext.ReportingPathologist = CreateReportingPathologist(hl7GenericMessage); // Order Details pathologyResultReport.SCSContext.OrderDetails = CreateOrderDetails(hl7GenericMessage); // Subject Of Care pathologyResultReport.SCSContext.SubjectOfCare = CreateSubjectOfCare(hl7GenericMessage); #endregion #region Setup and populate the SCS Content model // SCS Content model pathologyResultReport.SCSContent = PathologyResultReport.CreateSCSContent(); ReportAttachment reportAttachment = GetReportAttachment(hl7GenericMessage, reportData); // Pathology Test Result pathologyResultReport.SCSContent.PathologyTestResult = CreatePathologyTestResults(hl7GenericMessage); // Related Document pathologyResultReport.SCSContent.RelatedDocument = CreateRelatedDocument(hl7GenericMessage, reportAttachment); #endregion FillInAdditionalMetadata(pathologyResultReport, metadata); return(new PathologyTransformResult { PathologyResultReport = pathologyResultReport, Attachment = reportAttachment }); }
/// <summary> /// Create the reporting pathologist from information in the HL7 V2 message. /// </summary> /// <param name="message">The HL7 V2 message.</param> /// <returns></returns> internal static IParticipationReportingPathologist CreateReportingPathologist(HL7GenericMessage message) { var nameCn = message.Order.First().Observation.First().ObservationsReportID.PrincipalResultInterpreter.name; var reportingPathologist = PathologyResultReport.CreateReportingPathologist(); // Document reportingPathologist > Participant reportingPathologist.Participant = PathologyResultReport.CreateParticipantForReportingPathologist(); // Participation Period reportingPathologist.ParticipationEndTime = GetResultsReportStatusChange(message); var person = BaseCDAModel.CreatePersonWithOrganisation(); // Document reportingPathologist > Participant > Person or Organisation or Device > Person > Person Name person.PersonNames = new List <IPersonName> { GetPersonNameFromCn(nameCn) }; // Document reportingPathologist > Participant > Entity Identifier person.Identifiers = new List <Identifier> { BaseCDAModel.CreateHealthIdentifier(HealthIdentifierType.HPII, nameCn.IDnumberST) }; reportingPathologist.Participant.Person = person; return(reportingPathologist); }
/// <summary> /// Create the diagnostic imaging examination test results from information in the HL7 V2 message. /// </summary> /// <param name="genericMessage">The HL7 V2 message.</param> /// <returns>List of DiagnosticImagingExaminationResult</returns> internal IList <IDiagnosticImagingExaminationResult> CreateImagingExaminationResults(HL7GenericMessage hl7GenericMessage) { IList <IDiagnosticImagingExaminationResult> imagingTestResults = new List <IDiagnosticImagingExaminationResult>(); foreach (var order in hl7GenericMessage.Order) { foreach (var observation in order.Observation) { OBR obrSegment = observation.ObservationsReportID; if (obrSegment.UniversalServiceID.identifier != TransformerConstants.ReportText) { IDiagnosticImagingExaminationResult testResult = DiagnosticImagingReport.CreateDiagnosticImagingExaminationResult(); // ReportingRadiologistForImagingExaminationResult var principalResultInterpreter = hl7GenericMessage.Order.First().Observation.First().ObservationsReportID.PrincipalResultInterpreter.name; testResult.ReportingRadiologistForImagingExaminationResult = GetNameStringFromCN(principalResultInterpreter); // ExaminationResultName testResult.ExaminationResultName = GetTestResultName(obrSegment.UniversalServiceID); // Modality DiagnosticService diagnosticService; if (EnumHelper.TryGetEnumValue <DiagnosticService, NameAttribute>( attribute => attribute.Code == obrSegment.DiagnosticServSectID, out diagnosticService)) { testResult.Modality = BaseCDAModel.CreateCodableText(obrSegment.DiagnosticServSectID, CodingSystem.HL7DiagnosticServiceSectionID, diagnosticService.GetAttributeValue <NameAttribute, string>(a => a.Name)); } else { testResult.Modality = BaseCDAModel.CreateCodableText(obrSegment.DiagnosticServSectID); } // Examination Procedure (Validate this, must be present) if (obrSegment.UniversalServiceID != null && !string.IsNullOrEmpty(obrSegment.UniversalServiceID.text)) { testResult.ExaminationProcedure = obrSegment.UniversalServiceID.text; } // Examination Details (Validate this, must be present) testResult.ExaminationDetails = DiagnosticImagingReport.CreateExaminationDetails(); testResult.ExaminationDetails.ImageDateTime = new ISO8601DateTime(obrSegment.ObservationDateTime.TimestampValue.GetValueOrDefault()); // Observation Date Time testResult.ObservationDateTime = new ISO8601DateTime(obrSegment.ObservationDateTime.TimestampValue.GetValueOrDefault()); // Overall Result Status Hl7V3ResultStatus resultStatus; if (EnumHelper.TryGetEnumValue <Hl7V3ResultStatus, NameAttribute>( attribute => attribute.Code == obrSegment.ResultStatus, out resultStatus)) { testResult.OverallResultStatus = BaseCDAModel.CreateResultStatus(resultStatus); } else { testResult.OverallResultStatus = BaseCDAModel.CreateCodableText(NullFlavour.NoInformation); } imagingTestResults.Add(testResult); } } } return(imagingTestResults); }
/// <summary> /// Create a DiagnosticImagingTransformResult instance (containing a DiagnosticImagingReport and a ReportAttachment instance) from a /// HL7 V2 diagnostic imaging message. The DiagnosticImagingTransformResult instance is then used to generate a CDA document. /// </summary> /// <param name="hl7GenericMessage">The HL7 V2 message to transform.</param> /// <param name="metadata">Mandatory information to supplement the transform.</param> /// <param name="reportData">Report data.</param> /// <returns></returns> internal DiagnosticImagingTransformResult Transform(HL7GenericMessage hl7GenericMessage, DiagnosticImagingMetadata metadata, byte[] reportData = null) { DiagnosticImagingReport diagnosticImagingReport = DiagnosticImagingReport.CreateDiagnosticImagingReport(); // Include Logo diagnosticImagingReport.IncludeLogo = false; // Set Creation Time diagnosticImagingReport.DocumentCreationTime = GetResultsReportStatusChange(hl7GenericMessage); // Document Status diagnosticImagingReport.DocumentStatus = GetReportStatus(hl7GenericMessage); #region Setup and populate the CDA context model // CDA Context model var cdaContext = DiagnosticImagingReport.CreateCDAContext(); // Document Id cdaContext.DocumentId = BaseCDAModel.CreateIdentifier(BaseCDAModel.CreateOid(), null); // Set Id cdaContext.SetId = BaseCDAModel.CreateIdentifier(BaseCDAModel.CreateGuid(), null); // CDA Context Version cdaContext.Version = "1"; // Legal Authenticator cdaContext.LegalAuthenticator = CreateLegalAuthenticator(hl7GenericMessage); // Custodian cdaContext.Custodian = BaseCDAModel.CreateCustodian(); ICustodian custodian = BaseCDAModel.CreateParticipantCustodian(); cdaContext.Custodian.Participant = custodian; diagnosticImagingReport.CDAContext = cdaContext; #endregion #region Setup and Populate the SCS Context model // SCS Context model diagnosticImagingReport.SCSContext = DiagnosticImagingReport.CreateSCSContext(); // Author Health Care Provider diagnosticImagingReport.SCSContext.Author = CreateAuthor(hl7GenericMessage); // The Reporting Radiologist diagnosticImagingReport.SCSContext.ReportingRadiologist = CreateReportingRadiologist(hl7GenericMessage); // Order Details diagnosticImagingReport.SCSContext.OrderDetails = CreateOrderDetails(hl7GenericMessage); // Subject Of Care diagnosticImagingReport.SCSContext.SubjectOfCare = CreateSubjectOfCare(hl7GenericMessage); #endregion #region Setup and populate the SCS Content model // SCS Content model diagnosticImagingReport.SCSContent = DiagnosticImagingReport.CreateSCSContent(); ReportAttachment reportAttachment = GetReportAttachment(hl7GenericMessage, reportData); // Imaging Examination Results diagnosticImagingReport.SCSContent.ImagingExaminationResults = CreateImagingExaminationResults(hl7GenericMessage); // Related Document diagnosticImagingReport.SCSContent.RelatedDocument = CreateRelatedDocument(hl7GenericMessage, reportAttachment); #endregion FillInAdditionalMetadata(diagnosticImagingReport, metadata); return(new DiagnosticImagingTransformResult { DiagnosticImagingReport = diagnosticImagingReport, Attachment = reportAttachment }); }
/// <summary> /// Validates the order. /// </summary> /// <param name="hl7GenericMessage">The HL7 generic message.</param> /// <param name="metadata">Diagnostic Imaging metadata instance.</param> /// <exception cref="MessageValidationException"> /// Order /// or /// Observation /// or /// ObservationsReportID /// </exception> internal static void ValidateOrder(HL7GenericMessage hl7GenericMessage, DiagnosticImagingMetadata metadata) { if (hl7GenericMessage.Order?.First().Observation?.First().ObservationsReportID?.PrincipalResultInterpreter? .name?.assigningauthority?.namespaceID != TransformerConstants.Aushic && String.IsNullOrEmpty(metadata.ReportingRadiologist.Hpii)) { throw new MessageValidationException("ReportingRadiologist.Hpii must be set in the metadata, if not provided in OBR-32 of the HL7 V2 message."); } if (hl7GenericMessage.Order == null || hl7GenericMessage.Order.Length == 0) { throw new MessageValidationException(nameof(hl7GenericMessage.Order)); } foreach (OrderGroup orderGroup in hl7GenericMessage.Order) { if (orderGroup.Observation == null || orderGroup.Observation.Length == 0) { throw new MessageValidationException(nameof(orderGroup.Observation)); } foreach (ObservationGroup observationGroup in orderGroup.Observation) { OBR obrSegment = observationGroup.ObservationsReportID; if (observationGroup.ObservationsReportID == null) { throw new MessageValidationException(nameof(observationGroup.ObservationsReportID)); } if (obrSegment.UniversalServiceID?.identifier == null) { throw new MessageValidationException("Message OBR contains no UniversalServiceID.identifier"); } if (obrSegment.UniversalServiceID.identifier != TransformerConstants.ReportText) { if (obrSegment.ResultsRptStatusChngDateTime == null || !obrSegment.ResultsRptStatusChngDateTime.Any(r => r.TimestampValue.HasValue)) { throw new MessageValidationException(ConstantsResource.InvalidResultsDateTime); } if (obrSegment.UniversalServiceID == null || String.IsNullOrEmpty(obrSegment.UniversalServiceID.alternatetext ?? obrSegment.UniversalServiceID.text)) { throw new MessageValidationException(ConstantsResource.NoTestResultNameSupplied); } if (obrSegment.ObservationDateTime?.TimestampValue == null) { throw new MessageValidationException(ConstantsResource.InvalidObservationDateTime); } Hl7V3ResultStatus hl7V3ResultStatus; if (!EnumHelper.TryGetEnumValue <Hl7V3ResultStatus, NameAttribute>(attribute => attribute.Code == obrSegment.ResultStatus, out hl7V3ResultStatus)) { throw new MessageValidationException(ConstantsResource.IncorrectTestResultStatusSupplied); } if (obrSegment.UniversalServiceID.text == null && obrSegment.UniversalServiceID.alternatetext == null) { throw new MessageValidationException("Message OBR contains no UniversalServiceID value"); } ValidatePrincipalResultInterpreter(obrSegment.PrincipalResultInterpreter); } } ValidateOrderingProvider(orderGroup); } }
/// <summary> /// Transforms the HL7 v2 pathology message into a MHR compliant CDA document. /// </summary> /// <param name="message">HL7 pathology message model.</param> /// <param name="metadata">Additional data required from the source system.</param> /// <param name="reportData"></param> /// <returns>Transformed pathology report model</returns> public PathologyTransformResult Transform(HL7GenericMessage message, PathologyMetadata metadata, byte[] reportData = null) { _pathologyMessageValidator.Validate(message, metadata, reportData); return(_pathologyMessageTransformer.Transform(message, metadata, reportData)); }
/// <summary> /// Create the subject of care from information in the HL7 V2 message. /// </summary> /// <param name="message">The HL7 V2 message.</param> /// <returns></returns> internal static IParticipationSubjectOfCare CreateSubjectOfCare(HL7GenericMessage message) { IParticipationSubjectOfCare subjectOfCare = BaseCDAModel.CreateSubjectOfCare(); var pid = message.PatientIdentification; var participant = BaseCDAModel.CreateParticipantForSubjectOfCare(); // Subject of Care > Participant > Person or Organisation or Device > Person var person = BaseCDAModel.CreatePersonForSubjectOfCare(); // Subject of Care > Participant > Address var hl7Addresses = pid.PatientAddress; if (hl7Addresses != null && hl7Addresses.Length > 0) { participant.Addresses = new List <IAddress>(); for (int x = 0; x < hl7Addresses.Length; x++) { participant.Addresses.Add(GetAustralianAddress(hl7Addresses[x])); } } // Subject of Care > Participant > Person or Organisation or Device > Person > Demographic Data > Sex if (pid.Sex?.identifier != null) { person.Gender = GetGender(pid.Sex.identifier); } // Subject of Care > Participant > Person or Organisation or Device > Person > Demographic Data > Date of Birth Detail > // Date of Birth if (pid.DateTimeOfBirth != null && pid.DateTimeOfBirth.TimestampValue.HasValue) { person.DateOfBirth = new ISO8601DateTime(pid.DateTimeOfBirth.TimestampValue.Value); } // Subject of Care > Participant > Person or Organisation or Device > Person > Demographic Data > Indigenous Status if (pid.Race != null && pid.Race.Length > 0) { IndigenousStatus indigenousStatus; if (!EnumHelper.TryGetEnumValue <IndigenousStatus, NameAttribute>(a => a.Code == pid.Race[0].identifier, out indigenousStatus)) { throw new ArgumentException("No matching IndigenousStatus value found"); } person.IndigenousStatus = indigenousStatus; } else { person.IndigenousStatus = IndigenousStatus.NotStatedOrInadequatelyDescribed; } // Subject of Care > Participant > Person or Organisation or Device > Person > Person Name if (pid.PatientName != null && pid.PatientName.Length > 0) { person.PersonNames = new List <IPersonName>(); for (int x = 0; x < pid.PatientName.Length; x++) { person.PersonNames.Add(GetPersonName(pid.PatientName[x])); } } // Identifier if (pid.PatientIdentifierList != null && pid.PatientIdentifierList.Length > 0) { foreach (var identifier in pid.PatientIdentifierList) { if (identifier.assigningauthority.namespaceID == "AUSHIC" && identifier.identifiertypecode == "NI") { person.Identifiers = new List <Identifier> { BaseCDAModel.CreateHealthIdentifier(HealthIdentifierType.IHI, identifier.ID) }; } } } participant.Person = person; subjectOfCare.Participant = participant; return(subjectOfCare); }