@darkpos/pricing 1.0.21 → 1.0.23

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.
@@ -25,7 +25,9 @@ module.exports = ({ utils, modifierActions }) => {
25
25
  );
26
26
  }, 0);
27
27
 
28
- // check validation
28
+ if (modifier.compute.type === 'percentage' && modifier.type !== 'credit')
29
+ return itemsModifiers;
30
+
29
31
  if (math.abs(totalDistributed) !== math.abs(orderModifierTotal)) {
30
32
  const difference = math.sub(orderModifierTotal, totalDistributed);
31
33
  const selectedItem = items.find(
@@ -66,17 +66,26 @@ module.exports = ({ _, utils, modifierActions }) => {
66
66
 
67
67
  modifiers.push(_modifier);
68
68
  const { type, _computed } = _modifier;
69
- let computedAmount = modifierActions.isIgnoreQuantity(_modifier)
70
- ? _computed.amount
71
- : math.mul(_computed.amount, quantity);
69
+
70
+ const computedAmountCalc = math.mul(_computed.amount, quantity);
71
+ const computedPriceCalc = math.mul(computedPrice * quantity);
72
+
73
+ let computedAmount =
74
+ _modifier.compute.type === 'percentage' ||
75
+ modifierActions.isIgnoreQuantity(_modifier) ||
76
+ math.gt(math.abs(computedAmountCalc), computedPriceCalc)
77
+ ? _computed.amount
78
+ : computedAmountCalc;
79
+
72
80
  // subscription modifiers have fixed amount and can't be multiplied by quantity
73
81
  if (modifierActions.isSubscription(_modifier))
74
82
  computedAmount = _computed.amount;
75
83
 
84
+ prvPrice = math.add(prvPrice, math.div(_computed.amount, quantity));
85
+ prvSort = sort;
86
+
76
87
  if (included) {
77
88
  subTotals._included = math.add(subTotals._included, computedAmount);
78
- prvPrice = math.add(prvPrice, computedAmount);
79
- prvSort = sort;
80
89
  } else {
81
90
  subTotals._xincluded = math.add(subTotals._xincluded, computedAmount);
82
91
  subTotals[type] = math.add(subTotals[type] || 0, computedAmount);
@@ -89,7 +98,9 @@ module.exports = ({ _, utils, modifierActions }) => {
89
98
 
90
99
  subTotals._actual = math.add(subTotals._simple, subTotals._included);
91
100
 
92
- const total = math.add(subTotals._actual, subTotals._xincluded);
101
+ const total = math.toDecimalPlaces(
102
+ math.add(subTotals._actual, subTotals._xincluded)
103
+ );
93
104
 
94
105
  return {
95
106
  ...item,
@@ -16,15 +16,17 @@ module.exports = ({ utils }) => {
16
16
  }
17
17
  }
18
18
 
19
- const total = Object.keys(subTotals).reduce(
20
- (acc, key) => math.add(acc, subTotals[key]),
21
- subTotal
19
+ const total = math.toDecimalPlaces(
20
+ Object.keys(subTotals).reduce(
21
+ (acc, key) => math.add(acc, subTotals[key]),
22
+ subTotal
23
+ )
22
24
  );
23
25
 
24
26
  subTotals = Object.keys(subTotals).reduce(
25
27
  (acc, key) => ({
26
28
  ...acc,
27
- [key]: subTotals[key],
29
+ [key]: math.toDecimalPlaces(subTotals[key]),
28
30
  }),
29
31
  {}
30
32
  );
@@ -1,13 +1,13 @@
1
1
  /**
2
2
  * Get calculated modifier
3
3
  */
4
- module.exports = ({ _, constants, utils, localization, actions }) => {
4
+ module.exports = ({ _, constants, utils, localization, actions }) => {
5
5
  const { math } = utils;
6
6
  const { Modifier } = constants;
7
7
 
8
8
  return function calculate(
9
9
  modifier = {},
10
- options = { price: 0, skip: false }
10
+ options = { price: 0, quantity: 0, skip: false }
11
11
  ) {
12
12
  const { name, compute } = modifier;
13
13
  const { type, action, amount = 0 } = compute || {};
@@ -15,8 +15,16 @@
15
15
  amount: 0,
16
16
  description: '',
17
17
  };
18
- const maxAmount = actions.getProperty(modifier, 'maxAmount');
18
+
19
+ const maxAmountProp = actions.getProperty(modifier, 'maxAmount');
20
+
19
21
  if (!options.skip) {
22
+ const maxAmountCalc = math.mul(options.price, options.quantity);
23
+
24
+ const maxAmount = maxAmountProp
25
+ ? math.min(maxAmountProp, maxAmountCalc)
26
+ : maxAmountCalc;
27
+
20
28
  const multiplier = action === Modifier.Compute.Actions.SUBTRACT ? -1 : 1;
21
29
 
22
30
  if (type === Modifier.Compute.Types.FIXED)
@@ -24,15 +32,16 @@
24
32
 
25
33
  if (type === Modifier.Compute.Types.PERCENTAGE)
26
34
  _computed.amount = math.div(
27
- math.mul(multiplier, options.price, amount),
35
+ math.mul(multiplier, options.price, options.quantity, amount),
28
36
  100
29
37
  );
30
38
 
31
39
  if (!type || action === Modifier.Compute.Actions.OVERRIDE)
32
40
  _computed.amount = 0;
33
41
 
34
- if (maxAmount && math.gt(math.abs(_computed.amount), maxAmount))
35
- _computed.amount = maxAmount;
42
+ if (math.gt(math.abs(_computed.amount), maxAmount)) {
43
+ _computed.amount = maxAmount * multiplier;
44
+ }
36
45
  }
37
46
 
38
47
  const localAmount = localization.formatAmount(_computed.amount);
@@ -16,9 +16,14 @@ module.exports = ({ _, utils, constants, actions }) => {
16
16
  let modifierAmount = amount;
17
17
 
18
18
  if (type === Modifier.Compute.Types.PERCENTAGE) {
19
- const modifierAmountByPercentage = math.div(
20
- math.mul(options.orderTotal, amount),
21
- 100
19
+ const modifierAmountByPercentage = math.toDecimalPlaces(
20
+ math.div(
21
+ math.mul(
22
+ modifier.type === 'credit' ? options.orderTotal : options.itemTotal,
23
+ amount
24
+ ),
25
+ 100
26
+ )
22
27
  );
23
28
  modifierAmount =
24
29
  maxAmount !== null && modifierAmountByPercentage > maxAmount
@@ -26,14 +31,20 @@ module.exports = ({ _, utils, constants, actions }) => {
26
31
  : modifierAmountByPercentage;
27
32
  }
28
33
 
29
- let amountToApply = 0;
34
+ let amountToApply = modifierAmount;
30
35
 
31
- if (!math.isZero(options.orderTotal))
32
- amountToApply = math.div(
33
- math.mul(modifierAmount, options.itemTotal),
34
- options.orderTotal,
35
- options.itemQuantity
36
+ if (
37
+ !math.isZero(options.orderTotal) &&
38
+ (type !== Modifier.Compute.Types.PERCENTAGE || modifier.type === 'credit')
39
+ ) {
40
+ amountToApply = math.toDecimalPlaces(
41
+ math.div(
42
+ math.mul(modifierAmount, options.itemTotal),
43
+ options.orderTotal,
44
+ options.itemQuantity
45
+ )
36
46
  );
47
+ }
37
48
 
38
49
  const modifierToAdd = actions.create({
39
50
  ..._.cloneDeep(modifier),
@@ -43,6 +54,12 @@ module.exports = ({ _, utils, constants, actions }) => {
43
54
  amount: amountToApply,
44
55
  action: compute.action || Modifier.Compute.Actions.SUBTRACT,
45
56
  },
57
+ properties: {
58
+ ignoreQuantity:
59
+ (modifier.properties && modifier.properties.ignoreQuantity) ||
60
+ type === Modifier.Compute.Types.PERCENTAGE,
61
+ ...(modifier.properties || {}),
62
+ },
46
63
  });
47
64
  if (maxAmount !== null) delete modifierToAdd.properties.maxAmount;
48
65
 
@@ -0,0 +1,9 @@
1
+ module.exports = () =>
2
+ function getModifiersByMaxSort(modifiers, maxSort) {
3
+ if (!Array.isArray(modifiers) || !Number.isInteger(maxSort))
4
+ return modifiers;
5
+
6
+ return modifiers.filter(
7
+ mod => !mod.properties || mod.properties.sort < maxSort
8
+ );
9
+ };
@@ -7,9 +7,11 @@ module.exports = ({ utils }) => {
7
7
  totalSplitedOrder,
8
8
  }) =>
9
9
  totalOriginOrder
10
- ? math.div(
11
- math.mul(modifierAmount, totalSplitedOrder || 0),
12
- totalOriginOrder
10
+ ? math.toDecimalPlaces(
11
+ math.div(
12
+ math.mul(modifierAmount, totalSplitedOrder || 0),
13
+ totalOriginOrder
14
+ )
13
15
  )
14
16
  : 0;
15
17
 
@@ -45,6 +45,7 @@ const getInheritedModifiers = require('./getInheritedModifiers');
45
45
  const getLaundryModifiers = require('./getLaundryModifiers');
46
46
  const getMatchTagsModifiers = require('./getMatchTagsModifiers');
47
47
  const getModifierIndex = require('./getModifierIndex');
48
+ const getModifiersByMaxSort = require('./getModifiersByMaxSort');
48
49
  const getPreferences = require('./getPreferences');
49
50
  const getPromotionModifiers = require('./getPromotionModifiers');
50
51
  const getPromptMessage = require('./getPromptMessage');
@@ -180,6 +181,7 @@ const modifierActions = (deps = {}) => {
180
181
  getLaundryModifiers: getLaundryModifiers(innerDeps),
181
182
  getMatchTagsModifiers: getMatchTagsModifiers(innerDeps),
182
183
  getModifierIndex: getModifierIndex(innerDeps),
184
+ getModifiersByMaxSort: getModifiersByMaxSort(innerDeps),
183
185
  getPreferences: getPreferences(innerDeps),
184
186
  getPromotionModifiers: getPromotionModifiers(innerDeps),
185
187
  getPromptMessage: getPromptMessage(innerDeps),
@@ -1,24 +1,25 @@
1
1
  /* eslint-disable no-prototype-builtins */
2
- module.exports = () => {
2
+ module.exports = ({ actions }) => {
3
3
  function compareValues(key, order = 'asc') {
4
4
  return function innerSort(a, b) {
5
5
  // property doesn't exist on either object
6
- if (
7
- !a.properties ||
8
- !a.properties.hasOwnProperty(key) ||
9
- !b.properties ||
10
- !b.properties.hasOwnProperty(key)
11
- )
6
+ const aVal = actions.getProperty(a, key);
7
+ const bVal = actions.getProperty(b, key);
8
+
9
+ if (aVal == null && bVal === null) {
12
10
  return 0;
11
+ }
12
+
13
+ if (aVal == null) {
14
+ return -1;
15
+ }
16
+
17
+ if (bVal === null) {
18
+ return 1;
19
+ }
13
20
 
14
- const varA =
15
- typeof a.properties[key] === 'string'
16
- ? a.properties[key].toUpperCase()
17
- : a.properties[key];
18
- const varB =
19
- typeof b.properties[key] === 'string'
20
- ? b.properties[key].toUpperCase()
21
- : b.properties[key];
21
+ const varA = typeof aVal === 'string' ? aVal.toUpperCase() : aVal;
22
+ const varB = typeof bVal === 'string' ? bVal.toUpperCase() : bVal;
22
23
 
23
24
  let comparison = 0;
24
25
  if (varA > varB) comparison = 1;
@@ -11,10 +11,12 @@ module.exports = ({ _, itemActions, modifierActions }) =>
11
11
  if (!items.length)
12
12
  return { ...order, subTotals: {}, subTotal: 0, total: 0 };
13
13
 
14
- const orderModifiers = modifierActions.removeLocked(order.modifiers);
14
+ const sortedOrderModifiers = modifierActions.sort(
15
+ modifierActions.removeLocked(order.modifiers)
16
+ );
15
17
 
16
18
  let itemsWNIM = items.map(item =>
17
- itemActions.removeModifiers({ item, modifiers: orderModifiers })
19
+ itemActions.removeModifiers({ item, modifiers: sortedOrderModifiers })
18
20
  );
19
21
 
20
22
  itemsWNIM = itemActions.calculate(itemsWNIM);
@@ -25,25 +27,39 @@ module.exports = ({ _, itemActions, modifierActions }) =>
25
27
  items: itemsWNIM,
26
28
  };
27
29
 
28
- if (!orderModifiers.length) return newOrder;
30
+ if (!sortedOrderModifiers.length) return newOrder;
29
31
 
30
- const newItems = itemsWNIM || items;
31
- let itemsWIM = _.cloneDeep(newItems);
32
+ let tempItems = itemsWNIM || items;
33
+ let itemsWIM = _.cloneDeep(tempItems);
34
+ let prvSort = null;
32
35
 
33
36
  let computedTotal = newOrder.total;
34
37
 
35
- for (const modifier of orderModifiers) {
38
+ for (const modifier of sortedOrderModifiers) {
36
39
  const isCredit = modifierActions.isCredit(modifier);
37
- let tempItems = newItems;
40
+ const sort = modifierActions.getProperty(modifier, 'sort');
41
+
42
+ if (prvSort !== sort) {
43
+ if (sort) {
44
+ tempItems = itemsWIM.map(item => ({
45
+ ...item,
46
+ modifiers: modifierActions.getModifiersByMaxSort(
47
+ item.modifiers,
48
+ modifier.properties.sort
49
+ ),
50
+ }));
51
+ } else {
52
+ tempItems = itemsWIM;
53
+ }
54
+ tempItems = itemActions.calculate(tempItems);
55
+ }
38
56
 
39
57
  if (isCredit) {
40
58
  const calculatedItemWIM = itemActions.calculate(itemsWIM);
41
59
  computedTotal = itemActions.getTotals(calculatedItemWIM).total;
42
60
  }
43
61
 
44
- const hasItems = modifierActions.hasItems({ modifier });
45
-
46
- if (hasItems) {
62
+ if (modifierActions.hasItems({ modifier })) {
47
63
  tempItems = itemActions.getItems(tempItems, modifier.items);
48
64
  }
49
65
 
@@ -54,8 +70,6 @@ module.exports = ({ _, itemActions, modifierActions }) =>
54
70
  })
55
71
  );
56
72
 
57
- tempItems = itemActions.calculate(tempItems);
58
-
59
73
  computedTotal = itemActions.getTotals(tempItems).total;
60
74
 
61
75
  const itemsModifiers = itemActions.addIndirectModifier({
@@ -71,6 +85,7 @@ module.exports = ({ _, itemActions, modifierActions }) =>
71
85
  Boolean
72
86
  ),
73
87
  }));
88
+ prvSort = sort;
74
89
  }
75
90
 
76
91
  const calculatedItemWIM = itemActions.calculate(itemsWIM);
@@ -17,6 +17,7 @@ module.exports = ({ utils }) => {
17
17
  orderSubTotals[key]
18
18
  );
19
19
  }
20
+
20
21
  return {
21
22
  total: math.add(acc.total, order.total),
22
23
  subTotals,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@darkpos/pricing",
3
- "version": "1.0.21",
3
+ "version": "1.0.23",
4
4
  "description": "Pricing calculator",
5
5
  "author": "Dark POS",
6
6
  "license": "ISC",
@@ -19,7 +19,7 @@
19
19
  "access": "public"
20
20
  },
21
21
  "dependencies": {
22
- "@darkpos/utils": "1.0.8",
22
+ "@darkpos/utils": "1.0.9",
23
23
  "lodash": "^4.17.21",
24
24
  "moment-timezone": "^0.5.34"
25
25
  },
@@ -36,5 +36,5 @@
36
36
  "supertest": "^6.2.3",
37
37
  "supervisor": "^0.12.0"
38
38
  },
39
- "gitHead": "30595eb4b38240679c45e5eff7ac875719e9dcd0"
39
+ "gitHead": "6648705882ec8351463ba823c213cf7c198129ce"
40
40
  }