public IList <Schedule> FilterAndGetValidSchedules(ServiceSupply serviceSupply, List <Schedule> schedules, ShiftCenterService healthService)
        {
            var validSchedules = new List <Schedule>();

            // Policlinic Booking Restriction Hours
            var BRH = serviceSupply.ShiftCenter.BookingRestrictionHours;

            var startReservationDate = serviceSupply.StartReservationDate > DateTime.Now ? serviceSupply.StartReservationDate : DateTime.Now;
            var lastDay = startReservationDate.AddDays(serviceSupply.ShiftCenter.ActiveDaysAhead);

            var startPoint       = serviceSupply.ReservationRangeStartPoint;
            var endPoint         = serviceSupply.ReservationRangeEndPointDiffMinutes;
            var endPointPosition = serviceSupply.ReservationRangeEndPointPosition;

            foreach (var schedule in schedules)
            {
                if (schedule.Start_DateTime.Date < startReservationDate.Date || schedule.Start_DateTime.Date > lastDay.Date)
                {
                    continue;
                }
                //===========================================================
                //برای روز آخر میخواهیم که نوبت دهی از ساعت 8 به بعد شروع شود
                if (schedule.Start_DateTime.Date == lastDay.Date)
                {
                    var reservationStartTimeForLastDay = DateTime.Parse(DateTime.Now.ToShortDateString() + " 08:00:00");
                    if (DateTime.Now < reservationStartTimeForLastDay)
                    {
                        continue;
                    }
                }
                //===========================================================
                //محدوده ای برای نوبت دهی در نظر گرفته نشده است
                if (startPoint == null && endPoint == null)
                {
                    if ((schedule.Start_DateTime - DateTime.Now).TotalHours <= BRH)
                    {
                        continue;
                    }
                }
                else
                {
                    //شروع نوبت دهی همزمان با شروع ویزیت
                    if (startPoint == 0)
                    {
                        if (DateTime.Now < schedule.Start_DateTime)
                        {
                            continue;
                        }
                    }
                    //Diff Minutes before visit time
                    if (startPoint > 0)
                    {
                        if ((schedule.Start_DateTime - DateTime.Now).TotalMinutes > startPoint)
                        {
                            continue;
                        }
                    }
                    //پایان نوبت دهی تا انتهای زمان ویزیت
                    if (endPoint == -1)
                    {
                        if (DateTime.Now > schedule.End_DateTime)
                        {
                            continue;
                        }
                    }
                    //پایان نوبت دهی تا شروع زمان ویزیت
                    if (endPoint == 0)
                    {
                        if (DateTime.Now >= schedule.Start_DateTime)
                        {
                            continue;
                        }
                    }
                    //پایان نوبت دهی مدتی قبل یا بعد از شروع ویزیت
                    if (endPoint > 0)
                    {
                        var endPointTime = DateTime.Now;
                        //پایان قبل از شروع ویزیت
                        if (endPointPosition == Position.BEFORE)
                        {
                            endPointTime = schedule.Start_DateTime.AddMinutes(-endPoint);
                        }
                        else if (endPointPosition == Position.AFTER)
                        {
                            endPointTime = schedule.Start_DateTime.AddMinutes(endPoint);
                        }

                        if (DateTime.Now > endPointTime)
                        {
                            continue;
                        }
                    }
                }

                //Check remained free appoints for polyclinic health service
                var appints = healthService != null ?
                              (from a in serviceSupply.Appointments
                               where (a.ShiftCenterService == null || a.ShiftCenterServiceId == healthService.Id) &&
                               a.Start_DateTime.Date == schedule.Start_DateTime.Date &&
                               a.Start_DateTime >= schedule.Start_DateTime &&
                               a.End_DateTime <= schedule.End_DateTime &&
                               !a.IsDeleted
                               select a).ToList()
                    :
                              (from a in serviceSupply.Appointments
                               where a.Start_DateTime.Date == schedule.Start_DateTime.Date &&
                               a.Start_DateTime >= schedule.Start_DateTime &&
                               a.End_DateTime <= schedule.End_DateTime &&
                               !a.IsDeleted
                               select a).ToList();

                if (schedule.MaxCount - appints.Count <= 0)
                {
                    continue;
                }

                validSchedules.Add(schedule);
            }

            return(validSchedules.Count > 0 ? validSchedules : null);
        }
        /// <summary>
        /// این متد برای یک تاریخ مشخص همه بازه های زمانی که پزشک می تواند سرویس ارایه دهد را محاسبه می کند
        /// بازه های زمانی غیراستراحت را محاسبه می کند
        /// </summary>
        /// <param name="supply">ارایه</param>
        /// <param name="Date">تاریخ موردنظر</param>
        /// <returns>لیست بازه های زمانی با قابلیت ارایه سرویس</returns>
        public IEnumerable <TimePeriodModel> Get_Non_Break_Times(ServiceSupply supply, DateTime Date, ShiftCenterService polyclinicHealthService, bool applyLimits = true)
        {
            IList <Schedule> schedules;

            if (applyLimits)
            {
                schedules = GetSchedulesByDate(supply, Date, polyclinicHealthService);
            }
            else
            {
                schedules = GetSchedulesByDateWithoutFilter(supply, Date, polyclinicHealthService);
            }

            if (schedules != null && schedules.Count > 0)
            {
                var nonBreaks = new List <TimePeriodModel>();
                var _duration = supply.Duration;

                foreach (var item in schedules)
                {
                    if (item.MaxCount > 0)
                    {
                        var appointsForSchedule = supply.Appointments.Where(a => a.Start_DateTime >= item.Start_DateTime && a.End_DateTime <= item.End_DateTime && (a.ShiftCenterService == null || (polyclinicHealthService != null && a.ShiftCenterServiceId == polyclinicHealthService.Id)) && !a.IsDeleted);
                        if (appointsForSchedule.Count() > 0)
                        {
                            var firstAppoint = appointsForSchedule.FirstOrDefault();
                            _duration = (int)(firstAppoint.End_DateTime - firstAppoint.Start_DateTime).TotalMinutes;
                        }
                        else
                        {
                            var _maxCount = item.MaxCount;
                            var manualSchedulesForOtherHealthServices = (from ms in supply.Schedules
                                                                         where ms.Start_DateTime == item.Start_DateTime &&
                                                                         ms.End_DateTime == item.End_DateTime &&
                                                                         ms.ShiftCenterServiceId != item.ShiftCenterServiceId
                                                                         select ms).ToList();
                            if (manualSchedulesForOtherHealthServices.Count > 0)
                            {
                                foreach (var ms in manualSchedulesForOtherHealthServices)
                                {
                                    _maxCount += ms.MaxCount;
                                }
                            }
                            else
                            {
                                var shift = Utils.GetScheduleShift(item.Start_DateTime, item.End_DateTime);

                                var usualSchedulesForOtherHelathServices = (from us in supply.UsualSchedulePlans
                                                                            where us.Shift == shift &&
                                                                            us.DayOfWeek == item.Start_DateTime.DayOfWeek &&
                                                                            us.StartTime == item.Start_DateTime.ToShortTimeString() &&
                                                                            us.EndTime == item.End_DateTime.ToShortTimeString() &&
                                                                            us.ShiftCenterServiceId != item.ShiftCenterServiceId
                                                                            select us).ToList();

                                foreach (var us in usualSchedulesForOtherHelathServices)
                                {
                                    _maxCount += us.MaxCount;
                                }
                            }
                            _duration = (int)Math.Ceiling(((item.End_DateTime - item.Start_DateTime).TotalMinutes) / _maxCount);
                        }
                    }

                    nonBreaks.Add(new TimePeriodModel
                    {
                        StartDateTime = item.Start_DateTime,
                        EndDateTime   = item.End_DateTime,
                        Duration      = _duration,
                        Type          = TimePeriodType.Empty
                    });
                }

                return(nonBreaks.OrderBy(x => x.StartDateTime));
            }
            return(null);
        }
Exemple #3
0
        /// <summary>
        /// مشخص می کند که آیا بازه زمانی موردنظر برای ارایه خالی است یا نه؟
        /// </summary>
        /// <param name="serviceSupply">ارایه</param>
        /// <param name="datetime">تاریخ و زمان</param>
        /// <returns></returns>
        public bool IsEmptyTimePeriod(ServiceSupply serviceSupply, TimePeriodModel timePriod, ShiftCenterService polyclinicHealthService)
        {
            var founded = Calculate_Empty_TimePeriods(serviceSupply, timePriod.StartDateTime, polyclinicHealthService)
                          .Where(x => x.StartDateTime == timePriod.StartDateTime && x.EndDateTime == timePriod.EndDateTime).FirstOrDefault();

            if (founded == null)
            {
                return(false);
            }

            return(true);
        }
Exemple #4
0
        public bool IsAvailableEmptyTimePeriod(int serviceSupplyId, DateTime StartDateTime, DateTime EndDateTime, ShiftCenterService polyclinicHealthService)
        {
            if (StartDateTime.ToShortDateString() != EndDateTime.ToShortDateString())
            {
                return(false);
            }
            if (StartDateTime >= EndDateTime)
            {
                return(false);
            }

            var serviceSupply = _serviceSupplyService.GetServiceSupplyById(serviceSupplyId);

            if (serviceSupply == null)
            {
                throw new EntityNotFoundException();
            }

            var founded = Calculate_Available_Empty_TimePeriods_By_Percent(serviceSupply, StartDateTime, polyclinicHealthService)
                          .Where(x => x.StartDateTime == StartDateTime &&
                                 x.EndDateTime == EndDateTime).FirstOrDefault();

            if (founded == null)
            {
                return(false);
            }

            return(true);
        }
Exemple #5
0
        /// <summary>
        /// از تاریخ و ساعت مشخص شده شروع می کند و اولین بازه زمانی خالی را برای ارایه موردنظر پیدا می کند
        /// </summary>
        /// <param name="serviceSupply">ارایه موردنظر</param>
        /// <param name="From_DateTime">تاریخ</param>
        /// <param name="StartTime">ساعت</param>
        /// <returns></returns>
        public TimePeriodModel Find_First_Empty_TimePeriod_From_DateTime(ServiceSupply serviceSupply, DateTime from, ShiftCenterService polyclinicHealthService)
        {
            if (!serviceSupply.IsAvailable)
            {
                return(null);
            }

            var availableEmptyPeriodsByPercent = new List <TimePeriodModel>();

            var startReservationDate = serviceSupply.StartReservationDate > from ? serviceSupply.StartReservationDate : from;
            var lastDay = startReservationDate.AddDays(serviceSupply.ShiftCenter.ActiveDaysAhead);

            for (var dt = startReservationDate.Date; dt <= lastDay.Date; dt = dt.AddDays(1))
            {
                var schedules = _serviceSupplyManager.GetSchedulesByDate(serviceSupply, dt, polyclinicHealthService);
                if (schedules != null && schedules.Count > 0)
                {
                    foreach (var schedule in schedules)
                    {
                        var result = Calculate_Available_Empty_TimePeriods_By_Percent(serviceSupply, schedule.Start_DateTime, polyclinicHealthService);

                        if (result != null && result.Count() > 0)
                        {
                            return(result.FirstOrDefault(x => x.StartDateTime >= DateTime.Now));
                        }
                    }
                }
            }

            return(null);
        }
Exemple #6
0
        /// <summary>
        /// از یک تاریخ تا تاریخ دیگری اولین بازه زمانی خالی را برای ارایه پیدا می کند
        /// </summary>
        /// <param name="serviceSupply"></param>
        /// <param name="From_DateTime"></param>
        /// <param name="To_DateTime"></param>
        /// <returns></returns>
        public TimePeriodModel Find_First_Empty_TimePeriod_FromDateTime_ToDateTime(ServiceSupply serviceSupply, DateTime From_DateTime, DateTime To_DateTime, ShiftCenterService polyclinicHealthService)
        {
            var BRH = serviceSupply.ShiftCenter.BookingRestrictionHours;

            if (From_DateTime >= To_DateTime)
            {
                throw new Exception(Messages.ValidEmptyTimePeriodNotFound);
            }

            if (From_DateTime < DateTime.Now)
            {
                throw new Exception(Messages.ValidEmptyTimePeriodNotFound);
            }


            for (var dt = From_DateTime; dt <= To_DateTime || dt.ToShortDateString().Trim() == To_DateTime.ToShortDateString().Trim(); dt = dt.AddDays(1))
            {
                var schedules = _serviceSupplyManager.GetSchedulesByDate(serviceSupply, dt, polyclinicHealthService);
                foreach (var schedule in schedules)
                {
                    //اگر در روز مورد نظر وضعیت زمانبندی برابر در دسترس باشد
                    if (schedule != null && (schedule.Start_DateTime - DateTime.Now).TotalHours > BRH && schedule.IsAvailable)
                    {
                        var timePeriods = Calculate_Available_Empty_TimePeriods_By_Percent(serviceSupply, dt, polyclinicHealthService).ToList();
                        foreach (var item in timePeriods)
                        {
                            if (item != null && (item.StartDateTime >= From_DateTime && item.EndDateTime <= To_DateTime))
                            {
                                return(item);
                            }
                        }
                    }
                }
            }

            return(null);
        }
Exemple #7
0
        /// <summary>
        /// از همین الان شروع می کند و اولین بازه زمانی خالی را برای ارایه پیدا می کند و بر می گرداند
        /// </summary>
        /// <param name="serviceSupply">ارایه موردنظر</param>
        /// <returns></returns>
        public TimePeriodModel FindFirstEmptyTimePeriodFromNow(ServiceSupply serviceSupply, ShiftCenterService polyclinicHealthService)
        {
            if (!serviceSupply.IsAvailable)
            {
                return(null);
            }

            var startReservationDate = serviceSupply.StartReservationDate > DateTime.Now ? serviceSupply.StartReservationDate : DateTime.Now;
            var lastDay = startReservationDate.AddDays(serviceSupply.ShiftCenter.ActiveDaysAhead);

            for (var dt = startReservationDate.Date; dt <= lastDay.Date; dt = dt.AddDays(1))
            {
                //var schedules = GetSchedulesByDate(serviceSupply, dt, polyclinicHealthService);
                //if (schedules != null && schedules.Count > 0)
                //{
                //    foreach (var schedule in schedules)
                //    {
                var result = Calculate_Available_Empty_TimePeriods_By_Percent(serviceSupply, dt, polyclinicHealthService);

                if (result != null && result.Count() > 0)
                {
                    return(result.FirstOrDefault(x => x.StartDateTime >= DateTime.Now));
                }
                //}
                //}
            }

            return(null);
        }
Exemple #8
0
 /// <summary>
 /// همه بازه های زمانی خالی مربوط به ارایه در تاریخ مشخص شده را بر می گرداند
 /// </summary>
 /// <param name="serviceSupply">ارایه موردنظر</param>
 /// <param name="Date">تاریخ</param>
 /// <returns></returns>
 public IEnumerable <TimePeriodModel> Calculate_Empty_TimePeriods(ServiceSupply serviceSupply, DateTime Date, ShiftCenterService polyclinicHealthService)
 {
     return(Calculate_All_TimePeriods(serviceSupply, Date, polyclinicHealthService).Where(x => x.Type == TimePeriodType.Empty));
 }
Exemple #9
0
        public IEnumerable <TimePeriodModel> CalculateFinalBookableTimePeriods(ServiceSupply serviceSupply, DateTime Date, ShiftCenterService polyclinicHealthService)
        {
            var allTimePeriods = Calculate_All_TimePeriods(serviceSupply, Date, polyclinicHealthService);

            if (allTimePeriods != null && allTimePeriods.Count() > 0)
            {
                var finalBookables = allTimePeriods.Where(x => x.Type == TimePeriodType.InProgressAppointment && x.StartDateTime >= DateTime.Now).OrderBy(x => x.StartDateTime);

                return(finalBookables);
            }

            return(null);
        }
Exemple #10
0
        /// <summary>
        /// در تاریخ موردنظر اولین بازه زمانی خالی را برای ارایه موردنظر بدست می آورد
        /// </summary>
        /// <param name="serviceSupply">ارایه موردنظر</param>
        /// <param name="Date">تاریخ</param>
        /// <returns></returns>
        public TimePeriodModel FindFirstEmptyTimePeriodInDate(ServiceSupply serviceSupply, DateTime Date, ShiftCenterService polyclinicHealthService)
        {
            var emptyPeriods = Calculate_Available_Empty_TimePeriods_By_Percent(serviceSupply, Date, polyclinicHealthService);

            if (emptyPeriods != null && emptyPeriods.Count() > 0)
            {
                return(emptyPeriods.FirstOrDefault());
            }

            return(null);
        }
Exemple #11
0
        /// <summary>
        /// این متد لیست همه بازه های زمانی که قابلیت رزرو دارند را برای یک ارایه در یک تاریخ محاسبه و بر می گرداند
        /// </summary>
        /// <param name="serviceSupply">ارایه موردنظر</param>
        /// <param name="Date">تاریخ - روز</param>
        /// <returns>لیست بازه های زمانی دارای قابلیت رزرو</returns>
        public IList <TimePeriodModel> Calculate_Bookable_TimePeriods(ServiceSupply serviceSupply, DateTime Date, ShiftCenterService polyclinicHealthService)
        {
            var BookableTimes = new List <TimePeriodModel>();

            var nonBreakTimes = _serviceSupplyManager.Get_Non_Break_Times(serviceSupply, Date, polyclinicHealthService);

            if (nonBreakTimes != null && nonBreakTimes.Count() >= 1)
            {
                foreach (var item in nonBreakTimes)
                {
                    for (var dt = item.StartDateTime; dt <= item.EndDateTime; dt = dt.AddMinutes(item.Duration))
                    {
                        var tpEndTime = dt.AddMinutes(item.Duration);
                        if (tpEndTime <= item.EndDateTime)
                        {
                            BookableTimes.Add(new TimePeriodModel
                            {
                                StartDateTime = dt,
                                EndDateTime   = tpEndTime,
                                Duration      = item.Duration,
                                Type          = TimePeriodType.Empty
                            });
                        }
                        else
                        {
                            var tpStartTime = tpEndTime.AddMinutes(-item.Duration);

                            if (tpStartTime > item.StartDateTime && tpStartTime < item.EndDateTime)
                            {
                                BookableTimes.Add(new TimePeriodModel
                                {
                                    StartDateTime = tpStartTime,
                                    EndDateTime   = item.EndDateTime,
                                    Duration      = item.Duration,
                                    Type          = TimePeriodType.Empty
                                });
                            }
                        }
                    }
                }
                return(BookableTimes.OrderBy(x => x.StartDateTime).ToList());
            }

            return(null);
        }
Exemple #12
0
        /// <summary>
        /// محاسبه بازه های زمانی در دسترس و محدود کردن تعداد آنها بر اساس درصد رزرو آنلاین
        /// </summary>
        /// <param name="serviceSupply"></param>
        /// <param name="Date"></param>
        /// <returns></returns>
        public IEnumerable <TimePeriodModel> Calculate_Available_Empty_TimePeriods_By_Percent(ServiceSupply serviceSupply, DateTime Date, ShiftCenterService polyclinicHealthService)
        {
            if (!serviceSupply.IsAvailable)
            {
                return(null);
            }

            var finalPercentPeriods = new List <TimePeriodModel>();

            var allTimePeriods = Calculate_All_TimePeriods(serviceSupply, Date, polyclinicHealthService);

            if (allTimePeriods != null && allTimePeriods.Count() > 0)
            {
                if (serviceSupply.OnlineReservationPercent < 100)
                {
                    var schedules = _serviceSupplyManager.GetSchedulesByDate(serviceSupply, Date, polyclinicHealthService);
                    foreach (var schedule in schedules)
                    {
                        for (var dt = schedule.Start_DateTime; dt <= schedule.End_DateTime; dt = dt.AddHours(1))
                        {
                            var hourPeriods = allTimePeriods.Where(x => x.StartDateTime >= dt && x.EndDateTime <= dt.AddHours(1)).ToList();
                            if (hourPeriods != null && hourPeriods.Count >= 1)
                            {
                                var hourPeriodsByPercentCount = serviceSupply.OnlineReservationPercent * hourPeriods.Count / 100;
                                if (hourPeriodsByPercentCount > 0)
                                {
                                    for (var i = 0; i < hourPeriodsByPercentCount; i++)
                                    {
                                        finalPercentPeriods.Add(hourPeriods.ElementAt(i));
                                    }
                                }
                            }
                        }
                        return(finalPercentPeriods.Where(x => x.Type == TimePeriodType.Empty && x.StartDateTime >= DateTime.Now).OrderBy(x => x.StartDateTime));
                    }
                }
                return(allTimePeriods.Where(x => x.Type == TimePeriodType.Empty && x.StartDateTime >= DateTime.Now).OrderBy(x => x.StartDateTime));
            }
            return(null);
        }
Exemple #13
0
 /// <summary>
 /// همه بازه های زمانی در دسترس و قابل استفاده را بر می گرداند
 /// </summary>
 /// <param name="serviceSupply">ارایه موردنظر</param>
 /// <param name="Date">تاریخ</param>
 /// <returns>لیست بازه های زمانی در دسترس و قابل استفاده</returns>
 public IEnumerable <TimePeriodModel> Calculate_Available_Empty_TimePeriods(ServiceSupply serviceSupply, DateTime Date, ShiftCenterService polyclinicHealthService)
 {
     return
         (Calculate_Empty_TimePeriods(serviceSupply, Date, polyclinicHealthService)
          .Where(x => x.StartDateTime >= DateTime.Now));
 }
        public IList <Schedule> GetSchedulesByDateWithoutFilter(ServiceSupply serviceSupply, DateTime Date, ShiftCenterService polyClinicHealthService)
        {
            //بررسی می کنیم که آیا زمانبندی دستی  و منحصربفرد برای تاریخ موردنظر تعریف شده است یا نه؟
            var specialSchedules = serviceSupply.Schedules.Where(x => x.Start_DateTime.Date == Date.Date && x.ShiftCenterServiceId == polyClinicHealthService.Id && x.IsAvailable).ToList();

            if (specialSchedules.Count > 0)
            {
                return(specialSchedules);
            }
            else
            {
                //باید مطمین شویم که تاریخ موردنظر جزو روزهای تعطیل نمی باشد
                //var isVocation = IsSystemVocationDay(Date) || serviceSupply.PoliClinic.PoliClinicVocationDays.Count(x => x.Date.Date == Date.Date) >= 1;

                if (/*IsSystemVocationDay(Date) ||*/ IsLocalVocationDay(Date, serviceSupply))
                {
                    return(null);
                }

                var usualDayPlans = serviceSupply.UsualSchedulePlans.Where(x => x.DayOfWeek == Date.DayOfWeek && x.ShiftCenterServiceId == polyClinicHealthService.Id).ToList();

                if (usualDayPlans.Count == 0)
                {
                    return(null);
                }

                var usualSchedules = new List <Schedule>();
                foreach (var plan in usualDayPlans)
                {
                    usualSchedules.Add(new Schedule
                    {
                        CreatedAt            = DateTime.Now,
                        DayOfWeek            = plan.DayOfWeek.ToString(),
                        Description_Ku       = "",
                        IsAvailable          = serviceSupply.IsAvailable,
                        MaxCount             = plan.MaxCount,
                        Shift                = plan.Shift,
                        ShiftCenterServiceId = plan.ShiftCenterServiceId,
                        ServiceSupply        = serviceSupply,
                        ServiceSupplyId      = serviceSupply.Id,
                        Start_DateTime       = DateTime.Parse(Date.ToShortDateString() + " " + plan.StartTime),
                        End_DateTime         = DateTime.Parse(Date.ToShortDateString() + " " + plan.EndTime)
                    });
                }

                return(usualSchedules);
            }
        }
Exemple #15
0
        public DoctorTimePeriods FindFirstDateEmptyTimePeriodsFromNow(ServiceSupply serviceSupply, ShiftCenterService polyclinicHealthService)
        {
            if (!serviceSupply.IsAvailable)
            {
                return new DoctorTimePeriods {
                           TimePeriods = new List <TimePeriodModel>(), HasOffers = false
                }
            }
            ;

            var startReservationDate = serviceSupply.StartReservationDate > DateTime.Now ? serviceSupply.StartReservationDate : DateTime.Now;
            var lastDay = startReservationDate.AddDays(serviceSupply.ShiftCenter.ActiveDaysAhead);

            for (var dt = startReservationDate.Date; dt <= lastDay.Date; dt = dt.AddDays(1))
            {
                var result = Calculate_Available_Empty_TimePeriods_By_Percent(serviceSupply, dt, polyclinicHealthService);

                if (result != null && result.Any())
                {
                    // TODO: We can check here if doctor has offer for this date or not
                    // Then get offer here and calculate all time periods include offers

                    var hasOffer = serviceSupply.Offers.Any(x => x.StartDateTime.Value.Date == dt.Date);

                    var turns = result.Where(x => x.StartDateTime >= DateTime.Now);

                    if (serviceSupply.ReservationType == ReservationType.Selective)
                    {
                        return(new DoctorTimePeriods {
                            TimePeriods = turns.ToList(), HasOffers = hasOffer
                        });
                    }
                    else
                    {
                        return(new DoctorTimePeriods {
                            TimePeriods = turns.Take(1).ToList(), HasOffers = hasOffer
                        });
                    }
                }
            }

            return(new DoctorTimePeriods {
                TimePeriods = new List <TimePeriodModel>(), HasOffers = false
            });
        }
        public async Task <BookingAppointmentResult> BookAppointmentAsync(
            ServiceSupply serviceSupply,
            PatientModel patinetModel,
            string Date,
            string StartTime,
            string EndTime,
            bool _existUser,
            PaymentStatus paymentStatus,
            ShiftCenterService polyclinicHealthService,
            ReservationChannel channel,
            Lang requestLang,
            int?offerId = null)
        {
            var resultMessage = Messages.ErrorOccuredWhileFinalBookTurn;

            try
            {
                if (serviceSupply == null)
                {
                    throw new ArgumentNullException(nameof(serviceSupply));
                }

                if (string.IsNullOrEmpty(Date) || string.IsNullOrEmpty(StartTime) || string.IsNullOrEmpty(EndTime))
                {
                    throw new ArgumentNullException("Date");
                }

                var tmpStatus = paymentStatus == PaymentStatus.NotPayed ? AppointmentStatus.Unknown : AppointmentStatus.Pending;

                var startDateTime = DateTime.Parse(Date + " " + StartTime);

                var endDateTime = DateTime.Parse(Date + " " + EndTime);

                var date = DateTime.Parse(Date).Date;

                long   appointmentId = -1;
                string trackingCode  = string.Empty;

                var strategy = _dbContext.Database.CreateExecutionStrategy();
                await strategy.ExecuteAsync(async() =>
                {
                    using (var transaction = _dbContext.Database.BeginTransaction())
                    {
                        try
                        {
                            if (offerId != null)
                            {
                                var offer = await _dbContext.Offers.FindAsync(offerId.Value);

                                if (offer == null)
                                {
                                    throw new AwroNoreException("Offer Not Found");
                                }

                                if (offer.RemainedCount <= 0)
                                {
                                    throw new AwroNoreException("All Offer Appointments Are Reserved");
                                }

                                offer.RemainedCount -= 1;

                                _dbContext.Entry(offer).State = EntityState.Modified;

                                await _dbContext.SaveChangesAsync();
                            }

                            #region book appointment for new user
                            if (!_existUser)
                            {
                                var patientUser = new Person
                                {
                                    NamePrefix      = patinetModel.NamePrefix,
                                    FirstName       = patinetModel.FirstName,
                                    SecondName      = patinetModel.SecondName,
                                    ThirdName       = patinetModel.ThirdName,
                                    Age             = patinetModel.Age,
                                    Gender          = patinetModel.Gender,
                                    Mobile          = patinetModel.Mobile,
                                    ZipCode         = patinetModel.ZipCode,
                                    Address         = patinetModel.Address,
                                    Description     = patinetModel.Description,
                                    CreatedAt       = DateTime.Now,
                                    IsApproved      = true,
                                    IsDeleted       = false,
                                    CreatorRole     = Shared.Enums.LoginAs.UNKNOWN,
                                    CreationPlaceId = null
                                };

                                _dbContext.Persons.Add(patientUser);

                                _dbContext.SaveChanges();

                                // TODO:
                                // var createUser = userManager.Create(patientUser, patinetModel.Password);

                                //if (createUser.Succeeded)
                                //{
                                //    var assignPatientRole = userManager.AddToRole(patientUser.Id, UsersRoleName.Patient.ToString());
                                //    if (!assignPatientRole.Succeeded)
                                //    {
                                //        throw new Exception(Messages.ErrorOccuredWhileAssignRole);
                                //    }
                                //}

                                _dbContext.PatientPersonInfo.Add(new PatientPersonInfo
                                {
                                    PersonId  = patientUser.Id,
                                    CreatedAt = DateTime.Now
                                });

                                #region Set Patient Insurance
                                int?_patientInsuranceId = null;

                                if (patinetModel.InsuranceId != 0 && patinetModel.InsuranceNumber != null)
                                {
                                    var _patientInsurance = new PatientInsurance
                                    {
                                        UserPatientId            = patientUser.Id,
                                        ServiceSupplyInsuranceId = patinetModel.InsuranceId,
                                        InsuranceNumber          = patinetModel.InsuranceNumber,
                                        CreatedAt = DateTime.Now
                                    };
                                    _dbContext.PatientInsurances.Add(_patientInsurance);
                                    _dbContext.SaveChanges();
                                    _patientInsuranceId = _patientInsurance.Id;
                                }
                                #endregion

                                var finalBookabeTimePeriods = _doctorServiceManager.CalculateFinalBookableTimePeriods(serviceSupply, startDateTime, polyclinicHealthService);

                                if (finalBookabeTimePeriods == null || finalBookabeTimePeriods.Count() <= 0)
                                {
                                    throw new Exception(Messages.ValidEmptyTimePeriodNotFound);
                                }

                                var ipaTimePeriod = finalBookabeTimePeriods.FirstOrDefault(f => f.StartDateTime == startDateTime && f.EndDateTime == endDateTime && f.Type == TimePeriodType.InProgressAppointment);

                                if (ipaTimePeriod == null)
                                {
                                    throw new Exception(Messages.ValidEmptyTimePeriodNotFound);
                                }

                                trackingCode = await _appointmentService.GenerateUniqueTrackingNumberAsync();

                                var appointment = new Appointment
                                {
                                    UniqueTrackingCode   = trackingCode,
                                    Book_DateTime        = DateTime.Now,
                                    Start_DateTime       = startDateTime,
                                    End_DateTime         = endDateTime,
                                    Description          = " ",
                                    Status               = tmpStatus,
                                    ServiceSupplyId      = serviceSupply.Id,
                                    PersonId             = patientUser.Id,
                                    PatientInsuranceId   = _patientInsuranceId,
                                    IsAnnounced          = false,
                                    Paymentstatus        = paymentStatus,
                                    IsDeleted            = false,
                                    ShiftCenterServiceId = polyclinicHealthService.Id,
                                    ReservationChannel   = channel,
                                    CreatedAt            = DateTime.Now,
                                    OfferId              = offerId,
                                    RequestLang          = requestLang
                                };
                                _dbContext.Appointments.Add(appointment);
                                _dbContext.SaveChanges();

                                #region Send SMS notification
                                if (channel != ReservationChannel.Kiosk)
                                {
                                    try
                                    {
                                        var doctor_name       = serviceSupply.Person.FullName;
                                        var persian_dayOfWeek = Utils.ConvertDayOfWeek(startDateTime.DayOfWeek.ToString());
                                        var day_number        = startDateTime.ToShortDateString().Split('/')[2];
                                        var persian_month     = Utils.GetMonthName(startDateTime);
                                        var year_number       = startDateTime.ToShortDateString().Split('/')[0];
                                        var time = startDateTime.ToShortTimeString();

                                        var smsBody = $"{Messages.YourAppointmentForDoctor} { doctor_name} ، { persian_dayOfWeek} { day_number} { persian_month} {year_number} ،{Global.Hour}: {time}";

                                        if (channel == ReservationChannel.ClinicManagerSection)
                                        {
                                            smsBody = smsBody = "Turn for doctor  " + doctor_name + ", " + persian_dayOfWeek + " " + day_number + " " + persian_month + " " + year_number;
                                        }

                                        string[] recepient = { $"964{patinetModel.Mobile}" };

                                        if (serviceSupply.ShiftCenter.IsIndependent)
                                        {
                                            if (Lng == Lang.KU)
                                            {
                                                if (serviceSupply.ShiftCenter.FinalBookSMSMessage_Ku != null)
                                                {
                                                    smsBody = serviceSupply.ShiftCenter.FinalBookSMSMessage_Ku;
                                                }
                                            }
                                            else if (Lng == Lang.AR)
                                            {
                                                if (serviceSupply.ShiftCenter.FinalBookSMSMessage_Ar != null)
                                                {
                                                    smsBody = serviceSupply.ShiftCenter.FinalBookSMSMessage_Ar;
                                                }
                                            }
                                        }
                                        else if (serviceSupply.ShiftCenter.Clinic != null && serviceSupply.ShiftCenter.Clinic.IsIndependent)
                                        {
                                            if (Lng == Lang.KU)
                                            {
                                                if (serviceSupply.ShiftCenter.Clinic.FinalBookSMSMessage_Ku != null)
                                                {
                                                    smsBody = serviceSupply.ShiftCenter.Clinic.FinalBookSMSMessage_Ku;
                                                }
                                            }
                                            else if (Lng == Lang.AR)
                                            {
                                                if (serviceSupply.ShiftCenter.Clinic.FinalBookSMSMessage_Ar != null)
                                                {
                                                    smsBody = serviceSupply.ShiftCenter.Clinic.FinalBookSMSMessage_Ar;
                                                }
                                            }
                                        }
                                        else if (serviceSupply.ShiftCenter.Clinic != null && serviceSupply.ShiftCenter.Clinic.Hospital != null)
                                        {
                                            if (Lng == Lang.KU)
                                            {
                                                if (serviceSupply.ShiftCenter.Clinic.Hospital.FinalBookSMSMessage_Ku != null)
                                                {
                                                    smsBody = serviceSupply.ShiftCenter.Clinic.Hospital.FinalBookSMSMessage_Ku;
                                                }
                                            }
                                            else if (Lng == Lang.AR)
                                            {
                                                if (serviceSupply.ShiftCenter.Clinic.Hospital.FinalBookSMSMessage_Ar != null)
                                                {
                                                    smsBody = serviceSupply.ShiftCenter.Clinic.Hospital.FinalBookSMSMessage_Ar;
                                                }
                                            }
                                        }

                                        _plivoService.SendMessage(recepient.ToList(), smsBody);

                                        _dbContext.Entry(appointment).State = EntityState.Modified;

                                        appointment.IsAnnounced = true;
                                    }
                                    catch
                                    {
                                    }
                                }
                                #endregion

                                _iPAsManager.Delete(serviceSupply.Id, startDateTime);

                                _dbContext.SaveChanges();

                                appointmentId = appointment.Id;
                            }
                            #endregion

                            #region book appointment for existing user
                            else if (_existUser == true)
                            {
                                var user = await _dbContext.Persons.FirstOrDefaultAsync(u => u.Mobile == patinetModel.Mobile);
                                if (user == null)
                                {
                                    throw new EntityNotFoundException();
                                }

                                // TODO
                                //if (!userManager.IsInRole(user.Id, UsersRoleName.Patient.ToString()))
                                //{
                                //    var assignPatientRole = userManager.AddToRole(user.Id, UsersRoleName.Patient.ToString());
                                //    if (!assignPatientRole.Succeeded)
                                //    {
                                //        throw new Exception(Messages.ErrorOccuredWhileAssignRole);
                                //    }
                                //}

                                if (user.PatientPersonInfo == null)
                                {
                                    _dbContext.PatientPersonInfo.Add(new PatientPersonInfo
                                    {
                                        PersonId  = user.Id,
                                        CreatedAt = DateTime.Now
                                    });
                                }

                                #region Set Patient Insurance
                                //Check if user already used current insurance name and number
                                int?patientInsuranId = null;
                                if (patinetModel.InsuranceId != 0 && patinetModel.InsuranceNumber != null)
                                {
                                    var oldInsurance = user.PatientPersonInfo.PatientInsurances.FirstOrDefault(pi => pi.InsuranceNumber == patinetModel.InsuranceNumber && pi.ServiceSupplyInsuranceId == patinetModel.InsuranceId);
                                    if (oldInsurance == null)
                                    {
                                        var _patientInsurance = new PatientInsurance
                                        {
                                            UserPatientId            = user.Id,
                                            ServiceSupplyInsuranceId = patinetModel.InsuranceId,
                                            InsuranceNumber          = patinetModel.InsuranceNumber,
                                            CreatedAt = DateTime.Now
                                        };
                                        _dbContext.PatientInsurances.Add(_patientInsurance);
                                        _dbContext.SaveChanges();
                                        patientInsuranId = _patientInsurance.Id;
                                    }
                                    else
                                    {
                                        patientInsuranId = oldInsurance.Id;
                                    }
                                }
                                #endregion

                                var finalBookabeTimePeriods = _doctorServiceManager.CalculateFinalBookableTimePeriods(serviceSupply, startDateTime, polyclinicHealthService);

                                if (finalBookabeTimePeriods == null || finalBookabeTimePeriods.Count() <= 0)
                                {
                                    throw new Exception(Messages.ValidEmptyTimePeriodNotFound);
                                }

                                var ipaTimePeriod = finalBookabeTimePeriods.FirstOrDefault(f => f.StartDateTime == startDateTime && f.EndDateTime == endDateTime && f.Type == TimePeriodType.InProgressAppointment);

                                if (ipaTimePeriod == null)
                                {
                                    throw new Exception(Messages.ValidEmptyTimePeriodNotFound);
                                }

                                trackingCode = await _appointmentService.GenerateUniqueTrackingNumberAsync();

                                var appointment = new Appointment
                                {
                                    UniqueTrackingCode   = trackingCode,
                                    Book_DateTime        = DateTime.Now,
                                    Start_DateTime       = startDateTime,
                                    End_DateTime         = endDateTime,
                                    Description          = " ",
                                    Status               = tmpStatus,
                                    ServiceSupplyId      = serviceSupply.Id,
                                    PersonId             = user.Id,
                                    PatientInsuranceId   = patientInsuranId,
                                    IsAnnounced          = false,
                                    Paymentstatus        = paymentStatus,
                                    IsDeleted            = false,
                                    ShiftCenterServiceId = polyclinicHealthService.Id,
                                    ReservationChannel   = channel,
                                    CreatedAt            = DateTime.Now,
                                    OfferId              = offerId,
                                    RequestLang          = requestLang
                                };

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

                                #region Send SMS notification
                                if (channel != ReservationChannel.Kiosk)
                                {
                                    try
                                    {
                                        var doctor_name       = serviceSupply.Person.FullName;
                                        var persian_dayOfWeek = Utils.ConvertDayOfWeek(startDateTime.DayOfWeek.ToString());
                                        var day_number        = startDateTime.ToShortDateString().Split('/')[2];
                                        var persian_month     = Utils.GetMonthName(startDateTime);
                                        var year_number       = startDateTime.ToShortDateString().Split('/')[0];
                                        var time = startDateTime.ToShortTimeString();

                                        var smsBody = $"{Messages.YourAppointmentForDoctor} { doctor_name} ، { persian_dayOfWeek} { day_number} { persian_month} {year_number} ،{Global.Hour}: {time}";

                                        if (channel == ReservationChannel.ClinicManagerSection)
                                        {
                                            smsBody = smsBody = "Turn for doctor  " + doctor_name + ", " + persian_dayOfWeek + " " + day_number + " " + persian_month + " " + year_number;
                                        }

                                        string[] recepient = { $"964{patinetModel.Mobile}" };

                                        if (serviceSupply.ShiftCenter.IsIndependent)
                                        {
                                            if (Lng == Lang.KU)
                                            {
                                                if (serviceSupply.ShiftCenter.FinalBookSMSMessage_Ku != null)
                                                {
                                                    smsBody = serviceSupply.ShiftCenter.FinalBookSMSMessage_Ku;
                                                }
                                            }
                                            else if (Lng == Lang.AR)
                                            {
                                                if (serviceSupply.ShiftCenter.FinalBookSMSMessage_Ar != null)
                                                {
                                                    smsBody = serviceSupply.ShiftCenter.FinalBookSMSMessage_Ar;
                                                }
                                            }
                                        }
                                        else if (serviceSupply.ShiftCenter.Clinic != null && serviceSupply.ShiftCenter.Clinic.IsIndependent)
                                        {
                                            if (Lng == Lang.KU)
                                            {
                                                if (serviceSupply.ShiftCenter.Clinic.FinalBookSMSMessage_Ku != null)
                                                {
                                                    smsBody = serviceSupply.ShiftCenter.Clinic.FinalBookSMSMessage_Ku;
                                                }
                                            }
                                            else if (Lng == Lang.AR)
                                            {
                                                if (serviceSupply.ShiftCenter.Clinic.FinalBookSMSMessage_Ar != null)
                                                {
                                                    smsBody = serviceSupply.ShiftCenter.Clinic.FinalBookSMSMessage_Ar;
                                                }
                                            }
                                        }
                                        else if (serviceSupply.ShiftCenter.Clinic != null && serviceSupply.ShiftCenter.Clinic.Hospital != null)
                                        {
                                            if (Lng == Lang.KU)
                                            {
                                                if (serviceSupply.ShiftCenter.Clinic.Hospital.FinalBookSMSMessage_Ku != null)
                                                {
                                                    smsBody = serviceSupply.ShiftCenter.Clinic.Hospital.FinalBookSMSMessage_Ku;
                                                }
                                            }
                                            else if (Lng == Lang.AR)
                                            {
                                                if (serviceSupply.ShiftCenter.Clinic.Hospital.FinalBookSMSMessage_Ar != null)
                                                {
                                                    smsBody = serviceSupply.ShiftCenter.Clinic.Hospital.FinalBookSMSMessage_Ar;
                                                }
                                            }
                                        }

                                        _plivoService.SendMessage(recepient.ToList(), smsBody);

                                        _dbContext.Entry(appointment).State = EntityState.Modified;

                                        appointment.IsAnnounced = true;
                                    }
                                    catch
                                    {
                                    }
                                }
                                #endregion

                                _iPAsManager.Delete(serviceSupply.Id, startDateTime);

                                _dbContext.SaveChanges();

                                appointmentId = appointment.Id;
                            }
                            #endregion

                            transaction.Commit();
                        }
                        catch (Exception ex)
                        {
                            transaction.Rollback();
                            throw ex;
                        }
                    }
                });

                return(new BookingAppointmentResult
                {
                    Status = BookingAppointmentStatus.Success,
                    Message = Messages.TurnBookedFinally,
                    AppointmentId = appointmentId,
                    TrackingCode = trackingCode
                });
            }
            catch (Exception ex)
            {
                resultMessage = ex.Message;
            }
            return(new BookingAppointmentResult
            {
                Status = BookingAppointmentStatus.Failure,
                Message = resultMessage
            });
        }
Exemple #17
0
        /// <summary>
        /// لیست همه بازه های زمانی قابل رزرو و رزرو شده و یا در حال رزرو را بر می گرداند
        /// </summary>
        /// <param name="serviceSupply">ارایه موردنظر</param>
        /// <param name="Date">تاریخ - روز</param>
        /// <returns></returns>
        public IEnumerable <TimePeriodModel> Calculate_All_TimePeriods(ServiceSupply serviceSupply, DateTime Date, ShiftCenterService polyclinicHealthService)
        {
            var BookableTimePeriods = Calculate_Bookable_TimePeriods(serviceSupply, Date, polyclinicHealthService);

            if (BookableTimePeriods != null && BookableTimePeriods.Count() >= 1)
            {
                // This is necessary
                BookableTimePeriods = BookableTimePeriods.ToList();

                var appointments = Get_All_Appointments(serviceSupply, Date).ToList();

                var inProgressAppointments = Calculate_InProgressAppointments_TimePriods(serviceSupply, Date).ToList();

                if ((appointments == null || appointments.Count <= 0) &&
                    (inProgressAppointments == null || inProgressAppointments.Count <= 0))
                {
                    return(BookableTimePeriods);
                }

                if (appointments != null && appointments.Count >= 1)
                {
                    foreach (var pa in appointments)
                    {
                        foreach (var bookable in BookableTimePeriods)
                        {
                            if (bookable.StartDateTime == pa.Start_DateTime && bookable.Type != TimePeriodType.InProgressAppointment)
                            {
                                BookableTimePeriods.ElementAt(BookableTimePeriods.IndexOf(bookable)).Type = pa.OfferId == null ? TimePeriodType.Appointment : TimePeriodType.OfferAppointment;
                                break;
                            }
                        }
                    }
                }

                if (inProgressAppointments != null && inProgressAppointments.Count >= 1)
                {
                    foreach (var ipa in inProgressAppointments)
                    {
                        foreach (var bookable in BookableTimePeriods)
                        {
                            if (bookable.StartDateTime == ipa.StartDateTime && bookable.Type != TimePeriodType.Appointment)
                            {
                                BookableTimePeriods.ElementAt(BookableTimePeriods.IndexOf(bookable)).Type = TimePeriodType.InProgressAppointment;
                            }
                        }
                    }
                }

                return(BookableTimePeriods.OrderBy(x => x.StartDateTime));
            }

            return(null);
        }