Creating & sending
The Create Statement dialog is where a supplier picks who gets a statement, checks it, and sends it. One click can send a separate statement to every customer who owes money. Each customer gets their own statement with its own number; nothing is combined.
Who uses it
- Supplier staff with Full Access to Customers (from the Customers page) or to Invoices (from the Invoices page). See Permissions.
- Restaurants only receive the result: see PDF, email & text.
How it works
The dialog has three screens. The back arrow in the title returns to the first one with everything kept.
Create Statement ──Preview Statement──▶ Preview Statement ──Create & Send──▶ Send Statement ──Send──▶ sent
└──────────────────────────────Create & Send───────────────────────────────▶┘
Opening the dialog
| Where | Button | Shown when |
|---|---|---|
| Invoices page | Create Statement, next to Add Payment | Full Access to Invoices |
| Customers page | Create Statement (outlined, file icon), next to Add New Customer | Full Access to Invoices, and not on the inactive-customers view |
The Customers page also keeps an older Create Statement (Legacy) button for the previous order system (Full Access to Customers). Use the button without "(Legacy)".
The Invoices button and the Customers button (without "(Legacy)") open the same dialog. Create Statement (Legacy) opens an older version with the same screens and wording, but it lists only invoices from orders placed before the move to the current Orders pages; a customer who owes only on newer orders doesn't appear in it. See Known limitations. The rest of this page describes the current dialog. It always starts fresh: Statement Date today, status All, empty search, nothing selected, nothing expanded. Closing it throws everything away, including typed emails and phones and any preview PDFs.
Screen 1: Create Statement
Filters along the top
| Control | Exact wording | What it does |
|---|---|---|
| Date picker | Statement Date | The calendar day printed on the statement and used for Open/Overdue and aging. Defaults to today. The calendar won't let you pick a future date or one more than a year back (verify: a date typed in by hand outside that range looks like it is still accepted, because only the calendar enforces it). |
| Drop-down | Outstanding Status: All / Overdue | Overdue keeps only customers with at least one overdue invoice and shows only their overdue invoices. "Overdue" here means overdue today (New York calendar), not on the Statement Date. See the caution below. |
| Search | placeholder Search by Customer Name/Phone number | Narrows by customer name, about 0.3 seconds after you stop typing. It matches the name only; typing a phone number finds nothing. |
| Checkbox | Expand to show all invoices | Opens every customer's invoice list. You can still close single rows afterwards. |
Changing the status filter or the search keeps the customers you already ticked, but cancels "select everything" (below).
The customer table
| Column | Shows | Sortable |
|---|---|---|
| (checkbox) | Tick the customer | — |
| (arrow) | Open the customer's invoices | — |
| Customer | Logo or first letter, and name | Yes |
| Editable. Starts with the customer's billing contact email, else the restaurant's own email. Placeholder Add email | No | |
| Phone Number | Editable. Starts with the billing contact phone, else the restaurant's own phone. A stored phone that isn't a valid number is skipped, so a bad billing-contact phone falls back to the restaurant's. Placeholder Add phone | No |
| Total Balance | Sum of every listed invoice's amount owed (how) | Yes |
Default order is by customer name, A to Z. The table loads 20 customers at a time as you scroll, with Showing {loaded} of {total} customers underneath.
Email and phone are checked when you leave the field: a malformed email or phone shows an error, but only on ticked customers. Changes here are used for this send only. They aren't saved to the customer.
A customer's invoices (open the arrow)
| Column | Shows |
|---|---|
| (checkbox) | Include this invoice |
| Outstanding Invoices | Invoice number |
| Due Date | Due date |
| Status | Open, or a highlighted Overdue chip |
| Amount Due | What's still owed on it |
| Last Sent | When it was last on a statement that went out, or — |
Selecting
| Action | Result |
|---|---|
| Tick a customer | All their listed invoices are ticked |
| Untick some of their invoices | The customer's box shows a dash (partly selected). Only ticked invoices go on their statement. |
| Untick their last invoice | The customer is unticked |
| Customer has neither email nor phone | Their box and invoice boxes are greyed out. Hovering the customer's box says Add an email or phone number below to enable sending. Typing either unlocks them straight away. |
| Header box when nothing is ticked | Ticks every customer loaded so far that has an email or phone. If more customers haven't loaded yet, it switches to select everything: every matching customer, including ones you haven't scrolled to, is included. |
| Tick every loaded customer by hand, with more still to load | Same as the header box: it switches to select everything on its own. |
| Untick a customer while selecting everything | They're left out; the header box shows a dash |
| Header box when anything is ticked | Clears everything |
The footer shows No Customers Selected, 1 Customer Selected or {n} Customers Selected. When selecting everything, the count is the total matching customers minus the ones you unticked. That total includes customers with no email or phone, who are skipped when sending, so the count can be higher than the statements that go out.
Buttons: Preview Statement and Create & Send. Both are disabled until at least one customer is ticked, with the tooltip Select at least one customer to continue. Both first check every ticked customer's email and phone; if one is malformed, you stay on this screen with the error shown.
With Outstanding Status → Overdue, the dialog shows only overdue invoices. But if you leave all of a customer's shown invoices ticked, the statement that's sent (and its preview) includes every unpaid invoice of that customer, Open ones too. Only when you untick at least one invoice does the statement stick to exactly the ones ticked. See Known limitations.
Screen 2: Preview Statement
- Shows the PDF for one ticked customer at a time, titled STATEMENT PREVIEW (no number yet). Customer name and {n} / {total} in the title row, with Previous customer / Next customer arrows.
- While loading: Loading PDF preview…. If the preview fails, the error text shows in place of the PDF, for example No outstanding invoices found for this customer or None of the selected invoices have outstanding balances.
- When selecting everything and not all customers are loaded: Showing {shown} of {total} recipients. Click Create & Send to dispatch all.
- Print Statement prints the preview PDF (disabled until it has loaded). Create & Send goes to screen 3.
Making a preview creates nothing and uses up no statement number. It does create a pay link for any invoice that didn't have one yet (see knock-on effects).
Each customer's preview is made once and reused until the dialog closes. If you change the Statement Date or the ticked invoices after previewing, the preview keeps showing the old version, but what's sent uses your latest choices. Close and reopen the dialog to see a fresh preview.
Screen 3: Send Statement
- A blue note: You are about to send {count} statement(s). Each selected customer will receive their own statement.
- A list of the customers with their email and phone. Click one to see its PDF on the right.
- Footer: {n} Customer(s) Selected and Send (disabled while sending, or with nobody to send to).
When selecting everything, the note, the list and the footer count only the customers loaded so far. Send still includes everyone matching. With 120 matching customers and 40 loaded, the screen says 40 but 120 statements go out.
Sending
After Send:
- Loading the rest. When selecting everything, the dialog first loads every remaining customer: Preparing statements... ({loaded} / {total}).
- Validation. Any ticked customer whose email or phone is malformed, including ones that were never on screen, stops the send with the error toast Invalid contact info on: {names}. Please fix or deselect. (first three names, then +{n} more). Nothing is sent. A bare country code like "+1" passes this check as "no phone" (verify: it is still sent to the server as the phone, which would reject that whole batch of 50 with a
requestfailure). - Sending, 50 customers at a time. One batch: Sending {total} statement(s).... Several: the same text until the first batch returns, then Sending statements... ({sent}/{total}), with Batch {n} of {m} underneath. The dialog can't be closed meanwhile.
- Result.
| Outcome | What you see |
|---|---|
| All succeeded | Toast Statement sent successfully. The dialog closes. |
| Some failed | Toast and overlay {succeeded} sent. {failed} failed., with View failure details listing each customer, the step and the reason. Buttons Close and Retry Failed. |
| A batch didn't reach the server | Counted as Some failed: every customer in that batch is listed with the step request and the network error. The other batches still go. |
| Over 1,000 customers | Failed to send statements · Cannot send more than 1000 statements at once. Please contact support. and Close. Nothing is sent. |
The {succeeded} sent number counts every statement that was created, including ones whose email and text then failed. Ten customers with one failed delivery reads 10 sent. 1 failed., not 9 and 1.
Retry Failed re-sends only the customers that failed. A customer whose statement was already created keeps the same statement and number and is only re-delivered; customers that succeeded aren't sent again. A customer whose statement was never created (step statement_creation, or request when the server never got the batch) gets a new statement on retry, frozen with that moment's balances.
Failure steps in the details
| Step | Means | Typical reason |
|---|---|---|
statement_creation | The statement couldn't be made | No outstanding invoices found for this customer (paid in the meantime), None of the selected invoices have outstanding balances |
pdf_generation | The PDF couldn't be made; nothing was sent | — |
email | Only email was tried, and it failed | SendGrid reported failure |
sms | Only text was tried, and it failed | OneSignal send failed |
delivery | Both were tried and both failed, or the customer's account couldn't be found | Both reasons joined with " | " |
request | The whole batch didn't reach the server | The network error |
The failure list names a customer by name when the dialog knows it, otherwise by its internal ID.
What counts as "sent"
A statement counts as sent when at least one of email or text went out.
| Text | Result shown | In View Statements | Last Sent updated | |
|---|---|---|---|---|
| Sent | Sent | Success | Yes | Yes |
| Sent | Failed | Success (the text failure isn't reported) | Yes | Yes |
| Failed | Sent | Success (the email failure isn't reported) | Yes | Yes |
| Failed | Failed | Failed (delivery) | No (saved, hidden) | No |
| Muted by Clipp | Muted by Clipp | Success, though nothing went out | No | No |
| Sent | Muted | Success | Yes | Yes |
Clipp can mute a supplier's email or text messages to customers (a setting with no screen in the app; Clipp staff set it). A muted channel isn't a failure.
Calculations
Amounts, Open/Overdue and aging are on What's on a statement.
Statement numbers. Each supplier has its own counter: 1, 2, 3… Every created statement takes the next number, including ones whose delivery then fails. A preview never takes a number.
| Action | Number used | Visible in View Statements |
|---|---|---|
| Preview for Acme Diner | none | — |
| Send to Acme Diner, email delivered | 41 | Yes |
| Send to Bay Grill, email and text both fail | 42 | No |
| Retry Failed → Bay Grill delivered | 42 (same) | Yes |
| Send to Bay Grill again later (new send) | 43 | Yes |
Knock-on effects
Sending a statement doesn't move money. Before/after for "Send a statement to Acme Diner for invoices INV-1041 ($300.00 owed) and INV-1052 ($99.99 owed, no pay link yet)":
| Area | Before | After |
|---|---|---|
| Statement record | — | Statement #41, Total Due $399.99, frozen invoices and aging, a private link |
| Pay links | INV-1052 has none | INV-1052 gets a pay link valid 90 days. INV-1041 keeps its existing link and expiry. |
| Invoice amounts and payment status | $300.00 / $99.99, Partially paid / Unpaid | Unchanged |
| Bookkeeping rows | — | None added |
| Store credit | — | Unchanged |
| AR aging and reports | — | Unchanged |
| Stock | — | Unchanged |
| Last Sent in the dialog | INV-1041: — · INV-1052: — | Today, for both |
| — | To the address in the dialog: Statement from {supplier} (content) | |
| Text | — | To the phone in the dialog (content) |
| Push notification | — | None |
| — | Saved with the statement, viewable from View Statements and the statement page |
Preview Statement has only one of these effects: it creates missing pay links.
Where it shows up
- Customers and Invoices pages: Create Statement.
- The statement afterwards: Statement history, the restaurant's statement page, the PDF, email and text.
Permissions
| Action | Needs |
|---|---|
| See Create Statement on Customers | Admin, or Full Access to Invoices |
| See Create Statement on Invoices | Admin, or Full Access to Invoices |
| Server: list, preview, create, send (Invoices dialog) | Full Access to Invoices, on the caller's own supplier. One supplier can't preview or send another's. |
| Server: same calls from the Customers dialog | Full Access to Invoices, the same as the Invoices dialog. Create Statement (Legacy) only needs any logged-in staff member of the same supplier. |
Read Only access hides the button.
Decisions
- One statement per customer, never a combined one. A bulk send is a loop of individual statements. (#1960)
- Send in batches of 50, five at a time on the server, with one retry key per send. Retrying never sends twice to customers that succeeded; a new send never reuses a previous one. (#1960, #1988)
- A statement that reached nobody is kept but hidden from history. Listing it would claim the customer received it. (#1981)
- Missing pay links are created when the statement is made. Every View & Pay link on the PDF must work. (#1981)
- Recipients default to the customer's billing contact, then the restaurant's own email and phone. Statements should reach accounts payable, not a general inbox. (#1988)
- The statement feature is on for every supplier. The
EnableInvoiceStatementsflag was removed with the rest of the feature-flag system. (#2079, #2080) - The Invoices dialog reads the invoices of current orders and shares the send engine with the Customers dialog. Numbering, batching, retry and delivery behave the same. (#2589)
- Clipp can mute a supplier's emails and texts, and a muted channel is not a failure. (#2450, #2452)
Specs
# prefix: SOST
Feature: Creating and sending statements
A supplier picks customers on the Invoices page and sends each one a statement of what they still owe on their
invoices. A preview shows the statement first. Each customer gets their own statement, and a customer
that fails can be retried without sending the others again.
Background:
Given a supplier user with full invoice access
And customers with invoices on orders that went out and still owe money
Rule: Only invoices that are still owed are listed
Scenario: SOST-001 the dialog lists each customer's owed invoices with their live balance
When the supplier chooses Create Statement on the Invoices page
Then every customer with an unpaid, billable invoice is listed with the total they owe
And expanding a customer shows each invoice's number, due date, status and amount due
And paid, cancelled and deleted invoices are not listed
Scenario: SOST-002 Overdue starts the calendar day after the due date and the filter keeps only those invoices
Given a customer has one invoice due yesterday and one due today
When the supplier sets Outstanding Status to Overdue
Then only the invoice due yesterday is listed and the customer's total counts only it
And customers with no overdue invoice disappear
Scenario: SOST-003 an invoice shows when it was last sent on a statement
Given an invoice was already sent on a statement
When the supplier expands that customer
Then the invoice shows the day it was last sent
Scenario: SOST-017 an invoice with a bank payment clearing is still listed at its full amount
Given a customer paid an invoice by bank transfer that has not cleared yet
When the supplier chooses Create Statement
Then the invoice is listed with its full remaining amount
And it counts toward the customer's total until the money lands
Rule: The supplier picks customers, invoices and contact details
Scenario: SOST-004 a customer needs an email or phone before it can be selected
Given a customer has no email and no phone on file
Then the customer cannot be selected until the supplier types an email or a phone number
Scenario: SOST-005 an invalid email or phone blocks the send
Given the supplier typed an email that is not valid for a selected customer
When the supplier continues
Then the dialog stays on the list and marks the field
Scenario: SOST-006 the Statement Date is a calendar day that defaults to today
Given the supplier leaves the date alone
When the supplier sends statements
Then the statement is dated today, as the supplier's calendar day, with no shift to another day
And the calendar will not offer a future date or one more than a year back
Rule: The supplier can preview a statement before sending
Scenario: SOST-007 the preview shows each selected customer's statement
Given the supplier selected two customers
When the supplier chooses Preview Statement
Then the first customer's statement PDF is shown with a Print Statement button
And the supplier can step to the next customer
Rule: Create & Send makes one statement per customer
Scenario: SOST-008 each selected customer gets a statement of exactly the invoices picked
Given the supplier ticked only some of a customer's invoices
When the supplier chooses Create & Send and then Send
Then the customer's statement holds just those invoices, each with a pay link
And the supplier is told "Statement sent successfully." and the dialog closes
Scenario: SOST-009 a customer with no invoices ticked gets all of its owed invoices
Given the supplier selected a customer without choosing single invoices
When the statement is created
Then it holds every invoice the customer still owes
Scenario: SOST-010 sending the same request twice creates one statement
Given the same send is submitted twice, for instance by a retry
Then the customer has one statement, not two
Scenario: SOST-011 a large send goes out in batches of 50 and stops at 1,000 customers
Given the supplier selected 120 customers
When the supplier sends
Then the statements go out in batches of 50, 50 and 20 under one send reference
And more than 1,000 customers are refused with a message to contact support
Rule: A failed customer is reported and can be retried alone
Scenario: SOST-012 an invoice that is no longer owed is left off, and fails its customer only when none remain
Given a selected invoice was paid, deleted or belongs to someone else
When the supplier sends
Then that invoice is left off the statement and never statemented for another customer
And a customer with none of its selected invoices still owed fails with the reason while the other customers are still sent
Scenario: SOST-013 a customer with nothing owed fails without failing the others
Given a selected customer has nothing outstanding any more
When the supplier sends
Then that customer is reported as failed and the rest are sent
Scenario: SOST-014 the supplier retries only the failed customers
Given some statements failed
Then the supplier is told how many were sent and how many failed, with each reason
When the supplier chooses Retry
Then only the failed customers are sent again under the same send reference
And a customer already sent is not sent twice
Rule: Only staff with full invoice access can create statements
Scenario: SOST-015 the Create Statement button needs full invoice access
Given a supplier user without full invoice access
When they open the Invoices page
Then there is no Create Statement button
Scenario: SOST-016 the statement calls are refused without full invoice access
Given a user who is not supplier staff with full invoice access
When they ask for outstanding invoices, a preview or a send
Then the request is refused
The spec covers the Invoices dialog.
Known limitations
- Overdue filter can send Open invoices too, when all shown invoices are left ticked (see the caution above).
- Preview can be stale after changing the date or ticked invoices; only closing the dialog refreshes it.
- A failure on one channel is silent when the other channel worked.
- A send where both channels are muted reports success but reaches nobody, and the statement doesn't appear in View Statements.
- Search says "Name/Phone number" but matches names only.
- Contact edits aren't saved to the customer; the next statement starts from the stored contact again.
- Create Statement (Legacy) reads the older invoices only. Its dialog lists invoices from orders placed before the move to the current Orders pages, so a customer who owes only on newer orders is missing, and one who owes on both shows just the older part. Its server calls check the supplier but not the role. Use Create Statement instead.
- No Create Statement on a single customer's page; only View Statements is there.
- Statement numbers have gaps for statements that failed to deliver.
- Pay links already on an invoice aren't refreshed. If an invoice's link was made 80 days before the statement, the statement's View & Pay and Pay Now stop working 10 days after sending.
- "{n} sent" overstates when deliveries failed: it counts created statements, not delivered ones.
- The Send screen counts only loaded customers when selecting everything, and the footer count includes customers with no email or phone, who are skipped.
- The Statement Date limits live in the calendar only (verify): a typed future date may get through, and the server only checks that it is a real day.
FAQ
Why is a customer greyed out? They have no email or phone on file. Type one into the row and they become selectable.
I changed the Statement Date but the preview didn't change. Previews are made once per customer per dialog. Close and reopen the dialog. The statement that's sent uses the new date either way.
I picked "Overdue" but the restaurant got its Open invoices too. With all shown invoices ticked, the statement covers all unpaid invoices. Untick at least one to limit it to exactly the ticked ones.
It said "Statement sent successfully" but the restaurant never got the email. If the text went through, a failed email isn't reported. Also check whether Clipp has muted the supplier's emails.
It said "10 sent. 1 failed." Did ten customers get it? No, nine did. The first number counts statements created, including the one that then failed to deliver. Check View failure details.
I sent statements but View Statements is empty. Neither email nor text reached the customer, or both are muted for the supplier.
Why did statement #42 disappear and the next one is #43? #42 was created but didn't reach the customer. Use Retry Failed right away to re-deliver it under the same number.
Can I send the same statement again? Not as the same statement. A new Create & Send makes a new statement with a new number and today's balances.
Will a typo fix in the email field update the customer? No. Change the customer's contact on the customer page.