예제 #1
0
 [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));
        }