Our client would like a different price for products, if the customer selects 'pickup' as delivery. The reason for this is the delivery costs are part of the initial product price.
My thought process was some custom code which triggers after the delivery option is selected, which would add a custom discount for the difference. This would need to be clever enough to be able to be re-run if a new product is added to update the discount as well as remove the discount if the customer goes back and changes delivery option.
What do you think would be the best way to handle this? Any help would be very appreciated.
Yea, a discount could work if you work it in reverse, ie, the prices are inc delivery but you create a discount rule to reduce the price when "pickup" is selected. I think you could do this with an automatic discount rule. I think the thing here though would be that it would have to be a standard reduction on the prices, ie, you'd want to be knocking the same amount or percentage off every price.
Another option could be a custom order line calculator and maybe store multiple prices on the product node and then in the order line calculator you check the delivery method and if it's "pickup" you fetch the cheaper price.
Lastly, another option could be to write a custom price adjuster which could effectively do something similar.
I like the idea of two stored prices, I do actually have this as I was trying a few things over the weekend but couldn't get anything working, so thought I'd wait to hear from you.
Could you share some sample code for the order line calculator that would have access to the shipping option please?
I also assume the price will freeze, so when a new product added or shipping changed I need to unfreeze?
The order line calculator is responsible for freezing the prices so by returning a different price, it shouldn't be frozen. You can of course re-freeze the discounted price.
In terms of implementing the calculator, you'll want to inherit from the current calculator OrderLineCalculator and override the CalculateOrderLineUnitPrice method. That method is passed an order object and so from that you can determine if the shipping method is set, and if it is, fetch it via the vendr services to see if it is the pickup payment method.
If it is set to pickup, then use the order lines product reference to lookup the Umbraco node and get the alternative price and return that as the unit price value. If not, you can just fallback to the base implementation.
I'd probably get that working first and then you can worry about price freezing.
Thanks for this, think I have it working - can you check my code below to make sure I am not doing anything silly? I've not needed to do anything with the freezing thankfully.
public override Price CalculateOrderLineUnitPrice(OrderReadOnly order, OrderLineReadOnly orderLine, Guid currencyId, TaxRate taxRate)
{
if (order.ShippingInfo.ShippingMethodId.HasValue && order.ShippingInfo.ShippingMethodId.Value ==
Guid.Parse("4e8de459-3a6d-4b3a-89dc-b0e88d0d9f8e")) // shipping found and is pickup
{
if (!string.IsNullOrEmpty(orderLine.ProductVariantReference)) // is multi variant
{
if (Umbraco.Web.Composing.Current.UmbracoHelper.Content(orderLine.ProductReference) is MultiVariantShopItem productNode)
{
var variant = productNode.Variants.FirstOrDefault(x => x.Content.Key == Guid.Parse(orderLine.ProductVariantReference));
var variantObject = (ProductMultiVariant) variant?.Content;
if (variantObject != null && variantObject.PickupPrice.HasPriceFor(currencyId))
{
var price = Price.Calculate(variantObject.PickupPrice.GetPriceFor(currencyId).Value, taxRate, currencyId, true);
return price;
}
}
}
else
{
var product = (ProductVariant)Umbraco.Web.Composing.Current.UmbracoHelper.Content(orderLine.ProductReference);
if (product != null && product.PickupPrice.HasPriceFor(currencyId))
{
var price = Price.Calculate(product.PickupPrice.GetPriceFor(currencyId).Value, taxRate, currencyId, true);
return price;
}
}
}
return base.CalculateOrderLineUnitPrice(order, orderLine, currencyId, taxRate);
}
Custom pricing depending on delivery
Hi Matt,
Our client would like a different price for products, if the customer selects 'pickup' as delivery. The reason for this is the delivery costs are part of the initial product price.
My thought process was some custom code which triggers after the delivery option is selected, which would add a custom discount for the difference. This would need to be clever enough to be able to be re-run if a new product is added to update the discount as well as remove the discount if the customer goes back and changes delivery option.
What do you think would be the best way to handle this? Any help would be very appreciated.
Many thanks,
Hi Jamie,
Yea, a discount could work if you work it in reverse, ie, the prices are inc delivery but you create a discount rule to reduce the price when "pickup" is selected. I think you could do this with an automatic discount rule. I think the thing here though would be that it would have to be a standard reduction on the prices, ie, you'd want to be knocking the same amount or percentage off every price.
Another option could be a custom order line calculator and maybe store multiple prices on the product node and then in the order line calculator you check the delivery method and if it's "pickup" you fetch the cheaper price.
Lastly, another option could be to write a custom price adjuster which could effectively do something similar.
Hope this helps
Matt
Hi Matt,
I like the idea of two stored prices, I do actually have this as I was trying a few things over the weekend but couldn't get anything working, so thought I'd wait to hear from you.
Could you share some sample code for the order line calculator that would have access to the shipping option please?
I also assume the price will freeze, so when a new product added or shipping changed I need to unfreeze?
Hi Jamie,
The order line calculator is responsible for freezing the prices so by returning a different price, it shouldn't be frozen. You can of course re-freeze the discounted price.
In terms of implementing the calculator, you'll want to inherit from the current calculator
OrderLineCalculator
and override theCalculateOrderLineUnitPrice
method. That method is passed an order object and so from that you can determine if the shipping method is set, and if it is, fetch it via the vendr services to see if it is the pickup payment method.If it is set to pickup, then use the order lines product reference to lookup the Umbraco node and get the alternative price and return that as the unit price value. If not, you can just fallback to the base implementation.
I'd probably get that working first and then you can worry about price freezing.
Matt
Hi Matt,
Thanks for this, think I have it working - can you check my code below to make sure I am not doing anything silly? I've not needed to do anything with the freezing thankfully.
Looks spot on to me 👍
Nicely done.
is working on a reply...