public async Task<DTO.ClientRequest> AddLiveClientRequest(Guid clientId, Guid serviceId, bool isPriority, Dictionary<Guid, object> parameters, int subjects) { return await Task.Run(() => { CheckPermission(UserRole.Administrator, AdministratorPermissions.ClientsRequests); using (var session = SessionProvider.OpenSession()) using (var transaction = session.BeginTransaction()) { Client client = null; if (clientId != Guid.Empty) { client = session.Get<Client>(clientId); if (client == null) { throw new FaultException<ObjectNotFoundFault>(new ObjectNotFoundFault(clientId), string.Format("Клиент [{0}] не найден", clientId)); } } var service = session.Get<Service>(serviceId); if (service == null) { throw new FaultException<ObjectNotFoundFault>(new ObjectNotFoundFault(serviceId), string.Format("Услуга [{0}] не найдена", serviceId)); } if (!service.IsActive) { throw new FaultException("Выбранная услуга не активна"); } if (service.ClientRequire && client == null) { throw new FaultException("Выбранная услуга требует наличие клиента"); } var clientRequest = new ClientRequest() { Client = client, Service = service, ServiceStep = service.GetFirstStep(session), Subjects = subjects, IsPriority = client != null && client.VIP }; var currentTime = DateTime.Now.TimeOfDay; var todayQueuePlan = QueueInstance.TodayQueuePlan; using (var locker = todayQueuePlan.ReadLock()) { var schedule = todayQueuePlan.GetServiceSchedule(service); int count = session.CreateCriteria<ClientRequest>() .Add(Restrictions.Eq("RequestDate", DateTime.Today)) .Add(Restrictions.Eq("Client", client)) .Add(Restrictions.Eq("Service", service)) .SetProjection(Projections.RowCount()) .UniqueResult<int>(); if (count >= schedule.MaxClientRequests) { throw new FaultException("Достигнуто максимальное кол-во запрос на текущий день"); } #if !DEBUG if (currentTime < schedule.StartTime) { throw new FaultException(string.Format("Время начала оказания услуги наступит в {0}", schedule.StartTime)); } #endif try { var freeTime = todayQueuePlan.GetServiceFreeTime(service, clientRequest.ServiceStep, ClientRequestType.Live, service.IsPlanSubjects ? subjects : 1); var timeIntervals = freeTime.TimeIntervals; if (timeIntervals.Length == 0) { throw new FaultException("Нет свободного времени для оказания услуги"); } } catch (Exception exception) { throw new FaultException(exception.Message); } } logger.Info("Добавление нового запроса в план очереди"); using (var locker = todayQueuePlan.WriteLock()) { clientRequest.Number = ++todayQueuePlan.LastNumber; } clientRequest.RequestDate = DateTime.Today; clientRequest.RequestTime = currentTime.Add(service.ClientCallDelay); clientRequest.IsPriority = isPriority; clientRequest.Type = ClientRequestType.Live; var error = clientRequest.Validate().FirstOrDefault(); if (error != null) { throw new FaultException(error.Message); } session.Save(clientRequest); var queueEvent = new ClientRequestEvent() { ClientRequest = clientRequest, Message = string.Format("[{0}] добавил новый запрос клиента в живую очередь [{1}]", currentUser, clientRequest) }; session.Save(queueEvent); var defaultConfig = session.Get<DefaultConfig>(ConfigType.Default); if (defaultConfig.IsDebug) { session.Save(new QueuePlanReport() { ClientRequest = clientRequest, Report = string.Join(Environment.NewLine, todayQueuePlan.Report) }); } using (var locker = todayQueuePlan.WriteLock()) { transaction.Commit(); todayQueuePlan.AddClientRequest(clientRequest); todayQueuePlan.Build(currentTime); } QueueInstance.Event(queueEvent); logger.Info("Запрос добавлен в план очереди"); return Mapper.Map<ClientRequest, DTO.ClientRequest>(clientRequest); } }); }
public async Task<DTO.ClientRequest> AddEarlyClientRequest(Guid clientId, Guid serviceId, DateTime requestDate, TimeSpan requestTime, Dictionary<Guid, object> parameters, int subjects) { return await Task.Run(() => { CheckPermission(UserRole.Administrator, AdministratorPermissions.ClientsRequests); using (var session = SessionProvider.OpenSession()) using (var transaction = session.BeginTransaction()) { Client client = null; if (clientId != Guid.Empty) { client = session.Get<Client>(clientId); if (client == null) { throw new FaultException<ObjectNotFoundFault>(new ObjectNotFoundFault(clientId), string.Format("Клиент [{0}] не найден", clientId)); } } var service = session.Get<Service>(serviceId); if (service == null) { throw new FaultException<ObjectNotFoundFault>(new ObjectNotFoundFault(serviceId), string.Format("Услуга [{0}] не найдена", serviceId)); } if (!service.IsActive) { throw new FaultException("Выбранная услуга не активна"); } if (service.ClientRequire && client == null) { throw new FaultException("Выбранная услуга требует наличие клиента"); } requestDate = requestDate.Date; var isRequestDateToday = requestDate == DateTime.Today; QueuePlan queuePlan; if (isRequestDateToday) { queuePlan = QueueInstance.TodayQueuePlan; } else { if (requestDate - DateTime.Today > TimeSpan.FromDays(service.MaxEarlyDays)) { throw new FaultException(string.Format("По указанной услуге запись возможна не более чем за {0} дней", service.MaxEarlyDays)); } queuePlan = new QueuePlan(); queuePlan.Load(requestDate); queuePlan.Build(); } var clientRequest = new ClientRequest() { Client = client, Service = service, ServiceStep = service.GetFirstStep(session), Subjects = subjects }; using (var locker = queuePlan.ReadLock()) { var schedule = queuePlan.GetServiceSchedule(service); int count = session.CreateCriteria<ClientRequest>() .Add(Restrictions.Eq("RequestDate", requestDate)) .Add(Restrictions.Eq("Client", client)) .Add(Restrictions.Eq("Service", service)) .SetProjection(Projections.RowCount()) .UniqueResult<int>(); if (count >= schedule.MaxClientRequests) { throw new FaultException("Достигнуто максимальное кол-во запрос на текущий день"); } try { var freeTime = queuePlan.GetServiceFreeTime(service, clientRequest.ServiceStep, ClientRequestType.Early, subjects); var timeIntervals = freeTime.TimeIntervals; if (timeIntervals.Length == 0) { throw new FaultException("Нет свободного времени для оказания услуги"); } if (!timeIntervals.Contains(requestTime)) { throw new FaultException("Выбрано недопустимое время"); } } catch (Exception exception) { throw new FaultException(exception.Message); } if (subjects < 1) { throw new FaultException("Количество объектов должно быть больше 0"); } } logger.Info("Добавление нового запроса в план очереди"); using (var locker = queuePlan.WriteLock()) { clientRequest.Number = ++queuePlan.LastNumber; } clientRequest.RequestDate = requestDate; clientRequest.RequestTime = requestTime; clientRequest.Type = ClientRequestType.Early; var error = clientRequest.Validate().FirstOrDefault(); if (error != null) { throw new FaultException(error.Message); } session.Save(clientRequest); var queueEvent = new ClientRequestEvent() { ClientRequest = clientRequest, Message = string.Format("[{0}] добавил новый запрос клиента по предварительной записи на дату [{1}] и время [{2}] [{3}]", currentUser, requestDate.ToShortDateString(), requestTime, clientRequest) }; session.Save(queueEvent); var defaultConfig = session.Get<DefaultConfig>(ConfigType.Default); if (defaultConfig.IsDebug) { session.Save(new QueuePlanReport() { ClientRequest = clientRequest, Report = string.Join(Environment.NewLine, queuePlan.Report) }); } if (isRequestDateToday) { using (var locker = queuePlan.WriteLock()) { transaction.Commit(); queuePlan.AddClientRequest(clientRequest); queuePlan.Build(DateTime.Now.TimeOfDay); } } else { transaction.Commit(); } QueueInstance.Event(queueEvent); logger.Info("Запрос добавлен в план очереди"); return Mapper.Map<ClientRequest, DTO.ClientRequest>(clientRequest); } }); }