salesforce-appraiser-review.../force-app/main/default/classes/CLMDocGenCallout.cls

173 lines
7.1 KiB
OpenEdge ABL

public class CLMDocGenCallout {
// S1 demo environment
private static final String CLM_ACCOUNT_ID_S1 = '2371cf36-eb8a-43fe-9f28-b5bbe7644397';
private static final String CLM_BASE_S1 = 'callout:CLMNamedCred/v2/' + CLM_ACCOUNT_ID_S1;
// UAT demo environment
private static final String CLM_ACCOUNT_ID_UAT = 'bccae332-c7db-4892-ab85-257df0f70fea';
private static final String CLM_BASE_UAT = 'callout:CLMuatNamedCreds/v2/' + CLM_ACCOUNT_ID_UAT;
private static final Integer HTTP_TIMEOUT = 30000;
/** Resolve the correct CLM base URL. env: 'UAT' or 'S1'. */
private static String clmBase(String env) {
return env == 'S1' ? CLM_BASE_S1 : CLM_BASE_UAT;
}
/** Defaults to UAT environment. */
public static CLMDocGenResponse generateDocument(
String caseId,
String templateDocHref,
String destinationFolderHref,
String destinationDocName
) {
return generateDocument(caseId, templateDocHref, destinationFolderHref, destinationDocName, 'UAT');
}
/**
* Generate a merged document via CLM documentxmlmergetasks (no user interaction).
* @param caseId Appraiser_Case__c record Id
* @param templateDocHref Full CLM Href URL of the template .docx document
* @param destinationFolderHref Full CLM Href URL of the destination folder
* @param destinationDocName Filename for the generated document, e.g. "Review_AC-00001.docx"
* @param env 'UAT' (apiuatna11.springcm.com) or 'S1' (api.s1.us.clm.demo.docusign.net)
*/
public static CLMDocGenResponse generateDocument(
String caseId,
String templateDocHref,
String destinationFolderHref,
String destinationDocName,
String env
) {
Map<String, Object> casePayload = AppraiserCasePayloadBuilder.buildPayload(caseId);
Map<String, Object> requestBody = new Map<String, Object>{
'TemplateDocument' => new Map<String, Object>{
'Href' => templateDocHref
},
'DataXML' => buildDataXml(casePayload),
'DestinationDocumentName' => destinationDocName,
'DestinationFolder' => new Map<String, Object>{
'Href' => destinationFolderHref
}
};
HttpRequest req = new HttpRequest();
req.setEndpoint(clmBase(env) + '/documentxmlmergetasks');
req.setMethod('POST');
req.setHeader('Content-Type', 'application/json');
req.setTimeout(HTTP_TIMEOUT);
req.setBody(JSON.serialize(requestBody));
try {
Http http = new Http();
HttpResponse res = http.send(req);
return parseTaskResponse(res);
} catch (Exception ex) {
return new CLMDocGenResponse(false, 'HTTP Callout Error: ' + ex.getMessage(), null, null);
}
}
/** Poll the status of a submitted merge task by its GUID. */
/** Poll the status of a submitted merge task by its GUID (defaults to UAT). */
public static CLMDocGenResponse getTaskStatus(String taskId) {
return getTaskStatus(taskId, 'UAT');
}
public static CLMDocGenResponse getTaskStatus(String taskId, String env) {
HttpRequest req = new HttpRequest();
req.setEndpoint(clmBase(env) + '/documentxmlmergetasks/' + taskId);
req.setMethod('GET');
req.setTimeout(HTTP_TIMEOUT);
try {
Http http = new Http();
HttpResponse res = http.send(req);
return parseTaskResponse(res);
} catch (Exception ex) {
return new CLMDocGenResponse(false, 'HTTP Callout Error: ' + ex.getMessage(), null, null);
}
}
/** Probe any CLM resource path for debugging. env: 'UAT' or 'S1'. */
public static String probe(String resource) {
return probe(resource, 'UAT');
}
public static String probe(String resource, String env) {
HttpRequest req = new HttpRequest();
req.setEndpoint(clmBase(env) + '/' + resource);
req.setMethod('GET');
req.setTimeout(HTTP_TIMEOUT);
HttpResponse res = new Http().send(req);
return 'HTTP ' + res.getStatusCode() + ': ' + res.getBody();
}
/**
* Build the DataXML string from the case payload.
* Flat fields become direct child elements of <TemplateFieldData>.
* DeficiencyList items expand into numbered elements:
* Deficiency_1_Number, Deficiency_1_Description, Deficiency_1_Resolution, etc.
*/
private static String buildDataXml(Map<String, Object> payload) {
String xml = '<TemplateFieldData>';
for (String key : payload.keySet()) {
if (key == 'DeficiencyList') continue;
xml += '<' + key + '>' + escapeXml(String.valueOf(payload.get(key))) + '</' + key + '>';
}
List<Object> deficiencies = (List<Object>) payload.get('DeficiencyList');
if (deficiencies != null) {
for (Integer i = 0; i < deficiencies.size(); i++) {
Map<String, Object> d = (Map<String, Object>) deficiencies[i];
String p = 'Deficiency_' + (i + 1) + '_';
xml += '<' + p + 'Number>' + escapeXml(String.valueOf(d.get('deficiencyNumber'))) + '</' + p + 'Number>';
xml += '<' + p + 'Description>' + escapeXml(String.valueOf(d.get('description'))) + '</' + p + 'Description>';
xml += '<' + p + 'Resolution>' + escapeXml(String.valueOf(d.get('resolution'))) + '</' + p + 'Resolution>';
}
xml += '<DeficiencyCount>' + deficiencies.size() + '</DeficiencyCount>';
}
xml += '</TemplateFieldData>';
return xml;
}
private static String escapeXml(String s) {
if (s == null) return '';
return s.replace('&', '&amp;')
.replace('<', '&lt;')
.replace('>', '&gt;')
.replace('"', '&quot;')
.replace('\'', '&apos;');
}
private static CLMDocGenResponse parseTaskResponse(HttpResponse res) {
Integer statusCode = res.getStatusCode();
String body = res.getBody();
if (statusCode >= 200 && statusCode < 300) {
Map<String, Object> m = (Map<String, Object>) JSON.deserializeUntyped(body);
String href = (String) m.get('Href');
String status = (String) m.get('Status');
String taskId = href != null ? href.substringAfterLast('/') : null;
return new CLMDocGenResponse(true, 'Task status: ' + status, href, taskId);
} else {
return new CLMDocGenResponse(false, 'CLM API Error (HTTP ' + statusCode + '): ' + body, null, null);
}
}
public class CLMDocGenResponse {
public Boolean success;
public String message;
public String documentUrl;
public String documentId;
public CLMDocGenResponse(Boolean success, String message, String documentUrl, String documentId) {
this.success = success;
this.message = message;
this.documentUrl = documentUrl;
this.documentId = documentId;
}
}
}