@happyvertical/smrt-commerce 0.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/AGENTS.md +44 -0
  2. package/CLAUDE.md +1 -0
  3. package/LICENSE +7 -0
  4. package/README.md +146 -0
  5. package/dist/__smrt-register__.d.ts +2 -0
  6. package/dist/__smrt-register__.d.ts.map +1 -0
  7. package/dist/collections/ContractCollection.d.ts +87 -0
  8. package/dist/collections/ContractCollection.d.ts.map +1 -0
  9. package/dist/collections/CustomerCollection.d.ts +58 -0
  10. package/dist/collections/CustomerCollection.d.ts.map +1 -0
  11. package/dist/collections/FulfillmentCollection.d.ts +75 -0
  12. package/dist/collections/FulfillmentCollection.d.ts.map +1 -0
  13. package/dist/collections/InvoiceCollection.d.ts +162 -0
  14. package/dist/collections/InvoiceCollection.d.ts.map +1 -0
  15. package/dist/collections/InvoiceLineItemCollection.d.ts +90 -0
  16. package/dist/collections/InvoiceLineItemCollection.d.ts.map +1 -0
  17. package/dist/collections/PaymentAllocationCollection.d.ts +86 -0
  18. package/dist/collections/PaymentAllocationCollection.d.ts.map +1 -0
  19. package/dist/collections/PaymentCollection.d.ts +96 -0
  20. package/dist/collections/PaymentCollection.d.ts.map +1 -0
  21. package/dist/collections/PaymentIntentCollection.d.ts +66 -0
  22. package/dist/collections/PaymentIntentCollection.d.ts.map +1 -0
  23. package/dist/collections/PayoutCollection.d.ts +47 -0
  24. package/dist/collections/PayoutCollection.d.ts.map +1 -0
  25. package/dist/collections/VendorCollection.d.ts +59 -0
  26. package/dist/collections/VendorCollection.d.ts.map +1 -0
  27. package/dist/collections/index.d.ts +15 -0
  28. package/dist/collections/index.d.ts.map +1 -0
  29. package/dist/index.d.ts +5 -0
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.js +5308 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/manifest.json +13852 -0
  34. package/dist/models/Contract.d.ts +425 -0
  35. package/dist/models/Contract.d.ts.map +1 -0
  36. package/dist/models/ContractLineItem.d.ts +92 -0
  37. package/dist/models/ContractLineItem.d.ts.map +1 -0
  38. package/dist/models/Customer.d.ts +98 -0
  39. package/dist/models/Customer.d.ts.map +1 -0
  40. package/dist/models/Fulfillment.d.ts +99 -0
  41. package/dist/models/Fulfillment.d.ts.map +1 -0
  42. package/dist/models/FulfillmentLineItem.d.ts +42 -0
  43. package/dist/models/FulfillmentLineItem.d.ts.map +1 -0
  44. package/dist/models/Invoice.d.ts +326 -0
  45. package/dist/models/Invoice.d.ts.map +1 -0
  46. package/dist/models/InvoiceLineItem.d.ts +120 -0
  47. package/dist/models/InvoiceLineItem.d.ts.map +1 -0
  48. package/dist/models/Payment.d.ts +269 -0
  49. package/dist/models/Payment.d.ts.map +1 -0
  50. package/dist/models/PaymentAllocation.d.ts +93 -0
  51. package/dist/models/PaymentAllocation.d.ts.map +1 -0
  52. package/dist/models/PaymentIntent.d.ts +341 -0
  53. package/dist/models/PaymentIntent.d.ts.map +1 -0
  54. package/dist/models/Payout.d.ts +200 -0
  55. package/dist/models/Payout.d.ts.map +1 -0
  56. package/dist/models/Vendor.d.ts +153 -0
  57. package/dist/models/Vendor.d.ts.map +1 -0
  58. package/dist/models/index.d.ts +17 -0
  59. package/dist/models/index.d.ts.map +1 -0
  60. package/dist/playground.d.ts +2 -0
  61. package/dist/playground.d.ts.map +1 -0
  62. package/dist/playground.js +108 -0
  63. package/dist/playground.js.map +1 -0
  64. package/dist/smrt-knowledge.json +5494 -0
  65. package/dist/svelte/components/InvoiceActions.svelte +191 -0
  66. package/dist/svelte/components/InvoiceActions.svelte.d.ts +26 -0
  67. package/dist/svelte/components/InvoiceActions.svelte.d.ts.map +1 -0
  68. package/dist/svelte/components/InvoiceCard.svelte +233 -0
  69. package/dist/svelte/components/InvoiceCard.svelte.d.ts +16 -0
  70. package/dist/svelte/components/InvoiceCard.svelte.d.ts.map +1 -0
  71. package/dist/svelte/components/InvoiceHeader.svelte +258 -0
  72. package/dist/svelte/components/InvoiceHeader.svelte.d.ts +26 -0
  73. package/dist/svelte/components/InvoiceHeader.svelte.d.ts.map +1 -0
  74. package/dist/svelte/components/InvoiceLineItems.svelte +322 -0
  75. package/dist/svelte/components/InvoiceLineItems.svelte.d.ts +24 -0
  76. package/dist/svelte/components/InvoiceLineItems.svelte.d.ts.map +1 -0
  77. package/dist/svelte/components/InvoiceTotals.svelte +193 -0
  78. package/dist/svelte/components/InvoiceTotals.svelte.d.ts +27 -0
  79. package/dist/svelte/components/InvoiceTotals.svelte.d.ts.map +1 -0
  80. package/dist/svelte/components/UnbilledItems.svelte +355 -0
  81. package/dist/svelte/components/UnbilledItems.svelte.d.ts +18 -0
  82. package/dist/svelte/components/UnbilledItems.svelte.d.ts.map +1 -0
  83. package/dist/svelte/i18n.d.ts +19 -0
  84. package/dist/svelte/i18n.d.ts.map +1 -0
  85. package/dist/svelte/i18n.js +19 -0
  86. package/dist/svelte/index.d.ts +40 -0
  87. package/dist/svelte/index.d.ts.map +1 -0
  88. package/dist/svelte/index.js +43 -0
  89. package/dist/svelte/playground.d.ts +103 -0
  90. package/dist/svelte/playground.d.ts.map +1 -0
  91. package/dist/svelte/playground.js +103 -0
  92. package/dist/svelte/types.d.ts +47 -0
  93. package/dist/svelte/types.d.ts.map +1 -0
  94. package/dist/svelte/types.js +4 -0
  95. package/dist/types/index.d.ts +234 -0
  96. package/dist/types/index.d.ts.map +1 -0
  97. package/dist/ui.d.ts +10 -0
  98. package/dist/ui.d.ts.map +1 -0
  99. package/dist/ui.js +85 -0
  100. package/dist/ui.js.map +1 -0
  101. package/package.json +87 -0
@@ -0,0 +1,99 @@
1
+ import { SmrtObject } from '@happyvertical/smrt-core';
2
+ import { Address, FulfillmentStatus, FulfillmentType } from '../types/index.js';
3
+ /**
4
+ * Fulfillment tracks the delivery or completion of contract items.
5
+ *
6
+ * A contract can have multiple fulfillments (e.g., partial shipments).
7
+ * Each fulfillment tracks what was delivered and when.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * const fulfillment = await fulfillments.create({
12
+ * contractId: order.id,
13
+ * fulfillmentType: FulfillmentType.SHIPMENT,
14
+ * trackingNumber: 'UPS-123456789',
15
+ * carrier: 'UPS',
16
+ * shippingAddress: {
17
+ * street1: '123 Main St',
18
+ * city: 'Anytown',
19
+ * state: 'CA',
20
+ * postalCode: '90210',
21
+ * country: 'US'
22
+ * }
23
+ * });
24
+ * ```
25
+ */
26
+ export declare class Fulfillment extends SmrtObject {
27
+ /**
28
+ * Tenant ID for multi-tenant isolation
29
+ * Nullable to support both tenant-scoped and global fulfillments
30
+ */
31
+ tenantId: string | null;
32
+ /**
33
+ * Parent contract being fulfilled
34
+ */
35
+ contractId: string;
36
+ /**
37
+ * Type of fulfillment
38
+ */
39
+ fulfillmentType: FulfillmentType;
40
+ /**
41
+ * Current fulfillment status
42
+ */
43
+ status: FulfillmentStatus;
44
+ /**
45
+ * Tracking number from carrier
46
+ */
47
+ trackingNumber: string;
48
+ /**
49
+ * Shipping carrier name
50
+ */
51
+ carrier: string;
52
+ /**
53
+ * Shipping destination address
54
+ */
55
+ shippingAddress: Address;
56
+ /**
57
+ * When the shipment was sent
58
+ */
59
+ shippedAt: Date | null;
60
+ /**
61
+ * When the shipment was delivered
62
+ */
63
+ deliveredAt: Date | null;
64
+ /**
65
+ * Estimated delivery date
66
+ */
67
+ estimatedDelivery: Date | null;
68
+ /**
69
+ * Notes about this fulfillment
70
+ */
71
+ notes: string;
72
+ constructor(options?: any);
73
+ /**
74
+ * Check if fulfillment is complete
75
+ */
76
+ isDelivered(): boolean;
77
+ /**
78
+ * Check if fulfillment is in transit
79
+ */
80
+ isInTransit(): boolean;
81
+ /**
82
+ * Check if fulfillment is pending
83
+ */
84
+ isPending(): boolean;
85
+ /**
86
+ * Mark as shipped
87
+ */
88
+ markShipped(trackingNumber?: string, carrier?: string): void;
89
+ /**
90
+ * Mark as delivered
91
+ */
92
+ markDelivered(): void;
93
+ /**
94
+ * Cancel fulfillment
95
+ */
96
+ cancel(): void;
97
+ }
98
+ export default Fulfillment;
99
+ //# sourceMappingURL=Fulfillment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Fulfillment.d.ts","sourceRoot":"","sources":["../../src/models/Fulfillment.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAc,UAAU,EAAQ,MAAM,0BAA0B,CAAC;AAExE,OAAO,EACL,KAAK,OAAO,EACZ,iBAAiB,EACjB,eAAe,EAChB,MAAM,mBAAmB,CAAC;AAE3B;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAMa,WAAY,SAAQ,UAAU;IACzC;;;OAGG;IAEH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAE/B;;OAEG;IAEH,UAAU,EAAE,MAAM,CAAM;IAExB;;OAEG;IACH,eAAe,EAAE,eAAe,CAA4B;IAE5D;;OAEG;IACH,MAAM,EAAE,iBAAiB,CAA6B;IAEtD;;OAEG;IACH,cAAc,EAAE,MAAM,CAAM;IAE5B;;OAEG;IACH,OAAO,EAAE,MAAM,CAAM;IAErB;;OAEG;IACH,eAAe,EAAE,OAAO,CAAM;IAE9B;;OAEG;IACH,SAAS,EAAE,IAAI,GAAG,IAAI,CAAQ;IAE9B;;OAEG;IACH,WAAW,EAAE,IAAI,GAAG,IAAI,CAAQ;IAEhC;;OAEG;IACH,iBAAiB,EAAE,IAAI,GAAG,IAAI,CAAQ;IAEtC;;OAEG;IACH,KAAK,EAAE,MAAM,CAAM;gBAEP,OAAO,GAAE,GAAQ;IAoB7B;;OAEG;IACH,WAAW,IAAI,OAAO;IAItB;;OAEG;IACH,WAAW,IAAI,OAAO;IAItB;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;OAEG;IACH,WAAW,CAAC,cAAc,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI;IAO5D;;OAEG;IACH,aAAa,IAAI,IAAI;IAKrB;;OAEG;IACH,MAAM,IAAI,IAAI;CAGf;AAED,eAAe,WAAW,CAAC"}
@@ -0,0 +1,42 @@
1
+ import { SmrtObject } from '@happyvertical/smrt-core';
2
+ /**
3
+ * FulfillmentLineItem tracks which contract line items are included
4
+ * in a specific fulfillment and how much was fulfilled.
5
+ *
6
+ * This allows partial fulfillment - e.g., shipping 5 of 10 items ordered.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * const fulfillmentItem = await fulfillmentItems.create({
11
+ * fulfillmentId: fulfillment.id,
12
+ * contractLineItemId: lineItem.id,
13
+ * quantityFulfilled: 5 // of 10 ordered
14
+ * });
15
+ * ```
16
+ */
17
+ export declare class FulfillmentLineItem extends SmrtObject {
18
+ /**
19
+ * Tenant ID for multi-tenant isolation
20
+ * Nullable to support both tenant-scoped and global fulfillment line items
21
+ */
22
+ tenantId: string | null;
23
+ /**
24
+ * Parent fulfillment
25
+ */
26
+ fulfillmentId: string;
27
+ /**
28
+ * Contract line item being fulfilled
29
+ */
30
+ contractLineItemId: string;
31
+ /**
32
+ * Quantity fulfilled in this fulfillment
33
+ */
34
+ quantityFulfilled: number;
35
+ /**
36
+ * Notes about this line item
37
+ */
38
+ notes: string;
39
+ constructor(options?: any);
40
+ }
41
+ export default FulfillmentLineItem;
42
+ //# sourceMappingURL=FulfillmentLineItem.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FulfillmentLineItem.d.ts","sourceRoot":"","sources":["../../src/models/FulfillmentLineItem.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAc,UAAU,EAAQ,MAAM,0BAA0B,CAAC;AAGxE;;;;;;;;;;;;;;GAcG;AACH,qBAMa,mBAAoB,SAAQ,UAAU;IACjD;;;OAGG;IAEH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAE/B;;OAEG;IAEH,aAAa,EAAE,MAAM,CAAM;IAE3B;;OAEG;IAEH,kBAAkB,EAAE,MAAM,CAAM;IAEhC;;OAEG;IACH,iBAAiB,EAAE,MAAM,CAAO;IAEhC;;OAEG;IACH,KAAK,EAAE,MAAM,CAAM;gBAEP,OAAO,GAAE,GAAQ;CAW9B;AAED,eAAe,mBAAmB,CAAC"}
@@ -0,0 +1,326 @@
1
+ import { SmrtObject } from '@happyvertical/smrt-core';
2
+ import { InvoiceStatus, RecognizeRevenueOptions } from '../types/index.js';
3
+ /**
4
+ * Invoice represents a bill sent to a customer for goods or services.
5
+ *
6
+ * Invoices are distinct from Contracts - a Contract is an agreement,
7
+ * while an Invoice is the billing document requesting payment.
8
+ *
9
+ * Invoices integrate with:
10
+ * - `@happyvertical/smrt-ledgers` for revenue recognition (double-entry accounting)
11
+ * - `@happyvertical/accounting` SDK for syncing with external providers (QBO, Stripe)
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * // Create an invoice
16
+ * const invoice = await invoices.create({
17
+ * customerId: customer.id,
18
+ * invoiceNumber: await invoices.generateInvoiceNumber(),
19
+ * issueDate: new Date(),
20
+ * dueDate: addDays(new Date(), 30),
21
+ * subtotal: 1000,
22
+ * taxAmount: 50,
23
+ * totalAmount: 1050,
24
+ * currency: 'CAD'
25
+ * });
26
+ *
27
+ * // Recognize revenue in ledger
28
+ * await invoice.recognizeRevenue({
29
+ * arAccountId: arAccount.id,
30
+ * revenueAccountId: revenueAccount.id,
31
+ * taxAccountId: taxAccount.id
32
+ * });
33
+ * ```
34
+ */
35
+ export declare class Invoice extends SmrtObject {
36
+ /**
37
+ * Tenant ID for multi-tenant isolation
38
+ * Nullable to support both tenant-scoped and global invoices
39
+ */
40
+ tenantId: string | null;
41
+ /**
42
+ * Customer this invoice is for
43
+ */
44
+ customerId: string;
45
+ /**
46
+ * Optional link to Contract (cross-package reference)
47
+ */
48
+ contractId: string;
49
+ /**
50
+ * Invoice number (e.g., INV-2025-0001)
51
+ * Generated via InvoiceCollection.generateInvoiceNumber()
52
+ */
53
+ invoiceNumber: string;
54
+ /**
55
+ * External reference (e.g., customer PO number)
56
+ */
57
+ reference: string;
58
+ /**
59
+ * Date invoice was issued
60
+ */
61
+ issueDate: Date;
62
+ /**
63
+ * Payment due date
64
+ */
65
+ dueDate: Date;
66
+ /**
67
+ * Date invoice was fully paid
68
+ */
69
+ paidDate: Date | null;
70
+ /**
71
+ * Subtotal before tax
72
+ */
73
+ subtotal: number;
74
+ /**
75
+ * Tax amount
76
+ */
77
+ taxAmount: number;
78
+ /**
79
+ * Total amount due (subtotal + tax)
80
+ */
81
+ totalAmount: number;
82
+ /**
83
+ * Amount paid (sum of PaymentAllocations)
84
+ */
85
+ amountPaid: number;
86
+ /**
87
+ * Currency code (ISO 4217)
88
+ */
89
+ currency: string;
90
+ /**
91
+ * Current invoice status
92
+ */
93
+ status: InvoiceStatus;
94
+ /**
95
+ * Journal ID for AR recognition (cross-package ref to smrt-ledgers)
96
+ */
97
+ arJournalId: string;
98
+ /**
99
+ * Journal ID for revenue recognition (cross-package ref to smrt-ledgers)
100
+ */
101
+ revenueJournalId: string;
102
+ /**
103
+ * External ID in accounting provider (e.g., QBO invoice ID)
104
+ */
105
+ externalId: string;
106
+ /**
107
+ * Customer's external ID in accounting provider.
108
+ * Used to link invoice to customer in external system.
109
+ */
110
+ customerExternalId: string;
111
+ /**
112
+ * Accounting provider name ('quickbooks' | 'stripe' | etc.)
113
+ */
114
+ externalProvider: string;
115
+ /**
116
+ * When invoice was last synced to provider
117
+ */
118
+ syncedAt: Date | null;
119
+ /**
120
+ * When invoice was sent to customer
121
+ */
122
+ sentAt: Date | null;
123
+ /**
124
+ * When customer viewed the invoice
125
+ */
126
+ viewedAt: Date | null;
127
+ /**
128
+ * Number of payment reminders sent
129
+ */
130
+ remindersSent: number;
131
+ /**
132
+ * When last reminder was sent
133
+ */
134
+ lastReminderAt: Date | null;
135
+ /**
136
+ * Internal notes (not shown to customer)
137
+ */
138
+ notes: string;
139
+ /**
140
+ * Notes shown to customer on invoice
141
+ */
142
+ customerNotes: string;
143
+ /**
144
+ * Payment terms text
145
+ */
146
+ terms: string;
147
+ constructor(options?: any);
148
+ /**
149
+ * Capture the persisted status the row was loaded with, so the save-time
150
+ * transition guard can reject illegal status flips made via raw field
151
+ * assignment (mass-assignment on a generated update route, a stale caller,
152
+ * etc.). Only rows that already exist in the database carry a "prior"
153
+ * status — freshly-constructed (not-yet-saved) invoices have no prior and
154
+ * may start in any status.
155
+ */
156
+ initialize(): Promise<this>;
157
+ /**
158
+ * Recompute and validate financial fields before every write so forged
159
+ * totals, negative amounts, and illegal status flips can't be persisted via
160
+ * raw mass-assignment on the generated CRUD routes.
161
+ *
162
+ * Behaviour:
163
+ * - **Totals are authoritative from line items.** When the invoice is
164
+ * persisted and has line items, `subtotal` / `taxAmount` / `totalAmount`
165
+ * are recomputed from those items, overriding whatever the caller sent.
166
+ * This blocks "create real line items but claim a tiny total" forgery.
167
+ * - **Without line items**, the caller-supplied totals are accepted but the
168
+ * `totalAmount === subtotal + taxAmount` arithmetic invariant is enforced.
169
+ * - **amountPaid is derived/validated.** When persisted, it is recomputed
170
+ * from PaymentAllocations rather than trusted from the caller. It may
171
+ * never exceed `totalAmount` (beyond rounding tolerance).
172
+ * - **Non-negativity** is enforced on all four amounts.
173
+ * - **Status transitions** are validated against the prior persisted status.
174
+ */
175
+ save(): Promise<this>;
176
+ /**
177
+ * Resolve the AUTHORITATIVE prior status (S5 audit #1390 round 4). The
178
+ * {@link loadedInvoiceStatus} WeakMap is only populated when {@link initialize}
179
+ * hydrated the row, so a `create({ id: <existing>, _skipLoad: true })` upsert
180
+ * yields an instance whose WeakMap entry is missing — trusting it would treat
181
+ * the write as a brand-new row and skip the transition guard entirely. Read
182
+ * the persisted row's status directly so a create-onto-existing is correctly
183
+ * treated as an update. `undefined` means no row exists (genuinely new).
184
+ */
185
+ private resolvePriorStatus;
186
+ /**
187
+ * Recompute subtotal/tax/total from line items (when present) and derive
188
+ * amountPaid from PaymentAllocations. Falls back to the arithmetic invariant
189
+ * when the invoice has no line items. Tolerant of smrt-ledgers being absent
190
+ * (the dynamic imports stay inside the package).
191
+ */
192
+ private recomputeAmountsForSave;
193
+ /**
194
+ * After amounts are recomputed and amountPaid is re-derived from allocations,
195
+ * assert the persisted `status` is consistent with the derived
196
+ * amountPaid-vs-totalAmount relationship. This blocks the raw
197
+ * `SENT → PAID with amountPaid=0` flip (and its inverse, claiming PARTIAL/SENT
198
+ * while fully allocated) that the status-transition map alone permits because
199
+ * SENT → PAID is a structurally legal edge.
200
+ *
201
+ * Only enforced for the payment-derived statuses (PAID / PARTIAL and the
202
+ * unpaid open states SENT / VIEWED). Lifecycle statuses that aren't a
203
+ * function of amountPaid — DRAFT, OVERDUE, CANCELLED, WRITTEN_OFF — are left
204
+ * to their own transition rules.
205
+ */
206
+ private assertPaymentStatusConsistent;
207
+ /**
208
+ * Enforce `totalAmount === subtotal + taxAmount` (within rounding tolerance).
209
+ * Used when the invoice has no line items to recompute from.
210
+ */
211
+ private assertTotalArithmetic;
212
+ /**
213
+ * Reject negative financial values and an amountPaid that exceeds the total
214
+ * (beyond rounding tolerance — overpayment is modelled elsewhere, not by
215
+ * letting amountPaid float above the invoice total).
216
+ */
217
+ private assertNonNegativeAmounts;
218
+ /**
219
+ * Reject an illegal status flip done via raw field assignment. Compares the
220
+ * about-to-be-written status against the status the row was loaded with.
221
+ * No-op transitions (status unchanged) and brand-new rows are always allowed.
222
+ */
223
+ private assertStatusTransition;
224
+ /**
225
+ * Check if invoice is a draft
226
+ */
227
+ isDraft(): boolean;
228
+ /**
229
+ * Check if invoice has been sent
230
+ */
231
+ isSent(): boolean;
232
+ /**
233
+ * Check if invoice is fully paid
234
+ */
235
+ isPaid(): boolean;
236
+ /**
237
+ * Check if invoice is partially paid
238
+ */
239
+ isPartial(): boolean;
240
+ /**
241
+ * Check if invoice is overdue
242
+ */
243
+ isOverdue(): boolean;
244
+ /**
245
+ * Get remaining amount due
246
+ */
247
+ getAmountDue(): number;
248
+ /**
249
+ * Mark invoice as sent
250
+ */
251
+ markSent(): void;
252
+ /**
253
+ * Record that the invoice was viewed by the customer.
254
+ *
255
+ * This method is idempotent - calling it multiple times will only
256
+ * record the first view time. Status only transitions to VIEWED if
257
+ * the current status is SENT (other statuses like PARTIAL or PAID
258
+ * are preserved).
259
+ */
260
+ markViewed(): void;
261
+ /**
262
+ * Update payment amount and status.
263
+ *
264
+ * Called when PaymentAllocations change. Handles both forward transitions
265
+ * (SENT → PARTIAL → PAID) and reversals (PAID → PARTIAL → original status).
266
+ *
267
+ * Terminal statuses (CANCELLED, WRITTEN_OFF) are not modified.
268
+ */
269
+ updatePaymentStatus(amountPaid: number): void;
270
+ /**
271
+ * Cancel the invoice
272
+ */
273
+ cancel(): void;
274
+ /**
275
+ * Write off the invoice (bad debt)
276
+ */
277
+ writeOff(): void;
278
+ /**
279
+ * Recognize revenue and create AR journal entry.
280
+ *
281
+ * Creates a balanced journal entry in smrt-ledgers:
282
+ * - Debit: Accounts Receivable (assets increase)
283
+ * - Credit: Revenue (revenue increases)
284
+ * - Credit: Tax Payable (liability increases, if taxAmount > 0)
285
+ *
286
+ * **Note**: This method saves the invoice after setting arJournalId.
287
+ *
288
+ * @param options - Account IDs for the journal entry
289
+ * @returns The created journal
290
+ *
291
+ * @example
292
+ * ```typescript
293
+ * const journal = await invoice.recognizeRevenue({
294
+ * arAccountId: '1120',
295
+ * revenueAccountId: '4100',
296
+ * taxAccountId: '2130'
297
+ * });
298
+ * ```
299
+ */
300
+ recognizeRevenue(options: RecognizeRevenueOptions): Promise<any>;
301
+ /**
302
+ * Get the AR journal entry (if revenue was recognized)
303
+ */
304
+ getArJournal(): Promise<any | null>;
305
+ /**
306
+ * Convert to InvoiceInput for SDK accounting provider sync.
307
+ *
308
+ * Fetches line items and maps all fields to the format expected
309
+ * by @happyvertical/accounting providers.
310
+ *
311
+ * @returns InvoiceInput compatible with @happyvertical/accounting
312
+ *
313
+ * @example
314
+ * ```typescript
315
+ * const provider = await getAccountingProvider({ type: 'quickbooks', ... });
316
+ * const input = await invoice.toAccountingInput();
317
+ * const result = await provider.invoices.push(input);
318
+ * invoice.externalId = result.externalId;
319
+ * invoice.syncedAt = result.syncedAt;
320
+ * await invoice.save();
321
+ * ```
322
+ */
323
+ toAccountingInput(): Promise<any>;
324
+ }
325
+ export default Invoice;
326
+ //# sourceMappingURL=Invoice.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Invoice.d.ts","sourceRoot":"","sources":["../../src/models/Invoice.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,120 @@
1
+ import { SmrtObject } from '@happyvertical/smrt-core';
2
+ /**
3
+ * InvoiceLineItem represents a single line item on an invoice.
4
+ *
5
+ * Line items contain details of what is being billed, including
6
+ * quantity, pricing, and optional source tracking (e.g., from ad campaigns).
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * const lineItem = await lineItems.create({
11
+ * invoiceId: invoice.id,
12
+ * description: 'Display Advertising - Summer Campaign',
13
+ * quantity: 50000, // impressions
14
+ * unitPrice: 0.01, // per impression
15
+ * taxRate: 0.05,
16
+ * sourceType: 'campaign',
17
+ * sourceId: 'campaign-uuid',
18
+ * periodStart: new Date('2025-06-01'),
19
+ * periodEnd: new Date('2025-06-30')
20
+ * });
21
+ * ```
22
+ */
23
+ export declare class InvoiceLineItem extends SmrtObject {
24
+ /**
25
+ * Tenant ID for multi-tenant isolation
26
+ * Nullable to support both tenant-scoped and global invoice line items
27
+ */
28
+ tenantId: string | null;
29
+ /**
30
+ * Parent invoice
31
+ */
32
+ invoiceId: string;
33
+ /**
34
+ * Item description
35
+ */
36
+ description: string;
37
+ /**
38
+ * SKU or item code
39
+ */
40
+ sku: string;
41
+ /**
42
+ * Quantity (e.g., impressions, hours, units)
43
+ */
44
+ quantity: number;
45
+ /**
46
+ * Unit price before discount
47
+ */
48
+ unitPrice: number;
49
+ /**
50
+ * Discount amount (flat, not percentage)
51
+ */
52
+ discount: number;
53
+ /**
54
+ * Tax rate as decimal (e.g., 0.05 for 5%)
55
+ */
56
+ taxRate: number;
57
+ /**
58
+ * Calculated line amount
59
+ */
60
+ amount: number;
61
+ /**
62
+ * Type of source ('campaign' | 'contract' | 'manual' | etc.)
63
+ */
64
+ sourceType: string;
65
+ /**
66
+ * ID of the source (e.g., campaign ID, contract ID)
67
+ */
68
+ sourceId: string;
69
+ /**
70
+ * Service period start (for time-based billing)
71
+ */
72
+ periodStart: Date | null;
73
+ /**
74
+ * Service period end (for time-based billing)
75
+ */
76
+ periodEnd: Date | null;
77
+ /**
78
+ * Revenue account ID (cross-package ref to smrt-ledgers)
79
+ * Used for revenue recognition to specific accounts
80
+ */
81
+ revenueAccountId: string;
82
+ /**
83
+ * Sort order within the invoice
84
+ */
85
+ sortOrder: number;
86
+ constructor(options?: any);
87
+ /**
88
+ * Calculate the line amount.
89
+ *
90
+ * Formula: (quantity * unitPrice - discount) * (1 + taxRate)
91
+ *
92
+ * Tax is calculated on the discounted subtotal. This follows the common
93
+ * "discount before tax" approach used in most North American jurisdictions.
94
+ * For jurisdictions requiring different tax calculation methods, override
95
+ * this method or calculate amounts externally.
96
+ */
97
+ calculateAmount(): number;
98
+ /**
99
+ * Get subtotal (before tax)
100
+ */
101
+ getSubtotal(): number;
102
+ /**
103
+ * Get tax amount
104
+ */
105
+ getTaxAmount(): number;
106
+ /**
107
+ * Check if line item has source tracking
108
+ */
109
+ hasSource(): boolean;
110
+ /**
111
+ * Check if line item has a service period
112
+ */
113
+ hasPeriod(): boolean;
114
+ /**
115
+ * Convert to line item format for SDK accounting provider
116
+ */
117
+ toAccountingLineItem(): any;
118
+ }
119
+ export default InvoiceLineItem;
120
+ //# sourceMappingURL=InvoiceLineItem.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InvoiceLineItem.d.ts","sourceRoot":"","sources":["../../src/models/InvoiceLineItem.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAGL,UAAU,EAEX,MAAM,0BAA0B,CAAC;AAGlC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAMa,eAAgB,SAAQ,UAAU;IAC7C;;;OAGG;IAEH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAE/B;;OAEG;IAEH,SAAS,EAAE,MAAM,CAAM;IAEvB;;OAEG;IACH,WAAW,EAAE,MAAM,CAAM;IAEzB;;OAEG;IACH,GAAG,EAAE,MAAM,CAAM;IAEjB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAK;IAErB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAK;IAEtB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAK;IAErB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAK;IAEpB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAK;IAMnB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAM;IAExB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAM;IAEtB;;OAEG;IACH,WAAW,EAAE,IAAI,GAAG,IAAI,CAAQ;IAEhC;;OAEG;IACH,SAAS,EAAE,IAAI,GAAG,IAAI,CAAQ;IAM9B;;;OAGG;IAEH,gBAAgB,EAAE,MAAM,CAAM;IAE9B;;OAEG;IACH,SAAS,EAAE,MAAM,CAAK;gBAEV,OAAO,GAAE,GAAQ;IAsB7B;;;;;;;;;OASG;IACH,eAAe,IAAI,MAAM;IAMzB;;OAEG;IACH,WAAW,IAAI,MAAM;IAIrB;;OAEG;IACH,YAAY,IAAI,MAAM;IAItB;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;OAEG;IACH,oBAAoB,IAAI,GAAG;CAa5B;AAED,eAAe,eAAe,CAAC"}