@darkpos/pricing 1.0.130 → 1.0.132

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.
@@ -1153,81 +1153,6 @@ describe('Item actions', () => {
1153
1153
  expect(result.items).toMatchObject([item2]);
1154
1154
  });
1155
1155
 
1156
- test('Should add related item and its related addModifiers to the parent item, then removing that relateditem should also remove the mod from the parent item', () => {
1157
- const rawRelatedItem1 = {
1158
- name: 'the related item',
1159
- _id: '67e2cadd8dcf08ebcc5ef888',
1160
- };
1161
-
1162
- const rawRelatedItem2 = {
1163
- name: 'the 2nd related item',
1164
- _id: '67e2cadd8dcf08ebcc5ef88a',
1165
- };
1166
-
1167
- const groupMod = {
1168
- _id: '67e2cadd8dcf08ebcc5ef889',
1169
- name: 'General Repair Department',
1170
- attributes: ['group'],
1171
- modifierId: 'mod1',
1172
- properties: {
1173
- group: {
1174
- items: [],
1175
- },
1176
- },
1177
- };
1178
-
1179
- const parentItem = {
1180
- name: 'the parent item',
1181
- modifiers: [groupMod],
1182
- _id: '67e2cadd8dcf08ebcc5ef887',
1183
- __typename: 'OrderItem',
1184
- };
1185
-
1186
- const relatedItem1 = {
1187
- ...rawRelatedItem1,
1188
- properties: {
1189
- relatedItem: true,
1190
- parentId: parentItem._id,
1191
- includeParent: true,
1192
- addModifiers: [groupMod],
1193
- groupPath: ',67e2cadd8dcf08ebcc5ef889',
1194
- },
1195
- __typename: 'OrderItem',
1196
- };
1197
-
1198
- const relatedItem2 = {
1199
- ...rawRelatedItem2,
1200
- properties: {
1201
- relatedItem: true,
1202
- parentId: parentItem._id,
1203
- includeParent: true,
1204
- addModifiers: [groupMod],
1205
- groupPath: ',67e2cadd8dcf08ebcc5ef889',
1206
- },
1207
- __typename: 'OrderItem',
1208
- };
1209
- const order = {
1210
- items: [parentItem, relatedItem1, relatedItem2],
1211
- };
1212
-
1213
- const result = pricingService.order.removeItem({
1214
- order,
1215
- item: relatedItem2,
1216
- });
1217
-
1218
- expect(result.items.length).toBe(2);
1219
- expect(result.items[0].modifiers.length).toBe(1);
1220
- expect(result.items[0].modifiers[0].modifierId).toBe('mod1');
1221
-
1222
- const result2 = pricingService.order.removeItem({
1223
- order: result,
1224
- item: relatedItem1,
1225
- });
1226
-
1227
- expect(result2.items.length).toBe(1);
1228
- expect(result2.items[0].modifiers.length).toBe(0);
1229
- });
1230
-
1231
1156
  test('Should not remove the group modifier if it still hasModifiers', () => {
1232
1157
  const rawRelatedItem1 = {
1233
1158
  name: 'the related item',
@@ -1283,7 +1208,7 @@ describe('Item actions', () => {
1283
1208
  properties: {
1284
1209
  relatedItem: true,
1285
1210
  parentId: parentItem._id,
1286
- includeParent: true,
1211
+ repairOnly: false,
1287
1212
  addModifiers: [groupMod],
1288
1213
  groupPath: ',67e2cadd8dcf08ebcc5ef889',
1289
1214
  },
@@ -1295,7 +1220,7 @@ describe('Item actions', () => {
1295
1220
  properties: {
1296
1221
  relatedItem: true,
1297
1222
  parentId: parentItem._id,
1298
- includeParent: true,
1223
+ repairOnly: false,
1299
1224
  addModifiers: [groupMod],
1300
1225
  groupPath: ',67e2cadd8dcf08ebcc5ef889',
1301
1226
  },
@@ -374,4 +374,172 @@ describe('addItemModifier Function', () => {
374
374
 
375
375
  expect(result.items[0].price).toBe(129);
376
376
  });
377
+
378
+ test('Calculate item with Override Modifier and unitAsAmountMultiplier=true', () => {
379
+ const item = {
380
+ location: {},
381
+ status: {
382
+ picked: {
383
+ value: false,
384
+ date: '',
385
+ },
386
+ paid: {
387
+ value: false,
388
+ date: '',
389
+ },
390
+ tracker: [],
391
+ },
392
+ name: 'Short Pants2',
393
+ description: '',
394
+ pieces: 1,
395
+ modifiersTotalAmount: 0,
396
+ total: 510,
397
+ totalPaid: 0,
398
+ price: 10,
399
+ quantity: 1,
400
+ path: ',68eeba20cbfa2b080d75f7ea,68eeba2d9366a6367d7baaea,',
401
+ notes: [],
402
+ serial: null,
403
+ sku: '',
404
+ modifiers: [
405
+ {
406
+ _id: '690a3d23de696e15c594f7f2',
407
+ attributes: ['department'],
408
+ modifierId: '68efd827aeec0b1c557f79d4',
409
+ _parentId: null,
410
+ locked: false,
411
+ name: 'Dry Cleaning',
412
+ sku: '',
413
+ description: '',
414
+ group: '',
415
+ type: '',
416
+ tags: ['default'],
417
+ order: 0,
418
+ included: false,
419
+ direct: true,
420
+ hidden: false,
421
+ print: true,
422
+ required: false,
423
+ recommended: false,
424
+ default: false,
425
+ code: 'DC',
426
+ properties: {
427
+ department: {
428
+ tagSize: 'small',
429
+ splitUnit: 'quantity',
430
+ maxItems: '',
431
+ autoSplit: false,
432
+ },
433
+ sort: null,
434
+ },
435
+ _computed: {
436
+ amount: 0,
437
+ description: 'Dry Cleaning',
438
+ },
439
+ conditions: {
440
+ valid: true,
441
+ },
442
+ compute: null,
443
+ _createdAt: '2025-10-15T17:21:43.526Z',
444
+ _updatedAt: '2025-10-15T17:26:13.671Z',
445
+ __typename: 'Modifier',
446
+ addModifiers: [],
447
+ delModifiers: [],
448
+ },
449
+ {
450
+ _id: '690a3d2ede696e15c594f7f3',
451
+ attributes: ['override'],
452
+ modifierId: '690a195d3117c6cb92a692c0',
453
+ _parentId: null,
454
+ locked: false,
455
+ name: 'Pleats',
456
+ sku: '',
457
+ description: '',
458
+ group: '',
459
+ type: '',
460
+ tags: ['default'],
461
+ order: 0,
462
+ included: false,
463
+ direct: true,
464
+ hidden: false,
465
+ print: true,
466
+ required: false,
467
+ recommended: false,
468
+ default: false,
469
+ code: '',
470
+ properties: {
471
+ subscription: {},
472
+ override: {
473
+ field: 'amount',
474
+ type: 'manual',
475
+ options: null,
476
+ fixedValue: 20,
477
+ service: null,
478
+ unitAsAmountMultiplier: true,
479
+ amountMultiplier: 25,
480
+ multiplier: false,
481
+ },
482
+ group: {
483
+ items: [],
484
+ modifiers: [],
485
+ },
486
+ department: {},
487
+ sort: null,
488
+ },
489
+ _computed: {
490
+ amount: 500,
491
+ description: 'Pleats ($500.00)',
492
+ },
493
+ conditions: {
494
+ valid: true,
495
+ },
496
+ compute: {
497
+ type: 'fixed',
498
+ amount: 20,
499
+ action: 'add',
500
+ },
501
+ _createdAt: '2025-11-04T15:18:53.231Z',
502
+ _updatedAt: '2025-11-04T16:54:33.773Z',
503
+ __typename: 'Modifier',
504
+ addModifiers: [],
505
+ delModifiers: [],
506
+ },
507
+ ],
508
+ _id: '690a3d23de696e15c594f7f1',
509
+ _updatedAt: '2025-11-04T17:05:05.845Z',
510
+ _createdAt: '2025-10-14T21:02:10.991Z',
511
+ weight: 0,
512
+ properties: {},
513
+ hasInventory: true,
514
+ inventoryType: 'push',
515
+ serialRequired: false,
516
+ tags: [],
517
+ category: null,
518
+ __typename: 'OrderItem',
519
+ priceLevels: [
520
+ {
521
+ value: 10,
522
+ tags: ['default'],
523
+ },
524
+ {
525
+ value: 8,
526
+ tags: ['default', 'vip'],
527
+ },
528
+ ],
529
+ costLevels: [],
530
+ itemId: '68eeba52cbfa2b080d75fa02',
531
+ menuRuleId: '68eeba559366a6367d7bab08',
532
+ subTotals: {
533
+ _included: 0,
534
+ _xincluded: 500,
535
+ _direct: 500,
536
+ _xdirect: 0,
537
+ _simple: 10,
538
+ _actual: 10,
539
+ '': 500,
540
+ },
541
+ };
542
+ const calculatedItem = pricingService.item.calculate(item);
543
+ expect(calculatedItem.total).toBe(510);
544
+ });
377
545
  });
@@ -264,7 +264,7 @@ test('getInvalidRequiredModifiers having related items', () => {
264
264
  relatedItem: true,
265
265
  parentItemId: '62cdbfd01ee1b4001932821a',
266
266
  parentId: '67dc63610c106ab7d481d7dd',
267
- includeParent: true,
267
+ repairOnly: false,
268
268
  groupPath: ',67dc63610c106ab7d481d7de',
269
269
  },
270
270
  },
@@ -1672,14 +1672,16 @@ describe('hasModifier Function', () => {
1672
1672
  relatedItem: true,
1673
1673
  parentItemId: item.itemId,
1674
1674
  parentId: item._id,
1675
- includeParent: true,
1675
+ repairOnly: false,
1676
1676
  groupPath: ',groupMod10',
1677
+ removeParentItem: true,
1677
1678
  },
1678
1679
  },
1679
1680
  });
1680
1681
 
1681
1682
  expect(updatedOrder.items.length).toBe(2);
1682
- expect(updatedOrder.items[1]).toMatchObject({
1683
+
1684
+ const parentItem = {
1683
1685
  _id: 1,
1684
1686
  itemId: 'ab',
1685
1687
  modifiers: [
@@ -1696,7 +1698,8 @@ describe('hasModifier Function', () => {
1696
1698
  ],
1697
1699
  price: 500,
1698
1700
  total: 10000,
1699
- });
1701
+ };
1702
+ expect(updatedOrder.items[1]).toMatchObject(parentItem);
1700
1703
 
1701
1704
  const result = pricingService.item.hasModifier({
1702
1705
  item: updatedOrder.items[1],
@@ -1717,53 +1720,17 @@ describe('hasModifier Function', () => {
1717
1720
  relatedItem: true,
1718
1721
  parentItemId: item.itemId,
1719
1722
  parentId: item._id,
1720
- includeParent: false,
1723
+ repairOnly: true,
1721
1724
  groupPath: ',groupMod10',
1725
+ removeParentItem: true,
1722
1726
  },
1723
1727
  },
1724
1728
  });
1725
1729
 
1726
- expect(updatedOrder2.items.length).toBe(2);
1727
-
1728
- expect(updatedOrder2.items[1]).toMatchObject({
1729
- _id: 1,
1730
- itemId: 'ab',
1731
- modifiers: [
1732
- {
1733
- _id: 'groupMod10',
1734
- attributes: ['group'],
1735
- properties: {
1736
- group: {
1737
- items: [{ _id: 'abc', name: 'related item abc', itemId: 'abc' }],
1738
- modifiers: [{ _id: '123', name: 'related mod' }],
1739
- },
1740
- },
1741
- conditions: { valid: true },
1742
- compute: null,
1743
- _computed: { amount: 0, description: 'undefined' },
1744
- },
1745
- ],
1746
- price: 0,
1747
- total: 0,
1748
- subTotals: {
1749
- _included: 0,
1750
- _xincluded: 0,
1751
- _direct: 0,
1752
- _xdirect: 0,
1753
- _actual: 0,
1754
- },
1755
- });
1756
-
1757
- const result2 = pricingService.item.hasModifier({
1758
- item: updatedOrder2.items[1],
1759
- modifier: groupMod,
1760
- relatedItems: pricingService.order.getRelatedItems({
1761
- order: updatedOrder2,
1762
- item: updatedOrder2.items[1],
1763
- }),
1764
- });
1730
+ expect(updatedOrder2.items.length).toBe(1);
1731
+ expect(updatedOrder2.parentItems.length).toBe(1);
1765
1732
 
1766
- expect(result2).toBe(true);
1733
+ expect(updatedOrder2.parentItems[0]).toMatchObject(parentItem);
1767
1734
  });
1768
1735
 
1769
1736
  test('hasModifier, matching by spreadFrom', () => {
@@ -1800,4 +1767,107 @@ describe('hasModifier Function', () => {
1800
1767
 
1801
1768
  expect(result).toBe(true);
1802
1769
  });
1770
+
1771
+ test('hasModifier, using only 1 related items and keeping original item', () => {
1772
+ const relatedModItem = {
1773
+ _id: 'abc',
1774
+ name: 'related item abc',
1775
+ itemId: 'abc',
1776
+ };
1777
+ const groupMod = {
1778
+ _id: 'groupMod10',
1779
+ attributes: ['group'],
1780
+ properties: {
1781
+ group: {
1782
+ items: [relatedModItem],
1783
+ modifiers: [
1784
+ {
1785
+ _id: '123',
1786
+ name: 'related mod',
1787
+ },
1788
+ ],
1789
+ },
1790
+ },
1791
+ };
1792
+
1793
+ const item = {
1794
+ _id: 1,
1795
+ itemId: 'ab',
1796
+ modifiers: [groupMod],
1797
+ price: 500,
1798
+ total: 10000,
1799
+ };
1800
+
1801
+ const order = {
1802
+ items: [item],
1803
+ modifiers: [],
1804
+ };
1805
+
1806
+ const { updatedOrder } = pricingService.order.addItem({
1807
+ order,
1808
+ item: {
1809
+ ...relatedModItem,
1810
+ properties: {
1811
+ relatedItem: true,
1812
+ parentItemId: item.itemId,
1813
+ parentId: item._id,
1814
+ repairOnly: false,
1815
+ groupPath: ',groupMod10',
1816
+ },
1817
+ },
1818
+ });
1819
+
1820
+ expect(updatedOrder.items.length).toBe(2);
1821
+
1822
+ const parentItem = {
1823
+ _id: 1,
1824
+ itemId: 'ab',
1825
+ modifiers: [
1826
+ {
1827
+ _id: 'groupMod10',
1828
+ attributes: ['group'],
1829
+ properties: {
1830
+ group: {
1831
+ items: [{ _id: 'abc', name: 'related item abc', itemId: 'abc' }],
1832
+ modifiers: [{ _id: '123', name: 'related mod' }],
1833
+ },
1834
+ },
1835
+ },
1836
+ ],
1837
+ price: 500,
1838
+ total: 10000,
1839
+ };
1840
+ expect(updatedOrder.items[1]).toMatchObject(parentItem);
1841
+
1842
+ const result = pricingService.item.hasModifier({
1843
+ item: updatedOrder.items[1],
1844
+ modifier: groupMod,
1845
+ relatedItems: pricingService.order.getRelatedItems({
1846
+ order: updatedOrder,
1847
+ item: updatedOrder.items[1],
1848
+ }),
1849
+ });
1850
+
1851
+ expect(result).toBe(true);
1852
+
1853
+ const relatedItemtoAdd = {
1854
+ ...relatedModItem,
1855
+ properties: {
1856
+ relatedItem: true,
1857
+ parentItemId: item.itemId,
1858
+ parentId: item._id,
1859
+ repairOnly: false,
1860
+ groupPath: ',groupMod10',
1861
+ },
1862
+ };
1863
+
1864
+ const { updatedOrder: updatedOrder2 } = pricingService.order.addItem({
1865
+ order,
1866
+ item: relatedItemtoAdd,
1867
+ });
1868
+
1869
+ expect(updatedOrder2.items.length).toBe(2);
1870
+ expect(updatedOrder2.items[0].name).toBe('related item abc');
1871
+ expect(updatedOrder2.items[1]).toMatchObject(parentItem);
1872
+ });
1803
1873
  });
@@ -231,7 +231,7 @@ describe('addItem function', () => {
231
231
  relatedItem: true,
232
232
  parentItemId: updatedOrder.items[0].itemId,
233
233
  parentId: updatedOrder.items[0]._id,
234
- includeParent: true,
234
+ repairOnly: false,
235
235
  addModifiers: [
236
236
  {
237
237
  _id: 'mod1',
@@ -253,11 +253,7 @@ describe('addItem function', () => {
253
253
  });
254
254
  expect(updatedOrder2.items[1]).toMatchObject({
255
255
  name: 'the parent item',
256
- modifiers: [
257
- {
258
- name: 'General Repair Department',
259
- },
260
- ],
256
+ modifiers: [],
261
257
  });
262
258
 
263
259
  const relatedItem2 = {
@@ -270,7 +266,7 @@ describe('addItem function', () => {
270
266
  relatedItem: true,
271
267
  parentItemId: updatedOrder.items[0].itemId,
272
268
  parentId: updatedOrder.items[0]._id,
273
- includeParent: true,
269
+ repairOnly: false,
274
270
  addModifiers: [
275
271
  {
276
272
  _id: 'mod1',
@@ -295,11 +291,7 @@ describe('addItem function', () => {
295
291
  });
296
292
  expect(updatedOrder3.items[2]).toMatchObject({
297
293
  name: 'the parent item',
298
- modifiers: [
299
- {
300
- name: 'General Repair Department',
301
- },
302
- ],
294
+ modifiers: [],
303
295
  });
304
296
  });
305
297
  });
@@ -3858,4 +3858,79 @@ describe('Order actions', () => {
3858
3858
  );
3859
3859
  expect(newOrder.items[2].total).toEqual(7.44);
3860
3860
  });
3861
+
3862
+ test('Should return same items if there are no related items', () => {
3863
+ const items = [
3864
+ { _id: '1', properties: {} },
3865
+ { _id: '2', properties: {} },
3866
+ ];
3867
+ const parentItems = [{ _id: '10', properties: {} }];
3868
+
3869
+ const result = pricingService.order.getItemsWithParents({
3870
+ items,
3871
+ parentItems,
3872
+ });
3873
+
3874
+ expect(result).toEqual(items);
3875
+ });
3876
+
3877
+ test('Should insert missing parent before first related item', () => {
3878
+ const items = [
3879
+ { _id: '1', properties: {} },
3880
+ { _id: '2', properties: { parentId: '10', relatedItem: true } },
3881
+ { _id: '3', properties: {} },
3882
+ ];
3883
+
3884
+ const parentItems = [
3885
+ { _id: '10', properties: {} },
3886
+ { _id: '11', properties: {} },
3887
+ ];
3888
+
3889
+ const result = pricingService.order.getItemsWithParents({
3890
+ items,
3891
+ parentItems,
3892
+ });
3893
+
3894
+ expect(result).toEqual([
3895
+ { _id: '1', properties: {} },
3896
+ { _id: '10', properties: {} },
3897
+ { _id: '2', properties: { parentId: '10', relatedItem: true } },
3898
+ { _id: '3', properties: {} },
3899
+ ]);
3900
+ });
3901
+
3902
+ test('Should not duplicate parent if already inserted', () => {
3903
+ const items = [
3904
+ { _id: '2', properties: { parentId: '10', relatedItem: true } },
3905
+ { _id: '3', properties: { parentId: '10', relatedItem: true } },
3906
+ ];
3907
+
3908
+ const parentItems = [{ _id: '10', properties: {} }];
3909
+
3910
+ const result = pricingService.order.getItemsWithParents({
3911
+ items,
3912
+ parentItems,
3913
+ });
3914
+
3915
+ const parentCount = result.filter(i => i._id === '10').length;
3916
+ expect(parentCount).toBe(1);
3917
+ expect(result[0]._id).toBe('10');
3918
+ });
3919
+
3920
+ test('Should skip injection if parent already exists in items', () => {
3921
+ const items = [
3922
+ { _id: '10', properties: {} },
3923
+ { _id: '2', properties: { parentId: '10', relatedItem: true } },
3924
+ ];
3925
+ const parentItems = [{ _id: '10', properties: {} }];
3926
+
3927
+ const result = pricingService.order.getItemsWithParents({
3928
+ items,
3929
+ parentItems,
3930
+ });
3931
+
3932
+ const parentCount = result.filter(i => i._id === '10').length;
3933
+ expect(parentCount).toBe(1);
3934
+ expect(result).toEqual(items);
3935
+ });
3861
3936
  });
@@ -522,6 +522,16 @@ describe('Auto Split', () => {
522
522
  __typename: 'Modifier',
523
523
  };
524
524
 
525
+ const parentItem = {
526
+ name: "2pc Men's Suit",
527
+ modifiers: [dtModifier],
528
+ _id: '686d62b3e0f59b1de5d93b28',
529
+ pieces: 2,
530
+ quantity: 1,
531
+ weight: 0,
532
+ properties: {},
533
+ };
534
+
525
535
  const parentOrder = {
526
536
  _id: '686d62ace0f59b1de5d93b27',
527
537
 
@@ -535,19 +545,12 @@ describe('Auto Split', () => {
535
545
  relatedItem: true,
536
546
  parentItemId: '67fea241af24e570c032b319',
537
547
  parentId: '686d62b3e0f59b1de5d93b28',
538
- includeParent: true,
548
+ repairOnly: false,
539
549
  },
540
550
  },
541
- {
542
- name: "2pc Men's Suit",
543
- modifiers: [dtModifier],
544
- _id: '686d62b3e0f59b1de5d93b28',
545
- pieces: 2,
546
- quantity: 1,
547
- weight: 0,
548
- properties: {},
549
- },
551
+ parentItem,
550
552
  ],
553
+ parentItems: [parentItem],
551
554
  modifiers: [],
552
555
  status: {},
553
556
  };
@@ -644,7 +647,7 @@ describe('Auto Split', () => {
644
647
  relatedItem: true,
645
648
  parentItemId: '67fea241af24e570c032b319',
646
649
  parentId: '686d62b3e0f59b1de5d93b28',
647
- includeParent: true,
650
+ repairOnly: false,
648
651
  },
649
652
  },
650
653
  {
@@ -1,7 +1,7 @@
1
1
  module.exports = ({ actions, modifierActions }) =>
2
- function getSplitDepartment({ items, item }) {
2
+ function getSplitDepartment({ parentItems, item }) {
3
3
  if (actions.isRelatedItem(item)) {
4
- const parentItem = actions.getParentItem(items, item);
4
+ const parentItem = actions.getParentItem(parentItems, item);
5
5
 
6
6
  if (parentItem) {
7
7
  const parentDeps = actions.getDepartmentModifiers(parentItem);
@@ -0,0 +1,10 @@
1
+ module.exports = ({ actions }) =>
2
+ function hasRelatedItems({ parentItem, items }) {
3
+ if (!parentItem || !items) return [];
4
+
5
+ return items.some(
6
+ item =>
7
+ actions.isRelatedItem(item) &&
8
+ item.properties.parentId === parentItem._id
9
+ );
10
+ };
package/lib/item/index.js CHANGED
@@ -25,7 +25,7 @@ const getItemsTotalPaid = require('./getItemsTotalPaid');
25
25
  const getModifierTags = require('./getModifierTags');
26
26
  const isRelatedItem = require('./isRelatedItem');
27
27
  const getParentItem = require('./getParentItem');
28
- const isParentIncluded = require('./isParentIncluded');
28
+ const isRepairOnly = require('./isRepairOnly');
29
29
  const hasCreateSubscription = require('./hasCreateSubscription');
30
30
  const getItemModifiers = require('./getItemModifiers');
31
31
  const getItemsBalance = require('./getItemsBalance');
@@ -46,8 +46,6 @@ const getBasePrice = require('./getBasePrice');
46
46
  const validateModifiersByQuantity = require('./validateModifiersByQuantity');
47
47
  const getModifiersBySingleValueId = require('./getModifiersBySingleValueId');
48
48
  const getLastLocation = require('./getLastLocation');
49
- const hasAddModifiers = require('./hasAddModifiers');
50
- const getAddModifiers = require('./getAddModifiers');
51
49
  const getRelatedItems = require('./getRelatedItems');
52
50
  const getRelatedModifiers = require('./getRelatedModifiers');
53
51
  const unpickItem = require('./unpick');
@@ -74,6 +72,9 @@ const isPriceChanged = require('./isPriceChanged');
74
72
  const isSerialRequired = require('./isSerialRequired');
75
73
  const isSerialLengthValid = require('./isSerialLengthValid');
76
74
  const getSerialStatus = require('./getSerialStatus');
75
+ const removeDepartmentModifiers = require('./removeDepartmentModifiers');
76
+ const isRemoveParentItem = require('./isRemoveParentItem');
77
+ const hasRelatedItems = require('./hasRelatedItems');
77
78
 
78
79
  const itemActions = (deps = {}) => {
79
80
  const actions = {};
@@ -111,7 +112,7 @@ const itemActions = (deps = {}) => {
111
112
  getModifierTags: getModifierTags(innerDeps),
112
113
  isRelatedItem: isRelatedItem(innerDeps),
113
114
  getParentItem: getParentItem(innerDeps),
114
- isParentIncluded: isParentIncluded(innerDeps),
115
+ isRepairOnly: isRepairOnly(innerDeps),
115
116
  hasCreateSubscription: hasCreateSubscription(innerDeps),
116
117
  getItemModifiers: getItemModifiers(innerDeps),
117
118
  getItemsBalance: getItemsBalance(innerDeps),
@@ -133,8 +134,6 @@ const itemActions = (deps = {}) => {
133
134
  validateModifiersByQuantity: validateModifiersByQuantity(innerDeps),
134
135
  getModifiersBySingleValueId: getModifiersBySingleValueId(innerDeps),
135
136
  getLastLocation: getLastLocation(innerDeps),
136
- hasAddModifiers: hasAddModifiers(innerDeps),
137
- getAddModifiers: getAddModifiers(innerDeps),
138
137
  getRelatedItems: getRelatedItems(innerDeps),
139
138
  getRelatedModifiers: getRelatedModifiers(innerDeps),
140
139
  unpickItem: unpickItem(innerDeps),
@@ -161,6 +160,9 @@ const itemActions = (deps = {}) => {
161
160
  isSerialRequired: isSerialRequired(innerDeps),
162
161
  isSerialLengthValid: isSerialLengthValid(innerDeps),
163
162
  getSerialStatus: getSerialStatus(innerDeps),
163
+ removeDepartmentModifiers: removeDepartmentModifiers(innerDeps),
164
+ isRemoveParentItem: isRemoveParentItem(innerDeps),
165
+ hasRelatedItems: hasRelatedItems(innerDeps),
164
166
  });
165
167
 
166
168
  Object.keys(freezedActions).forEach(actionName => {
@@ -0,0 +1,4 @@
1
+ module.exports = () =>
2
+ function isRemoveParentItem(item) {
3
+ return !!(item && item.properties && item.properties.removeParentItem);
4
+ };
@@ -0,0 +1,4 @@
1
+ module.exports = () =>
2
+ function isRepairOnly(item) {
3
+ return !!(!!item && !!item.properties && !!item.properties.repairOnly);
4
+ };
@@ -0,0 +1,19 @@
1
+ module.exports = ({ actions, modifierActions }) =>
2
+ function removeDepartmentModifiers({ item, order }) {
3
+ if (!item) return undefined;
4
+ if (!Array.isArray(item.modifiers)) return item;
5
+ const deparmentModifiers = item.modifiers.filter(mod =>
6
+ modifierActions.isDepartment(mod)
7
+ );
8
+
9
+ const newItem = deparmentModifiers.reduce(
10
+ (nextItem, modifier) =>
11
+ actions.removeModifier({
12
+ item: nextItem,
13
+ modifier,
14
+ order,
15
+ }),
16
+ item
17
+ );
18
+ return newItem;
19
+ };
@@ -70,6 +70,14 @@ module.exports = ({ _, constants, utils, actions }) => {
70
70
  _computed.amount = math.mul(_computed.amount, options.quantity);
71
71
  }
72
72
 
73
+ if (
74
+ actions.isAmountOverride(_modifier) &&
75
+ actions.isAmountMultiplier(_modifier)
76
+ ) {
77
+ const amountMultiplier = actions.getAmountMultiplier(_modifier);
78
+ _computed.amount = math.mul(_computed.amount, amountMultiplier);
79
+ }
80
+
73
81
  if (actions.isTotalOverride(_modifier)) {
74
82
  _computed.amount = math.sub(compute.amount, options.maxDiscountAmount);
75
83
  }
@@ -0,0 +1,10 @@
1
+ module.exports = ({ actions }) =>
2
+ function getAmountMultiplier(modifier) {
3
+ if (!actions.isOverride(modifier)) return 1;
4
+ if (!actions.isAmountMultiplier(modifier)) return 1;
5
+
6
+ return (
7
+ (modifier.properties && modifier.properties.override.amountMultiplier) ||
8
+ 1
9
+ );
10
+ };
@@ -1,30 +1,14 @@
1
- module.exports = ({ actions }) => {
2
- const isRelated = modifier => actions.isGroupOfItems(modifier);
1
+ module.exports = ({ actions }) =>
2
+ function getInheritedModifiers({ parentItem }) {
3
+ if (!parentItem || !Array.isArray(parentItem.modifiers)) return [];
3
4
 
4
- return function getInheritedModifiers({ parentItem, childItem }) {
5
- if (!parentItem || !childItem) return [];
5
+ const modifiersToAdd = [];
6
6
 
7
- const { addModifiers: parentModifiers } = parentItem;
8
- const { addModifiers: childModifiers = [], _id } = childItem;
9
- const modifiers = [...childModifiers];
7
+ parentItem.modifiers.forEach(parentMod => {
8
+ if (!actions.isDepartment(parentMod) && !actions.isGroup(parentMod)) {
9
+ modifiersToAdd.push(parentMod);
10
+ }
11
+ });
10
12
 
11
- const relatedItemModifier = parentModifiers.find(each => isRelated(each));
12
- if (!relatedItemModifier) return modifiers;
13
-
14
- const { properties = {} } = relatedItemModifier;
15
- const items = (properties.group && properties.group.items) || [];
16
-
17
- const relatedItem = items.find(each => each._id === _id);
18
- if (!relatedItem) return [];
19
-
20
- if (properties.inheritModifiers && parentModifiers.length) {
21
- const inheritedModifiers = parentModifiers
22
- .filter(each => !isRelated(each))
23
- .map(each => actions.duplicate(each));
24
-
25
- if (inheritedModifiers.length) modifiers.push(...inheritedModifiers);
26
- }
27
-
28
- return modifiers;
13
+ return modifiersToAdd;
29
14
  };
30
- };
@@ -179,6 +179,9 @@ const isEmptyOverride = require('./isEmptyOverride');
179
179
  const getMaxUsesPerCustomer = require('./getMaxUsesPerCustomer');
180
180
  const getPromoCustomerIds = require('./getPromoCustomerIds');
181
181
  const getCountPerCustomer = require('./getCountPerCustomer');
182
+ const getAmountMultiplier = require('./getAmountMultiplier');
183
+ const isAmountMultiplier = require('./isAmountMultiplier');
184
+ const isRemoveParentItem = require('./isRemoveParentItem');
182
185
 
183
186
  const modifierActions = (deps = {}) => {
184
187
  const actions = {};
@@ -370,6 +373,9 @@ const modifierActions = (deps = {}) => {
370
373
  getMaxUsesPerCustomer: getMaxUsesPerCustomer(innerDeps),
371
374
  getPromoCustomerIds: getPromoCustomerIds(innerDeps),
372
375
  getCountPerCustomer: getCountPerCustomer(innerDeps),
376
+ getAmountMultiplier: getAmountMultiplier(innerDeps),
377
+ isAmountMultiplier: isAmountMultiplier(innerDeps),
378
+ isRemoveParentItem: isRemoveParentItem(innerDeps),
373
379
  });
374
380
 
375
381
  Object.keys(freezedActions).forEach(actionName => {
@@ -0,0 +1,10 @@
1
+ module.exports = () =>
2
+ function isAmountMultiplier(modifier) {
3
+ if (!modifier) return false;
4
+ return !!(
5
+ modifier &&
6
+ modifier.properties &&
7
+ modifier.properties.override &&
8
+ modifier.properties.override.unitAsAmountMultiplier
9
+ );
10
+ };
@@ -0,0 +1,9 @@
1
+ module.exports = () =>
2
+ function isRemoveParentItem(modifier) {
3
+ return !!(
4
+ modifier &&
5
+ modifier.properties &&
6
+ modifier.properties.group &&
7
+ modifier.properties.group.removeParentItem
8
+ );
9
+ };
@@ -147,7 +147,11 @@ module.exports = ({ actions, itemActions, modifierActions, settings, _ }) => {
147
147
  }
148
148
  }
149
149
 
150
- if (autoBarcode && !orderItem.serial) {
150
+ if (
151
+ autoBarcode &&
152
+ !orderItem.serial &&
153
+ !itemActions.isRelatedItem(orderItem)
154
+ ) {
151
155
  orderItem.serial = autoBarcode;
152
156
  }
153
157
 
@@ -164,17 +168,30 @@ module.exports = ({ actions, itemActions, modifierActions, settings, _ }) => {
164
168
  item: orderItem,
165
169
  });
166
170
  if (itemActions.isRelatedItem(orderItem)) {
167
- const parent = itemActions.getParentItem(order.items, orderItem);
168
- // get inherited modifiers
169
- const inheritedModifiers = modifierActions.getInheritedModifiers({
170
- parent,
171
- child: item,
172
- });
173
- if (!_.isEmpty(inheritedModifiers))
174
- modifiersToAdd.push(...inheritedModifiers);
175
- // Remove parent if it is only a repair Item
176
- if (!itemActions.isParentIncluded(orderItem) && !!parent) {
177
- order = actions.resetItem({ order, item: parent });
171
+ let parent = itemActions.getParentItem(order.parentItems, orderItem);
172
+
173
+ if (!parent) {
174
+ parent = itemActions.getParentItem(order.items, orderItem);
175
+ order = actions.copyItemToParents({ order, item: parent });
176
+ }
177
+
178
+ modifiersToAdd.push(
179
+ ...modifierActions.getInheritedModifiers({ parentItem: parent })
180
+ );
181
+
182
+ orderItem.serial = parent.serial;
183
+
184
+ if (parent && itemActions.isRepairOnly(orderItem)) {
185
+ if (itemActions.isRemoveParentItem(item)) {
186
+ order = actions.removeItem({
187
+ order,
188
+ item: parent,
189
+ skipParentsCheck: true,
190
+ keepRelatedItems: true,
191
+ });
192
+ } else {
193
+ order = actions.resetItem({ order, item: parent });
194
+ }
178
195
  }
179
196
  }
180
197
  }
@@ -248,37 +265,6 @@ module.exports = ({ actions, itemActions, modifierActions, settings, _ }) => {
248
265
  nextOrder.items.splice(idxToRemove, 1);
249
266
  }
250
267
 
251
- if (
252
- itemActions.isRelatedItem(item) &&
253
- itemActions.hasAddModifiers(item) &&
254
- itemActions.isParentIncluded(item)
255
- ) {
256
- const parentItem = itemActions.getParentItem(nextOrder.items, item);
257
- const parentIndex = actions.getItemIndex({
258
- order: nextOrder,
259
- item: parentItem,
260
- });
261
- const relatedModifiersToAdd = itemActions
262
- .getAddModifiers(item)
263
- .filter(
264
- mod =>
265
- !parentItem.modifiers.some(
266
- itemMod => itemMod.modifierId === mod._id
267
- )
268
- );
269
-
270
- nextOrder = relatedModifiersToAdd.reduce(
271
- (acc, modifier) =>
272
- actions.addItemModifier({
273
- itemIndex: parentIndex,
274
- order: acc,
275
- modifier,
276
- originalItem: parentItem,
277
- }),
278
- nextOrder
279
- );
280
- }
281
-
282
268
  return {
283
269
  updatedOrder: nextOrder,
284
270
  itemIndex: nextItemIndex,
@@ -192,7 +192,7 @@ module.exports = ({ actions, itemActions, modifierActions, utils, _ }) => {
192
192
  relatedItem: true,
193
193
  parentId: item._id,
194
194
  parentItemId: item.itemId,
195
- includeParent: true,
195
+ repairOnly: false,
196
196
  },
197
197
  },
198
198
  order: acc,
@@ -0,0 +1,19 @@
1
+ module.exports = ({ itemActions }) =>
2
+ function copyItemToParents({ item, order }) {
3
+ if (!order || !item || itemActions.isRelatedItem(item)) return order;
4
+ if (!item._id) return order;
5
+
6
+ const alreadyExists =
7
+ order.parentItems &&
8
+ order.parentItems.some(parentItem => parentItem._id === item._id);
9
+
10
+ if (alreadyExists) return order;
11
+
12
+ const parentItems = Array.isArray(order.parentItems)
13
+ ? [...order.parentItems]
14
+ : [];
15
+
16
+ parentItems.push(item);
17
+
18
+ return { ...order, parentItems };
19
+ };
@@ -0,0 +1,31 @@
1
+ module.exports = ({ itemActions }) =>
2
+ function getItemsWithParents({ items, parentItems }) {
3
+ if (!Array.isArray(items)) return [];
4
+
5
+ if (!Array.isArray(parentItems) || parentItems.length === 0) return items;
6
+
7
+ const result = [];
8
+
9
+ items.forEach(item => {
10
+ if (!itemActions.isRelatedItem(item)) {
11
+ result.push(item);
12
+ return;
13
+ }
14
+
15
+ const parentId =
16
+ item && item.properties ? item.properties.parentId : undefined;
17
+ const parentInOrder = items.find(p => p && p._id === parentId);
18
+ const parentInParentItems = parentItems.find(
19
+ p => p && p._id === parentId
20
+ );
21
+ const parentInResult = result.find(i => i && i._id === parentId);
22
+
23
+ if (!parentInOrder && parentInParentItems && !parentInResult) {
24
+ result.push(parentInParentItems);
25
+ }
26
+
27
+ result.push(item);
28
+ });
29
+
30
+ return result;
31
+ };
@@ -92,6 +92,8 @@ const mapSubOrders = require('./mapSubOrders');
92
92
  const isFullyPaid = require('./isFullyPaid');
93
93
  const getUpdatedStatus = require('./getUpdatedStatus');
94
94
  const setPieces = require('./setPieces');
95
+ const copyItemToParents = require('./copyItemToParents');
96
+ const getItemsWithParents = require('./getItemsWithParents');
95
97
 
96
98
  const orderActions = (deps = {}) => {
97
99
  const actions = {};
@@ -195,6 +197,8 @@ const orderActions = (deps = {}) => {
195
197
  isFullyPaid: isFullyPaid(innerDeps),
196
198
  getUpdatedStatus: getUpdatedStatus(innerDeps),
197
199
  setPieces: setPieces(innerDeps),
200
+ copyItemToParents: copyItemToParents(innerDeps),
201
+ getItemsWithParents: getItemsWithParents(innerDeps),
198
202
  });
199
203
 
200
204
  Object.keys(freezedActions).forEach(actionName => {
@@ -1,5 +1,5 @@
1
1
  module.exports = ({ actions, itemActions }) => {
2
- const remove = ({ order, item, checkQuantity }) => {
2
+ const remove = ({ order, item, checkQuantity, keepRelatedItems }) => {
3
3
  const orderItemIdx = actions.getItemIndex({ order, item });
4
4
  if (orderItemIdx < 0) return order;
5
5
 
@@ -19,53 +19,12 @@ module.exports = ({ actions, itemActions }) => {
19
19
 
20
20
  items.splice(orderItemIdx, 1);
21
21
 
22
- let resultedOrder = {
22
+ const resultedOrder = {
23
23
  ...order,
24
24
  items,
25
25
  };
26
26
 
27
- if (itemActions.isRelatedItem(item) && itemActions.hasAddModifiers(item)) {
28
- const parentItem = itemActions.getParentItem(order.items, item);
29
-
30
- if (parentItem) {
31
- resultedOrder = item.properties.addModifiers.reduce(
32
- (prevOrder, addModifier) => {
33
- if (
34
- !itemActions.hasModifier({
35
- item: parentItem,
36
- modifier: addModifier,
37
- relatedItems: actions.getRelatedItems({
38
- order: prevOrder,
39
- item: parentItem,
40
- }),
41
- })
42
- ) {
43
- const updatedItem = itemActions.removeModifier({
44
- item: parentItem,
45
- modifier: addModifier,
46
- originalItem: parentItem,
47
- });
48
- const itemIndexToUpdate = actions.getItemIndex({
49
- order: prevOrder,
50
- item: parentItem,
51
- });
52
- if (itemIndexToUpdate >= 0) {
53
- const itemsToUpdate = [...prevOrder.items];
54
-
55
- itemsToUpdate.splice(itemIndexToUpdate, 1, updatedItem);
56
-
57
- return {
58
- ...resultedOrder,
59
- items: itemsToUpdate,
60
- };
61
- }
62
- }
63
- return resultedOrder;
64
- },
65
- resultedOrder
66
- );
67
- }
68
- }
27
+ if (keepRelatedItems) return resultedOrder;
69
28
 
70
29
  const relatedItems = actions.getRelatedItems({ order, item });
71
30
  if (relatedItems.length > 0) {
@@ -83,10 +42,22 @@ module.exports = ({ actions, itemActions }) => {
83
42
  return resultedOrder;
84
43
  };
85
44
 
86
- return function removeItem({ order, item, checkQuantity }) {
45
+ return function removeItem({
46
+ order,
47
+ item,
48
+ checkQuantity,
49
+ skipParentsCheck,
50
+ keepRelatedItems,
51
+ }) {
87
52
  if (!order || !Array.isArray(order.items) || !item) return order;
88
53
 
89
- const nextOrder = remove({ order, item, checkQuantity });
54
+ const nextOrder = remove({ order, item, checkQuantity, keepRelatedItems });
55
+
56
+ if (!skipParentsCheck && Array.isArray(nextOrder.parentItems)) {
57
+ nextOrder.parentItems = nextOrder.parentItems.filter(parentItem =>
58
+ itemActions.hasRelatedItems({ parentItem, items: nextOrder.items })
59
+ );
60
+ }
90
61
 
91
62
  return nextOrder;
92
63
  };
@@ -49,8 +49,13 @@ module.exports = ({
49
49
  return Number(aIsRelated) - Number(bIsRelated);
50
50
  });
51
51
 
52
+ const { parentItems } = parentOrderParam;
53
+
52
54
  const itemsByDepartments = _.groupBy(sortedItems, item =>
53
- itemActions.getSplitDepartment({ items: sortedItems, item })
55
+ itemActions.getSplitDepartment({
56
+ parentItems,
57
+ item,
58
+ })
54
59
  );
55
60
  const itemGroups = Object.values(itemsByDepartments);
56
61
  let splitOrders = [];
@@ -64,7 +69,7 @@ module.exports = ({
64
69
  // Assuming there is one department in the item
65
70
  const department = itemActions.getDepartmentModifiers(items[0])[0];
66
71
  const departmentName = itemActions.getSplitDepartment({
67
- items: sortedItems,
72
+ parentItems,
68
73
  item: items[0],
69
74
  });
70
75
  const maxItems = modifierActions.getDepartmentMaxItems(department);
@@ -129,7 +134,7 @@ module.exports = ({
129
134
  maxItems &&
130
135
  departmentName ===
131
136
  itemActions.getSplitDepartment({
132
- items: sortedItems,
137
+ parentItems,
133
138
  item: items[0],
134
139
  })
135
140
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@darkpos/pricing",
3
- "version": "1.0.130",
3
+ "version": "1.0.132",
4
4
  "description": "Pricing calculator",
5
5
  "author": "Dark POS",
6
6
  "license": "ISC",
@@ -52,5 +52,5 @@
52
52
  "supertest": "^6.2.3",
53
53
  "supervisor": "^0.12.0"
54
54
  },
55
- "gitHead": "a2d90179e995ae985e8b6843a1143dda0e874850"
55
+ "gitHead": "aa74813e6d89c8f6befeebeb07ebaaefef8e5d31"
56
56
  }
@@ -1,89 +0,0 @@
1
- const usePricing = require('../index');
2
- const mockStores = require('./mocks/stores');
3
-
4
- const session = {
5
- store: mockStores[0],
6
- };
7
-
8
- const pricingService = usePricing(session);
9
-
10
- describe('Manual actions', () => {
11
- test('Should add related item and its related addModifiers to the parent item, then removing that relateditem should also remove the mod from the parent item', () => {
12
- const rawRelatedItem1 = {
13
- name: 'the related item',
14
- _id: '67e2cadd8dcf08ebcc5ef888',
15
- };
16
-
17
- const rawRelatedItem2 = {
18
- name: 'the 2nd related item',
19
- _id: '67e2cadd8dcf08ebcc5ef88a',
20
- };
21
-
22
- const groupMod = {
23
- _id: '67e2cadd8dcf08ebcc5ef889',
24
- name: 'General Repair Department',
25
- attributes: ['group'],
26
- modifierId: 'mod1',
27
- properties: {
28
- group: {
29
- items: [],
30
- },
31
- },
32
- };
33
-
34
- const parentItem = {
35
- name: 'the parent item',
36
- modifiers: [groupMod],
37
- _id: '67e2cadd8dcf08ebcc5ef887',
38
- __typename: 'OrderItem',
39
-
40
- itemId: 'abcd123',
41
- };
42
-
43
- const relatedItem1 = {
44
- ...rawRelatedItem1,
45
- properties: {
46
- relatedItem: true,
47
- parentId: parentItem._id,
48
- parentItemId: parentItem.itemId,
49
- includeParent: true,
50
- addModifiers: [groupMod],
51
- groupPath: ',67e2cadd8dcf08ebcc5ef889',
52
- },
53
- __typename: 'OrderItem',
54
- };
55
-
56
- const relatedItem2 = {
57
- ...rawRelatedItem2,
58
- properties: {
59
- relatedItem: true,
60
- parentId: parentItem._id,
61
- parentItemId: parentItem.itemId,
62
- includeParent: true,
63
- addModifiers: [groupMod],
64
- groupPath: ',67e2cadd8dcf08ebcc5ef889',
65
- },
66
- __typename: 'OrderItem',
67
- };
68
- const order = {
69
- items: [parentItem, relatedItem1, relatedItem2],
70
- };
71
-
72
- const result = pricingService.order.removeItem({
73
- order,
74
- item: relatedItem2,
75
- });
76
-
77
- expect(result.items.length).toBe(2);
78
- expect(result.items[0].modifiers.length).toBe(1);
79
- expect(result.items[0].modifiers[0].modifierId).toBe('mod1');
80
-
81
- // const result2 = pricingService.order.removeItem({
82
- // order: result,
83
- // item: relatedItem1,
84
- // });
85
-
86
- // expect(result2.items.length).toBe(1);
87
- // expect(result2.items[0].modifiers.length).toBe(0);
88
- });
89
- });
@@ -1,11 +0,0 @@
1
- module.exports = () =>
2
- function getAddModifiers(item) {
3
- if (
4
- !item ||
5
- !item.properties ||
6
- !Array.isArray(item.properties.addModifiers)
7
- )
8
- return [];
9
-
10
- return item.properties.addModifiers;
11
- };
@@ -1,9 +0,0 @@
1
- module.exports = () =>
2
- function hasAddModifiers(item) {
3
- return (
4
- !!item &&
5
- !!item.properties &&
6
- !!item.properties.addModifiers &&
7
- !!item.properties.addModifiers.length
8
- );
9
- };
@@ -1,4 +0,0 @@
1
- module.exports = () =>
2
- function isParentIncluded(item) {
3
- return item && item.properties && item.properties.includeParent;
4
- };