@zoxllc/shopify-checkout-extensions 0.0.8 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +136 -0
- package/EXAMPLES.md +463 -0
- package/INTEGRATION.md +482 -0
- package/README.md +5 -1
- package/dist/common/AndSelector.d.ts +11 -0
- package/dist/common/AndSelector.d.ts.map +1 -0
- package/dist/common/AndSelector.js +30 -0
- package/dist/common/Campaign.d.ts +24 -0
- package/dist/common/Campaign.d.ts.map +1 -0
- package/dist/common/Campaign.js +41 -0
- package/dist/common/CampaignConfiguration.d.ts +10 -0
- package/dist/common/CampaignConfiguration.d.ts.map +1 -0
- package/dist/common/CampaignConfiguration.js +7 -0
- package/dist/common/CampaignFactory.d.ts +22 -0
- package/dist/common/CampaignFactory.d.ts.map +1 -0
- package/dist/common/CampaignFactory.js +98 -0
- package/dist/common/CartAmountQualifier.d.ts +22 -0
- package/dist/common/CartAmountQualifier.d.ts.map +1 -0
- package/dist/common/CartAmountQualifier.js +46 -0
- package/dist/common/CartHasItemQualifier.d.ts +21 -0
- package/dist/common/CartHasItemQualifier.d.ts.map +1 -0
- package/dist/common/CartHasItemQualifier.js +54 -0
- package/dist/common/CartQuantityQualifier.d.ts +22 -0
- package/dist/common/CartQuantityQualifier.d.ts.map +1 -0
- package/dist/common/CartQuantityQualifier.js +62 -0
- package/dist/common/ConfigSchema.d.ts +71 -0
- package/dist/common/ConfigSchema.d.ts.map +1 -0
- package/dist/common/ConfigSchema.js +69 -0
- package/dist/common/ConfigValidator.d.ts +29 -0
- package/dist/common/ConfigValidator.d.ts.map +1 -0
- package/dist/common/ConfigValidator.js +84 -0
- package/dist/common/CountryCodeQualifier.d.ts +15 -0
- package/dist/common/CountryCodeQualifier.d.ts.map +1 -0
- package/dist/common/CountryCodeQualifier.js +30 -0
- package/dist/common/CustomerEmailQualifier.d.ts +16 -0
- package/dist/common/CustomerEmailQualifier.d.ts.map +1 -0
- package/dist/common/CustomerEmailQualifier.js +52 -0
- package/dist/common/CustomerSubscriberQualifier.d.ts +18 -0
- package/dist/common/CustomerSubscriberQualifier.d.ts.map +1 -0
- package/dist/common/CustomerSubscriberQualifier.js +28 -0
- package/dist/common/CustomerTagQualifier.d.ts +16 -0
- package/dist/common/CustomerTagQualifier.d.ts.map +1 -0
- package/dist/common/CustomerTagQualifier.js +45 -0
- package/dist/common/DiscountCart.d.ts +23 -0
- package/dist/common/DiscountCart.d.ts.map +1 -0
- package/dist/common/DiscountCart.js +103 -0
- package/dist/common/DiscountInterface.d.ts +17 -0
- package/dist/common/DiscountInterface.d.ts.map +1 -0
- package/dist/common/DiscountInterface.js +2 -0
- package/dist/common/OrSelector.d.ts +11 -0
- package/dist/common/OrSelector.d.ts.map +1 -0
- package/dist/common/OrSelector.js +30 -0
- package/dist/common/PostCartAmountQualifier.d.ts +9 -0
- package/dist/common/PostCartAmountQualifier.d.ts.map +1 -0
- package/dist/common/PostCartAmountQualifier.js +17 -0
- package/dist/common/ProductHandleSelector.d.ts +8 -0
- package/dist/common/ProductHandleSelector.d.ts.map +1 -0
- package/dist/common/ProductHandleSelector.js +22 -0
- package/dist/common/ProductIdSelector.d.ts +8 -0
- package/dist/common/ProductIdSelector.d.ts.map +1 -0
- package/dist/common/ProductIdSelector.js +22 -0
- package/dist/common/ProductTagSelector.d.ts +10 -0
- package/dist/common/ProductTagSelector.d.ts.map +1 -0
- package/dist/common/ProductTagSelector.js +39 -0
- package/dist/common/ProductTypeSelector.d.ts +8 -0
- package/dist/common/ProductTypeSelector.d.ts.map +1 -0
- package/dist/common/ProductTypeSelector.js +25 -0
- package/dist/common/Qualifier.d.ts +30 -0
- package/dist/common/Qualifier.d.ts.map +1 -0
- package/dist/common/Qualifier.js +61 -0
- package/dist/common/SaleItemSelector.d.ts +11 -0
- package/dist/common/SaleItemSelector.d.ts.map +1 -0
- package/dist/common/SaleItemSelector.js +30 -0
- package/dist/common/Selector.d.ts +27 -0
- package/dist/common/Selector.d.ts.map +1 -0
- package/dist/common/Selector.js +51 -0
- package/dist/common/SubscriptionItemSelector.d.ts +7 -0
- package/dist/common/SubscriptionItemSelector.d.ts.map +1 -0
- package/dist/common/SubscriptionItemSelector.js +19 -0
- package/dist/form/CampaignForm.d.ts +1 -0
- package/dist/form/CampaignForm.d.ts.map +1 -0
- package/dist/form/CampaignForm.js +1 -0
- package/{src/index.ts → dist/index.d.ts} +23 -27
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +80 -0
- package/dist/lineItem/BuyXGetY.d.ts +18 -0
- package/dist/lineItem/BuyXGetY.d.ts.map +1 -0
- package/dist/lineItem/BuyXGetY.js +85 -0
- package/dist/lineItem/ConditionalDiscount.d.ts +14 -0
- package/dist/lineItem/ConditionalDiscount.d.ts.map +1 -0
- package/dist/lineItem/ConditionalDiscount.js +81 -0
- package/dist/lineItem/FixedItemDiscount.d.ts +9 -0
- package/dist/lineItem/FixedItemDiscount.d.ts.map +1 -0
- package/dist/lineItem/FixedItemDiscount.js +35 -0
- package/dist/lineItem/MultiTierDiscount.d.ts +47 -0
- package/dist/lineItem/MultiTierDiscount.d.ts.map +1 -0
- package/dist/lineItem/MultiTierDiscount.js +150 -0
- package/dist/lineItem/PercentageDiscount.d.ts +8 -0
- package/dist/lineItem/PercentageDiscount.d.ts.map +1 -0
- package/dist/lineItem/PercentageDiscount.js +32 -0
- package/dist/lineItem/api.d.ts +2026 -0
- package/dist/lineItem/api.d.ts.map +1 -0
- package/dist/lineItem/api.js +1157 -0
- package/dist/shipping/FixedDiscount.d.ts +8 -0
- package/dist/shipping/FixedDiscount.d.ts.map +1 -0
- package/dist/shipping/FixedDiscount.js +30 -0
- package/dist/shipping/RateNameSelector.d.ts +10 -0
- package/dist/shipping/RateNameSelector.d.ts.map +1 -0
- package/dist/shipping/RateNameSelector.js +45 -0
- package/dist/shipping/ShippingDiscount.d.ts +14 -0
- package/dist/shipping/ShippingDiscount.d.ts.map +1 -0
- package/dist/shipping/ShippingDiscount.js +48 -0
- package/dist/shipping/api.d.ts +2019 -0
- package/dist/shipping/api.d.ts.map +1 -0
- package/dist/shipping/api.js +1147 -0
- package/package.json +26 -7
- package/migrate.ts +0 -64
- package/src/common/AndSelector.ts +0 -42
- package/src/common/Campaign.ts +0 -70
- package/src/common/CampaignConfiguration.ts +0 -10
- package/src/common/CampaignFactory.ts +0 -233
- package/src/common/CartAmountQualifier.ts +0 -64
- package/src/common/CartHasItemQualifier.ts +0 -80
- package/src/common/CartQuantityQualifier.ts +0 -94
- package/src/common/CountryCodeQualifier.ts +0 -49
- package/src/common/CustomerEmailQualifier.ts +0 -67
- package/src/common/CustomerSubscriberQualifier.ts +0 -32
- package/src/common/CustomerTagQualifier.ts +0 -69
- package/src/common/DiscountCart.ts +0 -161
- package/src/common/DiscountInterface.ts +0 -26
- package/src/common/OrSelector.ts +0 -40
- package/src/common/PostCartAmountQualifier.ts +0 -21
- package/src/common/ProductHandleSelector.ts +0 -32
- package/src/common/ProductIdSelector.ts +0 -34
- package/src/common/ProductTagSelector.ts +0 -63
- package/src/common/ProductTypeSelector.ts +0 -40
- package/src/common/Qualifier.ts +0 -67
- package/src/common/SaleItemSelector.ts +0 -36
- package/src/common/Selector.ts +0 -66
- package/src/common/SubscriptionItemSelector.ts +0 -23
- package/src/lineItem/BuyXGetY.ts +0 -131
- package/src/lineItem/ConditionalDiscount.ts +0 -102
- package/src/lineItem/FixedItemDiscount.ts +0 -51
- package/src/lineItem/PercentageDiscount.ts +0 -44
- package/src/lineItem/api.ts +0 -2103
- package/src/shipping/FixedDiscount.ts +0 -37
- package/src/shipping/RateNameSelector.ts +0 -54
- package/src/shipping/ShippingDiscount.ts +0 -75
- package/src/shipping/api.ts +0 -2014
- package/tests/AndSelector.test.ts +0 -27
- package/tests/CartQuantityQualifier.test.ts +0 -381
- package/tests/CountryCodeQualifier.test.ts +0 -55
- package/tests/CustomerSubscriberQualifier.test.ts +0 -101
- package/tests/CustomerTagQualifier.test.ts +0 -71
- package/tests/DiscountCart.test.ts +0 -115
- package/tests/OrSelector.test.ts +0 -27
- package/tests/ProductIdSelector.test.ts +0 -83
- package/tests/ProductTagSelector.test.ts +0 -75
- package/tests/Qualifier.test.ts +0 -193
- package/tests/RateNameSelector.test.ts +0 -107
- package/tests/SaleItemSelector.test.ts +0 -113
- package/tests/Selector.test.ts +0 -83
- package/tests/ShippingDiscount.test.ts +0 -147
- package/tsconfig.json +0 -25
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FixedItemDiscount = void 0;
|
|
4
|
+
class FixedItemDiscount {
|
|
5
|
+
amount;
|
|
6
|
+
appliesToEachItem;
|
|
7
|
+
message;
|
|
8
|
+
constructor(amount, appliesToEachItem, message) {
|
|
9
|
+
this.amount = amount;
|
|
10
|
+
this.appliesToEachItem = appliesToEachItem;
|
|
11
|
+
this.message = message;
|
|
12
|
+
}
|
|
13
|
+
apply(items) {
|
|
14
|
+
const targets = items.map(({ lineItem, maxDiscounts }) => {
|
|
15
|
+
const variant = lineItem.merchandise;
|
|
16
|
+
return {
|
|
17
|
+
productVariant: {
|
|
18
|
+
id: variant.id,
|
|
19
|
+
quantity: maxDiscounts == 0 ? undefined : maxDiscounts,
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
});
|
|
23
|
+
return {
|
|
24
|
+
targets,
|
|
25
|
+
value: {
|
|
26
|
+
fixedAmount: {
|
|
27
|
+
amount: this.amount,
|
|
28
|
+
appliesToEachItem: this.appliesToEachItem,
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
message: this.message,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
exports.FixedItemDiscount = FixedItemDiscount;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { Campaign } from '../common/Campaign';
|
|
2
|
+
import type { DiscountCart } from '../common/DiscountCart';
|
|
3
|
+
import type { DiscountInterface } from '../common/DiscountInterface';
|
|
4
|
+
import type { QualifierBehavior, Qualifier } from '../common/Qualifier';
|
|
5
|
+
import type { AndSelector } from '../common/AndSelector';
|
|
6
|
+
import type { OrSelector } from '../common/OrSelector';
|
|
7
|
+
export interface Tier {
|
|
8
|
+
threshold: number;
|
|
9
|
+
discount: DiscountInterface;
|
|
10
|
+
productIds?: string[];
|
|
11
|
+
productTags?: string[];
|
|
12
|
+
itemsToDiscount?: number;
|
|
13
|
+
label?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* MultiTierDiscount - Applies tiered discounts based on cart subtotal
|
|
17
|
+
*
|
|
18
|
+
* This campaign evaluates the cart total (excluding gifts) and applies
|
|
19
|
+
* the discount from the highest qualifying tier.
|
|
20
|
+
*
|
|
21
|
+
* Example use case: Tiered gift with purchase
|
|
22
|
+
* - Spend $75: Get free product A
|
|
23
|
+
* - Spend $100: Get free product B
|
|
24
|
+
* - Spend $250: Get free product C
|
|
25
|
+
*
|
|
26
|
+
* Only the highest qualifying tier is applied (e.g., if cart is $150,
|
|
27
|
+
* only the $100 tier applies, not both $75 and $100).
|
|
28
|
+
*/
|
|
29
|
+
export declare class MultiTierDiscount extends Campaign {
|
|
30
|
+
tiers: Tier[];
|
|
31
|
+
excludeGiftTags: string[];
|
|
32
|
+
constructor(behavior: QualifierBehavior, qualifiers: [Qualifier | AndSelector | OrSelector], tiers: Tier[], excludeGiftTags?: string[]);
|
|
33
|
+
/**
|
|
34
|
+
* Calculate cart subtotal excluding gift items
|
|
35
|
+
*/
|
|
36
|
+
private calculateCartSubtotal;
|
|
37
|
+
/**
|
|
38
|
+
* Find the highest qualifying tier based on cart subtotal
|
|
39
|
+
*/
|
|
40
|
+
private findQualifyingTier;
|
|
41
|
+
/**
|
|
42
|
+
* Filter line items that match the tier's product criteria
|
|
43
|
+
*/
|
|
44
|
+
private getApplicableLineItems;
|
|
45
|
+
run(discountCart: DiscountCart): DiscountCart;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=MultiTierDiscount.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MultiTierDiscount.d.ts","sourceRoot":"","sources":["../../src/lineItem/MultiTierDiscount.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,EAEV,iBAAiB,EAClB,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EACV,iBAAiB,EACjB,SAAS,EACV,MAAM,qBAAqB,CAAC;AAE7B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEvD,MAAM,WAAW,IAAI;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;;;GAaG;AACH,qBAAa,iBAAkB,SAAQ,QAAQ;IAC7C,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,eAAe,EAAE,MAAM,EAAE,CAAC;gBAGxB,QAAQ,EAAE,iBAAiB,EAC3B,UAAU,EAAE,CAAC,SAAS,GAAG,WAAW,GAAG,UAAU,CAAC,EAClD,KAAK,EAAE,IAAI,EAAE,EACb,eAAe,GAAE,MAAM,EAA0B;IASnD;;OAEG;IACH,OAAO,CAAC,qBAAqB;IA8B7B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAS1B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IA+B9B,GAAG,CAAC,YAAY,EAAE,YAAY,GAAG,YAAY;CA2E9C"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MultiTierDiscount = void 0;
|
|
4
|
+
const Campaign_1 = require("../common/Campaign");
|
|
5
|
+
/**
|
|
6
|
+
* MultiTierDiscount - Applies tiered discounts based on cart subtotal
|
|
7
|
+
*
|
|
8
|
+
* This campaign evaluates the cart total (excluding gifts) and applies
|
|
9
|
+
* the discount from the highest qualifying tier.
|
|
10
|
+
*
|
|
11
|
+
* Example use case: Tiered gift with purchase
|
|
12
|
+
* - Spend $75: Get free product A
|
|
13
|
+
* - Spend $100: Get free product B
|
|
14
|
+
* - Spend $250: Get free product C
|
|
15
|
+
*
|
|
16
|
+
* Only the highest qualifying tier is applied (e.g., if cart is $150,
|
|
17
|
+
* only the $100 tier applies, not both $75 and $100).
|
|
18
|
+
*/
|
|
19
|
+
class MultiTierDiscount extends Campaign_1.Campaign {
|
|
20
|
+
tiers;
|
|
21
|
+
excludeGiftTags;
|
|
22
|
+
constructor(behavior, qualifiers, tiers, excludeGiftTags = ['meta-exclude-gift']) {
|
|
23
|
+
super(behavior, qualifiers);
|
|
24
|
+
// Sort tiers by threshold descending (highest first)
|
|
25
|
+
this.tiers = [...tiers].sort((a, b) => b.threshold - a.threshold);
|
|
26
|
+
this.excludeGiftTags = excludeGiftTags;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Calculate cart subtotal excluding gift items
|
|
30
|
+
*/
|
|
31
|
+
calculateCartSubtotal(discountCart) {
|
|
32
|
+
let subtotal = 0;
|
|
33
|
+
for (const line of discountCart.cart.lines) {
|
|
34
|
+
// Check if this item should be excluded from subtotal calculation
|
|
35
|
+
let isExcludedGift = false;
|
|
36
|
+
// Type guard: Only ProductVariant has product property
|
|
37
|
+
if (line.merchandise.__typename === 'ProductVariant') {
|
|
38
|
+
const variant = line.merchandise;
|
|
39
|
+
// Check if product has any of the exclude tags
|
|
40
|
+
isExcludedGift = this.excludeGiftTags.some(tag => variant.product.hasTags.filter((t) => t.hasTag && t.tag === tag).length > 0);
|
|
41
|
+
}
|
|
42
|
+
if (isExcludedGift) {
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
// Add line total to subtotal
|
|
46
|
+
const lineTotal = parseFloat(String(line.cost.totalAmount.amount));
|
|
47
|
+
subtotal += lineTotal;
|
|
48
|
+
}
|
|
49
|
+
return subtotal;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Find the highest qualifying tier based on cart subtotal
|
|
53
|
+
*/
|
|
54
|
+
findQualifyingTier(cartSubtotal) {
|
|
55
|
+
for (const tier of this.tiers) {
|
|
56
|
+
if (cartSubtotal >= tier.threshold) {
|
|
57
|
+
return tier;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Filter line items that match the tier's product criteria
|
|
64
|
+
*/
|
|
65
|
+
getApplicableLineItems(discountCart, tier) {
|
|
66
|
+
return discountCart.cart.lines.filter((line) => {
|
|
67
|
+
// Type guard: Only ProductVariant has product property
|
|
68
|
+
if (line.merchandise.__typename !== 'ProductVariant') {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
// If tier specifies product IDs, match against those
|
|
72
|
+
if (tier.productIds && tier.productIds.length > 0) {
|
|
73
|
+
const productId = line.merchandise.product.id.split('/').pop();
|
|
74
|
+
return tier.productIds.includes(productId || '');
|
|
75
|
+
}
|
|
76
|
+
// If tier specifies product tags, match against those
|
|
77
|
+
if (tier.productTags && tier.productTags.length > 0) {
|
|
78
|
+
const variant = line.merchandise;
|
|
79
|
+
return tier.productTags.some((tag) => variant.product.hasTags.filter((t) => t.hasTag && t.tag === tag).length > 0);
|
|
80
|
+
}
|
|
81
|
+
// If no product criteria specified, apply to all items
|
|
82
|
+
return true;
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
run(discountCart) {
|
|
86
|
+
// First check if cart qualifies for any discount
|
|
87
|
+
if (!this.qualifies(discountCart)) {
|
|
88
|
+
return discountCart;
|
|
89
|
+
}
|
|
90
|
+
// Calculate cart subtotal (excluding gifts)
|
|
91
|
+
const cartSubtotal = this.calculateCartSubtotal(discountCart);
|
|
92
|
+
// Find the highest qualifying tier
|
|
93
|
+
const qualifyingTier = this.findQualifyingTier(cartSubtotal);
|
|
94
|
+
if (!qualifyingTier) {
|
|
95
|
+
// Cart doesn't meet minimum threshold
|
|
96
|
+
return discountCart;
|
|
97
|
+
}
|
|
98
|
+
// Get line items that match this tier's product criteria
|
|
99
|
+
const applicableLineItems = this.getApplicableLineItems(discountCart, qualifyingTier);
|
|
100
|
+
if (applicableLineItems.length === 0) {
|
|
101
|
+
// No matching products found
|
|
102
|
+
return discountCart;
|
|
103
|
+
}
|
|
104
|
+
// Sort by price (ascending) to discount cheapest items first
|
|
105
|
+
applicableLineItems.sort((a, b) => {
|
|
106
|
+
const priceA = parseFloat(String(a.cost.amountPerQuantity.amount));
|
|
107
|
+
const priceB = parseFloat(String(b.cost.amountPerQuantity.amount));
|
|
108
|
+
return priceA - priceB;
|
|
109
|
+
});
|
|
110
|
+
const itemsToApplyDiscounts = [];
|
|
111
|
+
let remainingDiscounts = qualifyingTier.itemsToDiscount;
|
|
112
|
+
// Apply discount to matching items up to the limit
|
|
113
|
+
applicableLineItems.forEach((lineItem) => {
|
|
114
|
+
if (remainingDiscounts === 0)
|
|
115
|
+
return;
|
|
116
|
+
if (remainingDiscounts !== undefined) {
|
|
117
|
+
// Apply to as many items as possible up to the limit
|
|
118
|
+
if (lineItem.quantity >= remainingDiscounts) {
|
|
119
|
+
itemsToApplyDiscounts.push({
|
|
120
|
+
lineItem,
|
|
121
|
+
maxDiscounts: remainingDiscounts,
|
|
122
|
+
});
|
|
123
|
+
remainingDiscounts = 0;
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
// Apply to all items in this line
|
|
127
|
+
itemsToApplyDiscounts.push({
|
|
128
|
+
lineItem,
|
|
129
|
+
maxDiscounts: lineItem.quantity,
|
|
130
|
+
});
|
|
131
|
+
remainingDiscounts -= lineItem.quantity;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
// No limit, apply to all matching items
|
|
136
|
+
itemsToApplyDiscounts.push({
|
|
137
|
+
lineItem,
|
|
138
|
+
maxDiscounts: lineItem.quantity,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
// Apply the tier's discount to all selected items
|
|
143
|
+
itemsToApplyDiscounts.forEach((item) => {
|
|
144
|
+
const discount = qualifyingTier.discount;
|
|
145
|
+
discount.apply([item]);
|
|
146
|
+
});
|
|
147
|
+
return discountCart;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
exports.MultiTierDiscount = MultiTierDiscount;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Discount, ApplyDiscount, DiscountInterface } from '../common/DiscountInterface';
|
|
2
|
+
export declare class PercentageDiscount implements DiscountInterface {
|
|
3
|
+
discount: number;
|
|
4
|
+
message?: string;
|
|
5
|
+
constructor(percentage: number, message?: string);
|
|
6
|
+
apply(items: ApplyDiscount[]): Discount;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=PercentageDiscount.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PercentageDiscount.d.ts","sourceRoot":"","sources":["../../src/lineItem/PercentageDiscount.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,QAAQ,EACR,aAAa,EACb,iBAAiB,EAClB,MAAM,6BAA6B,CAAC;AAErC,qBAAa,kBACX,YAAW,iBAAiB;IAE5B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;gBAEL,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM;IAKhD,KAAK,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,QAAQ;CAyBxC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PercentageDiscount = void 0;
|
|
4
|
+
class PercentageDiscount {
|
|
5
|
+
discount;
|
|
6
|
+
message;
|
|
7
|
+
constructor(percentage, message) {
|
|
8
|
+
this.discount = percentage;
|
|
9
|
+
this.message = message;
|
|
10
|
+
}
|
|
11
|
+
apply(items) {
|
|
12
|
+
const targets = items.map(({ lineItem, maxDiscounts }) => {
|
|
13
|
+
const variant = lineItem.merchandise;
|
|
14
|
+
return {
|
|
15
|
+
productVariant: {
|
|
16
|
+
id: variant.id,
|
|
17
|
+
quantity: maxDiscounts == 0 ? undefined : maxDiscounts,
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
});
|
|
21
|
+
return {
|
|
22
|
+
targets,
|
|
23
|
+
value: {
|
|
24
|
+
percentage: {
|
|
25
|
+
value: this.discount,
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
message: this.message,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
exports.PercentageDiscount = PercentageDiscount;
|