Inheritance: IdentifiedEntity
Example #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
            };
        }
Example #2
0
        /// <summary>
        /// Получить параметры обслуживания
        /// </summary>
        public ServiceRendering[] GetServiceRenderings(Schedule schedule, ServiceStep serviceStep, ServiceRenderingMode serviceRenderingMode)
        {
            var key = new ServiceRenderingKey(schedule, serviceStep, serviceRenderingMode);

            if (!serviceRenderings.ContainsKey(key))
            {
                logger.Info("Загрузка параметров оказания услуги для раписания [{0}]", schedule);

                using (var session = SessionProvider.OpenSession())
                using (var transaction = session.BeginTransaction())
                {
                    serviceRenderings.Add(key, session.CreateCriteria<ServiceRendering>()
                         .Add(Restrictions.Eq("Schedule", schedule))
                         .Add(serviceStep != null ? Restrictions.Eq("ServiceStep", serviceStep) : Restrictions.IsNull("ServiceStep"))
                         .Add(new Disjunction()
                             .Add(Restrictions.Eq("Mode", serviceRenderingMode))
                             .Add(Restrictions.Eq("Mode", ServiceRenderingMode.AllRequests)))
                         .List<ServiceRendering>()
                         .ToArray());

                    transaction.Commit();
                }
            }

            return serviceRenderings[key];
        }
Example #3
0
        public async Task<DTO.ServiceStep> EditServiceStep(DTO.ServiceStep source)
        {
            return await Task.Run(() =>
            {
                CheckPermission(UserRole.Administrator, AdministratorPermissions.Services);

                using (var session = SessionProvider.OpenSession())
                using (var transaction = session.BeginTransaction())
                {
                    ServiceStep serviceStep;

                    if (!source.Empty())
                    {
                        var serviceStepId = source.Id;
                        serviceStep = session.Get<ServiceStep>(serviceStepId);
                        if (serviceStep == null)
                        {
                            throw new FaultException<ObjectNotFoundFault>(new ObjectNotFoundFault(serviceStepId),
                                string.Format("Этап услуги [{0}] не найден", serviceStepId));
                        }
                    }
                    else
                    {
                        serviceStep = new ServiceStep();
                    }

                    if (source.Service != null)
                    {
                        var serviceId = source.Service.Id;

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

                    serviceStep.Name = source.Name;

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

                    session.Save(serviceStep);
                    transaction.Commit();

                    return Mapper.Map<ServiceStep, DTO.ServiceStep>(serviceStep);
                }
            });
        }