1public with sharing class MultiRootPolicyRenewal 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 == 'multiRootRenewPolicy') {
10 System.debug('Start of connect API call to multi-root renew 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 effectiveFromDate = (String) inputMap.get('effectiveFromDate');
18 String effectiveToDate = (String) inputMap.get('effectiveToDate');
19 String transactionName = (String) inputMap.get('transactionName');
20 Map<String, Object> additionalFields = (Map<String, Object>) inputMap.get('additionalFields');
21
22 System.debug('Context ID: ' + contextId);
23 System.debug('Policy ID: ' + policyId);
24 System.debug('Policy Name: ' + policyName);
25 System.debug('Policy Number: ' + policyNumber);
26 System.debug('Effective From Date: ' + effectiveFromDate);
27 System.debug('Effective To Date: ' + effectiveToDate);
28 System.debug('Transaction Name: ' + transactionName);
29 System.debug('Additional Fields: ' + additionalFields);
30
31 // Initialize the job identifier
32 String jobIdentifier = null;
33
34 // Validate required parameters
35 if (String.isBlank(contextId)) {
36 System.debug('ERROR: Context ID is required');
37 outputMap.put('error', 'Context ID is required');
38 return null;
39 }
40
41 if (String.isBlank(policyId)) {
42 System.debug('ERROR: Policy ID is required');
43 outputMap.put('error', 'Policy ID is required');
44 return null;
45 }
46
47 try {
48
49 // Step 1: Create Multi-Root Policy Renewal input using the provided context ID
50 ConnectApi.RenewPolicyInputRepresentation renewalInput =
51 new ConnectApi.RenewPolicyInputRepresentation();
52
53 // Use the provided context ID (REQUIRED)
54 renewalInput.contextId = contextId;
55
56 // Populate fields for InsurancePolicyInputRepresentation (nested object)
57 ConnectApi.InsurancePolicyInputRepresentation insurancePolicy =
58 new ConnectApi.InsurancePolicyInputRepresentation();
59
60 // Set policy basic fields (all optional)
61 if (!String.isBlank(policyName)) {
62 insurancePolicy.policyName = policyName;
63 }
64 if (!String.isBlank(policyNumber)) {
65 insurancePolicy.policyNumber = policyNumber;
66 }
67
68 // Set effective dates on the insurancePolicy object (not on renewalInput directly)
69 if (!String.isBlank(effectiveFromDate)) {
70 insurancePolicy.effectiveFromDate = effectiveFromDate;
71 }
72 if (!String.isBlank(effectiveToDate)) {
73 insurancePolicy.effectiveToDate = effectiveToDate;
74 }
75
76 // Only set insurancePolicy if any fields were set
77 if (!String.isBlank(policyName) || !String.isBlank(policyNumber) ||
78 !String.isBlank(effectiveFromDate) || !String.isBlank(effectiveToDate)) {
79 renewalInput.insurancePolicy = insurancePolicy;
80 }
81
82 // Populate transaction record (optional)
83 if (!String.isBlank(transactionName)) {
84 ConnectApi.InsurancePolicyTransactionInputRepresentation transactionRecord =
85 new ConnectApi.InsurancePolicyTransactionInputRepresentation();
86 transactionRecord.name = transactionName;
87 renewalInput.transactionRecord = transactionRecord;
88 }
89
90 // Populate additional fields for child policies
91 if (additionalFields != null && !additionalFields.isEmpty()) {
92 System.debug('Processing additional fields for child policies');
93 renewalInput.additionalFields = buildAdditionalFieldsList(additionalFields);
94 }
95
96 // Step 2: Execute Multi-Root Policy Renewal with the provided context ID and policy ID
97 System.debug('Executing Multi-Root Policy Renewal with context ID: ' + contextId + ' and policy ID: ' + policyId);
98
99 // Call the Connect API - Multi-Root Renewal is ASYNCHRONOUS and returns a job identifier
100 // NOTE: Parameter order is INPUT first, then policyId
101 ConnectApi.PolicyAsyncRepresentation renewalResult =
102 ConnectApi.InsurancePolicyAdminFamily.multiRootRenewPolicy(renewalInput, policyId);
103
104 // Get the job identifier
105 jobIdentifier = renewalResult.jobIdentifier;
106
107 // Log success
108 System.debug('Multi-root policy renewal job started successfully. Job ID: ' + jobIdentifier);
109 System.debug('Context: ' + contextId);
110 System.debug('Policy ID: ' + policyId);
111
112 // Put the job identifier in the output map
113 outputMap.put('jobIdentifier', jobIdentifier);
114 outputMap.put('renewalResult', renewalResult);
115
116 } catch (Exception e) {
117 System.debug('Error while executing multi-root policy renewal: ' + e.getMessage());
118 System.debug('Stack Trace: ' + e.getStackTraceString());
119 outputMap.put('error', e.getMessage());
120 }
121
122 // Return the job identifier
123 return jobIdentifier;
124 }
125
126 // If the action is not recognized, return null
127 return null;
128 }
129
130
131 /**
132 * Build additional fields list for multi-root policies
133 * Converts from Map structure to List<ConnectApi.AdditionalFieldsMapValue>
134 *
135 * Input structure:
136 * {
137 * "additionalFieldsList": [
138 * {
139 * "additionalFieldsMapValue": {
140 * "instanceKey": "AutoSilver",
141 * "fields": { "EffectiveFromDate": "2025-01-01", "EffectiveToDate": "2026-01-01"}
142 * }
143 * }
144 * ]
145 * }
146 */
147 private static List<ConnectApi.AdditionalFieldsMapValue> buildAdditionalFieldsList(Map<String, Object> additionalFieldsInput) {
148 List<ConnectApi.AdditionalFieldsMapValue> fieldsList = new List<ConnectApi.AdditionalFieldsMapValue>();
149
150 // Get the additionalFieldsList array
151 List<Object> additionalFieldsList = (List<Object>) additionalFieldsInput.get('additionalFieldsList');
152
153 if (additionalFieldsList != null && !additionalFieldsList.isEmpty()) {
154 for (Object item : additionalFieldsList) {
155 Map<String, Object> itemMap = (Map<String, Object>) item;
156 Object mapValue = itemMap.get('additionalFieldsMapValue');
157
158 if (mapValue != null) {
159 // Create ConnectApi.AdditionalFieldsMapValue instance
160 ConnectApi.AdditionalFieldsMapValue fieldMapValue = new ConnectApi.AdditionalFieldsMapValue();
161
162 // Set the additionalFieldsMapValue property
163 // This property accepts Object type which will be the Map containing instanceKey and fields
164 fieldMapValue.additionalFieldsMapValue = mapValue;
165
166 fieldsList.add(fieldMapValue);
167 }
168 }
169 }
170
171 return fieldsList;
172 }
173}
174
175/*
176 * USAGE EXAMPLE:
177 * Copy and paste this code into Developer Console Execute Anonymous Window
178 */
179
180// Create instance of the callable class
181MultiRootPolicyRenewal callable = new MultiRootPolicyRenewal();
182
183// Build additional fields for child policies
184// Structure matches the JSON payload exactly
185Map<String, Object> additionalFields = new Map<String, Object>();
186List<Object> additionalFieldsList = new List<Object>();
187
188// Child Policy 1: Auto Insurance
189Map<String, Object> autoPolicy = new Map<String, Object>();
190Map<String, Object> autoMapValue = new Map<String, Object>();
191autoMapValue.put('instanceKey', 'AutoSilver');
192Map<String, Object> autoFields = new Map<String, Object>();
193autoFields.put('PolicyName', 'James Auto Policy');
194autoFields.put('Name', 'James Auto Policy');
195autoMapValue.put('fields', autoFields);
196autoPolicy.put('additionalFieldsMapValue', autoMapValue);
197additionalFieldsList.add(autoPolicy);
198
199// Child Policy 2: Health Insurance
200Map<String, Object> healthPolicy = new Map<String, Object>();
201Map<String, Object> healthMapValue = new Map<String, Object>();
202healthMapValue.put('instanceKey', 'FamilyHealth');
203
204Map<String, Object> healthFields = new Map<String, Object>();
205healthFields.put('PolicyName', 'James Medical Policy');
206healthFields.put('Name', 'James Medical Policy');
207healthMapValue.put('fields', healthFields);
208healthPolicy.put('additionalFieldsMapValue', healthMapValue);
209additionalFieldsList.add(healthPolicy);
210
211additionalFields.put('additionalFieldsList', additionalFieldsList);
212input.put('additionalFields', additionalFields);
213
214// Prepare the input arguments - WITH ADDITIONAL FIELDS
215Map<String, Object> input = new Map<String, Object>();
216input.put('contextId', <your-context-id-here>); // REQUIRED
217input.put('policyId', <your-policy-id-here>); // REQUIRED
218input.put('effectiveFromDate', '2026-01-01'); // Optional
219input.put('effectiveToDate', '2027-01-01'); // Optional
220input.put('policyName', 'Renewed Multi-Root Policy');
221input.put('transactionName', 'Multi-Root Annual Renewal with Updates');
222input.put('additionalFields', additionalFields);
223
224// Prepare the output map
225Map<String, Object> output = new Map<String, Object>();
226
227// Prepare the args map
228Map<String, Object> args = new Map<String, Object>();
229args.put('input', input);
230args.put('output', output);
231
232// Call the 'multiRootRenewPolicy' action
233Object result = callable.call('multiRootRenewPolicy', args);
234
235// Check results
236if (output.containsKey('error')) {
237 System.debug('ERROR: ' + output.get('error'));
238} else if (output.containsKey('jobIdentifier')) {
239 String jobId = (String) output.get('jobIdentifier');
240 System.debug('SUCCESS: Multi-root renewal job started with Job ID: ' + jobId);
241 System.debug('Use this job ID to track the renewal progress');
242}