feat(mcp): the create tools preview and confirm, and the party keeps its contact block (P4b S4.4)
An invoice is issued, not edited. Without `confirmed` the create tools now preview: the posting (with the accounts' codes, which the live chart may not hold yet), the number it will take, its due date, terms and early discount, warnings, and for an invoice the DRAFT copy of the PDF, handed over as a file. Nothing is written and no number is used up. With `confirmed` the invoice posts, takes the number the preview showed, and files the issued copy with itself in the same call: `receipt.attached` on its entry plus the link to the invoice, its SHA-256 in the event (A-1, A-7, B-40). The copy the customer received is therefore the copy in the books, and `books.document`'s re-created page can never be mistaken for it. The result also carries a `mailto` link for a human to send it; the books never send (A-4). A bill keeps what the plan says a bill is: the vendor's own invoice number, the vendor's invoice filed on its entry as its evidence, and, in books that have declared `documents_v2`, an account on every line, so no bill can land in General Expenses by default any more (A-9, A-10, A-13). A vendor number entered twice is refused unless the caller says why, and the reason is journaled with the second bill (B-40 item 4). Books that have not declared the feature keep recording bills exactly as before, so the owner's books keep working between units (D-39, 8.0.4). Terms are resolved in one place and in one order: the due date given, else the terms given, else the customer's or vendor's own default, else the books' `invoicing.default_terms`; a document given only a due date stores no terms, so an old-shape invoice is still written byte for byte as before (B-39, A-13). D-55: a party carries the owner's full contact block (phone, contact person, billing and shipping addresses, billing email). It rides the same `party.updated` event behind `documents_v2`, and an invoice's bill-to is snapshotted at issue with the billing address and billing email in place of the general ones when the party has them — `PartySnapshot::from_party` is the one place that rule lives, so a later edit cannot change what was sent, and the next invoice takes today's details. Tests: the wire tests are the new `crates/ledger-cli/tests/documents.rs` (preview writes nothing, the DRAFT copy, the issued copy's SHA-256 equals `books.get_receipt`'s, numbers run, a bill's file and terms, the duplicate refusal, the line-account rules, the terms fallback, the `party_id` alias and the ambiguity it refuses, the contact block's set and clear, and the bill-to at issue); `format_upgrade.rs` gains `documents_v2_refused_until_consent` and the cut-over test now refuses and then makes a document carrying a new field (8.0.6 item 3); the store tests are `the_contact_block_round_trips_and_replays` and `an_invoice_keeps_the_billing_details_it_was_issued_with`, and `books_written_under_older_rules_still_open` gains a hand-written contact-block event (8.0.6 item 1). Merge does not need the owner's go-ahead: the live books refuse a write that needs `documents_v2` until he gives it, and take every other write as before (8.0.6 item 6). No figure moved: S4 moves none.
This commit is contained in:
1 parent
ed637f0e27
commit
d5b9e5cf99
28 files changed
+2604
-190
No files matched your search
+18
-2
@@ -34,8 +34,8 @@ No other statuses.
|
||||
| Bank reconciliation (cleared flags + report) | Reconcile | done | — |
|
||||
| QuickBooks CSV import (bank txns, chart of accounts) | Banking → Upload | done | R-FUTURE-4 |
|
||||
| QuickBooks IIF + XLSX export | Export / reports | done | R-FUTURE-4 |
|
||||
| A/R invoices + payments + aging | Business → Invoices | done | R-FUTURE-5 |
|
||||
| A/P bills + payments + aging | Business → Bills | done | R-FUTURE-5 |
|
||||
| A/R invoices + payments + aging | Business → Invoices | done | R-FUTURE-5; numbers, terms, line accounts, the party snapshots and the issued PDF filed with the invoice, through `books.create_invoice`'s preview and confirm (P4b S4.4) |
|
||||
| A/P bills + payments + aging | Business → Bills | done | R-FUTURE-5; the vendor's own invoice number (a duplicate refused), terms, line accounts and the vendor's invoice filed as the bill's evidence, through `books.create_bill`'s preview and confirm (P4b S4.4) |
|
||||
| Payroll runs (accounting only, no tax tables) + tax remittance | Payroll | done | — |
|
||||
| Tracking classes (divisional P&L) | Class tracking | done | invoice and bill lines take a class too (projects, rules.md B-37 item 8; QBO/Xero class or tracking per line) |
|
||||
| CPA handoff package (TB + GL xlsx, P&L + BS pdf, zip) | Reports → export | done | — |
|
||||
@@ -92,6 +92,22 @@ and the rule index from B-1 to B-45 (`bookspec/spec/rules-index.md`). Every
|
||||
existing bookspec example still runs on every `cargo test`, through both
|
||||
the loader's own checks and the `Engine` trait.
|
||||
|
||||
### P4b S4.4: the create tools preview and confirm (2026-10-27)
|
||||
|
||||
The A/R and A/P rows above gain their note rather than a new row: no
|
||||
parity item changed status, so the floor stands. `books.create_invoice`
|
||||
and `books.create_bill` now preview without `confirmed` (the posting, the
|
||||
number and due date it will take, the DRAFT or the discount, and nothing
|
||||
written) and post with it (A-1), which is what the workflow reference
|
||||
does before a document leaves the company. A bill in books that have
|
||||
declared `documents_v2` names each line's account and keeps the vendor's
|
||||
invoice (A-10, A-13); an invoice keeps the copy it issued (A-7, B-40) and
|
||||
a `mailto` link for a human to send it, since the books never send (A-4).
|
||||
`books.update_party` takes the party's email and terms per side (A-13) and
|
||||
the owner's full contact block (D-55: phone, contact person, billing and
|
||||
shipping addresses, billing email), which an invoice's bill-to copies at
|
||||
issue.
|
||||
|
||||
### P9a self-host deployment (2026-10-26)
|
||||
|
||||
P9a is a deployment, not a semantic feature: the same engine, store, MCP
|
||||
|
||||
Reference in new issue
Block a user