@dainamite/billing 0.20.0 → 0.22.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 (604) hide show
  1. package/CHANGELOG.md +103 -0
  2. package/dist/modules/billing/acl.js +13 -1
  3. package/dist/modules/billing/acl.js.map +2 -2
  4. package/dist/modules/billing/api/accounts/[id]/summary/route.js +52 -0
  5. package/dist/modules/billing/api/accounts/[id]/summary/route.js.map +7 -0
  6. package/dist/modules/billing/api/accounts/route.js +47 -4
  7. package/dist/modules/billing/api/accounts/route.js.map +2 -2
  8. package/dist/modules/billing/api/export/account/[id]/route.js +11 -7
  9. package/dist/modules/billing/api/export/account/[id]/route.js.map +2 -2
  10. package/dist/modules/billing/api/invoices/[id]/memos/route.js +54 -0
  11. package/dist/modules/billing/api/invoices/[id]/memos/route.js.map +7 -0
  12. package/dist/modules/billing/api/invoices/[id]/pdf/route.js +70 -0
  13. package/dist/modules/billing/api/invoices/[id]/pdf/route.js.map +7 -0
  14. package/dist/modules/billing/api/invoices/[id]/route.js +44 -24
  15. package/dist/modules/billing/api/invoices/[id]/route.js.map +2 -2
  16. package/dist/modules/billing/api/invoices/[id]/send/route.js +107 -0
  17. package/dist/modules/billing/api/invoices/[id]/send/route.js.map +7 -0
  18. package/dist/modules/billing/api/invoices/add-line/route.js +2 -2
  19. package/dist/modules/billing/api/invoices/add-line/route.js.map +2 -2
  20. package/dist/modules/billing/api/invoices/delete-draft/route.js +33 -0
  21. package/dist/modules/billing/api/invoices/delete-draft/route.js.map +7 -0
  22. package/dist/modules/billing/api/invoices/edit-line/route.js +2 -2
  23. package/dist/modules/billing/api/invoices/edit-line/route.js.map +2 -2
  24. package/dist/modules/billing/api/invoices/post/route.js +2 -2
  25. package/dist/modules/billing/api/invoices/post/route.js.map +2 -2
  26. package/dist/modules/billing/api/invoices/remove-line/route.js +2 -2
  27. package/dist/modules/billing/api/invoices/remove-line/route.js.map +2 -2
  28. package/dist/modules/billing/api/invoices/route.js +45 -46
  29. package/dist/modules/billing/api/invoices/route.js.map +2 -2
  30. package/dist/modules/billing/api/items/bulk/route.js +1 -1
  31. package/dist/modules/billing/api/items/bulk/route.js.map +2 -2
  32. package/dist/modules/billing/api/items/change-price/route.js +44 -0
  33. package/dist/modules/billing/api/items/change-price/route.js.map +7 -0
  34. package/dist/modules/billing/api/items/route.js +19 -7
  35. package/dist/modules/billing/api/items/route.js.map +2 -2
  36. package/dist/modules/billing/api/payment-imports/[id]/route.js +49 -0
  37. package/dist/modules/billing/api/payment-imports/[id]/route.js.map +7 -0
  38. package/dist/modules/billing/api/payment-imports/route.js +57 -0
  39. package/dist/modules/billing/api/payment-imports/route.js.map +7 -0
  40. package/dist/modules/billing/api/payments/[id]/route.js +60 -0
  41. package/dist/modules/billing/api/payments/[id]/route.js.map +7 -0
  42. package/dist/modules/billing/api/payments/allocate/route.js +35 -0
  43. package/dist/modules/billing/api/payments/allocate/route.js.map +7 -0
  44. package/dist/modules/billing/api/payments/assign/route.js +36 -0
  45. package/dist/modules/billing/api/payments/assign/route.js.map +7 -0
  46. package/dist/modules/billing/api/payments/convert-to-topup/route.js +35 -0
  47. package/dist/modules/billing/api/payments/convert-to-topup/route.js.map +7 -0
  48. package/dist/modules/billing/api/payments/ignore/route.js +35 -0
  49. package/dist/modules/billing/api/payments/ignore/route.js.map +7 -0
  50. package/dist/modules/billing/api/payments/import/route.js +63 -0
  51. package/dist/modules/billing/api/payments/import/route.js.map +7 -0
  52. package/dist/modules/billing/api/payments/restore/route.js +35 -0
  53. package/dist/modules/billing/api/payments/restore/route.js.map +7 -0
  54. package/dist/modules/billing/api/payments/route.js +114 -0
  55. package/dist/modules/billing/api/payments/route.js.map +7 -0
  56. package/dist/modules/billing/api/payments/unallocate/route.js +35 -0
  57. package/dist/modules/billing/api/payments/unallocate/route.js.map +7 -0
  58. package/dist/modules/billing/api/payments/unassign/route.js +35 -0
  59. package/dist/modules/billing/api/payments/unassign/route.js.map +7 -0
  60. package/dist/modules/billing/api/run-outcomes/route.js +43 -6
  61. package/dist/modules/billing/api/run-outcomes/route.js.map +2 -2
  62. package/dist/modules/billing/api/runs/[id]/post-drafts/route.js +61 -0
  63. package/dist/modules/billing/api/runs/[id]/post-drafts/route.js.map +7 -0
  64. package/dist/modules/billing/api/runs/[id]/route.js +53 -0
  65. package/dist/modules/billing/api/runs/[id]/route.js.map +7 -0
  66. package/dist/modules/billing/api/runs/retry-failed/route.js +1 -1
  67. package/dist/modules/billing/api/runs/retry-failed/route.js.map +2 -2
  68. package/dist/modules/billing/api/runs/route.js +9 -3
  69. package/dist/modules/billing/api/runs/route.js.map +2 -2
  70. package/dist/modules/billing/api/settings/number-preview/route.js +42 -0
  71. package/dist/modules/billing/api/settings/number-preview/route.js.map +7 -0
  72. package/dist/modules/billing/api/settings/route.js +92 -0
  73. package/dist/modules/billing/api/settings/route.js.map +7 -0
  74. package/dist/modules/billing/api/statements/route.js +3 -0
  75. package/dist/modules/billing/api/statements/route.js.map +2 -2
  76. package/dist/modules/billing/api/test-invoices/wipe/route.js +2 -2
  77. package/dist/modules/billing/api/test-invoices/wipe/route.js.map +2 -2
  78. package/dist/modules/billing/backend/billing/accounts/[id]/page.js +121 -232
  79. package/dist/modules/billing/backend/billing/accounts/[id]/page.js.map +2 -2
  80. package/dist/modules/billing/backend/billing/accounts/create/page.js +6 -0
  81. package/dist/modules/billing/backend/billing/accounts/create/page.js.map +2 -2
  82. package/dist/modules/billing/backend/billing/accounts/page.js +63 -4
  83. package/dist/modules/billing/backend/billing/accounts/page.js.map +2 -2
  84. package/dist/modules/billing/backend/billing/invoices/[id]/page.js +297 -65
  85. package/dist/modules/billing/backend/billing/invoices/[id]/page.js.map +3 -3
  86. package/dist/modules/billing/backend/billing/invoices/page.js +6 -172
  87. package/dist/modules/billing/backend/billing/invoices/page.js.map +2 -2
  88. package/dist/modules/billing/backend/billing/items/[id]/page.js +51 -7
  89. package/dist/modules/billing/backend/billing/items/[id]/page.js.map +2 -2
  90. package/dist/modules/billing/backend/billing/items/create/page.js +9 -6
  91. package/dist/modules/billing/backend/billing/items/create/page.js.map +2 -2
  92. package/dist/modules/billing/backend/billing/items/page.js +8 -2
  93. package/dist/modules/billing/backend/billing/items/page.js.map +2 -2
  94. package/dist/modules/billing/backend/billing/payments/[id]/page.js +297 -0
  95. package/dist/modules/billing/backend/billing/payments/[id]/page.js.map +7 -0
  96. package/dist/modules/billing/backend/billing/payments/[id]/page.meta.js +21 -0
  97. package/dist/modules/billing/backend/billing/payments/[id]/page.meta.js.map +7 -0
  98. package/dist/modules/billing/backend/billing/payments/imports/[id]/page.js +74 -0
  99. package/dist/modules/billing/backend/billing/payments/imports/[id]/page.js.map +7 -0
  100. package/dist/modules/billing/backend/billing/payments/imports/[id]/page.meta.js +21 -0
  101. package/dist/modules/billing/backend/billing/payments/imports/[id]/page.meta.js.map +7 -0
  102. package/dist/modules/billing/backend/billing/payments/page.js +58 -0
  103. package/dist/modules/billing/backend/billing/payments/page.js.map +7 -0
  104. package/dist/modules/billing/backend/billing/payments/page.meta.js +18 -0
  105. package/dist/modules/billing/backend/billing/payments/page.meta.js.map +7 -0
  106. package/dist/modules/billing/backend/billing/runs/[id]/page.js +49 -14
  107. package/dist/modules/billing/backend/billing/runs/[id]/page.js.map +2 -2
  108. package/dist/modules/billing/backend/billing/runs/page.js +58 -7
  109. package/dist/modules/billing/backend/billing/runs/page.js.map +2 -2
  110. package/dist/modules/billing/backend/billing/statements/[id]/page.js +61 -6
  111. package/dist/modules/billing/backend/billing/statements/[id]/page.js.map +2 -2
  112. package/dist/modules/billing/backend/billing/statements/page.js +1 -1
  113. package/dist/modules/billing/backend/billing/statements/page.js.map +2 -2
  114. package/dist/modules/billing/backend/billing/topups/page.js +1 -1
  115. package/dist/modules/billing/backend/billing/topups/page.js.map +2 -2
  116. package/dist/modules/billing/backend/billing/transactions/page.js +1 -1
  117. package/dist/modules/billing/backend/billing/transactions/page.js.map +2 -2
  118. package/dist/modules/billing/backend/billing/usage/create/page.js +3 -2
  119. package/dist/modules/billing/backend/billing/usage/create/page.js.map +2 -2
  120. package/dist/modules/billing/backend/config/billing/page.js +472 -0
  121. package/dist/modules/billing/backend/config/billing/page.js.map +7 -0
  122. package/dist/modules/billing/backend/config/billing/page.meta.js +19 -0
  123. package/dist/modules/billing/backend/config/billing/page.meta.js.map +7 -0
  124. package/dist/modules/billing/cli.js +22 -1
  125. package/dist/modules/billing/cli.js.map +2 -2
  126. package/dist/modules/billing/commands/accounts.js +6 -0
  127. package/dist/modules/billing/commands/accounts.js.map +2 -2
  128. package/dist/modules/billing/commands/index.js +3 -0
  129. package/dist/modules/billing/commands/index.js.map +2 -2
  130. package/dist/modules/billing/commands/invoices.js +269 -167
  131. package/dist/modules/billing/commands/invoices.js.map +2 -2
  132. package/dist/modules/billing/commands/items.js +108 -0
  133. package/dist/modules/billing/commands/items.js.map +2 -2
  134. package/dist/modules/billing/commands/memos.js +179 -0
  135. package/dist/modules/billing/commands/memos.js.map +7 -0
  136. package/dist/modules/billing/commands/payments.js +379 -0
  137. package/dist/modules/billing/commands/payments.js.map +7 -0
  138. package/dist/modules/billing/commands/runs.js +151 -4
  139. package/dist/modules/billing/commands/runs.js.map +2 -2
  140. package/dist/modules/billing/commands/settings.js +59 -0
  141. package/dist/modules/billing/commands/settings.js.map +7 -0
  142. package/dist/modules/billing/commands/topups.js +9 -2
  143. package/dist/modules/billing/commands/topups.js.map +2 -2
  144. package/dist/modules/billing/commands/transactions.js +2 -2
  145. package/dist/modules/billing/commands/transactions.js.map +2 -2
  146. package/dist/modules/billing/components/AccountForm.js +149 -42
  147. package/dist/modules/billing/components/AccountForm.js.map +2 -2
  148. package/dist/modules/billing/components/AccountInvoicesSection.js +64 -0
  149. package/dist/modules/billing/components/AccountInvoicesSection.js.map +7 -0
  150. package/dist/modules/billing/components/AccountPaymentsSection.js +43 -0
  151. package/dist/modules/billing/components/AccountPaymentsSection.js.map +7 -0
  152. package/dist/modules/billing/components/AccountPicker.js +56 -0
  153. package/dist/modules/billing/components/AccountPicker.js.map +7 -0
  154. package/dist/modules/billing/components/AllocatePaymentDialog.js +134 -0
  155. package/dist/modules/billing/components/AllocatePaymentDialog.js.map +7 -0
  156. package/dist/modules/billing/components/BillingDataTable.js +21 -0
  157. package/dist/modules/billing/components/BillingDataTable.js.map +7 -0
  158. package/dist/modules/billing/components/BillingSettingsLink.js +19 -0
  159. package/dist/modules/billing/components/BillingSettingsLink.js.map +7 -0
  160. package/dist/modules/billing/components/ChangeItemPriceDialog.js +158 -0
  161. package/dist/modules/billing/components/ChangeItemPriceDialog.js.map +7 -0
  162. package/dist/modules/billing/components/CreateMemoDialog.js +200 -0
  163. package/dist/modules/billing/components/CreateMemoDialog.js.map +7 -0
  164. package/dist/modules/billing/components/CustomerLabel.js +33 -0
  165. package/dist/modules/billing/components/CustomerLabel.js.map +7 -0
  166. package/dist/modules/billing/components/InvoicesTable.js +270 -0
  167. package/dist/modules/billing/components/InvoicesTable.js.map +7 -0
  168. package/dist/modules/billing/components/ItemForm.js +176 -44
  169. package/dist/modules/billing/components/ItemForm.js.map +2 -2
  170. package/dist/modules/billing/components/ItemPriceField.js +46 -0
  171. package/dist/modules/billing/components/ItemPriceField.js.map +7 -0
  172. package/dist/modules/billing/components/LineFormDialog.js +25 -2
  173. package/dist/modules/billing/components/LineFormDialog.js.map +2 -2
  174. package/dist/modules/billing/components/ManualPaymentDialog.js +122 -0
  175. package/dist/modules/billing/components/ManualPaymentDialog.js.map +7 -0
  176. package/dist/modules/billing/components/MoneyInput.js +14 -0
  177. package/dist/modules/billing/components/MoneyInput.js.map +7 -0
  178. package/dist/modules/billing/components/PaymentUploadDialog.js +115 -0
  179. package/dist/modules/billing/components/PaymentUploadDialog.js.map +7 -0
  180. package/dist/modules/billing/components/PaymentsTable.js +171 -0
  181. package/dist/modules/billing/components/PaymentsTable.js.map +7 -0
  182. package/dist/modules/billing/components/PostRunDraftsButton.js +105 -0
  183. package/dist/modules/billing/components/PostRunDraftsButton.js.map +7 -0
  184. package/dist/modules/billing/components/PrepaidPanel.js +14 -4
  185. package/dist/modules/billing/components/PrepaidPanel.js.map +2 -2
  186. package/dist/modules/billing/components/RunCyclesSection.js +209 -0
  187. package/dist/modules/billing/components/RunCyclesSection.js.map +7 -0
  188. package/dist/modules/billing/components/TestRunActions.js +127 -0
  189. package/dist/modules/billing/components/TestRunActions.js.map +7 -0
  190. package/dist/modules/billing/components/account/AccountItemsTab.js +157 -0
  191. package/dist/modules/billing/components/account/AccountItemsTab.js.map +7 -0
  192. package/dist/modules/billing/components/account/AccountRunBillingDialog.js +122 -0
  193. package/dist/modules/billing/components/account/AccountRunBillingDialog.js.map +7 -0
  194. package/dist/modules/billing/components/account/AccountRunsTab.js +152 -0
  195. package/dist/modules/billing/components/account/AccountRunsTab.js.map +7 -0
  196. package/dist/modules/billing/components/account/AccountStatementsTab.js +98 -0
  197. package/dist/modules/billing/components/account/AccountStatementsTab.js.map +7 -0
  198. package/dist/modules/billing/components/account/AccountSummaryCards.js +125 -0
  199. package/dist/modules/billing/components/account/AccountSummaryCards.js.map +7 -0
  200. package/dist/modules/billing/components/account/AccountUsageTab.js +91 -0
  201. package/dist/modules/billing/components/account/AccountUsageTab.js.map +7 -0
  202. package/dist/modules/billing/components/account/AccountView.js +73 -0
  203. package/dist/modules/billing/components/account/AccountView.js.map +7 -0
  204. package/dist/modules/billing/components/account/accountRow.js +39 -0
  205. package/dist/modules/billing/components/account/accountRow.js.map +7 -0
  206. package/dist/modules/billing/components/customerNames.js +42 -0
  207. package/dist/modules/billing/components/customerNames.js.map +7 -0
  208. package/dist/modules/billing/data/entities.js +560 -4
  209. package/dist/modules/billing/data/entities.js.map +2 -2
  210. package/dist/modules/billing/data/entityIds.js +10 -1
  211. package/dist/modules/billing/data/entityIds.js.map +2 -2
  212. package/dist/modules/billing/data/validators.js +269 -15
  213. package/dist/modules/billing/data/validators.js.map +2 -2
  214. package/dist/modules/billing/events.js +50 -0
  215. package/dist/modules/billing/events.js.map +2 -2
  216. package/dist/modules/billing/i18n/de.json +880 -0
  217. package/dist/modules/billing/i18n/en.json +457 -21
  218. package/dist/modules/billing/i18n/es.json +880 -0
  219. package/dist/modules/billing/i18n/pl.json +458 -22
  220. package/dist/modules/billing/index.js +6 -2
  221. package/dist/modules/billing/index.js.map +2 -2
  222. package/dist/modules/billing/lib/accountFinancials.js +58 -0
  223. package/dist/modules/billing/lib/accountFinancials.js.map +7 -0
  224. package/dist/modules/billing/lib/accountLock.js +14 -0
  225. package/dist/modules/billing/lib/accountLock.js.map +7 -0
  226. package/dist/modules/billing/lib/accountStatus.js +9 -7
  227. package/dist/modules/billing/lib/accountStatus.js.map +2 -2
  228. package/dist/modules/billing/lib/accountSummary.js +106 -0
  229. package/dist/modules/billing/lib/accountSummary.js.map +7 -0
  230. package/dist/modules/billing/lib/allocation.js +356 -0
  231. package/dist/modules/billing/lib/allocation.js.map +7 -0
  232. package/dist/modules/billing/lib/allocationEvents.js +22 -0
  233. package/dist/modules/billing/lib/allocationEvents.js.map +7 -0
  234. package/dist/modules/billing/lib/billPeriod.js +15 -1
  235. package/dist/modules/billing/lib/billPeriod.js.map +2 -2
  236. package/dist/modules/billing/lib/billRunEngine.js +237 -102
  237. package/dist/modules/billing/lib/billRunEngine.js.map +2 -2
  238. package/dist/modules/billing/lib/billingSettings.js +116 -0
  239. package/dist/modules/billing/lib/billingSettings.js.map +7 -0
  240. package/dist/modules/billing/lib/commandRoute.js +81 -0
  241. package/dist/modules/billing/lib/commandRoute.js.map +7 -0
  242. package/dist/modules/billing/lib/customerLookup.js +97 -0
  243. package/dist/modules/billing/lib/customerLookup.js.map +7 -0
  244. package/dist/modules/billing/lib/dateOnly.js +13 -0
  245. package/dist/modules/billing/lib/dateOnly.js.map +7 -0
  246. package/dist/modules/billing/lib/documentParties.js +16 -0
  247. package/dist/modules/billing/lib/documentParties.js.map +7 -0
  248. package/dist/modules/billing/lib/documentTypes.js +27 -0
  249. package/dist/modules/billing/lib/documentTypes.js.map +7 -0
  250. package/dist/modules/billing/lib/dueDate.js +18 -0
  251. package/dist/modules/billing/lib/dueDate.js.map +7 -0
  252. package/dist/modules/billing/lib/iban.js +29 -0
  253. package/dist/modules/billing/lib/iban.js.map +7 -0
  254. package/dist/modules/billing/lib/invoiceDelivery.js +133 -0
  255. package/dist/modules/billing/lib/invoiceDelivery.js.map +7 -0
  256. package/dist/modules/billing/lib/invoiceLanguages.js +28 -0
  257. package/dist/modules/billing/lib/invoiceLanguages.js.map +7 -0
  258. package/dist/modules/billing/lib/invoiceWriter.js +107 -99
  259. package/dist/modules/billing/lib/invoiceWriter.js.map +2 -2
  260. package/dist/modules/billing/lib/itemBillingState.js +27 -0
  261. package/dist/modules/billing/lib/itemBillingState.js.map +7 -0
  262. package/dist/modules/billing/lib/itemPriceChange.js +18 -0
  263. package/dist/modules/billing/lib/itemPriceChange.js.map +7 -0
  264. package/dist/modules/billing/lib/itemSelector.js.map +2 -2
  265. package/dist/modules/billing/lib/lineAmounts.js +32 -0
  266. package/dist/modules/billing/lib/lineAmounts.js.map +7 -0
  267. package/dist/modules/billing/lib/memoGuards.js +25 -0
  268. package/dist/modules/billing/lib/memoGuards.js.map +7 -0
  269. package/dist/modules/billing/lib/navigation.js +48 -0
  270. package/dist/modules/billing/lib/navigation.js.map +7 -0
  271. package/dist/modules/billing/lib/numbering.js +120 -0
  272. package/dist/modules/billing/lib/numbering.js.map +7 -0
  273. package/dist/modules/billing/lib/overdue.js +36 -0
  274. package/dist/modules/billing/lib/overdue.js.map +7 -0
  275. package/dist/modules/billing/lib/paymentCsv.js +125 -0
  276. package/dist/modules/billing/lib/paymentCsv.js.map +7 -0
  277. package/dist/modules/billing/lib/paymentGateway.js +15 -0
  278. package/dist/modules/billing/lib/paymentGateway.js.map +7 -0
  279. package/dist/modules/billing/lib/paymentImport.js +164 -0
  280. package/dist/modules/billing/lib/paymentImport.js.map +7 -0
  281. package/dist/modules/billing/lib/paymentMatcher.js +36 -0
  282. package/dist/modules/billing/lib/paymentMatcher.js.map +7 -0
  283. package/dist/modules/billing/lib/pdf/attachmentStore.js +46 -0
  284. package/dist/modules/billing/lib/pdf/attachmentStore.js.map +7 -0
  285. package/dist/modules/billing/lib/pdf/fonts/embeddedFonts.js +7 -0
  286. package/dist/modules/billing/lib/pdf/fonts/embeddedFonts.js.map +7 -0
  287. package/dist/modules/billing/lib/pdf/invoiceModel.js +194 -0
  288. package/dist/modules/billing/lib/pdf/invoiceModel.js.map +7 -0
  289. package/dist/modules/billing/lib/pdf/invoicePdf.js +165 -0
  290. package/dist/modules/billing/lib/pdf/invoicePdf.js.map +7 -0
  291. package/dist/modules/billing/lib/pdf/invoiceTemplate.js +276 -0
  292. package/dist/modules/billing/lib/pdf/invoiceTemplate.js.map +7 -0
  293. package/dist/modules/billing/lib/prepaidConfig.js +17 -25
  294. package/dist/modules/billing/lib/prepaidConfig.js.map +2 -2
  295. package/dist/modules/billing/lib/prepaidConsume.js +26 -7
  296. package/dist/modules/billing/lib/prepaidConsume.js.map +2 -2
  297. package/dist/modules/billing/lib/prepaidPeriodClose.js +277 -158
  298. package/dist/modules/billing/lib/prepaidPeriodClose.js.map +2 -2
  299. package/dist/modules/billing/lib/prepaidTaxPoint.js +37 -0
  300. package/dist/modules/billing/lib/prepaidTaxPoint.js.map +7 -0
  301. package/dist/modules/billing/lib/seeds/demo.js +51 -3
  302. package/dist/modules/billing/lib/seeds/demo.js.map +2 -2
  303. package/dist/modules/billing/lib/seeds/paymentsSample.js +93 -0
  304. package/dist/modules/billing/lib/seeds/paymentsSample.js.map +7 -0
  305. package/dist/modules/billing/lib/seeds/sellerSettings.js +41 -0
  306. package/dist/modules/billing/lib/seeds/sellerSettings.js.map +7 -0
  307. package/dist/modules/billing/lib/servicePeriods.js +121 -0
  308. package/dist/modules/billing/lib/servicePeriods.js.map +7 -0
  309. package/dist/modules/billing/lib/testRunCleanup.js +24 -0
  310. package/dist/modules/billing/lib/testRunCleanup.js.map +7 -0
  311. package/dist/modules/billing/lib/topupCapture.js +2 -2
  312. package/dist/modules/billing/lib/topupCapture.js.map +2 -2
  313. package/dist/modules/billing/lib/topupReceipt.js +58 -79
  314. package/dist/modules/billing/lib/topupReceipt.js.map +2 -2
  315. package/dist/modules/billing/lib/usageRater.js.map +1 -1
  316. package/dist/modules/billing/lib/usageRunner.js +14 -6
  317. package/dist/modules/billing/lib/usageRunner.js.map +2 -2
  318. package/dist/modules/billing/lib/vat.js +39 -0
  319. package/dist/modules/billing/lib/vat.js.map +7 -0
  320. package/dist/modules/billing/migrations/Migration20261114000000_billing_customer_kind.js +15 -0
  321. package/dist/modules/billing/migrations/Migration20261114000000_billing_customer_kind.js.map +7 -0
  322. package/dist/modules/billing/migrations/Migration20261114100000_billing_cycle_semantics.js +25 -0
  323. package/dist/modules/billing/migrations/Migration20261114100000_billing_cycle_semantics.js.map +7 -0
  324. package/dist/modules/billing/migrations/Migration20261115000000_billing_invoice_ledger.js +115 -0
  325. package/dist/modules/billing/migrations/Migration20261115000000_billing_invoice_ledger.js.map +7 -0
  326. package/dist/modules/billing/migrations/Migration20261116000000_billing_invoice_documents.js +47 -0
  327. package/dist/modules/billing/migrations/Migration20261116000000_billing_invoice_documents.js.map +7 -0
  328. package/dist/modules/billing/migrations/Migration20261117000000_billing_payments.js +89 -0
  329. package/dist/modules/billing/migrations/Migration20261117000000_billing_payments.js.map +7 -0
  330. package/dist/modules/billing/migrations/Migration20261118000000_billing_memos.js +17 -0
  331. package/dist/modules/billing/migrations/Migration20261118000000_billing_memos.js.map +7 -0
  332. package/dist/modules/billing/migrations/Migration20261119000000_billing_operator_feedback.js +27 -0
  333. package/dist/modules/billing/migrations/Migration20261119000000_billing_operator_feedback.js.map +7 -0
  334. package/dist/modules/billing/migrations/Migration20261120000000_billing_allocation_scope_indexes.js +29 -0
  335. package/dist/modules/billing/migrations/Migration20261120000000_billing_allocation_scope_indexes.js.map +7 -0
  336. package/dist/modules/billing/setup.js +7 -184
  337. package/dist/modules/billing/setup.js.map +2 -2
  338. package/dist/modules/billing/subscribers/credit-memo-auto-send.js +16 -0
  339. package/dist/modules/billing/subscribers/credit-memo-auto-send.js.map +7 -0
  340. package/dist/modules/billing/subscribers/debit-memo-apply-credit.js +16 -0
  341. package/dist/modules/billing/subscribers/debit-memo-apply-credit.js.map +7 -0
  342. package/dist/modules/billing/subscribers/debit-memo-auto-send.js +16 -0
  343. package/dist/modules/billing/subscribers/debit-memo-auto-send.js.map +7 -0
  344. package/dist/modules/billing/subscribers/invoice-apply-credit.js +34 -0
  345. package/dist/modules/billing/subscribers/invoice-apply-credit.js.map +7 -0
  346. package/dist/modules/billing/subscribers/invoice-auto-send.js +30 -0
  347. package/dist/modules/billing/subscribers/invoice-auto-send.js.map +7 -0
  348. package/dist/modules/billing/subscribers/payment-captured-to-paid.js +69 -33
  349. package/dist/modules/billing/subscribers/payment-captured-to-paid.js.map +2 -2
  350. package/dist/modules/billing/subscribers/prepaid-topup-captured.js +4 -6
  351. package/dist/modules/billing/subscribers/prepaid-topup-captured.js.map +2 -2
  352. package/generated/entities/billing_account/index.ts +3 -0
  353. package/generated/entities/billing_allocation/index.ts +18 -0
  354. package/generated/entities/billing_document_sequence/index.ts +11 -0
  355. package/generated/entities/billing_invoice/index.ts +38 -0
  356. package/generated/entities/billing_invoice_line/index.ts +24 -0
  357. package/generated/entities/billing_item/index.ts +4 -0
  358. package/generated/entities/billing_payment/index.ts +25 -0
  359. package/generated/entities/billing_payment_import/index.ts +14 -0
  360. package/generated/entities/billing_run/index.ts +0 -1
  361. package/generated/entities/billing_run_outcome/index.ts +1 -0
  362. package/generated/entities/billing_settings/index.ts +26 -0
  363. package/generated/entities/billing_statement/index.ts +1 -0
  364. package/generated/entities.ids.generated.ts +7 -0
  365. package/package.json +5 -1
  366. package/src/modules/billing/__integration__/TC-BILL-004.spec.ts +171 -0
  367. package/src/modules/billing/__integration__/TC-BILL-005.spec.ts +134 -0
  368. package/src/modules/billing/__integration__/TC-BILL-006.spec.ts +101 -0
  369. package/src/modules/billing/__integration__/TC-BILL-007.spec.ts +140 -0
  370. package/src/modules/billing/__integration__/TC-BILL-008.spec.ts +108 -0
  371. package/src/modules/billing/__integration__/TC-BILL-009.spec.ts +113 -0
  372. package/src/modules/billing/__integration__/TC-BILL-010.spec.ts +118 -0
  373. package/src/modules/billing/__integration__/TC-BILL-011.spec.ts +142 -0
  374. package/src/modules/billing/__integration__/TC-BILL-012.spec.ts +115 -0
  375. package/src/modules/billing/__integration__/TC-BILL-013.spec.ts +118 -0
  376. package/src/modules/billing/__integration__/sellerSettings.ts +24 -0
  377. package/src/modules/billing/__tests__/commands/invoices.test.ts +436 -354
  378. package/src/modules/billing/__tests__/commands/itemsBulk.test.ts +33 -0
  379. package/src/modules/billing/__tests__/commands/memos.test.ts +205 -0
  380. package/src/modules/billing/__tests__/commands/payments.test.ts +241 -0
  381. package/src/modules/billing/__tests__/commands/runsDelete.test.ts +146 -0
  382. package/src/modules/billing/__tests__/commands/runsPostDrafts.test.ts +106 -0
  383. package/src/modules/billing/__tests__/commands/topups.test.ts +11 -0
  384. package/src/modules/billing/__tests__/entityRegistry.test.ts +8 -1
  385. package/src/modules/billing/__tests__/helpers/prepaidMockEm.ts +28 -11
  386. package/src/modules/billing/__tests__/i18n/dictionaries.test.ts +64 -0
  387. package/src/modules/billing/__tests__/lib/accountFinancials.test.ts +53 -0
  388. package/src/modules/billing/__tests__/lib/accountSummary.test.ts +97 -0
  389. package/src/modules/billing/__tests__/lib/allocation.test.ts +319 -0
  390. package/src/modules/billing/__tests__/lib/billRunEngine.test.ts +228 -17
  391. package/src/modules/billing/__tests__/lib/billingSettings.test.ts +109 -0
  392. package/src/modules/billing/__tests__/lib/customerLookup.test.ts +156 -0
  393. package/src/modules/billing/__tests__/lib/dueDate.test.ts +35 -0
  394. package/src/modules/billing/__tests__/lib/iban.test.ts +38 -0
  395. package/src/modules/billing/__tests__/lib/invoiceDelivery.test.ts +206 -0
  396. package/src/modules/billing/__tests__/lib/invoiceLanguages.test.ts +49 -0
  397. package/src/modules/billing/__tests__/lib/invoiceWriter.test.ts +212 -10
  398. package/src/modules/billing/__tests__/lib/itemBillingState.test.ts +42 -0
  399. package/src/modules/billing/__tests__/lib/itemPriceChange.test.ts +165 -0
  400. package/src/modules/billing/__tests__/lib/lineAmounts.test.ts +86 -0
  401. package/src/modules/billing/__tests__/lib/navigation.test.ts +71 -0
  402. package/src/modules/billing/__tests__/lib/numbering.test.ts +91 -0
  403. package/src/modules/billing/__tests__/lib/overdue.test.ts +36 -0
  404. package/src/modules/billing/__tests__/lib/paymentCsv.test.ts +148 -0
  405. package/src/modules/billing/__tests__/lib/paymentImport.test.ts +113 -0
  406. package/src/modules/billing/__tests__/lib/paymentsSample.test.ts +73 -0
  407. package/src/modules/billing/__tests__/lib/pdf/invoicePdf.test.ts +269 -0
  408. package/src/modules/billing/__tests__/lib/pdf/invoicePdfService.test.ts +147 -0
  409. package/src/modules/billing/__tests__/lib/prepaidPeriodClose.test.ts +374 -98
  410. package/src/modules/billing/__tests__/lib/prepaidTaxPoint.test.ts +118 -0
  411. package/src/modules/billing/__tests__/lib/seedsDemo.test.ts +53 -2
  412. package/src/modules/billing/__tests__/lib/sellerSettings.test.ts +28 -0
  413. package/src/modules/billing/__tests__/lib/servicePeriods.test.ts +190 -0
  414. package/src/modules/billing/__tests__/lib/topupCapture.test.ts +6 -28
  415. package/src/modules/billing/__tests__/lib/topupReceipt.test.ts +21 -52
  416. package/src/modules/billing/__tests__/lib/vat.test.ts +51 -0
  417. package/src/modules/billing/__tests__/package-isolation.test.ts +22 -8
  418. package/src/modules/billing/__tests__/setup.test.ts +13 -4
  419. package/src/modules/billing/__tests__/validators.test.ts +197 -3
  420. package/src/modules/billing/acl.ts +12 -0
  421. package/src/modules/billing/api/accounts/[id]/summary/route.ts +62 -0
  422. package/src/modules/billing/api/accounts/route.ts +59 -4
  423. package/src/modules/billing/api/export/account/[id]/route.ts +13 -11
  424. package/src/modules/billing/api/invoices/[id]/memos/route.ts +63 -0
  425. package/src/modules/billing/api/invoices/[id]/pdf/route.ts +80 -0
  426. package/src/modules/billing/api/invoices/[id]/route.ts +57 -70
  427. package/src/modules/billing/api/invoices/[id]/send/route.ts +127 -0
  428. package/src/modules/billing/api/invoices/add-line/route.ts +2 -2
  429. package/src/modules/billing/api/invoices/delete-draft/route.ts +33 -0
  430. package/src/modules/billing/api/invoices/edit-line/route.ts +2 -2
  431. package/src/modules/billing/api/invoices/post/route.ts +7 -6
  432. package/src/modules/billing/api/invoices/remove-line/route.ts +2 -2
  433. package/src/modules/billing/api/invoices/route.ts +81 -86
  434. package/src/modules/billing/api/items/bulk/route.ts +2 -1
  435. package/src/modules/billing/api/items/change-price/route.ts +54 -0
  436. package/src/modules/billing/api/items/route.ts +23 -7
  437. package/src/modules/billing/api/payment-imports/[id]/route.ts +49 -0
  438. package/src/modules/billing/api/payment-imports/route.ts +57 -0
  439. package/src/modules/billing/api/payments/[id]/route.ts +63 -0
  440. package/src/modules/billing/api/payments/allocate/route.ts +35 -0
  441. package/src/modules/billing/api/payments/assign/route.ts +36 -0
  442. package/src/modules/billing/api/payments/convert-to-topup/route.ts +35 -0
  443. package/src/modules/billing/api/payments/ignore/route.ts +35 -0
  444. package/src/modules/billing/api/payments/import/route.ts +72 -0
  445. package/src/modules/billing/api/payments/restore/route.ts +35 -0
  446. package/src/modules/billing/api/payments/route.ts +147 -0
  447. package/src/modules/billing/api/payments/unallocate/route.ts +35 -0
  448. package/src/modules/billing/api/payments/unassign/route.ts +35 -0
  449. package/src/modules/billing/api/run-outcomes/route.ts +49 -6
  450. package/src/modules/billing/api/runs/[id]/post-drafts/route.ts +71 -0
  451. package/src/modules/billing/api/runs/[id]/route.ts +59 -0
  452. package/src/modules/billing/api/runs/retry-failed/route.ts +2 -1
  453. package/src/modules/billing/api/runs/route.ts +15 -7
  454. package/src/modules/billing/api/settings/number-preview/route.ts +46 -0
  455. package/src/modules/billing/api/settings/route.ts +116 -0
  456. package/src/modules/billing/api/statements/route.ts +5 -0
  457. package/src/modules/billing/api/test-invoices/wipe/route.ts +2 -2
  458. package/src/modules/billing/backend/billing/accounts/[id]/page.tsx +151 -372
  459. package/src/modules/billing/backend/billing/accounts/create/page.tsx +6 -0
  460. package/src/modules/billing/backend/billing/accounts/page.tsx +70 -4
  461. package/src/modules/billing/backend/billing/invoices/[id]/page.tsx +444 -95
  462. package/src/modules/billing/backend/billing/invoices/page.tsx +8 -227
  463. package/src/modules/billing/backend/billing/items/[id]/page.tsx +75 -6
  464. package/src/modules/billing/backend/billing/items/create/page.tsx +13 -8
  465. package/src/modules/billing/backend/billing/items/page.tsx +18 -2
  466. package/src/modules/billing/backend/billing/payments/[id]/page.meta.ts +19 -0
  467. package/src/modules/billing/backend/billing/payments/[id]/page.tsx +415 -0
  468. package/src/modules/billing/backend/billing/payments/imports/[id]/page.meta.ts +19 -0
  469. package/src/modules/billing/backend/billing/payments/imports/[id]/page.tsx +106 -0
  470. package/src/modules/billing/backend/billing/payments/page.meta.ts +16 -0
  471. package/src/modules/billing/backend/billing/payments/page.tsx +56 -0
  472. package/src/modules/billing/backend/billing/runs/[id]/page.tsx +49 -18
  473. package/src/modules/billing/backend/billing/runs/page.tsx +59 -8
  474. package/src/modules/billing/backend/billing/statements/[id]/page.tsx +86 -5
  475. package/src/modules/billing/backend/billing/statements/page.tsx +1 -1
  476. package/src/modules/billing/backend/billing/topups/page.tsx +1 -1
  477. package/src/modules/billing/backend/billing/transactions/page.tsx +1 -1
  478. package/src/modules/billing/backend/billing/usage/create/page.tsx +3 -2
  479. package/src/modules/billing/backend/config/billing/page.meta.ts +21 -0
  480. package/src/modules/billing/backend/config/billing/page.tsx +549 -0
  481. package/src/modules/billing/cli.ts +31 -1
  482. package/src/modules/billing/commands/accounts.ts +6 -0
  483. package/src/modules/billing/commands/index.ts +3 -0
  484. package/src/modules/billing/commands/invoices.ts +364 -231
  485. package/src/modules/billing/commands/items.ts +143 -0
  486. package/src/modules/billing/commands/memos.ts +218 -0
  487. package/src/modules/billing/commands/payments.ts +428 -0
  488. package/src/modules/billing/commands/runs.ts +205 -3
  489. package/src/modules/billing/commands/settings.ts +77 -0
  490. package/src/modules/billing/commands/topups.ts +12 -3
  491. package/src/modules/billing/commands/transactions.ts +2 -2
  492. package/src/modules/billing/components/AccountForm.tsx +199 -53
  493. package/src/modules/billing/components/AccountInvoicesSection.tsx +75 -0
  494. package/src/modules/billing/components/AccountPaymentsSection.tsx +42 -0
  495. package/src/modules/billing/components/AccountPicker.tsx +70 -0
  496. package/src/modules/billing/components/AllocatePaymentDialog.tsx +167 -0
  497. package/src/modules/billing/components/BillingDataTable.tsx +34 -0
  498. package/src/modules/billing/components/BillingSettingsLink.tsx +25 -0
  499. package/src/modules/billing/components/ChangeItemPriceDialog.tsx +180 -0
  500. package/src/modules/billing/components/CreateMemoDialog.tsx +232 -0
  501. package/src/modules/billing/components/CustomerLabel.tsx +53 -0
  502. package/src/modules/billing/components/InvoicesTable.tsx +344 -0
  503. package/src/modules/billing/components/ItemForm.tsx +233 -44
  504. package/src/modules/billing/components/ItemPriceField.tsx +81 -0
  505. package/src/modules/billing/components/LineFormDialog.tsx +25 -1
  506. package/src/modules/billing/components/ManualPaymentDialog.tsx +140 -0
  507. package/src/modules/billing/components/MoneyInput.tsx +26 -0
  508. package/src/modules/billing/components/PaymentUploadDialog.tsx +148 -0
  509. package/src/modules/billing/components/PaymentsTable.tsx +213 -0
  510. package/src/modules/billing/components/PostRunDraftsButton.tsx +129 -0
  511. package/src/modules/billing/components/PrepaidPanel.tsx +19 -6
  512. package/src/modules/billing/components/RunCyclesSection.tsx +298 -0
  513. package/src/modules/billing/components/TestRunActions.tsx +152 -0
  514. package/src/modules/billing/components/account/AccountItemsTab.tsx +192 -0
  515. package/src/modules/billing/components/account/AccountRunBillingDialog.tsx +147 -0
  516. package/src/modules/billing/components/account/AccountRunsTab.tsx +201 -0
  517. package/src/modules/billing/components/account/AccountStatementsTab.tsx +120 -0
  518. package/src/modules/billing/components/account/AccountSummaryCards.tsx +153 -0
  519. package/src/modules/billing/components/account/AccountUsageTab.tsx +122 -0
  520. package/src/modules/billing/components/account/AccountView.tsx +101 -0
  521. package/src/modules/billing/components/account/accountRow.ts +70 -0
  522. package/src/modules/billing/components/customerNames.ts +62 -0
  523. package/src/modules/billing/data/entities.ts +656 -6
  524. package/src/modules/billing/data/entityIds.ts +9 -0
  525. package/src/modules/billing/data/validators.ts +388 -8
  526. package/src/modules/billing/events.ts +56 -3
  527. package/src/modules/billing/i18n/de.json +880 -0
  528. package/src/modules/billing/i18n/en.json +457 -21
  529. package/src/modules/billing/i18n/es.json +880 -0
  530. package/src/modules/billing/i18n/pl.json +458 -22
  531. package/src/modules/billing/index.ts +6 -2
  532. package/src/modules/billing/lib/accountFinancials.ts +84 -0
  533. package/src/modules/billing/lib/accountLock.ts +32 -0
  534. package/src/modules/billing/lib/accountStatus.ts +11 -9
  535. package/src/modules/billing/lib/accountSummary.ts +172 -0
  536. package/src/modules/billing/lib/allocation.ts +515 -0
  537. package/src/modules/billing/lib/allocationEvents.ts +26 -0
  538. package/src/modules/billing/lib/billPeriod.ts +19 -0
  539. package/src/modules/billing/lib/billRunEngine.ts +350 -150
  540. package/src/modules/billing/lib/billingSettings.ts +145 -0
  541. package/src/modules/billing/lib/commandRoute.ts +112 -0
  542. package/src/modules/billing/lib/customerLookup.ts +157 -0
  543. package/src/modules/billing/lib/dateOnly.ts +22 -0
  544. package/src/modules/billing/lib/documentParties.ts +23 -0
  545. package/src/modules/billing/lib/documentTypes.ts +37 -0
  546. package/src/modules/billing/lib/dueDate.ts +26 -0
  547. package/src/modules/billing/lib/iban.ts +36 -0
  548. package/src/modules/billing/lib/invoiceDelivery.ts +196 -0
  549. package/src/modules/billing/lib/invoiceLanguages.ts +57 -0
  550. package/src/modules/billing/lib/invoiceWriter.ts +162 -148
  551. package/src/modules/billing/lib/itemBillingState.ts +67 -0
  552. package/src/modules/billing/lib/itemPriceChange.ts +56 -0
  553. package/src/modules/billing/lib/itemSelector.ts +4 -1
  554. package/src/modules/billing/lib/lineAmounts.ts +61 -0
  555. package/src/modules/billing/lib/memoGuards.ts +41 -0
  556. package/src/modules/billing/lib/navigation.ts +64 -0
  557. package/src/modules/billing/lib/numbering.ts +174 -0
  558. package/src/modules/billing/lib/overdue.ts +60 -0
  559. package/src/modules/billing/lib/paymentCsv.ts +171 -0
  560. package/src/modules/billing/lib/paymentGateway.ts +52 -0
  561. package/src/modules/billing/lib/paymentImport.ts +228 -0
  562. package/src/modules/billing/lib/paymentMatcher.ts +88 -0
  563. package/src/modules/billing/lib/pdf/attachmentStore.ts +60 -0
  564. package/src/modules/billing/lib/pdf/fonts/NotoSans-Bold.ttf +0 -0
  565. package/src/modules/billing/lib/pdf/fonts/NotoSans-Regular.ttf +0 -0
  566. package/src/modules/billing/lib/pdf/fonts/OFL.txt +93 -0
  567. package/src/modules/billing/lib/pdf/fonts/embeddedFonts.ts +9 -0
  568. package/src/modules/billing/lib/pdf/invoiceModel.ts +329 -0
  569. package/src/modules/billing/lib/pdf/invoicePdf.ts +220 -0
  570. package/src/modules/billing/lib/pdf/invoiceTemplate.ts +338 -0
  571. package/src/modules/billing/lib/prepaidConfig.ts +27 -36
  572. package/src/modules/billing/lib/prepaidConsume.ts +29 -6
  573. package/src/modules/billing/lib/prepaidPeriodClose.ts +407 -239
  574. package/src/modules/billing/lib/prepaidTaxPoint.ts +76 -0
  575. package/src/modules/billing/lib/seeds/demo.ts +79 -6
  576. package/src/modules/billing/lib/seeds/paymentsSample.ts +136 -0
  577. package/src/modules/billing/lib/seeds/sellerSettings.ts +78 -0
  578. package/src/modules/billing/lib/servicePeriods.ts +226 -0
  579. package/src/modules/billing/lib/testRunCleanup.ts +42 -0
  580. package/src/modules/billing/lib/topupCapture.ts +3 -4
  581. package/src/modules/billing/lib/topupReceipt.ts +70 -103
  582. package/src/modules/billing/lib/usageRater.ts +1 -1
  583. package/src/modules/billing/lib/usageRunner.ts +17 -5
  584. package/src/modules/billing/lib/vat.ts +56 -0
  585. package/src/modules/billing/migrations/Migration20261114000000_billing_customer_kind.ts +25 -0
  586. package/src/modules/billing/migrations/Migration20261114100000_billing_cycle_semantics.ts +37 -0
  587. package/src/modules/billing/migrations/Migration20261115000000_billing_invoice_ledger.ts +132 -0
  588. package/src/modules/billing/migrations/Migration20261116000000_billing_invoice_documents.ts +58 -0
  589. package/src/modules/billing/migrations/Migration20261117000000_billing_payments.ts +97 -0
  590. package/src/modules/billing/migrations/Migration20261118000000_billing_memos.ts +21 -0
  591. package/src/modules/billing/migrations/Migration20261119000000_billing_operator_feedback.ts +39 -0
  592. package/src/modules/billing/migrations/Migration20261120000000_billing_allocation_scope_indexes.ts +35 -0
  593. package/src/modules/billing/setup.ts +11 -237
  594. package/src/modules/billing/subscribers/credit-memo-auto-send.ts +15 -0
  595. package/src/modules/billing/subscribers/debit-memo-apply-credit.ts +15 -0
  596. package/src/modules/billing/subscribers/debit-memo-auto-send.ts +15 -0
  597. package/src/modules/billing/subscribers/invoice-apply-credit.ts +39 -0
  598. package/src/modules/billing/subscribers/invoice-auto-send.ts +46 -0
  599. package/src/modules/billing/subscribers/payment-captured-to-paid.ts +84 -62
  600. package/src/modules/billing/subscribers/prepaid-topup-captured.ts +4 -8
  601. package/dist/modules/billing/lib/invoiceStatus.js +0 -38
  602. package/dist/modules/billing/lib/invoiceStatus.js.map +0 -7
  603. package/src/modules/billing/__tests__/lib/invoiceStatus.test.ts +0 -97
  604. package/src/modules/billing/lib/invoiceStatus.ts +0 -61
@@ -0,0 +1,46 @@
1
+ import type { EntityManager } from '@mikro-orm/postgresql'
2
+ import { createRequestContainer } from '@open-mercato/shared/lib/di/container'
3
+ import { BillingAccount, BillingInvoice } from '../data/entities'
4
+ import { hasSuccessfulDelivery, isDeliverableEmail, sendInvoice, type SendInvoiceDeps } from '../lib/invoiceDelivery'
5
+
6
+ /**
7
+ * Auto-send (Spec B): `billing.invoice.posted` → email the document when the
8
+ * account has `auto_send_invoice` on.
9
+ *
10
+ * Persistent and idempotent: a redelivered event finds a `sent` auto
11
+ * delivery in `metadata.deliveries` and does nothing. Receipts, test
12
+ * documents and accounts with a placeholder / missing email are skipped
13
+ * without a delivery entry (the operator can still send manually once the
14
+ * address is fixed). A transport failure is recorded as a `failed`
15
+ * delivery by `sendInvoice` and not retried automatically.
16
+ */
17
+
18
+ export const metadata = {
19
+ event: 'billing.invoice.posted',
20
+ persistent: true,
21
+ id: 'billing-invoice-auto-send',
22
+ }
23
+
24
+ type PostedPayload = {
25
+ invoiceId?: string
26
+ tenantId?: string
27
+ organizationId?: string
28
+ }
29
+
30
+ export async function autoSendInvoice(em: EntityManager, payload: PostedPayload, deps: SendInvoiceDeps = {}): Promise<'sent' | 'failed' | 'skipped'> {
31
+ if (!payload?.invoiceId || !payload.tenantId || !payload.organizationId) return 'skipped'
32
+ const scope = { tenantId: payload.tenantId, organizationId: payload.organizationId }
33
+ const invoice = await em.findOne(BillingInvoice, { id: payload.invoiceId, ...scope, deletedAt: null } as never)
34
+ if (!invoice || invoice.testRun || invoice.status === 'draft' || invoice.documentType === 'receipt') return 'skipped'
35
+ if (hasSuccessfulDelivery(invoice, 'auto')) return 'skipped'
36
+ const account = await em.findOne(BillingAccount, { id: invoice.billAccountId, ...scope } as never)
37
+ if (!account?.autoSendInvoice || !isDeliverableEmail(account.invoiceEmail)) return 'skipped'
38
+ const result = await sendInvoice(em, { invoiceId: invoice.id, ...scope, trigger: 'auto' }, deps)
39
+ return result.status
40
+ }
41
+
42
+ export default async function handle(payload: PostedPayload): Promise<void> {
43
+ const container = await createRequestContainer()
44
+ const em = (container.resolve('em') as EntityManager).fork()
45
+ await autoSendInvoice(em, payload)
46
+ }
@@ -1,34 +1,24 @@
1
1
  import type { EntityManager } from '@mikro-orm/postgresql'
2
2
  import { createRequestContainer } from '@open-mercato/shared/lib/di/container'
3
- import { SalesInvoice } from '@open-mercato/core/modules/sales/data/entities'
4
- import { resolveInvoiceStatusEntryId } from '../lib/invoiceStatus'
3
+ import { BillingInvoice, BillingPayment } from '../data/entities'
4
+ import { withAccountLock } from '../lib/accountLock'
5
+ import { allocate, applyAccountCredit, emptyEffects, mergeEffects, toCents, type AllocationEffects } from '../lib/allocation'
6
+ import { emitAllocationEffects } from '../lib/allocationEvents'
7
+ import { emitBillingEvent } from '../events'
5
8
 
6
9
  /**
7
- * Subscriber: payment captured → billing invoice paid.
10
+ * Subscriber: gateway payment captured → billing payment + allocation
11
+ * (Spec C, P-D9 — the single code path to "paid").
8
12
  *
9
- * Spec wishlist was `payments.payment.completed` carrying `invoice_id`.
10
- * The actual upstream event is `payment_gateways.payment.captured` and
11
- * its payload carries `paymentId` — set by whoever created the payment
12
- * session. Billing flows that drive their own payment sessions can
13
- * pass `paymentId = invoice.id`; the subscriber matches on that.
13
+ * The payment session is created with `paymentId = invoice.id`, so the
14
+ * captured event identifies the billing invoice. Instead of flipping the
15
+ * invoice status, the capture becomes a `BillingPayment` (`source =
16
+ * gateway`, `external_ref = transactionId ?? paymentId`) allocated to that
17
+ * invoice through the allocation service; any remainder is account credit.
14
18
  *
15
- * Behaviour:
16
- * 1. Try to find a `core/sales` invoice with `id = payload.paymentId`
17
- * scoped to the same tenant/organization.
18
- * 2. If found AND its `status == 'posted'`, flip it to `'paid'`
19
- * (resolves the `paid` `DictionaryEntry`, updates `status` +
20
- * `status_entry_id`). Drafts and already-paid / voided invoices
21
- * are left untouched.
22
- * 3. If `paymentId` does not point at a billing-known invoice (e.g.
23
- * the payment was for a `sales.order`), the subscriber is a
24
- * no-op — every other module's own subscriber owns its slice.
25
- *
26
- * Cross-tenant safety: we always re-scope by `tenantId` +
27
- * `organizationId` from the event payload. A malformed payload (e.g.
28
- * missing scope fields) short-circuits without touching the DB.
29
- *
30
- * Idempotency: re-firing the same captured event finds the invoice
31
- * already paid and skips silently.
19
+ * Idempotent: a re-delivered event finds the payment by `external_ref` and
20
+ * does nothing. Payments for anything that is not an open billing
21
+ * receivable are ignored (other modules own them).
32
22
  */
33
23
 
34
24
  export const metadata = {
@@ -37,53 +27,85 @@ export const metadata = {
37
27
  id: 'billing-payment-captured-to-paid',
38
28
  }
39
29
 
40
- type CapturedPayload = {
30
+ export type CapturedPayload = {
41
31
  paymentId?: string
42
32
  transactionId?: string
43
33
  organizationId?: string
44
34
  tenantId?: string
45
35
  providerKey?: string
36
+ amount?: number | string
37
+ currencyCode?: string
46
38
  }
47
39
 
48
- export default async function handle(payload: CapturedPayload): Promise<void> {
49
- if (!payload?.paymentId || !payload.tenantId || !payload.organizationId) {
50
- return
51
- }
40
+ export async function recordGatewayCapture(
41
+ em: EntityManager,
42
+ payload: CapturedPayload,
43
+ ): Promise<'recorded' | 'duplicate' | 'skipped'> {
44
+ if (!payload?.paymentId || !payload.tenantId || !payload.organizationId) return 'skipped'
45
+ const scope = { tenantId: payload.tenantId, organizationId: payload.organizationId }
46
+ const invoice = await em.findOne(BillingInvoice, { id: payload.paymentId, ...scope, deletedAt: null } as never)
47
+ if (!invoice || invoice.testRun || !['invoice', 'debit_memo'].includes(invoice.documentType)) return 'skipped'
48
+ const externalRef = payload.transactionId ?? payload.paymentId
49
+ const existing = await em.findOne(BillingPayment, { ...scope, externalRef } as never)
50
+ if (existing) return 'duplicate'
51
+ if (!['posted', 'partially_paid'].includes(invoice.status)) return 'skipped'
52
52
 
53
- const container = await createRequestContainer()
54
- const em = (container.resolve('em') as EntityManager).fork()
55
-
56
- const invoice = await em.findOne(SalesInvoice, {
57
- id: payload.paymentId,
58
- tenantId: payload.tenantId,
59
- organizationId: payload.organizationId,
60
- deletedAt: null,
53
+ const captured = toCents(payload.amount ?? invoice.outstanding)
54
+ if (captured <= 0) return 'skipped'
55
+ const amount = (captured / 100).toFixed(4)
56
+ const now = new Date()
57
+ const payment = em.create(BillingPayment, {
58
+ ...scope,
59
+ receivedAt: new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate())),
60
+ amount,
61
+ currencyCode: (payload.currencyCode ?? invoice.currencyCode).toUpperCase(),
62
+ reference: invoice.number,
63
+ source: 'gateway',
64
+ billAccountId: invoice.billAccountId,
65
+ status: 'matched',
66
+ unallocatedAmount: amount,
67
+ sourceRef: `gateway:${externalRef}`,
68
+ externalRef,
69
+ metadata: { provider_key: payload.providerKey ?? null },
70
+ createdAt: now,
71
+ updatedAt: now,
61
72
  })
62
- if (!invoice) {
63
- // The captured payment isn't for a billing invoice — silent
64
- // no-op. Other subscribers (sales, checkout) handle their slice.
65
- return
66
- }
67
- if (invoice.status === 'paid') {
68
- // Already paid — idempotent re-firing.
69
- return
70
- }
71
- if (invoice.status !== 'posted') {
72
- // A captured payment for a draft / void invoice is suspicious but
73
- // not actionable here. Future iteration: log to audit_logs.
74
- return
75
- }
73
+ em.persist(payment)
74
+ await em.flush()
76
75
 
77
- const paidStatusEntryId = await resolveInvoiceStatusEntryId(
76
+ const effects: AllocationEffects = await withAccountLock(
78
77
  em,
79
- payload.tenantId,
80
- payload.organizationId,
81
- 'paid',
78
+ { tenantId: scope.tenantId, billAccountId: invoice.billAccountId },
79
+ async (tem) => {
80
+ const all = emptyEffects()
81
+ const take = Math.min(captured, toCents(invoice.outstanding))
82
+ if (take > 0 && payment.currencyCode === invoice.currencyCode) {
83
+ mergeEffects(
84
+ all,
85
+ await allocate(tem, scope, {
86
+ source: { type: 'payment', id: payment.id },
87
+ invoiceId: invoice.id,
88
+ amountCents: take,
89
+ by: 'gateway',
90
+ }),
91
+ )
92
+ }
93
+ mergeEffects(
94
+ all,
95
+ await applyAccountCredit(tem, scope, { id: invoice.billAccountId, currencyCode: payment.currencyCode }, {
96
+ onlySources: [{ type: 'payment', id: payment.id }],
97
+ }),
98
+ )
99
+ return all
100
+ },
82
101
  )
83
- invoice.status = 'paid'
84
- invoice.statusEntryId = paidStatusEntryId
85
- invoice.paidTotalAmount = invoice.grandTotalGrossAmount
86
- invoice.outstandingAmount = '0'
87
- invoice.updatedAt = new Date()
88
- await em.flush()
102
+ await emitBillingEvent('billing.payment.created', { ...scope, paymentId: payment.id, source: 'gateway' })
103
+ await emitAllocationEffects(scope, effects)
104
+ return 'recorded'
105
+ }
106
+
107
+ export default async function handle(payload: CapturedPayload): Promise<void> {
108
+ const container = await createRequestContainer()
109
+ const em = (container.resolve('em') as EntityManager).fork()
110
+ await recordGatewayCapture(em, payload)
89
111
  }
@@ -1,7 +1,5 @@
1
1
  import type { EntityManager } from '@mikro-orm/postgresql'
2
2
  import { createRequestContainer } from '@open-mercato/shared/lib/di/container'
3
- import type { SalesDocumentNumberGenerator } from '@open-mercato/core/modules/sales/services/salesDocumentNumberGenerator'
4
- import type { TaxCalculationService } from '@open-mercato/core/modules/sales/services/taxCalculationService'
5
3
  import { BillingAccount, BillingTopup } from '../data/entities'
6
4
  import { emitBillingEvent } from '../events'
7
5
  import { captureTopup } from '../lib/topupCapture'
@@ -66,15 +64,13 @@ export default async function handle(payload: CapturedPayload): Promise<void> {
66
64
  return
67
65
  }
68
66
 
69
- const taxRate = await getTopupTaxRate(em)
70
- const numberGenerator = container.resolve(
71
- 'salesDocumentNumberGenerator',
72
- ) as SalesDocumentNumberGenerator
73
- const taxService = container.resolve('taxCalculationService') as TaxCalculationService
67
+ const taxRate = await getTopupTaxRate(em, {
68
+ tenantId: account.tenantId,
69
+ organizationId: account.organizationId,
70
+ })
74
71
 
75
72
  const result = await captureTopup(
76
73
  em,
77
- { numberGenerator, taxService },
78
74
  {
79
75
  topup,
80
76
  account: {
@@ -1,38 +0,0 @@
1
- import {
2
- Dictionary,
3
- DictionaryEntry
4
- } from "@open-mercato/core/modules/dictionaries/data/entities";
5
- const SALES_INVOICE_STATUS_DICTIONARY_KEY = "sales.invoice_status";
6
- const cache = /* @__PURE__ */ new Map();
7
- function key(tenantId, organizationId, status) {
8
- return `${tenantId}:${organizationId}:${status}`;
9
- }
10
- async function resolveInvoiceStatusEntryId(em, tenantId, organizationId, status) {
11
- const cacheKey = key(tenantId, organizationId, status);
12
- const cached = cache.get(cacheKey);
13
- if (cached) return cached;
14
- const dictionary = await em.findOne(Dictionary, {
15
- tenantId,
16
- organizationId,
17
- key: SALES_INVOICE_STATUS_DICTIONARY_KEY,
18
- deletedAt: null
19
- });
20
- if (!dictionary) return null;
21
- const entry = await em.findOne(DictionaryEntry, {
22
- dictionary,
23
- tenantId,
24
- organizationId,
25
- value: status
26
- });
27
- if (!entry) return null;
28
- cache.set(cacheKey, entry.id);
29
- return entry.id;
30
- }
31
- function __resetInvoiceStatusCacheForTests() {
32
- cache.clear();
33
- }
34
- export {
35
- __resetInvoiceStatusCacheForTests,
36
- resolveInvoiceStatusEntryId
37
- };
38
- //# sourceMappingURL=invoiceStatus.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../src/modules/billing/lib/invoiceStatus.ts"],
4
- "sourcesContent": ["import type { EntityManager } from '@mikro-orm/postgresql'\nimport {\n Dictionary,\n DictionaryEntry,\n} from '@open-mercato/core/modules/dictionaries/data/entities'\nimport type { InvoiceStatus } from '../data/validators'\n\n/**\n * Resolve the `sales.invoice_status` dictionary entry id for a given\n * status value, scoped per `(tenantId, organizationId)`.\n *\n * Used by:\n * - `invoiceWriter` to set `statusEntryId` on the draft at create time.\n * - The \"post\" command to flip draft \u2192 posted.\n * - The payment-captured subscriber to flip posted \u2192 paid.\n *\n * Cached because the lookup is hot (every Bill Run draft hits it\n * once, every posted invoice hits it twice, every paid invoice once)\n * and the dictionary entry id never changes for the lifetime of a\n * tenant. Exposed `__resetInvoiceStatusCacheForTests` to keep tests\n * deterministic across runs.\n */\n\nconst SALES_INVOICE_STATUS_DICTIONARY_KEY = 'sales.invoice_status'\n\nconst cache = new Map<string, string>()\n\nfunction key(tenantId: string, organizationId: string, status: InvoiceStatus): string {\n return `${tenantId}:${organizationId}:${status}`\n}\n\nexport async function resolveInvoiceStatusEntryId(\n em: EntityManager,\n tenantId: string,\n organizationId: string,\n status: InvoiceStatus,\n): Promise<string | null> {\n const cacheKey = key(tenantId, organizationId, status)\n const cached = cache.get(cacheKey)\n if (cached) return cached\n const dictionary = await em.findOne(Dictionary, {\n tenantId,\n organizationId,\n key: SALES_INVOICE_STATUS_DICTIONARY_KEY,\n deletedAt: null,\n })\n if (!dictionary) return null\n const entry = await em.findOne(DictionaryEntry, {\n dictionary,\n tenantId,\n organizationId,\n value: status,\n })\n if (!entry) return null\n cache.set(cacheKey, entry.id)\n return entry.id\n}\n\nexport function __resetInvoiceStatusCacheForTests(): void {\n cache.clear()\n}\n"],
5
- "mappings": "AACA;AAAA,EACE;AAAA,EACA;AAAA,OACK;AAmBP,MAAM,sCAAsC;AAE5C,MAAM,QAAQ,oBAAI,IAAoB;AAEtC,SAAS,IAAI,UAAkB,gBAAwB,QAA+B;AACpF,SAAO,GAAG,QAAQ,IAAI,cAAc,IAAI,MAAM;AAChD;AAEA,eAAsB,4BACpB,IACA,UACA,gBACA,QACwB;AACxB,QAAM,WAAW,IAAI,UAAU,gBAAgB,MAAM;AACrD,QAAM,SAAS,MAAM,IAAI,QAAQ;AACjC,MAAI,OAAQ,QAAO;AACnB,QAAM,aAAa,MAAM,GAAG,QAAQ,YAAY;AAAA,IAC9C;AAAA,IACA;AAAA,IACA,KAAK;AAAA,IACL,WAAW;AAAA,EACb,CAAC;AACD,MAAI,CAAC,WAAY,QAAO;AACxB,QAAM,QAAQ,MAAM,GAAG,QAAQ,iBAAiB;AAAA,IAC9C;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO;AAAA,EACT,CAAC;AACD,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,IAAI,UAAU,MAAM,EAAE;AAC5B,SAAO,MAAM;AACf;AAEO,SAAS,oCAA0C;AACxD,QAAM,MAAM;AACd;",
6
- "names": []
7
- }
@@ -1,97 +0,0 @@
1
- import {
2
- __resetInvoiceStatusCacheForTests,
3
- resolveInvoiceStatusEntryId,
4
- } from '../../lib/invoiceStatus'
5
-
6
- type MockEm = {
7
- findOne: jest.MockedFunction<(entity: unknown, where: Record<string, unknown>) => Promise<unknown>>
8
- }
9
-
10
- function createMockEm(): MockEm {
11
- return { findOne: jest.fn() }
12
- }
13
-
14
- const TENANT = 'tenant-1'
15
- const ORG = 'org-1'
16
-
17
- beforeEach(() => {
18
- __resetInvoiceStatusCacheForTests()
19
- })
20
-
21
- describe('resolveInvoiceStatusEntryId', () => {
22
- it('looks up dictionary then matching entry', async () => {
23
- const em = createMockEm()
24
- em.findOne
25
- .mockResolvedValueOnce({ id: 'dict-1' })
26
- .mockResolvedValueOnce({ id: 'entry-draft' })
27
-
28
- const result = await resolveInvoiceStatusEntryId(em as never, TENANT, ORG, 'draft')
29
-
30
- expect(result).toBe('entry-draft')
31
- expect(em.findOne).toHaveBeenCalledTimes(2)
32
- const [, dictWhere] = em.findOne.mock.calls[0]
33
- expect((dictWhere as { key: string }).key).toBe('sales.invoice_status')
34
- const [, entryWhere] = em.findOne.mock.calls[1]
35
- expect((entryWhere as { value: string }).value).toBe('draft')
36
- })
37
-
38
- it('caches the resolved id per (tenant, org, status)', async () => {
39
- const em = createMockEm()
40
- em.findOne
41
- .mockResolvedValueOnce({ id: 'dict-1' })
42
- .mockResolvedValueOnce({ id: 'entry-paid' })
43
-
44
- const a = await resolveInvoiceStatusEntryId(em as never, TENANT, ORG, 'paid')
45
- const b = await resolveInvoiceStatusEntryId(em as never, TENANT, ORG, 'paid')
46
-
47
- expect(a).toBe('entry-paid')
48
- expect(b).toBe('entry-paid')
49
- // Second call hits cache — no extra findOne invocations.
50
- expect(em.findOne).toHaveBeenCalledTimes(2)
51
- })
52
-
53
- it('separate cache entries per status (draft vs posted vs paid vs void)', async () => {
54
- const em = createMockEm()
55
- em.findOne
56
- .mockResolvedValueOnce({ id: 'dict-1' })
57
- .mockResolvedValueOnce({ id: 'entry-draft' })
58
- .mockResolvedValueOnce({ id: 'dict-1' })
59
- .mockResolvedValueOnce({ id: 'entry-posted' })
60
-
61
- expect(await resolveInvoiceStatusEntryId(em as never, TENANT, ORG, 'draft')).toBe(
62
- 'entry-draft',
63
- )
64
- expect(await resolveInvoiceStatusEntryId(em as never, TENANT, ORG, 'posted')).toBe(
65
- 'entry-posted',
66
- )
67
- })
68
-
69
- it('returns null when the dictionary is missing', async () => {
70
- const em = createMockEm()
71
- em.findOne.mockResolvedValueOnce(null)
72
- expect(await resolveInvoiceStatusEntryId(em as never, TENANT, ORG, 'draft')).toBeNull()
73
- })
74
-
75
- it('returns null when the entry value is missing', async () => {
76
- const em = createMockEm()
77
- em.findOne.mockResolvedValueOnce({ id: 'dict-1' }).mockResolvedValueOnce(null)
78
- expect(await resolveInvoiceStatusEntryId(em as never, TENANT, ORG, 'void')).toBeNull()
79
- })
80
-
81
- it('separate cache entries per tenant', async () => {
82
- const em = createMockEm()
83
- em.findOne
84
- .mockResolvedValueOnce({ id: 'dict-A' })
85
- .mockResolvedValueOnce({ id: 'entry-A' })
86
- .mockResolvedValueOnce({ id: 'dict-B' })
87
- .mockResolvedValueOnce({ id: 'entry-B' })
88
-
89
- expect(await resolveInvoiceStatusEntryId(em as never, 't-A', ORG, 'draft')).toBe(
90
- 'entry-A',
91
- )
92
- expect(await resolveInvoiceStatusEntryId(em as never, 't-B', ORG, 'draft')).toBe(
93
- 'entry-B',
94
- )
95
- expect(em.findOne).toHaveBeenCalledTimes(4)
96
- })
97
- })
@@ -1,61 +0,0 @@
1
- import type { EntityManager } from '@mikro-orm/postgresql'
2
- import {
3
- Dictionary,
4
- DictionaryEntry,
5
- } from '@open-mercato/core/modules/dictionaries/data/entities'
6
- import type { InvoiceStatus } from '../data/validators'
7
-
8
- /**
9
- * Resolve the `sales.invoice_status` dictionary entry id for a given
10
- * status value, scoped per `(tenantId, organizationId)`.
11
- *
12
- * Used by:
13
- * - `invoiceWriter` to set `statusEntryId` on the draft at create time.
14
- * - The "post" command to flip draft → posted.
15
- * - The payment-captured subscriber to flip posted → paid.
16
- *
17
- * Cached because the lookup is hot (every Bill Run draft hits it
18
- * once, every posted invoice hits it twice, every paid invoice once)
19
- * and the dictionary entry id never changes for the lifetime of a
20
- * tenant. Exposed `__resetInvoiceStatusCacheForTests` to keep tests
21
- * deterministic across runs.
22
- */
23
-
24
- const SALES_INVOICE_STATUS_DICTIONARY_KEY = 'sales.invoice_status'
25
-
26
- const cache = new Map<string, string>()
27
-
28
- function key(tenantId: string, organizationId: string, status: InvoiceStatus): string {
29
- return `${tenantId}:${organizationId}:${status}`
30
- }
31
-
32
- export async function resolveInvoiceStatusEntryId(
33
- em: EntityManager,
34
- tenantId: string,
35
- organizationId: string,
36
- status: InvoiceStatus,
37
- ): Promise<string | null> {
38
- const cacheKey = key(tenantId, organizationId, status)
39
- const cached = cache.get(cacheKey)
40
- if (cached) return cached
41
- const dictionary = await em.findOne(Dictionary, {
42
- tenantId,
43
- organizationId,
44
- key: SALES_INVOICE_STATUS_DICTIONARY_KEY,
45
- deletedAt: null,
46
- })
47
- if (!dictionary) return null
48
- const entry = await em.findOne(DictionaryEntry, {
49
- dictionary,
50
- tenantId,
51
- organizationId,
52
- value: status,
53
- })
54
- if (!entry) return null
55
- cache.set(cacheKey, entry.id)
56
- return entry.id
57
- }
58
-
59
- export function __resetInvoiceStatusCacheForTests(): void {
60
- cache.clear()
61
- }