Example #1
0
        public Appointment MakeAppointment(int doctorId, int patientId, DateTime date, string hour, string comment)
        {
            Patient patient = database.Patients.Find(patientId);
            Doctor  doctor  = database.Doctors.Find(doctorId);

            if (!doctorService.IsSlotStringValid(hour))
            {
                return(null);
            }

            int slot = SlotHelper.HourToSlot(hour);

            if (!doctorService.IsSlotAvailable(doctor, date, slot))
            {
                return(null);
            }

            Appointment appointment = new Appointment();

            appointment.Doctor     = doctor;
            appointment.Patient    = patient;
            appointment.Date       = date;
            appointment.StartSlot  = slot;
            appointment.EndSlot    = slot;
            appointment.Comment    = comment;
            appointment.RoomNumber = 555;

            database.Appointments.Add(appointment);
            database.SaveChanges();

            return(appointment);
        }
Example #2
0
        public string[] ComputeFreeSlots(Doctor doctor, DateTime date)
        {
            WorkingHours[] workingHours = GetWorkingHoursForDay(doctor, date);

            if (workingHours.Length == 0)
            {
                return(new string[0]);
            }

            List <int> freeSlots = GetFreeSlotsForDate(doctor, date);

            if (freeSlots.Count == 0)
            {
                return(new string[0]);
            }

            List <string> freeHours = new List <string>();

            foreach (int Slot in freeSlots)
            {
                freeHours.Add(SlotHelper.SlotToHour(Slot));
            }

            return(freeHours.ToArray());
        }
Example #3
0
 public string GetHoursStringForDayOfWeek(Doctor doctor, DayOfWeek dayOfWeek)
 {
     WorkingHours[] hours = GetWorkingHoursForDay(doctor, dayOfWeek);
     if (hours == null || hours.Length == 0)
     {
         return("Unavailable");
     }
     return(string.Join(", ",
                        hours.Select(h => SlotHelper.SlotToHour(h.StartSlot) + " - " + SlotHelper.SlotToHour(h.EndSlot))
                        ));
 }
Example #4
0
        public async Task <IActionResult> GetSlot(string date)
        {
            var user = await _userManager.GetUserAsync(User);

            var slots = SlotHelper.GetAllSlots();

            var counselorSlots = _context.Slots.Where(x => x.BaseUserId == user.Id && x.Date == DateTime.ParseExact(date, "MM/dd/yyyy", CultureInfo.InvariantCulture)).ToList();

            foreach (var slot in slots)
            {
                if (counselorSlots.Any(x => x.StartTime == slot.StartTime && x.EndTime == slot.EndTime))
                {
                    slot.IsAvailable = false;
                }
            }

            return(Ok(slots));
        }
        public ActionResult <List <Clinician> > GetWorkingClinician(string shopCode, DateTime date, string employeeTypeCodes = null)
        {
            string[] employeeTypes = null;
            if (!string.IsNullOrWhiteSpace(employeeTypeCodes))
            {
                employeeTypes = employeeTypeCodes.Split("|");
            }

            List <Clinician> Result = new List <Clinician>();
            var predicate           = PredicateBuilder.New <CM_S_EMPLOYEE>(true);

            if (employeeTypes == null)
            {
                employeeTypes = new string[] { "SRO" }
            }
            ;                                                           //{ "SRO", "AUD", "CSO" };


            List <string> AllowedTypes = new List <string>();

            employeeTypes.ToList().ForEach(E => AllowedTypes.Add("'" + E + "'"));

            StringBuilder SQL = new StringBuilder("SELECT DISTINCT E.* FROM CM_S_EMPLOYEE E");

            SQL.Append(" JOIN AG_B_EMPLOYEE_WORKING_HOURS WH ON E.SHOP_CODE=WH.SHOP_CODE AND E.EMPLOYEE_CODE=WH.EMPLOYEE_CODE");
            SQL.Append($" WHERE E.SHOP_CODE IN ('*', '{shopCode}') AND WH.DT_VALID <= '{date:yyyy-MM-dd}' AND E.EMPLOYEE_TYPE_CODE IN (" + string.Join(", ", AllowedTypes) + ")");
            SQL.Append(" AND (E.DT_START IS NULL OR E.DT_START <= CAST(GETDATE() AS DATE)) AND (E.DT_END IS NULL OR E.DT_END >= CAST(GETDATE() AS DATE))");

            List <CM_S_EMPLOYEE> employees = DBContext.CM_S_EMPLOYEE.FromSql(SQL.ToString()).ToList();
            List <AG_B_EMPLOYEE_WORKING_HOURS> workingHours = GetEmployeeValidWorkingHours(shopCode, employees, date);

            foreach (CM_S_EMPLOYEE item in employees)
            {
                if (workingHours.Any(E => E.EMPLOYEE_CODE == item.EMPLOYEE_CODE && SlotHelper.BynaryCheck(E, date)))
                {
                    Clinician model = EntityMapper.Map <Clinician, CM_S_EMPLOYEE>(DBContext, item);
                    Result.Add(model);
                }
            }

            return(Result);
        }
    }
Example #6
0
        public void SlotToHour_Full_Day_Slots_Should_Equal_DateTime_Reference()
        {
            // Arrange
            // 1 int = 15 minute slot; 96 slots = 24h
            const int slotCount = 96;

            string[] fullDayDateTimeReference = new string[slotCount];
            string[] fullDaySlots             = new string[slotCount];
            // Act
            for (int i = 0; i < slotCount; i++)
            {
                fullDaySlots[i]             = SlotHelper.SlotToHour(i);
                fullDayDateTimeReference[i] = DateTime.Now.Date.AddMinutes(i * 15).ToString("HH:mm");
            }
            // Assert
            for (int i = 0; i < slotCount; i++)
            {
                Assert.Equal(fullDaySlots[i], fullDayDateTimeReference[i]);
            }
        }
Example #7
0
        internal static bool Prefix(Equipment __instance, string slot, Pickupable pickupable, bool verbose, ref bool __result)
        {
            TechType techTypeInSlot = pickupable.GetTechType();

            if (SlotHelper.IsExtendedSeamothSlot(slot))
            {
                switch (techTypeInSlot)
                {
                case TechType.VehicleStorageModule:
                    // Do not allow storage modules in extended slots in Seamoth
                    __result = false;
                    ErrorMessage.AddMessage("Slot Extender:\nStorage module not allowed for this slot!");
                    return(false);

                case TechType.SeamothTorpedoModule:
                    // Do not allow torpedo modules in extended slots in Seamoth
                    __result = false;
                    ErrorMessage.AddMessage("Slot Extender:\nTorpedo module not allowed for this slot!");
                    return(false);
                }

                return(true);
            }

            if (techTypeInSlot == TechType.VehicleStorageModule && __instance.owner.name.Equals("Exosuit(Clone)"))
            {
                // Do not allow more than four storage modules in Exosuit slots
                if (__instance.GetCount(TechType.VehicleStorageModule) >= 4)
                {
                    __result = false;
                    ErrorMessage.AddMessage("Slot Extender:\nStorage module limit reached!");
                    return(false);
                }
            }

            return(true);
        }
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            var doctors = new[]
            {
                new
                {
                    Id             = 1,
                    Name           = "Dr",
                    Surname        = "Etker",
                    Specialization = "Kisiele",
                    Text           = "Very good doctor"
                },
                new
                {
                    Id             = 2,
                    Name           = "Dr",
                    Surname        = "Pepper",
                    Specialization = "Drinking",
                    Text           = "Not so good doctor"
                },
                new
                {
                    Id             = 3,
                    Name           = "Dr",
                    Surname        = "Dre",
                    Specialization = "Wrapping",
                    Text           = "Quite good doctor."
                }
            };
            var workingHours = new[] {
                new
                {
                    Id        = 1,
                    Date      = new DateTime(2019, 11, 11), // Monday
                    StartSlot = SlotHelper.HourToSlot("8:00"),
                    EndSlot   = SlotHelper.HourToSlot("16:00"),
                    DoctorId  = doctors[0].Id,
                },
                new
                {
                    Id        = 2,
                    Date      = new DateTime(2019, 11, 13), // Wednesday
                    StartSlot = SlotHelper.HourToSlot("7:30"),
                    EndSlot   = SlotHelper.HourToSlot("15:30"),
                    DoctorId  = doctors[0].Id,
                },
                new
                {
                    Id        = 3,
                    Date      = new DateTime(2019, 11, 13), // Wednesday
                    StartSlot = SlotHelper.HourToSlot("6:30"),
                    EndSlot   = SlotHelper.HourToSlot("14:30"),
                    DoctorId  = doctors[1].Id,
                }
            };

            modelBuilder.Entity <Doctor>().HasData(doctors);
            modelBuilder.Entity <WorkingHours>().HasData(workingHours);

            base.OnModelCreating(modelBuilder);
        }
Example #9
0
 internal static void Prefix(string slot, ref EquipmentType __result)
 {
     SlotHelper.ExpandSlotMapping();
 }
Example #10
0
 public List <string> GetFreeHoursForDate(Doctor doctor, DateTime date)
 {
     return(GetFreeSlotsForDate(doctor, date).Select(x => SlotHelper.SlotToHour(x)).ToList());
 }
Example #11
0
        internal static bool Prefix(Equipment __instance, string slot, Pickupable pickupable, bool verbose, ref bool __result)
        {
            TechType techTypeInSlot = pickupable.GetTechType();

            bool isExtendedSeamothSlot = SlotHelper.IsExtendedSeamothSlot(slot);

            if (isExtendedSeamothSlot && techTypeInSlot == TechType.SeamothTorpedoModule)
            {
                // Do not allow torpedo modules in extended slots in Seamoth
                __result = false;
                ErrorMessage.AddDebug("Slot Extender:\nTorpedo module not allowed for this slot!");
                return(false);
            }

            if (techTypeInSlot == TechType.VehicleStorageModule)
            {
                if (__instance.owner.GetComponent <Exosuit>())
                {
                    // Do not allow more than four storage modules in Exosuit slots
                    if (__instance.GetCount(TechType.VehicleStorageModule) >= 4)
                    {
                        __result = false;
                        ErrorMessage.AddDebug("Slot Extender:\nStorage module limit reached!");
                        return(false);
                    }
                }
                else if (SEConfig.STORAGE_SLOTS_OFFSET == 0)
                {
                    if (!isExtendedSeamothSlot)
                    {
                        return(true);
                    }

                    // Do not allow storage modules in extended slots in Seamoth
                    __result = false;
                    ErrorMessage.AddDebug("Slot Extender:\nStorage module not allowed for this slot!");
                    return(false);
                }
                else if (__instance.owner.GetComponent <SeaMoth>() is SeaMoth seamoth)
                {
                    int slotID = int.Parse(slot.Substring(13)) - 1;

                    if (slotID > 3 && (slotID < SEConfig.STORAGE_SLOTS_OFFSET || slotID > SEConfig.STORAGE_SLOTS_OFFSET + 3))
                    {
                        ErrorMessage.AddDebug("Slot Extender:\nStorage module not allowed for this slot!");
                        return(false);
                    }

                    // HACK: trying to swap one storage to another while drag, silently refusing because of ui problems
                    if (seamoth.GetSlotItem(slotID)?.item.GetTechType() == TechType.VehicleStorageModule)
                    {
                        __result = false;
                        return(false);
                    }

                    SeamothStorageInput storageInput = seamoth.storageInputs[slotID % SEConfig.STORAGE_SLOTS_OFFSET];
                    var fieldState = AccessTools.Field(typeof(SeamothStorageInput), "state");
                    __result = !(bool)fieldState.GetValue(storageInput); //already active

                    if (!__result && verbose)
                    {
                        int _slotID = (slotID < 4? slotID + SEConfig.STORAGE_SLOTS_OFFSET: slotID - SEConfig.STORAGE_SLOTS_OFFSET) + 1;
                        ErrorMessage.AddDebug($"Slot Extender:\nStorage module is already in the slot {_slotID}");
                    }

                    return(false);
                }
            }

            return(true);
        }
        protected List <AvailabilitySlot> GetAvailableSlots(string shopCode, IEnumerable <CM_S_EMPLOYEE> employees, DateTime date, string serviceCode, short slotSize, IEnumerable <AG_B_EMPLOYEE_WORKING_HOURS> workingHours)
        {
            const string defaultDescription = "Available";

            if (shopCode == null)
            {
                throw new ArgumentNullException(nameof(shopCode), "shopCode cannot be null");
            }
            if (serviceCode == null)
            {
                throw new ArgumentNullException(nameof(serviceCode), "ServiceCode cannot be null");
            }
            if (employees == null)
            {
                throw new ArgumentNullException(nameof(employees), "employees cannot be null");
            }
            if (workingHours == null)
            {
                throw new ArgumentNullException(nameof(workingHours), "workingHours cannot be null");
            }

            //Load special availability types
            string[] specialAvailabilityServiceCodes = FoxDataService.GetSpecialAvailabilityServiceCodes(shopCode);
            string[] unavailabilityServiceCodes      = FoxDataService.GetUnavailabilityServiceCodes(shopCode);

            List <AvailabilitySlot> Result  = new List <AvailabilitySlot>();
            AG_S_SERVICE            service = DBContext.AG_S_SERVICE.FirstOrDefault(E => E.SERVICE_CODE == serviceCode);

            if (service == null)
            {
                throw new ArgumentException($"No service found for service code: {serviceCode}");
            }

            if (employees.Any())
            {
                List <AvailabilitySlot> availableSlots = new List <AvailabilitySlot>();

                //Add slots for each employee
                foreach (CM_S_EMPLOYEE employee in employees)
                {
                    foreach (AG_B_EMPLOYEE_WORKING_HOURS workingHour in workingHours.Where(E => E.EMPLOYEE_CODE == employee.EMPLOYEE_CODE && E.DT_VALID <= date && SlotHelper.BynaryCheck(E, date)).OrderByDescending(E => E.DT_VALID).OrderBy(E => E.START_HOUR))
                    {
                        //Create standard availability slots
                        availableSlots.AddRange(SlotHelper.CreateSlots(date, workingHour.START_HOUR.GetValueOrDefault(), workingHour.END_HOUR.GetValueOrDefault(), slotSize, employee.EMPLOYEE_CODE, employee.EMPLOYEE_DESCR, defaultDescription, service.BACKGROUND_COLOR.GetValueOrDefault(), service.FOREGROUND_COLOR.GetValueOrDefault()));
                    }
                }

                string[] employeeCodes = employees.Select(E => E.EMPLOYEE_CODE).Distinct().ToArray();

                //Add special availability
                AG_B_APPOINTMENT[] specials = DBContext.AG_B_APPOINTMENT.Where(E => E.APPOINTMENT_SHOP_CODE == shopCode && employeeCodes.Contains(E.EMPLOYEE_CODE) && AllowedAppointmentStatus.Contains(E.STATUS_CODE) && specialAvailabilityServiceCodes.Contains(E.AG_S_SERVICE.SERVICE_TYPE_CODE) && E.DT_APPOINTMENT.Date == date.Date).ToArray();
                foreach (AG_B_APPOINTMENT special in specials)
                {
                    CM_S_EMPLOYEE           employee     = employees.FirstOrDefault(E => E.EMPLOYEE_CODE == special.EMPLOYEE_CODE);
                    List <AvailabilitySlot> specialSlots = SlotHelper.CreateSlots(special.DT_APPOINTMENT.Date, special.DT_APPOINTMENT.TimeOfDay, special.DT_APPOINTMENT.AddMinutes(special.DURATION.GetValueOrDefault()).TimeOfDay, slotSize, employee?.EMPLOYEE_CODE, employee?.EMPLOYEE_DESCR, defaultDescription, service.BACKGROUND_COLOR.GetValueOrDefault(), service.FOREGROUND_COLOR.GetValueOrDefault());
                    foreach (AvailabilitySlot slot in specialSlots)
                    {
                        if (!availableSlots.Contains(slot))
                        {
                            availableSlots.Add(slot);
                        }
                    }
                }
                //Get already booked slots
                AG_B_APPOINTMENT[] appointments = DBContext.AG_B_APPOINTMENT.Where(E => E.APPOINTMENT_SHOP_CODE == shopCode && AllowedAppointmentStatus.Contains(E.STATUS_CODE) && employeeCodes.Contains(E.EMPLOYEE_CODE) && !specialAvailabilityServiceCodes.Contains(E.AG_S_SERVICE.SERVICE_TYPE_CODE) && E.DT_APPOINTMENT.Date == date.Date).ToArray();
                //Get special unavailability
                AG_B_APPOINTMENT[]      unavailabilties = DBContext.AG_B_APPOINTMENT.Where(E => E.APPOINTMENT_SHOP_CODE == shopCode && AllowedAppointmentStatus.Contains(E.STATUS_CODE) && employeeCodes.Contains(E.EMPLOYEE_CODE) && unavailabilityServiceCodes.Contains(E.AG_S_SERVICE.SERVICE_TYPE_CODE) && E.DT_APPOINTMENT.Date == date.Date).ToArray();
                List <AG_B_APPOINTMENT> busySlots       = new List <AG_B_APPOINTMENT>(appointments);
                busySlots.AddRange(unavailabilties);
                //Remove busy slots
                if (busySlots.Any())
                {
                    foreach (AG_B_APPOINTMENT appointment in busySlots)
                    {
                        availableSlots.RemoveAll(E => E.ResourceId == appointment.EMPLOYEE_CODE &&
                                                 ((appointment.DT_APPOINTMENT >= E.Start && appointment.DT_APPOINTMENT < E.End) ||
                                                  (appointment.DT_APPOINTMENT.AddMinutes(appointment.DURATION.GetValueOrDefault()) > E.Start && appointment.DT_APPOINTMENT.AddMinutes(appointment.DURATION.GetValueOrDefault()) < E.End) ||
                                                  (appointment.DT_APPOINTMENT <= E.Start && appointment.DT_APPOINTMENT.AddMinutes(appointment.DURATION.GetValueOrDefault()) > E.End)));
                    }
                }

                if (employeeCodes.Any() && availableSlots.Any())
                {
                    Result.AddRange(availableSlots.OrderBy(E => E.ResourceId).OrderBy(E => E.Start).Distinct(new AvailabilitySlotComparer()));
                }
                else
                {
                    Result.AddRange(availableSlots);
                }
            }

            return(Result);
        }