Statement of Account Applet
Send customers their statements in batches: a run covers a period and a set of companies and customers, the server makes one statement for each company-and-customer pair, and prints or e-mails it. Nothing here changes a balance; it reads finalised documents and writes only the run, its lines, its events and its templates. A run you create by hand sends nothing until someone presses EMAIL ALL or EMAIL SELECTED on its Lines tab. A run made from a scheduled event behaves differently: it waits, unrendered, until someone presses RUN, and then e-mails every customer as each statement renders, without the EMAIL ALL step.
Overview
The Statement of Account applet produces customer statements in batches. You create a run for a period, tell it which companies and which customers to cover, choose a layout and choose whether the output is printed or e-mailed; the server then expands the run into one line per company-and-customer pair and, when you press RUN, renders a PDF for each line. For an e-mail run you create, the e-mails go only when you press EMAIL ALL or EMAIL SELECTED on the Lines tab; for one made from a scheduled event, see Scheduled runs.
It is a reporting and distribution applet. It writes statement runs, their lines, events and templates, and nothing else. No journal, no stock, no document, no change to any balance.
Where it fits
| Direction | What | Why |
|---|---|---|
| Upstream | Organization | A run is scoped to one or more companies. Only customers that have a FINAL document against that company are considered. |
| Upstream | Customer Maintenance / Entity | Supplies the customer’s categories, its default sales agent, and every e-mail address a statement can be sent to. |
| Upstream | Sales documents — Sales Invoice (Internal) and every other document | A customer only enters a run if it has at least one FINAL document of any type for the company before the statement end date. |
| Upstream | Printable formats (txn type STATEMENT_OF_ACCOUNT) | Chosen per run; the layout of the PDF. |
| Downstream | The customer’s inbox, or a batch PDF download | |
| Adjacent | Debtor Report | The same receivable position as an internal report rather than a customer-facing document. |
Screens and menus
Route root: applet/tnt/wavelet/erp/statement-of-account-applet. Landing route is Statement Of Account Runs.
| Menu item | Route | What it is |
|---|---|---|
| Statement Of Account Runs | statement-of-account | Listing, create and view of runs. The view has Main Details and Lines tabs. |
| Statement Of Account Templates | statement-of-account-template | Reusable header plus company / customer-category / sales-agent filter lists. |
| Statement Of Account Events | statement-of-account-events | Scheduled runs, optionally recurring through an RRULE. |
| Audit Trail | audit-trail | Not routed in this applet — the route is commented out. The sidebar hides the menu’s own entry and shows its own Audit Trail link to owners, admins and holders of the audit-trail report permission; that link opens a not-found page here. |
Settings menu: Application Settings (settings/field-settings) and Printable Format Settings
(settings/printable-format-settings). Personalization menu: Default Selection (your personal
default branch, location and company — saved, and used by nothing in this applet).
The searches apply less than they offer. The Runs search panel has eight fields, and only the keyword (matched on the batch number) and Company filter the list; the other six are ignored. On the Lines tab the Company Code search field is never read. Filter by keyword or company, or sort the grid.
Routed but not linked from any menu: settings/default-selection, settings/webhook,
settings/feature-visibility, settings/client-side-permission-listing (which is also the default
redirect for settings), settings/role-pricing-scheme-link-listing, the permission wizard and the
four permission listings, and personalization/sidebar. Two further settings routes — Workflow
Settings and Email Template — are commented out of both the routing table and the menu.
Configuration
Before you can use it
| Prerequisite | Where | Why it blocks you |
|---|---|---|
At least one printable format with txn type STATEMENT_OF_ACCOUNT | Printable format maintenance | The Printable Format control on the run form filters on that txn type. Without one there is nothing to select and nothing to render. |
| Customers carrying a customer category, or customers with a default sales agent | Customer Maintenance | A run selects customers only by category or by sales agent. There is no “all customers” option, and a run with neither produces no lines. |
| FINAL sales documents for the company in the period | Sales applets | A customer is a candidate only if it has at least one FINAL document. A customer with only draft documents is never in a run. |
| E-mail addresses on the customer, for an e-mail run | Customer Maintenance | Addresses are gathered from the entity’s main e-mail, its primary and secondary address contacts, staff/family contacts and login subjects, according to the run’s own check boxes. Invalid addresses are filtered out silently. |
Applet settings
Settings › Application Settings. There is nothing here that changes what this applet will let you do. The screen is nineteen toggles, every one of which removes a column from a grid. How settings are stored and who they apply to.
Three things about that screen are not visible on it:
- Thirteen of the nineteen work and six do not. The HDR Settings group hides columns on the Runs listing; the six Line Settings toggles — company code, customer name, run start and end date, run status, recipient e-mails — save and do nothing, because the Lines grid builds its columns without consulting them. If you hid a column on the Lines grid and it is still there, that is why.
- A hidden column cannot be brought back from the grid itself. Each toggle hides the column and removes it from the grid’s column tool panel too, so a user cannot restore it for their own session.
- Anyone who can open Settings can change them, and the change is tenant-wide. No client-side permission codes are registered for this applet at all, so there is nothing to grant and nothing to hold back.
The one setting here that changes what a document does is PRINTABLE: marking a format as the default
on Settings › Printable Format Settings writes that format’s identifier, and the run, event and
template forms all pre-select it (printable_format_hdr_guid ?? appletSettings.PRINTABLE).
On the screen and doing nothing
- The six
HIDE_LINE_*toggles named above — rendered, saved, read by nothing in this applet or the backend. DEFAULT_BRANCH,DEFAULT_LOCATION, the default company, validity days and pricing scheme — declared in the settings model. The tenant-wide Default Selection screen that would write them is routed but commented out of the settings menu; the personal Default Selection in the Personalization menu does save your own branch, location and company, but no run, event or template form reads them. A reader looking for “make every run default to one company” will find the setting and no effect from it; the company is chosen on the run.- Three settings with no control on this applet’s settings screen. Two act on the Runs listing if set through the API — one removes Company from the search panel, one clears grid filters after each search. The third, the document-delete-button setting, is read and then overridden by the rule that DELETE appears only on a completed run.
There is no inline settings gear anywhere in this applet.
Document behaviour settings
A run is not a generic document: there is no posting, no printable-per-status, no approval and no workflow. The two behaviours that look like settings are fields on the run itself — Statement Type and Run Type — and are described under Fields.
Settings in other applets that control this applet
| Setting | Where it is set | Effect here |
|---|---|---|
| Customer categories (entity labels) | Customer Maintenance | One of the only two ways a customer can be selected into a run. |
default_sales_agent on the customer | Customer Maintenance | The other way. Note that selecting a sales agent picks up every customer whose default agent matches, regardless of the period, in addition to customers who appear as sales_entity_hdr_guid on a FINAL document in the period. |
| The customer’s e-mail addresses — its main e-mail, the e-mail on each main, billing and shipping address and the secondary contacts under them, its contact persons, and the main e-mail of each login linked to it | Customer Maintenance / Entity | Read once, when the run’s lines are built at save — not when the e-mail goes. Correct an address before you create the run: a run created earlier keeps the list it built, and every later EMAIL press sends to that list. |
| Statement-of-account printable formats | Printable format maintenance | The layout only. The figures in it are not taken when you save the run: they are fetched when each line is rendered, after you press RUN, from the documents as they stand at that moment. See Where the figures come from. |
Who can change what
Creating, reading, changing and deleting runs, templates and events is governed by one statement-of-account permission family (owner, admin, create, read, update, delete).
No client-side permissions are defined for this applet, so the Client-Side Permission listing — which
is also where settings opens — is empty.
Fields
Run — Main Details
| Field | Meaning | Required | Notes |
|---|---|---|---|
| Statement Type | AGING or TRANSACTION_HISTORY | Yes | Controls the layout and whether Month From is shown. |
| Run Type | PRINT or EMAIL (labelled Print and Email) | Yes | EMAIL reveals Recipient Emails and the five recipient check boxes. |
| Companies | One or more companies | Yes | Stored as companies_json = {companies: [...], companies_name: [...]}. |
| Sales Agent / Customer Category | Two independent check boxes; Sales Agent is ticked by default | At least one | The form wants at least one ticked and every ticked one filled. Both lists are sent whatever is ticked, and when any category is present the server uses the categories and ignores the agents — ticking both does not narrow the run. The Runs listing does the opposite and shows the categories column blank whenever agents are present. See How the lines are chosen. |
| Sales Agent(s) | Employees / entities acting as sales agent | When Sales Agent is chosen | Stored as sales_agents = {agents: [...], agents_name: [...]}. |
| Customer Category(s) | Entity labels | When Customer Category is chosen | Stored as customer_categories = {categories: [...], categories_name: [...]}. |
| Month From | Start of the statement period | Only for TRANSACTION_HISTORY | The control is hidden for AGING, and an Aging run stores a fixed start of 1 January 2022 whatever the control held. |
| Month To | End of the statement period | Yes | Snapped to whole months on every change. The form shows the end of the last day, but the run stores the start of the last day (converted to UTC from your browser’s zone); the server adds one second when it picks customers. |
| Printable Format | The PDF layout | Yes | Filtered to txn type STATEMENT_OF_ACCOUNT; defaults to the PRINTABLE applet setting. |
| Recipient Emails | Extra addresses typed in | No | Only for EMAIL. Invalid addresses are dropped without a message. |
| Main / Primary Address Contacts / Secondary Address Contacts / Staff Family / Login Subjects | Which stored addresses to include | No | Only for EMAIL. Stored in soa_settings_json.email_config; all five default to on. |
| Email All Outstanding Docs | Meant to attach every outstanding document | No | Saved with the run and read by nothing: the e-mail carries the statement PDF and no other attachment. If a customer needs copies of the open invoices, send them yourself. |
| Exclude company from its own customer list | Leave the selected company out of its own customer list | No | Works: the server drops a customer that is the selected company’s own entity record. See step 1 of How the lines are chosen. Also on the template and event forms. |
Once the run is saved the form also shows Run By (who created it) and Run Status. Every field above is disabled once the run exists. A run is effectively immutable after CREATE; on
this screen the only actions are RUN (while the status is CREATED), the download and e-mail buttons on
the Lines tab, and DELETE — which is offered only once the run is COMPLETED. Regenerate and retry exist in the API only; the applet has no button for either.
Run — Lines
One line per company-and-customer pair, holding the batch running number, the header GUID, company, customer, run status and — for an e-mail run — the resolved recipient list. Lines are created by the server, never by hand.
Event
An event carries the same run configuration (statement type, run type, printable format, period, e-mail configuration) plus a code, whether it recurs, a start and end date, a recurrence rule and an optional Template, with its own company, customer-category and sales-agent filters. A recurring event is expanded into one event per occurrence when it is saved. The Events listing’s Run Status column shows whether an event is still waiting (pending) or has been converted into a run.
Template
The same shape as an event, minus the scheduling. A template is selected on the Event form and pre-fills it, and when the event is created from it the template’s company, customer-category and sales-agent filter lists are copied onto the event — so the event keeps them even if the template later changes. A run is built from the event, never from the template.
Lifecycle and effects
Run statuses are CREATED → IN_PROGRESS → COMPLETED, or FAILED.
Creating a run
Saving the form creates the run at CREATED and starts the job that builds its lines at once.
How the lines are chosen
- For each selected company, list the entities marked as customers that have any document of any type with posting status FINAL dated before the statement end date. The statement start date is not used here — a customer with an old FINAL document and nothing in the period is still a candidate — and neither is the document’s record status, so a deleted FINAL document still makes its customer a candidate. Since 1 October 2026, with Exclude company from its own customer list ticked, the selected company’s own entity record is left out, so a company does not send a statement to itself. Only that company is excluded: a sister company that buys from it is still a customer here.
- Collect the customers belonging to the selected categories.
- If both sets are non-empty, intersect them per company and create the lines. This happens whenever any category is present — the sales agents on the run are then ignored, even if both boxes were ticked.
- Otherwise, if there are sales agents and no categories, build the customer set from customers on FINAL documents in the period whose sales agent is one of the agents, together with every customer whose default sales agent is one of the agents, then intersect per company and create the lines.
- If an intersection comes out empty, the run is set to
FAILEDwith No customers matched the provided criteria.
Note the shape of that logic: if neither a category nor a sales agent survives, neither branch runs, no lines are created and no failure is recorded. The run stays where it was.
Because the run stores the start of Month To’s last day (see Fields), a customer whose only FINAL document is timed later on that last day may be left out of the candidates (read in source, not run; it depends on the time the document’s date carries). If a customer with a last-day sale is missing, check that document’s date and time.
Running
Run moves a CREATED run to IN_PROGRESS, creates the lines if none exist yet, and then renders
each line’s PDF in the background. Lines reach COMPLETED individually, and the run reaches COMPLETED
when the last line does.
Rendering is not sending. For an e-mail run you create, nothing leaves until someone presses EMAIL ALL (enabled once the run is Completed) or ticks lines and presses EMAIL SELECTED on the Lines tab. There is no setting on the form that sends automatically (a run made from a scheduled event is the exception — see Scheduled runs). Whoever runs collections presses it, after checking the Recipient Emails column for customers with no address and for addresses that should not receive the statement. A line records the date its e-mail was sent, so a line with no sent date has not gone.
EMAIL SELECTED and DOWNLOAD SELECTED are live before the run completes. A ticked line whose PDF has not rendered yet is skipped without a word, and the success message still says the e-mails were sent. Wait for the run to reach Completed, then check the sent date on every line you ticked.
What each e-mail looks like, none of which the form lets you change:
- One e-mail per customer, every address on the To line — each recipient sees every other address. If a customer’s contact list includes someone who should not see the others, remove that address from the customer before you create the run.
- A fixed subject and body: the month, then Statement of Account (AGING) or (TRANSACTION_HISTORY) and the customer’s name; the body is a three-line “Dear Valued Customer” note. It is sent from the platform’s default sender address, not your company’s.
- A customer with no valid address fails, and stops the batch (read in source, not run). The failed
line is marked
FAILEDand the EMAIL ALL pass does not go on to the customers after it. Test it once: in a two-customer e-mail run where the first customer has no address, press EMAIL ALL and check whether the second line gets a sent date. Until you have seen it behave, send in batches with EMAIL SELECTED, leaving out lines whose Recipient Emails column is empty.
Where the figures come from
The run stores no amounts. Each line’s figures are fetched from the finalised documents when that line is rendered, not when you saved the run — so a run saved on the 1st and run on the 5th includes a receipt keyed on the 3rd but dated inside the statement period. The PDF, once rendered, is kept and re-sent unchanged by every later EMAIL press. To send a customer a fresh statement after a late receipt or a back-dated invoice, create a new run; the screen has no way to re-render an old one.
- Purchase invoices, purchase returns and goods received notes are left out of a run made on the Runs screen, so a customer who is also your supplier gets a statement of the sales side only. A run made from a scheduled event includes them: the event form saves the exclusion under a name the statement does not read, and the run copies the event’s settings as they are. A template saves no exclusion at all. How to spot it: a scheduled statement for a customer who is also a supplier lists purchase invoices, returns or goods received notes and a balance that nets the two sides. For such customers, create the run by hand on the Runs screen.
- The period on the statement is the run’s own start and end dates; the printable format sets the layout, not the period.
- Dates are cut on Malaysian time, whatever the company’s own time zone.
- An Aging statement for a month that has already ended can leave off documents dated on that month’s last day (read in source, not run). The list of documents stops at the start of the last day, while the aging boxes include it, so the two can disagree by the last day’s invoices and receipts. A statement for the current month is not affected. Test it once before you rely on month-end aging statements: finalise one invoice dated the last day of a month, then in the following month create an Aging run for that month and that customer, and look for the invoice on the PDF. If it is missing, use a Transaction History run for that month instead, and compare its closing balance with the Debtor Report before you send.
- A customer billed in a foreign currency gets each dollar invoice twice — the invoice in dollars and the ringgit copy BigLedger makes of it at FINAL — and the copy stays open after the customer has paid, because receipts are knocked off against the dollar invoice. The statement lists both unless it is given a currency, and a run gives it none: the Aging and the Transaction History run both pass an empty currency, and the run, event and template forms have no currency field. The Debtor Report’s own Statement of Account tab has that filter; a run does not. A run selects its customers by category or sales agent, so the way to keep such a customer out of a batch is to leave them out of the categories or agents the run covers, or to leave their line unticked and send the rest with EMAIL SELECTED — then send theirs from the Debtor Report’s statement tab opened from a listing filtered to the invoice currency (Foreign-currency customers). On an Email run made from a scheduled event there is no later point to catch it: each statement goes to the customer as it renders. Reported to BigLedger as a defect; this page changes when the fix ships.
Regenerate (for a run at COMPLETED or FAILED) and retry (which re-processes lines still at
CREATED) are API actions with no button in this applet. A run can stick at IN_PROGRESS in two ways: a
line that never completes, or a printable format that no longer resolves (deleted, or its layout file
gone). In the second case RUN still reports success, nothing appears in the Error column, and no line
renders — check that the run’s printable format still exists before you do anything else. A stuck run
cannot be recovered from the screen, and it cannot be deleted either, because DELETE appears only on a
completed run. Create a new run for the same customers and send that; ask BigLedger support to retry or
clear the stuck one, and until then tell whoever reads the Runs listing which run is the live one.
The PDF job, STATEMENT_OF_ACCOUNT_RUN_PDF_GENERATION_PROCESSOR, would sweep every unfinished CREATED
run in the tenant, but nothing in the product queues it and it is not one of the default scheduled jobs, so
unless it has been scheduled for your tenant it never runs. In practice a run renders only when someone
presses RUN.
Scheduled runs
STATEMENT_OF_ACCOUNT_RECURRING_EVENTS_PROCESSOR is a scheduled job, and it does nothing unless it is
scheduled for your tenant in the Scheduler. On each pass it
takes every ACTIVE event still pending whose period has ended within the last seven days (since
3 October 2026 — before that only the previous 24 hours, so an event missed on the day was never
caught up), builds a run from the event and its filters, and marks the event as converted, with the
new run attached. An event therefore converts once; recurrence comes from the separate events the
recurrence rule created, not from re-firing one event. Three things the same change settled: an
EMAIL event’s run is marked to send as it renders; an occurrence that
carries no filters of its own takes the series’ filters (the applet attaches company, category and
sales-agent filters to the first occurrence only); and the occurrences of a recurring event are expanded
on the creator’s company time zone (Malaysia when none is set), back-to-back periods such as a monthly
statement end where the next begins, and the whole series is written in one transaction — a failure on
any occurrence writes none.
What happens next is not automatic. The converted run has its lines built at once, but nothing renders
it: the PDF job described under Where the figures come from is not
scheduled anywhere by default, so the run sits at CREATED until someone opens it and presses RUN.
For an EMAIL event, RUN then renders each statement and e-mails it as soon as it renders, to every
customer on the run — the EMAIL ALL review step on the Lines tab is skipped. How to spot one: a run on
the Runs listing that nobody created by hand, still at CREATED after its period ended. Before pressing
RUN on an e-mail run made from an event, open its Lines tab and check the Recipient Emails column, because
there is no later point at which to stop it.
FAILED status. Backend 4623d9e7ae writes the keys the line step reads and gives an occurrence its
series’ filters, so a scheduled run now selects customers the way a manual one does (a known issue, since fixed).
A run converted before that build still has the old keys; create it by hand.What a run writes
The run, its lines, and the rendered PDFs in file storage. Nothing else. There is no journal, no stock movement and no change to any customer balance — a statement reports the receivable position, it does not create it.
Related applets
- Customer Maintenance — categories, default sales agent and every e-mail address a statement can reach.
- Entity — the underlying entity record, its address contacts and login subjects.
- Organization — the companies a run is scoped to.
- Employee — sales agents.
- Sales Invoice (Internal) — the FINAL documents that make a customer eligible.
- Debtor Report — the internal view of the same receivables.
- Ledger and Journal — where the receivable balance actually lives.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| A scheduled event fired before 3 October 2026 and its run has no lines and never failed | Until backend 4623d9e7ae the conversion wrote customer_categories / sales_agents while the line processor read categories / agents (a known issue, since fixed). | Create that run by hand — pressing RUN re-reads the same JSON. Events converted on the fixed build carry the right keys and need nothing. |
| Run status FAILED, No customers matched the provided criteria. | The category or sales-agent set produced no customer that also has a FINAL document against one of the selected companies. | Check that the customers carry the category, and that they have at least one FINAL document for that company before the statement end date. |
| A customer you expected is missing from the lines | It has no posting_status = FINAL document for that company, or it is not in the selected category and its default_sales_agent is not one of the selected agents. | There is no “all customers” option; widen the category or agent selection. |
| A customer appears with no activity in the period | Candidates are customers with any FINAL document before the end date; the start date is not applied. | Expected behaviour; the statement itself covers the run’s start and end dates. |
| Line Settings toggles do nothing | The six HIDE_LINE_* keys are saved but read by nothing. | Use the grid’s own column tool panel on the Lines tab. |
| A hidden column cannot be restored from the grid | Each HIDE_HDR_* sets suppressColumnsToolPanel as well as hide. | Turn the toggle off in Settings → Application Settings. |
| Nothing to choose in Printable Format | No printable format exists with txn type STATEMENT_OF_ACCOUNT. | Create one in printable-format maintenance. |
| An e-mail run sends to fewer people than expected | Addresses that fail validation are dropped silently, and each of the five recipient sources is an independent check box. | Verify the entity’s main e-mail, address contacts and login subjects; re-check the boxes. |
| A run is stuck at IN_PROGRESS | A line never completed, or the run’s printable format no longer resolves — RUN still reported success and the Error column stays empty. RUN only acts on CREATED, and retry has no button in this applet. | Check that the printable format still exists; create a new run and send that one; ask BigLedger support to retry the stuck run. It cannot be deleted from the screen until it completes. |
| Month From is not shown | It renders only when Statement Type is TRANSACTION_HISTORY. | Expected. For AGING the period is the single Month To. |
| Customers say they never received the e-mailed statement | An e-mail run you create renders PDFs but sends nothing by itself; EMAIL SELECTED pressed before the run completed skips lines with no PDF yet. | Open the run’s Lines tab: a line with no sent date has not gone. Press EMAIL ALL or EMAIL SELECTED once the run is Completed. |
| A scheduled run sat at CREATED for days, then every customer was e-mailed the moment someone pressed RUN | Nothing renders an event’s run until RUN is pressed, and an e-mail event’s run sends each statement as it renders, without the EMAIL ALL step. | Check the Lines tab of every event-made run before pressing RUN. See Scheduled runs. |
| A scheduled statement lists purchase invoices or goods received notes | Runs made from events do not carry the purchase-document exclusion that runs made on the Runs screen do. | Create the run for that customer by hand on the Runs screen. |
| A customer billed in a foreign currency gets each invoice twice, or a paid dollar invoice still shows open in ringgit | The statement reads the dollar invoice and the ringgit copy made at FINAL alike, knock-offs land on the dollar invoice only, and a run passes no currency (reported to BigLedger). | Leave that customer out of the run’s categories or agents, or leave the line unticked at EMAIL SELECTED; send theirs from the Debtor Report’s statement tab with the listing filtered to the invoice currency — see Where the figures come from. |
| A run picked a category’s customers although sales agents were chosen | Both lists are sent whatever is ticked, and categories win. | Clear the category list when you mean to select by sales agent — unticking the box is not enough, because the list is sent anyway. |
| An event stopped running after you edited it; its Run Status is empty | In the build served on 7 October 2026, saving an edited event blanks its run status, and the scheduled job picks up only pending events. | Delete the event and create it again; do not edit saved events until the fixed build is served. |
| A month-end Aging statement is missing an invoice dated the last day of the month | The document list of a past-month Aging statement stops at the start of the month’s last day (read in source, not run). | Run the test under Where the figures come from; send a Transaction History run for that month instead. |
Related documentation
- Chasing Overdue Accounts — the monthly statement run as part of collections, and how to check every credit customer received one.
- Financial Accounting module — where customer statements sit in the collections cycle.
- Customer Maintenance applet — categories, sales agent and contact e-mail reference.