private async Task RemoveFromStock(OrderAuthorizedIntegrationEvent message) { using var scope = _serviceProvider.CreateScope(); var productsAvailable = new List <Product>(); var productRepository = scope.ServiceProvider.GetRequiredService <IProductRepository>(); var productIds = string.Join(",", message.Items.Select(i => i.Key)); var products = await productRepository.GetProductsById(productIds); if (products.Count != message.Items.Count) { CancelOrderWithoutStock(message); return; } foreach (var product in products) { var qty = message.Items.FirstOrDefault(p => p.Key == product.Id).Value; if (product.IsAvailable(qty)) { product.RemoveStock(qty); productsAvailable.Add(product); } } if (productsAvailable.Count != message.Items.Count) { CancelOrderWithoutStock(message); return; } foreach (var product in productsAvailable) { productRepository.Update(product); } if (!await productRepository.UnitOfWork.Commit()) { //this exception will not be market as completed and it will return to the queue to be managed later. //This needs to be checked, depends on the situation is not better to throw an exception, but manage this in a log process, etc. throw new DomainException($"Error to update the stock of the order {message.OrderId}"); } var orderItemRemovedStock = new OrderItemRemovedFromStockIntegrationEvent(message.CustomerId, message.OrderId); await _messageBus.PublishAsync(orderItemRemovedStock); //Payment API will subscribe this event }
private async Task ManageInventory(OrderAuthorizedIntegrationEvent message) { using (var scope = _serviceProvider.CreateScope()) { var productsWithStock = new List <Product>(); var productRepository = scope.ServiceProvider.GetRequiredService <IProductRepository>(); var idsProducts = string.Join(",", message.Items.Select(c => c.Key)); var products = await productRepository.GetPoductsById(idsProducts); if (products.Count != message.Items.Count) { CancelOrderWithOutStock(message); return; } foreach (var product in products) { var quantityProduct = message.Items.FirstOrDefault(p => p.Key == product.Id).Value; if (product.IsAvailable(quantityProduct)) { product.RemoveStock(quantityProduct); productsWithStock.Add(product); } } if (productsWithStock.Count != message.Items.Count) { CancelOrderWithOutStock(message); return; } foreach (var product in productsWithStock) { productRepository.Update(product); } if (!await productRepository.UnitOfWork.Commit()) { throw new DomainException($"Failed to update inventory - {message.OrderId}"); } var orderWriteOfftStock = new OrderWritedOffStockIntegrationEvent(message.CustomerId, message.OrderId); await _bus.PublishAsync(orderWriteOfftStock); } }
/// <summary> /// /// </summary> /// <param name="state"></param> State will controlled by the timer /// <returns></returns> private async void ProcessOrder(object state) { using var scope = _serviceProvider.CreateScope(); var orderQueries = scope.ServiceProvider.GetRequiredService <IOrderQueries>(); var order = await orderQueries.GetAuthorizedOrders(); if (order == null) { return; } var bus = scope.ServiceProvider.GetRequiredService <IMessageBus>(); //Send to the queue var authorizedOrder = new OrderAuthorizedIntegrationEvent(order.CustomerId, order.Id, order.Items.ToDictionary(oi => oi.ProductId, oi => oi.Qty)); await bus.PublishAsync(authorizedOrder); _logger.LogInformation($"Order ID: {order.Id} was sent to remove from the catalog stock"); }
private async void ProcessOrders(object state) { _logger.LogInformation("order processing service in progress"); using (var scope = _serviceProvider.CreateScope()) { var orderQueries = scope.ServiceProvider.GetRequiredService <IOrderQueries>(); var order = await orderQueries.GetOrdersAuthorized(); if (order == null) { return; } var bus = scope.ServiceProvider.GetRequiredService <IMessageBus>(); var orderAuthorized = new OrderAuthorizedIntegrationEvent(order.CustomerId, order.Id, order.OrderItems.ToDictionary(p => p.ProductId, p => p.Quantity)); await bus.PublishAsync(orderAuthorized); _logger.LogInformation($"Order ID: {order.Id} forwarded to CatalogAPI to manage inventory - subtract items from stock."); } }
/// <summary> /// There will have 2 consumers (Payment and Order) /// </summary> /// <param name="message"></param> private async void CancelOrderWithoutStock(OrderAuthorizedIntegrationEvent message) { var canceledOrder = new OrderCanceledIntegrationEvent(message.CustomerId, message.OrderId); await _messageBus.PublishAsync(canceledOrder); }
public async void CancelOrderWithOutStock(OrderAuthorizedIntegrationEvent message) { var orderCanceled = new OrderCanceledIntegrationEvent(message.CustomerId, message.OrderId); await _bus.PublishAsync(orderCanceled); }