Settlement & statements

Settlement is where completed work becomes billable. Time entries from the Record phase are priced, grouped into budget periods, and issued as a statement — a monthly bundle with a cover letter, work summary, line items, and amount due.

Budget periods

Each client has a monthly budget period that aligns with their billing cycle. The budget period stores dollar amounts — not minutes or hours. This is the immutability principle: once a budget period is created, its dollar values are the permanent record. If rates change mid-cycle, existing periods aren't retroactively recalculated. New rates apply to new periods.

Two-rate pricing

Field uses two rates to price work:

Budget rate — $2.50/min

Applied to work that falls within the client's monthly budget. This is the base rate for routine maintenance and any work covered by the included minutes.

Overage rate — $3.75/min

Applied to a-la-carte work that exceeds the monthly budget (overage). The higher rate reflects the ad-hoc nature of the work — no commitment discount.

How time becomes line items

When a work item moves through Record, its confirmed time entries are attributed to the client's current budget period. Field checks whether the entry falls within the remaining budget or exceeds it. Budget-rate entries fill the included allocation first. Once the budget is exhausted, additional entries are priced at the overage rate. Each entry becomes a line item with the duration, rate, and dollar amount.

Harvest sync

If you use Harvest for time tracking, time logged in Field pushes to Harvest automatically. The confirmed entries in Record are the source of truth for settlement — Harvest is a convenience layer, not the billing record.

Statements

At the close of each billing period, Field generates a statement for the client: a cover letter, a summary of the work done, line items, and the amount due. Statements are a workflow tool — they're not accounting software and not a substitute for recording formal invoices in your own bookkeeping system (QuickBooks, FreshBooks, Wave, Xero, or whatever you use).

Statements are reproducible. The rendered PDF is captured as a snapshot at send time, so regenerating a statement produces the same output even if you've changed your settings or rates since then.

Statement lifecycle

A statement moves through four states: draftreviewpublishedsent. Once published, the statement is locked: cover letter, line items, and section toggles can no longer be edited. The published row carries the invoice number, due date, and the rendered PDF snapshot. To correct a published or sent statement, you have to either void it (via Stripe if escalated) or delete and reissue. This protects the persisted snapshot from drifting out of sync with what was actually sent.

Composer attachment

The outbound composer's invoice attachment dropdown only lists statements that are published, have a rendered snapshot, and haven't been sent yet. Drafts and review-status statements don't appear — they need to be published first. The fastest path is the per-card Send via composer button on /admin/outbound, which publishes and prepares the snapshot before opening the modal.

Recovering a stranded send

If an email send fails AND the system can't roll back the row to its pre-send state, the statement gets stranded as sent with no email having actually gone out. Field surfaces a stranded-claim error toast that includes a recovery token (the sent_at value of the failed send). On the canonical statement page, when status is sent, a Recover stranded send button becomes available — click it, paste the token from the error, and the row resets to published so you can retry. The token gates this action so a legitimately-sent statement can't be accidentally reopened (which would risk a duplicate email).

Reports use the same pattern: a Recoverlink appears next to each sent-marked row in the client profile's Reports section, with the same token-gated reset. The recovery action is intentionally token-gated for both surfaces — if you click Recover on a row you're unsure about, pasting the wrong (or stale) token is a no-op rather than a destructive reset.

Send concurrency & Stripe void

While a statement send is in progress, Stripe void operations (e.g. from voiding a Stripe-escalated invoice) wait for the send to finish. If you see a Stripe void retry in your dashboard during a send, that's expected — Field is serializing the two operations so a customer can't be emailed an invoice for a row that's being voided. Voids that fail for other reasons (unrelated to a live send) trigger a Pushover alert so you can investigate before Stripe's retry budget exhausts.

Stripe escalation

If you connect Stripe, you can escalate a statement to a Stripe-hosted invoice. The escalation creates a Stripe invoice attached to the statement; the statement remains the canonical Field record. Use this for late payers, clients where you want Stripe's dunning and hosted PDF, or when a client needs to pay by card through a formal invoice link.

Voiding a Stripe invoice resets the underlying statement to draft and clears all publish/send artifacts (invoice number, due date, snapshot, sent_at). The work entries the original publish billed are unbilled too — but only the entries that statement actually owns; rebillings into a different statement are protected.

Overage handling

When work exceeds the monthly budget, Field doesn't block it. The operator continues working and time is tracked at the overage rate. The overage amount appears on the client's next statement. Operators can see budget consumption in real time on each site's dashboard — a percentage indicator shows how much of the monthly allocation has been used.