Last active
May 3, 2022 13:02
-
-
Save mattbrailsford/518c5771de89a0fc35d0644ca126d229 to your computer and use it in GitHub Desktop.
Example order line calculator that support price breaks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using Umbraco.Core.Models.PublishedContent; | |
using Umbraco.Web; | |
using Vendr.Core.Calculators; | |
using Vendr.Core.Models; | |
using Vendr.Core.Services; | |
using Vendr.Web.Models; | |
namespace Vendr.DemoStore.Web.Calculators | |
{ | |
public class PriceBreakOrderLineCalculator : OrderLineCalculator | |
{ | |
private readonly IStoreService _storeService; | |
private readonly IPriceFreezerService _priceFreezerService; | |
private readonly IUmbracoContextAccessor _umbracoContextAccessor; | |
public PriceBreakOrderLineCalculator(ITaxService taxService, IStoreService storeService, IProductPriceFreezerService productPriceFreezerService, | |
IPriceFreezerService priceFreezerService, IUmbracoContextAccessor umbracoContextAccessor) | |
: base(taxService, storeService, productPriceFreezerService) | |
{ | |
_storeService = storeService; | |
_priceFreezerService = priceFreezerService; | |
_umbracoContextAccessor = umbracoContextAccessor; | |
} | |
public override Price CalculateOrderLineUnitPrice(OrderReadOnly order, OrderLineReadOnly orderLine, Guid currencyId, TaxRate taxRate) | |
{ | |
var store = _storeService.GetStore(order.StoreId); | |
// See if the product node has a priceBreaks value | |
var node = _umbracoContextAccessor.UmbracoContext.Content.GetById(Guid.Parse(orderLine.ProductReference)); | |
if (node.HasValue("priceBreaks")) | |
{ | |
// Work out which price break applies (if any) | |
var priceBreaks = node.Value<IEnumerable<IPublishedElement>>("priceBreaks"); | |
IPublishedElement targetPriceBreak = null; | |
foreach (var priceBreak in priceBreaks) | |
{ | |
var minQuantity = priceBreak.Value<int>("minQuantity"); | |
if (orderLine.Quantity >= minQuantity) | |
{ | |
targetPriceBreak = priceBreak; | |
} | |
else | |
{ | |
break; | |
} | |
} | |
// See if we have a price break | |
if (targetPriceBreak != null) | |
{ | |
// See if we have a frozen price for this price break and if so, use it | |
var key = $"{order.StoreId}_{order.Id}_{orderLine.ProductReference}_{targetPriceBreak.Key}"; | |
var price = _priceFreezerService.GetFrozenPrice(order.Id, key, currencyId); | |
if (price == null || price.Equals(ProductPrice.ZeroValue(currencyId))) | |
{ | |
// No frozen price yet, so work out the price and freeze it (if we can) | |
var priceBreakPrices = targetPriceBreak.Value<PricePropertyValue>("price"); | |
var priceBreakPrice = priceBreakPrices.GetPriceFor(currencyId); | |
if (priceBreakPrice != null) | |
{ | |
// Freeze the price if the order isn't new | |
// (ie, it doesn't exist in the DB yet and so an FK would fail) | |
if (!order.IsNew) | |
{ | |
_priceFreezerService.FreezePrice(order.Id, key, priceBreakPrice); | |
} | |
price = priceBreakPrice; | |
} | |
} | |
return Price.Calculate(price.Value, taxRate, currencyId, store.PricesIncludeTax); | |
} | |
} | |
return base.CalculateOrderLineUnitPrice(order, orderLine, currencyId, taxRate); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment