Release

Vendr 1.4.0 Release Candidate

12 November 2020

All you need to know about the Licensing and Price Adjustment updates coming soon to Vendr and how you can be ready for them.

Vendr 1.4.0 Release Candidate

Vendr 1.4.0 is just around the corner and whilst it may not look like anything has changed feature wise, this release is all about updating some of the foundations of Vendr to make it more stable and flexible for the future.

With this update however comes some breaking changes, so to give people a chance to review those changes prior to official release, we are putting out a 1.4.0 release candidate to allow people time to give it a thorough test in their setups.

Vendr 1.4.0 is made up of two updated features.

Licensing Updates

One of the things we've had a lot of requests for with Vendr is additional pricing/licensing options and particularly a subscription model. In order to prepare for these additional options we've had to make a few updates around our licensing code. Fundamentally, these changes should be backwards compatible and anyone with an existing licence will have their licence continue to work in the same way with the same, unlimited feature access. We'll announce more later about the new options, but we needed to make this update to allow those changes to be possible.

What to test?

For anybody with a licensed install, all we need you to test is that your licence continues to work as expected. If the licence fails, you'll likely see the trial notification in the back office, and on the Vendr settings root node, you'll see your licence as inactive. We have tested this and haven't seen any regression issues, but we'd love people to check this for themselves to be 100% sure.

Price/Amount Adjustments

This one is the big update in this release and what we'd like people to test the most.

In 1.4.0 we are introducing a new concept called Price/Amount Adjustments. What adjustments allow you to do is create a record/log of all changes that occur to a price/amount throughout the calculation process such that there is no ambiguity as to why a price is what it is.

In earlier versions of Vendr it was possible for developers to modify a price during the calculation process by extending the calculation pipeline. Developers could work out a discount or fee and subtract/add that to the relevant price amount, however, there was no way to record WHY the price had changed. This to us was a big problem as unless you knew why the price was different, it wasn't possible to add all the order prices together to get to the same total and so it would look like the calculation was incorrect.

To fix this, and to provide the flexibility to do some pretty cool stuff we'll outline in a moment, we've added the concept of Price/Amount Adjustments. 

About Price Adjustments

In Vendr 1.4.0 all order prices that can be adjusted now have an Adjustments property which is a collection of PriceAdjustment objects. Price Adjustments all inherit from the PriceAdjustment<TSelf> class.

public abstract class PriceAdjustment<TSelf> 
{
    public Type Type { get; }
    public Price Price { get; }
    public Price OriginalPrice { get; }
}

Implementations of the PriceAdjustment<TSelf> class can extend it with additional meta data properties that should be recorded against the adjustment. For example, our discount adjustment looks like:

public class DiscountAdjustment : PriceAdjustment<DiscountAdjustment>
{
    public Guid DiscountId { get; set; }
    public string DiscountName { get; set; }
}

Now when Vendr performs it's calculation routine, there is no ambiguity as to how a price is what it is, as all prices are now the sum of their base prices +/- all the adjustments in the prices adjustments collection. To accommodate all the different adjustment types, Price adjustments can be positive (a fee) or negative (a discount). 

And of course, price adjustments are completely plugable with developers able to register their own PriceAdjuster using the Umbraco DI container configuration composer.

public class MyPriceAdjuster : PriceAdjusterBase
{
    public override void ApplyPriceAdjustments(PriceAdjusterArgs args)
    {
        // TODO: Calculate adjustment
        args.SubtotalPriceAdjustments.Add(new MyAdjustment());
    }
}
[ComposeAfter(typeof(VendrWebComposer))]
public class MyComposer : IUserComposer
{
    public void Compose(Composition composition)
    {
        composition.WithPriceAdjusters()
            .Append<MyPriceAdjuster>();
    }
}

About Amount Adjustments & TransactionAmount

Another similar problem we had in an early version of Vendr was how Gift Cards work. Previously, the Gift Card amount would be calculated during the order calculation process and would simply be deducted from the orders TotalPrice.Value, which we found confusing. Similar to price adjustments, it just felt weird that the TotalPrice could have a TotalPrice.WithoutTax and TotalPrice.Tax values that might not add up to the TotalPrice.Value value.

When we thought about it, we realized that what we were really trying to achieve was the ability to adjust the transaction amount that we wish to capture from the payment gateway . In other words, we want to have the order Total Price, but be able to say, regardless of what the Total Price is, this is the monetary amount we wish to capture.

When we understood this, it made perfect sense that these should just be another type of adjustment, Amount Adjustments (Amount Adjustments because we are adjusting a monetary amount without a tax component). And by making these adjustments too, we could also have a complete log of why the transaction amount is what it is, just like we did the order prices. As you might expect, Amount Adjustments work in the same way as Price Adjustments and can be extended just the same, but we use Amount Adjustment/Adjuster base classes instead.

With the creation of Amount Adjustments however, we also had to create a new price property on the order TransactionAmount to hold this information as we felt the order TotalPrice didn't represent this particular value appropriately. The TransactionAmount property is an object that contains multiple sub properties such as versions of the transaction amount pre and post adjustment and also the calculated adjustment amount as well as the list of applied adjustments. From the TransactionAmount property then you can access all information about why the transaction amount is what it is calculated to be.

public class TransactionAmount
{
    public IReadOnlyCollection<AmountAdjustment> Adjustments { get; }
    public Amount WithoutAdjustments { get;  }
    public Amount Adjustment { get;  }
    public Amount Value { get;  }
}

Functionally this new property doesn't pose any great problems, it's mostly a logical/organizational change, however it is something developers should be aware of as this will likely change the price value developers should be rendering in their cart/order email templates as their final price value, and will also affect any custom payment providers as these will also need to be updated to use this new price value.

What other breaking changes has Price/Amount Adjustments introduced?

Along with the introduction of the TransactionAmount property mentioned above, because adjustments are so fundamental to order prices, there have unfortunately been a number of breaking changes in their implementation.

  1. Discounts are now Price Adjustments and so all price "Discount" related properties have been renamed to "Adjustment" related properties.
  2. Because Discounts are now Price Adjustments, Discounts are now no longer calculated as their own calculation pipeline task (CalculateOrderDiscountsTask). Instead, there is now an adjustments calculation pipeline task that calculates all adjustments (ApplyOrderPriceAdjustmentsTask), of which Discounts are now a type of adjuster (DiscountsPriceAdjuster).
  3. Because price adjustments can be positive or negative, all discount adjustments are now negative in value (important if you using discounts to calculate a value).
  4. All order calculation pipeline tasks related to "Discounts"/"Discounted" have all be renamed to "Adjustments"/"Adjusted" task names. All previous tasks have been made obsolete with intelisense to guide you to the new implementation.
  5. Gift Cards are now Amount Adjustments and so all "Gift Card" related properties are now found in the "Adjustment" related properties.
  6. Because Gift Cards are now Amount Adjustments, Gift Cards are now no longer calculated as their own calculation pipeline task (CalculateOrderGiftCardAmountsTask). Instead, there is now an adjustments calculation pipeline task that calculates all adjustments (ApplyOrderAmountAdjustmentsTask), of which Gift Cards are now a type of adjuster (GiftCardsAmountAdjuster).
  7. Gift Card / Amount Adjustment values are now found on the TransactionAmount property rather than the TotalPrice property of an order.
  8. Because of the introduction of the TransactionAmount property, payment providers will need to be updated to use this value as the amount the payment gateway should capture.

What else can we do with Price/Amount Adjustments?

With so many fundamental breaking changes you may be wondering if the only benefit is better visibility of calculated prices and that answer that is no. Price/Amount Adjustments also open up some great opportunities too.

  1. Custom Fees - With price adjustment /adjusters is now much easier for you to add custom fees to an order.
  2. Bulk Pricing - With price adjustments/adjusters it makes bulk pricing possible as you can now have a base product price but then add adjustments to alter the price based upon the order line quantities.
  3. Reward/Loyalty Points - With amount adjustments/adjusters it makes it possible to have other types of transaction amount alterations such as redeemable reward/loyalty points.

The upgrade process

Whilst all Umbraco installs can be pretty different, the upgrade process for Vendr 1.4.0 should follow something like these steps:

  • Install package
  • Update cart page
    • Swap all WithoutDiscounts prices for WithoutAdjustments ones
  • Update checkout pages
    • Swap all WithoutDiscounts prices for WithoutAdjustments ones
    • Update discount display logic to use adjustments
      (new GetTotalPriceAdjustmentByType extension method to help if displaying one total discount amount)
      (discount adjustments will be negative in value, so remove any hard coded '-' symbols)
    • Update gift card display logic to use adjustments
      (new GetTotalAmountAdjustmentByType extension method to help if displaying one total gift card amount)
      (discount adjustments will be negative in value, so remove any hard coded '-' symbols)
    • Update order grand total display to use TransactionAmount
  • Update any custom email templates with similar changes as referenced above
  • Upgrade all payment providers
    • Any custom payment providers should be updated to use the new TransactionAmount order property as the value to capture
  • Upgrade Vendr Checkout if used
  • Check/Upgrade any custom integrations
    • Custom order pipelines for task name changes
    • Custom calculation logic that depends on discount values
    • Update any custom fees code to use adjustments

What to test?

As you can see, there is quite a lot that has changed here and this is why we wanted to put out a release candidate so that people can raise any issues prior to an official release. When testing this release candidate, developers should review the following areas:

  1. Cart/checkout templates rendering order total price.
  2. Any custom order calculation pipeline tasks.
  3. Any code that references any "Discount" related properties.
  4. Any custom payment providers accessing the order total price.
  5. Any custom fees applied to an order should now use adjustments.

How to get your hands on the Vendr 1.4.0 Release Candidate

The Vendr 1.4.0 RC release is available now from our dev NuGet feed at https://nuget.outfield.digital/prerelease/vendr/v3/index.json.

This should be added to Visual Studio as a NuGet source and then the latest Vendr 1.4.0-rc build can be installed as normal (Be sure to make sure you have the "Include prerelease" checkbox checked).

The following NuGet package versions have been prepared for this RC.

  • Vendr 1.4.0-rc
  • Vendr.Checkout 1.2.0-rc
  • Vendr.PaymentProvider.Invoicing 1.1.0-rc
  • Vendr.PaymentProvider.Stripe 1.2.0-rc
  • Vendr.PaymentProvider.PayPal 1.1.0-rc

If you are using Umbraco packages rather than NuGet, you can find a series of zip package files for Vendr and some common add-on packages linked below:

In addition to the above package files, you can also access a copy of the Vendr Demo Store updated to use Vendr 1.4.0 RC for download from our GitHub repository.

How to feedback

Any issues found whilst testing the release candidate should be reported on our issue tracker, highlighting in the issue title that it is specifically related to the 1.4.0 RC.

If developers have any questions on implementing the changes from the release candidate, these should be asked on the Umbraco developer portal support forums.

When will Vendr 1.4.0 be released

Vendr 1.4.0 will be released in 4 weeks time on the 10th of December 2020. If any issues are found during the RC period however this may push back the release date, but we want to ensure we give developers/agencies enough time to test things before we make the full release.