Version 1.1.0 · installation, settings and troubleshooting
Requires Perfex CRM 3.2 or newer, which means PHP 8.1 or newer. No third-party service and no subscription.
statements-1.1.0.zip. If your host blocks uploads, unzip it and copy the statements folder into modules/ instead.Activation creates two small tables of its own, statements_sends and statements_credit_limits, and one email template. It never alters your invoices, payments or customers: the module only reads them.
Open Statements → Schema check once after installing. It reads your database and confirms every table and column the module needs.
Every required row should be green. The three supplier rows will show as optional and absent unless you run a purchasing module, which is normal.
modules/statements/config/schema.php. Balances are not trustworthy until this check passes, so do it first.Open any customer and choose the Statement ledger tab, or go to Statements → Receivables ageing and click a customer.
The statement shows an opening balance, every invoice, payment and credit in the period, a running balance down the page, and a closing balance. Currencies are never added together. A customer invoiced in dollars and euros gets two sections with two balances, because one combined number would be wrong in both.
Buttons: PDF, CSV, WhatsApp and Email to customer.
Statements → Receivables ageing shows what everyone owes, in buckets you configure, per currency. Below it sit two more views: totals by the staff member who sold each invoice, and the chase list, largest balance first, with the age of the oldest overdue invoice, any credit limit breach, and when a statement was last sent.
Filter by date, by sale agent or by customer group. Whatever you filter, the totals are recalculated from the rows shown.
Print all produces one PDF containing a statement per customer with a balance, one per page. Each page ends with a tear-off remittance slip.
The WhatsApp button opens a message with the balance, the overdue portion and the age of the oldest invoice already written. There is no API, no account and no per-message fee: you read the message and press send yourself. If the contact has no usable phone number, WhatsApp opens and asks who to send it to.
Statements → Statement settings, administrators only.
| Setting | What it does |
|---|---|
| Ageing buckets | Comma separated days. 30,60,90 gives current, 1-30, 31-60, 61-90 and 90+. |
| Default period | How many months a statement covers when you open one without choosing dates. |
| Email subject | {companyname} is replaced with yours. |
| Pay links | Puts a link on each unpaid line, using the invoice link Perfex already serves. Turn it off if you do not take online payment. |
| Remittance slip | The tear-off panel at the foot of the PDF. |
| Customer's language | Writes each statement in the language on the customer's profile, falling back to yours. |
| WhatsApp country code | Added to local numbers that have no country code, for example 234 or 91. |
The email wording itself lives with all your others, under Setup → Email templates → Statement of account. Three merge fields are specific to it: {statement_period}, {statement_balances} and {statement_pay_links}. Remove any of them and the rest still sends.
Switch on Send statements automatically and choose a day of the month. On or after that day, the next run of your existing Perfex cron emails a statement to every customer carrying a balance above the floor you set.
Perfex has no credit limit of its own. Set one per customer and currency at the foot of their statement, and the ageing report shows the percentage used, or a red flag with the amount over. Both the chase list and its CSV carry the limit and the excess. Zero removes the limit.
| Capability | Allows |
|---|---|
| View | Reading statements, the ageing report and the exports. |
| Send | Emailing a statement, individually or in bulk. |
| Set credit limits | Setting or clearing a limit. |
Reading and sending are separate on purpose: sending is an outbound action on your company's behalf.
A statement is also gated the same way Perfex gates the customer record. Administrators and staff with the global customers view capability see everyone. Anyone else sees only the customers they are assigned to under Customer Admins, including in the totals, the chase list, the exports and the dashboard widget.
Perfex core has no supplier records at all; bills payable come from a purchasing module. Supplier statements therefore stay switched off until those tables are confirmed present, rather than showing an empty statement that reads like a supplier who is owed nothing.
If you run a purchasing module, set enabled to true for the three supplier groups in modules/statements/config/schema.php and re-run the schema check. The names there follow the Purchase Management module's conventions and may need adjusting for a different one.
statements_ageing_reportThe language file has not loaded. Deactivate and reactivate the module. If it persists, confirm modules/statements/language/english/statements_lang.php was uploaded.
See section 2. The page tells you which column it expected and which exist.
Check in this order: the invoice's currency, whether the invoice is a draft or cancelled, which are deliberately excluded, and whether payments or credit notes are recorded against the invoice rather than the customer. What an invoice still owes is its total, less payments against it, less credits applied to it.
Send any other Perfex email to the same address first. If that fails too, the problem is your SMTP settings under Setup → Settings → Email, not this module. A customer with no active contact cannot be emailed, and the module reports that rather than claiming success.
Check that it is switched on, that the day has been reached, that your cron job is running, and the activity log for a line beginning "Statements: scheduled run". It only sends once per calendar month.
The PDF uses your Perfex PDF settings, under Setup → Settings → PDF. Whatever applies to your invoices applies here.
The files are UTF-8 with a byte order mark, which Excel reads correctly. If you have changed Excel's import defaults, open it through Data → From Text and choose UTF-8.