@darkpos/pricing 1.0.104 → 1.0.105

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.
@@ -1315,6 +1315,10 @@ describe('Conditions not met for the item', () => {
1315
1315
  expect(calculatedOrder.total).toBe(7.5);
1316
1316
  expect(calculatedOrder.items[0].total).toBe(7.5);
1317
1317
  expect(calculatedOrder.items[0].modifiers[0].conditions.valid).toBe(true);
1318
+ expect(calculatedOrder.items[0].modifiers[0].locked).toBe(true);
1319
+ expect(calculatedOrder.items[0].modifiers[0].properties.customerId).toBe(
1320
+ '123456789'
1321
+ );
1318
1322
  });
1319
1323
 
1320
1324
  test('Should mark modifier as not valid if customerTotalSales !== 0', () => {
@@ -1372,6 +1376,7 @@ describe('Conditions not met for the item', () => {
1372
1376
  expect(calculatedOrder.total).toBe(10);
1373
1377
  expect(calculatedOrder.items[0].total).toBe(10);
1374
1378
  expect(calculatedOrder.items[0].modifiers[0].conditions.valid).toBe(false);
1379
+ expect(calculatedOrder.items[0].modifiers[0].locked).toBe(undefined);
1375
1380
  });
1376
1381
 
1377
1382
  test('Should mark modifier as valid if customerTotalVisits === 0', () => {
@@ -1429,6 +1434,10 @@ describe('Conditions not met for the item', () => {
1429
1434
  expect(calculatedOrder.total).toBe(7.5);
1430
1435
  expect(calculatedOrder.items[0].total).toBe(7.5);
1431
1436
  expect(calculatedOrder.items[0].modifiers[0].conditions.valid).toBe(true);
1437
+ expect(calculatedOrder.items[0].modifiers[0].locked).toBe(true);
1438
+ expect(calculatedOrder.items[0].modifiers[0].properties.customerId).toBe(
1439
+ '123456789'
1440
+ );
1432
1441
  });
1433
1442
 
1434
1443
  test('Should mark modifier as not valid if customerTotalVisits !== 0', () => {
@@ -1486,5 +1495,133 @@ describe('Conditions not met for the item', () => {
1486
1495
  expect(calculatedOrder.total).toBe(10);
1487
1496
  expect(calculatedOrder.items[0].total).toBe(10);
1488
1497
  expect(calculatedOrder.items[0].modifiers[0].conditions.valid).toBe(false);
1498
+ expect(calculatedOrder.items[0].modifiers[0].locked).toBe(undefined);
1499
+ });
1500
+
1501
+ test('Should mark modifier as not valid if there is no customer', () => {
1502
+ const modifier = {
1503
+ _id: '6819114c06c23d37c1f19412',
1504
+ name: 'first order discount',
1505
+ type: 'discount',
1506
+ tags: ['default'],
1507
+ direct: true,
1508
+ conditions: {
1509
+ valid: null,
1510
+ rules: [
1511
+ {
1512
+ key: 'customerTotalVisits',
1513
+ value: 0,
1514
+ operand: '$eq',
1515
+ },
1516
+ ],
1517
+ },
1518
+ compute: {
1519
+ type: 'percentage',
1520
+ action: 'subtract',
1521
+ amount: 25,
1522
+ },
1523
+ };
1524
+
1525
+ const item = {
1526
+ _id: 'abc',
1527
+ price: 10,
1528
+ quantity: 1,
1529
+ modifiers: [],
1530
+ };
1531
+
1532
+ let order = {
1533
+ items: [item],
1534
+ };
1535
+
1536
+ order = pricingService.order.addItemModifier({
1537
+ order,
1538
+ modifier,
1539
+ itemIndex: 0,
1540
+ });
1541
+
1542
+ expect(order.items[0].modifiers.length).toBe(1);
1543
+
1544
+ const calculatedOrder = pricingService.order.calculate(order);
1545
+
1546
+ expect(calculatedOrder.total).toBe(10);
1547
+ expect(calculatedOrder.items[0].total).toBe(10);
1548
+ expect(calculatedOrder.items[0].modifiers[0].conditions.valid).toBe(false);
1549
+ expect(calculatedOrder.items[0].modifiers[0].locked).toBe(undefined);
1550
+ expect(calculatedOrder.items[0].modifiers[0].properties).toBe(undefined);
1551
+ });
1552
+
1553
+ test('Should mark modifier as valid if there is a customer, no matter is stats is undefined', () => {
1554
+ const modifier = {
1555
+ _id: '6819114c06c23d37c1f19412',
1556
+ name: 'first order discount',
1557
+ type: 'discount',
1558
+ tags: ['default'],
1559
+ direct: true,
1560
+ conditions: {
1561
+ valid: null,
1562
+ rules: [
1563
+ {
1564
+ key: 'customerTotalVisits',
1565
+ value: 0,
1566
+ operand: '$eq',
1567
+ },
1568
+ ],
1569
+ },
1570
+ compute: {
1571
+ type: 'percentage',
1572
+ action: 'subtract',
1573
+ amount: 25,
1574
+ },
1575
+ };
1576
+
1577
+ const item = {
1578
+ _id: 'abc',
1579
+ price: 10,
1580
+ quantity: 1,
1581
+ modifiers: [],
1582
+ };
1583
+
1584
+ let order = {
1585
+ items: [item],
1586
+ customer: {
1587
+ _id: 'abcd1234',
1588
+ },
1589
+ };
1590
+
1591
+ order = pricingService.order.addItemModifier({
1592
+ order,
1593
+ modifier,
1594
+ itemIndex: 0,
1595
+ });
1596
+
1597
+ expect(order.items[0].modifiers.length).toBe(1);
1598
+
1599
+ let calculatedOrder = pricingService.order.calculate(order);
1600
+
1601
+ expect(calculatedOrder.total).toBe(7.5);
1602
+ expect(calculatedOrder.items[0].total).toBe(7.5);
1603
+ expect(calculatedOrder.items[0].modifiers[0].conditions.valid).toBe(true);
1604
+ expect(calculatedOrder.items[0].modifiers[0].locked).toBe(true);
1605
+ expect(calculatedOrder.items[0].modifiers[0].properties.customerId).toBe(
1606
+ 'abcd1234'
1607
+ );
1608
+
1609
+ calculatedOrder = pricingService.order.calculate({
1610
+ ...calculatedOrder,
1611
+ customer: {
1612
+ _id: '11122555',
1613
+ stats: {
1614
+ totalVisits: 15,
1615
+ },
1616
+ },
1617
+ });
1618
+
1619
+ expect(calculatedOrder.total).toBe(10);
1620
+ expect(calculatedOrder.items[0].total).toBe(10);
1621
+ expect(calculatedOrder.items[0].modifiers[0].conditions.valid).toBe(false);
1622
+ expect(calculatedOrder.items[0].modifiers[0].locked).toBe(false);
1623
+ expect(calculatedOrder.items[0].modifiers[0].properties.customerId).toBe(
1624
+ undefined
1625
+ );
1489
1626
  });
1490
1627
  });
@@ -12,18 +12,7 @@ module.exports = ({ _, utils, actions, modifierActions }) => {
12
12
  const isPrepay = opts.isPrepay || false;
13
13
  const startRequestDate = opts.startRequestDate || null;
14
14
  const endRequestDate = opts.endRequestDate || null;
15
-
16
- let customerTotalVisits = 0;
17
- let customerTotalSales = 0;
18
-
19
- if (
20
- opts.customer &&
21
- typeof opts.customer !== 'string' &&
22
- opts.customer.stats
23
- ) {
24
- customerTotalVisits = opts.customer.stats.totalVisits || 0;
25
- customerTotalSales = opts.customer.stats.totalSales || 0;
26
- }
15
+ const customer = opts.customer || null;
27
16
 
28
17
  const lockPaymentModifiers = !!opts.lockPaymentModifiers;
29
18
  const allItems = Array.isArray(opts.items) ? opts.items : [];
@@ -56,16 +45,21 @@ module.exports = ({ _, utils, actions, modifierActions }) => {
56
45
  subTotals._simple = math.mul(price, quantity);
57
46
 
58
47
  const modifiers = [];
59
- const { modifiers: itemModifiersPrev = [] } =
48
+ let { modifiers: itemModifiersPrev = [] } =
60
49
  actions.removeModifiersByQuantity(item);
61
50
 
51
+ itemModifiersPrev = modifierActions.unlockCustomerStatsModifiers({
52
+ modifiers: itemModifiersPrev,
53
+ customer,
54
+ });
55
+
62
56
  const itemModifiers = [...itemModifiersPrev].filter(
63
57
  mod =>
64
58
  !modifierActions.isCalculatedPaymentModifier(mod) ||
65
59
  modifierActions.isLocked(mod)
66
60
  );
67
61
 
68
- const validatedModifiers = actions.validateModifiers({
62
+ let validatedModifiers = actions.validateModifiers({
69
63
  item,
70
64
  itemModifiers,
71
65
  startRequestDate,
@@ -74,8 +68,12 @@ module.exports = ({ _, utils, actions, modifierActions }) => {
74
68
  paymentMethod,
75
69
  paymentType,
76
70
  isPrepay,
77
- customerTotalVisits,
78
- customerTotalSales,
71
+ customer,
72
+ });
73
+
74
+ validatedModifiers = modifierActions.lockCustomerStatsModifiers({
75
+ modifiers: validatedModifiers,
76
+ customer,
79
77
  });
80
78
 
81
79
  const modifiersToCompute = validatedModifiers.filter(
@@ -8,8 +8,7 @@ module.exports = ({ modifierActions }) =>
8
8
  paymentMethod,
9
9
  paymentType,
10
10
  isPrepay,
11
- customerTotalVisits,
12
- customerTotalSales,
11
+ customer,
13
12
  }) {
14
13
  const validatedModifiers = [];
15
14
  const firstValidatedModifiers = itemModifiers.map(each =>
@@ -21,8 +20,7 @@ module.exports = ({ modifierActions }) =>
21
20
  paymentMethod,
22
21
  paymentType,
23
22
  isPrepay,
24
- customerTotalVisits,
25
- customerTotalSales,
23
+ customer,
26
24
  })
27
25
  );
28
26
 
@@ -1,4 +1,15 @@
1
1
  module.exports = ({ actions, utils }) => {
2
+ const getCustomerStat = (customer, key) => {
3
+ if (
4
+ !customer ||
5
+ !customer.stats ||
6
+ typeof customer.stats[key] !== 'number'
7
+ ) {
8
+ return 0;
9
+ }
10
+ return customer.stats[key];
11
+ };
12
+
2
13
  const modifierConditionPass = (
3
14
  modifier,
4
15
  {
@@ -9,8 +20,7 @@ module.exports = ({ actions, utils }) => {
9
20
  paymentMethod,
10
21
  paymentType,
11
22
  isPrepay,
12
- customerTotalVisits,
13
- customerTotalSales,
23
+ customer,
14
24
  }
15
25
  ) =>
16
26
  modifier.conditions && Array.isArray(modifier.conditions.rules)
@@ -86,14 +96,16 @@ module.exports = ({ actions, utils }) => {
86
96
  condition.operand
87
97
  );
88
98
  case 'customerTotalVisits':
99
+ if (!actions.isValidCustomer(customer)) return false;
89
100
  return actions.validateNumberCondition(
90
- customerTotalVisits,
101
+ getCustomerStat(customer, 'totalVisits'),
91
102
  condition.value,
92
103
  condition.operand
93
104
  );
94
105
  case 'customerTotalSales':
106
+ if (!actions.isValidCustomer(customer)) return false;
95
107
  return actions.validateNumberCondition(
96
- customerTotalSales,
108
+ getCustomerStat(customer, 'totalSales'),
97
109
  condition.value,
98
110
  condition.operand
99
111
  );
@@ -138,8 +150,7 @@ module.exports = ({ actions, utils }) => {
138
150
  paymentMethod,
139
151
  paymentType,
140
152
  isPrepay,
141
- customerTotalVisits,
142
- customerTotalSales,
153
+ customer,
143
154
  } = opts;
144
155
  return (
145
156
  modifier &&
@@ -151,8 +162,7 @@ module.exports = ({ actions, utils }) => {
151
162
  paymentMethod,
152
163
  paymentType,
153
164
  isPrepay,
154
- customerTotalVisits,
155
- customerTotalSales,
165
+ customer,
156
166
  })
157
167
  );
158
168
  }
@@ -167,6 +167,12 @@ const isNotesOverride = require('./isNotesOverride');
167
167
  const isOverrideSubtotal = require('./isOverrideSubtotal');
168
168
  const validatePaymentCondition = require('./validatePaymentCondition');
169
169
  const createManualModifier = require('./createManualModifier');
170
+ const isCustomerStatsModifier = require('./isCustomerStatsModifier');
171
+ const isTotalSalesModifier = require('./isTotalSalesModifier');
172
+ const isTotalVisitsModifier = require('./isTotalVisitsModifier');
173
+ const isValidCustomer = require('./isValidCustomer');
174
+ const lockCustomerStatsModifiers = require('./lockCustomerStatsModifiers');
175
+ const unlockCustomerStatsModifiers = require('./unlockCustomerStatsModifiers');
170
176
 
171
177
  const modifierActions = (deps = {}) => {
172
178
  const actions = {};
@@ -347,6 +353,12 @@ const modifierActions = (deps = {}) => {
347
353
  isOverrideSubtotal: isOverrideSubtotal(innerDeps),
348
354
  validatePaymentCondition: validatePaymentCondition(innerDeps),
349
355
  createManualModifier: createManualModifier(innerDeps),
356
+ isCustomerStatsModifier: isCustomerStatsModifier(innerDeps),
357
+ isTotalSalesModifier: isTotalSalesModifier(innerDeps),
358
+ isTotalVisitsModifier: isTotalVisitsModifier(innerDeps),
359
+ isValidCustomer: isValidCustomer(innerDeps),
360
+ lockCustomerStatsModifiers: lockCustomerStatsModifiers(innerDeps),
361
+ unlockCustomerStatsModifiers: unlockCustomerStatsModifiers(innerDeps),
350
362
  });
351
363
 
352
364
  Object.keys(freezedActions).forEach(actionName => {
@@ -0,0 +1,7 @@
1
+ module.exports = ({ actions }) =>
2
+ function isCustomerStatModifier(modifier) {
3
+ return (
4
+ actions.isTotalSalesModifier(modifier) ||
5
+ actions.isTotalVisitsModifier(modifier)
6
+ );
7
+ };
@@ -0,0 +1,11 @@
1
+ module.exports = () =>
2
+ function isPaymentTypeModifier(modifier) {
3
+ return !!(
4
+ modifier &&
5
+ modifier.conditions &&
6
+ Array.isArray(modifier.conditions.rules) &&
7
+ modifier.conditions.rules.some(
8
+ condition => condition.key === 'customerTotalSales'
9
+ )
10
+ );
11
+ };
@@ -0,0 +1,11 @@
1
+ module.exports = () =>
2
+ function isTotalVisitsModifier(modifier) {
3
+ return !!(
4
+ modifier &&
5
+ modifier.conditions &&
6
+ Array.isArray(modifier.conditions.rules) &&
7
+ modifier.conditions.rules.some(
8
+ condition => condition.key === 'customerTotalVisits'
9
+ )
10
+ );
11
+ };
@@ -0,0 +1,4 @@
1
+ module.exports = () =>
2
+ function isValid(customer) {
3
+ return customer && typeof customer !== 'string' && customer._id;
4
+ };
@@ -0,0 +1,22 @@
1
+ module.exports = ({ actions }) =>
2
+ function lockCustomerStatsModifiers({ modifiers, customer }) {
3
+ if (!Array.isArray(modifiers)) return [];
4
+ return modifiers.map(valMod => {
5
+ if (
6
+ actions.isValidCustomer(customer) &&
7
+ actions.isCustomerStatsModifier(valMod) &&
8
+ actions.isValid(valMod)
9
+ ) {
10
+ return {
11
+ ...valMod,
12
+ locked: true,
13
+ properties: {
14
+ ...(valMod.properties || {}),
15
+ customerId: customer._id,
16
+ },
17
+ };
18
+ }
19
+
20
+ return valMod;
21
+ });
22
+ };
@@ -0,0 +1,23 @@
1
+ module.exports = ({ actions }) =>
2
+ function unlockCustomerStatsModifiers({ modifiers, customer }) {
3
+ if (!Array.isArray(modifiers)) return [];
4
+ return modifiers.map(valMod => {
5
+ if (
6
+ actions.isValidCustomer(customer) &&
7
+ actions.isCustomerStatsModifier(valMod) &&
8
+ actions.isLocked(valMod) &&
9
+ valMod.properties.customerId !== customer._id
10
+ ) {
11
+ return {
12
+ ...valMod,
13
+ locked: false,
14
+ properties: {
15
+ ...(valMod.properties || {}),
16
+ customerId: undefined,
17
+ },
18
+ };
19
+ }
20
+
21
+ return valMod;
22
+ });
23
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@darkpos/pricing",
3
- "version": "1.0.104",
3
+ "version": "1.0.105",
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": "0a74400677d6852460e9a7773a3e6480912ad8b3"
57
+ "gitHead": "09c5c7462144195081cfc13eb82f55f4530a77aa"
58
58
  }