} // end of CheckAvailabilityOfDoctors #endregion //-------------------------------------------------------------------------------------------------- // Control Mechansisms //-------------------------------------------------------------------------------------------------- #region PatientSlotTimePlusPriority /// <summary> /// Helping method to choose the next patient based on slot time and priority /// </summary> /// <param name="requests">All current requests</param> /// <returns>Next request to handle</returns> public RequestOutpatientAction PatientSlotTimePlusPriority(List <RequestOutpatientAction> requests) { if (requests.Count == 0) { return(null); } // determine the earliest slot time RequestOutpatientAction minSlotTime = requests.Aggregate((curmin, x) => (curmin == null || (x.TimeRequested) < curmin.TimeRequested ? x : curmin)); // filter all requests of that time List <RequestOutpatientAction> requestWithEarliestSlotTime = requests.Where(p => p.SlotTime == minSlotTime.SlotTime).ToList(); // return request with highest priority return(requests.Aggregate((curmin, x) => (curmin == null || (x.Patient.PatientClass.Priority) < curmin.Patient.PatientClass.Priority ? x : curmin))); } // end of
} // end of PerformControlled #endregion #region ChooseResourcesForAction /// <summary> /// Helping method to choose resource for action requests, first available resources /// that satisfy requirements are chosen or it is checked if preassigned staff members /// (e.g. corresponding doctors) have capacitiy to undertake action /// </summary> /// <param name="outPatientRequestRequest">The request that is the soruce for the action</param> /// <param name="resources">Out parameter of chosen resources for action</param> /// <returns>True if all resources have been assigned, false else</returns> public bool ChooseResourcesForAction( RequestOutpatientAction outPatientRequestRequest, out ResourceSet resources) { resources = new ResourceSet(); #region Doctors List <EntityDoctor> chosenDoctors = new List <EntityDoctor>(); #region MainDoc if (outPatientRequestRequest.ActionType.MainDoctorRequirements != null) { if (outPatientRequestRequest.ResourceSet.MainDoctor != null) { if (outPatientRequestRequest.ResourceSet.MainDoctor.IsWaiting()) { chosenDoctors.Add(resources.MainDoctor); resources.MainDoctor = outPatientRequestRequest.ResourceSet.MainDoctor; } else { return(false); } // end if } else { List <EntityDoctor> possibleDocs = ControlledDoctors.Where(p => p.IsWaiting() && p.SatisfiesSkillSet(outPatientRequestRequest.ActionType.MainDoctorRequirements) && !p.StaffOutsideShift).ToList(); if (possibleDocs.Count == 0) { return(false); } resources.MainDoctor = possibleDocs.First(); chosenDoctors.Add(resources.MainDoctor); } // end if } // end if #endregion #region AssistingDoctors if (outPatientRequestRequest.ActionType.AssistingDoctorRequirements != null) { if (outPatientRequestRequest.ResourceSet.AssistingDoctors != null) { foreach (EntityDoctor doctor in outPatientRequestRequest.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 outPatientRequestRequest.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 (outPatientRequestRequest.ActionType.MainNurseRequirements != null) { if (outPatientRequestRequest.ResourceSet.MainNurse != null) { if (outPatientRequestRequest.ResourceSet.MainNurse.IsWaiting()) { chosenNurses.Add(resources.MainNurse); resources.MainNurse = outPatientRequestRequest.ResourceSet.MainNurse; } else { return(false); } // end if } else { List <EntityNurse> possibleDocs = ControlledNurses.Where(p => p.IsWaiting() && p.SatisfiesSkillSet(outPatientRequestRequest.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 (outPatientRequestRequest.ActionType.AssistingNurseRequirements != null) { if (outPatientRequestRequest.ResourceSet.AssistingNurses != null) { foreach (EntityNurse nurse in outPatientRequestRequest.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 outPatientRequestRequest.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 if (outPatientRequestRequest.Patient.OccupiedFacility != null && outPatientRequestRequest.Patient.OccupiedFacility.SatisfiesSkillSet(outPatientRequestRequest.ActionType.FacilityRequirements)) { resources.TreatmentFacility = outPatientRequestRequest.Patient.OccupiedFacility; } else { bool foundFacility = false; foreach (EntityTreatmentFacility fac in AssignedTreatmentFacilities.Where(p => !p.BlockedForPatient)) { if (!fac.Occupied && fac.SatisfiesSkillSet(outPatientRequestRequest.ActionType.FacilityRequirements)) { resources.TreatmentFacility = fac; foundFacility = true; break; } // end if } // end foreach if (!foundFacility) { return(false); } } // end if #endregion return(true); } // end of ChooseResourcesForAction
} // end of PerformAssessment #endregion #region PerformDisptatching // <summary> /// Handles requests of staff members to leave that are out of shift, register, assessment and treatment /// using patient slot times and priority /// </summary> /// <param name="startTime">Time rules are executed</param> /// <param name="simEngine">SimEngine responsible for simulation execution</param> /// <returns>False</returns> protected bool PerformDisptatching(DateTime time, ISimulationEngine simEngine) { #region StaffOutsideShift List <RequestBeAbsent> staffEndRequests = RAEL.Where(p => p is RequestBeAbsent).Cast <RequestBeAbsent>().ToList(); foreach (RequestBeAbsent req in staffEndRequests) { if (req.StaffMember.IsWaiting() && req.StaffMember.CurrentPatients.Count == 0) { req.StaffMember.StopCurrentActivities(time, simEngine); EventStaffLeave staffLeave = new EventStaffLeave(req.StaffMember.ParentControlUnit, req.StaffMember); staffLeave.Trigger(time, simEngine); RemoveRequest(req); } // end if } // end foreach #endregion #region Register List <RequestOutpatientAction> registerRequests = new List <RequestOutpatientAction>(RAEL.Where(p => p.Activity == "ActivityHealthCareAction" && ((RequestOutpatientAction)p).ActionType.Type == "Register").Cast <RequestOutpatientAction>()); while (registerRequests.Count > 0) { // Get Register request Triage-FIFO RequestOutpatientAction requestRegister = registerRequests.OrderBy(p => p.TimeRequested).First(); ResourceSet chosenResources; if (!ChooseResourcesForAction(requestRegister, out chosenResources)) { break; } // enf if RemoveRequest(requestRegister); registerRequests.Remove(requestRegister); EntityPatient patient = (EntityPatient)requestRegister.Origin.First(); ActivityHealthCareAction <OutpatientActionTypeClass> register = new ActivityHealthCareAction <OutpatientActionTypeClass>( this, InputData, patient, chosenResources, requestRegister.ActionType, patient.OutpatientTreatmentPath); chosenResources.StopCurrentActivities(time, simEngine); patient.StopCurrentActivities(time, simEngine); register.StartEvent.Trigger(time, simEngine); } // end while #endregion #region Assessment List <RequestOutpatientAction> assessmentRequests = new List <RequestOutpatientAction>(RAEL.Where(p => p.Activity == "ActivityHealthCareAction" && ((RequestOutpatientAction)p).ActionType.Type == "Assessment").Cast <RequestOutpatientAction>()); while (assessmentRequests.Count > 0) { ResourceSet chosenResources; // Get Register request Slottime-FIFO RequestOutpatientAction requestAssessment = PatientSlotTimePlusPriority(assessmentRequests); if (!ChooseResourcesForAction(requestAssessment, out chosenResources)) { break; } // enf if // Remove Request from RAEL list RemoveRequest(requestAssessment); assessmentRequests.Remove(requestAssessment); EntityPatient patient = (EntityPatient)requestAssessment.Origin.First(); ActivityHealthCareAction <OutpatientActionTypeClass> assessment = new ActivityHealthCareAction <OutpatientActionTypeClass>( this, InputData, patient, chosenResources, requestAssessment.ActionType, patient.OutpatientTreatmentPath); chosenResources.StopCurrentActivities(time, simEngine); patient.StopCurrentActivities(time, simEngine); assessment.StartEvent.Trigger(time, simEngine); } // end while #endregion #region Treatment List <RequestOutpatientAction> treatmentRequests = new List <RequestOutpatientAction>(RAEL.Where(p => p.Activity == "ActivityHealthCareAction" && ((RequestOutpatientAction)p).ActionType.Type == "Treatment").Cast <RequestOutpatientAction>()); while (treatmentRequests.Count > 0) { ResourceSet chosenResources; // Get Register request Triage-FIFO RequestOutpatientAction requestTreatment = PatientPriorityPlusFIFO <RequestOutpatientAction, OutpatientActionTypeClass>(treatmentRequests); if (!ChooseResourcesForAction(requestTreatment, out chosenResources)) { break; } // enf if // Remove Request from RAEL list and treatmentlist RemoveRequest(requestTreatment); treatmentRequests.Remove(requestTreatment); EntityPatient patient = (EntityPatient)requestTreatment.Origin.First(); ActivityHealthCareAction <OutpatientActionTypeClass> assessment = new ActivityHealthCareAction <OutpatientActionTypeClass>( this, InputData, patient, chosenResources, requestTreatment.ActionType, patient.OutpatientTreatmentPath); chosenResources.StopCurrentActivities(time, simEngine); patient.StopCurrentActivities(time, simEngine); assessment.StartEvent.Trigger(time, simEngine); } // end while #endregion return(false); } // end of PerformDisptatching