Create Appraiser Case custom record and DocGen service
This commit is contained in:
parent
1e532029fa
commit
e058dedb82
|
|
@ -0,0 +1,71 @@
|
|||
# DocuSign CLM Template Mapping Snippet
|
||||
|
||||
This project assumes Salesforce is the system of record and DocuSign CLM doc gen receives a payload built from `Appraiser_Case__c` and its related `Appraiser_Deficiency__c` records.
|
||||
|
||||
## Suggested Merge Payload
|
||||
|
||||
```json
|
||||
{
|
||||
"templateKey": "APPRAISER_REVIEW_LETTER",
|
||||
"recordId": "a01XXXXXXXXXXXX",
|
||||
"sourceObject": "Appraiser_Case__c",
|
||||
"mergeData": {
|
||||
"appraiserCaseNumber": "AC-000123",
|
||||
"appraiserFieldReviewDate": "2026-04-01",
|
||||
"propertyStreet": "123 Main St",
|
||||
"propertyCity": "Ottawa",
|
||||
"propertyStateProvince": "ON",
|
||||
"propertyPostalCode": "K1A 0A1",
|
||||
"propertyCountry": "Canada",
|
||||
"propertyAddressSingleLine": "123 Main St | Ottawa, ON, K1A 0A1 | Canada",
|
||||
"deficiencies": [
|
||||
{
|
||||
"deficiencyNumber": "1",
|
||||
"description": "Missing comparable sale analysis",
|
||||
"resolution": "Provide updated comparable sales section",
|
||||
"sortOrder": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Suggested Template Tokens
|
||||
|
||||
Use the actual DocuSign CLM token syntax used in your tenant, but the field model should be equivalent to:
|
||||
|
||||
- `{{mergeData.appraiserCaseNumber}}`
|
||||
- `{{mergeData.appraiserFieldReviewDate}}`
|
||||
- `{{mergeData.propertyStreet}}`
|
||||
- `{{mergeData.propertyCity}}`
|
||||
- `{{mergeData.propertyStateProvince}}`
|
||||
- `{{mergeData.propertyPostalCode}}`
|
||||
- `{{mergeData.propertyCountry}}`
|
||||
- `{{mergeData.propertyAddressSingleLine}}`
|
||||
|
||||
### Deficiency Repeat Block
|
||||
|
||||
```handlebars
|
||||
{{#each mergeData.deficiencies}}
|
||||
| {{deficiencyNumber}} | {{description}} | {{resolution}} |
|
||||
{{/each}}
|
||||
```
|
||||
|
||||
## Recommended Letter Sections
|
||||
|
||||
1. Header / logo block
|
||||
2. Review metadata
|
||||
- Case number
|
||||
- Field review date
|
||||
- Property address
|
||||
3. Deficiency table
|
||||
- Deficiency number
|
||||
- Description
|
||||
- Resolution
|
||||
4. Closing / signature block
|
||||
|
||||
## Notes
|
||||
|
||||
- Keep `deficiencies` as a repeatable child collection, not a flattened text blob.
|
||||
- If DocuSign CLM requires a REST callout payload, `AppraiserCaseDocGenService.buildDocGenRequestJson()` is a good source payload to hand to your integration layer.
|
||||
- If your CLM tenant uses a different collection token syntax, map the same logical field names there.
|
||||
|
|
@ -1,39 +1,11 @@
|
|||
# Deployment & Testing — Appraiser Review Letter
|
||||
|
||||
## Implemented Salesforce Metadata
|
||||
- Parent object: Appraiser_Case__c (label: Appraiser Case)
|
||||
- Name field (auto number): Appraiser Case Number (AC-{00000})
|
||||
- Fields on Appraiser Case:
|
||||
- Appraiser_Field_Review_Date__c (Date)
|
||||
- Property_Address__c (Text 255)
|
||||
- Child object for repeatable deficiencies: Appraiser_Case_Deficiency__c
|
||||
- Fields on Appraiser Case Deficiency:
|
||||
- Appraiser_Case__c (Master-Detail to Appraiser_Case__c)
|
||||
- Deficiency_Number__c (Number)
|
||||
- Description__c (Long Text Area)
|
||||
- Resolution__c (Long Text Area)
|
||||
- Permission set: Appraiser_Case_Access
|
||||
- Apex Classes:
|
||||
- AppraiserCasePayloadBuilder: Transforms Salesforce data to CLM merge payload
|
||||
- AppraiserCasePayloadBuilderTest: Unit tests for payload builder
|
||||
- CLMDocGenCallout: HTTP integration with DocuSign CLM API
|
||||
|
||||
## Deployment Steps
|
||||
1. Deploy custom objects & fields
|
||||
2. Deploy Apex classes (included in manifest)
|
||||
3. Configure Named Credentials for CLM API access
|
||||
4. Configure Remote Site Settings for CLM instance
|
||||
5. Map merge fields to object schema
|
||||
6. Configure CLM template and connect API
|
||||
7. Test with sample Appraiser Case records
|
||||
|
||||
### Suggested CLI Deploy Commands
|
||||
1. Authenticate to your org:
|
||||
- sf org login web --alias appraiser-dev
|
||||
2. Validate source deploy:
|
||||
- sf project deploy validate --target-org appraiser-dev --manifest manifest/package.xml
|
||||
3. Deploy metadata:
|
||||
- sf project deploy start --target-org appraiser-dev --manifest manifest/package.xml
|
||||
2. Copy updated template files into Salesforce docs directory
|
||||
3. Map merge fields to object schema
|
||||
4. Configure CLM template and connect API
|
||||
5. Test with sample Appraisal and Deficiency objects
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -43,39 +15,6 @@
|
|||
- Test table rendering for arrays (DeficiencyList, ReviewerComments)
|
||||
- Document any failed merges or formatting gaps
|
||||
|
||||
## CLM Data Mapping Starter
|
||||
- AppraiserCaseNumber -> Appraiser_Case__c.Name
|
||||
- AppraiserFieldReviewDate -> Appraiser_Case__c.Appraiser_Field_Review_Date__c
|
||||
- PropertyAddress -> Appraiser_Case__c.Property_Address__c
|
||||
- DeficiencyList[] -> Appraiser_Case__c.Deficiencies__r
|
||||
- deficiencyNumber -> Deficiency_Number__c
|
||||
- description -> Description__c
|
||||
- resolution -> Resolution__c
|
||||
|
||||
## Smoke Test Execution
|
||||
After deployment, sample test data was created:
|
||||
- Appraiser Case: AC-00001 (a0wKW000007OIiCYAW)
|
||||
- 3 related deficiency records verified
|
||||
|
||||
### Test Payload Query (run in Apex Execute or Query Editor)
|
||||
```soql
|
||||
SELECT Id, Name, Appraiser_Field_Review_Date__c, Property_Address__c,
|
||||
(SELECT Id, Deficiency_Number__c, Description__c, Resolution__c
|
||||
FROM Deficiencies__r ORDER BY Deficiency_Number__c)
|
||||
FROM Appraiser_Case__c
|
||||
WHERE Id='a0wKW000007OIiCYAW'
|
||||
```
|
||||
|
||||
### Test Payload Generation (Apex)
|
||||
```apex
|
||||
String caseId = 'a0wKW000007OIiCYAW';
|
||||
Map<String, Object> payload = AppraiserCasePayloadBuilder.buildPayload(caseId);
|
||||
System.debug(JSON.serializePretty(payload));
|
||||
```
|
||||
|
||||
## CLM Doc Gen Integration
|
||||
See [CLM_INTEGRATION.md](CLM_INTEGRATION.md) for complete setup and integration patterns.
|
||||
|
||||
---
|
||||
|
||||
_Last updated: 2026-02-26 13:26 PM_
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
# Next Steps — DocuSign CLM Launch Path
|
||||
|
||||
I added a placeholder Quick Action metadata file so there is an explicit place in the project for the document generation launch pattern.
|
||||
|
||||
## Reality check
|
||||
|
||||
DocuSign CLM launch configuration varies by package and org setup. Because of that, the action in this repo is a scaffold/placeholder, not a guaranteed final production action.
|
||||
|
||||
## Recommended implementation path
|
||||
|
||||
### Option A — Screen Flow (recommended first)
|
||||
- Create a Screen Flow or autolaunched Flow that accepts `recordId`
|
||||
- Call an Apex invocable or Apex action that builds the payload
|
||||
- Hand that payload to your DocuSign CLM mechanism
|
||||
- Redirect user to resulting document or status page
|
||||
|
||||
### Option B — LWC / Aura quick action
|
||||
- Use a Lightning Web Component quick action on `Appraiser_Case__c`
|
||||
- Call `AppraiserCaseDocGenService.buildDocGenRequestJson(recordId, templateKey)`
|
||||
- Send the payload to the installed DocuSign CLM endpoint or orchestration layer
|
||||
|
||||
### Option C — Button / URL hack
|
||||
- Usually fast, usually brittle. I don’t recommend it unless your CLM package explicitly documents it.
|
||||
|
||||
## What to confirm in your org
|
||||
|
||||
1. Exact DocuSign CLM package/API available in Salesforce
|
||||
2. Whether generation is initiated by package component, Flow action, Apex callout, or named credential call
|
||||
3. Template identifier format (`templateKey`, template Id, or external document key)
|
||||
4. Returned artifact behavior (attach to record, email, save to CLM repository, etc.)
|
||||
|
||||
## Good next move
|
||||
|
||||
Once you know the exact DocuSign package artifact available in the org, I can wire the placeholder into a real Flow/LWC/Apex launch path.
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
# Salesforce Setup — Appraiser Case + DocuSign CLM
|
||||
|
||||
## What was added
|
||||
|
||||
### Custom object: `Appraiser_Case__c`
|
||||
- Auto-number name field labeled **Appraiser Case Number**
|
||||
- `Appraiser_Field_Review_Date__c` (Date)
|
||||
- `Property_Street__c` (Text 255)
|
||||
- `Property_City__c` (Text 80)
|
||||
- `Property_State_Province__c` (Text 80)
|
||||
- `Property_Postal_Code__c` (Text 20)
|
||||
- `Property_Country__c` (Text 80)
|
||||
|
||||
### Child custom object: `Appraiser_Deficiency__c`
|
||||
- Master-detail to `Appraiser_Case__c`
|
||||
- `Deficiency_Number__c` (Text 50)
|
||||
- `Description__c` (Long Text Area)
|
||||
- `Resolution__c` (Long Text Area)
|
||||
- `Sort_Order__c` (Number)
|
||||
|
||||
### Layouts
|
||||
- Basic page layout for Appraiser Case
|
||||
- Basic page layout for Appraiser Deficiency
|
||||
- Related list on Appraiser Case for deficiencies
|
||||
- Basic list view on Appraiser Case
|
||||
|
||||
### Tabs and permissions
|
||||
- Custom tabs for both objects
|
||||
- Permission set: `Appraiser_Case_Admin`
|
||||
|
||||
### Apex
|
||||
- `AppraiserCaseDocGenService.cls`
|
||||
- `AppraiserCaseDocGenServiceTest.cls`
|
||||
|
||||
### Sample data
|
||||
- Anonymous Apex script: `scripts/apex/createSampleAppraiserCase.apex`
|
||||
|
||||
## Deploy
|
||||
|
||||
From the project root:
|
||||
|
||||
```bash
|
||||
sf project deploy start --source-dir force-app
|
||||
```
|
||||
|
||||
Or from elsewhere:
|
||||
|
||||
```bash
|
||||
sf project deploy start --source-dir /home/paulh/.openclaw/workspace/projects/salesforce-appraiser-review-letter/force-app
|
||||
```
|
||||
|
||||
## Test Apex
|
||||
|
||||
```bash
|
||||
sf apex run test --tests AppraiserCaseDocGenServiceTest --result-format human
|
||||
```
|
||||
|
||||
## Load sample data
|
||||
|
||||
```bash
|
||||
sf apex run --file scripts/apex/createSampleAppraiserCase.apex
|
||||
```
|
||||
|
||||
## Assign permission set
|
||||
|
||||
```bash
|
||||
sf org assign permset --name Appraiser_Case_Admin
|
||||
```
|
||||
|
||||
## Suggested next steps in Salesforce
|
||||
|
||||
1. Deploy metadata.
|
||||
2. Assign permission set.
|
||||
3. Run the sample Apex script.
|
||||
4. Open the `Appraiser Case` tab and verify the record + related deficiencies.
|
||||
5. Validate the JSON payload in debug logs or by running the Apex methods directly.
|
||||
6. Wire the DocuSign CLM launch path based on the exact package capability in your org.
|
||||
|
||||
## About the quick action
|
||||
|
||||
A placeholder quick action metadata file was added to mark the launch point, but DocuSign CLM launch mechanics vary by package/org. See `docs/NEXT_STEPS_DOCGEN.md` for the practical wiring options.
|
||||
|
||||
## About “page layout” and “default setup”
|
||||
|
||||
You said “just do default.” In Salesforce terms that means I created the baseline metadata so records can be created and edited in a normal Lightning UI without custom polish yet.
|
||||
|
|
@ -42,39 +42,6 @@ Outline technical and functional requirements for Appraiser Review Letter templa
|
|||
- What is the authoritative object and field schema for merge?
|
||||
- Are custom field mappings needed for relationships (e.g. lookup fields)?
|
||||
|
||||
## Initial Authoritative Salesforce Schema
|
||||
- Appraiser_Case__c (Appraiser Case)
|
||||
- Name (label: Appraiser Case Number, AutoNumber)
|
||||
- Appraiser_Field_Review_Date__c (Date)
|
||||
- Property_Address__c (Text)
|
||||
- Appraiser_Case_Deficiency__c (Appraiser Case Deficiency)
|
||||
- Appraiser_Case__c (Master-Detail -> Appraiser_Case__c)
|
||||
- Deficiency_Number__c (Number)
|
||||
- Description__c (Long Text Area)
|
||||
- Resolution__c (Long Text Area)
|
||||
|
||||
This schema supports CLM array merges by iterating child deficiency records tied to one appraiser case.
|
||||
|
||||
## CLM Integration
|
||||
|
||||
### Payload Structure (from AppraiserCasePayloadBuilder)
|
||||
The Apex class `AppraiserCasePayloadBuilder` transforms Salesforce records into CLM-ready JSON:
|
||||
- AppraiserCaseNumber (string) -> Appraiser_Case__c.Name
|
||||
- AppraiserFieldReviewDate (ISO date) -> Appraiser_Case__c.Appraiser_Field_Review_Date__c
|
||||
- PropertyAddress (string) -> Appraiser_Case__c.Property_Address__c
|
||||
- DeficiencyList (array of objects):
|
||||
- deficiencyNumber (number) -> Appraiser_Case_Deficiency__c.Deficiency_Number__c
|
||||
- description (string) -> Appraiser_Case_Deficiency__c.Description__c
|
||||
- resolution (string) -> Appraiser_Case_Deficiency__c.Resolution__c
|
||||
|
||||
### CLM API Integration (CLMDocGenCallout)
|
||||
- HTTP POST to DocuSign CLM API with merge payload
|
||||
- Named Credentials: Securely store CLM endpoint + OAuth token
|
||||
- Remote Site Settings: Whitelist CLM instance domain
|
||||
- Response includes document URL and ID for tracking
|
||||
|
||||
See [CLM_INTEGRATION.md](CLM_INTEGRATION.md) for setup and usage patterns.
|
||||
|
||||
---
|
||||
_Last updated: 2026-02-26 10:35 AM_
|
||||
_Work in progress: Integration and schema expansion next._
|
||||
---
|
||||
_Last updated: 2026-02-26 10:35 AM_
|
||||
_Work in progress: Integration and schema expansion next._
|
||||
|
|
|
|||
|
|
@ -0,0 +1,103 @@
|
|||
public with sharing class AppraiserCaseDocGenService {
|
||||
public class DeficiencyDTO {
|
||||
@AuraEnabled public String deficiencyNumber;
|
||||
@AuraEnabled public String description;
|
||||
@AuraEnabled public String resolution;
|
||||
@AuraEnabled public Decimal sortOrder;
|
||||
}
|
||||
|
||||
public class AppraiserCasePayload {
|
||||
@AuraEnabled public Id caseId;
|
||||
@AuraEnabled public String appraiserCaseNumber;
|
||||
@AuraEnabled public Date appraiserFieldReviewDate;
|
||||
@AuraEnabled public String propertyStreet;
|
||||
@AuraEnabled public String propertyCity;
|
||||
@AuraEnabled public String propertyStateProvince;
|
||||
@AuraEnabled public String propertyPostalCode;
|
||||
@AuraEnabled public String propertyCountry;
|
||||
@AuraEnabled public String propertyAddressSingleLine;
|
||||
@AuraEnabled public List<DeficiencyDTO> deficiencies;
|
||||
}
|
||||
|
||||
@AuraEnabled(cacheable=false)
|
||||
public static String buildPayloadJson(Id appraiserCaseId) {
|
||||
return JSON.serialize(buildPayload(appraiserCaseId));
|
||||
}
|
||||
|
||||
public static AppraiserCasePayload buildPayload(Id appraiserCaseId) {
|
||||
Appraiser_Case__c appraiserCase = [
|
||||
SELECT Id,
|
||||
Name,
|
||||
Appraiser_Field_Review_Date__c,
|
||||
Property_Street__c,
|
||||
Property_City__c,
|
||||
Property_State_Province__c,
|
||||
Property_Postal_Code__c,
|
||||
Property_Country__c,
|
||||
(SELECT Id,
|
||||
Name,
|
||||
Deficiency_Number__c,
|
||||
Description__c,
|
||||
Resolution__c,
|
||||
Sort_Order__c
|
||||
FROM Appraiser_Deficiencies__r
|
||||
ORDER BY Sort_Order__c ASC, CreatedDate ASC)
|
||||
FROM Appraiser_Case__c
|
||||
WHERE Id = :appraiserCaseId
|
||||
LIMIT 1
|
||||
];
|
||||
|
||||
AppraiserCasePayload payload = new AppraiserCasePayload();
|
||||
payload.caseId = appraiserCase.Id;
|
||||
payload.appraiserCaseNumber = appraiserCase.Name;
|
||||
payload.appraiserFieldReviewDate = appraiserCase.Appraiser_Field_Review_Date__c;
|
||||
payload.propertyStreet = appraiserCase.Property_Street__c;
|
||||
payload.propertyCity = appraiserCase.Property_City__c;
|
||||
payload.propertyStateProvince = appraiserCase.Property_State_Province__c;
|
||||
payload.propertyPostalCode = appraiserCase.Property_Postal_Code__c;
|
||||
payload.propertyCountry = appraiserCase.Property_Country__c;
|
||||
payload.propertyAddressSingleLine = buildAddress(appraiserCase);
|
||||
payload.deficiencies = new List<DeficiencyDTO>();
|
||||
|
||||
for (Appraiser_Deficiency__c deficiency : appraiserCase.Appraiser_Deficiencies__r) {
|
||||
DeficiencyDTO dto = new DeficiencyDTO();
|
||||
dto.deficiencyNumber = deficiency.Deficiency_Number__c;
|
||||
dto.description = deficiency.Description__c;
|
||||
dto.resolution = deficiency.Resolution__c;
|
||||
dto.sortOrder = deficiency.Sort_Order__c;
|
||||
payload.deficiencies.add(dto);
|
||||
}
|
||||
|
||||
return payload;
|
||||
}
|
||||
|
||||
private static String buildAddress(Appraiser_Case__c appraiserCase) {
|
||||
List<String> parts = new List<String>();
|
||||
if (String.isNotBlank(appraiserCase.Property_Street__c)) parts.add(appraiserCase.Property_Street__c);
|
||||
|
||||
List<String> cityLine = new List<String>();
|
||||
if (String.isNotBlank(appraiserCase.Property_City__c)) cityLine.add(appraiserCase.Property_City__c);
|
||||
if (String.isNotBlank(appraiserCase.Property_State_Province__c)) cityLine.add(appraiserCase.Property_State_Province__c);
|
||||
if (String.isNotBlank(appraiserCase.Property_Postal_Code__c)) cityLine.add(appraiserCase.Property_Postal_Code__c);
|
||||
if (!cityLine.isEmpty()) parts.add(String.join(cityLine, ', '));
|
||||
|
||||
if (String.isNotBlank(appraiserCase.Property_Country__c)) parts.add(appraiserCase.Property_Country__c);
|
||||
return String.join(parts, ' | ');
|
||||
}
|
||||
|
||||
@AuraEnabled(cacheable=false)
|
||||
public static Map<String, Object> buildDocGenRequest(Id appraiserCaseId, String templateKey) {
|
||||
AppraiserCasePayload payload = buildPayload(appraiserCaseId);
|
||||
Map<String, Object> requestBody = new Map<String, Object>();
|
||||
requestBody.put('templateKey', templateKey);
|
||||
requestBody.put('recordId', appraiserCaseId);
|
||||
requestBody.put('sourceObject', 'Appraiser_Case__c');
|
||||
requestBody.put('mergeData', payload);
|
||||
return requestBody;
|
||||
}
|
||||
|
||||
@AuraEnabled(cacheable=false)
|
||||
public static String buildDocGenRequestJson(Id appraiserCaseId, String templateKey) {
|
||||
return JSON.serialize(buildDocGenRequest(appraiserCaseId, templateKey));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
|
||||
<apiVersion>63.0</apiVersion>
|
||||
<status>Active</status>
|
||||
</ApexClass>
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
@IsTest
|
||||
private class AppraiserCaseDocGenServiceTest {
|
||||
@IsTest
|
||||
static void buildsPayloadAndRequestJson() {
|
||||
Appraiser_Case__c appraiserCase = new Appraiser_Case__c(
|
||||
Appraiser_Field_Review_Date__c = Date.newInstance(2026, 4, 1),
|
||||
Property_Street__c = '123 Main St',
|
||||
Property_City__c = 'Ottawa',
|
||||
Property_State_Province__c = 'ON',
|
||||
Property_Postal_Code__c = 'K1A 0A1',
|
||||
Property_Country__c = 'Canada'
|
||||
);
|
||||
insert appraiserCase;
|
||||
|
||||
insert new Appraiser_Deficiency__c(
|
||||
Name = 'Deficiency 1',
|
||||
Appraiser_Case__c = appraiserCase.Id,
|
||||
Deficiency_Number__c = '1',
|
||||
Description__c = 'Missing comparable sale analysis',
|
||||
Resolution__c = 'Provide updated comparable sales section',
|
||||
Sort_Order__c = 1
|
||||
);
|
||||
|
||||
Test.startTest();
|
||||
AppraiserCaseDocGenService.AppraiserCasePayload payload = AppraiserCaseDocGenService.buildPayload(appraiserCase.Id);
|
||||
String json = AppraiserCaseDocGenService.buildDocGenRequestJson(appraiserCase.Id, 'APPRAISER_REVIEW_LETTER');
|
||||
Test.stopTest();
|
||||
|
||||
System.assertEquals(appraiserCase.Id, payload.caseId);
|
||||
System.assertEquals('Ottawa', payload.propertyCity);
|
||||
System.assertEquals(1, payload.deficiencies.size());
|
||||
System.assertEquals('1', payload.deficiencies[0].deficiencyNumber);
|
||||
System.assert(json.contains('APPRAISER_REVIEW_LETTER'));
|
||||
System.assert(json.contains('Missing comparable sale analysis'));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
|
||||
<apiVersion>63.0</apiVersion>
|
||||
<status>Active</status>
|
||||
</ApexClass>
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Layout xmlns="http://soap.sforce.com/2006/04/metadata">
|
||||
<layoutSections>
|
||||
<customLabel>false</customLabel>
|
||||
<detailHeading>true</detailHeading>
|
||||
<editHeading>true</editHeading>
|
||||
<label>Information</label>
|
||||
<layoutColumns>
|
||||
<layoutItems>
|
||||
<behavior>Required</behavior>
|
||||
<field>Name</field>
|
||||
</layoutItems>
|
||||
<layoutItems>
|
||||
<behavior>Edit</behavior>
|
||||
<field>Appraiser_Field_Review_Date__c</field>
|
||||
</layoutItems>
|
||||
<layoutItems>
|
||||
<behavior>Edit</behavior>
|
||||
<field>CreatedDate</field>
|
||||
</layoutItems>
|
||||
</layoutColumns>
|
||||
<layoutColumns>
|
||||
<layoutItems>
|
||||
<behavior>Edit</behavior>
|
||||
<field>LastModifiedDate</field>
|
||||
</layoutItems>
|
||||
</layoutColumns>
|
||||
<style>TwoColumnsTopToBottom</style>
|
||||
</layoutSections>
|
||||
<layoutSections>
|
||||
<customLabel>false</customLabel>
|
||||
<detailHeading>true</detailHeading>
|
||||
<editHeading>true</editHeading>
|
||||
<label>Property Address</label>
|
||||
<layoutColumns>
|
||||
<layoutItems>
|
||||
<behavior>Edit</behavior>
|
||||
<field>Property_Street__c</field>
|
||||
</layoutItems>
|
||||
<layoutItems>
|
||||
<behavior>Edit</behavior>
|
||||
<field>Property_City__c</field>
|
||||
</layoutItems>
|
||||
<layoutItems>
|
||||
<behavior>Edit</behavior>
|
||||
<field>Property_State_Province__c</field>
|
||||
</layoutItems>
|
||||
</layoutColumns>
|
||||
<layoutColumns>
|
||||
<layoutItems>
|
||||
<behavior>Edit</behavior>
|
||||
<field>Property_Postal_Code__c</field>
|
||||
</layoutItems>
|
||||
<layoutItems>
|
||||
<behavior>Edit</behavior>
|
||||
<field>Property_Country__c</field>
|
||||
</layoutItems>
|
||||
</layoutColumns>
|
||||
<style>TwoColumnsTopToBottom</style>
|
||||
</layoutSections>
|
||||
<relatedLists>
|
||||
<fields>NAME</fields>
|
||||
<fields>Deficiency_Number__c</fields>
|
||||
<fields>Description__c</fields>
|
||||
<fields>Resolution__c</fields>
|
||||
<fields>Sort_Order__c</fields>
|
||||
<relatedList>Appraiser_Deficiencies__r</relatedList>
|
||||
</relatedLists>
|
||||
<relatedLists>
|
||||
<fields>SUBJECT</fields>
|
||||
<fields>STATUS</fields>
|
||||
<fields>DUE_DATE</fields>
|
||||
<relatedList>OpenActivities</relatedList>
|
||||
</relatedLists>
|
||||
<showEmailCheckbox>false</showEmailCheckbox>
|
||||
<showHighlightsPanel>true</showHighlightsPanel>
|
||||
<showInteractionLogPanel>false</showInteractionLogPanel>
|
||||
<showRunAssignmentRulesCheckbox>false</showRunAssignmentRulesCheckbox>
|
||||
<showSubmitAndAttachButton>false</showSubmitAndAttachButton>
|
||||
</Layout>
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Layout xmlns="http://soap.sforce.com/2006/04/metadata">
|
||||
<layoutSections>
|
||||
<customLabel>false</customLabel>
|
||||
<detailHeading>true</detailHeading>
|
||||
<editHeading>true</editHeading>
|
||||
<label>Information</label>
|
||||
<layoutColumns>
|
||||
<layoutItems>
|
||||
<behavior>Required</behavior>
|
||||
<field>Name</field>
|
||||
</layoutItems>
|
||||
<layoutItems>
|
||||
<behavior>Required</behavior>
|
||||
<field>Appraiser_Case__c</field>
|
||||
</layoutItems>
|
||||
<layoutItems>
|
||||
<behavior>Edit</behavior>
|
||||
<field>Deficiency_Number__c</field>
|
||||
</layoutItems>
|
||||
</layoutColumns>
|
||||
<layoutColumns>
|
||||
<layoutItems>
|
||||
<behavior>Edit</behavior>
|
||||
<field>Sort_Order__c</field>
|
||||
</layoutItems>
|
||||
</layoutColumns>
|
||||
<style>TwoColumnsTopToBottom</style>
|
||||
</layoutSections>
|
||||
<layoutSections>
|
||||
<customLabel>false</customLabel>
|
||||
<detailHeading>true</detailHeading>
|
||||
<editHeading>true</editHeading>
|
||||
<label>Details</label>
|
||||
<layoutColumns>
|
||||
<layoutItems>
|
||||
<behavior>Edit</behavior>
|
||||
<field>Description__c</field>
|
||||
</layoutItems>
|
||||
</layoutColumns>
|
||||
<layoutColumns>
|
||||
<layoutItems>
|
||||
<behavior>Edit</behavior>
|
||||
<field>Resolution__c</field>
|
||||
</layoutItems>
|
||||
</layoutColumns>
|
||||
<style>TwoColumnsTopToBottom</style>
|
||||
</layoutSections>
|
||||
<showEmailCheckbox>false</showEmailCheckbox>
|
||||
<showHighlightsPanel>true</showHighlightsPanel>
|
||||
<showInteractionLogPanel>false</showInteractionLogPanel>
|
||||
<showRunAssignmentRulesCheckbox>false</showRunAssignmentRulesCheckbox>
|
||||
<showSubmitAndAttachButton>false</showSubmitAndAttachButton>
|
||||
</Layout>
|
||||
|
|
@ -1,16 +1,38 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CustomObject xmlns="http://soap.sforce.com/2006/04/metadata">
|
||||
<actionOverrides>
|
||||
<actionName>New</actionName>
|
||||
<type>Default</type>
|
||||
</actionOverrides>
|
||||
<actionOverrides>
|
||||
<actionName>Edit</actionName>
|
||||
<type>Default</type>
|
||||
</actionOverrides>
|
||||
<actionOverrides>
|
||||
<actionName>View</actionName>
|
||||
<type>Default</type>
|
||||
</actionOverrides>
|
||||
<allowInChatterGroups>false</allowInChatterGroups>
|
||||
<compactLayoutAssignment>SYSTEM</compactLayoutAssignment>
|
||||
<deploymentStatus>Deployed</deploymentStatus>
|
||||
<description>Main record for appraiser review letter generation in CLM.</description>
|
||||
<enableActivities>true</enableActivities>
|
||||
<enableBulkApi>true</enableBulkApi>
|
||||
<enableFeeds>false</enableFeeds>
|
||||
<enableHistory>true</enableHistory>
|
||||
<enableLicensing>false</enableLicensing>
|
||||
<enableReports>true</enableReports>
|
||||
<enableSearch>true</enableSearch>
|
||||
<enableSharing>true</enableSharing>
|
||||
<enableStreamingApi>true</enableStreamingApi>
|
||||
<externalSharingModel>Private</externalSharingModel>
|
||||
<label>Appraiser Case</label>
|
||||
<nameField>
|
||||
<displayFormat>AC-{00000}</displayFormat>
|
||||
<displayFormat>AC-{000000}</displayFormat>
|
||||
<label>Appraiser Case Number</label>
|
||||
<type>AutoNumber</type>
|
||||
</nameField>
|
||||
<pluralLabel>Appraiser Cases</pluralLabel>
|
||||
<searchLayouts></searchLayouts>
|
||||
<sharingModel>ReadWrite</sharingModel>
|
||||
</CustomObject>
|
||||
<visibility>Public</visibility>
|
||||
</CustomObject>
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
|
||||
<fullName>Appraiser_Field_Review_Date__c</fullName>
|
||||
<description>Date the appraiser field review was completed.</description>
|
||||
<label>Appraiser Field Review Date</label>
|
||||
<required>false</required>
|
||||
<trackHistory>false</trackHistory>
|
||||
<trackHistory>true</trackHistory>
|
||||
<type>Date</type>
|
||||
</CustomField>
|
||||
</CustomField>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
|
||||
<fullName>Property_City__c</fullName>
|
||||
<label>Property City</label>
|
||||
<length>80</length>
|
||||
<required>false</required>
|
||||
<trackHistory>true</trackHistory>
|
||||
<type>Text</type>
|
||||
</CustomField>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
|
||||
<fullName>Property_Country__c</fullName>
|
||||
<label>Property Country</label>
|
||||
<length>80</length>
|
||||
<required>false</required>
|
||||
<trackHistory>true</trackHistory>
|
||||
<type>Text</type>
|
||||
</CustomField>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
|
||||
<fullName>Property_Postal_Code__c</fullName>
|
||||
<label>Property Postal Code</label>
|
||||
<length>20</length>
|
||||
<required>false</required>
|
||||
<trackHistory>true</trackHistory>
|
||||
<type>Text</type>
|
||||
</CustomField>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
|
||||
<fullName>Property_State_Province__c</fullName>
|
||||
<label>Property State/Province</label>
|
||||
<length>80</length>
|
||||
<required>false</required>
|
||||
<trackHistory>true</trackHistory>
|
||||
<type>Text</type>
|
||||
</CustomField>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
|
||||
<fullName>Property_Street__c</fullName>
|
||||
<label>Property Street</label>
|
||||
<length>255</length>
|
||||
<required>false</required>
|
||||
<trackHistory>true</trackHistory>
|
||||
<type>Text</type>
|
||||
</CustomField>
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ListView xmlns="http://soap.sforce.com/2006/04/metadata">
|
||||
<fullName>All</fullName>
|
||||
<columns>Name</columns>
|
||||
<columns>Appraiser_Field_Review_Date__c</columns>
|
||||
<columns>Property_Street__c</columns>
|
||||
<columns>Property_City__c</columns>
|
||||
<columns>Property_State_Province__c</columns>
|
||||
<columns>LastModifiedDate</columns>
|
||||
<filterScope>Everything</filterScope>
|
||||
<label>All</label>
|
||||
</ListView>
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CustomObject xmlns="http://soap.sforce.com/2006/04/metadata">
|
||||
<actionOverrides>
|
||||
<actionName>New</actionName>
|
||||
<type>Default</type>
|
||||
</actionOverrides>
|
||||
<actionOverrides>
|
||||
<actionName>Edit</actionName>
|
||||
<type>Default</type>
|
||||
</actionOverrides>
|
||||
<actionOverrides>
|
||||
<actionName>View</actionName>
|
||||
<type>Default</type>
|
||||
</actionOverrides>
|
||||
<allowInChatterGroups>false</allowInChatterGroups>
|
||||
<compactLayoutAssignment>SYSTEM</compactLayoutAssignment>
|
||||
<deploymentStatus>Deployed</deploymentStatus>
|
||||
<enableActivities>false</enableActivities>
|
||||
<enableBulkApi>true</enableBulkApi>
|
||||
<enableFeeds>false</enableFeeds>
|
||||
<enableHistory>true</enableHistory>
|
||||
<enableLicensing>false</enableLicensing>
|
||||
<enableReports>true</enableReports>
|
||||
<enableSearch>true</enableSearch>
|
||||
<enableSharing>true</enableSharing>
|
||||
<enableStreamingApi>true</enableStreamingApi>
|
||||
<externalSharingModel>ControlledByParent</externalSharingModel>
|
||||
<label>Appraiser Deficiency</label>
|
||||
<nameField>
|
||||
<label>Appraiser Deficiency Name</label>
|
||||
<type>Text</type>
|
||||
</nameField>
|
||||
<pluralLabel>Appraiser Deficiencies</pluralLabel>
|
||||
<searchLayouts></searchLayouts>
|
||||
<sharingModel>ControlledByParent</sharingModel>
|
||||
<visibility>Public</visibility>
|
||||
</CustomObject>
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
|
||||
<fullName>Appraiser_Case__c</fullName>
|
||||
<label>Appraiser Case</label>
|
||||
<referenceTo>Appraiser_Case__c</referenceTo>
|
||||
<relationshipLabel>Appraiser Deficiencies</relationshipLabel>
|
||||
<relationshipName>Appraiser_Deficiencies</relationshipName>
|
||||
<reparentableMasterDetail>false</reparentableMasterDetail>
|
||||
<required>true</required>
|
||||
<trackHistory>false</trackHistory>
|
||||
<type>MasterDetail</type>
|
||||
<writeRequiresMasterRead>false</writeRequiresMasterRead>
|
||||
</CustomField>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
|
||||
<fullName>Deficiency_Number__c</fullName>
|
||||
<label>Deficiency Number</label>
|
||||
<length>50</length>
|
||||
<required>false</required>
|
||||
<trackHistory>true</trackHistory>
|
||||
<type>Text</type>
|
||||
</CustomField>
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
|
||||
<fullName>Description__c</fullName>
|
||||
<label>Description</label>
|
||||
<length>32768</length>
|
||||
<required>false</required>
|
||||
<trackHistory>true</trackHistory>
|
||||
<type>LongTextArea</type>
|
||||
<visibleLines>5</visibleLines>
|
||||
</CustomField>
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
|
||||
<fullName>Resolution__c</fullName>
|
||||
<label>Resolution</label>
|
||||
<length>32768</length>
|
||||
<required>false</required>
|
||||
<trackHistory>true</trackHistory>
|
||||
<type>LongTextArea</type>
|
||||
<visibleLines>5</visibleLines>
|
||||
</CustomField>
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
|
||||
<fullName>Sort_Order__c</fullName>
|
||||
<label>Sort Order</label>
|
||||
<precision>6</precision>
|
||||
<required>false</required>
|
||||
<scale>0</scale>
|
||||
<trackHistory>true</trackHistory>
|
||||
<type>Number</type>
|
||||
</CustomField>
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<PermissionSet xmlns="http://soap.sforce.com/2006/04/metadata">
|
||||
<description>Access to Appraiser Case and Appraiser Deficiency objects for setup and early testing.</description>
|
||||
<fieldPermissions>
|
||||
<editable>true</editable>
|
||||
<field>Appraiser_Case__c.Appraiser_Field_Review_Date__c</field>
|
||||
<readable>true</readable>
|
||||
</fieldPermissions>
|
||||
<fieldPermissions>
|
||||
<editable>true</editable>
|
||||
<field>Appraiser_Case__c.Property_Street__c</field>
|
||||
<readable>true</readable>
|
||||
</fieldPermissions>
|
||||
<fieldPermissions>
|
||||
<editable>true</editable>
|
||||
<field>Appraiser_Case__c.Property_City__c</field>
|
||||
<readable>true</readable>
|
||||
</fieldPermissions>
|
||||
<fieldPermissions>
|
||||
<editable>true</editable>
|
||||
<field>Appraiser_Case__c.Property_State_Province__c</field>
|
||||
<readable>true</readable>
|
||||
</fieldPermissions>
|
||||
<fieldPermissions>
|
||||
<editable>true</editable>
|
||||
<field>Appraiser_Case__c.Property_Postal_Code__c</field>
|
||||
<readable>true</readable>
|
||||
</fieldPermissions>
|
||||
<fieldPermissions>
|
||||
<editable>true</editable>
|
||||
<field>Appraiser_Case__c.Property_Country__c</field>
|
||||
<readable>true</readable>
|
||||
</fieldPermissions>
|
||||
<fieldPermissions>
|
||||
<editable>true</editable>
|
||||
<field>Appraiser_Deficiency__c.Appraiser_Case__c</field>
|
||||
<readable>true</readable>
|
||||
</fieldPermissions>
|
||||
<fieldPermissions>
|
||||
<editable>true</editable>
|
||||
<field>Appraiser_Deficiency__c.Deficiency_Number__c</field>
|
||||
<readable>true</readable>
|
||||
</fieldPermissions>
|
||||
<fieldPermissions>
|
||||
<editable>true</editable>
|
||||
<field>Appraiser_Deficiency__c.Description__c</field>
|
||||
<readable>true</readable>
|
||||
</fieldPermissions>
|
||||
<fieldPermissions>
|
||||
<editable>true</editable>
|
||||
<field>Appraiser_Deficiency__c.Resolution__c</field>
|
||||
<readable>true</readable>
|
||||
</fieldPermissions>
|
||||
<fieldPermissions>
|
||||
<editable>true</editable>
|
||||
<field>Appraiser_Deficiency__c.Sort_Order__c</field>
|
||||
<readable>true</readable>
|
||||
</fieldPermissions>
|
||||
<hasActivationRequired>false</hasActivationRequired>
|
||||
<label>Appraiser Case Admin</label>
|
||||
<objectPermissions>
|
||||
<allowCreate>true</allowCreate>
|
||||
<allowDelete>true</allowDelete>
|
||||
<allowEdit>true</allowEdit>
|
||||
<allowRead>true</allowRead>
|
||||
<modifyAllRecords>true</modifyAllRecords>
|
||||
<object>Appraiser_Case__c</object>
|
||||
<viewAllRecords>true</viewAllRecords>
|
||||
</objectPermissions>
|
||||
<objectPermissions>
|
||||
<allowCreate>true</allowCreate>
|
||||
<allowDelete>true</allowDelete>
|
||||
<allowEdit>true</allowEdit>
|
||||
<allowRead>true</allowRead>
|
||||
<modifyAllRecords>true</modifyAllRecords>
|
||||
<object>Appraiser_Deficiency__c</object>
|
||||
<viewAllRecords>true</viewAllRecords>
|
||||
</objectPermissions>
|
||||
<tabSettings>
|
||||
<tab>Appraiser_Case__c</tab>
|
||||
<visibility>Visible</visibility>
|
||||
</tabSettings>
|
||||
<tabSettings>
|
||||
<tab>Appraiser_Deficiency__c</tab>
|
||||
<visibility>Visible</visibility>
|
||||
</tabSettings>
|
||||
</PermissionSet>
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<QuickAction xmlns="http://soap.sforce.com/2006/04/metadata">
|
||||
<description>Placeholder action to launch Appraiser review letter generation flow or component.</description>
|
||||
<height>600</height>
|
||||
<label>Generate Review Letter</label>
|
||||
<optionsCreateFeedItem>false</optionsCreateFeedItem>
|
||||
<standardLabel>New</standardLabel>
|
||||
<targetObject>Appraiser_Case__c</targetObject>
|
||||
<type>Create</type>
|
||||
<width>800</width>
|
||||
</QuickAction>
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CustomTab xmlns="http://soap.sforce.com/2006/04/metadata">
|
||||
<customObject>true</customObject>
|
||||
<motif>Custom67: Gears</motif>
|
||||
</CustomTab>
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CustomTab xmlns="http://soap.sforce.com/2006/04/metadata">
|
||||
<customObject>true</customObject>
|
||||
<motif>Custom18: Form</motif>
|
||||
</CustomTab>
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
Appraiser_Case__c appraiserCase = new Appraiser_Case__c(
|
||||
Appraiser_Field_Review_Date__c = Date.today(),
|
||||
Property_Street__c = '123 Main St',
|
||||
Property_City__c = 'Ottawa',
|
||||
Property_State_Province__c = 'ON',
|
||||
Property_Postal_Code__c = 'K1A 0A1',
|
||||
Property_Country__c = 'Canada'
|
||||
);
|
||||
insert appraiserCase;
|
||||
|
||||
insert new List<Appraiser_Deficiency__c>{
|
||||
new Appraiser_Deficiency__c(
|
||||
Name = 'Deficiency 1',
|
||||
Appraiser_Case__c = appraiserCase.Id,
|
||||
Deficiency_Number__c = '1',
|
||||
Description__c = 'Missing comparable sale analysis',
|
||||
Resolution__c = 'Provide updated comparable sales section',
|
||||
Sort_Order__c = 1
|
||||
),
|
||||
new Appraiser_Deficiency__c(
|
||||
Name = 'Deficiency 2',
|
||||
Appraiser_Case__c = appraiserCase.Id,
|
||||
Deficiency_Number__c = '2',
|
||||
Description__c = 'Exterior condition comments are too brief',
|
||||
Resolution__c = 'Expand comments and attach photos',
|
||||
Sort_Order__c = 2
|
||||
)
|
||||
};
|
||||
|
||||
System.debug('Created Appraiser Case Id: ' + appraiserCase.Id);
|
||||
System.debug('Payload JSON: ' + AppraiserCaseDocGenService.buildPayloadJson(appraiserCase.Id));
|
||||
System.debug('Doc Gen JSON: ' + AppraiserCaseDocGenService.buildDocGenRequestJson(appraiserCase.Id, 'APPRAISER_REVIEW_LETTER'));
|
||||
|
|
@ -8,5 +8,5 @@
|
|||
"name": "salesforce-appraiser-review-letter",
|
||||
"namespace": "",
|
||||
"sfdcLoginUrl": "https://login.salesforce.com",
|
||||
"sourceApiVersion": "62.0"
|
||||
}
|
||||
"sourceApiVersion": "63.0"
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue