} // end of HandleAvailabilitiesSpecialServiceRequest #endregion #region HandleRequireDocs /// <summary> /// Handles a request to send doctors for consultation or assisting between departments /// </summary> /// <param name="del">The original request for doctors to consult or assist</param> /// <param name="controlUnit">Control unit that filed request for assistance or consultation</param> /// <param name="time">Time request was filed</param> /// <param name="simEngine">SimEngine responsible for simulation execution</param> /// <returns>True if request has been handled</returns> static public bool HandleRequireDocs(IDelegate del, ControlUnit controlUnit, DateTime time, ISimulationEngine simEngine) { foreach (SkillSet reqSkill in ((DelegateRequestDocsForAssisting)del).RequiredSkillSets) { List <EntityDoctor> possibleDoc = ((ControlUnitHealthCare)controlUnit).FindDoctorWithSkillSet(reqSkill); if (possibleDoc.Count == 0) { break; } EntityDoctor chosenDoc = null; foreach (EntityDoctor doc in possibleDoc) { if (doc.ParentControlUnit == controlUnit) { ActivityMove possibleMove = doc.GetPossibleMovingActivity(); if (possibleMove != null && (possibleMove.Destination == del.OriginControlUnit || possibleMove.Destination == doc.BaseControlUnit)) { chosenDoc = doc; break; } // end if } // end if if (((ControlUnitHealthCare)doc.ParentControlUnit).ControlUnitType == Enums.ControlUnitType.Inpatient) { chosenDoc = doc; break; } // end if } // end foreach if (chosenDoc == null) { chosenDoc = possibleDoc.First(); } if (chosenDoc.ParentControlUnit == controlUnit) { ActivityMove possibleMove = chosenDoc.GetPossibleMovingActivity(); if (possibleMove != null && possibleMove.Destination == chosenDoc.BaseControlUnit) { simEngine.RemoveScheduledEvent(possibleMove.EndEvent); chosenDoc.StopCurrentActivities(time, simEngine); ActivityMove move = new ActivityMove(controlUnit, chosenDoc, controlUnit, del.OriginControlUnit, del, TimeSpan.FromMinutes(1)); move.StartEvent.Trigger(time, simEngine); } // end if } else { controlUnit.SendDelegateTo(chosenDoc.ParentControlUnit, new DelegateSentDocForAssistedTreatment((ControlUnitHealthCare)del.OriginControlUnit, reqSkill)); } // end if } // end foreach return(true); } // end of HandleRequireDocs
} // end of TriggerStartEvent #endregion #region TriggerEndEvent /// <summary> /// State change of the end event. Adds the enter event of the destination control unit /// or in case of pre-emption the scheduled end event is removed from the sim engine /// </summary> /// <param name="time"> Time of activity start</param> /// <param name="simEngine"> SimEngine the handles the activity triggering</param> override public void StateChangeEndEvent(DateTime time, ISimulationEngine simEngine) { if (time < EndTime) { simEngine.RemoveScheduledEvent(EndEvent); return; } // end if Event enterEvent = Destination.EntityEnterControlUnit(time, simEngine, MovingEntity, DelegateOrigin); if (enterEvent != null) { EndEvent.SequentialEvents.Add(enterEvent); } } // end of TriggerEndEvent
} // end of TriggerStartEvent #endregion #region TriggerEndEvent /// <summary> /// State changes of the activities end event. Most state changes are standardized and configurable via input. /// </summary> /// <param name="time"> time of activity start</param> /// <param name="simEngine"> SimEngine the handles the activity triggering</param> override public void StateChangeEndEvent(DateTime time, ISimulationEngine simEngine) { //-------------------------------------------------------------------------------------------------- // Some activities define the end of corresponding doctor, nurses for future reference //-------------------------------------------------------------------------------------------------- #region CorrespondingStaff if (ActionType.DefinesCorrespondingDocEnd) { Patient.CorrespondingDoctor = null; ResourceSet.MainDoctor.RemovePatient(Patient); } // end if if (ActionType.DefinesCorrespondingNurseEnd) { Patient.CorrespondingNurse = null; ResourceSet.MainNurse.RemovePatient(Patient); } // end if #endregion //-------------------------------------------------------------------------------------------------- // Occupation //-------------------------------------------------------------------------------------------------- #region Occupation if (ResourceSet.TreatmentFacility is EntityMultiplePatientTreatmentFacility) { ((EntityMultiplePatientTreatmentFacility)ResourceSet.TreatmentFacility).HoldedEntities.Remove(Patient); } else { ResourceSet.TreatmentFacility.Occupied = false; //-------------------------------------------------------------------------------------------------- // in case patient blocking is released required actions are taken //-------------------------------------------------------------------------------------------------- if (ActionType.DefinesFacilitiyOccupationEnd) { // facility is released ResourceSet.TreatmentFacility.PatientBlocking = null; // facility is removed from patient Patient.OccupiedFacility = null; } // end if } // end if #endregion //-------------------------------------------------------------------------------------------------- // If treatment has doctor(s), busyFactors are assigned //-------------------------------------------------------------------------------------------------- #region AssignBusyFactorsDoctors if (ResourceSet.MainDoctor != null) { ResourceSet.MainDoctor.BusyFactor -= ActionType.BusyFactorDoctor; ResourceSet.MainDoctor.BlockedForDispatching = false; } // end if if (ResourceSet.AssistingDoctors != null) { if (ResourceSet.AssistingDoctors.Length != ActionType.BusyFactorAssistingDoctors.Length) { throw new InvalidOperationException(); } for (int i = 0; i < ResourceSet.AssistingDoctors.Length; i++) { ResourceSet.AssistingDoctors[i].BusyFactor -= ActionType.BusyFactorAssistingDoctors[i]; ResourceSet.AssistingDoctors[i].BlockedForDispatching = false; } // end for } // end if #endregion //-------------------------------------------------------------------------------------------------- // If treatment has nurse(s), busyFactors are assigned //-------------------------------------------------------------------------------------------------- #region AssignBusyFactorsNurses if (ResourceSet.MainNurse != null) { ResourceSet.MainNurse.BusyFactor -= ActionType.BusyFactorNurse; } if (ResourceSet.AssistingNurses != null) { if (ResourceSet.AssistingNurses.Length != ActionType.BusyFactorAssistingNurses.Length) { throw new InvalidOperationException(); } for (int i = 0; i < ResourceSet.AssistingNurses.Length; i++) { ResourceSet.AssistingNurses[i].BusyFactor -= ActionType.BusyFactorAssistingNurses[i]; } // end for } // end if #endregion T nextActionType = PatientPath.GetCurrentActionType(); //-------------------------------------------------------------------------------------------------- // Preemption //-------------------------------------------------------------------------------------------------- #region Preempted if (!HoldingRequired) { if (Duration.Ticks > 0) { DegreeOfCompletion += (double)(time - StartTime).Ticks / Duration.Ticks; } else { DegreeOfCompletion = 1; } if (Math.Abs(DegreeOfCompletion - 1) > Helpers <double> .GetNumbericalPrecission()) { RequestHealthCareAction <T> req = new RequestHealthCareAction <T>(Patient, DegreeOfCompletion, ActionType, time, ResourceSet); ParentControlUnit.AddRequest(req); simEngine.RemoveScheduledEvent(EndEvent); EndEvent.SequentialEvents.Add(Patient.StartWaitingActivity(ParentDepartmentControl.WaitingAreaPatientForNextActionType(nextActionType))); return; } // end if } // end if #endregion #region NextActions //-------------------------------------------------------------------------------------------------- // In case of an holding treatment the next action was already taken //-------------------------------------------------------------------------------------------------- if (!HoldingRequired) { if (PatientPath.TakeNextAction(simEngine, EndEvent, time, ParentControlUnit)) { // either waiting or waiting in the treatment facility is launched if (Patient.OccupiedFacility == null || Patient.OccupiedFacility.ParentDepartmentControl != ParentDepartmentControl) { EndEvent.SequentialEvents.Add(Patient.StartWaitingActivity(ParentDepartmentControl.WaitingAreaPatientForNextActionType(nextActionType))); } else { ActivityWaitInFacility waitInFacility = new ActivityWaitInFacility(ParentControlUnit, Patient, Patient.OccupiedFacility); EndEvent.SequentialEvents.Add(waitInFacility.StartEvent); } // end if } // end if //-------------------------------------------------------------------------------------------------- // Possible waiting activities are started //-------------------------------------------------------------------------------------------------- #region StartWaitingActivities if (ResourceSet.MainDoctor != null && ResourceSet.MainDoctor.GetCurrentActivities().Count == 1) { EndEvent.SequentialEvents.Add(ResourceSet.MainDoctor.StartWaitingActivity(ParentDepartmentControl.WaitingRoomForStaff(ResourceSet.MainDoctor))); } if (ResourceSet.AssistingDoctors != null) { foreach (EntityDoctor doc in ResourceSet.AssistingDoctors) { if (doc.GetCurrentActivities().Count == 1) { EndEvent.SequentialEvents.Add(doc.StartWaitingActivity(ParentDepartmentControl.WaitingRoomForStaff(doc))); } } // end foreach } // end if if (ResourceSet.MainNurse != null && ResourceSet.MainNurse.GetCurrentActivities().Count == 1) { EndEvent.SequentialEvents.Add(ResourceSet.MainNurse.StartWaitingActivity(ParentDepartmentControl.WaitingRoomForStaff(ResourceSet.MainDoctor))); } if (ResourceSet.AssistingNurses != null) { foreach (EntityNurse nurse in ResourceSet.AssistingNurses) { if (nurse.GetCurrentActivities().Count == 1) { EndEvent.SequentialEvents.Add(nurse.StartWaitingActivity(ParentDepartmentControl.WaitingRoomForStaff(nurse))); } } // end foreach } // end if #endregion } #endregion #region ReleaseHolding if (ActionType.IsHold) { foreach (EntityStaff staff in AffectedEntities.Where(p => p is EntityStaff)) { staff.OnHold = false; } // end foreach return; } // end if #endregion } // end of TriggerEndEvent