Newer Version Available
Account Plan LWC Reference
Properties
account-plan-id: Id. Required. The ID of the account plan record to load.
Namespace
1cgcloudEvents
Here’s the event payload structure.
1{
2 detail : {
3 value: <<new value of the property>>,
4 property: <<property name>>,
5 recordId: <<promotionId>>
6 }
7}onstatuschange
This event is triggered when the lifecycle state of the TPM account plan component changes. Status changes are triggered by lifecycle operations on the account plan record.
1{
2 detail : {
3 value: 'VALID',
4 property: 'status',
5 recordId: 'a2WTC0000000F772AE'
6 }
7}The possible values are:
- LOADING: The account plan is being loaded.
- VALID: The account plan is loaded and can be interacted with.
- SAVING: The account plan is being saved to the database.
- ERROR: An irrecoverable error has occurred.
oncalculationstatuschange
This event is triggered when the account plan grids are calculated or recalculated.
1{
2 detail : {
3 value: 'LOADING',
4 property: 'calculationStatus',
5 recordId: 'a2WTC0000000F772AE'
6 }
7}The possible values are:
- LOADING: The calculations are being processed, or the engine is loading.
- VALID: The calculations are completed, and values can be requested.
- ERROR: An irrecoverable error has occurred.
- DISABLED: The calculations engine is disabled for the account plan.
oncategoryfilterchange
This event is triggered when the account plan’s selected product category filter changes. The event contains the selected category product ID.
1{
2 detail : {
3 value: '01pXXXXXXXXXXXXXXX000',
4 property: 'categoryFilter',
5 recordId: 'a2WTC0000000F772AE'
6 }
7}onkpisubsetsfilterchange
This event is triggered when the account plan subset filter changes. The event contains the selected category product ID.
1{
2 detail : {
3 value: 'BaselineManagement',
4 property: 'kpiSubsetFilter',
5 recordId: 'a2WTC0000000F772AE'
6 }
7}Example Implementation
Here’s an example of how to use the tpm-account-plan component.
1<!-- YourComponent.html -->
2<template>
3 <cgcloud-tpm-account-plan
4 account-plan-id={recordId} <!-- Id of the account plan record -->
5 <!-- Events -->
6 oncategoryfilterchange={onCategoryFilterChange}
7 oncalculationstatuschange={onCalculationStatusChange}
8 </cgcloud-tpm-account-plan>
9
10 <!-- Your Component code -->
11</template>1<!-- YourComponent.js-meta.xml -->
2<?xml version="1.0" encoding="UTF-8"?>
3<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
4 <apiVersion>55.0</apiVersion>
5 <isExposed>true</isExposed>
6 <targets>
7 <target>lightning__RecordPage</target>
8 </targets>
9 <targetConfigs>
10 <targetConfig targets="lightning__RecordPage">
11 <objects>
12 <object>cgcloud__Promotion__c</object>
13 </objects>
14 </targetConfig>
15 </targetConfigs>
16 <runtimeNamespace>cgcloud</runtimeNamespace>
17</LightningComponentBundle>1import {
2 LightningElement,
3 api
4} from 'lwc';
5
6// Import the TPMManualInput class to create new instances
7import {
8 TPMManualInput
9} from 'c/tpmGenericUtils';
10
11export default class SampleAccountPlanTester extends LightningElement {
12 @api recordId; // Record Id provided by the LWC framework
13
14 currentCategoryId = '';
15 currentCalculationStatus = 'LOADING';
16
17 onCategoryFilterChange(event) {
18 // Store currently selected category
19 this.currentCategoryId = event.detail.value;
20 }
21
22 onCalculationStatusChange(event) {
23 // Store current status of calculation engine
24 this.currentCalculationStatus = event.detail.value;
25 }
26
27 // In this method, we will be adding a new manual input to the grid.
28 // This can, for instance, be executed in the click of a button or after
29 // some user interaction
30 async addNewManualInputs() {
31 const tpmAccountPlan = this.template.querySelector('cgcloud-tpm-account-plan');
32
33 // Extract the current manual inputs
34 const currentManualInputs = tpmAccountPlan.getProperty('manualInputs');
35
36 // You can read information from the current Manual Inputs:
37 currentManualInputs.forEach((mi) => {
38 console.log(mi.getKPICode()); // 'ALMD'
39 console.log(mi.getPeriodDateFrom()); // Date
40 console.log(mi.getPeriodDateThru()); // Date
41 console.log(mi.ProductId()); // '01qXXXXXXXXXXXXXXX'
42 console.log(mi.getValue()); // 133
43 console.log(mi.isObsolete()); // false
44 });
45
46 // Example: KPI Code to set the manual input to
47 const kpiCode = 'ABCD';
48
49 // Example: Product Id to set the manual input to. If null,
50 // the manual input will be applied to the "Total" for the KPI
51 // productId can be any level on the product hierarchy that is part of
52 // the calculation (SubCategory, Brand, etc...)
53 const productId = '01tXXXXXXXXXXXXXXX';
54
55 // Methods used to extract data from Grid require the Grid to be in valid
56 // status. If trying to extract data from grid when not in the correct status
57 // an exception will be thrown
58 if (this.currentCalculationStatus !== 'VALID') {
59 throw new Error('Grid not in VALID status');
60 }
61
62 // Extract the periods information from the grid
63 const periods = await tpmAccountPlan.getPeriods();
64
65 // We find the period where we want to set the manual input.
66 // You can find periods by name or use the periods "dateFrom, "dateThru" and "periodtype"
67 // attributes to search for an specific period.
68 // In this example, we will set the manual input on the "Total" period
69 // that uses an specific label
70 const manualInputPeriod = periods.find((p) => p.periodtype === 'Total');
71
72 // Create the new instance
73 const newManualInput = new TPMManualInput({
74 kpiCode: kpiCode,
75 period: manualInputPeriod,
76 productId: productId,
77 value: 123 // Value to set
78 });
79
80 // Create a new array with our new manual input appended
81 const newManualInputArray = [currentManualInputs, newManualInput];
82
83 // Set the manual inputs
84 // If the array length is greater than the limit of
85 // manual inputs, the "set" operation will throw an error
86 tpmAccountPlan.setManualInputs(newManualInputArray);
87
88 // After setting the new manual inputs, the Grid will be automatically
89 // reloaded and re-rendered with the new values in place.
90
91 // At this point, manual inputs are still not saved to SFDC database.
92 // the user must save & calculate the account plan
93 }
94}TPM Account Plan Component Methods
Here are the methods supported by the tpm-account-plan LWC.
exportKPIs
API Version
58.0
Signature
exportKPIs(options)
Properties
| Name | Type | Description | Required or Optional |
|---|---|---|---|
| options.subsets | List<String> | List of loaded KPI subsets to retrieve data from. You can get a list of loaded subsets using the getKPISubsets() method. Provide either the KPI subsets or the KPI names. |
Optional |
| options.kpis | List<String> | List of KPI names to retrieve data from. You can get a list of loaded KPI names using the getKPIs() method. Provide either the KPI subsets or the KPI names. |
Optional |
| options.levels | List<String> | List of loaded levels to retrieve data from. You can get a list of loaded levels using the getLevelNames() method. |
Optional |
| options.periods | List<String> | List of loaded period types to retrieve data. You can get a list of loaded period types using the getPeriodTypes() method. |
Optional |
| options.format | List<String> | Format in which the response is returned. Possible formats are:
The default format is JSON. |
Optional |
The returned data is a list of rows (JavaScript objects or CSV rows). Each row represents the value of the KPI for the determined level. Each row contains values for all the periods specified in the request.
Example Implementation
1const api = this.template.querySelector('cgcloud-tpm-promotion');
2
3// Export options, the possible values can be extracted using
4// the other described methods
5const exportOptions = {
6 subsets: ["Planning"], // Subsets to request data
7 periods: [
8 "Total",
9 "Week"
10 ],
11 levels: [
12 "Total",
13 "Category",
14 "Product"
15 ],
16 format: "json"
17};
18
19// Correct Scenario
20api.getProperty('calculationStatus'); // 'VALID'
21
22api.exportKPIs(exportOptions)
23 .then((data) => {
24 // Example response as CSV
25 //
26 // kpiName,Category,Product,AP_LBL_TOTAL,03/2022,04/2022
27 // SampleKPI1,,,246,123,123
28 // SampleKPI1,01tTC0000000001AAA,,246,123,123
29 // SampleKPI1,01tTC0000000001AAA,01tTC0000000002AAA,246,123,123
30 // SampleKPI2,,,1974,987,987
31 // SampleKPI2,01tTC0000000001AAA,,1974,987,987
32 // SampleKPI2,01tTC0000000001AAA,01tTC0000000002AAA,1974,987,987
33
34 // Example response as JSON
35 //
36 // [{
37 // kpiName: "SampleKPI1",
38 // Category: null,
39 // Product: null,
40 // AP_LBL_TOTAL: 246,
41 // "03/2022": 123,
42 // "04/2022": 123
43 // }, {
44 // kpiName: "SampleKPI1",
45 // Category: "01tTC0000000001AAA",
46 // Product: null,
47 // AP_LBL_TOTAL: 246,
48 // "03/2022": 123,
49 // "04/2022": 123
50 // },{
51 // kpiName: "SampleKPI1",
52 // Category: "01tTC0000000001AAA",
53 // Product: "01tTC0000000002AAA",
54 // AP_LBL_TOTAL: 246,
55 // "03/2022": 123,
56 // "04/2022": 123
57 // },{
58 // kpiName: "SampleKPI2",
59 // Category: null,
60 // Product: null,
61 // AP_LBL_TOTAL: 1974,
62 // "03/2022": 987,
63 // "04/2022": 987
64 // },{
65 // kpiName: "SampleKPI2",
66 // Category: "01tTC0000000001AAA",
67 // Product: null,
68 // AP_LBL_TOTAL: 1974,
69 // "03/2022": 987,
70 // "04/2022": 987
71 // },{
72 // kpiName: "SampleKPI2",
73 // Category: "01tTC0000000001AAA",
74 // Product: "01tTC0000000002AAA",
75 // AP_LBL_TOTAL: 1974,
76 // "03/2022": 987,
77 // "04/2022": 987
78 // }]
79
80
81 // We can access the properties on the result:
82 const firstRecord = data[0];
83
84 console.log(firstRecord["kpiName"]); // "SampleKPI1"
85 // Since we request the total period,
86 // we can read the total period value
87 console.log(firstRecord["AP_LBL_TOTAL"]); // 246
88 // We can also read specific periods information
89 console.log(firstRecord["03/2022"]); // 123
90 // We can also know which level the row references
91 console.log(firstRecord["Category"]); // null
92 console.log(firstRecord["Product"]); // null
93 // Since Category is null, it means this data row
94 // represents the total value for KPI "SampleKPI1"
95
96 // For last record
97 const lastRecord = data[data.length - 1];
98
99 console.log(lastRecord["kpiName"]); // "SampleKPI2"
100 // Since we request the total period,
101 // we can read the total period value
102 console.log(lastRecord["AP_LBL_TOTAL"]); // 1974
103 // We can also read specific periods information
104 console.log(lastRecord["03/2022"]); // 987
105 // We can also know which level the row references
106 console.log(lastRecord["Category"]); // "01tTC0000000001AAA"
107 console.log(lastRecord["Product"]); // "01tTC0000000002AAA"
108 // Since Product is not null, it means this data row
109 // represents the value for KPI "SampleKPI2" for that
110 // specific product
111 });
112
113// Error Scenario
114api.getProperty('calculationStatus'); // 'LOADING'
115
116api.exportKPIs(exportOptions)
117 .catch((error) => {
118 console.log(error.message); // CalculationStatus is not "VALID". Current Status "LOADING"
119 });getProperty
API Version
59.0
Signature
getProperty(propName)
The available properties to retrieve are:
- status
- calculationStatus
- manualInputs
- kpiSubsetFilter
- categoryFilter
getLevelNames
API Version
59.0
Signature
getLevelNames()
Example Implementation
1const api = this.template.querySelector('cgcloud-tpm-account-plan');
2
3// Correct Scenario
4api.getProperty('calculationStatus'); // 'VALID'
5
6api.getLevelNames()
7 .then((levels) => {
8 console.log(levels); // [ "Brand", "Product"]
9 });
10
11// Error Scenario
12api.getProperty('calculationStatus'); // 'LOADING'
13
14api.getLevelNames()
15 .catch((error) => {
16 console.log(error.message); // CalculationStatus is not "VALID". Current Status "LOADING"
17 });getKPISubsets
API Version
59.0
Signature
getKPISubsets()
Example Implementation
1const api = this.template.querySelector('cgcloud-tpm-account-plan');
2
3// Correct Scenario
4api.getProperty('calculationStatus'); // 'VALID'
5
6api.getKPISubsets()
7 .then((subsets) => {
8 console.log(subsets); // ["Planning", ...
9 });
10
11// Error Scenario
12api.getProperty('calculationStatus'); // 'LOADING'
13
14api.getKPISubsets()
15 .catch((error) => {
16 console.log(error.message); // CalculationStatus is not "VALID". Current Status "LOADING"
17 });getKPIs
API Version
59.0
Signature
getKPIs()
Example Implementation
1const api = this.template.querySelector('cgcloud-tpm-account-plan');
2
3// Correct Scenario
4api.getProperty('calculationStatus'); // 'VALID'
5
6api.getKPIs()
7 .then((kpis) => {
8 // 0
9 console.log(kpis[0].id); // "0"
10 console.log(kpis[0].name); // "BasePrice"
11 console.log(kpis[0].kpitype); // "account"
12 console.log(kpis[0].skipped); // ["Tactic"]
13 console.log(kpis[0].type); // "read"
14 console.log(kpis[0].valuetype); // "Price"
15 });
16
17// Error Scenario
18api.getProperty('calculationStatus'); // 'LOADING'
19
20api.getKPIs()
21 .catch((error) => {
22 console.log(error.message); // CalculationStatus is not "VALID". Current Status "LOADING"
23 });getPeriods
API Version
59.0
Signature
getPeriods()
Example Implementation
1const api = this.template.querySelector('cgcloud-tpm-account-plan');
2
3// Correct Scenario
4api.getProperty('calculationStatus'); // 'VALID'
5
6api.getPeriods()
7 .then((periods) => {
8 // 0
9 console.log(periods[0].id); // "0"
10 console.log(periods[0].name); // "AP_LBL_TOTAL" (label of the period)
11 console.log(periods[0].periodtype); // "Total"
12 console.log(periods[0].dateFrom); // null
13 console.log(periods[0].dateThru); // null
14 // 1
15 console.log(periods[1].id); // 1
16 console.log(periods[1].name); // "36/2022" // label in case of label is specified alternativly it returns the ....
17 console.log(periods[1].periodtype); // "Week"
18 console.log(periods[1].dateFrom); // 1661731200000 timestamp
19 console.log(periods[1].dateThru); // 1662249600000 timestamp
20 });
21
22// Error Scenario
23api.getProperty('calculationStatus'); // 'LOADING'
24
25api.getPeriods()
26 .catch((error) => {
27 console.log(error.message); // CalculationStatus is not "VALID". Current Status "LOADING"
28 });getPeriodTypes
API Version
59.0
Signature
getPeriodTypes()
Example Implementation
1const api = this.template.querySelector('cgcloud-tpm-account-plan');
2
3// Correct Scenario
4api.getProperty('calculationStatus'); // 'VALID'
5
6api.getPeriodTypes()
7 .then((periodTypes) => {
8 console.log(periodTypes); // ["Total", "Week"]
9 });
10
11// Error Scenario
12api.getProperty('calculationStatus'); // 'LOADING'
13
14api.getPeriodTypes()
15 .catch((error) => {
16 console.log(error.message); // CalculationStatus is not "VALID". Current Status "LOADING"
17 });setManualInputs
API Version
Manual grid edits are an array of TPMManualInput instances. You can add new entries or remove entries from the existing array of elements.
60.0
Signature
setManualInputs(manualInputs)
Example Implementation
1// Import the TPMManualInput class to create new instances
2import {
3 TPMManualInput
4} from 'cgcloud/tpmGenericUtils';
5
6
7// In this method, we will be adding a new manual input to the grid.
8// This can, for instance, be executed in the click of a button or after
9// some user interaction
10async addNewManualInputs() {
11 const tpmAccountPlan = this.template.querySelector('cgcloud-tpm-account-plan');
12
13 // Extract the current manual inputs
14 const currentManualInputs = tpmAccountPlan.getProperty('manualInputs');
15
16 // You can read information from the current Manual Inputs:
17 currentManualInputs.forEach((mi) => {
18 console.log(mi.getKPICode()); // 'ALMN'
19 console.log(mi.getPeriodDateFrom()); // Date
20 console.log(mi.getPeriodDateThru()); // Date
21 console.log(mi.ProductId()); // '03sXXXXXXXXXXXXXXX'
22 console.log(mi.getValue()); // 133
23 });
24
25 // Example: KPI code to set the manual input to
26 const kpiCode = 'ABCD';
27
28 // Example: Product Id to set the manual input to. If null,
29 // the manual input will be applied to the "Total" for the KPI
30 // productId can be any level on the product hierarchy that is part of
31 // the calculation (SubCategory, Brand, etc)
32 const productId = '01tXXXXXXXXXXXXXXX';
33
34 // Methods used to extract data from Grid require the Grid to be in valid
35 // status. If trying to extract data from grid when not in the correct status
36 // an exception will be thrown
37 if (tpmAccountPlan.getProperty('calculationStatus') !== 'VALID') {
38 throw new Error('Grid not in VALID status');
39 }
40
41 // Extract the periods information from the grid
42 const periods = await tpmAccountPlan.getPeriods();
43
44 // We find the period where we want to set the manual input.
45 // You can find periods by name or use the periods "dateFrom, "dateThru" and "periodtype"
46 // attributes to search for an specific period.
47 // In this example, we will set the manual input on the "Total" period
48 // that uses an specific label
49 const manualInputPeriod = periods.find((p) => p.periodtype === 'Total');
50
51 // Create the new instance
52 const newManualInput = new TPMManualInput({
53 kpiCode: kpiCode,
54 period: manualInputPeriod,
55 productId: productId,
56 value: 123 // Value to set
57 });
58
59 // Create a new array with our new manual input appended
60 const newManualInputArray = [currentManualInputs, newManualInput];
61
62 // Set the manual inputs
63 tpmAccountPlan.setManualInputs(newManualInputArray);
64
65 // After setting the new manual inputs, the grids will be automatically
66 // reloaded and re-rendered with the new values in place.
67
68 // At this point, manual inputs are still not saved to SFDC database.
69 // the user must save the account plan
70}