Пример #1
0
        /// <summary>
        /// Create Get Patient details
        /// </summary>
        internal MARC.Everest.RMIM.CA.R020403.MFMI_MT700746CA.RegistrationEvent <MARC.Everest.RMIM.CA.R020403.PRPA_MT101102CA.IdentifiedEntity> CreateRegistrationEventDetailEx(RegistrationEvent res, List <IResultDetail> details)
        {
            var retVal = new MARC.Everest.RMIM.CA.R020403.MFMI_MT700746CA.RegistrationEvent <MARC.Everest.RMIM.CA.R020403.PRPA_MT101102CA.IdentifiedEntity>();

            var person          = res.FindComponent(HealthServiceRecordSiteRoleType.SubjectOf) as Person;
            var custodialDevice = res.FindComponent(HealthServiceRecordSiteRoleType.PlaceOfRecord | HealthServiceRecordSiteRoleType.ResponsibleFor) as RepositoryDevice;
            var replacement     = res.FindAllComponents(HealthServiceRecordSiteRoleType.ReplacementOf);

            // person
            if (person == null)
            {
                retVal.Subject = new MARC.Everest.RMIM.CA.R020403.MFMI_MT700746CA.Subject4 <MARC.Everest.RMIM.CA.R020403.PRPA_MT101102CA.IdentifiedEntity>()
                {
                    NullFlavor = NullFlavor.NoInformation
                }
            }
            ;
            else
            {
                retVal.Subject = new MARC.Everest.RMIM.CA.R020403.MFMI_MT700746CA.Subject4 <MARC.Everest.RMIM.CA.R020403.PRPA_MT101102CA.IdentifiedEntity>(CreateRegisteredRoleAlt(person, details));
            }

            // custodial device
            if (custodialDevice == null)
            {
                retVal.Custodian = new MARC.Everest.RMIM.CA.R020403.REPC_MT000007CA.Custodian()
                {
                    NullFlavor = NullFlavor.NoInformation
                }
            }
            ;
            else
            {
                retVal.Custodian = CreateCustodialDevice(custodialDevice, details);
            }

            // Replacement
            foreach (RegistrationEvent replc in replacement)
            {
                retVal.ReplacementOf.Add(new MARC.Everest.RMIM.CA.R020403.MFMI_MT700726CA.ReplacementOf(
                                             new MARC.Everest.RMIM.CA.R020403.MFMI_MT700726CA.PriorRegistration(
                                                 new MARC.Everest.RMIM.CA.R020403.MFMI_MT700726CA.Subject5(
                                                     new MARC.Everest.RMIM.CA.R020403.MFMI_MT700726CA.PriorRegisteredRole()
                {
                    Id = CreateII(replc.AlternateIdentifier, details)
                }
                                                     )
                                                 )
                                             ));
            }

            return(retVal);
        }
Пример #2
0
        /// <summary>
        /// Create custodial data from either a RepositoryDevice or a HealthcareParticipant
        /// </summary>
        private Everest.RMIM.UV.NE2008.MFMI_MT700701UV01.Custodian CreateCustodian(RegistrationEvent registrationEvent, TargetConfiguration configuration)
        {
            ISystemConfigurationService sysConfig = this.Context.GetService(typeof(ISystemConfigurationService)) as ISystemConfigurationService;

            var subject = registrationEvent.FindComponent(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.SubjectOf) as Person;
            var iiSet   = new List <II>(CreateIISet(subject.AlternateIdentifiers));

            iiSet.RemoveAll(ii => !configuration.NotificationDomain.Exists(o => o.Domain.Equals(ii.Root)));

            var oidData = sysConfig.OidRegistrar.FindData(iiSet[0].Root);

            if (oidData == null)
            {
                throw new InvalidOperationException("Cannot find notification settings for " + oidData);
            }

            var retVal = new Everest.RMIM.UV.NE2008.MFMI_MT700701UV01.Custodian(
                new Everest.RMIM.UV.NE2008.COCT_MT090003UV01.AssignedEntity()
                );

            // Device
            retVal.AssignedEntity.SetAssignedPrincipalChoiceList(
                new Everest.RMIM.UV.NE2008.COCT_MT090303UV01.Device(
                    SET <II> .CreateSET(new II(oidData.Attributes.Find(o => o.Key == "CustodialDeviceId").Value ?? oidData.Oid)),
                    null,
                    oidData.Attributes.Find(o => o.Key == "CustodialDeviceName").Value ?? oidData.Description
                    )
                );
            retVal.AssignedEntity.Id = SET <II> .CreateSET(new II(oidData.Oid));

            return(retVal);
        }
Пример #3
0
        /// <summary>
        /// Enrich the registration event
        /// </summary>
        internal void EnrichRegistrationEvent(IDbConnection conn, IDbTransaction tx, RegistrationEvent hsrEvent)
        {
            decimal tryDec;
            ISystemConfigurationService configService = ApplicationContext.ConfigurationService;

            // Create a query based on the person
            Person subject = hsrEvent.FindComponent(HealthServiceRecordSiteRoleType.SubjectOf) as Person;

            if (subject.AlternateIdentifiers.Exists(o => o.Domain == configService.OidRegistrar.GetOid(ClientRegistryOids.CLIENT_CRID).Oid))
            {
                subject = new Person()
                {
                    AlternateIdentifiers = new List <DomainIdentifier>(subject.AlternateIdentifiers.FindAll(o => o.Domain == configService.OidRegistrar.GetOid(ClientRegistryOids.CLIENT_CRID).Oid)),
                    Status = StatusType.Normal
                }
            }
            ;
            else if (subject.AlternateIdentifiers.Exists(o => o is AuthorityAssignedDomainIdentifier))
            {
                subject = new Person()
                {
                    AlternateIdentifiers = new List <DomainIdentifier>(subject.AlternateIdentifiers.FindAll(o => o is AuthorityAssignedDomainIdentifier)),
                    Status = StatusType.Normal
                }
            }
            ;
            else
            {
                subject = new Person()
                {
                    AlternateIdentifiers = new List <DomainIdentifier>(subject.AlternateIdentifiers),
                    Status = StatusType.Normal
                }
            };

            QueryEvent        query = new QueryEvent();
            RegistrationEvent evt   = new RegistrationEvent();

            query.Add(evt, "SUBJ", HealthServiceRecordSiteRoleType.SubjectOf, null);
            evt.Status = StatusType.Active | StatusType.Obsolete;
            evt.Add(subject, "SUBJ", HealthServiceRecordSiteRoleType.SubjectOf, null);
            query.Add(new QueryParameters()
            {
                MatchingAlgorithm = MatchAlgorithm.Exact,
                MatchStrength     = MatchStrength.Exact
            }, "FLTR", HealthServiceRecordSiteRoleType.FilterOf, null);
            var tRecordIds = QueryRecord(query);

            if (tRecordIds.Length != 1)
            {
                throw new MissingPrimaryKeyException(ApplicationContext.LocaleService.GetString("DBCF004"));
            }
            else if (tRecordIds[0].Domain != configService.OidRegistrar.GetOid(ClientRegistryOids.REGISTRATION_EVENT).Oid)
            {
                throw new MissingPrimaryKeyException(ApplicationContext.LocaleService.GetString("DBCF005"));
            }

            tryDec = Decimal.Parse(tRecordIds[0].Identifier);
            hsrEvent.AlternateIdentifier = tRecordIds[0];
        }
Пример #4
0
        /// <summary>
        /// Validate identifiers
        /// </summary>
        internal bool ValidateIdentifiers(RegistrationEvent data, List <IResultDetail> dtls)
        {
            Person subject = data.FindComponent(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.SubjectOf) as Person;
            //var scoper = subject.FindComponent(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.PlaceOfEntry | SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.InformantTo) as HealthcareParticipant;
            //var custodian = data.FindComponent(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.PlaceOfRecord | SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.ResponsibleFor);

            bool isValid = true;

            //// Validate the root
            //foreach (var id in subject.AlternateIdentifiers)
            //    if (scoper != null && !scoper.AlternateIdentifiers.Exists(o => o.Domain == id.Domain))
            //    {
            //        isValid = false;
            //        dtls.Add(new FormalConstraintViolationResultDetail(ResultDetailType.Error, this.m_localeService.GetString("MSGW015"), null, null));
            //    }
            //    else if (scoper != null && String.IsNullOrEmpty(id.AssigningAuthority))
            //        id.AssigningAuthority = scoper.LegalName.Parts[0].Value;
            //    else if (String.IsNullOrEmpty(id.AssigningAuthority) && custodian is RepositoryDevice && (custodian as RepositoryDevice).AlternateIdentifier.Domain == id.Domain)
            //        id.AssigningAuthority = (custodian as RepositoryDevice).Name;
            //    else if (String.IsNullOrEmpty(id.AssigningAuthority) && custodian is HealthcareParticipant && (custodian as HealthcareParticipant).AlternateIdentifiers.Exists(o => o.Domain == id.Domain))
            //        id.AssigningAuthority = (custodian as HealthcareParticipant).LegalName.Parts[0].Value;


            // Validate we know all identifiers
            foreach (var id in subject.AlternateIdentifiers)
            {
                if (String.IsNullOrEmpty(id.AssigningAuthority))
                {
                    dtls.Add(new FormalConstraintViolationResultDetail(ResultDetailType.Error, String.Format(m_localeService.GetString("MSGE06A"), id.Domain), null, null));
                    isValid = false;
                }
            }

            return(isValid);
        }
Пример #5
0
        /// <summary>
        /// Create patient structure for the person suitable for a create
        /// </summary>
        private Everest.RMIM.UV.NE2008.MFMI_MT700701UV01.Subject2 <Everest.RMIM.UV.NE2008.PRPA_MT201301UV02.Patient> CreatePatient(RegistrationEvent registrationEvent, TargetConfiguration configuration)
        {
            // Get the subject from the list of components
            var subject     = registrationEvent.FindComponent(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.SubjectOf) as Person;
            var masking     = subject.FindComponent(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.FilterOf) as MaskingIndicator;
            var providerOrg = subject.FindComponent(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.PlaceOfEntry | SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.InformantTo) as HealthcareParticipant;

            if (subject == null) // validate
            {
                return(null);
            }

            var iiSet = new List <II>(CreateIISet(subject.AlternateIdentifiers));

            iiSet.RemoveAll(ii => !configuration.NotificationDomain.Exists(o => o.Domain.Equals(ii.Root)));

            // Construct the return value
            var retVal = new Everest.RMIM.UV.NE2008.MFMI_MT700701UV01.Subject2 <Everest.RMIM.UV.NE2008.PRPA_MT201301UV02.Patient>(
                new Everest.RMIM.UV.NE2008.PRPA_MT201301UV02.Patient(
                    new SET <II>(iiSet),
                    CreatePerson(subject, configuration),
                    null
                    ));

            // Act as a source?
            // Masking indicator
            if (masking != null)
            {
                retVal.registeredRole.ConfidentialityCode = new SET <CE <string> >(CreateCD <String>(masking.MaskingCode));
            }

            // Provider org
            var oidData = m_configService.OidRegistrar.FindData(iiSet[0].Root);

            if (oidData != null)
            {
                retVal.registeredRole.ProviderOrganization = new Everest.RMIM.UV.NE2008.COCT_MT150003UV03.Organization()
                {
                    Id           = SET <II> .CreateSET(new II(oidData.Oid)),
                    Name         = BAG <ON> .CreateBAG(ON.CreateON(null, new ENXP(oidData.Attributes.Find(o => o.Key == "CustodialOrgName").Value ?? oidData.Description))),
                    ContactParty = new List <Everest.RMIM.UV.NE2008.COCT_MT150003UV03.ContactParty>()
                    {
                        new Everest.RMIM.UV.NE2008.COCT_MT150003UV03.ContactParty()
                        {
                            NullFlavor = NullFlavor.NoInformation
                        }
                    }
                };
            }
            return(retVal);
        }
        /// <summary>
        /// Find conflicts using identifiers
        /// </summary>
        public IEnumerable <SVC.Core.DataTypes.VersionedDomainIdentifier> FindIdConflicts(RegistrationEvent registration)
        {
            var registrationService = this.Context.GetService(typeof(IDataRegistrationService)) as IDataRegistrationService;

            VersionedDomainIdentifier[] pid = null;

            // Check if the person exists just via the identifier?
            // This is important because it is not necessarily a merge but an "update if exists"
            var             subject = registration.FindComponent(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.SubjectOf) as Person;
            QueryParameters qp      = new QueryParameters()
            {
                Confidence        = 1.0f,
                MatchingAlgorithm = MatchAlgorithm.Exact,
                MatchStrength     = MatchStrength.Exact
            };

            var config = this.Context.GetService(typeof(ISystemConfigurationService)) as ISystemConfigurationService;

            List <VersionedDomainIdentifier> conflictIds = new List <VersionedDomainIdentifier>();

            foreach (var id in subject.AlternateIdentifiers)
            {
                var data = config.OidRegistrar.FindData(id.Domain);
                if (data == null || !data.Attributes.Exists(a => a.Key == "IsUniqueIdentifier" && Convert.ToBoolean(a.Value)))
                {
                    continue;
                }
                var patientQuery      = new QueryEvent();
                var registrationEvent = new RegistrationEvent();
                patientQuery.Add(registrationEvent, "SUBJ", HealthServiceRecordSiteRoleType.SubjectOf, null);
                patientQuery.Add(qp, "FLT", SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.FilterOf, null);
                registrationEvent.Add(new Person()
                {
                    AlternateIdentifiers = new List <DomainIdentifier>()
                    {
                        id
                    }
                }, "SUBJ", SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.SubjectOf, null);
                // Perform the query
                pid = registrationService.QueryRecord(patientQuery);
                foreach (var result in pid)
                {
                    if (!conflictIds.Exists(o => o.Identifier.ToString() == result.Identifier))
                    {
                        conflictIds.Add(result);
                    }
                }
            }
            return(conflictIds.ToArray());
        }
Пример #7
0
        /// <summary>
        /// Update QRI
        /// </summary>
        private void UpdateQRI(RegistrationEvent res, NHapi.Model.V25.Segment.QRI qri)
        {
            var subject    = res.FindComponent(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.SubjectOf) as Person;
            var confidence = subject.FindComponent(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.CommentOn | SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.ComponentOf) as QueryParameters;

            if (confidence != null)
            {
                if (confidence.MatchingAlgorithm == MatchAlgorithm.Soundex)
                {
                    qri.AlgorithmDescriptor.Identifier.Value = "Soundex";
                }
                else if (confidence.MatchingAlgorithm == MatchAlgorithm.Variant)
                {
                    qri.AlgorithmDescriptor.Identifier.Value = "Variant";
                }

                if (confidence.MatchingAlgorithm == MatchAlgorithm.Unspecified) // identifier match
                {
                    qri.GetMatchReasonCode(qri.MatchReasonCodeRepetitionsUsed).Value = "ID";
                }
                else if (confidence.MatchingAlgorithm == MatchAlgorithm.Soundex) // soundex
                {
                    qri.GetMatchReasonCode(qri.MatchReasonCodeRepetitionsUsed).Value = "NP";
                }
                else if (confidence.MatchingAlgorithm == MatchAlgorithm.Exact) // match
                {
                    qri.GetMatchReasonCode(qri.MatchReasonCodeRepetitionsUsed).Value = "NA";
                }
                else if (confidence.MatchingAlgorithm == MatchAlgorithm.Variant) // variant
                {
                    qri.GetMatchReasonCode(qri.MatchReasonCodeRepetitionsUsed).Value = "VAR";
                }

                // Confidence
                qri.CandidateConfidence.Value = confidence.Confidence.ToString("0.##");
            }
        }
Пример #8
0
        /// <summary>
        /// Create an instance of the identified entity class from the specified person class
        /// </summary>
        internal MARC.Everest.RMIM.CA.R020403.PRPA_MT101102CA.IdentifiedEntity CreateIdentifiedEntity(RegistrationEvent verified, List <IResultDetail> dtls)
        {
            // Get localization service
            ILocalizationService locale = m_context.GetService(typeof(ILocalizationService)) as ILocalizationService;

            // Find the major components
            var person = verified.FindComponent(HealthServiceRecordSiteRoleType.SubjectOf) as Person;

            // Verify
            if (person == null)
            {
                dtls.Add(new NotImplementedResultDetail(ResultDetailType.Error, locale.GetString("DBCF0007"), null, null));
                return(new MARC.Everest.RMIM.CA.R020403.PRPA_MT101102CA.IdentifiedEntity()
                {
                    NullFlavor = NullFlavor.NoInformation
                });
            }

            var mask = person.FindComponent(HealthServiceRecordSiteRoleType.FilterOf) as MaskingIndicator;

            // Return value
            var retVal = new MARC.Everest.RMIM.CA.R020403.PRPA_MT101102CA.IdentifiedEntity(
                CreateIISet(person.AlternateIdentifiers, dtls),
                ConvertStatus(person.Status, dtls),
                CreateIVL(verified.EffectiveTime, dtls),
                mask == null ? null : CreateCV <String>(mask.MaskingCode, dtls),
                CreatePerson(person, dtls),
                new MARC.Everest.RMIM.CA.R020403.PRPA_MT101102CA.Subject()
            {
                NullFlavor = NullFlavor.NotApplicable
            }
                );

            // Return value
            return(retVal);
        }
Пример #9
0
        /// <summary>
        /// Convert the specified patient record to a registration event
        /// </summary>
        internal MARC.Everest.RMIM.UV.NE2008.MFMI_MT700711UV01.RegistrationEvent <MARC.Everest.RMIM.UV.NE2008.PRPA_MT201310UV02.Patient, object> CreateRegistrationEvent(RegistrationEvent res, List <IResultDetail> details)
        {
            // Patient
            var patient = res.FindComponent(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.SubjectOf) as Person;

            if (patient == null)
            {
                return new MARC.Everest.RMIM.UV.NE2008.MFMI_MT700711UV01.RegistrationEvent <MARC.Everest.RMIM.UV.NE2008.PRPA_MT201310UV02.Patient, object>()
                       {
                           NullFlavor = NullFlavor.NoInformation
                       }
            }
            ;

            var scoper         = patient.FindComponent(HealthServiceRecordSiteRoleType.PlaceOfEntry | HealthServiceRecordSiteRoleType.InformantTo) as HealthcareParticipant;
            var queryParameter = patient.FindComponent(HealthServiceRecordSiteRoleType.CommentOn | HealthServiceRecordSiteRoleType.ComponentOf) as QueryParameters;
            var mask           = patient.FindComponent(HealthServiceRecordSiteRoleType.FilterOf) as MaskingIndicator;

            var myOidData = this.m_configService.OidRegistrar.GetOid("CR_CID");

            // Return status
            var retVal = new MARC.Everest.RMIM.UV.NE2008.MFMI_MT700711UV01.RegistrationEvent <MARC.Everest.RMIM.UV.NE2008.PRPA_MT201310UV02.Patient, object>(
                ActStatus.Active,
                new MARC.Everest.RMIM.UV.NE2008.MFMI_MT700711UV01.Subject2 <MARC.Everest.RMIM.UV.NE2008.PRPA_MT201310UV02.Patient>(
                    new MARC.Everest.RMIM.UV.NE2008.PRPA_MT201310UV02.Patient(
                        CreateIISet(patient.AlternateIdentifiers, details),
                        ConvertStatus(patient.Status, details),
                        null,
                        new MARC.Everest.RMIM.UV.NE2008.COCT_MT150003UV03.Organization(
                            SET <II> .CreateSET(new II(myOidData.Oid, null)),
                            null,
                            BAG <ON> .CreateBAG(ON.CreateON(null, new ENXP(myOidData.Attributes.Find(o => o.Key == "CustodialOrgName").Value ?? myOidData.Description))),
                            new MARC.Everest.RMIM.UV.NE2008.COCT_MT150003UV03.ContactParty()
            {
                NullFlavor = NullFlavor.NoInformation
            }
                            ),
                        null
                        )
                    )
                );

            // Custodian
            retVal.Custodian = new MARC.Everest.RMIM.UV.NE2008.MFMI_MT700701UV01.Custodian(
                new MARC.Everest.RMIM.UV.NE2008.COCT_MT090003UV01.AssignedEntity(
                    SET <II> .CreateSET(new II(this.m_configService.Custodianship.Id.Domain))
                    )
            {
                RepresentedOrganization = new MARC.Everest.RMIM.UV.NE2008.COCT_MT150003UV03.Organization(
                    SET <II> .CreateSET(new II(this.m_configService.Custodianship.Id.Domain, null)),
                    null,
                    BAG <ON> .CreateBAG(ON.CreateON(null, new ENXP(this.m_configService.Custodianship.Name))),
                    new MARC.Everest.RMIM.UV.NE2008.COCT_MT150003UV03.ContactParty()
                {
                    NullFlavor = NullFlavor.NoInformation
                }
                    )
            }
                );
            retVal.Subject1.registeredRole.SetPatientEntityChoiceSubject(CreatePersonDetail(patient, details));


            // Mask
            if (mask != null)
            {
                retVal.Subject1.registeredRole.ConfidentialityCode = new SET <CE <string> >(
                    CreateCD <String>(mask.MaskingCode, details)
                    );
            }

            if (patient.VipCode != null)
            {
                retVal.Subject1.registeredRole.VeryImportantPersonCode = CreateCD <String>(patient.VipCode, details);
            }

            // Query observation
            if (queryParameter != null)
            {
                retVal.Subject1.registeredRole.SubjectOf1.Add(new MARC.Everest.RMIM.UV.NE2008.PRPA_MT201310UV02.Subject(
                                                                  new MARC.Everest.RMIM.UV.NE2008.PRPA_MT202310UV02.QueryMatchObservation(
                                                                      new CD <string>(queryParameter.MatchingAlgorithm == MatchAlgorithm.Soundex ? "PHCM" : "PTNM", "2.16.840.1.113883.2.20.5.2"),
                                                                      new INT((int)(queryParameter.Confidence * 100))
                                                                      )
                                                                  ));
            }

            return(retVal);
        }
Пример #10
0
        /// <summary>
        /// Handle duplicates resolved message
        /// </summary>
        private IGraphable HandlePatientRegistryDuplicatesResolved(MARC.Everest.Connectors.UnsolicitedDataEventArgs e, MARC.Everest.Connectors.IReceiveResult receivedMessage)
        {
            // Setup the lists of details and issues
            List <IResultDetail> dtls = new List <IResultDetail>(receivedMessage.Details);

            // System configuration service
            ISystemConfigurationService configService = Context.GetService(typeof(ISystemConfigurationService)) as ISystemConfigurationService;

            // Localization service
            ILocalizationService locale = Context.GetService(typeof(ILocalizationService)) as ILocalizationService;

            // Data Service
            IClientRegistryDataService dataSvc = Context.GetService(typeof(IClientRegistryDataService)) as IClientRegistryDataService;

            // Do basic check and add common validation errors
            MessageUtil.ValidateTransportWrapperUv(receivedMessage.Structure as IInteraction, configService, dtls);

            // Check the request is valid
            var request = receivedMessage.Structure as PRPA_IN201304UV02;

            if (request == null)
            {
                return(null);
            }

            // Determine if the received message was interpreted properly
            bool isValid = MessageUtil.IsValid(receivedMessage);

            // set the URI
            if (request.controlActProcess != null)
            {
                request.controlActProcess.Code = request.controlActProcess.Code ?? Util.Convert <CD <String> >(PRPA_IN201302UV02.GetTriggerEvent());
            }
            if (request.Receiver.Count > 0)
            {
                request.Receiver[0].Telecom = request.Receiver[0].Telecom ?? e.ReceiveEndpoint.ToString();
            }

            // Construct the acknowledgment
            var response = new MCCI_IN000002UV01(
                new II(configService.OidRegistrar.GetOid("CR_MSGID").Oid, Guid.NewGuid().ToString()),
                DateTime.Now,
                MCCI_IN000002UV01.GetInteractionId(),
                request.ProcessingCode,
                request.ProcessingModeCode,
                MessageUtil.CreateReceiver(request.Sender),
                MessageUtil.CreateSenderUv(e.ReceiveEndpoint, configService)
                );


            // Create the support classes
            List <AuditData> audits = new List <AuditData>();

            IheAuditUtil dataUtil = new IheAuditUtil()
            {
                Context = this.Context
            };

            // Try to execute the record
            try
            {
                // Determine if the message is valid
                if (!isValid)
                {
                    throw new MessageValidationException(locale.GetString("MSGE00A"), receivedMessage.Structure);
                }

                // Construct the canonical data structure
                UvComponentUtil cu = new UvComponentUtil()
                {
                    Context = this.Context
                };
                RegistrationEvent data = cu.CreateComponents(request.controlActProcess, dtls);

                // Componentization fail?
                if (data == null || !dataUtil.ValidateIdentifiers(data, dtls))
                {
                    throw new MessageValidationException(locale.GetString("MSGE00A"), receivedMessage.Structure);
                }

                // Store
                var result = dataSvc.Merge(data, request.ProcessingCode != ProcessingID.Production ? DataPersistenceMode.Debugging : DataPersistenceMode.Production);

                if (result == null || result.VersionId == null)
                {
                    throw new Exception(locale.GetString("DTPE001"));
                }

                dtls.AddRange(result.Details);

                // prepare the delete audit
                var person = data.FindComponent(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.SubjectOf) as Person;
                var replc  = person.FindAllComponents(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.ReplacementOf);

                foreach (PersonRegistrationRef rplc in replc)
                {
                    audits.Add(dataUtil.CreateAuditData("ITI-44",
                                                        ActionType.Delete,
                                                        dtls.Exists(r => r.Type == ResultDetailType.Error) ? OutcomeIndicator.MinorFail : OutcomeIndicator.Success,
                                                        e,
                                                        receivedMessage,
                                                        new List <VersionedDomainIdentifier>()
                    {
                        new VersionedDomainIdentifier()
                        {
                            Domain     = rplc.AlternateIdentifiers[0].Domain,
                            Identifier = rplc.AlternateIdentifiers[0].Identifier
                        }
                    },
                                                        data.FindComponent(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.AuthorOf) as HealthcareParticipant));
                }


                // Prepare for audit
                audits.Add(dataUtil.CreateAuditData("ITI-44",
                                                    ActionType.Update,
                                                    dtls.Exists(r => r.Type == ResultDetailType.Error) ? OutcomeIndicator.MinorFail : OutcomeIndicator.Success,
                                                    e,
                                                    receivedMessage,
                                                    new List <VersionedDomainIdentifier>()
                {
                    result.VersionId
                },
                                                    data.FindComponent(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.AuthorOf) as HealthcareParticipant
                                                    ));

                // Add ack
                response.Acknowledgement.Add(new MARC.Everest.RMIM.UV.NE2008.MCCI_MT100200UV01.Acknowledgement(
                                                 AcknowledgementType.AcceptAcknowledgementCommitAccept,
                                                 new MARC.Everest.RMIM.UV.NE2008.MCCI_MT100200UV01.TargetMessage(request.Id)
                                                 ));
            }
            catch (Exception ex)
            {
                Trace.TraceError(ex.ToString());

                // Prepare for audit
                audits.Add(dataUtil.CreateAuditData("ITI-44", ActionType.Create, OutcomeIndicator.EpicFail, e, receivedMessage,
                                                    new List <VersionedDomainIdentifier>(),
                                                    null
                                                    ));

                dtls.Add(new ResultDetail(ResultDetailType.Error, ex.Message, ex));
                response.Acknowledgement.Add(new MARC.Everest.RMIM.UV.NE2008.MCCI_MT100200UV01.Acknowledgement(
                                                 AcknowledgementType.AcceptAcknowledgementCommitError,
                                                 new MARC.Everest.RMIM.UV.NE2008.MCCI_MT100200UV01.TargetMessage(request.Id)
                                                 ));
            }
            finally
            {
                IAuditorService auditService = Context.GetService(typeof(IAuditorService)) as IAuditorService;
                if (auditService != null)
                {
                    foreach (var aud in audits)
                    {
                        auditService.SendAudit(aud);
                    }
                }
            }

            // Common response parameters
            response.ProfileId     = new SET <II>(MCCI_IN000002UV01.GetProfileId());
            response.VersionCode   = HL7StandardVersionCode.Version3_Prerelease1;
            response.AcceptAckCode = AcknowledgementCondition.Never;
            response.Acknowledgement[0].AcknowledgementDetail.AddRange(MessageUtil.CreateAckDetailsUv(dtls.ToArray()));
            return(response);
        }
        /// <summary>
        /// Find conflicts using fuzzy match
        /// </summary>
        public IEnumerable <VersionedDomainIdentifier> FindFuzzyConflicts(RegistrationEvent registration)
        {
            var registrationService = this.Context.GetService(typeof(IDataRegistrationService)) as IDataRegistrationService;
            var persistenceService  = this.Context.GetService(typeof(IDataPersistenceService)) as IDataPersistenceService;

            var clientRegistryConfigService = this.Context.GetService(typeof(IClientRegistryConfigurationService)) as IClientRegistryConfigurationService;

            VersionedDomainIdentifier[] pid = null;

            var             subject = registration.FindComponent(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.SubjectOf) as Person;
            QueryParameters qp      = new QueryParameters()
            {
                Confidence        = 1.0f,
                MatchingAlgorithm = MatchAlgorithm.Exact,
                MatchStrength     = MatchStrength.Exact
            };

            if (subject.Status != StatusType.Active)
            {
                return(pid);
            }

            var patientQuery      = new QueryEvent();
            var registrationEvent = new RegistrationEvent();

            patientQuery.Add(registrationEvent, "SUBJ", HealthServiceRecordSiteRoleType.SubjectOf, null);
            patientQuery.Add(qp, "FLT", SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.FilterOf, null);
            // Create merge filter for fuzzy match
            var ssubject = clientRegistryConfigService.CreateMergeFilter(subject);

            if (ssubject != null) // Minimum criteria was met
            {
                registrationEvent.Add(ssubject, "SUBJ", HealthServiceRecordSiteRoleType.SubjectOf, null);
                pid = registrationService.QueryRecord(patientQuery);
            }
            else
            {
                pid = new VersionedDomainIdentifier[0];
            }


            // Now, look for all with an assigning authority
            if (pid.Length > 0)
            {
                pid = pid.Where(o => !(o.Identifier == registration.Id.ToString() && o.Domain == ApplicationContext.ConfigurationService.OidRegistrar.GetOid(ClientRegistryOids.REGISTRATION_EVENT).Oid)).ToArray();
                // Load each match quickly and ensure that they don't already have a
                // different identifier from an assigning authority (not CR_CID) provided
                // in the registration method. For example, if John Smith, Male, 1984-05-22, 123 Main Street West is
                // registered from system X with ID 102 , and a subsequent registration message for John Smith, Male, 1984-05-22, 123 Main Street West
                // is received from system X with ID 104, it is pretty much assured they aren't the same person. If however the
                // latter message came from system Y with ID 104, then the two should be considered a match.
                ssubject.AlternateIdentifiers = new List <DomainIdentifier>();
                List <VersionedDomainIdentifier> exclude = new List <VersionedDomainIdentifier>();
                foreach (var altId in subject.AlternateIdentifiers)
                {
                    if (altId.Domain != ApplicationContext.ConfigurationService.OidRegistrar.GetOid(ClientRegistryOids.CLIENT_CRID).Oid)
                    {
                        var oidData = ApplicationContext.ConfigurationService.OidRegistrar.FindData(altId.Domain);
                        if (oidData == null ||
                            oidData.Attributes.Find(o => o.Key == "IsUniqueIdentifier").Value == null ||
                            Boolean.Parse(oidData.Attributes.Find(o => o.Key == "IsUniqueIdentifier").Value))
                        {
                            ssubject.AlternateIdentifiers.Add(new DomainIdentifier()
                            {
                                Domain = altId.Domain
                            });
                        }
                    }
                }


                foreach (var p in pid)
                {
                    var re  = persistenceService.GetContainer(p, true) as RegistrationEvent;
                    var pat = re.FindComponent(HealthServiceRecordSiteRoleType.SubjectOf) as Person;
                    if (pat.Id == subject.Id || pat.Status != StatusType.Active)  // same person
                    {
                        exclude.Add(re.AlternateIdentifier);
                    }
                    else if (pat.AlternateIdentifiers.Exists(o => ssubject.AlternateIdentifiers.Exists(r => r.Domain == o.Domain)))
                    {
                        exclude.Add(re.AlternateIdentifier);
                    }
                }

                pid = pid.Where(o => !exclude.Exists(i => i.Domain == o.Domain && i.Identifier == o.Identifier)).ToArray();
            }
            return(pid);
        }
Пример #12
0
        /// <summary>
        /// Update container
        /// </summary>
        public VersionedDomainIdentifier UpdateContainer(System.ComponentModel.IContainer storageData, DataPersistenceMode mode)
        {
            if (m_disposed)
            {
                throw new ObjectDisposedException("DatabasePersistenceService");
            }

            if (storageData == null)
            {
                throw new ArgumentNullException("storageData");
            }

            // Get the persister
            IComponentPersister         persister     = GetPersister(storageData.GetType());
            ISystemConfigurationService configService = ApplicationContext.ConfigurationService;

            if (persister != null)
            {
                IDbTransaction tx   = null;
                IDbConnection  conn = null;
                try
                {
                    conn = DatabasePersistenceService.ConnectionManager.GetConnection();

                    RegistrationEvent hsrEvent = storageData as RegistrationEvent;

                    // Is the record something that we have access to?
                    if (hsrEvent.AlternateIdentifier != null && !hsrEvent.AlternateIdentifier.Domain.Equals(configService.OidRegistrar.GetOid(ClientRegistryOids.REGISTRATION_EVENT).Oid))
                    {
                        throw new ArgumentException(String.Format("The record OID '{0}' cannot be retrieved by this repository, expecting OID '{1}'",
                                                                  hsrEvent.AlternateIdentifier.Domain, configService.OidRegistrar.GetOid(ClientRegistryOids.REGISTRATION_EVENT).Oid));
                    }

                    decimal tryDec         = default(decimal);
                    bool    isDirectUpdate = false;

                    // Is there no event identifier ?
                    if (hsrEvent.AlternateIdentifier != null && !Decimal.TryParse(hsrEvent.AlternateIdentifier.Identifier, out tryDec))
                    {
                        throw new ArgumentException(String.Format("The identifier '{0}' is not a valid identifier for this repository", hsrEvent.AlternateIdentifier.Identifier));
                    }
                    else if (hsrEvent.AlternateIdentifier == null) // The alternate identifier is null ... so we need to look up the registration event to version ... interesting....
                    {
                        this.EnrichRegistrationEvent(conn, tx, hsrEvent);
                    }
                    else
                    {
                        // Get the person name
                        isDirectUpdate = true; // Explicit update
                    }

                    // Validate and duplicate the components that are to be loaded as part of the new version
                    var oldHsrEvent = GetContainer(hsrEvent.AlternateIdentifier, true) as RegistrationEvent; // Get the old container
                    if (oldHsrEvent == null)
                    {
                        throw new MissingPrimaryKeyException(String.Format("Record {1}^^^&{0}&ISO does not exist", hsrEvent.AlternateIdentifier.Domain, hsrEvent.AlternateIdentifier.Identifier));
                    }

                    PersonPersister cp = new PersonPersister();

                    // Validate the old record target
                    Person oldRecordTarget = oldHsrEvent.FindComponent(HealthServiceRecordSiteRoleType.SubjectOf) as Person,
                           newRecordTarget = hsrEvent.FindComponent(HealthServiceRecordSiteRoleType.SubjectOf) as Person;

                    Person verifyRecordTarget = null;
                    if (!isDirectUpdate)
                    {
                        Trace.TraceInformation("Not Direct update, enriching the Patient Data");
                        int idCheck = 0;
                        while (verifyRecordTarget == null || idCheck > newRecordTarget.AlternateIdentifiers.Count)
                        {
                            verifyRecordTarget = cp.GetPerson(conn, null, newRecordTarget.AlternateIdentifiers[idCheck++], true);
                        }

                        if (verifyRecordTarget == null || oldRecordTarget.Id != verifyRecordTarget.Id)
                        {
                            throw new ConstraintException("The update request specifies a different subject than the request currently stored");
                        }
                    }
                    else
                    {
                        verifyRecordTarget = oldRecordTarget;
                    }
                    //newRecordTarget.VersionId = verifyRecordTarget.VersionId;
                    newRecordTarget.Id = verifyRecordTarget.Id;

                    // VAlidate classific
                    if (oldHsrEvent.EventClassifier != hsrEvent.EventClassifier &&
                        (hsrEvent.EventClassifier & RegistrationEventType.Register) == RegistrationEventType.None)
                    {
                        throw new ConstraintException("Record type mis-match between update data and the data already in the persistence store");
                    }

                    if (oldHsrEvent.LanguageCode != hsrEvent.LanguageCode)
                    {
                        throw new ConstraintException("Record language mis-match between update data and data already in persistence store. To change the language use a \"replaces\" relationship rather than an update");
                    }

                    // Are we performing a component update? If so the only two components we want freshened are the CommentOn (for adding comments)
                    // and the ReasonFor | OlderVersionOf comment for change summaries
                    if ((hsrEvent.EventClassifier & RegistrationEventType.ComponentEvent) != 0)
                    {
                        for (int i = hsrEvent.XmlComponents.Count - 1; i >= 0; i--)
                        {
                            if (((hsrEvent.XmlComponents[i].Site as HealthServiceRecordSite).SiteRoleType & (HealthServiceRecordSiteRoleType.CommentOn | HealthServiceRecordSiteRoleType.ReasonFor | HealthServiceRecordSiteRoleType.OlderVersionOf | HealthServiceRecordSiteRoleType.TargetOf)) == 0)
                            {
                                hsrEvent.Remove(hsrEvent.XmlComponents[i]);
                            }
                        }
                    }

                    // Copy over any components that aren't already specified or updated in the new record
                    // Merge the old and new. Sets the update mode appropriately
                    cp.MergePersons(newRecordTarget, oldRecordTarget);

                    // Next we copy this as a replacement of
                    hsrEvent.RemoveAllFromRole(HealthServiceRecordSiteRoleType.SubjectOf);
                    hsrEvent.Add(newRecordTarget, "SUBJ", HealthServiceRecordSiteRoleType.SubjectOf, null);

                    // Begin and update
                    tx = conn.BeginTransaction();

                    var retVal = persister.Persist(conn, tx, storageData as IComponent, true);

                    if (m_configuration.OverridePersistenceMode.HasValue)
                    {
                        mode = m_configuration.OverridePersistenceMode.Value;
                    }

                    if (mode == DataPersistenceMode.Production)
                    {
                        tx.Commit();
                        tx = null;

                        // Mark conflicts if any are outstanding pointing at the old versionj
                        if (this.m_clientRegistryMerge != null)
                        {
                            var existingConflicts = this.m_clientRegistryMerge.GetConflicts(oldHsrEvent.AlternateIdentifier);
                            if (existingConflicts.Count() > 0)
                            {
                                Trace.TraceInformation("Obsoleting existing conlflicts resolved");
                                this.m_clientRegistryMerge.ObsoleteConflicts(oldHsrEvent.AlternateIdentifier);
                            }
                            this.m_threadPool.QueueUserWorkItem(this.MarkConflictsAsync, retVal);
                        }

                        // Notify register
                        if (this.m_notificationService != null)
                        {
                            if (hsrEvent.Mode == RegistrationEventType.Replace)
                            {
                                this.m_notificationService.NotifyDuplicatesResolved(hsrEvent);
                            }
                            else
                            {
                                this.m_notificationService.NotifyUpdate(hsrEvent);
                            }
                        }
                    }
                    else
                    {
                        tx.Rollback();
                    }


                    return(retVal);
                }
                catch (Exception e)
                {
                    if (tx != null)
                    {
                        tx.Rollback();
                    }
                    throw;
                }
                finally
                {
                    if (tx != null)
                    {
                        tx.Dispose();
                    }
                    if (conn != null)
                    {
                        DatabasePersistenceService.ConnectionManager.ReleaseConnection(conn);
                        conn = null;
                    }
                }
            }
            else
            {
                Trace.TraceError("Can't find a persistence handler for type '{0}'", storageData.GetType().Name);
                throw new DataException(String.Format("Can't persist type '{0}'", storageData.GetType().Name));
            }
        }
Пример #13
0
        /// <summary>
        /// Create the response registration event
        /// </summary>
        internal MARC.Everest.RMIM.CA.R020403.MFMI_MT700746CA.RegistrationEvent <MARC.Everest.RMIM.CA.R020403.PRPA_MT101106CA.IdentifiedEntity> CreateRegistrationEventDetail(RegistrationEvent res, List <IResultDetail> details)
        {
            var retVal = new MARC.Everest.RMIM.CA.R020403.MFMI_MT700746CA.RegistrationEvent <MARC.Everest.RMIM.CA.R020403.PRPA_MT101106CA.IdentifiedEntity>();

            var person          = res.FindComponent(HealthServiceRecordSiteRoleType.SubjectOf) as Person;
            var custodialDevice = res.FindComponent(HealthServiceRecordSiteRoleType.PlaceOfRecord | HealthServiceRecordSiteRoleType.ResponsibleFor) as RepositoryDevice;
            var replacement     = res.FindAllComponents(HealthServiceRecordSiteRoleType.ReplacementOf);

            // person
            if (person == null)
            {
                retVal.Subject = new MARC.Everest.RMIM.CA.R020403.MFMI_MT700746CA.Subject4 <MARC.Everest.RMIM.CA.R020403.PRPA_MT101106CA.IdentifiedEntity>()
                {
                    NullFlavor = NullFlavor.NoInformation
                }
            }
            ;
            else
            {
                var regRole = CreateRegisteredRole(person, details);
                retVal.Subject = new MARC.Everest.RMIM.CA.R020403.MFMI_MT700746CA.Subject4 <MARC.Everest.RMIM.CA.R020403.PRPA_MT101106CA.IdentifiedEntity>(
                    new MARC.Everest.RMIM.CA.R020403.PRPA_MT101106CA.IdentifiedEntity(
                        regRole.Id,
                        regRole.StatusCode,
                        regRole.EffectiveTime,
                        regRole.ConfidentialityCode,
                        new MARC.Everest.RMIM.CA.R020403.PRPA_MT101106CA.Person(),
                        regRole.SubjectOf
                        ));
                if (regRole.IdentifiedPerson != null && regRole.IdentifiedPerson.NullFlavor == null)
                {
                    foreach (var othId in regRole.IdentifiedPerson.AsOtherIDs)
                    {
                        retVal.Subject.registeredRole.IdentifiedPerson.AsOtherIDs.Add(
                            new MARC.Everest.RMIM.CA.R020403.PRPA_MT101106CA.OtherIDs(
                                othId.Id,
                                othId.Code,
                                new MARC.Everest.RMIM.CA.R020403.PRPA_MT101106CA.IdOrganization(
                                    othId.AssigningIdOrganization.Id,
                                    othId.AssigningIdOrganization.Name)
                                ));
                    }
                }
            }

            // custodial device
            if (custodialDevice == null)
            {
                retVal.Custodian = new MARC.Everest.RMIM.CA.R020403.REPC_MT000007CA.Custodian()
                {
                    NullFlavor = NullFlavor.NoInformation
                }
            }
            ;
            else
            {
                retVal.Custodian = CreateCustodialDevice(custodialDevice, details);
            }

            // Replacement
            foreach (RegistrationEvent replc in replacement)
            {
                retVal.ReplacementOf.Add(new MARC.Everest.RMIM.CA.R020403.MFMI_MT700726CA.ReplacementOf(
                                             new MARC.Everest.RMIM.CA.R020403.MFMI_MT700726CA.PriorRegistration(
                                                 new MARC.Everest.RMIM.CA.R020403.MFMI_MT700726CA.Subject5(
                                                     new MARC.Everest.RMIM.CA.R020403.MFMI_MT700726CA.PriorRegisteredRole()
                {
                    Id = CreateII(replc.AlternateIdentifier, details)
                }
                                                     )
                                                 )
                                             ));
            }

            return(retVal);
        }