/// <summary> /// Create RSP_K21 message /// </summary> internal NHapi.Base.Model.IMessage CreateRSP_K21(RegistryQueryResult result, RegistryQueryRequest filter, List <Everest.Connectors.IResultDetail> dtls) { // Return value var retVal = new NHapi.Model.V25.Message.RSP_K21(); retVal.MSH.MessageType.MessageStructure.Value = "RSP_K21"; var qak = retVal.QAK; var msa = retVal.MSA; var dsc = retVal.DSC; var qpd = retVal.QPD; qak.QueryTag.Value = result.QueryTag; msa.AcknowledgmentCode.Value = "AA"; if (dtls.Exists(o => o.Type == Everest.Connectors.ResultDetailType.Error)) { qak.QueryResponseStatus.Value = "AE"; msa.AcknowledgmentCode.Value = "AE"; foreach (var dtl in dtls) { var err = retVal.GetStructure("ERR", retVal.currentReps("ERR")) as NHapi.Model.V25.Segment.ERR; MessageUtil.UpdateERR(err, dtl, Context); } } else if (result.Results == null || result.Results.Count == 0) { qak.QueryResponseStatus.Value = "NF"; } else { // Create the pid qak.QueryResponseStatus.Value = "OK"; qak.HitCount.Value = result.TotalResults.ToString(); qak.ThisPayload.Value = result.Results.Count.ToString(); //qak.HitsRemaining.Value = (result.TotalResults - result.StartRecordNumber).ToString(); foreach (RegistrationEvent res in result.Results) { var pid = retVal.GetQUERY_RESPONSE(retVal.QUERY_RESPONSERepetitionsUsed); UpdatePID(res, pid.PID, false); UpdateQRI(res, pid.QRI); pid.PID.SetIDPID.Value = retVal.QUERY_RESPONSERepetitionsUsed.ToString(); } // DSC segment? if (result.TotalResults > result.Results.Count) { retVal.DSC.ContinuationPointer.Value = result.ContinuationPtr; retVal.DSC.ContinuationStyle.Value = "I"; } } // Actual query paramaeters var regFilter = filter.QueryRequest.FindComponent(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.SubjectOf) as RegistrationEvent; var personFilter = regFilter.FindComponent(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.SubjectOf) as Person; qpd.QueryTag.Value = filter.QueryTag; qpd.MessageQueryName.Identifier.Value = "IHE PDQ Query"; var terser = new Terser(retVal); int qpdRep = 0; if (personFilter.GenderCode != null) { terser.Set(String.Format("/QPD-3({0})-1", qpdRep), "@PID.8"); terser.Set(String.Format("/QPD-3({0})-2", qpdRep++), personFilter.GenderCode); } if (personFilter.AlternateIdentifiers != null && personFilter.AlternateIdentifiers.Count > 0) { var altId = personFilter.AlternateIdentifiers[0]; if (altId.Domain != null) { terser.Set(String.Format("/QPD-3({0})-1", qpdRep), "@PID.3.4.2"); terser.Set(String.Format("/QPD-3({0})-2", qpdRep++), altId.Domain); terser.Set(String.Format("/QPD-3({0})-1", qpdRep), "@PID.3.4.3"); terser.Set(String.Format("/QPD-3({0})-2", qpdRep++), "ISO"); } if (altId.Identifier != null) { terser.Set(String.Format("/QPD-3({0})-1", qpdRep), "@PID.3.1"); terser.Set(String.Format("/QPD-3({0})-2", qpdRep++), altId.Identifier); } if (altId.AssigningAuthority != null) { terser.Set(String.Format("/QPD-3({0})-1", qpdRep), "@PID.3.4.1"); terser.Set(String.Format("/QPD-3({0})-2", qpdRep++), altId.AssigningAuthority); } } if (personFilter.Names != null && personFilter.Names.Count > 0) { var name = personFilter.Names[0]; foreach (var pt in name.Parts) { string pidNo = ComponentUtility.XPN_MAP.First(o => o.Value == pt.Type).Key; terser.Set(String.Format("/QPD-3({0})-1", qpdRep), String.Format("@PID.5.{0}", pidNo)); terser.Set(String.Format("/QPD-3({0})-2", qpdRep++), pt.Value); } if (name.Use != NameSet.NameSetUse.Search) { terser.Set(String.Format("/QPD-3({0})-1", qpdRep), "@PID.5.7"); terser.Set(String.Format("/QPD-3({0})-2", qpdRep++), ComponentUtility.XPN_USE_MAP.First(o => o.Value == name.Use).Key); } } if (personFilter.BirthTime != null) { terser.Set(String.Format("/QPD-3({0})-1", qpdRep), "@PID.7"); terser.Set(String.Format("/QPD-3({0})-2", qpdRep++), new TS(personFilter.BirthTime.Value).Value); } if (personFilter.Addresses != null && personFilter.Addresses.Count > 0) { var addr = personFilter.Addresses[0]; foreach (var pt in addr.Parts) { string pidNo = ComponentUtility.AD_MAP.First(o => o.Value == pt.PartType).Key; terser.Set(String.Format("/QPD-3({0})-1", qpdRep), String.Format("@PID.11.{0}", pidNo)); terser.Set(String.Format("/QPD-3({0})-2", qpdRep++), pt.AddressValue); } if (addr.Use != AddressSet.AddressSetUse.Search) { terser.Set(String.Format("/QPD-3({0})-1", qpdRep), "@PID.11.7"); terser.Set(String.Format("/QPD-3({0})-2", qpdRep++), ComponentUtility.AD_USE_MAP.First(o => o.Value == addr.Use).Key); } } var ma = personFilter.FindComponent(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.RepresentitiveOf) as PersonalRelationship; if (ma != null) { if (ma.LegalName != null) { foreach (var pt in ma.LegalName.Parts) { string pidNo = ComponentUtility.XPN_MAP.First(o => o.Value == pt.Type).Key; terser.Set(String.Format("/QPD-3({0})-1", qpdRep), String.Format("@PID.6.{0}", pidNo)); terser.Set(String.Format("/QPD-3({0})-2", qpdRep++), pt.Value); } } if (ma.AlternateIdentifiers != null && ma.AlternateIdentifiers.Count > 0) { var altId = ma.AlternateIdentifiers[0]; if (altId.Domain != null) { terser.Set(String.Format("/QPD-3({0})-1", qpdRep), "@PID.21.4.2"); terser.Set(String.Format("/QPD-3({0})-2", qpdRep++), altId.Domain); terser.Set(String.Format("/QPD-3({0})-1", qpdRep), "@PID.21.4.3"); terser.Set(String.Format("/QPD-3({0})-2", qpdRep++), "ISO"); } if (altId.Identifier != null) { terser.Set(String.Format("/QPD-3({0})-1", qpdRep), "@PID.21.1"); terser.Set(String.Format("/QPD-3({0})-2", qpdRep++), altId.Identifier); } if (altId.AssigningAuthority != null) { terser.Set(String.Format("/QPD-3({0})-1", qpdRep), "@PID.21.4.1"); terser.Set(String.Format("/QPD-3({0})-2", qpdRep++), altId.AssigningAuthority); } } } return(retVal); }
/// <summary> /// Handle a received message /// </summary> /// <param name="e"></param> /// <returns></returns> public NHapi.Base.Model.IMessage HandleMessage(HL7.TransportProtocol.Hl7MessageReceivedEventArgs e) { ISystemConfigurationService config = this.Context.GetService(typeof(ISystemConfigurationService)) as ISystemConfigurationService; ILocalizationService locale = this.Context.GetService(typeof(ILocalizationService)) as ILocalizationService; // Get the message type IMessage response = null; try { if (e.Message.Version == "2.5" || e.Message.Version == "2.3.1") { // Get the MSH segment var terser = new Terser(e.Message); var trigger = terser.Get("/MSH-9-2"); Trace.TraceInformation("Message is of type {0} {1}", e.Message.GetType().FullName, trigger); switch (trigger) { case "Q23": if (e.Message is NHapi.Model.V25.Message.QBP_Q21) { response = HandlePixQuery(e.Message as NHapi.Model.V25.Message.QBP_Q21, e); } else { response = MessageUtil.CreateNack(e.Message, "AR", "200", locale.GetString("MSGE074"), config); } break; case "A01": case "A04": case "A05": if (e.Message is NHapi.Model.V231.Message.ADT_A01) { response = HandlePixAdmit(e.Message as NHapi.Model.V231.Message.ADT_A01, e); } else { response = MessageUtil.CreateNack(e.Message, "AR", "200", locale.GetString("MSGE074"), config); } break; case "A08": if (e.Message is NHapi.Model.V231.Message.ADT_A01) { response = HandlePixUpdate(e.Message as NHapi.Model.V231.Message.ADT_A01, e); } else if (e.Message is NHapi.Model.V231.Message.ADT_A08) { response = HandlePixUpdate(e.Message as NHapi.Model.V231.Message.ADT_A08, e); } else { response = MessageUtil.CreateNack(e.Message, "AR", "200", locale.GetString("MSGE074"), config); } break; case "A40": if (e.Message is NHapi.Model.V231.Message.ADT_A39) { response = HandlePixMerge(e.Message as NHapi.Model.V231.Message.ADT_A39, e); } else if (e.Message is NHapi.Model.V231.Message.ADT_A40) { response = HandlePixMerge(e.Message as NHapi.Model.V231.Message.ADT_A40, e); } else { response = MessageUtil.CreateNack(e.Message, "AR", "200", locale.GetString("MSGE074"), config); } break; default: response = MessageUtil.CreateNack(e.Message, "AR", "201", locale.GetString("HL7201"), config); Trace.TraceError("{0} is not a supported trigger", trigger); break; } } // response still null? if (response == null) { response = MessageUtil.CreateNack(e.Message, "AR", "203", locale.GetString("HL7203"), config); } } catch (Exception ex) { Trace.TraceError(ex.ToString()); response = MessageUtil.CreateNack(e.Message, "AR", "207", ex.Message, config); } return(response); }
/// <summary> /// Update the specified PID /// </summary> public void UpdatePID(Core.ComponentModel.RegistrationEvent registrationEvent, NHapi.Model.V25.Segment.PID pid, bool summaryOnly) { var subject = registrationEvent.FindComponent(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.SubjectOf) as Person; var aut = registrationEvent.FindComponent(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.AuthorOf) as RepositoryDevice; // Update time pid.LastUpdateDateTime.Time.Value = ((TS)subject.Timestamp).Value; if (aut != null) { pid.LastUpdateFacility.NamespaceID.Value = aut.Jurisdiction; } // Alternate identifiers foreach (var altId in subject.AlternateIdentifiers) { var id = pid.GetPatientIdentifierList(pid.PatientIdentifierListRepetitionsUsed); UpdateCX(altId, id); } // Other identifiers foreach (var othId in subject.OtherIdentifiers) { var id = pid.GetPatientIdentifierList(pid.PatientIdentifierListRepetitionsUsed); UpdateCX(othId.Value, id); // Correct v3 codes if (othId.Key.CodeSystem == "1.3.6.1.4.1.33349.3.98.12") { id.IdentifierTypeCode.Value = othId.Key.Code; } else if (othId.Key.CodeSystem == "2.16.840.1.113883.2.20.3.85") { switch (othId.Key.Code) { case "SIN": id.IdentifierTypeCode.Value = "SS"; break; case "DL": id.IdentifierTypeCode.Value = othId.Key.Code; break; default: id.IdentifierTypeCode.Value = null; break; } } else { id.IdentifierTypeCode.Value = null; } } // IHE: This first repetition should be null if (summaryOnly) { pid.GetPatientName(0); pid.GetPatientName(1).NameTypeCode.Value = "S"; return; } // Populate Names if (subject.Names != null) { foreach (var name in subject.Names) { var xpn = pid.GetPatientName(pid.PatientNameRepetitionsUsed); UpdateXPN(name, xpn); } } // Birth time if (subject.BirthTime != null) { MARC.Everest.DataTypes.TS ts = new Everest.DataTypes.TS(subject.BirthTime.Value, ReverseLookup(ComponentUtility.TS_PREC_MAP, subject.BirthTime.Precision)); pid.DateTimeOfBirth.Time.Value = MARC.Everest.Connectors.Util.ToWireFormat(ts); } // Admin Sex if (subject.GenderCode != null) { pid.AdministrativeSex.Value = subject.GenderCode; } // Address if (subject.Addresses != null) { foreach (var addr in subject.Addresses) { var ad = pid.GetPatientAddress(pid.PatientAddressRepetitionsUsed); UpdateAD(addr, ad); } } // Death if (subject.DeceasedTime != null) { pid.PatientDeathIndicator.Value = "Y"; MARC.Everest.DataTypes.TS ts = new Everest.DataTypes.TS(subject.DeceasedTime.Value, ReverseLookup(ComponentUtility.TS_PREC_MAP, subject.DeceasedTime.Precision)); pid.PatientDeathDateAndTime.Time.Value = MARC.Everest.Connectors.Util.ToWireFormat(ts); } // MB Order if (subject.BirthOrder.HasValue) { pid.MultipleBirthIndicator.Value = "Y"; if (subject.BirthOrder.Value > 0) { pid.BirthOrder.Value = subject.BirthOrder.ToString(); } } // Citizenship if (subject.Citizenship != null) { foreach (var cit in subject.Citizenship) { if (cit.Status == SVC.Core.ComponentModel.Components.StatusType.Active) { var c = pid.GetCitizenship(pid.CitizenshipRepetitionsUsed); UpdateCE(new CodeValue(cit.CountryCode, this.m_config.OidRegistrar.GetOid("ISO3166-1").Oid), c); } } } if (subject.MaritalStatus != null) { UpdateCE(subject.MaritalStatus, pid.MaritalStatus); } // Language if (subject.Language != null) { foreach (var lang in subject.Language) { if (lang.Type == LanguageType.Preferred) { UpdateCE(new CodeValue(lang.Language, this.m_config.OidRegistrar.GetOid("ISO639-1").Oid), pid.PrimaryLanguage); break; } } } // Mothers name var relations = subject.FindAllComponents(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.RepresentitiveOf); foreach (var r in relations) { if (r is PersonalRelationship) { var psn = r as PersonalRelationship; if (psn.RelationshipKind != "MTH") { continue; } if (psn.AlternateIdentifiers != null) { foreach (var altid in psn.AlternateIdentifiers) { var id = pid.GetMotherSIdentifier(pid.MotherSIdentifierRepetitionsUsed); UpdateCX(altid, id); } } if (psn.LegalName != null) { UpdateXPN(psn.LegalName, pid.GetMotherSMaidenName(0)); } } } // Telecom addresses foreach (var tel in subject.TelecomAddresses) { if (tel.Use == "HP" && tel.Value.StartsWith("tel")) { MessageUtil.XTNFromTel(new TEL() { Value = tel.Value, Use = MARC.Everest.Connectors.Util.Convert <SET <CS <TelecommunicationAddressUse> > >(tel.Use), Capabilities = MARC.Everest.Connectors.Util.Convert <SET <CS <TelecommunicationCabability> > >(tel.Capability) }, pid.GetPhoneNumberHome(pid.PhoneNumberHomeRepetitionsUsed)); } else if (tel.Use == "HP") { pid.GetPhoneNumberHome(pid.PhoneNumberHomeRepetitionsUsed).EmailAddress.Value = tel.Value; } else if (tel.Use == "WP" && tel.Value.StartsWith("tel")) { MessageUtil.XTNFromTel(new TEL() { Value = tel.Value, Use = MARC.Everest.Connectors.Util.Convert <SET <CS <TelecommunicationAddressUse> > >(tel.Use), Capabilities = MARC.Everest.Connectors.Util.Convert <SET <CS <TelecommunicationCabability> > >(tel.Capability) }, pid.GetPhoneNumberBusiness(pid.PhoneNumberBusinessRepetitionsUsed)); } else if (tel.Use == "WP") { pid.GetPhoneNumberBusiness(pid.PhoneNumberBusinessRepetitionsUsed).EmailAddress.Value = tel.Value; } } // Race if (subject.Race != null) { foreach (var rc in subject.Race) { this.UpdateCE(rc, pid.GetRace(pid.RaceRepetitionsUsed)); } } // Ethnic code if (subject.EthnicGroup != null) { foreach (var e in subject.EthnicGroup) { this.UpdateCE(e, pid.GetEthnicGroup(pid.EthnicGroupRepetitionsUsed)); } } // Place of birth if (subject.BirthPlace != null) { pid.BirthPlace.Value = subject.BirthPlace.Name; } }
/// <summary> /// Handle a PIX query /// </summary> private IMessage HandlePixQuery(NHapi.Model.V25.Message.QBP_Q21 request, Hl7MessageReceivedEventArgs evt) { // Get config var config = this.Context.GetService(typeof(ISystemConfigurationService)) as ISystemConfigurationService; var locale = this.Context.GetService(typeof(ILocalizationService)) as ILocalizationService; var dataService = this.Context.GetService(typeof(IClientRegistryDataService)) as IClientRegistryDataService; // Create a details array List <IResultDetail> dtls = new List <IResultDetail>(); // Validate the inbound message MessageUtil.Validate((IMessage)request, config, dtls, this.Context); IMessage response = null; // Control if (request == null) { return(null); } // Construct appropriate audit AuditData audit = null; // Data controller AuditUtil auditUtil = new AuditUtil() { Context = this.Context }; //DataUtil dataUtil = new DataUtil() { Context = this.Context }; try { // Create Query Data ComponentUtility cu = new ComponentUtility() { Context = this.Context }; DeComponentUtility dcu = new DeComponentUtility() { Context = this.Context }; var data = cu.CreateQueryComponents(request, dtls); if (data == null) { throw new InvalidOperationException(locale.GetString("MSGE00A")); } RegistryQueryResult result = dataService.Query(data); dtls.AddRange(result.Details); // Update locations? foreach (var dtl in dtls) { if (dtl is PatientNotFoundResultDetail) { dtl.Location = "QPD^1^3^1^1"; } else if (dtl is UnrecognizedPatientDomainResultDetail) { dtl.Location = "QPD^1^3^1^4"; } else if (dtl is UnrecognizedTargetDomainResultDetail) { dtl.Location = "QPD^1^4^"; } } audit = auditUtil.CreateAuditData("ITI-9", ActionType.Execute, OutcomeIndicator.Success, evt, result); // Now process the result response = dcu.CreateRSP_K23(result, dtls); //var r = dcu.CreateRSP_K23(null, null); // Copy QPD try { (response as NHapi.Model.V25.Message.RSP_K23).QPD.MessageQueryName.Identifier.Value = request.QPD.MessageQueryName.Identifier.Value; Terser reqTerser = new Terser(request), rspTerser = new Terser(response); rspTerser.Set("/QPD-1", reqTerser.Get("/QPD-1")); rspTerser.Set("/QPD-2", reqTerser.Get("/QPD-2")); rspTerser.Set("/QPD-3-1", reqTerser.Get("/QPD-3-1")); rspTerser.Set("/QPD-3-4-1", reqTerser.Get("/QPD-3-4-1")); rspTerser.Set("/QPD-3-4-2", reqTerser.Get("/QPD-3-4-2")); rspTerser.Set("/QPD-3-4-3", reqTerser.Get("/QPD-3-4-3")); rspTerser.Set("/QPD-4-1", reqTerser.Get("/QPD-4-1")); rspTerser.Set("/QPD-4-4-1", reqTerser.Get("/QPD-4-4-1")); rspTerser.Set("/QPD-4-4-2", reqTerser.Get("/QPD-4-4-2")); rspTerser.Set("/QPD-4-4-3", reqTerser.Get("/QPD-4-4-3")); } catch (Exception e) { Trace.TraceError(e.ToString()); } //MessageUtil.((response as NHapi.Model.V25.Message.RSP_K23).QPD, request.QPD); MessageUtil.UpdateMSH(new NHapi.Base.Util.Terser(response), request, config); } catch (Exception e) { Trace.TraceError(e.ToString()); if (!dtls.Exists(o => o is UnrecognizedPatientDomainResultDetail || o is UnrecognizedTargetDomainResultDetail || o.Message == e.Message || o.Exception == e)) { dtls.Add(new ResultDetail(ResultDetailType.Error, e.Message, e)); } response = MessageUtil.CreateNack(request, dtls, this.Context, typeof(RSP_K23)); Terser errTerser = new Terser(response); // HACK: Fix the generic ACK with a real ACK for this message errTerser.Set("/MSH-9-2", "K23"); errTerser.Set("/MSH-9-3", "RSP_K23"); errTerser.Set("/QAK-2", "AE"); errTerser.Set("/MSA-1", "AE"); errTerser.Set("/QAK-1", request.QPD.QueryTag.Value); audit = auditUtil.CreateAuditData("ITI-9", ActionType.Execute, OutcomeIndicator.EpicFail, evt, new List <VersionedDomainIdentifier>()); } finally { IAuditorService auditSvc = this.Context.GetService(typeof(IAuditorService)) as IAuditorService; if (auditSvc != null) { auditSvc.SendAudit(audit); } } return(response); }
/// <summary> /// Handle a PIX admission /// </summary> private IMessage HandlePixAdmit(NHapi.Model.V231.Message.ADT_A01 request, Hl7MessageReceivedEventArgs evt) { // Get config var config = this.Context.GetService(typeof(ISystemConfigurationService)) as ISystemConfigurationService; var locale = this.Context.GetService(typeof(ILocalizationService)) as ILocalizationService; var dataService = this.Context.GetService(typeof(IClientRegistryDataService)) as IClientRegistryDataService; // Create a details array List <IResultDetail> dtls = new List <IResultDetail>(); // Validate the inbound message MessageUtil.Validate((IMessage)request, config, dtls, this.Context); IMessage response = null; // Control if (request == null) { return(null); } // Data controller AuditUtil auditUtil = new AuditUtil() { Context = this.Context }; //DataUtil dataUtil = new DataUtil() { Context = this.Context }; // Construct appropriate audit AuditData audit = null; try { // Create Query Data ComponentUtility cu = new ComponentUtility() { Context = this.Context }; DeComponentUtility dcu = new DeComponentUtility() { Context = this.Context }; var data = cu.CreateComponents(request, dtls); if (data == null) { throw new InvalidOperationException(locale.GetString("MSGE00A")); } var result = dataService.Register(data, request.MSH.ProcessingID.ProcessingID.Value == "P" ? DataPersistenceMode.Production : DataPersistenceMode.Debugging); if (result == null || result.VersionId == null) { throw new InvalidOperationException(locale.GetString("DTPE001")); } dtls.AddRange(result.Details); audit = auditUtil.CreateAuditData("ITI-8", result.VersionId.UpdateMode == UpdateModeType.Update ? ActionType.Update : ActionType.Create, OutcomeIndicator.Success, evt, new List <VersionedDomainIdentifier>() { result.VersionId }); // Now process the result response = MessageUtil.CreateNack(request, dtls, this.Context, typeof(NHapi.Model.V231.Message.ACK)); MessageUtil.UpdateMSH(new NHapi.Base.Util.Terser(response), request, config); (response as NHapi.Model.V231.Message.ACK).MSH.MessageType.TriggerEvent.Value = request.MSH.MessageType.TriggerEvent.Value; (response as NHapi.Model.V231.Message.ACK).MSH.MessageType.MessageType.Value = "ACK"; } catch (Exception e) { Trace.TraceError(e.ToString()); if (!dtls.Exists(o => o.Message == e.Message || o.Exception == e)) { dtls.Add(new ResultDetail(ResultDetailType.Error, e.Message, e)); } response = MessageUtil.CreateNack(request, dtls, this.Context, typeof(NHapi.Model.V231.Message.ACK)); audit = auditUtil.CreateAuditData("ITI-8", ActionType.Create, OutcomeIndicator.EpicFail, evt, new List <VersionedDomainIdentifier>()); } finally { IAuditorService auditSvc = this.Context.GetService(typeof(IAuditorService)) as IAuditorService; if (auditSvc != null) { auditSvc.SendAudit(audit); } } return(response); }
/// <summary> /// Handle the PIX merge request /// </summary> private IMessage HandlePixMerge(NHapi.Model.V231.Message.ADT_A39 request, Hl7MessageReceivedEventArgs evt) { // Get config var config = this.Context.GetService(typeof(ISystemConfigurationService)) as ISystemConfigurationService; var locale = this.Context.GetService(typeof(ILocalizationService)) as ILocalizationService; var dataService = this.Context.GetService(typeof(IClientRegistryDataService)) as IClientRegistryDataService; // Create a details array List <IResultDetail> dtls = new List <IResultDetail>(); // Validate the inbound message MessageUtil.Validate((IMessage)request, config, dtls, this.Context); IMessage response = null; // Control if (request == null) { return(null); } // Data controller //DataUtil dataUtil = new DataUtil() { Context = this.Context }; AuditUtil auditUtil = new AuditUtil() { Context = this.Context }; // Construct appropriate audit List <AuditData> audit = new List <AuditData>(); try { // Create Query Data ComponentUtility cu = new ComponentUtility() { Context = this.Context }; DeComponentUtility dcu = new DeComponentUtility() { Context = this.Context }; var data = cu.CreateComponents(request, dtls); if (data == null) { throw new InvalidOperationException(locale.GetString("MSGE00A")); } // Merge var result = dataService.Merge(data, request.MSH.ProcessingID.ProcessingID.Value == "P" ? DataPersistenceMode.Production : DataPersistenceMode.Debugging); if (result == null || result.VersionId == null) { throw new InvalidOperationException(locale.GetString("DTPE001")); } List <VersionedDomainIdentifier> deletedRecordIds = new List <VersionedDomainIdentifier>(), updatedRecordIds = new List <VersionedDomainIdentifier>(); // Subjects var oidData = config.OidRegistrar.GetOid("CR_CID").Oid; foreach (Person subj in data.FindAllComponents(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.SubjectOf)) { PersonRegistrationRef replcd = subj.FindComponent(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.ReplacementOf) as PersonRegistrationRef; deletedRecordIds.Add(new VersionedDomainIdentifier() { Identifier = replcd.Id.ToString(), Domain = oidData }); updatedRecordIds.Add(new VersionedDomainIdentifier() { Identifier = subj.Id.ToString(), Domain = oidData }); } // Now audit audit.Add(auditUtil.CreateAuditData("ITI-8", ActionType.Delete, OutcomeIndicator.Success, evt, deletedRecordIds)); audit.Add(auditUtil.CreateAuditData("ITI-8", ActionType.Update, OutcomeIndicator.Success, evt, updatedRecordIds)); // Now process the result response = MessageUtil.CreateNack(request, dtls, this.Context, typeof(NHapi.Model.V231.Message.ACK)); MessageUtil.UpdateMSH(new NHapi.Base.Util.Terser(response), request, config); (response as NHapi.Model.V231.Message.ACK).MSH.MessageType.TriggerEvent.Value = request.MSH.MessageType.TriggerEvent.Value; (response as NHapi.Model.V231.Message.ACK).MSH.MessageType.MessageType.Value = "ACK"; } catch (Exception e) { Trace.TraceError(e.ToString()); if (!dtls.Exists(o => o.Message == e.Message || o.Exception == e)) { dtls.Add(new ResultDetail(ResultDetailType.Error, e.Message, e)); } response = MessageUtil.CreateNack(request, dtls, this.Context, typeof(NHapi.Model.V231.Message.ACK)); audit.Add(auditUtil.CreateAuditData("ITI-8", ActionType.Delete, OutcomeIndicator.EpicFail, evt, new List <VersionedDomainIdentifier>())); } finally { IAuditorService auditSvc = this.Context.GetService(typeof(IAuditorService)) as IAuditorService; if (auditSvc != null) { foreach (var aud in audit) { auditSvc.SendAudit(aud); } } } return(response); }
/// <summary> /// Handle the pdq query /// </summary> private IMessage HandlePdqQuery(QBP_Q21 request, Hl7MessageReceivedEventArgs evt) { // Get config var config = this.Context.GetService(typeof(ISystemConfigurationService)) as ISystemConfigurationService; var locale = this.Context.GetService(typeof(ILocalizationService)) as ILocalizationService; var dataService = this.Context.GetService(typeof(IClientRegistryDataService)) as IClientRegistryDataService; // Create a details array List <IResultDetail> dtls = new List <IResultDetail>(); // Validate the inbound message MessageUtil.Validate((IMessage)request, config, dtls, this.Context); IMessage response = null; // Control if (request == null) { return(null); } // Data controller //DataUtil dataUtil = new DataUtil() { Context = this.Context }; AuditUtil auditUtil = new AuditUtil() { Context = this.Context }; // Construct appropriate audit AuditData audit = null; try { // Create Query Data ComponentUtility cu = new ComponentUtility() { Context = this.Context }; DeComponentUtility dcu = new DeComponentUtility() { Context = this.Context }; var data = cu.CreateQueryComponentsPdq(request, dtls); if (data == null) { Trace.TraceError("{0} problems mapping message:", dtls.Count); foreach (var itm in dtls) { Trace.TraceError($"\t{itm.Type} : {itm.Message}"); } throw new InvalidOperationException();// locale?.GetString("MSGE00A") ?? "Could not process components"); } // Is this a continue or new query? RegistryQueryResult result = dataService.Query(data); audit = auditUtil.CreateAuditData("ITI-21", ActionType.Execute, OutcomeIndicator.Success, evt, result); // Now process the result response = dcu.CreateRSP_K21(result, data, dtls); //MessageUtil.CopyQPD((response as RSP_K21).QPD, request.QPD, data); MessageUtil.UpdateMSH(new NHapi.Base.Util.Terser(response), request, config); Terser ters = new Terser(response); ters.Set("/MSH-9-2", "K22"); } catch (Exception e) { Trace.TraceError(e.ToString()); if (!dtls.Exists(o => o.Message == e.Message || o.Exception == e)) { if (dtls.Count == 0) { dtls.Add(new ResultDetail(ResultDetailType.Error, e.Message, e)); } } // HACK: Only one error allowed in nHAPI for some reason : // TODO: Fix NHapi dtls.RemoveAll(o => o.Type != ResultDetailType.Error); while (dtls.Count > 1) { dtls.RemoveAt(1); } response = MessageUtil.CreateNack(request, dtls, this.Context, typeof(RSP_K21)); Terser errTerser = new Terser(response); // HACK: Fix the generic ACK with a real ACK for this message errTerser.Set("/MSH-9-2", "K22"); errTerser.Set("/MSH-9-3", "RSP_K21"); errTerser.Set("/QAK-2", "AE"); errTerser.Set("/MSA-1", "AE"); errTerser.Set("/QAK-1", request.QPD.QueryTag.Value); audit = auditUtil.CreateAuditData("ITI-21", ActionType.Execute, OutcomeIndicator.EpicFail, evt, new List <VersionedDomainIdentifier>()); } finally { IAuditorService auditSvc = this.Context.GetService(typeof(IAuditorService)) as IAuditorService; if (auditSvc != null) { auditSvc.SendAudit(audit); } } return(response); }
/// <summary> /// Update the NK1 segment /// </summary> private void UpdateNK1(PersonalRelationship subject, NK1 nk1) { if (subject.AlternateIdentifiers != null) { foreach (var altId in subject.AlternateIdentifiers) { UpdateCX(altId, nk1.GetNextOfKinAssociatedPartySIdentifiers(nk1.NextOfKinAssociatedPartySIdentifiersRepetitionsUsed)); } } // Birth time if (subject.BirthTime != null) { MARC.Everest.DataTypes.TS ts = new Everest.DataTypes.TS(subject.BirthTime.Value, ReverseLookup(ComponentUtility.TS_PREC_MAP, subject.BirthTime.Precision)); nk1.DateTimeOfBirth.Time.Value = MARC.Everest.Connectors.Util.ToWireFormat(ts); } if (subject.GenderCode != null) { nk1.AdministrativeSex.Value = subject.GenderCode; } if (subject.LegalName != null) { UpdateXPN(subject.LegalName, nk1.GetName(0)); } if (subject.PerminantAddress != null) { UpdateAD(subject.PerminantAddress, nk1.GetAddress(0)); } if (subject.RelationshipKind != null) { nk1.Relationship.Identifier.Value = subject.RelationshipKind; } if (subject.TelecomAddresses != null) { foreach (var tel in subject.TelecomAddresses) { if (tel.Use == "HP" && tel.Value.StartsWith("tel")) { MessageUtil.XTNFromTel(new TEL() { Value = tel.Value, Use = MARC.Everest.Connectors.Util.Convert <SET <CS <TelecommunicationAddressUse> > >(tel.Use), Capabilities = MARC.Everest.Connectors.Util.Convert <SET <CS <TelecommunicationCabability> > >(tel.Capability) }, nk1.GetContactPersonSTelephoneNumber(nk1.ContactPersonSTelephoneNumberRepetitionsUsed)); } else if (tel.Use == "HP") { nk1.GetPhoneNumber(nk1.ContactPersonSTelephoneNumberRepetitionsUsed).EmailAddress.Value = tel.Value; } else if (tel.Use == "WP" && tel.Value.StartsWith("tel")) { MessageUtil.XTNFromTel(new TEL() { Value = tel.Value, Use = MARC.Everest.Connectors.Util.Convert <SET <CS <TelecommunicationAddressUse> > >(tel.Use), Capabilities = MARC.Everest.Connectors.Util.Convert <SET <CS <TelecommunicationCabability> > >(tel.Capability) }, nk1.GetContactPersonSTelephoneNumber(nk1.ContactPersonSTelephoneNumberRepetitionsUsed)); } else if (tel.Use == "WP") { nk1.GetPhoneNumber(nk1.ContactPersonSTelephoneNumberRepetitionsUsed).EmailAddress.Value = tel.Value; } } } }