@happyvertical/smrt-commerce 0.56.2 → 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 +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
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import { MoneyValidationError } from "../money.js";
|
|
2
|
+
import { g as withDocumentMoneyTransaction, m as lockDocumentMoneyParents, o as assertTenantMoneyCurrent } from "./detect-CY9ufaFb.js";
|
|
3
|
+
import { SmrtCollection, SmrtObject, field, foreignKey, isEmbeddedDatabase, isPostgresDatabase, smrt, withEmbeddedWriteTransaction } from "@happyvertical/smrt-core";
|
|
4
|
+
import { TenantScoped, getTenantId, tenantId } from "@happyvertical/smrt-tenancy";
|
|
5
|
+
//#region src/models/TaxSettings.ts
|
|
6
|
+
var __defProp = Object.defineProperty;
|
|
7
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
8
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, {
|
|
9
|
+
enumerable: true,
|
|
10
|
+
configurable: true,
|
|
11
|
+
writable: true,
|
|
12
|
+
value
|
|
13
|
+
}) : obj[key] = value;
|
|
14
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
15
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
16
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--) if (decorator = decorators[i]) result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
17
|
+
if (kind && result) __defProp(target, key, result);
|
|
18
|
+
return result;
|
|
19
|
+
};
|
|
20
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
21
|
+
var TaxSettings = class extends SmrtObject {
|
|
22
|
+
tenantId = "";
|
|
23
|
+
defaultSalesTaxCodeId = "";
|
|
24
|
+
defaultPurchaseTaxCodeId = "";
|
|
25
|
+
defaultLineAmountType = "exclusive";
|
|
26
|
+
taxRoundingScope = "line";
|
|
27
|
+
/** Stored JSON is guarded through the typed accessor below. */
|
|
28
|
+
taxRegistrationsJson = "[]";
|
|
29
|
+
get taxRegistrations() {
|
|
30
|
+
try {
|
|
31
|
+
const value = JSON.parse(this.taxRegistrationsJson);
|
|
32
|
+
if (!Array.isArray(value)) return [];
|
|
33
|
+
return value.filter((entry) => !!entry && typeof entry === "object" && typeof entry.taxComponentId === "string" && typeof entry.number === "string" && typeof entry.label === "string");
|
|
34
|
+
} catch {
|
|
35
|
+
return [];
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
set taxRegistrations(value) {
|
|
39
|
+
this.taxRegistrationsJson = typeof value === "string" ? value : JSON.stringify(value);
|
|
40
|
+
}
|
|
41
|
+
constructor(options = {}) {
|
|
42
|
+
super(options);
|
|
43
|
+
if (options.tenantId !== void 0) this.tenantId = options.tenantId;
|
|
44
|
+
if (options.defaultSalesTaxCodeId !== void 0) this.defaultSalesTaxCodeId = options.defaultSalesTaxCodeId;
|
|
45
|
+
if (options.defaultPurchaseTaxCodeId !== void 0) this.defaultPurchaseTaxCodeId = options.defaultPurchaseTaxCodeId;
|
|
46
|
+
if (options.defaultLineAmountType !== void 0) this.defaultLineAmountType = options.defaultLineAmountType;
|
|
47
|
+
if (options.taxRoundingScope !== void 0) this.taxRoundingScope = options.taxRoundingScope;
|
|
48
|
+
if (options.taxRegistrations !== void 0) this.taxRegistrations = structuredClone(options.taxRegistrations);
|
|
49
|
+
}
|
|
50
|
+
async save() {
|
|
51
|
+
if (![
|
|
52
|
+
"exclusive",
|
|
53
|
+
"inclusive",
|
|
54
|
+
"none"
|
|
55
|
+
].includes(this.defaultLineAmountType)) throw new Error("Tax settings defaultLineAmountType is invalid");
|
|
56
|
+
if (!["line", "document"].includes(this.taxRoundingScope)) throw new Error("Tax settings taxRoundingScope is invalid");
|
|
57
|
+
const registrations = this.parsedRegistrations();
|
|
58
|
+
if (!registrations) throw new Error("Tax registrations must be a valid JSON array");
|
|
59
|
+
if (registrations.some((entry) => !entry.taxComponentId || !entry.number.trim() || !entry.label.trim())) throw new Error("Tax registrations require component, number and label");
|
|
60
|
+
const firstTenant = this.isPersisted ? "" : this.tenantId || getTenantId() || "";
|
|
61
|
+
if (firstTenant) {
|
|
62
|
+
const { assertTenantMoneyCurrent } = await import("./detect-CY9ufaFb.js").then((n) => n.c);
|
|
63
|
+
await assertTenantMoneyCurrent(this.db, firstTenant);
|
|
64
|
+
}
|
|
65
|
+
return this.withTransaction(async () => {
|
|
66
|
+
const { TaxCodeCollection } = await import("./TaxCodeCollection-DaBOPG9c.js").then((n) => n.n);
|
|
67
|
+
const { TaxComponentCollection } = await import("./TaxComponentCollection-C4zxnyVu.js").then((n) => n.n);
|
|
68
|
+
const codes = await TaxCodeCollection.create({ db: this.db });
|
|
69
|
+
const components = await TaxComponentCollection.create({ db: this.db });
|
|
70
|
+
for (const id of [this.defaultSalesTaxCodeId, this.defaultPurchaseTaxCodeId].filter(Boolean)) {
|
|
71
|
+
const code = await codes.get({ id }, { cache: false });
|
|
72
|
+
if (!code || code.tenantId !== this.tenantId) throw new Error("Tax setting default codes must belong to its tenant");
|
|
73
|
+
}
|
|
74
|
+
for (const registration of registrations) {
|
|
75
|
+
const component = await components.get({ id: registration.taxComponentId }, { cache: false });
|
|
76
|
+
if (!component || component.tenantId !== this.tenantId) throw new Error("Tax setting registrations must belong to its tenant");
|
|
77
|
+
}
|
|
78
|
+
return await super.save();
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
parsedRegistrations() {
|
|
82
|
+
try {
|
|
83
|
+
const value = JSON.parse(this.taxRegistrationsJson);
|
|
84
|
+
if (!Array.isArray(value)) return null;
|
|
85
|
+
if (value.some((entry) => !entry || typeof entry !== "object" || typeof entry.taxComponentId !== "string" || typeof entry.number !== "string" || typeof entry.label !== "string")) return null;
|
|
86
|
+
return value;
|
|
87
|
+
} catch {
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
__publicField(TaxSettings, "__smrtPackage__", "@happyvertical/smrt-commerce");
|
|
93
|
+
__decorateClass([tenantId()], TaxSettings.prototype, "tenantId", 2);
|
|
94
|
+
__decorateClass([foreignKey("TaxCode", { description: "The default tax code for sales documents." })], TaxSettings.prototype, "defaultSalesTaxCodeId", 2);
|
|
95
|
+
__decorateClass([foreignKey("TaxCode", { description: "The default tax code for purchase documents." })], TaxSettings.prototype, "defaultPurchaseTaxCodeId", 2);
|
|
96
|
+
__decorateClass([field({ description: "Whether new document amounts are exclusive, inclusive or out of scope." })], TaxSettings.prototype, "defaultLineAmountType", 2);
|
|
97
|
+
__decorateClass([field({ description: "Whether components round per line or per document." })], TaxSettings.prototype, "taxRoundingScope", 2);
|
|
98
|
+
__decorateClass([field({
|
|
99
|
+
sensitive: true,
|
|
100
|
+
transient: true,
|
|
101
|
+
description: "Registration numbers by tax component, for issued-document snapshots."
|
|
102
|
+
})], TaxSettings.prototype, "taxRegistrations", 1);
|
|
103
|
+
TaxSettings = __decorateClass([TenantScoped({ mode: "required" }), smrt({
|
|
104
|
+
conflictColumns: ["tenant_id"],
|
|
105
|
+
api: {
|
|
106
|
+
include: [
|
|
107
|
+
"get",
|
|
108
|
+
"create",
|
|
109
|
+
"update"
|
|
110
|
+
],
|
|
111
|
+
writable: [
|
|
112
|
+
"defaultSalesTaxCodeId",
|
|
113
|
+
"defaultPurchaseTaxCodeId",
|
|
114
|
+
"defaultLineAmountType",
|
|
115
|
+
"taxRoundingScope",
|
|
116
|
+
"taxRegistrations"
|
|
117
|
+
]
|
|
118
|
+
},
|
|
119
|
+
mcp: { include: ["get"] },
|
|
120
|
+
cli: { skipApiCheck: true }
|
|
121
|
+
})], TaxSettings);
|
|
122
|
+
//#endregion
|
|
123
|
+
//#region src/tax/identity.ts
|
|
124
|
+
async function deterministicTaxId(tenantId, kind, key) {
|
|
125
|
+
if (!tenantId.trim() || !key.trim()) throw new Error("Tax bootstrap identity requires tenant and key");
|
|
126
|
+
const bytes = new TextEncoder().encode(JSON.stringify([
|
|
127
|
+
"commerce-tax",
|
|
128
|
+
tenantId,
|
|
129
|
+
kind,
|
|
130
|
+
key
|
|
131
|
+
]));
|
|
132
|
+
const uuid = new Uint8Array(await crypto.subtle.digest("SHA-256", bytes)).slice(0, 16);
|
|
133
|
+
uuid[6] = uuid[6] & 15 | 80;
|
|
134
|
+
uuid[8] = uuid[8] & 63 | 128;
|
|
135
|
+
const joined = Array.from(uuid, (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
136
|
+
return `${joined.slice(0, 8)}-${joined.slice(8, 12)}-${joined.slice(12, 16)}-${joined.slice(16, 20)}-${joined.slice(20)}`;
|
|
137
|
+
}
|
|
138
|
+
async function createOrLoadTaxSeed(create, load) {
|
|
139
|
+
for (let attempt = 0; attempt < 3; attempt++) try {
|
|
140
|
+
return await create();
|
|
141
|
+
} catch (error) {
|
|
142
|
+
const code = error?.code;
|
|
143
|
+
if (code === "RUNTIME_REVISION_CONFLICT" && attempt < 2) continue;
|
|
144
|
+
if (code !== "VALIDATION_UNIQUE_CONSTRAINT" && code !== "23505") throw error;
|
|
145
|
+
const winner = await load();
|
|
146
|
+
if (!winner) throw error;
|
|
147
|
+
return winner;
|
|
148
|
+
}
|
|
149
|
+
throw new Error("Tax seed retry exhausted");
|
|
150
|
+
}
|
|
151
|
+
//#endregion
|
|
152
|
+
//#region src/collections/TaxSettingsCollection.ts
|
|
153
|
+
async function lockTenantSettingsCreation(db, tenantId) {
|
|
154
|
+
if (!isPostgresDatabase(db)) return;
|
|
155
|
+
await db.query("SELECT pg_advisory_xact_lock(hashtext(CAST(? AS TEXT)))", `smrt-commerce-tax-settings:${tenantId}`);
|
|
156
|
+
}
|
|
157
|
+
async function materializeTenantTaxSettings(db, tenantId) {
|
|
158
|
+
const id = await deterministicTaxId(tenantId, "settings", "default");
|
|
159
|
+
await withEmbeddedWriteTransaction(db, isEmbeddedDatabase(db), async (tx) => {
|
|
160
|
+
await lockTenantSettingsCreation(tx, tenantId);
|
|
161
|
+
const settings = await TaxSettingsCollection.create({ db: tx });
|
|
162
|
+
if (await settings.getForTenant(tenantId)) return;
|
|
163
|
+
await createOrLoadTaxSeed(() => settings.create({
|
|
164
|
+
id,
|
|
165
|
+
tenantId
|
|
166
|
+
}), async () => (await settings.list({
|
|
167
|
+
where: { tenantId },
|
|
168
|
+
limit: 1
|
|
169
|
+
}))[0] ?? null);
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
var TaxSettingsCollection = class extends SmrtCollection {
|
|
173
|
+
static _itemClass = TaxSettings;
|
|
174
|
+
/**
|
|
175
|
+
* Load the tenant's settings row, creating it once when missing. A tenant
|
|
176
|
+
* whose stored documents predate tenant tax settings is refused with
|
|
177
|
+
* `COMMERCE_DATA_NEEDS_UPGRADE` rather than given fresh defaults.
|
|
178
|
+
*/
|
|
179
|
+
async getOrCreateForTenant(tenantId) {
|
|
180
|
+
await assertTenantMoneyCurrent(this.db, tenantId);
|
|
181
|
+
const existing = await this.getForTenant(tenantId);
|
|
182
|
+
if (existing) return existing;
|
|
183
|
+
await materializeTenantTaxSettings(this.db, tenantId);
|
|
184
|
+
const created = await this.getForTenant(tenantId);
|
|
185
|
+
if (!created) throw new MoneyValidationError("INVALID_MONEY_INPUT", "Tenant tax settings could not be materialized");
|
|
186
|
+
return created;
|
|
187
|
+
}
|
|
188
|
+
async getForTenant(tenantId) {
|
|
189
|
+
const listed = (await this.list({
|
|
190
|
+
where: { tenantId },
|
|
191
|
+
limit: 1
|
|
192
|
+
}))[0];
|
|
193
|
+
if (!listed?.id) return listed ?? null;
|
|
194
|
+
return await this.get({ id: listed.id }, { cache: false }) ?? null;
|
|
195
|
+
}
|
|
196
|
+
/** @internal Lock and re-read the tenant's settings row on this transaction. */
|
|
197
|
+
async lockForTenant(tenantId) {
|
|
198
|
+
const first = await this.getOrCreateForTenant(tenantId);
|
|
199
|
+
if (!first.id) throw new MoneyValidationError("INVALID_MONEY_INPUT", "Tenant tax settings have no identity");
|
|
200
|
+
await lockDocumentMoneyParents([{
|
|
201
|
+
id: first.id,
|
|
202
|
+
tenantId,
|
|
203
|
+
collection: this
|
|
204
|
+
}]);
|
|
205
|
+
const locked = await this.getForTenant(tenantId);
|
|
206
|
+
if (!locked || locked.id !== first.id) throw new MoneyValidationError("INVALID_MONEY_INPUT", "Tenant tax settings changed while acquiring the lock");
|
|
207
|
+
return locked;
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
//#endregion
|
|
211
|
+
//#region src/tenant-money-barrier.ts
|
|
212
|
+
function requiredText(value, label) {
|
|
213
|
+
if (!value || value.trim() !== value) throw new MoneyValidationError("INVALID_MONEY_INPUT", `${label} must be a nonempty trimmed string`);
|
|
214
|
+
return value;
|
|
215
|
+
}
|
|
216
|
+
var activeRuntimeScopes = /* @__PURE__ */ new WeakMap();
|
|
217
|
+
async function lockTenantMoneyRuntime(tx, tenantId) {
|
|
218
|
+
requiredText(tenantId, "Money tenant");
|
|
219
|
+
await assertTenantMoneyCurrent(tx, tenantId);
|
|
220
|
+
return (await TaxSettingsCollection.create({ db: tx })).lockForTenant(tenantId);
|
|
221
|
+
}
|
|
222
|
+
async function withTenantMoneyRuntime(db, tenantId, operation, existingScope) {
|
|
223
|
+
requiredText(tenantId, "Money tenant");
|
|
224
|
+
if (existingScope) {
|
|
225
|
+
if (existingScope.phase !== "runtime" || existingScope.db !== db || existingScope.tenantId !== tenantId) throw new MoneyValidationError("INVALID_MONEY_INPUT", "Tenant money runtime scope does not match the requested executor");
|
|
226
|
+
return operation(existingScope);
|
|
227
|
+
}
|
|
228
|
+
return withDocumentMoneyTransaction(db, async (tx) => {
|
|
229
|
+
const active = activeRuntimeScopes.get(tx)?.get(tenantId);
|
|
230
|
+
if (active) return operation(active);
|
|
231
|
+
const scope = {
|
|
232
|
+
db: tx,
|
|
233
|
+
tenantId,
|
|
234
|
+
settings: await lockTenantMoneyRuntime(tx, tenantId),
|
|
235
|
+
phase: "runtime"
|
|
236
|
+
};
|
|
237
|
+
const scopes = activeRuntimeScopes.get(tx) ?? /* @__PURE__ */ new Map();
|
|
238
|
+
scopes.set(tenantId, scope);
|
|
239
|
+
activeRuntimeScopes.set(tx, scopes);
|
|
240
|
+
try {
|
|
241
|
+
return await operation(scope);
|
|
242
|
+
} finally {
|
|
243
|
+
scopes.delete(tenantId);
|
|
244
|
+
if (scopes.size === 0) activeRuntimeScopes.delete(tx);
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
async function withTenantMoneyCollectionRead(db, tenantId, operation) {
|
|
249
|
+
await assertTenantMoneyCurrent(db, tenantId);
|
|
250
|
+
return operation(db);
|
|
251
|
+
}
|
|
252
|
+
//#endregion
|
|
253
|
+
export { materializeTenantTaxSettings as a, TaxSettings as c, TaxSettingsCollection as i, withTenantMoneyCollectionRead as n, createOrLoadTaxSeed as o, withTenantMoneyRuntime as r, deterministicTaxId as s, lockTenantMoneyRuntime as t };
|
|
254
|
+
|
|
255
|
+
//# sourceMappingURL=tenant-money-barrier-6TlqUeVj.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenant-money-barrier-6TlqUeVj.js","names":[],"sources":["../../src/models/TaxSettings.ts","../../src/tax/identity.ts","../../src/collections/TaxSettingsCollection.ts","../../src/tenant-money-barrier.ts"],"sourcesContent":["import { field, foreignKey, SmrtObject, smrt } from '@happyvertical/smrt-core';\nimport {\n getTenantId,\n TenantScoped,\n tenantId,\n} from '@happyvertical/smrt-tenancy';\nimport type { TaxSettingsOptions } from '../types/index.js';\n\nexport interface TaxRegistration {\n taxComponentId: string;\n number: string;\n label: string;\n}\n\n/** Tenant-level defaults and registration numbers for tax determination. */\n@TenantScoped({ mode: 'required' })\n@smrt({\n conflictColumns: ['tenant_id'],\n api: {\n include: ['get', 'create', 'update'],\n writable: [\n 'defaultSalesTaxCodeId',\n 'defaultPurchaseTaxCodeId',\n 'defaultLineAmountType',\n 'taxRoundingScope',\n 'taxRegistrations',\n ],\n },\n mcp: { include: ['get'] },\n cli: { skipApiCheck: true },\n})\nexport class TaxSettings extends SmrtObject { static __smrtPackage__ = \"@happyvertical/smrt-commerce\";\n @tenantId()\n tenantId = '';\n\n @foreignKey('TaxCode', {\n description: 'The default tax code for sales documents.',\n })\n defaultSalesTaxCodeId = '';\n\n @foreignKey('TaxCode', {\n description: 'The default tax code for purchase documents.',\n })\n defaultPurchaseTaxCodeId = '';\n\n @field({\n description:\n 'Whether new document amounts are exclusive, inclusive or out of scope.',\n })\n defaultLineAmountType: 'exclusive' | 'inclusive' | 'none' = 'exclusive';\n\n @field({ description: 'Whether components round per line or per document.' })\n taxRoundingScope: 'line' | 'document' = 'line';\n\n /** Stored JSON is guarded through the typed accessor below. */\n taxRegistrationsJson = '[]';\n\n @field({\n sensitive: true,\n transient: true,\n description:\n 'Registration numbers by tax component, for issued-document snapshots.',\n })\n get taxRegistrations(): TaxRegistration[] {\n try {\n const value: unknown = JSON.parse(this.taxRegistrationsJson);\n if (!Array.isArray(value)) return [];\n return value.filter(\n (entry): entry is TaxRegistration =>\n !!entry &&\n typeof entry === 'object' &&\n typeof (entry as TaxRegistration).taxComponentId === 'string' &&\n typeof (entry as TaxRegistration).number === 'string' &&\n typeof (entry as TaxRegistration).label === 'string',\n );\n } catch {\n return [];\n }\n }\n\n set taxRegistrations(value: TaxRegistration[] | string) {\n this.taxRegistrationsJson =\n typeof value === 'string' ? value : JSON.stringify(value);\n }\n\n constructor(options: TaxSettingsOptions = {}) {\n super(options);\n if (options.tenantId !== undefined) this.tenantId = options.tenantId;\n if (options.defaultSalesTaxCodeId !== undefined)\n this.defaultSalesTaxCodeId = options.defaultSalesTaxCodeId;\n if (options.defaultPurchaseTaxCodeId !== undefined)\n this.defaultPurchaseTaxCodeId = options.defaultPurchaseTaxCodeId;\n if (options.defaultLineAmountType !== undefined)\n this.defaultLineAmountType = options.defaultLineAmountType;\n if (options.taxRoundingScope !== undefined)\n this.taxRoundingScope = options.taxRoundingScope;\n if (options.taxRegistrations !== undefined)\n this.taxRegistrations = structuredClone(options.taxRegistrations);\n }\n\n override async save(): Promise<this> {\n if (\n !['exclusive', 'inclusive', 'none'].includes(this.defaultLineAmountType)\n )\n throw new Error('Tax settings defaultLineAmountType is invalid');\n if (!['line', 'document'].includes(this.taxRoundingScope))\n throw new Error('Tax settings taxRoundingScope is invalid');\n const registrations = this.parsedRegistrations();\n if (!registrations)\n throw new Error('Tax registrations must be a valid JSON array');\n if (\n registrations.some(\n (entry) =>\n !entry.taxComponentId || !entry.number.trim() || !entry.label.trim(),\n )\n )\n throw new Error('Tax registrations require component, number and label');\n // A tenant's first settings row must not adopt documents an earlier\n // version wrote: that tenant needs the upgrade, not fresh defaults.\n // The tenant may still be empty here: tenancy stamps it during save.\n const firstTenant = this.isPersisted\n ? ''\n : this.tenantId || getTenantId() || '';\n if (firstTenant) {\n const { assertTenantMoneyCurrent } = await import('../upgrade/detect.js');\n await assertTenantMoneyCurrent(this.db, firstTenant);\n }\n return this.withTransaction(async () => {\n const { TaxCodeCollection } = await import(\n '../collections/TaxCodeCollection.js'\n );\n const { TaxComponentCollection } = await import(\n '../collections/TaxComponentCollection.js'\n );\n const codes = await TaxCodeCollection.create({ db: this.db });\n const components = await TaxComponentCollection.create({ db: this.db });\n for (const id of [\n this.defaultSalesTaxCodeId,\n this.defaultPurchaseTaxCodeId,\n ].filter(Boolean)) {\n const code = await codes.get({ id }, { cache: false });\n if (!code || code.tenantId !== this.tenantId)\n throw new Error(\n 'Tax setting default codes must belong to its tenant',\n );\n }\n for (const registration of registrations) {\n const component = await components.get(\n { id: registration.taxComponentId },\n { cache: false },\n );\n if (!component || component.tenantId !== this.tenantId)\n throw new Error(\n 'Tax setting registrations must belong to its tenant',\n );\n }\n return (await super.save()) as this;\n });\n }\n\n private parsedRegistrations(): TaxRegistration[] | null {\n try {\n const value: unknown = JSON.parse(this.taxRegistrationsJson);\n if (!Array.isArray(value)) return null;\n if (\n value.some(\n (entry) =>\n !entry ||\n typeof entry !== 'object' ||\n typeof (entry as TaxRegistration).taxComponentId !== 'string' ||\n typeof (entry as TaxRegistration).number !== 'string' ||\n typeof (entry as TaxRegistration).label !== 'string',\n )\n )\n return null;\n return value as TaxRegistration[];\n } catch {\n return null;\n }\n }\n}\n","/** Stable UUID identities make tenant tax bootstrap retry and race safe. */\nexport async function deterministicTaxId(\n tenantId: string,\n kind: 'code' | 'component' | 'settings' | 'report',\n key: string,\n): Promise<string> {\n if (!tenantId.trim() || !key.trim())\n throw new Error('Tax bootstrap identity requires tenant and key');\n const bytes = new TextEncoder().encode(\n JSON.stringify(['commerce-tax', tenantId, kind, key]),\n );\n const digest = new Uint8Array(await crypto.subtle.digest('SHA-256', bytes));\n const uuid = digest.slice(0, 16);\n uuid[6] = (uuid[6] & 0x0f) | 0x50;\n uuid[8] = (uuid[8] & 0x3f) | 0x80;\n const hex = Array.from(uuid, (byte) => byte.toString(16).padStart(2, '0'));\n const joined = hex.join('');\n return `${joined.slice(0, 8)}-${joined.slice(8, 12)}-${joined.slice(12, 16)}-${joined.slice(16, 20)}-${joined.slice(20)}`;\n}\n\n/** A racing deterministic insert loses safely and reloads the committed row. */\nexport async function createOrLoadTaxSeed<T>(\n create: () => Promise<T>,\n load: () => Promise<T | null | undefined>,\n): Promise<T> {\n for (let attempt = 0; attempt < 3; attempt++) {\n try {\n return await create();\n } catch (error) {\n const code = (error as { code?: unknown } | null)?.code;\n if (code === 'RUNTIME_REVISION_CONFLICT' && attempt < 2) continue;\n if (code !== 'VALIDATION_UNIQUE_CONSTRAINT' && code !== '23505')\n throw error;\n const winner = await load();\n if (!winner) throw error;\n return winner;\n }\n }\n throw new Error('Tax seed retry exhausted');\n}\n","import {\n isEmbeddedDatabase,\n isPostgresDatabase,\n SmrtCollection,\n withEmbeddedWriteTransaction,\n} from '@happyvertical/smrt-core';\nimport type { DatabaseInterface } from '@happyvertical/smrt-core/migrations';\nimport { lockDocumentMoneyParents } from '../document-money-internal.js';\nimport { TaxSettings } from '../models/TaxSettings.js';\nimport { MoneyValidationError } from '../money.js';\nimport { createOrLoadTaxSeed, deterministicTaxId } from '../tax/identity.js';\nimport { assertTenantMoneyCurrent } from '../upgrade/detect.js';\n\n/**\n * Serialize settings-row creation for one tenant on PostgreSQL. The lock is\n * transaction-scoped; embedded engines are already single-writer through the\n * core embedded write queue that every model transaction enters.\n */\nasync function lockTenantSettingsCreation(\n db: DatabaseInterface,\n tenantId: string,\n): Promise<void> {\n if (!isPostgresDatabase(db)) return;\n await db.query(\n 'SELECT pg_advisory_xact_lock(hashtext(CAST(? AS TEXT)))',\n `smrt-commerce-tax-settings:${tenantId}`,\n );\n}\n\n/**\n * @internal Create a tenant's missing settings row exactly once, with the\n * model defaults. Creation serializes on a tenant advisory lock (PostgreSQL)\n * or the embedded write queue and re-reads before inserting, so racing first\n * writers converge on one row. An existing row is never changed.\n */\nexport async function materializeTenantTaxSettings(\n db: DatabaseInterface,\n tenantId: string,\n): Promise<void> {\n const id = await deterministicTaxId(tenantId, 'settings', 'default');\n await withEmbeddedWriteTransaction(db, isEmbeddedDatabase(db), async (tx) => {\n await lockTenantSettingsCreation(tx, tenantId);\n const settings = await TaxSettingsCollection.create({ db: tx });\n if (await settings.getForTenant(tenantId)) return;\n await createOrLoadTaxSeed(\n () => settings.create({ id, tenantId }),\n async () =>\n (await settings.list({ where: { tenantId }, limit: 1 }))[0] ?? null,\n );\n });\n}\n\nexport class TaxSettingsCollection extends SmrtCollection<TaxSettings> {\n static readonly _itemClass = TaxSettings;\n\n /**\n * Load the tenant's settings row, creating it once when missing. A tenant\n * whose stored documents predate tenant tax settings is refused with\n * `COMMERCE_DATA_NEEDS_UPGRADE` rather than given fresh defaults.\n */\n async getOrCreateForTenant(tenantId: string): Promise<TaxSettings> {\n await assertTenantMoneyCurrent(this.db, tenantId);\n const existing = await this.getForTenant(tenantId);\n if (existing) return existing;\n await materializeTenantTaxSettings(this.db, tenantId);\n const created = await this.getForTenant(tenantId);\n if (!created)\n throw new MoneyValidationError(\n 'INVALID_MONEY_INPUT',\n 'Tenant tax settings could not be materialized',\n );\n return created;\n }\n\n async getForTenant(tenantId: string): Promise<TaxSettings | null> {\n const listed = (await this.list({ where: { tenantId }, limit: 1 }))[0];\n if (!listed?.id) return listed ?? null;\n return (await this.get({ id: listed.id }, { cache: false })) ?? null;\n }\n\n /** @internal Lock and re-read the tenant's settings row on this transaction. */\n async lockForTenant(tenantId: string): Promise<TaxSettings> {\n const first = await this.getOrCreateForTenant(tenantId);\n if (!first.id)\n throw new MoneyValidationError(\n 'INVALID_MONEY_INPUT',\n 'Tenant tax settings have no identity',\n );\n await lockDocumentMoneyParents([\n { id: first.id, tenantId, collection: this },\n ]);\n const locked = await this.getForTenant(tenantId);\n if (!locked || locked.id !== first.id)\n throw new MoneyValidationError(\n 'INVALID_MONEY_INPUT',\n 'Tenant tax settings changed while acquiring the lock',\n );\n return locked;\n }\n}\n","/** Tenant serialization point for commerce money runtime work. */\n\nimport type { DatabaseInterface } from '@happyvertical/smrt-core/migrations';\nimport { TaxSettingsCollection } from './collections/TaxSettingsCollection.js';\nimport { withDocumentMoneyTransaction } from './document-money-internal.js';\nimport type { TaxSettings } from './models/TaxSettings.js';\nimport { MoneyValidationError } from './money.js';\nimport { assertTenantMoneyCurrent } from './upgrade/detect.js';\n\ndeclare const tenantMoneyScopeBrand: unique symbol;\n\n/** Transaction-affine proof that a tenant's settings row is locked on `db`. */\nexport interface TenantMoneyRuntimeScope {\n readonly db: DatabaseInterface;\n readonly tenantId: string;\n readonly settings: TaxSettings;\n readonly phase: 'runtime';\n readonly [tenantMoneyScopeBrand]: true;\n}\n\nfunction requiredText(value: string, label: string): string {\n if (!value || value.trim() !== value)\n throw new MoneyValidationError(\n 'INVALID_MONEY_INPUT',\n `${label} must be a nonempty trimmed string`,\n );\n return value;\n}\n\nconst activeRuntimeScopes = new WeakMap<\n object,\n Map<string, TenantMoneyRuntimeScope>\n>();\n\n/**\n * Lock and re-read the tenant's tax settings row before runtime money work,\n * creating it once when missing. Old-format money data is refused first with\n * `COMMERCE_DATA_NEEDS_UPGRADE`.\n */\nexport async function lockTenantMoneyRuntime(\n tx: DatabaseInterface,\n tenantId: string,\n): Promise<TaxSettings> {\n requiredText(tenantId, 'Money tenant');\n await assertTenantMoneyCurrent(tx, tenantId);\n return (await TaxSettingsCollection.create({ db: tx })).lockForTenant(\n tenantId,\n );\n}\n\n/**\n * Run tenant money work under the tenant settings lock on exactly one\n * executor.\n *\n * Supplying an existing scope proves re-entry on the same executor. Calls made\n * through the owning transaction wrapper also reuse its exact registered\n * executor. No optional adapter-property heuristic can grant this capability.\n */\nexport async function withTenantMoneyRuntime<T>(\n db: DatabaseInterface,\n tenantId: string,\n operation: (scope: TenantMoneyRuntimeScope) => Promise<T>,\n existingScope?: TenantMoneyRuntimeScope,\n): Promise<T> {\n requiredText(tenantId, 'Money tenant');\n if (existingScope) {\n if (\n existingScope.phase !== 'runtime' ||\n existingScope.db !== db ||\n existingScope.tenantId !== tenantId\n )\n throw new MoneyValidationError(\n 'INVALID_MONEY_INPUT',\n 'Tenant money runtime scope does not match the requested executor',\n );\n return operation(existingScope);\n }\n return withDocumentMoneyTransaction(db, async (tx) => {\n const active = activeRuntimeScopes.get(tx as object)?.get(tenantId);\n if (active) return operation(active);\n const settings = await lockTenantMoneyRuntime(tx, tenantId);\n const scope = {\n db: tx,\n tenantId,\n settings,\n phase: 'runtime',\n } as TenantMoneyRuntimeScope;\n const scopes = activeRuntimeScopes.get(tx as object) ?? new Map();\n scopes.set(tenantId, scope);\n activeRuntimeScopes.set(tx as object, scopes);\n try {\n return await operation(scope);\n } finally {\n scopes.delete(tenantId);\n if (scopes.size === 0) activeRuntimeScopes.delete(tx as object);\n }\n });\n}\n\n/**\n * @internal Guard a generated money-document collection read: a tenant whose\n * data predates the current money model is refused before any row is read.\n */\nexport async function withTenantMoneyCollectionRead<T>(\n db: DatabaseInterface,\n tenantId: string,\n operation: (boundDb: DatabaseInterface) => Promise<T>,\n): Promise<T> {\n await assertTenantMoneyCurrent(db, tenantId);\n return operation(db);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AA+BO,IAAM,cAAN,cAA0B,WAAW;CAE1C,WAAW;CAKX,wBAAwB;CAKxB,2BAA2B;CAM3B,wBAA4D;CAG5D,mBAAwC;;CAGxC,uBAAuB;CAQvB,IAAI,mBAAsC;EACxC,IAAI;GACF,MAAM,QAAiB,KAAK,MAAM,KAAK,oBAAoB;GAC3D,IAAI,CAAC,MAAM,QAAQ,KAAK,GAAG,OAAO,CAAC;GACnC,OAAO,MAAM,QACV,UACC,CAAC,CAAC,SACF,OAAO,UAAU,YACjB,OAAQ,MAA0B,mBAAmB,YACrD,OAAQ,MAA0B,WAAW,YAC7C,OAAQ,MAA0B,UAAU,QAChD;EACF,QAAQ;GACN,OAAO,CAAC;EACV;CACF;CAEA,IAAI,iBAAiB,OAAmC;EACtD,KAAK,uBACH,OAAO,UAAU,WAAW,QAAQ,KAAK,UAAU,KAAK;CAC5D;CAEA,YAAY,UAA8B,CAAC,GAAG;EAC5C,MAAM,OAAO;EACb,IAAI,QAAQ,aAAa,KAAA,GAAW,KAAK,WAAW,QAAQ;EAC5D,IAAI,QAAQ,0BAA0B,KAAA,GACpC,KAAK,wBAAwB,QAAQ;EACvC,IAAI,QAAQ,6BAA6B,KAAA,GACvC,KAAK,2BAA2B,QAAQ;EAC1C,IAAI,QAAQ,0BAA0B,KAAA,GACpC,KAAK,wBAAwB,QAAQ;EACvC,IAAI,QAAQ,qBAAqB,KAAA,GAC/B,KAAK,mBAAmB,QAAQ;EAClC,IAAI,QAAQ,qBAAqB,KAAA,GAC/B,KAAK,mBAAmB,gBAAgB,QAAQ,gBAAgB;CACpE;CAEA,MAAe,OAAsB;EACnC,IACE,CAAC;GAAC;GAAa;GAAa;EAAM,CAAA,CAAE,SAAS,KAAK,qBAAqB,GAEvE,MAAM,IAAI,MAAM,+CAA+C;EACjE,IAAI,CAAC,CAAC,QAAQ,UAAU,CAAA,CAAE,SAAS,KAAK,gBAAgB,GACtD,MAAM,IAAI,MAAM,0CAA0C;EAC5D,MAAM,gBAAgB,KAAK,oBAAoB;EAC/C,IAAI,CAAC,eACH,MAAM,IAAI,MAAM,8CAA8C;EAChE,IACE,cAAc,MACX,UACC,CAAC,MAAM,kBAAkB,CAAC,MAAM,OAAO,KAAK,KAAK,CAAC,MAAM,MAAM,KAAK,CACvE,GAEA,MAAM,IAAI,MAAM,uDAAuD;EAIzE,MAAM,cAAc,KAAK,cACrB,KACA,KAAK,YAAY,YAAY,KAAK;EACtC,IAAI,aAAa;GACf,MAAM,EAAE,6BAA6B,MAAM,OAAO,uBAAA,CAAA,MAAA,MAAA,EAAA,CAAA;GAClD,MAAM,yBAAyB,KAAK,IAAI,WAAW;EACrD;EACA,OAAO,KAAK,gBAAgB,YAAY;GACtC,MAAM,EAAE,sBAAsB,MAAM,OAClC,kCAAA,CAAA,MAAA,MAAA,EAAA,CAAA;GAEF,MAAM,EAAE,2BAA2B,MAAM,OACvC,uCAAA,CAAA,MAAA,MAAA,EAAA,CAAA;GAEF,MAAM,QAAQ,MAAM,kBAAkB,OAAO,EAAE,IAAI,KAAK,GAAG,CAAC;GAC5D,MAAM,aAAa,MAAM,uBAAuB,OAAO,EAAE,IAAI,KAAK,GAAG,CAAC;GACtE,KAAA,MAAW,MAAM,CACf,KAAK,uBACL,KAAK,wBACP,CAAA,CAAE,OAAO,OAAO,GAAG;IACjB,MAAM,OAAO,MAAM,MAAM,IAAI,EAAE,GAAG,GAAG,EAAE,OAAO,MAAM,CAAC;IACrD,IAAI,CAAC,QAAQ,KAAK,aAAa,KAAK,UAClC,MAAM,IAAI,MACR,qDACF;GACJ;GACA,KAAA,MAAW,gBAAgB,eAAe;IACxC,MAAM,YAAY,MAAM,WAAW,IACjC,EAAE,IAAI,aAAa,eAAe,GAClC,EAAE,OAAO,MAAM,CACjB;IACA,IAAI,CAAC,aAAa,UAAU,aAAa,KAAK,UAC5C,MAAM,IAAI,MACR,qDACF;GACJ;GACA,OAAQ,MAAM,MAAM,KAAK;EAC3B,CAAC;CACH;CAEQ,sBAAgD;EACtD,IAAI;GACF,MAAM,QAAiB,KAAK,MAAM,KAAK,oBAAoB;GAC3D,IAAI,CAAC,MAAM,QAAQ,KAAK,GAAG,OAAO;GAClC,IACE,MAAM,MACH,UACC,CAAC,SACD,OAAO,UAAU,YACjB,OAAQ,MAA0B,mBAAmB,YACrD,OAAQ,MAA0B,WAAW,YAC7C,OAAQ,MAA0B,UAAU,QAChD,GAEA,OAAO;GACT,OAAO;EACT,QAAQ;GACN,OAAO;EACT;CACF;AACF;AArJ8C,cAAjC,aAAwC,mBAAkB,8BAAA;AAErE,gBAAA,CADC,SAAS,CAAA,GADC,YAEX,WAAA,YAAA,CAAA;AAKA,gBAAA,CAHC,WAAW,WAAW,EACrB,aAAa,4CACf,CAAC,CAAA,GANU,YAOX,WAAA,yBAAA,CAAA;AAKA,gBAAA,CAHC,WAAW,WAAW,EACrB,aAAa,+CACf,CAAC,CAAA,GAXU,YAYX,WAAA,4BAAA,CAAA;AAMA,gBAAA,CAJC,MAAM,EACL,aACE,yEACJ,CAAC,CAAA,GAjBU,YAkBX,WAAA,yBAAA,CAAA;AAGA,gBAAA,CADC,MAAM,EAAE,aAAa,qDAAqD,CAAC,CAAA,GApBjE,YAqBX,WAAA,oBAAA,CAAA;AAWI,gBAAA,CANH,MAAM;CACL,WAAW;CACX,WAAW;CACX,aACE;AACJ,CAAC,CAAA,GA/BU,YAgCP,WAAA,oBAAA,CAAA;AAhCO,cAAN,gBAAA,CAhBN,aAAa,EAAE,MAAM,WAAW,CAAC,GACjC,KAAK;CACJ,iBAAiB,CAAC,WAAW;CAC7B,KAAK;EACH,SAAS;GAAC;GAAO;GAAU;EAAQ;EACnC,UAAU;GACR;GACA;GACA;GACA;GACA;EACF;CACF;CACA,KAAK,EAAE,SAAS,CAAC,KAAK,EAAE;CACxB,KAAK,EAAE,cAAc,KAAK;AAC5B,CAAC,CAAA,GACY,WAAA;;;AC9Bb,eAAsB,mBACpB,UACA,MACA,KACiB;CACjB,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC,IAAI,KAAK,GAChC,MAAM,IAAI,MAAM,gDAAgD;CAClE,MAAM,QAAQ,IAAI,YAAY,CAAA,CAAE,OAC9B,KAAK,UAAU;EAAC;EAAgB;EAAU;EAAM;CAAG,CAAC,CACtD;CAEA,MAAM,OAAO,IADM,WAAW,MAAM,OAAO,OAAO,OAAO,WAAW,KAAK,CAC5D,CAAA,CAAO,MAAM,GAAG,EAAE;CAC/B,KAAK,KAAM,KAAK,KAAK,KAAQ;CAC7B,KAAK,KAAM,KAAK,KAAK,KAAQ;CAE7B,MAAM,SADM,MAAM,KAAK,OAAO,SAAS,KAAK,SAAS,EAAE,CAAA,CAAE,SAAS,GAAG,GAAG,CACzD,CAAA,CAAI,KAAK,EAAE;CAC1B,OAAO,GAAG,OAAO,MAAM,GAAG,CAAC,EAAC,GAAI,OAAO,MAAM,GAAG,EAAE,EAAC,GAAI,OAAO,MAAM,IAAI,EAAE,EAAC,GAAI,OAAO,MAAM,IAAI,EAAE,EAAC,GAAI,OAAO,MAAM,EAAE;AACxH;AAGA,eAAsB,oBACpB,QACA,MACY;CACZ,KAAA,IAAS,UAAU,GAAG,UAAU,GAAG,WACjC,IAAI;EACF,OAAO,MAAM,OAAO;CACtB,SAAS,OAAO;EACd,MAAM,OAAQ,OAAqC;EACnD,IAAI,SAAS,+BAA+B,UAAU,GAAG;EACzD,IAAI,SAAS,kCAAkC,SAAS,SACtD,MAAM;EACR,MAAM,SAAS,MAAM,KAAK;EAC1B,IAAI,CAAC,QAAQ,MAAM;EACnB,OAAO;CACT;CAEF,MAAM,IAAI,MAAM,0BAA0B;AAC5C;;;ACrBA,eAAe,2BACb,IACA,UACe;CACf,IAAI,CAAC,mBAAmB,EAAE,GAAG;CAC7B,MAAM,GAAG,MACP,2DACA,8BAA8B,UAChC;AACF;AAQA,eAAsB,6BACpB,IACA,UACe;CACf,MAAM,KAAK,MAAM,mBAAmB,UAAU,YAAY,SAAS;CACnE,MAAM,6BAA6B,IAAI,mBAAmB,EAAE,GAAG,OAAO,OAAO;EAC3E,MAAM,2BAA2B,IAAI,QAAQ;EAC7C,MAAM,WAAW,MAAM,sBAAsB,OAAO,EAAE,IAAI,GAAG,CAAC;EAC9D,IAAI,MAAM,SAAS,aAAa,QAAQ,GAAG;EAC3C,MAAM,0BACE,SAAS,OAAO;GAAE;GAAI;EAAS,CAAC,GACtC,aACG,MAAM,SAAS,KAAK;GAAE,OAAO,EAAE,SAAS;GAAG,OAAO;EAAE,CAAC,EAAA,CAAG,MAAM,IACnE;CACF,CAAC;AACH;AAEO,IAAM,wBAAN,cAAoC,eAA4B;CACrE,OAAgB,aAAa;;;;;;CAO7B,MAAM,qBAAqB,UAAwC;EACjE,MAAM,yBAAyB,KAAK,IAAI,QAAQ;EAChD,MAAM,WAAW,MAAM,KAAK,aAAa,QAAQ;EACjD,IAAI,UAAU,OAAO;EACrB,MAAM,6BAA6B,KAAK,IAAI,QAAQ;EACpD,MAAM,UAAU,MAAM,KAAK,aAAa,QAAQ;EAChD,IAAI,CAAC,SACH,MAAM,IAAI,qBACR,uBACA,+CACF;EACF,OAAO;CACT;CAEA,MAAM,aAAa,UAA+C;EAChE,MAAM,UAAU,MAAM,KAAK,KAAK;GAAE,OAAO,EAAE,SAAS;GAAG,OAAO;EAAE,CAAC,EAAA,CAAG;EACpE,IAAI,CAAC,QAAQ,IAAI,OAAO,UAAU;EAClC,OAAQ,MAAM,KAAK,IAAI,EAAE,IAAI,OAAO,GAAG,GAAG,EAAE,OAAO,MAAM,CAAC,KAAM;CAClE;;CAGA,MAAM,cAAc,UAAwC;EAC1D,MAAM,QAAQ,MAAM,KAAK,qBAAqB,QAAQ;EACtD,IAAI,CAAC,MAAM,IACT,MAAM,IAAI,qBACR,uBACA,sCACF;EACF,MAAM,yBAAyB,CAC7B;GAAE,IAAI,MAAM;GAAI;GAAU,YAAY;EAAK,CAC7C,CAAC;EACD,MAAM,SAAS,MAAM,KAAK,aAAa,QAAQ;EAC/C,IAAI,CAAC,UAAU,OAAO,OAAO,MAAM,IACjC,MAAM,IAAI,qBACR,uBACA,sDACF;EACF,OAAO;CACT;AACF;;;AC/EA,SAAS,aAAa,OAAe,OAAuB;CAC1D,IAAI,CAAC,SAAS,MAAM,KAAK,MAAM,OAC7B,MAAM,IAAI,qBACR,uBACA,GAAG,MAAK,mCACV;CACF,OAAO;AACT;AAEA,IAAM,sCAAsB,IAAI,QAG9B;AAOF,eAAsB,uBACpB,IACA,UACsB;CACtB,aAAa,UAAU,cAAc;CACrC,MAAM,yBAAyB,IAAI,QAAQ;CAC3C,QAAQ,MAAM,sBAAsB,OAAO,EAAE,IAAI,GAAG,CAAC,EAAA,CAAG,cACtD,QACF;AACF;AAUA,eAAsB,uBACpB,IACA,UACA,WACA,eACY;CACZ,aAAa,UAAU,cAAc;CACrC,IAAI,eAAe;EACjB,IACE,cAAc,UAAU,aACxB,cAAc,OAAO,MACrB,cAAc,aAAa,UAE3B,MAAM,IAAI,qBACR,uBACA,kEACF;EACF,OAAO,UAAU,aAAa;CAChC;CACA,OAAO,6BAA6B,IAAI,OAAO,OAAO;EACpD,MAAM,SAAS,oBAAoB,IAAI,EAAY,CAAA,EAAG,IAAI,QAAQ;EAClE,IAAI,QAAQ,OAAO,UAAU,MAAM;EAEnC,MAAM,QAAQ;GACZ,IAAI;GACJ;GACA,UAAA,MAJqB,uBAAuB,IAAI,QAAQ;GAKxD,OAAO;EACT;EACA,MAAM,SAAS,oBAAoB,IAAI,EAAY,qBAAK,IAAI,IAAI;EAChE,OAAO,IAAI,UAAU,KAAK;EAC1B,oBAAoB,IAAI,IAAc,MAAM;EAC5C,IAAI;GACF,OAAO,MAAM,UAAU,KAAK;EAC9B,UAAE;GACA,OAAO,OAAO,QAAQ;GACtB,IAAI,OAAO,SAAS,GAAG,oBAAoB,OAAO,EAAY;EAChE;CACF,CAAC;AACH;AAMA,eAAsB,8BACpB,IACA,UACA,WACY;CACZ,MAAM,yBAAyB,IAAI,QAAQ;CAC3C,OAAO,UAAU,EAAE;AACrB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types-Bbm0Xflc.js","names":["CustomerStatus","CustomerType","VendorStatus","ContractType","ContractStatus","FulfillmentType","FulfillmentStatus","PaymentMethod","PaymentStatus","PaymentInstrumentStatus","PayoutStatus","PaymentIntentStatus","InvoiceStatus"],"sources":["../../src/types/index.ts"],"sourcesContent":["/**\n * Commerce package type definitions\n * @packageDocumentation\n */\n\nimport type { SmrtObjectOptions } from '@happyvertical/smrt-core';\nimport type {\n InvoiceCalculationContext,\n InvoiceLineDraft,\n} from '../svelte/invoices/calculations.js';\n\n// ============================================================================\n// Customer/Vendor Types\n// ============================================================================\n\nexport enum CustomerStatus {\n ACTIVE = 'active',\n INACTIVE = 'inactive',\n SUSPENDED = 'suspended',\n}\n\n/**\n * Customer classification — drives channel access, pricing tier, and credit terms.\n *\n * - DTC: direct-to-consumer (end shopper). Pays via storefront checkout.\n * - WHOLESALE: B2B buyer with negotiated terms (NET-30, line sheets, etc.).\n * - RETAIL: in-store walk-in / point-of-sale customer.\n */\nexport enum CustomerType {\n DTC = 'dtc',\n WHOLESALE = 'wholesale',\n RETAIL = 'retail',\n}\n\nexport enum VendorStatus {\n ACTIVE = 'active',\n INACTIVE = 'inactive',\n SUSPENDED = 'suspended',\n}\n\n// ============================================================================\n// Contract Types\n// ============================================================================\n\nexport enum ContractType {\n ESTIMATE = 'estimate',\n ORDER = 'order',\n LEASE = 'lease',\n AGREEMENT = 'agreement',\n SUPPLIER_QUOTE = 'supplier_quote',\n PURCHASE_ORDER = 'purchase_order',\n WHOLESALE_ORDER = 'wholesale_order',\n PRODUCTION_ORDER = 'production_order',\n CART = 'cart',\n /**\n * Industry-neutral licensing primitive. The `LicenseSale` STI subtype\n * carries an immutable rights snapshot, a licensee email, optional\n * legal-entity / jurisdiction fields, and a signed-PDF reference.\n * Any application that sells rights for a fee (stock media,\n * music licensing, code-asset marketplace, license keys, etc.)\n * uses this subtype.\n */\n LICENSE_SALE = 'license_sale',\n}\n\nexport enum ContractStatus {\n DRAFT = 'draft',\n SENT = 'sent',\n ACCEPTED = 'accepted',\n DECLINED = 'declined',\n COMPLETED = 'completed',\n CANCELLED = 'cancelled',\n}\n\n// ============================================================================\n// Fulfillment Types\n// ============================================================================\n\nexport enum FulfillmentType {\n SHIPMENT = 'shipment',\n DELIVERY = 'delivery',\n PICKUP = 'pickup',\n DIGITAL = 'digital',\n SERVICE = 'service',\n}\n\nexport enum FulfillmentStatus {\n PENDING = 'pending',\n PROCESSING = 'processing',\n SHIPPED = 'shipped',\n DELIVERED = 'delivered',\n CANCELLED = 'cancelled',\n}\n\n// ============================================================================\n// Payment Types\n// ============================================================================\n\nexport enum PaymentMethod {\n CASH = 'cash',\n CHECK = 'check',\n CREDIT_CARD = 'credit_card',\n BANK_TRANSFER = 'bank_transfer',\n CRYPTO = 'crypto',\n OTHER = 'other',\n}\n\nexport enum PaymentStatus {\n PENDING = 'pending',\n COMPLETED = 'completed',\n FAILED = 'failed',\n REFUNDED = 'refunded',\n CANCELLED = 'cancelled',\n}\n\nexport type PaymentKind = 'payment' | 'refund';\n\n/**\n * Lifecycle status for a saved {@link PaymentInstrument} (card on file).\n * `active` while chargeable, `expired` once the card lapses, `removed` when the\n * customer detaches it.\n */\nexport enum PaymentInstrumentStatus {\n ACTIVE = 'active',\n EXPIRED = 'expired',\n REMOVED = 'removed',\n}\n\n// ============================================================================\n// Payout Types\n// ============================================================================\n\n/**\n * Status machine for {@link Payout}.\n *\n * `pending → sent → confirmed → failed`. `failed` is terminal but the\n * model exposes a dedicated `resetFromFailed()` so an operator can\n * deliberately requeue a payout after fixing the underlying problem;\n * the reset moves the row back to `pending` and clears the failure\n * metadata.\n *\n * Skipping intermediate states is rejected — a `pending` payout cannot\n * jump straight to `confirmed`, and a `sent` payout cannot regress to\n * `pending` without going through `resetFromFailed()` first.\n */\nexport enum PayoutStatus {\n PENDING = 'pending',\n SENT = 'sent',\n CONFIRMED = 'confirmed',\n FAILED = 'failed',\n}\n\n// ============================================================================\n// PaymentIntent Types\n// ============================================================================\n\n/**\n * Status machine for {@link PaymentIntent}.\n *\n * `awaiting_payment → paid → (issued | retired)`, with `expired` and\n * `cancelled` as alternate terminal states reachable from\n * `awaiting_payment`.\n *\n * - `AWAITING_PAYMENT` — open quote, accepting any of the listed\n * payment options.\n * - `PAID` — one option was satisfied by an incoming payment. The\n * other options are implicitly retired; later inbound funds to a\n * retired option must be flagged for refund by the consumer.\n * - `ISSUED` — downstream rights / contract / fulfillment have been\n * created and linked. Terminal happy-path state.\n * - `RETIRED` — paid but the satisfaction was reversed (refund,\n * chargeback, etc.). Terminal.\n * - `EXPIRED` — the USD-price-lock window passed without payment.\n * Terminal.\n * - `CANCELLED` — the buyer or the system explicitly cancelled the\n * intent before it was paid. Terminal.\n */\nexport enum PaymentIntentStatus {\n AWAITING_PAYMENT = 'awaiting_payment',\n PAID = 'paid',\n ISSUED = 'issued',\n RETIRED = 'retired',\n EXPIRED = 'expired',\n CANCELLED = 'cancelled',\n}\n\n/**\n * One way for a {@link PaymentIntent} to be satisfied. The intent lists\n * an array of these; satisfying any one of them transitions the intent\n * to `PAID` and implicitly retires the rest.\n *\n * Industry-neutral: a marketplace that accepts USDC-on-Base and BTC\n * lists two options; a SaaS billing flow that accepts Stripe and\n * PayPal lists two; a kiosk that accepts only one rail lists one.\n */\nexport interface PaymentOption {\n /**\n * Stable id of the `PaymentBackend` adapter that fulfills this\n * option — must match a `backendId` the consumer's payment-routing\n * layer recognises. Examples: `base-usdc`, `solana-usdc`, `btc`,\n * `stripe`, `paypal`.\n */\n backendId: string;\n /**\n * Payout-rail-qualified currency code, e.g. `USDC-base`, `BTC`,\n * `USD-stripe`. The same convention used by\n * `Vendor.payoutAddresses` and `Payment.nativeCurrency`.\n */\n currency: string;\n /**\n * Optional chain identifier for blockchain-backed options (`base`,\n * `ethereum`, `solana`, ...). Pure-fiat options leave this empty.\n */\n chain?: string;\n /**\n * Destination address / account id the buyer should send funds to\n * for this option (EVM address, BTC address, Stripe payment-intent\n * id, etc.).\n */\n payTo: string;\n /**\n * Amount denominated in `currency`. Stored at decimal precision —\n * a USDC option might be `199.0`, a BTC option `0.00713`.\n */\n nativeAmount: number;\n /**\n * Optional on-chain memo / payment reference (Solana memo, BTC OP_RETURN\n * tag, Stripe metadata key). Some backends use this to disambiguate\n * which intent an inbound payment satisfies.\n */\n memo?: string;\n /**\n * Whether this option supports the x402 HTTP-402 payment-required\n * flow. Consumers that build agent-driven flows use this flag to\n * filter the offered options.\n */\n x402Capable?: boolean;\n /**\n * Optional per-option expiry — when a single rail's quote becomes\n * stale earlier than the intent-wide price-lock window (e.g. a\n * volatile-currency option that re-quotes more aggressively). ISO\n * 8601 string. Empty / missing means \"inherit the intent's\n * `priceLockExpiresAt`\".\n */\n expiresAt?: string;\n}\n\n// ============================================================================\n// Invoice Types\n// ============================================================================\n\nexport enum InvoiceStatus {\n DRAFT = 'draft',\n SENT = 'sent',\n VIEWED = 'viewed',\n PARTIAL = 'partial',\n PAID = 'paid',\n OVERDUE = 'overdue',\n CANCELLED = 'cancelled',\n WRITTEN_OFF = 'written_off',\n}\n\n// ============================================================================\n// Common Interfaces\n// ============================================================================\n\n/**\n * Address structure used for billing and shipping\n */\nexport interface Address {\n street1?: string;\n street2?: string;\n city?: string;\n state?: string;\n postalCode?: string;\n country?: string;\n}\n\n/**\n * A person to reach at a customer or vendor, stored on the party row\n * (`Customer.contacts` / `Vendor.contacts`, #3501). Every field is plain\n * text; `id` is a stable random identifier assigned when the row is first\n * saved. Write rows through `savePartyContacts()`.\n */\nexport interface PartyContact {\n id: string;\n name: string;\n /** Role or relationship, for example \"Accounts payable\". */\n label: string;\n email: string;\n phone: string;\n address: string;\n}\n\n/**\n * Options for recording a payment with ledger integration\n */\nexport interface RecordPaymentOptions {\n /** The ledger to record the journal entry in */\n ledgerId: string;\n /** Account ID for receivables (credit side) */\n receivablesAccountId: string;\n /** Account ID for cash/bank (debit side) */\n cashAccountId: string;\n}\n\n/**\n * Options for recognizing revenue on an invoice\n */\nexport interface RecognizeRevenueOptions {\n /** Account ID for accounts receivable (debit side) */\n arAccountId: string;\n /** Account ID for revenue (credit side) */\n revenueAccountId: string;\n /** Account ID for tax payable (credit side, optional) */\n taxAccountId?: string;\n /** Explicit ledger book currency. Required when the tenant uses money v2. */\n bookCurrency?: string;\n}\n\n/** Options for atomically cancelling a posted money-v2 invoice. */\nexport interface CancelRevenueOptions {\n /** Explicit ledger book currency; required for money-v2 cancellation. */\n bookCurrency?: string;\n}\n\n// ============================================================================\n// Accounting-provider sync shapes\n// ============================================================================\n\n/**\n * A single line item in the format expected by `@happyvertical/accounting`\n * providers (QBO, Stripe, …). Mirrors the object built by\n * {@link InvoiceLineItem.toAccountingLineItem}. The SDK isn't a dependency of\n * this package, so the shape is declared locally rather than imported.\n */\nexport interface AccountingLineItemInput {\n description: string;\n sku?: string;\n quantity: number;\n unitPrice: number;\n discount?: number;\n taxRate?: number;\n amount: number;\n periodStart?: Date;\n periodEnd?: Date;\n}\n\n/**\n * An invoice in the format expected by `@happyvertical/accounting` providers.\n * Mirrors the object built by {@link Invoice.toAccountingInput}; money is in\n * currency **major** units, as the SDK expects.\n */\nexport interface AccountingInvoiceInput {\n id: string;\n externalId?: string;\n invoiceNumber: string;\n customerId: string;\n customerExternalId?: string;\n issueDate: Date;\n dueDate: Date;\n lineItems: AccountingLineItemInput[];\n subtotal: number;\n taxAmount: number;\n totalAmount: number;\n currency: string;\n reference?: string;\n memo?: string;\n idempotencyKey?: string;\n quickbooksRequest?: {\n readonly requestId: string;\n readonly realmId: string;\n readonly environment: 'sandbox' | 'production';\n readonly payloadHash: string;\n };\n quickbooksMapping?: {\n globalTaxCalculation: 'TaxExcluded' | 'NotApplicable';\n };\n}\n\n// ============================================================================\n// Model constructor option interfaces\n//\n// Each model's `constructor(options)` accepts a partial bag of its own fields.\n// Declaring a dedicated `XxxOptions extends SmrtObjectOptions` interface keeps\n// the constructors strongly typed (no `any`) while still allowing the\n// framework's base options (db, ai, fs, _className, …) through.\n// ============================================================================\n\n/**\n * Constructor options for {@link Customer}.\n */\nexport interface CustomerOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n profileId?: string;\n creditLimit?: number;\n paymentTerms?: string;\n taxExempt?: boolean;\n taxId?: string;\n defaultTaxCodeId?: string;\n defaultShippingAddress?: Address;\n defaultBillingAddress?: Address;\n status?: CustomerStatus;\n customerType?: CustomerType | null;\n notes?: string;\n contacts?: PartyContact[] | string | null;\n}\n\n/**\n * Constructor options for {@link Vendor}.\n */\nexport interface VendorOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n profileId?: string;\n leadTimeDays?: number;\n minimumOrderAmount?: number;\n paymentTerms?: string;\n currency?: string;\n taxId?: string;\n defaultTaxCodeId?: string;\n defaultContactEmail?: string;\n defaultContactPhone?: string;\n status?: VendorStatus;\n notes?: string;\n payoutAddresses?: Record<string, string> | string | null;\n contacts?: PartyContact[] | string | null;\n}\n\n/** A component reference stored in a tax code's ordered component list. */\nexport interface TaxCodePart {\n taxComponentId: string;\n compound: boolean;\n}\n\nexport interface TaxComponentOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n name?: string;\n percent?: string;\n liabilityAccountId?: string;\n recoverable?: boolean;\n active?: boolean;\n}\n\nexport interface TaxCodeOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n code?: string;\n name?: string;\n kind?: 'taxable' | 'zero-rated' | 'exempt' | 'out-of-scope';\n appliesTo?: 'sales' | 'purchases' | 'both';\n components?: TaxCodePart[];\n active?: boolean;\n}\n\nexport interface TaxRegistrationOptions {\n taxComponentId: string;\n number: string;\n label: string;\n}\n\nexport interface TaxSettingsOptions extends SmrtObjectOptions {\n tenantId?: string;\n defaultSalesTaxCodeId?: string;\n defaultPurchaseTaxCodeId?: string;\n defaultLineAmountType?: 'exclusive' | 'inclusive' | 'none';\n taxRoundingScope?: 'line' | 'document';\n taxRegistrations?: TaxRegistrationOptions[];\n moneyModel?: 'legacy' | 'migrating' | 'v2';\n moneyMigrationId?: string;\n}\n\n/**\n * Constructor options for {@link Contract} and its STI subtypes.\n */\nexport interface ContractOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n contractType?: ContractType;\n status?: ContractStatus;\n subtotal?: number;\n discountTotal?: number;\n taxAmount?: number;\n totalAmount?: number;\n currency?: string;\n issueDate?: Date;\n dueDate?: Date | null;\n expiryDate?: Date | null;\n reference?: string;\n notes?: string;\n terms?: string;\n channelId?: string;\n lineAmountType?: 'exclusive' | 'inclusive' | 'none';\n taxRoundingScope?: 'line' | 'document';\n sellerTaxRegistrations?: TaxRegistrationOptions[];\n sellerTaxRegistrationsJson?: string;\n partyTaxId?: string;\n moneySnapshotId?: string;\n}\n\nexport interface SalesContractOptions extends ContractOptions {\n customerId?: string | null;\n}\n\nexport interface PurchaseContractOptions extends ContractOptions {\n vendorId?: string | null;\n}\n\n/** Purchase-order header options stored in the existing STI metadata. */\nexport interface PurchaseOrderOptions extends PurchaseContractOptions {\n /** Expected delivery calendar date (YYYY-MM-DD); empty means unspecified. */\n expectedDate?: string;\n /** Delivery address/instructions snapshot. */\n shipTo?: string;\n}\n\n/**\n * Constructor options for {@link LicenseSale} (Contract STI subtype). Extends\n * {@link ContractOptions} with the licensing-specific meta fields.\n */\nexport interface LicenseSaleOptions extends SalesContractOptions {\n skuId?: string;\n paymentId?: string;\n licenseeEmail?: string;\n licenseeLegalEntity?: string;\n licenseeJurisdiction?: string;\n rightsMedium?: string;\n rightsDistributionScope?: string;\n rightsExclusivity?: string;\n rightsDuration?: string;\n rightsTerritory?: string;\n rightsSublicensing?: boolean;\n rightsDerivatives?: boolean;\n pdfUrl?: string;\n pdfHash?: string;\n onChainHashRegistryRef?: string;\n}\n\n/**\n * Constructor options for {@link ContractLineItem}.\n */\nexport interface ContractLineItemOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n contractId?: string;\n description?: string;\n quantity?: number;\n unitPrice?: number;\n discount?: number;\n discountType?: 'none' | 'percent' | 'amount';\n discountRate?: string;\n taxRate?: number;\n taxMode?: 'inherit' | 'override';\n taxCodeId?: string | null;\n taxCodeCode?: string | null;\n taxCodeName?: string | null;\n taxComponents?: ContractTaxComponentSnapshot[];\n taxComponentsJson?: string | null;\n taxAmount?: number;\n legacyAmount?: number | null;\n moneySnapshotId?: string;\n amount?: number;\n productId?: string;\n sku?: string;\n startDate?: Date | null;\n endDate?: Date | null;\n billingPeriod?: string;\n sortOrder?: number;\n}\n\n/** Immutable component tax allocation for one Contract line. */\nexport interface ContractTaxComponentSnapshot {\n taxComponentId: string;\n name: string;\n percent: string;\n taxMinor: number;\n}\n\n/**\n * How the provider collects an invoice (#3190): `charge_automatically`\n * charges the payer's saved card; `send_invoice` asks the payer to pay. Empty\n * for an invoice never pushed to a provider, or pushed before it was recorded.\n */\nexport type InvoiceCollectionMethod =\n | ''\n | 'send_invoice'\n | 'charge_automatically';\n\nexport type InvoiceKind = 'invoice' | 'credit_note';\n\n/** Frozen source pricing plus the one authoritative credit calculation basis. */\nexport type InvoiceCreditCalculationBasis =\n | {\n kind: 'quantity';\n quantity: string;\n sourceQuantity: string;\n sourceUnitPrice: number;\n sourceDiscountType: 'none' | 'percent' | 'amount';\n sourceDiscountRate: string;\n sourceDiscountMinor: number;\n }\n | {\n kind: 'net_amount';\n netMinor: number;\n sourceQuantity: string;\n sourceUnitPrice: number;\n sourceDiscountType: 'none' | 'percent' | 'amount';\n sourceDiscountRate: string;\n sourceDiscountMinor: number;\n };\n\n/**\n * Constructor options for {@link Invoice}.\n */\nexport interface InvoiceOptions extends SmrtObjectOptions {\n kind?: InvoiceKind;\n creditedInvoiceId?: string | null;\n creditedAmount?: number;\n tenantId?: string | null;\n customerId?: string;\n contractId?: string;\n invoiceNumber?: string;\n reference?: string;\n issueDate?: Date;\n dueDate?: Date;\n paidDate?: Date | null;\n subtotal?: number;\n taxAmount?: number;\n providerTaxAmount?: number;\n totalAmount?: number;\n amountPaid?: number;\n currency?: string;\n status?: InvoiceStatus;\n arJournalId?: string;\n arReversalJournalId?: string | null;\n revenueJournalId?: string;\n externalId?: string;\n customerExternalId?: string;\n externalProvider?: string;\n syncedAt?: Date | null;\n collectionMethod?: InvoiceCollectionMethod;\n sentAt?: Date | null;\n viewedAt?: Date | null;\n remindersSent?: number;\n lastReminderAt?: Date | null;\n notes?: string;\n customerNotes?: string;\n terms?: string;\n lineAmountType?: 'exclusive' | 'inclusive' | 'none';\n taxRoundingScope?: 'line' | 'document';\n discountTotal?: number;\n sellerTaxRegistrations?: TaxRegistrationOptions[];\n sellerTaxRegistrationsJson?: string;\n partyTaxId?: string;\n moneySnapshotId?: string;\n accountingSyncStateJson?: string;\n}\n\nexport interface InvoiceTaxComponentSnapshot {\n taxComponentId: string;\n name: string;\n percent: string;\n taxMinor: number;\n}\n\n/** Retained editing modes, validated against resolved model fields before reuse. */\nexport interface InvoiceLineEditorState {\n /** Lossless editor draft; never authoritative for ordinary model saves. */\n draft: InvoiceLineDraft;\n /** Context used to resolve that draft; caller authority must still match on reload. */\n context: InvoiceCalculationContext;\n}\n\n/** Constructor options for {@link InvoiceLineItem}. */\nexport interface InvoiceLineItemOptions extends SmrtObjectOptions {\n creditedLineId?: string | null;\n creditCalculationBasis?: InvoiceCreditCalculationBasis | null;\n creditCalculationBasisJson?: string;\n /** Optional retained editor modes and their original calculation context. */\n invoiceEditorState?: InvoiceLineEditorState | null;\n /** Serialized editor state loaded from persistence; malformed JSON is ignored. */\n invoiceEditorStateJson?: string;\n tenantId?: string | null;\n invoiceId?: string;\n description?: string;\n sku?: string;\n productId?: string | null;\n quantity?: number;\n unitPrice?: number;\n discount?: number;\n discountType?: 'none' | 'percent' | 'amount';\n discountRate?: string;\n taxRate?: number;\n taxMode?: 'inherit' | 'override';\n taxCodeId?: string | null;\n taxCodeCode?: string | null;\n taxCodeName?: string | null;\n taxComponents?: InvoiceTaxComponentSnapshot[];\n taxComponentsJson?: string | null;\n taxAmount?: number;\n legacyAmount?: number | null;\n moneySnapshotId?: string;\n amount?: number;\n sourceType?: string;\n sourceId?: string;\n periodStart?: Date | null;\n periodEnd?: Date | null;\n revenueAccountId?: string | null;\n sortOrder?: number;\n}\n\n/**\n * Constructor options for {@link Fulfillment}.\n */\nexport interface FulfillmentOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n contractId?: string;\n fulfillmentType?: FulfillmentType;\n status?: FulfillmentStatus;\n trackingNumber?: string;\n carrier?: string;\n shippingAddress?: Address;\n shippedAt?: Date | null;\n deliveredAt?: Date | null;\n estimatedDelivery?: Date | null;\n notes?: string;\n}\n\n/**\n * Constructor options for {@link FulfillmentLineItem}.\n */\nexport interface FulfillmentLineItemOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n fulfillmentId?: string;\n contractLineItemId?: string;\n quantityFulfilled?: number;\n notes?: string;\n}\n\n/**\n * Constructor options for {@link Payment}.\n */\nexport interface PaymentOptions extends SmrtObjectOptions {\n kind?: PaymentKind;\n tenantId?: string | null;\n contractId?: string | null;\n customerId?: string | null;\n amount?: number;\n currency?: string;\n method?: PaymentMethod;\n status?: PaymentStatus;\n transactionId?: string;\n reference?: string;\n journalId?: string;\n paidAt?: Date | null;\n notes?: string;\n externalId?: string;\n externalProvider?: string;\n syncedAt?: Date | null;\n backendId?: string;\n backendTxRef?: string;\n nativeAmount?: number;\n nativeCurrency?: string;\n usdAtQuote?: number;\n usdAtConfirmation?: number;\n}\n\n/**\n * Constructor options for {@link PaymentInstrument}.\n */\nexport interface PaymentInstrumentOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n customerId?: string;\n backendId?: string;\n providerCustomerId?: string;\n providerPaymentMethodId?: string;\n type?: string;\n brand?: string;\n last4?: string;\n expMonth?: number;\n expYear?: number;\n isDefault?: boolean;\n status?: PaymentInstrumentStatus;\n}\n\n/**\n * Constructor options for {@link PaymentAllocation}.\n */\nexport interface PaymentAllocationOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n paymentId?: string;\n invoiceId?: string;\n amount?: number;\n allocatedAt?: Date;\n allocatedBy?: string;\n notes?: string;\n}\n\n/**\n * Constructor options for {@link PaymentIntent}.\n */\nexport interface PaymentIntentOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n skuId?: string;\n offeringRef?: string;\n licenseeEmail?: string;\n customerId?: string;\n paymentOptions?: PaymentOption[] | string;\n usdPriceLocked?: number;\n priceLockWindowMs?: number;\n priceLockExpiresAt?: Date | number | string | null;\n status?: PaymentIntentStatus;\n idempotencyKey?: string;\n paidOptionBackendId?: string;\n paymentId?: string;\n paidAt?: Date | number | string | null;\n issuedAt?: Date | number | string | null;\n expiredAt?: Date | number | string | null;\n cancelledAt?: Date | number | string | null;\n retiredAt?: Date | number | string | null;\n notes?: string;\n}\n\n/**\n * Constructor options for {@link Payout}.\n */\nexport interface PayoutOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n paymentId?: string;\n vendorId?: string;\n grossAmount?: number;\n operatorFee?: number;\n supplierNet?: number;\n currency?: string;\n backendId?: string;\n backendTxRef?: string;\n status?: PayoutStatus;\n sentAt?: Date | number | string | null;\n confirmedAt?: Date | number | string | null;\n failedAt?: Date | number | string | null;\n failureReason?: string;\n notes?: string;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAeO,IAAK,iBAAL,kBAAKA,oBAAL;CACLA,gBAAA,YAAS;CACTA,gBAAA,cAAW;CACXA,gBAAA,eAAY;CAHF,OAAAA;AAAA,EAAA,CAAA,kBAAA,CAAA,CAAA;AAaL,IAAK,eAAL,kBAAKC,kBAAL;CACLA,cAAA,SAAM;CACNA,cAAA,eAAY;CACZA,cAAA,YAAS;CAHC,OAAAA;AAAA,EAAA,CAAA,gBAAA,CAAA,CAAA;AAML,IAAK,eAAL,kBAAKC,kBAAL;CACLA,cAAA,YAAS;CACTA,cAAA,cAAW;CACXA,cAAA,eAAY;CAHF,OAAAA;AAAA,EAAA,CAAA,gBAAA,CAAA,CAAA;AAUL,IAAK,eAAL,kBAAKC,kBAAL;CACLA,cAAA,cAAW;CACXA,cAAA,WAAQ;CACRA,cAAA,WAAQ;CACRA,cAAA,eAAY;CACZA,cAAA,oBAAiB;CACjBA,cAAA,oBAAiB;CACjBA,cAAA,qBAAkB;CAClBA,cAAA,sBAAmB;CACnBA,cAAA,UAAO;CASPA,cAAA,kBAAe;CAlBL,OAAAA;AAAA,EAAA,CAAA,gBAAA,CAAA,CAAA;AAqBL,IAAK,iBAAL,kBAAKC,oBAAL;CACLA,gBAAA,WAAQ;CACRA,gBAAA,UAAO;CACPA,gBAAA,cAAW;CACXA,gBAAA,cAAW;CACXA,gBAAA,eAAY;CACZA,gBAAA,eAAY;CANF,OAAAA;AAAA,EAAA,CAAA,kBAAA,CAAA,CAAA;AAaL,IAAK,kBAAL,kBAAKC,qBAAL;CACLA,iBAAA,cAAW;CACXA,iBAAA,cAAW;CACXA,iBAAA,YAAS;CACTA,iBAAA,aAAU;CACVA,iBAAA,aAAU;CALA,OAAAA;AAAA,EAAA,CAAA,mBAAA,CAAA,CAAA;AAQL,IAAK,oBAAL,kBAAKC,uBAAL;CACLA,mBAAA,aAAU;CACVA,mBAAA,gBAAa;CACbA,mBAAA,aAAU;CACVA,mBAAA,eAAY;CACZA,mBAAA,eAAY;CALF,OAAAA;AAAA,EAAA,CAAA,qBAAA,CAAA,CAAA;AAYL,IAAK,gBAAL,kBAAKC,mBAAL;CACLA,eAAA,UAAO;CACPA,eAAA,WAAQ;CACRA,eAAA,iBAAc;CACdA,eAAA,mBAAgB;CAChBA,eAAA,YAAS;CACTA,eAAA,WAAQ;CANE,OAAAA;AAAA,EAAA,CAAA,iBAAA,CAAA,CAAA;AASL,IAAK,gBAAL,kBAAKC,mBAAL;CACLA,eAAA,aAAU;CACVA,eAAA,eAAY;CACZA,eAAA,YAAS;CACTA,eAAA,cAAW;CACXA,eAAA,eAAY;CALF,OAAAA;AAAA,EAAA,CAAA,iBAAA,CAAA,CAAA;AAeL,IAAK,0BAAL,kBAAKC,6BAAL;CACLA,yBAAA,YAAS;CACTA,yBAAA,aAAU;CACVA,yBAAA,aAAU;CAHA,OAAAA;AAAA,EAAA,CAAA,2BAAA,CAAA,CAAA;AAuBL,IAAK,eAAL,kBAAKC,kBAAL;CACLA,cAAA,aAAU;CACVA,cAAA,UAAO;CACPA,cAAA,eAAY;CACZA,cAAA,YAAS;CAJC,OAAAA;AAAA,EAAA,CAAA,gBAAA,CAAA,CAAA;AAgCL,IAAK,sBAAL,kBAAKC,yBAAL;CACLA,qBAAA,sBAAmB;CACnBA,qBAAA,UAAO;CACPA,qBAAA,YAAS;CACTA,qBAAA,aAAU;CACVA,qBAAA,aAAU;CACVA,qBAAA,eAAY;CANF,OAAAA;AAAA,EAAA,CAAA,uBAAA,CAAA,CAAA;AA0EL,IAAK,gBAAL,kBAAKC,mBAAL;CACLA,eAAA,WAAQ;CACRA,eAAA,UAAO;CACPA,eAAA,YAAS;CACTA,eAAA,aAAU;CACVA,eAAA,UAAO;CACPA,eAAA,aAAU;CACVA,eAAA,eAAY;CACZA,eAAA,iBAAc;CARJ,OAAAA;AAAA,EAAA,CAAA,iBAAA,CAAA,CAAA"}
|
|
1
|
+
{"version":3,"file":"types-Bbm0Xflc.js","names":["CustomerStatus","CustomerType","VendorStatus","ContractType","ContractStatus","FulfillmentType","FulfillmentStatus","PaymentMethod","PaymentStatus","PaymentInstrumentStatus","PayoutStatus","PaymentIntentStatus","InvoiceStatus"],"sources":["../../src/types/index.ts"],"sourcesContent":["/**\n * Commerce package type definitions\n * @packageDocumentation\n */\n\nimport type { SmrtObjectOptions } from '@happyvertical/smrt-core';\n\n// ============================================================================\n// Customer/Vendor Types\n// ============================================================================\n\nexport enum CustomerStatus {\n ACTIVE = 'active',\n INACTIVE = 'inactive',\n SUSPENDED = 'suspended',\n}\n\n/**\n * Customer classification — drives channel access, pricing tier, and credit terms.\n *\n * - DTC: direct-to-consumer (end shopper). Pays via storefront checkout.\n * - WHOLESALE: B2B buyer with negotiated terms (NET-30, line sheets, etc.).\n * - RETAIL: in-store walk-in / point-of-sale customer.\n */\nexport enum CustomerType {\n DTC = 'dtc',\n WHOLESALE = 'wholesale',\n RETAIL = 'retail',\n}\n\nexport enum VendorStatus {\n ACTIVE = 'active',\n INACTIVE = 'inactive',\n SUSPENDED = 'suspended',\n}\n\n// ============================================================================\n// Contract Types\n// ============================================================================\n\nexport enum ContractType {\n ESTIMATE = 'estimate',\n ORDER = 'order',\n LEASE = 'lease',\n AGREEMENT = 'agreement',\n SUPPLIER_QUOTE = 'supplier_quote',\n PURCHASE_ORDER = 'purchase_order',\n WHOLESALE_ORDER = 'wholesale_order',\n PRODUCTION_ORDER = 'production_order',\n CART = 'cart',\n /**\n * Industry-neutral licensing primitive. The `LicenseSale` STI subtype\n * carries an immutable rights snapshot, a licensee email, optional\n * legal-entity / jurisdiction fields, and a signed-PDF reference.\n * Any application that sells rights for a fee (stock media,\n * music licensing, code-asset marketplace, license keys, etc.)\n * uses this subtype.\n */\n LICENSE_SALE = 'license_sale',\n}\n\nexport enum ContractStatus {\n DRAFT = 'draft',\n SENT = 'sent',\n ACCEPTED = 'accepted',\n DECLINED = 'declined',\n COMPLETED = 'completed',\n CANCELLED = 'cancelled',\n}\n\n// ============================================================================\n// Fulfillment Types\n// ============================================================================\n\nexport enum FulfillmentType {\n SHIPMENT = 'shipment',\n DELIVERY = 'delivery',\n PICKUP = 'pickup',\n DIGITAL = 'digital',\n SERVICE = 'service',\n}\n\nexport enum FulfillmentStatus {\n PENDING = 'pending',\n PROCESSING = 'processing',\n SHIPPED = 'shipped',\n DELIVERED = 'delivered',\n CANCELLED = 'cancelled',\n}\n\n// ============================================================================\n// Payment Types\n// ============================================================================\n\nexport enum PaymentMethod {\n CASH = 'cash',\n CHECK = 'check',\n CREDIT_CARD = 'credit_card',\n BANK_TRANSFER = 'bank_transfer',\n CRYPTO = 'crypto',\n OTHER = 'other',\n}\n\nexport enum PaymentStatus {\n PENDING = 'pending',\n COMPLETED = 'completed',\n FAILED = 'failed',\n REFUNDED = 'refunded',\n CANCELLED = 'cancelled',\n}\n\nexport type PaymentKind = 'payment' | 'refund';\n\n/**\n * Lifecycle status for a saved {@link PaymentInstrument} (card on file).\n * `active` while chargeable, `expired` once the card lapses, `removed` when the\n * customer detaches it.\n */\nexport enum PaymentInstrumentStatus {\n ACTIVE = 'active',\n EXPIRED = 'expired',\n REMOVED = 'removed',\n}\n\n// ============================================================================\n// Payout Types\n// ============================================================================\n\n/**\n * Status machine for {@link Payout}.\n *\n * `pending → sent → confirmed → failed`. `failed` is terminal but the\n * model exposes a dedicated `resetFromFailed()` so an operator can\n * deliberately requeue a payout after fixing the underlying problem;\n * the reset moves the row back to `pending` and clears the failure\n * metadata.\n *\n * Skipping intermediate states is rejected — a `pending` payout cannot\n * jump straight to `confirmed`, and a `sent` payout cannot regress to\n * `pending` without going through `resetFromFailed()` first.\n */\nexport enum PayoutStatus {\n PENDING = 'pending',\n SENT = 'sent',\n CONFIRMED = 'confirmed',\n FAILED = 'failed',\n}\n\n// ============================================================================\n// PaymentIntent Types\n// ============================================================================\n\n/**\n * Status machine for {@link PaymentIntent}.\n *\n * `awaiting_payment → paid → (issued | retired)`, with `expired` and\n * `cancelled` as alternate terminal states reachable from\n * `awaiting_payment`.\n *\n * - `AWAITING_PAYMENT` — open quote, accepting any of the listed\n * payment options.\n * - `PAID` — one option was satisfied by an incoming payment. The\n * other options are implicitly retired; later inbound funds to a\n * retired option must be flagged for refund by the consumer.\n * - `ISSUED` — downstream rights / contract / fulfillment have been\n * created and linked. Terminal happy-path state.\n * - `RETIRED` — paid but the satisfaction was reversed (refund,\n * chargeback, etc.). Terminal.\n * - `EXPIRED` — the USD-price-lock window passed without payment.\n * Terminal.\n * - `CANCELLED` — the buyer or the system explicitly cancelled the\n * intent before it was paid. Terminal.\n */\nexport enum PaymentIntentStatus {\n AWAITING_PAYMENT = 'awaiting_payment',\n PAID = 'paid',\n ISSUED = 'issued',\n RETIRED = 'retired',\n EXPIRED = 'expired',\n CANCELLED = 'cancelled',\n}\n\n/**\n * One way for a {@link PaymentIntent} to be satisfied. The intent lists\n * an array of these; satisfying any one of them transitions the intent\n * to `PAID` and implicitly retires the rest.\n *\n * Industry-neutral: a marketplace that accepts USDC-on-Base and BTC\n * lists two options; a SaaS billing flow that accepts Stripe and\n * PayPal lists two; a kiosk that accepts only one rail lists one.\n */\nexport interface PaymentOption {\n /**\n * Stable id of the `PaymentBackend` adapter that fulfills this\n * option — must match a `backendId` the consumer's payment-routing\n * layer recognises. Examples: `base-usdc`, `solana-usdc`, `btc`,\n * `stripe`, `paypal`.\n */\n backendId: string;\n /**\n * Payout-rail-qualified currency code, e.g. `USDC-base`, `BTC`,\n * `USD-stripe`. The same convention used by\n * `Vendor.payoutAddresses` and `Payment.nativeCurrency`.\n */\n currency: string;\n /**\n * Optional chain identifier for blockchain-backed options (`base`,\n * `ethereum`, `solana`, ...). Pure-fiat options leave this empty.\n */\n chain?: string;\n /**\n * Destination address / account id the buyer should send funds to\n * for this option (EVM address, BTC address, Stripe payment-intent\n * id, etc.).\n */\n payTo: string;\n /**\n * Amount denominated in `currency`. Stored at decimal precision —\n * a USDC option might be `199.0`, a BTC option `0.00713`.\n */\n nativeAmount: number;\n /**\n * Optional on-chain memo / payment reference (Solana memo, BTC OP_RETURN\n * tag, Stripe metadata key). Some backends use this to disambiguate\n * which intent an inbound payment satisfies.\n */\n memo?: string;\n /**\n * Whether this option supports the x402 HTTP-402 payment-required\n * flow. Consumers that build agent-driven flows use this flag to\n * filter the offered options.\n */\n x402Capable?: boolean;\n /**\n * Optional per-option expiry — when a single rail's quote becomes\n * stale earlier than the intent-wide price-lock window (e.g. a\n * volatile-currency option that re-quotes more aggressively). ISO\n * 8601 string. Empty / missing means \"inherit the intent's\n * `priceLockExpiresAt`\".\n */\n expiresAt?: string;\n}\n\n// ============================================================================\n// Invoice Types\n// ============================================================================\n\nexport enum InvoiceStatus {\n DRAFT = 'draft',\n SENT = 'sent',\n VIEWED = 'viewed',\n PARTIAL = 'partial',\n PAID = 'paid',\n OVERDUE = 'overdue',\n CANCELLED = 'cancelled',\n WRITTEN_OFF = 'written_off',\n}\n\n// ============================================================================\n// Common Interfaces\n// ============================================================================\n\n/**\n * Address structure used for billing and shipping\n */\nexport interface Address {\n street1?: string;\n street2?: string;\n city?: string;\n state?: string;\n postalCode?: string;\n country?: string;\n}\n\n/**\n * A person to reach at a customer or vendor, stored on the party row\n * (`Customer.contacts` / `Vendor.contacts`, #3501). Every field is plain\n * text; `id` is a stable random identifier assigned when the row is first\n * saved. Write rows through `savePartyContacts()`.\n */\nexport interface PartyContact {\n id: string;\n name: string;\n /** Role or relationship, for example \"Accounts payable\". */\n label: string;\n email: string;\n phone: string;\n address: string;\n}\n\n/**\n * Options for recording a payment with ledger integration\n */\nexport interface RecordPaymentOptions {\n /** The ledger to record the journal entry in */\n ledgerId: string;\n /** Account ID for receivables (credit side) */\n receivablesAccountId: string;\n /** Account ID for cash/bank (debit side) */\n cashAccountId: string;\n}\n\n/**\n * Options for recognizing revenue on an invoice\n */\nexport interface RecognizeRevenueOptions {\n /** Account ID for accounts receivable (debit side) */\n arAccountId: string;\n /** Revenue account for lines that do not name their own (credit side). */\n revenueAccountId: string;\n /**\n * Tax payable account for tax components without a liability account and\n * for provider tax (credit side).\n */\n taxAccountId?: string;\n /** ISO 4217 ledger book currency; must equal the invoice currency. */\n bookCurrency: string;\n}\n\n/** Options for atomically cancelling a posted invoice. */\nexport interface CancelRevenueOptions {\n /** ISO 4217 ledger book currency; must equal the invoice currency. */\n bookCurrency: string;\n}\n\n// ============================================================================\n// Accounting-provider sync shapes\n// ============================================================================\n\n/**\n * A single line item in the format expected by `@happyvertical/accounting`\n * providers (QBO, Stripe, …). Mirrors the object built by\n * {@link InvoiceLineItem.toAccountingLineItem}. The SDK isn't a dependency of\n * this package, so the shape is declared locally rather than imported.\n */\nexport interface AccountingLineItemInput {\n description: string;\n sku?: string;\n quantity: number;\n unitPrice: number;\n discount?: number;\n taxRate?: number;\n amount: number;\n periodStart?: Date;\n periodEnd?: Date;\n}\n\n/**\n * An invoice in the format expected by `@happyvertical/accounting` providers.\n * Mirrors the object built by {@link Invoice.toAccountingInput}; money is in\n * currency **major** units, as the SDK expects.\n */\nexport interface AccountingInvoiceInput {\n id: string;\n externalId?: string;\n invoiceNumber: string;\n customerId: string;\n customerExternalId?: string;\n issueDate: Date;\n dueDate: Date;\n lineItems: AccountingLineItemInput[];\n subtotal: number;\n taxAmount: number;\n totalAmount: number;\n currency: string;\n reference?: string;\n memo?: string;\n idempotencyKey?: string;\n quickbooksRequest?: {\n readonly requestId: string;\n readonly realmId: string;\n readonly environment: 'sandbox' | 'production';\n readonly payloadHash: string;\n };\n quickbooksMapping?: {\n globalTaxCalculation: 'TaxExcluded' | 'NotApplicable';\n };\n}\n\n// ============================================================================\n// Model constructor option interfaces\n//\n// Each model's `constructor(options)` accepts a partial bag of its own fields.\n// Declaring a dedicated `XxxOptions extends SmrtObjectOptions` interface keeps\n// the constructors strongly typed (no `any`) while still allowing the\n// framework's base options (db, ai, fs, _className, …) through.\n// ============================================================================\n\n/**\n * Constructor options for {@link Customer}.\n */\nexport interface CustomerOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n profileId?: string;\n creditLimit?: number;\n paymentTerms?: string;\n taxExempt?: boolean;\n taxId?: string;\n defaultTaxCodeId?: string;\n defaultShippingAddress?: Address;\n defaultBillingAddress?: Address;\n status?: CustomerStatus;\n customerType?: CustomerType | null;\n notes?: string;\n contacts?: PartyContact[] | string | null;\n}\n\n/**\n * Constructor options for {@link Vendor}.\n */\nexport interface VendorOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n profileId?: string;\n leadTimeDays?: number;\n minimumOrderAmount?: number;\n paymentTerms?: string;\n currency?: string;\n taxId?: string;\n defaultTaxCodeId?: string;\n defaultContactEmail?: string;\n defaultContactPhone?: string;\n status?: VendorStatus;\n notes?: string;\n payoutAddresses?: Record<string, string> | string | null;\n contacts?: PartyContact[] | string | null;\n}\n\n/** A component reference stored in a tax code's ordered component list. */\nexport interface TaxCodePart {\n taxComponentId: string;\n compound: boolean;\n}\n\nexport interface TaxComponentOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n name?: string;\n percent?: string;\n liabilityAccountId?: string;\n recoverable?: boolean;\n active?: boolean;\n}\n\nexport interface TaxCodeOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n code?: string;\n name?: string;\n kind?: 'taxable' | 'zero-rated' | 'exempt' | 'out-of-scope';\n appliesTo?: 'sales' | 'purchases' | 'both';\n components?: TaxCodePart[];\n active?: boolean;\n}\n\nexport interface TaxRegistrationOptions {\n taxComponentId: string;\n number: string;\n label: string;\n}\n\nexport interface TaxSettingsOptions extends SmrtObjectOptions {\n tenantId?: string;\n defaultSalesTaxCodeId?: string;\n defaultPurchaseTaxCodeId?: string;\n defaultLineAmountType?: 'exclusive' | 'inclusive' | 'none';\n taxRoundingScope?: 'line' | 'document';\n taxRegistrations?: TaxRegistrationOptions[];\n}\n\n/**\n * Constructor options for {@link Contract} and its STI subtypes.\n */\nexport interface ContractOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n contractType?: ContractType;\n status?: ContractStatus;\n subtotal?: number;\n discountTotal?: number;\n taxAmount?: number;\n totalAmount?: number;\n currency?: string;\n issueDate?: Date;\n dueDate?: Date | null;\n expiryDate?: Date | null;\n reference?: string;\n notes?: string;\n terms?: string;\n channelId?: string;\n lineAmountType?: 'exclusive' | 'inclusive' | 'none';\n taxRoundingScope?: 'line' | 'document';\n sellerTaxRegistrations?: TaxRegistrationOptions[];\n sellerTaxRegistrationsJson?: string;\n partyTaxId?: string;\n moneySnapshotId?: string;\n}\n\nexport interface SalesContractOptions extends ContractOptions {\n customerId?: string | null;\n}\n\nexport interface PurchaseContractOptions extends ContractOptions {\n vendorId?: string | null;\n}\n\n/** Purchase-order header options stored in the existing STI metadata. */\nexport interface PurchaseOrderOptions extends PurchaseContractOptions {\n /** Expected delivery calendar date (YYYY-MM-DD); empty means unspecified. */\n expectedDate?: string;\n /** Delivery address/instructions snapshot. */\n shipTo?: string;\n}\n\n/**\n * Constructor options for {@link LicenseSale} (Contract STI subtype). Extends\n * {@link ContractOptions} with the licensing-specific meta fields.\n */\nexport interface LicenseSaleOptions extends SalesContractOptions {\n skuId?: string;\n paymentId?: string;\n licenseeEmail?: string;\n licenseeLegalEntity?: string;\n licenseeJurisdiction?: string;\n rightsMedium?: string;\n rightsDistributionScope?: string;\n rightsExclusivity?: string;\n rightsDuration?: string;\n rightsTerritory?: string;\n rightsSublicensing?: boolean;\n rightsDerivatives?: boolean;\n pdfUrl?: string;\n pdfHash?: string;\n onChainHashRegistryRef?: string;\n}\n\n/**\n * Constructor options for {@link ContractLineItem}.\n */\nexport interface ContractLineItemOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n contractId?: string;\n description?: string;\n quantity?: number;\n unitPrice?: number;\n discount?: number;\n discountType?: 'none' | 'percent' | 'amount';\n discountRate?: string;\n taxRate?: number;\n taxMode?: 'inherit' | 'override';\n taxCodeId?: string | null;\n taxCodeCode?: string | null;\n taxCodeName?: string | null;\n taxComponents?: ContractTaxComponentSnapshot[];\n taxComponentsJson?: string | null;\n taxAmount?: number;\n moneySnapshotId?: string;\n amount?: number;\n productId?: string;\n sku?: string;\n startDate?: Date | null;\n endDate?: Date | null;\n billingPeriod?: string;\n sortOrder?: number;\n}\n\n/** Immutable component tax allocation for one Contract line. */\nexport interface ContractTaxComponentSnapshot {\n taxComponentId: string;\n name: string;\n percent: string;\n taxMinor: number;\n}\n\n/**\n * How the provider collects an invoice (#3190): `charge_automatically`\n * charges the payer's saved card; `send_invoice` asks the payer to pay. Empty\n * for an invoice never pushed to a provider, or pushed before it was recorded.\n */\nexport type InvoiceCollectionMethod =\n | ''\n | 'send_invoice'\n | 'charge_automatically';\n\nexport type InvoiceKind = 'invoice' | 'credit_note';\n\n/** Frozen source pricing plus the one authoritative credit calculation basis. */\nexport type InvoiceCreditCalculationBasis =\n | {\n kind: 'quantity';\n quantity: string;\n sourceQuantity: string;\n sourceUnitPrice: number;\n sourceDiscountType: 'none' | 'percent' | 'amount';\n sourceDiscountRate: string;\n sourceDiscountMinor: number;\n }\n | {\n kind: 'net_amount';\n netMinor: number;\n sourceQuantity: string;\n sourceUnitPrice: number;\n sourceDiscountType: 'none' | 'percent' | 'amount';\n sourceDiscountRate: string;\n sourceDiscountMinor: number;\n };\n\n/**\n * Constructor options for {@link Invoice}.\n */\nexport interface InvoiceOptions extends SmrtObjectOptions {\n kind?: InvoiceKind;\n creditedInvoiceId?: string | null;\n creditedAmount?: number;\n tenantId?: string | null;\n customerId?: string;\n contractId?: string;\n invoiceNumber?: string;\n reference?: string;\n issueDate?: Date;\n dueDate?: Date;\n paidDate?: Date | null;\n subtotal?: number;\n taxAmount?: number;\n providerTaxAmount?: number;\n totalAmount?: number;\n amountPaid?: number;\n currency?: string;\n status?: InvoiceStatus;\n arJournalId?: string;\n arReversalJournalId?: string | null;\n revenueJournalId?: string;\n externalId?: string;\n customerExternalId?: string;\n externalProvider?: string;\n syncedAt?: Date | null;\n collectionMethod?: InvoiceCollectionMethod;\n sentAt?: Date | null;\n viewedAt?: Date | null;\n remindersSent?: number;\n lastReminderAt?: Date | null;\n notes?: string;\n customerNotes?: string;\n terms?: string;\n lineAmountType?: 'exclusive' | 'inclusive' | 'none';\n taxRoundingScope?: 'line' | 'document';\n discountTotal?: number;\n sellerTaxRegistrations?: TaxRegistrationOptions[];\n sellerTaxRegistrationsJson?: string;\n partyTaxId?: string;\n moneySnapshotId?: string;\n accountingSyncStateJson?: string;\n}\n\nexport interface InvoiceTaxComponentSnapshot {\n taxComponentId: string;\n name: string;\n percent: string;\n taxMinor: number;\n}\n\n/** Constructor options for {@link InvoiceLineItem}. */\nexport interface InvoiceLineItemOptions extends SmrtObjectOptions {\n creditedLineId?: string | null;\n creditCalculationBasis?: InvoiceCreditCalculationBasis | null;\n creditCalculationBasisJson?: string;\n tenantId?: string | null;\n invoiceId?: string;\n description?: string;\n sku?: string;\n productId?: string | null;\n quantity?: number;\n unitPrice?: number;\n discount?: number;\n discountType?: 'none' | 'percent' | 'amount';\n discountRate?: string;\n taxRate?: number;\n taxMode?: 'inherit' | 'override';\n taxCodeId?: string | null;\n taxCodeCode?: string | null;\n taxCodeName?: string | null;\n taxComponents?: InvoiceTaxComponentSnapshot[];\n taxComponentsJson?: string | null;\n taxAmount?: number;\n moneySnapshotId?: string;\n amount?: number;\n sourceType?: string;\n sourceId?: string;\n periodStart?: Date | null;\n periodEnd?: Date | null;\n revenueAccountId?: string | null;\n sortOrder?: number;\n}\n\n/**\n * Constructor options for {@link Fulfillment}.\n */\nexport interface FulfillmentOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n contractId?: string;\n fulfillmentType?: FulfillmentType;\n status?: FulfillmentStatus;\n trackingNumber?: string;\n carrier?: string;\n shippingAddress?: Address;\n shippedAt?: Date | null;\n deliveredAt?: Date | null;\n estimatedDelivery?: Date | null;\n notes?: string;\n}\n\n/**\n * Constructor options for {@link FulfillmentLineItem}.\n */\nexport interface FulfillmentLineItemOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n fulfillmentId?: string;\n contractLineItemId?: string;\n quantityFulfilled?: number;\n notes?: string;\n}\n\n/**\n * Constructor options for {@link Payment}.\n */\nexport interface PaymentOptions extends SmrtObjectOptions {\n kind?: PaymentKind;\n tenantId?: string | null;\n contractId?: string | null;\n customerId?: string | null;\n amount?: number;\n currency?: string;\n method?: PaymentMethod;\n status?: PaymentStatus;\n transactionId?: string;\n reference?: string;\n journalId?: string;\n paidAt?: Date | null;\n notes?: string;\n externalId?: string;\n externalProvider?: string;\n syncedAt?: Date | null;\n backendId?: string;\n backendTxRef?: string;\n nativeAmount?: number;\n nativeCurrency?: string;\n usdAtQuote?: number;\n usdAtConfirmation?: number;\n}\n\n/**\n * Constructor options for {@link PaymentInstrument}.\n */\nexport interface PaymentInstrumentOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n customerId?: string;\n backendId?: string;\n providerCustomerId?: string;\n providerPaymentMethodId?: string;\n type?: string;\n brand?: string;\n last4?: string;\n expMonth?: number;\n expYear?: number;\n isDefault?: boolean;\n status?: PaymentInstrumentStatus;\n}\n\n/**\n * Constructor options for {@link PaymentAllocation}.\n */\nexport interface PaymentAllocationOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n paymentId?: string;\n invoiceId?: string;\n amount?: number;\n allocatedAt?: Date;\n allocatedBy?: string;\n notes?: string;\n}\n\n/**\n * Constructor options for {@link PaymentIntent}.\n */\nexport interface PaymentIntentOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n skuId?: string;\n offeringRef?: string;\n licenseeEmail?: string;\n customerId?: string;\n paymentOptions?: PaymentOption[] | string;\n usdPriceLocked?: number;\n priceLockWindowMs?: number;\n priceLockExpiresAt?: Date | number | string | null;\n status?: PaymentIntentStatus;\n idempotencyKey?: string;\n paidOptionBackendId?: string;\n paymentId?: string;\n paidAt?: Date | number | string | null;\n issuedAt?: Date | number | string | null;\n expiredAt?: Date | number | string | null;\n cancelledAt?: Date | number | string | null;\n retiredAt?: Date | number | string | null;\n notes?: string;\n}\n\n/**\n * Constructor options for {@link Payout}.\n */\nexport interface PayoutOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n paymentId?: string;\n vendorId?: string;\n grossAmount?: number;\n operatorFee?: number;\n supplierNet?: number;\n currency?: string;\n backendId?: string;\n backendTxRef?: string;\n status?: PayoutStatus;\n sentAt?: Date | number | string | null;\n confirmedAt?: Date | number | string | null;\n failedAt?: Date | number | string | null;\n failureReason?: string;\n notes?: string;\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,19 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ISO_4217_MINOR_UNITS } from "@happyvertical/smrt-ui/currency";
|
|
2
|
+
//#region src/svelte/invoices/currency.ts
|
|
3
|
+
var CURRENCY_PATTERN = /^[A-Z]{3}$/;
|
|
4
|
+
function normalizeCurrency(currency) {
|
|
5
|
+
const code = String(currency ?? "").trim().toUpperCase();
|
|
6
|
+
if (!CURRENCY_PATTERN.test(code)) throw new Error(`Currency '${currency}' must be a three-letter code.`);
|
|
7
|
+
return code;
|
|
8
|
+
}
|
|
9
|
+
function currencyMinorUnitExponent(currency) {
|
|
10
|
+
const code = normalizeCurrency(currency);
|
|
11
|
+
const exponent = ISO_4217_MINOR_UNITS.get(code);
|
|
12
|
+
if (exponent === void 0) throw new Error(`Unsupported currency '${code}'.`);
|
|
13
|
+
if (exponent === null) throw new Error(`Currency '${code}' does not define a minor unit.`);
|
|
14
|
+
return exponent;
|
|
15
|
+
}
|
|
16
|
+
//#endregion
|
|
2
17
|
//#region src/billing/units.ts
|
|
3
18
|
function minorToMajorUnits(amount, currency) {
|
|
4
19
|
if (!Number.isSafeInteger(amount)) throw new Error(`Amount ${amount} must be a safe integer number of minor units.`);
|
|
@@ -40,6 +55,6 @@ function tenantKey(id) {
|
|
|
40
55
|
return id ? String(id).toLowerCase() : "";
|
|
41
56
|
}
|
|
42
57
|
//#endregion
|
|
43
|
-
export { majorToMinorUnits as a, isUuid as i, deterministicId as n, minorToMajorUnits as o, isTenantId as r, tenantKey as s, canonicalTenantId as t };
|
|
58
|
+
export { majorToMinorUnits as a, currencyMinorUnitExponent as c, isUuid as i, normalizeCurrency as l, deterministicId as n, minorToMajorUnits as o, isTenantId as r, tenantKey as s, canonicalTenantId as t };
|
|
44
59
|
|
|
45
|
-
//# sourceMappingURL=units-
|
|
60
|
+
//# sourceMappingURL=units-8ElbjVZK.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"units-8ElbjVZK.js","names":[],"sources":["../../src/svelte/invoices/currency.ts","../../src/billing/units.ts"],"sourcesContent":["/** Svelte-free currency precision shared by invoice previews and billing. */\n\nimport { ISO_4217_MINOR_UNITS } from '@happyvertical/smrt-ui/currency';\n\nconst CURRENCY_PATTERN = /^[A-Z]{3}$/;\n\n/** Upper-case, validate, and return an ISO 4217-shaped currency code. */\nexport function normalizeCurrency(currency: string): string {\n const code = String(currency ?? '')\n .trim()\n .toUpperCase();\n if (!CURRENCY_PATTERN.test(code)) {\n throw new Error(`Currency '${currency}' must be a three-letter code.`);\n }\n return code;\n}\n\n/**\n * The ISO 4217 minor-unit exponent of a currency (2 for USD and RSD, 0 for\n * JPY, 3 for IQD). Unknown codes and currencies without a minor unit fail\n * closed because assigning either an inferred or invented exponent changes\n * the represented amount.\n */\nexport function currencyMinorUnitExponent(currency: string): number {\n const code = normalizeCurrency(currency);\n const exponent = ISO_4217_MINOR_UNITS.get(code);\n if (exponent === undefined)\n throw new Error(`Unsupported currency '${code}'.`);\n if (exponent === null)\n throw new Error(`Currency '${code}' does not define a minor unit.`);\n return exponent;\n}\n","/**\n * Money-unit and identity helpers for billing-period close (#3060).\n *\n * Commerce stores money as integer minor units. `@happyvertical/accounting`\n * takes and returns currency *major* units and converts to the provider's own\n * representation itself, so the only conversion this package performs is the\n * ISO 4217 one: minor units ÷ 10^exponent.\n */\n\nimport {\n currencyMinorUnitExponent,\n normalizeCurrency,\n} from '../svelte/invoices/currency.js';\n\nexport {\n currencyMinorUnitExponent,\n normalizeCurrency,\n} from '../svelte/invoices/currency.js';\n\n/** Integer minor units → major units (`1999` USD → `19.99`). */\nexport function minorToMajorUnits(amount: number, currency: string): number {\n if (!Number.isSafeInteger(amount)) {\n throw new Error(\n `Amount ${amount} must be a safe integer number of minor units.`,\n );\n }\n return amount / 10 ** currencyMinorUnitExponent(currency);\n}\n\n/**\n * Major units → integer minor units. Rejects a value that is not a whole\n * number of minor units instead of rounding it: a provider amount that does\n * not round-trip exactly means the two sides disagree about the currency.\n */\nexport function majorToMinorUnits(amount: number, currency: string): number {\n if (!Number.isFinite(amount)) {\n throw new Error(`Provider amount ${amount} is not a finite number.`);\n }\n const scaled = amount * 10 ** currencyMinorUnitExponent(currency);\n const minor = Math.round(scaled);\n if (Math.abs(scaled - minor) > 1e-6 || !Number.isSafeInteger(minor)) {\n throw new Error(\n `Provider amount ${amount} ${normalizeCurrency(currency)} is not a whole number of minor units.`,\n );\n }\n return minor;\n}\n\n/**\n * A stable UUID derived from its parts (SHA-256, version/variant bits set).\n * Deterministic ids are what make every period-close write replay-safe: a\n * retry recomputes the same identity instead of creating a second row.\n */\nexport async function deterministicId(parts: string[]): Promise<string> {\n const bytes = new TextEncoder().encode(JSON.stringify(parts));\n const digest = new Uint8Array(await crypto.subtle.digest('SHA-256', bytes));\n const uuid = digest.slice(0, 16);\n uuid[6] = (uuid[6] & 0x0f) | 0x50;\n uuid[8] = (uuid[8] & 0x3f) | 0x80;\n const hex = Array.from(uuid, (byte) => byte.toString(16).padStart(2, '0'));\n const joined = hex.join('');\n return [\n joined.slice(0, 8),\n joined.slice(8, 12),\n joined.slice(12, 16),\n joined.slice(16, 20),\n joined.slice(20),\n ].join('-');\n}\n\nconst UUID_PATTERN =\n /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\n/** Validate and lower-case a tenant UUID. */\nexport function canonicalTenantId(id: string, label = 'Tenant ID'): string {\n if (typeof id !== 'string' || !UUID_PATTERN.test(id)) {\n throw new Error(`${label} must be a UUID.`);\n }\n return id.toLowerCase();\n}\n\n/** Whether `id` is a UUID (any case), such as a billing record id. */\nexport function isUuid(id: string): boolean {\n return typeof id === 'string' && UUID_PATTERN.test(id);\n}\n\n/** Whether `id` is a tenant UUID (any case). */\nexport function isTenantId(id: string): boolean {\n return typeof id === 'string' && UUID_PATTERN.test(id);\n}\n\n/** Lower-case a possibly-empty tenant id for comparison. */\nexport function tenantKey(id: string | null | undefined): string {\n return id ? String(id).toLowerCase() : '';\n}\n"],"mappings":";;AAIA,IAAM,mBAAmB;AAGlB,SAAS,kBAAkB,UAA0B;CAC1D,MAAM,OAAO,OAAO,YAAY,EAAE,CAAA,CAC/B,KAAK,CAAA,CACL,YAAY;CACf,IAAI,CAAC,iBAAiB,KAAK,IAAI,GAC7B,MAAM,IAAI,MAAM,aAAa,SAAQ,+BAAgC;CAEvE,OAAO;AACT;AAQO,SAAS,0BAA0B,UAA0B;CAClE,MAAM,OAAO,kBAAkB,QAAQ;CACvC,MAAM,WAAW,qBAAqB,IAAI,IAAI;CAC9C,IAAI,aAAa,KAAA,GACf,MAAM,IAAI,MAAM,yBAAyB,KAAI,GAAI;CACnD,IAAI,aAAa,MACf,MAAM,IAAI,MAAM,aAAa,KAAI,gCAAiC;CACpE,OAAO;AACT;;;ACXO,SAAS,kBAAkB,QAAgB,UAA0B;CAC1E,IAAI,CAAC,OAAO,cAAc,MAAM,GAC9B,MAAM,IAAI,MACR,UAAU,OAAM,+CAClB;CAEF,OAAO,SAAS,MAAM,0BAA0B,QAAQ;AAC1D;AAOO,SAAS,kBAAkB,QAAgB,UAA0B;CAC1E,IAAI,CAAC,OAAO,SAAS,MAAM,GACzB,MAAM,IAAI,MAAM,mBAAmB,OAAM,yBAA0B;CAErE,MAAM,SAAS,SAAS,MAAM,0BAA0B,QAAQ;CAChE,MAAM,QAAQ,KAAK,MAAM,MAAM;CAC/B,IAAI,KAAK,IAAI,SAAS,KAAK,IAAI,QAAQ,CAAC,OAAO,cAAc,KAAK,GAChE,MAAM,IAAI,MACR,mBAAmB,OAAM,GAAI,kBAAkB,QAAQ,EAAC,uCAC1D;CAEF,OAAO;AACT;AAOA,eAAsB,gBAAgB,OAAkC;CACtE,MAAM,QAAQ,IAAI,YAAY,CAAA,CAAE,OAAO,KAAK,UAAU,KAAK,CAAC;CAE5D,MAAM,OAAO,IADM,WAAW,MAAM,OAAO,OAAO,OAAO,WAAW,KAAK,CAC5D,CAAA,CAAO,MAAM,GAAG,EAAE;CAC/B,KAAK,KAAM,KAAK,KAAK,KAAQ;CAC7B,KAAK,KAAM,KAAK,KAAK,KAAQ;CAE7B,MAAM,SADM,MAAM,KAAK,OAAO,SAAS,KAAK,SAAS,EAAE,CAAA,CAAE,SAAS,GAAG,GAAG,CACzD,CAAA,CAAI,KAAK,EAAE;CAC1B,OAAO;EACL,OAAO,MAAM,GAAG,CAAC;EACjB,OAAO,MAAM,GAAG,EAAE;EAClB,OAAO,MAAM,IAAI,EAAE;EACnB,OAAO,MAAM,IAAI,EAAE;EACnB,OAAO,MAAM,EAAE;CACjB,CAAA,CAAE,KAAK,GAAG;AACZ;AAEA,IAAM,eACJ;AAGK,SAAS,kBAAkB,IAAY,QAAQ,aAAqB;CACzE,IAAI,OAAO,OAAO,YAAY,CAAC,aAAa,KAAK,EAAE,GACjD,MAAM,IAAI,MAAM,GAAG,MAAK,iBAAkB;CAE5C,OAAO,GAAG,YAAY;AACxB;AAGO,SAAS,OAAO,IAAqB;CAC1C,OAAO,OAAO,OAAO,YAAY,aAAa,KAAK,EAAE;AACvD;AAGO,SAAS,WAAW,IAAqB;CAC9C,OAAO,OAAO,OAAO,YAAY,aAAa,KAAK,EAAE;AACvD;AAGO,SAAS,UAAU,IAAuC;CAC/D,OAAO,KAAK,OAAO,EAAE,CAAA,CAAE,YAAY,IAAI;AACzC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContractCollection.d.ts","sourceRoot":"","sources":["../../src/collections/ContractCollection.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,cAAc,EACd,KAAK,eAAe,EACpB,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACrB,MAAM,0BAA0B,CAAC;AAOlC,OAAO,EACL,QAAQ,EAET,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"ContractCollection.d.ts","sourceRoot":"","sources":["../../src/collections/ContractCollection.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContractLineItemCollection.d.ts","sourceRoot":"","sources":["../../src/collections/ContractLineItemCollection.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,cAAc,EACd,KAAK,eAAe,EACpB,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACrB,MAAM,0BAA0B,CAAC;AAOlC,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"ContractLineItemCollection.d.ts","sourceRoot":"","sources":["../../src/collections/ContractLineItemCollection.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InvoiceCollection.d.ts","sourceRoot":"","sources":["../../src/collections/InvoiceCollection.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,cAAc,EACd,KAAK,eAAe,EACpB,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACrB,MAAM,0BAA0B,CAAC;AAOlC,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAE/C,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"InvoiceCollection.d.ts","sourceRoot":"","sources":["../../src/collections/InvoiceCollection.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,cAAc,EACd,KAAK,eAAe,EACpB,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACrB,MAAM,0BAA0B,CAAC;AAOlC,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAE/C,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGlD;;;GAGG;AACH,eAAO,MAAM,eAAe,mGAKlB,CAAC;AAEX;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,kDAAkD;IAClD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6EAA6E;IAC7E,MAAM,CAAC,EAAE,iBAAiB,GAAG,YAAY,CAAC;CAC3C;AAED,qBAAa,iBAAkB,SAAQ,cAAc,CAAC,OAAO,CAAC;IAC5D,MAAM,CAAC,QAAQ,CAAC,UAAU,iBAAW;YAEvB,aAAa;IAsBZ,GAAG,CAChB,MAAM,EAAE,MAAM,GAAG,eAAe,CAAC,OAAO,CAAC,EACzC,OAAO,GAAE,UAAU,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAM,GAC1D,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAIX,IAAI,CAAC,KAAK,CAAC,MAAM,SAAS,SAAS,eAAe,CAAC,OAAO,CAAC,EAAE,EAC1E,OAAO,EAAE,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAC,GAAG;QAC/D,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE,KAAK,CAAC;QAChB,QAAQ,EAAE,gBAAgB,CAAC;KAC5B,GACA,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IACtB,IAAI,CAAC,KAAK,CAAC,MAAM,SAAS,SAAS,eAAe,CAAC,OAAO,CAAC,EAAE,EAC1E,OAAO,EAAE,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAC,GAAG;QAC/D,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE,KAAK,CAAC;QAChB,QAAQ,CAAC,EAAE,SAAS,CAAC;KACtB,GACA,OAAO,CAAC,eAAe,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,CAAC;IAC/B,IAAI,CACjB,OAAO,EAAE,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAC,GAAG;QAC/D,MAAM,CAAC,EAAE,SAAS,CAAC;QACnB,QAAQ,EAAE,gBAAgB,CAAC;KAC5B,GACA,OAAO,CAAC,UAAU,EAAE,CAAC;IACT,IAAI,CAAC,OAAO,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAC7C,IAAI,CACjB,OAAO,EAAE,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAC,GAAG;QAC/D,MAAM,CAAC,EAAE,SAAS,CAAC;QACnB,QAAQ,CAAC,EAAE,SAAS,CAAC;KACtB,GACA,OAAO,CAAC,OAAO,EAAE,CAAC;IACN,IAAI,CACjB,OAAO,EACH,CAAC,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,GAAG;QAAE,MAAM,CAAC,EAAE,SAAS,CAAA;KAAE,CAAC,GACnE,SAAS,GACZ,OAAO,CAAC,UAAU,EAAE,CAAC;IACT,IAAI,CACjB,OAAO,EAAE,eAAe,CAAC,OAAO,CAAC,GAAG,SAAS,GAC5C,OAAO,CAAC,UAAU,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IAOpD;;;;;OAKG;IACG,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAO5D;;;;;OAKG;IACG,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAO5D;;;;;OAKG;IACG,YAAY,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAO7D;;;;OAIG;IACG,UAAU,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAItC;;;;OAIG;IACG,QAAQ,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAIpC;;;;OAIG;IACG,QAAQ,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAIpC;;;;OAIG;IACG,WAAW,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAIvC;;;;;;;;OAQG;IACG,WAAW,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAgBvC;;;;;;OAMG;IACG,eAAe,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAUzE;;;;;OAKG;IACG,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAQnE;;;;;OAKG;IACG,eAAe,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAc3C;;;;;OAKG;IACG,YAAY,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAQlE;;;;;OAKG;IACG,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAcjD;;;;;;;;;;;;;;;;;;;;;OAqBG;IACG,qBAAqB,CACzB,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,MAAM,CAAC;IAkBlB;;;;;OAKG;IACG,8BAA8B,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAgBzE;;;;;OAKG;IACG,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAIxD;;;;;;;;OAQG;IACG,UAAU,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAItC;;;;;;;;OAQG;IACG,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;CAG5D"}
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { SmrtCollection, type SmrtListOptions, type SmrtObject, type SmrtSelectedRow, type SmrtSelectField, type SmrtStiReadScope, type SmrtWhereClause } from '@happyvertical/smrt-core';
|
|
6
6
|
import { InvoiceLineItem } from '../models/InvoiceLineItem.js';
|
|
7
|
-
import type { AccountingLineItemInput } from '../types/index.js';
|
|
8
7
|
export declare class InvoiceLineItemCollection extends SmrtCollection<InvoiceLineItem> {
|
|
9
8
|
static readonly _itemClass: typeof InvoiceLineItem;
|
|
10
9
|
private withMoneyRead;
|
|
@@ -61,20 +60,6 @@ export declare class InvoiceLineItemCollection extends SmrtCollection<InvoiceLin
|
|
|
61
60
|
* @returns Total amount
|
|
62
61
|
*/
|
|
63
62
|
getTotalForInvoice(invoiceId: string): Promise<number>;
|
|
64
|
-
/**
|
|
65
|
-
* Calculate subtotal (before tax) for an invoice
|
|
66
|
-
*
|
|
67
|
-
* @param invoiceId - Invoice ID
|
|
68
|
-
* @returns Subtotal
|
|
69
|
-
*/
|
|
70
|
-
getSubtotalForInvoice(invoiceId: string): Promise<number>;
|
|
71
|
-
/**
|
|
72
|
-
* Calculate tax amount for an invoice
|
|
73
|
-
*
|
|
74
|
-
* @param invoiceId - Invoice ID
|
|
75
|
-
* @returns Tax amount
|
|
76
|
-
*/
|
|
77
|
-
getTaxForInvoice(invoiceId: string): Promise<number>;
|
|
78
63
|
/**
|
|
79
64
|
* Get the next sort order for an invoice
|
|
80
65
|
*
|
|
@@ -82,21 +67,6 @@ export declare class InvoiceLineItemCollection extends SmrtCollection<InvoiceLin
|
|
|
82
67
|
* @returns Next sort order number
|
|
83
68
|
*/
|
|
84
69
|
getNextSortOrder(invoiceId: string): Promise<number>;
|
|
85
|
-
/**
|
|
86
|
-
* Recalculate all line item amounts for an invoice
|
|
87
|
-
*
|
|
88
|
-
* @param invoiceId - Invoice ID
|
|
89
|
-
* @returns Updated line items
|
|
90
|
-
*/
|
|
91
|
-
recalculateAmounts(invoiceId: string): Promise<InvoiceLineItem[]>;
|
|
92
|
-
/**
|
|
93
|
-
* Convert line items to accounting format for SDK sync
|
|
94
|
-
*
|
|
95
|
-
* @param invoiceId - Invoice ID
|
|
96
|
-
* @returns Array of line items in accounting format, money in integer
|
|
97
|
-
* minor units (`Invoice.toAccountingInput()` converts to major units)
|
|
98
|
-
*/
|
|
99
|
-
toAccountingLineItems(invoiceId: string): Promise<AccountingLineItemInput[]>;
|
|
100
70
|
/**
|
|
101
71
|
* Find all invoice line items belonging to a specific tenant
|
|
102
72
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InvoiceLineItemCollection.d.ts","sourceRoot":"","sources":["../../src/collections/InvoiceLineItemCollection.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,cAAc,EACd,KAAK,eAAe,EACpB,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACrB,MAAM,0BAA0B,CAAC;AAOlC,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"InvoiceLineItemCollection.d.ts","sourceRoot":"","sources":["../../src/collections/InvoiceLineItemCollection.ts"],"names":[],"mappings":"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"}
|