@happyvertical/smrt-commerce 0.57.37 → 0.57.38
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/dist/allocation-integrity.d.ts +1 -1
- package/dist/allocation-integrity.d.ts.map +1 -1
- package/dist/chunks/{ContractLineItemCollection-DKcR46vL.js → ContractLineItemCollection-D74LbDOI.js} +8 -8
- package/dist/chunks/ContractLineItemCollection-D74LbDOI.js.map +1 -0
- package/dist/chunks/{DocumentTaxCollection-BjY9L6lc.js → DocumentTaxCollection-BmKyJGZi.js} +30 -30
- package/dist/chunks/DocumentTaxCollection-BmKyJGZi.js.map +1 -0
- package/dist/chunks/{InvoiceCollection-C50Hsu6G.js → InvoiceCollection-BPEzXaKm.js} +19 -14
- package/dist/chunks/InvoiceCollection-BPEzXaKm.js.map +1 -0
- package/dist/chunks/{TaxCodeCollection-CT09VQ9n.js → TaxCodeCollection-DpQeIqP4.js} +4 -4
- package/dist/chunks/TaxCodeCollection-DpQeIqP4.js.map +1 -0
- package/dist/chunks/{TaxComponentCollection-D8sFp8ZD.js → TaxComponentCollection-wFGWOaxy.js} +13 -8
- package/dist/chunks/TaxComponentCollection-wFGWOaxy.js.map +1 -0
- package/dist/chunks/{allocation-integrity-DrFgfSMd.js → allocation-integrity-DgnPec2a.js} +8 -8
- package/dist/chunks/allocation-integrity-DgnPec2a.js.map +1 -0
- package/dist/chunks/{contract-money-Cnezm9sA.js → contract-money-BxvY2Kcp.js} +14 -14
- package/dist/chunks/contract-money-BxvY2Kcp.js.map +1 -0
- package/dist/chunks/{invoice-posting-Dx-mfaRX.js → invoice-posting-C1q3CIYz.js} +3 -3
- package/dist/chunks/{invoice-posting-Dx-mfaRX.js.map → invoice-posting-C1q3CIYz.js.map} +1 -1
- package/dist/chunks/{retention-accounting-CvfeisFJ.js → retention-accounting-BAKsmbwJ.js} +18 -13
- package/dist/chunks/retention-accounting-BAKsmbwJ.js.map +1 -0
- package/dist/chunks/{tenant-money-barrier-DTELupG0.js → tenant-money-barrier-j1m0r6pe.js} +5 -5
- package/dist/chunks/tenant-money-barrier-j1m0r6pe.js.map +1 -0
- package/dist/contract-money.d.ts +3 -2
- package/dist/contract-money.d.ts.map +1 -1
- package/dist/document-money.d.ts +3 -2
- package/dist/document-money.d.ts.map +1 -1
- package/dist/index.js +23 -23
- package/dist/index.js.map +1 -1
- package/dist/invoices.js +1 -1
- package/dist/manifest.json +280 -28
- package/dist/models/Contract.d.ts +5 -5
- package/dist/models/Contract.d.ts.map +1 -1
- package/dist/models/ContractLineItem.d.ts +3 -3
- package/dist/models/ContractLineItem.d.ts.map +1 -1
- package/dist/models/DocumentTax.d.ts +3 -3
- package/dist/models/DocumentTax.d.ts.map +1 -1
- package/dist/models/Fulfillment.d.ts +2 -2
- package/dist/models/Fulfillment.d.ts.map +1 -1
- package/dist/models/FulfillmentLineItem.d.ts +2 -2
- package/dist/models/FulfillmentLineItem.d.ts.map +1 -1
- package/dist/models/Invoice.d.ts +3 -3
- package/dist/models/Invoice.d.ts.map +1 -1
- package/dist/models/InvoiceLineItem.d.ts +3 -3
- package/dist/models/InvoiceLineItem.d.ts.map +1 -1
- package/dist/models/Payment.d.ts +2 -2
- package/dist/models/Payment.d.ts.map +1 -1
- package/dist/models/PaymentAllocation.d.ts +2 -2
- package/dist/models/PaymentAllocation.d.ts.map +1 -1
- package/dist/models/PaymentIntent.d.ts +2 -2
- package/dist/models/PaymentIntent.d.ts.map +1 -1
- package/dist/models/Payout.d.ts +2 -2
- package/dist/models/Payout.d.ts.map +1 -1
- package/dist/models/PurchasePriceObservation.d.ts +3 -3
- package/dist/models/PurchasePriceObservation.d.ts.map +1 -1
- package/dist/models/TaxCode.d.ts +2 -2
- package/dist/models/TaxCode.d.ts.map +1 -1
- package/dist/models/TaxComponent.d.ts +2 -2
- package/dist/models/TaxComponent.d.ts.map +1 -1
- package/dist/models/TaxSettings.d.ts +2 -2
- package/dist/models/TaxSettings.d.ts.map +1 -1
- package/dist/smrt-knowledge.json +120 -21
- package/package.json +13 -13
- package/dist/chunks/ContractLineItemCollection-DKcR46vL.js.map +0 -1
- package/dist/chunks/DocumentTaxCollection-BjY9L6lc.js.map +0 -1
- package/dist/chunks/InvoiceCollection-C50Hsu6G.js.map +0 -1
- package/dist/chunks/TaxCodeCollection-CT09VQ9n.js.map +0 -1
- package/dist/chunks/TaxComponentCollection-D8sFp8ZD.js.map +0 -1
- package/dist/chunks/allocation-integrity-DrFgfSMd.js.map +0 -1
- package/dist/chunks/contract-money-Cnezm9sA.js.map +0 -1
- package/dist/chunks/retention-accounting-CvfeisFJ.js.map +0 -1
- package/dist/chunks/tenant-money-barrier-DTELupG0.js.map +0 -1
|
@@ -2,7 +2,7 @@ import type { Invoice } from './models/Invoice.js';
|
|
|
2
2
|
import type { Payment } from './models/Payment.js';
|
|
3
3
|
export declare function allocationOwner(value: string | null): string | null;
|
|
4
4
|
/** Claim the persisted parent before reading dependants, including at repeatable read. */
|
|
5
|
-
export declare function claimAllocationParent(parent: Payment | Invoice, kind: 'payment' | 'invoice'): Promise<void>;
|
|
5
|
+
export declare function claimAllocationParent(parent: Payment | Invoice, kind: 'payment' | 'invoice', expectedUpdatedAt?: Date | string): Promise<void>;
|
|
6
6
|
/** Exact totals must never silently exceed JavaScript's integer range. */
|
|
7
7
|
export declare function allocationTotal(rows: {
|
|
8
8
|
amount: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"allocation-integrity.d.ts","sourceRoot":"","sources":["../src/allocation-integrity.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAEnD,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAEnE;AAED,0FAA0F;AAC1F,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,OAAO,GAAG,OAAO,EACzB,IAAI,EAAE,SAAS,GAAG,SAAS,
|
|
1
|
+
{"version":3,"file":"allocation-integrity.d.ts","sourceRoot":"","sources":["../src/allocation-integrity.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAEnD,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAEnE;AAED,0FAA0F;AAC1F,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,OAAO,GAAG,OAAO,EACzB,IAAI,EAAE,SAAS,GAAG,SAAS,EAC3B,iBAAiB,CAAC,EAAE,IAAI,GAAG,MAAM,GAChC,OAAO,CAAC,IAAI,CAAC,CAoBf;AAED,0EAA0E;AAC1E,wBAAgB,eAAe,CAC7B,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,EAAE,EAC9C,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GACxB,MAAM,CAQR;AAED,4EAA4E;AAC5E,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,OAAO,GAAG,OAAO,EACzB,IAAI,EAAE,SAAS,GAAG,SAAS,GAC1B,OAAO,CAAC,IAAI,CAAC,CA2Df"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
|
|
2
2
|
import { MoneyValidationError } from "../money.js";
|
|
3
3
|
import { a as assertCommerceMoneySchemaCurrent, f as DOCUMENT_MONEY_READ_REBIND, p as DOCUMENT_MONEY_WRITE } from "./detect-DAE-_NAk.js";
|
|
4
|
-
import { n as withTenantMoneyCollectionRead } from "./tenant-money-barrier-
|
|
4
|
+
import { n as withTenantMoneyCollectionRead } from "./tenant-money-barrier-j1m0r6pe.js";
|
|
5
5
|
import { SmrtCollection, SmrtObject, crossPackageRef, field, foreignKey, smrt } from "@happyvertical/smrt-core";
|
|
6
6
|
import { TenantScoped, getTenantId, queryGlobal, queryWithGlobals, tenantId } from "@happyvertical/smrt-tenancy";
|
|
7
7
|
//#region src/models/ContractLineItem.ts
|
|
@@ -115,18 +115,18 @@ var ContractLineItem = class extends SmrtObject {
|
|
|
115
115
|
}
|
|
116
116
|
return this;
|
|
117
117
|
}
|
|
118
|
-
async save() {
|
|
119
|
-
const { saveContractLineItem } = await import("./contract-money-
|
|
120
|
-
return await saveContractLineItem(this);
|
|
118
|
+
async save(options) {
|
|
119
|
+
const { saveContractLineItem } = await import("./contract-money-BxvY2Kcp.js");
|
|
120
|
+
return await saveContractLineItem(this, options);
|
|
121
121
|
}
|
|
122
122
|
/** @internal Contract aggregate persistence only. */
|
|
123
|
-
async saveDerived(capability) {
|
|
123
|
+
async saveDerived(capability, options) {
|
|
124
124
|
if (capability !== DOCUMENT_MONEY_WRITE) throw new Error("Contract line money write capability is required");
|
|
125
125
|
for (const [field2, value] of [["unitPrice", this.unitPrice], ["discount", this.discount]]) if (!Number.isSafeInteger(value)) throw new MoneyValidationError("UNSAFE_MONEY", `Contract line ${field2} ${value} must be a safe integer number of minor units`);
|
|
126
|
-
return await super.save();
|
|
126
|
+
return await super.save(options);
|
|
127
127
|
}
|
|
128
128
|
async delete(options = {}) {
|
|
129
|
-
const { deleteContractLineItem } = await import("./contract-money-
|
|
129
|
+
const { deleteContractLineItem } = await import("./contract-money-BxvY2Kcp.js");
|
|
130
130
|
await deleteContractLineItem(this, options);
|
|
131
131
|
}
|
|
132
132
|
/** @internal Contract aggregate persistence only. */
|
|
@@ -257,4 +257,4 @@ var ContractLineItemCollection = class extends SmrtCollection {
|
|
|
257
257
|
//#endregion
|
|
258
258
|
export { ContractLineItemCollection_exports as n, ContractLineItem as r, ContractLineItemCollection as t };
|
|
259
259
|
|
|
260
|
-
//# sourceMappingURL=ContractLineItemCollection-
|
|
260
|
+
//# sourceMappingURL=ContractLineItemCollection-D74LbDOI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ContractLineItemCollection-D74LbDOI.js","names":["field"],"sources":["../../src/models/ContractLineItem.ts","../../src/collections/ContractLineItemCollection.ts"],"sourcesContent":["/**\n * ContractLineItem model - individual items on a contract\n * @packageDocumentation\n */\n\nimport {\n crossPackageRef,\n field,\n foreignKey,\n SmrtObject,\n type SmrtSaveOptions,\n smrt,\n} from '@happyvertical/smrt-core';\nimport type { DatabaseInterface } from '@happyvertical/smrt-core/migrations';\nimport { TenantScoped, tenantId } from '@happyvertical/smrt-tenancy';\nimport {\n DOCUMENT_MONEY_READ_REBIND,\n DOCUMENT_MONEY_WRITE,\n type DocumentMoneyReadRebindCapability,\n type DocumentMoneyWriteCapability,\n} from '../document-money-internal.js';\nimport { MoneyValidationError } from '../money.js';\nimport type {\n ContractLineItemOptions,\n ContractTaxComponentSnapshot,\n} from '../types/index.js';\n\n/**\n * ContractLineItem represents a single line item on a contract.\n *\n * Line items contain the details of what is being sold/purchased,\n * including quantity, pricing, and optional subscription details.\n *\n * @example\n * ```typescript\n * const lineItem = await lineItems.create({\n * contractId: order.id,\n * description: 'Widget Pro',\n * quantity: 10,\n * unitPrice: 4999, // $49.99 in cents\n * taxRate: 0.08\n * });\n * ```\n */\n@TenantScoped({ mode: 'optional' })\n@smrt({\n tableStrategy: 'sti',\n api: { include: ['list', 'get', 'create', 'update', 'delete'] },\n mcp: { include: ['list', 'get'] },\n cli: { skipApiCheck: true },\n})\nexport class ContractLineItem extends SmrtObject { static __smrtPackage__ = \"@happyvertical/smrt-commerce\";\n /** @internal Collection read guard returns this snapshot on its root DB. */\n rebindMoneyRead(\n capability: DocumentMoneyReadRebindCapability,\n db: DatabaseInterface,\n ): this {\n if (capability !== DOCUMENT_MONEY_READ_REBIND)\n throw new Error(\n 'Contract line read rebinding requires the owning capability',\n );\n this._db = db;\n this.options.db = db;\n return this;\n }\n\n /**\n * Tenant ID for multi-tenant isolation\n * Nullable to support both tenant-scoped and global line items\n */\n @tenantId({ nullable: true })\n tenantId: string | null = null;\n\n /**\n * Parent contract\n */\n @field({ description: 'The order, quote or agreement this line belongs to.' })\n @foreignKey('Contract', { role: 'items' })\n contractId: string = '';\n\n /**\n * Item description\n */\n @field({ description: 'What is being sold or bought on this line.' })\n description: string = '';\n\n /**\n * Quantity ordered. Decimal on purpose — contracts price fractional\n * quantities (hours, weight, bandwidth), as do invoice line items.\n */\n @field({ description: 'How many.' })\n quantity: number = 1.0;\n\n /**\n * Unit price before discount, in **integer minor units** (cents, satoshis),\n * in the document's pricing mode: tax-inclusive when its `lineAmountType`\n * is `inclusive`.\n *\n * The `= 0` initializer is load-bearing: SMRT maps an integer literal to\n * INTEGER and a decimal literal to DECIMAL. Money is exact, so `$49.99` is\n * `4999` (#2401).\n */\n @field({\n description:\n \"The price of one, before discount; includes tax when the document's prices include tax.\",\n ui: { format: 'money' },\n })\n unitPrice: number = 0;\n\n /**\n * Discount amount (flat, not percentage), in integer minor units (#2401).\n */\n @field({ ui: { format: 'money' } })\n discount: number = 0;\n\n discountType: 'none' | 'percent' | 'amount' = 'none';\n\n @field({ type: 'decimal' })\n discountRate = '0.0';\n\n /**\n * Tax rate as decimal (e.g., 0.08 for 8%). A rate is inherently fractional,\n * so it stays DECIMAL — INTEGER would truncate every meaningful value.\n */\n @field({\n description:\n 'The stored fractional tax rate for this line (0.05 means 5%).',\n })\n taxRate: number = 0.0;\n\n taxMode: 'inherit' | 'override' = 'inherit';\n\n @foreignKey('TaxCode', { nullable: true })\n taxCodeId: string | null = null;\n\n taxCodeCode: string | null = null;\n\n taxCodeName: string | null = null;\n\n taxComponentsJson: string | null = null;\n\n get taxComponents(): ContractTaxComponentSnapshot[] {\n if (this.taxComponentsJson === null) return [];\n try {\n const value: unknown = JSON.parse(this.taxComponentsJson);\n if (!Array.isArray(value)) return [];\n return value.filter(\n (entry): entry is ContractTaxComponentSnapshot =>\n !!entry &&\n typeof entry === 'object' &&\n typeof (entry as ContractTaxComponentSnapshot).taxComponentId ===\n 'string' &&\n typeof (entry as ContractTaxComponentSnapshot).name === 'string' &&\n typeof (entry as ContractTaxComponentSnapshot).percent === 'string' &&\n Number.isSafeInteger(\n (entry as ContractTaxComponentSnapshot).taxMinor,\n ),\n );\n } catch {\n return [];\n }\n }\n\n set taxComponents(value: ContractTaxComponentSnapshot[]) {\n this.taxComponentsJson = JSON.stringify(value);\n }\n\n /** Exact sum of frozen component taxes, in integer minor units. */\n @field({ ui: { format: 'money' } })\n taxAmount = 0;\n\n /** Stable issue/freeze identity, independent of lifecycle updated_at. */\n moneySnapshotId = '';\n\n /**\n * Line amount in integer minor units: net of discount and before tax for\n * `exclusive` / `none` documents, and tax-inclusive for `inclusive` ones;\n * {@link taxAmount} holds the tax. Derived by the Contract money aggregate\n * on every save.\n */\n @field({\n description:\n \"The line amount: net of discount, and including tax only when the document's prices include tax.\",\n ui: { format: 'money' },\n })\n amount: number = 0;\n\n /**\n * Optional product reference (cross-package, plain string)\n */\n @field({\n description: 'The product this line is for, if it is one you list.',\n })\n @crossPackageRef('@happyvertical/smrt-products:Product')\n productId: string = '';\n\n /**\n * SKU or item code\n */\n sku: string = '';\n\n /**\n * Start date (for lease/subscription items)\n */\n startDate: Date | null = null;\n\n /**\n * End date (for lease/subscription items)\n */\n endDate: Date | null = null;\n\n /**\n * Billing period (for subscriptions: 'monthly', 'yearly', etc.)\n */\n billingPeriod: string = '';\n\n /**\n * Sort order within the contract\n */\n sortOrder: number = 0;\n\n constructor(options: ContractLineItemOptions = {}) {\n super(options);\n if (options.tenantId !== undefined) this.tenantId = options.tenantId;\n if (options.contractId !== undefined) this.contractId = options.contractId;\n if (options.description !== undefined)\n this.description = options.description;\n if (options.quantity !== undefined) this.quantity = options.quantity;\n if (options.unitPrice !== undefined) this.unitPrice = options.unitPrice;\n if (options.discount !== undefined) this.discount = options.discount;\n if (options.discountType !== undefined)\n this.discountType = options.discountType;\n if (options.discountRate !== undefined)\n this.discountRate = options.discountRate;\n if (options.taxRate !== undefined) this.taxRate = options.taxRate;\n if (options.taxMode !== undefined) this.taxMode = options.taxMode;\n if (options.taxCodeId !== undefined) this.taxCodeId = options.taxCodeId;\n if (options.taxCodeCode !== undefined)\n this.taxCodeCode = options.taxCodeCode;\n if (options.taxCodeName !== undefined)\n this.taxCodeName = options.taxCodeName;\n if (options.taxComponentsJson !== undefined)\n this.taxComponentsJson = options.taxComponentsJson;\n if (options.taxComponents !== undefined)\n this.taxComponents = structuredClone(options.taxComponents);\n if (options.taxAmount !== undefined) this.taxAmount = options.taxAmount;\n if (options.moneySnapshotId !== undefined)\n this.moneySnapshotId = options.moneySnapshotId;\n if (options.amount !== undefined) this.amount = options.amount;\n if (options.productId !== undefined) this.productId = options.productId;\n if (options.sku !== undefined) this.sku = options.sku;\n if (options.startDate !== undefined) this.startDate = options.startDate;\n if (options.endDate !== undefined) this.endDate = options.endDate;\n if (options.billingPeriod !== undefined)\n this.billingPeriod = options.billingPeriod;\n if (options.sortOrder !== undefined) this.sortOrder = options.sortOrder;\n }\n\n override async initialize(): Promise<this> {\n await super.initialize();\n // A row read from the database must not be old-format money data.\n if (this.isPersisted) {\n const { assertHydratedMoneyRowCurrent } = await import(\n '../upgrade/detect.js'\n );\n await assertHydratedMoneyRowCurrent(this);\n }\n return this;\n }\n\n override async save(options?: SmrtSaveOptions): Promise<this> {\n const { saveContractLineItem } = await import('../contract-money.js');\n return (await saveContractLineItem(this, options)) as this;\n }\n\n /** @internal Contract aggregate persistence only. */\n async saveDerived(\n capability: DocumentMoneyWriteCapability,\n options?: SmrtSaveOptions,\n ): Promise<this> {\n if (capability !== DOCUMENT_MONEY_WRITE)\n throw new Error('Contract line money write capability is required');\n // Money is integer minor units: refuse a major-unit price before it can\n // reach the database (#2401), ahead of the aggregate recompute.\n for (const [field, value] of [\n ['unitPrice', this.unitPrice],\n ['discount', this.discount],\n ] as const)\n if (!Number.isSafeInteger(value))\n throw new MoneyValidationError(\n 'UNSAFE_MONEY',\n `Contract line ${field} ${value} must be a safe integer number of minor units`,\n );\n return (await super.save(options)) as this;\n }\n\n override async delete(\n options: { expectedUpdatedAt?: Date | string } = {},\n ): Promise<void> {\n const { deleteContractLineItem } = await import('../contract-money.js');\n await deleteContractLineItem(this, options);\n }\n\n /** @internal Contract aggregate persistence only. */\n async deleteDerived(\n capability: DocumentMoneyWriteCapability,\n options: { expectedUpdatedAt?: Date | string } = {},\n ): Promise<void> {\n if (capability !== DOCUMENT_MONEY_WRITE)\n throw new Error('Contract line money write capability is required');\n await super.delete(options);\n }\n\n /**\n * Check if this is a subscription/recurring item\n */\n isRecurring(): boolean {\n return !!this.billingPeriod && !!this.startDate;\n }\n\n /**\n * Check if subscription is active\n */\n isSubscriptionActive(): boolean {\n if (!this.isRecurring()) return false;\n if (!this.startDate) return false;\n\n const now = new Date();\n if (now < this.startDate) return false;\n if (this.endDate && now > this.endDate) return false;\n\n return true;\n }\n}\n\nexport default ContractLineItem;\n","/**\n * ContractLineItemCollection - Collection manager for ContractLineItem objects\n * @packageDocumentation\n */\n\nimport {\n SmrtCollection,\n type SmrtListOptions,\n type SmrtObject,\n type SmrtSelectedRow,\n type SmrtSelectField,\n type SmrtStiReadScope,\n type SmrtWhereClause,\n} from '@happyvertical/smrt-core';\nimport {\n getTenantId,\n queryGlobal,\n queryWithGlobals,\n} from '@happyvertical/smrt-tenancy';\nimport { DOCUMENT_MONEY_READ_REBIND } from '../document-money-internal.js';\nimport { ContractLineItem } from '../models/ContractLineItem.js';\nimport { withTenantMoneyCollectionRead } from '../tenant-money-barrier.js';\nimport { assertCommerceMoneySchemaCurrent } from '../upgrade/detect.js';\n\nexport class ContractLineItemCollection extends SmrtCollection<ContractLineItem> {\n static readonly _itemClass = ContractLineItem;\n\n private async withMoneyRead<T>(operation: () => Promise<T>): Promise<T> {\n const rootDb = this.db;\n const tenantId = getTenantId();\n if (!tenantId) {\n // Without a tenant, still refuse a database with old money storage.\n await assertCommerceMoneySchemaCurrent(rootDb);\n return operation();\n }\n const result = await withTenantMoneyCollectionRead(\n rootDb,\n tenantId,\n (boundDb) => this.withDatabase(boundDb, operation),\n );\n if (result instanceof ContractLineItem)\n result.rebindMoneyRead(DOCUMENT_MONEY_READ_REBIND, rootDb);\n else if (Array.isArray(result))\n for (const item of result)\n if (item instanceof ContractLineItem)\n item.rebindMoneyRead(DOCUMENT_MONEY_READ_REBIND, rootDb);\n return result;\n }\n\n override async get(\n filter: string | SmrtWhereClause<ContractLineItem>,\n options: Parameters<SmrtCollection<ContractLineItem>['get']>[1] = {},\n ): Promise<ContractLineItem | null> {\n return this.withMoneyRead(() => super.get(filter, options));\n }\n\n override async list<\n const Select extends readonly SmrtSelectField<ContractLineItem>[],\n >(\n options: Omit<SmrtListOptions<ContractLineItem>, 'select' | 'stiScope'> & {\n select: Select;\n include?: never;\n stiScope: SmrtStiReadScope;\n },\n ): Promise<Record<string, unknown>[]>;\n override async list<\n const Select extends readonly SmrtSelectField<ContractLineItem>[],\n >(\n options: Omit<SmrtListOptions<ContractLineItem>, 'select' | 'stiScope'> & {\n select: Select;\n include?: never;\n stiScope?: undefined;\n },\n ): Promise<SmrtSelectedRow<ContractLineItem, Select>[]>;\n override async list(\n options: Omit<SmrtListOptions<ContractLineItem>, 'select' | 'stiScope'> & {\n select?: undefined;\n stiScope: SmrtStiReadScope;\n },\n ): Promise<SmrtObject[]>;\n override async list(options?: undefined): Promise<ContractLineItem[]>;\n override async list(\n options: Omit<SmrtListOptions<ContractLineItem>, 'select' | 'stiScope'> & {\n select?: undefined;\n stiScope?: undefined;\n },\n ): Promise<ContractLineItem[]>;\n override async list(\n options:\n | (Omit<SmrtListOptions<ContractLineItem>, 'select'> & {\n select?: undefined;\n })\n | undefined,\n ): Promise<SmrtObject[]>;\n override async list(\n options: SmrtListOptions<ContractLineItem> | undefined,\n ): Promise<SmrtObject[] | Record<string, unknown>[]>;\n override async list(\n options: SmrtListOptions<ContractLineItem> = {},\n ): Promise<SmrtObject[] | Record<string, unknown>[]> {\n return this.withMoneyRead(() => super.list(options));\n }\n\n /**\n * Find contract line items by their parent contract.\n *\n * @param contractId - Contract ID\n * @returns Array of contract line items, sorted by sortOrder\n */\n async findByContract(contractId: string): Promise<ContractLineItem[]> {\n return await this.list({\n where: { contractId },\n orderBy: 'sortOrder ASC',\n });\n }\n\n // ============================================================================\n // Tenant Helper Methods\n // ============================================================================\n\n /**\n * Find all contract line items belonging to a specific tenant\n *\n * @param tenantId - Tenant ID\n * @returns Array of contract line items for the tenant\n */\n async findByTenant(tenantId: string): Promise<ContractLineItem[]> {\n return this.list({ where: { tenantId } });\n }\n\n /**\n * Find all global contract line items (not associated with any tenant).\n *\n * Routes through the shared tenant-global helper so it does not throw under\n * an active tenant context (an explicit `tenant_id IS NULL` filter would be\n * flagged as an isolation violation). (#1600)\n *\n * @returns Array of global contract line items\n */\n async findGlobal(): Promise<ContractLineItem[]> {\n return queryGlobal<ContractLineItem>(this);\n }\n\n /**\n * Find contract line items for a tenant including global line items.\n *\n * Fails closed if an active tenant context requests a different tenant's\n * rows; the admin/system path keeps the cross-tenant capability. (#1600)\n *\n * @param tenantId - Tenant ID\n * @returns Array of tenant-specific and global contract line items\n */\n async findWithGlobals(tenantId: string): Promise<ContractLineItem[]> {\n return queryWithGlobals<ContractLineItem>(\n this,\n tenantId,\n 'ContractLineItem.findWithGlobals',\n );\n }\n}\n"],"mappings":"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"}
|
|
@@ -4,11 +4,11 @@ import { MoneyValidationError, assertIntegerMinorUnits, calculateMoneyDocument,
|
|
|
4
4
|
import { n as withHistoricalCommerceWrite, t as assertHistoricalCommerceWrite } from "./historical-commerce-internal-C9ButfuH.js";
|
|
5
5
|
import { t as allocateFrozenCredit } from "./credit-allocation-yspz0Lab.js";
|
|
6
6
|
import { _ as withDocumentMoneyTransaction, a as assertCommerceMoneySchemaCurrent, f as DOCUMENT_MONEY_READ_REBIND, g as withDocumentMoneyObjectTransaction, h as lockDocumentMoneyParents, p as DOCUMENT_MONEY_WRITE } from "./detect-DAE-_NAk.js";
|
|
7
|
-
import { s as parseInvoiceRetention, t as InvoiceCollection } from "./InvoiceCollection-
|
|
8
|
-
import { n as withTenantMoneyCollectionRead, r as withTenantMoneyRuntime, t as lockTenantMoneyRuntime } from "./tenant-money-barrier-
|
|
9
|
-
import { t as TaxCodeCollection } from "./TaxCodeCollection-
|
|
10
|
-
import { t as ContractLineItemCollection } from "./ContractLineItemCollection-
|
|
11
|
-
import { t as TaxComponentCollection } from "./TaxComponentCollection-
|
|
7
|
+
import { s as parseInvoiceRetention, t as InvoiceCollection } from "./InvoiceCollection-BPEzXaKm.js";
|
|
8
|
+
import { n as withTenantMoneyCollectionRead, r as withTenantMoneyRuntime, t as lockTenantMoneyRuntime } from "./tenant-money-barrier-j1m0r6pe.js";
|
|
9
|
+
import { t as TaxCodeCollection } from "./TaxCodeCollection-DpQeIqP4.js";
|
|
10
|
+
import { t as ContractLineItemCollection } from "./ContractLineItemCollection-D74LbDOI.js";
|
|
11
|
+
import { t as TaxComponentCollection } from "./TaxComponentCollection-wFGWOaxy.js";
|
|
12
12
|
import { SmrtCollection, SmrtObject, crossPackageRef, field, foreignKey, smrt } from "@happyvertical/smrt-core";
|
|
13
13
|
import { TenantScoped, getTenantId, queryGlobal, queryWithGlobals, tenantId, withTenant } from "@happyvertical/smrt-tenancy";
|
|
14
14
|
import { ISO_4217_MINOR_UNITS } from "@happyvertical/smrt-ui/currency";
|
|
@@ -557,15 +557,15 @@ var InvoiceLineItem = class extends SmrtObject {
|
|
|
557
557
|
return this;
|
|
558
558
|
}
|
|
559
559
|
/** Persist through the invoice money aggregate. */
|
|
560
|
-
async save() {
|
|
560
|
+
async save(options) {
|
|
561
561
|
const { saveInvoiceLineItem } = await Promise.resolve().then(() => document_money_exports);
|
|
562
|
-
return await saveInvoiceLineItem(this);
|
|
562
|
+
return await saveInvoiceLineItem(this, options);
|
|
563
563
|
}
|
|
564
564
|
/** @internal Aggregate persistence only. */
|
|
565
|
-
async saveDerived(capability) {
|
|
565
|
+
async saveDerived(capability, options) {
|
|
566
566
|
if (capability !== DOCUMENT_MONEY_WRITE) throw new Error("Invoice line money write capability is required");
|
|
567
567
|
for (const [field2, value] of [["unitPrice", this.unitPrice], ["discount", this.discount]]) if (!Number.isSafeInteger(value)) throw new MoneyValidationError("UNSAFE_MONEY", `Invoice line ${field2} ${value} must be a safe integer number of minor units`);
|
|
568
|
-
return await super.save();
|
|
568
|
+
return await super.save(options);
|
|
569
569
|
}
|
|
570
570
|
async delete(options = {}) {
|
|
571
571
|
const { deleteInvoiceLineItem } = await Promise.resolve().then(() => document_money_exports);
|
|
@@ -1226,7 +1226,7 @@ var Contract = class extends SmrtObject {
|
|
|
1226
1226
|
* Calculate and update totals from line items
|
|
1227
1227
|
*/
|
|
1228
1228
|
async recalculateTotals() {
|
|
1229
|
-
const { recalculateContractTotals } = await import("./contract-money-
|
|
1229
|
+
const { recalculateContractTotals } = await import("./contract-money-BxvY2Kcp.js");
|
|
1230
1230
|
await recalculateContractTotals(this);
|
|
1231
1231
|
}
|
|
1232
1232
|
/**
|
|
@@ -1249,20 +1249,20 @@ var Contract = class extends SmrtObject {
|
|
|
1249
1249
|
* Validate the amounts and the status transition before persisting, then
|
|
1250
1250
|
* save. Inherited by every STI subtype (Estimate/Order/Lease/.../LicenseSale),
|
|
1251
1251
|
* so a forged `status` on any of them is caught here. LicenseSale layers its
|
|
1252
|
-
* own rights-immutability guard on top via `super.save()`. See S5 audit
|
|
1252
|
+
* own rights-immutability guard on top via `super.save(options)`. See S5 audit
|
|
1253
1253
|
* #1390.
|
|
1254
1254
|
*
|
|
1255
1255
|
* `subtotal` / `taxAmount` / `totalAmount` are mass-assignable on the
|
|
1256
1256
|
* generated create/update routes, so the minor-units check runs on every
|
|
1257
1257
|
* write surface (#2401).
|
|
1258
1258
|
*/
|
|
1259
|
-
async save() {
|
|
1260
|
-
const { saveContract } = await import("./contract-money-
|
|
1261
|
-
return await saveContract(this);
|
|
1259
|
+
async save(options) {
|
|
1260
|
+
const { saveContract } = await import("./contract-money-BxvY2Kcp.js");
|
|
1261
|
+
return await saveContract(this, options);
|
|
1262
1262
|
}
|
|
1263
1263
|
/** Received purchase monetary history cannot be deleted. */
|
|
1264
1264
|
async delete(options = {}) {
|
|
1265
|
-
const { deleteContract } = await import("./contract-money-
|
|
1265
|
+
const { deleteContract } = await import("./contract-money-BxvY2Kcp.js");
|
|
1266
1266
|
await deleteContract(this, options);
|
|
1267
1267
|
}
|
|
1268
1268
|
/** @internal Contract aggregate persistence only. */
|
|
@@ -1271,7 +1271,7 @@ var Contract = class extends SmrtObject {
|
|
|
1271
1271
|
await super.delete(options);
|
|
1272
1272
|
}
|
|
1273
1273
|
/** @internal Contract aggregate persistence only. */
|
|
1274
|
-
async saveDerived(capability) {
|
|
1274
|
+
async saveDerived(capability, options) {
|
|
1275
1275
|
if (capability !== DOCUMENT_MONEY_WRITE) throw new Error("Contract money write capability is required");
|
|
1276
1276
|
assertIntegerMinorUnits("Contract", this.reference || this.id || "<new>", [
|
|
1277
1277
|
["subtotal", this.subtotal],
|
|
@@ -1281,7 +1281,7 @@ var Contract = class extends SmrtObject {
|
|
|
1281
1281
|
]);
|
|
1282
1282
|
const prior = await this.resolvePriorStatus();
|
|
1283
1283
|
this.assertContractStatusTransition(prior);
|
|
1284
|
-
const result = await super.save();
|
|
1284
|
+
const result = await super.save(options);
|
|
1285
1285
|
loadedContractStatus.set(this, this.status);
|
|
1286
1286
|
return result;
|
|
1287
1287
|
}
|
|
@@ -1635,9 +1635,9 @@ var LicenseSale = class extends SalesContract {
|
|
|
1635
1635
|
* caller transitions to `ACCEPTED` and saves — `validateImmutable`
|
|
1636
1636
|
* picks that up post-save on the next call.
|
|
1637
1637
|
*/
|
|
1638
|
-
async save() {
|
|
1638
|
+
async save(options) {
|
|
1639
1639
|
this.validateImmutable();
|
|
1640
|
-
const result = await super.save();
|
|
1640
|
+
const result = await super.save(options);
|
|
1641
1641
|
if (this.status === ContractStatus.ACCEPTED && !issuedRightsSnapshot.has(this)) issuedRightsSnapshot.set(this, this.serializeRightsSnapshot());
|
|
1642
1642
|
return result;
|
|
1643
1643
|
}
|
|
@@ -2812,7 +2812,7 @@ async function getInvoiceMoneyFacts(input) {
|
|
|
2812
2812
|
db: scope.db
|
|
2813
2813
|
}));
|
|
2814
2814
|
}
|
|
2815
|
-
async function saveInvoice(input) {
|
|
2815
|
+
async function saveInvoice(input, options) {
|
|
2816
2816
|
const priorRevision = input.updated_at;
|
|
2817
2817
|
try {
|
|
2818
2818
|
return await withDocumentMoneyTransaction(input.db, async (tx) => input.withDatabase(tx, async (invoice) => {
|
|
@@ -2858,7 +2858,7 @@ async function saveInvoice(input) {
|
|
|
2858
2858
|
invoice.sellerTaxRegistrations = structuredClone(settings.taxRegistrations);
|
|
2859
2859
|
invoice.partyTaxId = customer?.taxId ?? "";
|
|
2860
2860
|
}
|
|
2861
|
-
return invoice.saveDerived(DOCUMENT_MONEY_WRITE);
|
|
2861
|
+
return invoice.saveDerived(DOCUMENT_MONEY_WRITE, options);
|
|
2862
2862
|
}
|
|
2863
2863
|
if (invoice.tenantId !== existing.tenantId) throw new MoneyValidationError("FROZEN_DOCUMENT", "Invoice tenant identity cannot change");
|
|
2864
2864
|
if (invoice.kind !== existing.kind || invoice.creditedInvoiceId !== existing.creditedInvoiceId) throw new MoneyValidationError("FROZEN_DOCUMENT", "Invoice kind and credited invoice identity are immutable");
|
|
@@ -2871,7 +2871,7 @@ async function saveInvoice(input) {
|
|
|
2871
2871
|
if (invoice.status === InvoiceStatus.CANCELLED && locked.invoice.status !== InvoiceStatus.CANCELLED && locked.invoice.kind === "credit_note" && locked.invoice.amountPaid > 0) throw new MoneyValidationError("FROZEN_DOCUMENT", "A refunded credit note cannot be cancelled");
|
|
2872
2872
|
if (invoice.status === InvoiceStatus.CANCELLED && locked.invoice.status !== InvoiceStatus.CANCELLED && locked.invoice.arJournalId && !locked.invoice.arReversalJournalId) throw new MoneyValidationError("FROZEN_DOCUMENT", "A posted invoice requires an atomic reversal before cancellation");
|
|
2873
2873
|
assertFieldsUnchanged(invoice, locked.invoice, FROZEN_INVOICE_FIELDS, "Invoice");
|
|
2874
|
-
const saved2 = await invoice.saveDerived(DOCUMENT_MONEY_WRITE);
|
|
2874
|
+
const saved2 = await invoice.saveDerived(DOCUMENT_MONEY_WRITE, options);
|
|
2875
2875
|
if (locked.source) await refreshIssuedCreditBalance(tx, locked.source);
|
|
2876
2876
|
return saved2;
|
|
2877
2877
|
}
|
|
@@ -2886,7 +2886,7 @@ async function saveInvoice(input) {
|
|
|
2886
2886
|
invoice.partyTaxId = customer?.taxId ?? "";
|
|
2887
2887
|
invoice.moneySnapshotId = snapshotId;
|
|
2888
2888
|
}
|
|
2889
|
-
const saved = await invoice.saveDerived(DOCUMENT_MONEY_WRITE);
|
|
2889
|
+
const saved = await invoice.saveDerived(DOCUMENT_MONEY_WRITE, options);
|
|
2890
2890
|
if (locked.source) await refreshIssuedCreditBalance(tx, locked.source);
|
|
2891
2891
|
return saved;
|
|
2892
2892
|
}));
|
|
@@ -2895,7 +2895,7 @@ async function saveInvoice(input) {
|
|
|
2895
2895
|
throw error;
|
|
2896
2896
|
}
|
|
2897
2897
|
}
|
|
2898
|
-
async function saveInvoiceLineItem(input) {
|
|
2898
|
+
async function saveInvoiceLineItem(input, options) {
|
|
2899
2899
|
return withDocumentMoneyObjectTransaction(input, async (line, tx) => {
|
|
2900
2900
|
const candidateTenantId = getTenantId() ?? line.tenantId ?? null;
|
|
2901
2901
|
const settings = await lockRuntimeSettings(tx, candidateTenantId);
|
|
@@ -2913,9 +2913,9 @@ async function saveInvoiceLineItem(input) {
|
|
|
2913
2913
|
if (isFrozen(invoice)) {
|
|
2914
2914
|
if (!persisted) throw new MoneyValidationError("FROZEN_DOCUMENT", "Cannot add a line to a frozen invoice");
|
|
2915
2915
|
assertFieldsUnchanged(line, persisted, FROZEN_LINE_FIELDS, "Invoice line");
|
|
2916
|
-
return line.saveDerived(DOCUMENT_MONEY_WRITE);
|
|
2916
|
+
return line.saveDerived(DOCUMENT_MONEY_WRITE, options);
|
|
2917
2917
|
}
|
|
2918
|
-
await line.saveDerived(DOCUMENT_MONEY_WRITE);
|
|
2918
|
+
await line.saveDerived(DOCUMENT_MONEY_WRITE, options);
|
|
2919
2919
|
const priorAggregate = aggregateSignature(invoice);
|
|
2920
2920
|
await recomputeInvoiceAggregate(tx, invoice, settings);
|
|
2921
2921
|
if (aggregateSignature(invoice) !== priorAggregate) await invoice.saveDerived(DOCUMENT_MONEY_WRITE);
|
|
@@ -3736,17 +3736,17 @@ var DocumentTax = class extends SmrtObject {
|
|
|
3736
3736
|
if (this.kind !== "taxable" || !this.taxComponentName || !this.percent) throw new MoneyValidationError("INVALID_MONEY_INPUT", "Component DocumentTax rows require taxable component snapshots");
|
|
3737
3737
|
if (this.recoverableMinor !== 0 && this.recoverableMinor !== this.taxMinor) throw new MoneyValidationError("INVALID_MONEY_INPUT", "DocumentTax recoverableMinor must be zero or the component tax total");
|
|
3738
3738
|
}
|
|
3739
|
-
async save() {
|
|
3739
|
+
async save(_options) {
|
|
3740
3740
|
throw new MoneyValidationError("FROZEN_DOCUMENT", "DocumentTax rows are derived and cannot be saved directly");
|
|
3741
3741
|
}
|
|
3742
3742
|
async delete(_options = {}) {
|
|
3743
3743
|
throw new MoneyValidationError("FROZEN_DOCUMENT", "DocumentTax rows are derived and cannot be deleted directly");
|
|
3744
3744
|
}
|
|
3745
3745
|
/** @internal Aggregate persistence only. */
|
|
3746
|
-
async saveDerived(capability) {
|
|
3746
|
+
async saveDerived(capability, options) {
|
|
3747
3747
|
if (capability !== DOCUMENT_MONEY_WRITE) throw new MoneyValidationError("FROZEN_DOCUMENT", "DocumentTax write capability is required");
|
|
3748
3748
|
this.assertValidDerivedRow();
|
|
3749
|
-
return await super.save();
|
|
3749
|
+
return await super.save(options);
|
|
3750
3750
|
}
|
|
3751
3751
|
/** @internal Aggregate persistence only. */
|
|
3752
3752
|
async deleteDerived(capability, options = {}) {
|
|
@@ -4399,4 +4399,4 @@ var DocumentTaxCollection = class extends SmrtCollection {
|
|
|
4399
4399
|
//#endregion
|
|
4400
4400
|
export { DEFAULT_PARTY_CONTACT_FIELD_NAMES as $, PurchaseContractCollection as A, PurchaseOrder as B, refreshIssuedCreditBalance as C, issueContractMilestoneInvoice as D, getContractBillingSchedule as E, Lease as F, isContractSnapshotReportEligible as G, SupplierQuote as H, LicenseSale as I, HistoricalSalesLine as J, Vendor as K, Order as L, Cart as M, Contract as N, ContractCollection as O, Estimate as P, Customer as Q, ProductionOrder as R, previewInvoiceMoney as S, approveContractBillingSchedule as T, WholesaleOrder as U, SalesContract as V, classifyContractPurchase as W, InvoiceLineItem as X, InvoiceLineItemCollection as Y, CustomerCollection as Z, historicalText as _, getReceivedSalesContractMoney as a, normalizePartyContacts as at, getInvoiceMoneyFacts as b, validateReceivedPurchaseMoneyFacts as c, validatePartyContactRows as ct, HistoricalSalesTaxClassificationRequired as d, PARTY_CONTACT_MAX_LENGTHS as et, listHistoricalSalesHeaderFacts as f, historicalCalendarDate as g, recordHistoricalSalesMoney as h, getReceivedPurchaseMoney as i, applyPartyContactIntent as it, Agreement as j, SalesContractCollection as k, VendorCollection as l, readHistoricalSalesLines as m, DocumentTaxCollection_exports as n, PartyContactPayloadError as nt, recordReceivedPurchaseMoney as o, readPartyContactRows as ot, getHistoricalSalesMoney as p, HistoricalSalesLineCollection as q, ReceivedPurchaseTaxClassificationRequired as r, PartyContactValidationError as rt, recordReceivedSalesContractMoney as s, savePartyContacts as st, DocumentTaxCollection as t, PartyContactPartyNotFoundError as tt, DocumentTax as u, validateHistoricalSalesMoneyFacts as v, allocateContractMilestones as w, lockAndReloadInvoice as x, document_money_exports as y, PurchaseContract as z };
|
|
4401
4401
|
|
|
4402
|
-
//# sourceMappingURL=DocumentTaxCollection-
|
|
4402
|
+
//# sourceMappingURL=DocumentTaxCollection-BmKyJGZi.js.map
|