@softwear/latestcollectioncore 1.0.63 → 1.0.65

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.
@@ -14,7 +14,7 @@ const mappingPairs = [
14
14
  { category: 'CustomSize', from: 'sizeSupplier', to: '_customsize' },
15
15
  { category: 'Size', from: 'sizeSupplier', to: 'size' },
16
16
  { category: 'Gender', from: 'articleGroupSupplier', to: '_gender', mustMatch: true },
17
- { category: 'ERM', from: ['_gender', 'articleGroup'], to: '_erm-code', mustMatch: true },
17
+ { category: 'ERM', from: ['_gender', 'articleGroup'], to: '_erm-code', mustMatch: true, defaultMappingSource: 'ermmapping' },
18
18
  ];
19
19
  const evaluateFromExpr = function (sku, from) {
20
20
  if (typeof from == 'string')
@@ -22,34 +22,16 @@ const evaluateFromExpr = function (sku, from) {
22
22
  return from.map((field) => sku[field] || '').join('.');
23
23
  };
24
24
  function default_1(brands, strategy) {
25
- // Helper function to convert all mapping rules for given category to an indexed object
26
- const indexedMapping = function (propertyMapping, category) {
27
- const filteredMappings = propertyMapping.filter((mapping) => mapping.category == category && mapping.from != undefined);
28
- if (filteredMappings.length == 0)
29
- return undefined;
30
- return filteredMappings.reduce((acc, item) => {
31
- acc[item.from] = item.to;
32
- return acc;
33
- }, {});
34
- };
35
- // Helper function to convert all mapping rules to an indexed object
36
- const indexFn = function (propertyMapping) {
37
- if (!propertyMapping)
38
- return {};
39
- const maps = {};
40
- index_1.MAPPING_CATEGORIES.forEach((category) => {
41
- const map = indexedMapping(propertyMapping, category);
42
- if (map !== undefined)
43
- maps[category] = map;
25
+ const indexedByBrandPropertyMapping = {};
26
+ brands.forEach(({ id, propertyMapping }) => {
27
+ if (!indexedByBrandPropertyMapping[id])
28
+ indexedByBrandPropertyMapping[id] = {};
29
+ propertyMapping === null || propertyMapping === void 0 ? void 0 : propertyMapping.forEach((mapping) => {
30
+ if (!indexedByBrandPropertyMapping[id][mapping.category])
31
+ indexedByBrandPropertyMapping[id][mapping.category] = {};
32
+ indexedByBrandPropertyMapping[id][mapping.category][mapping.from] = mapping.to;
44
33
  });
45
- return maps;
46
- };
47
- const indexedByBrandPropertyMapping = brands.reduce((acc, item) => {
48
- if (!acc[item.id])
49
- acc[item.id] = {};
50
- Object.assign(acc[item.id], indexFn(item.propertyMapping));
51
- return acc;
52
- }, {});
34
+ });
53
35
  if (strategy == 'clean')
54
36
  return function (sku) {
55
37
  const brand = sku.BRANDHASH || (0, index_1.hashBrand)(sku.brand);
@@ -72,7 +54,7 @@ function default_1(brands, strategy) {
72
54
  mappingPairs.forEach((pair) => {
73
55
  var _a, _b, _c, _d, _e;
74
56
  const from = evaluateFromExpr(sku, pair.from) || '';
75
- const redirectedMappingSource = (_a = mapping === null || mapping === void 0 ? void 0 : mapping[pair.category]) === null || _a === void 0 ? void 0 : _a['~~'];
57
+ const redirectedMappingSource = ((_a = mapping === null || mapping === void 0 ? void 0 : mapping[pair.category]) === null || _a === void 0 ? void 0 : _a['~~']) || pair.defaultMappingSource;
76
58
  const redirectedMapping = redirectedMappingSource ? indexedByBrandPropertyMapping[redirectedMappingSource] : {};
77
59
  const to = ((_b = mapping === null || mapping === void 0 ? void 0 : mapping[pair.category]) === null || _b === void 0 ? void 0 : _b[from]) || ((_c = mapping === null || mapping === void 0 ? void 0 : mapping[pair.category]) === null || _c === void 0 ? void 0 : _c['']) || ((_d = redirectedMapping === null || redirectedMapping === void 0 ? void 0 : redirectedMapping[pair.category]) === null || _d === void 0 ? void 0 : _d[from]) || ((_e = redirectedMapping === null || redirectedMapping === void 0 ? void 0 : redirectedMapping[pair.category]) === null || _e === void 0 ? void 0 : _e['']);
78
60
  if (to == undefined)
@@ -88,7 +70,7 @@ function default_1(brands, strategy) {
88
70
  if (sku[pair.to])
89
71
  return; // Do not replace sku-level-user-supplied values
90
72
  const from = evaluateFromExpr(sku, pair.from);
91
- const redirectedMappingSource = (_a = mapping === null || mapping === void 0 ? void 0 : mapping[pair.category]) === null || _a === void 0 ? void 0 : _a['~~'];
73
+ const redirectedMappingSource = ((_a = mapping === null || mapping === void 0 ? void 0 : mapping[pair.category]) === null || _a === void 0 ? void 0 : _a['~~']) || pair.defaultMappingSource;
92
74
  const redirectedMapping = redirectedMappingSource ? indexedByBrandPropertyMapping[redirectedMappingSource] : {};
93
75
  const to = ((_b = mapping === null || mapping === void 0 ? void 0 : mapping[pair.category]) === null || _b === void 0 ? void 0 : _b[from]) || ((_c = mapping === null || mapping === void 0 ? void 0 : mapping[pair.category]) === null || _c === void 0 ? void 0 : _c['']) || ((_d = redirectedMapping === null || redirectedMapping === void 0 ? void 0 : redirectedMapping[pair.category]) === null || _d === void 0 ? void 0 : _d[from]) || ((_e = redirectedMapping === null || redirectedMapping === void 0 ? void 0 : redirectedMapping[pair.category]) === null || _e === void 0 ? void 0 : _e['']);
94
76
  if (!from && !to)
package/dist/types.d.ts CHANGED
@@ -191,6 +191,11 @@ interface ProductI {
191
191
  warehouseLocation: string;
192
192
  year?: string;
193
193
  }
194
+ interface PropertyMappingI {
195
+ category: string;
196
+ from: string;
197
+ to: string;
198
+ }
194
199
  interface BrandSettingI {
195
200
  id: string;
196
201
  name: string;
@@ -211,7 +216,7 @@ interface BrandSettingI {
211
216
  whiteListTenants?: string[];
212
217
  associates?: object[];
213
218
  authGroups?: string[];
214
- propertyMapping?: object[];
219
+ propertyMapping?: PropertyMappingI[];
215
220
  fashionCloudId?: string;
216
221
  }
217
222
  declare enum mappingStrategyE {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@softwear/latestcollectioncore",
3
- "version": "1.0.63",
3
+ "version": "1.0.65",
4
4
  "description": "Core functions for LatestCollections applications",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,4 +1,4 @@
1
- import { hashBrand, SkuI, MAPPING_CATEGORIES, BrandSettingI, mappingStrategyE } from './index'
1
+ import { hashBrand, SkuI, BrandSettingI, mappingStrategyE } from './index'
2
2
 
3
3
  // The order of the following mappingPairs is significant.
4
4
  // The ERM mapping relies on the Gender and ProductGroup mapping to have been evaluated first
@@ -13,40 +13,31 @@ const mappingPairs = [
13
13
  { category: 'CustomSize', from: 'sizeSupplier', to: '_customsize' },
14
14
  { category: 'Size', from: 'sizeSupplier', to: 'size' },
15
15
  { category: 'Gender', from: 'articleGroupSupplier', to: '_gender', mustMatch: true },
16
- { category: 'ERM', from: ['_gender', 'articleGroup'], to: '_erm-code', mustMatch: true },
16
+ { category: 'ERM', from: ['_gender', 'articleGroup'], to: '_erm-code', mustMatch: true, defaultMappingSource: 'ermmapping' },
17
17
  ]
18
18
 
19
19
  const evaluateFromExpr = function (sku: SkuI, from: string | string[]): string {
20
20
  if (typeof from == 'string') return sku[from]
21
21
  return from.map((field) => sku[field] || '').join('.')
22
22
  }
23
- export default function (brands: Array<BrandSettingI>, strategy: mappingStrategyE): (sku: SkuI) => SkuI {
24
- // Helper function to convert all mapping rules for given category to an indexed object
25
- const indexedMapping = function (propertyMapping, category) {
26
- const filteredMappings = propertyMapping.filter((mapping) => mapping.category == category && mapping.from != undefined)
27
23
 
28
- if (filteredMappings.length == 0) return undefined
29
- return filteredMappings.reduce((acc, item) => {
30
- acc[item.from] = item.to
31
- return acc
32
- }, {})
33
- }
34
- // Helper function to convert all mapping rules to an indexed object
35
- const indexFn = function (propertyMapping) {
36
- if (!propertyMapping) return {}
37
- const maps = {}
38
- MAPPING_CATEGORIES.forEach((category) => {
39
- const map = indexedMapping(propertyMapping, category)
40
- if (map !== undefined) maps[category] = map
41
- })
42
- return maps
24
+ interface propertyMappingI {
25
+ [brandId: string]: {
26
+ [category: string]: {
27
+ [from: string]: string
28
+ }
43
29
  }
44
- const indexedByBrandPropertyMapping = brands.reduce((acc, item) => {
45
- if (!acc[item.id]) acc[item.id] = {}
46
- Object.assign(acc[item.id], indexFn(item.propertyMapping))
47
- return acc
48
- }, {})
30
+ }
49
31
 
32
+ export default function (brands: Array<BrandSettingI>, strategy: mappingStrategyE): (sku: SkuI) => SkuI {
33
+ const indexedByBrandPropertyMapping = {} as propertyMappingI
34
+ brands.forEach(({ id, propertyMapping }) => {
35
+ if (!indexedByBrandPropertyMapping[id]) indexedByBrandPropertyMapping[id] = {}
36
+ propertyMapping?.forEach((mapping) => {
37
+ if (!indexedByBrandPropertyMapping[id][mapping.category]) indexedByBrandPropertyMapping[id][mapping.category] = {}
38
+ indexedByBrandPropertyMapping[id][mapping.category][mapping.from] = mapping.to
39
+ })
40
+ })
50
41
  if (strategy == 'clean')
51
42
  return function (sku: SkuI): SkuI {
52
43
  const brand = sku.BRANDHASH || hashBrand(sku.brand)
@@ -65,7 +56,7 @@ export default function (brands: Array<BrandSettingI>, strategy: mappingStrategy
65
56
  const mapping = indexedByBrandPropertyMapping[brand]
66
57
  mappingPairs.forEach((pair) => {
67
58
  const from = evaluateFromExpr(sku, pair.from) || ''
68
- const redirectedMappingSource = mapping?.[pair.category]?.['~~']
59
+ const redirectedMappingSource = mapping?.[pair.category]?.['~~'] || pair.defaultMappingSource
69
60
  const redirectedMapping = redirectedMappingSource ? indexedByBrandPropertyMapping[redirectedMappingSource] : {}
70
61
 
71
62
  const to = mapping?.[pair.category]?.[from] || mapping?.[pair.category]?.[''] || redirectedMapping?.[pair.category]?.[from] || redirectedMapping?.[pair.category]?.['']
@@ -79,7 +70,7 @@ export default function (brands: Array<BrandSettingI>, strategy: mappingStrategy
79
70
  mappingPairs.forEach((pair) => {
80
71
  if (sku[pair.to]) return // Do not replace sku-level-user-supplied values
81
72
  const from = evaluateFromExpr(sku, pair.from)
82
- const redirectedMappingSource = mapping?.[pair.category]?.['~~']
73
+ const redirectedMappingSource = mapping?.[pair.category]?.['~~'] || pair.defaultMappingSource
83
74
  const redirectedMapping = redirectedMappingSource ? indexedByBrandPropertyMapping[redirectedMappingSource] : {}
84
75
 
85
76
  const to = mapping?.[pair.category]?.[from] || mapping?.[pair.category]?.[''] || redirectedMapping?.[pair.category]?.[from] || redirectedMapping?.[pair.category]?.['']
package/src/types.ts CHANGED
@@ -204,6 +204,11 @@ interface ProductI {
204
204
  year?: string
205
205
  }
206
206
 
207
+ interface PropertyMappingI {
208
+ category: string
209
+ from: string
210
+ to: string
211
+ }
207
212
  interface BrandSettingI {
208
213
  id: string
209
214
  name: string
@@ -224,7 +229,7 @@ interface BrandSettingI {
224
229
  whiteListTenants?: string[]
225
230
  associates?: object[]
226
231
  authGroups?: string[]
227
- propertyMapping?: object[]
232
+ propertyMapping?: PropertyMappingI[]
228
233
  fashionCloudId?: string
229
234
  }
230
235
 
@@ -233,6 +238,7 @@ enum mappingStrategyE {
233
238
  CLEAN = 'clean',
234
239
  MARK = 'markMissingMapping',
235
240
  }
241
+
236
242
  export {
237
243
  RowI,
238
244
  StockTransferSelectionI,
@@ -107,6 +107,16 @@ const skus = [
107
107
  collection: '22zomer',
108
108
  _customsize: 'medium',
109
109
  },
110
+ {
111
+ id: '1234567890138',
112
+ articleGroupSupplier: '11111',
113
+ brand: 'gstar',
114
+ collectionSupplier: 'SUMMER 2022',
115
+ colorCodeSupplier: '200',
116
+ colorFamily: 'Blue',
117
+ size: 'L',
118
+ sizeSupplier: 'L',
119
+ },
110
120
  ]
111
121
 
112
122
  const articleGroupMapping = [
@@ -190,6 +200,36 @@ const fallbackMapping = [
190
200
  ],
191
201
  },
192
202
  ]
203
+
204
+ const stackedMapping = [
205
+ {
206
+ id: 'gstar',
207
+ comment: 'LatestCollection level mapping',
208
+ propertyMapping: [
209
+ {
210
+ category: 'ProductGroup',
211
+ from: '12345',
212
+ to: 'LAT-articleGroupMapping',
213
+ },
214
+ {
215
+ category: 'ProductGroup',
216
+ from: '11111',
217
+ to: 'LAT-articleGroupMapping',
218
+ },
219
+ ],
220
+ },
221
+ {
222
+ id: 'gstar',
223
+ comment: 'Tenant level mapping',
224
+ propertyMapping: [
225
+ {
226
+ category: 'ProductGroup',
227
+ from: '12345',
228
+ to: 'TENANT-articleGroupMapping',
229
+ },
230
+ ],
231
+ },
232
+ ]
193
233
  describe('applyPropertyMapping', () => {
194
234
  it('returns empty array on an empty array', function () {
195
235
  expect(applyPropertyMapping([], []).length).to.equal(0)
@@ -345,4 +385,10 @@ describe('applyPropertyMapping', () => {
345
385
  expect(cleanedSkus[9]._customsize).to.equal(undefined)
346
386
  expect(cleanedSkus[9].collection).to.equal(undefined)
347
387
  })
388
+
389
+ it('applies mapping from different sources', function () {
390
+ const mappedSkus = applyPropertyMapping(deepCopy(skus), stackedMapping)
391
+ expect(mappedSkus[6].articleGroup).to.equal('TENANT-articleGroupMapping')
392
+ expect(mappedSkus[10].articleGroup).to.equal('LAT-articleGroupMapping')
393
+ })
348
394
  })