@darkpos/pricing 1.0.73 → 1.0.75
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.
- package/__TEST__/modifier/hasModifier.test.js +35 -0
- package/__TEST__/modifier.test.js +193 -0
- package/lib/index.js +3 -0
- package/lib/item/hasModifier.js +9 -2
- package/lib/modifier/getManualModifiers.js +64 -0
- package/lib/modifier/index.js +6 -0
- package/lib/modifier/shouldSpreadModifier.js +10 -0
- package/lib/modifier/spreadSingleGroupModifiers.js +30 -0
- package/package.json +3 -2
|
@@ -1751,4 +1751,39 @@ describe('hasModifier Function', () => {
|
|
|
1751
1751
|
|
|
1752
1752
|
expect(result2).toBe(true);
|
|
1753
1753
|
});
|
|
1754
|
+
|
|
1755
|
+
test('hasModifier, matching by spreadFrom', () => {
|
|
1756
|
+
const groupMod = {
|
|
1757
|
+
_id: 'groupMod10',
|
|
1758
|
+
attributes: ['group'],
|
|
1759
|
+
properties: {
|
|
1760
|
+
group: {},
|
|
1761
|
+
},
|
|
1762
|
+
modifierId: 'abcd123',
|
|
1763
|
+
};
|
|
1764
|
+
|
|
1765
|
+
const spreadedManualModifier = {
|
|
1766
|
+
_id: 'abc',
|
|
1767
|
+
name: 'related item abc',
|
|
1768
|
+
itemId: 'abc',
|
|
1769
|
+
properties: {
|
|
1770
|
+
spreadFrom: groupMod.modifierId,
|
|
1771
|
+
},
|
|
1772
|
+
};
|
|
1773
|
+
|
|
1774
|
+
const item = {
|
|
1775
|
+
_id: 1,
|
|
1776
|
+
itemId: 'ab',
|
|
1777
|
+
modifiers: [groupMod, spreadedManualModifier],
|
|
1778
|
+
price: 500,
|
|
1779
|
+
total: 10000,
|
|
1780
|
+
};
|
|
1781
|
+
|
|
1782
|
+
const result = pricingService.item.hasModifier({
|
|
1783
|
+
item,
|
|
1784
|
+
modifier: groupMod,
|
|
1785
|
+
});
|
|
1786
|
+
|
|
1787
|
+
expect(result).toBe(true);
|
|
1788
|
+
});
|
|
1754
1789
|
});
|
|
@@ -680,4 +680,197 @@ describe('Modifier actions', () => {
|
|
|
680
680
|
})
|
|
681
681
|
);
|
|
682
682
|
});
|
|
683
|
+
|
|
684
|
+
describe('getManualModifiers', () => {
|
|
685
|
+
it('should generate manual modifiers correctly for dry cleaning tags', () => {
|
|
686
|
+
const modifier = {
|
|
687
|
+
_id: 'abc123',
|
|
688
|
+
name: 'Base Modifier',
|
|
689
|
+
group: 'colorGroup1',
|
|
690
|
+
properties: {
|
|
691
|
+
group: {
|
|
692
|
+
manualModifiers: 'Red Tag, White Shirt, White Shirt , Blue Label',
|
|
693
|
+
},
|
|
694
|
+
},
|
|
695
|
+
};
|
|
696
|
+
|
|
697
|
+
const relatedModifiers = [{ name: 'White Shirt' }];
|
|
698
|
+
|
|
699
|
+
const result = pricingService.modifier.getManualModifiers({
|
|
700
|
+
modifier,
|
|
701
|
+
relatedModifiers,
|
|
702
|
+
});
|
|
703
|
+
|
|
704
|
+
expect(result).toHaveLength(2);
|
|
705
|
+
expect(result).toEqual(
|
|
706
|
+
expect.arrayContaining([
|
|
707
|
+
expect.objectContaining({
|
|
708
|
+
name: 'Red Tag',
|
|
709
|
+
direct: true,
|
|
710
|
+
group: 'colorGroup1',
|
|
711
|
+
properties: {
|
|
712
|
+
isManual: true,
|
|
713
|
+
},
|
|
714
|
+
_id: 'ead6eb247a93bca8f802f9b2',
|
|
715
|
+
}),
|
|
716
|
+
expect.objectContaining({
|
|
717
|
+
name: 'Blue Label',
|
|
718
|
+
direct: true,
|
|
719
|
+
group: 'colorGroup1',
|
|
720
|
+
properties: {
|
|
721
|
+
isManual: true,
|
|
722
|
+
},
|
|
723
|
+
_id: '4e23edf8fa734884f4618003',
|
|
724
|
+
}),
|
|
725
|
+
])
|
|
726
|
+
);
|
|
727
|
+
});
|
|
728
|
+
|
|
729
|
+
it('should return an empty array if no manual modifiers are present', () => {
|
|
730
|
+
const modifier = {
|
|
731
|
+
_id: 'xyz789',
|
|
732
|
+
properties: {
|
|
733
|
+
group: {
|
|
734
|
+
manualModifiers: '',
|
|
735
|
+
},
|
|
736
|
+
},
|
|
737
|
+
};
|
|
738
|
+
|
|
739
|
+
const result = pricingService.modifier.getManualModifiers({
|
|
740
|
+
modifier,
|
|
741
|
+
relatedModifiers: [],
|
|
742
|
+
});
|
|
743
|
+
expect(result).toEqual([]);
|
|
744
|
+
});
|
|
745
|
+
|
|
746
|
+
it('should return an empty array if required fields are missing', () => {
|
|
747
|
+
expect(
|
|
748
|
+
pricingService.modifier.getManualModifiers({ modifier: null })
|
|
749
|
+
).toEqual([]);
|
|
750
|
+
expect(
|
|
751
|
+
pricingService.modifier.getManualModifiers({ modifier: {} })
|
|
752
|
+
).toEqual([]);
|
|
753
|
+
});
|
|
754
|
+
});
|
|
755
|
+
|
|
756
|
+
describe('spreadSingleGroupModifiers', () => {
|
|
757
|
+
it('should spread the modifiers from a group, including its manual modifiers', () => {
|
|
758
|
+
const modifier = {
|
|
759
|
+
_id: 'abc123',
|
|
760
|
+
name: 'Base Modifier',
|
|
761
|
+
group: 'colorGroup1',
|
|
762
|
+
attributes: ['group'],
|
|
763
|
+
properties: {
|
|
764
|
+
group: {
|
|
765
|
+
manualModifiers: 'Red Tag, White Shirt, White Shirt , Blue Label',
|
|
766
|
+
},
|
|
767
|
+
},
|
|
768
|
+
};
|
|
769
|
+
|
|
770
|
+
const result = pricingService.modifier.spreadSingleGroupModifiers([
|
|
771
|
+
modifier,
|
|
772
|
+
]);
|
|
773
|
+
|
|
774
|
+
expect(result).toStrictEqual([
|
|
775
|
+
{
|
|
776
|
+
name: 'Red Tag',
|
|
777
|
+
_id: 'ead6eb247a93bca8f802f9b2',
|
|
778
|
+
direct: true,
|
|
779
|
+
group: 'colorGroup1',
|
|
780
|
+
properties: { isManual: true, spreadFrom: 'abc123' },
|
|
781
|
+
},
|
|
782
|
+
{
|
|
783
|
+
name: 'White Shirt',
|
|
784
|
+
_id: '4e23edf8fa734884f4618003',
|
|
785
|
+
direct: true,
|
|
786
|
+
group: 'colorGroup1',
|
|
787
|
+
properties: { isManual: true, spreadFrom: 'abc123' },
|
|
788
|
+
},
|
|
789
|
+
{
|
|
790
|
+
name: 'Blue Label',
|
|
791
|
+
_id: '94b02ee7ba009b09a913a786',
|
|
792
|
+
direct: true,
|
|
793
|
+
group: 'colorGroup1',
|
|
794
|
+
properties: { isManual: true, spreadFrom: 'abc123' },
|
|
795
|
+
},
|
|
796
|
+
]);
|
|
797
|
+
});
|
|
798
|
+
|
|
799
|
+
it('should not spread the modifiers from a group, as there are other modifiers with the same group', () => {
|
|
800
|
+
const modifier = {
|
|
801
|
+
_id: 'abc123',
|
|
802
|
+
name: 'Base Modifier',
|
|
803
|
+
group: 'colorGroup1',
|
|
804
|
+
attributes: ['group'],
|
|
805
|
+
properties: {
|
|
806
|
+
group: {
|
|
807
|
+
manualModifiers: 'Red Tag, White Shirt, White Shirt , Blue Label',
|
|
808
|
+
},
|
|
809
|
+
},
|
|
810
|
+
};
|
|
811
|
+
|
|
812
|
+
const otherModifier = {
|
|
813
|
+
_id: 'bcd123',
|
|
814
|
+
name: 'other Modifier',
|
|
815
|
+
group: 'colorGroup1',
|
|
816
|
+
};
|
|
817
|
+
|
|
818
|
+
const result = pricingService.modifier.spreadSingleGroupModifiers([
|
|
819
|
+
modifier,
|
|
820
|
+
otherModifier,
|
|
821
|
+
]);
|
|
822
|
+
|
|
823
|
+
expect(result).toStrictEqual([modifier, otherModifier]);
|
|
824
|
+
});
|
|
825
|
+
|
|
826
|
+
it('should spread the modifiers from a group, as there are no other modifiers with the same group', () => {
|
|
827
|
+
const modifier = {
|
|
828
|
+
_id: 'abc123',
|
|
829
|
+
name: 'Base Modifier',
|
|
830
|
+
group: 'colorGroup1',
|
|
831
|
+
attributes: ['group'],
|
|
832
|
+
properties: {
|
|
833
|
+
group: {
|
|
834
|
+
manualModifiers: 'Red Tag, White Shirt, White Shirt , Blue Label',
|
|
835
|
+
},
|
|
836
|
+
},
|
|
837
|
+
};
|
|
838
|
+
|
|
839
|
+
const otherModifier = {
|
|
840
|
+
_id: 'bcd123',
|
|
841
|
+
name: 'other Modifier',
|
|
842
|
+
group: 'Repair',
|
|
843
|
+
};
|
|
844
|
+
|
|
845
|
+
const result = pricingService.modifier.spreadSingleGroupModifiers([
|
|
846
|
+
modifier,
|
|
847
|
+
otherModifier,
|
|
848
|
+
]);
|
|
849
|
+
|
|
850
|
+
expect(result).toStrictEqual([
|
|
851
|
+
{
|
|
852
|
+
name: 'Red Tag',
|
|
853
|
+
_id: 'ead6eb247a93bca8f802f9b2',
|
|
854
|
+
direct: true,
|
|
855
|
+
group: 'colorGroup1',
|
|
856
|
+
properties: { isManual: true, spreadFrom: 'abc123' },
|
|
857
|
+
},
|
|
858
|
+
{
|
|
859
|
+
name: 'White Shirt',
|
|
860
|
+
_id: '4e23edf8fa734884f4618003',
|
|
861
|
+
direct: true,
|
|
862
|
+
group: 'colorGroup1',
|
|
863
|
+
properties: { isManual: true, spreadFrom: 'abc123' },
|
|
864
|
+
},
|
|
865
|
+
{
|
|
866
|
+
name: 'Blue Label',
|
|
867
|
+
_id: '94b02ee7ba009b09a913a786',
|
|
868
|
+
direct: true,
|
|
869
|
+
group: 'colorGroup1',
|
|
870
|
+
properties: { isManual: true, spreadFrom: 'abc123' },
|
|
871
|
+
},
|
|
872
|
+
{ _id: 'bcd123', name: 'other Modifier', group: 'Repair' },
|
|
873
|
+
]);
|
|
874
|
+
});
|
|
875
|
+
});
|
|
683
876
|
});
|
package/lib/index.js
CHANGED
|
@@ -2,6 +2,8 @@ const utils = require('@darkpos/utils');
|
|
|
2
2
|
const _ = require('lodash');
|
|
3
3
|
const moment = require('moment-timezone');
|
|
4
4
|
/** services */
|
|
5
|
+
const sha256 = require('crypto-js/sha256');
|
|
6
|
+
|
|
5
7
|
const makeStoreActions = require('./store');
|
|
6
8
|
const makeItemActions = require('./item');
|
|
7
9
|
const makeOrderActions = require('./order');
|
|
@@ -18,6 +20,7 @@ module.exports = session => {
|
|
|
18
20
|
utils,
|
|
19
21
|
localization,
|
|
20
22
|
_,
|
|
23
|
+
sha256,
|
|
21
24
|
moment,
|
|
22
25
|
constants,
|
|
23
26
|
};
|
package/lib/item/hasModifier.js
CHANGED
|
@@ -7,15 +7,22 @@ module.exports = ({ modifierActions }) =>
|
|
|
7
7
|
(groupPath.includes(modifier.modifierId) ||
|
|
8
8
|
groupPath.includes(modifier._id));
|
|
9
9
|
|
|
10
|
+
const isSpreadFrom = spreadFromId =>
|
|
11
|
+
spreadFromId &&
|
|
12
|
+
(spreadFromId === modifier.modifierId || spreadFromId === modifier._id);
|
|
13
|
+
|
|
10
14
|
if (modifierActions.isGroup(modifier)) {
|
|
11
15
|
const matchByRelatedModifier = item.modifiers.some(itemMod => {
|
|
12
16
|
if (
|
|
13
17
|
modifierActions.isGroup(itemMod) ||
|
|
14
18
|
!itemMod.properties ||
|
|
15
|
-
!itemMod.properties.groupPath
|
|
19
|
+
(!itemMod.properties.groupPath && !itemMod.properties.spreadFrom)
|
|
16
20
|
)
|
|
17
21
|
return false;
|
|
18
|
-
return
|
|
22
|
+
return (
|
|
23
|
+
isGroupPath(itemMod.properties.groupPath) ||
|
|
24
|
+
isSpreadFrom(itemMod.properties.spreadFrom)
|
|
25
|
+
);
|
|
19
26
|
});
|
|
20
27
|
|
|
21
28
|
const matchByRelatedItems =
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
module.exports = ({ sha256 }) => {
|
|
2
|
+
const csvToArray = input =>
|
|
3
|
+
input
|
|
4
|
+
.split(',')
|
|
5
|
+
.map(item => item.trim())
|
|
6
|
+
.filter(item => item !== '');
|
|
7
|
+
|
|
8
|
+
const cleanCSV = input => {
|
|
9
|
+
if (!input) return '';
|
|
10
|
+
return Array.from(
|
|
11
|
+
new Set(
|
|
12
|
+
input
|
|
13
|
+
.split(',')
|
|
14
|
+
.map(item => item.trim())
|
|
15
|
+
.filter(item => item !== '')
|
|
16
|
+
)
|
|
17
|
+
).join(',');
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
return function getManualModifiers({ modifier, relatedModifiers }) {
|
|
21
|
+
if (
|
|
22
|
+
!modifier ||
|
|
23
|
+
!modifier.properties ||
|
|
24
|
+
!modifier.properties.group ||
|
|
25
|
+
!modifier.properties.group.manualModifiers
|
|
26
|
+
)
|
|
27
|
+
return [];
|
|
28
|
+
|
|
29
|
+
const otherModifiers = Array.isArray(relatedModifiers)
|
|
30
|
+
? relatedModifiers
|
|
31
|
+
: [];
|
|
32
|
+
|
|
33
|
+
const manualModifiersCsv = modifier.properties.group.manualModifiers;
|
|
34
|
+
const modifiers = [];
|
|
35
|
+
|
|
36
|
+
if (manualModifiersCsv) {
|
|
37
|
+
const manualModifiersNames = csvToArray(
|
|
38
|
+
cleanCSV(manualModifiersCsv)
|
|
39
|
+
).filter(modName => otherModifiers.every(mod => mod.name !== modName));
|
|
40
|
+
|
|
41
|
+
modifiers.push(
|
|
42
|
+
...manualModifiersNames.map((each, index) => {
|
|
43
|
+
const hash = sha256(`${index}-${modifier._id}`).toString();
|
|
44
|
+
|
|
45
|
+
const _id = hash.substring(0, 24);
|
|
46
|
+
|
|
47
|
+
const manualModifier = {
|
|
48
|
+
name: each,
|
|
49
|
+
_id,
|
|
50
|
+
direct: true,
|
|
51
|
+
group: modifier.group,
|
|
52
|
+
properties: {
|
|
53
|
+
isManual: true,
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
return manualModifier;
|
|
58
|
+
})
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return modifiers;
|
|
63
|
+
};
|
|
64
|
+
};
|
package/lib/modifier/index.js
CHANGED
|
@@ -143,6 +143,9 @@ const isFixedOverride = require('./isFixedOverride');
|
|
|
143
143
|
const isLocked = require('./isLocked');
|
|
144
144
|
const hasAddModifier = require('./hasAddModifier');
|
|
145
145
|
const removeGroupRelations = require('./removeGroupRelations');
|
|
146
|
+
const getManualModifiers = require('./getManualModifiers');
|
|
147
|
+
const shouldSpreadModifier = require('./shouldSpreadModifier');
|
|
148
|
+
const spreadSingleGroupModifiers = require('./spreadSingleGroupModifiers');
|
|
146
149
|
|
|
147
150
|
const modifierActions = (deps = {}) => {
|
|
148
151
|
const actions = {};
|
|
@@ -299,6 +302,9 @@ const modifierActions = (deps = {}) => {
|
|
|
299
302
|
isLocked: isLocked(innerDeps),
|
|
300
303
|
hasAddModifier: hasAddModifier(innerDeps),
|
|
301
304
|
removeGroupRelations: removeGroupRelations(innerDeps),
|
|
305
|
+
getManualModifiers: getManualModifiers(innerDeps),
|
|
306
|
+
shouldSpreadModifier: shouldSpreadModifier(innerDeps),
|
|
307
|
+
spreadSingleGroupModifiers: spreadSingleGroupModifiers(innerDeps),
|
|
302
308
|
});
|
|
303
309
|
|
|
304
310
|
Object.keys(freezedActions).forEach(actionName => {
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
module.exports = ({ actions }) =>
|
|
2
|
+
function shouldSpreadModifier(modifier, all) {
|
|
3
|
+
return (
|
|
4
|
+
actions.isGroupOfModifiers(modifier) &&
|
|
5
|
+
!actions.enableAutoPopup(modifier) &&
|
|
6
|
+
!actions.isGroupOfItems(modifier) &&
|
|
7
|
+
modifier.group &&
|
|
8
|
+
!all.some(m => m._id !== modifier._id && m.group === modifier.group)
|
|
9
|
+
);
|
|
10
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module.exports = ({ actions }) =>
|
|
2
|
+
function spreadSingleGroupModifiers(modifiersParam) {
|
|
3
|
+
const result = [];
|
|
4
|
+
|
|
5
|
+
if (!Array.isArray(modifiersParam)) return [];
|
|
6
|
+
|
|
7
|
+
modifiersParam.forEach(modifier => {
|
|
8
|
+
if (actions.shouldSpreadModifier(modifier, modifiersParam)) {
|
|
9
|
+
const relatedModifiers = actions.getGroupRelatedModifiers({
|
|
10
|
+
modifier,
|
|
11
|
+
});
|
|
12
|
+
const manual = actions.getManualModifiers({
|
|
13
|
+
modifier,
|
|
14
|
+
relatedModifiers,
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
const nextModifiers = [...relatedModifiers, ...manual].map(mod => ({
|
|
18
|
+
...mod,
|
|
19
|
+
properties: {
|
|
20
|
+
...(mod.properties || {}),
|
|
21
|
+
spreadFrom: modifier._id,
|
|
22
|
+
},
|
|
23
|
+
}));
|
|
24
|
+
result.push(...nextModifiers);
|
|
25
|
+
} else {
|
|
26
|
+
result.push(modifier);
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
return result;
|
|
30
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@darkpos/pricing",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.75",
|
|
4
4
|
"description": "Pricing calculator",
|
|
5
5
|
"author": "Dark POS",
|
|
6
6
|
"license": "ISC",
|
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@darkpos/utils": "^1.0.11",
|
|
37
|
+
"crypto-js": "^4.2.0",
|
|
37
38
|
"lodash": "^4.17.21",
|
|
38
39
|
"moment-timezone": "^0.5.34"
|
|
39
40
|
},
|
|
@@ -50,5 +51,5 @@
|
|
|
50
51
|
"supertest": "^6.2.3",
|
|
51
52
|
"supervisor": "^0.12.0"
|
|
52
53
|
},
|
|
53
|
-
"gitHead": "
|
|
54
|
+
"gitHead": "b0331c1d450926e0feb4f79146c6dd4f81e5af61"
|
|
54
55
|
}
|