@voyant-travel/finance 0.119.5

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 (294) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +192 -0
  3. package/dist/action-ledger-drift.d.ts +29 -0
  4. package/dist/action-ledger-drift.d.ts.map +1 -0
  5. package/dist/action-ledger-drift.js +166 -0
  6. package/dist/booking-tax.d.ts +124 -0
  7. package/dist/booking-tax.d.ts.map +1 -0
  8. package/dist/booking-tax.js +264 -0
  9. package/dist/checkout-routes.d.ts +1154 -0
  10. package/dist/checkout-routes.d.ts.map +1 -0
  11. package/dist/checkout-routes.js +116 -0
  12. package/dist/checkout-service-plan.d.ts +137 -0
  13. package/dist/checkout-service-plan.d.ts.map +1 -0
  14. package/dist/checkout-service-plan.js +119 -0
  15. package/dist/checkout-service.d.ts +9 -0
  16. package/dist/checkout-service.d.ts.map +1 -0
  17. package/dist/checkout-service.js +324 -0
  18. package/dist/checkout-validation.d.ts +1682 -0
  19. package/dist/checkout-validation.d.ts.map +1 -0
  20. package/dist/checkout-validation.js +228 -0
  21. package/dist/document-download.d.ts +3 -0
  22. package/dist/document-download.d.ts.map +1 -0
  23. package/dist/document-download.js +1 -0
  24. package/dist/fx-money.d.ts +17 -0
  25. package/dist/fx-money.d.ts.map +1 -0
  26. package/dist/fx-money.js +194 -0
  27. package/dist/index.d.ts +65 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +108 -0
  30. package/dist/invoice-fx.d.ts +134 -0
  31. package/dist/invoice-fx.d.ts.map +1 -0
  32. package/dist/invoice-fx.js +240 -0
  33. package/dist/invoice-number-errors.d.ts +2 -0
  34. package/dist/invoice-number-errors.d.ts.map +1 -0
  35. package/dist/invoice-number-errors.js +58 -0
  36. package/dist/markets-ref.d.ts +149 -0
  37. package/dist/markets-ref.d.ts.map +1 -0
  38. package/dist/markets-ref.js +17 -0
  39. package/dist/payment-link.d.ts +23 -0
  40. package/dist/payment-link.d.ts.map +1 -0
  41. package/dist/payment-link.js +30 -0
  42. package/dist/payment-policy.d.ts +113 -0
  43. package/dist/payment-policy.d.ts.map +1 -0
  44. package/dist/payment-policy.js +193 -0
  45. package/dist/route-runtime.d.ts +22 -0
  46. package/dist/route-runtime.d.ts.map +1 -0
  47. package/dist/route-runtime.js +18 -0
  48. package/dist/routes-action-ledger.d.ts +181 -0
  49. package/dist/routes-action-ledger.d.ts.map +1 -0
  50. package/dist/routes-action-ledger.js +142 -0
  51. package/dist/routes-booking-billing.d.ts +852 -0
  52. package/dist/routes-booking-billing.d.ts.map +1 -0
  53. package/dist/routes-booking-billing.js +223 -0
  54. package/dist/routes-booking-create.d.ts +3 -0
  55. package/dist/routes-booking-create.d.ts.map +1 -0
  56. package/dist/routes-booking-create.js +194 -0
  57. package/dist/routes-booking-reads.d.ts +46 -0
  58. package/dist/routes-booking-reads.d.ts.map +1 -0
  59. package/dist/routes-booking-reads.js +20 -0
  60. package/dist/routes-documents.d.ts +195 -0
  61. package/dist/routes-documents.d.ts.map +1 -0
  62. package/dist/routes-documents.js +93 -0
  63. package/dist/routes-invoice-core.d.ts +794 -0
  64. package/dist/routes-invoice-core.d.ts.map +1 -0
  65. package/dist/routes-invoice-core.js +238 -0
  66. package/dist/routes-invoice-documents.d.ts +401 -0
  67. package/dist/routes-invoice-documents.d.ts.map +1 -0
  68. package/dist/routes-invoice-documents.js +91 -0
  69. package/dist/routes-invoice-issue.d.ts +384 -0
  70. package/dist/routes-invoice-issue.d.ts.map +1 -0
  71. package/dist/routes-invoice-issue.js +208 -0
  72. package/dist/routes-payment-processing.d.ts +1193 -0
  73. package/dist/routes-payment-processing.d.ts.map +1 -0
  74. package/dist/routes-payment-processing.js +238 -0
  75. package/dist/routes-payments.d.ts +309 -0
  76. package/dist/routes-payments.d.ts.map +1 -0
  77. package/dist/routes-payments.js +94 -0
  78. package/dist/routes-public.d.ts +1948 -0
  79. package/dist/routes-public.d.ts.map +1 -0
  80. package/dist/routes-public.js +275 -0
  81. package/dist/routes-reference-data.d.ts +977 -0
  82. package/dist/routes-reference-data.d.ts.map +1 -0
  83. package/dist/routes-reference-data.js +191 -0
  84. package/dist/routes-reports.d.ts +344 -0
  85. package/dist/routes-reports.d.ts.map +1 -0
  86. package/dist/routes-reports.js +93 -0
  87. package/dist/routes-runtime.d.ts +71 -0
  88. package/dist/routes-runtime.d.ts.map +1 -0
  89. package/dist/routes-runtime.js +59 -0
  90. package/dist/routes-settlement.d.ts +67 -0
  91. package/dist/routes-settlement.d.ts.map +1 -0
  92. package/dist/routes-settlement.js +23 -0
  93. package/dist/routes-shared.d.ts +35 -0
  94. package/dist/routes-shared.d.ts.map +1 -0
  95. package/dist/routes-shared.js +10 -0
  96. package/dist/routes-supplier-invoices.d.ts +778 -0
  97. package/dist/routes-supplier-invoices.d.ts.map +1 -0
  98. package/dist/routes-supplier-invoices.js +159 -0
  99. package/dist/routes-vouchers.d.ts +228 -0
  100. package/dist/routes-vouchers.d.ts.map +1 -0
  101. package/dist/routes-vouchers.js +54 -0
  102. package/dist/routes.d.ts +5577 -0
  103. package/dist/routes.d.ts.map +1 -0
  104. package/dist/routes.js +44 -0
  105. package/dist/schema/booking-billing.d.ts +1006 -0
  106. package/dist/schema/booking-billing.d.ts.map +1 -0
  107. package/dist/schema/booking-billing.js +106 -0
  108. package/dist/schema/enums.d.ts +48 -0
  109. package/dist/schema/enums.d.ts.map +1 -0
  110. package/dist/schema/enums.js +237 -0
  111. package/dist/schema/invoice-documents.d.ts +1245 -0
  112. package/dist/schema/invoice-documents.d.ts.map +1 -0
  113. package/dist/schema/invoice-documents.js +140 -0
  114. package/dist/schema/payment-instruments.d.ts +418 -0
  115. package/dist/schema/payment-instruments.d.ts.map +1 -0
  116. package/dist/schema/payment-instruments.js +45 -0
  117. package/dist/schema/payment-processing.d.ts +563 -0
  118. package/dist/schema/payment-processing.d.ts.map +1 -0
  119. package/dist/schema/payment-processing.js +65 -0
  120. package/dist/schema/payment-sessions.d.ts +728 -0
  121. package/dist/schema/payment-sessions.d.ts.map +1 -0
  122. package/dist/schema/payment-sessions.js +79 -0
  123. package/dist/schema/receivables.d.ts +1474 -0
  124. package/dist/schema/receivables.d.ts.map +1 -0
  125. package/dist/schema/receivables.js +179 -0
  126. package/dist/schema/relations.d.ts +82 -0
  127. package/dist/schema/relations.d.ts.map +1 -0
  128. package/dist/schema/relations.js +144 -0
  129. package/dist/schema/supplier-invoices.d.ts +1619 -0
  130. package/dist/schema/supplier-invoices.d.ts.map +1 -0
  131. package/dist/schema/supplier-invoices.js +228 -0
  132. package/dist/schema/tax.d.ts +712 -0
  133. package/dist/schema/tax.d.ts.map +1 -0
  134. package/dist/schema/tax.js +98 -0
  135. package/dist/schema/vouchers.d.ts +444 -0
  136. package/dist/schema/vouchers.d.ts.map +1 -0
  137. package/dist/schema/vouchers.js +64 -0
  138. package/dist/schema.d.ts +12 -0
  139. package/dist/schema.d.ts.map +1 -0
  140. package/dist/schema.js +11 -0
  141. package/dist/service-accountant-shares.d.ts +106 -0
  142. package/dist/service-accountant-shares.d.ts.map +1 -0
  143. package/dist/service-accountant-shares.js +331 -0
  144. package/dist/service-action-ledger-accounting.d.ts +104 -0
  145. package/dist/service-action-ledger-accounting.d.ts.map +1 -0
  146. package/dist/service-action-ledger-accounting.js +386 -0
  147. package/dist/service-action-ledger-booking-payments.d.ts +48 -0
  148. package/dist/service-action-ledger-booking-payments.d.ts.map +1 -0
  149. package/dist/service-action-ledger-booking-payments.js +178 -0
  150. package/dist/service-action-ledger-bookings.d.ts +44 -0
  151. package/dist/service-action-ledger-bookings.d.ts.map +1 -0
  152. package/dist/service-action-ledger-bookings.js +81 -0
  153. package/dist/service-action-ledger-payment-authorizations.d.ts +48 -0
  154. package/dist/service-action-ledger-payment-authorizations.d.ts.map +1 -0
  155. package/dist/service-action-ledger-payment-authorizations.js +209 -0
  156. package/dist/service-action-ledger-payment-sessions.d.ts +83 -0
  157. package/dist/service-action-ledger-payment-sessions.d.ts.map +1 -0
  158. package/dist/service-action-ledger-payment-sessions.js +294 -0
  159. package/dist/service-action-ledger-supplier-invoices.d.ts +27 -0
  160. package/dist/service-action-ledger-supplier-invoices.d.ts.map +1 -0
  161. package/dist/service-action-ledger-supplier-invoices.js +111 -0
  162. package/dist/service-action-ledger-supplier-payments.d.ts +21 -0
  163. package/dist/service-action-ledger-supplier-payments.d.ts.map +1 -0
  164. package/dist/service-action-ledger-supplier-payments.js +97 -0
  165. package/dist/service-action-ledger.d.ts +7 -0
  166. package/dist/service-action-ledger.d.ts.map +1 -0
  167. package/dist/service-action-ledger.js +6 -0
  168. package/dist/service-aggregates.d.ts +96 -0
  169. package/dist/service-aggregates.d.ts.map +1 -0
  170. package/dist/service-aggregates.js +294 -0
  171. package/dist/service-booking-billing.d.ts +2322 -0
  172. package/dist/service-booking-billing.d.ts.map +1 -0
  173. package/dist/service-booking-billing.js +8 -0
  174. package/dist/service-booking-create.d.ts +410 -0
  175. package/dist/service-booking-create.d.ts.map +1 -0
  176. package/dist/service-booking-create.js +1256 -0
  177. package/dist/service-booking-guarantees.d.ts +725 -0
  178. package/dist/service-booking-guarantees.d.ts.map +1 -0
  179. package/dist/service-booking-guarantees.js +153 -0
  180. package/dist/service-booking-item-billing.d.ts +1062 -0
  181. package/dist/service-booking-item-billing.d.ts.map +1 -0
  182. package/dist/service-booking-item-billing.js +77 -0
  183. package/dist/service-booking-payment-schedules.d.ts +557 -0
  184. package/dist/service-booking-payment-schedules.d.ts.map +1 -0
  185. package/dist/service-booking-payment-schedules.js +372 -0
  186. package/dist/service-bookings-dual-create.d.ts +308 -0
  187. package/dist/service-bookings-dual-create.d.ts.map +1 -0
  188. package/dist/service-bookings-dual-create.js +131 -0
  189. package/dist/service-boundary-sql.d.ts +6 -0
  190. package/dist/service-boundary-sql.d.ts.map +1 -0
  191. package/dist/service-boundary-sql.js +15 -0
  192. package/dist/service-cost-categories.d.ts +26 -0
  193. package/dist/service-cost-categories.d.ts.map +1 -0
  194. package/dist/service-cost-categories.js +76 -0
  195. package/dist/service-documents.d.ts +80 -0
  196. package/dist/service-documents.d.ts.map +1 -0
  197. package/dist/service-documents.js +228 -0
  198. package/dist/service-invoice-artifacts.d.ts +246 -0
  199. package/dist/service-invoice-artifacts.d.ts.map +1 -0
  200. package/dist/service-invoice-artifacts.js +277 -0
  201. package/dist/service-invoice-core.d.ts +405 -0
  202. package/dist/service-invoice-core.d.ts.map +1 -0
  203. package/dist/service-invoice-core.js +290 -0
  204. package/dist/service-invoice-credit-notes.d.ts +973 -0
  205. package/dist/service-invoice-credit-notes.d.ts.map +1 -0
  206. package/dist/service-invoice-credit-notes.js +142 -0
  207. package/dist/service-invoice-from-booking.d.ts +41 -0
  208. package/dist/service-invoice-from-booking.d.ts.map +1 -0
  209. package/dist/service-invoice-from-booking.js +267 -0
  210. package/dist/service-invoice-line-items.d.ts +432 -0
  211. package/dist/service-invoice-line-items.d.ts.map +1 -0
  212. package/dist/service-invoice-line-items.js +102 -0
  213. package/dist/service-invoice-numbering.d.ts +227 -0
  214. package/dist/service-invoice-numbering.d.ts.map +1 -0
  215. package/dist/service-invoice-numbering.js +260 -0
  216. package/dist/service-invoice-payments.d.ts +673 -0
  217. package/dist/service-invoice-payments.d.ts.map +1 -0
  218. package/dist/service-invoice-payments.js +398 -0
  219. package/dist/service-invoices.d.ts +2501 -0
  220. package/dist/service-invoices.d.ts.map +1 -0
  221. package/dist/service-invoices.js +12 -0
  222. package/dist/service-issue.d.ts +207 -0
  223. package/dist/service-issue.d.ts.map +1 -0
  224. package/dist/service-issue.js +431 -0
  225. package/dist/service-payment-authorizations.d.ts +164 -0
  226. package/dist/service-payment-authorizations.d.ts.map +1 -0
  227. package/dist/service-payment-authorizations.js +227 -0
  228. package/dist/service-payment-instruments.d.ts +116 -0
  229. package/dist/service-payment-instruments.d.ts.map +1 -0
  230. package/dist/service-payment-instruments.js +99 -0
  231. package/dist/service-payment-processing.d.ts +676 -0
  232. package/dist/service-payment-processing.d.ts.map +1 -0
  233. package/dist/service-payment-processing.js +10 -0
  234. package/dist/service-payment-session-completion.d.ts +48 -0
  235. package/dist/service-payment-session-completion.d.ts.map +1 -0
  236. package/dist/service-payment-session-completion.js +238 -0
  237. package/dist/service-payment-sessions.d.ts +361 -0
  238. package/dist/service-payment-sessions.d.ts.map +1 -0
  239. package/dist/service-payment-sessions.js +280 -0
  240. package/dist/service-profitability.d.ts +114 -0
  241. package/dist/service-profitability.d.ts.map +1 -0
  242. package/dist/service-profitability.js +794 -0
  243. package/dist/service-public.d.ts +553 -0
  244. package/dist/service-public.d.ts.map +1 -0
  245. package/dist/service-public.js +583 -0
  246. package/dist/service-reference-data.d.ts +272 -0
  247. package/dist/service-reference-data.d.ts.map +1 -0
  248. package/dist/service-reference-data.js +280 -0
  249. package/dist/service-rendition-wait.d.ts +38 -0
  250. package/dist/service-rendition-wait.d.ts.map +1 -0
  251. package/dist/service-rendition-wait.js +67 -0
  252. package/dist/service-reports.d.ts +37 -0
  253. package/dist/service-reports.d.ts.map +1 -0
  254. package/dist/service-reports.js +62 -0
  255. package/dist/service-settlement.d.ts +46 -0
  256. package/dist/service-settlement.d.ts.map +1 -0
  257. package/dist/service-settlement.js +185 -0
  258. package/dist/service-shared.d.ts +541 -0
  259. package/dist/service-shared.d.ts.map +1 -0
  260. package/dist/service-shared.js +764 -0
  261. package/dist/service-supplier-invoices.d.ts +871 -0
  262. package/dist/service-supplier-invoices.d.ts.map +1 -0
  263. package/dist/service-supplier-invoices.js +744 -0
  264. package/dist/service-supplier-payments.d.ts +69 -0
  265. package/dist/service-supplier-payments.d.ts.map +1 -0
  266. package/dist/service-supplier-payments.js +136 -0
  267. package/dist/service-vouchers-migration.d.ts +44 -0
  268. package/dist/service-vouchers-migration.d.ts.map +1 -0
  269. package/dist/service-vouchers-migration.js +148 -0
  270. package/dist/service-vouchers.d.ts +157 -0
  271. package/dist/service-vouchers.d.ts.map +1 -0
  272. package/dist/service-vouchers.js +191 -0
  273. package/dist/service.d.ts +6490 -0
  274. package/dist/service.d.ts.map +1 -0
  275. package/dist/service.js +29 -0
  276. package/dist/validation-billing.d.ts +2 -0
  277. package/dist/validation-billing.d.ts.map +1 -0
  278. package/dist/validation-billing.js +1 -0
  279. package/dist/validation-payments.d.ts +2 -0
  280. package/dist/validation-payments.d.ts.map +1 -0
  281. package/dist/validation-payments.js +1 -0
  282. package/dist/validation-public.d.ts +2 -0
  283. package/dist/validation-public.d.ts.map +1 -0
  284. package/dist/validation-public.js +1 -0
  285. package/dist/validation-shared.d.ts +2 -0
  286. package/dist/validation-shared.d.ts.map +1 -0
  287. package/dist/validation-shared.js +1 -0
  288. package/dist/validation-vouchers.d.ts +2 -0
  289. package/dist/validation-vouchers.d.ts.map +1 -0
  290. package/dist/validation-vouchers.js +1 -0
  291. package/dist/validation.d.ts +2 -0
  292. package/dist/validation.d.ts.map +1 -0
  293. package/dist/validation.js +1 -0
  294. package/package.json +121 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service-invoice-credit-notes.d.ts","sourceRoot":"","sources":["../src/service-invoice-credit-notes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,qBAAqB,EACrB,6BAA6B,EAC7B,sBAAsB,EACtB,qBAAqB,EACrB,kBAAkB,EAClB,qBAAqB,EACtB,MAAM,qBAAqB,CAAA;AAiB5B,eAAO,MAAM,+BAA+B;wBACtB,kBAAkB,aAAa,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBASnD,kBAAkB,aACX,MAAM,QACX,qBAAqB,YAClB,qBAAqB;;;;;;;;;;;;;;;yBA0C1B,kBAAkB,gBACR,MAAM,QACd,qBAAqB,YAClB,qBAAqB;;;;;;;;;;;;;;;gCAkDJ,kBAAkB,gBAAgB,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iCAS9D,kBAAkB,gBACR,MAAM,QACd,6BAA6B,YAC1B,qBAAqB;;;;;;;;;;kBAsDlB,kBAAkB,aAAa,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mBAS7C,kBAAkB,aACX,MAAM,UACT,MAAM,QACR,sBAAsB;;;;;;;CAuB/B,CAAA"}
@@ -0,0 +1,142 @@
1
+ import { appendActionLedgerMutation, asc, buildCreditNoteCreationActionLedgerInput, buildCreditNoteLineItemCreateActionLedgerInput, buildCreditNoteUpdateActionLedgerInput, creditNoteLineItems, creditNotes, desc, eq, financeNotes, invoices, resolveCreditNoteUpdateData, resolveFxMoneyBaseAmount, } from "./service-shared.js";
2
+ export const financeInvoiceCreditNoteService = {
3
+ listCreditNotes(db, invoiceId) {
4
+ return db
5
+ .select()
6
+ .from(creditNotes)
7
+ .where(eq(creditNotes.invoiceId, invoiceId))
8
+ .orderBy(desc(creditNotes.createdAt));
9
+ },
10
+ async createCreditNote(db, invoiceId, data, runtime = {}) {
11
+ const [invoice] = await db.select().from(invoices).where(eq(invoices.id, invoiceId)).limit(1);
12
+ if (!invoice) {
13
+ return null;
14
+ }
15
+ const creditNoteData = await resolveFxMoneyBaseAmount(db, data, {
16
+ ...runtime,
17
+ targetBaseCurrency: invoice.currency,
18
+ fallbackFxRateSetId: invoice.fxRateSetId ?? null,
19
+ date: new Date(),
20
+ });
21
+ return db.transaction(async (tx) => {
22
+ const [row] = await tx
23
+ .insert(creditNotes)
24
+ .values({ ...creditNoteData, invoiceId })
25
+ .returning();
26
+ if (row && runtime.actionLedgerContext) {
27
+ await appendActionLedgerMutation(tx, await buildCreditNoteCreationActionLedgerInput(runtime.actionLedgerContext, {
28
+ invoice,
29
+ creditNote: row,
30
+ }, {
31
+ authorizationSource: runtime.actionLedgerAuthorizationSource,
32
+ }));
33
+ }
34
+ return row;
35
+ });
36
+ },
37
+ async updateCreditNote(db, creditNoteId, data, runtime = {}) {
38
+ const updateData = await resolveCreditNoteUpdateData(db, creditNoteId, data, runtime);
39
+ if (!updateData)
40
+ return null;
41
+ const updateCreditNoteRow = async (writer) => {
42
+ const [row] = await writer
43
+ .update(creditNotes)
44
+ .set({ ...updateData, updatedAt: new Date() })
45
+ .where(eq(creditNotes.id, creditNoteId))
46
+ .returning();
47
+ if (!row) {
48
+ return null;
49
+ }
50
+ const [invoice] = await writer
51
+ .select()
52
+ .from(invoices)
53
+ .where(eq(invoices.id, row.invoiceId))
54
+ .limit(1);
55
+ return invoice ? { invoice, creditNote: row } : null;
56
+ };
57
+ const actionLedgerContext = runtime.actionLedgerContext;
58
+ if (actionLedgerContext) {
59
+ const result = await db.transaction(async (tx) => {
60
+ const updated = await updateCreditNoteRow(tx);
61
+ if (updated) {
62
+ await appendActionLedgerMutation(tx, buildCreditNoteUpdateActionLedgerInput(actionLedgerContext, { ...updated, changes: updateData }, { authorizationSource: runtime.actionLedgerAuthorizationSource }));
63
+ }
64
+ return updated;
65
+ });
66
+ return result?.creditNote ?? null;
67
+ }
68
+ return (await updateCreditNoteRow(db))?.creditNote ?? null;
69
+ },
70
+ listCreditNoteLineItems(db, creditNoteId) {
71
+ return db
72
+ .select()
73
+ .from(creditNoteLineItems)
74
+ .where(eq(creditNoteLineItems.creditNoteId, creditNoteId))
75
+ .orderBy(asc(creditNoteLineItems.sortOrder));
76
+ },
77
+ async createCreditNoteLineItem(db, creditNoteId, data, runtime = {}) {
78
+ const createLineItem = async (writer) => {
79
+ const [creditNote] = await writer
80
+ .select()
81
+ .from(creditNotes)
82
+ .where(eq(creditNotes.id, creditNoteId))
83
+ .limit(1);
84
+ if (!creditNote) {
85
+ return null;
86
+ }
87
+ const [invoice] = await writer
88
+ .select()
89
+ .from(invoices)
90
+ .where(eq(invoices.id, creditNote.invoiceId))
91
+ .limit(1);
92
+ if (!invoice) {
93
+ return null;
94
+ }
95
+ const [row] = await writer
96
+ .insert(creditNoteLineItems)
97
+ .values({ ...data, creditNoteId })
98
+ .returning();
99
+ return row ? { invoice, creditNote, lineItem: row } : null;
100
+ };
101
+ const actionLedgerContext = runtime.actionLedgerContext;
102
+ if (actionLedgerContext) {
103
+ const result = await db.transaction(async (tx) => {
104
+ const created = await createLineItem(tx);
105
+ if (created) {
106
+ await appendActionLedgerMutation(tx, buildCreditNoteLineItemCreateActionLedgerInput(actionLedgerContext, created, {
107
+ authorizationSource: runtime.actionLedgerAuthorizationSource,
108
+ }));
109
+ }
110
+ return created;
111
+ });
112
+ return result?.lineItem ?? null;
113
+ }
114
+ return (await createLineItem(db))?.lineItem ?? null;
115
+ },
116
+ listNotes(db, invoiceId) {
117
+ return db
118
+ .select()
119
+ .from(financeNotes)
120
+ .where(eq(financeNotes.invoiceId, invoiceId))
121
+ .orderBy(financeNotes.createdAt);
122
+ },
123
+ async createNote(db, invoiceId, userId, data) {
124
+ const [invoice] = await db
125
+ .select({ id: invoices.id })
126
+ .from(invoices)
127
+ .where(eq(invoices.id, invoiceId))
128
+ .limit(1);
129
+ if (!invoice) {
130
+ return null;
131
+ }
132
+ const [row] = await db
133
+ .insert(financeNotes)
134
+ .values({
135
+ invoiceId,
136
+ authorId: userId,
137
+ content: data.content,
138
+ })
139
+ .returning();
140
+ return row;
141
+ },
142
+ };
@@ -0,0 +1,41 @@
1
+ import type { CreateInvoiceFromBookingInput, FinanceServiceRuntime, InvoiceFromBookingData, PostgresJsDatabase } from "./service-shared.js";
2
+ export declare const financeInvoiceFromBookingService: {
3
+ createInvoiceFromBooking(db: PostgresJsDatabase, data: CreateInvoiceFromBookingInput, bookingData: InvoiceFromBookingData, runtime?: FinanceServiceRuntime): Promise<{
4
+ subtotalCents: number;
5
+ currency: string;
6
+ id: string;
7
+ createdAt: Date;
8
+ updatedAt: Date;
9
+ taxRegimeId: string | null;
10
+ taxCents: number;
11
+ totalCents: number;
12
+ status: "void" | "paid" | "draft" | "pending_external_allocation" | "issued" | "partially_paid" | "overdue";
13
+ bookingId: string;
14
+ notes: string | null;
15
+ templateId: string | null;
16
+ dueDate: string;
17
+ invoiceNumber: string;
18
+ invoiceType: "invoice" | "proforma" | "credit_note";
19
+ convertedFromInvoiceId: string | null;
20
+ seriesId: string | null;
21
+ sequence: number | null;
22
+ language: string | null;
23
+ personId: string | null;
24
+ organizationId: string | null;
25
+ baseCurrency: string | null;
26
+ fxRateSetId: string | null;
27
+ baseSubtotalCents: number | null;
28
+ baseTaxCents: number | null;
29
+ baseTotalCents: number | null;
30
+ paidCents: number;
31
+ basePaidCents: number | null;
32
+ balanceDueCents: number;
33
+ baseBalanceDueCents: number | null;
34
+ commissionPercent: number | null;
35
+ commissionAmountCents: number | null;
36
+ issueDate: string;
37
+ voidedAt: Date | null;
38
+ voidReason: string | null;
39
+ } | null>;
40
+ };
41
+ //# sourceMappingURL=service-invoice-from-booking.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service-invoice-from-booking.d.ts","sourceRoot":"","sources":["../src/service-invoice-from-booking.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,6BAA6B,EAC7B,qBAAqB,EACrB,sBAAsB,EACtB,kBAAkB,EACnB,MAAM,qBAAqB,CAAA;AAsG5B,eAAO,MAAM,gCAAgC;iCAErC,kBAAkB,QAChB,6BAA6B,eACtB,sBAAsB,YAC1B,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4PjC,CAAA"}
@@ -0,0 +1,267 @@
1
+ import { financeInvoiceNumberingService } from "./service-invoice-numbering.js";
2
+ import { assertInvoiceFromBookingOverrideTotals, bookingItemCommissions, bookingItemTaxLines, bookingItemToInvoiceLine, bookingPaymentScheduleToInvoiceLine, eq, InvoiceFromBookingValidationError, InvoiceLineItemsPersistenceError, InvoiceNumberAllocationError, InvoiceNumberConflictError, invoiceExternalRefs, invoiceFromBookingExternalRefValues, invoiceFromBookingOverrideLineItems, invoiceLineItems, invoiceScopeForType, invoices, isInvoiceNumberUniqueConstraintError, normalizeCurrencyCode, or, pendingExternalInvoiceNumber, resolveBookingInvoiceBaseAmount, resolveFxMoneyBaseAmount, resolveInvoiceFromBookingDueDate, resolveInvoiceLineDescriptions, resolvePaymentScheduleDisplayItem, } from "./service-shared.js";
3
+ async function resolveInvoiceNumberForBooking(db, data) {
4
+ const scope = invoiceScopeForType(data.invoiceType);
5
+ if (data.invoiceNumber) {
6
+ return {
7
+ invoiceNumber: data.invoiceNumber,
8
+ seriesId: data.seriesId ?? null,
9
+ sequence: null,
10
+ status: "draft",
11
+ };
12
+ }
13
+ const series = data.seriesId
14
+ ? await financeInvoiceNumberingService.getInvoiceNumberSeriesById(db, data.seriesId)
15
+ : await financeInvoiceNumberingService.resolveDefaultInvoiceNumberSeries(db, scope);
16
+ if (!series) {
17
+ throw new InvoiceNumberAllocationError(data.seriesId ? "invoice_number_series_not_found" : "no_active_series_for_scope", { scope, seriesId: data.seriesId });
18
+ }
19
+ if (!series.active) {
20
+ throw new InvoiceNumberAllocationError("invoice_number_series_inactive", {
21
+ scope,
22
+ seriesId: series.id,
23
+ });
24
+ }
25
+ if (series.scope !== scope) {
26
+ throw new InvoiceNumberAllocationError("invoice_number_series_scope_mismatch", {
27
+ scope,
28
+ seriesId: series.id,
29
+ });
30
+ }
31
+ if (series.externalProvider) {
32
+ return {
33
+ invoiceNumber: pendingExternalInvoiceNumber(scope),
34
+ seriesId: series.id,
35
+ sequence: null,
36
+ status: "pending_external_allocation",
37
+ };
38
+ }
39
+ const allocated = await financeInvoiceNumberingService.allocateInvoiceNumber(db, series.id);
40
+ if (allocated.status === "not_found") {
41
+ throw new InvoiceNumberAllocationError("invoice_number_series_not_found", {
42
+ scope,
43
+ seriesId: series.id,
44
+ });
45
+ }
46
+ if (allocated.status === "inactive") {
47
+ throw new InvoiceNumberAllocationError("invoice_number_series_inactive", {
48
+ scope,
49
+ seriesId: series.id,
50
+ });
51
+ }
52
+ return {
53
+ invoiceNumber: allocated.formattedNumber,
54
+ seriesId: allocated.seriesId,
55
+ sequence: allocated.sequence,
56
+ status: "draft",
57
+ };
58
+ }
59
+ export const financeInvoiceFromBookingService = {
60
+ async createInvoiceFromBooking(db, data, bookingData, runtime = {}) {
61
+ const { booking, items, paymentSchedule } = bookingData;
62
+ const invoiceDueDate = await resolveInvoiceFromBookingDueDate(data, bookingData, runtime);
63
+ const requestedCurrency = normalizeCurrencyCode(data.currency);
64
+ const bookingSellCurrency = normalizeCurrencyCode(booking.sellCurrency) ?? booking.sellCurrency;
65
+ const invoiceCurrency = requestedCurrency ?? normalizeCurrencyCode(paymentSchedule?.currency) ?? bookingSellCurrency;
66
+ const requestedBaseCurrency = normalizeCurrencyCode(data.baseCurrency);
67
+ const hasCrossCurrencyOverride = requestedCurrency !== null && requestedCurrency !== bookingSellCurrency;
68
+ if (hasCrossCurrencyOverride &&
69
+ (!requestedBaseCurrency || requestedBaseCurrency !== bookingSellCurrency)) {
70
+ throw new InvoiceFromBookingValidationError("Cross-currency invoice overrides require baseCurrency to match the booking sell currency", {
71
+ currency: invoiceCurrency,
72
+ baseCurrency: requestedBaseCurrency,
73
+ bookingSellCurrency,
74
+ });
75
+ }
76
+ const overrideLineItems = data.lineItems
77
+ ? invoiceFromBookingOverrideLineItems(data.lineItems)
78
+ : null;
79
+ if (hasCrossCurrencyOverride && !overrideLineItems) {
80
+ throw new InvoiceFromBookingValidationError("Cross-currency invoice overrides require replacement line items", {
81
+ currency: invoiceCurrency,
82
+ baseCurrency: requestedBaseCurrency,
83
+ bookingSellCurrency,
84
+ fields: ["lineItems"],
85
+ });
86
+ }
87
+ const shouldUseBookingItems = overrideLineItems === null && !paymentSchedule;
88
+ const invoiceItems = shouldUseBookingItems ? items : [];
89
+ const itemIds = invoiceItems.map((item) => item.id);
90
+ const taxes = itemIds.length === 0
91
+ ? []
92
+ : await db
93
+ .select()
94
+ .from(bookingItemTaxLines)
95
+ .where(or(...itemIds.map((id) => eq(bookingItemTaxLines.bookingItemId, id))));
96
+ const commissions = itemIds.length === 0
97
+ ? []
98
+ : await db
99
+ .select()
100
+ .from(bookingItemCommissions)
101
+ .where(or(...itemIds.map((id) => eq(bookingItemCommissions.bookingItemId, id))));
102
+ const taxesByBookingItemId = new Map();
103
+ for (const tax of taxes) {
104
+ const existing = taxesByBookingItemId.get(tax.bookingItemId) ?? [];
105
+ existing.push(tax);
106
+ taxesByBookingItemId.set(tax.bookingItemId, existing);
107
+ }
108
+ const scheduleItem = paymentSchedule
109
+ ? resolvePaymentScheduleDisplayItem(paymentSchedule, items)
110
+ : undefined;
111
+ const paymentScheduleLineDescriptionFormat = data.paymentScheduleLineDescriptionFormat ??
112
+ runtime.paymentScheduleLineDescriptionFormat ??
113
+ "schedule_first";
114
+ const resolvedLineItems = overrideLineItems ??
115
+ (paymentSchedule
116
+ ? [
117
+ bookingPaymentScheduleToInvoiceLine(booking, paymentSchedule, scheduleItem, paymentScheduleLineDescriptionFormat),
118
+ ]
119
+ : invoiceItems.length > 0
120
+ ? invoiceItems.map((item, sortOrder) => ({
121
+ ...bookingItemToInvoiceLine(item, taxesByBookingItemId.get(item.id) ?? [], sortOrder),
122
+ }))
123
+ : [
124
+ {
125
+ bookingItemId: null,
126
+ bookingPaymentScheduleId: null,
127
+ description: `Booking ${booking.bookingNumber}`,
128
+ quantity: 1,
129
+ unitPriceCents: booking.sellAmountCents ?? 0,
130
+ totalCents: booking.sellAmountCents ?? 0,
131
+ taxAmountCents: 0,
132
+ taxRate: null,
133
+ sortOrder: 0,
134
+ },
135
+ ]);
136
+ const lineItems = await resolveInvoiceLineDescriptions(resolvedLineItems, {
137
+ booking,
138
+ paymentSchedule,
139
+ items,
140
+ descriptionResolver: runtime.descriptionResolver,
141
+ });
142
+ const grossLineTotalCents = lineItems.reduce((sum, line) => sum + line.totalCents, 0);
143
+ const includedTaxCents = overrideLineItems
144
+ ? 0
145
+ : taxes.reduce((sum, tax) => {
146
+ if (tax.scope === "withheld" || !tax.includedInPrice)
147
+ return sum;
148
+ return sum + tax.amountCents;
149
+ }, 0);
150
+ const excludedTaxCents = overrideLineItems
151
+ ? overrideLineItems.reduce((sum, line) => sum + line.taxAmountCents, 0)
152
+ : taxes.reduce((sum, tax) => {
153
+ if (tax.scope === "withheld" || tax.includedInPrice)
154
+ return sum;
155
+ return sum + tax.amountCents;
156
+ }, 0);
157
+ const subtotalCents = Math.max(0, grossLineTotalCents - includedTaxCents);
158
+ const taxCents = includedTaxCents + excludedTaxCents;
159
+ const totalCents = subtotalCents + taxCents;
160
+ assertInvoiceFromBookingOverrideTotals(data, { subtotalCents, taxCents, totalCents });
161
+ const commissionAmountCents = overrideLineItems
162
+ ? 0
163
+ : commissions.reduce((sum, commission) => {
164
+ return sum + (commission.amountCents ?? 0);
165
+ }, 0);
166
+ // The `ck_invoices_base_currency_amounts` constraint requires
167
+ // that whenever ANY base_*_cents column is non-null, base_currency
168
+ // must be set too. Resolve the base side once and propagate nulls
169
+ // consistently when no booking/runtime base currency is available.
170
+ const bookingBaseAmountCents = paymentSchedule
171
+ ? resolveBookingInvoiceBaseAmount(booking, invoiceCurrency, paymentSchedule.amountCents)
172
+ : (booking.baseSellAmountCents ?? null);
173
+ const invoiceBaseCurrency = requestedBaseCurrency ?? booking.baseCurrency ?? null;
174
+ const invoiceFxRateSetId = data.fxRateSetId ?? booking.fxRateSetId ?? null;
175
+ const resolvedInvoiceBase = await resolveFxMoneyBaseAmount(db, {
176
+ amountCents: totalCents,
177
+ currency: invoiceCurrency,
178
+ baseCurrency: invoiceBaseCurrency,
179
+ baseAmountCents: hasCrossCurrencyOverride ? null : bookingBaseAmountCents,
180
+ fxRateSetId: invoiceFxRateSetId,
181
+ }, {
182
+ ...runtime,
183
+ targetBaseCurrency: invoiceBaseCurrency,
184
+ fallbackFxRateSetId: invoiceFxRateSetId,
185
+ date: data.issueDate,
186
+ setBaseCurrencyWhenUnresolved: Boolean(invoiceBaseCurrency),
187
+ });
188
+ const resolvedBaseCurrency = resolvedInvoiceBase.baseCurrency ?? null;
189
+ const invoiceBaseAmountCents = resolvedInvoiceBase.baseAmountCents ?? null;
190
+ const hasBaseCurrency = Boolean(resolvedBaseCurrency);
191
+ if (hasCrossCurrencyOverride && invoiceBaseAmountCents === null) {
192
+ throw new InvoiceFromBookingValidationError("Cross-currency invoice overrides require a resolvable base total", {
193
+ currency: invoiceCurrency,
194
+ baseCurrency: requestedBaseCurrency,
195
+ fxRateSetId: invoiceFxRateSetId,
196
+ });
197
+ }
198
+ const numberAssignment = await resolveInvoiceNumberForBooking(db, data);
199
+ try {
200
+ return await db.transaction(async (tx) => {
201
+ const [invoice] = await tx
202
+ .insert(invoices)
203
+ .values({
204
+ invoiceNumber: numberAssignment.invoiceNumber,
205
+ invoiceType: data.invoiceType,
206
+ seriesId: numberAssignment.seriesId,
207
+ sequence: numberAssignment.sequence,
208
+ bookingId: booking.id,
209
+ personId: booking.personId,
210
+ organizationId: booking.organizationId,
211
+ status: numberAssignment.status,
212
+ currency: invoiceCurrency,
213
+ baseCurrency: resolvedBaseCurrency,
214
+ fxRateSetId: resolvedInvoiceBase.fxRateSetId ?? null,
215
+ subtotalCents,
216
+ baseSubtotalCents: hasBaseCurrency ? invoiceBaseAmountCents : null,
217
+ taxCents,
218
+ baseTaxCents: null,
219
+ totalCents,
220
+ baseTotalCents: hasBaseCurrency ? invoiceBaseAmountCents : null,
221
+ paidCents: 0,
222
+ basePaidCents: hasBaseCurrency ? 0 : null,
223
+ balanceDueCents: totalCents,
224
+ baseBalanceDueCents: hasBaseCurrency ? invoiceBaseAmountCents : null,
225
+ commissionAmountCents: commissionAmountCents > 0 ? commissionAmountCents : null,
226
+ issueDate: data.issueDate,
227
+ dueDate: invoiceDueDate,
228
+ notes: data.notes ?? null,
229
+ })
230
+ .returning();
231
+ if (!invoice) {
232
+ return null;
233
+ }
234
+ if (data.externalRefs?.length) {
235
+ await tx
236
+ .insert(invoiceExternalRefs)
237
+ .values(invoiceFromBookingExternalRefValues(invoice.id, data.externalRefs));
238
+ }
239
+ const lineItemValues = lineItems.map((line) => ({
240
+ invoiceId: invoice.id,
241
+ bookingItemId: line.bookingItemId,
242
+ bookingPaymentScheduleId: line.bookingPaymentScheduleId,
243
+ description: line.description,
244
+ quantity: line.quantity,
245
+ unitPriceCents: line.unitPriceCents,
246
+ totalCents: line.totalCents,
247
+ taxRate: line.taxRate,
248
+ sortOrder: line.sortOrder,
249
+ }));
250
+ const insertedLineItems = await tx
251
+ .insert(invoiceLineItems)
252
+ .values(lineItemValues)
253
+ .returning({ id: invoiceLineItems.id });
254
+ if (insertedLineItems.length !== lineItemValues.length) {
255
+ throw new InvoiceLineItemsPersistenceError(invoice.id, lineItemValues.length, insertedLineItems.length);
256
+ }
257
+ return invoice;
258
+ });
259
+ }
260
+ catch (error) {
261
+ if (isInvoiceNumberUniqueConstraintError(error)) {
262
+ throw new InvoiceNumberConflictError(numberAssignment.invoiceNumber);
263
+ }
264
+ throw error;
265
+ }
266
+ },
267
+ };