@happyvertical/smrt-commerce 0.56.1 → 0.57.0
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 +159 -93
- package/agents/accounting-snapshot-mapper.md +3 -3
- package/agents/commercial-ui.md +2 -2
- package/agents/contract-money.md +9 -6
- package/agents/cost-billing.md +3 -6
- package/agents/customer-vendor-ui.md +6 -1
- package/agents/document-money.md +59 -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 +12 -8
- 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-DYjhj_pU.js → ContractLineItemCollection-BZcrlrrY.js} +22 -27
- package/dist/chunks/ContractLineItemCollection-BZcrlrrY.js.map +1 -0
- package/dist/chunks/{CustomerCollection-DQIujn4f.js → CustomerCollection-BIPH2ZUx.js} +3 -3
- package/dist/chunks/{CustomerCollection-DQIujn4f.js.map → CustomerCollection-BIPH2ZUx.js.map} +1 -1
- package/dist/chunks/{DocumentTaxCollection-BEpoqXAQ.js → DocumentTaxCollection-DDzlywMW.js} +41 -14
- package/dist/chunks/DocumentTaxCollection-DDzlywMW.js.map +1 -0
- package/dist/chunks/{InvoiceCollection-CKQflFjc.js → InvoiceCollection-cinzAqt6.js} +53 -164
- package/dist/chunks/InvoiceCollection-cinzAqt6.js.map +1 -0
- package/dist/chunks/{TaxCodeCollection-DOpzW4y8.js → TaxCodeCollection-DaBOPG9c.js} +11 -4
- package/dist/chunks/{TaxCodeCollection-DOpzW4y8.js.map → TaxCodeCollection-DaBOPG9c.js.map} +1 -1
- package/dist/chunks/{TaxComponentCollection-Cs2uXwEl.js → TaxComponentCollection-C4zxnyVu.js} +3 -3
- package/dist/chunks/{TaxComponentCollection-Cs2uXwEl.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-DI3G16BN.js → allocation-integrity-WmWyXhtG.js} +6 -6
- package/dist/chunks/{allocation-integrity-DI3G16BN.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-DNVhDJyC.js → document-money-DV5t4vlK.js} +389 -63
- package/dist/chunks/document-money-DV5t4vlK.js.map +1 -0
- package/dist/chunks/{invoice-posting-BwV8g7z0.js → invoice-posting-C2i5dOVZ.js} +21 -23
- 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-LDETvQ1C.js → types-Bbm0Xflc.js} +2 -1
- package/dist/chunks/types-Bbm0Xflc.js.map +1 -0
- 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 +686 -1656
- 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 +1041 -863
- package/dist/migrations/invoiceEditorStorage.d.ts +2 -4
- package/dist/migrations/invoiceEditorStorage.d.ts.map +1 -1
- package/dist/migrations/partyLinks.d.ts.map +1 -1
- package/dist/models/Contract.d.ts +10 -4
- package/dist/models/Contract.d.ts.map +1 -1
- package/dist/models/ContractLineItem.d.ts +9 -17
- package/dist/models/ContractLineItem.d.ts.map +1 -1
- package/dist/models/DocumentTax.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 +13 -32
- 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 +1 -2
- 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 +2886 -6121
- 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 +11 -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-DYjhj_pU.js.map +0 -1
- package/dist/chunks/DocumentTaxCollection-BEpoqXAQ.js.map +0 -1
- package/dist/chunks/InvoiceCollection-CKQflFjc.js.map +0 -1
- package/dist/chunks/InvoiceLineItemCollection-CHm9zdqh.js +0 -467
- package/dist/chunks/InvoiceLineItemCollection-CHm9zdqh.js.map +0 -1
- package/dist/chunks/TaxSettingsCollection-BBTZDH1S.js +0 -319
- package/dist/chunks/TaxSettingsCollection-BBTZDH1S.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-DNVhDJyC.js.map +0 -1
- package/dist/chunks/invoice-posting-BwV8g7z0.js.map +0 -1
- package/dist/chunks/revenue-journal-DY9fro8E.js.map +0 -1
- package/dist/chunks/tenant-money-barrier-DjRXgMnX.js +0 -135
- package/dist/chunks/tenant-money-barrier-DjRXgMnX.js.map +0 -1
- package/dist/chunks/types-LDETvQ1C.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
|
@@ -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.
|
|
@@ -47,8 +48,10 @@ The Contract branch gets a bounded, hydrated candidate set from
|
|
|
47
48
|
owner's descendant classifier before joining only those purchase ids to
|
|
48
49
|
`document_taxes` on document id and tenant id. This preserves custom
|
|
49
50
|
`PurchaseContract` descendants without hard-coding contract enums or party
|
|
50
|
-
display names. Contract rows include
|
|
51
|
-
|
|
51
|
+
display names. Contract rows include non-draft, non-cancelled frozen snapshots,
|
|
52
|
+
including `DECLINED`, except `SupplierQuote` and its descendants; exclusion uses
|
|
53
|
+
the hydrated STI subtype rather than the mutable `contractType` scalar. Their
|
|
54
|
+
`issueDate`, reference (falling back to
|
|
52
55
|
the id), and vendor party id are read from the frozen Contract. The query only
|
|
53
56
|
returns stored snapshots and never recalculates tax. A nullable tax-code kind
|
|
54
57
|
becomes an unassigned-source warning; it never becomes out-of-scope by
|
|
@@ -66,13 +69,14 @@ matching `DocumentTax.documentType` pairs: `invoice`/`invoice` or
|
|
|
66
69
|
`credit_note`/`credit_note`. Credit rows retain positive stored values and pass
|
|
67
70
|
through the aggregation's single credit sign step.
|
|
68
71
|
|
|
69
|
-
Refresh holds the tenant `TaxSettings` parent lock through the
|
|
70
|
-
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
|
|
71
74
|
the same transaction-bound database executor. Replacement rows use a stable
|
|
72
75
|
UUID derived from tenant, period, currency, row kind, and dimension, so retry
|
|
73
76
|
and concurrent same-period refreshes converge to one row set. Materialized
|
|
74
|
-
`list`, `get`, `count`, and Invoice drilldowns all
|
|
75
|
-
|
|
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.
|
|
76
80
|
|
|
77
81
|
Each document drilldown fact carries its printed invoice number or Contract
|
|
78
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"}
|
|
@@ -24,8 +24,11 @@ import { type BillingProvider, type BillingProviderCheckoutSession } from './pro
|
|
|
24
24
|
import { type AutoTopUpFailureHook, type AutoTopUpHookOptions } from './top-up.js';
|
|
25
25
|
/** Ledger accounts billing posts to, in the seller's books. */
|
|
26
26
|
export interface BillingLedgerAccounts {
|
|
27
|
-
/**
|
|
28
|
-
|
|
27
|
+
/**
|
|
28
|
+
* ISO 4217 currency of this ledger book. Invoices post only in this
|
|
29
|
+
* currency, so it must equal the seller's billing currency.
|
|
30
|
+
*/
|
|
31
|
+
bookCurrency: string;
|
|
29
32
|
/** Accounts receivable (debited when an invoice is issued). */
|
|
30
33
|
arAccountId: string;
|
|
31
34
|
/** Revenue (credited with the invoice subtotal). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/billing/runtime.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AAE7E,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EACL,KAAK,aAAa,EAClB,2BAA2B,EAC3B,KAAK,yBAAyB,EAC9B,sBAAsB,EACtB,mBAAmB,EACnB,sBAAsB,EACtB,wBAAwB,EACxB,0BAA0B,EAC1B,4BAA4B,EAC7B,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/billing/runtime.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { MoneyValidationError } from "../money.js";
|
|
3
|
+
import { a as assertCommerceMoneySchemaCurrent, f as DOCUMENT_MONEY_READ_REBIND, p as DOCUMENT_MONEY_WRITE } from "./detect-CY9ufaFb.js";
|
|
4
|
+
import { n as withTenantMoneyCollectionRead } from "./tenant-money-barrier-6TlqUeVj.js";
|
|
4
5
|
import { SmrtCollection, SmrtObject, crossPackageRef, field, foreignKey, smrt } from "@happyvertical/smrt-core";
|
|
5
6
|
import { TenantScoped, getTenantId, queryGlobal, queryWithGlobals, tenantId } from "@happyvertical/smrt-tenancy";
|
|
6
7
|
//#region src/models/ContractLineItem.ts
|
|
@@ -54,9 +55,7 @@ var ContractLineItem = class extends SmrtObject {
|
|
|
54
55
|
set taxComponents(value) {
|
|
55
56
|
this.taxComponentsJson = JSON.stringify(value);
|
|
56
57
|
}
|
|
57
|
-
/** Exact sum of frozen component taxes, in integer minor units. */
|
|
58
58
|
taxAmount = 0;
|
|
59
|
-
legacyAmount = null;
|
|
60
59
|
/** Stable issue/freeze identity, independent of lifecycle updated_at. */
|
|
61
60
|
moneySnapshotId = "";
|
|
62
61
|
amount = 0;
|
|
@@ -99,7 +98,6 @@ var ContractLineItem = class extends SmrtObject {
|
|
|
99
98
|
if (options.taxComponentsJson !== void 0) this.taxComponentsJson = options.taxComponentsJson;
|
|
100
99
|
if (options.taxComponents !== void 0) this.taxComponents = structuredClone(options.taxComponents);
|
|
101
100
|
if (options.taxAmount !== void 0) this.taxAmount = options.taxAmount;
|
|
102
|
-
if (options.legacyAmount !== void 0) this.legacyAmount = options.legacyAmount;
|
|
103
101
|
if (options.moneySnapshotId !== void 0) this.moneySnapshotId = options.moneySnapshotId;
|
|
104
102
|
if (options.amount !== void 0) this.amount = options.amount;
|
|
105
103
|
if (options.productId !== void 0) this.productId = options.productId;
|
|
@@ -109,32 +107,26 @@ var ContractLineItem = class extends SmrtObject {
|
|
|
109
107
|
if (options.billingPeriod !== void 0) this.billingPeriod = options.billingPeriod;
|
|
110
108
|
if (options.sortOrder !== void 0) this.sortOrder = options.sortOrder;
|
|
111
109
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
* plain `===` instead of an epsilon tolerance (#2401).
|
|
120
|
-
*/
|
|
121
|
-
calculateAmount() {
|
|
122
|
-
const subtotal = this.quantity * this.unitPrice - this.discount;
|
|
123
|
-
const tax = subtotal * this.taxRate;
|
|
124
|
-
return Math.round(subtotal + tax);
|
|
110
|
+
async initialize() {
|
|
111
|
+
await super.initialize();
|
|
112
|
+
if (this.isPersisted) {
|
|
113
|
+
const { assertHydratedMoneyRowCurrent } = await import("./detect-CY9ufaFb.js").then((n) => n.c);
|
|
114
|
+
await assertHydratedMoneyRowCurrent(this);
|
|
115
|
+
}
|
|
116
|
+
return this;
|
|
125
117
|
}
|
|
126
118
|
async save() {
|
|
127
|
-
const { saveContractLineItem } = await import("
|
|
119
|
+
const { saveContractLineItem } = await import("./contract-money-EuToOghh.js");
|
|
128
120
|
return await saveContractLineItem(this);
|
|
129
121
|
}
|
|
130
122
|
/** @internal Contract aggregate persistence only. */
|
|
131
|
-
async saveDerived(capability
|
|
123
|
+
async saveDerived(capability) {
|
|
132
124
|
if (capability !== DOCUMENT_MONEY_WRITE) throw new Error("Contract line money write capability is required");
|
|
133
|
-
|
|
125
|
+
for (const [field2, value] of [["unitPrice", this.unitPrice], ["discount", this.discount]]) if (!Number.isSafeInteger(value)) throw new MoneyValidationError("UNSAFE_MONEY", `Contract line ${field2} ${value} must be a safe integer number of minor units`);
|
|
134
126
|
return await super.save();
|
|
135
127
|
}
|
|
136
128
|
async delete(options = {}) {
|
|
137
|
-
const { deleteContractLineItem } = await import("
|
|
129
|
+
const { deleteContractLineItem } = await import("./contract-money-EuToOghh.js");
|
|
138
130
|
await deleteContractLineItem(this, options);
|
|
139
131
|
}
|
|
140
132
|
/** @internal Contract aggregate persistence only. */
|
|
@@ -166,16 +158,16 @@ __decorateClass([field({ description: "The order, quote or agreement this line b
|
|
|
166
158
|
__decorateClass([field({ description: "What is being sold or bought on this line." })], ContractLineItem.prototype, "description", 2);
|
|
167
159
|
__decorateClass([field({ description: "How many." })], ContractLineItem.prototype, "quantity", 2);
|
|
168
160
|
__decorateClass([field({
|
|
169
|
-
description: "The price of one, before tax.",
|
|
161
|
+
description: "The price of one, before discount; includes tax when the document's prices include tax.",
|
|
170
162
|
ui: { format: "money" }
|
|
171
163
|
})], ContractLineItem.prototype, "unitPrice", 2);
|
|
172
164
|
__decorateClass([field({ ui: { format: "money" } })], ContractLineItem.prototype, "discount", 2);
|
|
173
165
|
__decorateClass([field({ type: "decimal" })], ContractLineItem.prototype, "discountRate", 2);
|
|
174
166
|
__decorateClass([field({ description: "The stored fractional tax rate for this line (0.05 means 5%)." })], ContractLineItem.prototype, "taxRate", 2);
|
|
175
167
|
__decorateClass([foreignKey("TaxCode", { nullable: true })], ContractLineItem.prototype, "taxCodeId", 2);
|
|
176
|
-
__decorateClass([field({
|
|
168
|
+
__decorateClass([field({ ui: { format: "money" } })], ContractLineItem.prototype, "taxAmount", 2);
|
|
177
169
|
__decorateClass([field({
|
|
178
|
-
description: "The line
|
|
170
|
+
description: "The line amount: net of discount, and including tax only when the document's prices include tax.",
|
|
179
171
|
ui: { format: "money" }
|
|
180
172
|
})], ContractLineItem.prototype, "amount", 2);
|
|
181
173
|
__decorateClass([field({ description: "The product this line is for, if it is one you list." }), crossPackageRef("@happyvertical/smrt-products:Product")], ContractLineItem.prototype, "productId", 2);
|
|
@@ -199,7 +191,10 @@ var ContractLineItemCollection = class extends SmrtCollection {
|
|
|
199
191
|
async withMoneyRead(operation) {
|
|
200
192
|
const rootDb = this.db;
|
|
201
193
|
const tenantId = getTenantId();
|
|
202
|
-
if (!tenantId)
|
|
194
|
+
if (!tenantId) {
|
|
195
|
+
await assertCommerceMoneySchemaCurrent(rootDb);
|
|
196
|
+
return operation();
|
|
197
|
+
}
|
|
203
198
|
const result = await withTenantMoneyCollectionRead(rootDb, tenantId, (boundDb) => this.withDatabase(boundDb, operation));
|
|
204
199
|
if (result instanceof ContractLineItem) result.rebindMoneyRead(DOCUMENT_MONEY_READ_REBIND, rootDb);
|
|
205
200
|
else if (Array.isArray(result)) {
|
|
@@ -262,4 +257,4 @@ var ContractLineItemCollection = class extends SmrtCollection {
|
|
|
262
257
|
//#endregion
|
|
263
258
|
export { ContractLineItemCollection_exports as n, ContractLineItem as r, ContractLineItemCollection as t };
|
|
264
259
|
|
|
265
|
-
//# sourceMappingURL=ContractLineItemCollection-
|
|
260
|
+
//# sourceMappingURL=ContractLineItemCollection-BZcrlrrY.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ContractLineItemCollection-BZcrlrrY.js","names":["field"],"sources":["../../src/models/ContractLineItem.ts","../../src/collections/ContractLineItemCollection.ts"],"sourcesContent":["/**\n * ContractLineItem model - individual items on a contract\n * @packageDocumentation\n */\n\nimport {\n crossPackageRef,\n field,\n foreignKey,\n SmrtObject,\n smrt,\n} from '@happyvertical/smrt-core';\nimport type { DatabaseInterface } from '@happyvertical/smrt-core/migrations';\nimport { TenantScoped, tenantId } from '@happyvertical/smrt-tenancy';\nimport {\n DOCUMENT_MONEY_READ_REBIND,\n DOCUMENT_MONEY_WRITE,\n type DocumentMoneyReadRebindCapability,\n type DocumentMoneyWriteCapability,\n} from '../document-money-internal.js';\nimport { MoneyValidationError } from '../money.js';\nimport type {\n ContractLineItemOptions,\n ContractTaxComponentSnapshot,\n} from '../types/index.js';\n\n/**\n * ContractLineItem represents a single line item on a contract.\n *\n * Line items contain the details of what is being sold/purchased,\n * including quantity, pricing, and optional subscription details.\n *\n * @example\n * ```typescript\n * const lineItem = await lineItems.create({\n * contractId: order.id,\n * description: 'Widget Pro',\n * quantity: 10,\n * unitPrice: 4999, // $49.99 in cents\n * taxRate: 0.08\n * });\n * ```\n */\n@TenantScoped({ mode: 'optional' })\n@smrt({\n tableStrategy: 'sti',\n api: { include: ['list', 'get', 'create', 'update', 'delete'] },\n mcp: { include: ['list', 'get'] },\n cli: { skipApiCheck: true },\n})\nexport class ContractLineItem extends SmrtObject { static __smrtPackage__ = \"@happyvertical/smrt-commerce\";\n /** @internal Collection read guard returns this snapshot on its root DB. */\n rebindMoneyRead(\n capability: DocumentMoneyReadRebindCapability,\n db: DatabaseInterface,\n ): this {\n if (capability !== DOCUMENT_MONEY_READ_REBIND)\n throw new Error(\n 'Contract line read rebinding requires the owning capability',\n );\n this._db = db;\n this.options.db = db;\n return this;\n }\n\n /**\n * Tenant ID for multi-tenant isolation\n * Nullable to support both tenant-scoped and global line items\n */\n @tenantId({ nullable: true })\n tenantId: string | null = null;\n\n /**\n * Parent contract\n */\n @field({ description: 'The order, quote or agreement this line belongs to.' })\n @foreignKey('Contract', { role: 'items' })\n contractId: string = '';\n\n /**\n * Item description\n */\n @field({ description: 'What is being sold or bought on this line.' })\n description: string = '';\n\n /**\n * Quantity ordered. Decimal on purpose — contracts price fractional\n * quantities (hours, weight, bandwidth), as do invoice line items.\n */\n @field({ description: 'How many.' })\n quantity: number = 1.0;\n\n /**\n * Unit price before discount, in **integer minor units** (cents, satoshis),\n * in the document's pricing mode: tax-inclusive when its `lineAmountType`\n * is `inclusive`.\n *\n * The `= 0` initializer is load-bearing: SMRT maps an integer literal to\n * INTEGER and a decimal literal to DECIMAL. Money is exact, so `$49.99` is\n * `4999` (#2401).\n */\n @field({\n description:\n \"The price of one, before discount; includes tax when the document's prices include tax.\",\n ui: { format: 'money' },\n })\n unitPrice: number = 0;\n\n /**\n * Discount amount (flat, not percentage), in integer minor units (#2401).\n */\n @field({ ui: { format: 'money' } })\n discount: number = 0;\n\n discountType: 'none' | 'percent' | 'amount' = 'none';\n\n @field({ type: 'decimal' })\n discountRate = '0.0';\n\n /**\n * Tax rate as decimal (e.g., 0.08 for 8%). A rate is inherently fractional,\n * so it stays DECIMAL — INTEGER would truncate every meaningful value.\n */\n @field({\n description:\n 'The stored fractional tax rate for this line (0.05 means 5%).',\n })\n taxRate: number = 0.0;\n\n taxMode: 'inherit' | 'override' = 'inherit';\n\n @foreignKey('TaxCode', { nullable: true })\n taxCodeId: string | null = null;\n\n taxCodeCode: string | null = null;\n\n taxCodeName: string | null = null;\n\n taxComponentsJson: string | null = null;\n\n get taxComponents(): ContractTaxComponentSnapshot[] {\n if (this.taxComponentsJson === null) return [];\n try {\n const value: unknown = JSON.parse(this.taxComponentsJson);\n if (!Array.isArray(value)) return [];\n return value.filter(\n (entry): entry is ContractTaxComponentSnapshot =>\n !!entry &&\n typeof entry === 'object' &&\n typeof (entry as ContractTaxComponentSnapshot).taxComponentId ===\n 'string' &&\n typeof (entry as ContractTaxComponentSnapshot).name === 'string' &&\n typeof (entry as ContractTaxComponentSnapshot).percent === 'string' &&\n Number.isSafeInteger(\n (entry as ContractTaxComponentSnapshot).taxMinor,\n ),\n );\n } catch {\n return [];\n }\n }\n\n set taxComponents(value: ContractTaxComponentSnapshot[]) {\n this.taxComponentsJson = JSON.stringify(value);\n }\n\n /** Exact sum of frozen component taxes, in integer minor units. */\n @field({ ui: { format: 'money' } })\n taxAmount = 0;\n\n /** Stable issue/freeze identity, independent of lifecycle updated_at. */\n moneySnapshotId = '';\n\n /**\n * Line amount in integer minor units: net of discount and before tax for\n * `exclusive` / `none` documents, and tax-inclusive for `inclusive` ones;\n * {@link taxAmount} holds the tax. Derived by the Contract money aggregate\n * on every save.\n */\n @field({\n description:\n \"The line amount: net of discount, and including tax only when the document's prices include tax.\",\n ui: { format: 'money' },\n })\n amount: number = 0;\n\n /**\n * Optional product reference (cross-package, plain string)\n */\n @field({\n description: 'The product this line is for, if it is one you list.',\n })\n @crossPackageRef('@happyvertical/smrt-products:Product')\n productId: string = '';\n\n /**\n * SKU or item code\n */\n sku: string = '';\n\n /**\n * Start date (for lease/subscription items)\n */\n startDate: Date | null = null;\n\n /**\n * End date (for lease/subscription items)\n */\n endDate: Date | null = null;\n\n /**\n * Billing period (for subscriptions: 'monthly', 'yearly', etc.)\n */\n billingPeriod: string = '';\n\n /**\n * Sort order within the contract\n */\n sortOrder: number = 0;\n\n constructor(options: ContractLineItemOptions = {}) {\n super(options);\n if (options.tenantId !== undefined) this.tenantId = options.tenantId;\n if (options.contractId !== undefined) this.contractId = options.contractId;\n if (options.description !== undefined)\n this.description = options.description;\n if (options.quantity !== undefined) this.quantity = options.quantity;\n if (options.unitPrice !== undefined) this.unitPrice = options.unitPrice;\n if (options.discount !== undefined) this.discount = options.discount;\n if (options.discountType !== undefined)\n this.discountType = options.discountType;\n if (options.discountRate !== undefined)\n this.discountRate = options.discountRate;\n if (options.taxRate !== undefined) this.taxRate = options.taxRate;\n if (options.taxMode !== undefined) this.taxMode = options.taxMode;\n if (options.taxCodeId !== undefined) this.taxCodeId = options.taxCodeId;\n if (options.taxCodeCode !== undefined)\n this.taxCodeCode = options.taxCodeCode;\n if (options.taxCodeName !== undefined)\n this.taxCodeName = options.taxCodeName;\n if (options.taxComponentsJson !== undefined)\n this.taxComponentsJson = options.taxComponentsJson;\n if (options.taxComponents !== undefined)\n this.taxComponents = structuredClone(options.taxComponents);\n if (options.taxAmount !== undefined) this.taxAmount = options.taxAmount;\n if (options.moneySnapshotId !== undefined)\n this.moneySnapshotId = options.moneySnapshotId;\n if (options.amount !== undefined) this.amount = options.amount;\n if (options.productId !== undefined) this.productId = options.productId;\n if (options.sku !== undefined) this.sku = options.sku;\n if (options.startDate !== undefined) this.startDate = options.startDate;\n if (options.endDate !== undefined) this.endDate = options.endDate;\n if (options.billingPeriod !== undefined)\n this.billingPeriod = options.billingPeriod;\n if (options.sortOrder !== undefined) this.sortOrder = options.sortOrder;\n }\n\n override async initialize(): Promise<this> {\n await super.initialize();\n // A row read from the database must not be old-format money data.\n if (this.isPersisted) {\n const { assertHydratedMoneyRowCurrent } = await import(\n '../upgrade/detect.js'\n );\n await assertHydratedMoneyRowCurrent(this);\n }\n return this;\n }\n\n override async save(): Promise<this> {\n const { saveContractLineItem } = await import('../contract-money.js');\n return (await saveContractLineItem(this)) as this;\n }\n\n /** @internal Contract aggregate persistence only. */\n async saveDerived(capability: DocumentMoneyWriteCapability): Promise<this> {\n if (capability !== DOCUMENT_MONEY_WRITE)\n throw new Error('Contract line money write capability is required');\n // Money is integer minor units: refuse a major-unit price before it can\n // reach the database (#2401), ahead of the aggregate recompute.\n for (const [field, value] of [\n ['unitPrice', this.unitPrice],\n ['discount', this.discount],\n ] as const)\n if (!Number.isSafeInteger(value))\n throw new MoneyValidationError(\n 'UNSAFE_MONEY',\n `Contract line ${field} ${value} must be a safe integer number of minor units`,\n );\n return (await super.save()) as this;\n }\n\n override async delete(\n options: { expectedUpdatedAt?: Date | string } = {},\n ): Promise<void> {\n const { deleteContractLineItem } = await import('../contract-money.js');\n await deleteContractLineItem(this, options);\n }\n\n /** @internal Contract aggregate persistence only. */\n async deleteDerived(\n capability: DocumentMoneyWriteCapability,\n options: { expectedUpdatedAt?: Date | string } = {},\n ): Promise<void> {\n if (capability !== DOCUMENT_MONEY_WRITE)\n throw new Error('Contract line money write capability is required');\n await super.delete(options);\n }\n\n /**\n * Check if this is a subscription/recurring item\n */\n isRecurring(): boolean {\n return !!this.billingPeriod && !!this.startDate;\n }\n\n /**\n * Check if subscription is active\n */\n isSubscriptionActive(): boolean {\n if (!this.isRecurring()) return false;\n if (!this.startDate) return false;\n\n const now = new Date();\n if (now < this.startDate) return false;\n if (this.endDate && now > this.endDate) return false;\n\n return true;\n }\n}\n\nexport default ContractLineItem;\n","/**\n * ContractLineItemCollection - Collection manager for ContractLineItem objects\n * @packageDocumentation\n */\n\nimport {\n SmrtCollection,\n type SmrtListOptions,\n type SmrtObject,\n type SmrtSelectedRow,\n type SmrtSelectField,\n type SmrtStiReadScope,\n type SmrtWhereClause,\n} from '@happyvertical/smrt-core';\nimport {\n getTenantId,\n queryGlobal,\n queryWithGlobals,\n} from '@happyvertical/smrt-tenancy';\nimport { DOCUMENT_MONEY_READ_REBIND } from '../document-money-internal.js';\nimport { ContractLineItem } from '../models/ContractLineItem.js';\nimport { withTenantMoneyCollectionRead } from '../tenant-money-barrier.js';\nimport { assertCommerceMoneySchemaCurrent } from '../upgrade/detect.js';\n\nexport class ContractLineItemCollection extends SmrtCollection<ContractLineItem> {\n static readonly _itemClass = ContractLineItem;\n\n private async withMoneyRead<T>(operation: () => Promise<T>): Promise<T> {\n const rootDb = this.db;\n const tenantId = getTenantId();\n if (!tenantId) {\n // Without a tenant, still refuse a database with old money storage.\n await assertCommerceMoneySchemaCurrent(rootDb);\n return operation();\n }\n const result = await withTenantMoneyCollectionRead(\n rootDb,\n tenantId,\n (boundDb) => this.withDatabase(boundDb, operation),\n );\n if (result instanceof ContractLineItem)\n result.rebindMoneyRead(DOCUMENT_MONEY_READ_REBIND, rootDb);\n else if (Array.isArray(result))\n for (const item of result)\n if (item instanceof ContractLineItem)\n item.rebindMoneyRead(DOCUMENT_MONEY_READ_REBIND, rootDb);\n return result;\n }\n\n override async get(\n filter: string | SmrtWhereClause<ContractLineItem>,\n options: Parameters<SmrtCollection<ContractLineItem>['get']>[1] = {},\n ): Promise<ContractLineItem | null> {\n return this.withMoneyRead(() => super.get(filter, options));\n }\n\n override async list<\n const Select extends readonly SmrtSelectField<ContractLineItem>[],\n >(\n options: Omit<SmrtListOptions<ContractLineItem>, 'select' | 'stiScope'> & {\n select: Select;\n include?: never;\n stiScope: SmrtStiReadScope;\n },\n ): Promise<Record<string, unknown>[]>;\n override async list<\n const Select extends readonly SmrtSelectField<ContractLineItem>[],\n >(\n options: Omit<SmrtListOptions<ContractLineItem>, 'select' | 'stiScope'> & {\n select: Select;\n include?: never;\n stiScope?: undefined;\n },\n ): Promise<SmrtSelectedRow<ContractLineItem, Select>[]>;\n override async list(\n options: Omit<SmrtListOptions<ContractLineItem>, 'select' | 'stiScope'> & {\n select?: undefined;\n stiScope: SmrtStiReadScope;\n },\n ): Promise<SmrtObject[]>;\n override async list(options?: undefined): Promise<ContractLineItem[]>;\n override async list(\n options: Omit<SmrtListOptions<ContractLineItem>, 'select' | 'stiScope'> & {\n select?: undefined;\n stiScope?: undefined;\n },\n ): Promise<ContractLineItem[]>;\n override async list(\n options:\n | (Omit<SmrtListOptions<ContractLineItem>, 'select'> & {\n select?: undefined;\n })\n | undefined,\n ): Promise<SmrtObject[]>;\n override async list(\n options: SmrtListOptions<ContractLineItem> | undefined,\n ): Promise<SmrtObject[] | Record<string, unknown>[]>;\n override async list(\n options: SmrtListOptions<ContractLineItem> = {},\n ): Promise<SmrtObject[] | Record<string, unknown>[]> {\n return this.withMoneyRead(() => super.list(options));\n }\n\n /**\n * Find contract line items by their parent contract.\n *\n * @param contractId - Contract ID\n * @returns Array of contract line items, sorted by sortOrder\n */\n async findByContract(contractId: string): Promise<ContractLineItem[]> {\n return await this.list({\n where: { contractId },\n orderBy: 'sortOrder ASC',\n });\n }\n\n // ============================================================================\n // Tenant Helper Methods\n // ============================================================================\n\n /**\n * Find all contract line items belonging to a specific tenant\n *\n * @param tenantId - Tenant ID\n * @returns Array of contract line items for the tenant\n */\n async findByTenant(tenantId: string): Promise<ContractLineItem[]> {\n return this.list({ where: { tenantId } });\n }\n\n /**\n * Find all global contract line items (not associated with any tenant).\n *\n * Routes through the shared tenant-global helper so it does not throw under\n * an active tenant context (an explicit `tenant_id IS NULL` filter would be\n * flagged as an isolation violation). (#1600)\n *\n * @returns Array of global contract line items\n */\n async findGlobal(): Promise<ContractLineItem[]> {\n return queryGlobal<ContractLineItem>(this);\n }\n\n /**\n * Find contract line items for a tenant including global line items.\n *\n * Fails closed if an active tenant context requests a different tenant's\n * rows; the admin/system path keeps the cross-tenant capability. (#1600)\n *\n * @param tenantId - Tenant ID\n * @returns Array of tenant-specific and global contract line items\n */\n async findWithGlobals(tenantId: string): Promise<ContractLineItem[]> {\n return queryWithGlobals<ContractLineItem>(\n this,\n tenantId,\n 'ContractLineItem.findWithGlobals',\n );\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { r as CustomerStatus } from "./types-
|
|
1
|
+
import { C as Customer } from "./DocumentTaxCollection-DDzlywMW.js";
|
|
2
|
+
import { r as CustomerStatus } from "./types-Bbm0Xflc.js";
|
|
3
3
|
import { SmrtCollection } from "@happyvertical/smrt-core";
|
|
4
4
|
import { queryGlobal, queryWithGlobals } from "@happyvertical/smrt-tenancy";
|
|
5
5
|
//#region src/collections/CustomerCollection.ts
|
|
@@ -96,4 +96,4 @@ var CustomerCollection = class extends SmrtCollection {
|
|
|
96
96
|
//#endregion
|
|
97
97
|
export { CustomerCollection as t };
|
|
98
98
|
|
|
99
|
-
//# sourceMappingURL=CustomerCollection-
|
|
99
|
+
//# sourceMappingURL=CustomerCollection-BIPH2ZUx.js.map
|
package/dist/chunks/{CustomerCollection-DQIujn4f.js.map → CustomerCollection-BIPH2ZUx.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CustomerCollection-
|
|
1
|
+
{"version":3,"file":"CustomerCollection-BIPH2ZUx.js","names":[],"sources":["../../src/collections/CustomerCollection.ts"],"sourcesContent":["/**\n * CustomerCollection - Collection manager for Customer objects\n * @packageDocumentation\n */\n\nimport { SmrtCollection } from '@happyvertical/smrt-core';\nimport { queryGlobal, queryWithGlobals } from '@happyvertical/smrt-tenancy';\nimport { Customer } from '../models/Customer.js';\nimport { CustomerStatus } from '../types/index.js';\n\nexport class CustomerCollection extends SmrtCollection<Customer> {\n static readonly _itemClass = Customer;\n\n /**\n * Find customers by profile ID\n *\n * @param profileId - Profile ID from smrt-profiles\n * @returns Array of customers linked to this profile\n */\n async findByProfile(profileId: string): Promise<Customer[]> {\n return await this.list({\n where: { profileId },\n orderBy: 'created_at DESC',\n });\n }\n\n /**\n * Find all active customers\n *\n * @returns Array of active customers\n */\n async findActive(): Promise<Customer[]> {\n return await this.list({\n where: { status: CustomerStatus.ACTIVE },\n orderBy: 'created_at DESC',\n });\n }\n\n /**\n * Find customers by status\n *\n * @param status - Customer status\n * @returns Array of customers\n */\n async findByStatus(status: CustomerStatus): Promise<Customer[]> {\n return await this.list({\n where: { status },\n orderBy: 'created_at DESC',\n });\n }\n\n /**\n * Get or create a customer for a profile\n *\n * @param profileId - Profile ID\n * @param defaults - Default values if creating\n * @returns Customer\n */\n async getOrCreateForProfile(\n profileId: string,\n defaults: Partial<{\n creditLimit: number;\n paymentTerms: string;\n }> = {},\n ): Promise<Customer> {\n const existing = await this.findByProfile(profileId);\n if (existing.length > 0) {\n return existing[0];\n }\n\n const customer = await this.create({\n profileId,\n creditLimit: defaults.creditLimit ?? 0,\n paymentTerms: defaults.paymentTerms ?? '',\n status: CustomerStatus.ACTIVE,\n });\n await customer.save();\n return customer;\n }\n\n // ============================================================================\n // Tenant Helper Methods\n // ============================================================================\n\n /**\n * Find all customers belonging to a specific tenant\n *\n * @param tenantId - Tenant ID\n * @returns Array of customers for the tenant\n */\n async findByTenant(tenantId: string): Promise<Customer[]> {\n return this.list({ where: { tenantId } });\n }\n\n /**\n * Find all global customers (not associated with any tenant).\n *\n * Routes through the shared tenant-global helper so it does not throw under\n * an active tenant context (an explicit `tenant_id IS NULL` filter would be\n * flagged as an isolation violation). (#1600)\n *\n * @returns Array of global customers\n */\n async findGlobal(): Promise<Customer[]> {\n return queryGlobal<Customer>(this);\n }\n\n /**\n * Find customers for a tenant including global customers.\n *\n * Fails closed if an active tenant context requests a different tenant's\n * rows; the admin/system path keeps the cross-tenant capability. (#1600)\n *\n * @param tenantId - Tenant ID\n * @returns Array of tenant-specific and global customers\n */\n async findWithGlobals(tenantId: string): Promise<Customer[]> {\n return queryWithGlobals<Customer>(\n this,\n tenantId,\n 'Customer.findWithGlobals',\n );\n }\n}\n"],"mappings":";;;;;AAUO,IAAM,qBAAN,cAAiC,eAAyB;CAC/D,OAAgB,aAAa;;;;;;;CAQ7B,MAAM,cAAc,WAAwC;EAC1D,OAAO,MAAM,KAAK,KAAK;GACrB,OAAO,EAAE,UAAU;GACnB,SAAS;EACX,CAAC;CACH;;;;;;CAOA,MAAM,aAAkC;EACtC,OAAO,MAAM,KAAK,KAAK;GACrB,OAAO,EAAE,QAAQ,eAAe,OAAO;GACvC,SAAS;EACX,CAAC;CACH;;;;;;;CAQA,MAAM,aAAa,QAA6C;EAC9D,OAAO,MAAM,KAAK,KAAK;GACrB,OAAO,EAAE,OAAO;GAChB,SAAS;EACX,CAAC;CACH;;;;;;;;CASA,MAAM,sBACJ,WACA,WAGK,CAAC,GACa;EACnB,MAAM,WAAW,MAAM,KAAK,cAAc,SAAS;EACnD,IAAI,SAAS,SAAS,GACpB,OAAO,SAAS;EAGlB,MAAM,WAAW,MAAM,KAAK,OAAO;GACjC;GACA,aAAa,SAAS,eAAe;GACrC,cAAc,SAAS,gBAAgB;GACvC,QAAQ,eAAe;EACzB,CAAC;EACD,MAAM,SAAS,KAAK;EACpB,OAAO;CACT;;;;;;;CAYA,MAAM,aAAa,UAAuC;EACxD,OAAO,KAAK,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;CAC1C;;;;;;;;;;CAWA,MAAM,aAAkC;EACtC,OAAO,YAAsB,IAAI;CACnC;;;;;;;;;;CAWA,MAAM,gBAAgB,UAAuC;EAC3D,OAAO,iBACL,MACA,UACA,0BACF;CACF;AACF"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
|
|
2
|
-
import { i as CustomerType, n as ContractType, p as VendorStatus, r as CustomerStatus, t as ContractStatus } from "./types-
|
|
2
|
+
import { i as CustomerType, n as ContractType, p as VendorStatus, r as CustomerStatus, t as ContractStatus } from "./types-Bbm0Xflc.js";
|
|
3
3
|
import { MoneyValidationError, assertIntegerMinorUnits } from "../money.js";
|
|
4
|
-
import { a as DOCUMENT_MONEY_READ_REBIND,
|
|
5
|
-
import {
|
|
4
|
+
import { a as assertCommerceMoneySchemaCurrent, f as DOCUMENT_MONEY_READ_REBIND, p as DOCUMENT_MONEY_WRITE } from "./detect-CY9ufaFb.js";
|
|
5
|
+
import { n as withTenantMoneyCollectionRead } from "./tenant-money-barrier-6TlqUeVj.js";
|
|
6
6
|
import { SmrtCollection, SmrtObject, crossPackageRef, field, foreignKey, smrt } from "@happyvertical/smrt-core";
|
|
7
7
|
import { TenantScoped, getTenantId, queryGlobal, queryWithGlobals, tenantId, withTenant } from "@happyvertical/smrt-tenancy";
|
|
8
8
|
//#region src/party-contacts.ts
|
|
@@ -563,7 +563,7 @@ function classifyContractPurchase(contract) {
|
|
|
563
563
|
return "vendorId" in contract;
|
|
564
564
|
}
|
|
565
565
|
function isContractSnapshotReportEligible(contract) {
|
|
566
|
-
return contract.status !== ContractStatus.DRAFT && contract.status !== ContractStatus.CANCELLED;
|
|
566
|
+
return !(contract instanceof SupplierQuote) && contract.status !== ContractStatus.DRAFT && contract.status !== ContractStatus.CANCELLED;
|
|
567
567
|
}
|
|
568
568
|
var Contract = class extends SmrtObject {
|
|
569
569
|
/** @internal Collection read guard returns this snapshot on its root DB. */
|
|
@@ -577,7 +577,6 @@ var Contract = class extends SmrtObject {
|
|
|
577
577
|
contractType = ContractType.ORDER;
|
|
578
578
|
status = ContractStatus.DRAFT;
|
|
579
579
|
subtotal = 0;
|
|
580
|
-
/** Informational sum of resolved line discounts, in integer minor units. */
|
|
581
580
|
discountTotal = 0;
|
|
582
581
|
taxAmount = 0;
|
|
583
582
|
totalAmount = 0;
|
|
@@ -672,7 +671,7 @@ var Contract = class extends SmrtObject {
|
|
|
672
671
|
* Calculate and update totals from line items
|
|
673
672
|
*/
|
|
674
673
|
async recalculateTotals() {
|
|
675
|
-
const { recalculateContractTotals } = await import("
|
|
674
|
+
const { recalculateContractTotals } = await import("./contract-money-EuToOghh.js");
|
|
676
675
|
await recalculateContractTotals(this);
|
|
677
676
|
}
|
|
678
677
|
/**
|
|
@@ -683,6 +682,10 @@ var Contract = class extends SmrtObject {
|
|
|
683
682
|
*/
|
|
684
683
|
async initialize() {
|
|
685
684
|
await super.initialize();
|
|
685
|
+
if (this.isPersisted) {
|
|
686
|
+
const { assertHydratedMoneyRowCurrent } = await import("./detect-CY9ufaFb.js").then((n) => n.c);
|
|
687
|
+
await assertHydratedMoneyRowCurrent(this);
|
|
688
|
+
}
|
|
686
689
|
if (await this.isSaved()) loadedContractStatus.set(this, this.status);
|
|
687
690
|
return this;
|
|
688
691
|
}
|
|
@@ -698,7 +701,7 @@ var Contract = class extends SmrtObject {
|
|
|
698
701
|
* write surface (#2401).
|
|
699
702
|
*/
|
|
700
703
|
async save() {
|
|
701
|
-
const { saveContract } = await import("
|
|
704
|
+
const { saveContract } = await import("./contract-money-EuToOghh.js");
|
|
702
705
|
return await saveContract(this);
|
|
703
706
|
}
|
|
704
707
|
/** @internal Contract aggregate persistence only. */
|
|
@@ -761,6 +764,7 @@ __decorateClass$1([field({
|
|
|
761
764
|
description: "The amount before tax.",
|
|
762
765
|
ui: { format: "money" }
|
|
763
766
|
})], Contract.prototype, "subtotal", 2);
|
|
767
|
+
__decorateClass$1([field({ ui: { format: "money" } })], Contract.prototype, "discountTotal", 2);
|
|
764
768
|
__decorateClass$1([field({
|
|
765
769
|
description: "The tax charged.",
|
|
766
770
|
ui: { format: "money" }
|
|
@@ -815,7 +819,7 @@ var PurchaseContract = class extends Contract {
|
|
|
815
819
|
}
|
|
816
820
|
};
|
|
817
821
|
__publicField$1(PurchaseContract, "__smrtPackage__", "@happyvertical/smrt-commerce");
|
|
818
|
-
__decorateClass$1([foreignKey(Vendor, { description: "The vendor
|
|
822
|
+
__decorateClass$1([foreignKey(Vendor, { description: "The vendor supplying this quote or purchase contract." })], PurchaseContract.prototype, "vendorId", 2);
|
|
819
823
|
PurchaseContract = __decorateClass$1([TenantScoped({ mode: "optional" }), smrt({ abstract: true })], PurchaseContract);
|
|
820
824
|
var Estimate = class extends SalesContract {
|
|
821
825
|
customerId = null;
|
|
@@ -861,6 +865,17 @@ var Agreement = class extends SalesContract {
|
|
|
861
865
|
__publicField$1(Agreement, "__smrtPackage__", "@happyvertical/smrt-commerce");
|
|
862
866
|
__decorateClass$1([foreignKey(Customer, { required: true })], Agreement.prototype, "customerId", 2);
|
|
863
867
|
Agreement = __decorateClass$1([TenantScoped({ mode: "optional" }), smrt()], Agreement);
|
|
868
|
+
var SupplierQuote = class extends PurchaseContract {
|
|
869
|
+
vendorId = null;
|
|
870
|
+
contractType = ContractType.SUPPLIER_QUOTE;
|
|
871
|
+
constructor(options = {}) {
|
|
872
|
+
super(options);
|
|
873
|
+
if (options.vendorId !== void 0) this.vendorId = options.vendorId;
|
|
874
|
+
}
|
|
875
|
+
};
|
|
876
|
+
__publicField$1(SupplierQuote, "__smrtPackage__", "@happyvertical/smrt-commerce");
|
|
877
|
+
__decorateClass$1([foreignKey(Vendor, { required: true })], SupplierQuote.prototype, "vendorId", 2);
|
|
878
|
+
SupplierQuote = __decorateClass$1([TenantScoped({ mode: "optional" }), smrt()], SupplierQuote);
|
|
864
879
|
var PurchaseOrder = class extends PurchaseContract {
|
|
865
880
|
vendorId = null;
|
|
866
881
|
contractType = ContractType.PURCHASE_ORDER;
|
|
@@ -1105,7 +1120,10 @@ var ContractCollection = class extends SmrtCollection {
|
|
|
1105
1120
|
async withMoneyRead(operation) {
|
|
1106
1121
|
const rootDb = this.db;
|
|
1107
1122
|
const tenantId = getTenantId();
|
|
1108
|
-
if (!tenantId)
|
|
1123
|
+
if (!tenantId) {
|
|
1124
|
+
await assertCommerceMoneySchemaCurrent(rootDb);
|
|
1125
|
+
return operation();
|
|
1126
|
+
}
|
|
1109
1127
|
const result = await withTenantMoneyCollectionRead(rootDb, tenantId, (boundDb) => this.withDatabase(boundDb, operation));
|
|
1110
1128
|
if (result instanceof Contract) result.rebindMoneyRead(DOCUMENT_MONEY_READ_REBIND, rootDb);
|
|
1111
1129
|
else if (Array.isArray(result)) {
|
|
@@ -1386,9 +1404,18 @@ __decorateClass([field({
|
|
|
1386
1404
|
nullable: true
|
|
1387
1405
|
})], DocumentTax.prototype, "percent", 2);
|
|
1388
1406
|
__decorateClass([field({ nullable: true })], DocumentTax.prototype, "liabilityAccountId", 2);
|
|
1389
|
-
__decorateClass([field({
|
|
1390
|
-
|
|
1391
|
-
|
|
1407
|
+
__decorateClass([field({
|
|
1408
|
+
description: "Tax-exclusive base in integer minor units.",
|
|
1409
|
+
ui: { format: "money" }
|
|
1410
|
+
})], DocumentTax.prototype, "taxableMinor", 2);
|
|
1411
|
+
__decorateClass([field({
|
|
1412
|
+
description: "Tax total in integer minor units.",
|
|
1413
|
+
ui: { format: "money" }
|
|
1414
|
+
})], DocumentTax.prototype, "taxMinor", 2);
|
|
1415
|
+
__decorateClass([field({
|
|
1416
|
+
description: "Recoverable purchase tax in integer minor units.",
|
|
1417
|
+
ui: { format: "money" }
|
|
1418
|
+
})], DocumentTax.prototype, "recoverableMinor", 2);
|
|
1392
1419
|
DocumentTax = __decorateClass([TenantScoped({ mode: "required" }), smrt({
|
|
1393
1420
|
tableName: "document_taxes",
|
|
1394
1421
|
conflictColumns: [
|
|
@@ -1634,6 +1661,6 @@ var DocumentTaxCollection = class extends SmrtCollection {
|
|
|
1634
1661
|
}
|
|
1635
1662
|
};
|
|
1636
1663
|
//#endregion
|
|
1637
|
-
export {
|
|
1664
|
+
export { normalizePartyContacts as A, Customer as C, PartyContactPayloadError as D, PartyContactPartyNotFoundError as E, savePartyContacts as M, validatePartyContactRows as N, PartyContactValidationError as O, Vendor as S, PARTY_CONTACT_MAX_LENGTHS as T, SalesContract as _, SalesContractCollection as a, classifyContractPurchase as b, Cart as c, Lease as d, LicenseSale as f, PurchaseOrder as g, PurchaseContract as h, ContractCollection as i, readPartyContactRows as j, applyPartyContactIntent as k, Contract as l, ProductionOrder as m, DocumentTaxCollection_exports as n, PurchaseContractCollection as o, Order as p, DocumentTax as r, Agreement as s, DocumentTaxCollection as t, Estimate as u, SupplierQuote as v, DEFAULT_PARTY_CONTACT_FIELD_NAMES as w, isContractSnapshotReportEligible as x, WholesaleOrder as y };
|
|
1638
1665
|
|
|
1639
|
-
//# sourceMappingURL=DocumentTaxCollection-
|
|
1666
|
+
//# sourceMappingURL=DocumentTaxCollection-DDzlywMW.js.map
|