@darkpos/pricing 1.0.53 → 1.0.54

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.
@@ -71,7 +71,7 @@ describe('addIndirectModifier Function', () => {
71
71
  expect(result).toEqual({
72
72
  item1: {
73
73
  compute: { amount: 50 }, // Adjusted amount to fix the total distribution difference
74
- properties: { ignoreQuantity: true },
74
+ properties: { isQuantityMultiplier: false },
75
75
  },
76
76
  item2: { compute: { amount: 50 }, properties: {} },
77
77
  });
@@ -127,7 +127,7 @@ describe('addIndirectModifier Function', () => {
127
127
  item1: {
128
128
  compute: { amount: -35 },
129
129
  properties: {
130
- ignoreQuantity: true,
130
+ isQuantityMultiplier: false,
131
131
  },
132
132
  _computed: { amount: 15 },
133
133
  },
@@ -160,7 +160,7 @@ describe('addIndirectModifier Function', () => {
160
160
  item1: {
161
161
  compute: { amount: -30 },
162
162
  properties: {
163
- ignoreQuantity: true,
163
+ isQuantityMultiplier: false,
164
164
  },
165
165
  },
166
166
  item2: { compute: { amount: 50 }, properties: {} },
@@ -15,6 +15,9 @@ describe('Item actions', () => {
15
15
  type: 'discount',
16
16
  direct: false,
17
17
  included: false,
18
+ properties: {
19
+ isQuantityMultiplier: true,
20
+ },
18
21
  },
19
22
  {
20
23
  compute: {
@@ -26,6 +29,9 @@ describe('Item actions', () => {
26
29
  type: 'discount',
27
30
  direct: false,
28
31
  included: false,
32
+ properties: {
33
+ isQuantityMultiplier: true,
34
+ },
29
35
  },
30
36
  {
31
37
  compute: {
@@ -37,6 +43,9 @@ describe('Item actions', () => {
37
43
  type: 'discount',
38
44
  direct: false,
39
45
  included: false,
46
+ properties: {
47
+ isQuantityMultiplier: true,
48
+ },
40
49
  },
41
50
  ];
42
51
  const orderItem = { price: 30, quantity: 2, modifiers };
@@ -60,6 +69,9 @@ describe('Item actions', () => {
60
69
  name: 'modifier1',
61
70
  direct: true,
62
71
  included: false,
72
+ properties: {
73
+ isQuantityMultiplier: true,
74
+ },
63
75
  },
64
76
  {
65
77
  compute: {
@@ -71,6 +83,9 @@ describe('Item actions', () => {
71
83
  type: 'discount',
72
84
  direct: true,
73
85
  included: false,
86
+ properties: {
87
+ isQuantityMultiplier: true,
88
+ },
74
89
  },
75
90
  {
76
91
  compute: {
@@ -82,6 +97,9 @@ describe('Item actions', () => {
82
97
  type: 'tax',
83
98
  direct: true,
84
99
  included: false,
100
+ properties: {
101
+ isQuantityMultiplier: true,
102
+ },
85
103
  },
86
104
  ];
87
105
  const orderItem = { price: 30, quantity: 2, modifiers };
@@ -110,6 +128,9 @@ describe('Item actions', () => {
110
128
  type: 'discount',
111
129
  direct: true,
112
130
  included: true,
131
+ properties: {
132
+ isQuantityMultiplier: true,
133
+ },
113
134
  },
114
135
  {
115
136
  compute: {
@@ -121,6 +142,9 @@ describe('Item actions', () => {
121
142
  type: 'discount',
122
143
  direct: true,
123
144
  included: true,
145
+ properties: {
146
+ isQuantityMultiplier: true,
147
+ },
124
148
  },
125
149
  {
126
150
  compute: {
@@ -132,6 +156,9 @@ describe('Item actions', () => {
132
156
  type: 'upcharge',
133
157
  direct: true,
134
158
  included: true,
159
+ properties: {
160
+ isQuantityMultiplier: true,
161
+ },
135
162
  },
136
163
  ];
137
164
  const orderItem = { price: 30, quantity: 2, modifiers };
@@ -631,7 +658,7 @@ describe('Item actions', () => {
631
658
  expect(newItem).toHaveProperty('total', 70.5);
632
659
  expect(newItem).toHaveProperty('price', 13.5);
633
660
  expect(newItem.modifiers[0]).toHaveProperty('_computed', {
634
- amount: 10,
661
+ amount: 30,
635
662
  description: 'Override modamount fixed 10 ($30.00)',
636
663
  });
637
664
 
@@ -1672,7 +1672,7 @@ const addItemMock = {
1672
1672
  items: [],
1673
1673
  },
1674
1674
  sort: null,
1675
- ignoreQuantity: true,
1675
+ isQuantityMultiplier: false,
1676
1676
  },
1677
1677
  _computed: null,
1678
1678
  addModifiers: [],
@@ -1795,7 +1795,7 @@ const addItemMock = {
1795
1795
  },
1796
1796
  department: {},
1797
1797
  sort: null,
1798
- ignoreQuantity: false,
1798
+ isQuantityMultiplier: true,
1799
1799
  },
1800
1800
  _computed: null,
1801
1801
  addModifiers: [],
@@ -262,7 +262,7 @@
262
262
  },
263
263
  "properties": {
264
264
  "sort": 999,
265
- "ignoreQuantity": true
265
+ "isQuantityMultiplier": false
266
266
  },
267
267
  "_id": "63ade222dd19604ca368eb29",
268
268
  "modifierId": "63ade212dd19604ca368eb23",
@@ -96,7 +96,7 @@
96
96
  "default": false,
97
97
  "code": "",
98
98
  "properties": {
99
- "ignoreQuantity": true
99
+ "isQuantityMultiplier": false
100
100
  },
101
101
  "_computed": {
102
102
  "amount": -2.36,
@@ -149,7 +149,7 @@
149
149
  "default": false,
150
150
  "code": "",
151
151
  "properties": {
152
- "ignoreQuantity": true
152
+ "isQuantityMultiplier": false
153
153
  },
154
154
  "_computed": {
155
155
  "amount": 0.48,
@@ -98,7 +98,7 @@
98
98
  "default": false,
99
99
  "code": "",
100
100
  "properties": {
101
- "ignoreQuantity": true
101
+ "isQuantityMultiplier": false
102
102
  },
103
103
  "_computed": {
104
104
  "amount": -2.36,
@@ -1,38 +1,14 @@
1
- const _ = require('lodash');
2
- const utils = require('@darkpos/utils');
3
- const createIndirectModifierFunction = require('../../lib/modifier/createIndirectModifier');
1
+ const usePricing = require('../../index');
2
+
3
+ const pricingService = usePricing();
4
4
 
5
5
  describe('createIndirectModifier Function', () => {
6
6
  test('create indirect modifier with an undefined modifier compute', () => {
7
- const constants = {
8
- Modifier: {
9
- Compute: {
10
- Types: {
11
- PERCENTAGE: 'percentage',
12
- FIXED: 'fixed',
13
- },
14
- Actions: {
15
- SUBTRACT: 'subtract',
16
- },
17
- },
18
- },
19
- };
20
- const actions = {
21
- getProperty: (modifier, prop) => modifier[prop],
22
- create: modifier => modifier,
23
- };
24
- // const getComputeModField = jest.fn().mockReturnValue(null);
25
-
26
- const createIndirectModifier = createIndirectModifierFunction({
27
- _,
28
- utils,
29
- constants,
30
- actions,
31
- });
32
-
33
7
  const modifier = {
34
8
  type: 'credit',
35
- properties: {},
9
+ properties: {
10
+ isQuantityMultiplier: true,
11
+ },
36
12
  };
37
13
  const options = {
38
14
  orderTotal: 100,
@@ -40,9 +16,12 @@ describe('createIndirectModifier Function', () => {
40
16
  itemTotal: 50,
41
17
  };
42
18
 
43
- const result = createIndirectModifier(modifier, options);
19
+ const result = pricingService.modifier.createIndirectModifier(
20
+ modifier,
21
+ options
22
+ );
44
23
 
45
- expect(result).toEqual({
24
+ expect(result).toMatchObject({
46
25
  ...modifier,
47
26
  direct: false,
48
27
  compute: {
@@ -51,39 +30,14 @@ describe('createIndirectModifier Function', () => {
51
30
  action: 'subtract',
52
31
  },
53
32
  properties: {
54
- ignoreQuantity: false,
33
+ isQuantityMultiplier: true,
55
34
  },
56
35
  });
57
36
  });
58
37
  test('create indirect modifier with a null modifier compute', () => {
59
- const constants = {
60
- Modifier: {
61
- Compute: {
62
- Types: {
63
- PERCENTAGE: 'percentage',
64
- FIXED: 'fixed',
65
- },
66
- Actions: {
67
- SUBTRACT: 'subtract',
68
- },
69
- },
70
- },
71
- };
72
- const actions = {
73
- getProperty: (modifier, prop) => modifier[prop],
74
- create: modifier => modifier,
75
- };
76
-
77
- const createIndirectModifier = createIndirectModifierFunction({
78
- _,
79
- utils,
80
- constants,
81
- actions,
82
- });
83
-
84
38
  const modifier = {
85
39
  type: 'credit',
86
- properties: {},
40
+ properties: { isQuantityMultiplier: true },
87
41
  compute: null,
88
42
  };
89
43
  const options = {
@@ -92,9 +46,12 @@ describe('createIndirectModifier Function', () => {
92
46
  itemTotal: 50,
93
47
  };
94
48
 
95
- const result = createIndirectModifier(modifier, options);
49
+ const result = pricingService.modifier.createIndirectModifier(
50
+ modifier,
51
+ options
52
+ );
96
53
 
97
- expect(result).toEqual({
54
+ expect(result).toMatchObject({
98
55
  ...modifier,
99
56
  direct: false,
100
57
  compute: {
@@ -103,39 +60,14 @@ describe('createIndirectModifier Function', () => {
103
60
  action: 'subtract',
104
61
  },
105
62
  properties: {
106
- ignoreQuantity: false,
63
+ isQuantityMultiplier: true,
107
64
  },
108
65
  });
109
66
  });
110
67
  test('create indirect modifier regular modifier', () => {
111
- const constants = {
112
- Modifier: {
113
- Compute: {
114
- Types: {
115
- PERCENTAGE: 'percentage',
116
- FIXED: 'fixed',
117
- },
118
- Actions: {
119
- SUBTRACT: 'subtract',
120
- },
121
- },
122
- },
123
- };
124
- const actions = {
125
- getProperty: (modifier, prop) => modifier[prop],
126
- create: modifier => modifier,
127
- };
128
-
129
- const createIndirectModifier = createIndirectModifierFunction({
130
- _,
131
- utils,
132
- constants,
133
- actions,
134
- });
135
-
136
68
  const modifier = {
137
69
  type: 'credit',
138
- properties: {},
70
+ properties: { isQuantityMultiplier: true },
139
71
  compute: {
140
72
  type: 'fixed',
141
73
  action: 'add',
@@ -148,9 +80,12 @@ describe('createIndirectModifier Function', () => {
148
80
  itemTotal: 50,
149
81
  };
150
82
 
151
- const result = createIndirectModifier(modifier, options);
83
+ const result = pricingService.modifier.createIndirectModifier(
84
+ modifier,
85
+ options
86
+ );
152
87
 
153
- expect(result).toEqual({
88
+ expect(result).toMatchObject({
154
89
  ...modifier,
155
90
  direct: false,
156
91
  compute: {
@@ -159,7 +94,7 @@ describe('createIndirectModifier Function', () => {
159
94
  amount: 2.5,
160
95
  },
161
96
  properties: {
162
- ignoreQuantity: false,
97
+ isQuantityMultiplier: true,
163
98
  },
164
99
  });
165
100
  });
@@ -1485,7 +1485,7 @@ describe('hasModifier Function', () => {
1485
1485
  action: 'subtract',
1486
1486
  },
1487
1487
  properties: {
1488
- ignoreQuantity: false,
1488
+ isQuantityMultiplier: true,
1489
1489
  },
1490
1490
  _id: '67226d7fe779680a203df892',
1491
1491
  modifierId: '62cdbfd01ee1b4001932822e',
@@ -1531,7 +1531,7 @@ describe('hasModifier Function', () => {
1531
1531
  action: 'subtract',
1532
1532
  },
1533
1533
  properties: {
1534
- ignoreQuantity: false,
1534
+ isQuantityMultiplier: true,
1535
1535
  subscription: {},
1536
1536
  override: {},
1537
1537
  group: {
@@ -806,7 +806,7 @@ describe('Order actions', () => {
806
806
  default: false,
807
807
  code: 'L',
808
808
  properties: {
809
- ignoreQuantity: false,
809
+ isQuantityMultiplier: true,
810
810
  },
811
811
  _computed: {
812
812
  amount: 0,
@@ -848,7 +848,7 @@ describe('Order actions', () => {
848
848
  default: false,
849
849
  code: '',
850
850
  properties: {
851
- ignoreQuantity: false,
851
+ isQuantityMultiplier: true,
852
852
  group: {
853
853
  modifiers: [],
854
854
  items: [],
@@ -21,6 +21,9 @@ describe('Order actions', () => {
21
21
  },
22
22
  name: 'modifier1',
23
23
  type: 'discount',
24
+ properties: {
25
+ isQuantityMultiplier: true,
26
+ },
24
27
  },
25
28
  {
26
29
  compute: {
@@ -30,11 +33,17 @@ describe('Order actions', () => {
30
33
  },
31
34
  name: 'modifier2',
32
35
  type: 'discount',
36
+ properties: {
37
+ isQuantityMultiplier: true,
38
+ },
33
39
  },
34
40
  {
35
41
  compute: { amount: 2, type: 'fixed', action: 'subtract' },
36
42
  name: 'modifier3',
37
43
  type: 'discount',
44
+ properties: {
45
+ isQuantityMultiplier: true,
46
+ },
38
47
  },
39
48
  ];
40
49
  const orderItem = { price: 30, quantity: 2, modifiers };
@@ -61,6 +70,9 @@ describe('Order actions', () => {
61
70
  },
62
71
  name: 'modifier1',
63
72
  type: 'discount',
73
+ properties: {
74
+ isQuantityMultiplier: true,
75
+ },
64
76
  },
65
77
  ],
66
78
  };
@@ -107,6 +119,9 @@ describe('Order actions', () => {
107
119
  },
108
120
  name: 'modifier1',
109
121
  type: 'discount',
122
+ properties: {
123
+ isQuantityMultiplier: true,
124
+ },
110
125
  };
111
126
 
112
127
  const order = { items: [item1, item2], modifiers: [modifier1] };
@@ -720,6 +735,7 @@ describe('Order actions', () => {
720
735
  },
721
736
  properties: {
722
737
  sort: 99,
738
+ isQuantityMultiplier: true,
723
739
  },
724
740
  };
725
741
 
@@ -734,6 +750,7 @@ describe('Order actions', () => {
734
750
  type: 'discount',
735
751
  properties: {
736
752
  sort: 1,
753
+ isQuantityMultiplier: true,
737
754
  },
738
755
  };
739
756
 
@@ -812,6 +829,7 @@ describe('Order actions', () => {
812
829
  },
813
830
  properties: {
814
831
  sort: 99,
832
+ isQuantityMultiplier: true,
815
833
  },
816
834
  };
817
835
 
@@ -826,6 +844,7 @@ describe('Order actions', () => {
826
844
  type: 'discount',
827
845
  properties: {
828
846
  sort: 1,
847
+ isQuantityMultiplier: true,
829
848
  },
830
849
  };
831
850
 
@@ -904,6 +923,7 @@ describe('Order actions', () => {
904
923
  },
905
924
  properties: {
906
925
  sort: 99,
926
+ isQuantityMultiplier: true,
907
927
  },
908
928
  };
909
929
 
@@ -918,6 +938,7 @@ describe('Order actions', () => {
918
938
  type: 'discount',
919
939
  properties: {
920
940
  sort: 1,
941
+ isQuantityMultiplier: true,
921
942
  },
922
943
  };
923
944
 
@@ -1006,7 +1027,7 @@ describe('Order actions', () => {
1006
1027
  name: `1 USD`,
1007
1028
  type: 'fixed',
1008
1029
  properties: {
1009
- ignoreQuantity: true,
1030
+ isQuantityMultiplier: false,
1010
1031
  },
1011
1032
  };
1012
1033
 
@@ -1085,6 +1106,7 @@ describe('Order actions', () => {
1085
1106
  },
1086
1107
  properties: {
1087
1108
  sort: 2,
1109
+ isQuantityMultiplier: true,
1088
1110
  },
1089
1111
  };
1090
1112
 
@@ -1099,6 +1121,7 @@ describe('Order actions', () => {
1099
1121
  type: 'fixed',
1100
1122
  properties: {
1101
1123
  sort: 1,
1124
+ isQuantityMultiplier: true,
1102
1125
  },
1103
1126
  };
1104
1127
 
@@ -1157,7 +1180,7 @@ describe('Order actions', () => {
1157
1180
 
1158
1181
  expect(newOrder.items[2].modifiers[0]._computed).toHaveProperty(
1159
1182
  'amount',
1160
- -0.16666666666666666
1183
+ -0.3333333333333333
1161
1184
  );
1162
1185
  expect(newOrder.items[2].modifiers[1]._computed).toHaveProperty(
1163
1186
  'amount',
@@ -1871,6 +1894,7 @@ describe('Order actions', () => {
1871
1894
  },
1872
1895
  properties: {
1873
1896
  sort: 2,
1897
+ isQuantityMultiplier: true,
1874
1898
  },
1875
1899
  };
1876
1900
 
@@ -1885,6 +1909,7 @@ describe('Order actions', () => {
1885
1909
  type: 'percentage',
1886
1910
  properties: {
1887
1911
  sort: 1,
1912
+ isQuantityMultiplier: true,
1888
1913
  },
1889
1914
  };
1890
1915
 
@@ -2087,7 +2112,7 @@ describe('Order actions', () => {
2087
2112
  expect(newOrderFixedModifier).toHaveProperty('total', 20);
2088
2113
  });
2089
2114
 
2090
- test('CU-86dtxh2y5: #2.A- Get calculated Order, One item and fixed Fee Modifier (ignoreQuantity: false)', () => {
2115
+ test('CU-86dtxh2y5: #2.A- Get calculated Order, One item and fixed Fee Modifier (isQuantityMultiplier: true)', () => {
2091
2116
  const newOrderFixedModifier = pricingService.order.calculate({
2092
2117
  items: [
2093
2118
  {
@@ -2103,6 +2128,9 @@ describe('Order actions', () => {
2103
2128
  },
2104
2129
  name: 'fee 20 USD',
2105
2130
  type: 'fee',
2131
+ properties: {
2132
+ isQuantityMultiplier: true,
2133
+ },
2106
2134
  },
2107
2135
  ],
2108
2136
  },
@@ -2111,7 +2139,7 @@ describe('Order actions', () => {
2111
2139
  expect(newOrderFixedModifier).toHaveProperty('total', 50);
2112
2140
  });
2113
2141
 
2114
- test('CU-86dtxh2y5: #2.B- Get calculated Order, One item and fixed Fee Modifier (ignoreQuantity: true)', () => {
2142
+ test('CU-86dtxh2y5: #2.B- Get calculated Order, One item and fixed Fee Modifier (isQuantityMultiplier: false)', () => {
2115
2143
  const newOrderFixedModifier = pricingService.order.calculate({
2116
2144
  items: [
2117
2145
  {
@@ -2128,7 +2156,7 @@ describe('Order actions', () => {
2128
2156
  name: 'fee 20 USD',
2129
2157
  type: 'fee',
2130
2158
  properties: {
2131
- ignoreQuantity: true,
2159
+ isQuantityMultiplier: false,
2132
2160
  },
2133
2161
  },
2134
2162
  ],
@@ -2158,7 +2186,7 @@ describe('Order actions', () => {
2158
2186
  expect(newOrderFixedModifier).toHaveProperty('total', 120);
2159
2187
  });
2160
2188
 
2161
- test('CU-86dtxh2y5: #4- Get calculated Order, One item and fixed Fee Modifier, using createFeeModifier (ignoreQuantity: true)', () => {
2189
+ test('CU-86dtxh2y5: #4- Get calculated Order, One item and fixed Fee Modifier, using createFeeModifier (isQuantityMultiplier: false)', () => {
2162
2190
  const newOrderFixedModifier = pricingService.order.calculate({
2163
2191
  items: [
2164
2192
  {
@@ -2172,7 +2200,7 @@ describe('Order actions', () => {
2172
2200
  amount: 100,
2173
2201
  type: Types.FIXED,
2174
2202
  properties: {
2175
- ignoreQuantity: true,
2203
+ isQuantityMultiplier: false,
2176
2204
  },
2177
2205
  }),
2178
2206
  ],
@@ -2661,4 +2689,421 @@ describe('Order actions', () => {
2661
2689
  _actual: 4.65,
2662
2690
  });
2663
2691
  });
2692
+ test('CU-861n7pum9 - Calculate order -> discountMod percentage isIgnoreQuanity=true qt=1', () => {
2693
+ const discountMod = {
2694
+ _id: 1,
2695
+ compute: {
2696
+ amount: 50,
2697
+ type: 'percentage',
2698
+ action: 'subtract',
2699
+ },
2700
+ name: `50% discount`,
2701
+ type: 'discount',
2702
+ properties: {
2703
+ isQuantityMultiplier: false,
2704
+ },
2705
+ };
2706
+
2707
+ const item1 = {
2708
+ _id: 1,
2709
+ price: 10,
2710
+ quantity: 1,
2711
+ modifiers: [discountMod],
2712
+ };
2713
+
2714
+ const order = {
2715
+ items: [item1],
2716
+ };
2717
+
2718
+ const newOrder = pricingService.order.calculate(order);
2719
+
2720
+ expect(newOrder).toHaveProperty('total', 5);
2721
+ expect(newOrder).toHaveProperty('subTotal', 10);
2722
+ expect(newOrder).toHaveProperty('subTotals', {
2723
+ discount: -5,
2724
+ });
2725
+ expect(newOrder.items[0]).toHaveProperty('total', 5);
2726
+ expect(newOrder.items[0].modifiers[0]._computed).toHaveProperty(
2727
+ 'amount',
2728
+ -5
2729
+ );
2730
+ });
2731
+
2732
+ test('CU-861n7pum9 - Calculate order -> discountMod percentage isIgnoreQuanity=true qt=2', () => {
2733
+ const discountMod = {
2734
+ _id: 1,
2735
+ compute: {
2736
+ amount: 50,
2737
+ type: 'percentage',
2738
+ action: 'subtract',
2739
+ },
2740
+ name: `50% discount`,
2741
+ type: 'discount',
2742
+ properties: {
2743
+ isQuantityMultiplier: false,
2744
+ },
2745
+ };
2746
+
2747
+ const item1 = {
2748
+ _id: 1,
2749
+ price: 10,
2750
+ quantity: 2,
2751
+ modifiers: [discountMod],
2752
+ };
2753
+
2754
+ const order = {
2755
+ items: [item1],
2756
+ };
2757
+
2758
+ const newOrder = pricingService.order.calculate(order);
2759
+
2760
+ expect(newOrder).toHaveProperty('total', 15);
2761
+ expect(newOrder).toHaveProperty('subTotal', 20);
2762
+ expect(newOrder).toHaveProperty('subTotals', {
2763
+ discount: -5,
2764
+ });
2765
+ expect(newOrder.items[0]).toHaveProperty('total', 15);
2766
+ expect(newOrder.items[0].modifiers[0]).toHaveProperty('_computed', {
2767
+ amount: -5,
2768
+ description: '50% discount (-$5.00)',
2769
+ });
2770
+ });
2771
+ test('CU-861n7pum9 - Calculate order -> discountMod100Fixed qt=1', () => {
2772
+ const discountMod100Fixed = {
2773
+ _id: 1,
2774
+ compute: {
2775
+ amount: 100,
2776
+ type: 'fixed',
2777
+ action: 'subtract',
2778
+ },
2779
+ name: `100% discount`,
2780
+ type: 'discount',
2781
+ };
2782
+
2783
+ const item1 = {
2784
+ _id: 1,
2785
+ price: 10,
2786
+ quantity: 1,
2787
+ modifiers: [discountMod100Fixed],
2788
+ };
2789
+
2790
+ const calculatedItem = pricingService.item.calculate(item1);
2791
+
2792
+ expect(calculatedItem).toHaveProperty('total', 0);
2793
+ expect(calculatedItem).toHaveProperty('subTotals', {
2794
+ _actual: 10,
2795
+ _direct: 0,
2796
+ _included: 0,
2797
+ _simple: 10,
2798
+ _xdirect: -10,
2799
+ _xincluded: -10,
2800
+ discount: -10,
2801
+ });
2802
+ expect(calculatedItem).toHaveProperty('total', 0);
2803
+ expect(calculatedItem.modifiers[0]).toHaveProperty('_computed', {
2804
+ amount: -10,
2805
+ description: '100% discount (-$10.00)',
2806
+ });
2807
+ });
2808
+
2809
+ test('CU-861n7pum9 - Calculate order -> discountMod100Fixed and discountMod100Percentage qt=1', () => {
2810
+ const discountMod100Fixed = {
2811
+ _id: 1,
2812
+ compute: {
2813
+ amount: 100,
2814
+ type: 'fixed',
2815
+ action: 'subtract',
2816
+ },
2817
+ name: `100% discount`,
2818
+ type: 'discount',
2819
+ };
2820
+
2821
+ const item1 = {
2822
+ _id: 1,
2823
+ price: 10,
2824
+ quantity: 1,
2825
+ modifiers: [discountMod100Fixed, discountMod100Fixed],
2826
+ };
2827
+
2828
+ const calculatedItem = pricingService.item.calculate(item1);
2829
+
2830
+ expect(calculatedItem).toHaveProperty('total', 0);
2831
+ expect(calculatedItem).toHaveProperty('subTotals', {
2832
+ _actual: 10,
2833
+ _direct: 0,
2834
+ _included: 0,
2835
+ _simple: 10,
2836
+ _xdirect: -10,
2837
+ _xincluded: -10,
2838
+ discount: -10,
2839
+ });
2840
+ expect(calculatedItem).toHaveProperty('total', 0);
2841
+ expect(calculatedItem.modifiers[0]).toHaveProperty('_computed', {
2842
+ amount: -10,
2843
+ description: '100% discount (-$10.00)',
2844
+ });
2845
+
2846
+ expect(calculatedItem.modifiers[1]).toHaveProperty('_computed', {
2847
+ amount: -0,
2848
+ description: '100% discount',
2849
+ });
2850
+ });
2851
+
2852
+ test('CU-861n7pum9 - Calculate order -> discountMod100Fixed qt=2', () => {
2853
+ const discountMod100Fixed = {
2854
+ _id: 1,
2855
+ compute: {
2856
+ amount: 100,
2857
+ type: 'fixed',
2858
+ action: 'subtract',
2859
+ },
2860
+ name: `100 USD discount`,
2861
+ type: 'discount',
2862
+ };
2863
+
2864
+ const item1 = {
2865
+ _id: 1,
2866
+ price: 10,
2867
+ quantity: 2,
2868
+ modifiers: [discountMod100Fixed, discountMod100Fixed],
2869
+ };
2870
+
2871
+ const calculatedItem = pricingService.item.calculate(item1);
2872
+
2873
+ expect(calculatedItem).toHaveProperty('total', 0);
2874
+ expect(calculatedItem).toHaveProperty('subTotals', {
2875
+ _actual: 20,
2876
+ _direct: 0,
2877
+ _included: 0,
2878
+ _simple: 20,
2879
+ _xdirect: -20,
2880
+ _xincluded: -20,
2881
+ discount: -20,
2882
+ });
2883
+ expect(calculatedItem).toHaveProperty('total', 0);
2884
+ expect(calculatedItem.modifiers[0]).toHaveProperty('_computed', {
2885
+ amount: -20,
2886
+ description: '100 USD discount (-$20.00)',
2887
+ });
2888
+
2889
+ expect(calculatedItem.modifiers[1]).toHaveProperty('_computed', {
2890
+ amount: -0,
2891
+ description: '100 USD discount',
2892
+ });
2893
+ });
2894
+
2895
+ test('CU-861n7pum9 - Calculate order -> discountMod100Percentage qt=1', () => {
2896
+ const discountMod100Percentage = {
2897
+ _id: 1,
2898
+ compute: {
2899
+ amount: 100,
2900
+ type: 'percentage',
2901
+ action: 'subtract',
2902
+ },
2903
+ name: `100% discount`,
2904
+ type: 'discount',
2905
+ properties: {
2906
+ isQuantityMultiplier: true,
2907
+ },
2908
+ };
2909
+
2910
+ const item1 = {
2911
+ _id: 1,
2912
+ price: 10,
2913
+ quantity: 2,
2914
+ modifiers: [discountMod100Percentage, discountMod100Percentage],
2915
+ };
2916
+
2917
+ const calculatedItem = pricingService.item.calculate(item1);
2918
+
2919
+ expect(calculatedItem).toHaveProperty('total', 0);
2920
+ expect(calculatedItem).toHaveProperty('subTotals', {
2921
+ _actual: 20,
2922
+ _direct: 0,
2923
+ _included: 0,
2924
+ _simple: 20,
2925
+ _xdirect: -20,
2926
+ _xincluded: -20,
2927
+ discount: -20,
2928
+ });
2929
+ expect(calculatedItem).toHaveProperty('total', 0);
2930
+ expect(calculatedItem.modifiers[0]).toHaveProperty('_computed', {
2931
+ amount: -20,
2932
+ description: '100% discount (-$20.00)',
2933
+ });
2934
+
2935
+ expect(calculatedItem.modifiers[1]).toHaveProperty('_computed', {
2936
+ amount: -0,
2937
+ description: '100% discount',
2938
+ });
2939
+ });
2940
+
2941
+ test('CU-861n7pum9 - Calculate order -> discountMod100Percentage discountMod100Fixed qt=2', () => {
2942
+ const discountMod100Percentage = {
2943
+ _id: 1,
2944
+ compute: {
2945
+ amount: 100,
2946
+ type: 'percentage',
2947
+ action: 'subtract',
2948
+ },
2949
+ name: `100% discount`,
2950
+ type: 'discount',
2951
+ properties: {
2952
+ isQuantityMultiplier: true,
2953
+ },
2954
+ };
2955
+
2956
+ const discountMod100Fixed = {
2957
+ _id: 1,
2958
+ compute: {
2959
+ amount: 100,
2960
+ type: 'fixed',
2961
+ action: 'subtract',
2962
+ },
2963
+ name: `100 USD discount`,
2964
+ type: 'discount',
2965
+ };
2966
+
2967
+ const item1 = {
2968
+ _id: 1,
2969
+ price: 10,
2970
+ quantity: 2,
2971
+ modifiers: [
2972
+ discountMod100Percentage,
2973
+ discountMod100Fixed,
2974
+ discountMod100Percentage,
2975
+ discountMod100Fixed,
2976
+ ],
2977
+ };
2978
+
2979
+ const calculatedItem = pricingService.item.calculate(item1);
2980
+
2981
+ expect(calculatedItem).toHaveProperty('total', 0);
2982
+ expect(calculatedItem).toHaveProperty('subTotals', {
2983
+ _actual: 20,
2984
+ _direct: 0,
2985
+ _included: 0,
2986
+ _simple: 20,
2987
+ _xdirect: -20,
2988
+ _xincluded: -20,
2989
+ discount: -20,
2990
+ });
2991
+ expect(calculatedItem).toHaveProperty('total', 0);
2992
+ expect(calculatedItem.modifiers[0]).toHaveProperty('_computed', {
2993
+ amount: -20,
2994
+ description: '100% discount (-$20.00)',
2995
+ });
2996
+
2997
+ expect(calculatedItem.modifiers[1]).toHaveProperty('_computed', {
2998
+ amount: -0,
2999
+ description: '100 USD discount',
3000
+ });
3001
+ });
3002
+
3003
+ test('CU-861n7pum9 - Calculate order -> discountMod60Percentage discountMod100Fixed, sort, qt=2', () => {
3004
+ const discountMod60Percentage = {
3005
+ _id: 1,
3006
+ compute: {
3007
+ amount: 60,
3008
+ type: 'percentage',
3009
+ action: 'subtract',
3010
+ },
3011
+ name: `60% discount`,
3012
+ type: 'discount',
3013
+ properties: {
3014
+ sort: 3,
3015
+ isQuantityMultiplier: true,
3016
+ },
3017
+ };
3018
+
3019
+ const discountMod100Fixed = {
3020
+ _id: 1,
3021
+ compute: {
3022
+ amount: 100,
3023
+ type: 'fixed',
3024
+ action: 'subtract',
3025
+ },
3026
+ name: `100 USD discount`,
3027
+ type: 'discount',
3028
+ properties: {
3029
+ sort: 4,
3030
+ },
3031
+ };
3032
+
3033
+ const item1 = {
3034
+ _id: 1,
3035
+ price: 10,
3036
+ quantity: 2,
3037
+ modifiers: [discountMod60Percentage, discountMod100Fixed],
3038
+ };
3039
+
3040
+ const calculatedItem = pricingService.item.calculate(item1);
3041
+
3042
+ expect(calculatedItem).toHaveProperty('total', 0);
3043
+ expect(calculatedItem).toHaveProperty('subTotals', {
3044
+ _actual: 20,
3045
+ _direct: 0,
3046
+ _included: 0,
3047
+ _simple: 20,
3048
+ _xdirect: -20,
3049
+ _xincluded: -20,
3050
+ discount: -20,
3051
+ });
3052
+ expect(calculatedItem).toHaveProperty('total', 0);
3053
+ expect(calculatedItem.modifiers[0]).toHaveProperty('_computed', {
3054
+ amount: -12,
3055
+ description: '60% discount (-$12.00)',
3056
+ });
3057
+
3058
+ expect(calculatedItem.modifiers[1]).toHaveProperty('_computed', {
3059
+ amount: -8,
3060
+ description: '100 USD discount (-$8.00)',
3061
+ });
3062
+ });
3063
+
3064
+ test('CU-861n7pum9 - Calculate order -> discountMod9Fixed , sort, qt=2', () => {
3065
+ const discountMod9Fixed = {
3066
+ _id: 1,
3067
+ compute: {
3068
+ amount: 12,
3069
+ type: 'fixed',
3070
+ action: 'subtract',
3071
+ },
3072
+ name: `12 USD discount`,
3073
+ type: 'discount',
3074
+ properties: {
3075
+ isQuantityMultiplier: true,
3076
+ },
3077
+ };
3078
+
3079
+ const item1 = {
3080
+ _id: 1,
3081
+ price: 10,
3082
+ quantity: 2,
3083
+ modifiers: [discountMod9Fixed, discountMod9Fixed],
3084
+ };
3085
+
3086
+ const calculatedItem = pricingService.item.calculate(item1);
3087
+
3088
+ expect(calculatedItem).toHaveProperty('total', 0);
3089
+ expect(calculatedItem).toHaveProperty('subTotals', {
3090
+ _actual: 20,
3091
+ _direct: 0,
3092
+ _included: 0,
3093
+ _simple: 20,
3094
+ _xdirect: -20,
3095
+ _xincluded: -20,
3096
+ discount: -20,
3097
+ });
3098
+ expect(calculatedItem).toHaveProperty('total', 0);
3099
+ expect(calculatedItem.modifiers[0]).toHaveProperty('_computed', {
3100
+ amount: -20,
3101
+ description: '12 USD discount (-$20.00)',
3102
+ });
3103
+
3104
+ expect(calculatedItem.modifiers[1]).toHaveProperty('_computed', {
3105
+ amount: -0,
3106
+ description: '12 USD discount',
3107
+ });
3108
+ });
2664
3109
  });
@@ -50,7 +50,7 @@ module.exports = ({ utils, modifierActions, _ }) => {
50
50
  },
51
51
  properties: {
52
52
  ...inheritedModifier.properties,
53
- ignoreQuantity: true,
53
+ isQuantityMultiplier: false,
54
54
  },
55
55
  };
56
56
  }
@@ -1,5 +1,3 @@
1
- const { getComputeModField } = require('../modifier/utils');
2
-
3
1
  /* eslint-disable no-restricted-syntax */
4
2
  module.exports = ({ _, utils, actions, modifierActions }) => {
5
3
  const { math } = utils;
@@ -94,6 +92,9 @@ module.exports = ({ _, utils, actions, modifierActions }) => {
94
92
  })
95
93
  );
96
94
 
95
+ let computedPrice = price;
96
+ let total = math.mul(computedPrice, quantity);
97
+
97
98
  if (modifiersToCompute.length || paymentModifiersToCompute.length) {
98
99
  // sort modifiers based on sort
99
100
  const sortedModifiers = modifierActions.sort([
@@ -101,7 +102,6 @@ module.exports = ({ _, utils, actions, modifierActions }) => {
101
102
  ...paymentModifiersToCompute,
102
103
  ]);
103
104
 
104
- let computedPrice = price;
105
105
  let prvPrice = 0;
106
106
  let prvSort;
107
107
 
@@ -138,6 +138,7 @@ module.exports = ({ _, utils, actions, modifierActions }) => {
138
138
  price: computedPrice,
139
139
  quantity,
140
140
  basePrice: actions.getBasePrice(item),
141
+ maxDiscountAmount: total,
141
142
  }
142
143
  );
143
144
 
@@ -150,29 +151,7 @@ module.exports = ({ _, utils, actions, modifierActions }) => {
150
151
 
151
152
  const { type, _computed } = _modifier;
152
153
 
153
- const computedAmountCalc = math.mul(_computed.amount, quantity);
154
- const computedPriceCalc = math.mul(computedPrice * quantity);
155
-
156
- // adding this computeField because now the compute from a modifier can be null
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
-
169
- let computedAmount =
170
- isPercentage ||
171
- isIgnoreQuantity ||
172
- isNotFixedAddAndAmountGtPrice ||
173
- isAmountOverrideAndNotMultiplier
174
- ? _computed.amount
175
- : computedAmountCalc;
154
+ let computedAmount = _computed.amount;
176
155
 
177
156
  // subscription modifiers have fixed amount and can't be multiplied by quantity
178
157
  if (modifierActions.isSubscription(_modifier))
@@ -190,12 +169,15 @@ module.exports = ({ _, utils, actions, modifierActions }) => {
190
169
  if (direct)
191
170
  subTotals._direct = math.add(subTotals._direct, computedAmount);
192
171
  else subTotals._xdirect = math.add(subTotals._xdirect, computedAmount);
172
+
173
+ subTotals._actual = math.add(subTotals._simple, subTotals._included);
174
+ total = actions.getTotal({ subTotals });
193
175
  }
194
176
  }
195
177
 
196
178
  subTotals._actual = math.add(subTotals._simple, subTotals._included);
197
179
 
198
- const total = actions.getTotal({ subTotals });
180
+ total = actions.getTotal({ subTotals });
199
181
 
200
182
  return {
201
183
  ...item,
@@ -14,12 +14,14 @@ module.exports = ({ _, constants, utils, localization, actions }) => {
14
14
  const modifier = _modifier;
15
15
  const { name } = modifier;
16
16
  const compute = getComputeModField(modifier);
17
- const { type, action, amount = 0 } = compute;
17
+ const { type, amount: computeAmount = 0 } = compute;
18
18
  const _computed = {
19
19
  amount: 0,
20
20
  description: '',
21
21
  };
22
22
 
23
+ const amount = computeAmount;
24
+
23
25
  const maxAmountProp = actions.getProperty(modifier, 'maxAmount');
24
26
 
25
27
  if (!options.skip) {
@@ -32,22 +34,41 @@ module.exports = ({ _, constants, utils, localization, actions }) => {
32
34
  ? math.min(maxAmountProp, maxAmountCalc)
33
35
  : maxAmountCalc;
34
36
 
35
- const multiplier = action === Modifier.Compute.Actions.SUBTRACT ? -1 : 1;
37
+ const multiplier = actions.isSubtract(_modifier) ? -1 : 1;
36
38
 
37
- if (type === Modifier.Compute.Types.FIXED)
39
+ if (type === Modifier.Compute.Types.FIXED) {
38
40
  _computed.amount = math.mul(multiplier, amount);
41
+ }
39
42
 
40
- if (type === Modifier.Compute.Types.PERCENTAGE)
43
+ if (type === Modifier.Compute.Types.PERCENTAGE) {
41
44
  _computed.amount = math.div(
42
- math.mul(multiplier, options.price, options.quantity, amount),
45
+ math.mul(multiplier, options.price, amount),
43
46
  100
44
47
  );
48
+ }
45
49
 
46
50
  if (!type) _computed.amount = 0;
47
51
 
48
52
  if (math.gt(math.abs(_computed.amount), maxAmount)) {
49
53
  _computed.amount = maxAmount * multiplier;
50
54
  }
55
+
56
+ if (
57
+ (!actions.isOverride(_modifier) &&
58
+ actions.isQuantityMultiplier(_modifier)) ||
59
+ (actions.isAmountOverride(_modifier) && actions.isMultiplier(_modifier))
60
+ ) {
61
+ _computed.amount = math.mul(_computed.amount, options.quantity);
62
+ }
63
+
64
+ if (
65
+ actions.isSubtract(_modifier) &&
66
+ typeof _computed.amount === 'number' &&
67
+ typeof options.maxDiscountAmount === 'number' &&
68
+ math.gt(math.abs(_computed.amount), options.maxDiscountAmount)
69
+ ) {
70
+ _computed.amount = math.mul(options.maxDiscountAmount, -1);
71
+ }
51
72
  }
52
73
 
53
74
  const localAmount =
@@ -71,7 +92,7 @@ module.exports = ({ _, constants, utils, localization, actions }) => {
71
92
 
72
93
  if (actions.isAmountOverride(modifier) && isMultiplier) {
73
94
  _computed.description = `${name} (${localization.formatAmount(
74
- math.mul(_computed.amount, options.quantity)
95
+ _computed.amount
75
96
  )})`;
76
97
  }
77
98
 
@@ -19,7 +19,7 @@ module.exports = ({ constants, actions, localization }) => {
19
19
  type: Modifier.Types.FEE,
20
20
  name: `${name} ${Modifier.Types.FEE}`,
21
21
  properties: {
22
- ignoreQuantity: true,
22
+ isQuantityMultiplier: false,
23
23
  ...properties,
24
24
  },
25
25
  ...rest,
@@ -36,10 +36,9 @@ module.exports = ({ _, utils, constants, actions }) => {
36
36
  !math.isZero(options.orderTotal) &&
37
37
  (type !== Modifier.Compute.Types.PERCENTAGE || modifier.type === 'credit')
38
38
  ) {
39
- const modififierQuantity =
40
- modifier.properties && modifier.properties.ignoreQuantity
41
- ? 1
42
- : options.itemQuantity;
39
+ const modififierQuantity = !actions.isQuantityMultiplier(modifier)
40
+ ? 1
41
+ : options.itemQuantity;
43
42
 
44
43
  amountToApply = math.div(
45
44
  math.mul(modifierAmount, options.itemTotal),
@@ -57,10 +56,10 @@ module.exports = ({ _, utils, constants, actions }) => {
57
56
  action: compute.action || Modifier.Compute.Actions.SUBTRACT,
58
57
  },
59
58
  properties: {
60
- ignoreQuantity:
61
- (modifier.properties && modifier.properties.ignoreQuantity) ||
62
- type === Modifier.Compute.Types.PERCENTAGE,
63
59
  ...(modifier.properties || {}),
60
+ isQuantityMultiplier:
61
+ type !== Modifier.Compute.Types.PERCENTAGE &&
62
+ actions.isQuantityMultiplier(modifier),
64
63
  },
65
64
  });
66
65
  if (maxAmount !== null) delete modifierToAdd.properties.maxAmount;
@@ -103,7 +103,6 @@ const isAmountOverride = require('./isAmountOverride');
103
103
  const isValid = require('./isValid');
104
104
  const isDiscount = require('./isDiscount');
105
105
  const isHidden = require('./isHidden');
106
- const isIgnoreQuantity = require('./isIgnoreQuantity');
107
106
  const isGratuity = require('./isGratuity');
108
107
  const isPaymentMethodModifier = require('./isPaymentMethodModifier');
109
108
  const isPaymentTypeModifier = require('./isPaymentTypeModifier');
@@ -148,6 +147,8 @@ const isExtractCalculatedValue = require('./isExtractCalculatedValue');
148
147
  const getPriceWithoutModifier = require('./getPriceWithoutModifier');
149
148
  const isGroup = require('./isGroup');
150
149
  const isOptionsSelectedOverride = require('./isOptionsSelectedOverride');
150
+ const isFixedSubtract = require('./isFixedSubtract');
151
+ const isQuantityMultiplier = require('./isQuantityMultiplier');
151
152
 
152
153
  const modifierActions = (deps = {}) => {
153
154
  const actions = {};
@@ -262,7 +263,6 @@ const modifierActions = (deps = {}) => {
262
263
  isValid: isValid(innerDeps),
263
264
  isDiscount: isDiscount(innerDeps),
264
265
  isHidden: isHidden(innerDeps),
265
- isIgnoreQuantity: isIgnoreQuantity(innerDeps),
266
266
  isGratuity: isGratuity(innerDeps),
267
267
  isPaymentMethodModifier: isPaymentMethodModifier(innerDeps),
268
268
  isPaymentTypeModifier: isPaymentTypeModifier(innerDeps),
@@ -309,6 +309,8 @@ const modifierActions = (deps = {}) => {
309
309
  getPriceWithoutModifier: getPriceWithoutModifier(innerDeps),
310
310
  isGroup: isGroup(innerDeps),
311
311
  isOptionsSelectedOverride: isOptionsSelectedOverride(innerDeps),
312
+ isFixedSubtract: isFixedSubtract(innerDeps),
313
+ isQuantityMultiplier: isQuantityMultiplier(innerDeps),
312
314
  });
313
315
 
314
316
  Object.keys(freezedActions).forEach(actionName => {
@@ -0,0 +1,4 @@
1
+ module.exports = ({ actions }) =>
2
+ function isFixedSubtract(modifier) {
3
+ return actions.isSubtract(modifier) && actions.isFixed(modifier);
4
+ };
@@ -0,0 +1,5 @@
1
+ module.exports = () =>
2
+ function isQuantityMultiplier(modifier) {
3
+ if (!modifier || !modifier.properties) return false;
4
+ return !!modifier.properties.isQuantityMultiplier;
5
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@darkpos/pricing",
3
- "version": "1.0.53",
3
+ "version": "1.0.54",
4
4
  "description": "Pricing calculator",
5
5
  "author": "Dark POS",
6
6
  "license": "ISC",
@@ -19,6 +19,7 @@
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
21
  "test:getModifierTags": "jest --runInBand --detectOpenHandles --logHeapUsage --forceExit ./__TEST__/item/getModifierTags.test.js",
22
+ "test:createIndirectModifier": "jest --runInBand --detectOpenHandles --logHeapUsage --forceExit ./__TEST__/modifier/createIndirectModifier.test.js",
22
23
  "lint": "eslint --quiet lib/"
23
24
  },
24
25
  "publishConfig": {
@@ -42,5 +43,5 @@
42
43
  "supertest": "^6.2.3",
43
44
  "supervisor": "^0.12.0"
44
45
  },
45
- "gitHead": "ad5528b8430430e2a34e124218dc4ac1d3da1681"
46
+ "gitHead": "8bba2c9f52f54528ea2d0dece82406ef9fe69cb3"
46
47
  }
@@ -1,5 +0,0 @@
1
- module.exports = () =>
2
- function isIgnoreQuantity(modifier) {
3
- if (!modifier || !modifier.properties) return false;
4
- return modifier.properties.ignoreQuantity;
5
- };