@salesforce/afv-skills 1.59.0 → 1.60.0
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/package.json +1 -1
- package/skills/agentforce-architecture-analyze/SKILL.md +66 -17
- package/skills/agentforce-architecture-analyze/assets/cli/show_access_token.yaml +4 -7
- package/skills/agentforce-architecture-analyze/references/contract.json +1 -1
- package/skills/agentforce-architecture-analyze/scripts/emit_env.py +2 -2
- package/skills/agentforce-architecture-analyze/scripts/main.py +40 -44
- package/skills/agentforce-architecture-analyze/scripts/rest_client.py +11 -3
- package/skills/agentforce-architecture-analyze/scripts/sf_cli.py +77 -10
- package/skills/agentforce-architecture-analyze/scripts/tests/test_end_to_end_fixture.py +1 -0
- package/skills/agentforce-architecture-analyze/scripts/tests/test_flow_children_inflation.py +1 -0
- package/skills/agentforce-architecture-analyze/scripts/tests/test_main_pipeline.py +53 -2
- package/skills/agentforce-architecture-analyze/scripts/tests/test_resolve_creds.py +184 -36
- package/skills/agentforce-architecture-analyze/scripts/tests/test_rest_client.py +17 -0
- package/skills/agentforce-architecture-analyze/scripts/tests/test_sf_cli.py +165 -11
- package/skills/agentforce-architecture-analyze/scripts/tests/test_skill_md_pipeline_block.py +319 -0
- package/skills/agentforce-d360-analyze/SKILL.md +28 -10
- package/skills/agentforce-d360-analyze/scripts/dc.py +200 -50
- package/skills/agentforce-d360-analyze/scripts/discover_sessions.py +10 -6
- package/skills/agentforce-d360-analyze/scripts/fetch_dc.py +22 -6
- package/skills/agentforce-d360-analyze/scripts/resolve_session.py +21 -13
- package/skills/agentforce-d360-analyze/scripts/tests/test_dc_and_resolve_session.py +298 -76
- package/skills/agentforce-d360-analyze/scripts/tests/test_default_target_org.py +432 -0
- package/skills/agentforce-d360-analyze/scripts/tests/test_discover_sessions.py +1 -1
- package/skills/agentforce-d360-analyze/scripts/tests/test_resolve_session_main.py +9 -3
- package/skills/agentforce-d360-analyze/scripts/tests/test_skill_md_prefix_block.py +176 -0
- package/skills/consumer-goods-accruals-datakit-deploy/SKILL.md +17 -27
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/setup.js +7 -17
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/00-check-prerequisites.js +47 -63
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/01-download-static-resource.js +10 -13
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/02-replace-org-id.js +46 -46
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/03-deploy-metadata.js +4 -21
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/06-create-dataspace.js +58 -82
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/07-deploy-accruals-reports.js +16 -315
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/08-deploy-ui.js +9 -24
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/09-completion.js +44 -44
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/utils.js +11 -63
- package/skills/consumer-goods-rtr-datacloud-export-configure/SKILL.md +2 -1
- package/skills/consumer-goods-tpe-dashboard-configure/SKILL.md +2 -1
- package/skills/consumer-goods-tpe-dashboard-custom-kpi-configure/SKILL.md +2 -1
- package/skills/consumer-goods-tpe-datakit-deploy/SKILL.md +2 -1
- package/skills/data360-schema-get/SKILL.md +3 -3
- package/skills/design-systems-slds-validate/references/report-format.md +1 -1
- package/skills/dx-org-manage/SKILL.md +1 -0
- package/skills/dx-org-shape-manage/SKILL.md +1 -0
- package/skills/dx-org-snapshot-manage/SKILL.md +172 -0
- package/skills/dx-org-snapshot-manage/examples/create_error_output.json +16 -0
- package/skills/dx-org-snapshot-manage/examples/create_success_output.json +19 -0
- package/skills/dx-org-snapshot-manage/examples/delete_output.json +9 -0
- package/skills/dx-org-snapshot-manage/examples/get_output.json +19 -0
- package/skills/dx-org-snapshot-manage/examples/list_output.json +36 -0
- package/skills/dx-org-snapshot-manage/references/cli_flags.md +179 -0
- package/skills/dx-org-snapshot-manage/references/snapshot_usage.md +55 -0
- package/skills/dx-org-trial-expiration-check/SKILL.md +1 -1
- package/skills/dx-org-trial-expiration-check/scripts/check_expiration.sh +2 -2
- package/skills/education-cloud-student-recruitment-agent-configure/SKILL.md +7 -5
- package/skills/education-cloud-student-recruitment-agent-configure/references/prerequisites.md +11 -11
- package/skills/experience-content-media-image-generate/SKILL.md +83 -0
- package/skills/experience-content-media-image-generate/scripts/download-image.sh +84 -0
- package/skills/external-diagram-mermaid-generate/SKILL.md +12 -12
- package/skills/field-service-data-capture-migrate/references/component-mapping.md +1 -1
- package/skills/field-service-data-capture-migrate/references/fsm-dc-capability-catalog.md +1 -2
- package/skills/field-service-data-capture-migrate/references/known-deploy-errors.md +1 -0
- package/skills/field-service-data-capture-migrate/references/transformer-rules.md +1 -1
- package/skills/field-service-data-capture-migrate/scripts/transform_flow.py +12 -1
- package/skills/field-service-data-capture-migrate/scripts/vendor/build_flow.py +4 -1
- package/skills/field-service-setup-orchestrator-get/SKILL.md +0 -1
- package/skills/insurance-brokerage-agency-billing-configure/SKILL.md +233 -0
- package/skills/insurance-brokerage-agency-billing-configure/references/accounting-setup.md +117 -0
- package/skills/insurance-brokerage-agency-billing-configure/references/billing-rules-config.md +237 -0
- package/skills/insurance-brokerage-agency-billing-configure/references/billing-settings.md +271 -0
- package/skills/insurance-brokerage-agency-billing-configure/references/demo-policy-config.md +138 -0
- package/skills/insurance-brokerage-agency-billing-configure/references/org-defaults.md +64 -0
- package/skills/insurance-brokerage-agency-billing-configure/references/permissions-config.md +226 -0
- package/skills/insurance-brokerage-agency-billing-configure/references/prerequisites.md +142 -0
- package/skills/life-sciences-fieldsalesrep-coordinate/SKILL.md +3 -2
- package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-5-visit-creation-execution-state-and-recovery.md +3 -3
- package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-5-visit-creation-overview.md +68 -45
- package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-5-visit-creation-visit-creation-data.md +17 -18
- package/skills/life-sciences-kam-coordinate/references/stage-5-data-and-plan-templates-overview.md +16 -3
- package/skills/life-sciences-kam-coordinate/references/stage-5-data-creation-data.md +16 -13
- package/skills/marketing-message-test/SKILL.md +194 -0
- package/skills/marketing-message-test/references/api-contract.md +333 -0
- package/skills/omnistudio-callable-apex-generate/SKILL.md +3 -3
- package/skills/omnistudio-datamapper-generate/SKILL.md +6 -6
- package/skills/omnistudio-datapacks-deploy/SKILL.md +11 -11
- package/skills/omnistudio-dependencies-analyze/SKILL.md +5 -5
- package/skills/omnistudio-epc-catalog-generate/SKILL.md +6 -6
- package/skills/omnistudio-flexcard-generate/SKILL.md +6 -6
- package/skills/omnistudio-integration-procedure-generate/SKILL.md +6 -6
- package/skills/omnistudio-omniscript-generate/SKILL.md +6 -5
- package/skills/platform-apex-logs-debug/SKILL.md +1 -0
- package/skills/platform-metadata-deploy/SKILL.md +1 -0
- package/skills/platform-models-api-configure/SKILL.md +5 -5
- package/skills/platform-soql-query/SKILL.md +1 -0
- package/skills/service-itsm-agentic-setup-cmdb-coordinate/SKILL.md +17 -6
- package/skills/service-itsm-agentic-setup-incident-sla-configure/SKILL.md +107 -192
- package/skills/service-itsm-agentic-setup-incident-sla-configure/assets/attach-milestone-action.json +6 -6
- package/skills/service-itsm-agentic-setup-incident-sla-configure/examples/milestone-patterns.md +49 -20
- package/skills/service-itsm-agentic-setup-incident-sla-configure/examples/output-templates.md +4 -4
- package/skills/service-itsm-agentic-setup-incident-sla-configure/references/mcp-invocation.md +224 -290
- package/skills/service-itsm-agentic-setup-incident-sla-configure/references/workflow.md +295 -0
- package/skills/service-itsm-incident-priority-configure/SKILL.md +1 -1
- package/skills/service-itsm-slack-itservice-configure/SKILL.md +2 -1
- package/skills/service-itsm-slack-itservice-configure/references/manage-slack-connection.md +2 -2
- package/skills/service-omni-channel-setup-coordinate/SKILL.md +20 -13
- package/skills/service-omni-channel-setup-coordinate/scripts/integration-driver.sh +5 -55
- package/skills/service-omni-channel-setup-coordinate/scripts/tests/test_omni_contracts.py +0 -38
- package/skills/service-omni-command-center-analyze/SKILL.md +2 -3
- package/skills/service-omni-command-center-analyze/scripts/analyze.sh +3 -3
- package/skills/tableau-next-asset-create/README.md +65 -0
- package/skills/tableau-next-asset-create/SKILL.md +409 -0
- package/skills/tableau-next-asset-create/references/admin-users.md +149 -0
- package/skills/tableau-next-asset-create/references/ai-readiness.md +355 -0
- package/skills/tableau-next-asset-create/references/alerts.md +111 -0
- package/skills/tableau-next-asset-create/references/build-workflow.md +819 -0
- package/skills/tableau-next-asset-create/references/dashboard-authoring.md +302 -0
- package/skills/tableau-next-asset-create/references/dashboard-design-principles.md +352 -0
- package/skills/tableau-next-asset-create/references/data-transform-gotchas.md +210 -0
- package/skills/tableau-next-asset-create/references/data-understanding.md +387 -0
- package/skills/tableau-next-asset-create/references/deep-reference-index.md +74 -0
- package/skills/tableau-next-asset-create/references/destructive-operations.md +62 -0
- package/skills/tableau-next-asset-create/references/edit-dashboard.md +273 -0
- package/skills/tableau-next-asset-create/references/edit-visualization.md +529 -0
- package/skills/tableau-next-asset-create/references/empty-source-handling.md +104 -0
- package/skills/tableau-next-asset-create/references/ingest-and-metric-gotchas.md +638 -0
- package/skills/tableau-next-asset-create/references/insight-bundle.md +69 -0
- package/skills/tableau-next-asset-create/references/large-flat-file-handling.md +331 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/_envelope.json +54 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/_shared-widget-fields.json +122 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/add_page.json +29 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/delete_page.json +27 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/discard_dashboard.json +11 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/move_widget.json +30 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/move_widget_to_page.json +30 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/place_widget_on_page.json +30 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/remove_widget_from_dashboard.json +16 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/remove_widget_from_page.json +26 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/rename_page.json +28 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/save_dashboard.json +18 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/undo.json +11 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_button_widget.json +69 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_container_widget.json +88 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_filter_widget.json +146 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_metric_widget.json +78 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_navigation_widget.json +80 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_parameter_widget.json +160 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_text_widget.json +103 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_visualization_widget.json +68 -0
- package/skills/tableau-next-asset-create/references/sdm-tool-reference.md +721 -0
- package/skills/tableau-next-asset-create/references/semantic-query-and-enrichment.md +355 -0
- package/skills/tableau-next-asset-create/references/shared-gates.md +322 -0
- package/skills/tableau-next-asset-create/references/sharing-and-promotion.md +306 -0
- package/skills/tableau-next-asset-create/references/tasks/ai-readiness-audit.md +51 -0
- package/skills/tableau-next-asset-create/references/tasks/analyze-data.md +48 -0
- package/skills/tableau-next-asset-create/references/tasks/build-dashboard.md +66 -0
- package/skills/tableau-next-asset-create/references/tasks/build-end-to-end.md +73 -0
- package/skills/tableau-next-asset-create/references/tasks/create-data-transform.md +51 -0
- package/skills/tableau-next-asset-create/references/tasks/create-viz.md +58 -0
- package/skills/tableau-next-asset-create/references/tasks/edit-dashboard.md +80 -0
- package/skills/tableau-next-asset-create/references/tasks/edit-sdm.md +106 -0
- package/skills/tableau-next-asset-create/references/tasks/edit-viz.md +40 -0
- package/skills/tableau-next-asset-create/references/tasks/enrich-model.md +68 -0
- package/skills/tableau-next-asset-create/references/tasks/ingest-flat-file.md +68 -0
- package/skills/tableau-next-asset-create/references/tasks/manage-alert.md +35 -0
- package/skills/tableau-next-asset-create/references/tasks/profile-dataset.md +47 -0
- package/skills/tableau-next-asset-create/references/tasks/promote-or-reuse.md +46 -0
- package/skills/tableau-next-asset-create/references/tasks/provision-user.md +39 -0
- package/skills/tableau-next-asset-create/references/tasks/query-model.md +92 -0
- package/skills/tableau-next-asset-create/references/tasks/review-verified-questions.md +42 -0
- package/skills/tableau-next-asset-create/references/tasks/share-asset.md +37 -0
- package/skills/tableau-next-asset-create/references/verified-questions.md +125 -0
- package/skills/tableau-next-asset-create/references/viz-authoring.md +992 -0
- package/skills/service-itsm-agentic-setup-incident-sla-configure/assets/predefined-incident-policy.json +0 -102
package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/07-deploy-accruals-reports.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
const { execFileSync } = require('child_process');
|
|
1
2
|
const fs = require('fs');
|
|
2
|
-
const os = require('os');
|
|
3
3
|
const path = require('path');
|
|
4
|
-
const { execDeployJson,
|
|
4
|
+
const { exec, execDeployJson, getSfBin } = require('./utils');
|
|
5
5
|
|
|
6
6
|
const OBJECT_SOURCE_TARGET_MAPS_DIR = 'objectSourceTargetMaps';
|
|
7
7
|
|
|
@@ -41,8 +41,7 @@ async function deployAccrualsReports(
|
|
|
41
41
|
console.log(`Data Space Prefix: ${dataSpacePrefix || '(empty)'}`);
|
|
42
42
|
console.log(`Org Namespace: ${namespace || '(none)'}`);
|
|
43
43
|
|
|
44
|
-
|
|
45
|
-
const sourceDir = path.join(setupDir, 'TPM', 'Accruals', 'Accruals Reports');
|
|
44
|
+
const sourceDir = path.join(setupDir, 'CGCloudAddons', 'TPM', 'Accruals', 'Accruals Reports');
|
|
46
45
|
const tempDir = path.join(setupDir, 'temp-accruals-reports');
|
|
47
46
|
|
|
48
47
|
if (fs.existsSync(tempDir)) {
|
|
@@ -61,87 +60,6 @@ async function deployAccrualsReports(
|
|
|
61
60
|
const objectSourceTargetMapsPath = path.join(defaultDir, OBJECT_SOURCE_TARGET_MAPS_DIR);
|
|
62
61
|
const hasMaps = fs.existsSync(objectSourceTargetMapsPath);
|
|
63
62
|
|
|
64
|
-
// objectSourceTargetMaps reference Data Cloud DLO/DLM objects by name.
|
|
65
|
-
//
|
|
66
|
-
// The template uses _ORG_NS_ (replaced above with the org namespace, e.g. "cgcloud__")
|
|
67
|
-
// and _DATASPACE_PREFIX_ (replaced with e.g. "DS2_").
|
|
68
|
-
//
|
|
69
|
-
// For DLO (__dll) and DLM (__dlm) object names and their field names, _ORG_NS_ is wrong:
|
|
70
|
-
// Data Cloud objects (MktDataLakeObject / MktDataModelObject) carry their OWN
|
|
71
|
-
// NamespacePrefix, which is independent of the org/package namespace. We query the
|
|
72
|
-
// actual DLO NamespacePrefix from the org at runtime and use that for correction.
|
|
73
|
-
//
|
|
74
|
-
// For targetObjectName the DataSpace prefix (DS2_) must be KEPT — it is part of the
|
|
75
|
-
// DataSpace-scoped DMO name (e.g. DS2_accrualoutput_decorated__dlm).
|
|
76
|
-
//
|
|
77
|
-
// Field names inside DLO/DLM references also need the DLO namespace, not the org namespace.
|
|
78
|
-
if (hasMaps) {
|
|
79
|
-
// Query the actual NamespacePrefix of the DLO from the org (may differ from org namespace)
|
|
80
|
-
let dloNamespace = '';
|
|
81
|
-
try {
|
|
82
|
-
const dloQuery = execSfJson([
|
|
83
|
-
'data', 'query', '--target-org', orgAlias, '--json',
|
|
84
|
-
'--query', "SELECT NamespacePrefix FROM MktDataLakeObject WHERE DeveloperName='accrualoutput_decorated' LIMIT 1"
|
|
85
|
-
]);
|
|
86
|
-
const dloRecs = (dloQuery.result && dloQuery.result.records) || [];
|
|
87
|
-
const raw = dloRecs.length > 0 ? (dloRecs[0].NamespacePrefix || '') : '';
|
|
88
|
-
dloNamespace = raw ? (raw.endsWith('__') ? raw : raw + '__') : '';
|
|
89
|
-
} catch (dloNsErr) {
|
|
90
|
-
// MktDataLakeObject may not be accessible in all org configurations — fall back to no DLO namespace.
|
|
91
|
-
// Log so operators can see the root cause rather than hitting a silent mis-mapping later.
|
|
92
|
-
console.warn(`[WARN] Could not query DLO namespace (falling back to empty): ${dloNsErr.message}`);
|
|
93
|
-
dloNamespace = '';
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// The org namespace (applied by replaceDataSpacePlaceholders) that we need to undo on
|
|
97
|
-
// DLO/DLM names if it differs from the actual DLO namespace.
|
|
98
|
-
const appliedNs = namespace || ''; // what _ORG_NS_ was replaced with
|
|
99
|
-
|
|
100
|
-
const fixObjectName = (name) => {
|
|
101
|
-
let n = name;
|
|
102
|
-
// If the org namespace was applied to DLO/DLM names, undo it, then re-apply the
|
|
103
|
-
// correct DLO namespace (which may be different, e.g. '' for Data Cloud objects
|
|
104
|
-
// even in a namespaced org).
|
|
105
|
-
if (appliedNs && appliedNs !== dloNamespace) {
|
|
106
|
-
const escapedApplied = appliedNs.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
107
|
-
// Undo on DLO/DLM object names: cgcloud__accrualX__dll → <dloNs>accrualX__dll
|
|
108
|
-
n = n.replace(new RegExp(escapedApplied + '(\\w+__dl[lm])', 'g'), dloNamespace + '$1');
|
|
109
|
-
// Undo on field names inside DLO/DLM refs: __dll.cgcloud__Field__c → __dll.<dloNs>Field__c
|
|
110
|
-
n = n.replace(new RegExp('(__dl[lm]\\.)' + escapedApplied + '(\\w+__c)', 'g'), '$1' + dloNamespace + '$2');
|
|
111
|
-
}
|
|
112
|
-
// NOTE: do NOT touch the DataSpace prefix on __dlm names.
|
|
113
|
-
// The MDAPI targetObjectName must include the DataSpace prefix (e.g. DS2_accrualoutput_decorated__dlm)
|
|
114
|
-
// to resolve to the DataSpace-scoped DMO. Removing it causes error 1923914934.
|
|
115
|
-
return n;
|
|
116
|
-
};
|
|
117
|
-
for (const entry of fs.readdirSync(objectSourceTargetMapsPath)) {
|
|
118
|
-
const fp = path.join(objectSourceTargetMapsPath, entry);
|
|
119
|
-
if (!fs.statSync(fp).isFile()) continue;
|
|
120
|
-
// Fix file contents: fix object/field names, then strip the filterOperationType
|
|
121
|
-
// tag from fieldSourceTargetMaps entries. That tag is present in the template but
|
|
122
|
-
// is not present in working org-deployed maps and causes an "unexpected error" on deploy.
|
|
123
|
-
let fileContent = fixObjectName(fs.readFileSync(fp, 'utf8'));
|
|
124
|
-
fileContent = fileContent.replace(
|
|
125
|
-
/\s*<filterOperationType>[^<]*<\/filterOperationType>/g, ''
|
|
126
|
-
);
|
|
127
|
-
fs.writeFileSync(fp, fileContent, 'utf8');
|
|
128
|
-
// Fix the filename: strip any leading DataSpace prefix from the stem so the
|
|
129
|
-
// MDAPI DeveloperName (= file stem) matches the masterLabel inside the XML.
|
|
130
|
-
// The template uses _DATASPACE_PREFIX_ as a file-naming hint; after replacement
|
|
131
|
-
// the file starts with e.g. "DS2_" but the DeveloperName should not have that.
|
|
132
|
-
let fixedName = entry;
|
|
133
|
-
if (dataSpacePrefix && fixedName.startsWith(dataSpacePrefix)) {
|
|
134
|
-
fixedName = fixedName.slice(dataSpacePrefix.length);
|
|
135
|
-
}
|
|
136
|
-
if (namespace && fixedName.startsWith(namespace)) {
|
|
137
|
-
fixedName = fixedName.slice(namespace.length);
|
|
138
|
-
}
|
|
139
|
-
if (fixedName !== entry) {
|
|
140
|
-
fs.renameSync(fp, path.join(objectSourceTargetMapsPath, fixedName));
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
63
|
if (dryRun) {
|
|
146
64
|
console.log('[DRY RUN] Skipping deployment - files prepared at:');
|
|
147
65
|
console.log(` ${tempDir}`);
|
|
@@ -154,208 +72,42 @@ async function deployAccrualsReports(
|
|
|
154
72
|
return;
|
|
155
73
|
}
|
|
156
74
|
|
|
157
|
-
//
|
|
158
|
-
//
|
|
159
|
-
//
|
|
160
|
-
//
|
|
161
|
-
// "Not available for deploy" failures if CRM Analytics is not enabled.
|
|
162
|
-
// Pass 2 — objectSourceTargetMaps
|
|
163
|
-
// Pass 3 — wave (CRM Analytics dashboards), best-effort: warns but does not crash
|
|
164
|
-
// if CRM Analytics is not enabled in the org.
|
|
165
|
-
|
|
166
|
-
const wavePath = path.join(defaultDir, 'wave');
|
|
167
|
-
const hasWave = fs.existsSync(wavePath);
|
|
168
|
-
const stagedWavePath = path.join(tempDir, '__staged-wave');
|
|
169
|
-
|
|
170
|
-
// Stage wave aside so it doesn't contaminate the first two passes
|
|
171
|
-
if (hasWave) {
|
|
172
|
-
if (fs.existsSync(stagedWavePath)) fs.rmSync(stagedWavePath, { recursive: true });
|
|
173
|
-
console.log('Staging wave folder aside for the third deployment pass...');
|
|
174
|
-
fs.renameSync(wavePath, stagedWavePath);
|
|
175
|
-
}
|
|
176
|
-
|
|
75
|
+
// Pass 1: Deploy everything except objectSourceTargetMaps. The maps depend on
|
|
76
|
+
// fields that only exist once the DLM objects are in place, so we briefly
|
|
77
|
+
// move the maps folder out of the deploy tree, deploy the rest, then deploy
|
|
78
|
+
// the maps on their own.
|
|
177
79
|
let stagedMapsPath = null;
|
|
178
80
|
if (hasMaps) {
|
|
179
81
|
stagedMapsPath = path.join(tempDir, '__staged-objectSourceTargetMaps');
|
|
180
|
-
if (fs.existsSync(stagedMapsPath))
|
|
82
|
+
if (fs.existsSync(stagedMapsPath)) {
|
|
83
|
+
fs.rmSync(stagedMapsPath, { recursive: true });
|
|
84
|
+
}
|
|
181
85
|
console.log('Setting aside objectSourceTargetMaps for the second deployment pass...');
|
|
182
86
|
fs.renameSync(objectSourceTargetMapsPath, stagedMapsPath);
|
|
183
87
|
}
|
|
184
88
|
|
|
185
|
-
// Helper: convert tempDir source to MDAPI and deploy it, then clean up mdapi temp.
|
|
186
|
-
function convertAndDeploy(label) {
|
|
187
|
-
const mdapiOut = path.join(os.tmpdir(), `tpm_accruals_reports_mdapi_${label}_${Date.now()}`);
|
|
188
|
-
try {
|
|
189
|
-
const conv = execSfJson(['project', 'convert', 'source', '--output-dir', mdapiOut, '--json'], { cwd: tempDir });
|
|
190
|
-
if (conv.status !== 0) {
|
|
191
|
-
throw new Error(`Source conversion failed (${label}): ${conv.message || JSON.stringify(conv)}`);
|
|
192
|
-
}
|
|
193
|
-
execDeployJson(['project', 'deploy', 'start', '--metadata-dir', mdapiOut, '--target-org', orgAlias]);
|
|
194
|
-
} finally {
|
|
195
|
-
try { fs.rmSync(mdapiOut, { recursive: true }); } catch (cleanupErr) {
|
|
196
|
-
console.warn(`[WARN] Could not remove temp directory ${mdapiOut}: ${cleanupErr.message}`);
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
|
|
201
89
|
try {
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
convertAndDeploy('pass1');
|
|
90
|
+
console.log('Deploying Accruals Reports metadata (pass 1: objects, wave, ...)...');
|
|
91
|
+
execDeployJson(['project', 'deploy', 'start', '--source-dir', 'force-app', '--target-org', orgAlias], { cwd: tempDir });
|
|
205
92
|
|
|
206
|
-
// Pass 2: objectSourceTargetMaps.
|
|
207
|
-
// The ObjectSourceTargetMap MDAPI deploy requires the DataSpace-scoped DMO
|
|
208
|
-
// (DS2_accrualoutput_decorated) to have IsEnabled=true in MktDataModelObject.
|
|
209
|
-
// The DataKit deployment leaves it as INACTIVE. We activate it here via
|
|
210
|
-
// the Tooling API before deploying the map.
|
|
211
93
|
if (stagedMapsPath) {
|
|
212
94
|
console.log('Restoring objectSourceTargetMaps for the second deployment pass...');
|
|
213
95
|
fs.renameSync(stagedMapsPath, objectSourceTargetMapsPath);
|
|
214
96
|
stagedMapsPath = null;
|
|
215
97
|
|
|
216
|
-
// Activate the DataSpace-scoped DMO (MktDataModelObject) so MDAPI can deploy the map.
|
|
217
|
-
if (!skipDataSpace && dataSpacePrefix) {
|
|
218
|
-
console.log('Activating DataSpace-scoped DMO for objectSourceTargetMaps deploy...');
|
|
219
|
-
// DMO must be active before MDAPI will accept the ObjectSourceTargetMap.
|
|
220
|
-
// If activation fails, the map deploy will fail with opaque error 1923914934 — throw early with a clear message.
|
|
221
|
-
activateDmoForDataSpace(orgAlias, dataSpacePrefix, namespace);
|
|
222
|
-
}
|
|
223
|
-
|
|
224
98
|
console.log('Deploying Accruals Reports metadata (pass 2: objectSourceTargetMaps)...');
|
|
225
|
-
|
|
226
|
-
convertAndDeploy('pass2');
|
|
227
|
-
} catch (err) {
|
|
228
|
-
if (err.message && (err.message.includes('no CustomObject named') || err.message.includes('Not available for deploy'))) {
|
|
229
|
-
console.warn('[WARN] objectSourceTargetMaps deploy skipped — Data Cloud DLO/DLM objects not accessible via MDAPI in this org.');
|
|
230
|
-
console.warn('[WARN] This is expected when Data Cloud is not fully provisioned.');
|
|
231
|
-
console.warn(`[WARN] Original error: ${err.message.split('\n')[0]}`);
|
|
232
|
-
} else {
|
|
233
|
-
throw err;
|
|
234
|
-
}
|
|
235
|
-
}
|
|
99
|
+
execDeployJson(['project', 'deploy', 'start', '--source-dir', path.relative(tempDir, objectSourceTargetMapsPath).replace(/\\/g, '/'), '--target-org', orgAlias], { cwd: tempDir });
|
|
236
100
|
}
|
|
237
101
|
} finally {
|
|
238
|
-
//
|
|
102
|
+
// If pass 1 failed before we restored the staged maps, put them back so
|
|
103
|
+
// dry-run inspection still shows the full tree.
|
|
239
104
|
if (stagedMapsPath && fs.existsSync(stagedMapsPath) && !fs.existsSync(objectSourceTargetMapsPath)) {
|
|
240
105
|
fs.renameSync(stagedMapsPath, objectSourceTargetMapsPath);
|
|
241
106
|
}
|
|
242
|
-
if (hasWave && fs.existsSync(stagedWavePath) && !fs.existsSync(wavePath)) {
|
|
243
|
-
fs.renameSync(stagedWavePath, wavePath);
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
// Pass 3: wave (CRM Analytics) — split into two sub-passes:
|
|
248
|
-
// 3a: WaveApplication (.wapp) + WaveDashboards (.wdash/.wdash-meta.xml) only
|
|
249
|
-
// These can deploy even before any data has flowed through the pipeline.
|
|
250
|
-
// 3b: WaveXmd (.xmd-meta.xml) best-effort
|
|
251
|
-
// XMDs annotate datasets that only exist after the pipeline has run once.
|
|
252
|
-
// They are expected to fail on fresh installs; this is non-fatal.
|
|
253
|
-
if (hasWave) {
|
|
254
|
-
// Move wave back into place for conversion
|
|
255
|
-
if (fs.existsSync(stagedWavePath)) fs.renameSync(stagedWavePath, wavePath);
|
|
256
|
-
// Stage everything except wave aside so only wave deploys
|
|
257
|
-
const stageForWave = path.join(tempDir, '__staged-non-wave');
|
|
258
|
-
if (fs.existsSync(stageForWave)) fs.rmSync(stageForWave, { recursive: true });
|
|
259
|
-
fs.mkdirSync(stageForWave, { recursive: true });
|
|
260
|
-
const defaultEntries = fs.readdirSync(defaultDir, { withFileTypes: true });
|
|
261
|
-
for (const e of defaultEntries) {
|
|
262
|
-
if (e.name !== 'wave') {
|
|
263
|
-
fs.renameSync(path.join(defaultDir, e.name), path.join(stageForWave, e.name));
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
// Stage XMD files aside for pass 3b (they need datasets that don't exist yet on fresh install)
|
|
268
|
-
const xmdStageDir = path.join(tempDir, '__staged-xmd');
|
|
269
|
-
if (fs.existsSync(xmdStageDir)) fs.rmSync(xmdStageDir, { recursive: true });
|
|
270
|
-
fs.mkdirSync(xmdStageDir, { recursive: true });
|
|
271
|
-
const xmdFiles = fs.readdirSync(wavePath).filter(n => n.endsWith('.xmd-meta.xml'));
|
|
272
|
-
for (const xmd of xmdFiles) {
|
|
273
|
-
fs.renameSync(path.join(wavePath, xmd), path.join(xmdStageDir, xmd));
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
console.log('Deploying Accruals Reports metadata (pass 3a: WaveApplication + WaveDashboards)...');
|
|
277
|
-
let waveDeployOk = false;
|
|
278
|
-
try {
|
|
279
|
-
convertAndDeploy('pass3a-wave');
|
|
280
|
-
waveDeployOk = true;
|
|
281
|
-
} catch (err) {
|
|
282
|
-
if (err.message && err.message.includes('Not available for deploy for this organization')) {
|
|
283
|
-
console.warn('[WARN] Wave dashboards skipped — CRM Analytics is not enabled/licensed in this org.');
|
|
284
|
-
console.warn('[WARN] Enable Analytics Studio / CRM Analytics and re-run Step 7 to deploy the dashboards.');
|
|
285
|
-
} else {
|
|
286
|
-
console.warn(`[WARN] Wave dashboard deploy failed: ${err.message}`);
|
|
287
|
-
}
|
|
288
|
-
} finally {
|
|
289
|
-
// Restore staged non-wave folders
|
|
290
|
-
for (const e of fs.readdirSync(stageForWave, { withFileTypes: true })) {
|
|
291
|
-
const dest = path.join(defaultDir, e.name);
|
|
292
|
-
if (!fs.existsSync(dest)) {
|
|
293
|
-
fs.renameSync(path.join(stageForWave, e.name), dest);
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
try { fs.rmSync(stageForWave, { recursive: true }); } catch (cleanupErr) {
|
|
297
|
-
console.warn(`[WARN] Could not remove temp staging directory: ${cleanupErr.message}`);
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
if (waveDeployOk) {
|
|
302
|
-
console.log('[OK] Wave dashboards deployed.\n');
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
// Pass 3b: XMDs — best-effort, expected to fail if datasets don't exist yet
|
|
306
|
-
if (xmdFiles.length > 0) {
|
|
307
|
-
// Restore XMDs into wave folder
|
|
308
|
-
for (const xmd of xmdFiles) {
|
|
309
|
-
fs.renameSync(path.join(xmdStageDir, xmd), path.join(wavePath, xmd));
|
|
310
|
-
}
|
|
311
|
-
// Stage all non-XMD wave files aside
|
|
312
|
-
const stageNonXmd = path.join(tempDir, '__staged-non-xmd');
|
|
313
|
-
if (fs.existsSync(stageNonXmd)) fs.rmSync(stageNonXmd, { recursive: true });
|
|
314
|
-
fs.mkdirSync(stageNonXmd, { recursive: true });
|
|
315
|
-
const waveEntries = fs.readdirSync(wavePath, { withFileTypes: true });
|
|
316
|
-
for (const e of waveEntries) {
|
|
317
|
-
if (!e.name.endsWith('.xmd-meta.xml')) {
|
|
318
|
-
fs.renameSync(path.join(wavePath, e.name), path.join(stageNonXmd, e.name));
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
// Also stage non-wave default dirs aside
|
|
322
|
-
const stageForXmd = path.join(tempDir, '__staged-non-wave-for-xmd');
|
|
323
|
-
if (fs.existsSync(stageForXmd)) fs.rmSync(stageForXmd, { recursive: true });
|
|
324
|
-
fs.mkdirSync(stageForXmd, { recursive: true });
|
|
325
|
-
const defaultEntriesForXmd = fs.readdirSync(defaultDir, { withFileTypes: true });
|
|
326
|
-
for (const e of defaultEntriesForXmd) {
|
|
327
|
-
if (e.name !== 'wave') {
|
|
328
|
-
fs.renameSync(path.join(defaultDir, e.name), path.join(stageForXmd, e.name));
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
console.log('Deploying Accruals Reports metadata (pass 3b: WaveXmd, best-effort)...');
|
|
333
|
-
try {
|
|
334
|
-
convertAndDeploy('pass3b-xmd');
|
|
335
|
-
console.log('[OK] WaveXmd metadata deployed.\n');
|
|
336
|
-
} catch (err) {
|
|
337
|
-
console.warn('[WARN] WaveXmd deploy skipped — datasets not yet available (expected on fresh install).');
|
|
338
|
-
console.warn('[WARN] XMD files can be re-deployed after the accrual pipeline has run at least once.');
|
|
339
|
-
console.warn(`[WARN] Original error: ${err.message.split('\n')[0]}`);
|
|
340
|
-
} finally {
|
|
341
|
-
// Restore all staged items
|
|
342
|
-
for (const e of fs.readdirSync(stageNonXmd, { withFileTypes: true })) {
|
|
343
|
-
const dest = path.join(wavePath, e.name);
|
|
344
|
-
if (!fs.existsSync(dest)) fs.renameSync(path.join(stageNonXmd, e.name), dest);
|
|
345
|
-
}
|
|
346
|
-
try { fs.rmSync(stageNonXmd, { recursive: true }); } catch (_) {}
|
|
347
|
-
for (const e of fs.readdirSync(stageForXmd, { withFileTypes: true })) {
|
|
348
|
-
const dest = path.join(defaultDir, e.name);
|
|
349
|
-
if (!fs.existsSync(dest)) fs.renameSync(path.join(stageForXmd, e.name), dest);
|
|
350
|
-
}
|
|
351
|
-
try { fs.rmSync(stageForXmd, { recursive: true }); } catch (_) {}
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
try { fs.rmSync(xmdStageDir, { recursive: true }); } catch (_) {}
|
|
355
107
|
}
|
|
356
108
|
|
|
357
109
|
console.log('Cleaning up temp directory...');
|
|
358
|
-
|
|
110
|
+
fs.rmSync(tempDir, { recursive: true });
|
|
359
111
|
|
|
360
112
|
console.log('[OK] Accruals Reports deployed successfully\n');
|
|
361
113
|
}
|
|
@@ -463,55 +215,4 @@ function replaceInFile(filePath, dataSpaceName, dataSpacePrefix, namespace) {
|
|
|
463
215
|
}
|
|
464
216
|
}
|
|
465
217
|
|
|
466
|
-
/**
|
|
467
|
-
* Activate the DataSpace-scoped DMO (MktDataModelObject) via the Tooling API.
|
|
468
|
-
*
|
|
469
|
-
* The DataKit deployment creates the DS2_<name> DMO in INACTIVE state. MDAPI refuses to
|
|
470
|
-
* deploy an ObjectSourceTargetMap for an INACTIVE DMO (opaque error 1923914934). This
|
|
471
|
-
* function queries the MktDataModelObject by DeveloperName and sets IsEnabled=true via PATCH.
|
|
472
|
-
*/
|
|
473
|
-
function activateDmoForDataSpace(orgAlias, dataSpacePrefix, namespace) {
|
|
474
|
-
// DeveloperName = dataSpacePrefix (without trailing _) + '_accrualoutput_decorated'
|
|
475
|
-
const pfxBase = dataSpacePrefix.replace(/_$/, '');
|
|
476
|
-
const dmoDevName = `${pfxBase}_accrualoutput_decorated`;
|
|
477
|
-
|
|
478
|
-
// Query via sf data query --use-tooling-api — CLI supplies auth, no token extraction.
|
|
479
|
-
// Returns: status=0 on success, result.records as array.
|
|
480
|
-
const queryResult = execSfJson([
|
|
481
|
-
'data', 'query',
|
|
482
|
-
'--query', `SELECT Id,IsEnabled,DataModelObjectStatus FROM MktDataModelObject WHERE DeveloperName='${dmoDevName}'`,
|
|
483
|
-
'--use-tooling-api', '--target-org', orgAlias, '--json'
|
|
484
|
-
]);
|
|
485
|
-
const records = queryResult?.result?.records;
|
|
486
|
-
if (queryResult?.status !== 0 || !Array.isArray(records)) {
|
|
487
|
-
throw new Error(`Tooling query for DMO '${dmoDevName}' failed: ${queryResult?.message || JSON.stringify(queryResult)}`);
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
if (records.length === 0) {
|
|
491
|
-
console.warn(`[WARN] DMO '${dmoDevName}' not found — skipping activation.`);
|
|
492
|
-
return;
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
const { Id: dmoId, IsEnabled, DataModelObjectStatus } = records[0];
|
|
496
|
-
if (IsEnabled && DataModelObjectStatus === 'ACTIVE') {
|
|
497
|
-
console.log(`DMO '${dmoDevName}' already active — skipping.`);
|
|
498
|
-
return;
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
console.log(`Activating DMO '${dmoDevName}' (was IsEnabled=${IsEnabled}, status=${DataModelObjectStatus})...`);
|
|
502
|
-
// Update via sf data update record --use-tooling-api — CLI supplies auth, no token extraction.
|
|
503
|
-
// Returns: status=0 on success, result.success=true.
|
|
504
|
-
const updateResult = execSfJson([
|
|
505
|
-
'data', 'update', 'record',
|
|
506
|
-
'--sobject', 'MktDataModelObject',
|
|
507
|
-
'--record-id', dmoId,
|
|
508
|
-
'--values', `IsEnabled=true DataModelObjectStatus=ACTIVE RefEntityDeveloperName=accrualoutput_decorated`,
|
|
509
|
-
'--use-tooling-api', '--target-org', orgAlias, '--json'
|
|
510
|
-
]);
|
|
511
|
-
if (updateResult?.status !== 0 || !updateResult?.result?.success) {
|
|
512
|
-
throw new Error(`Tooling update for DMO '${dmoDevName}' failed: ${updateResult?.message || JSON.stringify(updateResult?.result)}`);
|
|
513
|
-
}
|
|
514
|
-
console.log(`[OK] DMO '${dmoDevName}' activated.`);
|
|
515
|
-
}
|
|
516
|
-
|
|
517
218
|
module.exports = deployAccrualsReports;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
const { execFileSync } = require('child_process');
|
|
2
2
|
const fs = require('fs');
|
|
3
|
-
|
|
3
|
+
|
|
4
4
|
const path = require('path');
|
|
5
5
|
|
|
6
|
-
const { exec, execDeployJson,
|
|
6
|
+
const { exec, execDeployJson, getSfBin } = require('./utils');
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
|
|
@@ -53,8 +53,7 @@ async function deployUI(orgAlias, setupDir, skipDataSpace, configuredDataSpaceNa
|
|
|
53
53
|
|
|
54
54
|
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
const sourceDir = path.join(setupDir, 'TPM', 'Accruals', 'UI');
|
|
56
|
+
const sourceDir = path.join(setupDir, 'CGCloudAddons', 'TPM', 'Accruals', 'UI');
|
|
58
57
|
|
|
59
58
|
const tempDir = path.join(setupDir, 'temp-ui');
|
|
60
59
|
|
|
@@ -104,32 +103,17 @@ async function deployUI(orgAlias, setupDir, skipDataSpace, configuredDataSpaceNa
|
|
|
104
103
|
|
|
105
104
|
|
|
106
105
|
|
|
107
|
-
// Convert to MDAPI format to bypass source-tracking "NothingToDeploy" on non-scratch orgs.
|
|
108
|
-
const mdapiOut = path.join(os.tmpdir(), `tpm_accruals_ui_mdapi_${Date.now()}`);
|
|
109
|
-
console.log('Converting UI source to MDAPI format...');
|
|
110
|
-
const convertResult = execSfJson(['project', 'convert', 'source', '--output-dir', mdapiOut, '--json'], { cwd: tempDir });
|
|
111
|
-
if (convertResult.status !== 0) {
|
|
112
|
-
console.warn(`[WARN] UI source conversion failed: ${convertResult.message || JSON.stringify(convertResult)}`);
|
|
113
|
-
console.warn('[WARN] Skipping UI deployment — source conversion error.');
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
106
|
console.log('Deploying UI components metadata...');
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
console.warn('[WARN] Skipping UI deployment — see warning above.');
|
|
123
|
-
return;
|
|
124
|
-
} finally {
|
|
125
|
-
try { fs.rmSync(mdapiOut, { recursive: true }); } catch (_) {}
|
|
126
|
-
}
|
|
107
|
+
|
|
108
|
+
execDeployJson(['project', 'deploy', 'start', '--source-dir', deployPath, '--target-org', orgAlias]);
|
|
109
|
+
|
|
110
|
+
|
|
127
111
|
|
|
128
112
|
// Clean up temp directory
|
|
129
113
|
|
|
130
114
|
console.log('Cleaning up temp directory...');
|
|
131
115
|
|
|
132
|
-
|
|
116
|
+
fs.rmSync(tempDir, { recursive: true });
|
|
133
117
|
|
|
134
118
|
|
|
135
119
|
|
|
@@ -414,3 +398,4 @@ function replaceInFile(filePath, dataSpaceName, dataSpacePrefix, salesOrg, names
|
|
|
414
398
|
|
|
415
399
|
|
|
416
400
|
module.exports = deployUI;
|
|
401
|
+
|
|
@@ -1,44 +1,44 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Step 9: Completion and Scheduling Instructions
|
|
3
|
-
* Informs the user about successful deployment and next steps for scheduling accrual calculations
|
|
4
|
-
* @param {boolean} dryRun - If true, show dry run completion message
|
|
5
|
-
*/
|
|
6
|
-
async function completion(dryRun = false) {
|
|
7
|
-
console.log('\n=== Step 9: Setup Complete ===');
|
|
8
|
-
|
|
9
|
-
if (dryRun) {
|
|
10
|
-
console.log('\n+============================================================================+');
|
|
11
|
-
console.log('| DRY RUN COMPLETED |');
|
|
12
|
-
console.log('+============================================================================+');
|
|
13
|
-
console.log('\nThe following directories contain the prepared files for inspection:');
|
|
14
|
-
console.log(' • CGCloudAddons/ - Downloaded and modified static resource');
|
|
15
|
-
console.log(' • temp-accruals-reports/ - Accruals Reports with placeholders replaced');
|
|
16
|
-
console.log(' • temp-ui/ - UI components with placeholders replaced');
|
|
17
|
-
console.log('\nTo execute the actual deployment, run the same command without --dry-run');
|
|
18
|
-
console.log('\n');
|
|
19
|
-
return;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
console.log('\n[OK] The Accruals solution has been successfully deployed to your Salesforce org!');
|
|
23
|
-
|
|
24
|
-
console.log('\n=== Next Steps: Scheduling Accrual Calculations ===');
|
|
25
|
-
console.log('\nTo calculate accruals, you need to schedule two processes in the following order:');
|
|
26
|
-
|
|
27
|
-
console.log('\n1. Schedule Data Cloud Connector Export');
|
|
28
|
-
console.log(' - Use the DataCloudExportScheduler class');
|
|
29
|
-
console.log(' - Schedule exports for the following tables:');
|
|
30
|
-
console.log(' • promotionmeasures');
|
|
31
|
-
console.log(' • paymenttacticmeasures');
|
|
32
|
-
console.log(' • dailymeasurereal');
|
|
33
|
-
console.log(' - Documentation: https://developer.salesforce.com/docs/atlas.en-us.retail_api.meta/retail_api/cg_tpm_apex_datacloudexportscheduler.htm');
|
|
34
|
-
console.log(' - This class can be executed ad-hoc or scheduled to run at a specific interval');
|
|
35
|
-
|
|
36
|
-
console.log('\n2. Schedule Accrual Calculation Chain');
|
|
37
|
-
console.log(' - Use the ScheduleTPMAccrualProcessChain class');
|
|
38
|
-
console.log(' - Documentation: https://developer.salesforce.com/docs/atlas.en-us.retail_api.meta/retail_api/global_tpm_accrual_process.htm');
|
|
39
|
-
console.log(' - This class can be executed ad-hoc or scheduled to run at a specific interval');
|
|
40
|
-
|
|
41
|
-
console.log('\n');
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
module.exports = completion;
|
|
1
|
+
/**
|
|
2
|
+
* Step 9: Completion and Scheduling Instructions
|
|
3
|
+
* Informs the user about successful deployment and next steps for scheduling accrual calculations
|
|
4
|
+
* @param {boolean} dryRun - If true, show dry run completion message
|
|
5
|
+
*/
|
|
6
|
+
async function completion(dryRun = false) {
|
|
7
|
+
console.log('\n=== Step 9: Setup Complete ===');
|
|
8
|
+
|
|
9
|
+
if (dryRun) {
|
|
10
|
+
console.log('\n+============================================================================+');
|
|
11
|
+
console.log('| DRY RUN COMPLETED |');
|
|
12
|
+
console.log('+============================================================================+');
|
|
13
|
+
console.log('\nThe following directories contain the prepared files for inspection:');
|
|
14
|
+
console.log(' • CGCloudAddons/ - Downloaded and modified static resource');
|
|
15
|
+
console.log(' • temp-accruals-reports/ - Accruals Reports with placeholders replaced');
|
|
16
|
+
console.log(' • temp-ui/ - UI components with placeholders replaced');
|
|
17
|
+
console.log('\nTo execute the actual deployment, run the same command without --dry-run');
|
|
18
|
+
console.log('\n');
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
console.log('\n[OK] The Accruals solution has been successfully deployed to your Salesforce org!');
|
|
23
|
+
|
|
24
|
+
console.log('\n=== Next Steps: Scheduling Accrual Calculations ===');
|
|
25
|
+
console.log('\nTo calculate accruals, you need to schedule two processes in the following order:');
|
|
26
|
+
|
|
27
|
+
console.log('\n1. Schedule Data Cloud Connector Export');
|
|
28
|
+
console.log(' - Use the DataCloudExportScheduler class');
|
|
29
|
+
console.log(' - Schedule exports for the following tables:');
|
|
30
|
+
console.log(' • promotionmeasures');
|
|
31
|
+
console.log(' • paymenttacticmeasures');
|
|
32
|
+
console.log(' • dailymeasurereal');
|
|
33
|
+
console.log(' - Documentation: https://developer.salesforce.com/docs/atlas.en-us.retail_api.meta/retail_api/cg_tpm_apex_datacloudexportscheduler.htm');
|
|
34
|
+
console.log(' - This class can be executed ad-hoc or scheduled to run at a specific interval');
|
|
35
|
+
|
|
36
|
+
console.log('\n2. Schedule Accrual Calculation Chain');
|
|
37
|
+
console.log(' - Use the ScheduleTPMAccrualProcessChain class');
|
|
38
|
+
console.log(' - Documentation: https://developer.salesforce.com/docs/atlas.en-us.retail_api.meta/retail_api/global_tpm_accrual_process.htm');
|
|
39
|
+
console.log(' - This class can be executed ad-hoc or scheduled to run at a specific interval');
|
|
40
|
+
|
|
41
|
+
console.log('\n');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
module.exports = completion;
|