/// <summary> /// Un-merges this order from its merge destination, returning a new order with the specified accession #, /// and marking this order as Replaced by the new order. /// </summary> /// <param name="cancelInfo"></param> /// <param name="newAccessionNumber"></param> /// <returns></returns> public virtual UnmergeResult Unmerge(OrderCancelInfo cancelInfo, string newAccessionNumber) { string failureReason; if (!CanUnmerge(cancelInfo, out failureReason)) { throw new WorkflowException(failureReason); } var destOrder = _mergeInfo.MergeDestinationOrder; // create replacement order var newOrder = new Order( _patient, _visit, null, // do not copy placer-number newAccessionNumber, // assign new acc # _diagnosticService, _enteredTime, _enteredBy, _enteredComment, _schedulingRequestTime, null, // will be set by call to UpdateScheduling() null, null, _orderingPractitioner, _orderingFacility, new HashedSet <Procedure>(), // will be added later new HashedSet <Procedure>(), // ghosts CollectionUtils.Map(_resultRecipients, (ResultRecipient rr) => (ResultRecipient)rr.Clone()), new List <OrderAttachment>(), _reasonForStudy, _priority, (int)_priority, OrderStatus.SC, null, null, new HashedSet <Order>(), ExtendedPropertyUtils.Copy(_extendedProperties) ); // reclaim order notes var notes = OrderNote.GetNotesForOrder(this); var reclaimNotes = CollectionUtils.Map( CollectionUtils.Select(notes, n => n.GhostOf != null), (OrderNote n) => n.GhostOf.Downcast <OrderNote>()); foreach (var note in reclaimNotes) { note.Order = newOrder; } // reclaim attachments var reclaimAttachments = CollectionUtils.Map(_attachments, (OrderAttachment a) => CollectionUtils.SelectFirst(destOrder.Attachments, b => Equals(a.Document.GhostOf, b.Document))); foreach (var attachment in reclaimAttachments) { destOrder.Attachments.Remove(attachment); newOrder.Attachments.Add(attachment); } // reclaim procedures // need to create new ghost copies on the dest order, so that HL7 can cancel them var reclaimProcedures = CollectionUtils.Map(_ghostProcedures, (Procedure p) => p.GhostOf); var ghostProcedures = CollectionUtils.Map(reclaimProcedures, (Procedure p) => p.CreateGhostCopy()); foreach (var procedure in reclaimProcedures) { newOrder.AddProcedure(procedure); } destOrder.Procedures.AddAll(ghostProcedures); // note: procedure Indexes are already set correctly // update scheduling/status information newOrder.UpdateScheduling(); newOrder.UpdateStatus(); // any orders that were merged into this order must be redirected to the new order, // in order to support recursive unmerge foreach (var sourceOrder in _mergeSourceOrders) { sourceOrder.MergeInfo.MergeDestinationOrder = newOrder; newOrder.MergeSourceOrders.Add(sourceOrder); } _mergeSourceOrders.Clear(); // change status of this order to RP, and set cancel info _cancelInfo = (OrderCancelInfo)cancelInfo.Clone(); _cancelInfo.ReplacementOrder = newOrder; // clear merge info on this order, since it is no longer considered merged _mergeInfo = null; // set status of this order to RP, and set end time manually SetStatus(OrderStatus.RP); _endTime = Platform.Time; return(new UnmergeResult { ReplacementOrder = newOrder, GhostProcedures = ghostProcedures }); }
/// <summary> /// Merge the current order into the destination order specified in the mergeInfo. /// </summary> /// <param name="mergeInfo"></param> public virtual MergeResult Merge(OrderMergeInfo mergeInfo) { var destOrder = mergeInfo.MergeDestinationOrder; string failureReason; if (!CanMerge(mergeInfo, out failureReason)) { throw new WorkflowException(failureReason); } _mergeInfo = mergeInfo; // copy all the result recipients to destination foreach (var rr in _resultRecipients) { var recipientAlreadyExist = CollectionUtils.Contains( destOrder.ResultRecipients, recipients => recipients.PractitionerContactPoint.Equals(rr.PractitionerContactPoint)); if (!recipientAlreadyExist) { destOrder.ResultRecipients.Add((ResultRecipient)rr.Clone()); } } // move all the attachments to destination, and replace with ghosts var ghostAttachments = CollectionUtils.Map(_attachments, (OrderAttachment a) => a.CreateGhostCopy()); foreach (var a in _attachments) { destOrder.Attachments.Add(a); } _attachments.Clear(); foreach (var ghost in ghostAttachments) { if (PersistenceScope.Current != null) { PersistenceScope.CurrentContext.Lock(ghost.Document, DirtyState.New); } _attachments.Add(ghost); } // Move all the order notes to destination, and create ghosts of notes for this order var notes = OrderNote.GetNotesForOrder(this); var ghostNotes = CollectionUtils.Map(notes, (OrderNote n) => n.CreateGhostCopy()); foreach (var n in notes) { n.Order = destOrder; } foreach (var n in ghostNotes) { PersistenceScope.CurrentContext.Lock(n, DirtyState.New); } // Create ghost copies of the original procedures before it is added to the destinations // Theese ghost procedures are required for HL7 messages. var ghostProcedures = CollectionUtils.Map(_procedures, (Procedure p) => p.CreateGhostCopy()); // Move all the procedures to the destination order. foreach (var p in _procedures) { destOrder.AddProcedure(p); } // update destination scheduling information destOrder.UpdateScheduling(); // Add ghost procedures back to the source order. _procedures.AddAll(ghostProcedures); // Set source order to merged status SetStatus(OrderStatus.MG); return(new MergeResult { GhostProcedures = ghostProcedures }); }