protected override void ActOnItem(WorkQueueItem item) { // We need to know if the target still exist. Use the default entity flag, rather than proxy. var target = PersistenceScope.CurrentContext.Load <Entity>(MergeWorkQueueItem.GetTargetRef(item), EntityLoadFlags.None); if (target == null) { throw new TargetAlreadyDeletedException(); // target has already been deleted somewhere else. Nothing to act on. } var handler = CollectionUtils.SelectFirst <IMergeHandler>( new MergeHandlerExtensionPoint().CreateExtensions(), h => h.SupportsTarget(target)); if (handler == null) { throw new NotSupportedException( string.Format("No extension found that supports merging entities of class {0}.", target.GetClass().FullName)); } var stage = GetStage(item); Platform.Log(LogLevel.Info, "Starting merge step on target {0} (stage {1})...", target.GetRef(), stage); var nextStage = handler.Merge(target, stage, PersistenceScope.CurrentContext); Platform.Log(LogLevel.Info, "Completed merge step on target {0} (stage {1}, next stage is {2}).", target.GetRef(), stage, nextStage); // update the work item with the new stage value item.ExtendedProperties[StageProperty] = nextStage.ToString(); }
private void RestartItemAtStageZero(WorkQueueItem item) { var nextStage = 0; Platform.Log(LogLevel.Info, "Failed to complete merge step on target {0} (stage {1}). Restarting at stage {2}.", MergeWorkQueueItem.GetTargetRef(item), GetStage(item), nextStage); // update the work item with the new stage value item.ExtendedProperties[StageProperty] = nextStage.ToString(); }
private void ConsiderItemCompletedSuccessfully(WorkQueueItem item) { var nextStage = -1; Platform.Log(LogLevel.Info, "Failed to complete merge step on target {0} (stage {1}) because target has already been deleted. Setting to stage {2}.", MergeWorkQueueItem.GetTargetRef(item), GetStage(item), nextStage); item.Complete(); item.ExtendedProperties[StageProperty] = nextStage.ToString(); }
public MergeExternalPractitionerResponse MergeExternalPractitioner(MergeExternalPractitionerRequest request) { Platform.CheckForNullReference(request, "request"); Platform.CheckMemberIsSet(request.LeftPractitionerRef, "LeftPractitionerRef"); Platform.CheckMemberIsSet(request.RightPractitionerRef, "RightPractitionerRef"); var left = PersistenceContext.Load <ExternalPractitioner>(request.LeftPractitionerRef, EntityLoadFlags.Proxy); var right = PersistenceContext.Load <ExternalPractitioner>(request.RightPractitionerRef, EntityLoadFlags.Proxy); // if we are only doing a cost estimate, exit here without modifying any data if (request.EstimateCostOnly) { var cost = EstimateAffectedRecords(right, left); return(new MergeExternalPractitionerResponse(cost)); } // unpack the request, loading all required entities var nameAssembler = new PersonNameAssembler(); var name = new PersonName(); nameAssembler.UpdatePersonName(request.Name, name); var defaultContactPoint = request.DefaultContactPointRef != null? PersistenceContext.Load <ExternalPractitionerContactPoint>(request.DefaultContactPointRef) : null; var deactivatedContactPoints = request.DeactivatedContactPointRefs == null ? new List <ExternalPractitionerContactPoint>() : CollectionUtils.Map(request.DeactivatedContactPointRefs, (EntityRef cpRef) => PersistenceContext.Load <ExternalPractitionerContactPoint>(cpRef)); var cpReplacements = CollectionUtils.Map(request.ContactPointReplacements ?? (new Dictionary <EntityRef, EntityRef>()), kvp => new KeyValuePair <ExternalPractitionerContactPoint, ExternalPractitionerContactPoint>( PersistenceContext.Load <ExternalPractitionerContactPoint>(kvp.Key, EntityLoadFlags.Proxy), PersistenceContext.Load <ExternalPractitionerContactPoint>(kvp.Value, EntityLoadFlags.Proxy))); // merge the practitioners var result = ExternalPractitioner.MergePractitioners(left, right, name, request.LicenseNumber, request.BillingNumber, request.ExtendedProperties, defaultContactPoint, deactivatedContactPoints, cpReplacements ); PersistenceContext.Lock(result, DirtyState.New); // if user has verify permission, verify the result if (Thread.CurrentPrincipal.IsInRole(AuthorityTokens.Admin.Data.ExternalPractitionerVerification)) { result.MarkVerified(); } // queue work items to migrate orders and visits foreach (var practitioner in new[] { right, left }) { var queueItem = MergeWorkQueueItem.Create(practitioner.GetRef()); PersistenceContext.Lock(queueItem, DirtyState.New); } PersistenceContext.SynchState(); var assembler = new ExternalPractitionerAssembler(); return(new MergeExternalPractitionerResponse(assembler.CreateExternalPractitionerSummary(result, this.PersistenceContext))); }
public MergeDuplicateContactPointResponse MergeDuplicateContactPoint(MergeDuplicateContactPointRequest request) { Platform.CheckForNullReference(request, "request"); Platform.CheckMemberIsSet(request.RetainedContactPointRef, "RetainedContactPointRef"); Platform.CheckMemberIsSet(request.ReplacedContactPointRef, "ReplacedContactPointRef"); var dest = PersistenceContext.Load <ExternalPractitionerContactPoint>(request.RetainedContactPointRef, EntityLoadFlags.Proxy); var src = PersistenceContext.Load <ExternalPractitionerContactPoint>(request.ReplacedContactPointRef, EntityLoadFlags.Proxy); // if we are only doing a cost estimate, exit here without modifying any data if (request.EstimateCostOnly) { // compute cost estimate. Need to include affected records of both src and dest, because both will be merged and deactivated. var cost = EstimateAffectedRecords(dest, src); return(new MergeDuplicateContactPointResponse(cost)); } // combine all phone numbers and addresses, expiring those from the src object var allPhoneNumbers = CollectionUtils.Concat( CloneAndExpire(dest.TelephoneNumbers, tn => tn.ValidRange, false), CloneAndExpire(src.TelephoneNumbers, tn => tn.ValidRange, true)); var allAddresses = CollectionUtils.Concat( CloneAndExpire(dest.Addresses, tn => tn.ValidRange, false), CloneAndExpire(src.Addresses, tn => tn.ValidRange, true)); var allEmailAddresses = CollectionUtils.Concat( CloneAndExpire(dest.EmailAddresses, tn => tn.ValidRange, false), CloneAndExpire(src.EmailAddresses, tn => tn.ValidRange, true)); // merge contact points var result = ExternalPractitionerContactPoint.MergeContactPoints( dest, src, dest.Name, dest.Description, dest.PreferredResultCommunicationMode, dest.InformationAuthority, allPhoneNumbers, allAddresses, allEmailAddresses); PersistenceContext.Lock(result, DirtyState.New); // if user has verify permission, verify the practitioner if (Thread.CurrentPrincipal.IsInRole(AuthorityTokens.Admin.Data.ExternalPractitionerVerification)) { result.Practitioner.MarkVerified(); } // queue work items to migrate orders foreach (var contactPoint in new[] { src, dest }) { var queueItem = MergeWorkQueueItem.Create(contactPoint.GetRef()); PersistenceContext.Lock(queueItem, DirtyState.New); } PersistenceContext.SynchState(); var assembler = new ExternalPractitionerAssembler(); return(new MergeDuplicateContactPointResponse(assembler.CreateExternalPractitionerContactPointSummary(result))); }