예제 #1
0
        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
        }
예제 #2
0
        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);
            }
        }
예제 #3
0
        /// <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");
        }
예제 #4
0
        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.");
            }
        }
예제 #5
0
 /// <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);
 }
예제 #6
0
 public async void CancelOrderWithOutStock(OrderAuthorizedIntegrationEvent message)
 {
     var orderCanceled = new OrderCanceledIntegrationEvent(message.CustomerId, message.OrderId);
     await _bus.PublishAsync(orderCanceled);
 }