} // 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
Beispiel #2
0
        } // 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
Beispiel #3
0
 /// <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
Beispiel #5
0
        } // 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
Beispiel #6
0
        } // 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