We are in need to have dynamic discount for every order based on date. So I was looking around. And thought that Price/Amount Adjustments would be the way to go here. Or does anyone else have an better idea?
I followed the guide for Price/Amount Adjustments listed here Vendr. But after adding it into the composer I got a bit lost on how to use on an actual order.
I'll do my best to explain. So, a customer buys for e.g. 1 year licence. And if they want to renew it. They will have to place a new order. During this order process, we will make an external API call. To check if this customer already has an active license. Let's say that it's 20 days before their license will expire. So we will then cancel their current license and give a discount. So let's 10 DKK * 20. So they will get 200 DKK discount.
I hope this makes some sort of sense. I personally don't like it this way. But it's unforuntly out of my hands to decide..
Ahh, ok, so you want to apply the remainder of the 1 year license cost and pro-rata discount the new license fee.
Then yea, I think this is a good candidate for a price adjustment.
Here's a bit of an outline of what I think you might need:
public class LicenseProRataDiscountAdjuster : PriceAdjusterBase
{
private readonly ILicenseService _licenseService;
public LicenseProRataDiscountAdjuster(ILicenseService licenseService)
{
_licenseService = licenseService;
}
public override void ApplyPriceAdjustments(PriceAdjusterArgs args)
{
// Check the order to see if we have a license upgrade
foreach(var orderLine in args.Order.OrderLines)
{
if (orderLine.Sku == "LIC-UPG") // Check to see if it's a license upgrade
{
var licenseId = orderLine.Properties["licenseId"];
var remainingPeriod = _licenseService.GetRemainingLicensePeriod(licenseId);
if (remainingPeriod > 0)
{
var price = new Price((10 * remainingPeriod) * -1, (0.1 & remainingPeriod) * -1, args.Order.CurrencyId); // Calculate discount price based on remaining period
var adjustment = new LicenseProRataDiscountAdjustment("Pro Rata Discount", "LIC-0001", price);
args.OrderLines[orderLine.Id].TotalPriceAdjustments.Add(adjustment);
}
}
}
}
}
[Serializable]
public class LicenseProRataDiscountAdjustment : PriceAdjustment<LicenseProRataDiscountAdjustment>
{
public string LicenseId { get; set; }
// A parameterless constructor is required for cloning
public LicenseProRataDiscountAdjustment()
: base()
{ }
// Additional helper constructors
public LicenseProRataDiscountAdjustment (string name, string licenseId, Price adjustment)
: base(name, adjustment)
{
LicenseId = licenseId;
}
}
Ultimately you need to create an adjustment type, then in your adjuster, you do your logic to work out if an adjustment applies. Here's I've assumed you've wrapped that in some kind of service that has been registered with the DI container and injected in your adjuster constructor.
In the ApplyPriceAdjustments method then, you look through the supplied order and find any order lines that qualify to be checked, then you use your service to look up the remainder of the license amount (here I've assumed you have added the licenseId as an order line property to the orderline). If the response from your service shows a discount is needed, then an adjustment is created and applied to the order lines total price.
You'll then need some logic on order finalization to cancel the other license and create your new one, but I'm guessing you'll be ok with that.
I am just wondering. Do I have to call the LicenseProRataDiscountAdjuster or the ApplyPriceAdjustments somwhere? If yes, how would that look like? I Or does it run automatically before getting to checkout page?
Once you've created your price adjuster and registered it with the DI container, it should get picked up and applied automatically.
All price adjusters are run whenever an order is re-calculated, which is usually whenever something happens to the order that could affect the price, such as adding order items to it, or setting the shipping / payment countries etc.
Gotcha! I manage to get it working like a charm! Thank you much! I just wanted to double check a thing with you! Do I need to add a separate line displaying the adjustment in "VendrCheckoutMaster. cshtml" or should it be displayed per default?
Re displaying it on the checkout, given it’s a custom detail, yes, you would need to update the checkout view (and probably your email template) to display this.
Dynamic discounts
Hi!
We are in need to have dynamic discount for every order based on date. So I was looking around. And thought that Price/Amount Adjustments would be the way to go here. Or does anyone else have an better idea?
I followed the guide for Price/Amount Adjustments listed here Vendr. But after adding it into the composer I got a bit lost on how to use on an actual order.
Would love some feedback on this!
//Johannes
Hey Johannes
There are a couple of options with these which could be either price/amount adjustments or maybe even custom discount implementations.
Do you want to give a bit more background on what you need to achieve and then I could recommend what would be the better fit.
// Matt
Hey Matt!
I'll do my best to explain. So, a customer buys for e.g. 1 year licence. And if they want to renew it. They will have to place a new order. During this order process, we will make an external API call. To check if this customer already has an active license. Let's say that it's 20 days before their license will expire. So we will then cancel their current license and give a discount. So let's 10 DKK * 20. So they will get 200 DKK discount.
I hope this makes some sort of sense. I personally don't like it this way. But it's unforuntly out of my hands to decide..
//Johannes
Ahh, ok, so you want to apply the remainder of the 1 year license cost and pro-rata discount the new license fee.
Then yea, I think this is a good candidate for a price adjustment.
Here's a bit of an outline of what I think you might need:
Ultimately you need to create an adjustment type, then in your adjuster, you do your logic to work out if an adjustment applies. Here's I've assumed you've wrapped that in some kind of service that has been registered with the DI container and injected in your adjuster constructor.
In the
ApplyPriceAdjustments
method then, you look through the supplied order and find any order lines that qualify to be checked, then you use your service to look up the remainder of the license amount (here I've assumed you have added the licenseId as an order line property to the orderline). If the response from your service shows a discount is needed, then an adjustment is created and applied to the order lines total price.You'll then need some logic on order finalization to cancel the other license and create your new one, but I'm guessing you'll be ok with that.
Hope this helps
Matt
Thank you so much Matt! This will be a huge help!
I am just wondering. Do I have to call the
LicenseProRataDiscountAdjuster
or theApplyPriceAdjustments
somwhere? If yes, how would that look like? I Or does it run automatically before getting to checkout page?Thanks once again!
//Johannes
Hey Johannes
Once you've created your price adjuster and registered it with the DI container, it should get picked up and applied automatically.
All price adjusters are run whenever an order is re-calculated, which is usually whenever something happens to the order that could affect the price, such as adding order items to it, or setting the shipping / payment countries etc.
// Matt
Hey Matt!
Gotcha! I manage to get it working like a charm! Thank you much! I just wanted to double check a thing with you! Do I need to add a separate line displaying the adjustment in "VendrCheckoutMaster. cshtml" or should it be displayed per default?
//Johannes
(What it looks like now)
Hi Johannes
No problem. Glad you got it all working.
Re displaying it on the checkout, given it’s a custom detail, yes, you would need to update the checkout view (and probably your email template) to display this.
Matt
is working on a reply...