@darkpos/pricing 1.0.51 → 1.0.52

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.
@@ -1,8 +1,10 @@
1
1
  const usePricing = require('../../lib/index');
2
2
 
3
3
  const pricingService = usePricing();
4
+ const pricingServiceGroupModifiers = usePricing({
5
+ store: { _settings: { order: { groupModifiers: true } } },
6
+ });
4
7
 
5
- const { getItemModifiersDescription } = pricingService.item;
6
8
  const mockModifier = {
7
9
  _id: '67106323db3c71afb52b07b7',
8
10
  attributes: ['override'],
@@ -37,7 +39,7 @@ const mockModifier = {
37
39
  },
38
40
  _computed: {
39
41
  amount: 0,
40
- description: 'ItemsPriceManual ($0.00)',
42
+ description: 'ItemsPriceManual',
41
43
  },
42
44
  addModifiers: [],
43
45
  delModifiers: [],
@@ -46,13 +48,13 @@ const mockModifier = {
46
48
  _createdAt: '2024-10-17T01:12:34.370Z',
47
49
  _updatedAt: '2024-10-17T01:12:34.370Z',
48
50
  };
49
- describe('getItemModifiersDescription Function', () => {
51
+ describe('getModifierTags Function', () => {
50
52
  beforeEach(() => {
51
53
  jest.clearAllMocks();
52
54
  });
53
55
 
54
56
  test('should return an empty array if item or modifiers are not provided', () => {
55
- const result = getItemModifiersDescription(null);
57
+ const result = pricingService.item.getModifierTags({});
56
58
  expect(result).toEqual([]);
57
59
  });
58
60
 
@@ -69,50 +71,59 @@ describe('getItemModifiersDescription Function', () => {
69
71
  ],
70
72
  };
71
73
 
72
- const result = getItemModifiersDescription(item);
74
+ const result = pricingService.item.getModifierTags({
75
+ item,
76
+ });
73
77
 
74
- expect(result).toEqual([
78
+ expect(result).toMatchObject([
75
79
  {
76
80
  label: 'Desc 1',
77
81
  value: 'mod1',
78
82
  data: item.modifiers[0],
79
83
  quantity: 1,
80
84
  },
85
+ {
86
+ label: 'ItemsPriceManual',
87
+ value: 'mod2',
88
+ data: item.modifiers[1],
89
+ quantity: 1,
90
+ },
81
91
  ]);
82
92
  });
83
93
 
84
94
  test('should handle selected override options in the modifier', () => {
85
95
  const item = {
86
96
  modifiers: [
87
- {
88
- ...mockModifier,
89
- _id: 'mod1',
90
- name: 'Modifier 1',
91
- compute: { amount: 100 },
92
- properties: { override: { selected: { selectedUnit: 'kg' } } },
93
- },
97
+ pricingService.modifier.calculate(
98
+ {
99
+ ...mockModifier,
100
+ _id: 'mod1',
101
+ name: 'Modifier 1',
102
+ compute: { amount: 200 },
103
+ properties: {
104
+ override: { selected: { selectedUnit: 'kg', value: 200 } },
105
+ },
106
+ },
107
+ { price: 10, quantity: 1 }
108
+ ),
94
109
  ],
95
110
  };
96
111
 
97
- const result = getItemModifiersDescription(item);
112
+ const result = pricingService.item.getModifierTags({
113
+ item,
114
+ });
98
115
 
99
116
  expect(result).toEqual([
100
117
  {
101
- label: 'Modifier 1 100 kg',
118
+ label: 'Modifier 1 ($200.00/kg)',
102
119
  value: 'mod1',
103
120
  data: item.modifiers[0],
104
- quantity: 0,
121
+ quantity: 1,
105
122
  },
106
123
  ]);
107
124
  });
108
125
 
109
126
  test('should group modifiers when groupModifiers setting is true', () => {
110
- const pricingService2 = usePricing({
111
- store: { _settings: { order: { groupModifiers: true } } },
112
- });
113
-
114
- const { getItemModifiersDescription: getItemModifiersDescription2 } =
115
- pricingService2.item;
116
127
  const item = {
117
128
  modifiers: [
118
129
  {
@@ -124,9 +135,9 @@ describe('getItemModifiersDescription Function', () => {
124
135
  ],
125
136
  };
126
137
 
127
- const result = getItemModifiersDescription2(item);
138
+ const result = pricingServiceGroupModifiers.item.getModifierTags({ item });
128
139
 
129
- expect(result).toEqual([
140
+ expect(result).toMatchObject([
130
141
  {
131
142
  label: '1 Desc 1',
132
143
  value: 'mod1',
@@ -0,0 +1,52 @@
1
+ const usePricing = require('../../index');
2
+
3
+ const pricingService = usePricing();
4
+
5
+ describe('pricingService.item.getNoteTags Function', () => {
6
+ test('should return empty array if no notes are provided', () => {
7
+ const result = pricingService.item.getNoteTags({
8
+ notes: null,
9
+ });
10
+ expect(result).toEqual([]);
11
+ });
12
+
13
+ test('should filter out notes that are null or have a url', () => {
14
+ const notes = [
15
+ { message: 'Note 1' },
16
+ { message: 'Note 2', url: 'http://example.com' }, // Should be filtered out
17
+ null, // Should be filtered out
18
+ ];
19
+
20
+ const result = pricingService.item.getNoteTags({ notes });
21
+
22
+ expect(result).toEqual([
23
+ { label: 'Note 1', value: '0', data: { message: 'Note 1' }, quantity: 1 },
24
+ ]);
25
+ });
26
+
27
+ test('should map notes to noteTags', () => {
28
+ const notes = [{ message: 'Note 1' }, { message: 'Note 2' }];
29
+
30
+ const result = pricingService.item.getNoteTags({ notes });
31
+
32
+ expect(result).toEqual([
33
+ { label: 'Note 1', value: '0', data: { message: 'Note 1' }, quantity: 1 },
34
+ { label: 'Note 2', value: '1', data: { message: 'Note 2' }, quantity: 1 },
35
+ ]);
36
+ });
37
+
38
+ test('should handle case where notes contain falsy values', () => {
39
+ const notes = [null, undefined, { message: 'Valid Note' }];
40
+
41
+ const result = pricingService.item.getNoteTags({ notes });
42
+
43
+ expect(result).toEqual([
44
+ {
45
+ label: 'Valid Note',
46
+ value: '0',
47
+ data: { message: 'Valid Note' },
48
+ quantity: 1,
49
+ },
50
+ ]);
51
+ });
52
+ });
@@ -536,4 +536,297 @@ describe('Item actions', () => {
536
536
  _actual: 100,
537
537
  });
538
538
  });
539
+ test('CU-86dvbn63z: Calculate item with quantity > 1 and modifierAmountFixed10', () => {
540
+ const itemWithModifierAmountFixed10 = {
541
+ name: "Men's 3pc Tuxedo",
542
+ pieces: 3,
543
+ total: 53.03,
544
+ price: 13.5,
545
+ quantity: 3,
546
+ modifiers: [
547
+ {
548
+ _id: '675354ee39a47228afd1f1a4',
549
+ attributes: ['override'],
550
+ modifierId: '6751f7eeb60c71cefee138ee',
551
+ name: 'Override modamount fixed 10',
552
+ group: 'Upcharge',
553
+ type: 'fee',
554
+ tags: ['default', 'all'],
555
+ direct: true,
556
+ properties: {
557
+ override: {
558
+ type: 'fixed',
559
+ field: 'amount',
560
+ fixedValue: 10,
561
+ multiplier: false,
562
+ },
563
+ },
564
+ compute: { type: 'fixed', amount: 10, action: 'add' },
565
+ },
566
+ ],
567
+ _id: '675354e939a47228afd1f199',
568
+ properties: { basePrice: 13.5 },
569
+
570
+ itemId: '62cdbfd01ee1b400193281ee',
571
+ };
572
+ const newItem = pricingService.item.calculate(
573
+ itemWithModifierAmountFixed10
574
+ );
575
+
576
+ expect(newItem).toHaveProperty('total', 50.5);
577
+ expect(newItem).toHaveProperty('price', 13.5);
578
+ expect(newItem.modifiers[0]).toHaveProperty('_computed', {
579
+ amount: 10,
580
+ description: 'Override modamount fixed 10 ($10.00)',
581
+ });
582
+
583
+ expect(newItem).toHaveProperty('subTotals', {
584
+ fee: 10,
585
+ _included: 0,
586
+ _xincluded: 10,
587
+ _direct: 10,
588
+ _xdirect: 0,
589
+ _simple: 40.5,
590
+ _actual: 40.5,
591
+ });
592
+ });
593
+
594
+ test('CU-86dvbn63z: Calculate item with quantity > 1 and modifierAmountFixed10 Multiplier', () => {
595
+ const itemWithModifierAmountFixed10Multiplier = {
596
+ name: "Men's 3pc Tuxedo",
597
+ pieces: 3,
598
+ total: 53.03,
599
+ price: 13.5,
600
+ quantity: 3,
601
+ modifiers: [
602
+ {
603
+ _id: '675354ee39a47228afd1f1a4',
604
+ attributes: ['override'],
605
+ modifierId: '6751f7eeb60c71cefee138ee',
606
+ name: 'Override modamount fixed 10',
607
+ group: 'Upcharge',
608
+ type: 'fee',
609
+ tags: ['default', 'all'],
610
+ direct: true,
611
+ properties: {
612
+ override: {
613
+ type: 'fixed',
614
+ field: 'amount',
615
+ fixedValue: 10,
616
+ multiplier: true,
617
+ },
618
+ },
619
+ compute: { type: 'fixed', amount: 10, action: 'add' },
620
+ },
621
+ ],
622
+ _id: '675354e939a47228afd1f199',
623
+ properties: { basePrice: 13.5 },
624
+
625
+ itemId: '62cdbfd01ee1b400193281ee',
626
+ };
627
+ const newItem = pricingService.item.calculate(
628
+ itemWithModifierAmountFixed10Multiplier
629
+ );
630
+
631
+ expect(newItem).toHaveProperty('total', 70.5);
632
+ expect(newItem).toHaveProperty('price', 13.5);
633
+ expect(newItem.modifiers[0]).toHaveProperty('_computed', {
634
+ amount: 10,
635
+ description: 'Override modamount fixed 10 ($30.00)',
636
+ });
637
+
638
+ expect(newItem).toHaveProperty('subTotals', {
639
+ fee: 30,
640
+ _included: 0,
641
+ _xincluded: 30,
642
+ _direct: 30,
643
+ _xdirect: 0,
644
+ _simple: 40.5,
645
+ _actual: 40.5,
646
+ });
647
+ });
648
+
649
+ test('CU-86dvbn63z: Calculate item with quantity > 1 and quantity override modifier', () => {
650
+ const itemWithQuantityOverride5 = {
651
+ name: "Men's 3pc Tuxedo",
652
+ pieces: 3,
653
+ total: 70.88,
654
+ price: 13.5,
655
+ quantity: 5,
656
+ modifiers: [
657
+ {
658
+ _id: '67535f3ab4c5ea63d2d7964b',
659
+ attributes: ['override'],
660
+ modifierId: '675359b5d08f91f558233f85',
661
+ _parentId: null,
662
+ locked: false,
663
+ name: 'Override Item Quantity 5',
664
+ sku: '',
665
+ description: '',
666
+ group: 'Upcharge',
667
+ type: 'tax',
668
+ tags: ['default'],
669
+ order: 0,
670
+ included: false,
671
+ direct: true,
672
+ hidden: false,
673
+ print: true,
674
+ required: false,
675
+ recommended: false,
676
+ default: false,
677
+ code: '',
678
+ properties: {
679
+ subscription: {},
680
+ override: { type: 'fixed', field: 'quantity', fixedValue: 5 },
681
+ group: { items: [], modifiers: [] },
682
+ department: {},
683
+ sort: null,
684
+ },
685
+ _computed: { amount: 0, description: 'Override Item Quantity 5' },
686
+ addModifiers: [],
687
+ delModifiers: [],
688
+ conditions: { valid: true },
689
+ compute: null,
690
+ _createdAt: '2024-12-06T20:08:21.409Z',
691
+ _updatedAt: '2024-12-06T20:18:37.174Z',
692
+ },
693
+ ],
694
+ _id: '67535f34b4c5ea63d2d79640',
695
+ properties: { basePrice: 13.5 },
696
+ itemId: '62cdbfd01ee1b400193281ee',
697
+ menuRuleId: '65660855dfffaf2da26fb870',
698
+ __typename: 'OrderItem',
699
+ };
700
+ const newItem = pricingService.item.calculate(itemWithQuantityOverride5);
701
+
702
+ expect(newItem).toHaveProperty('total', 67.5);
703
+ expect(newItem).toHaveProperty('price', 13.5);
704
+ expect(newItem.modifiers[0]).toHaveProperty('_computed', {
705
+ amount: 0,
706
+ description: 'Override Item Quantity 5',
707
+ });
708
+
709
+ expect(newItem).toHaveProperty('subTotals', {
710
+ _included: 0,
711
+ _xincluded: 0,
712
+ _direct: 0,
713
+ _xdirect: 0,
714
+ _simple: 67.5,
715
+ _actual: 67.5,
716
+ });
717
+ });
718
+
719
+ test('CU-86dvbn63z: Calculate item with quantity > 1 and modifieritemPriceFixed10', () => {
720
+ const itemWithModifierAmountFixed10 = {
721
+ name: "Men's 3pc Tuxedo",
722
+ pieces: 3,
723
+ price: 10,
724
+ quantity: 3,
725
+ modifiers: [
726
+ {
727
+ _id: '675354ee39a47228afd1f1a4',
728
+ attributes: ['override'],
729
+ modifierId: '6751f7eeb60c71cefee138ee',
730
+ name: 'Override item price fixed 10',
731
+ group: 'Upcharge',
732
+ type: 'fee',
733
+ tags: ['default', 'all'],
734
+ direct: true,
735
+ properties: {
736
+ override: {
737
+ type: 'fixed',
738
+ field: 'price',
739
+ fixedValue: 10,
740
+ multiplier: false,
741
+ },
742
+ },
743
+ compute: { type: 'fixed', amount: 10, action: 'add' },
744
+ },
745
+ ],
746
+ _id: '675354e939a47228afd1f199',
747
+ properties: { basePrice: 13.5 },
748
+
749
+ itemId: '62cdbfd01ee1b400193281ee',
750
+ };
751
+ const newItem = pricingService.item.calculate(
752
+ itemWithModifierAmountFixed10
753
+ );
754
+
755
+ expect(newItem).toHaveProperty('total', 30);
756
+ expect(newItem).toHaveProperty('price', 10);
757
+ expect(newItem.modifiers[0]).toHaveProperty('_computed', {
758
+ amount: 0,
759
+ description: 'Override item price fixed 10 ($10.00/Unit)',
760
+ });
761
+
762
+ expect(newItem).toHaveProperty('subTotals', {
763
+ _included: 0,
764
+ _xincluded: 0,
765
+ _direct: 0,
766
+ _xdirect: 0,
767
+ _simple: 30,
768
+ _actual: 30,
769
+ });
770
+ });
771
+
772
+ test('CU-86dvbn63z: Calculate item with quantity > 1 and modifieritemPriceFixed1 multiplier', () => {
773
+ const item = {
774
+ name: "Men's 3pc Tuxedo",
775
+ pieces: 3,
776
+ total: 141.75,
777
+ price: 135,
778
+ quantity: 1,
779
+ modifiers: [
780
+ {
781
+ _id: '67536495bc57ccecf751a5dc',
782
+ attributes: ['override'],
783
+ modifierId: '6751e9c0b60c71cefee0c3cc',
784
+ _parentId: null,
785
+ locked: false,
786
+ name: 'Override Item Price 10 USD Multiplier',
787
+ group: 'Upcharge',
788
+ type: 'fee',
789
+ tags: ['default', 'all'],
790
+
791
+ direct: true,
792
+
793
+ properties: {
794
+ override: {
795
+ type: 'fixed',
796
+ field: 'price',
797
+ fixedValue: 10,
798
+ multiplier: true,
799
+ },
800
+ },
801
+ _computed: {
802
+ amount: 0,
803
+ description:
804
+ 'Override Item Price 10 USD Multiplier (10 Unit @ $13.50/Unit)',
805
+ },
806
+ compute: { amount: 10 },
807
+ },
808
+ ],
809
+ _id: '675360d5bc57ccecf751a5b5',
810
+ properties: { basePrice: 13.5 },
811
+ itemId: '62cdbfd01ee1b400193281ee',
812
+ };
813
+ const newItem = pricingService.item.calculate(item);
814
+
815
+ expect(newItem).toHaveProperty('total', 135);
816
+ expect(newItem).toHaveProperty('price', 135);
817
+ expect(newItem.modifiers[0]).toHaveProperty('_computed', {
818
+ amount: 0,
819
+ description:
820
+ 'Override Item Price 10 USD Multiplier (10 Unit @ $13.50/Unit)',
821
+ });
822
+
823
+ expect(newItem).toHaveProperty('subTotals', {
824
+ _included: 0,
825
+ _xincluded: 0,
826
+ _direct: 0,
827
+ _xdirect: 0,
828
+ _simple: 135,
829
+ _actual: 135,
830
+ });
831
+ });
539
832
  });
@@ -73,7 +73,7 @@ const addItemMock = {
73
73
  properties: null,
74
74
  _computed: {
75
75
  amount: 0,
76
- description: 'null ($0.00)',
76
+ description: 'null',
77
77
  },
78
78
  },
79
79
  ],
@@ -1402,7 +1402,7 @@ describe('hasModifier Function', () => {
1402
1402
  },
1403
1403
  _computed: {
1404
1404
  amount: 0,
1405
- description: 'White ($0.00)',
1405
+ description: 'White',
1406
1406
  },
1407
1407
  addModifiers: [],
1408
1408
  delModifiers: [],
@@ -60,7 +60,7 @@ describe('Order actions', () => {
60
60
  expect(cashPercentageDiscountOrder.items[0].modifiers[0]._computed).toEqual(
61
61
  expect.objectContaining({
62
62
  amount: 0,
63
- description: 'CASH 10% DISCOUNT ($0.00)',
63
+ description: 'CASH 10% DISCOUNT',
64
64
  })
65
65
  );
66
66
 
@@ -469,7 +469,7 @@ describe('Order actions', () => {
469
469
  expect(testOrder.items[0].modifiers[0]._computed).toEqual(
470
470
  expect.objectContaining({
471
471
  amount: 0,
472
- description: 'CASH 20% DISCOUNT ($0.00)',
472
+ description: 'CASH 20% DISCOUNT',
473
473
  })
474
474
  );
475
475
 
@@ -500,7 +500,7 @@ describe('Order actions', () => {
500
500
  expect(testOrder.items[0].modifiers[0]._computed).toEqual(
501
501
  expect.objectContaining({
502
502
  amount: 0,
503
- description: 'CASH 20% DISCOUNT ($0.00)',
503
+ description: 'CASH 20% DISCOUNT',
504
504
  })
505
505
  );
506
506
 
@@ -533,7 +533,7 @@ describe('Order actions', () => {
533
533
  expect(testOrder.items[0].modifiers[0]._computed).toEqual(
534
534
  expect.objectContaining({
535
535
  amount: 0,
536
- description: 'CASH 20% DISCOUNT ($0.00)',
536
+ description: 'CASH 20% DISCOUNT',
537
537
  })
538
538
  );
539
539
 
@@ -589,7 +589,7 @@ describe('Order actions', () => {
589
589
  expect(fullyPaidOrderWithCredit.items[0].modifiers[0]._computed).toEqual(
590
590
  expect.objectContaining({
591
591
  amount: 0,
592
- description: 'CASH 20% DISCOUNT ($0.00)',
592
+ description: 'CASH 20% DISCOUNT',
593
593
  })
594
594
  );
595
595
 
@@ -638,7 +638,7 @@ describe('Order actions', () => {
638
638
  expect(fullyPaidOrderWithCash.items[0].modifiers[0]._computed).toEqual(
639
639
  expect.objectContaining({
640
640
  amount: 0,
641
- description: 'CASH 20% DISCOUNT ($0.00)',
641
+ description: 'CASH 20% DISCOUNT',
642
642
  })
643
643
  );
644
644
 
@@ -719,7 +719,7 @@ describe('Order actions', () => {
719
719
  },
720
720
  _computed: {
721
721
  amount: 0,
722
- description: 'Alice Blue ($0.00)',
722
+ description: 'Alice Blue',
723
723
  },
724
724
  addModifiers: [],
725
725
  delModifiers: [],
@@ -762,7 +762,7 @@ describe('Order actions', () => {
762
762
  },
763
763
  _computed: {
764
764
  amount: 0,
765
- description: 'CASH 20% DISCOUNT ($0.00)',
765
+ description: 'CASH 20% DISCOUNT',
766
766
  },
767
767
  addModifiers: [],
768
768
  delModifiers: [],
@@ -810,7 +810,7 @@ describe('Order actions', () => {
810
810
  },
811
811
  _computed: {
812
812
  amount: 0,
813
- description: 'Light ($0.00)',
813
+ description: 'Light',
814
814
  },
815
815
  addModifiers: [],
816
816
  delModifiers: [],
@@ -857,7 +857,7 @@ describe('Order actions', () => {
857
857
  },
858
858
  _computed: {
859
859
  amount: 0,
860
- description: 'Box ($0.00)',
860
+ description: 'Box',
861
861
  },
862
862
  addModifiers: [],
863
863
  delModifiers: [],
@@ -1096,14 +1096,14 @@ describe('Order actions', () => {
1096
1096
  expect(resultedOrder.items[0].modifiers[0]._computed).toEqual(
1097
1097
  expect.objectContaining({
1098
1098
  amount: 0,
1099
- description: 'Alice Blue ($0.00)',
1099
+ description: 'Alice Blue (0 Unit @ $13.50/Unit)',
1100
1100
  })
1101
1101
  );
1102
1102
 
1103
1103
  expect(resultedOrder.items[0].modifiers[1]._computed).toEqual(
1104
1104
  expect.objectContaining({
1105
1105
  amount: 0,
1106
- description: 'CASH 20% DISCOUNT ($0.00)',
1106
+ description: 'CASH 20% DISCOUNT',
1107
1107
  })
1108
1108
  );
1109
1109
 
@@ -1377,7 +1377,7 @@ describe('Order actions', () => {
1377
1377
  },
1378
1378
  _computed: {
1379
1379
  amount: 0,
1380
- description: 'Laundry ($0.00)',
1380
+ description: 'Laundry',
1381
1381
  },
1382
1382
  addModifiers: [],
1383
1383
  delModifiers: [],
@@ -1455,7 +1455,7 @@ describe('Order actions', () => {
1455
1455
  },
1456
1456
  _computed: {
1457
1457
  amount: 0,
1458
- description: 'Dry Cleaning ($0.00)',
1458
+ description: 'Dry Cleaning',
1459
1459
  },
1460
1460
  addModifiers: [],
1461
1461
  delModifiers: [],
@@ -1533,7 +1533,7 @@ describe('Order actions', () => {
1533
1533
  },
1534
1534
  _computed: {
1535
1535
  amount: 0,
1536
- description: 'Dry Cleaning ($0.00)',
1536
+ description: 'Dry Cleaning',
1537
1537
  },
1538
1538
  addModifiers: [],
1539
1539
  delModifiers: [],
@@ -85,7 +85,14 @@ module.exports = ({ _, utils, actions, modifierActions }) => {
85
85
  ceach => ceach.modifierId === each.modifierId
86
86
  )
87
87
  )
88
- .map(each => modifierActions.calculate(each, { skip: true }));
88
+ .map(each =>
89
+ modifierActions.calculate(each, {
90
+ price,
91
+ quantity,
92
+ skip: true,
93
+ basePrice: actions.getBasePrice(item),
94
+ })
95
+ );
89
96
 
90
97
  if (modifiersToCompute.length || paymentModifiersToCompute.length) {
91
98
  // sort modifiers based on sort
@@ -130,6 +137,7 @@ module.exports = ({ _, utils, actions, modifierActions }) => {
130
137
  {
131
138
  price: computedPrice,
132
139
  quantity,
140
+ basePrice: actions.getBasePrice(item),
133
141
  }
134
142
  );
135
143
 
@@ -147,11 +155,22 @@ module.exports = ({ _, utils, actions, modifierActions }) => {
147
155
 
148
156
  // adding this computeField because now the compute from a modifier can be null
149
157
  const computeField = getComputeModField(_modifier);
158
+
159
+ const isPercentage = computeField.type === 'percentage';
160
+ const isIgnoreQuantity = modifierActions.isIgnoreQuantity(_modifier);
161
+ const isNotFixedAddAndAmountGtPrice =
162
+ !modifierActions.isFixedAdd(_modifier) &&
163
+ math.gt(math.abs(computedAmountCalc), computedPriceCalc);
164
+
165
+ const isAmountOverrideAndNotMultiplier =
166
+ modifierActions.isAmountOverride(_modifier) &&
167
+ !modifierActions.isMultiplier(_modifier);
168
+
150
169
  let computedAmount =
151
- computeField.type === 'percentage' ||
152
- modifierActions.isIgnoreQuantity(_modifier) ||
153
- (!modifierActions.isFixedAdd(_modifier) &&
154
- math.gt(math.abs(computedAmountCalc), computedPriceCalc))
170
+ isPercentage ||
171
+ isIgnoreQuantity ||
172
+ isNotFixedAddAndAmountGtPrice ||
173
+ isAmountOverrideAndNotMultiplier
155
174
  ? _computed.amount
156
175
  : computedAmountCalc;
157
176
 
@@ -0,0 +1,7 @@
1
+ module.exports = () =>
2
+ function getBasePrice(item) {
3
+ if (!item) return 0;
4
+ if (!item.properties || typeof item.properties.basePrice !== 'number')
5
+ return item.price;
6
+ return item.properties.basePrice;
7
+ };
@@ -0,0 +1,45 @@
1
+ module.exports = ({ modifierActions, settings }) =>
2
+ function getModifierTags({ item, skipGrouping = false }) {
3
+ const groupModifiers =
4
+ settings && settings.order && settings.order.groupModifiers;
5
+
6
+ if (!item || !Array.isArray(item.modifiers)) return [];
7
+
8
+ let modifierTags = item.modifiers
9
+ .filter(
10
+ each => modifierActions.isValid(each) && !modifierActions.isGroup(each)
11
+ )
12
+ .map(modifier => {
13
+ const { name, _id } = modifier;
14
+
15
+ let label = name;
16
+
17
+ if (modifierActions.isGroupOfValues(modifier)) {
18
+ label = modifierActions.getSelectedValues(modifier) || label;
19
+ }
20
+
21
+ if (
22
+ modifier &&
23
+ !modifier.included &&
24
+ modifier._computed &&
25
+ modifier._computed.description
26
+ ) {
27
+ label = modifier._computed.description;
28
+ }
29
+
30
+ const modifierValue = {
31
+ label,
32
+ value: _id,
33
+ data: modifier,
34
+ quantity: 1,
35
+ };
36
+
37
+ return modifierValue;
38
+ });
39
+
40
+ if (groupModifiers && !skipGrouping) {
41
+ modifierTags = modifierActions.getGroupedModifiers(modifierTags);
42
+ }
43
+
44
+ return modifierTags;
45
+ };
@@ -1,5 +1,5 @@
1
1
  module.exports = () =>
2
- function getNotesToModifierTags({ notes, modifierTags }) {
2
+ function getNoteTags({ notes }) {
3
3
  let noteTags = [];
4
4
  if (notes && notes.length > 0) {
5
5
  noteTags =
@@ -17,5 +17,5 @@ module.exports = () =>
17
17
  }) || [];
18
18
  }
19
19
 
20
- return modifierTags.concat(noteTags);
20
+ return noteTags;
21
21
  };
package/lib/item/index.js CHANGED
@@ -23,7 +23,7 @@ const getItemsTotals = require('./getItemsTotals');
23
23
  const getNotIncludedModifiers = require('./getNotIncludedModifiers');
24
24
  const hasModifierWithValue = require('./hasModifierWithValue');
25
25
  const getItemsTotalPaid = require('./getItemsTotalPaid');
26
- const getItemModifiersDescription = require('./getItemModifiersDescription');
26
+ const getModifierTags = require('./getModifierTags');
27
27
  const isRelatedItem = require('./isRelatedItem');
28
28
  const getParentItem = require('./getParentItem');
29
29
  const isParentIncluded = require('./isParentIncluded');
@@ -44,6 +44,8 @@ const getInvalidRequiredModifiers = require('./getInvalidRequiredModifiers');
44
44
  const getPriceWithoutModifiers = require('./getPriceWithoutModifiers');
45
45
  const getTotalsDifference = require('./getTotalsDifference');
46
46
  const getTotalNeareastDifference = require('./getTotalNeareastDifference');
47
+ const getNoteTags = require('./getNoteTags');
48
+ const getBasePrice = require('./getBasePrice');
47
49
 
48
50
  const itemActions = (deps = {}) => {
49
51
  const actions = {};
@@ -79,7 +81,7 @@ const itemActions = (deps = {}) => {
79
81
  getNotIncludedModifiers: getNotIncludedModifiers(innerDeps),
80
82
  hasModifierWithValue: hasModifierWithValue(innerDeps),
81
83
  getItemsTotalPaid: getItemsTotalPaid(innerDeps),
82
- getItemModifiersDescription: getItemModifiersDescription(innerDeps),
84
+ getModifierTags: getModifierTags(innerDeps),
83
85
  isRelatedItem: isRelatedItem(innerDeps),
84
86
  getParentItem: getParentItem(innerDeps),
85
87
  isParentIncluded: isParentIncluded(innerDeps),
@@ -101,6 +103,8 @@ const itemActions = (deps = {}) => {
101
103
  getPriceWithoutModifiers: getPriceWithoutModifiers(innerDeps),
102
104
  getTotalsDifference: getTotalsDifference(innerDeps),
103
105
  getTotalNeareastDifference: getTotalNeareastDifference(innerDeps),
106
+ getNoteTags: getNoteTags(innerDeps),
107
+ getBasePrice: getBasePrice(innerDeps),
104
108
  });
105
109
 
106
110
  Object.keys(freezedActions).forEach(actionName => {
@@ -56,10 +56,8 @@ module.exports = ({ modifierActions, _, actions }) => {
56
56
  )
57
57
  );
58
58
 
59
- const hasOverride = modifiersToApply.find(
60
- each =>
61
- modifierActions.isOverride(each) ||
62
- modifierActions.isComputedOverride(each)
59
+ const hasOverride = modifiersToApply.find(each =>
60
+ modifierActions.isOverride(each)
63
61
  );
64
62
 
65
63
  if (hasOverride) {
@@ -68,10 +66,7 @@ module.exports = ({ modifierActions, _, actions }) => {
68
66
 
69
67
  if (modifierActions.isQuantityOverride(modifier)) nextItem.quantity = 1;
70
68
 
71
- if (
72
- modifierActions.isPriceOverride(modifier) ||
73
- modifierActions.isComputedOverride(modifier)
74
- )
69
+ if (modifierActions.isPriceOverride(modifier))
75
70
  nextItem.price = actions.getItemPrice({
76
71
  item: originalItem,
77
72
  cache,
@@ -9,7 +9,7 @@ module.exports = ({ _, constants, utils, localization, actions }) => {
9
9
 
10
10
  return function calculate(
11
11
  _modifier = {},
12
- options = { price: 0, quantity: 0, skip: false }
12
+ options = { price: 0, quantity: 0, skip: false, basePrice: 0 }
13
13
  ) {
14
14
  const modifier = _modifier;
15
15
  const { name } = modifier;
@@ -43,16 +43,49 @@ module.exports = ({ _, constants, utils, localization, actions }) => {
43
43
  100
44
44
  );
45
45
 
46
- if (!type || action === Modifier.Compute.Actions.OVERRIDE)
47
- _computed.amount = 0;
46
+ if (!type) _computed.amount = 0;
48
47
 
49
48
  if (math.gt(math.abs(_computed.amount), maxAmount)) {
50
49
  _computed.amount = maxAmount * multiplier;
51
50
  }
52
51
  }
53
52
 
54
- const localAmount = localization.formatAmount(_computed.amount);
55
- _computed.description = `${name} (${localAmount})`;
53
+ const localAmount =
54
+ !!_computed.amount && Number(_computed.amount) !== 0
55
+ ? `${localization.formatAmount(_computed.amount)}`
56
+ : '';
57
+
58
+ const localBasePrice = localization.formatAmount(
59
+ options.basePrice || options.price || 0
60
+ );
61
+
62
+ const isMultiplier = actions.isMultiplier(modifier);
63
+
64
+ _computed.description = `${name}${localAmount ? ` (${localAmount})` : ''}`;
65
+
66
+ if (actions.isPriceOverride(modifier)) {
67
+ _computed.description = isMultiplier
68
+ ? `${name} (${compute.amount} Unit @ ${localBasePrice}/Unit)`
69
+ : `${name} (${localization.formatAmount(compute.amount)}/Unit)`;
70
+ }
71
+
72
+ if (actions.isAmountOverride(modifier) && isMultiplier) {
73
+ _computed.description = `${name} (${localization.formatAmount(
74
+ math.mul(_computed.amount, options.quantity)
75
+ )})`;
76
+ }
77
+
78
+ if (actions.isOptionsSelectedOverride(modifier)) {
79
+ const selectedOverrideOptions = _.get(
80
+ modifier,
81
+ 'properties.override.selected'
82
+ );
83
+ _computed.description = isMultiplier
84
+ ? `${name} (${compute.amount} Unit @ ${localBasePrice}/${selectedOverrideOptions.selectedUnit})`
85
+ : `${name} (${localization.formatAmount(compute.amount)}/${
86
+ selectedOverrideOptions.selectedUnit
87
+ })`;
88
+ }
56
89
 
57
90
  return { ..._.cloneDeep(modifier), _computed };
58
91
  };
@@ -89,7 +89,6 @@ const isService = require('./isService');
89
89
  const isSingleValue = require('./isSingleValue');
90
90
  const isGroupOfItems = require('./isGroupOfItems');
91
91
  const isOverride = require('./isOverride');
92
- const isComputedOverride = require('./isComputedOverride');
93
92
  const isDepartment = require('./isDepartment');
94
93
  const isRequired = require('./isRequired');
95
94
  const isMultiplier = require('./isMultiplier');
@@ -129,7 +128,6 @@ const hasItems = require('./hasItems');
129
128
  const removeGroupData = require('./removeGroupData');
130
129
  const isRelatedModifier = require('./isRelatedModifier');
131
130
  const getGroupedModifiers = require('./getGroupedModifiers');
132
- const getNotesToModifierTags = require('./getNotesToModifierTags');
133
131
  const isOptionsOverride = require('./isOptionsOverride');
134
132
  const getGroupedModifierLabels = require('./getGroupedModifierLabels');
135
133
  const validate = require('./validate');
@@ -149,6 +147,7 @@ const isChild = require('./isChild');
149
147
  const isExtractCalculatedValue = require('./isExtractCalculatedValue');
150
148
  const getPriceWithoutModifier = require('./getPriceWithoutModifier');
151
149
  const isGroup = require('./isGroup');
150
+ const isOptionsSelectedOverride = require('./isOptionsSelectedOverride');
152
151
 
153
152
  const modifierActions = (deps = {}) => {
154
153
  const actions = {};
@@ -250,7 +249,6 @@ const modifierActions = (deps = {}) => {
250
249
  isSingleValue: isSingleValue(innerDeps),
251
250
  isGroupOfItems: isGroupOfItems(innerDeps),
252
251
  isOverride: isOverride(innerDeps),
253
- isComputedOverride: isComputedOverride(innerDeps),
254
252
  isDepartment: isDepartment(innerDeps),
255
253
  isRequired: isRequired(innerDeps),
256
254
  isMultiplier: isMultiplier(innerDeps),
@@ -289,7 +287,6 @@ const modifierActions = (deps = {}) => {
289
287
  removeGroupData: removeGroupData(innerDeps),
290
288
  isRelatedModifier: isRelatedModifier(innerDeps),
291
289
  getGroupedModifiers: getGroupedModifiers(innerDeps),
292
- getNotesToModifierTags: getNotesToModifierTags(innerDeps),
293
290
  isOptionsOverride: isOptionsOverride(innerDeps),
294
291
  getGroupedModifierLabels: getGroupedModifierLabels(innerDeps),
295
292
  validate: validate(innerDeps),
@@ -311,6 +308,7 @@ const modifierActions = (deps = {}) => {
311
308
  isExtractCalculatedValue: isExtractCalculatedValue(innerDeps),
312
309
  getPriceWithoutModifier: getPriceWithoutModifier(innerDeps),
313
310
  isGroup: isGroup(innerDeps),
311
+ isOptionsSelectedOverride: isOptionsSelectedOverride(innerDeps),
314
312
  });
315
313
 
316
314
  Object.keys(freezedActions).forEach(actionName => {
@@ -1,10 +1,5 @@
1
1
  module.exports = ({ actions }) =>
2
2
  function isGroup(modifier) {
3
3
  if (!modifier) return false;
4
- return !!(
5
- actions.hasAttribute(modifier, 'group') ||
6
- (modifier.properties &&
7
- modifier.properties.group &&
8
- Object.keys(modifier.properties.group) > 0)
9
- );
4
+ return !!actions.hasAttribute(modifier, 'group');
10
5
  };
@@ -0,0 +1,7 @@
1
+ module.exports = ({ _, actions }) =>
2
+ function isOptionsSelectedOverride(modifier) {
3
+ return !!(
4
+ actions.isOverride(modifier) &&
5
+ !!_.get(modifier, 'properties.override.selected')
6
+ );
7
+ };
@@ -143,13 +143,25 @@ module.exports = ({ actions, itemActions, modifierActions, utils, _ }) => {
143
143
  };
144
144
  }
145
145
 
146
- if (modifierActions.isQuantityOverride(modifier) && modifier.compute) {
147
- item.quantity = modifier.compute.amount || 1;
146
+ if (modifierActions.isQuantityOverride(modifier)) {
147
+ if (modifier.compute && typeof modifier.compute.amount === 'number') {
148
+ item.quantity = modifier.compute.amount || 1;
149
+ } else if (typeof modifier.properties.override.fixedValue === 'number') {
150
+ item.quantity = modifier.properties.override.fixedValue;
151
+ }
148
152
  }
149
153
 
150
- if (isPriceOverride || modifierActions.isComputedOverride(modifier)) {
154
+ if (isPriceOverride) {
155
+ item.properties = {
156
+ ...(item.properties || {}),
157
+ basePrice: item.price,
158
+ };
151
159
  item.price = getPrice({ modifier: modifierToAdd, item });
152
160
  } else {
161
+ item.properties = {
162
+ ...(item.properties || {}),
163
+ basePrice: item.price,
164
+ };
153
165
  item.price = itemActions.getItemPrice({
154
166
  item,
155
167
  cache,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@darkpos/pricing",
3
- "version": "1.0.51",
3
+ "version": "1.0.52",
4
4
  "description": "Pricing calculator",
5
5
  "author": "Dark POS",
6
6
  "license": "ISC",
@@ -18,6 +18,7 @@
18
18
  "test:hasModifier": "jest --runInBand --detectOpenHandles --logHeapUsage --forceExit ./__TEST__/modifier/hasModifier.test.js",
19
19
  "test:item": "jest --runInBand --detectOpenHandles --logHeapUsage --forceExit ./__TEST__/item.test.js",
20
20
  "test:split": "jest --runInBand --detectOpenHandles --logHeapUsage --forceExit ./__TEST__/order/split.test.js",
21
+ "test:getModifierTags": "jest --runInBand --detectOpenHandles --logHeapUsage --forceExit ./__TEST__/item/getModifierTags.test.js",
21
22
  "lint": "eslint --quiet lib/"
22
23
  },
23
24
  "publishConfig": {
@@ -41,5 +42,5 @@
41
42
  "supertest": "^6.2.3",
42
43
  "supervisor": "^0.12.0"
43
44
  },
44
- "gitHead": "256cf9e7f41cbdf88d38713f8edae725ec5e855e"
45
+ "gitHead": "43e5d458336e6d49ffbcf8af2a715428364a4df5"
45
46
  }
@@ -1,78 +0,0 @@
1
- const getNotesToModifierTagsFunction = require('../../lib/modifier/getNotesToModifierTags');
2
-
3
- describe('getNotesToModifierTags Function', () => {
4
- const getNotesToModifierTags = getNotesToModifierTagsFunction();
5
-
6
- test('should return modifierTags if no notes are provided', () => {
7
- const modifierTags = [
8
- { label: 'Modifier 1', value: 'mod1', data: {}, quantity: 1 },
9
- ];
10
-
11
- const result = getNotesToModifierTags({ notes: null, modifierTags });
12
- expect(result).toEqual(modifierTags);
13
- });
14
-
15
- test('should return modifierTags if notes array is empty', () => {
16
- const modifierTags = [
17
- { label: 'Modifier 1', value: 'mod1', data: {}, quantity: 1 },
18
- ];
19
-
20
- const result = getNotesToModifierTags({ notes: [], modifierTags });
21
- expect(result).toEqual(modifierTags);
22
- });
23
-
24
- test('should filter out notes that are null or have a url', () => {
25
- const notes = [
26
- { message: 'Note 1' },
27
- { message: 'Note 2', url: 'http://example.com' }, // Should be filtered out
28
- null, // Should be filtered out
29
- ];
30
-
31
- const modifierTags = [
32
- { label: 'Modifier 1', value: 'mod1', data: {}, quantity: 1 },
33
- ];
34
-
35
- const result = getNotesToModifierTags({ notes, modifierTags });
36
-
37
- expect(result).toEqual([
38
- { label: 'Modifier 1', value: 'mod1', data: {}, quantity: 1 },
39
- { label: 'Note 1', value: '0', data: { message: 'Note 1' }, quantity: 1 },
40
- ]);
41
- });
42
-
43
- test('should map notes to noteTags and append to modifierTags', () => {
44
- const notes = [{ message: 'Note 1' }, { message: 'Note 2' }];
45
-
46
- const modifierTags = [
47
- { label: 'Modifier 1', value: 'mod1', data: {}, quantity: 1 },
48
- ];
49
-
50
- const result = getNotesToModifierTags({ notes, modifierTags });
51
-
52
- expect(result).toEqual([
53
- { label: 'Modifier 1', value: 'mod1', data: {}, quantity: 1 },
54
- { label: 'Note 1', value: '0', data: { message: 'Note 1' }, quantity: 1 },
55
- { label: 'Note 2', value: '1', data: { message: 'Note 2' }, quantity: 1 },
56
- ]);
57
- });
58
-
59
- test('should handle case where notes contain falsy values', () => {
60
- const notes = [null, undefined, { message: 'Valid Note' }];
61
-
62
- const modifierTags = [
63
- { label: 'Modifier 1', value: 'mod1', data: {}, quantity: 1 },
64
- ];
65
-
66
- const result = getNotesToModifierTags({ notes, modifierTags });
67
-
68
- expect(result).toEqual([
69
- { label: 'Modifier 1', value: 'mod1', data: {}, quantity: 1 },
70
- {
71
- label: 'Valid Note',
72
- value: '0',
73
- data: { message: 'Valid Note' },
74
- quantity: 1,
75
- },
76
- ]);
77
- });
78
- });
@@ -1,38 +0,0 @@
1
- const isComputedOverrideFunction = require('../../lib/modifier/isComputedOverride');
2
-
3
- describe('isComputedOverride Function', () => {
4
- const Modifier = {
5
- Attributes: {
6
- OVERRIDE: 'override',
7
- },
8
- };
9
-
10
- const isComputedOverride = isComputedOverrideFunction({
11
- constants: { Modifier },
12
- });
13
-
14
- test('should return false if modifier is null or undefined', () => {
15
- expect(isComputedOverride(null)).toBe(false);
16
- expect(isComputedOverride(undefined)).toBe(false);
17
- });
18
-
19
- test('should return false if modifier does not have compute property', () => {
20
- const modifier = {};
21
- expect(isComputedOverride(modifier)).toBe(false);
22
- });
23
-
24
- test('should return false if compute does not have action property', () => {
25
- const modifier = { compute: {} };
26
- expect(isComputedOverride(modifier)).toBe(false);
27
- });
28
-
29
- test('should return false if compute action is not OVERRIDE', () => {
30
- const modifier = { compute: { action: 'other_action' } };
31
- expect(isComputedOverride(modifier)).toBe(false);
32
- });
33
-
34
- test('should return true if compute action is OVERRIDE', () => {
35
- const modifier = { compute: { action: 'override' } };
36
- expect(isComputedOverride(modifier)).toBe(true);
37
- });
38
- });
@@ -1,56 +0,0 @@
1
- module.exports = ({ modifierActions, _, settings }) =>
2
- function getItemModifiersDescription(item) {
3
- const groupModifiers =
4
- settings && settings.order && settings.order.groupModifiers;
5
- if (!item || !Array.isArray(item.modifiers)) return [];
6
- let description = item.modifiers
7
- .filter(
8
- each =>
9
- !modifierActions.isHidden(each) &&
10
- modifierActions.isValid(each) &&
11
- !modifierActions.isAmountOverride(each) &&
12
- !modifierActions.isDepartment(each) &&
13
- modifierActions.isDirect(each) &&
14
- !modifierActions.isGroup(each)
15
- )
16
- .map(modifier => {
17
- const { name, _id, compute = {} } = modifier;
18
- let label = name;
19
- if (modifierActions.isGroupOfValues(modifier))
20
- label = modifierActions.getSelectedValues(modifier) || label;
21
- const selectedOverrideOptions = _.get(
22
- modifier,
23
- 'properties.override.selected'
24
- );
25
- if (
26
- modifier &&
27
- !modifier.included &&
28
- modifier._computed &&
29
- modifier._computed.description
30
- ) {
31
- label = modifier._computed.description;
32
- }
33
-
34
- const modifierValue = {
35
- label,
36
- value: _id,
37
- data: modifier,
38
- quantity: 1,
39
- };
40
-
41
- if (selectedOverrideOptions) {
42
- modifierValue.label = `${name} ${compute.amount} ${selectedOverrideOptions.selectedUnit}`;
43
- modifierValue.quantity = 0;
44
- }
45
- return modifierValue;
46
- });
47
- if (groupModifiers) {
48
- description = modifierActions.getGroupedModifiers(description);
49
- }
50
-
51
- const descriptions = modifierActions.getNotesToModifierTags({
52
- notes: item.notes,
53
- modifierTags: description,
54
- });
55
- return descriptions;
56
- };
@@ -1,8 +0,0 @@
1
- module.exports = ({ constants }) => {
2
- const { Modifier } = constants;
3
- return function isComputedOverride(modifier) {
4
- const computeAction =
5
- modifier && modifier.compute && modifier.compute.action;
6
- return computeAction === Modifier.Attributes.OVERRIDE;
7
- };
8
- };