public async Task <Result <Guid> > Handle(CreatePurchaseOrderFromOrderCommand request, CancellationToken token) { var producer = await _context.Producers.SingleAsync(e => e.Id == request.ProducerId, token); var order = await _context.Orders.SingleAsync(e => e.Id == request.OrderId, token); var delivery = order.Deliveries.FirstOrDefault(d => d.DeliveryMode.ProducerId == producer.Id); var resultIdentifier = await _identifierService.GetNextPurchaseOrderReferenceAsync(request.ProducerId, token); if (!resultIdentifier.Succeeded) { return(Failure <Guid>(resultIdentifier)); } var purchaseOrder = order.AddPurchaseOrder(resultIdentifier.Data, producer); await _context.SaveChangesAsync(token); if (delivery.DeliveryMode.MaxPurchaseOrdersPerTimeSlot.HasValue) { await _tableService.IncreaseProducerDeliveryCountAsync(producer.Id, delivery.DeliveryModeId, purchaseOrder.ExpectedDelivery.ExpectedDeliveryDate, purchaseOrder.ExpectedDelivery.From, purchaseOrder.ExpectedDelivery.To, delivery.DeliveryMode.MaxPurchaseOrdersPerTimeSlot.Value, token); } if (delivery.DeliveryMode.AutoAcceptRelatedPurchaseOrder) { _mediatr.Post(new AcceptPurchaseOrderCommand(new RequestUser { Email = producer.Email, Id = producer.Id, Name = producer.Name, Roles = new List <string> { _roles.Producer.Value, _roles.Owner.Value } }) { PurchaseOrderId = purchaseOrder.Id, SkipNotification = false }); } return(Success(purchaseOrder.Id)); }
public async Task <Result <Guid> > Handle(CreatePurchaseOrderCommand request, CancellationToken token) { var producer = await _context.Producers.SingleAsync(e => e.Id == request.ProducerId, token); var client = await _context.Users.SingleAsync(e => e.Id == request.ClientId, token); var deliveryMode = await _context.DeliveryModes.SingleAsync( d => d.Id == request.DeliveryModeId && d.ProducerId == producer.Id, token); if (client.Kind == ProfileKind.Consumer) { return(Failure <Guid>( "Cette fonction ne peux être utilisée que pour créer des commandes pour les professionels.")); } if (request.Products == null || !request.Products.Any()) { return(Failure <Guid>( "Vous devez ajouter des produits à votre commande.")); } if (request.Products.Any(p => p.Quantity <= 0)) { return(Failure <Guid>( "Un ou plusieurs produits possèdent une quantité inférieure ou égale à 0.")); } if (request.ExpectedDeliveryDate < DateTimeOffset.UtcNow) { return(Failure <Guid>( "La date de livraison ne peut être inférieure à aujourd'hui.")); } if (request.From > request.To) { return(Failure <Guid>( "L'heure de début ne peut être supérieure à l'heure de fin.")); } var productsQuantity = new List <KeyValuePair <Domain.Product, int> >(); var productIds = request.Products.Select(p => p.Id).Distinct(); var products = await _context.Products .Where(p => productIds.Contains(p.Id) && p.ProducerId == producer.Id) .ToListAsync(token); Domain.Catalog catalog = null; var agreement = await _context.Agreements.SingleAsync( a => a.StoreId == client.Id && a.ProducerId == producer.Id && a.Status == AgreementStatus.Accepted, token); if (agreement != null) { catalog = agreement.Catalog; } catalog ??= await _context.Catalogs.SingleAsync( c => c.ProducerId == producer.Id && c.Kind == CatalogKind.Stores && c.Available && c.IsDefault, token); foreach (var product in products) { var quantity = request.Products.Where(p => p.Id == product.Id).Sum(p => p.Quantity); productsQuantity.Add(new KeyValuePair <Domain.Product, int>(product, quantity ?? 0)); } var resultIdentifier = await _identifierService.GetNextPurchaseOrderReferenceAsync(request.ProducerId, token); if (!resultIdentifier.Succeeded) { return(Failure <Guid>(resultIdentifier)); } var purchaseOrder = new Domain.PurchaseOrder(Guid.NewGuid(), resultIdentifier.Data, PurchaseOrderStatus.Accepted, request.ExpectedDeliveryDate, request.From, request.To, deliveryMode, producer, client, productsQuantity, catalog, request.SkipNotification, request.Comment); await _context.AddAsync(purchaseOrder, token); await _context.SaveChangesAsync(token); if (deliveryMode.MaxPurchaseOrdersPerTimeSlot.HasValue) { await _tableService.IncreaseProducerDeliveryCountAsync(producer.Id, deliveryMode.Id, request.ExpectedDeliveryDate, request.From, request.To, deliveryMode.MaxPurchaseOrdersPerTimeSlot.Value, token); } return(Success(purchaseOrder.Id)); }