@happyvertical/smrt-commerce 0.57.3 → 0.57.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +17 -0
- package/README.md +130 -0
- package/agents/accounting-snapshot-mapper.md +11 -0
- package/agents/contract-billing-schedules.md +67 -0
- package/agents/contract-money.md +81 -0
- package/agents/customer-funds.md +96 -0
- package/agents/historical-sales.md +132 -0
- package/agents/money-calculator.md +36 -0
- package/agents/money-model.md +6 -3
- package/agents/observed-purchase-prices.md +37 -0
- package/agents/payment-allocations.md +59 -0
- package/agents/received-sales-contract-money.md +38 -0
- package/dist/accounting-snapshot.d.ts +8 -1
- package/dist/accounting-snapshot.d.ts.map +1 -1
- package/dist/allocation-integrity.d.ts.map +1 -1
- package/dist/chunks/{ContractLineItemCollection-BZcrlrrY.js → ContractLineItemCollection-J4xtRtzE.js} +6 -6
- package/dist/chunks/{ContractLineItemCollection-BZcrlrrY.js.map → ContractLineItemCollection-J4xtRtzE.js.map} +1 -1
- package/dist/chunks/DocumentTaxCollection-C42x0YLW.js +4385 -0
- package/dist/chunks/DocumentTaxCollection-C42x0YLW.js.map +1 -0
- package/dist/chunks/HistoricalCustomerFundsCollections-B5x8gTW3.js +170 -0
- package/dist/chunks/HistoricalCustomerFundsCollections-B5x8gTW3.js.map +1 -0
- package/dist/chunks/{InvoiceCollection-cinzAqt6.js → InvoiceCollection-BIcge9Wl.js} +131 -18
- package/dist/chunks/InvoiceCollection-BIcge9Wl.js.map +1 -0
- package/dist/chunks/{TaxCodeCollection-DaBOPG9c.js → TaxCodeCollection-RWdVaheF.js} +3 -4
- package/dist/chunks/TaxCodeCollection-RWdVaheF.js.map +1 -0
- package/dist/chunks/{TaxComponentCollection-C4zxnyVu.js → TaxComponentCollection-Dt2jeWiC.js} +3 -3
- package/dist/chunks/{TaxComponentCollection-C4zxnyVu.js.map → TaxComponentCollection-Dt2jeWiC.js.map} +1 -1
- package/dist/chunks/{allocation-integrity-WmWyXhtG.js → allocation-integrity-DJ7-LY1j.js} +7 -7
- package/dist/chunks/{allocation-integrity-WmWyXhtG.js.map → allocation-integrity-DJ7-LY1j.js.map} +1 -1
- package/dist/chunks/{contract-money-EuToOghh.js → contract-money-DSRTMoXm.js} +45 -12
- package/dist/chunks/contract-money-DSRTMoXm.js.map +1 -0
- package/dist/chunks/customer-funds-internal-BQzoJXK5.js +24 -0
- package/dist/chunks/customer-funds-internal-BQzoJXK5.js.map +1 -0
- package/dist/chunks/{detect-CY9ufaFb.js → detect-DAE-_NAk.js} +5 -2
- package/dist/chunks/{detect-CY9ufaFb.js.map → detect-DAE-_NAk.js.map} +1 -1
- package/dist/chunks/historical-commerce-internal-C9ButfuH.js +18 -0
- package/dist/chunks/historical-commerce-internal-C9ButfuH.js.map +1 -0
- package/dist/chunks/{invoice-posting-C2i5dOVZ.js → invoice-posting-BeTPw3h9.js} +5 -5
- package/dist/chunks/invoice-posting-BeTPw3h9.js.map +1 -0
- package/dist/chunks/retention-accounting-Brdj9x-V.js +2323 -0
- package/dist/chunks/retention-accounting-Brdj9x-V.js.map +1 -0
- package/dist/chunks/retention-accounting-internal-CBQRvd74.js +17 -0
- package/dist/chunks/retention-accounting-internal-CBQRvd74.js.map +1 -0
- package/dist/chunks/{tenant-money-barrier-6TlqUeVj.js → tenant-money-barrier-DoF6lR8h.js} +5 -5
- package/dist/chunks/{tenant-money-barrier-6TlqUeVj.js.map → tenant-money-barrier-DoF6lR8h.js.map} +1 -1
- package/dist/chunks/types-Bbm0Xflc.js.map +1 -1
- package/dist/collections/DocumentTaxCollection.d.ts +4 -1
- package/dist/collections/DocumentTaxCollection.d.ts.map +1 -1
- package/dist/collections/HistoricalCustomerFundsCollections.d.ts +10 -0
- package/dist/collections/HistoricalCustomerFundsCollections.d.ts.map +1 -0
- package/dist/collections/HistoricalSalesLineCollection.d.ts +6 -0
- package/dist/collections/HistoricalSalesLineCollection.d.ts.map +1 -0
- package/dist/collections/PaymentAllocationCollection.d.ts +2 -6
- package/dist/collections/PaymentAllocationCollection.d.ts.map +1 -1
- package/dist/collections/PurchasePriceObservationCollection.d.ts +6 -0
- package/dist/collections/PurchasePriceObservationCollection.d.ts.map +1 -0
- package/dist/collections/index.d.ts +1 -0
- package/dist/collections/index.d.ts.map +1 -1
- package/dist/contract-billing-schedule.d.ts +83 -0
- package/dist/contract-billing-schedule.d.ts.map +1 -0
- package/dist/contract-money.d.ts +2 -0
- package/dist/contract-money.d.ts.map +1 -1
- package/dist/customer-funds-internal.d.ts +6 -0
- package/dist/customer-funds-internal.d.ts.map +1 -0
- package/dist/customer-funds.d.ts +108 -0
- package/dist/customer-funds.d.ts.map +1 -0
- package/dist/document-money.d.ts +11 -0
- package/dist/document-money.d.ts.map +1 -1
- package/dist/historical-commerce-internal.d.ts +3 -0
- package/dist/historical-commerce-internal.d.ts.map +1 -0
- package/dist/historical-customer-funds-types.d.ts +113 -0
- package/dist/historical-customer-funds-types.d.ts.map +1 -0
- package/dist/historical-customer-funds.d.ts +23 -0
- package/dist/historical-customer-funds.d.ts.map +1 -0
- package/dist/historical-funds-internal.d.ts +5 -0
- package/dist/historical-funds-internal.d.ts.map +1 -0
- package/dist/historical-sales-money.d.ts +22 -0
- package/dist/historical-sales-money.d.ts.map +1 -0
- package/dist/historical-sales-reports.d.ts +31 -0
- package/dist/historical-sales-reports.d.ts.map +1 -0
- package/dist/historical-sales-types.d.ts +106 -0
- package/dist/historical-sales-types.d.ts.map +1 -0
- package/dist/historical-sales-validation.d.ts +12 -0
- package/dist/historical-sales-validation.d.ts.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1668 -1643
- package/dist/index.js.map +1 -1
- package/dist/invoice-accounting-sync.d.ts +0 -1
- package/dist/invoice-accounting-sync.d.ts.map +1 -1
- package/dist/invoice-mcp.d.ts.map +1 -1
- package/dist/invoice-posting.d.ts.map +1 -1
- package/dist/invoice-retention.d.ts +16 -0
- package/dist/invoice-retention.d.ts.map +1 -0
- package/dist/invoices.d.ts +2 -0
- package/dist/invoices.d.ts.map +1 -1
- package/dist/invoices.js +2 -2
- package/dist/manifest.json +7563 -4419
- package/dist/models/Contract.d.ts +14 -0
- package/dist/models/Contract.d.ts.map +1 -1
- package/dist/models/DocumentTax.d.ts +2 -0
- package/dist/models/DocumentTax.d.ts.map +1 -1
- package/dist/models/HistoricalCustomerFunds.d.ts +36 -0
- package/dist/models/HistoricalCustomerFunds.d.ts.map +1 -0
- package/dist/models/HistoricalCustomerFundsAllocation.d.ts +32 -0
- package/dist/models/HistoricalCustomerFundsAllocation.d.ts.map +1 -0
- package/dist/models/HistoricalSalesLine.d.ts +29 -0
- package/dist/models/HistoricalSalesLine.d.ts.map +1 -0
- package/dist/models/Invoice.d.ts +10 -1
- package/dist/models/Invoice.d.ts.map +1 -1
- package/dist/models/Payment.d.ts +7 -1
- package/dist/models/Payment.d.ts.map +1 -1
- package/dist/models/PaymentAllocation.d.ts +3 -1
- package/dist/models/PaymentAllocation.d.ts.map +1 -1
- package/dist/models/PaymentIntent.d.ts.map +1 -1
- package/dist/models/Payout.d.ts.map +1 -1
- package/dist/models/PurchasePriceObservation.d.ts +15 -0
- package/dist/models/PurchasePriceObservation.d.ts.map +1 -0
- package/dist/models/TaxCode.d.ts +1 -1
- package/dist/models/TaxCode.d.ts.map +1 -1
- package/dist/models/index.d.ts +1 -0
- package/dist/models/index.d.ts.map +1 -1
- package/dist/money.d.ts +5 -1
- package/dist/money.d.ts.map +1 -1
- package/dist/money.js +62 -15
- package/dist/money.js.map +1 -1
- package/dist/observed-purchase-price-internal.d.ts +3 -0
- package/dist/observed-purchase-price-internal.d.ts.map +1 -0
- package/dist/observed-purchase-price.d.ts +71 -0
- package/dist/observed-purchase-price.d.ts.map +1 -0
- package/dist/received-purchase-money.d.ts +87 -0
- package/dist/received-purchase-money.d.ts.map +1 -0
- package/dist/recipes.d.ts +4 -1
- package/dist/recipes.d.ts.map +1 -1
- package/dist/retention-accounting-internal.d.ts +3 -0
- package/dist/retention-accounting-internal.d.ts.map +1 -0
- package/dist/retention-accounting.d.ts +164 -0
- package/dist/retention-accounting.d.ts.map +1 -0
- package/dist/retention-money.d.ts +43 -0
- package/dist/retention-money.d.ts.map +1 -0
- package/dist/smrt-knowledge.json +1866 -113
- package/dist/tax/cookbook.d.ts.map +1 -1
- package/dist/tax-summary.d.ts +1 -0
- package/dist/tax-summary.d.ts.map +1 -1
- package/dist/types/index.d.ts +20 -1
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +16 -16
- package/dist/chunks/CustomerCollection-BIPH2ZUx.js +0 -99
- package/dist/chunks/CustomerCollection-BIPH2ZUx.js.map +0 -1
- package/dist/chunks/DocumentTaxCollection-DDzlywMW.js +0 -1666
- package/dist/chunks/DocumentTaxCollection-DDzlywMW.js.map +0 -1
- package/dist/chunks/InvoiceCollection-cinzAqt6.js.map +0 -1
- package/dist/chunks/TaxCodeCollection-DaBOPG9c.js.map +0 -1
- package/dist/chunks/VendorCollection-D6ZcUYy8.js +0 -100
- package/dist/chunks/VendorCollection-D6ZcUYy8.js.map +0 -1
- package/dist/chunks/calculations-C9daQLsh.js +0 -82
- package/dist/chunks/calculations-C9daQLsh.js.map +0 -1
- package/dist/chunks/contract-money-EuToOghh.js.map +0 -1
- package/dist/chunks/document-money-DV5t4vlK.js +0 -1186
- package/dist/chunks/document-money-DV5t4vlK.js.map +0 -1
- package/dist/chunks/invoice-posting-C2i5dOVZ.js.map +0 -1
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
|
|
2
|
+
import { t as assertHistoricalCommerceWrite } from "./historical-commerce-internal-C9ButfuH.js";
|
|
3
|
+
import { SmrtCollection, SmrtObject, crossPackageRef, field, foreignKey, smrt } from "@happyvertical/smrt-core";
|
|
4
|
+
import { TenantScoped, tenantId } from "@happyvertical/smrt-tenancy";
|
|
5
|
+
//#region src/models/HistoricalCustomerFunds.ts
|
|
6
|
+
var __defProp$1 = Object.defineProperty;
|
|
7
|
+
var __getOwnPropDesc$1 = Object.getOwnPropertyDescriptor;
|
|
8
|
+
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, {
|
|
9
|
+
enumerable: true,
|
|
10
|
+
configurable: true,
|
|
11
|
+
writable: true,
|
|
12
|
+
value
|
|
13
|
+
}) : obj[key] = value;
|
|
14
|
+
var __decorateClass$1 = (decorators, target, key, kind) => {
|
|
15
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$1(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$1(target, key, result);
|
|
18
|
+
return result;
|
|
19
|
+
};
|
|
20
|
+
var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
21
|
+
var HistoricalCustomerFunds = class extends SmrtObject {
|
|
22
|
+
tenantId = "";
|
|
23
|
+
customerId = "";
|
|
24
|
+
contractId = null;
|
|
25
|
+
sourceKeyHash = "";
|
|
26
|
+
kind = "receipt";
|
|
27
|
+
origin = "historical";
|
|
28
|
+
paymentId = null;
|
|
29
|
+
currency = "";
|
|
30
|
+
amountMinor = 0;
|
|
31
|
+
effectiveOn = "";
|
|
32
|
+
sourceReceiptId = null;
|
|
33
|
+
sourceCreditNoteId = null;
|
|
34
|
+
snapshotJson = "";
|
|
35
|
+
constructor(options = {}) {
|
|
36
|
+
super(options);
|
|
37
|
+
for (const key of [
|
|
38
|
+
"tenantId",
|
|
39
|
+
"customerId",
|
|
40
|
+
"contractId",
|
|
41
|
+
"sourceKeyHash",
|
|
42
|
+
"kind",
|
|
43
|
+
"origin",
|
|
44
|
+
"paymentId",
|
|
45
|
+
"currency",
|
|
46
|
+
"amountMinor",
|
|
47
|
+
"effectiveOn",
|
|
48
|
+
"sourceReceiptId",
|
|
49
|
+
"sourceCreditNoteId",
|
|
50
|
+
"snapshotJson"
|
|
51
|
+
]) if (options[key] !== void 0) Object.assign(this, { [key]: options[key] });
|
|
52
|
+
}
|
|
53
|
+
async save(options) {
|
|
54
|
+
assertHistoricalCommerceWrite(this);
|
|
55
|
+
if (!this.tenantId || !this.customerId || !this.sourceKeyHash || !this.snapshotJson || !Number.isSafeInteger(this.amountMinor) || this.amountMinor <= 0) throw new Error("Historical customer funds require complete exact source evidence");
|
|
56
|
+
if (this.id && await this.db.get(this.tableName, { id: this.id })) throw new Error("Historical customer funds are immutable");
|
|
57
|
+
return super.save(options);
|
|
58
|
+
}
|
|
59
|
+
async delete() {
|
|
60
|
+
throw new Error("Historical customer cash evidence cannot be deleted");
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
__publicField$1(HistoricalCustomerFunds, "__smrtPackage__", "@happyvertical/smrt-commerce");
|
|
64
|
+
__decorateClass$1([tenantId()], HistoricalCustomerFunds.prototype, "tenantId", 2);
|
|
65
|
+
__decorateClass$1([foreignKey("Customer")], HistoricalCustomerFunds.prototype, "customerId", 2);
|
|
66
|
+
__decorateClass$1([foreignKey("Contract", { nullable: true })], HistoricalCustomerFunds.prototype, "contractId", 2);
|
|
67
|
+
__decorateClass$1([foreignKey("Payment", { nullable: true })], HistoricalCustomerFunds.prototype, "paymentId", 2);
|
|
68
|
+
__decorateClass$1([field({ ui: { format: "money" } })], HistoricalCustomerFunds.prototype, "amountMinor", 2);
|
|
69
|
+
__decorateClass$1([foreignKey("HistoricalCustomerFunds", { nullable: true })], HistoricalCustomerFunds.prototype, "sourceReceiptId", 2);
|
|
70
|
+
__decorateClass$1([foreignKey("Invoice", { nullable: true })], HistoricalCustomerFunds.prototype, "sourceCreditNoteId", 2);
|
|
71
|
+
HistoricalCustomerFunds = __decorateClass$1([TenantScoped({ mode: "required" }), smrt({
|
|
72
|
+
tableName: "historical_customer_funds",
|
|
73
|
+
indexes: [{
|
|
74
|
+
name: "historical_customer_funds_source",
|
|
75
|
+
columns: ["tenantId", "sourceKeyHash"],
|
|
76
|
+
unique: true
|
|
77
|
+
}],
|
|
78
|
+
api: { include: ["get", "list"] },
|
|
79
|
+
cli: { include: ["get", "list"] },
|
|
80
|
+
mcp: { include: ["get", "list"] }
|
|
81
|
+
})], HistoricalCustomerFunds);
|
|
82
|
+
//#endregion
|
|
83
|
+
//#region src/models/HistoricalCustomerFundsAllocation.ts
|
|
84
|
+
var __defProp = Object.defineProperty;
|
|
85
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
86
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, {
|
|
87
|
+
enumerable: true,
|
|
88
|
+
configurable: true,
|
|
89
|
+
writable: true,
|
|
90
|
+
value
|
|
91
|
+
}) : obj[key] = value;
|
|
92
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
93
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
94
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--) if (decorator = decorators[i]) result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
95
|
+
if (kind && result) __defProp(target, key, result);
|
|
96
|
+
return result;
|
|
97
|
+
};
|
|
98
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
99
|
+
var HistoricalCustomerFundsAllocation = class extends SmrtObject {
|
|
100
|
+
tenantId = "";
|
|
101
|
+
receiptId = null;
|
|
102
|
+
creditNoteId = null;
|
|
103
|
+
invoiceId = "";
|
|
104
|
+
sourceKeyHash = "";
|
|
105
|
+
amountMinor = 0;
|
|
106
|
+
effectiveOn = "";
|
|
107
|
+
origin = "historical";
|
|
108
|
+
effect = "payment";
|
|
109
|
+
journalId = null;
|
|
110
|
+
snapshotJson = "";
|
|
111
|
+
constructor(options = {}) {
|
|
112
|
+
super(options);
|
|
113
|
+
for (const key of [
|
|
114
|
+
"tenantId",
|
|
115
|
+
"receiptId",
|
|
116
|
+
"creditNoteId",
|
|
117
|
+
"invoiceId",
|
|
118
|
+
"sourceKeyHash",
|
|
119
|
+
"amountMinor",
|
|
120
|
+
"effectiveOn",
|
|
121
|
+
"origin",
|
|
122
|
+
"effect",
|
|
123
|
+
"journalId",
|
|
124
|
+
"snapshotJson"
|
|
125
|
+
]) if (options[key] !== void 0) Object.assign(this, { [key]: options[key] });
|
|
126
|
+
}
|
|
127
|
+
async save(options) {
|
|
128
|
+
assertHistoricalCommerceWrite(this);
|
|
129
|
+
if (!this.tenantId || !this.invoiceId || !this.sourceKeyHash || !this.snapshotJson || !Number.isSafeInteger(this.amountMinor) || this.amountMinor <= 0 || Boolean(this.receiptId) === Boolean(this.creditNoteId)) throw new Error("Historical funds allocation requires one exact source and an owned invoice");
|
|
130
|
+
if (this.id && await this.db.get(this.tableName, { id: this.id })) throw new Error("Historical customer funds applications are immutable");
|
|
131
|
+
return super.save(options);
|
|
132
|
+
}
|
|
133
|
+
async delete() {
|
|
134
|
+
throw new Error("Historical customer funds applications cannot be deleted");
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
__publicField(HistoricalCustomerFundsAllocation, "__smrtPackage__", "@happyvertical/smrt-commerce");
|
|
138
|
+
__decorateClass([tenantId()], HistoricalCustomerFundsAllocation.prototype, "tenantId", 2);
|
|
139
|
+
__decorateClass([foreignKey("HistoricalCustomerFunds", { nullable: true })], HistoricalCustomerFundsAllocation.prototype, "receiptId", 2);
|
|
140
|
+
__decorateClass([foreignKey("Invoice", { nullable: true })], HistoricalCustomerFundsAllocation.prototype, "creditNoteId", 2);
|
|
141
|
+
__decorateClass([foreignKey("Invoice")], HistoricalCustomerFundsAllocation.prototype, "invoiceId", 2);
|
|
142
|
+
__decorateClass([field({ ui: { format: "money" } })], HistoricalCustomerFundsAllocation.prototype, "amountMinor", 2);
|
|
143
|
+
__decorateClass([crossPackageRef("@happyvertical/smrt-ledgers:Journal", { nullable: true })], HistoricalCustomerFundsAllocation.prototype, "journalId", 2);
|
|
144
|
+
HistoricalCustomerFundsAllocation = __decorateClass([TenantScoped({ mode: "required" }), smrt({
|
|
145
|
+
tableName: "historical_customer_funds_allocations",
|
|
146
|
+
indexes: [{
|
|
147
|
+
name: "historical_funds_allocation_source",
|
|
148
|
+
columns: ["tenantId", "sourceKeyHash"],
|
|
149
|
+
unique: true
|
|
150
|
+
}],
|
|
151
|
+
api: { include: ["get", "list"] },
|
|
152
|
+
cli: { include: ["get", "list"] },
|
|
153
|
+
mcp: { include: ["get", "list"] }
|
|
154
|
+
})], HistoricalCustomerFundsAllocation);
|
|
155
|
+
//#endregion
|
|
156
|
+
//#region src/collections/HistoricalCustomerFundsCollections.ts
|
|
157
|
+
var HistoricalCustomerFundsCollections_exports = /* @__PURE__ */ __exportAll({
|
|
158
|
+
HistoricalCustomerFundsAllocationCollection: () => HistoricalCustomerFundsAllocationCollection,
|
|
159
|
+
HistoricalCustomerFundsCollection: () => HistoricalCustomerFundsCollection
|
|
160
|
+
});
|
|
161
|
+
var HistoricalCustomerFundsCollection = class extends SmrtCollection {
|
|
162
|
+
static _itemClass = HistoricalCustomerFunds;
|
|
163
|
+
};
|
|
164
|
+
var HistoricalCustomerFundsAllocationCollection = class extends SmrtCollection {
|
|
165
|
+
static _itemClass = HistoricalCustomerFundsAllocation;
|
|
166
|
+
};
|
|
167
|
+
//#endregion
|
|
168
|
+
export { HistoricalCustomerFunds as a, HistoricalCustomerFundsAllocation as i, HistoricalCustomerFundsCollection as n, HistoricalCustomerFundsCollections_exports as r, HistoricalCustomerFundsAllocationCollection as t };
|
|
169
|
+
|
|
170
|
+
//# sourceMappingURL=HistoricalCustomerFundsCollections-B5x8gTW3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HistoricalCustomerFundsCollections-B5x8gTW3.js","names":[],"sources":["../../src/models/HistoricalCustomerFunds.ts","../../src/models/HistoricalCustomerFundsAllocation.ts","../../src/collections/HistoricalCustomerFundsCollections.ts"],"sourcesContent":["import {\n field,\n foreignKey,\n SmrtObject,\n type SmrtObjectOptions,\n type SmrtSaveOptions,\n smrt,\n} from '@happyvertical/smrt-core';\nimport { TenantScoped, tenantId } from '@happyvertical/smrt-tenancy';\nimport { assertHistoricalCommerceWrite } from '../historical-commerce-internal.js';\nexport interface HistoricalCustomerFundsOptions extends SmrtObjectOptions {\n tenantId?: string;\n customerId?: string;\n contractId?: string | null;\n sourceKeyHash?: string;\n kind?: 'receipt' | 'refund';\n origin?: 'historical' | 'live';\n paymentId?: string | null;\n currency?: string;\n amountMinor?: number;\n effectiveOn?: string;\n sourceReceiptId?: string | null;\n sourceCreditNoteId?: string | null;\n snapshotJson?: string;\n}\n/** Retained original cash evidence. It is deliberately not a completed ledger-backed Payment. */\n@TenantScoped({ mode: 'required' })\n@smrt({\n tableName: 'historical_customer_funds',\n indexes: [\n {\n name: 'historical_customer_funds_source',\n columns: ['tenantId', 'sourceKeyHash'],\n unique: true,\n },\n ],\n api: { include: ['get', 'list'] },\n cli: { include: ['get', 'list'] },\n mcp: { include: ['get', 'list'] },\n})\nexport class HistoricalCustomerFunds extends SmrtObject { static __smrtPackage__ = \"@happyvertical/smrt-commerce\";\n @tenantId() tenantId = '';\n @foreignKey('Customer') customerId = '';\n @foreignKey('Contract', { nullable: true }) contractId: string | null = null;\n sourceKeyHash = '';\n kind: 'receipt' | 'refund' = 'receipt';\n origin: 'historical' | 'live' = 'historical';\n @foreignKey('Payment', { nullable: true }) paymentId: string | null = null;\n currency = '';\n @field({ ui: { format: 'money' } }) amountMinor = 0;\n effectiveOn = '';\n @foreignKey('HistoricalCustomerFunds', { nullable: true }) sourceReceiptId:\n | string\n | null = null;\n @foreignKey('Invoice', { nullable: true }) sourceCreditNoteId: string | null =\n null;\n snapshotJson = '';\n constructor(options: HistoricalCustomerFundsOptions = {}) {\n super(options);\n for (const key of [\n 'tenantId',\n 'customerId',\n 'contractId',\n 'sourceKeyHash',\n 'kind',\n 'origin',\n 'paymentId',\n 'currency',\n 'amountMinor',\n 'effectiveOn',\n 'sourceReceiptId',\n 'sourceCreditNoteId',\n 'snapshotJson',\n ] as const)\n if (options[key] !== undefined)\n Object.assign(this, { [key]: options[key] });\n }\n override async save(options?: SmrtSaveOptions): Promise<this> {\n assertHistoricalCommerceWrite(this);\n if (\n !this.tenantId ||\n !this.customerId ||\n !this.sourceKeyHash ||\n !this.snapshotJson ||\n !Number.isSafeInteger(this.amountMinor) ||\n this.amountMinor <= 0\n )\n throw new Error(\n 'Historical customer funds require complete exact source evidence',\n );\n if (this.id && (await this.db.get(this.tableName, { id: this.id })))\n throw new Error('Historical customer funds are immutable');\n return super.save(options);\n }\n override async delete(): Promise<void> {\n throw new Error('Historical customer cash evidence cannot be deleted');\n }\n}\n","import {\n crossPackageRef,\n field,\n foreignKey,\n SmrtObject,\n type SmrtObjectOptions,\n type SmrtSaveOptions,\n smrt,\n} from '@happyvertical/smrt-core';\nimport { TenantScoped, tenantId } from '@happyvertical/smrt-tenancy';\nimport { assertHistoricalCommerceWrite } from '../historical-commerce-internal.js';\nexport interface HistoricalCustomerFundsAllocationOptions\n extends SmrtObjectOptions {\n tenantId?: string;\n receiptId?: string | null;\n creditNoteId?: string | null;\n invoiceId?: string;\n sourceKeyHash?: string;\n amountMinor?: number;\n effectiveOn?: string;\n origin?: 'historical' | 'live';\n effect?: 'payment' | 'credit-audit' | 'refund-audit';\n journalId?: string | null;\n snapshotJson?: string;\n}\n/** Original applications have concrete identities; credit-audit records never count twice. */\n@TenantScoped({ mode: 'required' })\n@smrt({\n tableName: 'historical_customer_funds_allocations',\n indexes: [\n {\n name: 'historical_funds_allocation_source',\n columns: ['tenantId', 'sourceKeyHash'],\n unique: true,\n },\n ],\n api: { include: ['get', 'list'] },\n cli: { include: ['get', 'list'] },\n mcp: { include: ['get', 'list'] },\n})\nexport class HistoricalCustomerFundsAllocation extends SmrtObject { static __smrtPackage__ = \"@happyvertical/smrt-commerce\";\n @tenantId() tenantId = '';\n @foreignKey('HistoricalCustomerFunds', { nullable: true }) receiptId:\n | string\n | null = null;\n @foreignKey('Invoice', { nullable: true }) creditNoteId: string | null = null;\n @foreignKey('Invoice') invoiceId = '';\n sourceKeyHash = '';\n @field({ ui: { format: 'money' } }) amountMinor = 0;\n effectiveOn = '';\n origin: 'historical' | 'live' = 'historical';\n effect: 'payment' | 'credit-audit' | 'refund-audit' = 'payment';\n @crossPackageRef('@happyvertical/smrt-ledgers:Journal', { nullable: true })\n journalId: string | null = null;\n snapshotJson = '';\n constructor(options: HistoricalCustomerFundsAllocationOptions = {}) {\n super(options);\n for (const key of [\n 'tenantId',\n 'receiptId',\n 'creditNoteId',\n 'invoiceId',\n 'sourceKeyHash',\n 'amountMinor',\n 'effectiveOn',\n 'origin',\n 'effect',\n 'journalId',\n 'snapshotJson',\n ] as const)\n if (options[key] !== undefined)\n Object.assign(this, { [key]: options[key] });\n }\n override async save(options?: SmrtSaveOptions): Promise<this> {\n assertHistoricalCommerceWrite(this);\n if (\n !this.tenantId ||\n !this.invoiceId ||\n !this.sourceKeyHash ||\n !this.snapshotJson ||\n !Number.isSafeInteger(this.amountMinor) ||\n this.amountMinor <= 0 ||\n Boolean(this.receiptId) === Boolean(this.creditNoteId)\n )\n throw new Error(\n 'Historical funds allocation requires one exact source and an owned invoice',\n );\n if (this.id && (await this.db.get(this.tableName, { id: this.id })))\n throw new Error('Historical customer funds applications are immutable');\n return super.save(options);\n }\n override async delete(): Promise<void> {\n throw new Error('Historical customer funds applications cannot be deleted');\n }\n}\n","import { SmrtCollection } from '@happyvertical/smrt-core';\nimport { HistoricalCustomerFunds } from '../models/HistoricalCustomerFunds.js';\nimport { HistoricalCustomerFundsAllocation } from '../models/HistoricalCustomerFundsAllocation.js';\nexport class HistoricalCustomerFundsCollection extends SmrtCollection<HistoricalCustomerFunds> {\n static readonly _itemClass = HistoricalCustomerFunds;\n}\nexport class HistoricalCustomerFundsAllocationCollection extends SmrtCollection<HistoricalCustomerFundsAllocation> {\n static readonly _itemClass = HistoricalCustomerFundsAllocation;\n}\n"],"mappings":"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"}
|
|
@@ -1,11 +1,92 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
|
|
2
2
|
import { s as InvoiceStatus } from "./types-Bbm0Xflc.js";
|
|
3
|
-
import { i as claimAllocationParent, r as assertAllocationParent } from "./allocation-integrity-
|
|
3
|
+
import { i as claimAllocationParent, r as assertAllocationParent } from "./allocation-integrity-DJ7-LY1j.js";
|
|
4
4
|
import { MoneyValidationError, assertIntegerMinorUnits } from "../money.js";
|
|
5
|
-
import { a as assertCommerceMoneySchemaCurrent, f as DOCUMENT_MONEY_READ_REBIND, p as DOCUMENT_MONEY_WRITE } from "./detect-
|
|
6
|
-
import { n as withTenantMoneyCollectionRead } from "./tenant-money-barrier-
|
|
5
|
+
import { a as assertCommerceMoneySchemaCurrent, f as DOCUMENT_MONEY_READ_REBIND, p as DOCUMENT_MONEY_WRITE } from "./detect-DAE-_NAk.js";
|
|
6
|
+
import { n as withTenantMoneyCollectionRead } from "./tenant-money-barrier-DoF6lR8h.js";
|
|
7
7
|
import { SmrtCollection, SmrtObject, crossPackageRef, field, foreignKey, smrt } from "@happyvertical/smrt-core";
|
|
8
8
|
import { TenantScoped, getTenantId, queryGlobal, queryWithGlobals, tenantId } from "@happyvertical/smrt-tenancy";
|
|
9
|
+
//#region src/retention-money.ts
|
|
10
|
+
function invalid(message) {
|
|
11
|
+
throw new MoneyValidationError("INVALID_MONEY_INPUT", message);
|
|
12
|
+
}
|
|
13
|
+
function assertRetentionMinor(amount, label) {
|
|
14
|
+
if (!Number.isSafeInteger(amount)) invalid(`${label} must be a safe integer minor-unit amount`);
|
|
15
|
+
}
|
|
16
|
+
function validateRetentionEvidence(input) {
|
|
17
|
+
for (const key of [
|
|
18
|
+
"requestId",
|
|
19
|
+
"policyVersion",
|
|
20
|
+
"evidenceRef",
|
|
21
|
+
"actorId",
|
|
22
|
+
"reason"
|
|
23
|
+
]) {
|
|
24
|
+
const value = input[key];
|
|
25
|
+
if (typeof value !== "string" || !value || value.trim() !== value) invalid(`Retention ${key} must be nonempty trimmed text`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function parseInvoiceRetention(json) {
|
|
29
|
+
if (json === "") return null;
|
|
30
|
+
let state;
|
|
31
|
+
try {
|
|
32
|
+
state = JSON.parse(json);
|
|
33
|
+
} catch {
|
|
34
|
+
return invalid("Invalid retention state JSON");
|
|
35
|
+
}
|
|
36
|
+
if (!state || state.version !== 1 || state.creditPolicy !== "retained-first" || !Array.isArray(state.releases)) invalid("Unsupported retention state or credit policy");
|
|
37
|
+
validateRetentionEvidence(state);
|
|
38
|
+
if (!/^[A-Z]{3}$/.test(state.currency)) invalid("Retention currency is required");
|
|
39
|
+
const keys = /* @__PURE__ */ new Set([state.requestId]);
|
|
40
|
+
for (const event of [state, ...state.releases]) {
|
|
41
|
+
validateRetentionEvidence(event);
|
|
42
|
+
if (typeof event.recordedAt !== "string" || !Number.isFinite(Date.parse(event.recordedAt))) invalid("Retention event timestamp is required");
|
|
43
|
+
if (event.effectiveOn !== void 0 && (!/^\d{4}-\d{2}-\d{2}$/.test(event.effectiveOn) || !Number.isFinite(Date.parse(event.effectiveOn)) || new Date(event.effectiveOn).toISOString().slice(0, 10) !== event.effectiveOn)) invalid("Original retention event requires an exact calendar date");
|
|
44
|
+
if (event.sameDayCreditOrder !== void 0 && event.sameDayCreditOrder !== null && event.sameDayCreditOrder !== "release-before-credit" && event.sameDayCreditOrder !== "credit-before-release") invalid("Unsupported original retention release/credit ordering");
|
|
45
|
+
if (event !== state) {
|
|
46
|
+
if (keys.has(event.requestId)) invalid("Duplicate retention request identity");
|
|
47
|
+
keys.add(event.requestId);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return state;
|
|
51
|
+
}
|
|
52
|
+
function calculateInvoicePayable(input) {
|
|
53
|
+
for (const [name, amount] of Object.entries({
|
|
54
|
+
gross: input.totalAmount,
|
|
55
|
+
credits: input.creditedAmount,
|
|
56
|
+
paid: input.amountPaid
|
|
57
|
+
})) {
|
|
58
|
+
assertRetentionMinor(amount, name);
|
|
59
|
+
if (amount < 0) invalid(`${name} cannot be negative`);
|
|
60
|
+
}
|
|
61
|
+
if (input.creditedAmount > input.totalAmount || input.amountPaid > input.totalAmount) invalid("Credits or payments exceed invoice gross");
|
|
62
|
+
const state = parseInvoiceRetention(input.retentionStateJson ?? "");
|
|
63
|
+
const retained = state?.retainedMinor ?? 0;
|
|
64
|
+
assertRetentionMinor(retained, "Retained amount");
|
|
65
|
+
if (retained < 0 || retained > input.totalAmount) invalid("Retention exceeds invoice gross");
|
|
66
|
+
if (state && state.currency !== input.currency) invalid("Retention currency does not match invoice");
|
|
67
|
+
let released = 0n;
|
|
68
|
+
for (const event of state?.releases ?? []) {
|
|
69
|
+
assertRetentionMinor(event.amountMinor, "Released amount");
|
|
70
|
+
if (event.amountMinor <= 0) invalid("Release amount must be positive");
|
|
71
|
+
released += BigInt(event.amountMinor);
|
|
72
|
+
}
|
|
73
|
+
if (released > BigInt(retained)) invalid("Releases exceed retained amount");
|
|
74
|
+
const unreleased = retained - Number(released);
|
|
75
|
+
const creditedRetention = Math.min(unreleased, input.creditedAmount);
|
|
76
|
+
const remaining = unreleased - creditedRetention;
|
|
77
|
+
const cap = Math.max(0, input.totalAmount - input.creditedAmount - remaining);
|
|
78
|
+
return {
|
|
79
|
+
grossMinor: input.totalAmount,
|
|
80
|
+
retainedMinor: retained,
|
|
81
|
+
releasedMinor: Number(released),
|
|
82
|
+
creditedRetentionMinor: creditedRetention,
|
|
83
|
+
retainedRemainingMinor: remaining,
|
|
84
|
+
allocationCapMinor: cap,
|
|
85
|
+
grossBalanceMinor: input.totalAmount - input.creditedAmount - input.amountPaid,
|
|
86
|
+
currentlyDueMinor: Math.max(0, cap - input.amountPaid)
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
//#endregion
|
|
9
90
|
//#region src/models/Invoice.ts
|
|
10
91
|
var __defProp = Object.defineProperty;
|
|
11
92
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -77,6 +158,9 @@ var INVOICE_STATUS_TRANSITIONS = {
|
|
|
77
158
|
};
|
|
78
159
|
var loadedInvoiceStatus = /* @__PURE__ */ new WeakMap();
|
|
79
160
|
var Invoice = class extends SmrtObject {
|
|
161
|
+
moneyAuthority = "calculated";
|
|
162
|
+
historicalSalesMoneyJson = "";
|
|
163
|
+
historicalSourceKeyHash = null;
|
|
80
164
|
/** @internal Collection read guard returns this snapshot on its root DB. */
|
|
81
165
|
rebindMoneyRead(capability, db) {
|
|
82
166
|
if (capability !== DOCUMENT_MONEY_READ_REBIND) throw new MoneyValidationError("FROZEN_DOCUMENT", "Invoice read rebinding requires the owning capability");
|
|
@@ -87,6 +171,12 @@ var Invoice = class extends SmrtObject {
|
|
|
87
171
|
kind = "invoice";
|
|
88
172
|
creditedInvoiceId = null;
|
|
89
173
|
creditedAmount = 0;
|
|
174
|
+
/** Server-owned immutable retention policy and append-only release evidence. */
|
|
175
|
+
retentionStateJson = "";
|
|
176
|
+
retentionAccountingStateJson = "";
|
|
177
|
+
getPayableFacts() {
|
|
178
|
+
return calculateInvoicePayable(this);
|
|
179
|
+
}
|
|
90
180
|
tenantId = null;
|
|
91
181
|
customerId = "";
|
|
92
182
|
contractId = "";
|
|
@@ -180,6 +270,9 @@ var Invoice = class extends SmrtObject {
|
|
|
180
270
|
super(options);
|
|
181
271
|
if (options.kind !== void 0) this.kind = options.kind;
|
|
182
272
|
if (options.creditedInvoiceId !== void 0) this.creditedInvoiceId = options.creditedInvoiceId;
|
|
273
|
+
if (options.moneyAuthority !== void 0) this.moneyAuthority = options.moneyAuthority;
|
|
274
|
+
if (options.historicalSalesMoneyJson !== void 0) this.historicalSalesMoneyJson = options.historicalSalesMoneyJson;
|
|
275
|
+
if (options.historicalSourceKeyHash !== void 0) this.historicalSourceKeyHash = options.historicalSourceKeyHash;
|
|
183
276
|
if (options.creditedAmount !== void 0) this.creditedAmount = options.creditedAmount;
|
|
184
277
|
if (options.tenantId !== void 0) this.tenantId = options.tenantId;
|
|
185
278
|
if (options.customerId !== void 0) this.customerId = options.customerId;
|
|
@@ -231,7 +324,7 @@ var Invoice = class extends SmrtObject {
|
|
|
231
324
|
async initialize() {
|
|
232
325
|
await super.initialize();
|
|
233
326
|
if (this.isPersisted) {
|
|
234
|
-
const { assertHydratedMoneyRowCurrent } = await import("./detect-
|
|
327
|
+
const { assertHydratedMoneyRowCurrent } = await import("./detect-DAE-_NAk.js").then((n) => n.c);
|
|
235
328
|
await assertHydratedMoneyRowCurrent(this);
|
|
236
329
|
}
|
|
237
330
|
if (await this.isSaved()) loadedInvoiceStatus.set(this, this.status);
|
|
@@ -254,7 +347,7 @@ var Invoice = class extends SmrtObject {
|
|
|
254
347
|
* - **Status transitions** are validated against the prior persisted status.
|
|
255
348
|
*/
|
|
256
349
|
async save() {
|
|
257
|
-
const { saveInvoice } = await import("./
|
|
350
|
+
const { saveInvoice } = await import("./DocumentTaxCollection-C42x0YLW.js").then((n) => n.y);
|
|
258
351
|
return await saveInvoice(this);
|
|
259
352
|
}
|
|
260
353
|
/** @internal Aggregate persistence only. */
|
|
@@ -272,6 +365,10 @@ var Invoice = class extends SmrtObject {
|
|
|
272
365
|
this.assertNonNegativeAmounts();
|
|
273
366
|
this.assertStatusTransition(prior);
|
|
274
367
|
this.assertPaymentStatusConsistent();
|
|
368
|
+
const payable = calculateInvoicePayable(this);
|
|
369
|
+
if (this.retentionAccountingStateJson && [InvoiceStatus.CANCELLED, InvoiceStatus.WRITTEN_OFF].includes(this.status)) throw new MoneyValidationError("ACCOUNTING_SYNC_RECONCILIATION_REQUIRED", "Provider retention cannot be voided or written off without an explicit reconciled reversal contract");
|
|
370
|
+
if (this.retentionAccountingStateJson && (this.collectionMethod || this.providerTaxAmount)) throw new MoneyValidationError("INVALID_MONEY_INPUT", "Retention accounting does not support provider collection or tax overrides");
|
|
371
|
+
if (payable.retainedRemainingMinor > 0 && !this.retentionAccountingStateJson && (this.externalId || this.externalProvider || this.accountingSyncStateJson || this.collectionMethod || this.providerTaxAmount)) throw new MoneyValidationError("INVALID_MONEY_INPUT", "Unreleased retention requires an explicit provider retention contract");
|
|
275
372
|
await this.assertDraftDeliveryHistory(persisted);
|
|
276
373
|
await assertAllocationParent(this, "invoice");
|
|
277
374
|
const result = await super.save();
|
|
@@ -279,7 +376,7 @@ var Invoice = class extends SmrtObject {
|
|
|
279
376
|
return result;
|
|
280
377
|
}
|
|
281
378
|
async delete(options = {}) {
|
|
282
|
-
const { deleteInvoice } = await import("./
|
|
379
|
+
const { deleteInvoice } = await import("./DocumentTaxCollection-C42x0YLW.js").then((n) => n.y);
|
|
283
380
|
await deleteInvoice(this, options);
|
|
284
381
|
}
|
|
285
382
|
/** @internal Aggregate persistence only. */
|
|
@@ -304,7 +401,7 @@ var Invoice = class extends SmrtObject {
|
|
|
304
401
|
return loadedInvoiceStatus.get(this);
|
|
305
402
|
}
|
|
306
403
|
async recomputeAmountPaid() {
|
|
307
|
-
const { PaymentAllocationCollection } = await import("
|
|
404
|
+
const { PaymentAllocationCollection } = await import("./retention-accounting-Brdj9x-V.js").then((n) => n.x);
|
|
308
405
|
const allocationCollection = await PaymentAllocationCollection.create({
|
|
309
406
|
...this.options,
|
|
310
407
|
db: this.db
|
|
@@ -438,15 +535,16 @@ var Invoice = class extends SmrtObject {
|
|
|
438
535
|
* Check if invoice is overdue
|
|
439
536
|
*/
|
|
440
537
|
isOverdue() {
|
|
538
|
+
if (this.getAmountDue() === 0) return false;
|
|
441
539
|
if (this.status === InvoiceStatus.OVERDUE) return true;
|
|
442
540
|
if (this.isPaid() || this.status === InvoiceStatus.CANCELLED) return false;
|
|
443
|
-
return /* @__PURE__ */ new Date() > this.dueDate;
|
|
541
|
+
return this.dueDate !== null && /* @__PURE__ */ new Date() > this.dueDate;
|
|
444
542
|
}
|
|
445
543
|
/**
|
|
446
544
|
* Get remaining amount due
|
|
447
545
|
*/
|
|
448
546
|
getAmountDue() {
|
|
449
|
-
return
|
|
547
|
+
return this.getPayableFacts().currentlyDueMinor;
|
|
450
548
|
}
|
|
451
549
|
/** Signed amount still owed after payments and issued credit notes. */
|
|
452
550
|
getBalance() {
|
|
@@ -489,7 +587,7 @@ var Invoice = class extends SmrtObject {
|
|
|
489
587
|
this.amountPaid = amountPaid;
|
|
490
588
|
if (this.status === InvoiceStatus.CANCELLED || this.status === InvoiceStatus.WRITTEN_OFF) return;
|
|
491
589
|
if (this.isFullyPaid()) {
|
|
492
|
-
if (this.status !== InvoiceStatus.PAID || !this.paidDate) this.paidDate = /* @__PURE__ */ new Date();
|
|
590
|
+
if (this.moneyAuthority !== "historical" && (this.status !== InvoiceStatus.PAID || !this.paidDate)) this.paidDate = /* @__PURE__ */ new Date();
|
|
493
591
|
this.status = InvoiceStatus.PAID;
|
|
494
592
|
} else if (amountPaid + this.creditedAmount > 0) {
|
|
495
593
|
this.status = InvoiceStatus.PARTIAL;
|
|
@@ -497,7 +595,7 @@ var Invoice = class extends SmrtObject {
|
|
|
497
595
|
} else {
|
|
498
596
|
this.paidDate = null;
|
|
499
597
|
if (this.viewedAt) this.status = InvoiceStatus.VIEWED;
|
|
500
|
-
else if (this.sentAt) this.status = InvoiceStatus.SENT;
|
|
598
|
+
else if (this.sentAt || this.moneyAuthority === "historical") this.status = InvoiceStatus.SENT;
|
|
501
599
|
else this.status = InvoiceStatus.DRAFT;
|
|
502
600
|
}
|
|
503
601
|
}
|
|
@@ -510,7 +608,7 @@ var Invoice = class extends SmrtObject {
|
|
|
510
608
|
}
|
|
511
609
|
/** Cancel a posted invoice with an exact atomic journal reversal. */
|
|
512
610
|
async cancelWithRevenueReversal(options) {
|
|
513
|
-
const { cancelInvoiceWithRevenueReversal, rebindJournal } = await import("./invoice-posting-
|
|
611
|
+
const { cancelInvoiceWithRevenueReversal, rebindJournal } = await import("./invoice-posting-BeTPw3h9.js");
|
|
514
612
|
return rebindJournal(this.db, await cancelInvoiceWithRevenueReversal(this, options));
|
|
515
613
|
}
|
|
516
614
|
/**
|
|
@@ -541,7 +639,7 @@ var Invoice = class extends SmrtObject {
|
|
|
541
639
|
* ```
|
|
542
640
|
*/
|
|
543
641
|
async recognizeRevenue(options) {
|
|
544
|
-
const { recognizeInvoiceRevenue, rebindJournal } = await import("./invoice-posting-
|
|
642
|
+
const { recognizeInvoiceRevenue, rebindJournal } = await import("./invoice-posting-BeTPw3h9.js");
|
|
545
643
|
return rebindJournal(this.db, await recognizeInvoiceRevenue(this, options));
|
|
546
644
|
}
|
|
547
645
|
/**
|
|
@@ -579,7 +677,7 @@ var Invoice = class extends SmrtObject {
|
|
|
579
677
|
async toAccountingInput(options) {
|
|
580
678
|
if (!options) throw new MoneyValidationError("INVALID_MONEY_INPUT", "Accounting conversion requires explicit realm mapping");
|
|
581
679
|
if (!this.id || !this.tenantId) throw new MoneyValidationError("INVALID_MONEY_INPUT", "Accounting conversion requires a persisted tenant invoice");
|
|
582
|
-
const { toFrozenInvoiceAccountingInput } = await import("
|
|
680
|
+
const { toFrozenInvoiceAccountingInput } = await import("./retention-accounting-Brdj9x-V.js").then((n) => n.m);
|
|
583
681
|
return toFrozenInvoiceAccountingInput({
|
|
584
682
|
db: this.db,
|
|
585
683
|
tenantId: this.tenantId,
|
|
@@ -589,15 +687,25 @@ var Invoice = class extends SmrtObject {
|
|
|
589
687
|
}
|
|
590
688
|
};
|
|
591
689
|
__publicField(Invoice, "__smrtPackage__", "@happyvertical/smrt-commerce");
|
|
690
|
+
__decorateClass([field({ description: "Whether amounts were calculated or retained from an original issued invoice." })], Invoice.prototype, "moneyAuthority", 2);
|
|
691
|
+
__decorateClass([field({
|
|
692
|
+
type: "text",
|
|
693
|
+
nullable: true
|
|
694
|
+
})], Invoice.prototype, "historicalSourceKeyHash", 2);
|
|
592
695
|
__decorateClass([field({ description: "Invoice or customer credit note." })], Invoice.prototype, "kind", 2);
|
|
593
696
|
__decorateClass([foreignKey("Invoice", { nullable: true })], Invoice.prototype, "creditedInvoiceId", 2);
|
|
594
697
|
__decorateClass([field({ ui: { format: "money" } })], Invoice.prototype, "creditedAmount", 2);
|
|
698
|
+
__decorateClass([field({ sensitive: true })], Invoice.prototype, "retentionAccountingStateJson", 2);
|
|
595
699
|
__decorateClass([tenantId({ nullable: true })], Invoice.prototype, "tenantId", 2);
|
|
596
700
|
__decorateClass([field({ description: "The customer being billed." }), foreignKey("Customer")], Invoice.prototype, "customerId", 2);
|
|
597
701
|
__decorateClass([field({ description: "The order or agreement this invoice bills for, if any." }), foreignKey("SalesContract", { validateSubtype: true })], Invoice.prototype, "contractId", 2);
|
|
598
702
|
__decorateClass([field({ description: "The number printed on the invoice." })], Invoice.prototype, "invoiceNumber", 2);
|
|
599
703
|
__decorateClass([field({ description: "The date the invoice was issued." })], Invoice.prototype, "issueDate", 2);
|
|
600
|
-
__decorateClass([field({
|
|
704
|
+
__decorateClass([field({
|
|
705
|
+
type: "datetime",
|
|
706
|
+
nullable: true,
|
|
707
|
+
description: "The date payment is expected; null when the original source did not establish it."
|
|
708
|
+
})], Invoice.prototype, "dueDate", 2);
|
|
601
709
|
__decorateClass([field({ description: "The date it was paid in full." })], Invoice.prototype, "paidDate", 2);
|
|
602
710
|
__decorateClass([field({
|
|
603
711
|
description: "The amount before tax.",
|
|
@@ -671,7 +779,12 @@ Invoice = __decorateClass([TenantScoped({ mode: "optional" }), smrt({
|
|
|
671
779
|
exportName: "serializeInvoiceMcpGet"
|
|
672
780
|
} }
|
|
673
781
|
},
|
|
674
|
-
cli: { skipApiCheck: true }
|
|
782
|
+
cli: { skipApiCheck: true },
|
|
783
|
+
indexes: [{
|
|
784
|
+
name: "invoice_historical_source_identity",
|
|
785
|
+
columns: ["tenantId", "historicalSourceKeyHash"],
|
|
786
|
+
unique: true
|
|
787
|
+
}]
|
|
675
788
|
})], Invoice);
|
|
676
789
|
//#endregion
|
|
677
790
|
//#region src/collections/InvoiceCollection.ts
|
|
@@ -931,6 +1044,6 @@ var InvoiceCollection = class extends SmrtCollection {
|
|
|
931
1044
|
}
|
|
932
1045
|
};
|
|
933
1046
|
//#endregion
|
|
934
|
-
export { Invoice as i, InvoiceCollection_exports as n, UNPAID_STATUSES as r, InvoiceCollection as t };
|
|
1047
|
+
export { assertRetentionMinor as a, validateRetentionEvidence as c, Invoice as i, InvoiceCollection_exports as n, calculateInvoicePayable as o, UNPAID_STATUSES as r, parseInvoiceRetention as s, InvoiceCollection as t };
|
|
935
1048
|
|
|
936
|
-
//# sourceMappingURL=InvoiceCollection-
|
|
1049
|
+
//# sourceMappingURL=InvoiceCollection-BIcge9Wl.js.map
|