@darkpos/pricing 1.0.28 → 1.0.30

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.
@@ -0,0 +1,197 @@
1
+ const usePricing = require('../../index');
2
+ const mockStores = require('../mocks/stores');
3
+ const addItemObj = require('../mocks/addItemMock');
4
+
5
+ const session = {
6
+ store: mockStores[0],
7
+ };
8
+
9
+ const pricingService = usePricing(session);
10
+
11
+ describe('addItem function', () => {
12
+ test('should add a new item to an empty order', () => {
13
+ const addItem = pricingService.order.addItem;
14
+
15
+ // Mock an empty order
16
+ const order = {
17
+ items: [],
18
+ };
19
+
20
+ // Mock item to add
21
+ const item = {
22
+ itemId: '123',
23
+ quantity: 1,
24
+ price: 100,
25
+ modifiers: [],
26
+ };
27
+
28
+ // Call the function
29
+ const [updatedOrder, itemIndex, addedItem] = addItem({
30
+ order,
31
+ item,
32
+ itemIndex: -1, // No existing item in order
33
+ cache: addItemObj.cache, // Assuming some cache object
34
+ overridenQuantity: -1, // No overridden quantity
35
+ });
36
+
37
+ // Assertions
38
+ expect(updatedOrder.items).toHaveLength(1); // Should have one item
39
+ expect(updatedOrder.items[0].itemId).toBe('123'); // Item ID should match
40
+ expect(updatedOrder.items[0].quantity).toBe(1); // Quantity should be 1
41
+ expect(updatedOrder.items[0].price).toBe(100); // Price should be 100
42
+ expect(itemIndex).toBe(0); // Index of the added item should be 0
43
+ expect(addedItem).toEqual(updatedOrder.items[0]); // Added item should match the one in the order
44
+ });
45
+
46
+ test('should combine with an existing item if aggregation is enabled', () => {
47
+ const addItem = pricingService.order.addItem;
48
+
49
+ // Mock order with one existing item
50
+ const order = {
51
+ items: [
52
+ {
53
+ itemId: '123',
54
+ quantity: 1,
55
+ price: 100,
56
+ modifiers: [],
57
+ },
58
+ ],
59
+ };
60
+
61
+ // Mock item to add (same as existing item)
62
+ const item = {
63
+ itemId: '123',
64
+ quantity: 1,
65
+ price: 100,
66
+ modifiers: [],
67
+ };
68
+
69
+ // Call the function
70
+ const [updatedOrder, itemIndex, addedItem] = addItem({
71
+ order,
72
+ item,
73
+ itemIndex: -1, // Assuming no explicit index
74
+ cache: addItemObj.cache, // Assuming some cache object
75
+ overridenQuantity: -1, // No overridden quantity
76
+ });
77
+
78
+ // Assertions
79
+ expect(updatedOrder.items).toHaveLength(1); // Should still have one item
80
+ expect(updatedOrder.items[0].quantity).toBe(2); // Quantity should be 2 (aggregated)
81
+ expect(itemIndex).toBe(0); // Index should be 0
82
+ expect(addedItem.quantity).toBe(2); // Added item should have combined quantity
83
+ });
84
+
85
+ test('should add item with overridden quantity', () => {
86
+ const addItem = pricingService.order.addItem;
87
+
88
+ // Mock order with one existing item
89
+ const order = {
90
+ items: [],
91
+ };
92
+
93
+ // Mock item to add
94
+ const item = {
95
+ itemId: '456',
96
+ quantity: 1,
97
+ price: 200,
98
+ modifiers: [],
99
+ };
100
+
101
+ // Call the function with an overridden quantity
102
+ const [updatedOrder, itemIndex, addedItem] = addItem({
103
+ order,
104
+ item,
105
+ itemIndex: -1, // Assuming no explicit index
106
+ cache: addItemObj.cache, // Assuming some cache object
107
+ overridenQuantity: 5, // Override quantity to 5
108
+ });
109
+
110
+ // Assertions
111
+ expect(updatedOrder.items).toHaveLength(1); // Should have one item
112
+ expect(updatedOrder.items[0].quantity).toBe(5); // Quantity should be overridden to 5
113
+ expect(addedItem.quantity).toBe(5); // Added item should reflect overridden quantity
114
+ });
115
+
116
+ test('should handle adding an item with modifiers', () => {
117
+ const addItem = pricingService.order.addItem;
118
+
119
+ // Mock order with one existing item
120
+ const order = {
121
+ items: [],
122
+ };
123
+
124
+ // Mock item to add with modifiers
125
+ const item = {
126
+ itemId: '789',
127
+ quantity: 1,
128
+ price: 150,
129
+ modifiers: [
130
+ {
131
+ "_id": "66cdf18a1e48455e128a4f63",
132
+ "modifierId": 'mod1',
133
+ "_parentId": null,
134
+ "name": null,
135
+ "sku": null,
136
+ "description": null,
137
+ "group": null,
138
+ "type": null,
139
+ "attributes": [],
140
+ "color": null,
141
+ "backgroundColor": null,
142
+ "icon": null,
143
+ "url": null,
144
+ "tags": [],
145
+ "order": null,
146
+ "included": false,
147
+ "direct": true,
148
+ "hidden": false,
149
+ "required": false,
150
+ "code": null,
151
+ "properties": null,
152
+ "_computed": null
153
+ },
154
+ {
155
+ "_id": "66cdf18a1e48455e128a4f64",
156
+ "modifierId": 'mod2',
157
+ "_parentId": null,
158
+ "name": null,
159
+ "sku": null,
160
+ "description": null,
161
+ "group": null,
162
+ "type": null,
163
+ "attributes": [],
164
+ "color": null,
165
+ "backgroundColor": null,
166
+ "icon": null,
167
+ "url": null,
168
+ "tags": [],
169
+ "order": null,
170
+ "included": false,
171
+ "direct": true,
172
+ "hidden": false,
173
+ "required": false,
174
+ "code": null,
175
+ "properties": null,
176
+ "_computed": null
177
+ },
178
+ ],
179
+ };
180
+
181
+ // Call the function
182
+ const [updatedOrder, itemIndex, addedItem] = addItem({
183
+ order,
184
+ item,
185
+ itemIndex: -1, // Assuming no explicit index
186
+ cache: addItemObj.cache, // Assuming some cache object
187
+ overridenQuantity: -1, // No overridden quantity
188
+ });
189
+
190
+ // Assertions
191
+ expect(updatedOrder.items).toHaveLength(1); // Should have one item
192
+ expect(updatedOrder.items[0].modifiers).toHaveLength(2); // Item should have two modifiers
193
+ expect(updatedOrder.items[0].modifiers[0].modifierId).toBe('66cdf18a1e48455e128a4f63'); // Check first modifier
194
+ expect(updatedOrder.items[0].modifiers[1].modifierId).toBe('66cdf18a1e48455e128a4f64'); // Check second modifier
195
+ expect(updatedOrder.items[0].modifiers).toHaveLength(2); // Added item should have modifiers
196
+ });
197
+ });
@@ -0,0 +1,101 @@
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('getSameItems function', () => {
11
+ test('Get calculated Order, one item', () => {
12
+ const { getSameItems } = pricingService.order;
13
+
14
+ // Mock order with one item
15
+ const order = {
16
+ items: [
17
+ {
18
+ itemId: '123',
19
+ menuId: 'menu1',
20
+ path: [1, 2, 3],
21
+ serial: null,
22
+ },
23
+ ],
24
+ };
25
+
26
+ // Mock item to compare
27
+ const item = {
28
+ itemId: '123',
29
+ menuId: 'menu1',
30
+ path: [1, 2, 3],
31
+ serial: null,
32
+ };
33
+
34
+ // Call the function
35
+ const result = getSameItems({ order, item });
36
+
37
+ // Assertions
38
+ expect(result).toHaveLength(1); // Expecting one match
39
+ expect(result[0]).toEqual(order.items[0]); // The matched item should be the same as the one in the order
40
+ });
41
+
42
+ test('No match due to different itemId', () => {
43
+ const { getSameItems } = pricingService.order;
44
+
45
+ // Mock order with one item
46
+ const order = {
47
+ items: [
48
+ {
49
+ itemId: '123',
50
+ menuId: 'menu1',
51
+ path: [1, 2, 3],
52
+ serial: null,
53
+ },
54
+ ],
55
+ };
56
+
57
+ // Mock item to compare with a different itemId
58
+ const item = {
59
+ itemId: '456',
60
+ menuId: 'menu1',
61
+ path: [1, 2, 3],
62
+ serial: null,
63
+ };
64
+
65
+ // Call the function
66
+ const result = getSameItems({ order, item });
67
+
68
+ // Assertions
69
+ expect(result).toHaveLength(0); // Expecting no matches
70
+ });
71
+
72
+ test('No match due to different path', () => {
73
+ const { getSameItems } = pricingService.order;
74
+
75
+ // Mock order with one item
76
+ const order = {
77
+ items: [
78
+ {
79
+ itemId: '123',
80
+ menuId: 'menu1',
81
+ path: [1, 2, 3],
82
+ serial: null,
83
+ },
84
+ ],
85
+ };
86
+
87
+ // Mock item to compare with a different path
88
+ const item = {
89
+ itemId: '123',
90
+ menuId: 'menu1',
91
+ path: [4, 5, 6],
92
+ serial: null,
93
+ };
94
+
95
+ // Call the function
96
+ const result = getSameItems({ order, item });
97
+
98
+ // Assertions
99
+ expect(result).toHaveLength(0); // Expecting no matches
100
+ });
101
+ });
@@ -0,0 +1,284 @@
1
+ const moment = require('moment-timezone');
2
+ const _ = require('lodash');
3
+ const pickEndDateFunction = require('../../lib/order/pickEndDate');
4
+
5
+ describe('pickEndDate function', () => {
6
+ test('Get calculated Order, one item', () => {
7
+ const settings = {
8
+ localization: {
9
+ locale: 'en-US',
10
+ hour12: true,
11
+ currency: 'USD',
12
+ phoneFormat: 'NATIONAL',
13
+ timezone: 'America/New_York',
14
+ defaultCountry: {
15
+ label: 'United States',
16
+ value: 'US',
17
+ },
18
+ dateFormat: 'default',
19
+ },
20
+ schedule: {
21
+ open: [
22
+ {
23
+ groupId: '666b542d5ed0ff34672d9c14',
24
+ days: [6, 4, 3, 1, 2, 5],
25
+ startTime: '04:00',
26
+ endTime: '17:05',
27
+ },
28
+ {
29
+ startTime: '07:00',
30
+ endTime: '22:04',
31
+ days: [1, 2],
32
+ },
33
+ ],
34
+ close: [
35
+ {
36
+ date: '2024-08-27',
37
+ },
38
+ ],
39
+ },
40
+ };
41
+
42
+ const pickEndDate = pickEndDateFunction({ settings, _, moment });
43
+ const schedule = {
44
+ addDays: 1,
45
+ hour: 17,
46
+ minute: 0,
47
+ skipDays: [7],
48
+ cutHour: { hour: 16, minute: 0 },
49
+ cutDay: 2,
50
+ };
51
+
52
+ const now = moment('2024-08-25T15:00:00Z').tz('America/New_York');
53
+
54
+ jest.spyOn(moment, 'now').mockImplementation(() => now.valueOf());
55
+ const result = pickEndDate(schedule);
56
+
57
+ const expectedDate = now
58
+ .clone()
59
+ .add(2, 'days')
60
+ .set({ hour: 17, minute: 0, second: 0 })
61
+ .utc()
62
+ .format();
63
+
64
+ expect(result).toBe(expectedDate);
65
+ });
66
+
67
+ test('Order falls on a closed day', () => {
68
+ const settings = {
69
+ localization: {
70
+ locale: 'en-US',
71
+ hour12: true,
72
+ currency: 'USD',
73
+ phoneFormat: 'NATIONAL',
74
+ timezone: 'America/New_York',
75
+ defaultCountry: {
76
+ label: 'United States',
77
+ value: 'US',
78
+ },
79
+ dateFormat: 'default',
80
+ },
81
+ schedule: {
82
+ open: [
83
+ {
84
+ groupId: '666b542d5ed0ff34672d9c14',
85
+ days: [1, 2, 3, 4, 5], // Monday to Friday
86
+ startTime: '04:00',
87
+ endTime: '17:05',
88
+ },
89
+ ],
90
+ close: [
91
+ {
92
+ date: '2024-08-28', // Wednesday is closed
93
+ },
94
+ ],
95
+ },
96
+ };
97
+
98
+ const pickEndDate = pickEndDateFunction({ settings, _, moment });
99
+ const schedule = {
100
+ addDays: 1,
101
+ hour: 17,
102
+ minute: 0,
103
+ skipDays: [7], // Skip Sunday
104
+ cutHour: { hour: 16, minute: 0 },
105
+ cutDay: 2,
106
+ };
107
+
108
+ const now = moment('2024-08-27T15:00:00Z').tz('America/New_York'); // Tuesday
109
+
110
+ jest.spyOn(moment, 'now').mockImplementation(() => now.valueOf());
111
+ const result = pickEndDate(schedule);
112
+
113
+ const expectedDate = now
114
+ .clone()
115
+ .add(2, 'days') // Skips the closed Wednesday, goes to Thursday
116
+ .set({ hour: 17, minute: 0, second: 0 })
117
+ .utc()
118
+ .format();
119
+
120
+ expect(result).toBe(expectedDate);
121
+ });
122
+
123
+ test('Order calculated on a weekend', () => {
124
+ const settings = {
125
+ localization: {
126
+ locale: 'en-US',
127
+ hour12: true,
128
+ currency: 'USD',
129
+ phoneFormat: 'NATIONAL',
130
+ timezone: 'America/New_York',
131
+ defaultCountry: {
132
+ label: 'United States',
133
+ value: 'US',
134
+ },
135
+ dateFormat: 'default',
136
+ },
137
+ schedule: {
138
+ open: [
139
+ {
140
+ groupId: '666b542d5ed0ff34672d9c14',
141
+ days: [1, 2, 3, 4, 5], // Monday to Friday
142
+ startTime: '04:00',
143
+ endTime: '17:05',
144
+ },
145
+ ],
146
+ close: [],
147
+ },
148
+ };
149
+
150
+ const pickEndDate = pickEndDateFunction({ settings, _, moment });
151
+ const schedule = {
152
+ addDays: 1,
153
+ hour: 17,
154
+ minute: 0,
155
+ skipDays: [6, 7], // Skip Saturday and Sunday
156
+ cutHour: { hour: 16, minute: 0 },
157
+ cutDay: 5,
158
+ };
159
+
160
+ const now = moment('2024-08-23T15:00:00Z').tz('America/New_York'); // Friday
161
+
162
+ jest.spyOn(moment, 'now').mockImplementation(() => now.valueOf());
163
+ const result = pickEndDate(schedule);
164
+
165
+ const expectedDate = now
166
+ .clone()
167
+ .add(3, 'days') // Skips weekend, goes to Monday
168
+ .set({ hour: 17, minute: 0, second: 0 })
169
+ .utc()
170
+ .format();
171
+
172
+ expect(result).toBe(expectedDate);
173
+ });
174
+
175
+ test('Order time before cut-off hour', () => {
176
+ const settings = {
177
+ localization: {
178
+ locale: 'en-US',
179
+ hour12: true,
180
+ currency: 'USD',
181
+ phoneFormat: 'NATIONAL',
182
+ timezone: 'America/New_York',
183
+ defaultCountry: {
184
+ label: 'United States',
185
+ value: 'US',
186
+ },
187
+ dateFormat: 'default',
188
+ },
189
+ schedule: {
190
+ open: [
191
+ {
192
+ groupId: '666b542d5ed0ff34672d9c14',
193
+ days: [1, 2, 3, 4, 5], // Monday to Friday
194
+ startTime: '04:00',
195
+ endTime: '17:05',
196
+ },
197
+ ],
198
+ close: [],
199
+ },
200
+ };
201
+
202
+ const pickEndDate = pickEndDateFunction({ settings, _, moment });
203
+ const schedule = {
204
+ addDays: 0, // Same day
205
+ hour: 17,
206
+ minute: 0,
207
+ skipDays: [],
208
+ cutHour: { hour: 16, minute: 0 }, // Cut-off at 4 PM
209
+ cutDay: 5,
210
+ };
211
+
212
+ const now = moment('2024-08-25T15:00:00Z').tz('America/New_York'); // Friday, before cut-off
213
+
214
+ jest.spyOn(moment, 'now').mockImplementation(() => now.valueOf());
215
+ const result = pickEndDate(schedule);
216
+
217
+ const expectedDate = now
218
+ .clone()
219
+ .set({ hour: 17, minute: 0, second: 0 })
220
+ .utc()
221
+ .format();
222
+
223
+ expect(result).toBe(expectedDate);
224
+ });
225
+ test('Order time after cut-off hour', () => {
226
+ const settings = {
227
+ localization: {
228
+ locale: 'en-US',
229
+ hour12: true,
230
+ currency: 'USD',
231
+ phoneFormat: 'NATIONAL',
232
+ timezone: 'America/New_York',
233
+ defaultCountry: {
234
+ label: 'United States',
235
+ value: 'US',
236
+ },
237
+ dateFormat: 'default',
238
+ },
239
+ schedule: {
240
+ open: [
241
+ {
242
+ groupId: '666b542d5ed0ff34672d9c14',
243
+ days: [1, 2, 3, 4, 5], // Monday to Friday
244
+ startTime: '04:00',
245
+ endTime: '17:05',
246
+ },
247
+ ],
248
+ close: [],
249
+ },
250
+ };
251
+
252
+ const pickEndDate = pickEndDateFunction({ settings, _, moment });
253
+ const schedule = {
254
+ hour: 17,
255
+ minute: 0,
256
+ cutDay: 5,
257
+ skipDays: [],
258
+ cutHour: {
259
+ hour: 0,
260
+ minute: 0,
261
+ },
262
+ time: {
263
+ hour: 16,
264
+ minute: 0,
265
+ },
266
+ addDays: 1,
267
+ recommended: 'nothing_recommended',
268
+ };
269
+
270
+ const now = moment().tz('America/New_York'); // Friday, after cut-off
271
+
272
+ jest.spyOn(moment, 'now').mockImplementation(() => now.valueOf());
273
+ const result = pickEndDate(schedule);
274
+
275
+ const expectedDate = now
276
+ .clone()
277
+ .add(6, 'days') // Skips weekend, goes to Monday
278
+ .set({ hour: 17, minute: 0, second: 0 })
279
+ .utc()
280
+ .format();
281
+
282
+ expect(result).toBe(expectedDate);
283
+ });
284
+ });
@@ -4,8 +4,8 @@ module.exports = () =>
4
4
  return items.filter(each => {
5
5
  let check =
6
6
  each.itemId &&
7
- item._id &&
8
- each.itemId === item._id &&
7
+ item.itemId &&
8
+ each.itemId === item.itemId &&
9
9
  !each.serial &&
10
10
  !item.serial;
11
11
  if (check && each.menuId && item.menuId) {
@@ -13,7 +13,6 @@ module.exports = () =>
13
13
  each.menuId === item.menuId &&
14
14
  each.path.toString() === item.path.toString();
15
15
  }
16
-
17
16
  return check;
18
17
  });
19
18
  };
@@ -7,8 +7,7 @@ module.exports = ({ settings, _, moment }) => {
7
7
 
8
8
  if (!Array.isArray(close)) return [];
9
9
  return close.map(closedDate => ({
10
- isoWeekDay: moment(closedDate.date).tz(timezone).isoWeekday(),
11
- date: moment(closedDate.date).tz(timezone),
10
+ date: moment(closedDate.date), // the date is saved with the user timezone, no need to convert it back here (ex: date: '2024-08-27' would become date:'2024-08-26 23:00 -4:00')
12
11
  }));
13
12
  };
14
13
 
@@ -27,27 +26,28 @@ module.exports = ({ settings, _, moment }) => {
27
26
 
28
27
  const closedDays = getClosedDays();
29
28
 
30
- if (cutHour && todayTZ.get('hours') > cutHour.hour ||
31
- (
32
- todayTZ.get('hours') >= cutHour.hour &&
33
- todayTZ.get('minutes') > cutHour.minute
34
- )
35
- ) {
29
+ if (
30
+ (cutHour && todayTZ.get('hours') > cutHour.hour) ||
31
+ (todayTZ.get('hours') >= cutHour.hour &&
32
+ todayTZ.get('minutes') > cutHour.minute)
33
+ ) {
36
34
  endDateTZ = endDateTZ.add(cutDay, 'days');
37
35
  }
38
36
 
39
37
  let addDaysCounter = 0;
40
-
41
- while (addDaysCounter < addDays) {
38
+ // adding the skip days to the loop
39
+ const loop = addDays + skipDays.length;
40
+ while (addDaysCounter < loop) {
42
41
  endDateTZ = endDateTZ.add(1, 'days');
43
42
  const endDateISOWeekday = endDateTZ.isoWeekday();
44
-
43
+ // does the current endDateISOWeekday match with any skip day?
44
+ // is endDateISOWeekday a sunday?
45
45
  const shouldSkip =
46
- skipDays.includes(endDateISOWeekday) ||
47
- (endDateISOWeekday === 7 && skipDays === 0);
48
-
46
+ skipDays.includes(endDateISOWeekday) || endDateISOWeekday === 7;
47
+ // if addDaysCounter is greater than loop, than we shouldn't add more days
48
+ // day condition stays working until addDaysCounter is greater than loop
49
49
  if (
50
- !shouldSkip &&
50
+ !shouldSkip ||
51
51
  !closedDays.some(closedDay => closedDay.date.isSame(endDateTZ, 'day'))
52
52
  ) {
53
53
  addDaysCounter++;
@@ -60,4 +60,4 @@ module.exports = ({ settings, _, moment }) => {
60
60
 
61
61
  return moment.utc(endDateTZ).format();
62
62
  };
63
- };
63
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@darkpos/pricing",
3
- "version": "1.0.28",
3
+ "version": "1.0.30",
4
4
  "description": "Pricing calculator",
5
5
  "author": "Dark POS",
6
6
  "license": "ISC",
@@ -36,5 +36,5 @@
36
36
  "supertest": "^6.2.3",
37
37
  "supervisor": "^0.12.0"
38
38
  },
39
- "gitHead": "b6e37fe06bd25e18c66d7b2f1a06fb1c50bd0db6"
39
+ "gitHead": "a2b20141126aa1c7eb18c345a8aef54d3f6b0821"
40
40
  }