@happyvertical/smrt-commerce 0.56.2 → 0.57.1
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 +24 -11
- package/README.md +137 -89
- package/agents/accounting-snapshot-mapper.md +3 -3
- package/agents/commercial-ui.md +2 -2
- package/agents/contract-money.md +9 -12
- package/agents/cost-billing.md +3 -6
- package/agents/customer-vendor-ui.md +1 -2
- package/agents/document-money.md +58 -31
- package/agents/invoice-calculations.md +31 -56
- package/agents/invoice-preparation.md +62 -73
- package/agents/invoice-quantity.md +9 -21
- package/agents/minor-unit-migration.md +4 -4
- package/agents/money-calculator.md +7 -8
- package/agents/money-model.md +18 -22
- package/agents/money-upgrade.md +92 -0
- package/agents/revenue-journal.md +2 -2
- package/agents/tax-codes.md +17 -14
- package/agents/tax-summary.md +8 -6
- package/dist/billing/period-close.d.ts.map +1 -1
- package/dist/billing/runtime.d.ts +5 -2
- package/dist/billing/runtime.d.ts.map +1 -1
- package/dist/chunks/{ContractLineItemCollection--BrGMtNz.js → ContractLineItemCollection-BZcrlrrY.js} +19 -24
- package/dist/chunks/ContractLineItemCollection-BZcrlrrY.js.map +1 -0
- package/dist/chunks/{CustomerCollection-CjGaZSpf.js → CustomerCollection-BIPH2ZUx.js} +2 -2
- package/dist/chunks/{CustomerCollection-CjGaZSpf.js.map → CustomerCollection-BIPH2ZUx.js.map} +1 -1
- package/dist/chunks/{DocumentTaxCollection-KOkaQT2M.js → DocumentTaxCollection-DDzlywMW.js} +14 -7
- package/dist/chunks/DocumentTaxCollection-DDzlywMW.js.map +1 -0
- package/dist/chunks/{InvoiceCollection-BUe_8FT1.js → InvoiceCollection-cinzAqt6.js} +50 -161
- package/dist/chunks/InvoiceCollection-cinzAqt6.js.map +1 -0
- package/dist/chunks/{TaxCodeCollection-DF2eaJed.js → TaxCodeCollection-DaBOPG9c.js} +11 -4
- package/dist/chunks/{TaxCodeCollection-DF2eaJed.js.map → TaxCodeCollection-DaBOPG9c.js.map} +1 -1
- package/dist/chunks/{TaxComponentCollection-3x24xSNh.js → TaxComponentCollection-C4zxnyVu.js} +3 -3
- package/dist/chunks/{TaxComponentCollection-3x24xSNh.js.map → TaxComponentCollection-C4zxnyVu.js.map} +1 -1
- package/dist/chunks/VendorCollection-D6ZcUYy8.js +100 -0
- package/dist/chunks/VendorCollection-D6ZcUYy8.js.map +1 -0
- package/dist/chunks/{allocation-integrity-Cq0g6CfO.js → allocation-integrity-WmWyXhtG.js} +6 -6
- package/dist/chunks/{allocation-integrity-Cq0g6CfO.js.map → allocation-integrity-WmWyXhtG.js.map} +1 -1
- package/dist/chunks/calculations-C9daQLsh.js +82 -0
- package/dist/chunks/calculations-C9daQLsh.js.map +1 -0
- package/dist/chunks/contract-money-EuToOghh.js +301 -0
- package/dist/chunks/contract-money-EuToOghh.js.map +1 -0
- package/dist/chunks/detect-CY9ufaFb.js +328 -0
- package/dist/chunks/detect-CY9ufaFb.js.map +1 -0
- package/dist/chunks/{document-money-oUDvdjOf.js → document-money-DV5t4vlK.js} +388 -62
- package/dist/chunks/document-money-DV5t4vlK.js.map +1 -0
- package/dist/chunks/{invoice-posting-CF3fE_Ec.js → invoice-posting-C2i5dOVZ.js} +20 -22
- package/dist/chunks/invoice-posting-C2i5dOVZ.js.map +1 -0
- package/dist/chunks/{revenue-journal-DY9fro8E.js → revenue-journal-LLA9Kh_i.js} +3 -14
- package/dist/chunks/revenue-journal-LLA9Kh_i.js.map +1 -0
- package/dist/chunks/tenant-money-barrier-6TlqUeVj.js +255 -0
- package/dist/chunks/tenant-money-barrier-6TlqUeVj.js.map +1 -0
- package/dist/chunks/types-Bbm0Xflc.js.map +1 -1
- package/dist/chunks/{units-CNcjH_eE.js → units-8ElbjVZK.js} +18 -3
- package/dist/chunks/units-8ElbjVZK.js.map +1 -0
- package/dist/collections/ContractCollection.d.ts.map +1 -1
- package/dist/collections/ContractLineItemCollection.d.ts.map +1 -1
- package/dist/collections/InvoiceCollection.d.ts.map +1 -1
- package/dist/collections/InvoiceLineItemCollection.d.ts +0 -30
- package/dist/collections/InvoiceLineItemCollection.d.ts.map +1 -1
- package/dist/collections/TaxCodeCollection.d.ts +5 -1
- package/dist/collections/TaxCodeCollection.d.ts.map +1 -1
- package/dist/collections/TaxSettingsCollection.d.ts +15 -8
- package/dist/collections/TaxSettingsCollection.d.ts.map +1 -1
- package/dist/collections/TaxSummaryReportCollection.d.ts +3 -3
- package/dist/collections/TaxSummaryReportCollection.d.ts.map +1 -1
- package/dist/collections/index.d.ts +0 -1
- package/dist/collections/index.d.ts.map +1 -1
- package/dist/commerce-money-tools.d.ts.map +1 -1
- package/dist/contract-money.d.ts +1 -13
- package/dist/contract-money.d.ts.map +1 -1
- package/dist/document-money-internal.d.ts +7 -3
- package/dist/document-money-internal.d.ts.map +1 -1
- package/dist/document-money.d.ts +1 -11
- package/dist/document-money.d.ts.map +1 -1
- package/dist/index.d.ts +6 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +667 -1650
- package/dist/index.js.map +1 -1
- package/dist/invoice-accounting-sync.d.ts.map +1 -1
- package/dist/invoice-mcp.d.ts +3 -3
- package/dist/invoice-mcp.d.ts.map +1 -1
- package/dist/invoice-posting.d.ts +11 -5
- package/dist/invoice-posting.d.ts.map +1 -1
- package/dist/invoice-record-screen.d.ts +1 -1
- package/dist/invoice-record-screen.d.ts.map +1 -1
- package/dist/invoices.d.ts +6 -1
- package/dist/invoices.d.ts.map +1 -1
- package/dist/invoices.js +2 -2
- package/dist/manifest.json +37 -765
- package/dist/migrations/invoiceEditorStorage.d.ts +2 -4
- package/dist/migrations/invoiceEditorStorage.d.ts.map +1 -1
- package/dist/models/Contract.d.ts.map +1 -1
- package/dist/models/ContractLineItem.d.ts +6 -22
- package/dist/models/ContractLineItem.d.ts.map +1 -1
- package/dist/models/Invoice.d.ts +18 -48
- package/dist/models/Invoice.d.ts.map +1 -1
- package/dist/models/InvoiceLineItem.d.ts +8 -37
- package/dist/models/InvoiceLineItem.d.ts.map +1 -1
- package/dist/models/TaxSettings.d.ts +0 -10
- package/dist/models/TaxSettings.d.ts.map +1 -1
- package/dist/models/index.d.ts +0 -1
- package/dist/models/index.d.ts.map +1 -1
- package/dist/playground.js +1 -1
- package/dist/playground.js.map +1 -1
- package/dist/recipes.d.ts +8 -11
- package/dist/recipes.d.ts.map +1 -1
- package/dist/revenue-journal.d.ts +0 -8
- package/dist/revenue-journal.d.ts.map +1 -1
- package/dist/smrt-knowledge.json +79 -661
- package/dist/svelte/components/InvoiceEditor.svelte +7 -148
- package/dist/svelte/components/InvoiceEditor.svelte.d.ts +4 -1
- package/dist/svelte/components/InvoiceEditor.svelte.d.ts.map +1 -1
- package/dist/svelte/components/InvoiceTotals.svelte +14 -118
- package/dist/svelte/components/InvoiceTotals.svelte.d.ts +4 -27
- package/dist/svelte/components/InvoiceTotals.svelte.d.ts.map +1 -1
- package/dist/svelte/components/MoneyInvoiceEditor.svelte +3 -23
- package/dist/svelte/components/MoneyInvoiceEditor.svelte.d.ts +3 -26
- package/dist/svelte/components/MoneyInvoiceEditor.svelte.d.ts.map +1 -1
- package/dist/svelte/index.d.ts +2 -3
- package/dist/svelte/index.d.ts.map +1 -1
- package/dist/svelte/index.js +1 -2
- package/dist/svelte/invoices/calculations.d.ts +3 -108
- package/dist/svelte/invoices/calculations.d.ts.map +1 -1
- package/dist/svelte/invoices/calculations.js +12 -309
- package/dist/svelte/invoices/messages.d.ts +1 -37
- package/dist/svelte/invoices/messages.d.ts.map +1 -1
- package/dist/svelte/invoices/messages.js +1 -37
- package/dist/svelte/invoices/money-editor.d.ts +1 -1
- package/dist/svelte/invoices/money-editor.d.ts.map +1 -1
- package/dist/svelte/invoices/types.d.ts +14 -114
- package/dist/svelte/invoices/types.d.ts.map +1 -1
- package/dist/svelte/playground/InvoicePreparationPreview.svelte +85 -94
- package/dist/svelte/playground/InvoicePreparationPreview.svelte.d.ts.map +1 -1
- package/dist/svelte/playground.js +1 -1
- package/dist/tax/index.d.ts +2 -1
- package/dist/tax/index.d.ts.map +1 -1
- package/dist/tax/standard-codes.d.ts +12 -0
- package/dist/tax/standard-codes.d.ts.map +1 -0
- package/dist/tax/tenant-bootstrap.d.ts +29 -0
- package/dist/tax/tenant-bootstrap.d.ts.map +1 -0
- package/dist/tenant-money-barrier.d.ts +12 -44
- package/dist/tenant-money-barrier.d.ts.map +1 -1
- package/dist/types/index.d.ts +10 -23
- package/dist/types/index.d.ts.map +1 -1
- package/dist/ui.js +1 -1
- package/dist/ui.js.map +1 -1
- package/dist/upgrade/detect.d.ts +129 -0
- package/dist/upgrade/detect.d.ts.map +1 -0
- package/dist/upgrade/money-v2.d.ts +81 -0
- package/dist/upgrade/money-v2.d.ts.map +1 -0
- package/package.json +14 -13
- package/agents/line-amount-migration.md +0 -50
- package/dist/chunks/ContractLineItemCollection--BrGMtNz.js.map +0 -1
- package/dist/chunks/DocumentTaxCollection-KOkaQT2M.js.map +0 -1
- package/dist/chunks/InvoiceCollection-BUe_8FT1.js.map +0 -1
- package/dist/chunks/InvoiceLineItemCollection-CPQGghyd.js +0 -468
- package/dist/chunks/InvoiceLineItemCollection-CPQGghyd.js.map +0 -1
- package/dist/chunks/TaxSettingsCollection-DYYF-In-.js +0 -319
- package/dist/chunks/TaxSettingsCollection-DYYF-In-.js.map +0 -1
- package/dist/chunks/calculations-DaHR17il.js +0 -333
- package/dist/chunks/calculations-DaHR17il.js.map +0 -1
- package/dist/chunks/document-money-oUDvdjOf.js.map +0 -1
- package/dist/chunks/invoice-posting-CF3fE_Ec.js.map +0 -1
- package/dist/chunks/revenue-journal-DY9fro8E.js.map +0 -1
- package/dist/chunks/tenant-money-barrier-y6EAa6vY.js +0 -135
- package/dist/chunks/tenant-money-barrier-y6EAa6vY.js.map +0 -1
- package/dist/chunks/units-CNcjH_eE.js.map +0 -1
- package/dist/collections/MoneyMigrationDocumentCollection.d.ts +0 -12
- package/dist/collections/MoneyMigrationDocumentCollection.d.ts.map +0 -1
- package/dist/migrations/commerceLineAmounts.d.ts +0 -84
- package/dist/migrations/commerceLineAmounts.d.ts.map +0 -1
- package/dist/models/MoneyMigrationDocument.d.ts +0 -28
- package/dist/models/MoneyMigrationDocument.d.ts.map +0 -1
- package/dist/svelte/components/InvoiceLineEditor.svelte +0 -92
- package/dist/svelte/components/InvoiceLineEditor.svelte.d.ts +0 -8
- package/dist/svelte/components/InvoiceLineEditor.svelte.d.ts.map +0 -1
- package/dist/svelte/invoices/fields.d.ts +0 -6
- package/dist/svelte/invoices/fields.d.ts.map +0 -1
- package/dist/svelte/invoices/fields.js +0 -22
- package/dist/tax/legacy.d.ts +0 -48
- package/dist/tax/legacy.d.ts.map +0 -1
|
@@ -1,56 +1,31 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
`@happyvertical/smrt-commerce/invoices` is a Svelte-free entry
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
`calculateInvoiceDraft(values, { roundingScope: 'invoice' })` and the shared
|
|
33
|
-
`InvoiceEditor` / `InvoiceLineEditor` `roundingScope` prop accept `line` or
|
|
34
|
-
`invoice`. Omission preserves per-line rounding. The server chooses this option
|
|
35
|
-
from its authorized policy, and supplies it again when rendering rejected forms
|
|
36
|
-
or reopening retained drafts; it is not a client authority field.
|
|
37
|
-
|
|
38
|
-
Invoice scope groups numerically equal effective percentages, including textual
|
|
39
|
-
variants such as `5` and `5.000000`, and rounds each rate group once through
|
|
40
|
-
`calculateCostBillingTax`. Different rates remain independent components; explicit
|
|
41
|
-
zero overrides remain exempt. Quantity and discount rounding are unchanged. Two
|
|
42
|
-
10-minor lines at 5% therefore have tax 1 in invoice scope and 2 in line scope.
|
|
43
|
-
This is an additive single-rate-per-line editor, not a tax determination or
|
|
44
|
-
compound-tax solver. Invalid scope is a validation error. Drafts still reject
|
|
45
|
-
negative quantities/prices; the signed model calculator is unchanged.
|
|
46
|
-
|
|
47
|
-
`lineResults` and `resolveInvoiceLineDraft` remain standalone per-line
|
|
48
|
-
calculations, useful for validation and existing line-mode model storage. They
|
|
49
|
-
are **not allocations** of invoice-rounded tax: their tax/total fields may not
|
|
50
|
-
sum to the aggregate. In invoice mode the UI displays each line's subtotal and
|
|
51
|
-
an explanation, with tax and total shown only at invoice level. Persist the
|
|
52
|
-
aggregate with the authorized scope and retained draft when using invoice
|
|
53
|
-
rounding; do not reconstruct it by summing standalone resolved line totals.
|
|
54
|
-
No persistence schema or `InvoiceLineItem` tax behavior is changed by this
|
|
55
|
-
legacy-compatible adapter API. V2 persistence and issued tax snapshots are
|
|
56
|
-
defined by the [commercial money model](money-model.md).
|
|
1
|
+
# Invoice line calculation helper
|
|
2
|
+
|
|
3
|
+
`@happyvertical/smrt-commerce/invoices` is a Svelte-free entry for server
|
|
4
|
+
handlers and browsers. It exports `calculateInvoiceMinorLine`,
|
|
5
|
+
`MoneyValidationError` and the `MoneyValidationCode` type.
|
|
6
|
+
|
|
7
|
+
Document arithmetic, tax-code resolution, persisted tax components and issued
|
|
8
|
+
snapshots belong to the [commercial money model](money-model.md) and the
|
|
9
|
+
[money calculator](money-calculator.md). The invoice editor previews with
|
|
10
|
+
`calculateMoneyEditorDraft`; see [the invoice editor](invoice-preparation.md).
|
|
11
|
+
|
|
12
|
+
`calculateInvoiceMinorLine({ quantity, unitPrice, discount, taxRate })`
|
|
13
|
+
calculates one stored line in integer minor units, independent of currency. It
|
|
14
|
+
returns `grossMinor`, `discountMinor`, `subtotalMinor`, `taxMinor` and
|
|
15
|
+
`totalMinor`, and it runs the same money calculator the documents use:
|
|
16
|
+
|
|
17
|
+
- `quantity` is nonnegative, with at most six fractional digits;
|
|
18
|
+
- `unitPrice` is a signed safe integer, so credit lines may be negative;
|
|
19
|
+
- `discount` is a flat signed safe integer that carries the gross sign;
|
|
20
|
+
- `taxRate` is an already-resolved fraction in [0, 1], with at most eight
|
|
21
|
+
fractional digits. It is an input to this helper only; it never determines
|
|
22
|
+
tax on a stored invoice line, whose tax comes from its tax codes.
|
|
23
|
+
|
|
24
|
+
Rounding follows the money calculator, so a negative credit line rounds
|
|
25
|
+
symmetrically with its positive counterpart. Numeric quantities and rates use
|
|
26
|
+
their canonical decimal form, including exponent notation, and never a
|
|
27
|
+
`toFixed` expansion. Invalid quantities or rates, fractional or unsafe money,
|
|
28
|
+
and a discount with the wrong sign throw `RangeError` before persistence.
|
|
29
|
+
|
|
30
|
+
The [invoice quantity migration](invoice-quantity.md) uses this helper to
|
|
31
|
+
check that every stored quantity round-trips exactly.
|
|
@@ -1,86 +1,75 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Invoice editor and allocation fields
|
|
2
2
|
|
|
3
|
-
Import `InvoiceEditor`, `
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
Import `InvoiceEditor`, `InvoiceAllocationFields`, `InvoiceReview` and their
|
|
4
|
+
Props types from `@happyvertical/smrt-commerce/svelte`. `InvoiceEditor` is the
|
|
5
|
+
invoice form. It renders `MoneyInvoiceEditor` (also exported) and uses the
|
|
6
|
+
commercial money model, the only invoice money model. Line tax
|
|
7
|
+
comes from tax codes, never from a typed rate. See the
|
|
8
|
+
[commercial money model](money-model.md) and the
|
|
9
|
+
[money calculator](money-calculator.md).
|
|
8
10
|
|
|
9
|
-
`
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
Unit price and flat discount are currency-unit text; percentage values use `5`
|
|
14
|
-
for five percent. `discountType` is `flat` or `percent`; `taxMode` is `inherit` or
|
|
15
|
-
`override`. Explicit override `0` means zero tax; it never means inherit. Unknown
|
|
16
|
-
modes remain representable for rejected submissions. Dates remain text so invalid
|
|
17
|
-
values survive action failures. Customer options are caller-authorized projections;
|
|
18
|
-
unknown retained IDs remain visible. Currency uses the shared CurrencySelect.
|
|
11
|
+
`InvoiceEditorProps` requires `action` and `money: MoneyEditorProps`. Optional
|
|
12
|
+
props are `method` (default `post`), `canEdit`, `pending`, `hiddenFields`,
|
|
13
|
+
`intentField` (default `intent`), `saveIntent` (default `save`), `saveLabel`
|
|
14
|
+
and `onsubmit`. `money` carries:
|
|
19
15
|
|
|
20
|
-
|
|
16
|
+
- `mode: 'v2'` (a fixed discriminator);
|
|
17
|
+
- `draft`: currency, `lineAmountType` (`exclusive`, `inclusive` or `none`),
|
|
18
|
+
`roundingScope` (`line` or `document`) and ordered `lines`;
|
|
19
|
+
- `taxCodes`: the authorized tax-code choices, each with its components;
|
|
20
|
+
- optionally `frozen`, `status`, `kind` (`invoice` or `credit_note`), `stored`,
|
|
21
|
+
`onCreateCreditNote`, `customerTaxExempt`, `sellerTaxRegistrations`,
|
|
22
|
+
`partyTaxId`, `showNetSubtotal` and `names`.
|
|
21
23
|
|
|
22
|
-
`
|
|
23
|
-
|
|
24
|
-
the
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
`
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
drafts show an unavailable-total message rather than plausible numbers. The
|
|
31
|
-
calculator uses Commerce's explicit exponent table and its existing two-digit
|
|
32
|
-
fallback for other uppercase three-letter codes; the server must authorize its
|
|
33
|
-
supported currencies. Calculated values are never submitted as authority.
|
|
34
|
-
The server revalidates customer/SKU, prices, quantity, discounts, tax policy,
|
|
35
|
-
permissions and calculated totals. Header taxRate is a draft preview default,
|
|
36
|
-
not a new persisted Invoice tax field; replace it with authorized tax context
|
|
37
|
-
on the server. Client edits never establish approval or allocate inventory.
|
|
24
|
+
Each `MoneyEditorLineDraft` holds id, description, quantity, unitPrice,
|
|
25
|
+
`discountType` (`none`, `percent` or `amount`), discountValue (a nonnegative
|
|
26
|
+
magnitude; the calculator applies the line sign), `taxMode` (`inherit` or
|
|
27
|
+
`override`), `taxCodeId`, and the resolver's `inheritedTaxCodeId` and
|
|
28
|
+
`inheritedTaxCodeSource` (`product`, `customer`, `app`, `exempt-customer` or
|
|
29
|
+
`none`). Values are lossless strings, so input the server rejected comes back
|
|
30
|
+
unchanged. Choosing a tax code sets `taxMode` to `override`. Clearing it goes
|
|
31
|
+
back to the inherited code, and the editor shows that code's source.
|
|
38
32
|
|
|
39
33
|
```svelte
|
|
40
|
-
<InvoiceEditor action="?/save"
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
hiddenFields={[{ name: 'requestId', value: form?.requestId ?? data.requestId }]}>
|
|
44
|
-
{#snippet children(current)}
|
|
45
|
-
<InvoiceAllocationFields currency={current.currency}
|
|
46
|
-
allocations={form?.allocations ?? data.allocations}
|
|
47
|
-
sources={data.authorizedSources} mayReadSources={data.mayReadSources}
|
|
48
|
-
canEdit={data.mayEdit} />
|
|
49
|
-
{/snippet}
|
|
50
|
-
</InvoiceEditor>
|
|
34
|
+
<InvoiceEditor action="?/save" money={form?.money ?? data.money}
|
|
35
|
+
canEdit={data.mayEdit}
|
|
36
|
+
hiddenFields={[{ name: 'requestId', value: form?.requestId ?? data.requestId }]} />
|
|
51
37
|
```
|
|
52
38
|
|
|
53
|
-
Native
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
39
|
+
Native field names default to `lineAmountType`, `roundingScope`, then repeated
|
|
40
|
+
`lineId`, `lineDescription`, `lineQuantity`, `lineUnitPrice`,
|
|
41
|
+
`lineDiscountType`, `lineDiscountValue`, `lineTaxMode` and `lineTaxCodeId`, in
|
|
42
|
+
displayed order. Use `money.names` to rename them. `moneyEditorFieldNames`
|
|
43
|
+
exports the defaults, and `moneyEditorSubmission(draft)` returns the typed
|
|
44
|
+
shape those controls represent. Hidden fields are submitted exactly as given,
|
|
45
|
+
including repeated names. The default transport is a native POST, which also
|
|
46
|
+
works without JavaScript. `onsubmit` can enhance it.
|
|
47
|
+
|
|
48
|
+
`calculateMoneyEditorDraft(draft, taxCodes)` is the editor's only calculation:
|
|
49
|
+
the pure money calculator, run on the retained text. The preview gives no
|
|
50
|
+
authority. The server resolves tax codes (line override, else product, else
|
|
51
|
+
customer, else the tenant default), recomputes `taxAmount` and the totals, and
|
|
52
|
+
ignores any client total. Invalid input shows the calculator's message instead
|
|
53
|
+
of a total.
|
|
59
54
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
request identity simply because the user added a line. The default transport
|
|
66
|
-
is native POST, including without JavaScript. With JavaScript, input changes
|
|
67
|
-
update exact previews without mutating the supplied values object. `onsubmit`
|
|
68
|
-
may enhance transport; caller-owned retryStatus/pending controls submission.
|
|
55
|
+
A frozen document (`frozen: true`) renders only `stored`, the server's issued
|
|
56
|
+
snapshot. It never recalculates and disables every field. If `stored` is
|
|
57
|
+
missing, the editor reports that. A frozen invoice shows a credit-note action,
|
|
58
|
+
enabled only when the host supplies `onCreateCreditNote`. A credit note never
|
|
59
|
+
offers one.
|
|
69
60
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
61
|
+
`InvoiceAllocationFields` renders source-allocation rows without a form of its
|
|
62
|
+
own; put it in a caller-owned native form. Each row has key, sourceId, a
|
|
63
|
+
currency-unit amount, optional remove, and field errors.
|
|
64
|
+
`mayReadSources=false` hides supplied labels and balances and renders
|
|
65
|
+
references instead. Unavailable sources that were retained stay postable, so
|
|
66
|
+
the server can reconcile them. Native names stay sourceId, allocationAmount
|
|
67
|
+
and the checked zero-based removeRow. `fields` renames them, and `addIntent`
|
|
68
|
+
defaults to `addAllocation`. Availability, reservations, budget policy and
|
|
69
|
+
approval belong to the caller and server.
|
|
78
70
|
|
|
79
|
-
`
|
|
80
|
-
|
|
81
|
-
uncertain actions, return every original string, stable row key, errors and
|
|
82
|
-
caller request/tenant/fingerprint identity. No component generates request keys.
|
|
71
|
+
`InvoiceReview` presents a review snapshot that the caller supplies. Edits
|
|
72
|
+
never infer a status change. No component generates request keys.
|
|
83
73
|
|
|
84
74
|
Focused validation: Commerce `vitest.invoices.config.ts`,
|
|
85
|
-
`e2e/invoices/playwright.config.ts`, `typecheck
|
|
86
|
-
release gates and calculator/model checks remain separate owning validations.
|
|
75
|
+
`e2e/invoices/playwright.config.ts`, `typecheck` and `build`.
|
|
@@ -1,22 +1,11 @@
|
|
|
1
|
-
# Invoice quantity persistence
|
|
1
|
+
# Invoice quantity persistence
|
|
2
2
|
|
|
3
3
|
InvoiceLineItem accepts nonnegative decimal quantities with at most six decimal
|
|
4
4
|
places. The `1.0` default declares a floating-point quantity column. Unit price,
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
credit lines). Tax is a resolved fraction in [0, 1], with eight decimal places.
|
|
10
|
-
Accounting export retains an explicit zero rate instead of omitting it.
|
|
11
|
-
|
|
12
|
-
`applyEditorDraft(draft, authorizedContext)` resolves the shared invoice draft
|
|
13
|
-
helper into description/SKU/quantity/price/flat discount/tax and stores cloned
|
|
14
|
-
`invoiceEditorStateJson` TEXT, accessed through a guarded typed `invoiceEditorState` getter/setter. It does not save.
|
|
15
|
-
`getEditorDraft(authorizedContext)` returns a clone only when currency, inherited
|
|
16
|
-
tax authority, and all source fields still agree. Otherwise it returns null so the
|
|
17
|
-
caller can reconstruct a flat-discount/explicit-tax editor from resolved fields.
|
|
18
|
-
Normal save clears stale editor state and never derives money from metadata.
|
|
19
|
-
All other object metadata, authorization, and transaction ownership are unchanged.
|
|
5
|
+
discount and amount stay safe integer minor units. Every save goes through the
|
|
6
|
+
invoice money aggregate, which recomputes the line and ignores
|
|
7
|
+
any supplied amount. Tax comes from the line's resolved tax code, never from a
|
|
8
|
+
stored rate. See the [commercial money model](money-model.md).
|
|
20
9
|
|
|
21
10
|
## Existing integer columns
|
|
22
11
|
|
|
@@ -34,11 +23,10 @@ SQLite uses the public core table-rebuild planner to change the declaration to
|
|
|
34
23
|
REAL while preserving existing columns, constraints, indexes, and triggers. If
|
|
35
24
|
incoming foreign keys make that rebuild unsafe, the migration throws with the
|
|
36
25
|
planner reason and rolls back; it does not disable constraints or lose children.
|
|
37
|
-
Resolve that maintenance condition before deploying fractional writers. The
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
No schema mutation runs implicitly during runtime initialization or model save.
|
|
26
|
+
Resolve that maintenance condition before deploying fractional writers. The
|
|
27
|
+
migration no longer adds an editor-state column. An `invoice_editor_state_json`
|
|
28
|
+
column that an earlier version added is left in place and unused. No schema
|
|
29
|
+
mutation runs implicitly during runtime initialization or model save.
|
|
42
30
|
|
|
43
31
|
The actual DuckDB quantity/storage migration is tested. Complete Commerce model
|
|
44
32
|
persistence on DuckDB is currently unsupported because its hard foreign keys use
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Major-unit to minor-unit migration
|
|
2
2
|
|
|
3
|
-
This guide covers the
|
|
4
|
-
|
|
5
|
-
calculate tax, create snapshots
|
|
3
|
+
This guide covers the numeric-column rescale only. It is not the
|
|
4
|
+
[money data upgrade](money-upgrade.md): it does not change `TaxSettings`,
|
|
5
|
+
calculate tax, or create snapshots.
|
|
6
6
|
|
|
7
7
|
`preflightCommerceMoneyMinorUnits(db)` reports whether known commerce columns
|
|
8
8
|
still contain major units, rows that would round, and values outside JavaScript
|
|
@@ -35,11 +35,10 @@ codes include `TAX_CODE_DUPLICATE_COMPONENT`,
|
|
|
35
35
|
shared input, discount, percent, compound, state, scope, safety, freeze, and
|
|
36
36
|
currency codes exported as `MoneyValidationCode`.
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
before constructing that stored input.
|
|
38
|
+
`calculateInvoiceMinorLine(input)` in `src/svelte/invoices/calculations.ts`
|
|
39
|
+
(also exported from `@happyvertical/smrt-commerce/invoices`) runs one line
|
|
40
|
+
through this calculator with a single-component code built from its resolved
|
|
41
|
+
fraction. It takes no options. Its discount is signed minor units and passes
|
|
42
|
+
through unchanged, and its ties round half away from zero for negative
|
|
43
|
+
lines too. Editor magnitude normalization happens before constructing that
|
|
44
|
+
input. See [invoice line calculation](invoice-calculations.md).
|
package/agents/money-model.md
CHANGED
|
@@ -5,9 +5,9 @@ shapes, validation codes, and worked calculator examples live in the
|
|
|
5
5
|
[calculator guide](money-calculator.md) and
|
|
6
6
|
[package documentation](../../../docs/content/commerce-money.md). Money values
|
|
7
7
|
are signed safe-integer minor units; calculator tax percentages are exact text,
|
|
8
|
-
so `'5'` means 5%. The
|
|
9
|
-
`ContractLineItem.taxRate` fields are
|
|
10
|
-
`0.05` means 5
|
|
8
|
+
so `'5'` means 5%. The `InvoiceLineItem.taxRate` and
|
|
9
|
+
`ContractLineItem.taxRate` fields are server-derived fractions of the resolved
|
|
10
|
+
components (`0.05` means 5%); they are never tax inputs.
|
|
11
11
|
|
|
12
12
|
## Calculation contract
|
|
13
13
|
|
|
@@ -39,10 +39,10 @@ catalogue, seeds, registrations, and cookbook boundary are documented in
|
|
|
39
39
|
|
|
40
40
|
## Stored Invoice facts
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
42
|
+
There is one money model. Saving a draft resolves its current tax settings
|
|
43
|
+
once and atomically writes the header, line snapshots, and `DocumentTax` rows.
|
|
44
|
+
Every money document needs a tenant, and data written by an earlier version is
|
|
45
|
+
refused until it is upgraded ([money data upgrade](money-upgrade.md)). The detailed persistence, freeze, preview, credit-note, and
|
|
46
46
|
refund contracts are in [document money](document-money.md).
|
|
47
47
|
|
|
48
48
|
Once an Invoice leaves `DRAFT`, or receives an AR journal, its money snapshot
|
|
@@ -55,7 +55,7 @@ not invent a taxable component.
|
|
|
55
55
|
|
|
56
56
|
A credit note is an `Invoice` with `kind: 'credit_note'`. It stores positive
|
|
57
57
|
amounts; posting, reporting, and accounting adapters apply that direction once.
|
|
58
|
-
Issued-credit capacity and refunds are stable Invoice
|
|
58
|
+
Issued-credit capacity and refunds are stable Invoice behavior. A refund is
|
|
59
59
|
a positive `Payment` of kind `refund`, allocated only to a credit note. See
|
|
60
60
|
[document money](document-money.md) before presenting either balance as an
|
|
61
61
|
ordinary incoming payment.
|
|
@@ -63,15 +63,13 @@ ordinary incoming payment.
|
|
|
63
63
|
## Invoice MCP `get` projection
|
|
64
64
|
|
|
65
65
|
The standard Invoice MCP `get` tool uses `serializeInvoiceMcpGet`. For a
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
`FROZEN_DOCUMENT` code and the public message `Tenant money migration is in
|
|
74
|
-
progress`. If the caller's `PublicJsonOptions` hide any Invoice,
|
|
66
|
+
tenant invoice, the optional `money` value is the stored `InvoiceMoneyFacts`
|
|
67
|
+
projection: its header, line snapshots, and `DocumentTax` facts are read from
|
|
68
|
+
the stored snapshot and are never recalculated. An invoice without an id or
|
|
69
|
+
tenant returns the ordinary public Invoice projection.
|
|
70
|
+
|
|
71
|
+
A tenant whose data needs the upgrade refuses this read with
|
|
72
|
+
`COMMERCE_DATA_NEEDS_UPGRADE`. If the caller's `PublicJsonOptions` hide any Invoice,
|
|
75
73
|
`InvoiceLineItem`, or `DocumentTax` field needed by the money projection, the
|
|
76
74
|
serializer returns the base Invoice and omits the entire `money` alias. It does
|
|
77
75
|
not expose restricted values through a partial plain-object alias.
|
|
@@ -84,7 +82,7 @@ serializers](../../core/agents/generators.md#mcp-get-serializers).
|
|
|
84
82
|
## Reporting and integrations
|
|
85
83
|
|
|
86
84
|
The materialized `TaxSummaryReport` and its public descriptor/drilldown bridge
|
|
87
|
-
read stored Invoice `DocumentTax` facts under the tenant
|
|
85
|
+
read stored Invoice `DocumentTax` facts under the tenant money lock. See
|
|
88
86
|
[tax summary aggregation](tax-summary.md). Commerce exports
|
|
89
87
|
`createTaxSummaryMaterializedReportHost()` for an application-owned,
|
|
90
88
|
server-only host; register that host in the app's fixed report-host registry to
|
|
@@ -104,10 +102,8 @@ mapper](accounting-snapshot-mapper.md).
|
|
|
104
102
|
|
|
105
103
|
## Deliberate boundaries
|
|
106
104
|
|
|
107
|
-
|
|
108
|
-
[
|
|
109
|
-
The marker is a maintenance gate, not a customer-controlled setting. Contract
|
|
110
|
-
money persistence remains a separate aggregate contract; production report
|
|
105
|
+
Upgrading data written by an earlier version is documented in
|
|
106
|
+
[money data upgrade](money-upgrade.md). Contract money persistence remains a separate aggregate contract; production report
|
|
111
107
|
hosting is an application opt-in over the public host described above. The
|
|
112
108
|
model also does not provide currency conversion, cash-basis/deposit accounting,
|
|
113
109
|
partial recoverability, period locking, or compound tax.
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Money data upgrade
|
|
2
|
+
|
|
3
|
+
Commerce has one money model. It does not read money data written by an
|
|
4
|
+
earlier version, and it does not convert that data on the fly. It refuses it
|
|
5
|
+
and names the upgrade command. The operator steps are in the CLI guide,
|
|
6
|
+
[commerce money upgrade command](../../cli/agents/commerce-money-upgrade.md).
|
|
7
|
+
|
|
8
|
+
## Detection
|
|
9
|
+
|
|
10
|
+
`src/upgrade/detect.ts` owns detection. Four shapes count as old data:
|
|
11
|
+
|
|
12
|
+
- **Old schema.** The database still has `tax_settings.money_model`,
|
|
13
|
+
`tax_settings.money_migration_id`, `*_line_items.legacy_amount`, or the
|
|
14
|
+
`commerce_money_migration_documents` table. This refuses the whole database.
|
|
15
|
+
- **Documents without a tenant.** An Invoice or Contract row, header or line,
|
|
16
|
+
with no tenant. The current model writes none, and the upgrade cannot convert
|
|
17
|
+
one: assign it to a tenant or delete it. This refuses the whole database and
|
|
18
|
+
keeps the old schema in place until it is resolved.
|
|
19
|
+
- **Tenant without settings.** A tenant has Invoice or Contract rows but no
|
|
20
|
+
`tax_settings` row. This refuses that tenant only.
|
|
21
|
+
- **Old-format documents.** An issued Invoice or Contract without a money
|
|
22
|
+
snapshot, or a line with neither a tax code nor a component snapshot. The
|
|
23
|
+
current model never writes either, so these stay detectable after `db:migrate --drop-columns`
|
|
24
|
+
removed the old columns. This refuses that tenant only.
|
|
25
|
+
|
|
26
|
+
`assertCommerceMoneySchemaCurrent(db)` checks the schema.
|
|
27
|
+
`assertTenantMoneyCurrent(db, tenantId)` checks the schema, then the tenant.
|
|
28
|
+
On PostgreSQL every cross-tenant scan runs on a connection of its own (opened
|
|
29
|
+
from the database URL), in a transaction that raises `smrt.system_context`,
|
|
30
|
+
so the caller's connection and row policies are never touched; concurrent
|
|
31
|
+
checks for one database and tenant share a single scan. Both cache a passing
|
|
32
|
+
result per database (keyed by its connection URL, so
|
|
33
|
+
request executors share it) and tenant, so the check runs once per process.
|
|
34
|
+
Invoice, Contract and line models also run the check from `initialize()` on
|
|
35
|
+
every row hydrated from the database, which covers unscoped reads and every
|
|
36
|
+
collection class, including generated STI subtype collections. A
|
|
37
|
+
tenantless collection read still checks the schema, and a tenant's first
|
|
38
|
+
`TaxSettings` row is refused while that tenant holds old documents. Every runtime money read and write, the money MCP tools, the tax
|
|
39
|
+
summary, and `ensureCommerceTenant()` call them first.
|
|
40
|
+
|
|
41
|
+
A refusal is a `CommerceDataNeedsUpgradeError` with `code`
|
|
42
|
+
`COMMERCE_DATA_NEEDS_UPGRADE`. Its message ends with the command, for example
|
|
43
|
+
`Run smrt db:upgrade-commerce-money --tenant-id <id> to upgrade it.`
|
|
44
|
+
`commerceMoneyUpgradeCommand(tenantId?)` builds that command text.
|
|
45
|
+
|
|
46
|
+
`findCommerceMoneyUpgradeNeeds(db)` scans the whole database. It is
|
|
47
|
+
operator-only: it ignores the caller's row permissions, so never wire it into
|
|
48
|
+
a principal-facing surface. It returns `oldSchema`, `tenantlessDocuments`
|
|
49
|
+
(rows to assign or delete) and each tenant that needs the upgrade, with a
|
|
50
|
+
reason (`legacy-marker`, `interrupted-migration`, `missing-settings`, or
|
|
51
|
+
`old-format-documents`).
|
|
52
|
+
`smrt db:status` uses it to report the `commerce-money-upgrade` error
|
|
53
|
+
precondition, so `smrt app doctor` reports `migration-required`.
|
|
54
|
+
|
|
55
|
+
## Upgrade
|
|
56
|
+
|
|
57
|
+
`upgradeCommerceMoney(db, { tenantId? })` in `src/upgrade/money-v2.ts` is the
|
|
58
|
+
one-shot conversion behind `smrt db:upgrade-commerce-money`. Run the normal
|
|
59
|
+
schema migration first. Each tenant converts in its own transaction:
|
|
60
|
+
|
|
61
|
+
1. Its tax settings row and standard codes are seeded.
|
|
62
|
+
2. Each stored fractional rate maps to a code. A zero rate becomes `exempt`
|
|
63
|
+
for an exempt customer, otherwise `out-of-scope`. Any other rate becomes a
|
|
64
|
+
one-component `rate-<percent>` code, created once.
|
|
65
|
+
3. Issued documents are backfilled from their stored values: line net, line
|
|
66
|
+
tax, tax-code snapshot, `DocumentTax` rows, and a money snapshot. No stored
|
|
67
|
+
total changes.
|
|
68
|
+
4. Drafts are recomputed through the runtime from their prices. Only
|
|
69
|
+
old-format lines (no tax code and no component snapshot) are mapped; a
|
|
70
|
+
draft header keeps its amount type and rounding. The result lists each
|
|
71
|
+
draft whose total changed.
|
|
72
|
+
|
|
73
|
+
An issued document whose stored lines do not add up exactly to its stored
|
|
74
|
+
header fails its tenant. So do an invalid stored rate, an invoice posted under
|
|
75
|
+
the earlier version (its revenue journal carries that version's provenance,
|
|
76
|
+
which current posting and reversal refuse; void it and clear the link, or reset
|
|
77
|
+
the data), an existing `rate-<percent>` code or component that does not
|
|
78
|
+
mean exactly that rate, and an edited standard `exempt` or `out-of-scope`
|
|
79
|
+
code. Nothing in that tenant changes, and the result lists
|
|
80
|
+
each failing document. A tenant whose earlier
|
|
81
|
+
migration never finished also fails; roll it back with the version that started
|
|
82
|
+
it, or reset its data. Converted tenants are skipped on a rerun.
|
|
83
|
+
|
|
84
|
+
Once no tenant needs the upgrade, the old columns and table are dropped. The
|
|
85
|
+
upgrade leaves no mode flag. Read `failures` and `remaining` on the result; the
|
|
86
|
+
CLI exits nonzero on either. New `rate-<percent>` components have no liability
|
|
87
|
+
account and are listed in `componentsWithoutLiabilityAccount`; posting falls
|
|
88
|
+
back to the caller's `taxAccountId` until one is assigned.
|
|
89
|
+
|
|
90
|
+
The runtime never imports `money-v2.ts`. Delete the `upgrade/` directory, the
|
|
91
|
+
CLI command, and the detection call sites together once no supported version
|
|
92
|
+
can have written old-format data.
|
|
@@ -13,8 +13,8 @@ debit receivables and credit revenue/tax; signed credits naturally swap sides, a
|
|
|
13
13
|
For inclusive documents, stored line net is `amountMinor - taxMinor`; for exclusive
|
|
14
14
|
and no-tax pricing it is `amountMinor`. Revenue is grouped by each line's stored
|
|
15
15
|
account, falling back to the caller's revenue account. Component tax uses the
|
|
16
|
-
stored liability account and falls back to `taxAccountId`.
|
|
17
|
-
|
|
16
|
+
stored liability account and falls back to `taxAccountId`. The result has only
|
|
17
|
+
`entries`; there are no warnings. Provider tax is posted once as
|
|
18
18
|
its own entry to `taxAccountId`. Zero-tax and null-component reporting rows do not
|
|
19
19
|
produce entries.
|
|
20
20
|
|
package/agents/tax-codes.md
CHANGED
|
@@ -4,23 +4,22 @@
|
|
|
4
4
|
change a rate, archive the old component, create a replacement and update the
|
|
5
5
|
editable `TaxCode.components` list. Never edit a used component's percent.
|
|
6
6
|
|
|
7
|
-
Every tenant seeds `exempt`, `zero-rated`, `out-of-scope
|
|
8
|
-
`
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
Every tenant seeds `exempt`, `zero-rated`, and `out-of-scope`
|
|
8
|
+
(`STANDARD_TAX_CODES`, seeded by `ensureTenantTaxCodes(db, tenantId)` in
|
|
9
|
+
`src/tax/standard-codes.ts`). Those kinds have no components because they
|
|
10
|
+
report differently. They are reserved: billing lines and zero rates rely on
|
|
11
|
+
them never carrying tax, so `ensureTenantTaxCodes` (and through it the
|
|
12
|
+
bootstrap, billing period close and the upgrade) refuses a standard code
|
|
13
|
+
whose kind or components were changed. `TaxCodeCollection.findByCode(code, tenantId?)` finds a
|
|
14
|
+
code by its tenant-unique `code`, optionally for an explicit tenant.
|
|
15
|
+
The [money data upgrade](money-upgrade.md) adds a one-component
|
|
16
|
+
`rate-<percent>` code for each nonzero rate it finds in earlier-version data.
|
|
12
17
|
|
|
13
18
|
`TaxSettings` owns tenant defaults, tax registrations, default line amount type
|
|
14
19
|
and rounding scope. Cookbook policies adapt the portable settings document;
|
|
15
|
-
they do not replace persisted tax settings.
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
`migrating` or `v2` row is refused rather than resetting that tenant to legacy.
|
|
19
|
-
The ordinary save transaction locks and re-reads the tenant marker before its
|
|
20
|
-
natural-key upsert, serializing that check with migration claim and activation.
|
|
21
|
-
If the tenant has no marker to lock, its first ordinary save is insert-only: a
|
|
22
|
-
concurrent migration that creates the marker wins and the stale save is refused
|
|
23
|
-
instead of adopting and overwriting the migration-owned row.
|
|
20
|
+
they do not replace persisted tax settings. There is one settings row per
|
|
21
|
+
tenant, created once under a tenant lock (see
|
|
22
|
+
[document money](document-money.md#tenant-settings-and-bootstrap-4009)).
|
|
24
23
|
|
|
25
24
|
`applyCommerceCookbookSettings(db, tenantId, cookbook)` is the explicit
|
|
26
25
|
server-side activation boundary for core's portable `taxRate`, inclusion, and
|
|
@@ -34,6 +33,10 @@ import cookbook from './smrt.cookbook.json' with { type: 'json' };
|
|
|
34
33
|
await applyCommerceCookbookSettings(db, session.tenantId, cookbook);
|
|
35
34
|
```
|
|
36
35
|
|
|
36
|
+
`ensureCommerceTenant(db, tenantId, { cookbook })` wraps this call with the
|
|
37
|
+
settings row and standard code seed; prefer it for a newly created tenant
|
|
38
|
+
(#4009).
|
|
39
|
+
|
|
37
40
|
`smrt cookbook apply` writes project files and does not have a database or
|
|
38
41
|
tenant, so it deliberately performs no storage writes. Activation creates or
|
|
39
42
|
reuses a component and default tax code, then updates tenant `TaxSettings` in
|
package/agents/tax-summary.md
CHANGED
|
@@ -32,8 +32,9 @@ movement to every component.
|
|
|
32
32
|
## Materialized document report path
|
|
33
33
|
|
|
34
34
|
`TaxSummaryReport` is a tenant-scoped, manual materialized report. Its owner,
|
|
35
|
-
`TaxSummaryReportCollection.refreshTaxSummary()`,
|
|
36
|
-
|
|
35
|
+
`TaxSummaryReportCollection.refreshTaxSummary()`, requires a tenant and refuses
|
|
36
|
+
one whose money data needs the upgrade (`COMMERCE_DATA_NEEDS_UPGRADE`, see
|
|
37
|
+
[money data upgrade](money-upgrade.md)): earlier-version documents are not a
|
|
37
38
|
complete stored-tax source. The caller injects the public Expense and Journal
|
|
38
39
|
source adapters because commerce cannot depend on expenses; omitting either
|
|
39
40
|
adapter is a refusal, never a zero-ITC fallback.
|
|
@@ -68,13 +69,14 @@ matching `DocumentTax.documentType` pairs: `invoice`/`invoice` or
|
|
|
68
69
|
`credit_note`/`credit_note`. Credit rows retain positive stored values and pass
|
|
69
70
|
through the aggregation's single credit sign step.
|
|
70
71
|
|
|
71
|
-
Refresh holds the tenant `TaxSettings` parent lock through the
|
|
72
|
-
source reads, aggregation, and replacement. Every source-adapter call receives
|
|
72
|
+
Refresh holds the tenant `TaxSettings` parent lock through the upgrade check,
|
|
73
|
+
all source reads, aggregation, and replacement. Every source-adapter call receives
|
|
73
74
|
the same transaction-bound database executor. Replacement rows use a stable
|
|
74
75
|
UUID derived from tenant, period, currency, row kind, and dimension, so retry
|
|
75
76
|
and concurrent same-period refreshes converge to one row set. Materialized
|
|
76
|
-
`list`, `get`, `count`, and Invoice drilldowns all
|
|
77
|
-
|
|
77
|
+
`list`, `get`, `count`, and Invoice drilldowns all require a tenant context and
|
|
78
|
+
recheck it; a tenant that needs the upgrade is refused even for existing report
|
|
79
|
+
rows.
|
|
78
80
|
|
|
79
81
|
Each document drilldown fact carries its printed invoice number or Contract
|
|
80
82
|
reference, tenant-scoped customer/vendor party id, issue date, stored taxable
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"period-close.d.ts","sourceRoot":"","sources":["../../src/billing/period-close.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"period-close.d.ts","sourceRoot":"","sources":["../../src/billing/period-close.ts"],"names":[],"mappings":"AA8CA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAQnD,MAAM,WAAW,aAAa;IAC5B,uBAAuB;IACvB,WAAW,EAAE,IAAI,CAAC;IAClB,8DAA8D;IAC9D,SAAS,EAAE,IAAI,CAAC;CACjB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAgB;IAC/B,WAAW,CAAC,EAAE,IAAI,CAAC;IACnB,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,iDAAiD;IACjD,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ;AAED,MAAM,MAAM,kBAAkB,GAC1B,WAAW,GACX,OAAO,GACP,MAAM,GACN,iBAAiB,GACjB,QAAQ,CAAC;AAEb,MAAM,WAAW,sBAAsB;IACrC,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,oDAAoD;IACpD,WAAW,EAAE,IAAI,CAAC;IAClB,SAAS,EAAE,IAAI,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,OAAO,EAAE,kBAAkB,CAAC;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAkB,SAAQ,aAAa;IACtD,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,sBAAsB,EAAE,CAAC;CAClC;AAED,yEAAyE;AACzE,qBAAa,uBAAwB,SAAQ,KAAK;IACpC,QAAQ,CAAC,MAAM,EAAE,iBAAiB;gBAAzB,MAAM,EAAE,iBAAiB;CAW/C;AAmDD,4DAA4D;AAC5D,wBAAgB,qBAAqB,CAAC,GAAG,OAAa,GAAG,aAAa,CAQrE;AAkCD,wBAAgB,aAAa,CAC3B,OAAO,EAAE,IAAI,CAAC,cAAc,EAAE,gBAAgB,GAAG,MAAM,CAAC,EACxD,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,MAAM,CAAC,CAUjB;AAsED;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,cAAc,EACvB,KAAK,GAAE,gBAAqB,GAC3B,OAAO,CAAC,iBAAiB,CAAC,CAwE5B"}
|