@darkpos/pricing 1.0.96 → 1.0.99

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.
@@ -236,4 +236,142 @@ describe('addItemModifier Function', () => {
236
236
  pricingService.order.addItemModifier(invalidModifierMock, orderMock);
237
237
  }).toThrow(Error); // Expect an error to be thrown with invalid input
238
238
  });
239
+
240
+ test('Add department modifier with customerTagsExtend and confirm price is correct, then remove it and confirm correct price again.', () => {
241
+ const order = {
242
+ _id: '68532dec3d51e6291225ccd9',
243
+
244
+ items: [
245
+ {
246
+ pieces: 2,
247
+
248
+ total: 129,
249
+ price: 129,
250
+ quantity: 1,
251
+ modifiers: [],
252
+ tags: ['default'],
253
+ category: null,
254
+ __typename: 'OrderItem',
255
+ priceLevels: [
256
+ {
257
+ value: 129,
258
+ tags: ['default'],
259
+ },
260
+ {
261
+ value: 15,
262
+ tags: ['default', 'vip'],
263
+ },
264
+ {
265
+ value: 10,
266
+ tags: ['default', 'rich'],
267
+ },
268
+ ],
269
+ costLevels: [],
270
+ itemId: '67fea241af24e570c032b319',
271
+ subTotals: {},
272
+ },
273
+ ],
274
+ notes: [],
275
+ customer: {
276
+ _id: '67feae8eeb5aa1e1848374b9',
277
+ tags: ['default'],
278
+ },
279
+ start: {
280
+ location: {
281
+ name: 'Sunshine Cleaners',
282
+ locationType: 'store',
283
+ storeId: '67e1c09c05b96100127280a8',
284
+ },
285
+ requestDate: '2025-06-18T21:21:48.745Z',
286
+ },
287
+
288
+ _storeId: '',
289
+ __typename: 'Order',
290
+ subTotals: {},
291
+ };
292
+ const originalItem = {
293
+ _id: '67fea241af24e570c032b319',
294
+ _updatedAt: '2025-06-18T20:21:00.922Z',
295
+ _createdAt: '2025-04-15T18:15:30.262Z',
296
+ name: "2pc Men's Suit",
297
+ description: null,
298
+ pieces: 2,
299
+ weight: 0,
300
+ properties: {
301
+ url: null,
302
+ color: 'rgba(178,232,239,1)',
303
+ label: {
304
+ backgroundColor: 'rgba(255,235,59,1)',
305
+ align: null,
306
+ },
307
+ },
308
+ sku: null,
309
+ hasInventory: false,
310
+ inventoryType: 'push',
311
+ quantity: 0,
312
+ tags: ['default'],
313
+ category: null,
314
+ __typename: 'Item',
315
+ modifiers: [],
316
+ priceLevels: [
317
+ {
318
+ value: 129,
319
+ tags: ['default'],
320
+ },
321
+ {
322
+ value: 15,
323
+ tags: ['default', 'vip'],
324
+ },
325
+ {
326
+ value: 10,
327
+ tags: ['default', 'rich'],
328
+ },
329
+ ],
330
+ costLevels: [],
331
+ };
332
+ let result = pricingService.order.addItemModifier({
333
+ itemIndex: 0,
334
+ modifier: {
335
+ _id: '67fea241af24e570c032b33f',
336
+ attributes: ['department'],
337
+ name: 'Dry Cleaning',
338
+ group: 'Department',
339
+ tags: ['default'],
340
+ included: true,
341
+ direct: true,
342
+ code: 'D',
343
+ properties: {
344
+ group: null,
345
+ department: {
346
+ tagSize: 'small',
347
+ customerTagsExtend: ['vip'],
348
+ autoSplit: false,
349
+ splitUnit: 'quantity',
350
+ maxItems: '3',
351
+ },
352
+ url: null,
353
+ color: null,
354
+ label: {
355
+ backgroundColor: null,
356
+ align: null,
357
+ },
358
+ sort: null,
359
+ },
360
+ },
361
+ order,
362
+ force: true,
363
+ originalItem,
364
+ });
365
+
366
+ expect(result.items[0].price).toBe(15);
367
+
368
+ result = pricingService.order.removeItemModifier({
369
+ order: result,
370
+ modifier: result.items[0].modifiers[0],
371
+ itemIndex: 0,
372
+ originalItem,
373
+ });
374
+
375
+ expect(result.items[0].price).toBe(129);
376
+ });
239
377
  });
@@ -1435,4 +1435,67 @@ describe('Order actions', () => {
1435
1435
  expect(resultedOrderPrepay.modifiers[1]._computed.amount).toBe(-1);
1436
1436
  expect(resultedOrderPrepay.modifiers[2]._computed.amount).toBe(-1);
1437
1437
  });
1438
+
1439
+ test('Should ignore modifier when conditions are not met and apply it when they are', () => {
1440
+ const cashDiscountModifier = {
1441
+ _id: '670e7cd236bf42091cb35624',
1442
+ attributes: [],
1443
+ modifierId: '670d7f7e746d1ae0f847aba6',
1444
+ _parentId: null,
1445
+ locked: false,
1446
+ name: 'CASH 2 USD DISCOUNT',
1447
+ sku: '',
1448
+ description: '',
1449
+ group: 'Offers',
1450
+ type: 'discount',
1451
+ tags: ['default', 'all'],
1452
+ conditions: {
1453
+ valid: false,
1454
+ rules: [
1455
+ {
1456
+ key: 'paymentTypes',
1457
+ value: ['cash'],
1458
+ operand: '$nin',
1459
+ },
1460
+ ],
1461
+ },
1462
+ compute: {
1463
+ type: 'fixed',
1464
+ action: 'subtract',
1465
+ amount: 2,
1466
+ },
1467
+ };
1468
+ const orderItem = {
1469
+ price: 10,
1470
+ quantity: 1,
1471
+ modifiers: [cashDiscountModifier],
1472
+ total: 10,
1473
+ totalPaid: 0,
1474
+ };
1475
+
1476
+ let cashFixedDiscountOrder = pricingService.order.calculate(
1477
+ { items: [orderItem] },
1478
+ { paymentType: 'cash' }
1479
+ );
1480
+
1481
+ expect(cashFixedDiscountOrder).toHaveProperty('total', 10);
1482
+ expect(cashFixedDiscountOrder).toHaveProperty('subTotal', 10);
1483
+ expect(cashFixedDiscountOrder).toHaveProperty('subTotals', {});
1484
+ expect(cashFixedDiscountOrder.items[0].modifiers).toHaveLength(1);
1485
+
1486
+ cashFixedDiscountOrder = pricingService.order.calculate(
1487
+ { items: [orderItem] },
1488
+ {
1489
+ paymentType: 'check',
1490
+ amountToPay: 1,
1491
+ lockPaymentModifiers: true,
1492
+ }
1493
+ );
1494
+ expect(cashFixedDiscountOrder).toHaveProperty('total', 8);
1495
+ expect(cashFixedDiscountOrder).toHaveProperty('subTotal', 10);
1496
+ expect(cashFixedDiscountOrder).toHaveProperty('subTotals', {
1497
+ discount: -2,
1498
+ });
1499
+ expect(cashFixedDiscountOrder.items[0].modifiers).toHaveLength(2);
1500
+ });
1438
1501
  });
@@ -58,6 +58,9 @@ module.exports = ({ _, utils, actions, modifierActions }) => {
58
58
  startRequestDate,
59
59
  endRequestDate,
60
60
  allItems,
61
+ paymentMethod,
62
+ paymentType,
63
+ isPrepay,
61
64
  })
62
65
  );
63
66
 
@@ -66,19 +69,15 @@ module.exports = ({ _, utils, actions, modifierActions }) => {
66
69
  ((each.compute && each.compute.type) ||
67
70
  (modifierActions.isOverride(each) &&
68
71
  !modifierActions.isNotesOverride(each))) &&
69
- modifierActions.isValid(each)
72
+ modifierActions.isValid(each) &&
73
+ !modifierActions.isPaymentModifier(each)
70
74
  );
71
75
 
72
76
  const paymentModifiersToCompute = validatedModifiers
73
77
  .filter(
74
78
  modifier =>
75
- modifierActions.isPaymentModifier(modifier) &&
76
- modifierActions.hasPaymentMethodType({
77
- paymentModifier: modifier,
78
- paymentMethod,
79
- paymentType,
80
- isPrepay,
81
- })
79
+ modifierActions.isValid(modifier) &&
80
+ modifierActions.isPaymentModifier(modifier)
82
81
  )
83
82
  .filter(paymentModifier => {
84
83
  const childModifiers = modifierActions.getChildren({
@@ -161,10 +160,7 @@ module.exports = ({ _, utils, actions, modifierActions }) => {
161
160
  typeof item.totalPaid === 'number' && item.totalPaid > 0
162
161
  ? actions.getItemsBalance({ items: [item] })
163
162
  : math.sub(computedPrice, item.totalPaid),
164
- paymentMethod,
165
- paymentType,
166
163
  paymentId,
167
- isPrepay,
168
164
  });
169
165
  }
170
166
 
package/lib/item/index.js CHANGED
@@ -33,7 +33,6 @@ const isFullyPaid = require('./isFullyPaid');
33
33
  const getTotalPrice = require('./getTotalPrice');
34
34
  const getItems = require('./getItems');
35
35
  const getAmounts = require('./getAmounts');
36
- const hasPaymentMethodType = require('./hasPaymentMethodType');
37
36
  const removePaymentModifiersByPaymentId = require('./removePaymentModifiersByPaymentId');
38
37
  const hasPaymentModifierWithPaymentId = require('./hasPaymentModifierWithPaymentId');
39
38
  const getBalance = require('./getBalance');
@@ -111,7 +110,6 @@ const itemActions = (deps = {}) => {
111
110
  getTotalPrice: getTotalPrice(innerDeps),
112
111
  getItems: getItems(innerDeps),
113
112
  getAmounts: getAmounts(innerDeps),
114
- hasPaymentMethodType: hasPaymentMethodType(innerDeps),
115
113
  removePaymentModifiersByPaymentId:
116
114
  removePaymentModifiersByPaymentId(innerDeps),
117
115
  hasPaymentModifierWithPaymentId: hasPaymentModifierWithPaymentId(innerDeps),
@@ -1,7 +1,15 @@
1
1
  module.exports = ({ actions, utils }) => {
2
2
  const modifierConditionPass = (
3
3
  modifier,
4
- { item, startRequestDate, endRequestDate, allItems }
4
+ {
5
+ item,
6
+ startRequestDate,
7
+ endRequestDate,
8
+ allItems,
9
+ paymentMethod,
10
+ paymentType,
11
+ isPrepay,
12
+ }
5
13
  ) =>
6
14
  modifier.conditions && Array.isArray(modifier.conditions.rules)
7
15
  ? modifier.conditions.rules.every(condition => {
@@ -89,11 +97,17 @@ module.exports = ({ actions, utils }) => {
89
97
  condition.operand
90
98
  );
91
99
  case 'paymentMethods':
92
- return false;
100
+ return actions.validatePaymentCondition({
101
+ condition,
102
+ paymentValue: paymentMethod,
103
+ });
93
104
  case 'paymentTypes':
94
- return false;
105
+ return actions.validatePaymentCondition({
106
+ condition,
107
+ paymentValue: paymentType,
108
+ });
95
109
  case 'payment': {
96
- return false;
110
+ return !!isPrepay;
97
111
  }
98
112
  default:
99
113
  return false;
@@ -107,6 +121,9 @@ module.exports = ({ actions, utils }) => {
107
121
  endRequestDate = null,
108
122
  startRequestDate = null,
109
123
  allItems = null,
124
+ paymentMethod,
125
+ paymentType,
126
+ isPrepay,
110
127
  } = opts;
111
128
  return (
112
129
  modifier &&
@@ -115,6 +132,9 @@ module.exports = ({ actions, utils }) => {
115
132
  startRequestDate,
116
133
  endRequestDate,
117
134
  allItems,
135
+ paymentMethod,
136
+ paymentType,
137
+ isPrepay,
118
138
  })
119
139
  );
120
140
  }
@@ -5,20 +5,9 @@ module.exports = ({ actions, utils }) => {
5
5
  paymentModifier: paymentModifierParam,
6
6
  amountToPay: amountToPayParam,
7
7
  itemBalance: itemBalanceParam,
8
- paymentMethod,
9
- paymentType,
10
8
  paymentId,
11
- isPrepay,
12
9
  }) {
13
- if (
14
- !actions.hasPaymentMethodType({
15
- paymentModifier: paymentModifierParam,
16
- paymentMethod,
17
- paymentType,
18
- isPrepay,
19
- })
20
- )
21
- return undefined;
10
+ if (!actions.isValid(paymentModifierParam)) return false;
22
11
 
23
12
  const paymentModifier = {
24
13
  ...paymentModifierParam,
@@ -126,7 +126,6 @@ const validateInArr = require('./validateInArr');
126
126
  const isPercentage = require('./isPercentage');
127
127
  const getChildren = require('./getChildren');
128
128
  const getComputedAmount = require('./getComputedAmount');
129
- const hasPaymentMethodType = require('./hasPaymentMethodType');
130
129
  const calculatePaymentModifier = require('./calculatePaymentModifier');
131
130
  const calculatePaymentDiscountModifier = require('./calculatePaymentDiscountModifier');
132
131
  const calculatePaymentFeeModifier = require('./calculatePaymentFeeModifier');
@@ -167,6 +166,7 @@ const getOverrideAmount = require('./getOverrideAmount');
167
166
  const getOverrideNote = require('./getOverrideNote');
168
167
  const isNotesOverride = require('./isNotesOverride');
169
168
  const isOverrideSubtotal = require('./isOverrideSubtotal');
169
+ const validatePaymentCondition = require('./validatePaymentCondition');
170
170
 
171
171
  const modifierActions = (deps = {}) => {
172
172
  const actions = {};
@@ -304,7 +304,6 @@ const modifierActions = (deps = {}) => {
304
304
  isPercentage: isPercentage(innerDeps),
305
305
  getChildren: getChildren(innerDeps),
306
306
  getComputedAmount: getComputedAmount(innerDeps),
307
- hasPaymentMethodType: hasPaymentMethodType(innerDeps),
308
307
  calculatePaymentModifier: calculatePaymentModifier(innerDeps),
309
308
  calculatePaymentDiscountModifier:
310
309
  calculatePaymentDiscountModifier(innerDeps),
@@ -347,6 +346,7 @@ const modifierActions = (deps = {}) => {
347
346
  getOverrideNote: getOverrideNote(innerDeps),
348
347
  isNotesOverride: isNotesOverride(innerDeps),
349
348
  isOverrideSubtotal: isOverrideSubtotal(innerDeps),
349
+ validatePaymentCondition: validatePaymentCondition(innerDeps),
350
350
  });
351
351
 
352
352
  Object.keys(freezedActions).forEach(actionName => {
@@ -0,0 +1,16 @@
1
+ module.exports = () =>
2
+ function validatePaymentCondition({ condition, paymentValue }) {
3
+ const { value, operand } = condition;
4
+ if (!value || !operand || !paymentValue) return false;
5
+
6
+ const includes = value.includes(paymentValue);
7
+
8
+ switch (operand) {
9
+ case '$in':
10
+ return includes;
11
+ case '$nin':
12
+ return !includes;
13
+ default:
14
+ return false;
15
+ }
16
+ };
@@ -80,6 +80,8 @@ module.exports = ({ actions, itemActions, modifierActions, utils, _ }) => {
80
80
  order,
81
81
  modifier: _modifier,
82
82
  item: itemProp,
83
+ customer,
84
+ originalItem,
83
85
  onConditionsNotMet,
84
86
  onError,
85
87
  }) => {
@@ -115,6 +117,12 @@ module.exports = ({ actions, itemActions, modifierActions, utils, _ }) => {
115
117
  ...(item.properties || {}),
116
118
  };
117
119
 
120
+ item.price = itemActions.getItemPrice({
121
+ item,
122
+ itemPriceLevels: originalItem ? originalItem.priceLevels : undefined,
123
+ customer,
124
+ });
125
+
118
126
  return item;
119
127
  };
120
128
 
@@ -1,4 +1,4 @@
1
- module.exports = ({ actions, modifierActions, _ }) => {
1
+ module.exports = ({ actions, modifierActions, itemActions, _ }) => {
2
2
  const removeModifier = ({ item, modifier }) => {
3
3
  const nextItem = { ...item, modifiers: [] };
4
4
 
@@ -29,6 +29,7 @@ module.exports = ({ actions, modifierActions, _ }) => {
29
29
  return order;
30
30
 
31
31
  let item = actions.getSelectedItem({ order, itemIndex });
32
+ const customer = actions.getCustomer(order);
32
33
 
33
34
  const contains = modifierActions.contains(item.modifiers, modifier);
34
35
 
@@ -41,6 +42,12 @@ module.exports = ({ actions, modifierActions, _ }) => {
41
42
  originalItem,
42
43
  });
43
44
 
45
+ item.price = itemActions.getItemPrice({
46
+ item,
47
+ itemPriceLevels: originalItem ? originalItem.priceLevels : undefined,
48
+ customer,
49
+ });
50
+
44
51
  order.items[itemIndex] = item;
45
52
 
46
53
  return order;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@darkpos/pricing",
3
- "version": "1.0.96",
3
+ "version": "1.0.99",
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": "aed710f165a1442c14bba31c5936682faa6b9364"
57
+ "gitHead": "4c83ad5f183f5b887c0ebd70e00e143282bf85a4"
58
58
  }
@@ -1,23 +0,0 @@
1
- module.exports = ({ modifierActions }) =>
2
- function hasPaymentMethodType({
3
- item,
4
- paymentMethod,
5
- paymentType,
6
- isPrepay,
7
- }) {
8
- if (
9
- !item ||
10
- !Array.isArray(item.modifiers) ||
11
- (!paymentMethod && !paymentType)
12
- )
13
- return false;
14
-
15
- return item.modifiers.some(modifier =>
16
- modifierActions.hasPaymentMethodType({
17
- paymentModifier: modifier,
18
- paymentMethod,
19
- paymentType,
20
- isPrepay,
21
- })
22
- );
23
- };
@@ -1,29 +0,0 @@
1
- module.exports = ({ actions }) =>
2
- function hasPaymentMethodType({
3
- paymentModifier,
4
- paymentMethod,
5
- paymentType,
6
- isPrepay,
7
- }) {
8
- if (!actions.isPaymentModifier(paymentModifier)) return false;
9
-
10
- if (actions.isPrepayModifier(paymentModifier) && !isPrepay) return false;
11
-
12
- if (
13
- actions.isPaymentTypeModifier(paymentModifier) &&
14
- !paymentModifier.conditions.rules.some(rule =>
15
- rule.value.includes(paymentType)
16
- )
17
- )
18
- return false;
19
-
20
- if (
21
- actions.isPaymentMethodModifier(paymentModifier) &&
22
- !paymentModifier.conditions.rules.some(rule =>
23
- rule.value.includes(paymentMethod)
24
- )
25
- )
26
- return false;
27
-
28
- return true;
29
- };