@darkpos/pricing 1.0.138 → 1.0.139

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.
@@ -2570,5 +2570,112 @@ describe('Item actions', () => {
2570
2570
  'City Tax': 3,
2571
2571
  });
2572
2572
  });
2573
+
2574
+ test('mergeWithParentItem adds price, name, and modifiers to parent', () => {
2575
+ const parentItem = {
2576
+ _id: 'parent-1',
2577
+ itemId: 'parent-1',
2578
+ name: 'Parent',
2579
+ price: 100,
2580
+ total: 100,
2581
+ quantity: 1,
2582
+ modifiers: [
2583
+ {
2584
+ _id: 'mod-parent',
2585
+ modifierId: 'mod-parent',
2586
+ },
2587
+ ],
2588
+ };
2589
+
2590
+ const order = {
2591
+ items: [parentItem],
2592
+ modifiers: [],
2593
+ };
2594
+
2595
+ const relatedItem = {
2596
+ itemId: 'child-1',
2597
+ name: 'Child',
2598
+ price: 25,
2599
+ modifiers: [
2600
+ {
2601
+ _id: 'tax',
2602
+ compute: { amount: 5, type: 'fixed', action: 'add' },
2603
+ },
2604
+ ],
2605
+ properties: {
2606
+ relatedItem: true,
2607
+ parentId: parentItem._id,
2608
+ parentItemId: parentItem.itemId,
2609
+ mergeWithParentItem: true,
2610
+ },
2611
+ };
2612
+
2613
+ const { updatedOrder } = pricingService.order.addItem({
2614
+ order,
2615
+ item: relatedItem,
2616
+ });
2617
+
2618
+ expect(updatedOrder.items.length).toBe(1);
2619
+
2620
+ expect(updatedOrder.items[0]._id).toBe('parent-1');
2621
+
2622
+ expect(updatedOrder.items[0].price).toBe(125);
2623
+ expect(updatedOrder.items[0].name).toBe('Parent - Child');
2624
+ expect(updatedOrder.items[0].modifiers.length).toBe(2);
2625
+ expect(updatedOrder.items[0].modifiers[0]._id).toBe('mod-parent');
2626
+ expect(updatedOrder.items[0].modifiers[1].modifierId).toBe('tax');
2627
+ });
2628
+
2629
+ test('mergeWithParentItem does not duplicate parent modifiers', () => {
2630
+ const parentItem = {
2631
+ _id: 'parent-2',
2632
+ itemId: 'parent-2',
2633
+ name: 'Parent',
2634
+ price: 100,
2635
+ total: 100,
2636
+ quantity: 1,
2637
+ modifiers: [
2638
+ {
2639
+ _id: 'mod-shared-parent',
2640
+ modifierId: 'mod-shared',
2641
+ },
2642
+ ],
2643
+ };
2644
+
2645
+ const order = {
2646
+ items: [parentItem],
2647
+ modifiers: [],
2648
+ };
2649
+
2650
+ const relatedItem = {
2651
+ itemId: 'child-2',
2652
+ name: 'Child',
2653
+ price: 10,
2654
+ modifiers: [
2655
+ {
2656
+ _id: 'mod-shared',
2657
+ compute: { amount: 2, type: 'fixed', action: 'add' },
2658
+ },
2659
+ ],
2660
+ properties: {
2661
+ relatedItem: true,
2662
+ parentId: parentItem._id,
2663
+ parentItemId: parentItem.itemId,
2664
+ mergeWithParentItem: true,
2665
+ },
2666
+ };
2667
+
2668
+ const { updatedOrder } = pricingService.order.addItem({
2669
+ order,
2670
+ item: relatedItem,
2671
+ });
2672
+
2673
+ expect(updatedOrder.items.length).toBe(1);
2674
+ expect(updatedOrder.items[0]._id).toBe('parent-2');
2675
+ expect(updatedOrder.items[0].price).toBe(110);
2676
+ expect(updatedOrder.items[0].name).toBe('Parent - Child');
2677
+ expect(updatedOrder.items[0].modifiers.length).toBe(1);
2678
+ expect(updatedOrder.items[0].modifiers[0].modifierId).toBe('mod-shared');
2679
+ });
2573
2680
  });
2574
2681
  });
@@ -18,6 +18,7 @@ describe('addItem function', () => {
18
18
 
19
19
  // Mock item to add
20
20
  const item = {
21
+ _id: 'abc',
21
22
  itemId: '123',
22
23
  quantity: 1,
23
24
  price: 100,
package/lib/item/index.js CHANGED
@@ -74,6 +74,7 @@ const isSerialLengthValid = require('./isSerialLengthValid');
74
74
  const getSerialStatus = require('./getSerialStatus');
75
75
  const removeDepartmentModifiers = require('./removeDepartmentModifiers');
76
76
  const isRemoveParentItem = require('./isRemoveParentItem');
77
+ const isMergeWithParentItem = require('./isMergeWithParentItem');
77
78
  const hasRelatedItems = require('./hasRelatedItems');
78
79
  const getAddModifiers = require('./getAddModifiers');
79
80
  const hasAddModifiers = require('./hasAddModifiers');
@@ -168,6 +169,7 @@ const itemActions = (deps = {}) => {
168
169
  getSerialStatus: getSerialStatus(innerDeps),
169
170
  removeDepartmentModifiers: removeDepartmentModifiers(innerDeps),
170
171
  isRemoveParentItem: isRemoveParentItem(innerDeps),
172
+ isMergeWithParentItem: isMergeWithParentItem(innerDeps),
171
173
  hasRelatedItems: hasRelatedItems(innerDeps),
172
174
  getAddModifiers: getAddModifiers(innerDeps),
173
175
  hasAddModifiers: hasAddModifiers(innerDeps),
@@ -0,0 +1,4 @@
1
+ module.exports = () =>
2
+ function isMergeWithParentItem(item) {
3
+ return !!(item && item.properties && item.properties.mergeWithParentItem);
4
+ };
@@ -182,6 +182,7 @@ const getCountPerCustomer = require('./getCountPerCustomer');
182
182
  const getAmountMultiplier = require('./getAmountMultiplier');
183
183
  const isAmountMultiplier = require('./isAmountMultiplier');
184
184
  const isRemoveParentItem = require('./isRemoveParentItem');
185
+ const isMergeWithParentItem = require('./isMergeWithParentItem');
185
186
  const isTax = require('./isTax');
186
187
 
187
188
  const modifierActions = (deps = {}) => {
@@ -377,6 +378,7 @@ const modifierActions = (deps = {}) => {
377
378
  getAmountMultiplier: getAmountMultiplier(innerDeps),
378
379
  isAmountMultiplier: isAmountMultiplier(innerDeps),
379
380
  isRemoveParentItem: isRemoveParentItem(innerDeps),
381
+ isMergeWithParentItem: isMergeWithParentItem(innerDeps),
380
382
  isTax: isTax(innerDeps),
381
383
  });
382
384
 
@@ -0,0 +1,9 @@
1
+ module.exports = () =>
2
+ function isMergeWithParentItem(modifier) {
3
+ return !!(
4
+ modifier &&
5
+ modifier.properties &&
6
+ modifier.properties.group &&
7
+ modifier.properties.group.mergeWithParentItem
8
+ );
9
+ };
@@ -253,7 +253,7 @@ module.exports = ({ actions, itemActions, modifierActions, settings, _ }) => {
253
253
  nextItemIndex,
254
254
  });
255
255
 
256
- if (reArrangedOrder && newIndex) {
256
+ if (reArrangedOrder && newIndex >= 0) {
257
257
  nextOrder = { ...reArrangedOrder };
258
258
  nextItemIndex = newIndex;
259
259
  }
@@ -262,7 +262,7 @@ module.exports = ({ actions, itemActions, modifierActions, settings, _ }) => {
262
262
 
263
263
  if (combined && pendingItemIndex > -1 && idx !== itemIndex) {
264
264
  const idxToRemove = actions.getPendingItemIndex(nextOrder);
265
- nextOrder.items.splice(idxToRemove, 1);
265
+ if (idxToRemove > -1) nextOrder.items.splice(idxToRemove, 1);
266
266
  }
267
267
 
268
268
  nextOrder = actions.addModifiersToParentItem({
@@ -270,10 +270,29 @@ module.exports = ({ actions, itemActions, modifierActions, settings, _ }) => {
270
270
  relatedItem: orderItem,
271
271
  });
272
272
 
273
+ const relatedItemFromOrder =
274
+ actions.getSelectedItem({ order: nextOrder, itemIndex: nextItemIndex }) ||
275
+ nextItem ||
276
+ orderItem;
277
+
278
+ let newItem = relatedItemFromOrder;
279
+
280
+ if (itemActions.isMergeWithParentItem(relatedItemFromOrder)) {
281
+ const result = actions.mergeRelatedItemWithParentItem({
282
+ order: nextOrder,
283
+ relatedItem: relatedItemFromOrder,
284
+ originalItem: item,
285
+ });
286
+ nextOrder = result.order;
287
+ newItem = result.parent;
288
+ }
289
+
273
290
  return {
274
291
  updatedOrder: nextOrder,
275
- itemIndex: nextItemIndex,
276
- item: nextItem,
292
+ item: newItem,
293
+ itemIndex: nextOrder.items.findIndex(
294
+ eachItem => eachItem._id === newItem._id
295
+ ),
277
296
  };
278
297
  };
279
298
  };
@@ -95,6 +95,7 @@ const setPieces = require('./setPieces');
95
95
  const copyItemToParents = require('./copyItemToParents');
96
96
  const getItemsWithParents = require('./getItemsWithParents');
97
97
  const addModifiersToParentItem = require('./addModifiersToParentItem');
98
+ const mergeRelatedItemWithParentItem = require('./mergeRelatedItemWithParentItem');
98
99
  const removeEmptyNotes = require('./removeEmptyNotes');
99
100
  const getTaxes = require('./getTaxes');
100
101
  const getPickedStatus = require('./getPickedStatus');
@@ -205,6 +206,7 @@ const orderActions = (deps = {}) => {
205
206
  copyItemToParents: copyItemToParents(innerDeps),
206
207
  getItemsWithParents: getItemsWithParents(innerDeps),
207
208
  addModifiersToParentItem: addModifiersToParentItem(innerDeps),
209
+ mergeRelatedItemWithParentItem: mergeRelatedItemWithParentItem(innerDeps),
208
210
  removeEmptyNotes: removeEmptyNotes(innerDeps),
209
211
  getTaxes: getTaxes(innerDeps),
210
212
  getPickedStatus: getPickedStatus(innerDeps),
@@ -0,0 +1,94 @@
1
+ module.exports = ({ actions, itemActions, utils }) => {
2
+ const { math } = utils;
3
+
4
+ return function mergeRelatedItemWithParentItem({
5
+ order,
6
+ relatedItem,
7
+ originalItem,
8
+ }) {
9
+ if (
10
+ !order ||
11
+ !itemActions.isRelatedItem(relatedItem) ||
12
+ (!itemActions.isMergeWithParentItem(originalItem) &&
13
+ !itemActions.isMergeWithParentItem(relatedItem))
14
+ ) {
15
+ return order;
16
+ }
17
+
18
+ if (!Array.isArray(order.items)) return order;
19
+
20
+ const nextOrder = { ...order };
21
+
22
+ const parentItem = itemActions.getParentItem(nextOrder.items, relatedItem);
23
+ if (!parentItem) return nextOrder;
24
+
25
+ const parentIndex = actions.getItemIndex({
26
+ order: nextOrder,
27
+ item: parentItem,
28
+ });
29
+ if (parentIndex < 0) return nextOrder;
30
+
31
+ const relatedIndex = actions.getItemIndex({
32
+ order: nextOrder,
33
+ item: relatedItem,
34
+ });
35
+ if (relatedIndex < 0) return nextOrder;
36
+
37
+ let updatedParent = parentItem;
38
+
39
+ if (relatedItem && relatedItem.name) {
40
+ if (!updatedParent.name) updatedParent.name = relatedItem.name;
41
+ else if (!updatedParent.name.includes(relatedItem.name)) {
42
+ updatedParent.name = `${updatedParent.name} - ${relatedItem.name}`;
43
+ }
44
+ }
45
+
46
+ if (typeof relatedItem.price === 'number') {
47
+ updatedParent.price = math.add(
48
+ updatedParent.price || 0,
49
+ relatedItem.price
50
+ );
51
+ }
52
+
53
+ nextOrder.items = [...nextOrder.items];
54
+ nextOrder.items[parentIndex] = updatedParent;
55
+
56
+ const relatedModifiers = Array.isArray(relatedItem.modifiers)
57
+ ? relatedItem.modifiers
58
+ : [];
59
+
60
+ if (relatedModifiers.length) {
61
+ const parentModifierIds = (updatedParent.modifiers || [])
62
+ .map(mod => mod.modifierId || mod._id)
63
+ .filter(Boolean);
64
+
65
+ const modifiersToAdd = relatedModifiers.filter(mod => {
66
+ const modId = mod.modifierId || mod._id;
67
+ return modId && !parentModifierIds.includes(modId);
68
+ });
69
+
70
+ if (modifiersToAdd.length) {
71
+ const orderWithModifiers = modifiersToAdd.reduce(
72
+ (acc, modifier) =>
73
+ actions.addItemModifier({
74
+ itemIndex: parentIndex,
75
+ order: acc,
76
+ modifier,
77
+ originalItem: updatedParent,
78
+ }),
79
+ nextOrder
80
+ );
81
+ nextOrder.items = orderWithModifiers.items;
82
+ }
83
+ }
84
+
85
+ updatedParent =
86
+ actions.getSelectedItem({ order: nextOrder, itemIndex: parentIndex }) ||
87
+ updatedParent;
88
+
89
+ nextOrder.items[parentIndex] = updatedParent;
90
+ nextOrder.items.splice(relatedIndex, 1);
91
+
92
+ return { order: nextOrder, parent: updatedParent };
93
+ };
94
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@darkpos/pricing",
3
- "version": "1.0.138",
3
+ "version": "1.0.139",
4
4
  "description": "Pricing calculator",
5
5
  "author": "Dark POS",
6
6
  "license": "ISC",
@@ -53,5 +53,5 @@
53
53
  "supertest": "^6.2.3",
54
54
  "supervisor": "^0.12.0"
55
55
  },
56
- "gitHead": "95d90c9dccaf934d7d4a8adc8e46115e90b81664"
56
+ "gitHead": "643797505f915f1c4562c19e59a82dd98ae888ec"
57
57
  }