Skip to content

DiscountRewardProvider not assigning discount #748

@TresBlue

Description

@TresBlue

Which component is this issue related to?

Umbraco Commerce (Core)

Which Umbraco Commerce version are you using? (Please write the exact version, example: 10.1.0)

13.2.3

Bug summary

We’ve built our own DiscountRewardProvider following the documentation:
https://docs.umbraco.com/umbraco-commerce/13.latest/key-concepts/discount-rules-and-rewards

Our goal is to calculate discounts based on order lines. If an order line is a bundle, the discount should only apply to the unit/base price of the product.

However, when we implement this, no discount is applied.

What we observed while debugging

  • Our code is triggered three times.
  • On the first and third runs, ctx.Order.OrderLines do not have a UnitPrice, so no discount is applied.
  • On the second run, the order lines contain the expected information, and a price adjustment is added.

Despite this, once the process finishes, no discount appears on the order.

Additional check

If we hardcode a discount, it is applied successfully.

Specifics

Our code:

[DiscountRewardProvider("myDiscountReward", "My Discount Reward")]
public class MyDiscountRewardProvider(Lazy<IMemberService> _memberService,
	IUmbracoHelperAccessor helperAccessor) : DiscountRewardProviderBase<MyDiscountRewardProviderSettings>
{
	public override DiscountRewardCalculation CalculateReward(DiscountRewardContext ctx, MyDiscountRewardProviderSettings settings)
	{
		var result = new DiscountRewardCalculation();

		if (ctx.Order.OrderLines.All(x => x.UnitPrice?.Value == null))
		{
			// No usable prices yet, skip this evaluation
			return result;
		}

		if (!helperAccessor.TryGetUmbracoHelper(out var umbracoHelper))
		{
			return result;
		}

		if (string.IsNullOrWhiteSpace(ctx.Order.CustomerInfo.CustomerReference))
		{
			return result;
		}

		IMember member = null;
		int result2;
		if (Guid.TryParse(ctx.Order.CustomerInfo.CustomerReference, out var memberResult))
		{
			member = _memberService.Value.GetByKey(memberResult);
		}
		else if (int.TryParse(ctx.Order.CustomerInfo.CustomerReference, out result2))
		{
			member = _memberService.Value.GetById(result2);
		}

		if (member != null && member.GetValue<int>("hasSeasonTicket") == 1)
		{
			decimal price = 0;
			decimal priceTax = 0;

			foreach (var orderLine in ctx.Order.OrderLines)
			{
				var content = umbracoHelper.Content(Guid.Parse(orderLine.ProductReference));
				var product = content as IProduct;

				if (!product?.NoDiscountAllowed ?? true)
				{
					price += (orderLine.UnitPrice?.Value?.WithoutTax / settings.DiscountAmount) ?? 0;
					priceTax += (orderLine.UnitPrice?.Value?.Tax / settings.DiscountAmount) ?? 0;
				}
			}

			var discountPrice = new Price(-price, -priceTax, ctx.Currency);

			result.SubtotalPriceAdjustments.Add(new DiscountAdjustment(ctx.Discount, discountPrice));
		}


		return result;
	}
}

public class MyDiscountRewardProviderSettings
{
	[DiscountRewardProviderSetting(Key = "discountAmount",
		Name = "Discount Amount",
		Description = "The percentage discount given")]

	public decimal DiscountAmount { get; set; }

}

If we change var discountPrice = new Price(-price, -priceTax, ctx.Currency); to var discountPrice = new Price((decimal)-7.9, (decimal)-2.1, ctx.Currency);
the discount does get added.

Steps to reproduce

Use above code, add a product to your cart. Remove the member logic in above code.

Expected result / actual result

No response

Dependencies

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions