} // 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 ResourceSet /// <summary> /// Basic constructor /// </summary> /// <param name="mainDoc">Main doctor of health care action</param> /// <param name="mainNurse">Main nurse of health care action</param> /// <param name="facility">Main facility of health care action</param> /// <param name="assistingDoctors">Assisting doctors of health care action</param> /// <param name="assistingNurses">Assisting nurses of health care action</param> public ResourceSet(EntityDoctor mainDoc, EntityNurse mainNurse, EntityTreatmentFacility facility, EntityDoctor[] assistingDoctors = null, EntityNurse[] assistingNurses = null) { _mainDoc = mainDoc; _mainNurse = mainNurse; _treatmentFacility = facility; _assistingDoctors = assistingDoctors; _assistingNurses = assistingNurses; } // end of ResourceSet
/// <summary> /// Basic constructor /// </summary> /// <param name="patient">Patient to be admitted</param> /// <param name="admissionType">The type of admission, e.g. follow up</param> /// <param name="minDaySpan">The minimum number of days before patient can be admitted</param> /// <param name="mayDaySpan">The maximum number of days before a patient should/must be admitted</param> /// <param name="isExtern">Flag if the admission is generated within the model, e.g. emergency patient admitted to an outpatient clinic</param> /// <param name="correspondingDoctor">Admissions can be associated with a doctor to ensure the patient is seen by the same doctor again</param> public Admission( EntityPatient patient, AdmissionType admissionType, double minDaySpan = 0, double mayDaySpan = double.MaxValue, bool isExtern = false, EntityDoctor correspondingDoctor = null) { _patient = patient; _admissionType = admissionType; _minDaySpan = minDaySpan; _maxDaySpan = mayDaySpan; _isExtern = isExtern; _correspondingDoctor = correspondingDoctor; } // end of OutpatientAdmission
} // end of ChooseResourcesForAction #endregion #region CheckAvailabilityOfDoctors /// <summary> /// Checks if all skills of doctors are currently controlled by the control unit /// </summary> /// <param name="mainDocSkill">Skill required for main doctor</param> /// <param name="reqAssSkills">Skills required for assisting doctors</param> /// <returns>True if all skills are controlled</returns> public List <SkillSet> CheckAvailabilityOfDoctors(SkillSet mainDocSkill, SkillSet[] reqAssSkills) { //-------------------------------------------------------------------------------------------------- // At the moment it is assumed that the main doctoral skkill set is always available //-------------------------------------------------------------------------------------------------- List <SkillSet> nonAvailableSkillSets = new List <SkillSet>(); List <EntityDoctor> nonChosenDoctors = new List <EntityDoctor>(ControlledDoctors); if (reqAssSkills == null) { return(nonAvailableSkillSets); } foreach (SkillSet skillSet in reqAssSkills) { EntityDoctor foundDoc = null; foreach (EntityDoctor doc in nonChosenDoctors) { if (doc.SatisfiesSkillSet(skillSet)) { foundDoc = doc; break; } // end if } // end foreach if (foundDoc == null) { nonAvailableSkillSets.Add(skillSet); } else { nonChosenDoctors.Remove(foundDoc); } } // end foreach return(nonAvailableSkillSets); } // end of CheckAvailabilityOfDoctors
} // end of GetCurrentActivitiesPlusOrganizationalUnit #endregion #region SkipNextAction /// <summary> /// Defines conditional routine, e.g. if resources are qualified enough the next consultation does /// not have to take place. Per default no action should be skipped, if wanted the method has /// to be overriden by the user /// </summary> /// <param name="patient">Considered patient</param> /// <param name="mainDoc">Main doctor of the intial action</param> /// <param name="initialTreatmentType">The initial treatment that defines a possible skip</param> /// <param name="nextActionType">The action to be skipped</param> /// <returns>True if action should be skipped</returns> virtual public bool SkipNextAction(EntityPatient patient, EntityDoctor mainDoc, ActionTypeClass initialTreatmentType, ActionTypeClass nextActionType) { return(false); } // end of SkipNextAction
} // end of EntityLeaveControlUnit #endregion //-------------------------------------------------------------------------------------------------- // Custom Methods //-------------------------------------------------------------------------------------------------- #region ChooseResourcesForAction /// <summary> /// Helping method to choose resource for action requests, first available resources /// that satisfy requirements are chosen /// </summary> /// <param name="actionRequest">Request for that resources are looked for</param> /// <param name="resources">Out parameter that represent the assigned resources</param> /// <returns>True if all resources have been assigned, false else</returns> public bool ChooseResourcesForAction( RequestSpecialFacilityAction actionRequest, out ResourceSet resources) { resources = new ResourceSet(); #region Doctors List <EntityDoctor> chosenDoctors = new List <EntityDoctor>(); #region MainDoc if (actionRequest.ActionType.MainDoctorRequirements != null) { if (actionRequest.ResourceSet.MainDoctor != null) { if (actionRequest.ResourceSet.MainDoctor.IsWaiting()) { chosenDoctors.Add(resources.MainDoctor); resources.MainDoctor = actionRequest.ResourceSet.MainDoctor; } else { return(false); } // end if } else { } // end if } // end if #endregion #region AssistingDoctors if (actionRequest.ActionType.AssistingDoctorRequirements != null) { if (actionRequest.ResourceSet.AssistingDoctors != null) { foreach (EntityDoctor doctor in actionRequest.ResourceSet.AssistingDoctors) { if (!doctor.IsWaiting()) { return(false); } } // end foreach } else { List <EntityDoctor> foundDoctors = new List <EntityDoctor>(); List <EntityDoctor> allDoctors = new List <EntityDoctor>(ControlledDoctors); foreach (SkillSet skillSet in actionRequest.ActionType.AssistingDoctorRequirements) { EntityDoctor foundDoc = null; foreach (EntityDoctor doc in allDoctors) { if (doc.IsWaiting() && doc.SatisfiesSkillSet(skillSet) && !chosenDoctors.Contains(doc) && !doc.StaffOutsideShift) { foundDoc = doc; break; } // end if } // end foreach if (foundDoc == null) { return(false); } else { allDoctors.Remove(foundDoc); foundDoctors.Add(foundDoc); chosenDoctors.Add(foundDoc); } // end if } // end foreach resources.AssistingDoctors = foundDoctors.ToArray(); } // end if } // end if #endregion #endregion #region Nurses List <EntityNurse> chosenNurses = new List <EntityNurse>(); #region MainNurse if (actionRequest.ActionType.MainNurseRequirements != null) { if (actionRequest.ResourceSet.MainNurse != null) { if (actionRequest.ResourceSet.MainNurse.IsWaiting()) { chosenNurses.Add(resources.MainNurse); resources.MainNurse = actionRequest.ResourceSet.MainNurse; } else { return(false); } // end if } else { List <EntityNurse> possibleDocs = ControlledNurses.Where(p => p.IsWaiting() && p.SatisfiesSkillSet(actionRequest.ActionType.MainNurseRequirements) && !p.StaffOutsideShift).ToList(); if (possibleDocs.Count == 0) { return(false); } resources.MainNurse = possibleDocs.First(); chosenNurses.Add(resources.MainNurse); } // end if } // end if #endregion #region AssistingNurses if (actionRequest.ActionType.AssistingNurseRequirements != null) { if (actionRequest.ResourceSet.AssistingNurses != null) { foreach (EntityNurse nurse in actionRequest.ResourceSet.AssistingNurses) { if (!nurse.IsWaiting()) { return(false); } } // end foreach } else { List <EntityNurse> foundNurses = new List <EntityNurse>(); List <EntityNurse> allNurses = new List <EntityNurse>(ControlledNurses); foreach (SkillSet skillSet in actionRequest.ActionType.AssistingNurseRequirements) { EntityNurse foundDoc = null; foreach (EntityNurse nurse in allNurses) { if (nurse.IsWaiting() && nurse.SatisfiesSkillSet(skillSet) && !chosenNurses.Contains(nurse) && !nurse.StaffOutsideShift) { foundDoc = nurse; break; } // end if } // end foreach if (foundDoc == null) { return(false); } else { allNurses.Remove(foundDoc); foundNurses.Add(foundDoc); chosenNurses.Add(foundDoc); } // end if } // end foreach resources.AssistingNurses = foundNurses.ToArray(); } // end if } // end if #endregion #endregion #region TreatmentFacilities bool foundFacility = false; foreach (EntityTreatmentFacility fac in AssignedTreatmentFacilities.Where(p => !p.BlockedForPatient)) { if (!fac.Occupied && fac.SatisfiesSkillSet(actionRequest.ActionType.FacilityRequirements)) { resources.TreatmentFacility = fac; foundFacility = true; break; } // end if } // end foreach if (!foundFacility) { return(false); } #endregion return(true); } // end of ChooseResourcesForAction
} // end of PerformAssessment #endregion #region PerformDisptatching protected bool PerformDisptatching(DateTime time, ISimulationEngine simEngine) { #region StayInBed bool triggeredStayInBed = false; foreach (RequestInpatientStayInBed request in PossibleEmergencyStayInBed) { EntityPatient patient = request.Patient; List <EntityWard> possibleWards = WardsPerType[patient.InpatientPath.CurrentTreatmentBlock.WardType]; EntityBed bed = null; foreach (EntityWard ward in possibleWards) { bed = ward.GetBed(patient.InpatientPath.CurrentTreatmentBlock.BedType); if (bed != null) { break; } } // end foreach if (bed != null) { patient.InpatientPath.CurrentTreatmentBlock.InititateTreatmentBlock(bed.ParentWard, bed); patient.StopCurrentActivities(time, simEngine); ActivityInpatientStayInBed stayInBed = new ActivityInpatientStayInBed(this, patient, bed.ParentWard, bed, false); stayInBed.StartEvent.Trigger(time, simEngine); triggeredStayInBed = true; RemoveRequest(request); } // end if } // end foreach foreach (RequestInpatientChangeWard request in PossibleChangeWard) { EntityPatient patient = request.Patient; List <EntityWard> possibleWards = WardsPerType[patient.InpatientPath.CurrentTreatmentBlock.WardType]; EntityBed bed = null; foreach (EntityWard ward in possibleWards) { bed = ward.GetBed(patient.InpatientPath.CurrentTreatmentBlock.BedType); if (bed != null) { break; } } // end foreach if (bed != null) { patient.InpatientPath.CurrentTreatmentBlock.InititateTreatmentBlock(bed.ParentWard, bed); request.OldBed.RemovePatient(); patient.StopCurrentActivities(time, simEngine); ActivityInpatientStayInBed stayInBed = new ActivityInpatientStayInBed(this, patient, bed.ParentWard, bed, false); stayInBed.StartEvent.Trigger(time, simEngine); RemoveRequest(request); } // end if } // end foreach foreach (RequestInpatientStayInBed request in PossibleScheduledStayInBed) { EntityPatient patient = request.Patient; List <EntityWard> possibleWards = WardsPerType[patient.InpatientPath.CurrentTreatmentBlock.WardType]; EntityBed bed = null; foreach (EntityWard ward in possibleWards) { bed = ward.GetBed(patient.InpatientPath.CurrentTreatmentBlock.BedType); if (bed != null) { break; } } // end foreach if (bed != null) { patient.InpatientPath.CurrentTreatmentBlock.InititateTreatmentBlock(bed.ParentWard, bed); patient.StopCurrentActivities(time, simEngine); ActivityInpatientStayInBed stayInBed = new ActivityInpatientStayInBed(this, patient, bed.ParentWard, bed, false); stayInBed.StartEvent.Trigger(time, simEngine); RemoveRequest(request); } // end if } // end foreach #endregion #region InpatientActivities List <RequestInpatientActivity> originalRequests = PossibleRAEL.Where(p => p is RequestInpatientActivity).Cast <RequestInpatientActivity>().ToList(); List <RequestInpatientResumeActivity> resumeRequests = PossibleRAEL.Where(p => p is RequestInpatientResumeActivity).Cast <RequestInpatientResumeActivity>().ToList(); List <RequestInpatientActivity> requestsEmergencyTreatment = originalRequests.Where(p => p.InpatientTreatment.IsEmergencyTreatment && ((RequestInpatientActivity)p).EarliestTime <= time).Cast <RequestInpatientActivity>().ToList(); List <RequestInpatientActivity> requestsTreatment = originalRequests.Where(p => !p.InpatientTreatment.IsEmergencyTreatment && ((RequestInpatientActivity)p).EarliestTime <= time).Cast <RequestInpatientActivity>().ToList(); List <RequestInpatientResumeActivity> requestsResumeTreatment = resumeRequests.Where(p => !p.InpatientTreatment.IsEmergencyTreatment && ((RequestInpatientResumeActivity)p).EarliestTime <= time).Cast <RequestInpatientResumeActivity>().ToList(); #region EmergencyTreatments if (requestsEmergencyTreatment.Count > 0) { EntityPatient patient = requestsEmergencyTreatment.First().Patient; EntityDoctor doctor = ChooseDoctor(requestsEmergencyTreatment.First().Patient, requestsEmergencyTreatment.First()); if (doctor != null) { ActivityInpatientEmergencyTreatment newInpatientEmergencyTreatment = new ActivityInpatientEmergencyTreatment(this, patient, doctor, patient.Ward, patient.Bed); patient.StopCurrentActivities(time, simEngine); doctor.StopCurrentActivities(time, simEngine); newInpatientEmergencyTreatment.StartEvent.Trigger(time, simEngine); PossibleRAEL.Remove(requestsEmergencyTreatment[0]); RemoveRequest(requestsEmergencyTreatment[0]); requestsEmergencyTreatment.RemoveAt(0); return(true); } // end if } // end if #endregion #region Treatments if (requestsTreatment.Count > 0) { EntityPatient patient = requestsTreatment.First().Patient; EntityDoctor doctor = ChooseDoctor(requestsTreatment.First().Patient, requestsTreatment.First()); if (doctor != null) { ActivityInpatientTreatment newInpatientTreatment = new ActivityInpatientTreatment( this, patient, doctor, patient.Ward, patient.Bed, requestsTreatment.First().InpatientTreatment); patient.StopCurrentActivities(time, simEngine); doctor.StopCurrentActivities(time, simEngine); newInpatientTreatment.StartEvent.Trigger(time, simEngine); PossibleRAEL.Remove(requestsTreatment[0]); RemoveRequest(requestsTreatment[0]); requestsTreatment.RemoveAt(0); return(true); } // end if } // end if #endregion #region ResumeTreatments if (requestsResumeTreatment.Count > 0) { EntityPatient patient = requestsResumeTreatment.First().Patient; EntityDoctor doctor = ChooseDoctor(requestsResumeTreatment.First().Patient, requestsResumeTreatment.First()); if (doctor != null) { ActivityInpatientTreatment newInpatientTreatment = new ActivityInpatientTreatment(this, patient, doctor, patient.Ward, patient.Bed, requestsResumeTreatment.First().DegreeOfCompletion, requestsResumeTreatment.First().Duration, requestsResumeTreatment.First().InpatientTreatment); patient.StopCurrentActivities(time, simEngine); doctor.StopCurrentActivities(time, simEngine); newInpatientTreatment.StartEvent.Trigger(time, simEngine); PossibleRAEL.Remove(requestsResumeTreatment[0]); RemoveRequest(requestsResumeTreatment[0]); requestsResumeTreatment.RemoveAt(0); return(true); } // end if } // end if #endregion #endregion #region OrganizationalWork bool triggeredOrganizationalWork = false; List <RequestInpatientDoctorOrganziationalWork> allOrgReqs = PossibleRAEL.Where(p => p is RequestInpatientDoctorOrganziationalWork).Cast <RequestInpatientDoctorOrganziationalWork>().ToList(); foreach (RequestInpatientDoctorOrganziationalWork reqOrg in allOrgReqs) { if (reqOrg.Doctor.IsWaiting()) { reqOrg.Doctor.StopCurrentActivities(time, simEngine); ActivityInpatientDoctorOrganizationalWork orgWork = new ActivityInpatientDoctorOrganizationalWork(this, reqOrg.Doctor, WaitingRoomStaff, reqOrg.DegreeOfCompletion, reqOrg.Duration); orgWork.StartEvent.Trigger(time, simEngine); triggeredOrganizationalWork = true; PossibleRAEL.Remove(reqOrg); RemoveRequest(reqOrg); } // end if } // end foreach #endregion return(triggeredStayInBed || triggeredOrganizationalWork); } // end of PerformDisptatching
} // end of DurationInpatientTreatment #endregion #region DurationDoctorOrgWork public TimeSpan DurationDoctorOrgWork(EntityDoctor patient) { return(TimeSpan.FromHours(0.5)); } // end of DurationDoctorOrgWork