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