public static DeliveryFormMailerModel GetDeliveryFormModel(Domain.User producer, Domain.User client, Domain.Delivery delivery, string producerSiret = null, string clientSiret = null) { var purchaseOrders = GetPurchaseOrders(delivery.PurchaseOrders); var productsToDeliver = delivery.Products .Where(p => p.RowKind == ModificationKind.ToDeliver) .Select(p => GetProductModel(p, p.RowKind)) .ToList(); var productsDiffs = delivery.Products .Where(p => p.RowKind != ModificationKind.ToDeliver) .Select(p => GetProductModel(p, p.RowKind)) .ToList(); var returnablesDiffs = delivery.Products .Where(p => p.RowKind != ModificationKind.ToDeliver && p.HasReturnable) .GroupBy(p => new { p.ReturnableId, p.RowKind }) .Select(p => { var returnable = p.First(); return(new DeliveryReturnableMailerModel { Name = returnable.ReturnableName, Quantity = returnable.Quantity, Vat = returnable.ReturnableVat.Value, RowKind = p.Key.RowKind, TotalVatPrice = p.Sum(r => r.TotalReturnableVatPrice.Value), TotalOnSalePrice = p.Sum(r => r.TotalReturnableOnSalePrice.Value), TotalWholeSalePrice = p.Sum(r => r.TotalReturnableWholeSalePrice.Value), WholeSalePrice = returnable.ReturnableWholeSalePrice.Value }); }).ToList(); var returnedReturnables = delivery.ReturnedReturnables? .Select(GetReturnedReturnableModel) .ToList() ?? new List <DeliveryReturnableMailerModel>(); var vat5Price = GetVatPriceForPercent(productsToDeliver, productsDiffs, returnedReturnables, 5.5m); var vat10Price = GetVatPriceForPercent(productsToDeliver, productsDiffs, returnedReturnables, 10m); var vat20Price = GetVatPriceForPercent(productsToDeliver, productsDiffs, returnedReturnables, 20m) + delivery.DeliveryFeesVatPrice; return(new DeliveryFormMailerModel() { Identifier = delivery.Reference.AsDeliveryIdentifier(), Producer = GetUserModel(producer, producerSiret), Client = GetUserModel(client, clientSiret), PurchaseOrders = purchaseOrders, ProductsToDeliver = productsToDeliver, ProductsDiffs = productsDiffs, ReturnedReturnables = returnedReturnables, ReturnablesDiffs = returnablesDiffs, DeliveredOn = delivery.DeliveredOn ?? delivery.ScheduledOn, ScheduledOn = delivery.ScheduledOn, ReceptionnedBy = delivery.ReceptionedBy, Comment = delivery.Comment, DeliveryFeesWholeSalePrice = delivery.DeliveryFeesWholeSalePrice, DeliveryFeesVatPrice = delivery.DeliveryFeesVatPrice, DeliveryFeesOnSalePrice = delivery.DeliveryFeesOnSalePrice, TotalWholeSalePrice = productsToDeliver.Sum(po => po.TotalWholeSalePrice) + productsDiffs.Sum(p => p.TotalWholeSalePrice) + returnedReturnables.Sum(p => p.TotalWholeSalePrice) + delivery.DeliveryFeesWholeSalePrice, TotalVat5Price = vat5Price, TotalVat10Price = vat10Price, TotalVat20Price = vat20Price, TotalVatPrice = vat5Price + vat10Price + vat20Price, TotalOnSalePrice = productsToDeliver.Sum(po => po.TotalOnSalePrice) + productsDiffs.Sum(p => p.TotalOnSalePrice) + returnedReturnables.Sum(p => p.TotalOnSalePrice) + delivery.DeliveryFeesOnSalePrice, }); }
public async Task <Result> Handle(UpdateDeliveryBatchCommand request, CancellationToken token) { var deliveryBatch = await _context.DeliveryBatches.SingleOrDefaultAsync(c => c.Id == request.Id, token); if (deliveryBatch == null) { return(Failure("La tournée de livraison est introuvable.")); } if (deliveryBatch.Status != DeliveryBatchStatus.Waiting) { return(Failure("Impossible de modifier une livraison qui n'est pas en attente.")); } var clientIds = request.Deliveries.Select(d => d.ClientId); var existingClientIds = deliveryBatch.Deliveries.Select(d => d.ClientId); var deliveriesToRemove = existingClientIds.Except(clientIds); foreach (var clientIdToRemove in deliveriesToRemove) { var delivery = deliveryBatch.Deliveries.Single(d => d.ClientId == clientIdToRemove); deliveryBatch.RemoveDelivery(delivery); _context.Remove(delivery); } var currentPosition = 0; foreach (var clientDelivery in request.Deliveries.OrderBy(d => d.Position)) { var delivery = deliveryBatch.Deliveries.SingleOrDefault(d => d.ClientId == clientDelivery.ClientId); var purchaseOrders = await _context.PurchaseOrders .Where(p => clientDelivery.PurchaseOrderIds.Contains(p.Id)) .ToListAsync(token); if (purchaseOrders.Any(po => po.Status != PurchaseOrderStatus.Completed)) { throw SheaftException.Validation("Certaines commandes ne sont pas prête."); } if (purchaseOrders.Any(po => (int)po.ExpectedDelivery.Kind <= 4)) { throw SheaftException.Validation("Certaines commandes doivent être récupérée et non livrée."); } if (delivery == null) { var order = purchaseOrders.First(); var user = await _context.Users.SingleAsync(u => u.Id == order.ClientId, token); var identifier = await _identifierService.GetNextDeliveryReferenceAsync(deliveryBatch.AssignedTo.Id, token); if (!identifier.Succeeded) { return(Failure(identifier)); } delivery = new Domain.Delivery(identifier.Data, (Domain.Producer)deliveryBatch.AssignedTo, order.ExpectedDelivery.Kind, deliveryBatch.ScheduledOn, order.ExpectedDelivery.Address, user.Id, user.Name, purchaseOrders, currentPosition); deliveryBatch.AddDelivery(delivery); } else { var existingPurchaseOrderIds = delivery.PurchaseOrders.Select(po => po.Id); var newPurchaseOrderIds = purchaseOrders.Select(po => po.Id); var purchaseOrderIdsToRemove = existingPurchaseOrderIds.Except(newPurchaseOrderIds).ToList(); if (purchaseOrderIdsToRemove.Any()) { var purchaseOrdersToRemove = delivery.PurchaseOrders.Where(po => purchaseOrderIdsToRemove.Contains(po.Id)); delivery.RemovePurchaseOrders(purchaseOrdersToRemove); } foreach (var purchaseOrder in purchaseOrders) { var existingPurchaseOrder = delivery.PurchaseOrders.SingleOrDefault(po => po.Id == purchaseOrder.Id); if (existingPurchaseOrder == null) { delivery.AddPurchaseOrders(new[] { purchaseOrder }); } } } delivery.SetPosition(currentPosition); currentPosition++; } deliveryBatch.SetName(request.Name); await _context.SaveChangesAsync(token); var result = await _mediatr.Process(new GenerateDeliveryBatchDocumentsCommand(request.RequestUser){ Id = deliveryBatch.Id }, token); return(result is { Succeeded : false } ? Failure(result) : Success());
public async Task <Result <Guid> > Handle(CreateDeliveryBatchCommand request, CancellationToken token) { var purchaseOrders = await GetPurchaseOrdersAsync(request, token); if (purchaseOrders.Any(po => po.Status == PurchaseOrderStatus.Delivered)) { return(Failure <Guid>("Certaines commandes ont déjà été livrées.")); } if (purchaseOrders.Any(po => (int)po.ExpectedDelivery.Kind <= 4)) { return(Failure <Guid>("Impossible d'ajouter des commandes qui sont à récupérer par le client.")); } var name = GetDeliveryBatchName(request, purchaseOrders); var producer = await _context.Producers.SingleAsync(p => p.Id == request.ProducerId, token); var usersAgreements = await GetUsersPositionsAsync(request, token, purchaseOrders); var purchaseOrderIds = request.Deliveries.SelectMany(d => d.PurchaseOrderIds); var purchaseOrdersDeliveries = await _context.Deliveries.Where(d => d.PurchaseOrders.Any(po => purchaseOrderIds.Contains(po.Id))) .Include(d => d.PurchaseOrders) .ToListAsync(token); var deliveries = new List <Domain.Delivery>(); foreach (var delivery in purchaseOrdersDeliveries) { var assignedPurchaseOrders = delivery.PurchaseOrders .Where(po => purchaseOrderIds.Contains(po.Id)) .ToList(); if (delivery.PurchaseOrders.Count == assignedPurchaseOrders.Count) { if (delivery.DeliveryBatchId.HasValue && delivery.DeliveryBatch.ScheduledOn != request.ScheduledOn) { delivery.PostponeDelivery(); } deliveries.Add(delivery); foreach (var assignedPurchaseOrder in assignedPurchaseOrders) { var pendingPurchaseOrder = purchaseOrders.Single(po => po.Id == assignedPurchaseOrder.Id); purchaseOrders.Remove(pendingPurchaseOrder); } } else { delivery.RemovePurchaseOrders(assignedPurchaseOrders); var identifier = await _identifierService.GetNextDeliveryReferenceAsync(producer.Id, token); if (!identifier.Succeeded) { return(Failure <Guid>(identifier)); } var newDelivery = new Domain.Delivery(identifier.Data, producer, delivery.Kind, request.ScheduledOn, delivery.Address, delivery.ClientId, delivery.Client, assignedPurchaseOrders, delivery.Position); if (delivery.DeliveryBatch != null && delivery.DeliveryBatch.ScheduledOn != request.ScheduledOn) { newDelivery.PostponeDelivery(); } deliveries.Add(newDelivery); } } foreach (var purchaseOrderGrouped in purchaseOrders .GroupBy(p => p.ClientId) .OrderByDescending(e => e.Count()) .ToList()) { var order = purchaseOrderGrouped.First(); var existingDelivery = deliveries.SingleOrDefault(d => d.ClientId == order.ClientId); if (existingDelivery != null) { if (existingDelivery.PurchaseOrders.Any(po => po.Id == order.Id)) { continue; } existingDelivery.AddPurchaseOrders(new[] { order }); } else { var userAgreement = usersAgreements.First(a => a.User.Id == order.ClientId); var position = userAgreement?.Position ?? 0; while (deliveries.Any(d => d.Position == position)) { position++; } var identifier = await _identifierService.GetNextDeliveryReferenceAsync(producer.Id, token); if (!identifier.Succeeded) { return(Failure <Guid>(identifier)); } var delivery = new Domain.Delivery(identifier.Data, producer, order.ExpectedDelivery.Kind, request.ScheduledOn, order.ExpectedDelivery.Address, userAgreement.User.Id, userAgreement.User.Name, purchaseOrderGrouped.ToList(), position); deliveries.Add(delivery); } } var deliveryBatch = new Domain.DeliveryBatch(Guid.NewGuid(), name, request.ScheduledOn, request.From, producer, deliveries, request.CreatedFromPartialBatchId); if (request.CreatedFromPartialBatchId.HasValue) { foreach (var delivery in deliveries) { delivery.PostponeDelivery(); } } await _context.AddAsync(deliveryBatch, token); await _context.SaveChangesAsync(token); if (request.SetAsReady) { _mediatr.Post(new SetDeliveryBatchAsReadyCommand(request.RequestUser) { Id = deliveryBatch.Id }); } var result = await _mediatr.Process(new GenerateDeliveryBatchDocumentsCommand(request.RequestUser){ Id = deliveryBatch.Id }, token); return(result is { Succeeded : false } ? Failure <Guid>(result) : Success(deliveryBatch.Id));