@happyvertical/smrt-expenses 0.55.24 → 0.56.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +36 -5
- package/README.md +18 -4
- package/dist/actions/expense-actions.d.ts +77 -0
- package/dist/actions/expense-actions.d.ts.map +1 -0
- package/dist/actions/principal.d.ts +54 -0
- package/dist/actions/principal.d.ts.map +1 -0
- package/dist/chunks/{Expense-CY5jw_80.js → Expense-7afLcUTn.js} +12 -7
- package/dist/chunks/Expense-7afLcUTn.js.map +1 -0
- package/dist/chunks/ExpenseReceiptCollection-y1SlmnBS.js +304 -0
- package/dist/chunks/ExpenseReceiptCollection-y1SlmnBS.js.map +1 -0
- package/dist/chunks/expense-actions-Ce5CBaBE.js +132 -0
- package/dist/chunks/expense-actions-Ce5CBaBE.js.map +1 -0
- package/dist/chunks/principal-_1CdcvvW.js +107 -0
- package/dist/chunks/principal-_1CdcvvW.js.map +1 -0
- package/dist/collections/ExpenseCollection.d.ts +55 -3
- package/dist/collections/ExpenseCollection.d.ts.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +180 -312
- package/dist/index.js.map +1 -1
- package/dist/manifest.json +273 -8
- package/dist/models/Expense.d.ts +9 -5
- package/dist/models/Expense.d.ts.map +1 -1
- package/dist/recipes.d.ts +118 -0
- package/dist/recipes.d.ts.map +1 -0
- package/dist/smrt-knowledge.json +277 -10
- package/package.json +9 -8
- package/dist/chunks/Expense-CY5jw_80.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,41 +1,34 @@
|
|
|
1
|
+
import { n as ExpenseReceipt, r as __exportAll, t as ExpenseReceiptCollection } from "./chunks/ExpenseReceiptCollection-y1SlmnBS.js";
|
|
2
|
+
import { t as ExpenseActionError } from "./chunks/principal-_1CdcvvW.js";
|
|
1
3
|
import { DuplicateReceiptError, EXPENSE_PAYERS, EXPENSE_REVIEW_STATUSES, ExpenseError, SUGGESTED_EXPENSE_CATEGORIES } from "./types.js";
|
|
2
|
-
import {
|
|
3
|
-
import { ObjectRegistry, SmrtCollection,
|
|
4
|
-
import {
|
|
5
|
-
import { TenantScoped, tenantId } from "@happyvertical/smrt-tenancy";
|
|
6
|
-
import { AssetCollection } from "@happyvertical/smrt-assets";
|
|
7
|
-
//#region \0rolldown/runtime.js
|
|
8
|
-
var __defProp$3 = Object.defineProperty;
|
|
9
|
-
var __exportAll = (all, no_symbols) => {
|
|
10
|
-
let target = {};
|
|
11
|
-
for (var name in all) __defProp$3(target, name, {
|
|
12
|
-
get: all[name],
|
|
13
|
-
enumerable: true
|
|
14
|
-
});
|
|
15
|
-
if (!no_symbols) __defProp$3(target, Symbol.toStringTag, { value: "Module" });
|
|
16
|
-
return target;
|
|
17
|
-
};
|
|
18
|
-
//#endregion
|
|
4
|
+
import { r as computeContentSha256, t as Expense } from "./chunks/Expense-7afLcUTn.js";
|
|
5
|
+
import { ObjectRegistry, SmrtCollection, SmrtRecipe, method, smrt } from "@happyvertical/smrt-core";
|
|
6
|
+
import { ContractLineItemCollection, PurchaseContractCollection } from "@happyvertical/smrt-commerce";
|
|
19
7
|
//#region src/__smrt-register__.ts
|
|
20
|
-
ObjectRegistry.registerPackageManifest(JSON.parse(`{"version":"1.0.0","timestamp":0,"packageName":"@happyvertical/smrt-expenses","packageVersion":"0.55.24","objects":{"@happyvertical/smrt-expenses:ExpenseCollection":{"name":"expensecollection","className":"ExpenseCollection","qualifiedName":"@happyvertical/smrt-expenses:ExpenseCollection","collection":"expenses","description":"Collection for Expense. Reads go through the normal tenant interceptors, so inside withTenant() every method here sees only that tenant's expenses.","filePath":"/home/runner/work/smrt/smrt/packages/expenses/src/collections/ExpenseCollection.ts","packageName":"@happyvertical/smrt-expenses","fields":{},"methods":{"forCostObject":{"name":"forCostObject","async":true,"parameters":[{"name":"costObjectType","type":"string","optional":false},{"name":"costObjectId","type":"string","optional":false}],"returnType":"Promise<Expense[]>","isStatic":false,"isPublic":true},"totalsByCurrency":{"name":"totalsByCurrency","async":true,"parameters":[{"name":"options","type":"ExpenseTotalsOptions","optional":true}],"returnType":"Promise<CurrencyTotals>","isStatic":false,"isPublic":true},"commitmentPosition":{"name":"commitmentPosition","async":true,"parameters":[{"name":"commitmentId","type":"string","optional":false},{"name":"options","type":"object","optional":true,"memberTypes":["string"]}],"returnType":"Promise<CommitmentPosition>","isStatic":false,"isPublic":true}},"decoratorConfig":{"api":{"include":[]},"mcp":{"include":[]},"cli":false,"tableName":"expenses"},"extends":"SmrtCollection","extendsTypeArg":"Expense","exportName":"ExpenseCollection","collectionExportName":"ExpenseCollectionCollection","schema":{"tableName":"expenses","ddl":"CREATE TABLE IF NOT EXISTS \\"expenses\\" (\\n \\"id\\" UUID PRIMARY KEY NOT NULL,\\n \\"slug\\" TEXT NOT NULL,\\n \\"context\\" TEXT NOT NULL DEFAULT '',\\n \\"created_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"updated_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"tenant_id\\" UUID,\\n \\"cost_object_type\\" TEXT,\\n \\"cost_object_id\\" TEXT,\\n \\"category\\" TEXT,\\n \\"description\\" TEXT,\\n \\"amount\\" INTEGER,\\n \\"currency\\" TEXT,\\n \\"financial_breakdown\\" TEXT,\\n \\"paid_by_name\\" TEXT,\\n \\"refund_of_id\\" UUID,\\n \\"incurred_on\\" TEXT,\\n \\"recorded_at\\" TIMESTAMP,\\n \\"recorded_by_profile_id\\" UUID,\\n \\"paid_by\\" TEXT,\\n \\"paid_by_profile_id\\" UUID,\\n \\"vendor_id\\" UUID,\\n \\"commitment_id\\" UUID,\\n \\"commitment_line_id\\" UUID,\\n \\"review_status\\" TEXT,\\n \\"reviewed_by_profile_id\\" UUID,\\n \\"reviewed_at\\" TIMESTAMP,\\n \\"review_note\\" TEXT,\\n \\"duplicate_of_id\\" UUID,\\n \\"reimbursable\\" BOOLEAN,\\n \\"reimbursed_at\\" TIMESTAMP,\\n \\"reimbursement_reference\\" TEXT\\n);","columns":{"id":{"type":"UUID","primaryKey":true,"referenceKind":"id","notNull":true},"slug":{"type":"TEXT","notNull":true},"context":{"type":"TEXT","notNull":true,"default":""},"created_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"updated_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"tenant_id":{"type":"UUID","referenceKind":"tenantId","notNull":false,"unique":false},"cost_object_type":{"type":"TEXT","notNull":false,"unique":false},"cost_object_id":{"type":"TEXT","notNull":false,"unique":false},"category":{"type":"TEXT","notNull":false,"unique":false},"description":{"type":"TEXT","notNull":false,"unique":false},"amount":{"type":"INTEGER","notNull":false,"unique":false},"currency":{"type":"TEXT","notNull":false,"unique":false},"financial_breakdown":{"type":"TEXT","notNull":false,"unique":false},"paid_by_name":{"type":"TEXT","notNull":false,"unique":false},"refund_of_id":{"type":"UUID","referenceKind":"foreignKey","notNull":false,"unique":false,"foreignKey":{"table":"expenses","column":"id","onDelete":"RESTRICT","onUpdate":"CASCADE"}},"incurred_on":{"type":"TEXT","notNull":false,"unique":false},"recorded_at":{"type":"TIMESTAMP","notNull":false,"unique":false},"recorded_by_profile_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":false,"unique":false},"paid_by":{"type":"TEXT","notNull":false,"unique":false},"paid_by_profile_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":false,"unique":false},"vendor_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":false,"unique":false},"commitment_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":false,"unique":false},"commitment_line_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":false,"unique":false},"review_status":{"type":"TEXT","notNull":false,"unique":false},"reviewed_by_profile_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":false,"unique":false},"reviewed_at":{"type":"TIMESTAMP","notNull":false,"unique":false},"review_note":{"type":"TEXT","notNull":false,"unique":false},"duplicate_of_id":{"type":"UUID","referenceKind":"foreignKey","notNull":false,"unique":false,"foreignKey":{"table":"expenses","column":"id","onDelete":"SET NULL","onUpdate":"CASCADE"}},"reimbursable":{"type":"BOOLEAN","notNull":false,"unique":false},"reimbursed_at":{"type":"TIMESTAMP","notNull":false,"unique":false},"reimbursement_reference":{"type":"TEXT","notNull":false,"unique":false}},"indexes":[{"name":"expenses_slug_context_idx","columns":["tenant_id","slug","context"],"unique":true,"nullsNotDistinct":true},{"name":"expenses_cost_object_idx","columns":["tenant_id","cost_object_type","cost_object_id","incurred_on"]},{"name":"expenses_commitment_review_idx","columns":["tenant_id","commitment_id","review_status"]},{"name":"expenses_review_status_idx","columns":["tenant_id","review_status","incurred_on"]},{"name":"expenses_tenant_id_created_at_idx","columns":["tenant_id","created_at"]},{"name":"expenses_refund_of_id_idx","columns":["refund_of_id"]},{"name":"expenses_recorded_by_profile_id_idx","columns":["recorded_by_profile_id"]},{"name":"expenses_paid_by_profile_id_idx","columns":["paid_by_profile_id"]},{"name":"expenses_vendor_id_idx","columns":["vendor_id"]},{"name":"expenses_commitment_id_idx","columns":["commitment_id"]},{"name":"expenses_commitment_line_id_idx","columns":["commitment_line_id"]},{"name":"expenses_reviewed_by_profile_id_idx","columns":["reviewed_by_profile_id"]},{"name":"expenses_duplicate_of_id_idx","columns":["duplicate_of_id"]}],"version":"287668fa"},"importPath":"@happyvertical/smrt-expenses"},"@happyvertical/smrt-expenses:ExpenseReceiptCollection":{"name":"expensereceiptcollection","className":"ExpenseReceiptCollection","qualifiedName":"@happyvertical/smrt-expenses:ExpenseReceiptCollection","collection":"expensereceipts","description":"Junction collection over expense_receipts (left: expense, right: asset). Reads go through the normal tenant interceptors.","filePath":"/home/runner/work/smrt/smrt/packages/expenses/src/collections/ExpenseReceiptCollection.ts","packageName":"@happyvertical/smrt-expenses","fields":{},"methods":{"byRight":{"name":"byRight","async":true,"parameters":[{"name":"rightId","type":"string","optional":false},{"name":"opts","type":"JunctionFilterOptions","optional":true}],"returnType":"Promise<TItem[]>","isStatic":false,"isPublic":true},"byLeft":{"name":"byLeft","async":true,"parameters":[{"name":"leftId","type":"string","optional":false},{"name":"opts","type":"JunctionFilterOptions","optional":true}],"returnType":"Promise<TItem[]>","isStatic":false,"isPublic":true},"attach":{"name":"attach","async":true,"parameters":[{"name":"_expenseId","type":"string","optional":false},{"name":"_assetId","type":"string","optional":false},{"name":"_opts","type":"JunctionAttachOptions","optional":true}],"returnType":"Promise<ExpenseReceipt>","isStatic":false,"isPublic":true},"detach":{"name":"detach","async":true,"parameters":[{"name":"leftId","type":"string","optional":false},{"name":"rightId","type":"string","optional":false},{"name":"opts","type":"JunctionFilterOptions","optional":true}],"returnType":"Promise<void>","isStatic":false,"isPublic":true},"setLinks":{"name":"setLinks","async":true,"parameters":[{"name":"_expenseId","type":"string","optional":false},{"name":"_assetIds","type":"string[]","optional":false},{"name":"_opts","type":"JunctionAttachOptions","optional":true}],"returnType":"Promise<void>","isStatic":false,"isPublic":true},"attachReceipt":{"name":"attachReceipt","async":true,"parameters":[{"name":"input","type":"AttachReceiptInput","optional":false}],"returnType":"Promise<ExpenseReceipt>","isStatic":false,"isPublic":true},"receiptsFor":{"name":"receiptsFor","async":true,"parameters":[{"name":"expenseId","type":"string","optional":false}],"returnType":"Promise<ExpenseReceipt[]>","isStatic":false,"isPublic":true},"findDuplicateReceipts":{"name":"findDuplicateReceipts","async":true,"parameters":[{"name":"options","type":"FindDuplicateReceiptsOptions","optional":true}],"returnType":"Promise<DuplicateReceiptGroup[]>","isStatic":false,"isPublic":true}},"decoratorConfig":{"api":{"include":[]},"mcp":{"include":[]},"cli":false,"tableName":"expense_receipts"},"extends":"SmrtJunction","extendsTypeArg":"ExpenseReceipt","exportName":"ExpenseReceiptCollection","collectionExportName":"ExpenseReceiptCollectionCollection","schema":{"tableName":"expense_receipts","ddl":"CREATE TABLE IF NOT EXISTS \\"expense_receipts\\" (\\n \\"id\\" UUID PRIMARY KEY NOT NULL,\\n \\"slug\\" TEXT NOT NULL,\\n \\"context\\" TEXT NOT NULL DEFAULT '',\\n \\"created_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"updated_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"tenant_id\\" UUID,\\n \\"expense_id\\" UUID NOT NULL,\\n \\"asset_id\\" UUID NOT NULL,\\n \\"uploaded_by_profile_id\\" UUID,\\n \\"filename\\" TEXT,\\n \\"mime_type\\" TEXT,\\n \\"byte_count\\" INTEGER,\\n \\"content_sha256\\" TEXT NOT NULL\\n);","columns":{"id":{"type":"UUID","primaryKey":true,"referenceKind":"id","notNull":true},"slug":{"type":"TEXT","notNull":true},"context":{"type":"TEXT","notNull":true,"default":""},"created_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"updated_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"tenant_id":{"type":"UUID","referenceKind":"tenantId","notNull":false,"unique":false},"expense_id":{"type":"UUID","referenceKind":"foreignKey","notNull":true,"unique":false,"foreignKey":{"table":"expenses","column":"id","onDelete":"CASCADE","onUpdate":"CASCADE"}},"asset_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":true,"unique":false},"uploaded_by_profile_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":false,"unique":false},"filename":{"type":"TEXT","notNull":false,"unique":false},"mime_type":{"type":"TEXT","notNull":false,"unique":false},"byte_count":{"type":"INTEGER","notNull":false,"unique":false},"content_sha256":{"type":"TEXT","notNull":true,"unique":false}},"indexes":[{"name":"expense_receipts_slug_context_idx","columns":["tenant_id","slug","context"],"unique":true,"nullsNotDistinct":true},{"name":"expense_receipts_expense_sha256_key","columns":["expense_id","content_sha256"],"unique":true},{"name":"expense_receipts_tenant_sha256_idx","columns":["tenant_id","content_sha256"]},{"name":"expense_receipts_tenant_id_created_at_idx","columns":["tenant_id","created_at"]},{"name":"expense_receipts_asset_id_idx","columns":["asset_id"]},{"name":"expense_receipts_uploaded_by_profile_id_idx","columns":["uploaded_by_profile_id"]}],"version":"5aa77571"},"importPath":"@happyvertical/smrt-expenses"},"@happyvertical/smrt-expenses:Expense":{"name":"expense","className":"Expense","qualifiedName":"@happyvertical/smrt-expenses:Expense","collection":"expenses","description":"A cost someone incurred.","filePath":"/home/runner/work/smrt/smrt/packages/expenses/src/models/Expense.ts","packageName":"@happyvertical/smrt-expenses","fields":{"tenantId":{"type":"text","required":false,"_meta":{"sqlType":"UUID","nullable":true,"__tenancy":{"isTenantIdField":true,"autoFilter":true,"required":false,"autoPopulate":true,"nullable":true,"mode":"optional","field":"tenantId","allowSuperAdminBypass":false}}},"costObjectType":{"type":"text","required":false,"_meta":{}},"costObjectId":{"type":"text","required":false,"_meta":{}},"category":{"type":"text","required":false,"_meta":{}},"description":{"type":"text","required":false,"_meta":{}},"amount":{"type":"integer","required":false,"_meta":{}},"currency":{"type":"text","required":false,"_meta":{}},"financialBreakdown":{"type":"text","required":false,"_meta":{}},"paidByName":{"type":"text","required":false,"_meta":{}},"refundOfId":{"type":"foreignKey","required":false,"related":"Expense","_meta":{"onDelete":"RESTRICT"}},"incurredOn":{"type":"text","required":false,"_meta":{}},"recordedAt":{"type":"datetime","required":false},"recordedByProfileId":{"type":"crossPackageRef","required":false,"related":"PROFILE"},"paidBy":{"type":"text","required":false,"_meta":{},"enum":["company","person","third-party"]},"paidByProfileId":{"type":"crossPackageRef","required":false,"related":"PROFILE"},"vendorId":{"type":"crossPackageRef","required":false,"related":"@happyvertical/smrt-commerce:Vendor"},"commitmentId":{"type":"crossPackageRef","required":false,"related":"@happyvertical/smrt-commerce:Contract"},"commitmentLineId":{"type":"crossPackageRef","required":false,"related":"@happyvertical/smrt-commerce:ContractLineItem"},"reviewStatus":{"type":"text","required":false,"_meta":{"readonly":true},"enum":["unreviewed","reviewed","rejected"],"readonly":true},"reviewedByProfileId":{"type":"crossPackageRef","required":false,"related":"PROFILE"},"reviewedAt":{"type":"datetime","required":false,"_meta":{"readonly":true},"readonly":true},"reviewNote":{"type":"text","required":false,"_meta":{"readonly":true},"readonly":true},"duplicateOfId":{"type":"foreignKey","required":false,"related":"Expense","_meta":{"onDelete":"SET NULL"}},"reimbursable":{"type":"boolean","required":false,"_meta":{}},"reimbursedAt":{"type":"datetime","required":false},"reimbursementReference":{"type":"text","required":false,"_meta":{}}},"methods":{"getFinancialBreakdown":{"name":"getFinancialBreakdown","async":false,"parameters":[],"returnType":"ExpenseFinancialBreakdown | null","isStatic":false,"isPublic":true},"setFinancialBreakdown":{"name":"setFinancialBreakdown","async":false,"parameters":[{"name":"value","type":"ExpenseFinancialBreakdown | null","optional":false,"unionBranches":[{"type":"ExpenseFinancialBreakdown"},{"type":"null"}]}],"returnType":"void","isStatic":false,"isPublic":true},"getCostBasis":{"name":"getCostBasis","async":false,"parameters":[],"returnType":"ExpenseCostBasis | null","isStatic":false,"isPublic":true},"isReimbursed":{"name":"isReimbursed","async":false,"parameters":[],"returnType":"boolean","isStatic":false,"isPublic":true},"isCountable":{"name":"isCountable","async":false,"parameters":[],"returnType":"boolean","isStatic":false,"isPublic":true},"review":{"name":"review","async":true,"parameters":[{"name":"input","type":"ReviewExpenseInput","optional":false}],"returnType":"Promise<this>","isStatic":false,"isPublic":true},"reject":{"name":"reject","async":true,"parameters":[{"name":"input","type":"RejectExpenseInput","optional":false}],"returnType":"Promise<this>","isStatic":false,"isPublic":true},"markDuplicate":{"name":"markDuplicate","async":true,"parameters":[{"name":"input","type":"MarkDuplicateExpenseInput","optional":false}],"returnType":"Promise<this>","isStatic":false,"isPublic":true},"reopen":{"name":"reopen","async":true,"parameters":[{"name":"input","type":"ReopenExpenseInput","optional":false}],"returnType":"Promise<this>","isStatic":false,"isPublic":true},"markReimbursed":{"name":"markReimbursed","async":true,"parameters":[{"name":"input","type":"MarkReimbursedInput","optional":true}],"returnType":"Promise<this>","isStatic":false,"isPublic":true},"getCostObject":{"name":"getCostObject","async":true,"parameters":[],"returnType":"Promise<T | null>","isStatic":false,"isPublic":true},"save":{"name":"save","async":true,"parameters":[],"returnType":"Promise<this>","isStatic":false,"isPublic":true}},"decoratorConfig":{"tableName":"expenses","api":{"include":[]},"mcp":{"include":[]},"cli":false,"indexes":[{"name":"expenses_cost_object_idx","columns":["tenantId","costObjectType","costObjectId","incurredOn"]},{"name":"expenses_commitment_review_idx","columns":["tenantId","commitmentId","reviewStatus"]},{"name":"expenses_review_status_idx","columns":["tenantId","reviewStatus","incurredOn"]}],"tenantScoped":{"mode":"optional"},"conflictColumns":["tenant_id","slug","context"]},"extends":"SmrtObject","exportName":"Expense","collectionExportName":"ExpenseCollection","schema":{"tableName":"expenses","ddl":"CREATE TABLE IF NOT EXISTS \\"expenses\\" (\\n \\"id\\" UUID PRIMARY KEY NOT NULL,\\n \\"slug\\" TEXT NOT NULL,\\n \\"context\\" TEXT NOT NULL DEFAULT '',\\n \\"created_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"updated_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"tenant_id\\" UUID,\\n \\"cost_object_type\\" TEXT,\\n \\"cost_object_id\\" TEXT,\\n \\"category\\" TEXT,\\n \\"description\\" TEXT,\\n \\"amount\\" INTEGER,\\n \\"currency\\" TEXT,\\n \\"financial_breakdown\\" TEXT,\\n \\"paid_by_name\\" TEXT,\\n \\"refund_of_id\\" UUID,\\n \\"incurred_on\\" TEXT,\\n \\"recorded_at\\" TIMESTAMP,\\n \\"recorded_by_profile_id\\" UUID,\\n \\"paid_by\\" TEXT,\\n \\"paid_by_profile_id\\" UUID,\\n \\"vendor_id\\" UUID,\\n \\"commitment_id\\" UUID,\\n \\"commitment_line_id\\" UUID,\\n \\"review_status\\" TEXT,\\n \\"reviewed_by_profile_id\\" UUID,\\n \\"reviewed_at\\" TIMESTAMP,\\n \\"review_note\\" TEXT,\\n \\"duplicate_of_id\\" UUID,\\n \\"reimbursable\\" BOOLEAN,\\n \\"reimbursed_at\\" TIMESTAMP,\\n \\"reimbursement_reference\\" TEXT\\n);","columns":{"id":{"type":"UUID","primaryKey":true,"referenceKind":"id","notNull":true},"slug":{"type":"TEXT","notNull":true},"context":{"type":"TEXT","notNull":true,"default":""},"created_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"updated_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"tenant_id":{"type":"UUID","referenceKind":"tenantId","notNull":false,"unique":false},"cost_object_type":{"type":"TEXT","notNull":false,"unique":false},"cost_object_id":{"type":"TEXT","notNull":false,"unique":false},"category":{"type":"TEXT","notNull":false,"unique":false},"description":{"type":"TEXT","notNull":false,"unique":false},"amount":{"type":"INTEGER","notNull":false,"unique":false},"currency":{"type":"TEXT","notNull":false,"unique":false},"financial_breakdown":{"type":"TEXT","notNull":false,"unique":false},"paid_by_name":{"type":"TEXT","notNull":false,"unique":false},"refund_of_id":{"type":"UUID","referenceKind":"foreignKey","notNull":false,"unique":false,"foreignKey":{"table":"expenses","column":"id","onDelete":"RESTRICT","onUpdate":"CASCADE"}},"incurred_on":{"type":"TEXT","notNull":false,"unique":false},"recorded_at":{"type":"TIMESTAMP","notNull":false,"unique":false},"recorded_by_profile_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":false,"unique":false},"paid_by":{"type":"TEXT","notNull":false,"unique":false},"paid_by_profile_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":false,"unique":false},"vendor_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":false,"unique":false},"commitment_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":false,"unique":false},"commitment_line_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":false,"unique":false},"review_status":{"type":"TEXT","notNull":false,"unique":false},"reviewed_by_profile_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":false,"unique":false},"reviewed_at":{"type":"TIMESTAMP","notNull":false,"unique":false},"review_note":{"type":"TEXT","notNull":false,"unique":false},"duplicate_of_id":{"type":"UUID","referenceKind":"foreignKey","notNull":false,"unique":false,"foreignKey":{"table":"expenses","column":"id","onDelete":"SET NULL","onUpdate":"CASCADE"}},"reimbursable":{"type":"BOOLEAN","notNull":false,"unique":false},"reimbursed_at":{"type":"TIMESTAMP","notNull":false,"unique":false},"reimbursement_reference":{"type":"TEXT","notNull":false,"unique":false}},"indexes":[{"name":"expenses_slug_context_idx","columns":["tenant_id","slug","context"],"unique":true,"nullsNotDistinct":true},{"name":"expenses_cost_object_idx","columns":["tenant_id","cost_object_type","cost_object_id","incurred_on"]},{"name":"expenses_commitment_review_idx","columns":["tenant_id","commitment_id","review_status"]},{"name":"expenses_review_status_idx","columns":["tenant_id","review_status","incurred_on"]},{"name":"expenses_tenant_id_created_at_idx","columns":["tenant_id","created_at"]},{"name":"expenses_refund_of_id_idx","columns":["refund_of_id"]},{"name":"expenses_recorded_by_profile_id_idx","columns":["recorded_by_profile_id"]},{"name":"expenses_paid_by_profile_id_idx","columns":["paid_by_profile_id"]},{"name":"expenses_vendor_id_idx","columns":["vendor_id"]},{"name":"expenses_commitment_id_idx","columns":["commitment_id"]},{"name":"expenses_commitment_line_id_idx","columns":["commitment_line_id"]},{"name":"expenses_reviewed_by_profile_id_idx","columns":["reviewed_by_profile_id"]},{"name":"expenses_duplicate_of_id_idx","columns":["duplicate_of_id"]}],"version":"287668fa"},"importPath":"@happyvertical/smrt-expenses"},"@happyvertical/smrt-expenses:ExpenseReceipt":{"name":"expensereceipt","className":"ExpenseReceipt","qualifiedName":"@happyvertical/smrt-expenses:ExpenseReceipt","collection":"expensereceipts","description":"A receipt file attached to an expense.","filePath":"/home/runner/work/smrt/smrt/packages/expenses/src/models/ExpenseReceipt.ts","packageName":"@happyvertical/smrt-expenses","fields":{"tenantId":{"type":"text","required":false,"_meta":{"sqlType":"UUID","nullable":true,"__tenancy":{"isTenantIdField":true,"autoFilter":true,"required":false,"autoPopulate":true,"nullable":true,"mode":"optional","field":"tenantId","allowSuperAdminBypass":false}}},"expenseId":{"type":"foreignKey","required":true,"related":"Expense","_meta":{"required":true,"onDelete":"CASCADE"}},"assetId":{"type":"crossPackageRef","required":true,"related":"@happyvertical/smrt-assets:Asset"},"uploadedByProfileId":{"type":"crossPackageRef","required":false,"related":"@happyvertical/smrt-profiles:Profile"},"filename":{"type":"text","required":false,"_meta":{}},"mimeType":{"type":"text","required":false,"_meta":{}},"byteCount":{"type":"integer","required":false,"_meta":{}},"contentSha256":{"type":"text","required":true,"_meta":{"required":true}}},"methods":{"save":{"name":"save","async":true,"parameters":[],"returnType":"Promise<this>","isStatic":false,"isPublic":true}},"decoratorConfig":{"tableName":"expense_receipts","api":{"include":[]},"mcp":{"include":[]},"cli":false,"indexes":[{"name":"expense_receipts_expense_sha256_key","columns":["expenseId","contentSha256"],"unique":true},{"name":"expense_receipts_tenant_sha256_idx","columns":["tenantId","contentSha256"]}],"tenantScoped":{"mode":"optional"},"conflictColumns":["tenant_id","slug","context"]},"extends":"SmrtObject","exportName":"ExpenseReceipt","collectionExportName":"ExpenseReceiptCollection","validationRules":[{"field":"expenseId","rule":"required","fieldType":"foreignKey"},{"field":"assetId","rule":"required","fieldType":"crossPackageRef"},{"field":"contentSha256","rule":"required","fieldType":"text"}],"schema":{"tableName":"expense_receipts","ddl":"CREATE TABLE IF NOT EXISTS \\"expense_receipts\\" (\\n \\"id\\" UUID PRIMARY KEY NOT NULL,\\n \\"slug\\" TEXT NOT NULL,\\n \\"context\\" TEXT NOT NULL DEFAULT '',\\n \\"created_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"updated_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"tenant_id\\" UUID,\\n \\"expense_id\\" UUID NOT NULL,\\n \\"asset_id\\" UUID NOT NULL,\\n \\"uploaded_by_profile_id\\" UUID,\\n \\"filename\\" TEXT,\\n \\"mime_type\\" TEXT,\\n \\"byte_count\\" INTEGER,\\n \\"content_sha256\\" TEXT NOT NULL\\n);","columns":{"id":{"type":"UUID","primaryKey":true,"referenceKind":"id","notNull":true},"slug":{"type":"TEXT","notNull":true},"context":{"type":"TEXT","notNull":true,"default":""},"created_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"updated_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"tenant_id":{"type":"UUID","referenceKind":"tenantId","notNull":false,"unique":false},"expense_id":{"type":"UUID","referenceKind":"foreignKey","notNull":true,"unique":false,"foreignKey":{"table":"expenses","column":"id","onDelete":"CASCADE","onUpdate":"CASCADE"}},"asset_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":true,"unique":false},"uploaded_by_profile_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":false,"unique":false},"filename":{"type":"TEXT","notNull":false,"unique":false},"mime_type":{"type":"TEXT","notNull":false,"unique":false},"byte_count":{"type":"INTEGER","notNull":false,"unique":false},"content_sha256":{"type":"TEXT","notNull":true,"unique":false}},"indexes":[{"name":"expense_receipts_slug_context_idx","columns":["tenant_id","slug","context"],"unique":true,"nullsNotDistinct":true},{"name":"expense_receipts_expense_sha256_key","columns":["expense_id","content_sha256"],"unique":true},{"name":"expense_receipts_tenant_sha256_idx","columns":["tenant_id","content_sha256"]},{"name":"expense_receipts_tenant_id_created_at_idx","columns":["tenant_id","created_at"]},{"name":"expense_receipts_asset_id_idx","columns":["asset_id"]},{"name":"expense_receipts_uploaded_by_profile_id_idx","columns":["uploaded_by_profile_id"]}],"version":"5aa77571"},"importPath":"@happyvertical/smrt-expenses"}},"moduleType":"smrt","smrtDependencies":["@happyvertical/smrt-assets","@happyvertical/smrt-commerce","@happyvertical/smrt-core","@happyvertical/smrt-tenancy"],"browser":{"status":"server-only","issues":["#3615","#3624","#3626","#3627"],"reason":"node:crypto","via":["@happyvertical/smrt-commerce","@happyvertical/smrt-jobs","@happyvertical/smrt-ledgers","@happyvertical/smrt-subscriptions","@happyvertical/smrt-tenancy"]},"stampsConstructors":true}`));
|
|
8
|
+
ObjectRegistry.registerPackageManifest(JSON.parse(`{"version":"1.0.0","timestamp":0,"packageName":"@happyvertical/smrt-expenses","packageVersion":"0.56.1","objects":{"@happyvertical/smrt-expenses:ExpenseCollection":{"name":"expensecollection","className":"ExpenseCollection","qualifiedName":"@happyvertical/smrt-expenses:ExpenseCollection","collection":"expenses","description":"Collection for Expense. Reads go through the normal tenant interceptors, so inside withTenant() every method here sees only that tenant's expenses.","filePath":"/home/runner/work/smrt/smrt/packages/expenses/src/collections/ExpenseCollection.ts","packageName":"@happyvertical/smrt-expenses","fields":{},"methods":{"record":{"name":"record","async":true,"parameters":[{"name":"options","type":"RecordExpenseActionInput","optional":false}],"returnType":"Promise<Expense>","isStatic":false,"isPublic":true,"decoratorConfig":{"httpMethod":"POST","path":"record","effect":"write","idempotent":false,"openWorld":false,"description":"Record a new expense for review (service-backed)."}},"attachReceipt":{"name":"attachReceipt","async":true,"parameters":[{"name":"options","type":"AttachExpenseReceiptActionInput","optional":false}],"returnType":"Promise<ExpenseReceipt>","isStatic":false,"isPublic":true,"decoratorConfig":{"httpMethod":"POST","path":"attachReceipt","effect":"write","idempotent":false,"openWorld":false,"description":"Attach a receipt file to an expense (service-backed)."}},"recordReview":{"name":"recordReview","async":true,"parameters":[{"name":"options","type":"ReviewExpenseActionInput","optional":false}],"returnType":"Promise<Expense>","isStatic":false,"isPublic":true,"decoratorConfig":{"httpMethod":"POST","path":"recordReview","effect":"write","idempotent":false,"openWorld":false,"description":"Approve or reject an expense with a reason (service-backed)."}},"recordReimbursement":{"name":"recordReimbursement","async":true,"parameters":[{"name":"options","type":"MarkExpenseReimbursedActionInput","optional":false}],"returnType":"Promise<Expense>","isStatic":false,"isPublic":true,"decoratorConfig":{"httpMethod":"POST","path":"recordReimbursement","effect":"write","idempotent":false,"openWorld":false,"description":"Record that an expense was reimbursed (service-backed)."}},"forCostObject":{"name":"forCostObject","async":true,"parameters":[{"name":"costObjectType","type":"string","optional":false},{"name":"costObjectId","type":"string","optional":false}],"returnType":"Promise<Expense[]>","isStatic":false,"isPublic":true},"totalsByCurrency":{"name":"totalsByCurrency","async":true,"parameters":[{"name":"options","type":"ExpenseTotalsOptions","optional":true}],"returnType":"Promise<CurrencyTotals>","isStatic":false,"isPublic":true},"listReviewedTaxFacts":{"name":"listReviewedTaxFacts","async":true,"parameters":[{"name":"options","type":"ReviewedExpenseTaxFactsOptions","optional":false}],"returnType":"Promise<ReviewedExpenseTaxFact[]>","isStatic":false,"isPublic":true},"commitmentPosition":{"name":"commitmentPosition","async":true,"parameters":[{"name":"commitmentId","type":"string","optional":false},{"name":"options","type":"object","optional":true,"memberTypes":["string"]}],"returnType":"Promise<CommitmentPosition>","isStatic":false,"isPublic":true}},"decoratorConfig":{"api":{"include":["record","attachReceipt","recordReview","recordReimbursement"]},"mcp":{"include":[]},"cli":false,"tableName":"expenses"},"extends":"SmrtCollection","extendsTypeArg":"Expense","exportName":"ExpenseCollection","collectionExportName":"ExpenseCollectionCollection","schema":{"tableName":"expenses","ddl":"CREATE TABLE IF NOT EXISTS \\"expenses\\" (\\n \\"id\\" UUID PRIMARY KEY NOT NULL,\\n \\"slug\\" TEXT NOT NULL,\\n \\"context\\" TEXT NOT NULL DEFAULT '',\\n \\"created_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"updated_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"tenant_id\\" UUID,\\n \\"cost_object_type\\" TEXT,\\n \\"cost_object_id\\" TEXT,\\n \\"category\\" TEXT,\\n \\"description\\" TEXT,\\n \\"amount\\" INTEGER,\\n \\"currency\\" TEXT,\\n \\"financial_breakdown\\" TEXT,\\n \\"paid_by_name\\" TEXT,\\n \\"refund_of_id\\" UUID,\\n \\"incurred_on\\" TEXT,\\n \\"recorded_at\\" TIMESTAMP,\\n \\"recorded_by_profile_id\\" UUID,\\n \\"paid_by\\" TEXT,\\n \\"paid_by_profile_id\\" UUID,\\n \\"vendor_id\\" UUID,\\n \\"commitment_id\\" UUID,\\n \\"commitment_line_id\\" UUID,\\n \\"review_status\\" TEXT,\\n \\"reviewed_by_profile_id\\" UUID,\\n \\"reviewed_at\\" TIMESTAMP,\\n \\"review_note\\" TEXT,\\n \\"duplicate_of_id\\" UUID,\\n \\"reimbursable\\" BOOLEAN,\\n \\"reimbursed_at\\" TIMESTAMP,\\n \\"reimbursement_reference\\" TEXT\\n);","columns":{"id":{"type":"UUID","primaryKey":true,"referenceKind":"id","notNull":true},"slug":{"type":"TEXT","notNull":true},"context":{"type":"TEXT","notNull":true,"default":""},"created_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"updated_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"tenant_id":{"type":"UUID","referenceKind":"tenantId","notNull":false,"unique":false},"cost_object_type":{"type":"TEXT","notNull":false,"unique":false},"cost_object_id":{"type":"TEXT","notNull":false,"unique":false},"category":{"type":"TEXT","notNull":false,"unique":false},"description":{"type":"TEXT","notNull":false,"unique":false},"amount":{"type":"INTEGER","notNull":false,"unique":false},"currency":{"type":"TEXT","notNull":false,"unique":false},"financial_breakdown":{"type":"TEXT","notNull":false,"unique":false},"paid_by_name":{"type":"TEXT","notNull":false,"unique":false},"refund_of_id":{"type":"UUID","referenceKind":"foreignKey","notNull":false,"unique":false,"foreignKey":{"table":"expenses","column":"id","onDelete":"RESTRICT","onUpdate":"CASCADE"}},"incurred_on":{"type":"TEXT","notNull":false,"unique":false},"recorded_at":{"type":"TIMESTAMP","notNull":false,"unique":false},"recorded_by_profile_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":false,"unique":false},"paid_by":{"type":"TEXT","notNull":false,"unique":false},"paid_by_profile_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":false,"unique":false},"vendor_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":false,"unique":false},"commitment_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":false,"unique":false},"commitment_line_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":false,"unique":false},"review_status":{"type":"TEXT","notNull":false,"unique":false},"reviewed_by_profile_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":false,"unique":false},"reviewed_at":{"type":"TIMESTAMP","notNull":false,"unique":false},"review_note":{"type":"TEXT","notNull":false,"unique":false},"duplicate_of_id":{"type":"UUID","referenceKind":"foreignKey","notNull":false,"unique":false,"foreignKey":{"table":"expenses","column":"id","onDelete":"SET NULL","onUpdate":"CASCADE"}},"reimbursable":{"type":"BOOLEAN","notNull":false,"unique":false},"reimbursed_at":{"type":"TIMESTAMP","notNull":false,"unique":false},"reimbursement_reference":{"type":"TEXT","notNull":false,"unique":false}},"indexes":[{"name":"expenses_slug_context_idx","columns":["tenant_id","slug","context"],"unique":true,"nullsNotDistinct":true},{"name":"expenses_cost_object_idx","columns":["tenant_id","cost_object_type","cost_object_id","incurred_on"]},{"name":"expenses_commitment_review_idx","columns":["tenant_id","commitment_id","review_status"]},{"name":"expenses_review_status_idx","columns":["tenant_id","review_status","incurred_on"]},{"name":"expenses_tenant_id_created_at_idx","columns":["tenant_id","created_at"]},{"name":"expenses_refund_of_id_idx","columns":["refund_of_id"]},{"name":"expenses_recorded_by_profile_id_idx","columns":["recorded_by_profile_id"]},{"name":"expenses_paid_by_profile_id_idx","columns":["paid_by_profile_id"]},{"name":"expenses_vendor_id_idx","columns":["vendor_id"]},{"name":"expenses_commitment_id_idx","columns":["commitment_id"]},{"name":"expenses_commitment_line_id_idx","columns":["commitment_line_id"]},{"name":"expenses_reviewed_by_profile_id_idx","columns":["reviewed_by_profile_id"]},{"name":"expenses_duplicate_of_id_idx","columns":["duplicate_of_id"]}],"version":"287668fa"},"importPath":"@happyvertical/smrt-expenses"},"@happyvertical/smrt-expenses:ExpenseReceiptCollection":{"name":"expensereceiptcollection","className":"ExpenseReceiptCollection","qualifiedName":"@happyvertical/smrt-expenses:ExpenseReceiptCollection","collection":"expensereceipts","description":"Junction collection over expense_receipts (left: expense, right: asset). Reads go through the normal tenant interceptors.","filePath":"/home/runner/work/smrt/smrt/packages/expenses/src/collections/ExpenseReceiptCollection.ts","packageName":"@happyvertical/smrt-expenses","fields":{},"methods":{"byRight":{"name":"byRight","async":true,"parameters":[{"name":"rightId","type":"string","optional":false},{"name":"opts","type":"JunctionFilterOptions","optional":true}],"returnType":"Promise<TItem[]>","isStatic":false,"isPublic":true},"byLeft":{"name":"byLeft","async":true,"parameters":[{"name":"leftId","type":"string","optional":false},{"name":"opts","type":"JunctionFilterOptions","optional":true}],"returnType":"Promise<TItem[]>","isStatic":false,"isPublic":true},"attach":{"name":"attach","async":true,"parameters":[{"name":"_expenseId","type":"string","optional":false},{"name":"_assetId","type":"string","optional":false},{"name":"_opts","type":"JunctionAttachOptions","optional":true}],"returnType":"Promise<ExpenseReceipt>","isStatic":false,"isPublic":true},"detach":{"name":"detach","async":true,"parameters":[{"name":"leftId","type":"string","optional":false},{"name":"rightId","type":"string","optional":false},{"name":"opts","type":"JunctionFilterOptions","optional":true}],"returnType":"Promise<void>","isStatic":false,"isPublic":true},"setLinks":{"name":"setLinks","async":true,"parameters":[{"name":"_expenseId","type":"string","optional":false},{"name":"_assetIds","type":"string[]","optional":false},{"name":"_opts","type":"JunctionAttachOptions","optional":true}],"returnType":"Promise<void>","isStatic":false,"isPublic":true},"attachReceipt":{"name":"attachReceipt","async":true,"parameters":[{"name":"input","type":"AttachReceiptInput","optional":false}],"returnType":"Promise<ExpenseReceipt>","isStatic":false,"isPublic":true},"receiptsFor":{"name":"receiptsFor","async":true,"parameters":[{"name":"expenseId","type":"string","optional":false}],"returnType":"Promise<ExpenseReceipt[]>","isStatic":false,"isPublic":true},"findDuplicateReceipts":{"name":"findDuplicateReceipts","async":true,"parameters":[{"name":"options","type":"FindDuplicateReceiptsOptions","optional":true}],"returnType":"Promise<DuplicateReceiptGroup[]>","isStatic":false,"isPublic":true}},"decoratorConfig":{"api":{"include":[]},"mcp":{"include":[]},"cli":false,"tableName":"expense_receipts"},"extends":"SmrtJunction","extendsTypeArg":"ExpenseReceipt","exportName":"ExpenseReceiptCollection","collectionExportName":"ExpenseReceiptCollectionCollection","schema":{"tableName":"expense_receipts","ddl":"CREATE TABLE IF NOT EXISTS \\"expense_receipts\\" (\\n \\"id\\" UUID PRIMARY KEY NOT NULL,\\n \\"slug\\" TEXT NOT NULL,\\n \\"context\\" TEXT NOT NULL DEFAULT '',\\n \\"created_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"updated_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"tenant_id\\" UUID,\\n \\"expense_id\\" UUID NOT NULL,\\n \\"asset_id\\" UUID NOT NULL,\\n \\"uploaded_by_profile_id\\" UUID,\\n \\"filename\\" TEXT,\\n \\"mime_type\\" TEXT,\\n \\"byte_count\\" INTEGER,\\n \\"content_sha256\\" TEXT NOT NULL\\n);","columns":{"id":{"type":"UUID","primaryKey":true,"referenceKind":"id","notNull":true},"slug":{"type":"TEXT","notNull":true},"context":{"type":"TEXT","notNull":true,"default":""},"created_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"updated_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"tenant_id":{"type":"UUID","referenceKind":"tenantId","notNull":false,"unique":false},"expense_id":{"type":"UUID","referenceKind":"foreignKey","notNull":true,"unique":false,"foreignKey":{"table":"expenses","column":"id","onDelete":"CASCADE","onUpdate":"CASCADE"}},"asset_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":true,"unique":false},"uploaded_by_profile_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":false,"unique":false},"filename":{"type":"TEXT","notNull":false,"unique":false},"mime_type":{"type":"TEXT","notNull":false,"unique":false},"byte_count":{"type":"INTEGER","notNull":false,"unique":false},"content_sha256":{"type":"TEXT","notNull":true,"unique":false}},"indexes":[{"name":"expense_receipts_slug_context_idx","columns":["tenant_id","slug","context"],"unique":true,"nullsNotDistinct":true},{"name":"expense_receipts_expense_sha256_key","columns":["expense_id","content_sha256"],"unique":true},{"name":"expense_receipts_tenant_sha256_idx","columns":["tenant_id","content_sha256"]},{"name":"expense_receipts_tenant_id_created_at_idx","columns":["tenant_id","created_at"]},{"name":"expense_receipts_asset_id_idx","columns":["asset_id"]},{"name":"expense_receipts_uploaded_by_profile_id_idx","columns":["uploaded_by_profile_id"]}],"version":"5aa77571"},"importPath":"@happyvertical/smrt-expenses"},"@happyvertical/smrt-expenses:Expense":{"name":"expense","className":"Expense","qualifiedName":"@happyvertical/smrt-expenses:Expense","collection":"expenses","description":"A cost someone incurred.","filePath":"/home/runner/work/smrt/smrt/packages/expenses/src/models/Expense.ts","packageName":"@happyvertical/smrt-expenses","fields":{"tenantId":{"type":"text","required":false,"_meta":{"sqlType":"UUID","nullable":true,"__tenancy":{"isTenantIdField":true,"autoFilter":true,"required":false,"autoPopulate":true,"nullable":true,"mode":"optional","field":"tenantId","allowSuperAdminBypass":false}}},"costObjectType":{"type":"text","required":false,"_meta":{}},"costObjectId":{"type":"text","required":false,"_meta":{}},"category":{"type":"text","required":false,"_meta":{}},"description":{"type":"text","required":false,"_meta":{}},"amount":{"type":"integer","required":false,"_meta":{}},"currency":{"type":"text","required":false,"_meta":{}},"financialBreakdown":{"type":"text","required":false,"_meta":{}},"paidByName":{"type":"text","required":false,"_meta":{}},"refundOfId":{"type":"foreignKey","required":false,"related":"Expense","_meta":{"onDelete":"RESTRICT"}},"incurredOn":{"type":"text","required":false,"_meta":{}},"recordedAt":{"type":"datetime","required":false,"_meta":{}},"recordedByProfileId":{"type":"crossPackageRef","required":false,"related":"PROFILE"},"paidBy":{"type":"text","required":false,"_meta":{},"enum":["company","person","third-party"]},"paidByProfileId":{"type":"crossPackageRef","required":false,"related":"PROFILE"},"vendorId":{"type":"crossPackageRef","required":false,"related":"@happyvertical/smrt-commerce:Vendor"},"commitmentId":{"type":"crossPackageRef","required":false,"related":"@happyvertical/smrt-commerce:PurchaseContract","_meta":{"validateSubtype":true}},"commitmentLineId":{"type":"crossPackageRef","required":false,"related":"@happyvertical/smrt-commerce:ContractLineItem"},"reviewStatus":{"type":"text","required":false,"_meta":{"readonly":true},"enum":["unreviewed","reviewed","rejected"],"readonly":true},"reviewedByProfileId":{"type":"crossPackageRef","required":false,"related":"PROFILE"},"reviewedAt":{"type":"datetime","required":false,"_meta":{"readonly":true},"readonly":true},"reviewNote":{"type":"text","required":false,"_meta":{"readonly":true},"readonly":true},"duplicateOfId":{"type":"foreignKey","required":false,"related":"Expense","_meta":{"onDelete":"SET NULL"}},"reimbursable":{"type":"boolean","required":false,"_meta":{}},"reimbursedAt":{"type":"datetime","required":false,"_meta":{}},"reimbursementReference":{"type":"text","required":false,"_meta":{}}},"methods":{"getFinancialBreakdown":{"name":"getFinancialBreakdown","async":false,"parameters":[],"returnType":"ExpenseFinancialBreakdown | null","isStatic":false,"isPublic":true},"setFinancialBreakdown":{"name":"setFinancialBreakdown","async":false,"parameters":[{"name":"value","type":"ExpenseFinancialBreakdown | null","optional":false,"unionBranches":[{"type":"ExpenseFinancialBreakdown"},{"type":"null"}]}],"returnType":"void","isStatic":false,"isPublic":true},"getCostBasis":{"name":"getCostBasis","async":false,"parameters":[],"returnType":"ExpenseCostBasis | null","isStatic":false,"isPublic":true},"isReimbursed":{"name":"isReimbursed","async":false,"parameters":[],"returnType":"boolean","isStatic":false,"isPublic":true},"isCountable":{"name":"isCountable","async":false,"parameters":[],"returnType":"boolean","isStatic":false,"isPublic":true},"review":{"name":"review","async":true,"parameters":[{"name":"input","type":"ReviewExpenseInput","optional":false}],"returnType":"Promise<this>","isStatic":false,"isPublic":true},"reject":{"name":"reject","async":true,"parameters":[{"name":"input","type":"RejectExpenseInput","optional":false}],"returnType":"Promise<this>","isStatic":false,"isPublic":true},"markDuplicate":{"name":"markDuplicate","async":true,"parameters":[{"name":"input","type":"MarkDuplicateExpenseInput","optional":false}],"returnType":"Promise<this>","isStatic":false,"isPublic":true},"reopen":{"name":"reopen","async":true,"parameters":[{"name":"input","type":"ReopenExpenseInput","optional":false}],"returnType":"Promise<this>","isStatic":false,"isPublic":true},"markReimbursed":{"name":"markReimbursed","async":true,"parameters":[{"name":"input","type":"MarkReimbursedInput","optional":true}],"returnType":"Promise<this>","isStatic":false,"isPublic":true},"getCostObject":{"name":"getCostObject","async":true,"parameters":[],"returnType":"Promise<T | null>","isStatic":false,"isPublic":true},"save":{"name":"save","async":true,"parameters":[],"returnType":"Promise<this>","isStatic":false,"isPublic":true}},"decoratorConfig":{"tableName":"expenses","api":{"include":["record","attachReceipt","recordReview","recordReimbursement"]},"mcp":{"include":[]},"cli":false,"indexes":[{"name":"expenses_cost_object_idx","columns":["tenantId","costObjectType","costObjectId","incurredOn"]},{"name":"expenses_commitment_review_idx","columns":["tenantId","commitmentId","reviewStatus"]},{"name":"expenses_review_status_idx","columns":["tenantId","reviewStatus","incurredOn"]}],"tenantScoped":{"mode":"optional"},"conflictColumns":["tenant_id","slug","context"]},"extends":"SmrtObject","exportName":"Expense","collectionExportName":"ExpenseCollection","schema":{"tableName":"expenses","ddl":"CREATE TABLE IF NOT EXISTS \\"expenses\\" (\\n \\"id\\" UUID PRIMARY KEY NOT NULL,\\n \\"slug\\" TEXT NOT NULL,\\n \\"context\\" TEXT NOT NULL DEFAULT '',\\n \\"created_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"updated_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"tenant_id\\" UUID,\\n \\"cost_object_type\\" TEXT,\\n \\"cost_object_id\\" TEXT,\\n \\"category\\" TEXT,\\n \\"description\\" TEXT,\\n \\"amount\\" INTEGER,\\n \\"currency\\" TEXT,\\n \\"financial_breakdown\\" TEXT,\\n \\"paid_by_name\\" TEXT,\\n \\"refund_of_id\\" UUID,\\n \\"incurred_on\\" TEXT,\\n \\"recorded_at\\" TIMESTAMP,\\n \\"recorded_by_profile_id\\" UUID,\\n \\"paid_by\\" TEXT,\\n \\"paid_by_profile_id\\" UUID,\\n \\"vendor_id\\" UUID,\\n \\"commitment_id\\" UUID,\\n \\"commitment_line_id\\" UUID,\\n \\"review_status\\" TEXT,\\n \\"reviewed_by_profile_id\\" UUID,\\n \\"reviewed_at\\" TIMESTAMP,\\n \\"review_note\\" TEXT,\\n \\"duplicate_of_id\\" UUID,\\n \\"reimbursable\\" BOOLEAN,\\n \\"reimbursed_at\\" TIMESTAMP,\\n \\"reimbursement_reference\\" TEXT\\n);","columns":{"id":{"type":"UUID","primaryKey":true,"referenceKind":"id","notNull":true},"slug":{"type":"TEXT","notNull":true},"context":{"type":"TEXT","notNull":true,"default":""},"created_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"updated_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"tenant_id":{"type":"UUID","referenceKind":"tenantId","notNull":false,"unique":false},"cost_object_type":{"type":"TEXT","notNull":false,"unique":false},"cost_object_id":{"type":"TEXT","notNull":false,"unique":false},"category":{"type":"TEXT","notNull":false,"unique":false},"description":{"type":"TEXT","notNull":false,"unique":false},"amount":{"type":"INTEGER","notNull":false,"unique":false},"currency":{"type":"TEXT","notNull":false,"unique":false},"financial_breakdown":{"type":"TEXT","notNull":false,"unique":false},"paid_by_name":{"type":"TEXT","notNull":false,"unique":false},"refund_of_id":{"type":"UUID","referenceKind":"foreignKey","notNull":false,"unique":false,"foreignKey":{"table":"expenses","column":"id","onDelete":"RESTRICT","onUpdate":"CASCADE"}},"incurred_on":{"type":"TEXT","notNull":false,"unique":false},"recorded_at":{"type":"TIMESTAMP","notNull":false,"unique":false},"recorded_by_profile_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":false,"unique":false},"paid_by":{"type":"TEXT","notNull":false,"unique":false},"paid_by_profile_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":false,"unique":false},"vendor_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":false,"unique":false},"commitment_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":false,"unique":false},"commitment_line_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":false,"unique":false},"review_status":{"type":"TEXT","notNull":false,"unique":false},"reviewed_by_profile_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":false,"unique":false},"reviewed_at":{"type":"TIMESTAMP","notNull":false,"unique":false},"review_note":{"type":"TEXT","notNull":false,"unique":false},"duplicate_of_id":{"type":"UUID","referenceKind":"foreignKey","notNull":false,"unique":false,"foreignKey":{"table":"expenses","column":"id","onDelete":"SET NULL","onUpdate":"CASCADE"}},"reimbursable":{"type":"BOOLEAN","notNull":false,"unique":false},"reimbursed_at":{"type":"TIMESTAMP","notNull":false,"unique":false},"reimbursement_reference":{"type":"TEXT","notNull":false,"unique":false}},"indexes":[{"name":"expenses_slug_context_idx","columns":["tenant_id","slug","context"],"unique":true,"nullsNotDistinct":true},{"name":"expenses_cost_object_idx","columns":["tenant_id","cost_object_type","cost_object_id","incurred_on"]},{"name":"expenses_commitment_review_idx","columns":["tenant_id","commitment_id","review_status"]},{"name":"expenses_review_status_idx","columns":["tenant_id","review_status","incurred_on"]},{"name":"expenses_tenant_id_created_at_idx","columns":["tenant_id","created_at"]},{"name":"expenses_refund_of_id_idx","columns":["refund_of_id"]},{"name":"expenses_recorded_by_profile_id_idx","columns":["recorded_by_profile_id"]},{"name":"expenses_paid_by_profile_id_idx","columns":["paid_by_profile_id"]},{"name":"expenses_vendor_id_idx","columns":["vendor_id"]},{"name":"expenses_commitment_id_idx","columns":["commitment_id"]},{"name":"expenses_commitment_line_id_idx","columns":["commitment_line_id"]},{"name":"expenses_reviewed_by_profile_id_idx","columns":["reviewed_by_profile_id"]},{"name":"expenses_duplicate_of_id_idx","columns":["duplicate_of_id"]}],"version":"287668fa"},"importPath":"@happyvertical/smrt-expenses"},"@happyvertical/smrt-expenses:ExpenseReceipt":{"name":"expensereceipt","className":"ExpenseReceipt","qualifiedName":"@happyvertical/smrt-expenses:ExpenseReceipt","collection":"expensereceipts","description":"A receipt file attached to an expense.","filePath":"/home/runner/work/smrt/smrt/packages/expenses/src/models/ExpenseReceipt.ts","packageName":"@happyvertical/smrt-expenses","fields":{"tenantId":{"type":"text","required":false,"_meta":{"sqlType":"UUID","nullable":true,"__tenancy":{"isTenantIdField":true,"autoFilter":true,"required":false,"autoPopulate":true,"nullable":true,"mode":"optional","field":"tenantId","allowSuperAdminBypass":false}}},"expenseId":{"type":"foreignKey","required":true,"related":"Expense","_meta":{"required":true,"onDelete":"CASCADE"}},"assetId":{"type":"crossPackageRef","required":true,"related":"@happyvertical/smrt-assets:Asset"},"uploadedByProfileId":{"type":"crossPackageRef","required":false,"related":"@happyvertical/smrt-profiles:Profile"},"filename":{"type":"text","required":false,"_meta":{}},"mimeType":{"type":"text","required":false,"_meta":{}},"byteCount":{"type":"integer","required":false,"_meta":{}},"contentSha256":{"type":"text","required":true,"_meta":{"required":true}}},"methods":{"save":{"name":"save","async":true,"parameters":[],"returnType":"Promise<this>","isStatic":false,"isPublic":true}},"decoratorConfig":{"tableName":"expense_receipts","api":{"include":[]},"mcp":{"include":[]},"cli":false,"indexes":[{"name":"expense_receipts_expense_sha256_key","columns":["expenseId","contentSha256"],"unique":true},{"name":"expense_receipts_tenant_sha256_idx","columns":["tenantId","contentSha256"]}],"tenantScoped":{"mode":"optional"},"conflictColumns":["tenant_id","slug","context"]},"extends":"SmrtObject","exportName":"ExpenseReceipt","collectionExportName":"ExpenseReceiptCollection","validationRules":[{"field":"expenseId","rule":"required","fieldType":"foreignKey"},{"field":"assetId","rule":"required","fieldType":"crossPackageRef"},{"field":"contentSha256","rule":"required","fieldType":"text"}],"schema":{"tableName":"expense_receipts","ddl":"CREATE TABLE IF NOT EXISTS \\"expense_receipts\\" (\\n \\"id\\" UUID PRIMARY KEY NOT NULL,\\n \\"slug\\" TEXT NOT NULL,\\n \\"context\\" TEXT NOT NULL DEFAULT '',\\n \\"created_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"updated_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"tenant_id\\" UUID,\\n \\"expense_id\\" UUID NOT NULL,\\n \\"asset_id\\" UUID NOT NULL,\\n \\"uploaded_by_profile_id\\" UUID,\\n \\"filename\\" TEXT,\\n \\"mime_type\\" TEXT,\\n \\"byte_count\\" INTEGER,\\n \\"content_sha256\\" TEXT NOT NULL\\n);","columns":{"id":{"type":"UUID","primaryKey":true,"referenceKind":"id","notNull":true},"slug":{"type":"TEXT","notNull":true},"context":{"type":"TEXT","notNull":true,"default":""},"created_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"updated_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"tenant_id":{"type":"UUID","referenceKind":"tenantId","notNull":false,"unique":false},"expense_id":{"type":"UUID","referenceKind":"foreignKey","notNull":true,"unique":false,"foreignKey":{"table":"expenses","column":"id","onDelete":"CASCADE","onUpdate":"CASCADE"}},"asset_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":true,"unique":false},"uploaded_by_profile_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":false,"unique":false},"filename":{"type":"TEXT","notNull":false,"unique":false},"mime_type":{"type":"TEXT","notNull":false,"unique":false},"byte_count":{"type":"INTEGER","notNull":false,"unique":false},"content_sha256":{"type":"TEXT","notNull":true,"unique":false}},"indexes":[{"name":"expense_receipts_slug_context_idx","columns":["tenant_id","slug","context"],"unique":true,"nullsNotDistinct":true},{"name":"expense_receipts_expense_sha256_key","columns":["expense_id","content_sha256"],"unique":true},{"name":"expense_receipts_tenant_sha256_idx","columns":["tenant_id","content_sha256"]},{"name":"expense_receipts_tenant_id_created_at_idx","columns":["tenant_id","created_at"]},{"name":"expense_receipts_asset_id_idx","columns":["asset_id"]},{"name":"expense_receipts_uploaded_by_profile_id_idx","columns":["uploaded_by_profile_id"]}],"version":"5aa77571"},"importPath":"@happyvertical/smrt-expenses"}},"moduleType":"smrt","recipes":[{"id":"expenses.tracking","className":"ExpensesRecipe","label":"Expenses","summary":"Record what the business spends, with receipts, and review it.","synonyms":["costs","receipts","spending","reimbursements"],"models":["@happyvertical/smrt-expenses:Expense","@happyvertical/smrt-expenses:ExpenseReceipt"],"nav":[{"label":"Expenses","model":"@happyvertical/smrt-expenses:Expense","icon":"receipt","description":"Costs you have paid, with the receipt and who paid."}],"requires":[],"section":{"id":"accounting","label":"Accounting","icon":"bank","description":"Your books: accounts, journals and balances."},"options":{"@happyvertical/smrt-expenses:Expense":{"fields":{"description":{"order":1,"required":true},"amount":{"order":2},"currency":{"order":3},"incurredOn":{"label":"Date","order":4,"help":"The date on the receipt, as YYYY-MM-DD."},"category":{"order":5,"help":"One word, such as material, travel, freight or other."},"vendorId":{"label":"Vendor","order":6},"paidBy":{"order":7},"paidByProfileId":{"label":"Person who paid","order":8,"help":"Who paid out of their own pocket, when a person paid."},"paidByName":{"order":9},"reimbursable":{"order":10},"costObjectId":{"label":"Charged to","order":11,"help":"The job, project or client the cost belongs to."},"costObjectType":{"visibility":"hidden"},"financialBreakdown":{"visibility":"hidden"},"refundOfId":{"visibility":"hidden"},"recordedByProfileId":{"visibility":"hidden"},"commitmentId":{"visibility":"hidden"},"commitmentLineId":{"visibility":"hidden"},"reviewedByProfileId":{"visibility":"hidden"},"duplicateOfId":{"visibility":"hidden"}}},"@happyvertical/smrt-expenses:ExpenseReceipt":{"fields":{"contentSha256":{"visibility":"hidden"},"byteCount":{"visibility":"hidden"},"uploadedByProfileId":{"visibility":"hidden"}}}},"help":{"markdown":"## Overview\\n\\nExpenses are the costs the business pays: a receipt, who paid it and what it\\nwas for. Each expense is reviewed once, and a reimbursable one is marked when\\nthe person is paid back.\\n\\n## Tasks\\n\\n### Record an expense\\n\\n1. Create a new expense and write a short **{field:description}**.\\n2. Enter the **{field:amount}** and its **{field:currency}**.\\n3. Set the **{field:incurredOn}** date from the receipt and pick a\\n **{field:category}**.\\n4. Choose who **{field:paidBy}**: the company, a person or a third party.\\n5. When a person paid, pick the **{field:paidByProfileId}** and tick\\n **{field:reimbursable}** when they are owed the money back.\\n\\n### Review it\\n\\n1. Open the expense and check the receipt attached to it.\\n2. **{field:reviewStatus}** moves from unreviewed to reviewed, or to rejected,\\n when someone reviews it. A rejected expense can be reopened.\\n","fieldRefs":["amount","category","currency","description","incurredOn","paidBy","paidByProfileId","reimbursable","reviewStatus"]},"demo":{"mode":"server","reasons":["Needs a server because its package does not build for a browser: node:crypto; and its package depends on @happyvertical/smrt-agents, @happyvertical/smrt-commerce, @happyvertical/smrt-jobs, @happyvertical/smrt-ledgers, @happyvertical/smrt-products, @happyvertical/smrt-profiles, @happyvertical/smrt-reports, @happyvertical/smrt-secrets, @happyvertical/smrt-subscriptions, @happyvertical/smrt-tenancy, @happyvertical/smrt-users, which do not build for a browser (#3615, #3616, #3617, #3624, #3625, #3626, #3627)."]}}],"smrtDependencies":["@happyvertical/smrt-assets","@happyvertical/smrt-commerce","@happyvertical/smrt-core","@happyvertical/smrt-tenancy","@happyvertical/smrt-users"],"browser":{"status":"server-only","issues":["#3615","#3616","#3617","#3624","#3625","#3626","#3627"],"reason":"node:crypto","via":["@happyvertical/smrt-agents","@happyvertical/smrt-commerce","@happyvertical/smrt-jobs","@happyvertical/smrt-ledgers","@happyvertical/smrt-products","@happyvertical/smrt-profiles","@happyvertical/smrt-reports","@happyvertical/smrt-secrets","@happyvertical/smrt-subscriptions","@happyvertical/smrt-tenancy","@happyvertical/smrt-users"]},"stampsConstructors":true}`));
|
|
21
9
|
//#endregion
|
|
22
10
|
//#region src/collections/ExpenseCollection.ts
|
|
23
11
|
var ExpenseCollection_exports = /* @__PURE__ */ __exportAll({ ExpenseCollection: () => ExpenseCollection });
|
|
24
|
-
var __defProp
|
|
25
|
-
var __getOwnPropDesc
|
|
26
|
-
var __defNormalProp
|
|
12
|
+
var __defProp = Object.defineProperty;
|
|
13
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
14
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, {
|
|
27
15
|
enumerable: true,
|
|
28
16
|
configurable: true,
|
|
29
17
|
writable: true,
|
|
30
18
|
value
|
|
31
19
|
}) : obj[key] = value;
|
|
32
|
-
var __decorateClass
|
|
33
|
-
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc
|
|
20
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
21
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
34
22
|
for (var i = decorators.length - 1, decorator; i >= 0; i--) if (decorator = decorators[i]) result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
35
|
-
if (kind && result) __defProp
|
|
23
|
+
if (kind && result) __defProp(target, key, result);
|
|
36
24
|
return result;
|
|
37
25
|
};
|
|
38
|
-
var __publicField
|
|
26
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
27
|
+
function isCalendarDate(value) {
|
|
28
|
+
if (!/^\d{4}-\d{2}-\d{2}$/.test(value)) return false;
|
|
29
|
+
const date = /* @__PURE__ */ new Date(`${value}T00:00:00.000Z`);
|
|
30
|
+
return !Number.isNaN(date.getTime()) && date.toISOString().slice(0, 10) === value;
|
|
31
|
+
}
|
|
39
32
|
var AMOUNT_FIELDS = [
|
|
40
33
|
"id",
|
|
41
34
|
"amount",
|
|
@@ -61,6 +54,22 @@ function addTo(totals, currency, amount) {
|
|
|
61
54
|
};
|
|
62
55
|
}
|
|
63
56
|
var ExpenseCollection = class extends SmrtCollection {
|
|
57
|
+
async record(options) {
|
|
58
|
+
const { recordExpenseAction } = await import("./chunks/expense-actions-Ce5CBaBE.js");
|
|
59
|
+
return recordExpenseAction(this, options);
|
|
60
|
+
}
|
|
61
|
+
async attachReceipt(options) {
|
|
62
|
+
const { attachExpenseReceiptAction } = await import("./chunks/expense-actions-Ce5CBaBE.js");
|
|
63
|
+
return attachExpenseReceiptAction(this, options);
|
|
64
|
+
}
|
|
65
|
+
async recordReview(options) {
|
|
66
|
+
const { reviewExpenseAction } = await import("./chunks/expense-actions-Ce5CBaBE.js");
|
|
67
|
+
return reviewExpenseAction(this, options);
|
|
68
|
+
}
|
|
69
|
+
async recordReimbursement(options) {
|
|
70
|
+
const { markExpenseReimbursedAction } = await import("./chunks/expense-actions-Ce5CBaBE.js");
|
|
71
|
+
return markExpenseReimbursedAction(this, options);
|
|
72
|
+
}
|
|
64
73
|
/**
|
|
65
74
|
* Expenses charged to one cost object, oldest incurred first.
|
|
66
75
|
*
|
|
@@ -111,6 +120,36 @@ var ExpenseCollection = class extends SmrtCollection {
|
|
|
111
120
|
return totals;
|
|
112
121
|
}
|
|
113
122
|
/**
|
|
123
|
+
* Stored supplier-tax facts for reporting. Only reviewed non-duplicate
|
|
124
|
+
* expenses are returned; callers must retain a null breakdown as unknown.
|
|
125
|
+
*/
|
|
126
|
+
async listReviewedTaxFacts(options) {
|
|
127
|
+
if (!options.tenantId?.trim() || !isCalendarDate(options.from) || !isCalendarDate(options.to) || options.from > options.to || options.currency !== void 0 && !options.currency.trim()) throw new ExpenseError("EXPENSE_INVALID", "Tax facts require a tenant, an ordered calendar-date range, and a nonempty currency when supplied.");
|
|
128
|
+
return (await this.list({
|
|
129
|
+
where: {
|
|
130
|
+
tenantId: options.tenantId,
|
|
131
|
+
reviewStatus: "reviewed",
|
|
132
|
+
duplicateOfId: null,
|
|
133
|
+
"incurredOn >=": options.from,
|
|
134
|
+
"incurredOn <=": options.to,
|
|
135
|
+
...options.currency ? { currency: options.currency } : {}
|
|
136
|
+
},
|
|
137
|
+
orderBy: ["incurred_on ASC", "id ASC"]
|
|
138
|
+
})).map((expense) => {
|
|
139
|
+
if (!expense.id || expense.tenantId !== options.tenantId) throw new ExpenseError("EXPENSE_INVALID", "Tenant tax-fact query returned a row without its requested tenant identity.");
|
|
140
|
+
return {
|
|
141
|
+
id: expense.id,
|
|
142
|
+
expenseId: expense.id,
|
|
143
|
+
tenantId: expense.tenantId,
|
|
144
|
+
incurredOn: expense.incurredOn,
|
|
145
|
+
currency: expense.currency,
|
|
146
|
+
commitmentId: expense.commitmentId,
|
|
147
|
+
commitmentLineId: expense.commitmentLineId,
|
|
148
|
+
financialBreakdown: expense.getFinancialBreakdown()
|
|
149
|
+
};
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
114
153
|
* What remains open on a commitment — a commerce `Contract`, normally a
|
|
115
154
|
* `PurchaseOrder` — or on one of its lines.
|
|
116
155
|
*
|
|
@@ -126,7 +165,7 @@ var ExpenseCollection = class extends SmrtCollection {
|
|
|
126
165
|
* (or line) is not visible in the current tenant.
|
|
127
166
|
*/
|
|
128
167
|
async commitmentPosition(commitmentId, options = {}) {
|
|
129
|
-
const commitment = await (await
|
|
168
|
+
const commitment = await (await PurchaseContractCollection.create({ db: this.db })).get({ id: commitmentId });
|
|
130
169
|
if (!commitment) throw new ExpenseError("EXPENSE_COMMITMENT_MISMATCH", `Commitment ${commitmentId} was not found.`);
|
|
131
170
|
let committed = toMinorUnits(commitment.totalAmount);
|
|
132
171
|
if (options.lineId) {
|
|
@@ -179,298 +218,127 @@ var ExpenseCollection = class extends SmrtCollection {
|
|
|
179
218
|
return position;
|
|
180
219
|
}
|
|
181
220
|
};
|
|
182
|
-
__publicField
|
|
183
|
-
__publicField
|
|
184
|
-
|
|
185
|
-
|
|
221
|
+
__publicField(ExpenseCollection, "__smrtPackage__", "@happyvertical/smrt-expenses");
|
|
222
|
+
__publicField(ExpenseCollection, "_itemClass", Expense);
|
|
223
|
+
__decorateClass([method({
|
|
224
|
+
httpMethod: "POST",
|
|
225
|
+
path: "record",
|
|
226
|
+
effect: "write",
|
|
227
|
+
idempotent: false,
|
|
228
|
+
openWorld: false,
|
|
229
|
+
description: "Record a new expense for review (service-backed)."
|
|
230
|
+
})], ExpenseCollection.prototype, "record", 1);
|
|
231
|
+
__decorateClass([method({
|
|
232
|
+
httpMethod: "POST",
|
|
233
|
+
path: "attachReceipt",
|
|
234
|
+
effect: "write",
|
|
235
|
+
idempotent: false,
|
|
236
|
+
openWorld: false,
|
|
237
|
+
description: "Attach a receipt file to an expense (service-backed)."
|
|
238
|
+
})], ExpenseCollection.prototype, "attachReceipt", 1);
|
|
239
|
+
__decorateClass([method({
|
|
240
|
+
httpMethod: "POST",
|
|
241
|
+
path: "recordReview",
|
|
242
|
+
effect: "write",
|
|
243
|
+
idempotent: false,
|
|
244
|
+
openWorld: false,
|
|
245
|
+
description: "Approve or reject an expense with a reason (service-backed)."
|
|
246
|
+
})], ExpenseCollection.prototype, "recordReview", 1);
|
|
247
|
+
__decorateClass([method({
|
|
248
|
+
httpMethod: "POST",
|
|
249
|
+
path: "recordReimbursement",
|
|
250
|
+
effect: "write",
|
|
251
|
+
idempotent: false,
|
|
252
|
+
openWorld: false,
|
|
253
|
+
description: "Record that an expense was reimbursed (service-backed)."
|
|
254
|
+
})], ExpenseCollection.prototype, "recordReimbursement", 1);
|
|
255
|
+
ExpenseCollection = __decorateClass([smrt({
|
|
256
|
+
api: { include: [
|
|
257
|
+
"record",
|
|
258
|
+
"attachReceipt",
|
|
259
|
+
"recordReview",
|
|
260
|
+
"recordReimbursement"
|
|
261
|
+
] },
|
|
186
262
|
mcp: { include: [] },
|
|
187
263
|
cli: false
|
|
188
264
|
})], ExpenseCollection);
|
|
189
265
|
//#endregion
|
|
190
|
-
//#region src/
|
|
191
|
-
var
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
expenseId = "";
|
|
221
|
-
assetId = "";
|
|
222
|
-
uploadedByProfileId = null;
|
|
223
|
-
filename = "";
|
|
224
|
-
mimeType = "";
|
|
225
|
-
byteCount = 0;
|
|
226
|
-
contentSha256 = "";
|
|
227
|
-
constructor(options = {}) {
|
|
228
|
-
super(options);
|
|
229
|
-
if (options.tenantId !== void 0) this.tenantId = options.tenantId;
|
|
230
|
-
if (options.expenseId !== void 0) this.expenseId = options.expenseId;
|
|
231
|
-
if (options.assetId !== void 0) this.assetId = options.assetId;
|
|
232
|
-
if (options.uploadedByProfileId !== void 0) this.uploadedByProfileId = options.uploadedByProfileId;
|
|
233
|
-
if (options.filename !== void 0) this.filename = options.filename;
|
|
234
|
-
if (options.mimeType !== void 0) this.mimeType = options.mimeType;
|
|
235
|
-
if (options.byteCount !== void 0) this.byteCount = options.byteCount;
|
|
236
|
-
if (options.contentSha256 !== void 0) this.contentSha256 = options.contentSha256;
|
|
237
|
-
}
|
|
238
|
-
/**
|
|
239
|
-
* Validate the link, refuse a second copy of the same file on the same
|
|
240
|
-
* expense, then persist. Never touches the expense.
|
|
241
|
-
*
|
|
242
|
-
* @throws {DuplicateReceiptError} when the expense already has this file.
|
|
243
|
-
* @throws {ExpenseError} `EXPENSE_RECEIPT_INVALID` for a bad hash, a
|
|
244
|
-
* missing or foreign-tenant expense or asset, or a change to an
|
|
245
|
-
* immutable column.
|
|
246
|
-
*/
|
|
247
|
-
async save() {
|
|
248
|
-
const label = this.id || "<new>";
|
|
249
|
-
this.tenantId = normalizeTenantId(this.tenantId);
|
|
250
|
-
this.contentSha256 = normalizeSha256("ExpenseReceipt", label, this.contentSha256);
|
|
251
|
-
assertMinorUnits("ExpenseReceipt", label, "byteCount", this.byteCount, "EXPENSE_RECEIPT_INVALID");
|
|
252
|
-
if (!this.expenseId || !this.assetId) throw new ExpenseError("EXPENSE_RECEIPT_INVALID", `ExpenseReceipt ${label}: expenseId and assetId are required.`);
|
|
253
|
-
const persisted = this.id ? await this.db.get(this.tableName, { id: this.id }) ?? null : null;
|
|
254
|
-
const inserting = await pinNaturalKey("ExpenseReceipt", this, persisted);
|
|
255
|
-
if (persisted) {
|
|
256
|
-
const self = this;
|
|
257
|
-
for (const [fieldName, column] of IMMUTABLE) {
|
|
258
|
-
const value = fieldName === "tenantId" ? effectiveTenant(this.tenantId) : self[fieldName];
|
|
259
|
-
if (String(persisted[column] ?? "") !== String(value ?? "")) throw new ExpenseError("EXPENSE_RECEIPT_INVALID", `ExpenseReceipt ${this.id}: ${fieldName} cannot change; attach a new receipt instead.`);
|
|
260
|
-
}
|
|
261
|
-
} else {
|
|
262
|
-
await this.assertLinkTargets(label);
|
|
263
|
-
await this.assertNotDuplicate();
|
|
264
|
-
}
|
|
265
|
-
try {
|
|
266
|
-
return await super.save();
|
|
267
|
-
} catch (error) {
|
|
268
|
-
if (inserting && isUniqueViolationError(error)) throw await this.classifyInsertConflict(error);
|
|
269
|
-
throw error;
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
/**
|
|
273
|
-
* A refused INSERT is either the same file racing onto the same expense,
|
|
274
|
-
* or a natural-key collision with another receipt.
|
|
275
|
-
*
|
|
276
|
-
* Classified from the error first, by the violated key's name or columns
|
|
277
|
-
* (no other unique key on this table uses `expense_id` or
|
|
278
|
-
* `content_sha256`). That matters inside a caller's transaction,
|
|
279
|
-
* which the violation has already aborted on PostgreSQL, so nothing could
|
|
280
|
-
* be re-read there. Only an adapter that reports neither falls back to a
|
|
281
|
-
* re-read; if that re-read fails too, the original error is kept rather
|
|
282
|
-
* than guessed at.
|
|
283
|
-
*/
|
|
284
|
-
async classifyInsertConflict(error) {
|
|
285
|
-
const info = classifyDatabaseError(error);
|
|
286
|
-
const columns = violatedColumns(error);
|
|
287
|
-
if (info.constraint === RECEIPT_FILE_KEY || info.driverMessages.some((text) => text.includes(RECEIPT_FILE_KEY)) || columns.some((column) => RECEIPT_FILE_COLUMNS.has(column))) return new DuplicateReceiptError(this.expenseId, this.contentSha256, { cause: error });
|
|
288
|
-
if (info.constraint || columns.length > 0) return identityConflict("ExpenseReceipt", this, error);
|
|
289
|
-
try {
|
|
290
|
-
await this.assertNotDuplicate();
|
|
291
|
-
} catch (duplicate) {
|
|
292
|
-
if (duplicate instanceof DuplicateReceiptError) return new DuplicateReceiptError(this.expenseId, this.contentSha256, { cause: error });
|
|
293
|
-
return error;
|
|
294
|
-
}
|
|
295
|
-
return identityConflict("ExpenseReceipt", this, error);
|
|
296
|
-
}
|
|
297
|
-
async assertLinkTargets(label) {
|
|
298
|
-
const { ExpenseCollection } = await Promise.resolve().then(() => ExpenseCollection_exports);
|
|
299
|
-
const expense = await (await ExpenseCollection.create({ db: this.db })).get({ id: this.expenseId });
|
|
300
|
-
if (!expense) throw new ExpenseError("EXPENSE_RECEIPT_INVALID", `ExpenseReceipt ${label}: expense ${this.expenseId} was not found.`);
|
|
301
|
-
if (this.tenantId === null || this.tenantId === void 0) this.tenantId = expense.tenantId ?? null;
|
|
302
|
-
if ((this.tenantId ?? null) !== (expense.tenantId ?? null)) throw new ExpenseError("EXPENSE_RECEIPT_INVALID", `ExpenseReceipt ${label}: a receipt belongs to its expense's tenant.`);
|
|
303
|
-
const asset = await (await AssetCollection.create({ db: this.db })).get({ id: this.assetId });
|
|
304
|
-
const assetTenant = asset?.tenantId ?? null;
|
|
305
|
-
if (!asset || assetTenant !== null && assetTenant !== this.tenantId) throw new ExpenseError("EXPENSE_RECEIPT_INVALID", `ExpenseReceipt ${label}: asset ${this.assetId} was not found in the expense's tenant.`);
|
|
306
|
-
if (!this.filename) this.filename = asset.name ?? "";
|
|
307
|
-
if (!this.mimeType) this.mimeType = asset.mimeType ?? "";
|
|
308
|
-
}
|
|
309
|
-
async assertNotDuplicate() {
|
|
310
|
-
const { ExpenseReceiptCollection } = await Promise.resolve().then(() => ExpenseReceiptCollection_exports);
|
|
311
|
-
if ((await (await ExpenseReceiptCollection.create({ db: this.db })).list({
|
|
312
|
-
where: {
|
|
313
|
-
expenseId: this.expenseId,
|
|
314
|
-
contentSha256: this.contentSha256
|
|
266
|
+
//#region src/recipes.ts
|
|
267
|
+
var ExpensesRecipe = class extends SmrtRecipe {
|
|
268
|
+
static id = "expenses.tracking";
|
|
269
|
+
static help = "./tracking.recipe.md";
|
|
270
|
+
static label = "Expenses";
|
|
271
|
+
static summary = "Record what the business spends, with receipts, and review it.";
|
|
272
|
+
static synonyms = [
|
|
273
|
+
"costs",
|
|
274
|
+
"receipts",
|
|
275
|
+
"spending",
|
|
276
|
+
"reimbursements"
|
|
277
|
+
];
|
|
278
|
+
static section = {
|
|
279
|
+
id: "accounting",
|
|
280
|
+
label: "Accounting",
|
|
281
|
+
icon: "bank",
|
|
282
|
+
description: "Your books: accounts, journals and balances."
|
|
283
|
+
};
|
|
284
|
+
static models = [Expense, ExpenseReceipt];
|
|
285
|
+
static nav = [{
|
|
286
|
+
label: "Expenses",
|
|
287
|
+
model: Expense,
|
|
288
|
+
icon: "receipt",
|
|
289
|
+
description: "Costs you have paid, with the receipt and who paid."
|
|
290
|
+
}];
|
|
291
|
+
static options = {
|
|
292
|
+
Expense: { fields: {
|
|
293
|
+
description: {
|
|
294
|
+
order: 1,
|
|
295
|
+
required: true
|
|
315
296
|
},
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
}) : obj[key] = value;
|
|
360
|
-
var __decorateClass = (decorators, target, key, kind) => {
|
|
361
|
-
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
362
|
-
for (var i = decorators.length - 1, decorator; i >= 0; i--) if (decorator = decorators[i]) result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
363
|
-
if (kind && result) __defProp(target, key, result);
|
|
364
|
-
return result;
|
|
365
|
-
};
|
|
366
|
-
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
367
|
-
var DEFAULT_DUPLICATE_LIMIT = 100;
|
|
368
|
-
var MAX_DUPLICATE_LIMIT = 1e3;
|
|
369
|
-
var ExpenseReceiptCollection = class extends SmrtJunction {
|
|
370
|
-
leftField = "expenseId";
|
|
371
|
-
rightField = "assetId";
|
|
372
|
-
sortField = "createdAt";
|
|
373
|
-
positionField = null;
|
|
374
|
-
/**
|
|
375
|
-
* Attach a receipt file to an expense.
|
|
376
|
-
*
|
|
377
|
-
* Does not change the expense in any way — in particular not its review
|
|
378
|
-
* state.
|
|
379
|
-
*
|
|
380
|
-
* @throws {DuplicateReceiptError} when this expense already carries a file
|
|
381
|
-
* with the same SHA-256.
|
|
382
|
-
*/
|
|
383
|
-
async attachReceipt(input) {
|
|
384
|
-
const receipt = await this.create({
|
|
385
|
-
expenseId: input.expenseId,
|
|
386
|
-
assetId: input.assetId,
|
|
387
|
-
contentSha256: input.contentSha256,
|
|
388
|
-
uploadedByProfileId: input.uploadedByProfileId ?? null,
|
|
389
|
-
filename: input.filename ?? "",
|
|
390
|
-
mimeType: input.mimeType ?? "",
|
|
391
|
-
byteCount: input.byteCount ?? 0
|
|
392
|
-
});
|
|
393
|
-
await receipt.save();
|
|
394
|
-
return receipt;
|
|
395
|
-
}
|
|
396
|
-
/**
|
|
397
|
-
* Refused: a receipt is evidence and needs its content hash, which a
|
|
398
|
-
* generic junction attach does not carry. Use {@link attachReceipt}.
|
|
399
|
-
*
|
|
400
|
-
* @throws {ExpenseError} `EXPENSE_RECEIPT_INVALID`, always.
|
|
401
|
-
*/
|
|
402
|
-
async attach(_expenseId, _assetId, _opts = {}) {
|
|
403
|
-
throw new ExpenseError("EXPENSE_RECEIPT_INVALID", "ExpenseReceiptCollection.attach() is not supported: use attachReceipt(), which records and checks the file hash.");
|
|
404
|
-
}
|
|
405
|
-
/**
|
|
406
|
-
* Refused before anything is deleted. The inherited replace-all deletes
|
|
407
|
-
* every receipt of the expense and re-attaches without hashes, which would
|
|
408
|
-
* lose the evidence. Attach with {@link attachReceipt}; remove a link with
|
|
409
|
-
* `detach()`.
|
|
410
|
-
*
|
|
411
|
-
* @throws {ExpenseError} `EXPENSE_RECEIPT_INVALID`, always.
|
|
412
|
-
*/
|
|
413
|
-
async setLinks(_expenseId, _assetIds, _opts = {}) {
|
|
414
|
-
throw new ExpenseError("EXPENSE_RECEIPT_INVALID", "ExpenseReceiptCollection.setLinks() is not supported: it would delete receipt evidence. Use attachReceipt() to add and detach() to remove.");
|
|
415
|
-
}
|
|
416
|
-
/** Receipts of one expense, oldest first. */
|
|
417
|
-
async receiptsFor(expenseId) {
|
|
418
|
-
return this.byLeft(expenseId);
|
|
419
|
-
}
|
|
420
|
-
/**
|
|
421
|
-
* Files (by SHA-256) attached to more than one expense, for a person to
|
|
422
|
-
* review. Nothing is changed or rejected: the same receipt on two expenses
|
|
423
|
-
* may be a split cost or a double claim, and only a reviewer can tell.
|
|
424
|
-
*
|
|
425
|
-
* With `expenseId`, reports only files that expense shares with others;
|
|
426
|
-
* without it, scans the visible tenant (largest groups first).
|
|
427
|
-
*/
|
|
428
|
-
async findDuplicateReceipts(options = {}) {
|
|
429
|
-
const limit = Math.min(Math.max(Math.trunc(options.limit ?? DEFAULT_DUPLICATE_LIMIT), 1), MAX_DUPLICATE_LIMIT);
|
|
430
|
-
let hashes;
|
|
431
|
-
if (options.expenseId) {
|
|
432
|
-
const own = await this.byLeft(options.expenseId);
|
|
433
|
-
hashes = [...new Set(own.map((receipt) => receipt.contentSha256))];
|
|
434
|
-
} else {
|
|
435
|
-
const [facet] = await this.facets({ fields: [{
|
|
436
|
-
field: "contentSha256",
|
|
437
|
-
limit: MAX_DUPLICATE_LIMIT
|
|
438
|
-
}] });
|
|
439
|
-
hashes = (facet?.values ?? []).filter((value) => value.count > 1).map((value) => String(value.value)).slice(0, limit);
|
|
440
|
-
}
|
|
441
|
-
if (hashes.length === 0) return [];
|
|
442
|
-
const rows = await this.list({
|
|
443
|
-
where: { contentSha256: hashes },
|
|
444
|
-
orderBy: ["content_sha256 ASC", "created_at ASC"]
|
|
445
|
-
});
|
|
446
|
-
const byHash = /* @__PURE__ */ new Map();
|
|
447
|
-
for (const receipt of rows) {
|
|
448
|
-
const group = byHash.get(receipt.contentSha256) ?? [];
|
|
449
|
-
group.push(receipt);
|
|
450
|
-
byHash.set(receipt.contentSha256, group);
|
|
451
|
-
}
|
|
452
|
-
const groups = [];
|
|
453
|
-
for (const [contentSha256, receipts] of byHash) {
|
|
454
|
-
const expenseIds = [...new Set(receipts.map((receipt) => receipt.expenseId))].sort();
|
|
455
|
-
if (expenseIds.length < 2) continue;
|
|
456
|
-
groups.push({
|
|
457
|
-
contentSha256,
|
|
458
|
-
expenseIds,
|
|
459
|
-
receipts
|
|
460
|
-
});
|
|
461
|
-
}
|
|
462
|
-
groups.sort((a, b) => b.expenseIds.length - a.expenseIds.length || a.contentSha256.localeCompare(b.contentSha256));
|
|
463
|
-
return groups.slice(0, limit);
|
|
464
|
-
}
|
|
297
|
+
amount: { order: 2 },
|
|
298
|
+
currency: { order: 3 },
|
|
299
|
+
incurredOn: {
|
|
300
|
+
label: "Date",
|
|
301
|
+
order: 4,
|
|
302
|
+
help: "The date on the receipt, as YYYY-MM-DD."
|
|
303
|
+
},
|
|
304
|
+
category: {
|
|
305
|
+
order: 5,
|
|
306
|
+
help: "One word, such as material, travel, freight or other."
|
|
307
|
+
},
|
|
308
|
+
vendorId: {
|
|
309
|
+
label: "Vendor",
|
|
310
|
+
order: 6
|
|
311
|
+
},
|
|
312
|
+
paidBy: { order: 7 },
|
|
313
|
+
paidByProfileId: {
|
|
314
|
+
label: "Person who paid",
|
|
315
|
+
order: 8,
|
|
316
|
+
help: "Who paid out of their own pocket, when a person paid."
|
|
317
|
+
},
|
|
318
|
+
paidByName: { order: 9 },
|
|
319
|
+
reimbursable: { order: 10 },
|
|
320
|
+
costObjectId: {
|
|
321
|
+
label: "Charged to",
|
|
322
|
+
order: 11,
|
|
323
|
+
help: "The job, project or client the cost belongs to."
|
|
324
|
+
},
|
|
325
|
+
costObjectType: { visibility: "hidden" },
|
|
326
|
+
financialBreakdown: { visibility: "hidden" },
|
|
327
|
+
refundOfId: { visibility: "hidden" },
|
|
328
|
+
recordedByProfileId: { visibility: "hidden" },
|
|
329
|
+
commitmentId: { visibility: "hidden" },
|
|
330
|
+
commitmentLineId: { visibility: "hidden" },
|
|
331
|
+
reviewedByProfileId: { visibility: "hidden" },
|
|
332
|
+
duplicateOfId: { visibility: "hidden" }
|
|
333
|
+
} },
|
|
334
|
+
ExpenseReceipt: { fields: {
|
|
335
|
+
contentSha256: { visibility: "hidden" },
|
|
336
|
+
byteCount: { visibility: "hidden" },
|
|
337
|
+
uploadedByProfileId: { visibility: "hidden" }
|
|
338
|
+
} }
|
|
339
|
+
};
|
|
465
340
|
};
|
|
466
|
-
__publicField(ExpenseReceiptCollection, "__smrtPackage__", "@happyvertical/smrt-expenses");
|
|
467
|
-
__publicField(ExpenseReceiptCollection, "_itemClass", ExpenseReceipt);
|
|
468
|
-
ExpenseReceiptCollection = __decorateClass([smrt({
|
|
469
|
-
api: { include: [] },
|
|
470
|
-
mcp: { include: [] },
|
|
471
|
-
cli: false
|
|
472
|
-
})], ExpenseReceiptCollection);
|
|
473
341
|
//#endregion
|
|
474
|
-
export { DuplicateReceiptError, EXPENSE_PAYERS, EXPENSE_REVIEW_STATUSES, Expense, ExpenseCollection, ExpenseError, ExpenseReceipt, ExpenseReceiptCollection, SUGGESTED_EXPENSE_CATEGORIES, computeContentSha256, ExpenseCollection_exports as t };
|
|
342
|
+
export { DuplicateReceiptError, EXPENSE_PAYERS, EXPENSE_REVIEW_STATUSES, Expense, ExpenseActionError, ExpenseCollection, ExpenseError, ExpenseReceipt, ExpenseReceiptCollection, ExpensesRecipe, SUGGESTED_EXPENSE_CATEGORIES, computeContentSha256, ExpenseCollection_exports as t };
|
|
475
343
|
|
|
476
344
|
//# sourceMappingURL=index.js.map
|