1// Logical endpoint name
2String endpointName = 'GET_REPORT_DATA';
3
4// name of the salesorg for which the report should be executed
5String salesOrg = '0001';
6
7<namespace>.OffplatformCallout callout = new <namespace>.OffplatformCallout(endpointName,
8salesOrg);
9
10// Log Transaction Id
11String txId = <namespace>.TransactionHandler.getTransactionIdentifier();
12
13// Execute callout
14<namespace>.OffplatformCalloutResponse response = callout.execute(
15 txId,
16 new Map<String, String>(), // No URL Parameters
17 JSON.serialize(
18 new Map<String, Object> {
19 'unzippedresponse' => 'true', // Required
20 'productidsforapex' => true, // Required
21 'reportname' => 'Promotion Report', // Report to execute
22 'filters' => new Map<String, Object> { // Report filters. Filters are dependent on the report definition!
23 'periodmonth' => new Map<String, Object> {
24 'start' => 0,
25 'total' => 12,
26 'year' => 2022
27 },
28 'accountsfids' => new List<String> {'001TC000000Ot6mYAC'},
29 'productsfids' => new List<String> {'01tTC0000001oHLYAY'},
30 'promo_templatesfid' => new List<String> {'a2UTC00000017Hd2AI', 'a2UTC00000017Hb2AI'},
31 'promo_phase' => new List<String> {
32 'Planning',
33 'Modeling',
34 'Committed',
35 'ForApproval'
36 },
37 'productlevel'=> 'product'
38 }
39
40 }
41 )
42);
43
44if (response.status != 200) {
45 // Handle error and return error info to caller
46}
47
48// Deserialize Response
49Map<String, Object> report = (Map<String, Object>) JSON.deserializeUntyped(response.result);
50
51// The names of the components come from the uimapping section of the
52// report definition. The UI components defined in the report definition will be present
53// in the result
54
55// ScoreCard component is represented by an array of decimals.
56// Each value matches the kpi defined in the report configuration inside the "scorecard"
57// KPI Group under attributes->kpidimension
58// the matching is index based (Kpi in first position is index 0)
59List<Object> scoreCard = (List<Object>) report.get('ScoreCard');
60
61// Flatlist components are represented by an object with a header and data property.
62// header property contains all the column headers
63// data property is an array of arrays. Each outer
64// array represents a row and inner array represent column values
65// The 3 first elements of each row are reserved
66// - Index 0 represent the row type. All row types can be mapped with the "rowTypeMapping"
67// Present in the response.
68// All product related ids use a shorter format. These product ids can be mapped
69// to SFDC Product2 ids by using the "internalIdToSfId" property of the reponse
70
71Map<String, Object> prodIdToSFIdMap = (Map<String, Object>) report.get('internalIdToSfId');
72
73Map<String, Object> flatlist = (Map<String, Object>) report.get('FlatList');
74List<Object> header = (List<Object>) flatlist.get('header');
75Map<String, Object> rowTypeMapping = (Map<String, Object>) flatlist.get('rowTypeMapping');
76List<Object> data = (List<Object>) flatlist.get('data');
77
78// extract header names
79List<String> headerNames = new List<String>();
80for (Object obj: header) {
81 Map<String, Object> casted = (Map<String, Object>) obj;
82 headerNames.add(String.valueOf(casted.get('name')));
83}
84
85// Print all the data
86for (Integer i = 0; i < data.size(); ++i) {
87 system.debug('Printing Row #' + i);
88 List<Object> dataRow = (List<Object>) data.get(i);
89
90 // print rowTypeMapping
91 System.debug('RowType: ' + String.valueOf(rowTypeMapping.get(String.valueOf(dataRow.get(1)))));
92
93 for (Integer j = 0; j < headerNames.size(); ++j) {
94 String headerName = headerNames.get(j);
95 Object dataCell = dataRow.get(j + 3); // Offset by 3
96 if (headerName.startsWith('productdimension')
97 && dataCell != null
98 && prodIdToSFIdMap.containsKey(String.valueOf(dataCell))) {
99 dataCell = prodIdToSFIdMap.get(String.valueOf(dataCell));
100 }
101 System.debug(headerName + ': ' + dataCell);
102 }
103}