Overview
A user clicks "Generate Document" quick action on a record. The generation layer consumes template configuration (created by the template module), fetches Salesforce field values, merges them into a PDF or Word document client-side (VF page JavaScript), creates a Document_Workflow__c record to track the document, and optionally sends it for eSignature or creates records. Nothing here modifies templates or mappings — it purely executes pre-built configurations to produce documents.
|
Object |
Holds |
|---|---|
|
|
Template config (from template module) — used to fetch merge strategy, signer list, field mappings |
|
|
Field bindings (from template module) — used to build dataMap for form population |
|
|
Signer definitions (from template module) — SOQL queries executed at generation time to resolve email/name |
|
|
Workflow header — created during generation to track document state, parent record, signers, content version |
|
|
Signer queue item — one per signer, created when workflow transitions to Awaiting Signature, tracks individual signing progress |
Architecture
┌────────────────────────────────────────────────────────────┐
│ Quick Action: Generate Document │
│ ↓ │
│ documentGenerationScreen (LWC on quick action) │
│ (folder picker → template picker) │
│ ↓ │
│ GenerationScreenController (Apex + VF backing) │
│ getTemplateData() → loads VF page │
│ ↓ │
├────────────┬──────────────────────────┬───────────────────┤
│ PDF Path │ Word Path │ │
│ │ │ │
│ PDFPreview │ WordDocument │ │
│ Screen (VF)│ GenerationScreen (VF) │ │
│ │ │ │
│ PSPDFKit │ Word JS API │ │
│ merges │ merges fields │ │
│ fields │ client-side │ │
│ client-side│ │ │
└────────────┴──────────────────────────┴───────────────────┘
↓ postMessage (blob + fieldMap)
documentGenerationScreen (LWC)
handleVfMessages()
↓
GenerationScreenController.generateDocument()
↓
DocumentGenerationService.generateDocument()
↓
Creates: Document_Workflow__c + ContentVersion + Workflow_Items
Key mechanism — client-side merge + server-side workflow.
The document is rendered by PSPDFKit (PDF) or Word JS APIs (Word) inside a Visualforce page. Field merging happens client-side in the VF page JavaScript. When the user clicks Generate, the VF page posts the already-merged blob + fieldMap back to the LWC via window.postMessage. The LWC calls Apex generateDocument(), which receives the blob and creates workflow records. This separation keeps generation responsive and offloads computational work to the client.
Apex — GenerationScreenController
public with sharing. Backs both PDFPreviewScreen and WordDocumentGenerationScreen VF pages. All SOQL via Data wrapper with enforceSharing.
|
Method |
Returns |
What it does |
|---|---|---|
|
|
String |
VF page getter. Reads page params recordId, templateId. Calls DocumentGenerationService.getFormData(). Sets VF properties: base64String (document blob), dataMap (field→value JSON), readOnlyFields, requiredFields, dateFields, picklistMap, fieldNameLabelMap, bFlattenOnGeneration, licensekey. Returns 'Success' or 'Error'. |
|
|
Map<String,Object> |
Called by LWC on load. Calls DocumentGenerationService.getActiveTemplates(). Returns { templateDetails: Map (label→Id), templateFolders: Map (Id→folder), templateType: Map (Id→isPDF) }. |
|
|
String |
Receives base64 blob (already merged by VF JS). Detects PDF vs Word via Is_Document_PDF__c. Calls DocumentGenerationService.generateDocument(). Returns JSON: { Success, workflowId, fileTitle, successMessage, bGenerateDocumentOnly, isGenerateLink }. On error: { Success: false, errMessage }. |
|
|
String |
Returns Visualforce_URL org setting. Used by LWC for postMessage origin validation. |
|
|
Boolean |
Queries Enable_Field_Update_On_Generation setting. Controls post-signing field writes. |
|
|
List<String> |
Wired in LWC. Returns all unique Template_Group_Folder__c values. |
|
|
List<Document_Workflow__c> |
Queries workflows linked to recordId. Used by documentWorkFlowIndex LWC to show workflow status list. |
|
|
List<Document_Workflow_Item__c> |
Queries workflow items for a workflow. Used by documentWorkFlowIndividual to show per-signer queue. |
|
|
void |
Called after ContentVersion creation. Links file to workflow. Triggers workflow state transitions. |
Apex — DocumentGenerationService
public with sharing. Core generation logic. All SOQL via Data wrapper with enforceSharing.
|
Method |
Returns |
What it does |
|---|---|---|
|
|
Map<String,Object> |
Bootstrap call at VF load. Takes {templateId, recordId}. Queries Document_Template__c + Document_Data_Mapping__c. For each mapping, resolves dot-notation field path, looks up value on record, formats dates, handles child relationships. Returns { Success, dataMap, base64String, readOnlyField, requiredField, dateFields, bFlattenOnGeneration }. Detects null required fields and blocks generation. |
|
|
Map<String,Object> |
Queries Document_Template__c by Primary_sObject__c = source object type AND Status__c = Active. Calls DocumentGenerationService to build folder/type maps. Enforces licensing (Feature_Entitlement__c). |
|
|
Map<String,Object> |
Takes {templateId, recordId, base64String (already merged), fieldMap, bUpdateSalesforceData, signerConfig, signatureType}. Creates Document_Workflow__c (status = Document Generated). Creates ContentVersion (merged blob). If Send_Document_For_eSignature__c: queries Document_Signer_Mapping__c, runs each signer's SOQL (ParentId → actual record ID), creates Document_Workflow_Item__c per signer, updates workflow status → Awaiting Signature. Returns { Success, workflowId, fileTitle, bGenerateDocumentOnly, isGenerateLink }. |
|
|
Map<String,Object> |
Returns { picklistOptions, fieldNameLabelMap, fieldNameDataTypeMap } for VF picklist rendering. |
Apex — WordDocumentGenerationService
public with sharing. Handles Word (.docx) server-side field merge (alternative path).
|
Method |
Returns |
What it does |
|---|---|---|
|
|
Blob |
Takes field map. Iterates .docx XML, finds form fields, replaces with mapped values. Returns modified .docx blob. Word documents not flattened. |
Apex — WordDocumentGenerationController
public with sharing. VF page backing class for Word generation flow.
|
Member |
Type |
Purpose |
|---|---|---|
|
|
VF getter |
Reads page params templateId, recordId. Calls DocumentGenerationService.getFormData(). Sets VF properties. Returns 'Success' or 'Error'. |
Apex — WorkflowTriggerHandler
before insert/update on Document_Workflow__c. Enforces business rules on workflow creation/update.
|
Method |
Behavior |
|---|---|
|
|
Validates workflow state transitions, signer configuration validity, template existence. Calls addError on violations. |
LWC — documentGenerationScreen
Entry point quick action. Orchestrates template selection → VF page load → blob merge → workflow creation.
Tracked state
|
Property |
Purpose |
|---|---|
|
|
Injected by quick action framework |
|
|
If true, reload parent on success |
|
|
Toggles folder picker UI |
|
|
Toggles template radio-button picker UI |
|
|
Filtered picklist (label→value) of available templates |
|
|
Selected template ID |
|
|
Routes to PDF or Word VF page URL |
|
|
Triggers iframe load when true; shows VF page |
|
|
Licensing gate; blocks UI if false |
|
|
Map of template ID → isPDF (true/false) |
|
|
Visualforce origin URL for postMessage validation |
|
|
Toggles email delivery UI after generation |
|
|
Workflow ID returned from generateDocument; used for email delivery |
Key functions
|
Function |
Behavior |
|---|---|
|
|
Registers |
|
|
On first load: calls getTemplates(recordId) → builds templateOptions, templateGroups, docTypeMap, mapTemplateFolders. Calls getVfOrigin(). Calls checkStoringSalesforceData(). |
|
|
Checks docTypeMap[templateId]: PDF → |
|
|
Filters templateOptions by Template_Group_Folder__c. 'other' includes unfoldered templates. |
|
|
Listens for postMessage from VF iframe. Two message types: (1) |
|
|
Checks licensing. On fail, sets bUserAssignedLicense = false. |
VF Pages — PDFPreviewScreen
Controller: GenerationScreenController. Hosts PSPDFKit viewer iframe. Receives templateId, recordId as page params.
Flow: Page loads → calls getTemplateData() → PSPDFKit renders PDF with form fields populated → user interactively fills/adjusts values → clicks Generate → VF JavaScript collects field values (already merged by PSPDFKit) → posts blob + fieldMap back to LWC via postMessage.
|
VF Property |
Purpose |
|---|---|
|
|
Base64-encoded PDF blob (template file from Document_Template__c) |
|
|
JSON field→value map (from DocumentGenerationService.getFormData) |
|
|
JSON array of read-only field names |
|
|
JSON array of required-to-generate field names |
|
|
JSON array of date field names (for client-side formatting) |
|
|
JSON map of picklist options for form dropdowns |
|
|
JSON map of field API name → label (for error display) |
|
|
If true, PDF form fields will be flattened to static content (generate-only templates) |
|
|
If true, shows error overlay before rendering (required fields are null) |
|
|
Validation error message |
|
|
PSPDFKit license key from org settings |
|
|
Org URL for origin validation |
|
|
Visualforce URL for origin validation |
VF Pages — WordDocumentGenerationScreen
Controller: WordDocumentGenerationController. Loads Word template (.docx), allows field editing, posts merged blob back to LWC.
Flow: Similar to PDF. Word form fields populated from dataMap. User adjusts values. On submit, posts blob + fieldMap back to LWC.
|
VF Property |
Purpose |
|---|---|
|
|
Base64-encoded .docx blob |
|
|
Same as PDF |
|
|
Same as PDF |
|
|
Not used for Word (Word not flattened) |
|
|
License key |
VF Pages — WordDocumentGenerationScreen
Read-only component embedded on record page. Shows list of Document_Workflow__c records for the record, with per-signer status.
|
Method |
Behavior |
|---|---|
|
|
Queries workflows for the parent record. Populates lstWorkFlows. |
|
|
Platform event subscription (DocumentWorkFlow__e). On "Workflow Created" event: refreshes data. On "Workflow Item Created" event: calls child getWorkFlowItems() to refresh signer queue. |
LWC — documentWorkFlowIndividual (Single Workflow Card)
Child component inside documentWorkFlowIndex. Shows one workflow's status, progress ring, list of signers with timestamps.
|
Method |
Behavior |
|---|---|
|
|
Queries workflow items for this workflow. Builds display name (signer name + event type), formats timestamps, marks which signer is current. |
|
|
Updates progress bar CSS based on workflow.Status__c (Workflow Initiated → Document Generated → Awaiting Signature → Workflow Completed). Sets step number and progress variant. |
|
|
Calls GenerationScreenController.sendReminderEmail(). Sends reminder to current signer if configured. |
Message contract — LWC ↔ VF postMessage
documentGenerationScreen registers window.addEventListener('message', …) in connectedCallback. VF page posts JSON with type field. Origin validated via vfOrigin before processing.
|
type |
Payload |
Handling |
|---|---|---|
|
Toast |
|
Displays ShowToastEvent (field validation errors from VF) |
|
GenerateDocument |
|
Calls generateDocument Apex → creates ContentVersion → links to workflow → fires success event |
Cross-cutting conventions
|
Convention |
Detail |
|---|---|
|
PDF vs Word routing |
Is_Document_PDF__c checked in LWC.generateDocument() and GenerationScreenController.generateDocument(). Template module sets this from MIME type at upload. |
|
Dot-notation resolution |
Simple: |
|
Today sentinel |
|
|
Date formatting |
Date_Format__c on each mapping (e.g., MM/DD/YYYY). Applied at merge time. Defaults MM/DD/YYYY if blank. |
|
Required field validation |
At getFormData time, service checks Required_To_generate__c fields. If null, sets nullFieldsError = true, blocks rendering with error message. |
|
Flattening |
Flatten_document_while_generation__c = true only for generate-only (not eSign) templates. Flattening in VF JavaScript (PSPDFKit for PDF). Word not flattened. |
|
Workflow creation |
If Send_Document_For_eSignature__c = true: queries Document_Signer_Mapping__c, runs SOQL per signer (ParentId → actual ID at runtime), creates Workflow_Item per signer. |
|
Field updates post-signing |
If Update_Salesforce_data_on_signing__c = true on mapping + bUpdateSalesforceData enabled → value written back to record post-signing (async). |
|
Signer resolution |
SOQL in Document_Signer_Mapping__c.Signer_Query__c executed at generation time with ParentId substituted. Email/name extracted from result. |
|
Workflow state machine |
Document Generated → Awaiting Signature (if eSign) or Completed (if generate-only) → Workflow Completed (all signers signed) or Failed (error). |