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); } }
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); }