@contrail/flexplm 1.4.0 → 1.5.0-alpha.14a4f1b
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/lib/cli/commands/compile.d.ts +4 -0
- package/lib/cli/commands/compile.js +73 -0
- package/lib/cli/commands/compile.spec.d.ts +1 -0
- package/lib/cli/commands/compile.spec.js +80 -0
- package/lib/cli/commands/create.d.ts +5 -0
- package/lib/cli/commands/create.js +77 -0
- package/lib/cli/commands/create.spec.d.ts +1 -0
- package/lib/cli/commands/create.spec.js +78 -0
- package/lib/cli/commands/upload.d.ts +17 -0
- package/lib/cli/commands/upload.js +228 -0
- package/lib/cli/commands/upload.spec.d.ts +1 -0
- package/lib/cli/commands/upload.spec.js +88 -0
- package/lib/cli/index.d.ts +5 -0
- package/lib/cli/index.js +70 -0
- package/lib/cli/index.spec.d.ts +1 -0
- package/lib/cli/index.spec.js +85 -0
- package/lib/cli/template/mapping-template.ts.template +62 -0
- package/lib/entity-processor/base-entity-processor.d.ts +65 -0
- package/lib/entity-processor/base-entity-processor.js +71 -0
- package/lib/entity-processor/base-entity-processor.spec.js +1 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/interfaces/mapping-file.d.ts +460 -0
- package/lib/interfaces/mapping-file.js +2 -0
- package/lib/publish/base-process-publish-assortment.d.ts +25 -0
- package/lib/publish/base-process-publish-assortment.js +60 -6
- package/lib/publish/base-process-publish-assortment.spec.js +22 -4
- package/lib/publish/mockData.js +5 -0
- package/lib/transform/identifier-conversion-spec-mockData.js +34 -6
- package/lib/transform/identifier-conversion.d.ts +36 -0
- package/lib/transform/identifier-conversion.js +37 -1
- package/lib/transform/identifier-conversion.spec.js +35 -0
- package/lib/util/config-defaults.d.ts +18 -0
- package/lib/util/config-defaults.js +25 -15
- package/lib/util/config-defaults.spec.js +56 -0
- package/lib/util/data-converter-spec-mockData.js +17 -3
- package/lib/util/data-converter.d.ts +102 -0
- package/lib/util/data-converter.js +195 -34
- package/lib/util/data-converter.spec.js +430 -0
- package/lib/util/error-response-object.d.ts +5 -0
- package/lib/util/error-response-object.js +7 -0
- package/lib/util/event-short-message-status.js +1 -0
- package/lib/util/federation.js +8 -0
- package/lib/util/flexplm-connect.d.ts +7 -0
- package/lib/util/flexplm-connect.js +14 -0
- package/lib/util/logger-config.js +1 -0
- package/lib/util/map-util-spec-mockData.js +17 -3
- package/lib/util/map-utils.d.ts +27 -0
- package/lib/util/map-utils.js +27 -0
- package/lib/util/thumbnail-util.d.ts +21 -0
- package/lib/util/thumbnail-util.js +28 -1
- package/lib/util/thumbnail-util.spec.js +6 -0
- package/lib/util/type-conversion-utils-spec-mockData.js +3 -3
- package/lib/util/type-conversion-utils.d.ts +151 -0
- package/lib/util/type-conversion-utils.js +154 -0
- package/lib/util/type-defaults.d.ts +69 -0
- package/lib/util/type-defaults.js +98 -4
- package/lib/util/type-defaults.spec.js +114 -4
- package/lib/util/type-utils.d.ts +21 -0
- package/lib/util/type-utils.js +23 -0
- package/lib/util/type-utils.spec.js +2 -0
- package/package.json +21 -6
- package/scripts/copy-template.js +10 -0
- package/.github/pull_request_template.md +0 -31
- package/.github/workflows/flexplm-lib.yml +0 -27
- package/.github/workflows/publish-to-npm.yml +0 -121
- package/CHANGELOG.md +0 -40
- package/publish.bat +0 -5
- package/publish.sh +0 -5
- package/src/entity-processor/base-entity-processor.spec.ts +0 -689
- package/src/entity-processor/base-entity-processor.ts +0 -583
- package/src/flexplm-request.ts +0 -28
- package/src/flexplm-utils.spec.ts +0 -27
- package/src/flexplm-utils.ts +0 -29
- package/src/index.ts +0 -22
- package/src/interfaces/interfaces.ts +0 -122
- package/src/interfaces/item-family-changes.ts +0 -67
- package/src/interfaces/publish-change-data.ts +0 -43
- package/src/publish/base-process-publish-assortment-callback.ts +0 -50
- package/src/publish/base-process-publish-assortment.spec.ts +0 -1992
- package/src/publish/base-process-publish-assortment.ts +0 -1134
- package/src/publish/mockData.ts +0 -4561
- package/src/transform/identifier-conversion-spec-mockData.ts +0 -496
- package/src/transform/identifier-conversion.spec.ts +0 -354
- package/src/transform/identifier-conversion.ts +0 -282
- package/src/util/config-defaults.spec.ts +0 -392
- package/src/util/config-defaults.ts +0 -97
- package/src/util/data-converter-spec-mockData.ts +0 -231
- package/src/util/data-converter.spec.ts +0 -1120
- package/src/util/data-converter.ts +0 -766
- package/src/util/error-response-object.spec.ts +0 -116
- package/src/util/error-response-object.ts +0 -50
- package/src/util/event-short-message-status.ts +0 -22
- package/src/util/federation.ts +0 -172
- package/src/util/flexplm-connect.spec.ts +0 -132
- package/src/util/flexplm-connect.ts +0 -208
- package/src/util/logger-config.ts +0 -20
- package/src/util/map-util-spec-mockData.ts +0 -231
- package/src/util/map-utils.spec.ts +0 -103
- package/src/util/map-utils.ts +0 -41
- package/src/util/mockData.ts +0 -101
- package/src/util/thumbnail-util.spec.ts +0 -508
- package/src/util/thumbnail-util.ts +0 -272
- package/src/util/type-conversion-utils-spec-mockData.ts +0 -272
- package/src/util/type-conversion-utils.spec.ts +0 -1031
- package/src/util/type-conversion-utils.ts +0 -490
- package/src/util/type-defaults.spec.ts +0 -669
- package/src/util/type-defaults.ts +0 -281
- package/src/util/type-utils.spec.ts +0 -227
- package/src/util/type-utils.ts +0 -144
- package/tsconfig.json +0 -24
- package/tslint.json +0 -57
|
@@ -31,12 +31,26 @@ exports.mapping = {
|
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
|
+
// flex2vibe: {
|
|
35
|
+
// LCSRevisableEntity: {
|
|
36
|
+
// getMapKey: (object) =>{ return object;}
|
|
37
|
+
// },
|
|
38
|
+
// LCSLast: {
|
|
39
|
+
// getMapKey: (object) => {return object;}
|
|
40
|
+
// },
|
|
41
|
+
// LCSMaterial: {
|
|
42
|
+
// getMapKey: (object) =>{ return object;}
|
|
43
|
+
// },
|
|
44
|
+
// LCSBusinessObject: {
|
|
45
|
+
// getMapKey: (object) => {return object;}
|
|
46
|
+
// }
|
|
47
|
+
// },
|
|
34
48
|
},
|
|
35
49
|
LCSProduct: {
|
|
36
50
|
vibeOwningKeys: ['itemNumber', 'lifecycleStage'],
|
|
37
51
|
vibe2flex: {
|
|
38
52
|
getClass: () => 'LCSProduct',
|
|
39
|
-
getSoftType: (entity) => {
|
|
53
|
+
getSoftType: (entity /*, dependencies*/) => {
|
|
40
54
|
const prodType = entity['prodType'];
|
|
41
55
|
let val = '';
|
|
42
56
|
switch (prodType) {
|
|
@@ -61,7 +75,7 @@ exports.mapping = {
|
|
|
61
75
|
vibeIQIdentifier: 'itemNumber'
|
|
62
76
|
},
|
|
63
77
|
valueTransform: {
|
|
64
|
-
transformEx: (row) => {
|
|
78
|
+
transformEx: (row /*, dependencies*/) => {
|
|
65
79
|
return row['otherProp'] + 'xxx';
|
|
66
80
|
}
|
|
67
81
|
}
|
|
@@ -79,7 +93,7 @@ exports.mapping = {
|
|
|
79
93
|
vibeOwningKeys: ['itemNumber', 'lifecycleStage'],
|
|
80
94
|
vibe2flex: {
|
|
81
95
|
getClass: () => 'LCSSKU',
|
|
82
|
-
getSoftType: (entity) => {
|
|
96
|
+
getSoftType: (entity /*, dependencies*/) => {
|
|
83
97
|
const prodType = entity['prodType'];
|
|
84
98
|
let val = '';
|
|
85
99
|
switch (prodType) {
|
|
@@ -19,21 +19,123 @@ export declare class DataConverter {
|
|
|
19
19
|
getFlexPLMObjectDataFromEvent(event: any, dataToSkip: string[]): Promise<{}>;
|
|
20
20
|
getFlexPLMObjectData(newData: any, dataToSkip: string[], inflateObjRef: boolean): Promise<{}>;
|
|
21
21
|
getFlexPLMValue(prop: any, newData: any, inflateObjRef: boolean): Promise<any>;
|
|
22
|
+
/** Returns the display values for list properties (choice & multi_select)
|
|
23
|
+
*
|
|
24
|
+
* @param prop
|
|
25
|
+
* @param newData
|
|
26
|
+
* @returns
|
|
27
|
+
*/
|
|
22
28
|
getEnumerationValue(prop: any, nd: any): any;
|
|
23
29
|
getObjectReferenceValue(prop: any, newData: any, inflateObjRef?: boolean): Promise<any>;
|
|
30
|
+
/** (Deprecated) Use TypeConversionUtils.getMapKey()
|
|
31
|
+
* Will return the class to use to get mapping.
|
|
32
|
+
* This is needed because mappings will be different for different sub types
|
|
33
|
+
* of custom-entity
|
|
34
|
+
*
|
|
35
|
+
* @param obj: Entity being checked
|
|
36
|
+
* @param mapping: The whole mapping file
|
|
37
|
+
*/
|
|
24
38
|
getMappingClass(entity: object, mapping: any): string;
|
|
39
|
+
/** Sets entity values from FlexPLM data passed in
|
|
40
|
+
* Assumes the entity has a VibeIQ typeId and 'roles' value to filter if necessary.
|
|
41
|
+
* @param entity the entity to update
|
|
42
|
+
* @param data the FlexPLM data
|
|
43
|
+
* @param keysToSkip properties to skip
|
|
44
|
+
* @returns the modified entity with VibeIQ values
|
|
45
|
+
*/
|
|
25
46
|
setEntityValues(entity: any, data: any, keysToSkip?: string[]): Promise<any>;
|
|
47
|
+
/** Gets the entity values from FlexPLM data
|
|
48
|
+
* Assumes there isn't a VibeIQ typeId, so uses FlexPLM data to determine type
|
|
49
|
+
* @param objectClass FlexPLM object class
|
|
50
|
+
* @param data object data
|
|
51
|
+
* @param keysToSkip type properties to not process
|
|
52
|
+
* @returns object with VibeIQ values
|
|
53
|
+
*/
|
|
26
54
|
getEntityValues(objectClass: string, data: any, keysToSkip?: string[]): Promise<{}>;
|
|
55
|
+
/** Gets the VibeIQ value for the property from data
|
|
56
|
+
*
|
|
57
|
+
* @param prop the VibeIQ property
|
|
58
|
+
* @param data the FlexPLM data
|
|
59
|
+
* @returns value to be set in VibeIQ
|
|
60
|
+
*/
|
|
27
61
|
getEntityValue(prop: any, data: any): Promise<any>;
|
|
28
62
|
setEnumerationKeys(prop: any, nd: any, matchByDisplay: any): any;
|
|
63
|
+
/** Compares the potential changes to the entity and returns only the actual differences.
|
|
64
|
+
*
|
|
65
|
+
* @param entity the full entity
|
|
66
|
+
* @param changes the potential changes
|
|
67
|
+
* @returns only the change values that are different from the entity's value
|
|
68
|
+
*/
|
|
29
69
|
getPersistableChanges(entity: object, changes: object): object;
|
|
70
|
+
/** Sets object reference value from FlexPLM data passed in
|
|
71
|
+
*
|
|
72
|
+
* @param prop the VibeIQ property
|
|
73
|
+
* @param nd the VibeIQ data
|
|
74
|
+
* @returns the object reference id from VibeIQ
|
|
75
|
+
*/
|
|
30
76
|
setObjectReferenceValue(prop: any, nd: any): Promise<any>;
|
|
77
|
+
private applyInboundTransformMap;
|
|
78
|
+
private buildObjectReferenceContext;
|
|
79
|
+
private lookupObjectReferenceViaIdentityService;
|
|
80
|
+
private lookupObjectReferenceViaQuery;
|
|
81
|
+
private pickSingleResult;
|
|
82
|
+
/**
|
|
83
|
+
* Retrieves all object references of a specified entity type based on the provided criteria.
|
|
84
|
+
* This function handles pagination and asynchronously fetches object references until there are no more pages.
|
|
85
|
+
* @param {string} entityType - The type of entity for which object references are to be retrieved.
|
|
86
|
+
* @param {object} rootTypeCriteria - The criteria used to filter object references.
|
|
87
|
+
* @returns {Promise<Array>} A Promise that resolves to an array containing all object references.
|
|
88
|
+
*/
|
|
31
89
|
getAllObjectReferences(entityType: string, rootTypeCriteria: any, postProcessCriteria?: any): Promise<any[]>;
|
|
90
|
+
/**
|
|
91
|
+
* Checks if all keys and values of a given object are present in an array of objects.
|
|
92
|
+
* @param {Object} criteria - The object whose keys and values are to be checked in the array of objects.
|
|
93
|
+
* @param {Array<Object>} arrayOfObjects - The array of objects to be searched for matching keys and values.
|
|
94
|
+
* @param {string} entityTypePath - The type / subtype for the property; objects must be this type or a sub type of it.
|
|
95
|
+
* @returns {(Object|boolean)} Returns the array of objects that matches all keys and values of the provided object.
|
|
96
|
+
* If no match is found, returns empty array.
|
|
97
|
+
*/
|
|
32
98
|
checkKeysAndValues(criteria: any, arrayOfObjects: any, entityTypePath: any): any[];
|
|
99
|
+
/** Filters out archived and trashed entities from the provided array of entities.
|
|
100
|
+
*
|
|
101
|
+
* @param entities
|
|
102
|
+
* @returns
|
|
103
|
+
*/
|
|
33
104
|
filterOutArchivedAndTrashedEntities(entities: any[]): any[];
|
|
105
|
+
/** Sets userListId value from FlexPLM data passed in
|
|
106
|
+
*
|
|
107
|
+
* @param prop the VibeIQ property
|
|
108
|
+
* @param nd the VibeIQ data
|
|
109
|
+
* @returns the modified entity with FlexPLM values
|
|
110
|
+
*/
|
|
34
111
|
setUserListValue(prop: any, nd: any): Promise<any>;
|
|
112
|
+
/** Makes batch calls of 1000 of user-org entities until
|
|
113
|
+
* it find one with userEmail of passed in nd.email.
|
|
114
|
+
* Maxes out after querying for 15,000 user-org entities
|
|
115
|
+
*
|
|
116
|
+
* @param nd
|
|
117
|
+
* @returns
|
|
118
|
+
*/
|
|
35
119
|
getUserByEmail(nd: any): Promise<any>;
|
|
120
|
+
/** Shows warning if user email address not present in group associated to property
|
|
121
|
+
*
|
|
122
|
+
* @param prop the VibeIQ property
|
|
123
|
+
* @param userEmail user email address
|
|
124
|
+
*/
|
|
36
125
|
processGroupMemberCheck(prop: any, userEmail: any): Promise<void>;
|
|
126
|
+
/** Gets the VibeIQ value for the userList property from data
|
|
127
|
+
*
|
|
128
|
+
* @param prop the VibeIQ property
|
|
129
|
+
* @param newData the FlexPLM data
|
|
130
|
+
* @returns value to be set in VibeIQ
|
|
131
|
+
*/
|
|
37
132
|
getUserListValue(prop: any, newData: any): Promise<any>;
|
|
133
|
+
/** Makes batch calls of 1000 of user-org entities until
|
|
134
|
+
* it find one with user.id of passed in userId.
|
|
135
|
+
* Maxes out after querying for 15,000 user-org entities
|
|
136
|
+
*
|
|
137
|
+
* @param userId
|
|
138
|
+
* @returns
|
|
139
|
+
*/
|
|
38
140
|
getUserById(userId: any): Promise<any>;
|
|
39
141
|
}
|
|
@@ -7,6 +7,7 @@ const app_framework_1 = require("@contrail/app-framework");
|
|
|
7
7
|
const util_1 = require("@contrail/util");
|
|
8
8
|
const type_conversion_utils_1 = require("./type-conversion-utils");
|
|
9
9
|
const map_utils_1 = require("./map-utils");
|
|
10
|
+
const config_defaults_1 = require("./config-defaults");
|
|
10
11
|
class DataConverter {
|
|
11
12
|
static clearStaticUserCache() {
|
|
12
13
|
DataConverter.staticUserCache = {};
|
|
@@ -44,16 +45,22 @@ class DataConverter {
|
|
|
44
45
|
if (this.isVerboseDebugOn()) {
|
|
45
46
|
console.debug('newData: ' + JSON.stringify(newData));
|
|
46
47
|
}
|
|
48
|
+
//Using event to get propertyDiffs to find emptied values
|
|
49
|
+
//Add standard atts to skip
|
|
47
50
|
dataToSkip = dataToSkip.concat(['updatedOn', 'updatedById', 'createdOn', 'createdById', 'modifiedAt', 'orgId', 'createdAt', 'id', 'typeId', 'workspaceId']);
|
|
51
|
+
// const oldData = event.oldData;
|
|
48
52
|
const data = {};
|
|
49
53
|
const typeId = newData?.typeId;
|
|
50
54
|
if (!typeId) {
|
|
51
|
-
return;
|
|
55
|
+
return; // Don't have a type; so can't process
|
|
52
56
|
}
|
|
53
57
|
data['typePath'] = newData['typePath'];
|
|
54
58
|
const type = await this.typeUtils.getTypeById(typeId);
|
|
55
59
|
const typeProps = this.typeUtils.filterTypeProperties(type, newData);
|
|
56
60
|
for (const prop of typeProps) {
|
|
61
|
+
// if(this.logger.isTraceOn()){
|
|
62
|
+
// this.logger.log('prop: ' + JSON.stringify(prop));
|
|
63
|
+
// }
|
|
57
64
|
const slug = prop['slug'];
|
|
58
65
|
if (dataToSkip.includes(slug)) {
|
|
59
66
|
continue;
|
|
@@ -69,6 +76,7 @@ class DataConverter {
|
|
|
69
76
|
const propertyType = prop['propertyType'];
|
|
70
77
|
const slug = prop['slug'];
|
|
71
78
|
const nd = newData[slug];
|
|
79
|
+
// console.log('getFlexPLMValue: ' + propertyType + ', ' +slug + ', ' + nd + ', ' + od);
|
|
72
80
|
let value;
|
|
73
81
|
if (['string', 'text'].includes(propertyType)) {
|
|
74
82
|
value = nd || '';
|
|
@@ -79,6 +87,10 @@ class DataConverter {
|
|
|
79
87
|
else if ('date' === propertyType) {
|
|
80
88
|
if (nd) {
|
|
81
89
|
value = nd;
|
|
90
|
+
// const d = new Date(nd);
|
|
91
|
+
// console.log('Date.getTimezoneOffset(): ' + d.getTimezoneOffset());
|
|
92
|
+
// value = d.toISOString();
|
|
93
|
+
// console.log('date: ' + nd + ' -- ' + value);
|
|
82
94
|
}
|
|
83
95
|
else {
|
|
84
96
|
value = null;
|
|
@@ -100,11 +112,13 @@ class DataConverter {
|
|
|
100
112
|
}
|
|
101
113
|
}
|
|
102
114
|
else if ('image' === propertyType) {
|
|
115
|
+
// console.log('image-TODO');
|
|
103
116
|
}
|
|
104
117
|
else if ('formula' === propertyType) {
|
|
105
118
|
value = nd;
|
|
106
119
|
}
|
|
107
120
|
else if ('json' === propertyType) {
|
|
121
|
+
// console.log('json-TODO');
|
|
108
122
|
value = nd;
|
|
109
123
|
}
|
|
110
124
|
else if ('userList' === propertyType) {
|
|
@@ -115,6 +129,12 @@ class DataConverter {
|
|
|
115
129
|
}
|
|
116
130
|
return value;
|
|
117
131
|
}
|
|
132
|
+
/** Returns the display values for list properties (choice & multi_select)
|
|
133
|
+
*
|
|
134
|
+
* @param prop
|
|
135
|
+
* @param newData
|
|
136
|
+
* @returns
|
|
137
|
+
*/
|
|
118
138
|
getEnumerationValue(prop, nd) {
|
|
119
139
|
const propertyType = prop['propertyType'];
|
|
120
140
|
let value;
|
|
@@ -198,6 +218,14 @@ class DataConverter {
|
|
|
198
218
|
this.objRefCache[entityId] = value;
|
|
199
219
|
return value;
|
|
200
220
|
}
|
|
221
|
+
/** (Deprecated) Use TypeConversionUtils.getMapKey()
|
|
222
|
+
* Will return the class to use to get mapping.
|
|
223
|
+
* This is needed because mappings will be different for different sub types
|
|
224
|
+
* of custom-entity
|
|
225
|
+
*
|
|
226
|
+
* @param obj: Entity being checked
|
|
227
|
+
* @param mapping: The whole mapping file
|
|
228
|
+
*/
|
|
201
229
|
getMappingClass(entity, mapping) {
|
|
202
230
|
const entityTypePath = entity['typePath'];
|
|
203
231
|
const typeMapKey = mapping['typeMapKey'];
|
|
@@ -211,11 +239,22 @@ class DataConverter {
|
|
|
211
239
|
}
|
|
212
240
|
return objClass;
|
|
213
241
|
}
|
|
242
|
+
/** Sets entity values from FlexPLM data passed in
|
|
243
|
+
* Assumes the entity has a VibeIQ typeId and 'roles' value to filter if necessary.
|
|
244
|
+
* @param entity the entity to update
|
|
245
|
+
* @param data the FlexPLM data
|
|
246
|
+
* @param keysToSkip properties to skip
|
|
247
|
+
* @returns the modified entity with VibeIQ values
|
|
248
|
+
*/
|
|
214
249
|
async setEntityValues(entity, data, keysToSkip = []) {
|
|
250
|
+
// this.logger.log('setEntityValues: ' + JSON.stringify(entity));
|
|
251
|
+
// this.logger.log('data: ' + JSON.stringify(data));
|
|
215
252
|
const type = await this.typeUtils.getTypeById(entity.typeId);
|
|
216
253
|
keysToSkip = keysToSkip.concat(['updatedOn', 'updatedById', 'createdOn', 'createdById', 'modifiedAt', 'orgId', 'createdAt', 'id', 'typeId', 'typePath', 'workspaceId']);
|
|
217
254
|
let typeProps = this.typeUtils.filterTypeProperties(type, entity);
|
|
218
255
|
typeProps = typeProps.filter(prop => !keysToSkip.includes(prop['slug']));
|
|
256
|
+
//Only process properties that had a value sent; to not accidentally clear out values
|
|
257
|
+
//for properties that weren't sent.
|
|
219
258
|
const dataKeys = Object.getOwnPropertyNames(data);
|
|
220
259
|
typeProps = typeProps.filter(prop => dataKeys.includes(prop['slug']));
|
|
221
260
|
for (const prop of typeProps) {
|
|
@@ -226,16 +265,24 @@ class DataConverter {
|
|
|
226
265
|
keyName = slug + 'Id';
|
|
227
266
|
}
|
|
228
267
|
entity[keyName] = await this.getEntityValue(prop, data);
|
|
268
|
+
// console.log('entity[slug]: ' + entity[slug]);
|
|
229
269
|
}
|
|
230
270
|
return entity;
|
|
231
271
|
}
|
|
272
|
+
/** Gets the entity values from FlexPLM data
|
|
273
|
+
* Assumes there isn't a VibeIQ typeId, so uses FlexPLM data to determine type
|
|
274
|
+
* @param objectClass FlexPLM object class
|
|
275
|
+
* @param data object data
|
|
276
|
+
* @param keysToSkip type properties to not process
|
|
277
|
+
* @returns object with VibeIQ values
|
|
278
|
+
*/
|
|
232
279
|
async getEntityValues(objectClass, data, keysToSkip = []) {
|
|
233
280
|
const entityValues = {};
|
|
234
281
|
const tco = await this.typeUtils.getEntityTypeClientOptionsUsingMapping(this.transformMapFile, this.mapFileUtil, data);
|
|
235
282
|
const type = await this.typeUtils.getByRootAndPath(tco);
|
|
236
283
|
const typePath = type['typePath'];
|
|
237
284
|
if (typePath && (typePath.startsWith('item') || typePath.startsWith('project-item'))) {
|
|
238
|
-
if (['LCSProduct', 'LCSProductSeasonLink'].includes(objectClass)) {
|
|
285
|
+
if (['LCSProduct', 'LCSProductSeasonLink', 'LCSMaterial'].includes(objectClass)) {
|
|
239
286
|
entityValues['roles'] = ['family'];
|
|
240
287
|
}
|
|
241
288
|
else {
|
|
@@ -253,10 +300,17 @@ class DataConverter {
|
|
|
253
300
|
}
|
|
254
301
|
return entityValues;
|
|
255
302
|
}
|
|
303
|
+
/** Gets the VibeIQ value for the property from data
|
|
304
|
+
*
|
|
305
|
+
* @param prop the VibeIQ property
|
|
306
|
+
* @param data the FlexPLM data
|
|
307
|
+
* @returns value to be set in VibeIQ
|
|
308
|
+
*/
|
|
256
309
|
async getEntityValue(prop, data) {
|
|
257
310
|
const propertyType = prop['propertyType'];
|
|
258
311
|
const slug = prop['slug'];
|
|
259
312
|
const nd = data[slug];
|
|
313
|
+
// this.logger.log('getValue: ' + propertyType + ', ' +slug + ', ' + nd);
|
|
260
314
|
let value;
|
|
261
315
|
if (['string', 'text'].includes(propertyType)) {
|
|
262
316
|
value = nd;
|
|
@@ -266,6 +320,11 @@ class DataConverter {
|
|
|
266
320
|
}
|
|
267
321
|
else if ('date' === propertyType) {
|
|
268
322
|
if (nd) {
|
|
323
|
+
// const offset = new Date(nd).getTimezoneOffset() * 60 * 1_000;
|
|
324
|
+
// this.logger.log('nd: ' + nd);
|
|
325
|
+
// this.logger.log(offset);
|
|
326
|
+
// this.logger.log('No Offset: ' + new Date(nd).toISOString());
|
|
327
|
+
// const d = new Date(nd + offset);// Take system Timezone into account.
|
|
269
328
|
const d = new Date(nd);
|
|
270
329
|
value = d.toISOString();
|
|
271
330
|
}
|
|
@@ -286,10 +345,13 @@ class DataConverter {
|
|
|
286
345
|
value = await this.setObjectReferenceValue(prop, nd);
|
|
287
346
|
}
|
|
288
347
|
else if ('image' === propertyType) {
|
|
348
|
+
// console.log('TODO-image');
|
|
289
349
|
}
|
|
290
350
|
else if ('formula' === propertyType) {
|
|
351
|
+
// console.log('TODO-formula');
|
|
291
352
|
}
|
|
292
353
|
else if ('json' === propertyType) {
|
|
354
|
+
// console.log('TODO-json');
|
|
293
355
|
}
|
|
294
356
|
else if ('userList' === propertyType) {
|
|
295
357
|
value = await this.setUserListValue(prop, nd);
|
|
@@ -297,12 +359,14 @@ class DataConverter {
|
|
|
297
359
|
else if ('size_range' === propertyType) {
|
|
298
360
|
value = nd;
|
|
299
361
|
}
|
|
362
|
+
// console.log(value);
|
|
300
363
|
return value;
|
|
301
364
|
}
|
|
302
365
|
setEnumerationKeys(prop, nd, matchByDisplay) {
|
|
303
366
|
const propertyType = prop['propertyType'];
|
|
304
367
|
let value;
|
|
305
368
|
if (['choice', 'multi_select'].includes(propertyType)) {
|
|
369
|
+
//If there are no options, use empty array to not error out and don't set anything
|
|
306
370
|
const options = prop['options'] || [];
|
|
307
371
|
if ('choice' === propertyType) {
|
|
308
372
|
if (nd) {
|
|
@@ -332,6 +396,12 @@ class DataConverter {
|
|
|
332
396
|
}
|
|
333
397
|
return value;
|
|
334
398
|
}
|
|
399
|
+
/** Compares the potential changes to the entity and returns only the actual differences.
|
|
400
|
+
*
|
|
401
|
+
* @param entity the full entity
|
|
402
|
+
* @param changes the potential changes
|
|
403
|
+
* @returns only the change values that are different from the entity's value
|
|
404
|
+
*/
|
|
335
405
|
getPersistableChanges(entity, changes) {
|
|
336
406
|
const entityCompareValues = {};
|
|
337
407
|
for (const key of (Object.getOwnPropertyNames(changes))) {
|
|
@@ -346,31 +416,58 @@ class DataConverter {
|
|
|
346
416
|
}
|
|
347
417
|
return diffValues;
|
|
348
418
|
}
|
|
419
|
+
/** Sets object reference value from FlexPLM data passed in
|
|
420
|
+
*
|
|
421
|
+
* @param prop the VibeIQ property
|
|
422
|
+
* @param nd the VibeIQ data
|
|
423
|
+
* @returns the object reference id from VibeIQ
|
|
424
|
+
*/
|
|
349
425
|
async setObjectReferenceValue(prop, nd) {
|
|
350
|
-
let objectReferenceId = "";
|
|
351
426
|
if (!nd) {
|
|
352
|
-
return
|
|
427
|
+
return "";
|
|
428
|
+
}
|
|
429
|
+
nd = await this.applyInboundTransformMap(nd);
|
|
430
|
+
const ctx = await this.buildObjectReferenceContext(prop, nd);
|
|
431
|
+
if (!ctx) {
|
|
432
|
+
return "";
|
|
433
|
+
}
|
|
434
|
+
if (this.objRefCache[ctx.cacheKey]) {
|
|
435
|
+
if (app_framework_1.Logger.isDebugOn()) {
|
|
436
|
+
console.debug(`object reference cache hit: ${ctx.cacheKey}`);
|
|
437
|
+
}
|
|
438
|
+
return this.objRefCache[ctx.cacheKey];
|
|
353
439
|
}
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
440
|
+
const objectReferenceId = ctx.useIdentityService
|
|
441
|
+
? await this.lookupObjectReferenceViaIdentityService(ctx, nd)
|
|
442
|
+
: await this.lookupObjectReferenceViaQuery(ctx);
|
|
443
|
+
if (objectReferenceId) {
|
|
444
|
+
this.objRefCache[ctx.cacheKey] = objectReferenceId;
|
|
357
445
|
}
|
|
446
|
+
return objectReferenceId;
|
|
447
|
+
}
|
|
448
|
+
async applyInboundTransformMap(nd) {
|
|
449
|
+
if (!this.transformMapFile) {
|
|
450
|
+
return nd;
|
|
451
|
+
}
|
|
452
|
+
const mapKey = await type_conversion_utils_1.TypeConversionUtils.getMapKeyFromObject(this.transformMapFile, this.mapFileUtil, nd, type_conversion_utils_1.TypeConversionUtils.FLEX2VIBE_DIRECTION);
|
|
453
|
+
return map_utils_1.MapUtil.applyTransformMap(this.transformMapFile, this.mapFileUtil, nd, mapKey, type_conversion_utils_1.TypeConversionUtils.FLEX2VIBE_DIRECTION);
|
|
454
|
+
}
|
|
455
|
+
async buildObjectReferenceContext(prop, nd) {
|
|
358
456
|
const entityType = prop['referencedTypeRootSlug'];
|
|
359
457
|
const entityTypePath = prop['referencedTypePath'];
|
|
360
458
|
const entityKeys = Object.keys(nd);
|
|
361
459
|
const identifierKeys = await type_conversion_utils_1.TypeConversionUtils.getIdentifierPropertiesFromObject(this.transformMapFile, this.mapFileUtil, nd);
|
|
362
460
|
const hasAllIdentifiers = identifierKeys.every(key => entityKeys.includes(key));
|
|
363
|
-
if (identifierKeys.length
|
|
461
|
+
if (identifierKeys.length === 0 || !hasAllIdentifiers) {
|
|
364
462
|
console.warn(`The inbound ${entityType} for prop '${prop['slug']}' doesnt have all "identifier" properties, so there is no processing. Identifier properties: ${identifierKeys}`);
|
|
365
|
-
return
|
|
463
|
+
return null;
|
|
366
464
|
}
|
|
367
465
|
const rootType = await this.typeUtils.getByRootAndPath({ root: entityType });
|
|
368
466
|
const rootTypeProps = this.typeUtils.filterTypeProperties(rootType, nd);
|
|
369
|
-
|
|
370
|
-
|
|
467
|
+
const rootTypeCriteria = {};
|
|
468
|
+
const typeCriteria = {};
|
|
371
469
|
identifierKeys.forEach(keyName => {
|
|
372
|
-
|
|
373
|
-
if (foundInObjects) {
|
|
470
|
+
if (rootTypeProps.some(obj => obj.slug === keyName)) {
|
|
374
471
|
rootTypeCriteria[keyName] = nd[keyName];
|
|
375
472
|
}
|
|
376
473
|
else {
|
|
@@ -379,31 +476,51 @@ class DataConverter {
|
|
|
379
476
|
});
|
|
380
477
|
const combinedCriteria = { ...rootTypeCriteria, ...typeCriteria, typePath: entityTypePath };
|
|
381
478
|
const cacheKey = Object.values(combinedCriteria).join('_');
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
479
|
+
const rolesIsTypeDiscriminator = entityType === 'item' || entityType === 'project-item';
|
|
480
|
+
const identityLookupKeys = rolesIsTypeDiscriminator
|
|
481
|
+
? identifierKeys.filter(key => key !== 'roles')
|
|
482
|
+
: identifierKeys;
|
|
483
|
+
const useIdentityService = config_defaults_1.ConfigDefaults.isPropertyTrue(this.config?.search?.[entityType]?.useIdentityServiceForInboundData)
|
|
484
|
+
&& identityLookupKeys.length === 1;
|
|
485
|
+
return { entityType, entityTypePath, rootTypeCriteria, typeCriteria, combinedCriteria, cacheKey, useIdentityService, identityLookupKeys };
|
|
486
|
+
}
|
|
487
|
+
async lookupObjectReferenceViaIdentityService(ctx, nd) {
|
|
488
|
+
const propertyName = ctx.identityLookupKeys[0];
|
|
489
|
+
const propertyValue = nd[propertyName];
|
|
490
|
+
const poolKey = await type_conversion_utils_1.TypeConversionUtils.getUniquenessPoolKeyFromObject(this.transformMapFile, this.mapFileUtil, nd);
|
|
491
|
+
const identityResults = await new sdk_1.Entities().get({
|
|
492
|
+
entityName: 'identity',
|
|
493
|
+
criteria: { poolKey, propertyName, propertyValue }
|
|
494
|
+
}) ?? [];
|
|
495
|
+
const match = this.pickSingleResult(identityResults, ctx.combinedCriteria);
|
|
496
|
+
return match ? match.entityReference.split(':')[1] : "";
|
|
497
|
+
}
|
|
498
|
+
async lookupObjectReferenceViaQuery(ctx) {
|
|
499
|
+
let arrObjectReferences = await this.getAllObjectReferences(ctx.entityType, ctx.rootTypeCriteria);
|
|
500
|
+
if (ctx.entityType !== ctx.entityTypePath) {
|
|
501
|
+
arrObjectReferences = this.checkKeysAndValues(ctx.typeCriteria, arrObjectReferences, ctx.entityTypePath);
|
|
399
502
|
}
|
|
400
|
-
|
|
503
|
+
const match = this.pickSingleResult(arrObjectReferences, ctx.combinedCriteria);
|
|
504
|
+
return match ? match.id : "";
|
|
505
|
+
}
|
|
506
|
+
pickSingleResult(results, combinedCriteria) {
|
|
507
|
+
if (!results.length) {
|
|
401
508
|
console.warn(`The passed in object reference criteria ${JSON.stringify(combinedCriteria)} didn't match any entities.`);
|
|
402
|
-
return
|
|
509
|
+
return undefined;
|
|
403
510
|
}
|
|
404
|
-
|
|
405
|
-
|
|
511
|
+
if (results.length > 1) {
|
|
512
|
+
console.warn(`The passed in object reference criteria has duplicate records found ${JSON.stringify(combinedCriteria)}.`);
|
|
513
|
+
return undefined;
|
|
514
|
+
}
|
|
515
|
+
return results[0];
|
|
406
516
|
}
|
|
517
|
+
/**
|
|
518
|
+
* Retrieves all object references of a specified entity type based on the provided criteria.
|
|
519
|
+
* This function handles pagination and asynchronously fetches object references until there are no more pages.
|
|
520
|
+
* @param {string} entityType - The type of entity for which object references are to be retrieved.
|
|
521
|
+
* @param {object} rootTypeCriteria - The criteria used to filter object references.
|
|
522
|
+
* @returns {Promise<Array>} A Promise that resolves to an array containing all object references.
|
|
523
|
+
*/
|
|
407
524
|
async getAllObjectReferences(entityType, rootTypeCriteria, postProcessCriteria = null) {
|
|
408
525
|
const entities = new sdk_1.Entities();
|
|
409
526
|
let loads = [];
|
|
@@ -459,6 +576,14 @@ class DataConverter {
|
|
|
459
576
|
}
|
|
460
577
|
return loads;
|
|
461
578
|
}
|
|
579
|
+
/**
|
|
580
|
+
* Checks if all keys and values of a given object are present in an array of objects.
|
|
581
|
+
* @param {Object} criteria - The object whose keys and values are to be checked in the array of objects.
|
|
582
|
+
* @param {Array<Object>} arrayOfObjects - The array of objects to be searched for matching keys and values.
|
|
583
|
+
* @param {string} entityTypePath - The type / subtype for the property; objects must be this type or a sub type of it.
|
|
584
|
+
* @returns {(Object|boolean)} Returns the array of objects that matches all keys and values of the provided object.
|
|
585
|
+
* If no match is found, returns empty array.
|
|
586
|
+
*/
|
|
462
587
|
checkKeysAndValues(criteria, arrayOfObjects, entityTypePath) {
|
|
463
588
|
let arrOfMatchObjects = [];
|
|
464
589
|
for (let i = 0; i < arrayOfObjects.length; i++) {
|
|
@@ -482,6 +607,11 @@ class DataConverter {
|
|
|
482
607
|
}
|
|
483
608
|
return arrOfMatchObjects;
|
|
484
609
|
}
|
|
610
|
+
/** Filters out archived and trashed entities from the provided array of entities.
|
|
611
|
+
*
|
|
612
|
+
* @param entities
|
|
613
|
+
* @returns
|
|
614
|
+
*/
|
|
485
615
|
filterOutArchivedAndTrashedEntities(entities) {
|
|
486
616
|
if (!entities || !Array.isArray(entities) || entities.length === 0) {
|
|
487
617
|
return [];
|
|
@@ -492,6 +622,12 @@ class DataConverter {
|
|
|
492
622
|
return !isArchived && !isTrashed;
|
|
493
623
|
});
|
|
494
624
|
}
|
|
625
|
+
/** Sets userListId value from FlexPLM data passed in
|
|
626
|
+
*
|
|
627
|
+
* @param prop the VibeIQ property
|
|
628
|
+
* @param nd the VibeIQ data
|
|
629
|
+
* @returns the modified entity with FlexPLM values
|
|
630
|
+
*/
|
|
495
631
|
async setUserListValue(prop, nd) {
|
|
496
632
|
if (!nd?.email) {
|
|
497
633
|
return "";
|
|
@@ -512,6 +648,13 @@ class DataConverter {
|
|
|
512
648
|
}
|
|
513
649
|
return userId;
|
|
514
650
|
}
|
|
651
|
+
/** Makes batch calls of 1000 of user-org entities until
|
|
652
|
+
* it find one with userEmail of passed in nd.email.
|
|
653
|
+
* Maxes out after querying for 15,000 user-org entities
|
|
654
|
+
*
|
|
655
|
+
* @param nd
|
|
656
|
+
* @returns
|
|
657
|
+
*/
|
|
515
658
|
async getUserByEmail(nd) {
|
|
516
659
|
let userOrg = undefined;
|
|
517
660
|
let count = 0;
|
|
@@ -528,6 +671,11 @@ class DataConverter {
|
|
|
528
671
|
} while (!userOrg && size == getOptionsCriteria.take && count < 15);
|
|
529
672
|
return userOrg?.user;
|
|
530
673
|
}
|
|
674
|
+
/** Shows warning if user email address not present in group associated to property
|
|
675
|
+
*
|
|
676
|
+
* @param prop the VibeIQ property
|
|
677
|
+
* @param userEmail user email address
|
|
678
|
+
*/
|
|
531
679
|
async processGroupMemberCheck(prop, userEmail) {
|
|
532
680
|
let arrUserList = [];
|
|
533
681
|
if (this.userRefCache[prop.typePropertyUserListId]) {
|
|
@@ -550,6 +698,12 @@ class DataConverter {
|
|
|
550
698
|
}
|
|
551
699
|
}
|
|
552
700
|
}
|
|
701
|
+
/** Gets the VibeIQ value for the userList property from data
|
|
702
|
+
*
|
|
703
|
+
* @param prop the VibeIQ property
|
|
704
|
+
* @param newData the FlexPLM data
|
|
705
|
+
* @returns value to be set in VibeIQ
|
|
706
|
+
*/
|
|
553
707
|
async getUserListValue(prop, newData) {
|
|
554
708
|
const slug = prop['slug'];
|
|
555
709
|
if (app_framework_1.Logger.isDebugOn()) {
|
|
@@ -578,6 +732,13 @@ class DataConverter {
|
|
|
578
732
|
}
|
|
579
733
|
return value;
|
|
580
734
|
}
|
|
735
|
+
/** Makes batch calls of 1000 of user-org entities until
|
|
736
|
+
* it find one with user.id of passed in userId.
|
|
737
|
+
* Maxes out after querying for 15,000 user-org entities
|
|
738
|
+
*
|
|
739
|
+
* @param userId
|
|
740
|
+
* @returns
|
|
741
|
+
*/
|
|
581
742
|
async getUserById(userId) {
|
|
582
743
|
let userOrg = undefined;
|
|
583
744
|
let count = 0;
|