/// <summary> /// Moves patients from the PatientQueue to the either the IntesiveCareUnit or Sanatorium. Prioritizes by high severity first then high age. /// </summary> public void ThreadTwo() { lock (krankenhausLock) { using (var db = new KrankenhausContext()) { //Records the number of patient moves for KrankenhausMovedPatientsEventArgs int numberOfPatientsAddedToICU = 0; int numberOfPatientsAddedToICUFromQueue = 0; int numberOfPatientsAddedToICUFromSanatorium = 0; int numberOfPatietnsAddedToSanatoriumFromQueue = 0; var freeICUBeds = db.IntesiveCareUnit.Where(ICU => ICU.AvailableBed == true).ToList(); var patientsToRelocateFromQueueQuery = db.Patients.Where(P => P.PatientQueueID != null && P.ConditionLevel != 10 && P.ConditionLevel != 0); var patientsToRelocateFromSanatoriumQuery = db.Patients.Where(P => P.SanatoriumID != null && P.ConditionLevel != 10 && P.ConditionLevel != 0); var patientsToRelocate = patientsToRelocateFromSanatoriumQuery.Concat(patientsToRelocateFromQueueQuery).ToList(); patientsToRelocate = patientsToRelocate.OrderByDescending(P => P.ConditionLevel).ThenByDescending(P => P.Age).ToList(); if (freeICUBeds.Count != 0 && patientsToRelocate.Count != 0) { //Makes sure that out of range index exception doesn't appear when patients are fewer than number of free beds int maxNumberOfPatientsAssignableToICU = freeICUBeds.Count <= patientsToRelocate.Count ? freeICUBeds.Count : patientsToRelocate.Count; for (int i = 0; i < maxNumberOfPatientsAssignableToICU; i++) { int?intToQueryAgainstPatientQueue = patientsToRelocate[i].PatientQueueID; int?intToQueryAgainstSanatorium = patientsToRelocate[i].SanatoriumID; var patientInQueue = db.PatientQueue.Where(PQ => PQ.PatientQueueID == intToQueryAgainstPatientQueue).FirstOrDefault <PatientQueue>(); var patientsSanatoriumBed = db.Sanatorium.FirstOrDefault <Sanatorium>(S => S.SanatoriumID == intToQueryAgainstSanatorium); if (patientInQueue != null) { db.PatientQueue.Remove(patientInQueue); patientsToRelocate[i].AssingedToHopsitalBed = DateTime.UtcNow; db.SaveChanges(); freeICUBeds[i].AvailableBed = false; patientsToRelocate[i].IntensiveCareUnitID = freeICUBeds[i].IntensiveCareUnitID; patientsToRelocate[i].PatientQueueID = null; numberOfPatientsAddedToICUFromQueue++; numberOfPatientsAddedToICU++; db.SaveChanges(); } else if (patientsSanatoriumBed != null) { patientsSanatoriumBed.Patient = null; patientsSanatoriumBed.AvailableBed = true; freeICUBeds[i].AvailableBed = false; patientsToRelocate[i].IntensiveCareUnitID = freeICUBeds[i].IntensiveCareUnitID; patientsToRelocate[i].SanatoriumID = null; numberOfPatientsAddedToICUFromSanatorium++; numberOfPatientsAddedToICU++; db.SaveChanges(); } db.SaveChanges(); } if (numberOfPatientsAddedToICU > 0) { patientsToRelocate.RemoveRange(0, numberOfPatientsAddedToICU); } } var freeSanatoriumBeds = (from S in db.Sanatorium where S.AvailableBed == true select S).ToList(); //Removes all patiens who are already assinged to a bed i.e. a Sanatorium bed. patientsToRelocate.RemoveAll(P => P.AssingedToHopsitalBed != null); if (freeSanatoriumBeds.Count != 0 && patientsToRelocate.Count != 0) { //Makes sure that out of range index exception doesn't appear. int maxNumberOfPatientsAssignableToSanatorium = freeSanatoriumBeds.Count <= patientsToRelocate.Count ? freeSanatoriumBeds.Count : patientsToRelocate.Count; for (int i = 0; i < maxNumberOfPatientsAssignableToSanatorium; i++) { var intToQueryAgaint = patientsToRelocate[i].PatientQueueID; var patientInQueue = db.PatientQueue.FirstOrDefault <PatientQueue>(PQ => PQ.PatientQueueID == intToQueryAgaint); if (patientInQueue != null) { db.PatientQueue.Remove(patientInQueue); db.SaveChanges(); freeSanatoriumBeds[i].AvailableBed = false; patientsToRelocate[i].AssingedToHopsitalBed = DateTime.UtcNow; patientsToRelocate[i].Sanatorium = freeSanatoriumBeds[i]; patientsToRelocate[i].PatientQueue = null; numberOfPatietnsAddedToSanatoriumFromQueue++; } db.SaveChanges(); } } db.SaveChanges(); if (numberOfPatientsAddedToICUFromQueue + numberOfPatientsAddedToICUFromSanatorium + numberOfPatietnsAddedToSanatoriumFromQueue > 0) { PatientsMoved?.Invoke(this, new KrankenhausMovedPatientsEventArgs() { NumberOfPatientsFromQueueToSanatorium = numberOfPatietnsAddedToSanatoriumFromQueue, NumberOfPatientsFromQueueToICU = numberOfPatientsAddedToICUFromQueue, NumberOfPatientsFromSanatoriumToICU = numberOfPatientsAddedToICUFromSanatorium }); } } } }
/// <summary> /// Removes patients from ICU and sanatorium to AfterLife or Discharged depending on their status /// </summary> public void ThreadFour() { lock (krankenhausLock) { using (var db = new KrankenhausContext()) { int numberOfPatientsToAfterLife = 0; int numberOfPatientsDischarged = 0; var patientsToRelocate = db.Patients.Where(P => P.ConditionLevel == 0 && P.DischargedID == null || P.ConditionLevel == 10 && P.AfterLifeID == null).ToList(); var discharged = db.Dischargeds.FirstOrDefault(); var afterLifte = db.AfterLives.FirstOrDefault(); for (int i = 0; i < patientsToRelocate.Count; i++) { if (patientsToRelocate[i].PatientQueueID != null) { int?patientQueueIDToQueryAgainst = patientsToRelocate[i].PatientQueueID; var patientQueue = db.PatientQueue.Where(PQ => PQ.PatientQueueID == patientQueueIDToQueryAgainst).FirstOrDefault(); db.PatientQueue.Remove(patientQueue); } else if (patientsToRelocate[i].SanatoriumID != null) { int?patientSanatoriumIDToQueryAgainst = patientsToRelocate[i].SanatoriumID; var sanatoriumBed = db.Sanatorium.Where(S => S.SanatoriumID == patientSanatoriumIDToQueryAgainst).FirstOrDefault(); patientsToRelocate[i].SanatoriumID = null; sanatoriumBed.AvailableBed = true; } else if (patientsToRelocate[i].IntensiveCareUnitID != null) { int?patientICUIDToQueryAgainst = patientsToRelocate[i].IntensiveCareUnitID; var iCUBed = db.IntesiveCareUnit.Where(ICU => ICU.IntensiveCareUnitID == patientICUIDToQueryAgainst).FirstOrDefault(); patientsToRelocate[i].IntensiveCareUnitID = null; iCUBed.AvailableBed = true; } if (patientsToRelocate[i].ConditionLevel == 10) { patientsToRelocate[i].Afterlife = afterLifte; numberOfPatientsToAfterLife++; } else if (patientsToRelocate[i].ConditionLevel == 0) { patientsToRelocate[i].Discharged = discharged; numberOfPatientsDischarged++; } patientsToRelocate[i].SignedOut = DateTime.UtcNow; db.SaveChanges(); } if (numberOfPatientsDischarged + numberOfPatientsToAfterLife != 0) { PatientsMoved?.Invoke(this, new KrankenhausMovedPatientsEventArgs() { NumberOfDeceasedPatients = numberOfPatientsToAfterLife, NumberOfRecoveredPatients = numberOfPatientsDischarged }); } } } }