Adobe PDF Invoice and Statement Batch Generator
On a schedule, the flow reads due invoices/statements from Dataverse, merges each record into a branded template with Adobe PDF Services Document Generation, files the PDFs into a foldered SharePoint library, and emails each customer their statement. Replaces manual monthly statement runs with a governed, hands-off batch.
Provided as-is, without warranty of any kind. Review and test each pattern in a non-production environment before deploying it to live automations. See our Terms.
Overview
This flow produces branded customer invoices/statements at scale on a monthly schedule. It reads *due* billing records from a Dataverse table, merges each record into a branded HTML statement, archives the statement to SharePoint under a year/customer folder, emails each customer their statement (HTML body plus an .html attachment), marks the source record Generated, and posts a run summary to a Microsoft Teams channel and to the finance distribution list.
Why it matters: Monthly statement runs are repetitive and error-prone. Templated batch generation makes them consistent, archived, idempotent, and entirely hands-off.
Build status: Built — FlowLibs demo, ships Off. Flow Checker: 0 errors / 0 warnings.
Adobe PDF Services substitution: The brief called for Adobe PDF Services CreateDocumentFromTemplate (Document Generation). That operation's template input is a contentOnly multipart file-upload parameter that cannot be authored through the API / workflow-table deployment path FlowLibs uses, so Adobe document-generation ideas are built with an in-flow branded-HTML compose (action Compose_Statement_HTML), yielding a fully-bound, 0-error flow. To emit a real PDF when going live, either keep the HTML and add a converter step (Word Online GetFilePDF, or an Encodian/Plumsail HTML-to-PDF action), or add the Adobe CreateDocumentFromTemplate action by hand in the designer.
Use Case
Finance issues recurring monthly invoices/statements and wants them produced, filed, and sent automatically from CRM data — with no manual mail-merge. Each customer receives their statement by email; a copy is archived to SharePoint for audit; the billing record is stamped so the next run skips it; and finance gets a one-line confirmation in Teams and by email.
Flow Architecture
Monthly_Statement_Run
Recurrence (Month / interval 1)Kicks off the monthly statement run (set exact day/time in the designer).
Initialize correlation id + config
Initialize Variable (x10)Mint a @guid() run id and load config (due/generated status, company name, SharePoint site, library path, finance email, Teams group/channel); zero the counter.
List Due Invoices
Microsoft Dataverse — ListRecordsRead all due billing rows (flowlibs_status eq 'Pending', sorted by due date).
Apply To Each Record
Foreach (concurrency 1)Process each due record sequentially for an accurate count.
Select Line Items + Compose Statement HTML
Select + ComposeTurn line-item JSON into HTML table rows and merge the record into a branded HTML statement (Adobe DocGen substitute).
Archive Statement To SharePoint
SharePoint — CreateFileArchive the statement under .../<year>/<customer>/<invoiceno>.html (folders auto-create).
Email Statement To Customer
Office 365 Outlook — SendEmailV2Email the customer the statement (HTML body + .html attachment).
Update Invoice Record
Compose + Microsoft Dataverse — UpdateRecordMark the row Generated and stamp statement URL/timestamp/run id (whole-object bind); increment the generated count.
Post Run Summary To Teams
Microsoft Teams — PostMessageToConversationPost count + run id + completion time to the finance Teams channel.
Environment Variables
| Schema name | Type | Default | Description |
|---|---|---|---|
| flowlibs_BillingTable | String | flowlibs_invoices | Entity-set name read by List_Due_Invoices (new). |
| flowlibs_StatementLibraryPath | String | /Shared Documents/FlowLibs Statements | SharePoint folder base for archived statements; /year/customer appended (new). |
| flowlibs_SharePointSiteURL | String | https://your-tenant.sharepoint.com | SharePoint site for the archive (reused). |
| flowlibs_CompanyName | String | Contoso | Branding on statements + notifications (reused). |
| flowlibs_TeamsGroupId | String | <your-team-id> | Teams group for the run summary (reused). |
| flowlibs_TeamsChannelId | String | <your-channel-id> | Teams channel for the run summary (reused). |
| flowlibs_NotificationSenderEmail | String | alerts@yourcompany.com | Finance summary recipient (reused). |
Connectors & Connections
| Connector | API name | Actions used |
|---|---|---|
| Microsoft Dataverse | shared_commondataserviceforapps | ListRecords UpdateRecord |
| SharePoint | shared_sharepointonline | CreateFile |
| Office 365 Outlook | shared_office365 | SendEmailV2 |
| Microsoft Teams | shared_teams | PostMessageToConversation |
Customization Guide
Almost every realistic variant of this flow can be implemented by changing environment variable values. A few cases require small edits inside the flow definition — those are called out explicitly below.
- Which records are due
- Change Initialize_Due_Status (default Pending) or edit the List_Due_Invoices filter to add date/segment criteria (e.g. and flowlibs_duedate le ...).
- Branding
- Set flowlibs_CompanyName; adjust the inline CSS/colours in Compose_Statement_HTML (header colour #0f4c81).
- Line items
- Populate flowlibs_lineitems with a JSON array [{desc,qty,unit,amount}]; the Select action renders them into the statement table.
- Real PDF output
- Add a Word Online GetFilePDF (or Encodian/Plumsail HTML-to-PDF) step after Compose_Statement_HTML, or re-add the Adobe CreateDocumentFromTemplate action by hand.
- Archive layout
- Edit Archive_Statement_To_SharePoint folderPath (currently <libraryPath>/<yyyy>/<customer>).
- Schedule
- Open Monthly_Statement_Run and set the exact day-of-month / time. Turn the flow On to go live after authorizing the four connections and setting env-var values.
Key Expressions
The flow is intentionally light on Power Fx / WDL gymnastics — the heaviest expressions are the branch-name concatenation and the approval outcome check. They are listed below in the order they appear in the flow.
EXPR.01Due filter
OData filter selecting Pending billing rows.
EXPR.02Line-item rows (Select map)
Render each line item into an HTML table row.
EXPR.03Statement archive folder
Build the year/customer archive folder path.
EXPR.04Statement as email attachment
Attach the composed HTML statement to the customer email.
EXPR.05Write-back (whole-object bind)
Whole-object bind for the Dataverse UpdateRecord write-back.
Customize & download
Generate a ready-to-import copy of this solution with your environment-variable values baked in — available on Base, Pro, or Team.
Upgrade to customize
Comments
Sign in to join the conversation.
Sign inNo comments yet. Be the first to share your experience with this flow.