@darkpos/pricing 1.0.110 → 1.0.111
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/__TEST__/modifier/isModifierValid.test.js +58 -0
- package/__TEST__/order/conditionsNotMet.test.js +152 -0
- package/lib/modifier/areConditionsMet.js +21 -20
- package/lib/modifier/index.js +2 -0
- package/lib/modifier/isModifierValid.js +11 -0
- package/lib/modifier/validateNumberCondition.js +22 -8
- package/lib/order/addItemModifier.js +9 -2
- package/package.json +2 -2
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
const moment = require('moment-timezone');
|
|
2
|
+
const usePricing = require('../../index');
|
|
3
|
+
|
|
4
|
+
const pricingService = usePricing();
|
|
5
|
+
|
|
6
|
+
describe('Is valid Modifier', () => {
|
|
7
|
+
test('should return false if promo riched the limits', () => {
|
|
8
|
+
const today = moment();
|
|
9
|
+
|
|
10
|
+
const mockPromoModifier = {
|
|
11
|
+
attributes: ['promotion'],
|
|
12
|
+
name: 'Waly Promo',
|
|
13
|
+
sku: '#WALYPROMO',
|
|
14
|
+
properties: {
|
|
15
|
+
override: null,
|
|
16
|
+
sort: null,
|
|
17
|
+
promotion: {
|
|
18
|
+
numberOfUsesLimit: 4,
|
|
19
|
+
dateLimit: {
|
|
20
|
+
from: today.subtract(1, 'week').format('YYYY-MM-DD'),
|
|
21
|
+
to: moment().subtract(1, 'day').format('YYYY-MM-DD'),
|
|
22
|
+
},
|
|
23
|
+
numberOfUses: 3,
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
const isPromoValid =
|
|
28
|
+
pricingService.modifier.isModifierValid(mockPromoModifier);
|
|
29
|
+
|
|
30
|
+
expect(isPromoValid).toBe(false);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
test('should return true if promo has not riched the limits', () => {
|
|
34
|
+
const today = moment();
|
|
35
|
+
|
|
36
|
+
const mockPromoModifier = {
|
|
37
|
+
attributes: ['promotion'],
|
|
38
|
+
name: 'Waly Promo',
|
|
39
|
+
sku: '#WALYPROMO',
|
|
40
|
+
properties: {
|
|
41
|
+
override: null,
|
|
42
|
+
sort: null,
|
|
43
|
+
promotion: {
|
|
44
|
+
numberOfUsesLimit: 4,
|
|
45
|
+
dateLimit: {
|
|
46
|
+
from: today.subtract(1, 'day').format('YYYY-MM-DD'),
|
|
47
|
+
to: moment().add(1, 'day').format('YYYY-MM-DD'),
|
|
48
|
+
},
|
|
49
|
+
numberOfUses: 2,
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
const isPromoValid =
|
|
54
|
+
pricingService.modifier.isModifierValid(mockPromoModifier);
|
|
55
|
+
|
|
56
|
+
expect(isPromoValid).toBe(true);
|
|
57
|
+
});
|
|
58
|
+
});
|
|
@@ -1624,4 +1624,156 @@ describe('Conditions not met for the item', () => {
|
|
|
1624
1624
|
undefined
|
|
1625
1625
|
);
|
|
1626
1626
|
});
|
|
1627
|
+
|
|
1628
|
+
test('Total number of items conditions is met, using between', () => {
|
|
1629
|
+
const item1 = { pieces: 1, itemId: '1', price: 100, modifiers: [] };
|
|
1630
|
+
const item2 = { pieces: 1, itemId: '2', price: 100, modifiers: [] };
|
|
1631
|
+
const item3 = { pieces: 1, itemId: '3', price: 100, modifiers: [] };
|
|
1632
|
+
const item4 = { pieces: 1, itemId: '4', price: 100, modifiers: [] };
|
|
1633
|
+
const item5 = { pieces: 1, itemId: '5', price: 100, modifiers: [] };
|
|
1634
|
+
const item6 = { pieces: 1, itemId: '6', price: 100, modifiers: [] };
|
|
1635
|
+
|
|
1636
|
+
const order = {
|
|
1637
|
+
id: 'ord-123',
|
|
1638
|
+
items: [item1, item2, item3, item4, item5, item6],
|
|
1639
|
+
modifiers: [],
|
|
1640
|
+
};
|
|
1641
|
+
const modifier = {
|
|
1642
|
+
conditions: {
|
|
1643
|
+
rules: [
|
|
1644
|
+
{
|
|
1645
|
+
key: 'totalNumberOfItems',
|
|
1646
|
+
value: {
|
|
1647
|
+
from: 5,
|
|
1648
|
+
to: 15,
|
|
1649
|
+
},
|
|
1650
|
+
operand: '$between',
|
|
1651
|
+
},
|
|
1652
|
+
],
|
|
1653
|
+
},
|
|
1654
|
+
};
|
|
1655
|
+
const { addItemModifier } = pricingService.order;
|
|
1656
|
+
const calculatedOrder = pricingService.order.calculate(
|
|
1657
|
+
addItemModifier({
|
|
1658
|
+
order,
|
|
1659
|
+
modifier,
|
|
1660
|
+
itemIndex: 0,
|
|
1661
|
+
})
|
|
1662
|
+
);
|
|
1663
|
+
expect(calculatedOrder.items[0].modifiers.length).toEqual(1);
|
|
1664
|
+
expect(calculatedOrder.items[0].modifiers[0].conditions.valid).toEqual(
|
|
1665
|
+
true
|
|
1666
|
+
);
|
|
1667
|
+
});
|
|
1668
|
+
|
|
1669
|
+
test('Total number of items conditions is not met, using between', () => {
|
|
1670
|
+
const item1 = { pieces: 1, itemId: '1', price: 100, modifiers: [] };
|
|
1671
|
+
const item2 = { pieces: 1, itemId: '2', price: 100, modifiers: [] };
|
|
1672
|
+
const item3 = { pieces: 1, itemId: '3', price: 100, modifiers: [] };
|
|
1673
|
+
const item4 = { pieces: 1, itemId: '4', price: 100, modifiers: [] };
|
|
1674
|
+
|
|
1675
|
+
const order = {
|
|
1676
|
+
id: 'ord-123',
|
|
1677
|
+
items: [item1, item2, item3, item4],
|
|
1678
|
+
modifiers: [],
|
|
1679
|
+
};
|
|
1680
|
+
const modifier = {
|
|
1681
|
+
conditions: {
|
|
1682
|
+
rules: [
|
|
1683
|
+
{
|
|
1684
|
+
key: 'totalNumberOfItems',
|
|
1685
|
+
value: {
|
|
1686
|
+
from: 5,
|
|
1687
|
+
to: 15,
|
|
1688
|
+
},
|
|
1689
|
+
operand: '$between',
|
|
1690
|
+
},
|
|
1691
|
+
],
|
|
1692
|
+
},
|
|
1693
|
+
};
|
|
1694
|
+
const { addItemModifier } = pricingService.order;
|
|
1695
|
+
const calculatedOrder = pricingService.order.calculate(
|
|
1696
|
+
addItemModifier({
|
|
1697
|
+
order,
|
|
1698
|
+
modifier,
|
|
1699
|
+
itemIndex: 0,
|
|
1700
|
+
})
|
|
1701
|
+
);
|
|
1702
|
+
expect(calculatedOrder.items[0].modifiers.length).toEqual(1);
|
|
1703
|
+
expect(calculatedOrder.items[0].modifiers[0].conditions.valid).toEqual(
|
|
1704
|
+
false
|
|
1705
|
+
);
|
|
1706
|
+
});
|
|
1707
|
+
|
|
1708
|
+
test('Total number of items conditions is met, using gt', () => {
|
|
1709
|
+
const item1 = { pieces: 1, itemId: '1', price: 100, modifiers: [] };
|
|
1710
|
+
const item2 = { pieces: 1, itemId: '2', price: 100, modifiers: [] };
|
|
1711
|
+
const item3 = { pieces: 1, itemId: '3', price: 100, modifiers: [] };
|
|
1712
|
+
const item4 = { pieces: 1, itemId: '4', price: 100, modifiers: [] };
|
|
1713
|
+
|
|
1714
|
+
const order = {
|
|
1715
|
+
id: 'ord-123',
|
|
1716
|
+
items: [item1, item2, item3, item4],
|
|
1717
|
+
modifiers: [],
|
|
1718
|
+
};
|
|
1719
|
+
const modifier = {
|
|
1720
|
+
conditions: {
|
|
1721
|
+
rules: [
|
|
1722
|
+
{
|
|
1723
|
+
key: 'totalNumberOfItems',
|
|
1724
|
+
value: 2,
|
|
1725
|
+
operand: '$gt',
|
|
1726
|
+
},
|
|
1727
|
+
],
|
|
1728
|
+
},
|
|
1729
|
+
};
|
|
1730
|
+
const { addItemModifier } = pricingService.order;
|
|
1731
|
+
const calculatedOrder = pricingService.order.calculate(
|
|
1732
|
+
addItemModifier({
|
|
1733
|
+
order,
|
|
1734
|
+
modifier,
|
|
1735
|
+
itemIndex: 0,
|
|
1736
|
+
})
|
|
1737
|
+
);
|
|
1738
|
+
expect(calculatedOrder.items[0].modifiers.length).toEqual(1);
|
|
1739
|
+
expect(calculatedOrder.items[0].modifiers[0].conditions.valid).toEqual(
|
|
1740
|
+
true
|
|
1741
|
+
);
|
|
1742
|
+
});
|
|
1743
|
+
|
|
1744
|
+
test('Total number of items conditions is not met, using gt', () => {
|
|
1745
|
+
const item1 = { pieces: 1, itemId: '1', price: 100, modifiers: [] };
|
|
1746
|
+
const item2 = { pieces: 1, itemId: '2', price: 100, modifiers: [] };
|
|
1747
|
+
const item3 = { pieces: 1, itemId: '3', price: 100, modifiers: [] };
|
|
1748
|
+
const item4 = { pieces: 1, itemId: '4', price: 100, modifiers: [] };
|
|
1749
|
+
|
|
1750
|
+
const order = {
|
|
1751
|
+
id: 'ord-123',
|
|
1752
|
+
items: [item1, item2, item3, item4],
|
|
1753
|
+
modifiers: [],
|
|
1754
|
+
};
|
|
1755
|
+
const modifier = {
|
|
1756
|
+
conditions: {
|
|
1757
|
+
rules: [
|
|
1758
|
+
{
|
|
1759
|
+
key: 'totalNumberOfItems',
|
|
1760
|
+
value: 6,
|
|
1761
|
+
operand: '$gt',
|
|
1762
|
+
},
|
|
1763
|
+
],
|
|
1764
|
+
},
|
|
1765
|
+
};
|
|
1766
|
+
const { addItemModifier } = pricingService.order;
|
|
1767
|
+
const calculatedOrder = pricingService.order.calculate(
|
|
1768
|
+
addItemModifier({
|
|
1769
|
+
order,
|
|
1770
|
+
modifier,
|
|
1771
|
+
itemIndex: 0,
|
|
1772
|
+
})
|
|
1773
|
+
);
|
|
1774
|
+
expect(calculatedOrder.items[0].modifiers.length).toEqual(1);
|
|
1775
|
+
expect(calculatedOrder.items[0].modifiers[0].conditions.valid).toEqual(
|
|
1776
|
+
false
|
|
1777
|
+
);
|
|
1778
|
+
});
|
|
1627
1779
|
});
|
|
@@ -26,6 +26,11 @@ module.exports = ({ actions, utils }) => {
|
|
|
26
26
|
modifier.conditions && Array.isArray(modifier.conditions.rules)
|
|
27
27
|
? modifier.conditions.rules.every(condition => {
|
|
28
28
|
switch (condition.key) {
|
|
29
|
+
case 'totalNumberOfItems':
|
|
30
|
+
return actions.validateNumberCondition({
|
|
31
|
+
value: Array.isArray(allItems) ? allItems.length : 0,
|
|
32
|
+
condition,
|
|
33
|
+
});
|
|
29
34
|
case 'itemSet': {
|
|
30
35
|
if (!Array.isArray(allItems)) return true;
|
|
31
36
|
const conditionValue = Number(condition.value.itemSet || 0);
|
|
@@ -84,31 +89,27 @@ module.exports = ({ actions, utils }) => {
|
|
|
84
89
|
);
|
|
85
90
|
}
|
|
86
91
|
case 'itemPieces':
|
|
87
|
-
return actions.validateNumberCondition(
|
|
88
|
-
item.pieces,
|
|
89
|
-
condition
|
|
90
|
-
|
|
91
|
-
);
|
|
92
|
+
return actions.validateNumberCondition({
|
|
93
|
+
value: item.pieces,
|
|
94
|
+
condition,
|
|
95
|
+
});
|
|
92
96
|
case 'itemQuantity':
|
|
93
|
-
return actions.validateNumberCondition(
|
|
94
|
-
item.quantity,
|
|
95
|
-
condition
|
|
96
|
-
|
|
97
|
-
);
|
|
97
|
+
return actions.validateNumberCondition({
|
|
98
|
+
value: item.quantity,
|
|
99
|
+
condition,
|
|
100
|
+
});
|
|
98
101
|
case 'customerTotalVisits':
|
|
99
102
|
if (!actions.isValidCustomer(customer)) return false;
|
|
100
|
-
return actions.validateNumberCondition(
|
|
101
|
-
getCustomerStat(customer, 'totalVisits'),
|
|
102
|
-
condition
|
|
103
|
-
|
|
104
|
-
);
|
|
103
|
+
return actions.validateNumberCondition({
|
|
104
|
+
value: getCustomerStat(customer, 'totalVisits'),
|
|
105
|
+
condition,
|
|
106
|
+
});
|
|
105
107
|
case 'customerTotalSales':
|
|
106
108
|
if (!actions.isValidCustomer(customer)) return false;
|
|
107
|
-
return actions.validateNumberCondition(
|
|
108
|
-
getCustomerStat(customer, 'totalSales'),
|
|
109
|
-
condition
|
|
110
|
-
|
|
111
|
-
);
|
|
109
|
+
return actions.validateNumberCondition({
|
|
110
|
+
value: getCustomerStat(customer, 'totalSales'),
|
|
111
|
+
condition,
|
|
112
|
+
});
|
|
112
113
|
case 'modifiers':
|
|
113
114
|
return actions.validateRequiredModifiers(
|
|
114
115
|
item.modifiers,
|
package/lib/modifier/index.js
CHANGED
|
@@ -176,6 +176,7 @@ const unlockCustomerStatsModifiers = require('./unlockCustomerStatsModifiers');
|
|
|
176
176
|
const isAutoSplit = require('./isAutoSplit');
|
|
177
177
|
const isKeepRelatedItems = require('./isKeepRelatedItems');
|
|
178
178
|
const isSplitDepartment = require('./isSplitDepartment');
|
|
179
|
+
const isModifierValid = require('./isModifierValid');
|
|
179
180
|
|
|
180
181
|
const modifierActions = (deps = {}) => {
|
|
181
182
|
const actions = {};
|
|
@@ -365,6 +366,7 @@ const modifierActions = (deps = {}) => {
|
|
|
365
366
|
isAutoSplit: isAutoSplit(innerDeps),
|
|
366
367
|
isKeepRelatedItems: isKeepRelatedItems(innerDeps),
|
|
367
368
|
isSplitDepartment: isSplitDepartment(innerDeps),
|
|
369
|
+
isModifierValid: isModifierValid(innerDeps),
|
|
368
370
|
});
|
|
369
371
|
|
|
370
372
|
Object.keys(freezedActions).forEach(actionName => {
|
|
@@ -1,19 +1,33 @@
|
|
|
1
1
|
module.exports = () =>
|
|
2
|
-
function validateNumberCondition(
|
|
3
|
-
|
|
2
|
+
function validateNumberCondition({ value, condition }) {
|
|
3
|
+
const { operand } = condition;
|
|
4
|
+
|
|
5
|
+
const conditionValue = condition.value;
|
|
6
|
+
|
|
7
|
+
const fromValue =
|
|
8
|
+
typeof condition.value === 'object' ? condition.value.from : 0;
|
|
9
|
+
|
|
10
|
+
const toValue =
|
|
11
|
+
typeof condition.value === 'object' ? condition.value.to : 0;
|
|
12
|
+
|
|
13
|
+
if (!conditionValue && !operand) return true;
|
|
4
14
|
switch (operand) {
|
|
5
15
|
case '$eq':
|
|
6
|
-
return Number(
|
|
16
|
+
return Number(conditionValue) === value;
|
|
7
17
|
case '$ne':
|
|
8
|
-
return Number(
|
|
18
|
+
return Number(conditionValue) !== value;
|
|
9
19
|
case '$gt':
|
|
10
|
-
return Number(
|
|
20
|
+
return Number(conditionValue) < value;
|
|
11
21
|
case '$gte':
|
|
12
|
-
return Number(
|
|
22
|
+
return Number(conditionValue) <= value;
|
|
13
23
|
case '$lt':
|
|
14
|
-
return Number(
|
|
24
|
+
return Number(conditionValue) > value;
|
|
15
25
|
case '$lte':
|
|
16
|
-
return Number(
|
|
26
|
+
return Number(conditionValue) >= value;
|
|
27
|
+
case '$between':
|
|
28
|
+
return (
|
|
29
|
+
Number(value) >= Number(fromValue) && Number(value) <= Number(toValue)
|
|
30
|
+
);
|
|
17
31
|
default:
|
|
18
32
|
return false;
|
|
19
33
|
}
|
|
@@ -16,8 +16,15 @@ module.exports = ({ actions, itemActions, modifierActions, utils, _ }) => {
|
|
|
16
16
|
item: itemProp,
|
|
17
17
|
})
|
|
18
18
|
) {
|
|
19
|
-
onError
|
|
19
|
+
if (onError)
|
|
20
|
+
onError('modifier.has.reached.the.maximum.amount.of.applies');
|
|
21
|
+
|
|
22
|
+
return itemProp;
|
|
23
|
+
}
|
|
20
24
|
|
|
25
|
+
// Check if Modifier is Valid/Available
|
|
26
|
+
if (!modifierActions.isModifierValid(_modifier)) {
|
|
27
|
+
if (onError) onError('modifier.has.reached.the.maximum.of.uses');
|
|
21
28
|
return itemProp;
|
|
22
29
|
}
|
|
23
30
|
|
|
@@ -46,7 +53,7 @@ module.exports = ({ actions, itemActions, modifierActions, utils, _ }) => {
|
|
|
46
53
|
modifier,
|
|
47
54
|
itemIndex,
|
|
48
55
|
originalItem,
|
|
49
|
-
onError,
|
|
56
|
+
onError = () => {},
|
|
50
57
|
}) {
|
|
51
58
|
let order = _.cloneDeep(orderProp);
|
|
52
59
|
if (!order || itemIndex < 0 || !modifier) return order;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@darkpos/pricing",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.111",
|
|
4
4
|
"description": "Pricing calculator",
|
|
5
5
|
"author": "Dark POS",
|
|
6
6
|
"license": "ISC",
|
|
@@ -55,5 +55,5 @@
|
|
|
55
55
|
"supertest": "^6.2.3",
|
|
56
56
|
"supervisor": "^0.12.0"
|
|
57
57
|
},
|
|
58
|
-
"gitHead": "
|
|
58
|
+
"gitHead": "b12a6c9aef83deec91c4ebe365bd9d604a0eecdd"
|
|
59
59
|
}
|