@cloudcommerce/app-discounts 0.0.125 → 0.0.127
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/.turbo/turbo-build.log +1 -1
- package/lib-mjs/apply-discount.mjs +94 -20
- package/package.json +4 -4
package/.turbo/turbo-build.log
CHANGED
|
@@ -32,9 +32,11 @@ export default async ({ params, application }) => {
|
|
|
32
32
|
return response;
|
|
33
33
|
};
|
|
34
34
|
|
|
35
|
-
const addDiscount = (discount, flag, label) => {
|
|
35
|
+
const addDiscount = (discount, flag, label, maxDiscount) => {
|
|
36
36
|
let value;
|
|
37
|
-
|
|
37
|
+
if (typeof maxDiscount !== 'number') {
|
|
38
|
+
maxDiscount = params.amount[discount.apply_at || 'total'];
|
|
39
|
+
}
|
|
38
40
|
if (maxDiscount) {
|
|
39
41
|
// update amount discount and total
|
|
40
42
|
if (discount.type === 'percentage') {
|
|
@@ -82,6 +84,11 @@ export default async ({ params, application }) => {
|
|
|
82
84
|
}
|
|
83
85
|
const kitDiscounts = getValidDiscountRules(config.product_kit_discounts, params, params.items)
|
|
84
86
|
.sort((a, b) => {
|
|
87
|
+
if (!Array.isArray(a.product_ids) || !a.product_ids.length) {
|
|
88
|
+
if (Array.isArray(b.product_ids) && b.product_ids.length) {
|
|
89
|
+
return 1;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
85
92
|
if (a.min_quantity > b.min_quantity) {
|
|
86
93
|
return -1;
|
|
87
94
|
}
|
|
@@ -98,6 +105,8 @@ export default async ({ params, application }) => {
|
|
|
98
105
|
});
|
|
99
106
|
// prevent applying duplicated kit discount for same items
|
|
100
107
|
let discountedItemIds = [];
|
|
108
|
+
// check buy together recommendations
|
|
109
|
+
const buyTogether = [];
|
|
101
110
|
|
|
102
111
|
kitDiscounts.forEach((kitDiscount, index) => {
|
|
103
112
|
if (kitDiscount) {
|
|
@@ -106,39 +115,101 @@ export default async ({ params, application }) => {
|
|
|
106
115
|
: [];
|
|
107
116
|
let kitItems = productIds.length
|
|
108
117
|
? params.items.filter((item) => item.quantity && productIds.indexOf(item.product_id) > -1)
|
|
109
|
-
: params.items;
|
|
110
|
-
kitItems = kitItems.filter((item) => discountedItemIds.indexOf(item.
|
|
118
|
+
: params.items.filter((item) => item.quantity);
|
|
119
|
+
kitItems = kitItems.filter((item) => discountedItemIds.indexOf(item.product_id) === -1);
|
|
120
|
+
if (!kitItems.length) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const recommendBuyTogether = () => {
|
|
125
|
+
if (
|
|
126
|
+
params.items.length === 1
|
|
127
|
+
&& productIds.length <= 4
|
|
128
|
+
&& buyTogether.length < 300
|
|
129
|
+
) {
|
|
130
|
+
const baseProductId = params.items[0].product_id;
|
|
131
|
+
if (productIds.indexOf(baseProductId) === -1) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
const baseItemQuantity = params.items[0].quantity || 1;
|
|
135
|
+
const perItemQuantity = kitDiscount.min_quantity > 2
|
|
136
|
+
? Math.max(kitDiscount.min_quantity / (productIds.length - 1) - baseItemQuantity, 1)
|
|
137
|
+
: 1;
|
|
138
|
+
const buyTogetherProducts = {};
|
|
139
|
+
productIds.forEach((productId) => {
|
|
140
|
+
if (productId !== baseProductId) {
|
|
141
|
+
buyTogetherProducts[productId] = perItemQuantity;
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
if (Object.keys(buyTogetherProducts).length) {
|
|
145
|
+
buyTogether.push({
|
|
146
|
+
products: buyTogetherProducts,
|
|
147
|
+
discount: {
|
|
148
|
+
type: kitDiscount.discount.type,
|
|
149
|
+
value: kitDiscount.discount.value,
|
|
150
|
+
},
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
const discount = { ...kitDiscount.discount };
|
|
111
157
|
if (kitDiscount.min_quantity > 0) {
|
|
112
158
|
// check total items quantity
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
159
|
+
if (kitDiscount.same_product_quantity) {
|
|
160
|
+
kitItems = kitItems.filter((item) => item.quantity >= kitDiscount.min_quantity);
|
|
161
|
+
} else {
|
|
162
|
+
let totalQuantity = 0;
|
|
163
|
+
kitItems.forEach(({ quantity }) => {
|
|
164
|
+
totalQuantity += quantity;
|
|
165
|
+
});
|
|
166
|
+
if (totalQuantity < kitDiscount.min_quantity) {
|
|
167
|
+
if (productIds.length > 1 && kitDiscount.check_all_items !== false) {
|
|
168
|
+
recommendBuyTogether();
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
if (discount.type === 'fixed' && kitDiscount.cumulative_discount !== false) {
|
|
174
|
+
discount.value *= Math.floor(totalQuantity / kitDiscount.min_quantity);
|
|
175
|
+
}
|
|
122
176
|
}
|
|
123
177
|
}
|
|
124
178
|
|
|
125
|
-
if (!params.amount || !(
|
|
179
|
+
if (!params.amount || !(discount.min_amount > params.amount.total)) {
|
|
126
180
|
if (kitDiscount.check_all_items !== false) {
|
|
127
181
|
for (let i = 0; i < productIds.length; i++) {
|
|
128
182
|
const productId = productIds[i];
|
|
129
|
-
if (
|
|
130
|
-
|
|
183
|
+
if (
|
|
184
|
+
productId
|
|
185
|
+
&& !kitItems.find((item) => item.quantity && item.product_id === productId)
|
|
186
|
+
) {
|
|
131
187
|
// product not on current cart
|
|
188
|
+
recommendBuyTogether();
|
|
132
189
|
return;
|
|
133
190
|
}
|
|
134
191
|
}
|
|
135
192
|
}
|
|
136
193
|
// apply cumulative discount \o/
|
|
137
|
-
|
|
194
|
+
if (kitDiscount.same_product_quantity) {
|
|
195
|
+
kitItems.forEach((item, i) => {
|
|
196
|
+
addDiscount(
|
|
197
|
+
discount,
|
|
198
|
+
`KIT-${(index + 1)}-${i}`,
|
|
199
|
+
kitDiscount.label,
|
|
200
|
+
ecomUtils.price(item) * (item.quantity || 1),
|
|
201
|
+
);
|
|
202
|
+
});
|
|
203
|
+
} else {
|
|
204
|
+
addDiscount(discount, `KIT-${(index + 1)}`, kitDiscount.label);
|
|
205
|
+
}
|
|
138
206
|
discountedItemIds = discountedItemIds.concat(kitItems.map((item) => item.product_id));
|
|
139
207
|
}
|
|
140
208
|
}
|
|
141
209
|
});
|
|
210
|
+
if (buyTogether.length) {
|
|
211
|
+
response.buy_together = buyTogether;
|
|
212
|
+
}
|
|
142
213
|
|
|
143
214
|
// gift products (freebies) campaings
|
|
144
215
|
if (Array.isArray(config.freebies_rules)) {
|
|
@@ -162,7 +233,7 @@ export default async ({ params, application }) => {
|
|
|
162
233
|
// start calculating discount
|
|
163
234
|
let value = 0;
|
|
164
235
|
rule.product_ids.forEach((productId) => {
|
|
165
|
-
const item = params.items.find((
|
|
236
|
+
const item = params.items.find((_item) => productId === _item.product_id);
|
|
166
237
|
if (item) {
|
|
167
238
|
value += ecomUtils.price(item);
|
|
168
239
|
}
|
|
@@ -302,8 +373,11 @@ export default async ({ params, application }) => {
|
|
|
302
373
|
// eslint-disable-next-line no-await-in-loop
|
|
303
374
|
const { data } = await api.get(`${endpoint}${query}`);
|
|
304
375
|
countOrders = data.result.length;
|
|
305
|
-
} catch (
|
|
306
|
-
|
|
376
|
+
} catch (err) {
|
|
377
|
+
return {
|
|
378
|
+
error: 'CANT_CHECK_USAGE_LIMITS',
|
|
379
|
+
message: err.message,
|
|
380
|
+
};
|
|
307
381
|
}
|
|
308
382
|
|
|
309
383
|
if (countOrders >= max) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloudcommerce/app-discounts",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.127",
|
|
5
5
|
"description": "E-Com Plus Cloud Commerce app for complex discount rules",
|
|
6
6
|
"main": "lib/discounts.js",
|
|
7
7
|
"repository": {
|
|
@@ -16,11 +16,11 @@
|
|
|
16
16
|
},
|
|
17
17
|
"homepage": "https://github.com/ecomplus/cloud-commerce/tree/main/packages/apps/discounts#readme",
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@
|
|
20
|
-
"@
|
|
19
|
+
"@ecomplus/utils": "1.5.0-rc.3",
|
|
20
|
+
"@cloudcommerce/api": "0.0.127"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
|
-
"@cloudcommerce/types": "0.0.
|
|
23
|
+
"@cloudcommerce/types": "0.0.127"
|
|
24
24
|
},
|
|
25
25
|
"scripts": {
|
|
26
26
|
"build": "sh ../../../scripts/build-lib.sh"
|