public async Task UpdateCurrentClientRequest(ClientRequestState state) { await Task.Run(() => { CheckPermission(UserRole.Operator); using (var session = SessionProvider.OpenSession()) using (var transaction = session.BeginTransaction()) { var queueOperator = (Operator)currentUser; ClientRequest clientRequest; var todayQueuePlan = QueueInstance.TodayQueuePlan; using (var locker = todayQueuePlan.ReadLock()) { var currentClientRequestPlan = todayQueuePlan.GetOperatorPlan(queueOperator) .CurrentClientRequestPlan; if (currentClientRequestPlan == null) { throw new FaultException<ObjectNotFoundFault>(new ObjectNotFoundFault(queueOperator.GetId()), string.Format("Текущий запрос клиента не найден у оператора [{0}]", queueOperator)); } clientRequest = session.Merge(currentClientRequestPlan.ClientRequest); } try { var service = clientRequest.Service; var client = clientRequest.Client; string message; switch (clientRequest.State) { case ClientRequestState.Waiting: case ClientRequestState.Redirected: case ClientRequestState.Postponed: switch (state) { case ClientRequestState.Calling: message = string.Format("Клиент [{0}] вызывается к оператору [{1}] на рабочее место [{2}]", client, queueOperator, queueOperator.Workplace); clientRequest.Calling(queueOperator); break; default: throw new Exception(string.Format("Изменение состояния с [{0}] на [{1}] заявки клиента [{2}] не допустимо", clientRequest.State, state, clientRequest)); } break; case ClientRequestState.Calling: switch (state) { case ClientRequestState.Absence: if (clientRequest.ClientRecalls >= service.MaxClientRecalls) { message = string.Format("Клиент [{0}] не подошел к оператору [{1}]", client, queueOperator); clientRequest.Absence(); } else { message = string.Format("Клиент [{0}] не подошел к оператору [{1}] вызов откладывается", client, queueOperator); clientRequest.Postpone(TimeSpan.FromMinutes(5)); clientRequest.ClientRecalls++; } break; case ClientRequestState.Rendering: message = string.Format("Начало обслуживания клиента [{0}] у оператора [{1}]", client, queueOperator); var schedule = todayQueuePlan.GetServiceSchedule(service); clientRequest.Rendering(schedule.LiveClientInterval); break; default: throw new Exception(string.Format("Изменение состояния с [{0}] на [{1}] заявки клиента [{2}] не допустимо", clientRequest.State, state, clientRequest)); } break; case ClientRequestState.Rendering: switch (state) { case ClientRequestState.Rendered: if (!clientRequest.NextStep(session)) { if (clientRequest.Service.IsUseType && clientRequest.ServiceType == ServiceType.None) { throw new Exception("Укажите тип услуги перед окончанием обслуживания"); } clientRequest.Rendered(); message = string.Format("Завершено обслуживание клиента [{0}] у оператора [{1}] с производительностью {2:00.00}%", client, queueOperator, clientRequest.Productivity); } else { message = string.Format("Запросу установлен следующий этап оказания услуги [{0}]", clientRequest.ServiceStep); } break; default: throw new Exception(string.Format("Изменение состояния с [{0}] на [{1}] заявки клиента [{2}] не допустимо", clientRequest.State, state, clientRequest)); } break; default: throw new Exception(string.Format("Заявка клиента [{0}] находиться в не допустимом состоянии [{1}]", clientRequest, clientRequest.State)); } clientRequest.Version++; session.Save(clientRequest); var queueEvent = new ClientRequestEvent() { ClientRequest = clientRequest, Message = message }; session.Save(queueEvent); using (var locker = todayQueuePlan.WriteLock()) { transaction.Commit(); todayQueuePlan.Put(clientRequest); todayQueuePlan.Build(DateTime.Now.TimeOfDay); } QueueInstance.ClientRequestUpdated(clientRequest); QueueInstance.Event(queueEvent); } catch (Exception exception) { throw new FaultException(exception.Message); } } }); }
public virtual void Close(ClientRequestState state) { if (IsClosed) { throw new LogicException("Запрос уже закрыт"); } switch (State) { case ClientRequestState.Waiting: case ClientRequestState.Calling: case ClientRequestState.Redirected: case ClientRequestState.Postponed: case ClientRequestState.Rendering: State = state; IsClosed = true; break; default: throw new LogicException("Нельзя закрыть запрос клиента находящегося в данном статусе"); } }