Exemple #1
0
        /// <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));
     }
 }
Exemple #3
0
        /// <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));
        }
Exemple #4
0
        /// <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));
        }
Exemple #5
0
        /// <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));
        }
Exemple #6
0
        /// <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
                });
            }
        }
Exemple #7
0
        /// <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);
        }
Exemple #8
0
        /// <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");
            }
        }
Exemple #10
0
        /// <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);
        }
Exemple #12
0
        /// <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);
        }
Exemple #13
0
        /// <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));
        }
Exemple #14
0
        /// <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);
        }
Exemple #16
0
        /// <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);
        }
Exemple #18
0
        /// <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);
            }
        }
Exemple #19
0
        /// <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);
        }
Exemple #20
0
        /// <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);
        }
Exemple #21
0
        /// <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
            });
        }
Exemple #22
0
        /// <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));
        }
Exemple #27
0
        /// <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);
        }