/// <inheritdoc/> public string ToDelimitedString() { System.Globalization.CultureInfo culture = System.Globalization.CultureInfo.CurrentCulture; string separator = IsSubcomponent ? Configuration.SubcomponentSeparator : Configuration.ComponentSeparator; return(string.Format( culture, StringHelper.StringFormatSequence(0, 18, separator), PersonIdentifier, FamilyName?.ToDelimitedString(), GivenName, SecondAndFurtherGivenNamesOrInitialsThereof, Suffix, Prefix, Degree, SourceTable, AssigningAuthority?.ToDelimitedString(), NameTypeCode, IdentifierCheckDigit, CheckDigitScheme, IdentifierTypeCode, AssigningFacility?.ToDelimitedString(), NameRepresentationCode, NameContext?.ToDelimitedString(), NameValidityRange?.ToDelimitedString(), NameAssemblyOrder ).TrimEnd(separator.ToCharArray())); }
/// <summary> /// Converts a <see cref="EditAssigningAuthorityModel"/> instance to an <see cref="AssigningAuthorityInfo"/> instance. /// </summary> /// <returns>Returns an <see cref="AssigningAuthorityInfo"/> instance.</returns> public AssigningAuthority ToAssigningAuthorityInfo(AssigningAuthority authorityInfo) { authorityInfo.Url = this.Url; authorityInfo.DomainName = this.DomainName; authorityInfo.Description = this.Description; authorityInfo.Oid = this.Oid; authorityInfo.Name = this.Name; authorityInfo.ValidationRegex = this.ValidationRegex; if (!this.AddConcepts.Any()) { return(authorityInfo); } foreach (var concept in AddConcepts) { Guid id; if (Guid.TryParse(concept, out id)) { if (authorityInfo.AuthorityScopeXml == null) { authorityInfo.AuthorityScopeXml = new List <Guid>(); } authorityInfo.AuthorityScopeXml.Add(id); } } return(authorityInfo); }
/// <summary> /// Converts an <see cref="NHapi.Model.V25.Datatype.HD"/> instance to an <see cref="AssigningAuthority"/> instance. /// </summary> /// <param name="id">The id value to be converted.</param> /// <returns>Returns the converted assigning authority.</returns> public static AssigningAuthority ConvertAssigningAuthority(NHapi.Model.V25.Datatype.HD id, List <IResultDetail> details) { var assigningAuthorityRepositoryService = ApplicationContext.Current.GetAssigningAuthorityService(); AssigningAuthority assigningAuthority = null; if (id == null) { details.Add(new MandatoryElementMissingResultDetail(ResultDetailType.Error, null, null)); return(assigningAuthority); } if (!string.IsNullOrEmpty(id.NamespaceID.Value)) { assigningAuthority = assigningAuthorityRepositoryService.Find(a => a.Name == id.NamespaceID.Value).FirstOrDefault(); } if (!string.IsNullOrEmpty(id.UniversalID.Value)) { assigningAuthority = assigningAuthorityRepositoryService.Find(a => a.Oid == id.UniversalID.Value).FirstOrDefault(); } if (!string.IsNullOrEmpty(id.UniversalIDType.Value) && id.UniversalIDType.Value != "ISO") { details.Add(new NotImplementedResultDetail(ResultDetailType.Warning, ApplicationContext.Current.GetLocaleString("MSGW016"), null)); } return(assigningAuthority); }
/// <summary> /// Convert assigning authortiy to v2 /// </summary> public static HD FromModel(this HD me, AssigningAuthority authority) { me.NamespaceID.Value = authority.DomainName; me.UniversalID.Value = authority.Oid; me.UniversalIDType.Value = !String.IsNullOrEmpty(authority.Oid) ? "ISO" : null; return(me); }
/// <inheritdoc/> public string ToDelimitedString() { System.Globalization.CultureInfo culture = System.Globalization.CultureInfo.CurrentCulture; string separator = IsSubcomponent ? Configuration.SubcomponentSeparator : Configuration.ComponentSeparator; return(string.Format( culture, StringHelper.StringFormatSequence(0, 16, separator), PersonIdentifier, FamilyName, GivenName, SecondAndFurtherGivenNamesOrInitialsThereof, Suffix, Prefix, Degree, SourceTable, AssigningAuthority?.ToDelimitedString(), NameTypeCode, IdentifierCheckDigit, CheckDigitScheme, IdentifierTypeCode, AssigningFacility?.ToDelimitedString(), DateTimeActionPerformed.HasValue ? DateTimeActionPerformed.Value.ToString(Consts.DateTimeFormatPrecisionSecond, culture) : null, NameRepresentationCode ).TrimEnd(separator.ToCharArray())); }
/// <inheritdoc/> public string ToDelimitedString() { System.Globalization.CultureInfo culture = System.Globalization.CultureInfo.CurrentCulture; string separator = IsSubcomponent ? Configuration.SubcomponentSeparator : Configuration.ComponentSeparator; return(string.Format( culture, StringHelper.StringFormatSequence(0, 23, separator), PersonIdentifier, FamilyName?.ToDelimitedString(), GivenName, SecondAndFurtherGivenNamesOrInitialsThereof, Suffix, Prefix, Degree, SourceTable, AssigningAuthority?.ToDelimitedString(), NameTypeCode, IdentifierCheckDigit, CheckDigitScheme, IdentifierTypeCode, AssigningFacility?.ToDelimitedString(), NameRepresentationCode, NameContext?.ToDelimitedString(), NameValidityRange?.ToDelimitedString(), NameAssemblyOrder, EffectiveDate.HasValue ? EffectiveDate.Value.ToString(Consts.DateTimeFormatPrecisionSecond, culture) : null, ExpirationDate.HasValue ? ExpirationDate.Value.ToString(Consts.DateTimeFormatPrecisionSecond, culture) : null, ProfessionalSuffix, AssigningJurisdiction?.ToDelimitedString(), AssigningAgencyOrDepartment?.ToDelimitedString() ).TrimEnd(separator.ToCharArray())); }
public virtual string ToString(char separator) { return($"{OrganizationName}{separator}{OrganizationNameTypeCode?.BestValue}{separator}{ID}" + $"{separator}{CheckDigit}{separator}{CheckDigitScheme?.BestValue}" + $"{separator}{AssigningAuthority?.ToString()}{separator}{IdentifierTypeCode?.BestValue}" + $"{separator}{AssigningFacility?.ToString()}" .TrimEnd(separator)); }
public string ToString(char separator) { var ns = NextSeparator(separator); return ($"{ID}{separator}{CheckDigit}{separator}{CheckDigitScheme?.BestValue}{separator}" + $"{AssigningAuthority?.ToString(ns)}{separator}{IdentifierTypeCode?.BestValue}{separator}" + $"{AssigningFacility?.ToString(ns)}{EffectiveDate?.AsDTLocal()}{separator}{ExpirationDate?.AsDTLocal()}" .TrimEnd(separator)); }
/// <summary> /// Inserts an assigning authority. /// </summary> /// <param name="assigningAuthority">The assigning authority to be inserted.</param> /// <returns>Returns the inserted assigning authority.</returns> public AssigningAuthority Insert(AssigningAuthority assigningAuthority) { var persistenceService = ApplicationContext.Current.GetService <IDataPersistenceService <AssigningAuthority> >(); if (persistenceService == null) { throw new InvalidOperationException($"{nameof(IDataPersistenceService<AssigningAuthority>)} not found"); } return(persistenceService.Insert(assigningAuthority, AuthenticationContext.Current.Principal, TransactionMode.Commit)); }
/// <summary> /// Create the specified authority /// </summary> public static void CreateAuthority(string nsid, string oid, string url, string applicationName, byte[] deviceSecret) { // Create the test harness device / application var securityDevService = ApplicationServiceContext.Current.GetService <IRepositoryService <SecurityDevice> >(); var securityAppService = ApplicationServiceContext.Current.GetService <IRepositoryService <SecurityApplication> >(); var metadataService = ApplicationServiceContext.Current.GetService <IAssigningAuthorityRepositoryService>(); using (AuthenticationContext.EnterSystemContext()) { var pubId = $"{applicationName}|TEST"; var device = securityDevService.Find(o => o.Name == pubId).FirstOrDefault(); if (device == null) { device = new SecurityDevice { DeviceSecret = BitConverter.ToString(deviceSecret).Replace("-", ""), Name = $"{applicationName}|TEST" }; device.AddPolicy(PermissionPolicyIdentifiers.LoginAsService); device = securityDevService.Insert(device); } // Application var app = securityAppService.Find(o => o.Name == applicationName).FirstOrDefault(); if (app == null) { app = new SecurityApplication { Name = applicationName, ApplicationSecret = BitConverter.ToString(deviceSecret).Replace("-", "") }; app.AddPolicy(PermissionPolicyIdentifiers.LoginAsService); app.AddPolicy(PermissionPolicyIdentifiers.UnrestrictedClinicalData); app.AddPolicy(PermissionPolicyIdentifiers.UnrestrictedMetadata); app = securityAppService.Insert(app); } // Create AA var aa = metadataService.Get(nsid); if (aa == null) { aa = new AssigningAuthority(nsid, nsid, oid) { AssigningApplicationKey = app.Key, IsUnique = true, Url = url }; metadataService.Insert(aa); } } }
public override string ToString(char separator) { var ns = NextSeparator(separator); return ($"{ID}{separator}{FamilyName}{separator}{GivenName}{separator}{SecondGivenNamesOrInitials}" + $"{separator}{Suffix}{separator}{Prefix}{separator}{Degree}{separator}" + $"{SourceTable}{separator}{AssigningAuthority?.ToString(ns)}{separator}" + $"{NameTypeCode}{separator}{IdentifierCheckDigit}{separator}{CheckDigitScheme}{separator}" + $"{IdentifierTypeCode}{separator}{AssigningFacility?.ToString(ns)}{separator}" + $"{NameRepresentationCode}{separator}{NameContext?.ToString(ns)}{separator}" + $"{NameValidityRange?.ToString(ns)}{separator}{NameAssemblyOrder}" .TrimEnd(separator)); }
/// <summary> /// Convert this AA to OID Data for configuration purposes /// </summary> public static OidData ToOidData(this AssigningAuthority me) { return(new OidData() { Name = me.Name, Description = me.Description, Oid = me.Oid, Ref = new Uri(String.IsNullOrEmpty(me.Url) ? String.Format("urn:uuid:{0}", me.Oid) : me.Url), Attributes = new System.Collections.Generic.List <System.Collections.Generic.KeyValuePair <string, string> >() { new System.Collections.Generic.KeyValuePair <string, string>("HL7CX4", me.DomainName) //new System.Collections.Generic.KeyValuePair<string, string>("AssigningDevFacility", this.AssigningDevice.DeviceEvidence) } }); }
/// <inheritdoc/> public string ToDelimitedString() { System.Globalization.CultureInfo culture = System.Globalization.CultureInfo.CurrentCulture; string separator = IsSubcomponent ? Configuration.SubcomponentSeparator : Configuration.ComponentSeparator; return(string.Format( culture, StringHelper.StringFormatSequence(0, 6, separator), IdNumber, IdentifierCheckDigit, CheckDigitScheme, AssigningAuthority?.ToDelimitedString(), IdentifierTypeCode, AssigningFacility?.ToDelimitedString() ).TrimEnd(separator.ToCharArray())); }
/// <summary> /// Converts an <see cref="HD"/> instance to an <see cref="AssigningAuthority"/> instance. /// </summary> /// <param name="id">The id value to be converted.</param> /// <returns>Returns the converted assigning authority.</returns> public static AssigningAuthority ToModel(this HD id) { var assigningAuthorityRepositoryService = ApplicationServiceContext.Current.GetService <IAssigningAuthorityRepositoryService>(); AssigningAuthority assigningAuthority = null; if (id == null) { throw new ArgumentNullException(nameof(id), "Missing ID parameter"); } // Internal key identifier? if (!String.IsNullOrEmpty(id.NamespaceID.Value) && id.NamespaceID.Value == m_configuration.LocalAuthority.DomainName || !String.IsNullOrEmpty(id.UniversalID.Value) && id.UniversalID.Value == m_configuration.LocalAuthority.Oid) { return(m_configuration.LocalAuthority); } if (!string.IsNullOrEmpty(id.NamespaceID.Value)) { assigningAuthority = assigningAuthorityRepositoryService.Get(id.NamespaceID.Value); if (assigningAuthority == null) { throw new HL7DatatypeProcessingException("Error processing HD", 1, new KeyNotFoundException($"Authority {id.NamespaceID.Value} not found")); } } if (!string.IsNullOrEmpty(id.UniversalID.Value)) { var tAssigningAuthority = assigningAuthorityRepositoryService.Get(new Uri($"urn:oid:{id.UniversalID.Value}")); if (tAssigningAuthority == null) { throw new HL7DatatypeProcessingException("Error processing HD", 2, new KeyNotFoundException($"Authority {id.UniversalID.Value} not found")); } else if (assigningAuthority != null && tAssigningAuthority?.Key != assigningAuthority.Key) // Must agree { throw new HL7DatatypeProcessingException("Error processing HD", 2, new ArgumentException("When both NamespaceID and UniversalID are specified, both must agree with configured values")); } else { assigningAuthority = tAssigningAuthority; } } return(assigningAuthority); }
/// <summary> /// Determines whether the identifier is valid for the given assigning authority. /// </summary> /// <param name="assigningAuthority">The assigning authority.</param> /// <param name="value">The value.</param> /// <returns><c>true</c> Determines whether the identifier is valid for the given assigning authority; Otherwise, <c>false</c>.</returns> private bool IsValidIdentifier(AssigningAuthority assigningAuthority, string value) { var status = false; if (!string.IsNullOrEmpty(assigningAuthority.ValidationRegex) && !string.IsNullOrWhiteSpace(assigningAuthority.ValidationRegex)) { if (new Regex(assigningAuthority.ValidationRegex).IsMatch(value)) { status = true; } } else { status = true; } return(status); }
/// <inheritdoc/> public string ToDelimitedString() { System.Globalization.CultureInfo culture = System.Globalization.CultureInfo.CurrentCulture; string separator = IsSubcomponent ? Configuration.SubcomponentSeparator : Configuration.ComponentSeparator; return(string.Format( culture, StringHelper.StringFormatSequence(0, 8, separator), OrganizationName, OrganizationNameTypeCode, IdNumber.HasValue ? IdNumber.Value.ToString(Consts.NumericFormat, culture) : null, IdentifierCheckDigit.HasValue ? IdentifierCheckDigit.Value.ToString(Consts.NumericFormat, culture) : null, CheckDigitScheme, AssigningAuthority?.ToDelimitedString(), IdentifierTypeCode, AssigningFacility?.ToDelimitedString() ).TrimEnd(separator.ToCharArray())); }
/// <inheritdoc/> public string ToDelimitedString() { System.Globalization.CultureInfo culture = System.Globalization.CultureInfo.CurrentCulture; string separator = IsSubcomponent ? Configuration.SubcomponentSeparator : Configuration.ComponentSeparator; return(string.Format( culture, StringHelper.StringFormatSequence(0, 8, separator), IdNumber, IdentifierCheckDigit, CheckDigitScheme, AssigningAuthority?.ToDelimitedString(), IdentifierTypeCode, AssigningFacility?.ToDelimitedString(), EffectiveDate.HasValue ? EffectiveDate.Value.ToString(Consts.DateFormatPrecisionDay, culture) : null, ExpirationDate.HasValue ? ExpirationDate.Value.ToString(Consts.DateFormatPrecisionDay, culture) : null ).TrimEnd(separator.ToCharArray())); }
// [PolicyPermission(System.Security.Permissions.SecurityAction.Demand, PolicyId = PermissionPolicyIdentifiers.UnrestrictedMetadata)] public static void AddAssigningAuthority(AddAssigningAuthorityParams parms) { // First, resolve the assigner SecurityApplicationInfo assigner = null; if (!String.IsNullOrEmpty(parms.Assigner)) { assigner = m_amiClient.GetApplications(o => o.Name == parms.Assigner).CollectionItem.FirstOrDefault() as SecurityApplicationInfo; if (assigner == null) { throw new KeyNotFoundException("Assigner unknown"); } } // Scope List <Concept> scope = new List <Concept>(); if (parms.Scope?.Count > 0) { foreach (var s in parms.Scope) { var scp = m_hdsiClient.Query <Concept>(o => o.Mnemonic == s, 0, 1, false).Item.OfType <Concept>().FirstOrDefault(); if (scp == null) { throw new KeyNotFoundException($"Scope {s} unknown"); } scope.Add(scp); } } // Construct AA foreach (var domainName in parms.Authority) { var aa = new AssigningAuthority(domainName, parms.Name, parms.Oid) { Url = parms.Url, AuthorityScope = scope, AssigningApplication = assigner?.Entity, IsUnique = parms.Unique }; aa = m_amiClient.CreateAssigningAuthority(aa); Console.WriteLine("CREATE AUTHORITY {0} = {1}", aa.DomainName, aa.Key); } }
/// <summary> /// Get order information /// </summary> public Act GetOrder(Ecom_DocumentReferenceType documentReference, Guid moodConceptKey) { if (documentReference == null) { throw new ArgumentNullException("documentReference", "Document reference must be supplied for correlation lookup"); } else if (String.IsNullOrEmpty(documentReference.entityIdentification)) { throw new ArgumentException("Document reference must carry entityIdentification", "documentReference"); } Guid orderId = Guid.Empty; Act retVal = null; if (Guid.TryParse(documentReference.entityIdentification, out orderId)) { retVal = this.m_actRepository.Get(orderId, Guid.Empty); } if (retVal == null) { var oidService = ApplicationServiceContext.Current.GetService <IAssigningAuthorityRepositoryService>(); var gln = oidService.Get("GLN"); AssigningAuthority issuingAuthority = null; if (documentReference.contentOwner != null) { issuingAuthority = oidService.Find(o => o.Oid == $"{gln.Oid}.{documentReference.contentOwner.gln}").FirstOrDefault(); } if (issuingAuthority == null) { issuingAuthority = oidService.Get(this.m_configuration.DefaultContentOwnerAssigningAuthority); } if (issuingAuthority == null) { throw new InvalidOperationException("Could not find assigning authority linked with document reference owner. Please specify a default in the configuration"); } int tr = 0; retVal = this.m_actRepository.Find(o => o.ClassConceptKey == ActClassKeys.Supply && o.MoodConceptKey == moodConceptKey && o.Identifiers.Any(i => i.Value == documentReference.entityIdentification && i.AuthorityKey == issuingAuthority.Key), 0, 1, out tr).FirstOrDefault(); } return(retVal); }
/// <summary> /// Creates an assigning authority. /// </summary> /// <param name="assigningAuthorityInfo">The assigning authority to be created.</param> /// <returns>Returns the created assigning authority.</returns> public AssigningAuthority CreateAssigningAuthority(AssigningAuthority assigningAuthorityInfo) { return(this.Client.Post <AssigningAuthority, AssigningAuthority>("AssigningAuthority", assigningAuthorityInfo)); }
/// <summary> /// The issue despactch advice message will insert a new shipped order into the TImR system. /// </summary> public void IssueDespatchAdvice(DespatchAdviceMessageType advice) { if (advice == null || advice.despatchAdvice == null) { this.m_tracer.TraceError("Invalid message sent"); throw new InvalidOperationException(this.m_localizationService.GetString("error.messaging.gs1.invalidMessage")); } // TODO: Validate the standard header // Loop Bundle orderTransaction = new Bundle(); foreach (var adv in advice.despatchAdvice) { // Has this already been created? Place sourceLocation = this.m_gs1Util.GetLocation(adv.shipper), destinationLocation = this.m_gs1Util.GetLocation(adv.receiver); if (sourceLocation == null) { this.m_tracer.TraceError($"Shipper location not found"); throw new KeyNotFoundException(this.m_localizationService.FormatString("error.messaging.gs1.locationNotFound", new { param = "Shipper" })); } else if (destinationLocation == null) { this.m_tracer.TraceError($"Shipper location not found"); throw new KeyNotFoundException(this.m_localizationService.FormatString("error.messaging.gs1.locationNotFound", new { param = "Receiver" })); } // Find the original order which this despatch advice is fulfilling Act orderRequestAct = null; if (adv.orderResponse != null || adv.purchaseOrder != null) { orderRequestAct = this.m_gs1Util.GetOrder(adv.orderResponse ?? adv.purchaseOrder, ActMoodKeys.Request); if (orderRequestAct != null) // Orderless despatch! { // If the original order request is not comlete, then complete it orderRequestAct.StatusConceptKey = StatusKeys.Completed; orderTransaction.Add(orderRequestAct); } } // Find the author of the shipment var oidService = ApplicationServiceContext.Current.GetService <IAssigningAuthorityRepositoryService>(); var gln = oidService.Get("GLN"); AssigningAuthority issuingAuthority = null; if (adv.despatchAdviceIdentification.contentOwner != null) { issuingAuthority = oidService.Find(o => o.Oid == $"{gln.Oid}.{adv.despatchAdviceIdentification.contentOwner.gln}").FirstOrDefault(); } if (issuingAuthority == null) { issuingAuthority = oidService.Get(this.m_configuration.DefaultContentOwnerAssigningAuthority); } if (issuingAuthority == null) { this.m_tracer.TraceError("Could not find default issuing authority for advice identification. Please configure a valid OID"); throw new KeyNotFoundException(this.m_localizationService.GetString("error.messaging.gs1.issuingAuthority")); } int tr = 0; var existing = this.m_actRepository.Find(o => o.Identifiers.Any(i => i.AuthorityKey == issuingAuthority.Key && i.Value == adv.despatchAdviceIdentification.entityIdentification), 0, 1, out tr); if (existing.Any()) { this.m_tracer.TraceWarning("Duplicate despatch {0} will be ignored", adv.despatchAdviceIdentification.entityIdentification); continue; } // Now we want to create a new Supply act which that fulfills the old act Act fulfillAct = new Act() { CreationTime = DateTimeOffset.Now, MoodConceptKey = ActMoodKeys.Eventoccurrence, ClassConceptKey = ActClassKeys.Supply, StatusConceptKey = StatusKeys.Active, TypeConceptKey = Guid.Parse("14d69b32-f6c4-4a49-a527-a74893dbcf4a"), // Order ActTime = adv.despatchInformation.despatchDateTimeSpecified ? adv.despatchInformation.despatchDateTime : DateTime.Now, Extensions = new List <ActExtension>() { new ActExtension(Gs1ModelExtensions.ActualShipmentDate, typeof(DateExtensionHandler), adv.despatchInformation.actualShipDateTime), new ActExtension(Gs1ModelExtensions.ExpectedDeliveryDate, typeof(DateExtensionHandler), adv.despatchInformation.estimatedDeliveryDateTime) }, Tags = new List <ActTag>() { new ActTag("orderNumber", adv.despatchAdviceIdentification.entityIdentification), new ActTag("orderStatus", "shipped"), new ActTag("http://santedb.org/tags/contrib/importedData", "true") }, Identifiers = new List <ActIdentifier>() { new ActIdentifier(issuingAuthority, adv.despatchAdviceIdentification.entityIdentification) }, Participations = new List <ActParticipation>() { // TODO: Author // TODO: Performer new ActParticipation(ActParticipationKey.Location, sourceLocation.Key), new ActParticipation(ActParticipationKey.Destination, destinationLocation.Key) } }; orderTransaction.Add(fulfillAct); // Fullfillment if (orderRequestAct != null) { fulfillAct.Relationships = new List <ActRelationship>() { new ActRelationship(ActRelationshipTypeKeys.Fulfills, orderRequestAct.Key) } } ; // Now add participations for each material in the despatch foreach (var dal in adv.despatchAdviceLogisticUnit) { foreach (var line in dal.despatchAdviceLineItem) { if (line.despatchedQuantity.measurementUnitCode != "dose" && line.despatchedQuantity.measurementUnitCode != "unit") { this.m_tracer.TraceError("Despatched quantity must be reported in units or doses"); throw new InvalidOperationException(this.m_localizationService.GetString("error.messaging.gs1.despatchedQuantity")); } var material = this.m_gs1Util.GetManufacturedMaterial(line.transactionalTradeItem, this.m_configuration.AutoCreateMaterials); // Add a participation fulfillAct.Participations.Add(new ActParticipation(ActParticipationKey.Consumable, material.Key) { Quantity = (int)line.despatchedQuantity.Value }); } } } // insert transaction if (orderTransaction.Item.Count > 0) { try { ApplicationServiceContext.Current.GetService <IRepositoryService <Bundle> >().Insert(orderTransaction); } catch (Exception e) { this.m_tracer.TraceError("Error issuing despatch advice: {0}", e); throw new Exception(this.m_localizationService.FormatString("error.messaging.gs1.errorIssuing", new { param = e.Message }), e); } } }
/// <summary> /// Converts an <see cref="HD"/> instance to an <see cref="AssigningAuthority"/> instance. /// </summary> /// <param name="id">The id value to be converted.</param> /// <returns>Returns the converted assigning authority.</returns> public static AssigningAuthority ToModel(this HD id) { var assigningAuthorityRepositoryService = ApplicationServiceContext.Current.GetService <IAssigningAuthorityRepositoryService>(); AssigningAuthority assigningAuthority = null; if (id == null) { throw new ArgumentNullException(nameof(id), "Missing ID parameter"); } // Internal key identifier? if (!String.IsNullOrEmpty(id.NamespaceID.Value) && id.NamespaceID.Value == m_configuration.LocalAuthority.DomainName || !String.IsNullOrEmpty(id.UniversalID.Value) && id.UniversalID.Value == m_configuration.LocalAuthority.Oid) { return(m_configuration.LocalAuthority); } if (!string.IsNullOrEmpty(id.NamespaceID.Value)) { assigningAuthority = assigningAuthorityRepositoryService.Get(id.NamespaceID.Value); if (assigningAuthority == null) { throw new HL7DatatypeProcessingException("Error processing HD", 1, new KeyNotFoundException($"Authority {id.NamespaceID.Value} not found")); } } if (!string.IsNullOrEmpty(id.UniversalID.Value)) { var tAssigningAuthority = assigningAuthorityRepositoryService.Get(new Uri($"urn:oid:{id.UniversalID.Value}")); if (tAssigningAuthority == null) { throw new HL7DatatypeProcessingException("Error processing HD", 2, new KeyNotFoundException($"Authority {id.UniversalID.Value} not found")); } else if (assigningAuthority != null && tAssigningAuthority?.Key != assigningAuthority.Key) // Must agree { throw new HL7DatatypeProcessingException("Error processing HD", 2, new ArgumentException("When both NamespaceID and UniversalID are specified, both must agree with configured values")); } else { assigningAuthority = tAssigningAuthority; } } // Fuzzy lookup based on principal if (!m_configuration.StrictAssigningAuthorities && id.NamespaceID.IsEmpty() && id.UniversalID.IsEmpty()) { var claimsPrincipal = AuthenticationContext.Current.Principal as IClaimsPrincipal; if (claimsPrincipal == null) { throw new HL7DatatypeProcessingException($"Cannot perform application<>identity domain XREF - authentication provider must be claims principal", 4); } var appPrincipal = claimsPrincipal.Identities.OfType <IApplicationIdentity>().FirstOrDefault(); if (appPrincipal == null) { throw new SecurityException($"Cannot perform application<>identity domain XREF - no application principal present"); } assigningAuthority = assigningAuthorityRepositoryService.Find(o => o.AssigningApplication.Name == appPrincipal.Name, 0, 2, out int tr).FirstOrDefault(); if (tr > 1) { throw new HL7DatatypeProcessingException($"Ambiguous authority - {appPrincipal.Name} auto mapping of sender to authority can only be done if there are 1 authorities - this device has {tr}", 4); } } return(assigningAuthority); }
/// <summary> /// Checks of the selected concept is already in the authority scope list /// </summary> /// <returns>Returns true if the selected concept exists, false if not found</returns> public bool HasSelectedAuthorityScope(AssigningAuthority authorityInfo) { return(AddConcepts.Any() && authorityInfo.AuthorityScope.Any(scope => scope.Key.ToString().Equals(AddConcepts[0]))); }
/// <summary> /// Parse the Next Of Kin Data /// </summary> public virtual IEnumerable <IdentifiedData> Parse(ISegment segment, IEnumerable <IdentifiedData> context) { // Cast segment var nk1Segment = segment as NK1; var fieldNo = 0; // Person persistence service var personService = ApplicationServiceContext.Current.GetService <IDataPersistenceService <Person> >(); try { // Patient to which the parsing belongs var patient = context.OfType <Patient>().FirstOrDefault(); if (patient == null) { this.m_tracer.TraceError("NK1 Requires PID segment to be processed"); throw new InvalidOperationException(this.m_localizationService.FormatString("error.messaging.hl7.segmentRequirement", new { param = "NK1", param2 = "PID" })); } // Next of kin is a person Person retVal = new Person() { Key = Guid.NewGuid() }; EntityRelationship retValRelation = new EntityRelationship(EntityRelationshipTypeKeys.NextOfKin, retVal.Key) { SourceEntityKey = patient.Key }; bool foundByKey = false; // Look for existing person fieldNo = 33; foreach (var id in nk1Segment.GetNextOfKinAssociatedPartySIdentifiers()) { var idnumber = id.IDNumber.Value; AssigningAuthority authority = null; try { authority = id.AssigningAuthority.ToModel(); } catch (Exception e) { throw new HL7ProcessingException(e.Message, "NK1", nk1Segment.SetIDNK1.Value, 33, 3, e); } Guid idguid = Guid.Empty; int tr = 0; Person found = null; if (authority.Key == this.m_configuration.LocalAuthority.Key) { found = personService.Get(Guid.Parse(id.IDNumber.Value), null, true, AuthenticationContext.SystemPrincipal); } else if (authority?.IsUnique == true) { found = personService.Query(o => o.Identifiers.Any(i => i.Value == idnumber && i.Authority.Key == authority.Key), 0, 1, out tr, AuthenticationContext.SystemPrincipal).FirstOrDefault(); } if (found != null) { retVal = found; foundByKey = true; // Existing relationship? retValRelation = ApplicationServiceContext.Current.GetService <IDataPersistenceService <EntityRelationship> >().Query(r => r.SourceEntityKey == patient.Key.Value && r.TargetEntityKey == retVal.Key.Value, AuthenticationContext.SystemPrincipal).FirstOrDefault() ?? retValRelation; break; } } // Relationship type fieldNo = 3; if (!nk1Segment.Relationship.IsEmpty()) { retValRelation.RelationshipTypeKey = nk1Segment.Relationship.ToModel(RelationshipCodeSystem)?.Key; } // Some relationships only allow one person, we should update them var existingNokRel = patient.LoadCollection <EntityRelationship>(nameof(Entity.Relationships)).FirstOrDefault(o => o.RelationshipTypeKey == retValRelation.RelationshipTypeKey); if (existingNokRel != null) { retValRelation = existingNokRel; if (!foundByKey) // We didn't actually resolve anyone by current key so we should try to find them in the DB { retVal = context.FirstOrDefault(o => o.Key == existingNokRel.TargetEntityKey) as Person; // Mother isn't in context, load if (retVal == null) { retVal = personService.Get(existingNokRel.TargetEntityKey.Value, null, true, AuthenticationContext.SystemPrincipal); } if (retVal == null) { this.m_tracer.TraceError("Cannot locate described NOK entity on patient record"); throw new InvalidOperationException(this.m_localizationService.GetString("error.messaging.hl7.entityNOK")); } // IF the person is a PATIENT and not a PERSON we will not update them - too dangerous - ignore the NOK entry if (retVal is Patient && !foundByKey) { return(new IdentifiedData[0]); } } } fieldNo = 2; // Names if (nk1Segment.NameRepetitionsUsed > 0) { foreach (var itm in nk1Segment.GetName()) { var model = itm.ToModel(); var existing = retVal.Names.FirstOrDefault(o => o.NameUseKey == model.NameUseKey); if (existing == null) { retVal.Names.Add(model); } else { existing.CopyObjectData(model); } } } // Address fieldNo = 4; if (nk1Segment.AddressRepetitionsUsed > 0) { foreach (var itm in nk1Segment.GetAddress()) { var model = itm.ToModel(); var existing = retVal.Addresses.FirstOrDefault(o => o.AddressUseKey == model.AddressUseKey); if (existing == null) { retVal.Addresses.Add(model); } else { existing.CopyObjectData(model); } } } // Phone numbers fieldNo = 5; var telecoms = nk1Segment.GetBusinessPhoneNumber().Union(nk1Segment.GetPhoneNumber()); foreach (var itm in telecoms) { var model = itm.ToModel(); var existing = retVal.Telecoms.FirstOrDefault(o => o.AddressUseKey == model.AddressUseKey); if (existing == null) { retVal.Telecoms.Add(model); } else { existing.CopyObjectData(model); } } fieldNo = 15; if (!nk1Segment.AdministrativeSex.IsEmpty()) { retVal.GenderConcept = nk1Segment.AdministrativeSex.ToConcept(AdministrativeGenderCodeSystem); } // Organization fieldNo = 13; if (nk1Segment.OrganizationNameNK1RepetitionsUsed > 0) { var orgService = ApplicationServiceContext.Current.GetService <IDataPersistenceService <Organization> >(); foreach (var xon in nk1Segment.GetOrganizationNameNK1()) { var id = xon.ToModel(); // Lookup the organization scoper if (id != null) { var organization = orgService?.Query(o => o.Identifiers.Any(i => i.Value == id.Value && i.AuthorityKey == id.AuthorityKey), AuthenticationContext.SystemPrincipal).FirstOrDefault(); if (organization == null && !this.m_configuration.StrictMetadataMatch) { organization = new Organization() { Identifiers = new List <EntityIdentifier>() { id }, Names = new List <EntityName>() { new EntityName(NameUseKeys.Assigned, xon.OrganizationName.Value) } }; retVal.Relationships.Add(new EntityRelationship(EntityRelationshipTypeKeys.Scoper, organization) { ClassificationKey = RelationshipClassKeys.ContainedObjectLink }); } else { retVal.Relationships.Add(new EntityRelationship(EntityRelationshipTypeKeys.Scoper, organization)); } } else { this.m_tracer.TraceError("XON requires identifier"); throw new HL7DatatypeProcessingException(this.m_localizationService.GetString("error.messaging.hl7.requirementXON"), 10, new ArgumentNullException()); } } } // Context role, when the person should be contact fieldNo = 7; if (!nk1Segment.ContactRole.IsEmpty()) { var existingConRole = patient.Relationships.FirstOrDefault(o => o.RelationshipTypeKey == EntityRelationshipTypeKeys.Contact && retVal.Key == o.TargetEntityKey); if (existingConRole == null) { patient.Relationships.Add(new EntityRelationship(EntityRelationshipTypeKeys.Contact, retVal.Key) { RelationshipRole = nk1Segment.ContactRole.ToModel(ContactRoleRelationship, true) }); } else { existingConRole.RelationshipRole = nk1Segment.ContactRole.ToModel(ContactRoleRelationship, true); } } fieldNo = 16; if (!nk1Segment.DateTimeOfBirth.IsEmpty()) { retVal.DateOfBirth = nk1Segment.DateTimeOfBirth.ToModel(); retVal.DateOfBirthPrecision = nk1Segment.DateTimeOfBirth.ToDatePrecision(); } // Citizenship fieldNo = 19; if (nk1Segment.CitizenshipRepetitionsUsed > 0) { foreach (var cit in nk1Segment.GetCitizenship()) { var place = ApplicationServiceContext.Current.GetService <IDataPersistenceService <Place> >()?.Query(o => o.Identifiers.Any(i => i.Value == cit.Identifier.Value && i.Authority.Key == AssigningAuthorityKeys.Iso3166CountryCode), AuthenticationContext.SystemPrincipal).FirstOrDefault(); if (place != null) { if (!retVal.Relationships.Any(r => r.RelationshipTypeKey == EntityRelationshipTypeKeys.Citizen && r.TargetEntityKey == place.Key)) { retVal.Relationships.Add(new EntityRelationship(EntityRelationshipTypeKeys.Citizen, place.Key)); } } else { this.m_tracer.TraceError($"Cannot find country with code {cit.Identifier.Value}"); throw new KeyNotFoundException(this.m_localizationService.FormatString("error.messaging.hl7.countryCode", new { param = cit.Identifier.Value })); } } } fieldNo = 20; if (!nk1Segment.PrimaryLanguage.IsEmpty()) { retVal.LanguageCommunication = new List <PersonLanguageCommunication>() { new PersonLanguageCommunication(nk1Segment.PrimaryLanguage.Identifier.Value.ToLower(), true) } } ; // Privacy code fieldNo = 23; if (!nk1Segment.ProtectionIndicator.IsEmpty()) { var pip = ApplicationServiceContext.Current.GetService <IDataPersistenceService <SecurityPolicy> >(); if (nk1Segment.ProtectionIndicator.Value == "Y") { retVal.AddPolicy(DataPolicyIdentifiers.RestrictedInformation); } else if (nk1Segment.ProtectionIndicator.Value == "N") { retVal.Policies.Clear(); } else { this.m_tracer.TraceError($"Protection indicator {nk1Segment.ProtectionIndicator.Value} is invalid"); throw new ArgumentOutOfRangeException(this.m_localizationService.FormatString("error.messaging.hl7.protectionInvalid", new { param = nk1Segment.ProtectionIndicator.Value })); } } // Associated person identifiers fieldNo = 33; if (nk1Segment.NextOfKinAssociatedPartySIdentifiersRepetitionsUsed > 0) { retVal.Identifiers.AddRange(nk1Segment.GetNextOfKinAssociatedPartySIdentifiers().ToModel().ToList().Where(i => !retVal.Identifiers.Any(e => e.SemanticEquals(i)))); } // Find the existing relationship on the patient if (!patient.Relationships.Any(o => o.RelationshipTypeKey == retValRelation.RelationshipTypeKey && o.TargetEntityKey == retValRelation.TargetEntityKey)) { patient.Relationships.Add(retValRelation); } if (!context.Contains(retVal)) { return new IdentifiedData[] { retVal } } ; else { return(new IdentifiedData[0]); } } catch (HL7ProcessingException) // Just re-throw { throw; } catch (HL7DatatypeProcessingException e) { throw new HL7ProcessingException(this.m_localizationService.FormatString("error.type.HL7ProcessingException", new { param = "NK1" }), "NK1", nk1Segment.SetIDNK1.Value, fieldNo, e.Component, e); } catch (Exception e) { throw new HL7ProcessingException(this.m_localizationService.FormatString("error.type.HL7ProcessingException", new { param = "NK1" }), "NK1", nk1Segment.SetIDNK1.Value, fieldNo, 1, e); } }
public void TestShouldAdhereToClassifierCodes() { AssigningAuthority aa = new AssigningAuthority() { Name = "Ontario Health Insurance Card", DomainName = "OHIPCARD", Oid = "1.2.3.4.5.67" }; var aaPersistence = ApplicationServiceContext.Current.GetService <IDataPersistenceService <AssigningAuthority> >(); var ohipAuth = aaPersistence.Insert(aa, TransactionMode.Commit, s_authorization); Patient p = new Patient() { StatusConcept = new Concept() { Mnemonic = "ACTIVE" }, Names = new List <EntityName>() { new EntityName() { NameUse = new Concept() { Mnemonic = "OfficialRecord" }, Component = new List <EntityNameComponent>() { new EntityNameComponent() { ComponentType = new Concept() { Mnemonic = "Family" }, Value = "Johnson" }, new EntityNameComponent() { ComponentType = new Concept() { Mnemonic = "Given" }, Value = "William" }, new EntityNameComponent() { ComponentType = new Concept() { Mnemonic = "Given" }, Value = "P." }, new EntityNameComponent() { ComponentType = new Concept() { Mnemonic = "Given" }, Value = "Bear" } } } }, Identifiers = new List <EntityIdentifier>() { new EntityIdentifier( new AssigningAuthority() { DomainName = "OHIPCARD" }, "12343120423") }, Tags = new List <EntityTag>() { new EntityTag("hasBirthCertificate", "true") }, Extensions = new List <EntityExtension>() { new EntityExtension() { ExtensionType = new ExtensionType() { Name = "http://santedb.org/oiz/birthcertificate", ExtensionHandler = typeof(EntityPersistenceServiceTest) }, ExtensionValueXml = new byte[] { 1 } } }, GenderConcept = new Concept() { Mnemonic = "Male" }, DateOfBirth = new DateTime(1984, 03, 22), MultipleBirthOrder = 2, DeceasedDate = new DateTime(2016, 05, 02), DeceasedDatePrecision = DatePrecision.Day, DateOfBirthPrecision = DatePrecision.Day }; var afterInsert = base.DoTestInsert(p, s_authorization); Assert.AreEqual("Male", afterInsert.LoadProperty(o => o.GenderConcept).Mnemonic); Assert.AreEqual(EntityClassKeys.Patient, p.ClassConceptKey); Assert.AreEqual(DeterminerKeys.Specific, p.DeterminerConceptKey); Assert.AreEqual(StatusKeys.Active, p.StatusConceptKey); //Assert.AreEqual(aa.Key, afterInsert.Identifiers[0].AuthorityKey); }
/// <summary> /// Parse the Next Of Kin Data /// </summary> public virtual IEnumerable <IdentifiedData> Parse(ISegment segment, IEnumerable <IdentifiedData> context) { // Cast segment var nk1Segment = segment as NK1; var fieldNo = 0; // Person persistence service var personService = ApplicationServiceContext.Current.GetService <IDataPersistenceService <Person> >(); try { // Patient to which the parsing belongs var patient = context.OfType <Patient>().FirstOrDefault(); if (patient == null) { throw new InvalidOperationException("NK1 Requires PID segment to be processed"); } // Next of kin is a person Person retVal = new Person() { Key = Guid.NewGuid() }; EntityRelationship retValRelation = new EntityRelationship(EntityRelationshipTypeKeys.NextOfKin, retVal.Key) { SourceEntityKey = patient.Key }; bool foundByKey = false; // Look for existing person fieldNo = 33; foreach (var id in nk1Segment.GetNextOfKinAssociatedPartySIdentifiers()) { var idnumber = id.IDNumber.Value; AssigningAuthority authority = null; try { authority = id.AssigningAuthority.ToModel(); } catch (Exception e) { throw new HL7ProcessingException(e.Message, "NK1", nk1Segment.SetIDNK1.Value, 33, 3, e); } Guid idguid = Guid.Empty; int tr = 0; Person found = null; if (authority.Key == this.m_configuration.LocalAuthority.Key) { found = personService.Get(Guid.Parse(id.IDNumber.Value), null, true, AuthenticationContext.SystemPrincipal); } else if (authority?.IsUnique == true) { found = personService.Query(o => o.Identifiers.Any(i => i.Value == idnumber && i.Authority.Key == authority.Key), 0, 1, out tr, AuthenticationContext.SystemPrincipal).FirstOrDefault(); } if (found != null) { retVal = found; foundByKey = true; // Existing relationship? retValRelation = ApplicationServiceContext.Current.GetService <IDataPersistenceService <EntityRelationship> >().Query(r => r.SourceEntityKey == patient.Key.Value && r.TargetEntityKey == retVal.Key.Value, AuthenticationContext.SystemPrincipal).FirstOrDefault() ?? retValRelation; break; } } // Relationship type fieldNo = 3; if (!nk1Segment.Relationship.IsEmpty()) { retValRelation.RelationshipTypeKey = nk1Segment.Relationship.ToModel(RelationshipCodeSystem)?.Key; } // Some relationships only allow one person, we should update them var existingNokRel = patient.LoadCollection <EntityRelationship>(nameof(Entity.Relationships)).FirstOrDefault(o => o.RelationshipTypeKey == retValRelation.RelationshipTypeKey); if (existingNokRel != null) { retValRelation = existingNokRel; if (!foundByKey) // We didn't actually resolve anyone by current key so we should try to find them in the DB { retVal = context.FirstOrDefault(o => o.Key == existingNokRel.TargetEntityKey) as Person; // Mother isn't in context, load if (retVal == null) { retVal = personService.Get(existingNokRel.TargetEntityKey.Value, null, true, AuthenticationContext.SystemPrincipal); } if (retVal == null) { throw new InvalidOperationException("Cannot locate described NOK entity on patient record"); } // IF the person is a PATIENT and not a PERSON we will not update them - too dangerous - ignore the NOK entry if (retVal is Patient && !foundByKey) { return(new IdentifiedData[0]); } } } fieldNo = 2; // Names if (nk1Segment.NameRepetitionsUsed > 0) { foreach (var itm in nk1Segment.GetName()) { var model = itm.ToModel(); var existing = retVal.Names.FirstOrDefault(o => o.NameUseKey == model.NameUseKey); if (existing == null) { retVal.Names.Add(model); } else { existing.CopyObjectData(model); } } } // Address fieldNo = 4; if (nk1Segment.AddressRepetitionsUsed > 0) { foreach (var itm in nk1Segment.GetAddress()) { var model = itm.ToModel(); var existing = retVal.Addresses.FirstOrDefault(o => o.AddressUseKey == model.AddressUseKey); if (existing == null) { retVal.Addresses.Add(model); } else { existing.CopyObjectData(model); } } } // Phone numbers fieldNo = 5; var telecoms = nk1Segment.GetBusinessPhoneNumber().Union(nk1Segment.GetPhoneNumber()); foreach (var itm in telecoms) { var model = itm.ToModel(); var existing = retVal.Telecoms.FirstOrDefault(o => o.AddressUseKey == model.AddressUseKey); if (existing == null) { retVal.Telecoms.Add(model); } else { existing.CopyObjectData(model); } } // Context role, when the person should be contact fieldNo = 7; if (!nk1Segment.ContactRole.IsEmpty()) { var contactExtension = retVal.Extensions.FirstOrDefault(o => o.ExtensionTypeKey == ExtensionTypeKeys.ContactRolesExtension); if (contactExtension == null) { contactExtension = new EntityExtension(ExtensionTypeKeys.ContactRolesExtension, typeof(DictionaryExtensionHandler), new { roles = new[] { new { patientKey = patient.Key.Value, contact = nk1Segment.ContactRole.Identifier.Value } }.ToList() }); } else { var existingValue = (contactExtension.ExtensionValue as dynamic); existingValue.roles.Add(new { patientKey = patient.Key.Value, contact = nk1Segment.ContactRole.Identifier.Value }); } retVal.Extensions.Add(contactExtension); } fieldNo = 16; if (!nk1Segment.DateTimeOfBirth.IsEmpty()) { retVal.DateOfBirth = nk1Segment.DateTimeOfBirth.ToModel(); retVal.DateOfBirthPrecision = nk1Segment.DateTimeOfBirth.ToDatePrecision(); } // Citizenship fieldNo = 19; if (nk1Segment.CitizenshipRepetitionsUsed > 0) { foreach (var cit in nk1Segment.GetCitizenship()) { var places = ApplicationServiceContext.Current.GetService <IDataPersistenceService <Place> >()?.Query(o => o.Identifiers.Any(i => i.Value == cit.Identifier.Value && i.Authority.Key == AssigningAuthorityKeys.Iso3166CountryCode), AuthenticationContext.SystemPrincipal); if (places.Count() == 1) { retVal.Relationships.Add(new EntityRelationship(EntityRelationshipTypeKeys.Citizen, places.First().Key)); } } } fieldNo = 20; if (!nk1Segment.PrimaryLanguage.IsEmpty()) { retVal.LanguageCommunication = new List <PersonLanguageCommunication>() { new PersonLanguageCommunication(nk1Segment.PrimaryLanguage.Identifier.Value.ToLower(), true) } } ; // Privacy code fieldNo = 23; if (!nk1Segment.ProtectionIndicator.IsEmpty()) { var pip = ApplicationServiceContext.Current.GetService <IDataPersistenceService <SecurityPolicy> >(); if (nk1Segment.ProtectionIndicator.Value == "Y") { retVal.AddPolicy(DataPolicyIdentifiers.RestrictedInformation); } else if (nk1Segment.ProtectionIndicator.Value == "N") { retVal.Policies.Clear(); } else { throw new ArgumentOutOfRangeException($"Protection indicator {nk1Segment.ProtectionIndicator.Value} is invalid"); } } // Associated person identifiers fieldNo = 33; if (nk1Segment.NextOfKinAssociatedPartySIdentifiersRepetitionsUsed > 0) { retVal.Identifiers.AddRange(nk1Segment.GetNextOfKinAssociatedPartySIdentifiers().ToModel().ToList().Where(i => !retVal.Identifiers.Any(e => e.SemanticEquals(i)))); } // Find the existing relationship on the patient patient.Relationships.RemoveAll(o => o.SourceEntityKey == retValRelation.SourceEntityKey && o.TargetEntityKey == retValRelation.TargetEntityKey); patient.Relationships.Add(retValRelation); if (!context.Contains(retVal)) { return new IdentifiedData[] { retVal } } ; else { return(new IdentifiedData[0]); } } catch (HL7ProcessingException) // Just re-throw { throw; } catch (HL7DatatypeProcessingException e) { throw new HL7ProcessingException("Error processing NK1 segment", "NK1", nk1Segment.SetIDNK1.Value, fieldNo, e.Component, e); } catch (Exception e) { throw new HL7ProcessingException("Error processing NK1 segment", "NK1", nk1Segment.SetIDNK1.Value, fieldNo, 1, e); } }
/// <summary> /// Parse the parse the specified segment into a patient object /// </summary> /// <param name="segment">The segment to be parsed</param> /// <returns>The parsed patient information</returns> public virtual IEnumerable <IdentifiedData> Parse(ISegment segment, IEnumerable <IdentifiedData> context) { var patientService = ApplicationServiceContext.Current.GetService <IRepositoryService <Patient> >(); var pidSegment = segment as PID; int fieldNo = 0; try { Patient retVal = new Patient() { Key = Guid.NewGuid(), StatusConceptKey = StatusKeys.New }; Person motherEntity = null; List <IdentifiedData> retCollection = new List <IdentifiedData>(); retVal.CreationAct = context.OfType <ControlAct>().FirstOrDefault(); // Existing patient? if (pidSegment.Message.GetStructureName().StartsWith("ADT")) { foreach (var id in pidSegment.GetPatientIdentifierList()) { var idnumber = id.IDNumber.Value; AssigningAuthority authority; try { authority = id.AssigningAuthority.ToModel(); } catch (Exception e) { throw new HL7ProcessingException(this.m_localizationService.FormatString("error.type.HL7ProcessingException", new { param = "assigning authority" }), "PID", pidSegment.SetIDPID.Value, 3, 4, e); } // Authority not found? if (authority == null) { this.m_tracer.TraceError($"No authority configured for {id.AssigningAuthority.NamespaceID.Value}"); throw new HL7ProcessingException(this.m_localizationService.FormatString("error.messaging.hl7.authorityNone", new { param = id.AssigningAuthority.NamespaceID.Value }), "PID", pidSegment.SetIDPID.Value, 3, 4); } Guid idguid = Guid.Empty; Patient found = null; if (authority.Key == this.m_configuration.LocalAuthority.Key) { found = patientService.Get(Guid.Parse(id.IDNumber.Value), Guid.Empty); } else if (authority?.IsUnique == true) { found = patientService.Find(o => o.Identifiers.Any(i => i.Authority.Key == authority.Key && i.Value == idnumber)).FirstOrDefault(); } if (found != null) { retVal = (Patient)found.Clone(); break; } } } fieldNo = 2; if (!pidSegment.PatientID.IsEmpty()) { retVal.Identifiers.Add(pidSegment.PatientID.ToModel()); } fieldNo = 3; if (pidSegment.PatientIdentifierListRepetitionsUsed > 0) { var messageIdentifiers = pidSegment.GetPatientIdentifierList().ToModel(); if (this.m_configuration.IdentifierReplacementBehavior == IdentifierReplacementMode.AnyInDomain) { retVal.Identifiers.RemoveAll(o => messageIdentifiers.Any(i => i.EffectiveVersionSequenceId.HasValue && i.AuthorityKey == o.AuthorityKey)); } // Remove any identifiers matching the value explicitly retVal.Identifiers.RemoveAll(o => messageIdentifiers.Any(i => i.ObsoleteVersionSequenceId.HasValue && i.AuthorityKey == o.AuthorityKey && i.Value == o.Value)); // Add any identifiers which we don't have any other identifier domain for retVal.Identifiers.AddRange(messageIdentifiers.Where(o => !o.ObsoleteVersionSequenceId.HasValue && !retVal.Identifiers.Any(i => i.AuthorityKey == o.AuthorityKey && i.Value == o.Value))); } // Find the key for the patient var keyId = pidSegment.GetPatientIdentifierList().FirstOrDefault(o => o.AssigningAuthority.NamespaceID.Value == this.m_configuration.LocalAuthority.DomainName); if (keyId != null) { retVal.Key = Guid.Parse(keyId.IDNumber.Value); } if (!retVal.Identifiers.Any()) { throw new HL7ProcessingException(this.m_localizationService.GetString("error.messaging.hl7.identityPatient"), "PID", pidSegment.SetIDPID.Value, 3, 1); } fieldNo = 5; if (pidSegment.PatientNameRepetitionsUsed > 0) { foreach (var itm in pidSegment.GetPatientName()) { var model = itm.ToModel(); var existing = retVal.Names.FirstOrDefault(o => o.NameUseKey == model.NameUseKey); if (existing == null) { retVal.Names.Add(model); } else { existing.CopyObjectData(model); } } } fieldNo = 21; // Mother's maiden name, create a relationship for mother if (pidSegment.MotherSMaidenNameRepetitionsUsed > 0 || pidSegment.GetMotherSIdentifier().Any(o => !o.IsEmpty())) { var personService = ApplicationServiceContext.Current.GetService <IRepositoryService <Person> >(); Person existingMother = retVal.Relationships.FirstOrDefault(o => o.RelationshipTypeKey == EntityRelationshipTypeKeys.Mother)?.LoadProperty(o => o.TargetEntity).GetMaster() as Person; Person foundMother = null; // Attempt to find the existing mother in the database based on ID foreach (var id in pidSegment.GetMotherSIdentifier().Where(o => !o.IsEmpty())) { AssigningAuthority authority = null; try { authority = id.AssigningAuthority.ToModel(); } catch (Exception e) { throw new HL7ProcessingException(this.m_localizationService.FormatString("error.type.HL7ProcessingException", new { param = "mother's identifiers" }), "PID", pidSegment.SetIDPID.Value, 21, 3); } if ((authority.Key == this.m_configuration.LocalAuthority.Key || authority.DomainName == this.m_configuration.LocalAuthority.DomainName) && Guid.TryParse(id.IDNumber.Value, out Guid idNumberUuid)) { foundMother = personService.Get(idNumberUuid) ?? patientService.Get(idNumberUuid); } else if (authority?.IsUnique == true) { foundMother = personService.Find(o => o.Identifiers.Any(i => i.Value == id.IDNumber.Value && i.Authority.Key == authority.Key)).FirstOrDefault() ?? patientService.Find(o => o.Identifiers.Any(i => i.Value == id.IDNumber.Value && i.Authority.Key == authority.Key)).FirstOrDefault(); } if (foundMother != null) { break; } } fieldNo = 6; // Mother doesn't exist and there's no mother currently, so add it if (foundMother == null && existingMother == null) { motherEntity = new Person() { Key = Guid.NewGuid(), Identifiers = pidSegment.GetMotherSIdentifier().ToModel().ToList(), Names = pidSegment.GetMotherSMaidenName().ToModel(NameUseKeys.MaidenName).ToList(), StatusConceptKey = StatusKeys.New }; retCollection.Add(motherEntity); } else if (existingMother != null) // existing mother - update { if (!existingMother.LoadCollection(o => o.Identifiers).Any()) // update identifiers { existingMother.Identifiers = pidSegment.GetMotherSIdentifier().ToModel().ToList(); } motherEntity = existingMother; retCollection.Add(motherEntity); } else { motherEntity = foundMother; } var existingRelationship = retVal.Relationships.FirstOrDefault(r => r.SourceEntityKey == retVal.Key && r.RelationshipTypeKey == EntityRelationshipTypeKeys.Mother); if (existingRelationship == null) { retVal.Relationships.Add(new EntityRelationship(EntityRelationshipTypeKeys.Mother, motherEntity.Key)); } else if (existingRelationship.TargetEntityKey != motherEntity.Key) { // Was the mother found? existingRelationship.BatchOperation = BatchOperationType.Delete; retCollection.Add(existingRelationship); retVal.Relationships.Remove(existingRelationship); retCollection.Add(new EntityRelationship(EntityRelationshipTypeKeys.Mother, motherEntity.Key) { SourceEntityKey = retVal.Key }); } } // Nationality fieldNo = 28; if (!pidSegment.Nationality.IsEmpty()) { retVal.Nationality = pidSegment.Nationality.ToModel(); } // Date/time of birth fieldNo = 7; if (!pidSegment.DateTimeOfBirth.IsEmpty()) { retVal.DateOfBirth = pidSegment.DateTimeOfBirth.ToModel(); retVal.DateOfBirthPrecision = pidSegment.DateTimeOfBirth.ToDatePrecision(); } // Administrative gender fieldNo = 8; if (!pidSegment.AdministrativeSex.IsEmpty()) { retVal.GenderConcept = pidSegment.AdministrativeSex.ToConcept(AdministrativeGenderCodeSystem); } // Patient Alias fieldNo = 9; if (pidSegment.PatientAliasRepetitionsUsed > 0) { retVal.Names.AddRange(pidSegment.GetPatientAlias().ToModel()); } // Race codes fieldNo = 10; if (pidSegment.RaceRepetitionsUsed > 0) { retVal.Extensions.AddRange(pidSegment.GetRace().Select(o => new EntityExtension(ExtensionTypeKeys.PatientRaceExtension, typeof(ReferenceExtensionHandler), o.ToModel(RaceCodeSystem)))); } // Addresses fieldNo = 11; if (pidSegment.PatientAddressRepetitionsUsed > 0) { foreach (var itm in pidSegment.GetPatientAddress()) { var model = itm.ToModel(); var existing = retVal.Addresses.FirstOrDefault(o => o.AddressUseKey == model.AddressUseKey); if (existing == null) { retVal.Addresses.Add(model); } else { existing.CopyObjectData(model); } } } // Fields fieldNo = 13; var telecoms = pidSegment.GetPhoneNumberBusiness().Union(pidSegment.GetPhoneNumberHome()); foreach (var itm in telecoms) { var model = itm.ToModel(); var existing = retVal.Telecoms.FirstOrDefault(o => o.AddressUseKey == model.AddressUseKey); if (existing == null) { retVal.Telecoms.Add(model); } else { existing.CopyObjectData(model); } } // Language if (!pidSegment.PrimaryLanguage.IsEmpty()) { retVal.LanguageCommunication = new List <PersonLanguageCommunication>() { new PersonLanguageCommunication(pidSegment.PrimaryLanguage.Identifier.Value.ToLower(), true) } } ; // Marital Status fieldNo = 16; if (!pidSegment.MaritalStatus.IsEmpty()) { retVal.MaritalStatus = pidSegment.MaritalStatus.ToModel(MaritalStatusCodeSystem); } // Religion fieldNo = 17; if (!pidSegment.Religion.IsEmpty()) { retVal.ReligiousAffiliation = pidSegment.Religion.ToModel(ReligionCodeSystem); } // Ethinic groups fieldNo = 22; if (pidSegment.EthnicGroupRepetitionsUsed > 0) { retVal.EthnicGroupCodeKey = pidSegment.GetEthnicGroup().First().ToModel(EthnicGroupCodeSystem).Key; } fieldNo = 18; // Patient account, locate the specified account if (!pidSegment.PatientAccountNumber.IsEmpty()) { var account = ApplicationServiceContext.Current.GetService <IDataPersistenceService <Account> >()?.Query(o => o.Identifiers.Any(i => i.Value == pidSegment.PatientAccountNumber.IDNumber.Value), AuthenticationContext.SystemPrincipal).FirstOrDefault(); if (account != null) { retVal.Participations.Add(new ActParticipation(ActParticipationKey.Holder, retVal) { SourceEntityKey = account.Key }); } else { retVal.Participations.Add(new ActParticipation(ActParticipationKey.Holder, retVal) { SourceEntity = new Account() { Identifiers = new List <ActIdentifier>() { new ActIdentifier() { Authority = pidSegment.PatientAccountNumber.AssigningAuthority.ToModel(), Value = pidSegment.PatientAccountNumber.IDNumber.Value } }, StatusConceptKey = StatusKeys.New } }); } } // SSN fieldNo = 19; // Patient account, locate the specified account if (!String.IsNullOrEmpty(pidSegment.SSNNumberPatient.Value)) { var ssn = pidSegment.SSNNumberPatient.Value; // Lookup identity domain which is designated as SSN , if they already have one update it, if not, add it var existing = retVal.Identifiers.FirstOrDefault(o => o.AuthorityKey == this.m_configuration.SsnAuthority.Key || o.LoadProperty(x => x.AuthorityXml).DomainName == this.m_configuration.SsnAuthority?.DomainName); if (existing == null) { retVal.Identifiers.Add(new EntityIdentifier(this.m_configuration.SsnAuthority, ssn)); } else { existing.Value = ssn; } } // Birth place is present fieldNo = 23; if (!pidSegment.BirthPlace.IsEmpty()) // We need to find the birthplace relationship { var existing = retVal.LoadProperty(o => o.Relationships).FirstOrDefault(o => o.RelationshipTypeKey == EntityRelationshipTypeKeys.Birthplace); if (Guid.TryParse(pidSegment.BirthPlace.Value, out Guid birthPlaceId)) { if (existing == null) { retVal.LoadProperty(o => o.Relationships).Add(new EntityRelationship(EntityRelationshipTypeKeys.Birthplace, birthPlaceId)); } else { existing.TargetEntityKey = birthPlaceId; } } else { var places = ApplicationServiceContext.Current.GetService <IDataPersistenceService <Place> >()?.Query(o => o.Names.Any(n => n.Component.Any(c => c.Value == pidSegment.BirthPlace.Value)), AuthenticationContext.SystemPrincipal); if (this.m_configuration.BirthplaceClassKeys.Any()) { places = places.Where(o => this.m_configuration.BirthplaceClassKeys.Contains(o.ClassConceptKey.Value)); } // Still conflicts? Check for same region as address if (places.Count() > 1 && !this.m_configuration.StrictMetadataMatch) { var placeClasses = places.GroupBy(o => o.ClassConceptKey).OrderBy(o => Array.IndexOf(AddressHierarchy, o.Key.Value)); // Take the first wrung of the address hierarchy places = placeClasses.First(); if (places.Count() > 1) // Still more than one type of place { places = places.Where(p => p.LoadCollection <EntityAddress>(nameof(Entity.Addresses)).Any(a => a.Component.All(a2 => retVal.LoadCollection <EntityAddress>(nameof(Entity.Addresses)).Any(pa => pa.Component.Any(pc => pc.Value == a2.Value && pc.ComponentTypeKey == a2.ComponentTypeKey))))); } } // Assign if only one place if (places.Count() == 1) { if (existing == null) { retVal.Relationships.Add(new EntityRelationship(EntityRelationshipTypeKeys.Birthplace, places.First().Key)); } else { existing.TargetEntityKey = places.First().Key; } } else { throw new KeyNotFoundException(this.m_localizationService.FormatString("error.messaging.hl7.birthPlace", new { param = pidSegment.BirthPlace.Value, param2 = places.Count() })); } } } // MB indicator if (!pidSegment.MultipleBirthIndicator.IsEmpty()) { retVal.MultipleBirthOrder = pidSegment.MultipleBirthIndicator.Value == "Y" ? (int?)-1 : null; } if (!pidSegment.BirthOrder.IsEmpty()) { retVal.MultipleBirthOrder = Int32.Parse(pidSegment.BirthOrder.Value); } // Citizenship fieldNo = 26; if (pidSegment.CitizenshipRepetitionsUsed > 0) { foreach (var cit in pidSegment.GetCitizenship()) { var place = ApplicationServiceContext.Current.GetService <IDataPersistenceService <Place> >()?.Query(o => o.Identifiers.Any(i => i.Value == cit.Identifier.Value && i.Authority.Key == AssigningAuthorityKeys.Iso3166CountryCode), AuthenticationContext.SystemPrincipal).FirstOrDefault(); if (place != null) { if (!retVal.Relationships.Any(r => r.RelationshipTypeKey == EntityRelationshipTypeKeys.Citizen && r.TargetEntityKey == place.Key)) { retVal.Relationships.Add(new EntityRelationship(EntityRelationshipTypeKeys.Citizen, place.Key)); } } else { m_tracer.TraceError($"Cannot find country with code {cit.Identifier.Value}"); throw new KeyNotFoundException(this.m_localizationService.FormatString("error.messaging.hl7.countryCode", new { param = cit.Identifier.Value })); } } } // Death info fieldNo = 29; if (!pidSegment.PatientDeathIndicator.IsEmpty()) { retVal.DeceasedDate = pidSegment.PatientDeathIndicator.Value == "Y" ? (DateTime?)DateTime.MinValue : null; } if (!pidSegment.PatientDeathDateAndTime.IsEmpty()) { retVal.DeceasedDate = pidSegment.PatientDeathDateAndTime.ToModel(); retVal.DeceasedDatePrecision = pidSegment.PatientDeathDateAndTime.ToDatePrecision(); } // Last update time if (!pidSegment.LastUpdateDateTime.IsEmpty()) { retVal.CreationTime = (DateTimeOffset)pidSegment.LastUpdateDateTime.ToModel(); } //if(!pidSegment.LastUpdateFacility.IsEmpty()) //{ // // Find by user ID // var user = ApplicationServiceContext.Current.GetService<IDataPersistenceService<SecurityUser>>().Query(u=>u.UserName == pidSegment.LastUpdateFacility.NamespaceID.Value).FirstOrDefault(); // if (user != null) // retVal.CreatedBy = user; //} retVal.AddTag(Hl7Constants.FocalObjectTag, "true"); retCollection.Add(retVal); return(retCollection); } catch (HL7ProcessingException e) // Just re-throw { throw; } catch (HL7DatatypeProcessingException e) { throw new HL7ProcessingException(this.m_localizationService.FormatString("error.type.HL7ProcessingException", new { param = "PID" }), "PID", pidSegment.SetIDPID.Value, fieldNo, e.Component, e); } catch (Exception e) { throw new HL7ProcessingException(this.m_localizationService.FormatString("error.type.HL7ProcessingException", new { param = "PID" }), "PID", pidSegment.SetIDPID.Value, fieldNo, 1, e); } }
/// <summary> /// Parse the parse the specified segment into a patient object /// </summary> /// <param name="segment">The segment to be parsed</param> /// <returns>The parsed patient information</returns> public virtual IEnumerable <IdentifiedData> Parse(ISegment segment, IEnumerable <IdentifiedData> context) { var patientService = ApplicationServiceContext.Current.GetService <IDataPersistenceService <Patient> >(); var personService = ApplicationServiceContext.Current.GetService <IDataPersistenceService <Person> >(); var pidSegment = segment as PID; int fieldNo = 0; try { Patient retVal = new Patient() { Key = Guid.NewGuid() }; Person motherEntity = null; List <IdentifiedData> retCollection = new List <IdentifiedData>(); retVal.CreationAct = context.OfType <ControlAct>().FirstOrDefault(); // Existing patient? if (pidSegment.Message.GetStructureName().StartsWith("ADT")) { foreach (var id in pidSegment.GetPatientIdentifierList()) { var idnumber = id.IDNumber.Value; AssigningAuthority authority; try { authority = id.AssigningAuthority.ToModel(); } catch (Exception e) { throw new HL7ProcessingException("Error processig assigning authority", "PID", pidSegment.SetIDPID.Value, 3, 4, e); } if (authority == null) { throw new HL7ProcessingException($"No authority configured for {id.AssigningAuthority.NamespaceID.Value}", "PID", pidSegment.SetIDPID.Value, 3, 4); } Guid idguid = Guid.Empty; Person found = null; if (authority.Key == this.m_configuration.LocalAuthority.Key) { found = personService.Get(Guid.Parse(id.IDNumber.Value), null, true, AuthenticationContext.Current.Principal); } else if (authority?.IsUnique == true) { found = personService.Query(o => o.Identifiers.Any(i => i.Authority.Key == authority.Key && i.Value == idnumber), AuthenticationContext.SystemPrincipal).FirstOrDefault(); } if (found != null) { if (found is Patient) { retVal = (Patient)found; } else // We need to upgrade this person { retVal.CopyObjectData(found, false, true); retVal.Tags.Add(new EntityTag("$sys.reclass", "true")); } break; } } } fieldNo = 2; if (!pidSegment.PatientID.IsEmpty()) { retVal.Identifiers.Add(pidSegment.PatientID.ToModel()); } fieldNo = 3; if (pidSegment.PatientIdentifierListRepetitionsUsed > 0) { retVal.Identifiers.AddRange( pidSegment.GetPatientIdentifierList().ToModel().Where(o => !retVal.Identifiers.Any(i => i.Authority.Key == o.AuthorityKey && i.Value == o.Value)).ToArray() ); } // Find the key for the patient var keyId = pidSegment.GetPatientIdentifierList().FirstOrDefault(o => o.AssigningAuthority.NamespaceID.Value == this.m_configuration.LocalAuthority.DomainName); if (keyId != null) { retVal.Key = Guid.Parse(keyId.IDNumber.Value); } if (retVal.Identifiers.Count == 0) { throw new HL7ProcessingException("Couldn't understand any patient identity", "PID", pidSegment.SetIDPID.Value, 3, 1); } fieldNo = 5; if (pidSegment.PatientNameRepetitionsUsed > 0) { foreach (var itm in pidSegment.GetPatientName()) { var model = itm.ToModel(); var existing = retVal.Names.FirstOrDefault(o => o.NameUseKey == model.NameUseKey); if (existing == null) { retVal.Names.Add(model); } else { existing.CopyObjectData(model); } } } fieldNo = 21; // Mother's maiden name, create a relationship for mother if (pidSegment.MotherSMaidenNameRepetitionsUsed > 0 || pidSegment.MotherSIdentifierRepetitionsUsed > 0) { // Attempt to find the mother foreach (var id in pidSegment.GetMotherSIdentifier()) { AssigningAuthority authority = null; try { authority = id.AssigningAuthority.ToModel(); } catch (Exception e) { throw new HL7ProcessingException("Error processing mother's identifiers", "PID", pidSegment.SetIDPID.Value, 21, 3); } if (authority.Key == this.m_configuration.LocalAuthority.Key) { motherEntity = personService.Get(Guid.Parse(id.IDNumber.Value), null, true, AuthenticationContext.SystemPrincipal); } else if (authority?.IsUnique == true) { motherEntity = personService.Query(o => o.Identifiers.Any(i => i.Value == id.IDNumber.Value && i.Authority.Key == authority.Key), AuthenticationContext.SystemPrincipal).FirstOrDefault(); } } fieldNo = 6; // Mother doesn't exist, so add it if (motherEntity == null) { motherEntity = new Person() { Key = Guid.NewGuid(), Identifiers = pidSegment.GetMotherSIdentifier().ToModel().ToList(), Names = pidSegment.GetMotherSMaidenName().ToModel(NameUseKeys.MaidenName).ToList(), StatusConceptKey = StatusKeys.New } } ; var existingRelationship = retVal.Relationships.FirstOrDefault(r => r.SourceEntityKey == retVal.Key && r.TargetEntityKey == motherEntity.Key); if (existingRelationship == null) { // Find by mother relationship existingRelationship = retVal.Relationships.FirstOrDefault(o => o.RelationshipTypeKey == EntityRelationshipTypeKeys.Mother); if (existingRelationship == null) // No current mother relationship { retVal.Relationships.Add(new EntityRelationship(EntityRelationshipTypeKeys.Mother, motherEntity.Key)); } else if (!existingRelationship.LoadProperty <Entity>("TargetEntity").SemanticEquals(motherEntity)) { existingRelationship.TargetEntityKey = motherEntity.Key; } } else { existingRelationship.RelationshipTypeKey = EntityRelationshipTypeKeys.Mother; } } // Date/time of birth fieldNo = 7; if (!pidSegment.DateTimeOfBirth.IsEmpty()) { retVal.DateOfBirth = pidSegment.DateTimeOfBirth.ToModel(); retVal.DateOfBirthPrecision = pidSegment.DateTimeOfBirth.ToDatePrecision(); } // Administrative gender fieldNo = 8; if (!pidSegment.AdministrativeSex.IsEmpty()) { retVal.GenderConcept = pidSegment.AdministrativeSex.ToConcept(AdministrativeGenderCodeSystem); } // Patient Alias fieldNo = 9; if (pidSegment.PatientAliasRepetitionsUsed > 0) { retVal.Names.AddRange(pidSegment.GetPatientAlias().ToModel()); } // Race codes fieldNo = 10; if (pidSegment.RaceRepetitionsUsed > 0) { ; // TODO: Implement as an extension if needed } // Addresses fieldNo = 11; if (pidSegment.PatientAddressRepetitionsUsed > 0) { foreach (var itm in pidSegment.GetPatientAddress()) { var model = itm.ToModel(); var existing = retVal.Addresses.FirstOrDefault(o => o.AddressUseKey == model.AddressUseKey); if (existing == null) { retVal.Addresses.Add(model); } else { existing.CopyObjectData(model); } } } // Fields fieldNo = 13; var telecoms = pidSegment.GetPhoneNumberBusiness().Union(pidSegment.GetPhoneNumberHome()); foreach (var itm in telecoms) { var model = itm.ToModel(); var existing = retVal.Telecoms.FirstOrDefault(o => o.AddressUseKey == model.AddressUseKey); if (existing == null) { retVal.Telecoms.Add(model); } else { existing.CopyObjectData(model); } } // Language if (!pidSegment.PrimaryLanguage.IsEmpty()) { retVal.LanguageCommunication = new List <PersonLanguageCommunication>() { new PersonLanguageCommunication(pidSegment.PrimaryLanguage.Identifier.Value.ToLower(), true) } } ; // Marital Status fieldNo = 16; if (!pidSegment.MaritalStatus.IsEmpty()) { retVal.MaritalStatus = pidSegment.MaritalStatus.ToModel(MaritalStatusCodeSystem); } // Religion fieldNo = 17; if (!pidSegment.Religion.IsEmpty()) { retVal.ReligiousAffiliation = pidSegment.Religion.ToModel(ReligionCodeSystem); } // Ethinic groups fieldNo = 22; if (pidSegment.EthnicGroupRepetitionsUsed > 0) { retVal.EthnicGroupCodeKey = pidSegment.GetEthnicGroup().First().ToModel(EthnicGroupCodeSystem).Key; } fieldNo = 18; // Patient account, locate the specified account if (!pidSegment.PatientAccountNumber.IsEmpty()) { var account = ApplicationServiceContext.Current.GetService <IDataPersistenceService <Account> >()?.Query(o => o.Identifiers.Any(i => i.Value == pidSegment.PatientAccountNumber.IDNumber.Value), AuthenticationContext.SystemPrincipal).FirstOrDefault(); if (account != null) { retVal.Participations.Add(new ActParticipation(ActParticipationKey.Holder, retVal) { SourceEntityKey = account.Key }); } else { retVal.Participations.Add(new ActParticipation(ActParticipationKey.Holder, retVal) { SourceEntity = new Account() { Identifiers = new List <ActIdentifier>() { new ActIdentifier() { Authority = pidSegment.PatientAccountNumber.AssigningAuthority.ToModel(), Value = pidSegment.PatientAccountNumber.IDNumber.Value } }, StatusConceptKey = StatusKeys.New } }); } } // SSN fieldNo = 19; // Patient account, locate the specified account if (!String.IsNullOrEmpty(pidSegment.SSNNumberPatient.Value)) { var ssn = pidSegment.SSNNumberPatient.Value; // Lookup identity domain which is designated as SSN , if they already have one update it, if not, add it var existing = retVal.Identifiers.FirstOrDefault(o => o.Authority.DomainName == this.m_configuration.SsnAuthority?.DomainName); if (existing == null) { retVal.Identifiers.Add(new EntityIdentifier(this.m_configuration.SsnAuthority, ssn)); } else { existing.Value = ssn; } } // Birth place is present fieldNo = 23; if (!pidSegment.BirthPlace.IsEmpty()) // We need to find the birthplace relationship { var existing = retVal.Relationships.FirstOrDefault(o => o.RelationshipTypeKey == EntityRelationshipTypeKeys.Birthplace); if (Guid.TryParse(pidSegment.BirthPlace.Value, out Guid birthPlaceId)) { if (existing == null) { retVal.Relationships.Add(new EntityRelationship(EntityRelationshipTypeKeys.Birthplace, birthPlaceId)); } else { existing.TargetEntityKey = birthPlaceId; } } else { var places = ApplicationServiceContext.Current.GetService <IDataPersistenceService <Place> >()?.Query(o => o.Names.Any(n => n.Component.Any(c => c.Value == pidSegment.BirthPlace.Value)), AuthenticationContext.SystemPrincipal).Where(o => this.m_configuration.BirthplaceClassKeys.Contains(o.ClassConceptKey.Value)); if (places.Count() == 1) { if (existing == null) { retVal.Relationships.Add(new EntityRelationship(EntityRelationshipTypeKeys.Birthplace, places.First().Key)); } else { existing.TargetEntityKey = places.First().Key; } } else { throw new KeyNotFoundException($"Cannot find unique birth place registration with name {pidSegment.BirthPlace.Value} ({places.Count()} results found). Try using UUID."); } } } // MB indicator if (!pidSegment.MultipleBirthIndicator.IsEmpty()) { retVal.MultipleBirthOrder = pidSegment.MultipleBirthIndicator.Value == "Y" ? (int?)-1 : null; } if (!pidSegment.BirthOrder.IsEmpty()) { retVal.MultipleBirthOrder = Int32.Parse(pidSegment.BirthOrder.Value); } // Citizenship fieldNo = 26; if (pidSegment.CitizenshipRepetitionsUsed > 0) { foreach (var cit in pidSegment.GetCitizenship()) { var places = ApplicationServiceContext.Current.GetService <IDataPersistenceService <Place> >()?.Query(o => o.Identifiers.Any(i => i.Value == cit.Identifier.Value && i.Authority.Key == AssigningAuthorityKeys.Iso3166CountryCode), AuthenticationContext.SystemPrincipal); if (places.Count() == 1) { retVal.Relationships.Add(new EntityRelationship(EntityRelationshipTypeKeys.Citizen, places.First().Key)); } else { throw new KeyNotFoundException($"Cannot find country with code {cit.Identifier.Value}"); } } } // Death info fieldNo = 29; if (!pidSegment.PatientDeathIndicator.IsEmpty()) { retVal.DeceasedDate = pidSegment.PatientDeathIndicator.Value == "Y" ? (DateTime?)DateTime.MinValue : null; } if (!pidSegment.PatientDeathDateAndTime.IsEmpty()) { retVal.DeceasedDate = pidSegment.PatientDeathDateAndTime.ToModel(); retVal.DeceasedDatePrecision = pidSegment.PatientDeathDateAndTime.ToDatePrecision(); } // Last update time if (!pidSegment.LastUpdateDateTime.IsEmpty()) { retVal.CreationTime = (DateTimeOffset)pidSegment.LastUpdateDateTime.ToModel(); } //if(!pidSegment.LastUpdateFacility.IsEmpty()) //{ // // Find by user ID // var user = ApplicationServiceContext.Current.GetService<IDataPersistenceService<SecurityUser>>().Query(u=>u.UserName == pidSegment.LastUpdateFacility.NamespaceID.Value).FirstOrDefault(); // if (user != null) // retVal.CreatedBy = user; //} if (motherEntity != null) { retCollection.Add(motherEntity); } retCollection.Add(retVal); return(retCollection); } catch (HL7ProcessingException e) // Just re-throw { throw; } catch (HL7DatatypeProcessingException e) { throw new HL7ProcessingException("Error processing PID segment", "PID", pidSegment.SetIDPID.Value, fieldNo, e.Component, e); } catch (Exception e) { throw new HL7ProcessingException("Error processing PID segment", "PID", pidSegment.SetIDPID.Value, fieldNo, 1, e); } }
/// <summary> /// Updates an assigning authority. /// </summary> /// <param name="assigningAuthorityId">The id of the assigning authority to be updated.</param> /// <param name="assigningAuthorityInfo">The assigning authority info containing the updated information.</param> /// <returns>Returns the updated assigning authority.</returns> public AssigningAuthority UpdateAssigningAuthority(Guid assigningAuthorityId, AssigningAuthority assigningAuthorityInfo) { return(this.Client.Put <AssigningAuthority, AssigningAuthority>($"AssigningAuthority/{assigningAuthorityId}", assigningAuthorityInfo)); }
/// <summary> /// Initializes a new instance of the <see cref="AssigningAuthorityInfo"/> class /// with a specific assigning authority. /// </summary> public AssigningAuthorityInfo(AssigningAuthority assigningAuthority) { this.Id = assigningAuthority.Key.GetValueOrDefault(Guid.Empty); this.AssigningAuthority = assigningAuthority; }