Hide menu Last updated: Jul 14 2016

Order processing

When processing orders in Episerver commerce, please refer to the namespace EPiServer.Commerce.Order, specifically classes EPiServer.Commerce.Order.IOrderGroupExtensions, EPiServer.Commerce.Order.IInventoryProcessor, EPiServer.Commerce.Order.ILineItemValidator, EPiServer.Commerce.Order.IPaymentProcessor, EPiServer.Commerce.Order.IPlacedPriceProcessor, and EPiServer.Commerce.Order.IFulfillmentWarehouseProcessor, EPiServer.Commerce.Marketing.IPromotionEngine.  All samples below pass the dependencies to the extension methods to be able to easily unit test your applications.

Validation Issues

When performing different processing actions on an IOrderGroup, issues can cause modifications to line items.  These warnings and errors are represented in the class EPiServer.Commerce.Order.ValidationIssue.  Most processing tasks take a parameter with an Action<ILineItem, ValidationIssue>, which allows the caller to collect this information so a message can be displayed back to the user regarding the issue.

Validate line item

Validating the status of line item is useful to make sure the product is active, within the valid date range, and that the catalog entry is available in the current market.

var orderRepository = ServiceLocator.Current.GetInstance<IOrderRepository>();
var lineItemValidator = ServiceLocator.Current.GetInstance<ILineItemValidator>();
var contactId = PrincipalInfo.CurrentPrincipal.GetContactId();
var cart = orderRepository.LoadCart(contactId, "Default");
var validationIssues = new Dictionary<ILineItem, ValidationIssue>();

//Check all line items on cart
cart.ValidateOrRemoveLineItems((item, issue) => validationIssues.Add(item, issue), lineItemValidator);

//Check one lineitem
var lineItem = cart.GetAllLineItems().First();
if (!lineItemValidator.Validate(lineItem, cart.Market, (item, issue) => validationIssues.Add(item, issue)))
{
    //Check validationIssues for problems
}

Update placed price

Updating placed price is useful when an shopper has an item in their cart for an extended period of time. It is wise to check if the product price has changed and, if so, to update the price so the business does not lose money.

var orderRepository = ServiceLocator.Current.GetInstance<IOrderRepository>();
var placedPriceProcessor = ServiceLocator.Current.GetInstance<IPlacedPriceProcessor>();
var contactId = PrincipalInfo.CurrentPrincipal.GetContactId();
var cart = orderRepository.LoadCart(contactId, "Default");
var validationIssues = new Dictionary<ILineItem, ValidationIssue>();

//Update all placed prices on the cart
cart.UpdatePlacedPriceOrRemoveLineItems(PrincipalInfo.CurrentPrincipal.GetCustomerContact(), (item, issue) => validationIssues.Add(item, issue), placedPriceProcessor);

//Update line item placed price
var lineItem = cart.GetAllLineItems().First();
lineItem.UpdatePlacedPrice(PrincipalInfo.CurrentPrincipal.GetCustomerContact(), cart.Market, cart.Currency,(item, issue) => validationIssues.Add(item, issue), placedPriceProcessor);

//Update line item placed price
var lineItem = cart.GetAllLineItems().First();
placedPriceProcessor.UpdatePlacedPrice(lineItem, PrincipalInfo.CurrentPrincipal.GetCustomerContact(), cart.Market, cart.Currency,(item, issue) => validationIssues.Add(item, issue));

Apply Discount

Applying discounts will run the promotion engine to evaluate and apply discounts to the IOrderGroup.  It is important to add coupons to the IOrderForm before running apply discounts if certain discounts require coupons.

var orderRepository = ServiceLocator.Current.GetInstance<IOrderRepository>();
var promotionEngine = ServiceLocator.Current.GetInstance<IPromotionEngine>();
var contactId = PrincipalInfo.CurrentPrincipal.GetContactId();
var cart = orderRepository.LoadCart(contactId, "Default");

//run apply discounts on the cart
var rewardDescriptions = cart.ApplyDiscounts(promotionEngine, new PromotionEngineSettings());

//run apply discounts on the cart
var rewardDescriptions = promotionEngine.Run(cart, new PromotionEngineSettings());

Process Payments

Process payments allow the configured payments to be processed through their respective payment providers.

var orderRepository = ServiceLocator.Current.GetInstance<IOrderRepository>();
var paymentProcessor = ServiceLocator.Current.GetInstance<IPaymentProcessor>();
var orderGroupCalculator = ServiceLocator.Current.GetInstance<IOrderGroupCalculator>();
var contactId = PrincipalInfo.CurrentPrincipal.GetContactId();
var cart = orderRepository.LoadCart(contactId, "Default");


//Process payments for the cart
cart.ProcessPayments(paymentProcessor, orderGroupCalculator);

Update Inventory

Update inventory checks that a sufficient inventory quantity exists for the selected shipment warehouse. This method also updates the line item with the available quantity or, if none are available, removes it.

var orderRepository = ServiceLocator.Current.GetInstance<IOrderRepository>();
var inventoryProcessor = ServiceLocator.Current.GetInstance<IInventoryProcessor>();
var contactId = PrincipalInfo.CurrentPrincipal.GetContactId();
var cart = orderRepository.LoadCart(contactId, "Default");
var validationIssues = new Dictionary<ILineItem, ValidationIssue>();

//Update Inventory on cart
cart.UpdateInventoryOrRemoveLineItems((item, issue) => validationIssues.Add(item, issue), inventoryProcessor);

//Update inventory on shipment line items
var shipment = cart.GetFirstShipment();
inventoryProcessor.UpdateInventoryOrRemoveLineItem(shipment, (item, issue) => validationIssues.Add(item, issue));

Adjust Inventory

Adjusts inventory for each line item and removes it if no inventory exists. This operation is done in sequence for each shipment in an IOrderGroup, or for a specific shipment if the IInventoryProcessor method is called directly.

The behavior changes based on the value of the IOrderGroup's OrderStatus property. If calling the IInventoryProcessor directly, you should pass the status of the shipment's parent IOrderGroup:

  • Completed - permanents the reservation of inventory, decrementing available quantity.
  • Cancelled - cancels the reservation of inventory, incrementing available quantity.
  • InProgress || AwaitingExchange - reserves inventory to fulfill the shipment.

In addition, the value of IShipment.OrderShipmentStatus may override the behavior for a specific shipment:

  • Shipped - same behavior as OrderStatus.Completed but is applied regardless of the value of IOrderGroup.OrderStatus.
  • Cancelled - same behavior as OrderStatus.Cancelled but is applied regardless of the value of IOrderGroup.OrderStatus.
var orderRepository = ServiceLocator.Current.GetInstance<IOrderRepository>();
var inventoryProcessor = ServiceLocator.Current.GetInstance<IInventoryProcessor>();
var contactId = PrincipalInfo.CurrentPrincipal.GetContactId();
var cart = orderRepository.LoadCart(contactId, "Default");
var validationIssues = new Dictionary<ILineItem, ValidationIssue>();

//Adjust Inventory on cart
cart.AdjustInventoryOrRemoveLineItems((item, issue) => validationIssues.Add(item, issue), inventoryProcessor);

//Adjust inventory on shipment line items
var shipment = cart.GetFirstShipment();
inventoryProcessor.AdjustInventoryOrRemoveLineItems(shipment, cart.OrderStatus, (item, issue) => validationIssues.Add(item, issue));

Comments

Dont really understand the difference between "Update inventory" and "Adjust inventory" or the meaning of Update..  i guess "ValidateOrRemoveLineItems" does that already.. 


Adjust actually adjusts the "Inventory Record" and removes one item from "PurchaseAvailableQuantity" and add one to "PurchaseRequestedQuantity" 

I dont really understand how we should work with inventory..  

UpdateInventoryOrRemoveLineItem checks if the quantity is enough, also it checks for Min/MaxQuantity allowed for the SKU and change the quantity of the lineitems for that information. If the SKU has no stock, or MaxQuantity = 0, then it will remove the lineitem from the cart.

AdjustInventoryOrRemoveLineItems actually requests the inventory system to allocate the inventory for the lineitems. If it fails to do that (the SKU is out of stock, for example), it will remove the lineitem from the cart.

thank you for the answer,  follow up questions:

1. Whats the difference between UpdateInventoryOrRemoveLineItem and ValidateOrRemoveLineItems? Are both really needed? 

2. Do we need to trigger "AdjustInventoryOrRemoveLineItems" manually or is it or similar triggered by some other events? for example when creating purchase order. (its not but im just fishing here :) )

3.We have AdjustInventoryOrRemoveLineItems making a decrease of "PurchaseAvailableQuantity" and increase of "PurchaseRequestedQuantity" but what triggers a decrease of "PurchaseRequestedQuantity"?

Even when we set order to status completed the "PurchaseRequestedQuantity" still remains same.. what conditions needs to be fulfilled to have it actually decrease or do we need to set it manualy?

  1. ValidateOrRemoveLineItems checks the dates of the sku and if it is active.  If you dont care about those you do not need.
  2. You need to expclitly call it if you are not using workflows.
  3. When the order is shipped in commerce manager then the reservation is completed.  If you are not using commerce manager than you can call 
    AdjustInventoryOrRemoveLineItem after setting the status.