@darkpos/pricing 1.0.62 → 1.0.63

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.
@@ -193,4 +193,491 @@ describe('Modifier actions', () => {
193
193
  expect(error).toEqual('');
194
194
  expect(updatedOrder2).toEqual(order);
195
195
  });
196
+
197
+ test('CU-86dum5w1q Should not allow more than 1 child modifier with the same singleParentGroupId', () => {
198
+ const params = {
199
+ itemIndex: 0,
200
+ modifier: {
201
+ _id: '62cdbfd01ee1b400193281e1',
202
+ attributes: [],
203
+ cost: 0,
204
+ tags: [],
205
+ included: false,
206
+ direct: true,
207
+ hidden: false,
208
+ print: true,
209
+ required: false,
210
+ recommended: false,
211
+ default: false,
212
+ addModifiers: [],
213
+ delModifiers: [],
214
+ _hidden: false,
215
+ _isDeleted: false,
216
+ modifierId: null,
217
+ name: 'Dark Golden Rod',
218
+ sku: '',
219
+ description: 'Color: Orange',
220
+ group: 'Color',
221
+ type: '',
222
+ color: '#b8860b',
223
+ backgroundColor: '',
224
+ icon: '',
225
+ url: '',
226
+ order: 0,
227
+ code: '',
228
+ conditions: null,
229
+ compute: null,
230
+ _accountId: '62cdbfcdaaf93c00193d2dd3',
231
+ _storeId: '62cdbfce1ee1b40019328156',
232
+ _createdAt: '2022-07-12T18:39:18.038Z',
233
+ _updatedAt: '2022-07-12T18:39:18.038Z',
234
+ __typename: 'Modifier',
235
+ properties: { singleValueGroupId: '62cdbfd01ee1b4001932816a' },
236
+ },
237
+ order: {
238
+ _id: '67b4fb03c2d2f55164464c51',
239
+ parentId: null,
240
+ isParent: false,
241
+ subTotal: 213,
242
+ tax: 0,
243
+ modifiers: [],
244
+ discount: 0,
245
+ total: 213,
246
+ description: '',
247
+ displayId: '',
248
+ type: '',
249
+ location: {},
250
+ status: {
251
+ order: 'open',
252
+ kitchen: 'open',
253
+ delivery: 'none',
254
+ detailed: true,
255
+ },
256
+ attributes: [],
257
+ properties: {},
258
+ fee: 0,
259
+ user: null,
260
+ items: [
261
+ {
262
+ location: {},
263
+ status: {
264
+ picked: { value: false, date: '' },
265
+ paid: { value: false, date: '' },
266
+ tracker: [],
267
+ },
268
+ name: '2pc Dress with Long Jacket2',
269
+ description: 'a long jacket.',
270
+ pieces: 2,
271
+ modifiersTotalAmount: 0,
272
+ total: 213,
273
+ totalPaid: 0,
274
+ price: 213,
275
+ quantity: 1,
276
+ path: ',67213668c4b950f2f3c41e64,672136a0f3116216ca955091,',
277
+ notes: [],
278
+ serial: null,
279
+ sku: '',
280
+ modifiers: [
281
+ {
282
+ _id: '67b4fb13c2d2f55164464c55',
283
+ attributes: ['group'],
284
+ modifierId: '62cdbfd01ee1b4001932816a',
285
+ _parentId: null,
286
+ locked: false,
287
+ name: 'White',
288
+ sku: '',
289
+ description: 'Color: White',
290
+ group: 'Color',
291
+ type: null,
292
+ tags: ['default', 'all'],
293
+ order: null,
294
+ included: false,
295
+ direct: true,
296
+ hidden: false,
297
+ print: false,
298
+ required: true,
299
+ recommended: false,
300
+ default: false,
301
+ code: null,
302
+ properties: {
303
+ override: null,
304
+ group: {
305
+ displayType: 'card',
306
+ includeInGroup: true,
307
+ singleValue: true,
308
+ compact: false,
309
+ enableAutoPopup: true,
310
+ displayReplacePrompt: true,
311
+ promptMessage: '',
312
+ modifiers: [],
313
+ items: [],
314
+ values: ['RegularItem'],
315
+ manualModifiers: 'test1, asd,123',
316
+ },
317
+ sort: null,
318
+ label: {
319
+ text: 'White Label',
320
+ align: 'center',
321
+ backgroundColor: 'rgba(76,175,80,1)',
322
+ },
323
+ color: 'rgba(0,150,136,1)',
324
+ },
325
+ _computed: { amount: 0, description: 'White' },
326
+ conditions: { valid: true },
327
+ compute: null,
328
+ _createdAt: '2022-07-12T18:39:17.922Z',
329
+ _updatedAt: '2025-02-17T21:23:21.422Z',
330
+ addModifiers: [],
331
+ delModifiers: [],
332
+ },
333
+ {
334
+ _id: '67b4fb13c2d2f55164464c56',
335
+ attributes: ['group'],
336
+ modifierId: '62cdbfd01ee1b400193281b1',
337
+ _parentId: null,
338
+ locked: false,
339
+ name: 'Red',
340
+ sku: '',
341
+ description: 'Color: Red',
342
+ group: 'Color',
343
+ type: null,
344
+ tags: ['default', 'all'],
345
+ order: null,
346
+ included: false,
347
+ direct: true,
348
+ hidden: false,
349
+ print: false,
350
+ required: true,
351
+ recommended: false,
352
+ default: false,
353
+ code: null,
354
+ properties: {
355
+ group: {
356
+ displayType: 'list',
357
+ modifiers: [],
358
+ items: [],
359
+ compact: null,
360
+ includeInGroup: true,
361
+ singleValue: null,
362
+ enableAutoPopup: true,
363
+ displayReplacePrompt: null,
364
+ manualModifiers: '',
365
+ },
366
+ label: { text: '' },
367
+ sort: null,
368
+ color: 'rgba(255,0,0,1)',
369
+ },
370
+ _computed: { amount: 0, description: 'Red' },
371
+ conditions: { valid: true },
372
+ compute: null,
373
+ _createdAt: '2022-07-12T18:39:17.990Z',
374
+ _updatedAt: '2025-02-12T19:26:05.372Z',
375
+ addModifiers: [],
376
+ delModifiers: [],
377
+ },
378
+ {
379
+ _id: '67b4fb14c2d2f55164464c57',
380
+ attributes: [],
381
+ cost: 0,
382
+ tags: [],
383
+ included: false,
384
+ direct: true,
385
+ hidden: false,
386
+ print: true,
387
+ required: false,
388
+ recommended: false,
389
+ default: false,
390
+ addModifiers: [],
391
+ delModifiers: [],
392
+ _hidden: false,
393
+ _isDeleted: false,
394
+ modifierId: '62cdbfd01ee1b40019328188',
395
+ name: 'Linen',
396
+ sku: '',
397
+ description: 'Color: White',
398
+ group: 'Color',
399
+ type: '',
400
+ color: '#faf0e6',
401
+ backgroundColor: '',
402
+ icon: '',
403
+ url: '',
404
+ order: 0,
405
+ code: '',
406
+ conditions: { valid: true },
407
+ compute: null,
408
+ _accountId: '62cdbfcdaaf93c00193d2dd3',
409
+ _storeId: '62cdbfce1ee1b40019328156',
410
+ _createdAt: '2022-07-12T18:39:18.038Z',
411
+ _updatedAt: '2022-07-12T18:39:18.038Z',
412
+ __typename: 'Modifier',
413
+ properties: { singleValueGroupId: '62cdbfd01ee1b4001932816a' },
414
+ _computed: { amount: 0, description: 'Linen' },
415
+ },
416
+ {
417
+ _id: '67b4fb15c2d2f55164464c58',
418
+ attributes: [],
419
+ cost: 0,
420
+ tags: null,
421
+ included: false,
422
+ direct: true,
423
+ hidden: false,
424
+ print: false,
425
+ required: false,
426
+ recommended: false,
427
+ default: false,
428
+ addModifiers: [],
429
+ delModifiers: [],
430
+ _hidden: false,
431
+ _isDeleted: false,
432
+ modifierId: '62cdbfd01ee1b400193281b2',
433
+ name: 'Dark Red',
434
+ sku: '',
435
+ description: 'Color: Red',
436
+ group: 'Color',
437
+ type: null,
438
+ color: '#8b0000',
439
+ url: '',
440
+ conditions: { valid: true },
441
+ backgroundColor: null,
442
+ code: null,
443
+ compute: null,
444
+ icon: null,
445
+ order: null,
446
+ properties: { singleValueGroupId: null },
447
+ _accountId: '62cdbfcdaaf93c00193d2dd3',
448
+ _storeId: '62cdbfce1ee1b40019328156',
449
+ _createdAt: '2022-07-12T18:39:17.985Z',
450
+ _updatedAt: '2022-07-12T18:39:17.985Z',
451
+ __typename: 'Modifier',
452
+ _computed: { amount: 0, description: 'Dark Red' },
453
+ },
454
+ ],
455
+ _id: '67b4fb13c2d2f55164464c54',
456
+ _updatedAt: '2025-02-17T20:59:00.398Z',
457
+ _createdAt: '2022-07-12T18:39:17.318Z',
458
+ weight: null,
459
+ properties: {
460
+ label: { text: '', align: 'center', backgroundColor: null },
461
+ url: null,
462
+ color: 'rgba(254,86,33,1)',
463
+ iconName: 'ActivitySquare',
464
+ basePrice: 213,
465
+ },
466
+ hasInventory: true,
467
+ inventoryType: 'push',
468
+ category: { _id: '66db73e570fdebea682d28e2' },
469
+ __typename: 'OrderItem',
470
+ priceLevels: [
471
+ { value: 213, tags: ['default'] },
472
+ { value: 200, tags: ['vip'] },
473
+ { value: 12, tags: ['wholesale'] },
474
+ { value: 113, tags: ['default', 'press only'] },
475
+ { value: 100, tags: ['vip', 'press only'] },
476
+ { value: 0, tags: ['wholesale', 'press only'] },
477
+ ],
478
+ costLevels: [],
479
+ itemId: '62cdbfd01ee1b4001932821a',
480
+ categoryId: '66db73e570fdebea682d28e2',
481
+ menuRuleId: '672136a9f3116216ca955092',
482
+ subTotals: {
483
+ _included: 0,
484
+ _xincluded: 0,
485
+ _direct: 0,
486
+ _xdirect: 0,
487
+ _simple: 213,
488
+ _actual: 213,
489
+ },
490
+ },
491
+ ],
492
+ notes: [],
493
+ customer: {
494
+ _id: '66a3d7d366107c7369873980',
495
+ username: '',
496
+ firstName: 'Esteban',
497
+ lastName: 'Mathieu',
498
+ description: '',
499
+ attributes: [],
500
+ properties: {
501
+ charge: {
502
+ enabled: true,
503
+ walletCard: {
504
+ customerToken: 'cus_RCWJ73mmqUM5Td',
505
+ cardToken: 'card_1QKLmQFS0LoOx3AS7L9LWHUt',
506
+ },
507
+ },
508
+ billing: { name: 'Andreparent Pinto', enabled: false, limit: null },
509
+ events: [],
510
+ relationships: [],
511
+ defaultStore: '62cdbfce1ee1b40019328156',
512
+ gender: '',
513
+ company: 'WWE',
514
+ profilePic:
515
+ 'https://res.cloudinary.com/darkpos/image/upload/v1731358649/67326fb8260f353e43272369.jpg',
516
+ starch: '62cdbfd01ee1b4001932822e',
517
+ packing: '66cd14a4b74b7da4b9f195d3',
518
+ cycle: false,
519
+ declineNotifications: false,
520
+ escExempt: false,
521
+ route: false,
522
+ taxExempt: false,
523
+ term: '',
524
+ customFieldTest: '',
525
+ },
526
+ tags: ['default'],
527
+ status: '',
528
+ parent: { tags: ['default'] },
529
+ parentId: '66f174ddc289cb1302b2eb8e',
530
+ loyalty: null,
531
+ wallet: [
532
+ {
533
+ isDefault: true,
534
+ provider: 'credit-card-ppec',
535
+ customerToken: 'cus_R5fHSveVoEOdrg',
536
+ cardToken: 'card_1QDTwmFS0LoOx3ASEGiVK7nD',
537
+ cards: [
538
+ {
539
+ _id: 'card_1QfQNwFS0LoOx3AS3Zp8jIdx',
540
+ name: 'Andre S Dark',
541
+ token: 'card_1QfQNwFS0LoOx3AS3Zp8jIdx',
542
+ last4: '4444',
543
+ month: '12',
544
+ year: '2033',
545
+ billingAddress: 'Rua 6 130 c2',
546
+ zipCode: '21478',
547
+ type: 'card',
548
+ amount: null,
549
+ pin: null,
550
+ number: null,
551
+ },
552
+ ],
553
+ },
554
+ {
555
+ isDefault: false,
556
+ provider: 'darkpos',
557
+ customerToken: '673f93ddbb1a78190bb48361',
558
+ cardToken: null,
559
+ cards: [
560
+ {
561
+ _id: '673f93ddbb1a78190bb48362',
562
+ name: null,
563
+ token: '673f93ddbb1a78190bb48362',
564
+ last4: null,
565
+ month: null,
566
+ year: null,
567
+ billingAddress: null,
568
+ zipCode: null,
569
+ type: 'credit',
570
+ amount: 0,
571
+ pin: null,
572
+ number: null,
573
+ },
574
+ ],
575
+ },
576
+ ],
577
+ modifiers: [],
578
+ addresses: [
579
+ {
580
+ address1: '21 Jump Street',
581
+ address2: '',
582
+ city: 'LA',
583
+ state: 'California',
584
+ zip: '',
585
+ country: null,
586
+ primary: true,
587
+ type: null,
588
+ description: null,
589
+ location: { lat: 0, lng: 0 },
590
+ },
591
+ ],
592
+ contacts: [],
593
+ notes: [],
594
+ _accountId: '62cdbfcdaaf93c00193d2dd3',
595
+ _storeId: '62cdbfce1ee1b40019328156',
596
+ _isDeleted: false,
597
+ _deletedAt: null,
598
+ _updatedAt: '2025-02-17T20:59:00.355Z',
599
+ _createdAt: '2024-07-26T17:07:41.027Z',
600
+ isEmbedded: true,
601
+ },
602
+ start: {
603
+ actualDate: '2025-02-18T21:26:27.782Z',
604
+ requestDate: '2025-02-18T21:26:27.782Z',
605
+ __typename: 'OrderStart',
606
+ location: {
607
+ name: 'Tico Store #1',
608
+ locationType: 'store',
609
+ storeId: '62cdbfce1ee1b40019328156',
610
+ },
611
+ },
612
+ end: {
613
+ __typename: 'OrderEnd',
614
+ actualDate: '',
615
+ requestDate: '2025-02-21T21:30:00.000Z',
616
+ location: {
617
+ name: 'Tico Store #1',
618
+ locationType: 'store',
619
+ storeId: '62cdbfce1ee1b40019328156',
620
+ },
621
+ },
622
+ _storeId: '',
623
+ __typename: 'Order',
624
+ isOrderNew: true,
625
+ subTotals: {},
626
+ },
627
+ force: true,
628
+ originalItem: {
629
+ _id: '62cdbfd01ee1b4001932821a',
630
+ _updatedAt: '2025-02-17T20:59:00.398Z',
631
+ _createdAt: '2022-07-12T18:39:17.318Z',
632
+ name: '2pc Dress with Long Jacket2',
633
+ description: 'a long jacket.',
634
+ pieces: 2,
635
+ weight: 0,
636
+ properties: {
637
+ label: { text: '', align: 'center', backgroundColor: null },
638
+ url: null,
639
+ color: 'rgba(254,86,33,1)',
640
+ iconName: 'ActivitySquare',
641
+ },
642
+ sku: '',
643
+ hasInventory: true,
644
+ inventoryType: 'push',
645
+ quantity: 67,
646
+ category: { _id: '66db73e570fdebea682d28e2' },
647
+ __typename: 'Item',
648
+ modifiers: [],
649
+ priceLevels: [
650
+ { value: 213, tags: ['default'] },
651
+ { value: 200, tags: ['vip'] },
652
+ { value: 12, tags: ['wholesale'] },
653
+ { value: 113, tags: ['default', 'press only'] },
654
+ { value: 100, tags: ['vip', 'press only'] },
655
+ { value: 0, tags: ['wholesale', 'press only'] },
656
+ ],
657
+ costLevels: [],
658
+ },
659
+ };
660
+
661
+ const updatedOrder = pricingService.order.addItemModifier({
662
+ order: params.order,
663
+ modifier: params.modifier,
664
+ itemIndex: params.itemIndex,
665
+ });
666
+
667
+ expect(updatedOrder.items[0].modifiers.length).toEqual(4);
668
+ expect(updatedOrder.items[0].modifiers[0].name).toEqual('White');
669
+ expect(updatedOrder.items[0].modifiers[1].name).toEqual('Red');
670
+ expect(updatedOrder.items[0].modifiers[2].name).toEqual('Dark Red');
671
+ expect(updatedOrder.items[0].modifiers[2].properties).toEqual(
672
+ expect.objectContaining({
673
+ singleValueGroupId: null,
674
+ })
675
+ );
676
+ expect(updatedOrder.items[0].modifiers[3].name).toEqual('Dark Golden Rod');
677
+ expect(updatedOrder.items[0].modifiers[3].properties).toEqual(
678
+ expect.objectContaining({
679
+ singleValueGroupId: '62cdbfd01ee1b4001932816a',
680
+ })
681
+ );
682
+ });
196
683
  });
@@ -0,0 +1,11 @@
1
+ module.exports = ({ modifierActions }) =>
2
+ function getModifiersBySingleValueId({ item, singleValueGroupId }) {
3
+ if (!singleValueGroupId) return [];
4
+
5
+ if (!item || !item.modifiers) return [];
6
+ return item.modifiers.filter(
7
+ each =>
8
+ modifierActions.getProperty(each, 'singleValueGroupId') ===
9
+ singleValueGroupId
10
+ );
11
+ };
package/lib/item/index.js CHANGED
@@ -46,6 +46,7 @@ const getTotalNeareastDifference = require('./getTotalNeareastDifference');
46
46
  const getNoteTags = require('./getNoteTags');
47
47
  const getBasePrice = require('./getBasePrice');
48
48
  const removeModifiersByQuantity = require('./removeModifiersByQuantity');
49
+ const getModifiersBySingleValueId = require('./getModifiersBySingleValueId');
49
50
 
50
51
  const itemActions = (deps = {}) => {
51
52
  const actions = {};
@@ -105,6 +106,7 @@ const itemActions = (deps = {}) => {
105
106
  getNoteTags: getNoteTags(innerDeps),
106
107
  getBasePrice: getBasePrice(innerDeps),
107
108
  removeModifiersByQuantity: removeModifiersByQuantity(innerDeps),
109
+ getModifiersBySingleValueId: getModifiersBySingleValueId(innerDeps),
108
110
  });
109
111
 
110
112
  Object.keys(freezedActions).forEach(actionName => {
@@ -1,5 +1,7 @@
1
1
  module.exports = () =>
2
2
  function contains(modifiers = [], modifier = null) {
3
3
  if (!modifiers || !modifier) return false;
4
- return !!modifiers.find(each => each.modifierId === modifier._id);
4
+ return !!modifiers.find(
5
+ each => each.modifierId === modifier._id || each._id === modifier._id
6
+ );
5
7
  };
@@ -204,6 +204,30 @@ module.exports = ({ actions, itemActions, modifierActions, utils, _ }) => {
204
204
  return order;
205
205
  }
206
206
 
207
+ const modifiersToRemove = itemActions.getModifiersBySingleValueId({
208
+ item,
209
+ singleValueGroupId: modifierActions.getProperty(
210
+ modifier,
211
+ 'singleValueGroupId'
212
+ ),
213
+ });
214
+
215
+ if (modifiersToRemove.length > 0) {
216
+ order = modifiersToRemove.reduce(
217
+ (prevVal, modToRemove) => {
218
+ const result = actions.removeItemModifier({
219
+ order: prevVal,
220
+ modifier: modToRemove,
221
+ itemIndex,
222
+ originalItem,
223
+ });
224
+ return result;
225
+ },
226
+ { ...order }
227
+ );
228
+ item = actions.getSelectedItem({ order, itemIndex });
229
+ }
230
+
207
231
  if (
208
232
  contains &&
209
233
  modifierActions.isCompute(modifier) &&
@@ -12,9 +12,12 @@ module.exports = ({ actions, modifierActions, itemActions, utils, _ }) => {
12
12
  const removeModifier = ({ item, modifier, originalItem }) => {
13
13
  const nextItem = { ...item, modifiers: [] };
14
14
 
15
- nextItem.modifiers = item.modifiers.filter(
16
- each => (each.modifierId || each._id) !== modifier._id
17
- );
15
+ nextItem.modifiers = item.modifiers.filter(each => {
16
+ if (each.modifierId) {
17
+ return each.modifierId !== modifier._id && each._id !== modifier._id;
18
+ }
19
+ return each._id !== modifier._id;
20
+ });
18
21
 
19
22
  if (modifierActions.isAmountOverride(modifier))
20
23
  return {
@@ -41,10 +44,14 @@ module.exports = ({ actions, modifierActions, itemActions, utils, _ }) => {
41
44
 
42
45
  let item = actions.getSelectedItem({ order, itemIndex });
43
46
  const customer = actions.getCustomer(order);
47
+
44
48
  const contains = modifierActions.contains(item.modifiers, modifier);
45
49
 
46
50
  if (!contains) return order;
47
- if (modifierActions.isRequiredAndOverride(modifier)) return order;
51
+
52
+ if (modifierActions.isRequiredAndOverride(modifier)) {
53
+ return order;
54
+ }
48
55
 
49
56
  // Remove
50
57
  item = removeModifier({
@@ -52,6 +59,7 @@ module.exports = ({ actions, modifierActions, itemActions, utils, _ }) => {
52
59
  modifier,
53
60
  originalItem,
54
61
  });
62
+
55
63
  item.price = itemActions.getItemPrice({
56
64
  item,
57
65
  itemPriceLevels: originalItem ? originalItem.priceLevels : undefined,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@darkpos/pricing",
3
- "version": "1.0.62",
3
+ "version": "1.0.63",
4
4
  "description": "Pricing calculator",
5
5
  "author": "Dark POS",
6
6
  "license": "ISC",
@@ -22,6 +22,7 @@
22
22
  "test:createIndirectModifier": "jest --runInBand --detectOpenHandles --logHeapUsage --forceExit ./__TEST__/modifier/createIndirectModifier.test.js",
23
23
  "test:conditionsNotMet": "jest --runInBand --detectOpenHandles --logHeapUsage --forceExit ./__TEST__/order/conditionsNotMet.test.js",
24
24
  "test:pickEndDate": "jest --runInBand --detectOpenHandles --logHeapUsage --forceExit ./__TEST__/order/pickEndDate.test.js",
25
+ "test:modifier": "jest --runInBand --detectOpenHandles --logHeapUsage --forceExit ./__TEST__/modifier.test.js",
25
26
  "lint": "eslint --quiet lib/"
26
27
  },
27
28
  "publishConfig": {
@@ -45,5 +46,5 @@
45
46
  "supertest": "^6.2.3",
46
47
  "supervisor": "^0.12.0"
47
48
  },
48
- "gitHead": "46945a727cbb12468ce5e88b5d28a37ec1d321ee"
49
+ "gitHead": "0d2bce7580b5ba1078a16390ae63680af8b27d66"
49
50
  }