Calculators
Performing calculations with Calculators in Umbraco Commerce.
Defining a Custom Calculator Implementation
public class VolumeDiscountProductCalculator : ProductCalculatorBase
{
private readonly ITaxService _taxService;
private readonly IStoreService _storeService;
public VolumeDiscountProductCalculator(ITaxService taxService, IStoreService storeService)
{
_taxService = taxService;
_storeService = storeService;
}
public override async Task<Attempt<TaxRate>> TryCalculateProductTaxRateAsync(
IProductSnapshot productSnapshot,
TaxSource taxSource,
TaxRate fallbackTaxRate,
ProductCalculatorContext context = null,
CancellationToken cancellationToken = default)
{
productSnapshot.MustNotBeNull(nameof(productSnapshot));
fallbackTaxRate.MustNotBeNull(nameof(fallbackTaxRate));
TaxRate taxRate = fallbackTaxRate;
// Use the product's tax class if one is assigned
if (productSnapshot.TaxClassId != null)
{
taxRate = (await _taxService.GetTaxClassAsync(productSnapshot.TaxClassId.Value))
.GetTaxRate(taxSource);
}
return Attempt.Succeed(taxRate);
}
public override async Task<Attempt<Price>> TryCalculateProductPriceAsync(
IProductSnapshot productSnapshot,
Guid currencyId,
TaxRate taxRate,
ProductCalculatorContext context = null,
CancellationToken cancellationToken = default)
{
taxRate.MustNotBeNull(nameof(taxRate));
StoreReadOnly store = await _storeService.GetStoreAsync(productSnapshot.StoreId);
// Get the base unit price for the currency
var unitPrice = productSnapshot.Prices?.FirstOrDefault(x => x.CurrencyId == currencyId)?.Value ?? 0m;
// Apply volume discount based on quantity
var quantity = context?.OrderLine?.Quantity ?? 1m;
var discountedPrice = unitPrice;
if (quantity >= 100)
{
discountedPrice = unitPrice * 0.85m; // 15% discount for 100+ items
}
else if (quantity >= 50)
{
discountedPrice = unitPrice * 0.90m; // 10% discount for 50-99 items
}
else if (quantity >= 10)
{
discountedPrice = unitPrice * 0.95m; // 5% discount for 10-49 items
}
// Calculate final price with tax using the store's tax configuration
var price = Price.Calculate(discountedPrice, taxRate, currencyId, store.PricesIncludeTax);
return Attempt.Succeed(price);
}
}
Registering a custom Calculator implementation
Last updated
Was this helpful?