@darkpos/pricing 1.0.107 → 1.0.109
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__/item.test.js
CHANGED
|
@@ -1557,4 +1557,278 @@ describe('Item actions', () => {
|
|
|
1557
1557
|
'No Clean (0 Unit @ $0.00/Unit)'
|
|
1558
1558
|
);
|
|
1559
1559
|
});
|
|
1560
|
+
|
|
1561
|
+
test('Should not apply modifier value when extractCalculatedValue is true but modifier is invalid', () => {
|
|
1562
|
+
const prepayDiscount50Percent = {
|
|
1563
|
+
compute: {
|
|
1564
|
+
amount: 50,
|
|
1565
|
+
type: 'percentage',
|
|
1566
|
+
action: 'subtract',
|
|
1567
|
+
},
|
|
1568
|
+
properties: {
|
|
1569
|
+
extractCalculatedValue: true,
|
|
1570
|
+
},
|
|
1571
|
+
conditions: {
|
|
1572
|
+
valid: null,
|
|
1573
|
+
rules: [
|
|
1574
|
+
{
|
|
1575
|
+
key: 'payment',
|
|
1576
|
+
value: 'prepay',
|
|
1577
|
+
operand: '$in',
|
|
1578
|
+
},
|
|
1579
|
+
],
|
|
1580
|
+
},
|
|
1581
|
+
name: 'percentageDiscount50',
|
|
1582
|
+
type: 'discount',
|
|
1583
|
+
};
|
|
1584
|
+
|
|
1585
|
+
const orderItem = {
|
|
1586
|
+
price: 7.59,
|
|
1587
|
+
quantity: 1,
|
|
1588
|
+
modifiers: [prepayDiscount50Percent],
|
|
1589
|
+
};
|
|
1590
|
+
const order = {
|
|
1591
|
+
items: [orderItem],
|
|
1592
|
+
};
|
|
1593
|
+
|
|
1594
|
+
const calculatedOrder = pricingService.order.calculate(order);
|
|
1595
|
+
|
|
1596
|
+
expect(calculatedOrder.total).toBe(7.59);
|
|
1597
|
+
expect(calculatedOrder.items[0].price).toBe(7.59);
|
|
1598
|
+
expect(calculatedOrder.items[0].total).toBe(7.59);
|
|
1599
|
+
expect(calculatedOrder.items[0].modifiers.length).toBe(1);
|
|
1600
|
+
expect(calculatedOrder.items[0].modifiers[0]._computed).toMatchObject({
|
|
1601
|
+
amount: 0,
|
|
1602
|
+
description: 'percentageDiscount50',
|
|
1603
|
+
});
|
|
1604
|
+
});
|
|
1605
|
+
|
|
1606
|
+
test('Should apply modifier value when extractCalculatedValue is true and modifier is valid', () => {
|
|
1607
|
+
const prepayDiscount50Percent = {
|
|
1608
|
+
compute: {
|
|
1609
|
+
amount: 50,
|
|
1610
|
+
type: 'percentage',
|
|
1611
|
+
action: 'subtract',
|
|
1612
|
+
},
|
|
1613
|
+
properties: {
|
|
1614
|
+
extractCalculatedValue: true,
|
|
1615
|
+
},
|
|
1616
|
+
name: 'percentageDiscount50',
|
|
1617
|
+
type: 'discount',
|
|
1618
|
+
};
|
|
1619
|
+
|
|
1620
|
+
const orderItem = {
|
|
1621
|
+
price: 7.59,
|
|
1622
|
+
quantity: 1,
|
|
1623
|
+
modifiers: [prepayDiscount50Percent],
|
|
1624
|
+
};
|
|
1625
|
+
const order = {
|
|
1626
|
+
items: [orderItem],
|
|
1627
|
+
};
|
|
1628
|
+
|
|
1629
|
+
const calculatedOrder = pricingService.order.calculate(order);
|
|
1630
|
+
|
|
1631
|
+
expect(calculatedOrder.total).toBe(7.59);
|
|
1632
|
+
expect(calculatedOrder.items[0].price).toBe(7.59);
|
|
1633
|
+
expect(calculatedOrder.items[0].total).toBe(7.59);
|
|
1634
|
+
expect(calculatedOrder.items[0].modifiers.length).toBe(1);
|
|
1635
|
+
expect(calculatedOrder.items[0].modifiers[0]._computed).toMatchObject({
|
|
1636
|
+
amount: -7.59,
|
|
1637
|
+
description: 'percentageDiscount50 (-$7.59)',
|
|
1638
|
+
});
|
|
1639
|
+
});
|
|
1640
|
+
|
|
1641
|
+
test('Should apply modifier value when extractCalculatedValue is true and modifier is valid (being also a payment modifier)', () => {
|
|
1642
|
+
const prepayDiscount50Percent = {
|
|
1643
|
+
compute: {
|
|
1644
|
+
amount: 50,
|
|
1645
|
+
type: 'percentage',
|
|
1646
|
+
action: 'subtract',
|
|
1647
|
+
},
|
|
1648
|
+
properties: {
|
|
1649
|
+
extractCalculatedValue: true,
|
|
1650
|
+
},
|
|
1651
|
+
conditions: {
|
|
1652
|
+
valid: null,
|
|
1653
|
+
rules: [
|
|
1654
|
+
{
|
|
1655
|
+
key: 'payment',
|
|
1656
|
+
value: 'prepay',
|
|
1657
|
+
operand: '$in',
|
|
1658
|
+
},
|
|
1659
|
+
],
|
|
1660
|
+
},
|
|
1661
|
+
name: 'percentageDiscount50',
|
|
1662
|
+
type: 'discount',
|
|
1663
|
+
};
|
|
1664
|
+
|
|
1665
|
+
const orderItem = {
|
|
1666
|
+
price: 7.59,
|
|
1667
|
+
quantity: 1,
|
|
1668
|
+
modifiers: [prepayDiscount50Percent],
|
|
1669
|
+
};
|
|
1670
|
+
const order = {
|
|
1671
|
+
items: [orderItem],
|
|
1672
|
+
};
|
|
1673
|
+
|
|
1674
|
+
const calculatedOrder = pricingService.order.calculate(order, {
|
|
1675
|
+
isPrepay: true,
|
|
1676
|
+
});
|
|
1677
|
+
|
|
1678
|
+
expect(calculatedOrder.total).toBe(7.59);
|
|
1679
|
+
expect(calculatedOrder.items[0].price).toBe(7.59);
|
|
1680
|
+
expect(calculatedOrder.items[0].total).toBe(7.59);
|
|
1681
|
+
expect(calculatedOrder.items[0].modifiers.length).toBe(2);
|
|
1682
|
+
|
|
1683
|
+
expect(calculatedOrder.items[0].modifiers[0]._computed).toMatchObject({
|
|
1684
|
+
amount: 0,
|
|
1685
|
+
description: 'percentageDiscount50',
|
|
1686
|
+
});
|
|
1687
|
+
expect(calculatedOrder.items[0].modifiers[1]._computed).toMatchObject({
|
|
1688
|
+
amount: -7.59,
|
|
1689
|
+
description: '$7.59 discount (-$7.59)',
|
|
1690
|
+
});
|
|
1691
|
+
});
|
|
1692
|
+
|
|
1693
|
+
test('Should use a price override modifier and quantity override modifier in combination accordingly', () => {
|
|
1694
|
+
const overridePriceMod = {
|
|
1695
|
+
_id: '675354ee39a47228afd1f1a4',
|
|
1696
|
+
attributes: ['override'],
|
|
1697
|
+
modifierId: '6751f7eeb60c71cefee138ee',
|
|
1698
|
+
name: 'Override item price fixed 0',
|
|
1699
|
+
tags: ['default', 'all'],
|
|
1700
|
+
direct: true,
|
|
1701
|
+
properties: {
|
|
1702
|
+
override: {
|
|
1703
|
+
type: 'fixed',
|
|
1704
|
+
field: 'price',
|
|
1705
|
+
fixedValue: 0,
|
|
1706
|
+
multiplier: false,
|
|
1707
|
+
},
|
|
1708
|
+
},
|
|
1709
|
+
};
|
|
1710
|
+
const overrideQuantityMod = {
|
|
1711
|
+
_id: '675354ee39a47228afd1f1a5',
|
|
1712
|
+
attributes: ['override'],
|
|
1713
|
+
modifierId: '6751f7eeb60c71cefee138ff',
|
|
1714
|
+
name: 'Override item quantity fixed 20',
|
|
1715
|
+
tags: ['default', 'all'],
|
|
1716
|
+
direct: true,
|
|
1717
|
+
properties: {
|
|
1718
|
+
override: {
|
|
1719
|
+
type: 'fixed',
|
|
1720
|
+
field: 'quantity',
|
|
1721
|
+
fixedValue: 20,
|
|
1722
|
+
multiplier: false,
|
|
1723
|
+
},
|
|
1724
|
+
},
|
|
1725
|
+
};
|
|
1726
|
+
|
|
1727
|
+
const itemWithModifierAmountFixed10 = {
|
|
1728
|
+
name: "Men's 3pc Tuxedo",
|
|
1729
|
+
pieces: 1,
|
|
1730
|
+
price: 10,
|
|
1731
|
+
quantity: 1,
|
|
1732
|
+
modifiers: [overridePriceMod, overrideQuantityMod],
|
|
1733
|
+
_id: '675354e939a47228afd1f199',
|
|
1734
|
+
itemId: '62cdbfd01ee1b400193281ee',
|
|
1735
|
+
};
|
|
1736
|
+
const newItem = pricingService.item.calculate(
|
|
1737
|
+
itemWithModifierAmountFixed10
|
|
1738
|
+
);
|
|
1739
|
+
expect(newItem.price).toBe(0);
|
|
1740
|
+
expect(newItem.total).toBe(0);
|
|
1741
|
+
expect(newItem.quantity).toBe(20);
|
|
1742
|
+
expect(newItem).toHaveProperty('price', 0);
|
|
1743
|
+
expect(newItem.modifiers[0]).toHaveProperty('_computed', {
|
|
1744
|
+
amount: 0,
|
|
1745
|
+
description: 'Override item price fixed 0 ($0.00/Unit)',
|
|
1746
|
+
});
|
|
1747
|
+
|
|
1748
|
+
expect(newItem.modifiers[1]).toHaveProperty('_computed', {
|
|
1749
|
+
amount: 0,
|
|
1750
|
+
description: 'Override item quantity fixed 20',
|
|
1751
|
+
});
|
|
1752
|
+
|
|
1753
|
+
expect(newItem).toHaveProperty('subTotals', {
|
|
1754
|
+
_included: 0,
|
|
1755
|
+
_xincluded: 0,
|
|
1756
|
+
_direct: 0,
|
|
1757
|
+
_xdirect: 0,
|
|
1758
|
+
_simple: 0,
|
|
1759
|
+
_actual: 0,
|
|
1760
|
+
});
|
|
1761
|
+
});
|
|
1762
|
+
|
|
1763
|
+
test('Should use a total override modifier and quantity override modifier in combination accordingly', () => {
|
|
1764
|
+
const overrideTotalMod = {
|
|
1765
|
+
_id: '675354ee39a47228afd1f1a4',
|
|
1766
|
+
attributes: ['override'],
|
|
1767
|
+
modifierId: '6751f7eeb60c71cefee138ee',
|
|
1768
|
+
name: 'Override item total fixed 0',
|
|
1769
|
+
tags: ['default', 'all'],
|
|
1770
|
+
direct: true,
|
|
1771
|
+
properties: {
|
|
1772
|
+
override: {
|
|
1773
|
+
type: 'fixed',
|
|
1774
|
+
field: 'total',
|
|
1775
|
+
fixedValue: 0,
|
|
1776
|
+
multiplier: false,
|
|
1777
|
+
},
|
|
1778
|
+
sort: 2,
|
|
1779
|
+
},
|
|
1780
|
+
};
|
|
1781
|
+
const overrideQuantityMod = {
|
|
1782
|
+
_id: '675354ee39a47228afd1f1a5',
|
|
1783
|
+
attributes: ['override'],
|
|
1784
|
+
modifierId: '6751f7eeb60c71cefee138ff',
|
|
1785
|
+
name: 'Override item quantity fixed 20',
|
|
1786
|
+
tags: ['default', 'all'],
|
|
1787
|
+
direct: true,
|
|
1788
|
+
properties: {
|
|
1789
|
+
override: {
|
|
1790
|
+
type: 'fixed',
|
|
1791
|
+
field: 'quantity',
|
|
1792
|
+
fixedValue: 20,
|
|
1793
|
+
multiplier: false,
|
|
1794
|
+
},
|
|
1795
|
+
sort: 1,
|
|
1796
|
+
},
|
|
1797
|
+
};
|
|
1798
|
+
|
|
1799
|
+
const itemWithModifierAmountFixed10 = {
|
|
1800
|
+
name: "Men's 3pc Tuxedo",
|
|
1801
|
+
pieces: 1,
|
|
1802
|
+
price: 10,
|
|
1803
|
+
quantity: 1,
|
|
1804
|
+
modifiers: [overrideTotalMod, overrideQuantityMod],
|
|
1805
|
+
_id: '675354e939a47228afd1f199',
|
|
1806
|
+
itemId: '62cdbfd01ee1b400193281ee',
|
|
1807
|
+
};
|
|
1808
|
+
const newItem = pricingService.item.calculate(
|
|
1809
|
+
itemWithModifierAmountFixed10
|
|
1810
|
+
);
|
|
1811
|
+
expect(newItem.price).toBe(10);
|
|
1812
|
+
expect(newItem.total).toBe(0);
|
|
1813
|
+
expect(newItem.quantity).toBe(20);
|
|
1814
|
+
expect(newItem.modifiers[0]).toHaveProperty('_computed', {
|
|
1815
|
+
amount: 0,
|
|
1816
|
+
description: 'Override item quantity fixed 20',
|
|
1817
|
+
});
|
|
1818
|
+
|
|
1819
|
+
expect(newItem.modifiers[1]).toHaveProperty('_computed', {
|
|
1820
|
+
amount: -200,
|
|
1821
|
+
description: 'Override item total fixed 0 (-$200.00)',
|
|
1822
|
+
});
|
|
1823
|
+
|
|
1824
|
+
expect(newItem).toHaveProperty('subTotals', {
|
|
1825
|
+
_included: 0,
|
|
1826
|
+
_xincluded: -200,
|
|
1827
|
+
undefined: -200,
|
|
1828
|
+
_direct: -200,
|
|
1829
|
+
_xdirect: 0,
|
|
1830
|
+
_simple: 200,
|
|
1831
|
+
_actual: 200,
|
|
1832
|
+
});
|
|
1833
|
+
});
|
|
1560
1834
|
});
|
package/lib/item/calculate.js
CHANGED
|
@@ -40,10 +40,6 @@ module.exports = ({ _, utils, actions, modifierActions }) => {
|
|
|
40
40
|
item.properties.overwrittenQuantity = undefined;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
const price = parseFloat(actions.getPriceWithoutModifiers({ item }));
|
|
44
|
-
let quantity = parseInt(item.quantity, 10);
|
|
45
|
-
subTotals._simple = math.mul(price, quantity);
|
|
46
|
-
|
|
47
43
|
const modifiers = [];
|
|
48
44
|
let { modifiers: itemModifiersPrev = [] } =
|
|
49
45
|
actions.removeModifiersByQuantity(item);
|
|
@@ -103,6 +99,15 @@ module.exports = ({ _, utils, actions, modifierActions }) => {
|
|
|
103
99
|
);
|
|
104
100
|
});
|
|
105
101
|
|
|
102
|
+
let price = parseFloat(
|
|
103
|
+
actions.getPriceWithoutModifiers({
|
|
104
|
+
price: item.price,
|
|
105
|
+
modifiers: validatedModifiers,
|
|
106
|
+
})
|
|
107
|
+
);
|
|
108
|
+
let quantity = parseInt(item.quantity, 10);
|
|
109
|
+
subTotals._simple = math.mul(price, quantity);
|
|
110
|
+
|
|
106
111
|
const modifiersToNotCompute = actions.getModifiersToNotCompute({
|
|
107
112
|
item,
|
|
108
113
|
validatedModifiers,
|
|
@@ -169,6 +174,7 @@ module.exports = ({ _, utils, actions, modifierActions }) => {
|
|
|
169
174
|
overwrittenPrice: item.price,
|
|
170
175
|
};
|
|
171
176
|
item.price = priceOverride;
|
|
177
|
+
price = priceOverride;
|
|
172
178
|
}
|
|
173
179
|
|
|
174
180
|
if (modifierActions.isQuantityOverride(modifier)) {
|
|
@@ -177,7 +183,7 @@ module.exports = ({ _, utils, actions, modifierActions }) => {
|
|
|
177
183
|
...(item.properties ? item.properties : {}),
|
|
178
184
|
overwrittenQuantity: item.quantity,
|
|
179
185
|
};
|
|
180
|
-
subTotals._simple = math.mul(price, newQuantity);
|
|
186
|
+
subTotals._simple = math.mul(item.price, newQuantity);
|
|
181
187
|
item.quantity = parseInt(newQuantity, 10);
|
|
182
188
|
quantity = parseInt(newQuantity, 10);
|
|
183
189
|
}
|
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
module.exports = ({ actions, modifierActions }) =>
|
|
2
2
|
/* eslint-disable no-restricted-syntax */
|
|
3
|
-
function getPriceWithoutModifiers({
|
|
4
|
-
const basePrice = actions.getBasePrice(
|
|
3
|
+
function getPriceWithoutModifiers({ price, modifiers }) {
|
|
4
|
+
const basePrice = actions.getBasePrice({ price });
|
|
5
5
|
|
|
6
|
-
if (
|
|
7
|
-
!item ||
|
|
8
|
-
!Array.isArray(item.modifiers) ||
|
|
9
|
-
typeof basePrice !== 'number'
|
|
10
|
-
)
|
|
6
|
+
if (!Array.isArray(modifiers) || typeof basePrice !== 'number')
|
|
11
7
|
return basePrice;
|
|
12
8
|
|
|
13
|
-
const calculatedModifiers =
|
|
14
|
-
|
|
9
|
+
const calculatedModifiers = modifiers.filter(
|
|
10
|
+
modifier =>
|
|
11
|
+
modifierActions.isValid(modifier) &&
|
|
12
|
+
modifierActions.isExtractCalculatedValue({ modifier })
|
|
15
13
|
);
|
|
16
14
|
|
|
17
15
|
if (calculatedModifiers.length === 0) return basePrice;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@darkpos/pricing",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.109",
|
|
4
4
|
"description": "Pricing calculator",
|
|
5
5
|
"author": "Dark POS",
|
|
6
6
|
"license": "ISC",
|
|
@@ -54,5 +54,5 @@
|
|
|
54
54
|
"supertest": "^6.2.3",
|
|
55
55
|
"supervisor": "^0.12.0"
|
|
56
56
|
},
|
|
57
|
-
"gitHead": "
|
|
57
|
+
"gitHead": "a971788284c326a00e19c914ffbfdc22f1069c72"
|
|
58
58
|
}
|