Skip to content

Commit 8bbefd1

Browse files
Merge pull request #260 from salesforcecli/u/abhinavkumar2/W-16279013
@W-17077674@
2 parents 8684c7d + fac96f3 commit 8bbefd1

File tree

11 files changed

+207
-93
lines changed

11 files changed

+207
-93
lines changed

messages/assess.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
"duplicatedCardName": "Duplicated Flex Card name",
2222
"duplicatedDrName": "Duplicated DataRaptor name",
2323
"duplicatedOSName": "Duplicated OmniScript name",
24+
"duplicatedName": "Duplicated name",
2425
"errorWhileActivatingOs": "Could not activate OmniScript / Integration Procedure: ",
2526
"errorWhileActivatingCard": "Could not activate Card: ",
2627
"errorWhileUploadingCard": "An error ocurred while uploading Card: ",

src/migration/dataraptor.ts

Lines changed: 94 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,18 @@
22
import { AnyJson } from '@salesforce/ts-types';
33
import DRBundleMappings from '../mappings/DRBundle';
44
import DRMapItemMappings from '../mappings/DRMapItem';
5-
import { DebugTimer, QueryTools } from '../utils';
5+
import { DebugTimer, oldNew, QueryTools } from '../utils';
66
import { NetUtils } from '../utils/net';
77
import { BaseMigrationTool } from './base';
88
import { MigrationResult, MigrationTool, ObjectMapping, TransformData, UploadRecordResult } from './interfaces';
99
import { DataRaptorAssessmentInfo } from '../../src/utils';
1010

11-
import { getAllFunctionMetadata, getReplacedString } from '../utils/formula/FormulaUtil';
11+
import {
12+
getAllFunctionMetadata,
13+
getReplacedString,
14+
populateRegexForFunctionMetadata,
15+
} from '../utils/formula/FormulaUtil';
16+
import { StringVal } from '../utils/StringValue/stringval';
1217

1318
export class DataRaptorMigrationTool extends BaseMigrationTool implements MigrationTool {
1419
static readonly DRBUNDLE_NAME = 'DRBundle__c';
@@ -183,10 +188,25 @@ export class DataRaptorMigrationTool extends BaseMigrationTool implements Migrat
183188
};
184189
}
185190

191+
private async getAllDRToItemsMap(): Promise<Map<string, AnyJson[]>> {
192+
const drToItemsMap = new Map<string, AnyJson[]>();
193+
const drItems = await this.getAllItems();
194+
for (const drItem of drItems) {
195+
const drName = drItem['Name'];
196+
if (drToItemsMap.has(drName)) {
197+
drToItemsMap.get(drName).push(drItem);
198+
} else {
199+
drToItemsMap.set(drName, [drItem]);
200+
}
201+
}
202+
return drToItemsMap;
203+
}
204+
186205
public async assess(): Promise<DataRaptorAssessmentInfo[]> {
187206
try {
188207
DebugTimer.getInstance().lap('Query data raptors');
189208
const dataRaptors = await this.getAllDataRaptors();
209+
190210
const dataRaptorAssessmentInfos = this.processDRComponents(dataRaptors);
191211
/* this.ux.log('dataRaptorAssessmentInfos');
192212
this.ux.log(dataRaptorAssessmentInfos.toString()); */
@@ -201,40 +221,73 @@ export class DataRaptorMigrationTool extends BaseMigrationTool implements Migrat
201221
const dataRaptorAssessmentInfos: DataRaptorAssessmentInfo[] = [];
202222
// Query all the functionMetadata with all required fields
203223
const functionDefinitionMetadata = await getAllFunctionMetadata(this.namespace, this.connection);
224+
populateRegexForFunctionMetadata(functionDefinitionMetadata);
225+
const existingDataRaptorNames = new Set<string>();
226+
const dataRaptorItemsMap = await this.getAllDRToItemsMap();
204227

205228
// Now process each OmniScript and its elements
206229
for (const dataRaptor of dataRaptors) {
230+
if (dataRaptor[this.namespacePrefix + 'Type__c'] === 'Migration') continue;
231+
const drName = dataRaptor['Name'];
207232
// Await here since processOSComponents is now async
208-
this.ux.log(dataRaptor['Name']);
209-
this.ux.log(dataRaptor[this.namespacePrefix + 'Formula__c']);
210-
var customFunctionString = '';
211-
if (dataRaptor[this.namespacePrefix + 'Formula__c'] != null) {
212-
this.ux.log('formula');
213-
customFunctionString =
214-
'Original Formula :' + dataRaptor[this.namespacePrefix + 'Formula__c'] + '\n\n' + 'Replaced Formula :Formula';
215-
try {
216-
customFunctionString +=
217-
'Replaced Formula :Formula \n\n' +
218-
getReplacedString(
219-
this.namespacePrefix,
220-
dataRaptor[this.namespacePrefix + 'Formula__c'],
221-
functionDefinitionMetadata
222-
);
223-
} catch (ex) {
224-
this.logger.error(JSON.stringify(ex));
225-
console.log(
226-
"There was some problem while updating the formula syntax, please check the all the formula's syntax once : " +
227-
dataRaptor[this.namespacePrefix + 'Formula__c']
228-
);
229-
}
233+
this.ux.log(drName);
234+
const warnings: string[] = [];
235+
const existingDRNameVal = new StringVal(drName, 'name');
236+
237+
if (!existingDRNameVal.isNameCleaned()) {
238+
warnings.push(
239+
this.messages.getMessage('changeMessage', [
240+
existingDRNameVal.type,
241+
existingDRNameVal.val,
242+
existingDRNameVal.cleanName(),
243+
])
244+
);
245+
}
246+
if (existingDataRaptorNames.has(existingDRNameVal.cleanName())) {
247+
warnings.push(this.messages.getMessage('duplicatedName') + ' ' + existingDRNameVal.cleanName());
248+
} else {
249+
existingDataRaptorNames.add(existingDRNameVal.cleanName());
250+
}
251+
const apexDependencies = [];
252+
if (dataRaptor[this.namespacePrefix + 'CustomInputClass__c']) {
253+
apexDependencies.push(dataRaptor[this.namespacePrefix + 'CustomInputClass__c']);
254+
}
255+
if (dataRaptor[this.namespacePrefix + 'CustomOutputClass__c']) {
256+
apexDependencies.push(dataRaptor[this.namespacePrefix + 'CustomOutputClass__c']);
230257
}
231258

259+
const formulaChanges: oldNew[] = [];
260+
const drItems = dataRaptorItemsMap.get(drName);
261+
if (drItems) {
262+
for (const drItem of drItems) {
263+
// this.ux.log(dataRaptor[this.namespacePrefix + 'Formula__c']);
264+
const formula = drItem[this.namespacePrefix + 'Formula__c'];
265+
if (formula) {
266+
try {
267+
const newFormula = getReplacedString(this.namespacePrefix, formula, functionDefinitionMetadata);
268+
if (newFormula !== formula) {
269+
formulaChanges.push({
270+
old: formula,
271+
new: newFormula,
272+
});
273+
}
274+
} catch (ex) {
275+
this.logger.error(JSON.stringify(ex));
276+
console.log(
277+
"There was some problem while updating the formula syntax, please check the all the formula's syntax once : " +
278+
formula
279+
);
280+
}
281+
}
282+
}
283+
}
232284
const dataRaptorAssessmentInfo: DataRaptorAssessmentInfo = {
233-
name: dataRaptor['Name'],
234-
customFunction: customFunctionString,
285+
name: existingDRNameVal.val,
235286
id: dataRaptor['Id'],
287+
formulaChanges: formulaChanges,
236288
infos: [],
237-
warnings: [],
289+
apexDependencies: apexDependencies,
290+
warnings: warnings,
238291
};
239292
dataRaptorAssessmentInfos.push(dataRaptorAssessmentInfo);
240293
}
@@ -263,6 +316,20 @@ export class DataRaptorMigrationTool extends BaseMigrationTool implements Migrat
263316
);
264317
}
265318

319+
/*
320+
private async getAllItemsForDataRaptorByName(drName: string): Promise<AnyJson[]> {
321+
const filters = new Map<string, any>();
322+
//Query all Elements
323+
return await QueryTools.queryWithFilter(
324+
this.connection,
325+
this.namespace,
326+
DataRaptorMigrationTool.DRMAPITEM_NAME,
327+
this.getDRMapItemFields(),
328+
filters.set('Name', drName)
329+
);
330+
}
331+
*/
332+
266333
// Get All Items for one DataRaptor
267334
private async getItemsForDataRaptor(
268335
dataRaptorItems: AnyJson[],

src/migration/omniscript.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,12 @@ export class OmniScriptMigrationTool extends BaseMigrationTool implements Migrat
274274
const lwcName = propertySet['lwcName'];
275275
dependenciesLWC.push({ name: lwcName, location: nameVal });
276276
}
277+
// To fetch custom overrides
278+
if (propertySet['lwcComponentOverride']) {
279+
const nameVal = `${elemName}`;
280+
const lwcName = propertySet['lwcComponentOverride'];
281+
dependenciesLWC.push({ name: lwcName, location: nameVal });
282+
}
277283
}
278284

279285
const omniProcessType = omniscript[this.namespacePrefix + 'IsProcedure__c']
@@ -325,7 +331,7 @@ export class OmniScriptMigrationTool extends BaseMigrationTool implements Migrat
325331
);
326332
}
327333
if (existingOmniscriptNames.has(recordName)) {
328-
warnings.push(this.messages.getMessage('duplicatedName') + recordName);
334+
warnings.push(this.messages.getMessage('duplicatedName') + ' ' + recordName);
329335
} else {
330336
existingOmniscriptNames.add(recordName);
331337
}

src/migration/related/ApexMigration.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ export class ApexMigration extends BaseRelatedObjectMigration implements Related
5050
const pwd = shell.pwd();
5151
shell.cd(this.projectPath);
5252
const targetOrg: Org = this.org;
53-
sfProject.retrieve(APEXCLASS, targetOrg.getUsername());
53+
// sfProject.retrieve(APEXCLASS, targetOrg.getUsername());
5454
const apexAssessmentInfos = this.processApexFiles(this.projectPath);
5555
sfProject.deploy(APEXCLASS, targetOrg.getUsername());
5656
shell.cd(pwd);
@@ -60,8 +60,8 @@ export class ApexMigration extends BaseRelatedObjectMigration implements Related
6060
public assess(): ApexAssessmentInfo[] {
6161
const pwd = shell.pwd();
6262
shell.cd(this.projectPath);
63-
const targetOrg: Org = this.org;
64-
sfProject.retrieve(APEXCLASS, targetOrg.getUsername());
63+
// const targetOrg: Org = this.org;
64+
// sfProject.retrieve(APEXCLASS, this.org.getUsername());
6565
const apexAssessmentInfos = this.processApexFiles(this.projectPath);
6666
shell.cd(pwd);
6767
return apexAssessmentInfos;

src/migration/related/LwcMigration.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export class LwcMigration extends BaseRelatedObjectMigration implements RelatedO
2727
const type = 'assessment';
2828
const pwd = shell.pwd();
2929
shell.cd(this.projectPath);
30-
sfProject.retrieve(LWCTYPE, this.org.getUsername());
30+
// sfProject.retrieve(LWCTYPE, this.org.getUsername());
3131
const filesMap = this.processLwcFiles(this.projectPath);
3232
shell.cd(pwd);
3333
return this.processFiles(filesMap, type);

src/utils/formula/FormulaUtil.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,17 +78,21 @@ export async function getAllFunctionMetadata(namespace: string, connection: Conn
7878
return await QueryTools.queryAll(connection, namespace, 'FunctionDefinition__mdt', getFunctionDefinitionFields());
7979
}
8080

81+
export function populateRegexForFunctionMetadata(functionDefinitionMetadata: AnyJson[]) {
82+
functionDefinitionMetadata.forEach((functionDef) => {
83+
functionDef['regex'] = new RegExp('\\b' + functionDef['DeveloperName'] + '\\b', 'g');
84+
});
85+
}
8186
export function getReplacedString(
8287
namespacePrefix: string,
8388
inputString: string,
8489
functionDefinitionMetadata: AnyJson[]
8590
): string {
8691
let formulaSyntax = inputString;
8792
for (let functionDefMd of functionDefinitionMetadata) {
88-
const FormulaName = functionDefMd['DeveloperName'];
89-
const regExStr = new RegExp('\\b' + FormulaName + '\\b', 'g');
90-
const numberOfOccurances: number =
91-
formulaSyntax.match(regExStr) !== null ? formulaSyntax.match(regExStr).length : 0;
93+
const regExStr = functionDefMd['regex'];
94+
const match = formulaSyntax.match(regExStr);
95+
const numberOfOccurances: number = match !== null ? match.length : 0;
9296
if (numberOfOccurances > 0) {
9397
for (var count: number = 1; count <= numberOfOccurances; count++) {
9498
formulaSyntax = getReplacedformulaString(

src/utils/interfaces.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,11 @@ export interface FlexCardAssessmentInfo {
9090

9191
export interface DataRaptorAssessmentInfo {
9292
name: string;
93-
customFunction: string;
9493
id: string;
94+
formulaChanges: oldNew[];
9595
infos: string[];
9696
warnings: string[];
97+
apexDependencies: string[];
9798
}
9899

99100
export interface OmniAssessmentInfo {
@@ -124,3 +125,8 @@ export interface nameLocation {
124125
name: string;
125126
location: string;
126127
}
128+
129+
export interface oldNew {
130+
old: string;
131+
new: string;
132+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import { DataRaptorAssessmentInfo } from '../interfaces';
2+
import { reportingHelper } from './reportingHelper';
3+
4+
export class DRAssessmentReporter {
5+
public static generateDRAssesment(
6+
dataRaptorAssessmentInfos: DataRaptorAssessmentInfo[],
7+
instanceUrl: string
8+
): string {
9+
let tableBody = '';
10+
tableBody += '<div class="slds-text-heading_large">Data Raptor Components Assessment</div>';
11+
for (const dr of dataRaptorAssessmentInfos) {
12+
const row = `
13+
<tr class="slds-hint_parent">
14+
<td style="word-wrap: break-word; white-space: normal; max-width: 200px;">
15+
<div class="slds-truncate" title="${dr.name}">${dr.name}</div>
16+
</td>
17+
<td style="word-wrap: break-word; white-space: normal; max-width: 100px;">
18+
<div class="slds-truncate" title="${dr.id}">
19+
<a href="${instanceUrl}/${dr.id}">${dr.id}</div>
20+
</td>
21+
<td style="word-wrap: break-word; white-space: normal; max-width: 60%; overflow: hidden;">
22+
${reportingHelper.convertToBuletedList(dr.warnings)}
23+
</td>
24+
<td style="word-wrap: break-word; white-space: normal; max-width: 200px;">
25+
<div> ${reportingHelper.decorateChanges(dr.formulaChanges, 'Formula')} </div>
26+
</td>
27+
<td style="word-wrap: break-word; white-space: normal; max-width: 60%; overflow: hidden;">
28+
${reportingHelper.convertToBuletedList(dr.apexDependencies)}
29+
</td>
30+
31+
</tr>`;
32+
tableBody += row;
33+
}
34+
35+
return DRAssessmentReporter.getDRAssessmentReport(tableBody);
36+
}
37+
38+
private static getDRAssessmentReport(tableContent: string): string {
39+
const tableBody = `
40+
<div style="margin-block:15px">
41+
<table style="width: 100%; table-layout: auto;" class="slds-table slds-table_cell-buffer slds-table_bordered slds-table_striped slds-table_col-bordered" aria-label="Results for Data Raptor updates">
42+
<thead>
43+
<tr class="slds-line-height_reset">
44+
<th class="" scope="col" style="width: 20%; word-wrap: break-word; white-space: normal; text-align: left;">
45+
<div class="slds-truncate" title="Name">Name</div>
46+
</th>
47+
<th class="" scope="col" style="width: 10%; word-wrap: break-word; white-space: normal; text-align: left;">
48+
<div class="slds-truncate" title="ID">ID</div>
49+
</th>
50+
<th class="" scope="col" style="width: 20%; word-wrap: break-word; white-space: normal; text-align: left;">
51+
<div class="slds-truncate" title="Summary">Summary</div>
52+
</th>
53+
<th class="" scope="col" style="width: 20%; word-wrap: break-word; white-space: normal; text-align: left;">
54+
<div class="slds-truncate" title="Custom Function Change">Custom Function Changes</div>
55+
</th>
56+
<th class="" scope="col" style="width: 20%; word-wrap: break-word; white-space: normal; text-align: left;">
57+
<div class="slds-truncate" title="Apex dependencies">Apex dependencies</div>
58+
</th>
59+
</tr>
60+
</thead>
61+
<tbody>
62+
${tableContent}
63+
</tbody>
64+
</table>
65+
</div>`;
66+
return tableBody;
67+
}
68+
}

0 commit comments

Comments
 (0)