@contrail/flexplm 1.7.8 → 1.8.0-alpha.0261c7e
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/README.md +19 -1
- package/lib/interfaces/mapping-file.d.ts +9 -0
- package/lib/util/type-conversion-utils.d.ts +19 -0
- package/lib/util/type-conversion-utils.js +50 -0
- package/lib/util/type-conversion-utils.spec.js +122 -0
- package/lib/util/type-defaults.d.ts +12 -0
- package/lib/util/type-defaults.js +34 -5
- package/lib/util/type-defaults.spec.js +111 -0
- package/lib/util/type-utils.js +3 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1 +1,19 @@
|
|
|
1
|
-
Core model for contrail, which establishes the base peristence services (without dependency on a persistence implementaiton) and core NestJS elements such as the InvocationContext.
|
|
1
|
+
Core model for contrail, which establishes the base peristence services (without dependency on a persistence implementaiton) and core NestJS elements such as the InvocationContext.
|
|
2
|
+
|
|
3
|
+
## LCSCountry defaults
|
|
4
|
+
`LCSCountry` <-> VibeIQ `custom-entity:country` works with built-in defaults for the type mapping. The built-in conventions are:
|
|
5
|
+
|
|
6
|
+
| Item | Default |
|
|
7
|
+
|---|---|
|
|
8
|
+
| VibeIQ type path | `custom-entity:country` (case-insensitive) |
|
|
9
|
+
| FlexPLM class / type path | `LCSCountry` / `Country` |
|
|
10
|
+
| Identifier property | `vibeIQIdentifier` (same key in both systems; no rekey runs without a mapping) |
|
|
11
|
+
| Informational property | `name` |
|
|
12
|
+
|
|
13
|
+
A mapping section for `LCSCountry` overrides any of these. The mapping section must also declare which system creates Countries, with the existing creation gates (there is no default; if it is not declared, the app treats Country as read-only):
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
LCSCountry: { isInboundCreatable: () => true, isOutboundCreatable: () => false }, // FlexPLM creates
|
|
17
|
+
LCSCountry: { isInboundCreatable: () => false, isOutboundCreatable: () => true }, // VibeIQ creates
|
|
18
|
+
```
|
|
19
|
+
Read the declared origin with `TypeConversionUtils.getOriginSystem(...)`.
|
|
@@ -340,6 +340,13 @@ export interface MappingSection {
|
|
|
340
340
|
* update existing entities.
|
|
341
341
|
* - Conditional — inspect the row and allow / disallow per record.
|
|
342
342
|
*
|
|
343
|
+
* On the **`LCSCountry`** section this pair declares which system creates
|
|
344
|
+
* Countries: `isInboundCreatable: () => true` together with
|
|
345
|
+
* `isOutboundCreatable: () => false` means FlexPLM creates them (the
|
|
346
|
+
* reverse pair means VibeIQ creates them). Both functions must be present
|
|
347
|
+
* and opposite; otherwise the origin is undeclared and the connector treats
|
|
348
|
+
* Country as read-only. See `TypeConversionUtils.getOriginSystem`.
|
|
349
|
+
*
|
|
343
350
|
* On the **season-link** sections (`LCSProductSeasonLink` /
|
|
344
351
|
* `LCSSKUSeasonLink`), `() => true` enables the add-to-project
|
|
345
352
|
* flow: FlexPLM-driven inbound events can add an item to a Vibe
|
|
@@ -707,6 +714,7 @@ interface MappingFileBase {
|
|
|
707
714
|
* | `item` | `LCSProduct` / `LCSSKU` | Syncs once `lifecycleStage` is out of `concept`. Sends Primary Viewable as the thumbnail (no other images). Creates `LCSProduct` / `LCSSKU` if missing; auto-retries `LCSSKU` creation when the parent `LCSProduct` isn't ready yet. |
|
|
708
715
|
* | `color` | `LCSColor` | Syncs on create / update. Sends Primary Viewable as the thumbnail. Creates `LCSColor` if missing. |
|
|
709
716
|
* | `custom-entity` | `LCSRevisableEntity` | Syncs on create / update. Creates `LCSRevisableEntity` if missing. Workflows should gate on the custom-entity subtype so only the intended subtypes publish. |
|
|
717
|
+
* | `custom-entity` (`custom-entity:country`) | `LCSCountry` | Built-in defaults for type path (`Country`), identifier (`vibeIQIdentifier`, same key in both systems) and name; the mapping section overrides each default and **must** declare the origin. Which system creates Countries is declared in the `LCSCountry` mapping section with the `isInboundCreatable` / `isOutboundCreatable` pair: `(true, false)` = FlexPLM creates, `(false, true)` = VibeIQ creates; anything else is undeclared. See `TypeConversionUtils.getOriginSystem`. |
|
|
710
718
|
* | `project-item` | `LCSProductSeasonLink` / `LCSSKUSeasonLink` | Syncs on plan publish. Requires the assortment to have `publishToFlexPLM=true` and `flexPLMSeasonName` set. Adds the Product / SKU to the `LCSSeason` if not already linked. Only project-items changed since the last publish are sent (configurable to reach further back). Processing on the FlexPLM side is async via a Windchill Queue. |
|
|
711
719
|
* | `item:material` | `LCSMaterial` | Supported via custom mapping section + `typeConversion`. Route `item:material` typePath to a mapping section that declares `getClass: () => 'LCSMaterial'` and `getSoftType: () => 'Material'`. See {@link TypeConversion} for the `LCSMaterial.processAsItem` config flag that pairs with this. |
|
|
712
720
|
* | `custom-entity` | `LCSLast` / `LCSLifecycleManaged` | **Not yet supported.** |
|
|
@@ -724,6 +732,7 @@ interface MappingFileBase {
|
|
|
724
732
|
* | `LCSLifecycleManaged` | `custom-entity` | Configurable to create new custom-entities; updates existing. |
|
|
725
733
|
* | `LCSMaterial` | `custom-entity` (default) or `item:material` | Default: custom-entity. To route to `item:material` instead, set `{ "LCSMaterial": { "processAsItem": true } }` in the connector app config and write a mapping section with `getClass: () => 'item'` + `getSoftType: () => 'item:material'`. Wire it via `flex2vibe.LCSMaterial.getMapKey` returning that section's name. |
|
|
726
734
|
* | `LCSRevisableEntity` | `custom-entity` | Configurable to create new custom-entities; updates existing. |
|
|
735
|
+
* | `LCSCountry` | `custom-entity` (`custom-entity:country`) | Built-in defaults for type path and identifier; the mapping section must declare the origin. Identifier `vibeIQIdentifier` (same key in both systems). Creation is allowed only when the `LCSCountry` section declares FlexPLM as the origin: `isInboundCreatable: () => true` and `isOutboundCreatable: () => false`. |
|
|
727
736
|
* | (any) | `item` (direct, no link) | **Not yet supported.** |
|
|
728
737
|
*
|
|
729
738
|
* @example
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { MapFileUtil } from '@contrail/transform-data';
|
|
2
|
+
/** The system that originates (creates) an entity type: 'flexplm' or 'vibeiq'. */
|
|
3
|
+
export type OriginSystem = 'flexplm' | 'vibeiq';
|
|
2
4
|
/** This class is helper functions to get the data for converting
|
|
3
5
|
* VibeIQ entities to / from FlexPLM Objects
|
|
4
6
|
*/
|
|
@@ -147,6 +149,23 @@ export declare class TypeConversionUtils {
|
|
|
147
149
|
static getMapKeyFromObject(fileId: any, mapFileUtil: MapFileUtil, object: any, direction: string): Promise<string | undefined>;
|
|
148
150
|
static isInboundCreatableFromObject(fileId: string, mapFileUtil: MapFileUtil, object: any, context?: any): Promise<boolean>;
|
|
149
151
|
static isOutboundCreatableFromEntity(fileId: string, mapFileUtil: MapFileUtil, entity: any, context?: any): Promise<boolean>;
|
|
152
|
+
/** Returns which system originates (creates) an entity type, declared in its mapping section
|
|
153
|
+
* with the isInboundCreatable / isOutboundCreatable pair:
|
|
154
|
+
* - isInboundCreatable true and isOutboundCreatable false -> 'flexplm' (FlexPLM creates)
|
|
155
|
+
* - isInboundCreatable false and isOutboundCreatable true -> 'vibeiq' (VibeIQ creates)
|
|
156
|
+
* Anything else is undeclared and returns undefined: no mapping file, no section, either function
|
|
157
|
+
* missing, both true, both false, or an error while resolving. Unlike isInboundCreatableFromObject /
|
|
158
|
+
* isOutboundCreatableFromEntity, there are NO defaults: the origin must be stated explicitly,
|
|
159
|
+
* so callers can fail safe (treat the entity as read-only) when it is not.
|
|
160
|
+
*
|
|
161
|
+
* @param fileId id for mapFile
|
|
162
|
+
* @param mapFileUtil class to get mapfile
|
|
163
|
+
* @param entityOrObject VibeIQ entity (vibe2flex) or FlexPLM object (flex2vibe)
|
|
164
|
+
* @param direction VIBE2FLEX_DIRECTION or FLEX2VIBE_DIRECTION; selects how the map section key is resolved
|
|
165
|
+
* @param context optional context object passed to the mapping functions
|
|
166
|
+
* @returns Promise<'flexplm' | 'vibeiq' | undefined>
|
|
167
|
+
*/
|
|
168
|
+
static getOriginSystem(fileId: string, mapFileUtil: MapFileUtil, entityOrObject: any, direction: string, context?: any): Promise<OriginSystem | undefined>;
|
|
150
169
|
/** Takes in a FlexPLM object and determines whether inbound
|
|
151
170
|
* images should be synced. In most cases, the creation owning system
|
|
152
171
|
* will also control image syncing. Defaults to false if no mapping exists.
|
|
@@ -143,6 +143,11 @@ class TypeConversionUtils {
|
|
|
143
143
|
const mappingData = await mapFileUtil.getMappingSection(transformMapFile, 'typeConversion', direction);
|
|
144
144
|
if (mappingData && mappingData[type] && mappingData[type]['getMapKey']) {
|
|
145
145
|
const mapKey = await mappingData[type]['getMapKey'](entity);
|
|
146
|
+
// An org's custom-entity routing usually returns '' for the subtypes it does not list.
|
|
147
|
+
// Country has a built-in section key, so its section is found without a typeConversion entry.
|
|
148
|
+
if (!mapKey && type_defaults_1.TypeDefaults.isCountryEntity(entity)) {
|
|
149
|
+
return type_defaults_1.TypeDefaults.COUNTRY_OBJECT_CLASS;
|
|
150
|
+
}
|
|
146
151
|
return mapKey;
|
|
147
152
|
}
|
|
148
153
|
}
|
|
@@ -360,6 +365,51 @@ class TypeConversionUtils {
|
|
|
360
365
|
}
|
|
361
366
|
return isOutboundCreatable;
|
|
362
367
|
}
|
|
368
|
+
/** Returns which system originates (creates) an entity type, declared in its mapping section
|
|
369
|
+
* with the isInboundCreatable / isOutboundCreatable pair:
|
|
370
|
+
* - isInboundCreatable true and isOutboundCreatable false -> 'flexplm' (FlexPLM creates)
|
|
371
|
+
* - isInboundCreatable false and isOutboundCreatable true -> 'vibeiq' (VibeIQ creates)
|
|
372
|
+
* Anything else is undeclared and returns undefined: no mapping file, no section, either function
|
|
373
|
+
* missing, both true, both false, or an error while resolving. Unlike isInboundCreatableFromObject /
|
|
374
|
+
* isOutboundCreatableFromEntity, there are NO defaults: the origin must be stated explicitly,
|
|
375
|
+
* so callers can fail safe (treat the entity as read-only) when it is not.
|
|
376
|
+
*
|
|
377
|
+
* @param fileId id for mapFile
|
|
378
|
+
* @param mapFileUtil class to get mapfile
|
|
379
|
+
* @param entityOrObject VibeIQ entity (vibe2flex) or FlexPLM object (flex2vibe)
|
|
380
|
+
* @param direction VIBE2FLEX_DIRECTION or FLEX2VIBE_DIRECTION; selects how the map section key is resolved
|
|
381
|
+
* @param context optional context object passed to the mapping functions
|
|
382
|
+
* @returns Promise<'flexplm' | 'vibeiq' | undefined>
|
|
383
|
+
*/
|
|
384
|
+
static async getOriginSystem(fileId, mapFileUtil, entityOrObject, direction, context) {
|
|
385
|
+
if (!fileId || !entityOrObject) {
|
|
386
|
+
return undefined;
|
|
387
|
+
}
|
|
388
|
+
try {
|
|
389
|
+
const mapKey = (TypeConversionUtils.VIBE2FLEX_DIRECTION === direction)
|
|
390
|
+
? await this.getMapKey(fileId, mapFileUtil, entityOrObject, direction)
|
|
391
|
+
: await this.getMapKeyFromObject(fileId, mapFileUtil, entityOrObject, direction);
|
|
392
|
+
if (!mapKey) {
|
|
393
|
+
return undefined;
|
|
394
|
+
}
|
|
395
|
+
const mapData = await map_utils_1.MapUtil.getFullMapSection(fileId, mapFileUtil, mapKey);
|
|
396
|
+
if (!mapData || typeof mapData['isInboundCreatable'] !== 'function' || typeof mapData['isOutboundCreatable'] !== 'function') {
|
|
397
|
+
return undefined;
|
|
398
|
+
}
|
|
399
|
+
const inbound = !!(await mapData['isInboundCreatable'](entityOrObject, context));
|
|
400
|
+
const outbound = !!(await mapData['isOutboundCreatable'](entityOrObject, context));
|
|
401
|
+
if (inbound && !outbound) {
|
|
402
|
+
return 'flexplm';
|
|
403
|
+
}
|
|
404
|
+
if (!inbound && outbound) {
|
|
405
|
+
return 'vibeiq';
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
catch (e) {
|
|
409
|
+
console.error('TypeConversionUtils.getOriginSystem: unable to read the origin from the mapping file: ' + e?.message);
|
|
410
|
+
}
|
|
411
|
+
return undefined;
|
|
412
|
+
}
|
|
363
413
|
/** Takes in a FlexPLM object and determines whether inbound
|
|
364
414
|
* images should be synced. In most cases, the creation owning system
|
|
365
415
|
* will also control image syncing. Defaults to false if no mapping exists.
|
|
@@ -924,4 +924,126 @@ describe('conversion-utils', () => {
|
|
|
924
924
|
expect(results).toBeTruthy();
|
|
925
925
|
});
|
|
926
926
|
});
|
|
927
|
+
describe('Country with no mapping section (SDK defaults)', () => {
|
|
928
|
+
const mapFileUtil = new transform_data_1.MapFileUtil(new sdk_1.Entities());
|
|
929
|
+
const mapWithoutCountry = {
|
|
930
|
+
typeConversion: {
|
|
931
|
+
vibe2flex: { 'custom-entity': { getMapKey: () => '' } },
|
|
932
|
+
flex2vibe: {}
|
|
933
|
+
}
|
|
934
|
+
};
|
|
935
|
+
let spy;
|
|
936
|
+
beforeEach(() => {
|
|
937
|
+
spy = jest.spyOn(mapFileUtil, 'getMapFile').mockImplementation(async () => mapWithoutCountry);
|
|
938
|
+
});
|
|
939
|
+
afterEach(() => {
|
|
940
|
+
spy.mockRestore();
|
|
941
|
+
});
|
|
942
|
+
it('VibeIQ -> FlexPLM uses defaults', async () => {
|
|
943
|
+
const entity = { entityType: 'custom-entity', typePath: 'custom-entity:country' };
|
|
944
|
+
expect(await type_conversion_utils_1.TypeConversionUtils.getObjectClass(TRANSFORM_MAP_FILE, mapFileUtil, entity)).toEqual('LCSCountry');
|
|
945
|
+
expect(await type_conversion_utils_1.TypeConversionUtils.getObjectTypePath(TRANSFORM_MAP_FILE, mapFileUtil, entity)).toEqual('Country');
|
|
946
|
+
expect(await type_conversion_utils_1.TypeConversionUtils.getIdentifierProperties(TRANSFORM_MAP_FILE, mapFileUtil, entity)).toEqual(['vibeIQIdentifier']);
|
|
947
|
+
expect(await type_conversion_utils_1.TypeConversionUtils.getInformationalProperties(TRANSFORM_MAP_FILE, mapFileUtil, entity)).toEqual(['name']);
|
|
948
|
+
});
|
|
949
|
+
it('FlexPLM -> VibeIQ uses defaults', async () => {
|
|
950
|
+
const object = { flexPLMObjectClass: 'LCSCountry', flexPLMTypePath: 'Country' };
|
|
951
|
+
expect(await type_conversion_utils_1.TypeConversionUtils.getMapKeyFromObject(TRANSFORM_MAP_FILE, mapFileUtil, object, type_conversion_utils_1.TypeConversionUtils.FLEX2VIBE_DIRECTION)).toEqual('LCSCountry');
|
|
952
|
+
expect(await type_conversion_utils_1.TypeConversionUtils.getEntityClassFromObject(TRANSFORM_MAP_FILE, mapFileUtil, object)).toEqual('custom-entity');
|
|
953
|
+
expect(await type_conversion_utils_1.TypeConversionUtils.getEntityTypePathFromObject(TRANSFORM_MAP_FILE, mapFileUtil, object)).toEqual('custom-entity:country');
|
|
954
|
+
expect(await type_conversion_utils_1.TypeConversionUtils.getIdentifierPropertiesFromObject(TRANSFORM_MAP_FILE, mapFileUtil, object)).toEqual(['vibeIQIdentifier']);
|
|
955
|
+
expect(await type_conversion_utils_1.TypeConversionUtils.getInformationalPropertiesFromObject(TRANSFORM_MAP_FILE, mapFileUtil, object)).toEqual(['name']);
|
|
956
|
+
});
|
|
957
|
+
it('a mapping section still overrides the defaults', async () => {
|
|
958
|
+
const overriding = {
|
|
959
|
+
typeConversion: { vibe2flex: { 'custom-entity': { getMapKey: () => 'LCSCountry' } }, flex2vibe: {} },
|
|
960
|
+
LCSCountry: { getIdentifierProperties: () => ['isoCode'] }
|
|
961
|
+
};
|
|
962
|
+
spy.mockImplementation(async () => overriding);
|
|
963
|
+
const entity = { entityType: 'custom-entity', typePath: 'custom-entity:country' };
|
|
964
|
+
expect(await type_conversion_utils_1.TypeConversionUtils.getIdentifierProperties(TRANSFORM_MAP_FILE, mapFileUtil, entity)).toEqual(['isoCode']);
|
|
965
|
+
});
|
|
966
|
+
});
|
|
967
|
+
describe('getOriginSystem (isInboundCreatable / isOutboundCreatable pair)', () => {
|
|
968
|
+
const mapFileUtil = new transform_data_1.MapFileUtil(new sdk_1.Entities());
|
|
969
|
+
const countryEntity = { entityType: 'custom-entity', typePath: 'custom-entity:country' };
|
|
970
|
+
const countryObject = { flexPLMObjectClass: 'LCSCountry', flexPLMTypePath: 'Country' };
|
|
971
|
+
let spy;
|
|
972
|
+
// Org-style routing: custom-entity subtypes that are not listed return ''
|
|
973
|
+
const typeConversion = {
|
|
974
|
+
vibe2flex: { 'custom-entity': { getMapKey: () => '' } },
|
|
975
|
+
flex2vibe: {},
|
|
976
|
+
};
|
|
977
|
+
function useMap(countrySection) {
|
|
978
|
+
const map = { typeConversion };
|
|
979
|
+
if (countrySection) {
|
|
980
|
+
map.LCSCountry = countrySection;
|
|
981
|
+
}
|
|
982
|
+
spy.mockImplementation(async () => map);
|
|
983
|
+
}
|
|
984
|
+
beforeEach(() => {
|
|
985
|
+
spy = jest.spyOn(mapFileUtil, 'getMapFile');
|
|
986
|
+
});
|
|
987
|
+
afterEach(() => {
|
|
988
|
+
spy.mockRestore();
|
|
989
|
+
});
|
|
990
|
+
it("is 'flexplm' when inbound is creatable and outbound is not (both directions)", async () => {
|
|
991
|
+
useMap({ isInboundCreatable: () => true, isOutboundCreatable: () => false });
|
|
992
|
+
expect(await type_conversion_utils_1.TypeConversionUtils.getOriginSystem(TRANSFORM_MAP_FILE, mapFileUtil, countryEntity, type_conversion_utils_1.TypeConversionUtils.VIBE2FLEX_DIRECTION)).toBe('flexplm');
|
|
993
|
+
expect(await type_conversion_utils_1.TypeConversionUtils.getOriginSystem(TRANSFORM_MAP_FILE, mapFileUtil, countryObject, type_conversion_utils_1.TypeConversionUtils.FLEX2VIBE_DIRECTION)).toBe('flexplm');
|
|
994
|
+
});
|
|
995
|
+
it("is 'vibeiq' when outbound is creatable and inbound is not (both directions)", async () => {
|
|
996
|
+
useMap({ isInboundCreatable: () => false, isOutboundCreatable: () => true });
|
|
997
|
+
expect(await type_conversion_utils_1.TypeConversionUtils.getOriginSystem(TRANSFORM_MAP_FILE, mapFileUtil, countryEntity, type_conversion_utils_1.TypeConversionUtils.VIBE2FLEX_DIRECTION)).toBe('vibeiq');
|
|
998
|
+
expect(await type_conversion_utils_1.TypeConversionUtils.getOriginSystem(TRANSFORM_MAP_FILE, mapFileUtil, countryObject, type_conversion_utils_1.TypeConversionUtils.FLEX2VIBE_DIRECTION)).toBe('vibeiq');
|
|
999
|
+
});
|
|
1000
|
+
it('supports async mapping functions', async () => {
|
|
1001
|
+
useMap({ isInboundCreatable: async () => true, isOutboundCreatable: async () => false });
|
|
1002
|
+
expect(await type_conversion_utils_1.TypeConversionUtils.getOriginSystem(TRANSFORM_MAP_FILE, mapFileUtil, countryObject, type_conversion_utils_1.TypeConversionUtils.FLEX2VIBE_DIRECTION)).toBe('flexplm');
|
|
1003
|
+
});
|
|
1004
|
+
it('is undefined when both are true', async () => {
|
|
1005
|
+
useMap({ isInboundCreatable: () => true, isOutboundCreatable: () => true });
|
|
1006
|
+
expect(await type_conversion_utils_1.TypeConversionUtils.getOriginSystem(TRANSFORM_MAP_FILE, mapFileUtil, countryObject, type_conversion_utils_1.TypeConversionUtils.FLEX2VIBE_DIRECTION)).toBeUndefined();
|
|
1007
|
+
});
|
|
1008
|
+
it('is undefined when both are false', async () => {
|
|
1009
|
+
useMap({ isInboundCreatable: () => false, isOutboundCreatable: () => false });
|
|
1010
|
+
expect(await type_conversion_utils_1.TypeConversionUtils.getOriginSystem(TRANSFORM_MAP_FILE, mapFileUtil, countryEntity, type_conversion_utils_1.TypeConversionUtils.VIBE2FLEX_DIRECTION)).toBeUndefined();
|
|
1011
|
+
});
|
|
1012
|
+
it('is undefined when either function is missing (no defaults)', async () => {
|
|
1013
|
+
useMap({ isInboundCreatable: () => true });
|
|
1014
|
+
expect(await type_conversion_utils_1.TypeConversionUtils.getOriginSystem(TRANSFORM_MAP_FILE, mapFileUtil, countryObject, type_conversion_utils_1.TypeConversionUtils.FLEX2VIBE_DIRECTION)).toBeUndefined();
|
|
1015
|
+
useMap({ isOutboundCreatable: () => true });
|
|
1016
|
+
expect(await type_conversion_utils_1.TypeConversionUtils.getOriginSystem(TRANSFORM_MAP_FILE, mapFileUtil, countryEntity, type_conversion_utils_1.TypeConversionUtils.VIBE2FLEX_DIRECTION)).toBeUndefined();
|
|
1017
|
+
});
|
|
1018
|
+
it('is undefined when there is no LCSCountry section', async () => {
|
|
1019
|
+
useMap();
|
|
1020
|
+
expect(await type_conversion_utils_1.TypeConversionUtils.getOriginSystem(TRANSFORM_MAP_FILE, mapFileUtil, countryEntity, type_conversion_utils_1.TypeConversionUtils.VIBE2FLEX_DIRECTION)).toBeUndefined();
|
|
1021
|
+
expect(await type_conversion_utils_1.TypeConversionUtils.getOriginSystem(TRANSFORM_MAP_FILE, mapFileUtil, countryObject, type_conversion_utils_1.TypeConversionUtils.FLEX2VIBE_DIRECTION)).toBeUndefined();
|
|
1022
|
+
});
|
|
1023
|
+
it('is undefined when there is no mapping file id or no entity', async () => {
|
|
1024
|
+
useMap({ isInboundCreatable: () => true, isOutboundCreatable: () => false });
|
|
1025
|
+
expect(await type_conversion_utils_1.TypeConversionUtils.getOriginSystem('', mapFileUtil, countryObject, type_conversion_utils_1.TypeConversionUtils.FLEX2VIBE_DIRECTION)).toBeUndefined();
|
|
1026
|
+
expect(await type_conversion_utils_1.TypeConversionUtils.getOriginSystem(TRANSFORM_MAP_FILE, mapFileUtil, undefined, type_conversion_utils_1.TypeConversionUtils.FLEX2VIBE_DIRECTION)).toBeUndefined();
|
|
1027
|
+
});
|
|
1028
|
+
it('is undefined (and logs) when a mapping function throws', async () => {
|
|
1029
|
+
useMap({ isInboundCreatable: () => { throw new Error('boom'); }, isOutboundCreatable: () => false });
|
|
1030
|
+
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => undefined);
|
|
1031
|
+
try {
|
|
1032
|
+
expect(await type_conversion_utils_1.TypeConversionUtils.getOriginSystem(TRANSFORM_MAP_FILE, mapFileUtil, countryObject, type_conversion_utils_1.TypeConversionUtils.FLEX2VIBE_DIRECTION)).toBeUndefined();
|
|
1033
|
+
expect(errorSpy).toHaveBeenCalled();
|
|
1034
|
+
}
|
|
1035
|
+
finally {
|
|
1036
|
+
errorSpy.mockRestore();
|
|
1037
|
+
}
|
|
1038
|
+
});
|
|
1039
|
+
it('does not change the creatable defaults of other types', async () => {
|
|
1040
|
+
useMap({ isInboundCreatable: () => true, isOutboundCreatable: () => false });
|
|
1041
|
+
const other = { entityType: 'custom-entity', typePath: 'custom-entity:exchangeRate' };
|
|
1042
|
+
expect(await type_conversion_utils_1.TypeConversionUtils.getMapKey(TRANSFORM_MAP_FILE, mapFileUtil, other, type_conversion_utils_1.TypeConversionUtils.VIBE2FLEX_DIRECTION)).toEqual('');
|
|
1043
|
+
});
|
|
1044
|
+
it('finds the Country section even when the org custom-entity routing returns an empty key', async () => {
|
|
1045
|
+
useMap({ isInboundCreatable: () => true, isOutboundCreatable: () => false });
|
|
1046
|
+
expect(await type_conversion_utils_1.TypeConversionUtils.getMapKey(TRANSFORM_MAP_FILE, mapFileUtil, countryEntity, type_conversion_utils_1.TypeConversionUtils.VIBE2FLEX_DIRECTION)).toEqual('LCSCountry');
|
|
1047
|
+
});
|
|
1048
|
+
});
|
|
927
1049
|
});
|
|
@@ -3,6 +3,11 @@ export declare class TypeDefaults {
|
|
|
3
3
|
static NO_OBJECT_CLASS: string;
|
|
4
4
|
static NO_TYPE_PATH: string;
|
|
5
5
|
static processLCSMaterialAsItem: boolean;
|
|
6
|
+
static COUNTRY_OBJECT_CLASS: string;
|
|
7
|
+
static COUNTRY_VIBE_TYPE_PATH: string;
|
|
8
|
+
static COUNTRY_FLEX_TYPE_PATH: string;
|
|
9
|
+
static COUNTRY_IDENTIFIER_PROPERTY: string;
|
|
10
|
+
static COUNTRY_INFORMATIONAL_PROPERTY: string;
|
|
6
11
|
constructor();
|
|
7
12
|
/** Applies values from the resolved config to TypeDefaults static state.
|
|
8
13
|
* Currently toggles whether LCSMaterial is treated as an item (new) or a
|
|
@@ -14,6 +19,13 @@ export declare class TypeDefaults {
|
|
|
14
19
|
*/
|
|
15
20
|
static applyConfig(config: any): void;
|
|
16
21
|
static isPropertyTrue(value: any): boolean;
|
|
22
|
+
/** True when the VibeIQ entity is a Country: a custom-entity whose typePath is
|
|
23
|
+
* 'custom-entity:country' (compared case-insensitively).
|
|
24
|
+
*
|
|
25
|
+
* @param entity VibeIQ entity
|
|
26
|
+
* @returns boolean
|
|
27
|
+
*/
|
|
28
|
+
static isCountryEntity(entity: any): boolean;
|
|
17
29
|
/**Takes in full entity and returs the default FlexPLM
|
|
18
30
|
* object class.
|
|
19
31
|
*
|
|
@@ -18,6 +18,16 @@ class TypeDefaults {
|
|
|
18
18
|
static isPropertyTrue(value) {
|
|
19
19
|
return value === true || (typeof value === 'string' && value.toLowerCase() === 'true');
|
|
20
20
|
}
|
|
21
|
+
/** True when the VibeIQ entity is a Country: a custom-entity whose typePath is
|
|
22
|
+
* 'custom-entity:country' (compared case-insensitively).
|
|
23
|
+
*
|
|
24
|
+
* @param entity VibeIQ entity
|
|
25
|
+
* @returns boolean
|
|
26
|
+
*/
|
|
27
|
+
static isCountryEntity(entity) {
|
|
28
|
+
const typePath = entity?.['typePath'];
|
|
29
|
+
return typeof typePath === 'string' && typePath.toLowerCase() === TypeDefaults.COUNTRY_VIBE_TYPE_PATH;
|
|
30
|
+
}
|
|
21
31
|
/**Takes in full entity and returs the default FlexPLM
|
|
22
32
|
* object class.
|
|
23
33
|
*
|
|
@@ -47,7 +57,7 @@ class TypeDefaults {
|
|
|
47
57
|
objectClass = 'LCSColor';
|
|
48
58
|
}
|
|
49
59
|
else if ('custom-entity' === entityType) {
|
|
50
|
-
objectClass = 'LCSRevisableEntity';
|
|
60
|
+
objectClass = TypeDefaults.isCountryEntity(entity) ? TypeDefaults.COUNTRY_OBJECT_CLASS : 'LCSRevisableEntity';
|
|
51
61
|
}
|
|
52
62
|
else if ('project' === entityType) {
|
|
53
63
|
objectClass = 'LCSSeason';
|
|
@@ -80,7 +90,7 @@ class TypeDefaults {
|
|
|
80
90
|
typePath = 'Color';
|
|
81
91
|
break;
|
|
82
92
|
case 'custom-entity':
|
|
83
|
-
typePath = 'Revisable Entity';
|
|
93
|
+
typePath = TypeDefaults.isCountryEntity(entity) ? TypeDefaults.COUNTRY_FLEX_TYPE_PATH : 'Revisable Entity';
|
|
84
94
|
break;
|
|
85
95
|
case 'project':
|
|
86
96
|
typePath = 'Season';
|
|
@@ -122,9 +132,11 @@ class TypeDefaults {
|
|
|
122
132
|
}
|
|
123
133
|
break;
|
|
124
134
|
case 'color':
|
|
125
|
-
case 'custom-entity':
|
|
126
135
|
identifierProps.push('name');
|
|
127
136
|
break;
|
|
137
|
+
case 'custom-entity':
|
|
138
|
+
identifierProps.push(TypeDefaults.isCountryEntity(entity) ? TypeDefaults.COUNTRY_IDENTIFIER_PROPERTY : 'name');
|
|
139
|
+
break;
|
|
128
140
|
}
|
|
129
141
|
return identifierProps;
|
|
130
142
|
}
|
|
@@ -149,6 +161,9 @@ class TypeDefaults {
|
|
|
149
161
|
else if (['project', 'assortment'].includes(entityType)) {
|
|
150
162
|
properties.push('name');
|
|
151
163
|
}
|
|
164
|
+
else if (TypeDefaults.isCountryEntity(entity)) {
|
|
165
|
+
properties.push(TypeDefaults.COUNTRY_INFORMATIONAL_PROPERTY);
|
|
166
|
+
}
|
|
152
167
|
return properties;
|
|
153
168
|
}
|
|
154
169
|
/** Returns the VibeIQ entity type from an entity.
|
|
@@ -186,8 +201,8 @@ class TypeDefaults {
|
|
|
186
201
|
? ['LCSProduct', 'LCSSKU', 'LCSMaterial']
|
|
187
202
|
: ['LCSProduct', 'LCSSKU'];
|
|
188
203
|
const customEntityClasses = TypeDefaults.processLCSMaterialAsItem
|
|
189
|
-
? ['LCSRevisableEntity', 'LCSLifecycleManaged', 'LCSLast']
|
|
190
|
-
: ['LCSRevisableEntity', 'LCSLifecycleManaged', 'LCSLast', 'LCSMaterial'];
|
|
204
|
+
? ['LCSRevisableEntity', 'LCSLifecycleManaged', 'LCSLast', TypeDefaults.COUNTRY_OBJECT_CLASS]
|
|
205
|
+
: ['LCSRevisableEntity', 'LCSLifecycleManaged', 'LCSLast', 'LCSMaterial', TypeDefaults.COUNTRY_OBJECT_CLASS];
|
|
191
206
|
if (itemClasses.includes(objectClass)) {
|
|
192
207
|
entityClass = 'item';
|
|
193
208
|
}
|
|
@@ -237,6 +252,9 @@ class TypeDefaults {
|
|
|
237
252
|
case 'SeasonGroup':
|
|
238
253
|
typePath = 'assortment';
|
|
239
254
|
break;
|
|
255
|
+
case 'LCSCountry':
|
|
256
|
+
typePath = TypeDefaults.COUNTRY_VIBE_TYPE_PATH;
|
|
257
|
+
break;
|
|
240
258
|
}
|
|
241
259
|
if (typePath === '')
|
|
242
260
|
throw Error(TypeDefaults.NO_TYPE_PATH);
|
|
@@ -271,6 +289,9 @@ class TypeDefaults {
|
|
|
271
289
|
case 'SeasonGroup':
|
|
272
290
|
identifierProps.push('seasonGroupName');
|
|
273
291
|
break;
|
|
292
|
+
case 'LCSCountry':
|
|
293
|
+
identifierProps.push(TypeDefaults.COUNTRY_IDENTIFIER_PROPERTY);
|
|
294
|
+
break;
|
|
274
295
|
case 'LCSColor':
|
|
275
296
|
case 'LCSRevisableEntity':
|
|
276
297
|
case 'LCSLifecycleManaged':
|
|
@@ -302,6 +323,9 @@ class TypeDefaults {
|
|
|
302
323
|
else if (['LCSSeason', 'SeasonGroup'].includes(objectClass)) {
|
|
303
324
|
properties.push('name');
|
|
304
325
|
}
|
|
326
|
+
else if (TypeDefaults.COUNTRY_OBJECT_CLASS === objectClass) {
|
|
327
|
+
properties.push(TypeDefaults.COUNTRY_INFORMATIONAL_PROPERTY);
|
|
328
|
+
}
|
|
305
329
|
return properties;
|
|
306
330
|
}
|
|
307
331
|
static getObjectClass(object) {
|
|
@@ -313,3 +337,8 @@ TypeDefaults.NO_ENTITY_TYPE = 'Not able to determine the entity type of the enti
|
|
|
313
337
|
TypeDefaults.NO_OBJECT_CLASS = 'Please ensure that the flexPLMObjectClass property is provided.';
|
|
314
338
|
TypeDefaults.NO_TYPE_PATH = 'Please ensure that the flexPLMTypePath property is provided.';
|
|
315
339
|
TypeDefaults.processLCSMaterialAsItem = false;
|
|
340
|
+
TypeDefaults.COUNTRY_OBJECT_CLASS = 'LCSCountry';
|
|
341
|
+
TypeDefaults.COUNTRY_VIBE_TYPE_PATH = 'custom-entity:country';
|
|
342
|
+
TypeDefaults.COUNTRY_FLEX_TYPE_PATH = 'Country';
|
|
343
|
+
TypeDefaults.COUNTRY_IDENTIFIER_PROPERTY = 'vibeIQIdentifier';
|
|
344
|
+
TypeDefaults.COUNTRY_INFORMATIONAL_PROPERTY = 'name';
|
|
@@ -42,6 +42,28 @@ describe('Type Defaults', () => {
|
|
|
42
42
|
const objectClass = type_defaults_1.TypeDefaults.getDefaultObjectClass(newData);
|
|
43
43
|
expect(objectClass).toEqual('LCSColor');
|
|
44
44
|
});
|
|
45
|
+
it('LCSCountry', () => {
|
|
46
|
+
const newData = {
|
|
47
|
+
entityType: 'custom-entity',
|
|
48
|
+
typePath: 'custom-entity:country'
|
|
49
|
+
};
|
|
50
|
+
const objectClass = type_defaults_1.TypeDefaults.getDefaultObjectClass(newData);
|
|
51
|
+
expect(objectClass).toEqual('LCSCountry');
|
|
52
|
+
});
|
|
53
|
+
it('LCSCountry - typePath is case-insensitive', () => {
|
|
54
|
+
const newData = {
|
|
55
|
+
entityType: 'custom-entity',
|
|
56
|
+
typePath: 'custom-entity:Country'
|
|
57
|
+
};
|
|
58
|
+
expect(type_defaults_1.TypeDefaults.getDefaultObjectClass(newData)).toEqual('LCSCountry');
|
|
59
|
+
});
|
|
60
|
+
it('other custom-entity subtype is still LCSRevisableEntity', () => {
|
|
61
|
+
const newData = {
|
|
62
|
+
entityType: 'custom-entity',
|
|
63
|
+
typePath: 'custom-entity:exchangeRate'
|
|
64
|
+
};
|
|
65
|
+
expect(type_defaults_1.TypeDefaults.getDefaultObjectClass(newData)).toEqual('LCSRevisableEntity');
|
|
66
|
+
});
|
|
45
67
|
it('LCSRevisableEntity', () => {
|
|
46
68
|
const newData = {
|
|
47
69
|
entityType: 'custom-entity'
|
|
@@ -120,6 +142,20 @@ describe('Type Defaults', () => {
|
|
|
120
142
|
const typePath = type_defaults_1.TypeDefaults.getDefaultObjectTypePath(newData);
|
|
121
143
|
expect(typePath).toEqual('Color');
|
|
122
144
|
});
|
|
145
|
+
it('custom-entity - country', () => {
|
|
146
|
+
const newData = {
|
|
147
|
+
entityType: 'custom-entity',
|
|
148
|
+
typePath: 'custom-entity:country'
|
|
149
|
+
};
|
|
150
|
+
expect(type_defaults_1.TypeDefaults.getDefaultObjectTypePath(newData)).toEqual('Country');
|
|
151
|
+
});
|
|
152
|
+
it('custom-entity - other subtype stays Revisable Entity', () => {
|
|
153
|
+
const newData = {
|
|
154
|
+
entityType: 'custom-entity',
|
|
155
|
+
typePath: 'custom-entity:exchangeRate'
|
|
156
|
+
};
|
|
157
|
+
expect(type_defaults_1.TypeDefaults.getDefaultObjectTypePath(newData)).toEqual('Revisable Entity');
|
|
158
|
+
});
|
|
123
159
|
it('custom-entity', () => {
|
|
124
160
|
const newData = {
|
|
125
161
|
entityType: 'custom-entity'
|
|
@@ -219,6 +255,21 @@ describe('Type Defaults', () => {
|
|
|
219
255
|
expect(defaultIdentifiers).toContain('name');
|
|
220
256
|
expect(defaultIdentifiers).toHaveLength(1);
|
|
221
257
|
});
|
|
258
|
+
it('custom-entity - country', () => {
|
|
259
|
+
const newData = {
|
|
260
|
+
entityType: 'custom-entity',
|
|
261
|
+
typePath: 'custom-entity:country'
|
|
262
|
+
};
|
|
263
|
+
const defaultIdentifiers = type_defaults_1.TypeDefaults.getDefaultIdentifierProperties(newData);
|
|
264
|
+
expect(defaultIdentifiers).toEqual(['vibeIQIdentifier']);
|
|
265
|
+
});
|
|
266
|
+
it('custom-entity - other subtype stays name', () => {
|
|
267
|
+
const newData = {
|
|
268
|
+
entityType: 'custom-entity',
|
|
269
|
+
typePath: 'custom-entity:exchangeRate'
|
|
270
|
+
};
|
|
271
|
+
expect(type_defaults_1.TypeDefaults.getDefaultIdentifierProperties(newData)).toEqual(['name']);
|
|
272
|
+
});
|
|
222
273
|
it('custom-entity', () => {
|
|
223
274
|
const newData = {
|
|
224
275
|
entityType: 'custom-entity'
|
|
@@ -270,6 +321,20 @@ describe('Type Defaults', () => {
|
|
|
270
321
|
const defaultIdentifiers = type_defaults_1.TypeDefaults.getDefaultInformationalProperties(newData);
|
|
271
322
|
expect(defaultIdentifiers).toHaveLength(0);
|
|
272
323
|
});
|
|
324
|
+
it('custom-entity - country', () => {
|
|
325
|
+
const newData = {
|
|
326
|
+
entityType: 'custom-entity',
|
|
327
|
+
typePath: 'custom-entity:country'
|
|
328
|
+
};
|
|
329
|
+
expect(type_defaults_1.TypeDefaults.getDefaultInformationalProperties(newData)).toEqual(['name']);
|
|
330
|
+
});
|
|
331
|
+
it('custom-entity - other subtype has none', () => {
|
|
332
|
+
const newData = {
|
|
333
|
+
entityType: 'custom-entity',
|
|
334
|
+
typePath: 'custom-entity:exchangeRate'
|
|
335
|
+
};
|
|
336
|
+
expect(type_defaults_1.TypeDefaults.getDefaultInformationalProperties(newData)).toEqual([]);
|
|
337
|
+
});
|
|
273
338
|
it('custom-entity', () => {
|
|
274
339
|
const newData = {
|
|
275
340
|
entityType: 'custom-entity'
|
|
@@ -278,6 +343,16 @@ describe('Type Defaults', () => {
|
|
|
278
343
|
expect(defaultIdentifiers).toHaveLength(0);
|
|
279
344
|
});
|
|
280
345
|
});
|
|
346
|
+
describe('isCountryEntity', () => {
|
|
347
|
+
it('true for custom-entity:country', () => {
|
|
348
|
+
expect(type_defaults_1.TypeDefaults.isCountryEntity({ typePath: 'custom-entity:country' })).toBe(true);
|
|
349
|
+
});
|
|
350
|
+
it('false for another subtype, a missing typePath, or undefined', () => {
|
|
351
|
+
expect(type_defaults_1.TypeDefaults.isCountryEntity({ typePath: 'custom-entity:other' })).toBe(false);
|
|
352
|
+
expect(type_defaults_1.TypeDefaults.isCountryEntity({})).toBe(false);
|
|
353
|
+
expect(type_defaults_1.TypeDefaults.isCountryEntity(undefined)).toBe(false);
|
|
354
|
+
});
|
|
355
|
+
});
|
|
281
356
|
describe('getEntityType', () => {
|
|
282
357
|
it('entityType', () => {
|
|
283
358
|
const entityType = 'item';
|
|
@@ -355,6 +430,24 @@ describe('Type Defaults', () => {
|
|
|
355
430
|
const entityClass = type_defaults_1.TypeDefaults.getDefaultEntityClass(object);
|
|
356
431
|
expect(entityClass).toBe('assortment');
|
|
357
432
|
});
|
|
433
|
+
it('custom-entity - LCSCountry', () => {
|
|
434
|
+
const object = {
|
|
435
|
+
flexPLMObjectClass: 'LCSCountry'
|
|
436
|
+
};
|
|
437
|
+
expect(type_defaults_1.TypeDefaults.getDefaultEntityClass(object)).toBe('custom-entity');
|
|
438
|
+
});
|
|
439
|
+
it('custom-entity - LCSCountry - processAsItem=true', () => {
|
|
440
|
+
const object = {
|
|
441
|
+
flexPLMObjectClass: 'LCSCountry'
|
|
442
|
+
};
|
|
443
|
+
type_defaults_1.TypeDefaults.applyConfig({ LCSMaterial: { processAsItem: true } });
|
|
444
|
+
try {
|
|
445
|
+
expect(type_defaults_1.TypeDefaults.getDefaultEntityClass(object)).toBe('custom-entity');
|
|
446
|
+
}
|
|
447
|
+
finally {
|
|
448
|
+
type_defaults_1.TypeDefaults.applyConfig({});
|
|
449
|
+
}
|
|
450
|
+
});
|
|
358
451
|
it('custom-entity - LCSRevisableEntity', () => {
|
|
359
452
|
const object = {
|
|
360
453
|
flexPLMObjectClass: 'LCSRevisableEntity'
|
|
@@ -419,6 +512,12 @@ describe('Type Defaults', () => {
|
|
|
419
512
|
const typePath = type_defaults_1.TypeDefaults.getDefaultEntityTypePath(object);
|
|
420
513
|
expect(typePath).toBe('project-item');
|
|
421
514
|
});
|
|
515
|
+
it('LCSCountry', () => {
|
|
516
|
+
const object = {
|
|
517
|
+
flexPLMObjectClass: 'LCSCountry'
|
|
518
|
+
};
|
|
519
|
+
expect(type_defaults_1.TypeDefaults.getDefaultEntityTypePath(object)).toBe('custom-entity:country');
|
|
520
|
+
});
|
|
422
521
|
it('LCSColor', () => {
|
|
423
522
|
const object = {
|
|
424
523
|
flexPLMObjectClass: 'LCSColor'
|
|
@@ -501,6 +600,12 @@ describe('Type Defaults', () => {
|
|
|
501
600
|
expect(defaultIdentifiers).toContain('name');
|
|
502
601
|
expect(defaultIdentifiers).toHaveLength(1);
|
|
503
602
|
});
|
|
603
|
+
it('LCSCountry', () => {
|
|
604
|
+
const object = {
|
|
605
|
+
flexPLMObjectClass: 'LCSCountry'
|
|
606
|
+
};
|
|
607
|
+
expect(type_defaults_1.TypeDefaults.getDefaultIdentifierPropertiesFromObject(object)).toEqual(['vibeIQIdentifier']);
|
|
608
|
+
});
|
|
504
609
|
it('LCSRevisableEntity', () => {
|
|
505
610
|
const object = {
|
|
506
611
|
flexPLMObjectClass: 'LCSRevisableEntity'
|
|
@@ -541,6 +646,12 @@ describe('Type Defaults', () => {
|
|
|
541
646
|
});
|
|
542
647
|
}); //getDefaultIdentifierPropertiesFromObject
|
|
543
648
|
describe('getDefaultInformationalPropertiesFromObject', () => {
|
|
649
|
+
it('LCSCountry', () => {
|
|
650
|
+
const object = {
|
|
651
|
+
flexPLMObjectClass: 'LCSCountry'
|
|
652
|
+
};
|
|
653
|
+
expect(type_defaults_1.TypeDefaults.getDefaultInformationalPropertiesFromObject(object)).toEqual(['name']);
|
|
654
|
+
});
|
|
544
655
|
it('LCSProduct', () => {
|
|
545
656
|
const object = {
|
|
546
657
|
flexPLMObjectClass: 'LCSProduct'
|
package/lib/util/type-utils.js
CHANGED
|
@@ -4,6 +4,7 @@ exports.TypeUtils = void 0;
|
|
|
4
4
|
const app_framework_1 = require("@contrail/app-framework");
|
|
5
5
|
const sdk_1 = require("@contrail/sdk");
|
|
6
6
|
const type_conversion_utils_1 = require("./type-conversion-utils");
|
|
7
|
+
const type_defaults_1 = require("./type-defaults");
|
|
7
8
|
class TypeUtils {
|
|
8
9
|
constructor() {
|
|
9
10
|
this.typesObj = new sdk_1.Types();
|
|
@@ -52,7 +53,7 @@ class TypeUtils {
|
|
|
52
53
|
objectClass = 'LCSColor';
|
|
53
54
|
}
|
|
54
55
|
else if ('custom-entity' === entityType) {
|
|
55
|
-
objectClass = 'LCSRevisableEntity';
|
|
56
|
+
objectClass = type_defaults_1.TypeDefaults.isCountryEntity(newData) ? type_defaults_1.TypeDefaults.COUNTRY_OBJECT_CLASS : 'LCSRevisableEntity';
|
|
56
57
|
}
|
|
57
58
|
return objectClass;
|
|
58
59
|
}
|
|
@@ -89,7 +90,7 @@ class TypeUtils {
|
|
|
89
90
|
root: 'color'
|
|
90
91
|
};
|
|
91
92
|
}
|
|
92
|
-
else if (['LCSBusinessObject', 'LCSRevisableEntity', 'LCSLast'].includes(objectClass)) {
|
|
93
|
+
else if (['LCSBusinessObject', 'LCSRevisableEntity', 'LCSLast', type_defaults_1.TypeDefaults.COUNTRY_OBJECT_CLASS].includes(objectClass)) {
|
|
93
94
|
//TODO need to write logic using mapping file
|
|
94
95
|
tco = {
|
|
95
96
|
root: 'custom-entity'
|