} // 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 ControlUnitHealthCare #endregion #region Initialize /// <summary> /// Overrides the base initialize method of control units. All staff members, treatment facilities /// and waiting areas are intialized and assigned to sub organizational control units and structural areas /// </summary> /// <param name="startTime">Time the simulation starts</param> /// <param name="simEngine">SimEngine that handles the simulation run</param> public override void Initialize(DateTime startTime, ISimulationEngine simEngine) { #region TreatmentFacilityInitialize string[] structuralAreaIdentifier = InputData.GetStructuralAreaIdentifiers(); Dictionary <string, StructuralArea> strucArePerName = new Dictionary <string, StructuralArea>(); // create all structural areas that occur in waiting areas and treamtent facilities foreach (string identifier in structuralAreaIdentifier) { strucArePerName.Add(identifier, new StructuralArea(identifier)); } // end foreach _assingedTreatmentFacilities = new List <EntityTreatmentFacility>(); ResourceAssignmentPhysical <EntityTreatmentFacility>[] treatmentFacilityAssigns = InputData.GetTreatmentFacilities(); // assign treatment facilities to organizational and structural areas foreach (ResourceAssignmentPhysical <EntityTreatmentFacility> assignment in treatmentFacilityAssigns) { assignment.Resource.SetParentDepartmentControl(this); assignment.Resource.AssignmentType = assignment.AssignmentType; if (assignment.OrganizationalUnit != "RootDepartment") { // the facility is assigned to the specified organizational control OrganizationalUnitPerName[assignment.OrganizationalUnit].AddEntity(assignment.Resource); OrganizationalUnitPerName[assignment.OrganizationalUnit].AddAssignedTreatmentFacility(assignment.Resource); } else { // if no organizational area was specified or the root department was specified // the facility is added in the department control AddEntity(assignment.Resource); AssignedTreatmentFacilities.Add(assignment.Resource); } // end if // faciltiy is added to the specified structural area if (!strucArePerName.ContainsKey(assignment.StructuralArea)) { throw new InvalidOperationException("Structural area identifier not specified"); } if (assignment.Resource is EntityMultiplePatientTreatmentFacility) { strucArePerName[assignment.StructuralArea].MultiplePatientTreatmentFacilities.Add((EntityMultiplePatientTreatmentFacility)assignment.Resource); } else { strucArePerName[assignment.StructuralArea].TreatmentFacilities.Add(assignment.Resource); } } // end foreach #endregion #region WaitingAreas // same principle as for treatment facility is used for waiting areas foreach (ResourceAssignmentPhysical <EntityWaitingArea> waitingRoomAssignment in InputData.GetWaitingRoomPatients()) { if (waitingRoomAssignment.OrganizationalUnit != "RootDepartment") { OrganizationalUnitPerName[waitingRoomAssignment.OrganizationalUnit].AddEntity(waitingRoomAssignment.Resource); } else { AddEntity(waitingRoomAssignment.Resource); } // end if if (!strucArePerName.ContainsKey(waitingRoomAssignment.StructuralArea)) { throw new InvalidOperationException("Structural area identifier not specified"); } strucArePerName[waitingRoomAssignment.StructuralArea].WaitingAreasPatients.Add(waitingRoomAssignment.Resource); } // end foreach foreach (ResourceAssignmentPhysical <EntityWaitingArea> waitingRoomAssignment in InputData.GetWaitingRoomsStaff()) { if (waitingRoomAssignment.OrganizationalUnit != "RootDepartment") { OrganizationalUnitPerName[waitingRoomAssignment.OrganizationalUnit].AddEntity(waitingRoomAssignment.Resource); } else { AddEntity(waitingRoomAssignment.Resource); } // end if if (!strucArePerName.ContainsKey(waitingRoomAssignment.StructuralArea)) { throw new InvalidOperationException("Structural area identifier not specified"); } strucArePerName[waitingRoomAssignment.StructuralArea].StaffWaitingRoom = waitingRoomAssignment.Resource; } // end foreach #endregion _structuralAres = strucArePerName.Values.ToArray(); #region StaffInitialze // the starting staff assignements specified by the input is obtained List <ResourceAssignmentStaff> staffAssignments = InputData.StaffHandler.GetStartingStaff(startTime); foreach (ResourceAssignmentStaff staffAssignment in staffAssignments) { staffAssignment.Resource.StaffOutsideShift = false; staffAssignment.Resource.BlockedForDispatching = false; staffAssignment.Resource.BaseControlUnit = this; staffAssignment.Resource.AssignmentType = staffAssignment.AssignmentType; // staff is either assigned to a organizational control or the department control if (staffAssignment.OrganizationalUnit == "RootDepartment") { AddEntity(staffAssignment.Resource); } else { OrganizationalUnitPerName[staffAssignment.OrganizationalUnit].AddEntity(staffAssignment.Resource); } } // end foreach DateTime nextStaffChange; // the next time the staffing levels change an event is scheduled with the associated staff changes Event staffChangeEvent = InputData.StaffHandler.GetNextStaffChangingEvent(this, startTime, out nextStaffChange); simEngine.AddScheduledEvent(staffChangeEvent, nextStaffChange); // all hanlded staff members (doctors and nurses) are sent in a waiting activity foreach (EntityDoctor doc in HandledDoctors) { Event docWait = doc.StartWaitingActivity(WaitingRoomForStaff(doc)); docWait.Trigger(startTime, simEngine); } // end foreach foreach (EntityNurse nurse in HandledNurses) { Event nurseWait = nurse.StartWaitingActivity(WaitingRoomForStaff(nurse)); nurseWait.Trigger(startTime, simEngine); } // end foreach #endregion // base initializ is called to move down the tree base.Initialize(startTime, simEngine); } // end of Initilaize
} // end of PerformAssessment #endregion #region PerformDisptatching /// <summary> /// Handles requests of staff members to leave that are out of shift, routes action requests /// to corresponding organizational control units and handles a shared treatment facility by /// assigning it to the busier organizational unit /// </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 RequestRouting List <RequestEmergencyAction> actionRequests = new List <RequestEmergencyAction>(RAEL.Where(p => p.Activity == "ActivityHealthCareAction").Cast <RequestEmergencyAction>()); foreach (RequestEmergencyAction request in actionRequests) { if (request.ActionType.Type == "Triage" || request.ActionType.Type == "Register") { OrganizationalUnitPerName["OrgUnitTriageRegister"].AssignRequest(request); } else { if (request.Patient.PatientClass.Category == "Surgical") { OrganizationalUnitPerName["OrgUnitSurgical"].AssignRequest(request); } else { OrganizationalUnitPerName["OrgUnitInternal"].AssignRequest(request); } } // end if RemoveRequest(request); } // end foreach #endregion #region ResourceSharing foreach (EntityTreatmentFacility sharedTreatFac in AssignedTreatmentFacilities.Where(p => p.AssignmentType == AssignmentType.Shared)) { if (sharedTreatFac.PatientBlocking != null) { continue; } if (sharedTreatFac.CurrentlyAssignedOrganizationalUnit != null) { sharedTreatFac.CurrentlyAssignedOrganizationalUnit.RemoveAssignedTreatmentFacility(sharedTreatFac); } if (OrganizationalUnitPerName["OrgUnitInternal"].RAEL.Count > OrganizationalUnitPerName["OrgUnitSurgical"].RAEL.Count) { OrganizationalUnitPerName["OrgUnitSurgical"].AddAssignedTreatmentFacility(sharedTreatFac); } else { OrganizationalUnitPerName["OrgUnitInternal"].AddAssignedTreatmentFacility(sharedTreatFac); } // end if } // end foreach #endregion return(false); } // end of PerformDisptatching