Наследование: IdentifiedEntity
Пример #1
0
        /// <summary>
        /// Получить доступные временные интервалы
        /// </summary>
        public ServiceFreeTime GetServiceFreeTime(Service service, ServiceStep serviceStep, ClientRequestType requestType, int subjects = 1)
        {
            var schedule = GetServiceSchedule(service);
            if (schedule == null)
            {
                throw new Exception("Не удалось определить расписание для услуги");
            }

            if (!schedule.IsWorked)
            {
                throw new Exception("На указанную дату услуга не оказывается");
            }

            switch (requestType)
            {
                case ClientRequestType.Live:
                    if (!schedule.RenderingMode.HasFlag(ServiceRenderingMode.LiveRequests))
                    {
                        throw new Exception("Живая очередь для данной услуги на указанный день отключена");
                    }
                    break;

                case ClientRequestType.Early:
                    if (!schedule.RenderingMode.HasFlag(ServiceRenderingMode.EarlyRequests))
                    {
                        throw new Exception("Предварительная запись для данной услуги на указанный день отключена");
                    }

                    break;
            }

            var report = new List<string>()
            {
                string.Format("Поиск свободного времени на дату {0:dd.MM.yyyy} и время {1:hh\\:mm\\:ss}", PlanDate, PlanTime)
            };

            // Только подходящие параметры обслуживания
            var serviceRenderingMode = requestType == ClientRequestType.Early
                ? ServiceRenderingMode.EarlyRequests
                : ServiceRenderingMode.LiveRequests;

            report.Add(string.Format("Выбран режим обслуживания [{0}]", serviceRenderingMode));

            var renderings = GetServiceRenderings(schedule, serviceStep, serviceRenderingMode);

            var potentialOperatorsPlans = OperatorsPlans
                .Where(p => renderings.Any(r => r.Operator.IsActive && r.Operator.Equals(p.Operator)))
                .ToList();

            if (potentialOperatorsPlans.Count == 0)
            {
                throw new Exception("В системе нет активных операторов способных оказать услугу");
            }

            report.Add("Найдены следующие потенциальные планы операторов");
            foreach (var o in potentialOperatorsPlans)
            {
                report.Add(o.ToString());
            }

            if (PlanDate == DateTime.Today && schedule.OnlineOperatorsOnly)
            {
                potentialOperatorsPlans.RemoveAll(o => !o.Operator.Online);
                report.Add("Оставлены только операторы онлайн");
                foreach (var o in potentialOperatorsPlans)
                {
                    report.Add(o.ToString());
                }
            }

            var timeIntervals = new List<TimeSpan>();

            var startTime = schedule.StartTime;
            if (PlanTime > startTime)
            {
                startTime = PlanTime;
            }

            report.Add(string.Format("Поиск интервалов времени с {0:hh\\:mm\\:ss}", startTime));

            var clientInterval = requestType == ClientRequestType.Live
                ? schedule.LiveClientInterval : schedule.EarlyClientInterval;

            int openedRequests = 0;

            foreach (var potentialOperatorPlan in potentialOperatorsPlans)
            {
                openedRequests += potentialOperatorPlan.ClientRequestPlans
                    .Select(p => p.ClientRequest)
                    .Count(r => r.Type == requestType);

                report.Add(string.Format("В плане оператора [{0}] {1} открытых запросов", potentialOperatorPlan, openedRequests));

                var intervalTime = startTime;

                while (intervalTime < schedule.FinishTime)
                {
                    intervalTime = potentialOperatorPlan.GetNearTimeInterval(intervalTime, schedule, requestType, subjects);

                    report.Add(string.Format("Найден ближайший интвервал времени {0:hh\\:mm\\:ss}", intervalTime));

                    var timeIntervalRounding = service.TimeIntervalRounding;
                    if (timeIntervalRounding != TimeSpan.Zero)
                    {
                        var rounding = new TimeSpan(intervalTime.Ticks % timeIntervalRounding.Ticks);
                        if (rounding != TimeSpan.Zero)
                        {
                            report.Add(string.Format("Округление интервала {0:hh\\:mm\\:ss}", rounding));

                            intervalTime = intervalTime.Add(rounding <= schedule.Intersection ? -rounding : timeIntervalRounding.Subtract(rounding));
                        }
                    }

                    report.Add(string.Format("Найден интвервал времени {0:hh\\:mm\\:ss}", intervalTime));

                    timeIntervals.Add(intervalTime);
                    intervalTime = intervalTime.Add(clientInterval);

                    if (timeIntervals.Count() > 1000)
                    {
                        throw new OverflowException("Возможно переполнение памяти. Обратитесь к администратору.");
                    }
                }
            }

            int freeTimeIntervals;

            if (PlanDate != DateTime.Today)
            {
                int maxOnlineOperators = schedule.MaxOnlineOperators > 0 ? schedule.MaxOnlineOperators : potentialOperatorsPlans.Count;

                int maxRequests = (int)((schedule.EarlyFinishTime - schedule.EarlyStartTime).Ticks / clientInterval.Ticks) * maxOnlineOperators;
                report.Add(string.Format("Максимальное кол-во запросов {0}", maxRequests));

                int maxEarlyClientRequests = maxRequests * schedule.EarlyReservation / 100;
                report.Add(string.Format("Максимальное кол-во запросов с учетом резервирования {0}", maxEarlyClientRequests));

                freeTimeIntervals = maxEarlyClientRequests - openedRequests;
                if (freeTimeIntervals <= 0)
                {
                    throw new Exception("Возможности резервирования для данной услуги на указанный день исчерпаны");
                }

                timeIntervals.RemoveAll(i => i < schedule.EarlyStartTime);
                timeIntervals.RemoveAll(i => i.Add(clientInterval - schedule.Intersection) > schedule.EarlyFinishTime);

                if (freeTimeIntervals > timeIntervals.Count)
                {
                    freeTimeIntervals = timeIntervals.Count;
                }
            }
            else
            {
                timeIntervals.RemoveAll(i => i.Add(clientInterval - schedule.Intersection) > schedule.FinishTime);

                freeTimeIntervals = timeIntervals.Count;
            }

            return new ServiceFreeTime()
            {
                Service = service,
                Schedule = schedule,
                TimeIntervals = timeIntervals.ToArray(),
                FreeTimeIntervals = freeTimeIntervals,
                Report = report
            };
        }
Пример #2
0
        /// <summary>
        /// Получить расписание для услуги
        /// </summary>
        /// <param name="service"></param>
        /// <returns></returns>
        public Schedule GetServiceSchedule(Service service)
        {
            if (!serviceSchedule.ContainsKey(service))
            {
                logger.Info("Загрузка расписания для услуги [{0}]", service);

                using (var session = SessionProvider.OpenSession())
                using (var transaction = session.BeginTransaction())
                {
                    Schedule schedule = session.CreateCriteria<ServiceExceptionSchedule>()
                         .Add(Restrictions.Eq("Service", service))
                         .Add(Restrictions.Eq("ScheduleDate", PlanDate))
                         .SetMaxResults(1)
                         .UniqueResult<ServiceExceptionSchedule>();
                    if (schedule == null)
                    {
                        schedule = session.CreateCriteria<DefaultExceptionSchedule>()
                            .Add(Restrictions.Eq("ScheduleDate", PlanDate))
                            .UniqueResult<DefaultExceptionSchedule>();
                        if (schedule == null)
                        {
                            var dayOfWeek = PlanDate.DayOfWeek;

                            schedule = session.CreateCriteria<ServiceWeekdaySchedule>()
                                .Add(Restrictions.Eq("Service", service))
                                .Add(Restrictions.Eq("DayOfWeek", dayOfWeek))
                                .SetMaxResults(1)
                                .UniqueResult<ServiceWeekdaySchedule>();
                            if (schedule == null)
                            {
                                schedule = session.CreateCriteria<DefaultWeekdaySchedule>()
                                    .Add(Restrictions.Eq("DayOfWeek", dayOfWeek))
                                    .UniqueResult<DefaultWeekdaySchedule>();
                            }
                        }
                    }

                    if (schedule == null)
                    {
                        throw new Exception("Не удалось определить расписание для услуги");
                    }

                    serviceSchedule.Add(service, schedule);
                    transaction.Commit();
                }
            }

            return serviceSchedule[service];
        }
Пример #3
0
        public async Task<DTO.Service> EditService(DTO.Service source)
        {
            return await Task.Run(() =>
            {
                CheckPermission(UserRole.Administrator, AdministratorPermissions.Services);

                using (var session = SessionProvider.OpenSession())
                using (var transaction = session.BeginTransaction())
                {
                    Service service;

                    if (!source.Empty())
                    {
                        var serviceId = source.Id;
                        service = session.Get<Service>(serviceId);
                        if (service == null)
                        {
                            throw new FaultException<ObjectNotFoundFault>(new ObjectNotFoundFault(serviceId), string.Format("Услуга [{0}] не найдена", serviceId));
                        }
                    }
                    else
                    {
                        service = new Service();
                    }

                    service.IsActive = source.IsActive;
                    service.Code = source.Code;
                    service.Priority = source.Priority;
                    service.Name = source.Name;
                    service.Comment = source.Comment;
                    service.Tags = source.Tags;
                    service.Description = source.Description;
                    service.Link = source.Link;
                    service.MaxSubjects = source.MaxSubjects;
                    service.MaxEarlyDays = source.MaxEarlyDays;
                    service.MaxClientRecalls = source.MaxClientRecalls;
                    service.IsPlanSubjects = source.IsPlanSubjects;
                    service.ClientRequire = source.ClientRequire;
                    service.ClientCallDelay = source.ClientCallDelay;
                    service.TimeIntervalRounding = source.TimeIntervalRounding;
                    service.IsUseType = source.IsUseType;
                    service.LiveRegistrator = source.LiveRegistrator;
                    service.EarlyRegistrator = source.EarlyRegistrator;
                    service.Color = source.Color;
                    service.FontSize = source.FontSize;

                    if (source.ServiceGroup != null)
                    {
                        Guid serviceGroupId = source.ServiceGroup.Id;

                        ServiceGroup serviceGroup = session.Get<ServiceGroup>(serviceGroupId);
                        if (serviceGroup == null)
                        {
                            throw new FaultException<ObjectNotFoundFault>(new ObjectNotFoundFault(serviceGroupId),
                                string.Format("Группа услуг [{0}] не найдена", serviceGroupId));
                        }

                        service.ServiceGroup = serviceGroup;
                    }
                    else
                    {
                        service.ServiceGroup = null;
                    }

                    var errors = service.Validate();
                    if (errors.Length > 0)
                    {
                        throw new FaultException(errors.First().Message);
                    }

                    session.Save(service);

                    var todayQueuePlan = QueueInstance.TodayQueuePlan;
                    using (var locker = todayQueuePlan.WriteLock())
                    {
                        transaction.Commit();

                        todayQueuePlan.Put(service);
                    }

                    return Mapper.Map<Service, DTO.Service>(service);
                }
            });
        }