@@ -23,26 +23,30 @@ There are two types of Discount Rules in Umbraco Commerce:
2323An example of an Order Discount Rule Provider would look something like this:
2424
2525``` csharp
26- [DiscountRuleProvider (" myCustomOrderRule " )]
27- public class MyCustomOrderRuleProvider : OrderDiscountRuleProviderBase <MyCustomOrderRuleProviderSettings >
26+ [DiscountRuleProvider (" customerEmailDomainRule " )]
27+ public class CustomerEmailDomainRuleProvider : OrderDiscountRuleProviderBase <CustomerEmailDomainSettings >
2828{
29- public override async Task <DiscountRuleResult > ValidateRuleAsync (DiscountRuleContext ctx , MyCustomOrderRuleProviderSettings settings )
29+ public CustomerEmailDomainRuleProvider (UmbracoCommerceContext ctx ) : base (ctx ) { }
30+
31+ public override DiscountRuleResult ValidateRule (DiscountRuleContext ctx , CustomerEmailDomainSettings settings )
3032 {
31- if (/* Some custom logic */ )
32- return Fulfilled ();
33+ var customerEmail = ctx .Order .CustomerInfo .Email ;
34+
35+ if (string .IsNullOrEmpty (customerEmail ) || string .IsNullOrEmpty (settings .EmailDomain ))
36+ return Unfulfilled ();
3337
34- return Unfulfilled ();
38+ // Check if customer email ends with the specified domain
39+ return customerEmail .EndsWith ($" @{settings .EmailDomain }" , StringComparison .OrdinalIgnoreCase )
40+ ? Fulfilled ()
41+ : Unfulfilled ();
3542 }
3643}
3744
38- public class MyCustomOrderRuleProviderSettings
45+ public class CustomerEmailDomainSettings
3946{
40- [DiscountRuleProviderSetting (Key = " priceType" )]
41- public OrderPriceType PriceType { get ; set ; }
42-
43- ...
47+ [DiscountRuleProviderSetting (Key = " emailDomain" )]
48+ public string EmailDomain { get ; set ; }
4449}
45-
4650```
4751
4852All Order Discount Rule Providers inherit from a base class ` OrderDiscountRuleProviderBase<TSettings> ` . ` TSettings ` is the type of a Plain Old Class Object (POCO) model class representing the Discount Rule Providers settings.
@@ -66,24 +70,26 @@ If the passed-in context (which contains a reference to the Order) meets the Rul
6670An example of an Order Line Discount Rule Provider would look something like this:
6771
6872``` csharp
69- [DiscountRuleProvider (" myCustomOrderLineRule " )]
70- public class MyCustomOrderLineRuleProvider : OrderLineDiscountRuleProviderBase <MyCustomOrderLineRuleProviderSettings >
73+ [DiscountRuleProvider (" minimumQuantityRule " )]
74+ public class MinimumQuantityRuleProvider : OrderLineDiscountRuleProviderBase <MinimumQuantitySettings >
7175{
72- public override async Task <DiscountRuleResult > ValidateRuleAsync (DiscountRuleContext ctx , MyCustomOrderLineRuleProviderSettings settings )
76+ public MinimumQuantityRuleProvider (UmbracoCommerceContext ctx ) : base (ctx ) { }
77+
78+ public override DiscountRuleResult ValidateRule (DiscountRuleContext ctx , MinimumQuantitySettings settings )
7379 {
74- if (/* Some custom logic */ )
75- return Fulfilled (fulfilledOrderLines );
76-
77- return Unfulfilled ();
80+ // Check if any line meets minimum quantity
81+ var qualifyingLines = ctx .ApplicableOrderLines
82+ .Where (line => line .Quantity >= settings .MinimumQuantity )
83+ .ToList ();
84+
85+ return qualifyingLines .Any () ? Fulfilled (qualifyingLines ) : Unfulfilled ();
7886 }
7987}
8088
81- public class MyCustomOrderLineRuleProviderSettings
89+ public class MinimumQuantitySettings
8290{
83- [DiscountRuleProviderSetting (Key = " priceType" )]
84- public OrderPriceType PriceType { get ; set ; }
85-
86- ...
91+ [DiscountRuleProviderSetting (Key = " minimumQuantity" )]
92+ public decimal MinimumQuantity { get ; set ; }
8793}
8894
8995```
@@ -97,27 +103,49 @@ All Order Line Discount Rule Providers inherit from a base class `OrderLineDisco
97103An example of a Discount Reward Provider would look something like this:
98104
99105``` csharp
100- [DiscountRewardProvider (" myDiscountReward " )]
101- public class MyDiscountRewardProvider : DiscountRewardProviderBase <MyDiscountRewardProviderSettings >
106+ [DiscountRewardProvider (" tieredPercentageReward " )]
107+ public class TieredPercentageRewardProvider : DiscountRewardProviderBase <TieredPercentageSettings >
102108{
103- public override async Task <DiscountRewardCalculation > CalculateRewardAsync (DiscountRewardContext ctx , MyDiscountRewardProviderSettings settings )
109+ public TieredPercentageRewardProvider (UmbracoCommerceContext ctx ) : base (ctx ) { }
110+
111+ public override DiscountRewardCalculation CalculateReward (DiscountRewardContext ctx , TieredPercentageSettings settings )
104112 {
105113 var result = new DiscountRewardCalculation ();
114+ var orderTotal = ctx .OrderCalculation .SubtotalPrice .Value .WithoutTax ;
115+
116+ // Determine discount percentage based on order value
117+ var discountPercentage = orderTotal >= settings .HighTierThreshold ? settings .HighTierPercentage :
118+ orderTotal >= settings .MidTierThreshold ? settings .MidTierPercentage :
119+ settings .BaseTierPercentage ;
106120
107- // Some custom calculation logic goes here
121+ var discountAmount = orderTotal * (discountPercentage / 100 m );
122+
123+ // Adjustment price must be negative for discounts or positive for fees
124+ var price = new Price (discountAmount * - 1 , 0 , ctx .Order .CurrencyId );
125+
126+ result .SubtotalPriceAdjustments .Add (new DiscountAdjustment (ctx .Discount , price ));
108127
109128 return result ;
110129 }
111130}
112131
113- public class MyDiscountRewardProviderSettings
132+ public class TieredPercentageSettings
114133{
115- [DiscountRewardProviderSetting (Key = " priceType " )]
116- public OrderPriceType PriceType { get ; set ; }
134+ [DiscountRuleProviderSetting (Key = " baseTierPercentage " )]
135+ public decimal BaseTierPercentage { get ; set ; }
117136
118- ...
119- }
137+ [DiscountRuleProviderSetting (Key = " midTierThreshold" )]
138+ public decimal MidTierThreshold { get ; set ; }
139+
140+ [DiscountRuleProviderSetting (Key = " midTierPercentage" )]
141+ public decimal MidTierPercentage { get ; set ; }
120142
143+ [DiscountRuleProviderSetting (Key = " highTierThreshold" )]
144+ public decimal HighTierThreshold { get ; set ; }
145+
146+ [DiscountRuleProviderSetting (Key = " highTierPercentage" )]
147+ public decimal HighTierPercentage { get ; set ; }
148+ }
121149```
122150
123151All Discount Reward Providers inherit from a base class ` DiscountRewardProviderBase<TSettings> ` . ` TSettings ` is the Type of a POCO model class representing the Discount Reward Providers settings.
@@ -157,43 +185,54 @@ Both the `DiscountRuleProviderAttribute` and the `DiscountRewardProviderAttribut
157185A basic label component is defined as follows:
158186
159187``` typescript
160- import { customElement , html , property } from " @umbraco-cms/backoffice/external/lit" ;
188+ import { css , customElement , html , property , when } from " @umbraco-cms/backoffice/external/lit" ;
161189import { UmbLitElement } from " @umbraco-cms/backoffice/lit-element" ;
190+ import { UmbTextStyles } from " @umbraco-cms/backoffice/style" ;
162191
163- @customElement (' my -discount-rule-label' )
164- export class MyDiscountRuleLabelElement extends UmbLitElement {
192+ @customElement (' uc-customer-email-domain -discount-rule-label' )
193+ export class UcCustomerEmailDomainDiscountRuleLabelElement extends UmbLitElement {
165194
166195 @property ()
167- value? : Record <string , unknown >;
196+ value? : Record <string , unknown >;
168197
169198 render() {
170- return html ` -- CREATE YOUR LABEL HERE -- `
199+ return when (this .value , () => html `
200+ Customer email ends with '@${this .value ! .emailDomain }'
201+ ` )
171202 }
203+
204+ static styles = [
205+ UmbTextStyles ,
206+ css `
207+ :host {
208+ display: block;
209+ }
210+ ` ,
211+ ];
172212}
173213
174- export default MyDiscountRuleLabelElement ;
214+ export default UcCustomerEmailDomainDiscountRuleLabelElement ;
175215
176216declare global {
177217 interface HTMLElementTagNameMap {
178- ' my- discount-rule-label' : MyDiscountRuleLabelElement ;
218+ ' uc-customer-email-domain- discount-rule-label' : UcCustomerEmailDomainDiscountRuleLabelElement ;
179219 }
180220}
181-
182221```
183222
184- The component will pass a ` Record<string, unknown> ` value representing the rule/rewards configured values. Use this value to create your label.
223+ The component will be passed a ` Record<string, unknown> ` value representing the rule/rewards configured values. Use this value to create your label.
185224
186225Once defined, your component can be registered as a Property Editor UI via a manifest entry.
187226
188227``` javascript
189- const myDiscountRuleLabelManifest = {
228+ const customerEmailDomainDiscountRuleLabelManifest = {
190229 type: " propertyEditorUi" ,
191- alias: " My.PropertyEditorUi.MyDiscountRuleLabel " ,
192- name: " My Discount Rule Label" ,
193- element : () => import (' ./my -discount-rule-label.element.js' )
194- };
230+ alias: " My.PropertyEditorUi.CustomerEmailDomainDiscountRuleLabel " ,
231+ name: " Customer Email Domain Discount Rule Label" ,
232+ element : () => import (' ./customer-email-domain -discount-rule-label.element.js' )
233+ };
195234
196- export const manifests = [ myDiscountRuleLabelManifest ];
235+ export const manifests = [ customerEmailDomainDiscountRuleLabelManifest ];
197236```
198237
199238{% hint style="info" %}
0 commit comments