/// <summary> /// Persist a component to the database /// </summary> public MARC.HI.EHRS.SVC.Core.DataTypes.VersionedDomainIdentifier Persist(System.Data.IDbConnection conn, System.Data.IDbTransaction tx, System.ComponentModel.IComponent data, bool isUpdate) { // Get config service ISystemConfigurationService configService = ApplicationContext.ConfigurationService; //ApplicationContext.Current.GetService(typeof(ISystemConfigurationService)) as ISystemConfigurationService; // Create the personal relationship in a strongly typed fashion PersonalRelationship pr = data as PersonalRelationship; Person clientContainer = pr.Site.Container as Person, relationshipPerson = null; // Get the person persister var persister = new PersonPersister(); // First, let's see if we can fetch the client if (pr.Id != default(decimal)) { var personalRelationship = this.DePersist(conn, pr.Id, pr.Site.Container, (pr.Site as HealthServiceRecordSite).SiteRoleType, true) as PersonalRelationship; relationshipPerson = personalRelationship.FindComponent(HealthServiceRecordSiteRoleType.SubjectOf) as Person; } else if (pr.AlternateIdentifiers != null) { int i = 0; while (relationshipPerson == null && i < pr.AlternateIdentifiers.Count) { relationshipPerson = persister.GetPerson(conn, tx, pr.AlternateIdentifiers[i++], true); } } if (relationshipPerson == null) { List <DomainIdentifier> candidateId = new List <DomainIdentifier>(); // Is this an existing person (same name and relation) using (IDbCommand cmd = DbUtil.CreateCommandStoredProc(conn, tx)) { cmd.CommandText = "get_psn_rltnshps"; cmd.Parameters.Add(DbUtil.CreateParameterIn(cmd, "src_psn_id_in", DbType.Decimal, clientContainer.Id)); cmd.Parameters.Add(DbUtil.CreateParameterIn(cmd, "src_psn_vrsn_id_in", DbType.Decimal, clientContainer.VersionId)); using (IDataReader rdr = cmd.ExecuteReader()) { while (rdr.Read()) { if (rdr["kind_cs"].ToString() == pr.RelationshipKind) { candidateId.Add(new DomainIdentifier() { Domain = configService.OidRegistrar.GetOid("CR_CID").Oid, Identifier = rdr["src_psn_id"].ToString() }); } } } } // Now load candidates and check foreach (var id in candidateId) { var candidate = persister.GetPerson(conn, tx, id, true); if (NON_DUPLICATE_REL.Contains(pr.RelationshipKind)) { relationshipPerson = candidate; break; } else if (candidate.Names.Exists(n => n.SimilarityTo(pr.LegalName) >= DatabasePersistenceService.ValidationSettings.PersonNameMatch)) { relationshipPerson = candidate; break; } } } // Did we get one? // If not, then we need to register a patient in the database if (relationshipPerson == null) { if (pr.LegalName == null) { throw new DataException(ApplicationContext.LocaleService.GetString("DBCF00B")); } relationshipPerson = new Person() { AlternateIdentifiers = pr.AlternateIdentifiers, Names = new List <NameSet>() { pr.LegalName }, Addresses = new List <AddressSet>() { pr.PerminantAddress }, GenderCode = pr.GenderCode, BirthTime = pr.BirthTime, TelecomAddresses = pr.TelecomAddresses, Status = StatusType.Active, RoleCode = PersonRole.PRS }; var registrationEvent = DbUtil.GetRegistrationEvent(pr).Clone() as RegistrationEvent; registrationEvent.Id = default(decimal); registrationEvent.EventClassifier = RegistrationEventType.ComponentEvent; registrationEvent.RemoveAllFromRole(HealthServiceRecordSiteRoleType.SubjectOf); registrationEvent.Add(relationshipPerson, "SUBJ", HealthServiceRecordSiteRoleType.SubjectOf, null); registrationEvent.Status = StatusType.Completed; // Persist or merge? new RegistrationEventPersister().Persist(conn, tx, registrationEvent, isUpdate); //var clientIdentifier = persister.Persist(conn, tx, relationshipPerson, isUpdate); // Should persist } else if (relationshipPerson.RoleCode != PersonRole.PAT) { var updatedPerson = new Person() { Id = relationshipPerson.Id, AlternateIdentifiers = pr.AlternateIdentifiers, Names = new List <NameSet>() { pr.LegalName }, Addresses = new List <AddressSet>() { }, GenderCode = pr.GenderCode, BirthTime = pr.BirthTime, TelecomAddresses = pr.TelecomAddresses, Status = StatusType.Active, RoleCode = relationshipPerson.RoleCode }; if (pr.PerminantAddress != null) { updatedPerson.Addresses.Add(pr.PerminantAddress); } persister.MergePersons(updatedPerson, relationshipPerson, true); relationshipPerson = updatedPerson; var registrationEvent = DbUtil.GetRegistrationEvent(pr).Clone() as RegistrationEvent; registrationEvent.Id = default(decimal); registrationEvent.EventClassifier = RegistrationEventType.ComponentEvent; registrationEvent.RemoveAllFromRole(HealthServiceRecordSiteRoleType.SubjectOf); registrationEvent.Add(relationshipPerson, "SUBJ", HealthServiceRecordSiteRoleType.SubjectOf, null); registrationEvent.Status = StatusType.Completed; new RegistrationEventPersister().Persist(conn, tx, registrationEvent, isUpdate); } // Validate if (!NON_DUPLICATE_REL.Contains(pr.RelationshipKind) && pr.AlternateIdentifiers.Count == 0 && !relationshipPerson.Names.Exists(o => QueryUtil.MatchName(pr.LegalName, o) >= DatabasePersistenceService.ValidationSettings.PersonNameMatch)) { throw new DataException(ApplicationContext.LocaleService.GetString("DBCF00A")); } // If the container for this personal relationship is a client, then we'll need to link that // personal relationship with the client to whom they have a relation with. if (clientContainer != null) // We need to do some linking { pr.Id = LinkClients(conn, tx, relationshipPerson.Id, clientContainer.Id, pr.RelationshipKind, pr.Status); } else if (clientContainer == null) // We need to do some digging to find out "who" this person is related to (the record target) { throw new ConstraintException(ApplicationContext.LocaleService.GetString("DBCF003")); } // todo: Container is a HSR return(new VersionedDomainIdentifier() { Domain = configService.OidRegistrar.GetOid(ClientRegistryOids.RELATIONSHIP_OID).Oid, Identifier = pr.Id.ToString() }); }
/// <summary> /// Persist an object /// </summary> public VersionedDomainIdentifier Persist(System.Data.IDbConnection conn, System.Data.IDbTransaction tx, System.ComponentModel.IComponent data, bool isUpdate) { ISystemConfigurationService configServce = ApplicationContext.ConfigurationService; //ApplicationContext.Current.GetService(typeof(ISystemConfigurationService)) as ISystemConfigurationService; // First, we must determine if we're going to be performing an update or a put HealthcareParticipant ptcpt = data as HealthcareParticipant; // Do we have the shrid? if (ptcpt.Id == default(decimal) && ptcpt.AlternateIdentifiers.Count > 0) // nope { // Attempt to get the SHRID int iId = 0; HealthcareParticipant resPtcpt = null; while (resPtcpt == null && iId < ptcpt.AlternateIdentifiers.Count) { resPtcpt = GetProvider(conn, tx, ptcpt.AlternateIdentifiers[iId]); iId++; } if (resPtcpt == null && !DatabasePersistenceService.ValidationSettings.PersonsMustExist) // We need to create a client { // Validate Clients if (DatabasePersistenceService.ValidationSettings.ValidateHealthcareParticipants) { IHealthcareWorkerIdentityService ptcptLookup = ApplicationContext.CurrentContext.GetService(typeof(IHealthcareWorkerIdentityService)) as IHealthcareWorkerIdentityService; if (ptcptLookup == null) { throw new InvalidOperationException("Unable to validate participant as no participant lookup service exists that can fulfill this request"); } resPtcpt = ptcptLookup.FindParticipant(ptcpt.AlternateIdentifiers[0]); if (resPtcpt == null || QueryUtil.MatchName(resPtcpt.LegalName, resPtcpt.LegalName) < DatabasePersistenceService.ValidationSettings.PersonNameMatch) { throw new DataException(String.Format("Could not validate participant {1}^^^&{0}&ISO against the participant validation service", ptcpt.AlternateIdentifiers[0].Domain, ptcpt.AlternateIdentifiers[0].Identifier)); } } CreatePtcpt(conn, tx, ptcpt); } else if (resPtcpt == null) { throw new DataException(String.Format("Particiapant {1}^^^&{0}&ISO cannot be found in this system", ptcpt.AlternateIdentifiers[0].Domain, ptcpt.AlternateIdentifiers[0].Identifier)); } else { // Validate the name given matches the legal name. Has to be more than // 80% match if (QueryUtil.MatchName(ptcpt.LegalName, resPtcpt.LegalName) < DatabasePersistenceService.ValidationSettings.PersonNameMatch) { throw new DataException(String.Format("The provided legal name does not match the legal name of participant {1}^^^&{0}&ISO, please ensure participant name is correct", ptcpt.AlternateIdentifiers[0].Domain, ptcpt.AlternateIdentifiers[0].Identifier)); } ptcpt.Id = resPtcpt.Id; ptcpt.LegalName = resPtcpt.LegalName ?? ptcpt.LegalName; ptcpt.PrimaryAddress = resPtcpt.PrimaryAddress ?? ptcpt.PrimaryAddress; ptcpt.Type = resPtcpt.Type ?? ptcpt.Type; // TODO: Update the information about the provider // Register alternative identifiers foreach (var id in ptcpt.AlternateIdentifiers) { if (resPtcpt.AlternateIdentifiers.Count(o => o.Domain == id.Domain) == 0) // register { CreateAlternateIdentifier(conn, tx, ptcpt.Id, id); } } } } // Persist the site with the container if known if (ptcpt.Site != null && ptcpt.Site.Container is RegistrationEvent) { LinkHealthServiceRecord(conn, tx, (ptcpt.Site.Container as RegistrationEvent).Id, ptcpt.Site as HealthServiceRecordSite); } // Persist any components within the provider record DbUtil.PersistComponents(conn, tx, isUpdate, this, ptcpt); // Return the versioned identifier return(new VersionedDomainIdentifier() { Domain = configServce.OidRegistrar.GetOid(ClientRegistryOids.PROVIDER_CRID).Oid, Identifier = ptcpt.Id.ToString() }); }