CustomerOrder.Actor.CustomerOrderActor.FulfillOrderAsync C# (CSharp) Méthode

FulfillOrderAsync() private méthode

This method takes in a list of CustomerOrderItem objects. Using a Service Proxy to access the Inventory Service, the method iterates onces through the order and tries to remove the quantity specified in the order from inventory. If the inventory has insufficient stock to remove the requested amount for a particular item, the entire order is marked as backordered and the item in question is added to a "backordered" item list, which is fulfilled in a separate method. In its current form, this application addresses the question of race conditions to remove the same item by making a rule that no order ever fails. While an item that is displayed in the store may not be available any longer by the time an order is placed, the automatic restock policy instituted in the Inventory Service means that our FulfillOrder method and its sub-methods can continue to query the Inventory Service on repeat (with a timer in between each cycle) until the order is fulfilled.
private FulfillOrderAsync ( ) : Task
Résultat Task
        internal async Task FulfillOrderAsync()
        {

            await this.SetOrderStatusAsync(CustomerOrderStatus.InProcess);

            IList<CustomerOrderItem> orderedItems = await this.StateManager.GetStateAsync<IList<CustomerOrderItem>>(OrderItemListPropertyName);

            ActorEventSource.Current.ActorMessage(this, "Fullfilling customer order. ID: {0}. Items: {1}", this.Id.GetGuidId(), orderedItems.Count);

            foreach (CustomerOrderItem tempitem in orderedItems)
            {
                ActorEventSource.Current.Message("OrderContains:{0}", tempitem);
            }

            //We loop through the customer order list. 
            //For every item that cannot be fulfilled, we add to backordered. 
            foreach (CustomerOrderItem item in orderedItems.Where(x => x.FulfillmentRemaining > 0))
            {
                IInventoryService inventoryService = this.ServiceProxyFactory.CreateServiceProxy<IInventoryService>(this.builder.ToUri(), item.ItemId.GetPartitionKey());

                //First, check the item is listed in inventory.  
                //This will avoid infinite backorder status.
                if ((await inventoryService.IsItemInInventoryAsync(item.ItemId, this.tokenSource.Token)) == false)
                {
                    await this.SetOrderStatusAsync(CustomerOrderStatus.Canceled);
                    return;
                }

                int numberItemsRemoved =
                    await
                        inventoryService.RemoveStockAsync(
                            item.ItemId,
                            item.Quantity,
                            new CustomerOrderActorMessageId(
                                new ActorId(this.Id.GetGuidId()),
                                await this.StateManager.GetStateAsync<long>(RequestIdPropertyName)));

                item.FulfillmentRemaining -= numberItemsRemoved;
            }

            IList<CustomerOrderItem> items = await this.StateManager.GetStateAsync<IList<CustomerOrderItem>>(OrderItemListPropertyName);
            bool backordered = false;

            // Set the status appropriately
            foreach (CustomerOrderItem item in items)
            {
                if (item.FulfillmentRemaining > 0)
                {
                    backordered = true;
                    break;
                }
            }

            if (backordered)
            {
                await this.SetOrderStatusAsync(CustomerOrderStatus.Backordered);
            }
            else
            {
                await this.SetOrderStatusAsync(CustomerOrderStatus.Shipped);
            }

            ActorEventSource.Current.ActorMessage(
                this,
                "{0}; Fulfilled: {1}. Backordered: {2}",
                await this.GetOrderStatusAsStringAsync(),
                items.Count(x => x.FulfillmentRemaining == 0),
                items.Count(x => x.FulfillmentRemaining > 0));

            long messageRequestId = await this.StateManager.GetStateAsync<long>(RequestIdPropertyName);
            await this.StateManager.SetStateAsync<long>(RequestIdPropertyName, ++messageRequestId);
        }

Usage Example

        public async Task TestFulfillOrderSimple()
        {
            // The default mock inventory service behavior is to always complete an order.
            MockInventoryService inventoryService = new MockInventoryService();

            MockServiceProxy serviceProxy = new MockServiceProxy();
            serviceProxy.Supports<IInventoryService>(serviceUri => inventoryService);

            CustomerOrderActor target = new CustomerOrderActor();

            PropertyInfo idProperty = typeof(Actor).GetProperty("Id");
            idProperty.SetValue(target, new ActorId(Guid.NewGuid()));

            target.ServiceProxy = serviceProxy;

            await target.StateManager.SetStateAsync<CustomerOrderStatus>(RequestIdPropertyName, CustomerOrderStatus.Submitted);
            await target.StateManager.SetStateAsync<long>(RequestIdPropertyName, 0);
            await target.StateManager.SetStateAsync<List<CustomerOrderItem>>(OrderItemListPropertyName, new List<CustomerOrderItem>()
            {
                new CustomerOrderItem(new InventoryItemId(), 4)
            });

            await target.FulfillOrderAsync();

            Assert.AreEqual<CustomerOrderStatus>(CustomerOrderStatus.Shipped, await target.StateManager.GetStateAsync<CustomerOrderStatus>(OrderStatusPropertyName));
        }
All Usage Examples Of CustomerOrder.Actor.CustomerOrderActor::FulfillOrderAsync