}         // end of HealthCareActionEnd

        #endregion

        #region HealthCareActionStart

        /// <summary>
        /// Method that visualized the start of a health care action, patient is added to
        /// the drawing system and all entities (staff and patient) are set to
        /// the corresponding positions in the treatment facility (if it is not a
        /// multiple patient treatment facility). Further, human resources are
        /// removed from the parent visualization engine to avoid double drawing.
        /// </summary>
        /// <param name="activity">Instance of health care action</param>
        /// <param name="time">Time the activity is started</param>
        public void HealthCareActionStart(Activity activity, DateTime time)
        {
            ActivityHealthCareAction <T> action = (ActivityHealthCareAction <T>)activity;

            if (action.ResourceSet.TreatmentFacility is EntityMultiplePatientTreatmentFacility)
            {
                return;
            }

            DrawPatient drawPatient = (DrawPatient)DrawingObjectPerEntity(action.Patient);

            DrawBaseTreatmentFacility drawTreatFac = (DrawBaseTreatmentFacility)ParentDepartmentVisualization.DrawingObjectPerEntity(action.ResourceSet.TreatmentFacility);

            drawPatient.SetPositionType(drawTreatFac.PatientPositionType);

            drawPatient.SetPosition(drawTreatFac.PatientInRoomPosition);

            int staffCount = 0;

            if (action.ResourceSet.MainDoctor != null)
            {
                ParentDepartmentVisualization.RemoveDrawingObjectPerEntity(action.ResourceSet.MainDoctor);
                DrawDoctor drawMainDoctor = (DrawDoctor)DrawingObjectPerEntity(action.ResourceSet.MainDoctor);
                drawMainDoctor.SetPosition(drawTreatFac.GetStaffPosition(staffCount));
                staffCount++;
            } // end if

            if (action.ResourceSet.MainNurse != null)
            {
                ParentDepartmentVisualization.RemoveDrawingObjectPerEntity(action.ResourceSet.MainNurse);
                DrawNurse drawMainNurse = (DrawNurse)DrawingObjectPerEntity(action.ResourceSet.MainNurse);
                drawMainNurse.SetPosition(drawTreatFac.GetStaffPosition(staffCount));
                staffCount++;
            } // end if

            if (action.ResourceSet.AssistingDoctors != null)
            {
                foreach (EntityDoctor ent in action.ResourceSet.AssistingDoctors)
                {
                    ParentDepartmentVisualization.RemoveDrawingObjectPerEntity(ent);
                    DrawDoctor drawAssistDoctor = (DrawDoctor)DrawingObjectPerEntity(ent);
                    drawAssistDoctor.SetPosition(drawTreatFac.GetStaffPosition(staffCount));
                    staffCount++;
                } // end foreach
            }     // end if

            if (action.ResourceSet.AssistingNurses != null)
            {
                foreach (EntityNurse ent in action.ResourceSet.AssistingNurses)
                {
                    ParentDepartmentVisualization.RemoveDrawingObjectPerEntity(ent);
                    DrawNurse drawAssistNurse = (DrawNurse)DrawingObjectPerEntity(ent);
                    drawAssistNurse.SetPosition(drawTreatFac.GetStaffPosition(staffCount));
                    staffCount++;
                } // end foreach
            }     // end if
        }         // end of HealthCareActionEnd
        }     // end of AdditionalStaticVisualization

        #endregion

        #region HealthCareActionEnd

        /// <summary>
        /// Method that visualized the end of a health care action, patient is removed from
        /// the drawing system
        /// </summary>
        /// <param name="activity">Instance of health care action</param>
        /// <param name="time">Time the activity is ended</param>
        public void HealthCareActionEnd(Activity activity, DateTime time)
        {
            ActivityHealthCareAction <T> action = (ActivityHealthCareAction <T>)activity;

            if (action.ResourceSet.TreatmentFacility is EntityMultiplePatientTreatmentFacility)
            {
                return;
            }

            RemoveDrawingObjectPerEntity(action.Patient);
        } // end of HealthCareActionEnd
Beispiel #3
0
        } // end of PerformCustomRules

        #endregion

        #region PerformDisptatching

        /// <summary>
        /// Dispatches all requests with respect to FIFO rule, does not distinguish between
        /// different treatments (XRay, MRI, CT, Lab)
        /// </summary>
        /// <param name="startTime">Start time of the simulation model</param>
        /// <param name="simEngine">SimEngine responsible for simulation execution</param>
        /// <returns>False</returns>
        private bool PerformDisptatching(DateTime time, ISimulationEngine simEngine)
        {
            List <RequestSpecialFacilityAction> actionRequests = RAEL.Where(p => p.GetType() == typeof(RequestSpecialFacilityAction)).Cast <RequestSpecialFacilityAction>().ToList();

            while (actionRequests.Count > 0)
            {
                ResourceSet chosenResources;

                // Get action request Triage-FIFO
                RequestSpecialFacilityAction requestAction = PatientPriorityPlusFIFO <RequestSpecialFacilityAction, SpecialServiceActionTypeClass>(actionRequests);

                actionRequests.Remove(requestAction);

                if (!ChooseResourcesForAction(requestAction,
                                              out chosenResources))
                {
                    continue;
                } // enf if

                // Remove Request from RAEL list
                RemoveRequest(requestAction);
                EntityPatient patient = (EntityPatient)requestAction.Origin.First();

                ActivityHealthCareAction <SpecialServiceActionTypeClass> action = new ActivityHealthCareAction <SpecialServiceActionTypeClass>(
                    this,
                    InputData,
                    patient,
                    chosenResources,
                    requestAction.ActionType,
                    patient.SpecialFacilityPath);

                chosenResources.StopCurrentActivities(time, simEngine);
                patient.StopCurrentActivities(time, simEngine);
                action.StartEvent.Trigger(time, simEngine);
            } // end while

            return(false);
        } // end of PerformDisptatching
        }             // end of DrawHoldingEntity

        #endregion

        #region HealthCareActionEnd

        /// <summary>
        /// Method that visualized the end of a health care action, patient and other human resources are removed from
        /// the drawing system
        /// </summary>
        /// <param name="activity">Instance of health care action</param>
        /// <param name="time">Time the activity is ended</param>
        public void HealthCareActionEnd(Activity activity, DateTime time)
        {
            ActivityHealthCareAction <T> action = (ActivityHealthCareAction <T>)activity;

            if (action.ResourceSet.TreatmentFacility is EntityMultiplePatientTreatmentFacility)
            {
                return;
            }

            RemoveDrawingObjectPerEntity(action.Patient);

            if (action.ResourceSet.MainDoctor != null)
            {
                RemoveDrawingObjectPerEntity(action.ResourceSet.MainDoctor);
            } // end if

            if (action.ResourceSet.MainNurse != null)
            {
                RemoveDrawingObjectPerEntity(action.ResourceSet.MainNurse);
            } // end if

            if (action.ResourceSet.AssistingDoctors != null)
            {
                foreach (EntityDoctor ent in action.ResourceSet.AssistingDoctors)
                {
                    RemoveDrawingObjectPerEntity(ent);
                } // end foreach
            }     // end if

            if (action.ResourceSet.AssistingNurses != null)
            {
                foreach (EntityNurse ent in action.ResourceSet.AssistingNurses)
                {
                    RemoveDrawingObjectPerEntity(ent);
                } // end foreach
            }     // end if
        }         // end of HealthCareActionEnd
        } // 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

        #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 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