[HasPermission(typeof(AttributeRequirement <CanCreateLoadCarrierReceiptRequirement>))] //TODO Create a separate Requirement for sorting public Task <ActionResult <LoadCarrierSorting> > Post( [FromBody] LoadCarrierSortingCreateRequest request) { return(this._loadCarrierSortingService.Create(request).Convert <LoadCarrierSorting>(this)); }
public async Task <IWrappedResponse> Create(LoadCarrierSortingCreateRequest request) { var loadCarrierReceipt = _olmaLoadCarrierReceiptRepo.FindByCondition(r => r.Id == request.LoadCarrierReceiptId) .Include(r => r.Positions) .Include(r => r.PostingAccount) .Include(r => r.PostingRequests) .Include(r => r.Document) .Single(); var loadCarrierSorting = Mapper.Map <Olma.LoadCarrierSorting>(request); foreach (var position in request.Positions) { var receiptPosition = loadCarrierReceipt.Positions.Single(p => p.LoadCarrierId == position.LoadCarrierId); var sortingPosition = loadCarrierSorting.Positions.Single(p => p.LoadCarrierId == position.LoadCarrierId); sortingPosition.Outputs = new List <Olma.LoadCarrierSortingResultOutput>(); var inputQuantity = receiptPosition.LoadCarrierQuantity; sortingPosition.InputQuantity = inputQuantity; foreach (var output in position.Outputs) { var inputLoadCarrier = _olmaLoadCarrierRepo.GetByKey(position.LoadCarrierId); var outputLoadCarrier = _olmaLoadCarrierRepo.FindByCondition(l => l.TypeId == inputLoadCarrier.TypeId && l.QualityId == output.LoadCarrierQualityId).Single(); var _output = new Olma.LoadCarrierSortingResultOutput() { LoadCarrierId = outputLoadCarrier.Id, LoadCarrierQuantity = output.Quantity }; sortingPosition.Outputs.Add(_output); } var sumOutputQuantities = sortingPosition.Outputs.Sum(o => o.LoadCarrierQuantity); if (sumOutputQuantities > inputQuantity) { throw new ArgumentException("Sum of output quantities does not match input"); } sortingPosition.RemainingQuantity = inputQuantity - sumOutputQuantities; } var strategy = _olmaDbContext.Database.CreateExecutionStrategy(); var result = await strategy.ExecuteAsync(async() => { await using var ctxTransaction = await _olmaDbContext.Database.BeginTransactionAsync(); // Create LoadCarrierSorting var loadCarrierSortingResult = _olmaLoadCarrierSortingRepo .Create <Olma.LoadCarrierSorting, Olma.LoadCarrierSorting, LoadCarrierSorting>(loadCarrierSorting); // Create PostingRequestsCreateRequest #region PostingRequestsCreateRequest var postingAccount = loadCarrierReceipt.PostingAccount; foreach (var receiptPosition in loadCarrierReceipt.Positions) { var sortingPosition = loadCarrierSorting.Positions.Single(p => p.LoadCarrierId == receiptPosition.LoadCarrierId); var postingRequestsCreateRequest = new PostingRequestsCreateRequest { Type = PostingRequestType.Charge, //HACK Only to fix UI, from LTMS WebApp viewpoint it would be a charge ReferenceNumber = loadCarrierReceipt.Document?.Number, Reason = PostingRequestReason.LoadCarrierReceipt, LoadCarrierReceiptId = loadCarrierReceipt.Id, RefLtmsProcessId = loadCarrierReceipt.PostingRequests.First().RefLtmsProcessId, RefLtmsTransactionId = Guid.NewGuid(), PostingAccountId = postingAccount.Id, RefLtmsProcessTypeId = (int)RefLtmsProcessType.Sorting, SourceRefLtmsAccountId = postingAccount.RefLtmsAccountId, DestinationRefLtmsAccountId = postingAccount.RefLtmsAccountId, DeliveryNoteNumber = loadCarrierReceipt.DeliveryNoteNumber, PickUpNoteNumber = loadCarrierReceipt.PickUpNoteNumber }; var debitPosition = new PostingRequestPosition //TODO: make it support 1 + n positions { LoadCarrierId = sortingPosition.LoadCarrierId, LoadCarrierQuantity = -sortingPosition.InputQuantity }; var creditPositions = sortingPosition.Outputs.Select(o => new PostingRequestPosition { LoadCarrierId = o.LoadCarrierId, LoadCarrierQuantity = o.LoadCarrierQuantity } ); var positions = new List <PostingRequestPosition>() { debitPosition }; positions.AddRange(creditPositions); postingRequestsCreateRequest.Positions = positions; var postingRequestsServiceResponse = (IWrappedResponse <IEnumerable <PostingRequest> >) await _postingRequestsService .Create(postingRequestsCreateRequest); if (postingRequestsServiceResponse.ResultType != ResultType.Created) { await ctxTransaction.RollbackAsync(); return(new WrappedResponse <LoadCarrierSorting> { ResultType = postingRequestsServiceResponse.ResultType, State = postingRequestsServiceResponse.State }); } } #endregion //Set IsSortingCompleted Flag on LoadCarrierReceipt if (loadCarrierSorting.Positions.Count == loadCarrierReceipt.Positions.Count && loadCarrierSorting.Positions.SelectMany(p => p.Outputs).Sum(o => o.LoadCarrierQuantity) == loadCarrierReceipt.Positions.Sum(p => p.LoadCarrierQuantity)) { loadCarrierReceipt.IsSortingCompleted = true; _olmaLoadCarrierRepo.Save(); } // Commit await ctxTransaction.CommitAsync(); return(loadCarrierSortingResult); }); return(Created(result.Data)); }