private void ValidateInterpreters(InterpreterAnswerDto interpreter, InterpreterAnswerDto extraInterpreter, bool hasExtraInterpreter) { if (!interpreter.Accepted && !hasExtraInterpreter) { throw new InvalidOperationException("Ingen tolk är tillsatt. använd \"Tacka nej till bokning\" om intentionen är att inte tillsätta någon tolk."); } if (!interpreter.Accepted && hasExtraInterpreter && extraInterpreter.Accepted) { throw new InvalidOperationException("Om den sammanhållna bokningen beställer två tolkar så måste den första tolken tillsättas."); } if (!interpreter.Accepted && hasExtraInterpreter && !extraInterpreter.Accepted) { throw new InvalidOperationException("Ingen tolk är tillsatt. använd \"Tacka nej till bokning\" om intentionen är att inte tillsätta någon tolk."); } if (hasExtraInterpreter && !extraInterpreter.Accepted && !_tolkBaseOptions.AllowDeclineExtraInterpreterOnRequestGroups) { throw new InvalidOperationException("Om den sammanhållna bokningen beställer två tolkar så måste den extra tolken tillsättas."); } if (hasExtraInterpreter && interpreter.Accepted && extraInterpreter.Accepted && interpreter.Interpreter.InterpreterBrokerId == extraInterpreter.Interpreter.InterpreterBrokerId && !(interpreter.Interpreter.Interpreter?.IsProtected ?? false)) { throw new InvalidOperationException("Man kan inte tillsätta samma tolk som extra tolk."); } }
public async Task <IActionResult> Process(RequestGroupProcessModel model) { var requestGroup = await _dbContext.RequestGroups.GetRequestGroupToProcessById(model.RequestGroupId); if ((await _authorizationService.AuthorizeAsync(User, requestGroup, Policies.Accept)).Succeeded) { if (!requestGroup.IsToBeProcessedByBroker) { return(RedirectToAction("Index", "Home", new { ErrorMessage = "Förfrågan är redan behandlad" })); } InterpreterAnswerDto interpreterModel = null; try { interpreterModel = await GetInterpreter(model.InterpreterAnswerModel, requestGroup.Ranking.BrokerId); } catch (ArgumentException ex) { ModelState.AddModelError($"{nameof(model.InterpreterAnswerModel)}.{ex.ParamName}", ex.Message); } InterpreterAnswerDto extrainterpreterModel = null; try { extrainterpreterModel = model.ExtraInterpreterAnswerModel != null ? await GetInterpreter(model.ExtraInterpreterAnswerModel, requestGroup.Ranking.BrokerId) : null; } catch (ArgumentException ex) { ModelState.AddModelError($"{nameof(model.ExtraInterpreterAnswerModel)}.{ex.ParamName}", ex.Message); } if (ModelState.IsValid) { try { await _requestService.AcceptGroup( requestGroup, _clock.SwedenNow, User.GetUserId(), User.TryGetImpersonatorId(), model.InterpreterLocation.Value, interpreterModel, extrainterpreterModel, model.Files?.Select(f => new RequestGroupAttachment { AttachmentId = f.Id }).ToList(), (model.SetLatestAnswerTimeForCustomer != null && EnumHelper.Parse <TrueFalse>(model.SetLatestAnswerTimeForCustomer.SelectedItem.Value) == TrueFalse.Yes)?model.LatestAnswerTimeForCustomer : null, model.BrokerReferenceNumber ); await _dbContext.SaveChangesAsync(); return(RedirectToAction("Index", "Home", new { message = "Svar har skickats på sammanhållen bokning" })); } catch (InvalidOperationException e) { _logger.LogError("Process failed for requestgroup, RequestGroupId: {requestGroup.RequestGroupId}, message {e.Message}", requestGroup.RequestGroupId, e.Message); return(RedirectToAction("Index", "Home", new { errormessage = e.Message })); } } //Should return to Process if error is of a kind that can be handled in the ui. return(View(nameof(Process), model)); } return(Forbid()); }
public async Task <IActionResult> Answer([FromBody] RequestGroupAnswerModel model) { if (model == null) { return(ReturnError(ErrorCodes.IncomingPayloadIsMissing)); } try { var brokerId = User.TryGetBrokerId().Value; var apiUserId = User.UserId(); var user = await _apiUserService.GetBrokerUser(model.CallingUser, brokerId); var requestGroup = await _dbContext.RequestGroups.GetFullRequestGroupForApiWithBrokerAndOrderNumber(model.OrderGroupNumber, brokerId); if (requestGroup == null) { return(ReturnError(ErrorCodes.RequestGroupNotFound)); } if (!(requestGroup.Status == RequestStatus.Created || requestGroup.Status == RequestStatus.Received)) { return(ReturnError(ErrorCodes.RequestGroupNotInCorrectState)); } var mainInterpreterAnswer = _apiUserService.GetInterpreterModel(model.InterpreterAnswer, brokerId); InterpreterAnswerDto extraInterpreterAnswer = null; requestGroup.OrderGroup.Orders = await _dbContext.Orders.GetOrdersForOrderGroup(requestGroup.OrderGroup.OrderGroupId).ToListAsync(); if (requestGroup.HasExtraInterpreter) { extraInterpreterAnswer = _apiUserService.GetInterpreterModel(model.ExtraInterpreterAnswer, brokerId, false); } var now = _timeService.SwedenNow; if (requestGroup.Status == RequestStatus.Created) { await _requestService.AcknowledgeGroup(requestGroup, now, user?.Id ?? apiUserId, (user != null ? (int?)apiUserId : null)); } try { await _requestService.AcceptGroup( requestGroup, now, user?.Id ?? apiUserId, user != null?(int?)apiUserId : null, EnumHelper.GetEnumByCustomName <InterpreterLocation>(model.InterpreterLocation).Value, mainInterpreterAnswer, extraInterpreterAnswer, //Does not handle attachments yet. new List <RequestGroupAttachment>(), model.LatestAnswerTimeForCustomer, model.BrokerReferenceNumber ); await _dbContext.SaveChangesAsync(); //End of service return(Ok(new GroupAnswerResponse { InterpreterId = mainInterpreterAnswer.Interpreter.InterpreterBrokerId, ExtraInterpreterId = extraInterpreterAnswer?.Interpreter?.InterpreterBrokerId })); } catch (InvalidOperationException ex) { return(ReturnError(ErrorCodes.RequestNotCorrectlyAnswered, ex.Message)); } } catch (InvalidApiCallException ex) { return(ReturnError(ex.ErrorCode)); } catch (Exception ex) { _logger.LogError(ex, "Failed to handle request group answer"); return(ReturnError(ErrorCodes.UnspecifiedProblem)); } }
public async Task AcceptGroup( RequestGroup requestGroup, DateTimeOffset answerTime, int userId, int?impersonatorId, InterpreterLocation interpreterLocation, InterpreterAnswerDto interpreter, InterpreterAnswerDto extraInterpreter, List <RequestGroupAttachment> attachedFiles, DateTimeOffset?latestAnswerTimeForCustomer, string brokerReferenceNumber ) { NullCheckHelper.ArgumentCheckNull(requestGroup, nameof(AcceptGroup), nameof(RequestService)); NullCheckHelper.ArgumentCheckNull(interpreter, nameof(AcceptGroup), nameof(RequestService)); CheckSetLatestAnswerTimeForCustomerValid(latestAnswerTimeForCustomer, nameof(AcceptGroup)); var declinedRequests = new List <Request>(); await _orderService.AddOrdersWithListsForGroupToProcess(requestGroup.OrderGroup); bool isSingleOccasion = requestGroup.OrderGroup.IsSingleOccasion; bool hasExtraInterpreter = requestGroup.HasExtraInterpreter; if (hasExtraInterpreter) { NullCheckHelper.ArgumentCheckNull(extraInterpreter, nameof(AcceptGroup), nameof(RequestService)); } ValidateInterpreters(interpreter, extraInterpreter, hasExtraInterpreter); bool hasTravelCosts = (interpreter.ExpectedTravelCosts ?? 0) > 0 || (extraInterpreter?.ExpectedTravelCosts ?? 0) > 0; var travelCostsShouldBeApproved = hasTravelCosts && requestGroup.OrderGroup.AllowExceedingTravelCost == AllowExceedingTravelCost.YesShouldBeApproved; bool partialAnswer = false; //1. Get the verification results for the interpreter(s) var verificationResult = await VerifyInterpreter(requestGroup.OrderGroup.FirstOrder.OrderId, interpreter.Interpreter, interpreter.CompetenceLevel); var extraInterpreterVerificationResult = hasExtraInterpreter && extraInterpreter.Accepted ? await VerifyInterpreter(requestGroup.OrderGroup.FirstOrder.OrderId, extraInterpreter.Interpreter, extraInterpreter.CompetenceLevel) : null; requestGroup.Requests = await _tolkDbContext.Requests.GetRequestsForRequestGroup(requestGroup.RequestGroupId).ToListAsync(); await AddPriceRowsToRequestsInGroup(requestGroup); await AddRequirementAnswersToRequestsInGroup(requestGroup); requestGroup.Requests.ForEach(r => r.Order = requestGroup.OrderGroup.Orders.Where(o => o.OrderId == r.OrderId).SingleOrDefault()); foreach (var request in requestGroup.Requests) { bool isExtraInterpreterOccasion = request.Order.IsExtraInterpreterForOrderId.HasValue; if (isExtraInterpreterOccasion) { if (extraInterpreter.Accepted) { AcceptReqestGroupRequest(request, answerTime, userId, impersonatorId, extraInterpreter, interpreterLocation, Enumerable.Empty <RequestAttachment>().ToList(), extraInterpreterVerificationResult, latestAnswerTimeForCustomer, travelCostsShouldBeApproved ); } else { partialAnswer = true; await Decline(request, answerTime, userId, impersonatorId, extraInterpreter.DeclineMessage, false, false); declinedRequests.Add(request); } } else { AcceptReqestGroupRequest(request, answerTime, userId, impersonatorId, interpreter, interpreterLocation, Enumerable.Empty <RequestAttachment>().ToList(), verificationResult, latestAnswerTimeForCustomer, travelCostsShouldBeApproved ); } } // add the attachments to the group... requestGroup.Accept(answerTime, userId, impersonatorId, attachedFiles, hasTravelCosts, partialAnswer, latestAnswerTimeForCustomer, brokerReferenceNumber); if (partialAnswer) { //Need to split the declined part of the group, and make a separate order- and request group for that, to forward to the next in line. if any... await _orderService.CreatePartialRequestGroup(requestGroup, declinedRequests); if (requestGroup.RequiresApproval(hasTravelCosts)) { _notificationService.PartialRequestGroupAnswerAccepted(requestGroup); } else { _notificationService.PartialRequestGroupAnswerAutomaticallyApproved(requestGroup); } } else { //2. Set the request group and order group in correct state if (requestGroup.RequiresApproval(hasTravelCosts)) { _notificationService.RequestGroupAccepted(requestGroup); } else { _notificationService.RequestGroupAnswerAutomaticallyApproved(requestGroup); } } }
private void AcceptReqestGroupRequest(Request request, DateTimeOffset acceptTime, int userId, int?impersonatorId, InterpreterAnswerDto interpreter, InterpreterLocation interpreterLocation, List <RequestAttachment> attachedFiles, VerificationResult?verificationResult, DateTimeOffset?latestAnswerTimeForCustomer, bool overrideRequireAccept = false) { AcceptRequest(request, acceptTime, userId, impersonatorId, interpreter.Interpreter, interpreterLocation, interpreter.CompetenceLevel, ReplaceIds(request.Order.Requirements, interpreter.RequirementAnswers).ToList(), attachedFiles, interpreter.ExpectedTravelCosts, interpreter.ExpectedTravelCostInfo, verificationResult, latestAnswerTimeForCustomer, string.Empty, overrideRequireAccept); }