@happyvertical/smrt-commerce 0.57.3 → 0.57.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +17 -0
- package/README.md +130 -0
- package/agents/accounting-snapshot-mapper.md +11 -0
- package/agents/contract-billing-schedules.md +67 -0
- package/agents/contract-money.md +81 -0
- package/agents/customer-funds.md +96 -0
- package/agents/historical-sales.md +132 -0
- package/agents/money-calculator.md +36 -0
- package/agents/money-model.md +6 -3
- package/agents/observed-purchase-prices.md +37 -0
- package/agents/payment-allocations.md +59 -0
- package/agents/received-sales-contract-money.md +38 -0
- package/dist/accounting-snapshot.d.ts +8 -1
- package/dist/accounting-snapshot.d.ts.map +1 -1
- package/dist/allocation-integrity.d.ts.map +1 -1
- package/dist/chunks/{ContractLineItemCollection-BZcrlrrY.js → ContractLineItemCollection-J4xtRtzE.js} +6 -6
- package/dist/chunks/{ContractLineItemCollection-BZcrlrrY.js.map → ContractLineItemCollection-J4xtRtzE.js.map} +1 -1
- package/dist/chunks/DocumentTaxCollection-C42x0YLW.js +4385 -0
- package/dist/chunks/DocumentTaxCollection-C42x0YLW.js.map +1 -0
- package/dist/chunks/HistoricalCustomerFundsCollections-B5x8gTW3.js +170 -0
- package/dist/chunks/HistoricalCustomerFundsCollections-B5x8gTW3.js.map +1 -0
- package/dist/chunks/{InvoiceCollection-cinzAqt6.js → InvoiceCollection-BIcge9Wl.js} +131 -18
- package/dist/chunks/InvoiceCollection-BIcge9Wl.js.map +1 -0
- package/dist/chunks/{TaxCodeCollection-DaBOPG9c.js → TaxCodeCollection-RWdVaheF.js} +3 -4
- package/dist/chunks/TaxCodeCollection-RWdVaheF.js.map +1 -0
- package/dist/chunks/{TaxComponentCollection-C4zxnyVu.js → TaxComponentCollection-Dt2jeWiC.js} +3 -3
- package/dist/chunks/{TaxComponentCollection-C4zxnyVu.js.map → TaxComponentCollection-Dt2jeWiC.js.map} +1 -1
- package/dist/chunks/{allocation-integrity-WmWyXhtG.js → allocation-integrity-DJ7-LY1j.js} +7 -7
- package/dist/chunks/{allocation-integrity-WmWyXhtG.js.map → allocation-integrity-DJ7-LY1j.js.map} +1 -1
- package/dist/chunks/{contract-money-EuToOghh.js → contract-money-DSRTMoXm.js} +45 -12
- package/dist/chunks/contract-money-DSRTMoXm.js.map +1 -0
- package/dist/chunks/customer-funds-internal-BQzoJXK5.js +24 -0
- package/dist/chunks/customer-funds-internal-BQzoJXK5.js.map +1 -0
- package/dist/chunks/{detect-CY9ufaFb.js → detect-DAE-_NAk.js} +5 -2
- package/dist/chunks/{detect-CY9ufaFb.js.map → detect-DAE-_NAk.js.map} +1 -1
- package/dist/chunks/historical-commerce-internal-C9ButfuH.js +18 -0
- package/dist/chunks/historical-commerce-internal-C9ButfuH.js.map +1 -0
- package/dist/chunks/{invoice-posting-C2i5dOVZ.js → invoice-posting-BeTPw3h9.js} +5 -5
- package/dist/chunks/invoice-posting-BeTPw3h9.js.map +1 -0
- package/dist/chunks/retention-accounting-Brdj9x-V.js +2323 -0
- package/dist/chunks/retention-accounting-Brdj9x-V.js.map +1 -0
- package/dist/chunks/retention-accounting-internal-CBQRvd74.js +17 -0
- package/dist/chunks/retention-accounting-internal-CBQRvd74.js.map +1 -0
- package/dist/chunks/{tenant-money-barrier-6TlqUeVj.js → tenant-money-barrier-DoF6lR8h.js} +5 -5
- package/dist/chunks/{tenant-money-barrier-6TlqUeVj.js.map → tenant-money-barrier-DoF6lR8h.js.map} +1 -1
- package/dist/chunks/types-Bbm0Xflc.js.map +1 -1
- package/dist/collections/DocumentTaxCollection.d.ts +4 -1
- package/dist/collections/DocumentTaxCollection.d.ts.map +1 -1
- package/dist/collections/HistoricalCustomerFundsCollections.d.ts +10 -0
- package/dist/collections/HistoricalCustomerFundsCollections.d.ts.map +1 -0
- package/dist/collections/HistoricalSalesLineCollection.d.ts +6 -0
- package/dist/collections/HistoricalSalesLineCollection.d.ts.map +1 -0
- package/dist/collections/PaymentAllocationCollection.d.ts +2 -6
- package/dist/collections/PaymentAllocationCollection.d.ts.map +1 -1
- package/dist/collections/PurchasePriceObservationCollection.d.ts +6 -0
- package/dist/collections/PurchasePriceObservationCollection.d.ts.map +1 -0
- package/dist/collections/index.d.ts +1 -0
- package/dist/collections/index.d.ts.map +1 -1
- package/dist/contract-billing-schedule.d.ts +83 -0
- package/dist/contract-billing-schedule.d.ts.map +1 -0
- package/dist/contract-money.d.ts +2 -0
- package/dist/contract-money.d.ts.map +1 -1
- package/dist/customer-funds-internal.d.ts +6 -0
- package/dist/customer-funds-internal.d.ts.map +1 -0
- package/dist/customer-funds.d.ts +108 -0
- package/dist/customer-funds.d.ts.map +1 -0
- package/dist/document-money.d.ts +11 -0
- package/dist/document-money.d.ts.map +1 -1
- package/dist/historical-commerce-internal.d.ts +3 -0
- package/dist/historical-commerce-internal.d.ts.map +1 -0
- package/dist/historical-customer-funds-types.d.ts +113 -0
- package/dist/historical-customer-funds-types.d.ts.map +1 -0
- package/dist/historical-customer-funds.d.ts +23 -0
- package/dist/historical-customer-funds.d.ts.map +1 -0
- package/dist/historical-funds-internal.d.ts +5 -0
- package/dist/historical-funds-internal.d.ts.map +1 -0
- package/dist/historical-sales-money.d.ts +22 -0
- package/dist/historical-sales-money.d.ts.map +1 -0
- package/dist/historical-sales-reports.d.ts +31 -0
- package/dist/historical-sales-reports.d.ts.map +1 -0
- package/dist/historical-sales-types.d.ts +106 -0
- package/dist/historical-sales-types.d.ts.map +1 -0
- package/dist/historical-sales-validation.d.ts +12 -0
- package/dist/historical-sales-validation.d.ts.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1668 -1643
- package/dist/index.js.map +1 -1
- package/dist/invoice-accounting-sync.d.ts +0 -1
- package/dist/invoice-accounting-sync.d.ts.map +1 -1
- package/dist/invoice-mcp.d.ts.map +1 -1
- package/dist/invoice-posting.d.ts.map +1 -1
- package/dist/invoice-retention.d.ts +16 -0
- package/dist/invoice-retention.d.ts.map +1 -0
- package/dist/invoices.d.ts +2 -0
- package/dist/invoices.d.ts.map +1 -1
- package/dist/invoices.js +2 -2
- package/dist/manifest.json +7563 -4419
- package/dist/models/Contract.d.ts +14 -0
- package/dist/models/Contract.d.ts.map +1 -1
- package/dist/models/DocumentTax.d.ts +2 -0
- package/dist/models/DocumentTax.d.ts.map +1 -1
- package/dist/models/HistoricalCustomerFunds.d.ts +36 -0
- package/dist/models/HistoricalCustomerFunds.d.ts.map +1 -0
- package/dist/models/HistoricalCustomerFundsAllocation.d.ts +32 -0
- package/dist/models/HistoricalCustomerFundsAllocation.d.ts.map +1 -0
- package/dist/models/HistoricalSalesLine.d.ts +29 -0
- package/dist/models/HistoricalSalesLine.d.ts.map +1 -0
- package/dist/models/Invoice.d.ts +10 -1
- package/dist/models/Invoice.d.ts.map +1 -1
- package/dist/models/Payment.d.ts +7 -1
- package/dist/models/Payment.d.ts.map +1 -1
- package/dist/models/PaymentAllocation.d.ts +3 -1
- package/dist/models/PaymentAllocation.d.ts.map +1 -1
- package/dist/models/PaymentIntent.d.ts.map +1 -1
- package/dist/models/Payout.d.ts.map +1 -1
- package/dist/models/PurchasePriceObservation.d.ts +15 -0
- package/dist/models/PurchasePriceObservation.d.ts.map +1 -0
- package/dist/models/TaxCode.d.ts +1 -1
- package/dist/models/TaxCode.d.ts.map +1 -1
- package/dist/models/index.d.ts +1 -0
- package/dist/models/index.d.ts.map +1 -1
- package/dist/money.d.ts +5 -1
- package/dist/money.d.ts.map +1 -1
- package/dist/money.js +62 -15
- package/dist/money.js.map +1 -1
- package/dist/observed-purchase-price-internal.d.ts +3 -0
- package/dist/observed-purchase-price-internal.d.ts.map +1 -0
- package/dist/observed-purchase-price.d.ts +71 -0
- package/dist/observed-purchase-price.d.ts.map +1 -0
- package/dist/received-purchase-money.d.ts +87 -0
- package/dist/received-purchase-money.d.ts.map +1 -0
- package/dist/recipes.d.ts +4 -1
- package/dist/recipes.d.ts.map +1 -1
- package/dist/retention-accounting-internal.d.ts +3 -0
- package/dist/retention-accounting-internal.d.ts.map +1 -0
- package/dist/retention-accounting.d.ts +164 -0
- package/dist/retention-accounting.d.ts.map +1 -0
- package/dist/retention-money.d.ts +43 -0
- package/dist/retention-money.d.ts.map +1 -0
- package/dist/smrt-knowledge.json +1866 -113
- package/dist/tax/cookbook.d.ts.map +1 -1
- package/dist/tax-summary.d.ts +1 -0
- package/dist/tax-summary.d.ts.map +1 -1
- package/dist/types/index.d.ts +20 -1
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +16 -16
- package/dist/chunks/CustomerCollection-BIPH2ZUx.js +0 -99
- package/dist/chunks/CustomerCollection-BIPH2ZUx.js.map +0 -1
- package/dist/chunks/DocumentTaxCollection-DDzlywMW.js +0 -1666
- package/dist/chunks/DocumentTaxCollection-DDzlywMW.js.map +0 -1
- package/dist/chunks/InvoiceCollection-cinzAqt6.js.map +0 -1
- package/dist/chunks/TaxCodeCollection-DaBOPG9c.js.map +0 -1
- package/dist/chunks/VendorCollection-D6ZcUYy8.js +0 -100
- package/dist/chunks/VendorCollection-D6ZcUYy8.js.map +0 -1
- package/dist/chunks/calculations-C9daQLsh.js +0 -82
- package/dist/chunks/calculations-C9daQLsh.js.map +0 -1
- package/dist/chunks/contract-money-EuToOghh.js.map +0 -1
- package/dist/chunks/document-money-DV5t4vlK.js +0 -1186
- package/dist/chunks/document-money-DV5t4vlK.js.map +0 -1
- package/dist/chunks/invoice-posting-C2i5dOVZ.js.map +0 -1
package/AGENTS.md
CHANGED
|
@@ -31,6 +31,8 @@ recipes show carry `@field({ description })` text; keep both in plain
|
|
|
31
31
|
language for end users and update them when a recipe's fields change. See
|
|
32
32
|
[core recipes](../core/agents/recipes.md).
|
|
33
33
|
|
|
34
|
+
See [historical issued sales](agents/historical-sales.md) for exact original source
|
|
35
|
+
money, immutable source children and combined historical/live customer funds.
|
|
34
36
|
See [payment allocation integrity](agents/payment-allocations.md) for atomic splits,
|
|
35
37
|
retry identity, parent corrections and supported dialects.
|
|
36
38
|
See [tax codes](agents/tax-codes.md) for tenant-owned rate components, default codes,
|
|
@@ -215,3 +217,18 @@ See [agents/purchasing-ui.md](agents/purchasing-ui.md) for caller responsibiliti
|
|
|
215
217
|
|
|
216
218
|
Pure signed cost billing and explicit tax rounding are available through the
|
|
217
219
|
independent `cost-billing` subpath; see [contract](agents/cost-billing.md).
|
|
220
|
+
|
|
221
|
+
See [contract billing schedules](agents/contract-billing-schedules.md) for exact
|
|
222
|
+
approved milestone capacity, immutable amendments and atomic canonical invoice issue.
|
|
223
|
+
|
|
224
|
+
## Customer funds (#4079)
|
|
225
|
+
|
|
226
|
+
See [customer advances](agents/customer-funds.md) for explicitly configured
|
|
227
|
+
unapplied-AR/deposit-liability receipts, conserved application/refund capacity,
|
|
228
|
+
real liability reclassification, final-invoice attestation and mutation guards.
|
|
229
|
+
Use the public commands; `Payment.customerFundsJson` is command-owned.
|
|
230
|
+
|
|
231
|
+
See [observed purchase prices](agents/observed-purchase-prices.md) for incomplete
|
|
232
|
+
original supplier prices, explicit unknown totals and reviewed completion.
|
|
233
|
+
See [received sales agreement money](agents/received-sales-contract-money.md) for
|
|
234
|
+
exact complete source Order/Agreement evidence without synthetic lines or tax recognition.
|
package/README.md
CHANGED
|
@@ -323,6 +323,10 @@ and retry only if it is still pending. An already completed payment retains the
|
|
|
323
323
|
owner: if it rolls back after settlement returns, reload the payment before retry.
|
|
324
324
|
These guarantees cover new postings, not orphaned journals written by older
|
|
325
325
|
versions. The returned journal uses the caller's database executor.
|
|
326
|
+
Both payment and refund journal lines retain the payment's explicit currency and
|
|
327
|
+
exact amount; posting does not convert currencies or fall back to USD. When
|
|
328
|
+
reporting accounts that contain different currencies, use the public
|
|
329
|
+
`listPostedMovements` currency filter rather than combining their amounts.
|
|
326
330
|
|
|
327
331
|
### Cross-Package References
|
|
328
332
|
|
|
@@ -827,3 +831,129 @@ native POST of vendor, reference, notes, expected date and ship-to fields. Pass
|
|
|
827
831
|
allocations and totals unchanged. `PurchaseOrder` stores `expectedDate` and
|
|
828
832
|
`shipTo` in existing STI metadata. See [the purchasing contract](agents/purchasing-ui.md#purchase-order-header)
|
|
829
833
|
for validation, retained values and transport details.
|
|
834
|
+
|
|
835
|
+
### Invoice retention and release
|
|
836
|
+
|
|
837
|
+
`configureInvoiceRetention` freezes an explicit retained minor-unit amount on an
|
|
838
|
+
unpaid draft. Supply tenant, invoice, currency, expected invoice revision,
|
|
839
|
+
request identity, actor, reason, evidence reference, and versioned host policy.
|
|
840
|
+
The supported `creditPolicy: 'retained-first'` is an explicit caller choice:
|
|
841
|
+
issued credits reduce unreleased retention first, then current payable. Hosts
|
|
842
|
+
must choose and authorize their regional policy; Commerce supplies no legal
|
|
843
|
+
percentage or release date default. Configuration cannot be overwritten; replace
|
|
844
|
+
an unissued draft to change the original agreement.
|
|
845
|
+
|
|
846
|
+
`releaseInvoiceRetention` appends evidence under the invoice's transaction lock.
|
|
847
|
+
It cannot release more than the currently retained remainder. Exact request
|
|
848
|
+
replays are safe; changed payloads or stale revisions fail. Both commands retain
|
|
849
|
+
caller transaction affinity. Original gross, tax, line snapshots and approved
|
|
850
|
+
configuration stay unchanged. Credits and credit cancellation derive remaining
|
|
851
|
+
retention without rewriting release history.
|
|
852
|
+
|
|
853
|
+
`invoice.getPayableFacts()` separates `grossBalanceMinor`,
|
|
854
|
+
`retainedRemainingMinor`, `currentlyDueMinor`, and `allocationCapMinor`. The
|
|
855
|
+
allocation API enforces the current cap. `getAmountDue()` returns current due;
|
|
856
|
+
`getBalance()` remains the signed gross balance. An invoice with paid current
|
|
857
|
+
due and unreleased retention is not fully paid or overdue. Display gross and
|
|
858
|
+
current payable separately; pass explicit current due and remaining holdback to
|
|
859
|
+
the exact retained invoice UI props rather than treating gross as payable.
|
|
860
|
+
Stored money facts include `payable` for retained invoices; MCP projection honors
|
|
861
|
+
field visibility for every source of the payable alias.
|
|
862
|
+
|
|
863
|
+
Provider-controlled imports/automatic collection cannot acquire retention.
|
|
864
|
+
Accounting export refuses unreleased retention until the provider has an
|
|
865
|
+
explicit payable representation; it never silently requests collection of
|
|
866
|
+
gross. Fully released invoices use the existing gross accounting contract.
|
|
867
|
+
|
|
868
|
+
## Retained invoice accounting
|
|
869
|
+
|
|
870
|
+
`loadRetainedInvoiceAccountingSnapshot` supplies a read-only frozen document for
|
|
871
|
+
reviewing item/tax mapping before posting; `toRetainedInvoiceAccountingInput`
|
|
872
|
+
validates that reviewed mapping against those frozen lines. Both preserve tenant and caller executor
|
|
873
|
+
scope and performs no provider operation. Generic accounting snapshot/export still
|
|
874
|
+
refuses unreleased retention. A supplied host-managed release due date may precede
|
|
875
|
+
the release date: preserving original past-due terms makes the released amount
|
|
876
|
+
immediately overdue rather than silently extending payment terms.
|
|
877
|
+
|
|
878
|
+
`loadRetainedCreditAccountingSnapshot` and `toRetainedCreditAccountingInput`
|
|
879
|
+
provide the equivalent review path for an issued calculated credit. The caller
|
|
880
|
+
supplies both original invoice and credit IDs; the owning API verifies tenant,
|
|
881
|
+
customer, currency and exact original lineage, then retains the existing frozen
|
|
882
|
+
reader's issue and provider-realm checks. Generic retained-credit export remains
|
|
883
|
+
blocked. Review never creates a credit adjustment or contacts a provider.
|
|
884
|
+
|
|
885
|
+
The public `syncRetainedInvoiceToAccounting`, `releaseRetainedInvoiceToAccounting`,
|
|
886
|
+
`syncRetainedCreditToAccounting`, and `syncRetainedRefundToAccounting` commands
|
|
887
|
+
implement an explicit QuickBooks accrual reclassification contract. They require
|
|
888
|
+
SDK `receivableTransfers` from the published SDK0.104.1 cohort
|
|
889
|
+
(happyvertical/sdk#1414 / #1415; absent from SDK0.104.0).
|
|
890
|
+
They are available from the Commerce root and `/invoices` entry points.
|
|
891
|
+
|
|
892
|
+
The tenant must review/version the realm, environment, customer, AR account,
|
|
893
|
+
retained-asset account and optional bank account mapping. Supported choices are
|
|
894
|
+
`accrual`, `invoice-tax-point` and `host-managed` release due dates. Verified home
|
|
895
|
+
currency only; no inferred FX, tax timing, recovery percentage or release date.
|
|
896
|
+
Hosts authorize actors before these server commands and provide an active tenant.
|
|
897
|
+
|
|
898
|
+
For gross10500/retained1000, the original approved invoice remains10500. A
|
|
899
|
+
withholding journal debits retained assets and credits customer AR1000; a
|
|
900
|
+
zero-cash application links that credit to the original invoice. A partial release
|
|
901
|
+
creates the opposite journal and an explicitly dated host collection obligation.
|
|
902
|
+
The original invoice and its tax snapshot are unchanged. Provider collections and
|
|
903
|
+
provider tax overrides are unsupported for this contract.
|
|
904
|
+
|
|
905
|
+
Initial export requires an issued, unpaid, uncredited, unreleased host-owned
|
|
906
|
+
invoice with no prior provider identity. Historical source-owned invoices require
|
|
907
|
+
a separate reconciled ownership contract and are rejected: importing history must
|
|
908
|
+
not duplicate its original journal. Existing local retention commands continue to
|
|
909
|
+
reject provider-controlled releases; use the provider release command instead.
|
|
910
|
+
|
|
911
|
+
Retained-first credits cancel the applicable retained asset through a release
|
|
912
|
+
journal, apply the exported credit memo to that journal, and apply any due portion
|
|
913
|
+
to the original invoice. Unapplied credit remains available for a refund. Refund
|
|
914
|
+
sync requires an already completed local refund Payment, its cash journal and one
|
|
915
|
+
exact source-credit allocation. It records the cash journal and applies the
|
|
916
|
+
existing credit; it performs no bank action and makes no settlement-certification
|
|
917
|
+
claim. That source payment/allocation becomes immutable. Provider-managed invoice
|
|
918
|
+
voids/write-offs, credit cancellation/reallocation and refund deletion are rejected
|
|
919
|
+
rather than silently erasing remote postings. Corrective reversal contracts are
|
|
920
|
+
not implemented by these commands.
|
|
921
|
+
|
|
922
|
+
### Recovery and concurrency
|
|
923
|
+
|
|
924
|
+
Each external write has persisted request bytes/hash, attempt owner, status and
|
|
925
|
+
validated readback. Confirmed earlier steps survive a later failure. Unknown or
|
|
926
|
+
interrupted steps block new operations; `reconcileRetainedAccountingStep` requires
|
|
927
|
+
the observed request/attempt, a known remote ID for exact provider readback, or
|
|
928
|
+
explicit authoritative absence evidence. An interrupted in-flight owner must be
|
|
929
|
+
proven stopped. Reconciliation evidence and previous attempts remain recorded.
|
|
930
|
+
`reconcileRetainedBaseInvoice` wraps the existing frozen invoice recovery contract.
|
|
931
|
+
`reconcileRetainedCreditAccounting` resolves the reserved credit-memo creation step. Ordinary credit export is blocked for provider-retained sources.
|
|
932
|
+
|
|
933
|
+
The descriptor hash is not remote idempotency. The SDK uses documented QuickBooks
|
|
934
|
+
request-ID duplicate handling; never create a new request identity merely because
|
|
935
|
+
a response was lost. Exact local replays reuse confirmed steps. Competing commands
|
|
936
|
+
serialize under the tenant/source invoice locks, and releases check an observed
|
|
937
|
+
invoice revision. Source credits cannot change during an unfinished retention
|
|
938
|
+
operation. Commands reject caller-owned Commerce money transactions because a
|
|
939
|
+
provider write cannot be rolled back with local SQL.
|
|
940
|
+
|
|
941
|
+
`readRetainedInvoiceAccountingState` exposes the persisted operation/readback
|
|
942
|
+
history. Canonical `Invoice.getPayableFacts()` remains the source of local gross,
|
|
943
|
+
retained, released, credited and currently due amounts. Provider invoice
|
|
944
|
+
`TotalAmt - Balance` includes noncash applications and must never be labeled cash
|
|
945
|
+
received. SDK readback separates noncash applications, recorded cash journals and
|
|
946
|
+
unverified bank settlement.
|
|
947
|
+
|
|
948
|
+
Validation uses native SQLite/PostgreSQL persistence with mocked public provider
|
|
949
|
+
operations, plus the SDK's exact request/readback fixtures. No live provider call
|
|
950
|
+
or sandbox certification has been performed. Primary contract evidence and
|
|
951
|
+
provider-field limits are documented in the SDK Accounting README.
|
|
952
|
+
|
|
953
|
+
### Incomplete supplier price evidence
|
|
954
|
+
|
|
955
|
+
Use `recordPurchasePriceObservation`, `readPurchasePriceObservation`, and
|
|
956
|
+
`completePurchasePriceObservation` for source quotes/orders that lack complete
|
|
957
|
+
net/tax/gross facts. Unknown totals remain null and no calculated or reportable
|
|
958
|
+
Contract exists until explicit reviewed completion. See
|
|
959
|
+
[observed purchase prices](agents/observed-purchase-prices.md).
|
|
@@ -109,3 +109,14 @@ example A is tax-exclusive and example B is tax-inclusive. Both cover line and
|
|
|
109
109
|
document allocation; example B's document scope preserves line 3's allocated
|
|
110
110
|
GST cent. Focused sync tests inspect the exact public SDK request inputs and
|
|
111
111
|
persisted create descriptors without performing a provider network write.
|
|
112
|
+
|
|
113
|
+
## Compound tax configuration
|
|
114
|
+
|
|
115
|
+
`FrozenQuickBooksTaxMapping.lines[lineId].taxComponents` may retain the
|
|
116
|
+
caller-verified ordered realm TaxCode configuration as `{taxRateRef, compound}`
|
|
117
|
+
entries. Compound frozen lines require that exact sequence and their stored
|
|
118
|
+
`taxableMinor` bases. The mapper projects `compound` and `taxableAmount` into the
|
|
119
|
+
public accounting SDK without changing statutory percentages or declared taxes.
|
|
120
|
+
Missing/mismatched configuration fails explicitly. Hosts own tenant-scoped review
|
|
121
|
+
and provenance of the existing realm code's applicability/order; a taxCodeRef
|
|
122
|
+
string alone is insufficient evidence. Use the SDK release containing sdk#1412.
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Contract milestone billing (#4074)
|
|
2
|
+
|
|
3
|
+
Use the public Commerce `approveContractBillingSchedule`,
|
|
4
|
+
`issueContractMilestoneInvoice`, `getContractBillingSchedule` and
|
|
5
|
+
`allocateContractMilestones` exports for fixed-value milestone billing. These
|
|
6
|
+
commands own monetary capacity. The host owns construction scope, estimated cost,
|
|
7
|
+
approval permissions, signed evidence, regional policy and UI.
|
|
8
|
+
|
|
9
|
+
Start with an accepted, frozen customer `Order` or `Agreement`. The first schedule
|
|
10
|
+
requires `amendmentMinor: 0`, `expectedRevision: 0`, currency, explicit `basis:
|
|
11
|
+
'net' | 'gross'`, `approvalEvidenceRef`, `taxPolicyEvidenceRef` and exact milestone
|
|
12
|
+
`{ key, label, amountMinor }` entries. Their sum must equal the original Contract
|
|
13
|
+
subtotal for net basis or totalAmount for gross basis. There is no editable
|
|
14
|
+
schedule override of the accepted Contract value.
|
|
15
|
+
|
|
16
|
+
Each amendment supplies the current expected revision, a new request identity,
|
|
17
|
+
an explicit signed `amendmentMinor`, approval evidence and the complete next
|
|
18
|
+
schedule. Its ceiling is derived from the original frozen value plus all approved
|
|
19
|
+
amendments. Currency/basis cannot change. Already issued milestone keys, labels
|
|
20
|
+
and amounts must remain unchanged. Prior revisions and original Contract money
|
|
21
|
+
remain immutable. Unissued milestones can be rescheduled through an explicitly
|
|
22
|
+
approved revision. Net capacity is not a gross ceiling: each invoice's tax must
|
|
23
|
+
also be explicitly approved under the versioned policy.
|
|
24
|
+
|
|
25
|
+
`allocateContractMilestones(totalMinor, weights)` accepts positive integer
|
|
26
|
+
relative weights. All nonfinal shares truncate exact rational arithmetic; the
|
|
27
|
+
final entry receives the exact remainder. For example 100 with weights [1,1,1]
|
|
28
|
+
returns [33,33,34]. Zero amounts are allowed; negative/unsafe money and nonpositive
|
|
29
|
+
weights reject. The helper chooses no tax policy or commercial percentages.
|
|
30
|
+
|
|
31
|
+
Prepare a normal canonical draft Invoice and real line items through the public
|
|
32
|
+
Commerce collections. Draft preparation consumes no capacity; an unissued draft may be cancelled
|
|
33
|
+
without a claim. Then call:
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
const claim = await issueContractMilestoneInvoice({
|
|
37
|
+
db, tenantId, contractId, requestId: 'issue:start:v1',
|
|
38
|
+
revision: 1, milestoneKey: 'start', invoiceId,
|
|
39
|
+
approvedMoney: { netMinor: 4000, taxMinor: 200, grossMinor: 4200 },
|
|
40
|
+
invoiceApprovalEvidenceRef: 'approved-invoice:123',
|
|
41
|
+
});
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
The command checks same tenant/customer/currency/Contract, derives current line
|
|
45
|
+
money, verifies the exact approved net/tax/gross and schedule amount, freezes the
|
|
46
|
+
invoice and records the claim atomically. Tax-policy evidence is a host-owned
|
|
47
|
+
reviewed version reference, not an instruction to infer tax rates. Preserve the
|
|
48
|
+
approval's policy and original evidence in the host. Ordinary issue against a
|
|
49
|
+
scheduled Contract is refused, including direct creation in a non-draft state.
|
|
50
|
+
Existing issued contract invoices prevent adopting a schedule retroactively.
|
|
51
|
+
|
|
52
|
+
The explicit capacity policy is `issued-consumed`: cancellation, credits,
|
|
53
|
+
write-offs, payments, retention and refunds never reopen a claimed milestone.
|
|
54
|
+
Credits correct the canonical receivable and settlement continues through existing
|
|
55
|
+
Payment/PaymentAllocation facilities. Unapplied payments remain the deposit cash
|
|
56
|
+
authority. A replacement billing entitlement requires an explicit approved
|
|
57
|
+
amendment; this API does not infer that a credit authorizes re-billing. Applications
|
|
58
|
+
must explain that policy rather than present a hidden re-bill action. Issued
|
|
59
|
+
claims remain readable after later amendments and cancellations.
|
|
60
|
+
|
|
61
|
+
Every mutation requires the active tenant context and uses the tenant money
|
|
62
|
+
serialization barrier on the exact parent transaction executor. Identical request
|
|
63
|
+
replay returns the original evidence; a changed payload, stale revision or second
|
|
64
|
+
claim rejects. A parent rollback reverses both invoice issue and schedule claim.
|
|
65
|
+
A detached read DTO cannot modify persisted state. Ordinary Contract writes and
|
|
66
|
+
deletes cannot erase schedule history. Host authorization precedes these commands;
|
|
67
|
+
none is exposed as an unauthenticated generated mutation.
|
package/agents/contract-money.md
CHANGED
|
@@ -19,3 +19,84 @@ freeze just like other Contracts, but quote snapshots (including custom
|
|
|
19
19
|
descendants) are excluded by their hydrated STI subtype, not the mutable
|
|
20
20
|
`contractType` scalar, from report candidates and purchase tax facts. Awarding
|
|
21
21
|
requires a separate PurchaseOrder.
|
|
22
|
+
|
|
23
|
+
## Received supplier monetary evidence
|
|
24
|
+
|
|
25
|
+
`recordReceivedPurchaseMoney({ db, tenantId, contractId, requestId, evidenceRef,
|
|
26
|
+
facts, sourceQuote? })` records declared money on an existing empty draft
|
|
27
|
+
`SupplierQuote` or `PurchaseOrder`. Authorize the human in the host first and
|
|
28
|
+
call inside its active tenant context. The command locks tenant settings and
|
|
29
|
+
the document on its transaction executor; an outer transaction can include
|
|
30
|
+
creation of the quote/order. It returns a `ReceivedPurchaseMoneySnapshot`;
|
|
31
|
+
`getReceivedPurchaseMoney(contract)` returns that validated snapshot or `null`
|
|
32
|
+
for calculated documents. The public command is not an unguarded MCP action.
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
await recordReceivedPurchaseMoney({
|
|
36
|
+
db, tenantId, contractId: quote.id, requestId: 'received-revision-1',
|
|
37
|
+
evidenceRef: 'supplier-document:revision-1',
|
|
38
|
+
facts: {
|
|
39
|
+
currency: 'CAD', netMinor: 10000, taxMinor: 537, grossMinor: 10537,
|
|
40
|
+
taxComponents: null,
|
|
41
|
+
detail: { kind: 'header-only' },
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
// Reload after the command; stale instances cannot overwrite its authority.
|
|
45
|
+
const received = await contracts.get({ id: quote.id }, { cache: false });
|
|
46
|
+
received.status = ContractStatus.ACCEPTED;
|
|
47
|
+
await received.save();
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
This sets `moneyAuthority='received'`; aggregate headers retain exactly
|
|
51
|
+
10000/537/10537 without guessing a tax rate. The default `calculated` mode and
|
|
52
|
+
its line/tax-code calculator are unchanged. Received facts become immutable
|
|
53
|
+
when recorded. Exact retries return the original snapshot even after acceptance;
|
|
54
|
+
changed requests need a new document revision. Direct authority/evidence writes,
|
|
55
|
+
header edits, calculated lines, party/type changes and deleting received history
|
|
56
|
+
are rejected. Acceptance sets the normal `moneySnapshotId` without recalculating
|
|
57
|
+
source amounts. A stable application quote identity may reference a distinct
|
|
58
|
+
canonical `SupplierQuote` for each immutable revision.
|
|
59
|
+
|
|
60
|
+
`detail` must explicitly be `header-only` or `lines`. The latter supplies complete
|
|
61
|
+
source `netMinor`, `taxMinor`, `grossMinor` per uniquely keyed line with exact
|
|
62
|
+
aggregate reconciliation. Optional `quantityText`/`unitRateText` retain original
|
|
63
|
+
decimal text, never drive recomputation. When source lines are incomplete, retain
|
|
64
|
+
them in the referenced source evidence and use header-only monetary facts; do
|
|
65
|
+
not invent `ContractLineItem` quantities, tax lines, or allocations.
|
|
66
|
+
|
|
67
|
+
`taxComponents:null` means unknown decomposition. `[]` means known zero tax,
|
|
68
|
+
which requires `taxMinor:0`, but does not classify that zero as exempt/zero-rated.
|
|
69
|
+
Each supplied component retains its source key, label, amount, explicit
|
|
70
|
+
`classification` (`taxable`, `zero-rated`, `exempt`, `out-of-scope`, or `null`)
|
|
71
|
+
and `recoverableMinor` (including explicit zero or unknown `null`). Optional
|
|
72
|
+
`taxCodeId`, `taxComponentId` and `taxableMinor` remain unknown when omitted. Values are exact
|
|
73
|
+
safe nonnegative minor units; sums use integer arithmetic. No recoverability,
|
|
74
|
+
rate, taxable basis or classification is inferred from a label or amount.
|
|
75
|
+
|
|
76
|
+
An order can include
|
|
77
|
+
`sourceQuote:{contractId,relationship:'copy'|'negotiated'}`. The quote must be
|
|
78
|
+
accepted, frozen, received, and match tenant/vendor/currency. `copy` requires
|
|
79
|
+
identical facts. `negotiated` requires separately supplied approved monetary
|
|
80
|
+
facts and a separate evidence reference; it never prorates a quote. The command
|
|
81
|
+
records lineage but does not manufacture acceptance or financial approvals.
|
|
82
|
+
|
|
83
|
+
Received SupplierQuotes remain excluded from incurred purchase-tax reporting.
|
|
84
|
+
PurchaseOrders retain their existing report eligibility. For a received order,
|
|
85
|
+
public document report facts project explicit source amounts without creating
|
|
86
|
+
calculated `DocumentTax` rows or fictitious rates. Each report component must
|
|
87
|
+
have an explicit classification, tenant-owned tax code, taxable basis, recoverable amount and, for
|
|
88
|
+
`taxable`, a tenant-owned `taxComponentId`. Missing facts raise
|
|
89
|
+
`ReceivedPurchaseTaxClassificationRequired` with code
|
|
90
|
+
`RECEIVED_PURCHASE_TAX_CLASSIFICATION_REQUIRED` and the affected order ID. This
|
|
91
|
+
blocks only a report whose tenant/date/currency window includes that order;
|
|
92
|
+
recording, accepting and awarding unknown-classification evidence remains valid.
|
|
93
|
+
Existing calculated PO reporting is unchanged. Correct classification through an
|
|
94
|
+
explicit reviewed replacement revision and cancellation of the superseded
|
|
95
|
+
report-eligible order, preserving its history; never rewrite frozen evidence or
|
|
96
|
+
silently omit the unknown order from a report.
|
|
97
|
+
|
|
98
|
+
The two added Contract fields use the normal generated schema/migration flow;
|
|
99
|
+
apply the generated migration before using the new public command on an existing
|
|
100
|
+
database. Native SQLite/PostgreSQL acceptance is in
|
|
101
|
+
`received-purchase-money.test.ts` / `received-purchase-money.optional.test.ts`.
|
|
102
|
+
DuckDB retains the existing unsupported native Contract foreign-key boundary.
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Customer advances and unallocated cash
|
|
2
|
+
|
|
3
|
+
The public `recordCustomerFunds`, `allocateCustomerFunds`, `refundCustomerFunds`,
|
|
4
|
+
`reverseCustomerFundsAllocation` and `getCustomerFundsFacts` commands reuse
|
|
5
|
+
Payment, PaymentAllocation and smrt-ledgers journals. They do not create invoice
|
|
6
|
+
revenue, issue credit notes, transmit money to a bank or call a provider.
|
|
7
|
+
Applications authorize each command and supply human/source evidence.
|
|
8
|
+
|
|
9
|
+
A receipt requires an explicit immutable policy version:
|
|
10
|
+
|
|
11
|
+
- `mode`: `unapplied-ar` or `deposit-liability`.
|
|
12
|
+
- `taxTiming: 'invoice-tax-point'`: the caller has explicitly reviewed that tax
|
|
13
|
+
belongs on the eventual invoice. This is the only supported timing. The API
|
|
14
|
+
does not assume that every jurisdiction treats deposits as untaxed; other
|
|
15
|
+
timing policies are rejected and need a separate supported accounting model.
|
|
16
|
+
- `releaseEligibility`: `any-issued-invoice` or `final-invoice-only`.
|
|
17
|
+
- Distinct cash and receivables asset accounts, plus a liability account only
|
|
18
|
+
for liability mode. Every account must be active in the same tenant chart.
|
|
19
|
+
|
|
20
|
+
Ledgers currently has no separate Ledger entity or currency-restricted Account
|
|
21
|
+
field. The ledger boundary is its tenant-owned chart; currency is explicit on
|
|
22
|
+
this receipt and every journal entry. The legacy `RecordPaymentOptions.ledgerId`
|
|
23
|
+
is unused by existing Payment settlement. These commands neither pretend it
|
|
24
|
+
validates an independent ledger nor invent account metadata conventions.
|
|
25
|
+
|
|
26
|
+
| Operation | Unapplied AR | Deposit liability |
|
|
27
|
+
| --- | --- | --- |
|
|
28
|
+
| Receipt | DR cash / CR AR | DR cash / CR customer liability |
|
|
29
|
+
| Application | Existing settlement allocation | DR customer liability / CR AR |
|
|
30
|
+
| Unallocated refund | DR AR / CR cash | DR customer liability / CR cash |
|
|
31
|
+
| Application reversal | Reverse settlement allocation | DR AR / CR customer liability |
|
|
32
|
+
|
|
33
|
+
All amounts are positive safe integer minor units. Available capacity is exactly
|
|
34
|
+
`received - active applications - settled source-linked refunds`. A refund is a
|
|
35
|
+
positive outgoing Payment with immutable source-receipt lineage; it is not an
|
|
36
|
+
invoice credit refund. Reversal retains the original application and appends an
|
|
37
|
+
inverse operation and journal, removing only the active settlement row. An issued
|
|
38
|
+
invoice credit or credit refund blocks application reversal so previously spent
|
|
39
|
+
cash cannot become refundable a second time. Resolve that invoice correction
|
|
40
|
+
through its own authority first.
|
|
41
|
+
|
|
42
|
+
Each request carries `effectiveOn` (calendar date), `evidenceRef`, `actorId` and a
|
|
43
|
+
stable `requestId`. Effective dates are distinct from recording timestamps and
|
|
44
|
+
must be chronological within a receipt's movements. Receipt/refund `paidAt` and
|
|
45
|
+
journal dates use the explicitly supplied effective date. Exact replays return
|
|
46
|
+
current conserved facts; changing the request payload fails. Refund/application
|
|
47
|
+
races serialize on the tenant money boundary and receipt revision. Caller-owned
|
|
48
|
+
transactions include the payment, journals, allocation, status and audit evidence.
|
|
49
|
+
|
|
50
|
+
Application requires a matching issued invoice, customer, currency, optional
|
|
51
|
+
sales contract and actual `moneySnapshotId`. `release` also names the frozen
|
|
52
|
+
receipt policy version and the host's immutable invoice-approval evidence. Under
|
|
53
|
+
final-only policy, the host must verify and attest `kind: 'final-invoice'` from
|
|
54
|
+
that frozen approval. This is an application authorization responsibility, not a
|
|
55
|
+
user-supplied checkbox or inference from invoice numbering. The generic library
|
|
56
|
+
checks the attestation shape and exact canonical monetary snapshot; it does not
|
|
57
|
+
know construction milestone/finality rules.
|
|
58
|
+
|
|
59
|
+
`Payment.customerFundsJson` is command-owned. Ordinary saves, deletes,
|
|
60
|
+
PaymentAllocation create/update/delete, collection allocation helpers, payment
|
|
61
|
+
intent settlement and supplier payouts cannot repurpose managed advances or
|
|
62
|
+
bypass required journal entries. Managed refunds cannot be allocated to invoice
|
|
63
|
+
credits. `getUnallocatedFromPayment` subtracts managed refunds and requires the
|
|
64
|
+
persisted receipt amount. Direct SQL and administrative ledger mutations remain
|
|
65
|
+
outside this domain authority; facts refuse missing/voided journal evidence.
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
await withTenant({ tenantId }, async () => {
|
|
69
|
+
const received = await recordCustomerFunds({
|
|
70
|
+
db, tenantId, customerId, currency: 'CAD', amountMinor: 10000,
|
|
71
|
+
method: PaymentMethod.BANK_TRANSFER, requestId: receiptRequestId,
|
|
72
|
+
effectiveOn: '2026-10-01', evidenceRef: bankReceiptRef, actorId,
|
|
73
|
+
policy: {
|
|
74
|
+
version: reviewedPolicyVersion, mode: 'deposit-liability',
|
|
75
|
+
taxTiming: 'invoice-tax-point', releaseEligibility: 'final-invoice-only',
|
|
76
|
+
cashAccountId, receivablesAccountId, liabilityAccountId,
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
await allocateCustomerFunds({
|
|
80
|
+
db, tenantId, paymentId: received.paymentId, invoiceId, amountMinor: 8000,
|
|
81
|
+
requestId: applicationRequestId, effectiveOn: '2026-10-10',
|
|
82
|
+
evidenceRef: applicationEvidenceRef, actorId,
|
|
83
|
+
release: {
|
|
84
|
+
kind: 'final-invoice', invoiceSnapshotId,
|
|
85
|
+
approvalEvidenceRef: frozenFinalInvoiceApprovalRef,
|
|
86
|
+
policyVersion: reviewedPolicyVersion,
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Native `customer-funds.test.ts` and `customer-funds.optional.test.ts` prove exact
|
|
93
|
+
journals, both modes, direct-path protections, dates, finality evidence,
|
|
94
|
+
conservation, invoice-credit interaction, retries, caller rollback and a real
|
|
95
|
+
PostgreSQL post-journal write fault plus refund/application race. Run PostgreSQL
|
|
96
|
+
through the standard managed database wrapper; never use an application's schema.
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# Historical issued sales and original customer funds (#4081)
|
|
2
|
+
|
|
3
|
+
Historical intake is a separate source authority, not a new sale, send, or cash
|
|
4
|
+
posting. Hosts must authorize the reviewer/importer, preserve original evidence,
|
|
5
|
+
and call these public commands with the explicit active tenant. All writes use
|
|
6
|
+
one caller-affine transaction and the existing tenant money serialization lock.
|
|
7
|
+
|
|
8
|
+
`recordHistoricalSalesMoney({ db, tenantId, invoiceId, requestId, evidenceRef,
|
|
9
|
+
review, source, facts, creditedSource? })` adopts an empty draft Invoice. Supply
|
|
10
|
+
original integer minor-unit net/tax/gross, explicit signed-versus-magnitude
|
|
11
|
+
polarity, original issue calendar date/time zone, and a nullable unknown due date.
|
|
12
|
+
Normal calculated Invoice construction still defaults its due date as before.
|
|
13
|
+
Historical invoices expose `moneyAuthority: 'historical'` and a frozen source
|
|
14
|
+
snapshot. They create no InvoiceLineItems, fake quantities/rates, delivery event,
|
|
15
|
+
AR/revenue journal, or provider invoice.
|
|
16
|
+
|
|
17
|
+
A `detail: { kind: 'lines', lines }` source creates immutable
|
|
18
|
+
`HistoricalSalesLine` children. The returned `{ snapshot, lines }` binds every
|
|
19
|
+
source key to a concrete `lineId`; use these IDs for consumer crosswalks.
|
|
20
|
+
Unknown line tax, gross, quantity and rate remain null. Signed real adjustment
|
|
21
|
+
lines retain their source values. The line net sum and every fully known other
|
|
22
|
+
sum must exactly equal its corresponding original header.
|
|
23
|
+
|
|
24
|
+
Historical credits specify the exact original invoice/money snapshot and
|
|
25
|
+
optional concrete original child IDs. Independent net, tax and gross capacity
|
|
26
|
+
checks never prorate a header. `getHistoricalSalesMoney` and
|
|
27
|
+
`readHistoricalSalesLines` validate immutable retained authority.
|
|
28
|
+
`getInvoiceMoneyFacts` includes the historical source projection. Exact header
|
|
29
|
+
reports remain available through `listHistoricalSalesHeaderFacts` even when tax
|
|
30
|
+
classification is unknown. Breakdown-dependent tax reports require explicit
|
|
31
|
+
reviewed component identities, taxable and net bases and classification; they
|
|
32
|
+
never infer a percentage from the source amount or borrow today's rate.
|
|
33
|
+
|
|
34
|
+
Optional original `source.retention` records exact retained cents, an explicit
|
|
35
|
+
retained-first credit policy, source actors/evidence and original calendar-dated
|
|
36
|
+
releases. This contract represents retention configured at original issue; its
|
|
37
|
+
original effective date must equal the issue calendar date. A later retention
|
|
38
|
+
configuration requires its own supported source event contract. Derived retention
|
|
39
|
+
events retain actual `recordedAt` and separate
|
|
40
|
+
`effectiveOn`; as-of original cash eligibility uses the original dates. Ordinary
|
|
41
|
+
current retention configuration/release commands keep their existing behavior.
|
|
42
|
+
Original credit/release sequencing rejects a release whose retained-first
|
|
43
|
+
capacity was already consumed; same-day ordering must be explicitly reviewed.
|
|
44
|
+
Release payment terms remain the original invoice due date, including an
|
|
45
|
+
explicitly unknown date. No jurisdiction terms are invented.
|
|
46
|
+
|
|
47
|
+
`recordHistoricalCustomerFunds` retains original receipt/refund evidence and
|
|
48
|
+
explicit original deposit/release policy without creating a Payment or journal.
|
|
49
|
+
Original accounting ownership and journal references are evidence, not authority
|
|
50
|
+
to create duplicate original cash. Refunds identify either conserved unapplied
|
|
51
|
+
funds or one exact issued credit. Their headers immediately reserve refund
|
|
52
|
+
capacity, even before their original allocation row is imported.
|
|
53
|
+
|
|
54
|
+
`recordHistoricalCustomerAllocation` records exact source allocation identities.
|
|
55
|
+
Receipt applications affect the shared invoice paid balance once. Same-original
|
|
56
|
+
credit allocation rows and refund allocation rows audit their already-recorded
|
|
57
|
+
economic effects and do not reduce balances again. Cross-invoice transferable
|
|
58
|
+
credits are not represented by this contract. Same-day cash/credit chronology
|
|
59
|
+
requires explicit reviewed ordering; earlier original cash remains preserved
|
|
60
|
+
when a later credit creates owed/refundable overpayment. Original cash dates
|
|
61
|
+
remain separate from current balances and import timestamps.
|
|
62
|
+
|
|
63
|
+
`getHistoricalCustomerFundsPosition` returns exact received/allocated/refunded/
|
|
64
|
+
available minor units. `applyHistoricalCustomerFunds` and
|
|
65
|
+
`refundHistoricalCustomerFunds` perform NEW movements against remaining original
|
|
66
|
+
funds using explicit current active same-tenant accounts and the pinned original
|
|
67
|
+
policy terms. Applications use the existing liability-to-AR reclassification;
|
|
68
|
+
refunds use the existing journal-backed Payment command and retain the historical
|
|
69
|
+
receipt ID. Original receipts are never forged into completed Payments. Shared
|
|
70
|
+
live/historical paid/refund capacity prevents a second allocation or refund.
|
|
71
|
+
|
|
72
|
+
Stable source namespace/key identities replay exact facts across import runs
|
|
73
|
+
without replacing the original importer or evidence. Changed facts/policy or
|
|
74
|
+
source-version reuse conflicts. Ordinary/generated model writes and deletion
|
|
75
|
+
cannot mutate these immutable records. Provider synchronization and new revenue
|
|
76
|
+
recognition reject historical authority until an explicit supported historical
|
|
77
|
+
accounting representation is supplied; exact original money is still readable.
|
|
78
|
+
|
|
79
|
+
Focused evidence covers source/header immutability, concrete children, original
|
|
80
|
+
cash/credit/refund chronology, conservation, CAD journals for new movements,
|
|
81
|
+
caller rollback and isolated PostgreSQL execution. Consumer historical adapters
|
|
82
|
+
must still map every source table and prove full-cohort reconciliation; adopting
|
|
83
|
+
these public facts alone is not full reference-import acceptance.
|
|
84
|
+
|
|
85
|
+
Current explicitly dated retention releases append after the immutable original
|
|
86
|
+
release prefix. Both remain readable without changing original dates or source
|
|
87
|
+
authority; replay binds the explicit date and caller rollback restores the
|
|
88
|
+
complete release history. Provider releases retain their effective date in the
|
|
89
|
+
canonical retention history as well as provider evidence. Shared SQLite and
|
|
90
|
+
PostgreSQL retention suites verify reload, exact retry, original-prefix tamper
|
|
91
|
+
refusal, and transactional rollback.
|
|
92
|
+
|
|
93
|
+
Historical cash allocations are validated as dated payment prefixes, independent
|
|
94
|
+
of source import order. Backdated insertion rechecks later application dates;
|
|
95
|
+
ordinary public allocations retain their canonical allocatedAt chronology.
|
|
96
|
+
Same-day credit ordering remains explicit. Later credits alone do not
|
|
97
|
+
retroactively invalidate cash received before their issue date.
|
|
98
|
+
|
|
99
|
+
Current `releaseInvoiceRetention` commands retain optional `sameDayCreditOrder`
|
|
100
|
+
in their immutable evidence, alongside the effective calendar date. An exact
|
|
101
|
+
retry must preserve that ordering; changing or removing it is a changed request.
|
|
102
|
+
A later original credit import on the release date uses the retained ordering:
|
|
103
|
+
`release-before-credit` releases first, while `credit-before-release` applies
|
|
104
|
+
the retained-first credit before checking remaining release capacity. Missing
|
|
105
|
+
ordering remains ambiguous and is refused rather than inferred from record time.
|
|
106
|
+
### Bounded historical report scope
|
|
107
|
+
|
|
108
|
+
Historical header and tax reports apply the explicit tenant, historical money
|
|
109
|
+
authority, inclusive issue-date period, optional currency, and non-draft/non-cancelled
|
|
110
|
+
status predicates in the collection query before enforcing the 100,000-document
|
|
111
|
+
scope limit. Unrelated archived invoices do not consume a smaller report's limit;
|
|
112
|
+
more than 100,000 matching documents is refused rather than truncated.
|
|
113
|
+
|
|
114
|
+
Regression design (#4063, PR #4101 comment 4300513731):
|
|
115
|
+
|
|
116
|
+
| Invariant / trigger | Positive / refusal | Actor and executor | Runtime / evidence |
|
|
117
|
+
| --- | --- | --- | --- |
|
|
118
|
+
| Small matching period in a large tenant archive | Query-boundary fixture returns the single matching row only when all predicates precede the limit; matching scope above the cap still refuses | Explicit tenant and caller database; reads only | Focused Vitest; sparse overflow result avoids creating an archive |
|
|
119
|
+
| Native collection scope | Exact inclusive boundaries, optional currency, historical authority and tenant isolation; draft/cancelled excluded | Active tenant, native test database | Focused SQLite and isolated PostgreSQL public historical-money + report proof |
|
|
120
|
+
|
|
121
|
+
No persistence behavior changes; rollback/retry and external-provider edges are
|
|
122
|
+
not applicable to this read-only query correction. The coordinator owns broader
|
|
123
|
+
cohort validation and exact-head review under the resumed four-comment batch.
|
|
124
|
+
|
|
125
|
+
Evidence on Node26/pnpm11.25.0: the focused archive-query regression failed against
|
|
126
|
+
78f3ac856 (two failures, one pass), then passed after this query fix. The standard
|
|
127
|
+
`node scripts/run-with-ci-postgres.mjs -- pnpm --filter @happyvertical/smrt-commerce exec vitest run src/__tests__/historical-sales-report-scope.test.ts src/__tests__/historical-sales-report-scope-native.test.ts`
|
|
128
|
+
proof passed all five cases in9.80seconds, including actual SQLite and isolated
|
|
129
|
+
PostgreSQL scope/tenant checks. No100,000-row fixture, production writes or schema
|
|
130
|
+
changes were needed. Full logs remain external at the2026-10-16 MVP session's
|
|
131
|
+
`nonfinancial-import/scoped-sales-regression-base.log`, `scoped-sales-focused.log`
|
|
132
|
+
and `scoped-sales-postgres.log`. Native token usage was unavailable.
|
|
@@ -42,3 +42,39 @@ fraction. It takes no options. Its discount is signed minor units and passes
|
|
|
42
42
|
through unchanged, and its ties round half away from zero for negative
|
|
43
43
|
lines too. Editor magnitude normalization happens before constructing that
|
|
44
44
|
input. See [invoice line calculation](invoice-calculations.md).
|
|
45
|
+
|
|
46
|
+
## Ordered compound taxes
|
|
47
|
+
|
|
48
|
+
`TaxComponentInput.compound: true` uses every preceding component in the same
|
|
49
|
+
ordered tax code. Different applicable line/category subsets use different codes;
|
|
50
|
+
no missing predecessor is invented. Exclusive and explicit-net credit inputs use
|
|
51
|
+
prior rounded taxes at line scope or prior allocated taxes at document scope.
|
|
52
|
+
Shared components retain one rate. Contradictory dependency orders across codes
|
|
53
|
+
fail with `TAX_COMPONENT_DEPENDENCY_CYCLE`.
|
|
54
|
+
|
|
55
|
+
Inclusive extraction computes exact ordered rational factors, then rounds or
|
|
56
|
+
allocates the extracted component taxes. Net is the gross-minus-tax residual.
|
|
57
|
+
This is not a promise that an inclusive extraction reverses an exclusive rounded
|
|
58
|
+
calculation penny-for-penny. Signed reversals use the same symmetric rules.
|
|
59
|
+
|
|
60
|
+
Compound result components and frozen line snapshots carry `compound: true` and
|
|
61
|
+
`taxableMinor`. Component tax rows preserve this actual basis, with `netMinor`
|
|
62
|
+
separate so kind/revenue summaries do not include tax-on-tax as net revenue.
|
|
63
|
+
Historical additive snapshots omit these optional fields. Credits reconstruct the
|
|
64
|
+
frozen ordered components; a final credit consumes the remaining frozen bases and
|
|
65
|
+
taxes. The compatibility line `taxRate` is the observed effective tax/net ratio
|
|
66
|
+
for compound lines, not a flattened statutory rate; never use it to reconstruct
|
|
67
|
+
a document. Use component snapshots and canonical minor-unit totals.
|
|
68
|
+
|
|
69
|
+
`DocumentTax.netMinor` is a nullable generated-schema field. Additive records use
|
|
70
|
+
null and retain their previous reporting shape. Upgrade schemas before projecting
|
|
71
|
+
reports. Received purchase components may declare a taxable basis above net;
|
|
72
|
+
when that occurs their explicit `netMinor` is required for report classification.
|
|
73
|
+
Recording evidence remains allowed without that classification.
|
|
74
|
+
|
|
75
|
+
Compound accounting synchronization uses the public SDK ordered snapshot contract
|
|
76
|
+
([SDK #1412](https://github.com/happyvertical/sdk/issues/1412)). The mapper preserves
|
|
77
|
+
original rates, exact taxable bases and caller-verified realm TaxCode ordering.
|
|
78
|
+
Missing or mismatched reviewed mapping still raises `ACCOUNTING_SYNC_UNSUPPORTED`.
|
|
79
|
+
It never substitutes a flattened rate. Deployment requires the SDK release that
|
|
80
|
+
contains this public contract; the prior additive-only SDK cannot accept it.
|
package/agents/money-model.md
CHANGED
|
@@ -27,7 +27,7 @@ line-ID code-unit order breaking ties. It leaves no document residual. Across
|
|
|
27
27
|
`n` small lines, the two scopes can differ by up to `ceil(n / 2)` minor units
|
|
28
28
|
per component. Store the chosen scope; do not silently substitute a later
|
|
29
29
|
setting. `MoneyValidationError.code` is the public branch point for invalid
|
|
30
|
-
money, discounts, tax-code state and scope,
|
|
30
|
+
money, discounts, tax-code state and scope, contradictory compound dependencies, frozen
|
|
31
31
|
records, and unsafe values.
|
|
32
32
|
|
|
33
33
|
Tax-code resolution is pure once the caller has loaded authorized codes. It
|
|
@@ -105,5 +105,8 @@ mapper](accounting-snapshot-mapper.md).
|
|
|
105
105
|
Upgrading data written by an earlier version is documented in
|
|
106
106
|
[money data upgrade](money-upgrade.md). Contract money persistence remains a separate aggregate contract; production report
|
|
107
107
|
hosting is an application opt-in over the public host described above. The
|
|
108
|
-
model also does not provide currency conversion
|
|
109
|
-
partial recoverability
|
|
108
|
+
model also does not provide currency conversion or general cash-basis accounting,
|
|
109
|
+
partial recoverability or period locking. Ordered compound taxes are supported as
|
|
110
|
+
documented in [money calculator](money-calculator.md). Explicit invoice-tax-point
|
|
111
|
+
customer deposits and unallocated cash are provided by the separate
|
|
112
|
+
[customer-funds authority](customer-funds.md), not by invoice pricing.
|