Interface IShippingCalculator
Shipping calculator calculates shipping totals
Namespace: EPiServer.Commerce.Order
Assembly: Mediachase.Commerce.dll
Version: 10.8.0Syntax
public interface IShippingCalculator
Examples
/// <summary>
/// Sample implementation of <see cref="IShippingCalculator"/>.
/// </summary>
public class ShippingCalculatorSample : IShippingCalculator
{
private readonly ILineItemCalculator _lineItemCalculator;
private readonly ServiceCollectionAccessor<IShippingPlugin> _shippingPluginsAccessor;
private readonly IReturnLineItemCalculator _returnLineItemCalculator;
private readonly ITaxCalculator _taxCalculator;
public ShippingCalculatorSample(
ILineItemCalculator lineItemCalculator,
IReturnLineItemCalculator returnLineItemCalculator,
ITaxCalculator taxCalculator,
ServiceCollectionAccessor<IShippingPlugin> shippingPluginsAccessor)
{
_lineItemCalculator = lineItemCalculator;
_returnLineItemCalculator = returnLineItemCalculator;
_taxCalculator = taxCalculator;
_shippingPluginsAccessor = shippingPluginsAccessor;
}
[Obsolete("This method is no longer used, use IOrderGroupCalculator.GetShippingSubTotal instead.")]
public Money GetShippingCost(IOrderGroup orderGroup, IMarket market, Currency currency)
{
var orderGroupCalculator = ServiceLocator.Current.GetInstance<IOrderGroupCalculator>();
return orderGroupCalculator.GetShippingSubTotal(orderGroup);
}
[Obsolete("This method is no longer used, use IOrderFormCalculator.GetShippingSubTotal instead.")]
public Money GetShippingCost(IOrderForm orderForm, IMarket market, Currency currency)
{
var orderFormCalculator = ServiceLocator.Current.GetInstance<IOrderFormCalculator>();
return orderFormCalculator.GetShippingSubTotal(orderForm, market, currency);
}
public Money GetShippingCost(IShipment shipment, IMarket market, Currency currency)
{
var zeroMoney = new Money(0m, currency);
var allShippingMethods = ShippingManager.GetShippingMethods(string.Empty);
var row = allShippingMethods.ShippingMethod.FindByShippingMethodId(shipment.ShippingMethodId);
if (row == null)
{
return zeroMoney;
}
var type = Type.GetType(row.ShippingOptionRow.ClassName);
var provider = _shippingPluginsAccessor().First(s => s.GetType() == type);
var message = string.Empty;
var rate = provider.GetRate(market, row.ShippingMethodId, shipment, ref message);
if (rate == null)
{
throw new Exception(string.Format("There is no rate configured for the shipping method {0}: {1}",
row.ShippingOptionRow.ClassName, message));
}
if (!CurrencyFormatter.CanBeConverted(rate.Money, currency))
{
throw new InvalidOperationException(
string.Format("Cannot convert selected shipping's currency({0}) to the target currency({1}).",
rate.Money.Currency.CurrencyCode, currency.CurrencyCode));
}
return CurrencyFormatter.ConvertCurrency(rate.Money, currency);
}
public Money GetDiscountedShippingAmount(IShipment shipment, IMarket market, Currency currency)
{
//It's the shipping cost with all shipping discounts applied on the shipment.
return GetShippingCost(shipment, market, currency) - shipment.GetShipmentDiscountPrice(currency);
}
public Money GetShippingItemsTotal(IShipment shipment, Currency currency)
{
var itemsTotalAmount = shipment.LineItems
.Where(x => x.Quantity > 0 && !x.IsGift) // Gift items should not be included in the calculation.
.Sum(lineItem => _lineItemCalculator.GetDiscountedPrice(lineItem, currency).Amount);
return new Money(itemsTotalAmount, currency);
}
public Money GetShippingReturnItemsTotal(IShipment shipment, Currency currency)
{
//NOTE: the shipment must belong to an IReturnOrderForm.
var itemsTotalAmount = shipment.LineItems.OfType<IReturnLineItem>()
.Where(x => x.ReturnQuantity > 0 && !x.IsGift) // Gift items should be excluded from the calculation.
.Sum(returnLineItem => _returnLineItemCalculator.GetDiscountedPrice(returnLineItem, currency).Amount);
return new Money(itemsTotalAmount, currency);
}
public Money GetShipmentDiscountPrice(IShipment shipment, Currency currency)
{
return shipment.GetShipmentDiscountPrice(currency);
}
public ShippingTotals GetShippingTotals(IShipment shipment, IMarket market, Currency currency)
{
var shippingSubtotal = GetShippingItemsTotal(shipment, currency);
var shippingCost = GetShippingCost(shipment, market, currency);
var shippingTax = GetShippingTax(shipment, market, currency);
var lineItemPricesDictionary = shipment.LineItems.ToDictionary(item => item, item => _lineItemCalculator.GetLineItemPrices(item, currency));
return new ShippingTotals(shippingSubtotal, shippingCost, shippingTax, lineItemPricesDictionary);
}
public Money GetShippingTax(IShipment shipment, IMarket market, Currency currency)
{
var shipmentSubtotal = GetShippingItemsTotal(shipment, currency);
return CalculateShippingTax(shipment, market, currency, shipmentSubtotal,
(item, curr) => _lineItemCalculator.GetDiscountedPrice(item, curr),
item => item.Quantity);
}
public Money GetSalesTax(IShipment shipment, IMarket market, Currency currency)
{
var shippingAddress = shipment.ShippingAddress;
if (shippingAddress == null)
{
// The tax rate depends on the shipping address - where line items will be shipped to.
return new Money(0m, currency);
}
var salesTaxAmount = shipment.LineItems
.Where(x => x.Quantity > 0 && !x.IsGift) // Gift items should be excluded from the calculation.
.Sum(item => _lineItemCalculator.GetSalesTax(item, market, currency, shippingAddress).Amount);
return new Money(salesTaxAmount, currency);
}
public Money GetReturnShippingTax(IShipment shipment, IMarket market, Currency currency)
{
var shipmentSubtotal = GetShippingReturnItemsTotal(shipment, currency);
return CalculateShippingTax(shipment, market, currency, shipmentSubtotal,
(item, curr) => _returnLineItemCalculator.GetDiscountedPrice((IReturnLineItem)item, curr),
item => item.ReturnQuantity);
}
public Money GetReturnSalesTax(IShipment shipment, IMarket market, Currency currency)
{
var shippingAddress = shipment.ShippingAddress;
if (shippingAddress == null)
{
// The tax rate depends on the shipping address - where line items will be shipped to.
return new Money(0m, currency);
}
var returnSalesTaxAmount = shipment.LineItems.OfType<IReturnLineItem>()
.Where(x => x.ReturnQuantity > 0 && !x.IsGift) // Gift items should be excluded from the calculation.
.Sum(returnItem => _returnLineItemCalculator.GetSalesTax(returnItem, market, currency, shippingAddress).Amount);
return new Money(returnSalesTaxAmount, currency);
}
public ShippingTotals GetReturnShippingTotals(IShipment shipment, Currency currency)
{
var zeroMoney = new Money(0, currency);
var total = GetShippingReturnItemsTotal(shipment, currency);
var lineItemPrices = shipment.LineItems
.ToDictionary(item => item, item => _returnLineItemCalculator.GetLineItemPrices((IReturnLineItem)item, currency));
// A return shipment doesn't include any shipping cost and shipping tax.
return new ShippingTotals(total, zeroMoney, zeroMoney, lineItemPrices);
}
private Money CalculateShippingTax(
IShipment shipment,
IMarket market,
Currency currency,
Money shipmentSubtotal,
Func<ILineItem, Currency, Money> getDiscountedPriceFunction,
Func<ILineItem, decimal> getQuantityFunction)
{
// The tax rate depends on the shipping address - where line items will be shipped to.
if (shipment.ShippingAddress == null)
{
return new Money(0m, currency);
}
var shippingTax = 0m;
var shippingSubTotal = GetDiscountedShippingAmount(shipment, market, currency).Amount;
var lineItemsQuantity = shipment.LineItems.Sum(lineItem => getQuantityFunction(lineItem));
foreach (var item in shipment.LineItems)
{
var quantity = getQuantityFunction(item);
if (quantity <= 0)
{
continue;
}
//The base price used to calculate shipping tax for a line item is the discounted price of the line item distributed on every quantity of the line item.
var itemDiscountedPrice = getDiscountedPriceFunction(item, currency).Amount;
var itemShippingSubTotalAmount = shippingSubTotal * (shipmentSubtotal.Amount == 0 ? quantity / lineItemsQuantity : itemDiscountedPrice / shipmentSubtotal.Amount);
var itemShippingSubTotal = new Money(itemShippingSubTotalAmount, currency);
shippingTax += _taxCalculator.GetShippingTax(item, market, shipment.ShippingAddress, itemShippingSubTotal).Amount;
}
return new Money(shippingTax, currency).Round();
}
}
Methods
GetDiscountedShippingAmount(IShipment, IMarket, Currency)
Gets the discounted shipping amount for the shipment
Declaration
Money GetDiscountedShippingAmount(IShipment shipment, IMarket market, Currency currency)
Parameters
Type | Name | Description |
---|---|---|
IShipment | shipment | The shipment |
IMarket | market | The market to be used in the calculation. |
Currency | currency | The currency to be used in the calculations |
Returns
Type | Description |
---|---|
Money | The discounted subtotal of the shipment. |
Examples
GetShipmentDiscountPrice(IShipment, Currency)
Gets the shipment discount price.
Declaration
Money GetShipmentDiscountPrice(IShipment shipment, Currency currency)
Parameters
Type | Name | Description |
---|---|---|
IShipment | shipment | The shipment. |
Currency | currency | The currency. |
Returns
Type | Description |
---|---|
Money | The shipment discount price. |
GetShippingCost(IOrderForm, IMarket, Currency)
Gets the shipping cost of the orderForm
Declaration
Money GetShippingCost(IOrderForm orderForm, IMarket market, Currency currency)
Parameters
Type | Name | Description |
---|---|---|
IOrderForm | orderForm | The order form |
IMarket | market | The market to be used in the calculation. |
Currency | currency | The currency to be used in the calculations |
Returns
Type | Description |
---|---|
Money | The shipping cost of the order form. |
Examples
GetShippingCost(IOrderGroup, IMarket, Currency)
Gets the shipping cost of the orderGroup
Declaration
Money GetShippingCost(IOrderGroup orderGroup, IMarket market, Currency currency)
Parameters
Type | Name | Description |
---|---|---|
IOrderGroup | orderGroup | the order group |
IMarket | market | The market to be used in the calculation. |
Currency | currency | The currency to be used in the calculations |
Returns
Type | Description |
---|---|
Money | The shipping cost of the order group. |
Examples
GetShippingCost(IShipment, IMarket, Currency)
Gets the shipping cost of the shipment
Declaration
Money GetShippingCost(IShipment shipment, IMarket market, Currency currency)
Parameters
Type | Name | Description |
---|---|---|
IShipment | shipment | The shipment |
IMarket | market | The market to be used in the calculation. |
Currency | currency | The currency to be used in the calculations |
Returns
Type | Description |
---|---|
Money | The shipping cost of the shipment. |
Examples
GetShippingItemsTotal(IShipment, Currency)
Gets the total of extended prices for all line items in the shipment.
Declaration
Money GetShippingItemsTotal(IShipment shipment, Currency currency)
Parameters
Type | Name | Description |
---|---|---|
IShipment | shipment | The shipment |
Currency | currency | The currency to be used in the calculations |
Returns
Type | Description |
---|---|
Money | The subtotal of the shipment. |
Examples