} // end of #endregion //-------------------------------------------------------------------------------------------------- // Methods //-------------------------------------------------------------------------------------------------- #region PerformCustomRules /// <summary> /// Custom rules of control, assigns all requests in specified order, patient priority and FIFO principle is /// used for requests of same type /// </summary> /// <param name="startTime">Time rules are executed</param> /// <param name="simEngine">SimEngine responsible for simulation execution</param> /// <returns>False</returns> protected override bool PerformCustomRules(DateTime time, ISimulationEngine simEngine) { #region Register List <RequestEmergencyAction> registerRequests = new List <RequestEmergencyAction>(RAEL.Where(p => p.Activity == "ActivityHealthCareAction" && ((RequestEmergencyAction)p).ActionType.Type == "Register").Cast <RequestEmergencyAction>()); while (registerRequests.Count > 0) { // Get Register request Triage-FIFO RequestEmergencyAction requestRegister = PatientPriorityPlusFIFO <RequestEmergencyAction, EmergencyActionTypeClass>(registerRequests); ResourceSet chosenResources; if (!((ControlUnitEmergencyExample)ParentDepartmentControl).ChooseResourcesForAction( ControlledDoctors, ControlledNurses, AssignedTreatmentFacilities, requestRegister, out chosenResources)) { break; } // enf if RemoveRequest(requestRegister); registerRequests.Remove(requestRegister); EntityPatient patient = (EntityPatient)requestRegister.Origin.First(); ActivityHealthCareAction <EmergencyActionTypeClass> register = new ActivityHealthCareAction <EmergencyActionTypeClass>( this, InputData, patient, chosenResources, requestRegister.ActionType, patient.EmergencyTreatmentPath); chosenResources.StopCurrentActivities(time, simEngine); patient.StopCurrentActivities(time, simEngine); register.StartEvent.Trigger(time, simEngine); } // end while #endregion #region Triage List <RequestEmergencyAction> triageRequests = new List <RequestEmergencyAction>(RAEL.Where(p => p.Activity == "ActivityHealthCareAction" && ((RequestEmergencyAction)p).ActionType.Type == "Triage").Cast <RequestEmergencyAction>()); while (triageRequests.Count > 0) { ResourceSet chosenResources; // Get Register request Triage-FIFO RequestEmergencyAction requestTriage = PatientPriorityPlusFIFO <RequestEmergencyAction, EmergencyActionTypeClass>(triageRequests); if (!((ControlUnitEmergencyExample)ParentDepartmentControl).ChooseResourcesForAction( ControlledDoctors, ControlledNurses, AssignedTreatmentFacilities, requestTriage, out chosenResources)) { break; } // enf if // Remove Request from RAEL list RemoveRequest(requestTriage); triageRequests.Remove(requestTriage); EntityPatient patient = (EntityPatient)requestTriage.Origin.First(); ActivityHealthCareAction <EmergencyActionTypeClass> triage = new ActivityHealthCareAction <EmergencyActionTypeClass>( this, InputData, patient, chosenResources, requestTriage.ActionType, patient.EmergencyTreatmentPath); chosenResources.StopCurrentActivities(time, simEngine); patient.StopCurrentActivities(time, simEngine); triage.StartEvent.Trigger(time, simEngine); } // end while #endregion return(false); } // end of PerformCustomRules
} // end of #endregion //-------------------------------------------------------------------------------------------------- // Methods //-------------------------------------------------------------------------------------------------- #region PerformCustomRules /// <summary> /// Custom rules of control, assigns all requests in specified order, patient priority and FIFO principle is /// used for requests of same type /// </summary> /// <param name="startTime">Time rules are executed</param> /// <param name="simEngine">SimEngine responsible for simulation execution</param> /// <returns>False</returns> protected override bool PerformCustomRules(DateTime time, ISimulationEngine simEngine) { #region Consultation List <RequestEmergencyAction> consultationRequests = new List <RequestEmergencyAction>(RAEL.Where(p => p.Activity == "ActivityHealthCareAction" && ((RequestEmergencyAction)p).ActionType.Type == "Consultation").Cast <RequestEmergencyAction>()); List <RequestEmergencyAction> possibleConsultationRequests = new List <RequestEmergencyAction>(); #region CheckForControllingAllRequiredResources foreach (RequestEmergencyAction request in consultationRequests) { if (request.ReadyForDispatch) { possibleConsultationRequests.Add(request); } else { List <SkillSet> nonAvailableDoctorSkills = ((ControlUnitEmergencyExample)ParentDepartmentControl).CheckAvailabilityOfDoctors(request.ActionType.MainDoctorRequirements, request.ActionType.AssistingDoctorRequirements); if (nonAvailableDoctorSkills.Count() == 0) { possibleConsultationRequests.Add(request); request.ReadyForDispatch = true; } else { if (nonAvailableDoctorSkills.Count > 0 && !request.StaffRequested) { ((ControlUnitEmergencyExample)ParentDepartmentControl).DelegateOutBox.Add(new DelegateRequestDocsForAssisting(this, nonAvailableDoctorSkills)); } request.StaffRequested = true; } // end if } // end if } // end foreach #endregion while (possibleConsultationRequests.Count > 0) { ResourceSet chosenResources; // Get Register request Triage-FIFO RequestEmergencyAction requestConsultation = PatientPriorityPlusFIFO <RequestEmergencyAction, EmergencyActionTypeClass>(possibleConsultationRequests); if (!((ControlUnitEmergencyExample)ParentDepartmentControl).ChooseResourcesForAction( ControlledDoctors, ControlledNurses, AssignedTreatmentFacilities, requestConsultation, out chosenResources)) { break; } // enf if // Remove Request from RAEL list RemoveRequest(requestConsultation); possibleConsultationRequests.Remove(requestConsultation); EntityPatient patient = (EntityPatient)requestConsultation.Origin.First(); ActivityHealthCareAction <EmergencyActionTypeClass> consultation = new ActivityHealthCareAction <EmergencyActionTypeClass>( this, InputData, patient, chosenResources, requestConsultation.ActionType, patient.EmergencyTreatmentPath); chosenResources.StopCurrentActivities(time, simEngine); patient.StopCurrentActivities(time, simEngine); consultation.StartEvent.Trigger(time, simEngine); } // end while #endregion #region BedPlacement List <RequestEmergencyAction> bedPlacementRequests = new List <RequestEmergencyAction>(RAEL.Where(p => p.Activity == "ActivityHealthCareAction" && ((RequestEmergencyAction)p).ActionType.Type == "BedPlacement").Cast <RequestEmergencyAction>()); while (bedPlacementRequests.Count > 0) { ResourceSet chosenResources; // Get Register request Triage-FIFO RequestEmergencyAction bedPlacementRequest = PatientPriorityPlusFIFO <RequestEmergencyAction, EmergencyActionTypeClass>(bedPlacementRequests); if (!((ControlUnitEmergencyExample)ParentDepartmentControl).ChooseResourcesForAction( ControlledDoctors, ControlledNurses, AssignedTreatmentFacilities, bedPlacementRequest, out chosenResources)) { break; } // enf if // Remove Request from RAEL list RemoveRequest(bedPlacementRequest); bedPlacementRequests.Remove(bedPlacementRequest); EntityPatient patient = (EntityPatient)bedPlacementRequest.Origin.First(); ActivityHealthCareAction <EmergencyActionTypeClass> bedPlacement = new ActivityHealthCareAction <EmergencyActionTypeClass>( this, InputData, patient, chosenResources, bedPlacementRequest.ActionType, patient.EmergencyTreatmentPath ); chosenResources.StopCurrentActivities(time, simEngine); patient.StopCurrentActivities(time, simEngine); bedPlacement.StartEvent.Trigger(time, simEngine); } // end while #endregion #region Assessment List <RequestEmergencyAction> assessmentRequests = new List <RequestEmergencyAction>(RAEL.Where(p => p.Activity == "ActivityHealthCareAction" && ((RequestEmergencyAction)p).ActionType.Type == "Assessment").Cast <RequestEmergencyAction>()); while (assessmentRequests.Count > 0) { ResourceSet chosenResources; // Get Register request Triage-FIFO RequestEmergencyAction requestAssessment = PatientPriorityPlusFIFO <RequestEmergencyAction, EmergencyActionTypeClass>(assessmentRequests); if (!((ControlUnitEmergencyExample)ParentDepartmentControl).ChooseResourcesForAction( ControlledDoctors, ControlledNurses, AssignedTreatmentFacilities, requestAssessment, out chosenResources)) { break; } // enf if // Remove Request from RAEL list RemoveRequest(requestAssessment); assessmentRequests.Remove(requestAssessment); EntityPatient patient = (EntityPatient)requestAssessment.Origin.First(); ActivityHealthCareAction <EmergencyActionTypeClass> assessment = new ActivityHealthCareAction <EmergencyActionTypeClass>( this, InputData, patient, chosenResources, requestAssessment.ActionType, patient.EmergencyTreatmentPath); chosenResources.StopCurrentActivities(time, simEngine); patient.StopCurrentActivities(time, simEngine); assessment.StartEvent.Trigger(time, simEngine); } // end while #endregion #region Treatment List <RequestEmergencyAction> treatmentRequests = new List <RequestEmergencyAction>(RAEL.Where(p => p.Activity == "ActivityHealthCareAction" && ((RequestEmergencyAction)p).ActionType.Type == "Treatment").Cast <RequestEmergencyAction>()); while (treatmentRequests.Count > 0) { ResourceSet chosenResources; // Get Register request Triage-FIFO RequestEmergencyAction requestTreatment = PatientPriorityPlusFIFO <RequestEmergencyAction, EmergencyActionTypeClass>(treatmentRequests); if (!((ControlUnitEmergencyExample)ParentDepartmentControl).ChooseResourcesForAction( ControlledDoctors, ControlledNurses, AssignedTreatmentFacilities, 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 <EmergencyActionTypeClass> assessment = new ActivityHealthCareAction <EmergencyActionTypeClass>( this, InputData, patient, chosenResources, requestTreatment.ActionType, patient.EmergencyTreatmentPath); chosenResources.StopCurrentActivities(time, simEngine); patient.StopCurrentActivities(time, simEngine); assessment.StartEvent.Trigger(time, simEngine); } // end while #endregion return(false); } // end of PerformCustomRules
} // end of PerformControlled #endregion //-------------------------------------------------------------------------------------------------- // Custom Mehtods //-------------------------------------------------------------------------------------------------- #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="doctorsToChoose">Doctors that can be selected for action</param> /// <param name="nursesToChoose">Nurses that can be selected for action</param> /// <param name="treatmentFacilitiesToChoose">Treatment facilities that can be selected for action</param> /// <param name="emergencyRequest">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( IEnumerable <EntityDoctor> doctorsToChoose, IEnumerable <EntityNurse> nursesToChoose, IEnumerable <EntityTreatmentFacility> treatmentFacilitiesToChoose, RequestEmergencyAction emergencyRequest, out ResourceSet resources) { resources = new ResourceSet(); #region Doctors List <EntityDoctor> chosenDoctors = new List <EntityDoctor>(); #region MainDoc if (emergencyRequest.ActionType.MainDoctorRequirements != null) { if (emergencyRequest.ResourceSet.MainDoctor != null) { if (emergencyRequest.ResourceSet.MainDoctor.IsWaiting()) { chosenDoctors.Add(resources.MainDoctor); resources.MainDoctor = emergencyRequest.ResourceSet.MainDoctor; } else { return(false); } // end if } else { List <EntityDoctor> possibleDocs = doctorsToChoose.Where(p => p.IsWaiting() && p.SatisfiesSkillSet(emergencyRequest.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 (emergencyRequest.ActionType.AssistingDoctorRequirements != null) { if (emergencyRequest.ResourceSet.AssistingDoctors != null) { foreach (EntityDoctor doctor in emergencyRequest.ResourceSet.AssistingDoctors) { if (!doctor.IsWaiting()) { return(false); } } // end foreach } else { List <EntityDoctor> foundDoctors = new List <EntityDoctor>(); List <EntityDoctor> allDoctors = new List <EntityDoctor>(doctorsToChoose); foreach (SkillSet skillSet in emergencyRequest.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 (emergencyRequest.ActionType.MainNurseRequirements != null) { if (emergencyRequest.ResourceSet.MainNurse != null) { if (emergencyRequest.ResourceSet.MainNurse.IsWaiting()) { chosenNurses.Add(resources.MainNurse); resources.MainNurse = emergencyRequest.ResourceSet.MainNurse; } else { return(false); } // end if } else { List <EntityNurse> possibleDocs = nursesToChoose.Where(p => p.IsWaiting() && p.SatisfiesSkillSet(emergencyRequest.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 (emergencyRequest.ActionType.AssistingNurseRequirements != null) { if (emergencyRequest.ResourceSet.AssistingNurses != null) { foreach (EntityNurse nurse in emergencyRequest.ResourceSet.AssistingNurses) { if (!nurse.IsWaiting()) { return(false); } } // end foreach } else { List <EntityNurse> foundNurses = new List <EntityNurse>(); List <EntityNurse> allNurses = new List <EntityNurse>(nursesToChoose); foreach (SkillSet skillSet in emergencyRequest.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 (emergencyRequest.Patient.OccupiedFacility != null && emergencyRequest.Patient.OccupiedFacility.SatisfiesSkillSet(emergencyRequest.ActionType.FacilityRequirements)) { resources.TreatmentFacility = emergencyRequest.Patient.OccupiedFacility; } else { bool foundFacility = false; foreach (EntityTreatmentFacility fac in treatmentFacilitiesToChoose.Where(p => !p.BlockedForPatient)) { if (!fac.Occupied && fac.SatisfiesSkillSet(emergencyRequest.ActionType.FacilityRequirements)) { resources.TreatmentFacility = fac; foundFacility = true; break; } // end if } // end foreach if (!foundFacility) { return(false); } } // end if #endregion return(true); } // end of ChooseResourcesForAction