1public with sharing class MultiRootPolicyEndorsement implements System.Callable {
2
3 public Object call(String action, Map<String, Object> args) {
4 // Retrieve the input and output maps from the arguments
5 Map<String, Object> inputMap = (Map<String, Object>) args.get('input');
6 Map<String, Object> outputMap = (Map<String, Object>) args.get('output');
7
8 // Check the action type
9 if (action == 'multiRootEndorsePolicy') {
10 System.debug('Start of connect API call to multi-root endorse policy');
11
12 // Get input parameters from the input map
13 String contextId = (String) inputMap.get('contextId');
14 String policyId = (String) inputMap.get('policyId');
15 String policyName = (String) inputMap.get('policyName');
16 String policyNumber = (String) inputMap.get('policyNumber');
17 String effectiveDate = (String) inputMap.get('effectiveDate');
18 String transactionName = (String) inputMap.get('transactionName');
19 Map<String, Object> additionalFields = (Map<String, Object>) inputMap.get('additionalFields');
20
21 System.debug('Context ID: ' + contextId);
22 System.debug('Policy ID: ' + policyId);
23 System.debug('Policy Name: ' + policyName);
24 System.debug('Policy Number: ' + policyNumber);
25 System.debug('Effective Date: ' + effectiveDate);
26 System.debug('Transaction Name: ' + transactionName);
27 System.debug('Additional Fields: ' + additionalFields);
28
29 // Initialize the job identifier
30 String jobIdentifier = null;
31
32 // Validate required parameters
33 if (String.isBlank(contextId)) {
34 System.debug('ERROR: Context ID is required');
35 outputMap.put('error', 'Context ID is required');
36 return null;
37 }
38
39 try {
40
41 // Step 1: Create Multi-Root Policy Endorsement input using the provided context ID
42 ConnectApi.EndorsePolicyInputRepresentation policyInput =
43 new ConnectApi.EndorsePolicyInputRepresentation();
44
45 // Populate fields for InsurancePolicyInputRepresentation
46 ConnectApi.InsurancePolicyInputRepresentation insurancePolicy =
47 new ConnectApi.InsurancePolicyInputRepresentation();
48
49 // Set policy basic fields (all optional except contextId)
50 if (!String.isBlank(policyName)) {
51 insurancePolicy.policyName = policyName;
52 }
53 if (!String.isBlank(policyNumber)) {
54 insurancePolicy.policyNumber = policyNumber;
55 }
56
57 policyInput.insurancePolicy = insurancePolicy;
58
59 // Populate transaction record (optional)
60 if (!String.isBlank(transactionName)) {
61 ConnectApi.InsurancePolicyTransactionInputRepresentation transactionRecord =
62 new ConnectApi.InsurancePolicyTransactionInputRepresentation();
63 transactionRecord.name = transactionName;
64 policyInput.transactionRecord = transactionRecord;
65 }
66
67 // Use the provided context ID (REQUIRED)
68 policyInput.contextId = contextId;
69
70 // Use the provided Effective Date (REQUIRED)
71 policyInput.effectiveDate = effectiveDate;
72
73 // Populate additional fields for child policies
74 if (additionalFields != null && !additionalFields.isEmpty()) {
75 System.debug('Processing additional fields for child policies');
76 policyInput.additionalFields = buildAdditionalFieldsList(additionalFields);
77 }
78
79 // Step 2: Execute Multi-Root Policy Endorsement with the provided context ID
80 System.debug('Executing Multi-Root Policy Endorsement with context ID: ' + contextId + ' policy ID:' + policyId);
81
82 Id idPolicyId = Id.valueOf(policyId);
83
84 // Call the Connect API - Multi-Root Endorsement is ASYNCHRONOUS and returns a job identifier
85 ConnectApi.PolicyAsyncRepresentation endorseResult =
86 ConnectApi.InsurancePolicyAdminFamily.multiRootEndorsePolicy(policyInput, idPolicyId);
87
88 // Get the job identifier
89 jobIdentifier = endorseResult.jobIdentifier;
90
91 // Log success
92 System.debug('Multi-root policy endorsement job started successfully. Job ID: ' + jobIdentifier);
93 System.debug('Context: ' + contextId);
94 if (!String.isBlank(policyName)) {
95 System.debug('Policy Name: ' + policyName);
96 }
97
98 // Put the job identifier in the output map
99 outputMap.put('jobIdentifier', jobIdentifier);
100 outputMap.put('endorsementResult', endorseResult);
101
102 } catch (Exception e) {
103 System.debug('Error while executing multi-root policy endorsement: ' + e.getMessage());
104 System.debug('Stack Trace: ' + e.getStackTraceString());
105 outputMap.put('error', e.getMessage());
106 }
107
108 // Return the job identifier
109 return jobIdentifier;
110 }
111
112 // If the action is not recognized, return null
113 return null;
114 }
115
116
117
118 /**
119 * Build additional fields list for multi-root policies
120 * Converts from Map structure to List<ConnectApi.AdditionalFieldsMapValue>
121 *
122 * Input structure:
123 * {
124 * "additionalFieldsList": [
125 * {
126 * "additionalFieldsMapValue": {
127 * "instanceKey": "AutoSilver",
128 * "fields": { "PolicyName": "James Auto Policy"}
129 * }
130 * }
131 * ]
132 * }
133 */
134 private static List<ConnectApi.AdditionalFieldsMapValue> buildAdditionalFieldsList(Map<String, Object> additionalFieldsInput) {
135 List<ConnectApi.AdditionalFieldsMapValue> fieldsList = new List<ConnectApi.AdditionalFieldsMapValue>();
136
137 // Get the additionalFieldsList array
138 List<Object> additionalFieldsList = (List<Object>) additionalFieldsInput.get('additionalFieldsList');
139
140 if (additionalFieldsList != null && !additionalFieldsList.isEmpty()) {
141 for (Object item : additionalFieldsList) {
142 Map<String, Object> itemMap = (Map<String, Object>) item;
143 Object mapValue = itemMap.get('additionalFieldsMapValue');
144
145 if (mapValue != null) {
146 // Create ConnectApi.AdditionalFieldsMapValue instance
147 ConnectApi.AdditionalFieldsMapValue fieldMapValue = new ConnectApi.AdditionalFieldsMapValue();
148
149 // Set the additionalFieldsMapValue property
150 // This property accepts Object type which will be the Map containing instanceKey and fields
151 fieldMapValue.additionalFieldsMapValue = mapValue;
152
153 fieldsList.add(fieldMapValue);
154 }
155 }
156 }
157
158 return fieldsList;
159 }
160}
161
162/*
163 * USAGE EXAMPLE:
164 * Multi-Root Policy Endorsement with Additional Fields
165 */
166
167// Create instance of the callable class
168MultiRootPolicyEndorsement callable = new MultiRootPolicyEndorsement();
169
170// Prepare the input arguments with additional fields
171Map<String, Object> input = new Map<String, Object>();
172input.put('contextId', '0000000i18tq18g002917629263342460535451b25974898aae9a44aab48ef3c'); // REQUIRED - Replace with your context ID
173input.put('policyId', '0YTSM0000001MrJ4AU'); // REQUIRED - Replace with your policy ID
174input.put('policyName', 'James Multi-Root Policy');
175input.put('policyNumber', 'James Multi-Root Policy');
176input.put('referencePolicyNumber', 'James1234');
177input.put('effectiveDate', '2025-08-30'); // REQUIRED
178input.put('transactionName', 'Endorsed Policy Transaction');
179
180// Build additional fields for child policies
181// Structure matches the JSON payload exactly
182Map<String, Object> additionalFields = new Map<String, Object>();
183List<Object> additionalFieldsList = new List<Object>();
184
185// Child Policy 1: Auto Insurance
186Map<String, Object> autoPolicy = new Map<String, Object>();
187Map<String, Object> autoMapValue = new Map<String, Object>();
188autoMapValue.put('instanceKey', 'AutoSilver');
189Map<String, Object> autoFields = new Map<String, Object>();
190autoFields.put('PolicyName', 'James Auto Policy');
191autoFields.put('Name', 'James Auto Policy');
192autoMapValue.put('fields', autoFields);
193autoPolicy.put('additionalFieldsMapValue', autoMapValue);
194additionalFieldsList.add(autoPolicy);
195
196// Child Policy 2: Health Insurance
197Map<String, Object> healthPolicy = new Map<String, Object>();
198Map<String, Object> healthMapValue = new Map<String, Object>();
199healthMapValue.put('instanceKey', 'FamilyHealth');
200
201Map<String, Object> healthFields = new Map<String, Object>();
202healthFields.put('PolicyName', 'James Medical Policy');
203healthFields.put('Name', 'James Medical Policy');
204healthMapValue.put('fields', healthFields);
205healthPolicy.put('additionalFieldsMapValue', healthMapValue);
206additionalFieldsList.add(healthPolicy);
207
208additionalFields.put('additionalFieldsList', additionalFieldsList);
209input.put('additionalFields', additionalFields);
210
211// Prepare the output map
212Map<String, Object> output = new Map<String, Object>();
213
214// Prepare the args map
215Map<String, Object> args = new Map<String, Object>();
216args.put('input', input);
217args.put('output', output);
218
219// Call the 'multiRootEndorsePolicy' action
220Object result = callable.call('multiRootEndorsePolicy', args);
221
222// Check results
223System.debug('Job Identifier: ' + result);
224if (output.containsKey('error')) {
225 System.debug('ERROR: ' + output.get('error'));
226} else if (output.containsKey('endorsementResult')) {
227 System.debug('SUCCESS: Multi-root policy endorsement job started with ID: ' + output.get('jobIdentifier'));
228 System.debug('This job will endorse the input policy and apply the changes using the context, with additional fields on parent and child policies.');
229 System.debug('Monitor this job ID for completion status.');
230}