@darkpos/pricing 1.0.93 → 1.0.95

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.
Files changed (34) hide show
  1. package/__TEST__/item.test.js +46 -48
  2. package/__TEST__/modifier/addItemModifier.test.js +181 -60
  3. package/__TEST__/modifier/overrideModifiers.test.js +196 -0
  4. package/__TEST__/order/order-payment-modifier.test.js +3 -11
  5. package/lib/item/calculate.js +66 -18
  6. package/lib/item/getItemPrice.js +1 -12
  7. package/lib/item/getPriceWithoutModifiers.js +7 -5
  8. package/lib/item/index.js +6 -0
  9. package/lib/item/isOverwrittenPrice.js +4 -0
  10. package/lib/item/isOverwrittenQuantity.js +4 -0
  11. package/lib/item/overrideNotes.js +24 -0
  12. package/lib/item/removeModifier.js +1 -22
  13. package/lib/item/removeModifiers.js +1 -2
  14. package/lib/modifier/areConditionsMet.js +1 -1
  15. package/lib/modifier/calculate.js +20 -2
  16. package/lib/modifier/createDescription.js +1 -1
  17. package/lib/modifier/duplicate.js +3 -0
  18. package/lib/modifier/getOverrideAmount.js +7 -0
  19. package/lib/modifier/getOverrideNote.js +5 -0
  20. package/lib/modifier/getServiceOverride.js +5 -0
  21. package/lib/modifier/index.js +18 -12
  22. package/lib/modifier/{isManual.js → isManualOverride.js} +1 -1
  23. package/lib/modifier/{isMultiplier.js → isMultiplierOverride.js} +1 -1
  24. package/lib/modifier/isNotesOverride.js +7 -0
  25. package/lib/modifier/isOverrideSubtotal.js +9 -0
  26. package/lib/modifier/{isService.js → isServiceOverride.js} +1 -1
  27. package/lib/modifier/isTotalOverride.js +7 -0
  28. package/lib/order/addItem.js +10 -12
  29. package/lib/order/addItemModifier.js +15 -62
  30. package/lib/order/removeItemModifier.js +2 -27
  31. package/package.json +4 -2
  32. package/lib/modifier/createAmountOverrideModifier.js +0 -18
  33. package/lib/modifier/getService.js +0 -5
  34. package/lib/modifier/mutateModifier.js +0 -23
@@ -648,7 +648,6 @@ describe('Item actions', () => {
648
648
  multiplier: true,
649
649
  },
650
650
  },
651
- compute: { type: 'fixed', amount: 10, action: 'add' },
652
651
  },
653
652
  ],
654
653
  _id: '675354e939a47228afd1f199',
@@ -679,60 +678,43 @@ describe('Item actions', () => {
679
678
  });
680
679
 
681
680
  test('CU-86dvbn63z: Calculate item with quantity > 1 and quantity override modifier', () => {
681
+ const quantityOverrideMod = {
682
+ _id: '67535f3ab4c5ea63d2d7964b',
683
+ attributes: ['override'],
684
+ modifierId: '675359b5d08f91f558233f85',
685
+ name: 'Override Item Quantity 5',
686
+ group: 'Upcharge',
687
+ type: 'tax',
688
+ tags: ['default'],
689
+ direct: true,
690
+ properties: {
691
+ subscription: {},
692
+ override: { type: 'fixed', field: 'quantity', fixedValue: 5 },
693
+ group: { items: [], modifiers: [] },
694
+ department: {},
695
+ sort: null,
696
+ },
697
+ compute: null,
698
+ };
682
699
  const itemWithQuantityOverride5 = {
683
700
  name: "Men's 3pc Tuxedo",
684
701
  pieces: 3,
685
702
  total: 70.88,
686
703
  price: 13.5,
687
- quantity: 5,
688
- modifiers: [
689
- {
690
- _id: '67535f3ab4c5ea63d2d7964b',
691
- attributes: ['override'],
692
- modifierId: '675359b5d08f91f558233f85',
693
- _parentId: null,
694
- locked: false,
695
- name: 'Override Item Quantity 5',
696
- sku: '',
697
- description: '',
698
- group: 'Upcharge',
699
- type: 'tax',
700
- tags: ['default'],
701
- order: 0,
702
- included: false,
703
- direct: true,
704
- hidden: false,
705
- print: true,
706
- required: false,
707
- recommended: false,
708
- default: false,
709
- code: '',
710
- properties: {
711
- subscription: {},
712
- override: { type: 'fixed', field: 'quantity', fixedValue: 5 },
713
- group: { items: [], modifiers: [] },
714
- department: {},
715
- sort: null,
716
- },
717
- _computed: { amount: 0, description: 'Override Item Quantity 5' },
718
- addModifiers: [],
719
- delModifiers: [],
720
- conditions: { valid: true },
721
- compute: null,
722
- _createdAt: '2024-12-06T20:08:21.409Z',
723
- _updatedAt: '2024-12-06T20:18:37.174Z',
724
- },
725
- ],
704
+ quantity: 3,
705
+ modifiers: [quantityOverrideMod],
726
706
  _id: '67535f34b4c5ea63d2d79640',
727
707
  properties: { basePrice: 13.5 },
728
708
  itemId: '62cdbfd01ee1b400193281ee',
729
709
  menuRuleId: '65660855dfffaf2da26fb870',
730
710
  __typename: 'OrderItem',
731
711
  };
732
- const newItem = pricingService.item.calculate(itemWithQuantityOverride5);
712
+ let newItem = pricingService.item.calculate(itemWithQuantityOverride5);
733
713
 
734
714
  expect(newItem).toHaveProperty('total', 67.5);
735
715
  expect(newItem).toHaveProperty('price', 13.5);
716
+ expect(newItem).toHaveProperty('quantity', 5);
717
+
736
718
  expect(newItem.modifiers[0]).toHaveProperty('_computed', {
737
719
  amount: 0,
738
720
  description: 'Override Item Quantity 5',
@@ -746,6 +728,29 @@ describe('Item actions', () => {
746
728
  _simple: 67.5,
747
729
  _actual: 67.5,
748
730
  });
731
+
732
+ newItem = pricingService.item.calculate(
733
+ pricingService.item.removeModifiers({
734
+ item: newItem,
735
+ modifiers: [quantityOverrideMod],
736
+ customer: undefined,
737
+ order: { items: [newItem] },
738
+ })
739
+ );
740
+ expect(newItem.price).toBe(13.5);
741
+ expect(newItem.total).toBe(40.5);
742
+ expect(newItem.quantity).toBe(3);
743
+
744
+ expect(newItem.modifiers.length).toBe(0);
745
+
746
+ expect(newItem).toHaveProperty('subTotals', {
747
+ _included: 0,
748
+ _xincluded: 0,
749
+ _direct: 0,
750
+ _xdirect: 0,
751
+ _simple: 40.5,
752
+ _actual: 40.5,
753
+ });
749
754
  });
750
755
 
751
756
  test('CU-86dvbn63z: Calculate item with quantity > 1 and modifieritemPriceFixed10', () => {
@@ -772,7 +777,6 @@ describe('Item actions', () => {
772
777
  multiplier: false,
773
778
  },
774
779
  },
775
- compute: { type: 'fixed', amount: 10, action: 'add' },
776
780
  },
777
781
  ],
778
782
  _id: '675354e939a47228afd1f199',
@@ -830,12 +834,6 @@ describe('Item actions', () => {
830
834
  multiplier: true,
831
835
  },
832
836
  },
833
- _computed: {
834
- amount: 0,
835
- description:
836
- 'Override Item Price 10 USD Multiplier (10 Unit @ $13.50/Unit)',
837
- },
838
- compute: { amount: 10 },
839
837
  },
840
838
  ],
841
839
  _id: '675360d5bc57ccecf751a5b5',
@@ -1,96 +1,217 @@
1
+ const usePricing = require('../../index');
2
+ const mockStores = require('../mocks/stores');
3
+
1
4
  const addItemMock = require('./mocks/addItemModifierMock.json');
2
5
  const orderMock = require('./mocks/orderMock.json');
3
- const usePricing = require('../../index');
4
6
 
5
- const pricingService = usePricing();
7
+ const session = {
8
+ store: mockStores[0],
9
+ };
10
+
11
+ const pricingService = usePricing(session);
6
12
 
7
13
  describe('addItemModifier Function', () => {
8
- test('Add an override price modifier to the item', () => {
9
- let { order } = addItemMock;
10
- const { modifier2, itemIndex } = addItemMock;
11
-
12
- /**
13
- * modifier2 properties
14
- * "override": {
15
- "field": "price",
16
- "type": "fixed",
17
- "multiplier": null,
18
- "fixedValue": 40
19
- },
20
- */
14
+ const priceOverrideModifier = {
15
+ _id: '66ec3e3efe02e7ee35f595be',
16
+ attributes: ['override'],
17
+ modifierId: '66ec3e3efe02e7ee35f595be',
18
+ _parentId: null,
19
+ locked: false,
20
+ name: 'Price Override 40',
21
+ direct: true,
22
+ properties: {
23
+ override: {
24
+ field: 'price',
25
+ type: 'fixed',
26
+ multiplier: null,
27
+ fixedValue: 40,
28
+ },
29
+ },
30
+ };
31
+ const amountOverrideModifier = {
32
+ _id: '66ec3e3efe02e7ee35f595bd',
33
+ attributes: ['override'],
34
+ modifierId: '66ec3e3efe02e7ee35f595bd',
35
+ name: 'Amount Override 20',
36
+ sku: '123123',
37
+ tags: ['default'],
38
+ order: 2,
39
+ direct: true,
40
+ properties: {
41
+ override: {
42
+ field: 'amount',
43
+ type: 'fixed',
44
+ fixedValue: 20,
45
+ },
46
+ },
47
+ };
48
+
49
+ const baseItem = {
50
+ name: 'Andre Pants',
51
+ pieces: 1,
52
+ total: 2,
53
+ totalPaid: 0,
54
+ price: 2,
55
+ quantity: 1,
56
+ _id: '66ec759cd57e32c3455724a0',
57
+ modifiers: [],
58
+ priceLevels: [
59
+ {
60
+ value: 10,
61
+ tags: ['default'],
62
+ },
63
+ {
64
+ value: 2,
65
+ tags: ['vip'],
66
+ },
67
+ {
68
+ value: 10,
69
+ tags: ['default', 'press only'],
70
+ },
71
+ {
72
+ value: 2,
73
+ tags: ['vip', 'press only'],
74
+ },
75
+ ],
76
+ };
77
+ test('Add an override price modifier to an item, change the quantity and then remove the modifier', () => {
78
+ let order = {
79
+ _id: '66ec7594d57e32c34557249f',
80
+ customer: {
81
+ _id: '66bb8d1e38ebaee653177a92',
82
+ tags: ['default', 'vip'],
83
+ },
84
+ };
85
+
86
+ order = pricingService.order.addItem({
87
+ order,
88
+ item: baseItem,
89
+ }).updatedOrder;
90
+
21
91
  order = pricingService.order.addItemModifier({
22
92
  order,
23
- modifier: modifier2,
24
- itemIndex,
93
+ modifier: priceOverrideModifier,
94
+ itemIndex: 0,
25
95
  });
26
96
 
27
- const calculatedOrder = pricingService.order.calculate({
97
+ order = pricingService.order.calculate({
28
98
  ...order,
29
- items: order.items,
30
99
  });
31
100
 
32
- const item0 = calculatedOrder.items[0];
33
- // Check that the modifier adds the correct fixed amount
34
- expect(item0.price).toBe(40);
101
+ expect(order.items[0].price).toBe(40);
102
+ expect(order.items[0].total).toBe(40);
103
+ expect(order.items[0].subTotals).toMatchObject({
104
+ _actual: 40,
105
+ _direct: 0,
106
+ _included: 0,
107
+ _simple: 40,
108
+ _xdirect: 0,
109
+ _xincluded: 0,
110
+ });
111
+
112
+ order = pricingService.order.calculate({
113
+ ...order,
114
+ items: [{ ...order.items[0], quantity: 2 }],
115
+ });
116
+
117
+ expect(order.items[0].price).toBe(40);
118
+ expect(order.items[0].total).toBe(80);
119
+ expect(order.items[0].subTotals).toMatchObject({
120
+ _actual: 80,
121
+ _direct: 0,
122
+ _included: 0,
123
+ _simple: 80,
124
+ _xdirect: 0,
125
+ _xincluded: 0,
126
+ });
127
+
128
+ const calculatedItem = pricingService.item.calculate(
129
+ pricingService.item.removeModifier({
130
+ item: order.items[0],
131
+ modifier: order.items[0].modifiers[0],
132
+ order,
133
+ })
134
+ );
135
+
136
+ expect(calculatedItem.price).toBe(2);
137
+ expect(calculatedItem.total).toBe(4);
138
+ expect(calculatedItem.subTotals).toMatchObject({
139
+ _actual: 4,
140
+ _direct: 0,
141
+ _included: 0,
142
+ _simple: 4,
143
+ _xdirect: 0,
144
+ _xincluded: 0,
145
+ });
35
146
  });
36
147
  test('Add an override amount to the item', () => {
37
- let { order } = addItemMock;
38
- const { modifier1, itemIndex } = addItemMock;
39
-
40
- /**
41
- * modifier2 properties
42
- "override": {
43
- "field": "amount",
44
- "type": "fixed",
45
- "multiplier": null,
46
- "fixedValue": 20
47
- },
48
- */
148
+ let order = {
149
+ _id: '66ec7594d57e32c34557249f',
150
+ customer: {
151
+ _id: '66bb8d1e38ebaee653177a92',
152
+ tags: ['default', 'vip'],
153
+ },
154
+ };
155
+
156
+ order = pricingService.order.addItem({
157
+ order,
158
+ item: baseItem,
159
+ }).updatedOrder;
160
+
49
161
  order = pricingService.order.addItemModifier({
50
162
  order,
51
- modifier: modifier1,
52
- itemIndex,
163
+ modifier: amountOverrideModifier,
164
+ itemIndex: 0,
53
165
  });
54
166
 
55
- const calculatedOrder = pricingService.order.calculate({
56
- ...order,
57
- items: order.items,
58
- });
59
- const item0 = calculatedOrder.items[0];
167
+ const calculatedOrder = pricingService.order.calculate(order);
60
168
 
61
- // The item price shouldn't change
62
- expect(item0.price).toBe(2);
169
+ expect(calculatedOrder.items[0].price).toBe(2);
170
+ expect(calculatedOrder.items[0].total).toBe(22);
171
+ expect(calculatedOrder.items[0].modifiers[0].compute).toMatchObject({});
172
+ expect(calculatedOrder.items[0].modifiers[0]._computed).toMatchObject({
173
+ amount: 20,
174
+ description: 'Amount Override 20 ($20.00)',
175
+ });
63
176
 
64
- // expect the modifier compute amount to match the item
65
- expect(item0.modifiers[0].compute.amount).toBe(20);
177
+ expect(calculatedOrder.items[0].modifiers[0]._computed.amount).toBe(20);
66
178
  });
67
179
  test('Add an override amount and override at the same time to the item', () => {
68
- let { order } = addItemMock;
69
- const { modifier1, modifier2, itemIndex } = addItemMock;
180
+ let order = {
181
+ _id: '66ec7594d57e32c34557249f',
182
+ customer: {
183
+ _id: '66bb8d1e38ebaee653177a92',
184
+ tags: ['default', 'vip'],
185
+ },
186
+ };
187
+
188
+ order = pricingService.order.addItem({
189
+ order,
190
+ item: baseItem,
191
+ }).updatedOrder;
70
192
 
71
193
  order = pricingService.order.addItemModifier({
72
194
  order,
73
- modifier: modifier1,
74
- itemIndex,
195
+ modifier: amountOverrideModifier,
196
+ itemIndex: 0,
75
197
  });
76
198
 
77
199
  order = pricingService.order.addItemModifier({
78
200
  order,
79
- modifier: modifier2,
80
- itemIndex,
201
+ modifier: priceOverrideModifier,
202
+ itemIndex: 0,
81
203
  });
82
204
 
83
- const calculatedOrder = pricingService.order.calculate({
205
+ order = pricingService.order.calculate({
84
206
  ...order,
85
- items: order.items,
86
207
  });
87
- const item0 = calculatedOrder.items[0];
88
- // item price should match the price override
89
- expect(item0.price).toBe(40);
90
- // amount override should be 20
91
- expect(item0.modifiers[1].compute.amount).toBe(20);
92
- /// price override should be 40
93
- expect(item0.modifiers[0].compute.amount).toBe(40);
208
+
209
+ expect(order.items[0].price).toBe(40);
210
+ expect(order.items[0].modifiers[0].compute.amount).toBe(20);
211
+ expect(order.items[0].modifiers[0]._computed.amount).toBe(20);
212
+
213
+ expect(order.items[0].modifiers[1].compute.amount).toBe(40);
214
+ expect(order.items[0].modifiers[1]._computed.amount).toBe(0);
94
215
  });
95
216
 
96
217
  test('Verify item total after adding the modifier', () => {
@@ -0,0 +1,196 @@
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('Override Modifiers', () => {
11
+ test('Should calculate override modifier itemTotal: minimum $20 for up to 10 pounds, after 10 pounds it costs $2/pound. (having 8 pounds)', () => {
12
+ const itemTotalOverride20 = {
13
+ _id: '682cb7d9c48475c7215b662a',
14
+ name: 'Minimum $20 for up to 10 pounds',
15
+ properties: {
16
+ override: {
17
+ field: 'total',
18
+ type: 'fixed',
19
+ fixedValue: 20,
20
+ },
21
+ sort: null,
22
+ },
23
+ attributes: ['override'],
24
+ order: 0,
25
+ tags: ['default'],
26
+ direct: true,
27
+ conditions: {
28
+ valid: null,
29
+ rules: [
30
+ {
31
+ key: 'itemQuantity',
32
+ value: '10',
33
+ operand: '$lt',
34
+ },
35
+ ],
36
+ },
37
+ compute: null,
38
+ };
39
+
40
+ const orderItem1 = {
41
+ price: 2,
42
+ quantity: 8,
43
+ modifiers: [itemTotalOverride20],
44
+ };
45
+
46
+ const calculatedItem = pricingService.item.calculate(orderItem1);
47
+
48
+ expect(calculatedItem).toHaveProperty('total', 20);
49
+ expect(calculatedItem.modifiers[0]._computed).toMatchObject({
50
+ amount: 4,
51
+ description: 'Minimum $20 for up to 10 pounds ($4.00)',
52
+ });
53
+ expect(calculatedItem.modifiers[0].conditions.valid).toBe(true);
54
+ });
55
+
56
+ test('Should calculate override modifier itemTotal: minimum $20 for up to 10 pounds, after 10 pounds it costs $2/pound. (having 12 pounds)', () => {
57
+ const itemTotalOverride20 = {
58
+ _id: '682cb7d9c48475c7215b662a',
59
+ name: 'Minimum $20 for up to 10 pounds',
60
+ properties: {
61
+ override: {
62
+ field: 'total',
63
+ type: 'fixed',
64
+ fixedValue: 20,
65
+ },
66
+ sort: null,
67
+ },
68
+ attributes: ['override'],
69
+ order: 0,
70
+ tags: ['default'],
71
+ direct: true,
72
+ conditions: {
73
+ valid: null,
74
+ rules: [
75
+ {
76
+ key: 'itemQuantity',
77
+ value: '10',
78
+ operand: '$lt',
79
+ },
80
+ ],
81
+ },
82
+ compute: null,
83
+ };
84
+
85
+ const orderItem1 = {
86
+ price: 2,
87
+ quantity: 12,
88
+ modifiers: [itemTotalOverride20],
89
+ };
90
+
91
+ const calculatedItem = pricingService.item.calculate(orderItem1);
92
+
93
+ expect(calculatedItem).toHaveProperty('total', 24);
94
+ expect(calculatedItem.modifiers[0]._computed).toMatchObject({
95
+ amount: 0,
96
+ description: 'Minimum $20 for up to 10 pounds',
97
+ });
98
+ expect(calculatedItem.modifiers[0].conditions.valid).toBe(false);
99
+ });
100
+
101
+ test('Should Override Notes Modifier', () => {
102
+ const notesOverrideModifier = {
103
+ _id: '682cb7d9c48475c7215b662a',
104
+ name: 'Add Note',
105
+ properties: {
106
+ override: {
107
+ field: 'notes',
108
+ fixedValue: 'This is a note coming from an override modifier',
109
+ },
110
+ sort: null,
111
+ },
112
+ attributes: ['override'],
113
+ order: 0,
114
+ tags: ['default'],
115
+ direct: true,
116
+ conditions: {},
117
+ compute: null,
118
+ };
119
+
120
+ const orderItem1 = {
121
+ price: 2,
122
+ quantity: 8,
123
+ modifiers: [notesOverrideModifier],
124
+ };
125
+
126
+ const calculatedItem = pricingService.item.calculate(orderItem1);
127
+
128
+ expect(calculatedItem).toHaveProperty('total', 16);
129
+ expect(calculatedItem.notes).toMatchObject([
130
+ {
131
+ attributes: [],
132
+ date: undefined,
133
+ user: null,
134
+ message: 'This is a note coming from an override modifier',
135
+ },
136
+ ]);
137
+
138
+ expect(calculatedItem.modifiers[0]._computed).toMatchObject({
139
+ amount: 0,
140
+ description: 'Add Note',
141
+ });
142
+ expect(calculatedItem.modifiers[0].conditions.valid).toBe(true);
143
+ });
144
+
145
+ test('Should not Override Notes becuase of conditions', () => {
146
+ const notesOverrideModifier = {
147
+ _id: '682cb7d9c48475c7215b662a',
148
+ name: 'Add Note',
149
+ properties: {
150
+ override: {
151
+ field: 'notes',
152
+ fixedValue: 'This is a note coming from an override modifier',
153
+ },
154
+ sort: null,
155
+ },
156
+ attributes: ['override'],
157
+ order: 0,
158
+ tags: ['default'],
159
+ direct: true,
160
+ conditions: {
161
+ valid: false,
162
+ rules: [
163
+ {
164
+ key: 'paymentMethods',
165
+ value: ['cash-cash'],
166
+ operand: '$in',
167
+ },
168
+ {
169
+ key: 'paymentTypes',
170
+ value: ['cash'],
171
+ operand: '$in',
172
+ },
173
+ ],
174
+ },
175
+ compute: null,
176
+ };
177
+
178
+ const orderItem1 = {
179
+ price: 2,
180
+ quantity: 8,
181
+ modifiers: [notesOverrideModifier],
182
+ notes: ['hello world'],
183
+ };
184
+
185
+ const calculatedItem = pricingService.item.calculate(orderItem1);
186
+
187
+ expect(calculatedItem.total).toBe(16);
188
+ expect(calculatedItem.notes).toMatchObject(['hello world']);
189
+
190
+ expect(calculatedItem.modifiers[0]._computed).toMatchObject({
191
+ amount: 0,
192
+ description: 'Add Note',
193
+ });
194
+ expect(calculatedItem.modifiers[0].conditions.valid).toBe(false);
195
+ });
196
+ });
@@ -686,7 +686,7 @@ describe('Order actions', () => {
686
686
  modifiers: [
687
687
  {
688
688
  _id: '671818d40e5dd150d9830904',
689
- attributes: ['override'],
689
+ attributes: [],
690
690
  modifierId: '62cdbfd01ee1b4001932818f',
691
691
  _parentId: null,
692
692
  locked: null,
@@ -705,15 +705,7 @@ describe('Order actions', () => {
705
705
  recommended: false,
706
706
  default: false,
707
707
  code: '',
708
- properties: {
709
- override: {
710
- field: 'price',
711
- type: 'manual',
712
- multiplier: true,
713
- },
714
- group: null,
715
- sort: null,
716
- },
708
+ properties: {},
717
709
  _computed: {
718
710
  amount: 0,
719
711
  description: 'Alice Blue',
@@ -1093,7 +1085,7 @@ describe('Order actions', () => {
1093
1085
  expect(resultedOrder.items[0].modifiers[0]._computed).toEqual(
1094
1086
  expect.objectContaining({
1095
1087
  amount: 0,
1096
- description: 'Alice Blue (0 Unit @ $13.50/Unit)',
1088
+ description: 'Alice Blue',
1097
1089
  })
1098
1090
  );
1099
1091