@dainamite/billing 0.19.0 → 0.21.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 (614) hide show
  1. package/CHANGELOG.md +172 -0
  2. package/README.md +14 -0
  3. package/dist/modules/billing/acl.js +13 -1
  4. package/dist/modules/billing/acl.js.map +2 -2
  5. package/dist/modules/billing/api/accounts/[id]/summary/route.js +52 -0
  6. package/dist/modules/billing/api/accounts/[id]/summary/route.js.map +7 -0
  7. package/dist/modules/billing/api/accounts/route.js +46 -4
  8. package/dist/modules/billing/api/accounts/route.js.map +2 -2
  9. package/dist/modules/billing/api/export/account/[id]/route.js +16 -12
  10. package/dist/modules/billing/api/export/account/[id]/route.js.map +2 -2
  11. package/dist/modules/billing/api/invoices/[id]/memos/route.js +54 -0
  12. package/dist/modules/billing/api/invoices/[id]/memos/route.js.map +7 -0
  13. package/dist/modules/billing/api/invoices/[id]/pdf/route.js +69 -0
  14. package/dist/modules/billing/api/invoices/[id]/pdf/route.js.map +7 -0
  15. package/dist/modules/billing/api/invoices/[id]/route.js +44 -24
  16. package/dist/modules/billing/api/invoices/[id]/route.js.map +2 -2
  17. package/dist/modules/billing/api/invoices/[id]/send/route.js +107 -0
  18. package/dist/modules/billing/api/invoices/[id]/send/route.js.map +7 -0
  19. package/dist/modules/billing/api/invoices/add-line/route.js +3 -3
  20. package/dist/modules/billing/api/invoices/add-line/route.js.map +2 -2
  21. package/dist/modules/billing/api/invoices/delete-draft/route.js +33 -0
  22. package/dist/modules/billing/api/invoices/delete-draft/route.js.map +7 -0
  23. package/dist/modules/billing/api/invoices/edit-line/route.js +3 -3
  24. package/dist/modules/billing/api/invoices/edit-line/route.js.map +2 -2
  25. package/dist/modules/billing/api/invoices/post/route.js +2 -2
  26. package/dist/modules/billing/api/invoices/post/route.js.map +2 -2
  27. package/dist/modules/billing/api/invoices/remove-line/route.js +3 -3
  28. package/dist/modules/billing/api/invoices/remove-line/route.js.map +2 -2
  29. package/dist/modules/billing/api/invoices/route.js +45 -46
  30. package/dist/modules/billing/api/invoices/route.js.map +2 -2
  31. package/dist/modules/billing/api/items/bulk/route.js +1 -1
  32. package/dist/modules/billing/api/items/bulk/route.js.map +2 -2
  33. package/dist/modules/billing/api/items/change-price/route.js +44 -0
  34. package/dist/modules/billing/api/items/change-price/route.js.map +7 -0
  35. package/dist/modules/billing/api/items/route.js +19 -7
  36. package/dist/modules/billing/api/items/route.js.map +2 -2
  37. package/dist/modules/billing/api/payment-imports/[id]/route.js +49 -0
  38. package/dist/modules/billing/api/payment-imports/[id]/route.js.map +7 -0
  39. package/dist/modules/billing/api/payment-imports/route.js +57 -0
  40. package/dist/modules/billing/api/payment-imports/route.js.map +7 -0
  41. package/dist/modules/billing/api/payments/[id]/route.js +60 -0
  42. package/dist/modules/billing/api/payments/[id]/route.js.map +7 -0
  43. package/dist/modules/billing/api/payments/allocate/route.js +35 -0
  44. package/dist/modules/billing/api/payments/allocate/route.js.map +7 -0
  45. package/dist/modules/billing/api/payments/assign/route.js +36 -0
  46. package/dist/modules/billing/api/payments/assign/route.js.map +7 -0
  47. package/dist/modules/billing/api/payments/convert-to-topup/route.js +35 -0
  48. package/dist/modules/billing/api/payments/convert-to-topup/route.js.map +7 -0
  49. package/dist/modules/billing/api/payments/ignore/route.js +35 -0
  50. package/dist/modules/billing/api/payments/ignore/route.js.map +7 -0
  51. package/dist/modules/billing/api/payments/import/route.js +63 -0
  52. package/dist/modules/billing/api/payments/import/route.js.map +7 -0
  53. package/dist/modules/billing/api/payments/restore/route.js +35 -0
  54. package/dist/modules/billing/api/payments/restore/route.js.map +7 -0
  55. package/dist/modules/billing/api/payments/route.js +114 -0
  56. package/dist/modules/billing/api/payments/route.js.map +7 -0
  57. package/dist/modules/billing/api/payments/unallocate/route.js +35 -0
  58. package/dist/modules/billing/api/payments/unallocate/route.js.map +7 -0
  59. package/dist/modules/billing/api/payments/unassign/route.js +35 -0
  60. package/dist/modules/billing/api/payments/unassign/route.js.map +7 -0
  61. package/dist/modules/billing/api/run-outcomes/route.js +44 -7
  62. package/dist/modules/billing/api/run-outcomes/route.js.map +2 -2
  63. package/dist/modules/billing/api/runs/[id]/post-drafts/route.js +61 -0
  64. package/dist/modules/billing/api/runs/[id]/post-drafts/route.js.map +7 -0
  65. package/dist/modules/billing/api/runs/[id]/route.js +53 -0
  66. package/dist/modules/billing/api/runs/[id]/route.js.map +7 -0
  67. package/dist/modules/billing/api/runs/retry-failed/route.js +3 -3
  68. package/dist/modules/billing/api/runs/retry-failed/route.js.map +2 -2
  69. package/dist/modules/billing/api/runs/route.js +11 -5
  70. package/dist/modules/billing/api/runs/route.js.map +2 -2
  71. package/dist/modules/billing/api/settings/number-preview/route.js +42 -0
  72. package/dist/modules/billing/api/settings/number-preview/route.js.map +7 -0
  73. package/dist/modules/billing/api/settings/route.js +92 -0
  74. package/dist/modules/billing/api/settings/route.js.map +7 -0
  75. package/dist/modules/billing/api/statements/route.js +3 -0
  76. package/dist/modules/billing/api/statements/route.js.map +2 -2
  77. package/dist/modules/billing/api/test-invoices/wipe/route.js +2 -2
  78. package/dist/modules/billing/api/test-invoices/wipe/route.js.map +2 -2
  79. package/dist/modules/billing/backend/billing/accounts/[id]/page.js +121 -232
  80. package/dist/modules/billing/backend/billing/accounts/[id]/page.js.map +2 -2
  81. package/dist/modules/billing/backend/billing/accounts/create/page.js +6 -0
  82. package/dist/modules/billing/backend/billing/accounts/create/page.js.map +2 -2
  83. package/dist/modules/billing/backend/billing/accounts/page.js +63 -4
  84. package/dist/modules/billing/backend/billing/accounts/page.js.map +2 -2
  85. package/dist/modules/billing/backend/billing/invoices/[id]/page.js +297 -65
  86. package/dist/modules/billing/backend/billing/invoices/[id]/page.js.map +3 -3
  87. package/dist/modules/billing/backend/billing/invoices/page.js +6 -172
  88. package/dist/modules/billing/backend/billing/invoices/page.js.map +2 -2
  89. package/dist/modules/billing/backend/billing/items/[id]/page.js +51 -7
  90. package/dist/modules/billing/backend/billing/items/[id]/page.js.map +2 -2
  91. package/dist/modules/billing/backend/billing/items/create/page.js +9 -6
  92. package/dist/modules/billing/backend/billing/items/create/page.js.map +2 -2
  93. package/dist/modules/billing/backend/billing/items/page.js +8 -2
  94. package/dist/modules/billing/backend/billing/items/page.js.map +2 -2
  95. package/dist/modules/billing/backend/billing/payments/[id]/page.js +297 -0
  96. package/dist/modules/billing/backend/billing/payments/[id]/page.js.map +7 -0
  97. package/dist/modules/billing/backend/billing/payments/[id]/page.meta.js +21 -0
  98. package/dist/modules/billing/backend/billing/payments/[id]/page.meta.js.map +7 -0
  99. package/dist/modules/billing/backend/billing/payments/imports/[id]/page.js +74 -0
  100. package/dist/modules/billing/backend/billing/payments/imports/[id]/page.js.map +7 -0
  101. package/dist/modules/billing/backend/billing/payments/imports/[id]/page.meta.js +21 -0
  102. package/dist/modules/billing/backend/billing/payments/imports/[id]/page.meta.js.map +7 -0
  103. package/dist/modules/billing/backend/billing/payments/page.js +58 -0
  104. package/dist/modules/billing/backend/billing/payments/page.js.map +7 -0
  105. package/dist/modules/billing/backend/billing/payments/page.meta.js +18 -0
  106. package/dist/modules/billing/backend/billing/payments/page.meta.js.map +7 -0
  107. package/dist/modules/billing/backend/billing/runs/[id]/page.js +49 -14
  108. package/dist/modules/billing/backend/billing/runs/[id]/page.js.map +2 -2
  109. package/dist/modules/billing/backend/billing/runs/page.js +58 -7
  110. package/dist/modules/billing/backend/billing/runs/page.js.map +2 -2
  111. package/dist/modules/billing/backend/billing/statements/[id]/page.js +61 -6
  112. package/dist/modules/billing/backend/billing/statements/[id]/page.js.map +2 -2
  113. package/dist/modules/billing/backend/billing/statements/page.js +1 -1
  114. package/dist/modules/billing/backend/billing/statements/page.js.map +2 -2
  115. package/dist/modules/billing/backend/billing/topups/page.js +1 -1
  116. package/dist/modules/billing/backend/billing/topups/page.js.map +2 -2
  117. package/dist/modules/billing/backend/billing/transactions/page.js +1 -1
  118. package/dist/modules/billing/backend/billing/transactions/page.js.map +2 -2
  119. package/dist/modules/billing/backend/billing/usage/create/page.js +3 -2
  120. package/dist/modules/billing/backend/billing/usage/create/page.js.map +2 -2
  121. package/dist/modules/billing/backend/config/billing/page.js +472 -0
  122. package/dist/modules/billing/backend/config/billing/page.js.map +7 -0
  123. package/dist/modules/billing/backend/config/billing/page.meta.js +19 -0
  124. package/dist/modules/billing/backend/config/billing/page.meta.js.map +7 -0
  125. package/dist/modules/billing/ce.js.map +2 -2
  126. package/dist/modules/billing/cli.js +22 -1
  127. package/dist/modules/billing/cli.js.map +2 -2
  128. package/dist/modules/billing/commands/accounts.js +6 -0
  129. package/dist/modules/billing/commands/accounts.js.map +2 -2
  130. package/dist/modules/billing/commands/index.js +3 -0
  131. package/dist/modules/billing/commands/index.js.map +2 -2
  132. package/dist/modules/billing/commands/invoices.js +272 -170
  133. package/dist/modules/billing/commands/invoices.js.map +2 -2
  134. package/dist/modules/billing/commands/items.js +108 -0
  135. package/dist/modules/billing/commands/items.js.map +2 -2
  136. package/dist/modules/billing/commands/memos.js +179 -0
  137. package/dist/modules/billing/commands/memos.js.map +7 -0
  138. package/dist/modules/billing/commands/payments.js +379 -0
  139. package/dist/modules/billing/commands/payments.js.map +7 -0
  140. package/dist/modules/billing/commands/runs.js +154 -7
  141. package/dist/modules/billing/commands/runs.js.map +2 -2
  142. package/dist/modules/billing/commands/settings.js +59 -0
  143. package/dist/modules/billing/commands/settings.js.map +7 -0
  144. package/dist/modules/billing/commands/topups.js +9 -2
  145. package/dist/modules/billing/commands/topups.js.map +2 -2
  146. package/dist/modules/billing/commands/transactions.js +2 -2
  147. package/dist/modules/billing/commands/transactions.js.map +2 -2
  148. package/dist/modules/billing/components/AccountForm.js +149 -42
  149. package/dist/modules/billing/components/AccountForm.js.map +2 -2
  150. package/dist/modules/billing/components/AccountInvoicesSection.js +64 -0
  151. package/dist/modules/billing/components/AccountInvoicesSection.js.map +7 -0
  152. package/dist/modules/billing/components/AccountPaymentsSection.js +43 -0
  153. package/dist/modules/billing/components/AccountPaymentsSection.js.map +7 -0
  154. package/dist/modules/billing/components/AccountPicker.js +56 -0
  155. package/dist/modules/billing/components/AccountPicker.js.map +7 -0
  156. package/dist/modules/billing/components/AllocatePaymentDialog.js +134 -0
  157. package/dist/modules/billing/components/AllocatePaymentDialog.js.map +7 -0
  158. package/dist/modules/billing/components/BillingDataTable.js +21 -0
  159. package/dist/modules/billing/components/BillingDataTable.js.map +7 -0
  160. package/dist/modules/billing/components/BillingSettingsLink.js +19 -0
  161. package/dist/modules/billing/components/BillingSettingsLink.js.map +7 -0
  162. package/dist/modules/billing/components/ChangeItemPriceDialog.js +158 -0
  163. package/dist/modules/billing/components/ChangeItemPriceDialog.js.map +7 -0
  164. package/dist/modules/billing/components/CreateMemoDialog.js +200 -0
  165. package/dist/modules/billing/components/CreateMemoDialog.js.map +7 -0
  166. package/dist/modules/billing/components/CustomerLabel.js +33 -0
  167. package/dist/modules/billing/components/CustomerLabel.js.map +7 -0
  168. package/dist/modules/billing/components/InvoicesTable.js +270 -0
  169. package/dist/modules/billing/components/InvoicesTable.js.map +7 -0
  170. package/dist/modules/billing/components/ItemForm.js +176 -44
  171. package/dist/modules/billing/components/ItemForm.js.map +2 -2
  172. package/dist/modules/billing/components/ItemPriceField.js +46 -0
  173. package/dist/modules/billing/components/ItemPriceField.js.map +7 -0
  174. package/dist/modules/billing/components/LineFormDialog.js +25 -2
  175. package/dist/modules/billing/components/LineFormDialog.js.map +2 -2
  176. package/dist/modules/billing/components/ManualPaymentDialog.js +122 -0
  177. package/dist/modules/billing/components/ManualPaymentDialog.js.map +7 -0
  178. package/dist/modules/billing/components/MoneyInput.js +14 -0
  179. package/dist/modules/billing/components/MoneyInput.js.map +7 -0
  180. package/dist/modules/billing/components/PaymentUploadDialog.js +115 -0
  181. package/dist/modules/billing/components/PaymentUploadDialog.js.map +7 -0
  182. package/dist/modules/billing/components/PaymentsTable.js +171 -0
  183. package/dist/modules/billing/components/PaymentsTable.js.map +7 -0
  184. package/dist/modules/billing/components/PostRunDraftsButton.js +105 -0
  185. package/dist/modules/billing/components/PostRunDraftsButton.js.map +7 -0
  186. package/dist/modules/billing/components/PrepaidPanel.js +14 -4
  187. package/dist/modules/billing/components/PrepaidPanel.js.map +2 -2
  188. package/dist/modules/billing/components/RunCyclesSection.js +209 -0
  189. package/dist/modules/billing/components/RunCyclesSection.js.map +7 -0
  190. package/dist/modules/billing/components/TestRunActions.js +127 -0
  191. package/dist/modules/billing/components/TestRunActions.js.map +7 -0
  192. package/dist/modules/billing/components/account/AccountItemsTab.js +157 -0
  193. package/dist/modules/billing/components/account/AccountItemsTab.js.map +7 -0
  194. package/dist/modules/billing/components/account/AccountRunBillingDialog.js +122 -0
  195. package/dist/modules/billing/components/account/AccountRunBillingDialog.js.map +7 -0
  196. package/dist/modules/billing/components/account/AccountRunsTab.js +152 -0
  197. package/dist/modules/billing/components/account/AccountRunsTab.js.map +7 -0
  198. package/dist/modules/billing/components/account/AccountStatementsTab.js +98 -0
  199. package/dist/modules/billing/components/account/AccountStatementsTab.js.map +7 -0
  200. package/dist/modules/billing/components/account/AccountSummaryCards.js +125 -0
  201. package/dist/modules/billing/components/account/AccountSummaryCards.js.map +7 -0
  202. package/dist/modules/billing/components/account/AccountUsageTab.js +91 -0
  203. package/dist/modules/billing/components/account/AccountUsageTab.js.map +7 -0
  204. package/dist/modules/billing/components/account/AccountView.js +73 -0
  205. package/dist/modules/billing/components/account/AccountView.js.map +7 -0
  206. package/dist/modules/billing/components/account/accountRow.js +39 -0
  207. package/dist/modules/billing/components/account/accountRow.js.map +7 -0
  208. package/dist/modules/billing/components/customerNames.js +42 -0
  209. package/dist/modules/billing/components/customerNames.js.map +7 -0
  210. package/dist/modules/billing/data/entities.js +615 -59
  211. package/dist/modules/billing/data/entities.js.map +2 -2
  212. package/dist/modules/billing/data/entityIds.js +10 -1
  213. package/dist/modules/billing/data/entityIds.js.map +2 -2
  214. package/dist/modules/billing/data/validators.js +269 -15
  215. package/dist/modules/billing/data/validators.js.map +2 -2
  216. package/dist/modules/billing/events.js +70 -0
  217. package/dist/modules/billing/events.js.map +2 -2
  218. package/dist/modules/billing/i18n/en.json +457 -21
  219. package/dist/modules/billing/i18n/pl.json +457 -21
  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 +241 -106
  237. package/dist/modules/billing/lib/billRunEngine.js.map +2 -2
  238. package/dist/modules/billing/lib/billRunLabel.js.map +1 -1
  239. package/dist/modules/billing/lib/billingSettings.js +116 -0
  240. package/dist/modules/billing/lib/billingSettings.js.map +7 -0
  241. package/dist/modules/billing/lib/commandRoute.js +81 -0
  242. package/dist/modules/billing/lib/commandRoute.js.map +7 -0
  243. package/dist/modules/billing/lib/customerLookup.js +97 -0
  244. package/dist/modules/billing/lib/customerLookup.js.map +7 -0
  245. package/dist/modules/billing/lib/dateOnly.js +13 -0
  246. package/dist/modules/billing/lib/dateOnly.js.map +7 -0
  247. package/dist/modules/billing/lib/documentParties.js +16 -0
  248. package/dist/modules/billing/lib/documentParties.js.map +7 -0
  249. package/dist/modules/billing/lib/documentTypes.js +27 -0
  250. package/dist/modules/billing/lib/documentTypes.js.map +7 -0
  251. package/dist/modules/billing/lib/dueDate.js +18 -0
  252. package/dist/modules/billing/lib/dueDate.js.map +7 -0
  253. package/dist/modules/billing/lib/iban.js +29 -0
  254. package/dist/modules/billing/lib/iban.js.map +7 -0
  255. package/dist/modules/billing/lib/invoiceDelivery.js +131 -0
  256. package/dist/modules/billing/lib/invoiceDelivery.js.map +7 -0
  257. package/dist/modules/billing/lib/invoiceLanguages.js +16 -0
  258. package/dist/modules/billing/lib/invoiceLanguages.js.map +7 -0
  259. package/dist/modules/billing/lib/invoiceWriter.js +107 -99
  260. package/dist/modules/billing/lib/invoiceWriter.js.map +2 -2
  261. package/dist/modules/billing/lib/itemBillingState.js +27 -0
  262. package/dist/modules/billing/lib/itemBillingState.js.map +7 -0
  263. package/dist/modules/billing/lib/itemPriceChange.js +18 -0
  264. package/dist/modules/billing/lib/itemPriceChange.js.map +7 -0
  265. package/dist/modules/billing/lib/itemSelector.js.map +2 -2
  266. package/dist/modules/billing/lib/lineAmounts.js +32 -0
  267. package/dist/modules/billing/lib/lineAmounts.js.map +7 -0
  268. package/dist/modules/billing/lib/memoGuards.js +25 -0
  269. package/dist/modules/billing/lib/memoGuards.js.map +7 -0
  270. package/dist/modules/billing/lib/navigation.js +48 -0
  271. package/dist/modules/billing/lib/navigation.js.map +7 -0
  272. package/dist/modules/billing/lib/numbering.js +120 -0
  273. package/dist/modules/billing/lib/numbering.js.map +7 -0
  274. package/dist/modules/billing/lib/overdue.js +36 -0
  275. package/dist/modules/billing/lib/overdue.js.map +7 -0
  276. package/dist/modules/billing/lib/paymentCsv.js +125 -0
  277. package/dist/modules/billing/lib/paymentCsv.js.map +7 -0
  278. package/dist/modules/billing/lib/paymentGateway.js +15 -0
  279. package/dist/modules/billing/lib/paymentGateway.js.map +7 -0
  280. package/dist/modules/billing/lib/paymentImport.js +164 -0
  281. package/dist/modules/billing/lib/paymentImport.js.map +7 -0
  282. package/dist/modules/billing/lib/paymentMatcher.js +36 -0
  283. package/dist/modules/billing/lib/paymentMatcher.js.map +7 -0
  284. package/dist/modules/billing/lib/pdf/attachmentStore.js +46 -0
  285. package/dist/modules/billing/lib/pdf/attachmentStore.js.map +7 -0
  286. package/dist/modules/billing/lib/pdf/fonts/embeddedFonts.js +7 -0
  287. package/dist/modules/billing/lib/pdf/fonts/embeddedFonts.js.map +7 -0
  288. package/dist/modules/billing/lib/pdf/invoiceModel.js +194 -0
  289. package/dist/modules/billing/lib/pdf/invoiceModel.js.map +7 -0
  290. package/dist/modules/billing/lib/pdf/invoicePdf.js +165 -0
  291. package/dist/modules/billing/lib/pdf/invoicePdf.js.map +7 -0
  292. package/dist/modules/billing/lib/pdf/invoiceTemplate.js +274 -0
  293. package/dist/modules/billing/lib/pdf/invoiceTemplate.js.map +7 -0
  294. package/dist/modules/billing/lib/prepaidConfig.js +17 -25
  295. package/dist/modules/billing/lib/prepaidConfig.js.map +2 -2
  296. package/dist/modules/billing/lib/prepaidConsume.js +26 -7
  297. package/dist/modules/billing/lib/prepaidConsume.js.map +2 -2
  298. package/dist/modules/billing/lib/prepaidPeriodClose.js +277 -158
  299. package/dist/modules/billing/lib/prepaidPeriodClose.js.map +2 -2
  300. package/dist/modules/billing/lib/prepaidTaxPoint.js +37 -0
  301. package/dist/modules/billing/lib/prepaidTaxPoint.js.map +7 -0
  302. package/dist/modules/billing/lib/seeds/demo.js +51 -3
  303. package/dist/modules/billing/lib/seeds/demo.js.map +2 -2
  304. package/dist/modules/billing/lib/seeds/paymentsSample.js +93 -0
  305. package/dist/modules/billing/lib/seeds/paymentsSample.js.map +7 -0
  306. package/dist/modules/billing/lib/seeds/sellerSettings.js +41 -0
  307. package/dist/modules/billing/lib/seeds/sellerSettings.js.map +7 -0
  308. package/dist/modules/billing/lib/servicePeriods.js +121 -0
  309. package/dist/modules/billing/lib/servicePeriods.js.map +7 -0
  310. package/dist/modules/billing/lib/tenantLock.js.map +1 -1
  311. package/dist/modules/billing/lib/testRunCleanup.js +24 -0
  312. package/dist/modules/billing/lib/testRunCleanup.js.map +7 -0
  313. package/dist/modules/billing/lib/topupCapture.js +2 -2
  314. package/dist/modules/billing/lib/topupCapture.js.map +2 -2
  315. package/dist/modules/billing/lib/topupReceipt.js +58 -79
  316. package/dist/modules/billing/lib/topupReceipt.js.map +2 -2
  317. package/dist/modules/billing/lib/usageRater.js.map +1 -1
  318. package/dist/modules/billing/lib/usageRunner.js +14 -6
  319. package/dist/modules/billing/lib/usageRunner.js.map +2 -2
  320. package/dist/modules/billing/lib/vat.js +39 -0
  321. package/dist/modules/billing/lib/vat.js.map +7 -0
  322. package/dist/modules/billing/migrations/Migration20261114000000_billing_customer_kind.js +15 -0
  323. package/dist/modules/billing/migrations/Migration20261114000000_billing_customer_kind.js.map +7 -0
  324. package/dist/modules/billing/migrations/Migration20261114100000_billing_cycle_semantics.js +25 -0
  325. package/dist/modules/billing/migrations/Migration20261114100000_billing_cycle_semantics.js.map +7 -0
  326. package/dist/modules/billing/migrations/Migration20261115000000_billing_invoice_ledger.js +115 -0
  327. package/dist/modules/billing/migrations/Migration20261115000000_billing_invoice_ledger.js.map +7 -0
  328. package/dist/modules/billing/migrations/Migration20261116000000_billing_invoice_documents.js +47 -0
  329. package/dist/modules/billing/migrations/Migration20261116000000_billing_invoice_documents.js.map +7 -0
  330. package/dist/modules/billing/migrations/Migration20261117000000_billing_payments.js +89 -0
  331. package/dist/modules/billing/migrations/Migration20261117000000_billing_payments.js.map +7 -0
  332. package/dist/modules/billing/migrations/Migration20261118000000_billing_memos.js +17 -0
  333. package/dist/modules/billing/migrations/Migration20261118000000_billing_memos.js.map +7 -0
  334. package/dist/modules/billing/migrations/Migration20261119000000_billing_operator_feedback.js +27 -0
  335. package/dist/modules/billing/migrations/Migration20261119000000_billing_operator_feedback.js.map +7 -0
  336. package/dist/modules/billing/migrations/Migration20261120000000_billing_allocation_scope_indexes.js +29 -0
  337. package/dist/modules/billing/migrations/Migration20261120000000_billing_allocation_scope_indexes.js.map +7 -0
  338. package/dist/modules/billing/setup.js +7 -184
  339. package/dist/modules/billing/setup.js.map +2 -2
  340. package/dist/modules/billing/subscribers/credit-memo-auto-send.js +16 -0
  341. package/dist/modules/billing/subscribers/credit-memo-auto-send.js.map +7 -0
  342. package/dist/modules/billing/subscribers/debit-memo-apply-credit.js +16 -0
  343. package/dist/modules/billing/subscribers/debit-memo-apply-credit.js.map +7 -0
  344. package/dist/modules/billing/subscribers/debit-memo-auto-send.js +16 -0
  345. package/dist/modules/billing/subscribers/debit-memo-auto-send.js.map +7 -0
  346. package/dist/modules/billing/subscribers/invoice-apply-credit.js +34 -0
  347. package/dist/modules/billing/subscribers/invoice-apply-credit.js.map +7 -0
  348. package/dist/modules/billing/subscribers/invoice-auto-send.js +30 -0
  349. package/dist/modules/billing/subscribers/invoice-auto-send.js.map +7 -0
  350. package/dist/modules/billing/subscribers/payment-captured-to-paid.js +69 -33
  351. package/dist/modules/billing/subscribers/payment-captured-to-paid.js.map +2 -2
  352. package/dist/modules/billing/subscribers/prepaid-topup-captured.js +4 -6
  353. package/dist/modules/billing/subscribers/prepaid-topup-captured.js.map +2 -2
  354. package/dist/modules/billing/workers/reap-stale-bill-runs.js +2 -2
  355. package/dist/modules/billing/workers/reap-stale-bill-runs.js.map +2 -2
  356. package/generated/entities/billing_account/index.ts +26 -0
  357. package/generated/entities/billing_account_balance/index.ts +13 -0
  358. package/generated/entities/billing_account_transaction/index.ts +21 -0
  359. package/generated/entities/billing_account_usage/index.ts +18 -0
  360. package/generated/entities/billing_allocation/index.ts +18 -0
  361. package/generated/entities/billing_document_sequence/index.ts +11 -0
  362. package/generated/entities/billing_draft_invoice_edit/index.ts +14 -0
  363. package/generated/entities/billing_invoice/index.ts +38 -0
  364. package/generated/entities/billing_invoice_line/index.ts +24 -0
  365. package/generated/entities/billing_item/index.ts +26 -0
  366. package/generated/entities/billing_payment/index.ts +25 -0
  367. package/generated/entities/billing_payment_import/index.ts +14 -0
  368. package/generated/entities/billing_run/index.ts +20 -0
  369. package/generated/entities/billing_run_outcome/index.ts +18 -0
  370. package/generated/entities/billing_settings/index.ts +26 -0
  371. package/generated/entities/billing_statement/index.ts +22 -0
  372. package/generated/entities/billing_topup/index.ts +20 -0
  373. package/generated/entities.ids.generated.ts +35 -0
  374. package/package.json +15 -10
  375. package/src/modules/billing/__integration__/TC-BILL-004.spec.ts +170 -0
  376. package/src/modules/billing/__integration__/TC-BILL-005.spec.ts +134 -0
  377. package/src/modules/billing/__integration__/TC-BILL-006.spec.ts +101 -0
  378. package/src/modules/billing/__integration__/TC-BILL-007.spec.ts +140 -0
  379. package/src/modules/billing/__integration__/TC-BILL-008.spec.ts +108 -0
  380. package/src/modules/billing/__integration__/TC-BILL-009.spec.ts +113 -0
  381. package/src/modules/billing/__integration__/TC-BILL-010.spec.ts +118 -0
  382. package/src/modules/billing/__integration__/TC-BILL-011.spec.ts +142 -0
  383. package/src/modules/billing/__integration__/TC-BILL-012.spec.ts +115 -0
  384. package/src/modules/billing/__integration__/TC-BILL-013.spec.ts +118 -0
  385. package/src/modules/billing/__integration__/sellerSettings.ts +24 -0
  386. package/src/modules/billing/__tests__/commands/invoices.test.ts +437 -355
  387. package/src/modules/billing/__tests__/commands/itemsBulk.test.ts +33 -0
  388. package/src/modules/billing/__tests__/commands/memos.test.ts +205 -0
  389. package/src/modules/billing/__tests__/commands/payments.test.ts +241 -0
  390. package/src/modules/billing/__tests__/commands/runsDelete.test.ts +146 -0
  391. package/src/modules/billing/__tests__/commands/runsPostDrafts.test.ts +106 -0
  392. package/src/modules/billing/__tests__/commands/topups.test.ts +11 -0
  393. package/src/modules/billing/__tests__/entityRegistry.test.ts +326 -0
  394. package/src/modules/billing/__tests__/events.test.ts +142 -0
  395. package/src/modules/billing/__tests__/helpers/prepaidMockEm.ts +28 -11
  396. package/src/modules/billing/__tests__/lib/accountFinancials.test.ts +53 -0
  397. package/src/modules/billing/__tests__/lib/accountSummary.test.ts +97 -0
  398. package/src/modules/billing/__tests__/lib/allocation.test.ts +319 -0
  399. package/src/modules/billing/__tests__/lib/billRunEngine.test.ts +231 -20
  400. package/src/modules/billing/__tests__/lib/billingSettings.test.ts +109 -0
  401. package/src/modules/billing/__tests__/lib/customerLookup.test.ts +156 -0
  402. package/src/modules/billing/__tests__/lib/dueDate.test.ts +35 -0
  403. package/src/modules/billing/__tests__/lib/iban.test.ts +38 -0
  404. package/src/modules/billing/__tests__/lib/invoiceDelivery.test.ts +189 -0
  405. package/src/modules/billing/__tests__/lib/invoiceWriter.test.ts +212 -10
  406. package/src/modules/billing/__tests__/lib/itemBillingState.test.ts +42 -0
  407. package/src/modules/billing/__tests__/lib/itemPriceChange.test.ts +165 -0
  408. package/src/modules/billing/__tests__/lib/lineAmounts.test.ts +86 -0
  409. package/src/modules/billing/__tests__/lib/navigation.test.ts +71 -0
  410. package/src/modules/billing/__tests__/lib/numbering.test.ts +91 -0
  411. package/src/modules/billing/__tests__/lib/overdue.test.ts +36 -0
  412. package/src/modules/billing/__tests__/lib/paymentCsv.test.ts +148 -0
  413. package/src/modules/billing/__tests__/lib/paymentImport.test.ts +113 -0
  414. package/src/modules/billing/__tests__/lib/paymentsSample.test.ts +73 -0
  415. package/src/modules/billing/__tests__/lib/pdf/invoicePdf.test.ts +199 -0
  416. package/src/modules/billing/__tests__/lib/pdf/invoicePdfService.test.ts +147 -0
  417. package/src/modules/billing/__tests__/lib/prepaidPeriodClose.test.ts +374 -98
  418. package/src/modules/billing/__tests__/lib/prepaidTaxPoint.test.ts +118 -0
  419. package/src/modules/billing/__tests__/lib/seedsDemo.test.ts +53 -2
  420. package/src/modules/billing/__tests__/lib/sellerSettings.test.ts +28 -0
  421. package/src/modules/billing/__tests__/lib/servicePeriods.test.ts +190 -0
  422. package/src/modules/billing/__tests__/lib/topupCapture.test.ts +6 -28
  423. package/src/modules/billing/__tests__/lib/topupReceipt.test.ts +21 -52
  424. package/src/modules/billing/__tests__/lib/vat.test.ts +51 -0
  425. package/src/modules/billing/__tests__/package-isolation.test.ts +22 -8
  426. package/src/modules/billing/__tests__/setup.test.ts +13 -4
  427. package/src/modules/billing/__tests__/validators.test.ts +193 -3
  428. package/src/modules/billing/acl.ts +12 -0
  429. package/src/modules/billing/api/accounts/[id]/summary/route.ts +62 -0
  430. package/src/modules/billing/api/accounts/route.ts +58 -4
  431. package/src/modules/billing/api/export/account/[id]/route.ts +20 -18
  432. package/src/modules/billing/api/invoices/[id]/memos/route.ts +63 -0
  433. package/src/modules/billing/api/invoices/[id]/pdf/route.ts +79 -0
  434. package/src/modules/billing/api/invoices/[id]/route.ts +57 -70
  435. package/src/modules/billing/api/invoices/[id]/send/route.ts +127 -0
  436. package/src/modules/billing/api/invoices/add-line/route.ts +3 -3
  437. package/src/modules/billing/api/invoices/delete-draft/route.ts +33 -0
  438. package/src/modules/billing/api/invoices/edit-line/route.ts +4 -4
  439. package/src/modules/billing/api/invoices/post/route.ts +7 -6
  440. package/src/modules/billing/api/invoices/remove-line/route.ts +3 -3
  441. package/src/modules/billing/api/invoices/route.ts +81 -86
  442. package/src/modules/billing/api/items/bulk/route.ts +2 -1
  443. package/src/modules/billing/api/items/change-price/route.ts +54 -0
  444. package/src/modules/billing/api/items/route.ts +23 -7
  445. package/src/modules/billing/api/payment-imports/[id]/route.ts +49 -0
  446. package/src/modules/billing/api/payment-imports/route.ts +57 -0
  447. package/src/modules/billing/api/payments/[id]/route.ts +63 -0
  448. package/src/modules/billing/api/payments/allocate/route.ts +35 -0
  449. package/src/modules/billing/api/payments/assign/route.ts +36 -0
  450. package/src/modules/billing/api/payments/convert-to-topup/route.ts +35 -0
  451. package/src/modules/billing/api/payments/ignore/route.ts +35 -0
  452. package/src/modules/billing/api/payments/import/route.ts +72 -0
  453. package/src/modules/billing/api/payments/restore/route.ts +35 -0
  454. package/src/modules/billing/api/payments/route.ts +147 -0
  455. package/src/modules/billing/api/payments/unallocate/route.ts +35 -0
  456. package/src/modules/billing/api/payments/unassign/route.ts +35 -0
  457. package/src/modules/billing/api/run-outcomes/route.ts +50 -7
  458. package/src/modules/billing/api/runs/[id]/post-drafts/route.ts +71 -0
  459. package/src/modules/billing/api/runs/[id]/route.ts +59 -0
  460. package/src/modules/billing/api/runs/retry-failed/route.ts +4 -3
  461. package/src/modules/billing/api/runs/route.ts +17 -9
  462. package/src/modules/billing/api/settings/number-preview/route.ts +46 -0
  463. package/src/modules/billing/api/settings/route.ts +116 -0
  464. package/src/modules/billing/api/statements/route.ts +5 -0
  465. package/src/modules/billing/api/test-invoices/wipe/route.ts +2 -2
  466. package/src/modules/billing/backend/billing/accounts/[id]/page.tsx +151 -372
  467. package/src/modules/billing/backend/billing/accounts/create/page.tsx +6 -0
  468. package/src/modules/billing/backend/billing/accounts/page.tsx +71 -5
  469. package/src/modules/billing/backend/billing/invoices/[id]/page.tsx +445 -96
  470. package/src/modules/billing/backend/billing/invoices/page.tsx +8 -227
  471. package/src/modules/billing/backend/billing/items/[id]/page.tsx +75 -6
  472. package/src/modules/billing/backend/billing/items/create/page.tsx +13 -8
  473. package/src/modules/billing/backend/billing/items/page.tsx +19 -3
  474. package/src/modules/billing/backend/billing/payments/[id]/page.meta.ts +19 -0
  475. package/src/modules/billing/backend/billing/payments/[id]/page.tsx +415 -0
  476. package/src/modules/billing/backend/billing/payments/imports/[id]/page.meta.ts +19 -0
  477. package/src/modules/billing/backend/billing/payments/imports/[id]/page.tsx +106 -0
  478. package/src/modules/billing/backend/billing/payments/page.meta.ts +16 -0
  479. package/src/modules/billing/backend/billing/payments/page.tsx +56 -0
  480. package/src/modules/billing/backend/billing/runs/[id]/page.tsx +50 -19
  481. package/src/modules/billing/backend/billing/runs/page.tsx +60 -9
  482. package/src/modules/billing/backend/billing/statements/[id]/page.tsx +87 -6
  483. package/src/modules/billing/backend/billing/statements/page.tsx +2 -2
  484. package/src/modules/billing/backend/billing/topups/page.tsx +2 -2
  485. package/src/modules/billing/backend/billing/transactions/page.tsx +2 -2
  486. package/src/modules/billing/backend/billing/usage/create/page.tsx +3 -2
  487. package/src/modules/billing/backend/config/billing/page.meta.ts +21 -0
  488. package/src/modules/billing/backend/config/billing/page.tsx +549 -0
  489. package/src/modules/billing/ce.ts +8 -7
  490. package/src/modules/billing/cli.ts +31 -1
  491. package/src/modules/billing/commands/accounts.ts +6 -0
  492. package/src/modules/billing/commands/index.ts +3 -0
  493. package/src/modules/billing/commands/invoices.ts +371 -238
  494. package/src/modules/billing/commands/items.ts +143 -0
  495. package/src/modules/billing/commands/memos.ts +218 -0
  496. package/src/modules/billing/commands/payments.ts +428 -0
  497. package/src/modules/billing/commands/runs.ts +208 -6
  498. package/src/modules/billing/commands/settings.ts +77 -0
  499. package/src/modules/billing/commands/topups.ts +12 -3
  500. package/src/modules/billing/commands/transactions.ts +2 -2
  501. package/src/modules/billing/components/AccountForm.tsx +199 -53
  502. package/src/modules/billing/components/AccountInvoicesSection.tsx +75 -0
  503. package/src/modules/billing/components/AccountPaymentsSection.tsx +42 -0
  504. package/src/modules/billing/components/AccountPicker.tsx +70 -0
  505. package/src/modules/billing/components/AllocatePaymentDialog.tsx +167 -0
  506. package/src/modules/billing/components/BillingDataTable.tsx +34 -0
  507. package/src/modules/billing/components/BillingSettingsLink.tsx +25 -0
  508. package/src/modules/billing/components/ChangeItemPriceDialog.tsx +180 -0
  509. package/src/modules/billing/components/CreateMemoDialog.tsx +232 -0
  510. package/src/modules/billing/components/CustomerLabel.tsx +53 -0
  511. package/src/modules/billing/components/InvoicesTable.tsx +344 -0
  512. package/src/modules/billing/components/ItemForm.tsx +233 -44
  513. package/src/modules/billing/components/ItemPriceField.tsx +81 -0
  514. package/src/modules/billing/components/LineFormDialog.tsx +25 -1
  515. package/src/modules/billing/components/ManualPaymentDialog.tsx +140 -0
  516. package/src/modules/billing/components/MoneyInput.tsx +26 -0
  517. package/src/modules/billing/components/PaymentUploadDialog.tsx +148 -0
  518. package/src/modules/billing/components/PaymentsTable.tsx +213 -0
  519. package/src/modules/billing/components/PostRunDraftsButton.tsx +129 -0
  520. package/src/modules/billing/components/PrepaidPanel.tsx +20 -7
  521. package/src/modules/billing/components/RunCyclesSection.tsx +298 -0
  522. package/src/modules/billing/components/TestRunActions.tsx +152 -0
  523. package/src/modules/billing/components/account/AccountItemsTab.tsx +192 -0
  524. package/src/modules/billing/components/account/AccountRunBillingDialog.tsx +147 -0
  525. package/src/modules/billing/components/account/AccountRunsTab.tsx +201 -0
  526. package/src/modules/billing/components/account/AccountStatementsTab.tsx +120 -0
  527. package/src/modules/billing/components/account/AccountSummaryCards.tsx +153 -0
  528. package/src/modules/billing/components/account/AccountUsageTab.tsx +122 -0
  529. package/src/modules/billing/components/account/AccountView.tsx +101 -0
  530. package/src/modules/billing/components/account/accountRow.ts +70 -0
  531. package/src/modules/billing/components/customerNames.ts +62 -0
  532. package/src/modules/billing/data/entities.ts +685 -15
  533. package/src/modules/billing/data/entityIds.ts +25 -11
  534. package/src/modules/billing/data/validators.ts +388 -8
  535. package/src/modules/billing/events.ts +82 -3
  536. package/src/modules/billing/i18n/en.json +457 -21
  537. package/src/modules/billing/i18n/pl.json +457 -21
  538. package/src/modules/billing/index.ts +6 -2
  539. package/src/modules/billing/lib/accountFinancials.ts +84 -0
  540. package/src/modules/billing/lib/accountLock.ts +32 -0
  541. package/src/modules/billing/lib/accountStatus.ts +11 -9
  542. package/src/modules/billing/lib/accountSummary.ts +172 -0
  543. package/src/modules/billing/lib/allocation.ts +515 -0
  544. package/src/modules/billing/lib/allocationEvents.ts +26 -0
  545. package/src/modules/billing/lib/billPeriod.ts +19 -0
  546. package/src/modules/billing/lib/billRunEngine.ts +362 -162
  547. package/src/modules/billing/lib/billRunLabel.ts +1 -1
  548. package/src/modules/billing/lib/billingSettings.ts +145 -0
  549. package/src/modules/billing/lib/commandRoute.ts +112 -0
  550. package/src/modules/billing/lib/customerLookup.ts +157 -0
  551. package/src/modules/billing/lib/dateOnly.ts +22 -0
  552. package/src/modules/billing/lib/documentParties.ts +23 -0
  553. package/src/modules/billing/lib/documentTypes.ts +37 -0
  554. package/src/modules/billing/lib/dueDate.ts +26 -0
  555. package/src/modules/billing/lib/iban.ts +36 -0
  556. package/src/modules/billing/lib/invoiceDelivery.ts +197 -0
  557. package/src/modules/billing/lib/invoiceLanguages.ts +34 -0
  558. package/src/modules/billing/lib/invoiceWriter.ts +162 -148
  559. package/src/modules/billing/lib/itemBillingState.ts +67 -0
  560. package/src/modules/billing/lib/itemPriceChange.ts +56 -0
  561. package/src/modules/billing/lib/itemSelector.ts +4 -1
  562. package/src/modules/billing/lib/lineAmounts.ts +61 -0
  563. package/src/modules/billing/lib/memoGuards.ts +41 -0
  564. package/src/modules/billing/lib/navigation.ts +64 -0
  565. package/src/modules/billing/lib/numbering.ts +174 -0
  566. package/src/modules/billing/lib/overdue.ts +60 -0
  567. package/src/modules/billing/lib/paymentCsv.ts +171 -0
  568. package/src/modules/billing/lib/paymentGateway.ts +52 -0
  569. package/src/modules/billing/lib/paymentImport.ts +228 -0
  570. package/src/modules/billing/lib/paymentMatcher.ts +88 -0
  571. package/src/modules/billing/lib/pdf/attachmentStore.ts +60 -0
  572. package/src/modules/billing/lib/pdf/fonts/NotoSans-Bold.ttf +0 -0
  573. package/src/modules/billing/lib/pdf/fonts/NotoSans-Regular.ttf +0 -0
  574. package/src/modules/billing/lib/pdf/fonts/OFL.txt +93 -0
  575. package/src/modules/billing/lib/pdf/fonts/embeddedFonts.ts +9 -0
  576. package/src/modules/billing/lib/pdf/invoiceModel.ts +328 -0
  577. package/src/modules/billing/lib/pdf/invoicePdf.ts +216 -0
  578. package/src/modules/billing/lib/pdf/invoiceTemplate.ts +338 -0
  579. package/src/modules/billing/lib/prepaidConfig.ts +27 -36
  580. package/src/modules/billing/lib/prepaidConsume.ts +29 -6
  581. package/src/modules/billing/lib/prepaidPeriodClose.ts +410 -242
  582. package/src/modules/billing/lib/prepaidTaxPoint.ts +76 -0
  583. package/src/modules/billing/lib/seeds/demo.ts +79 -6
  584. package/src/modules/billing/lib/seeds/paymentsSample.ts +136 -0
  585. package/src/modules/billing/lib/seeds/sellerSettings.ts +78 -0
  586. package/src/modules/billing/lib/servicePeriods.ts +226 -0
  587. package/src/modules/billing/lib/tenantLock.ts +1 -1
  588. package/src/modules/billing/lib/testRunCleanup.ts +42 -0
  589. package/src/modules/billing/lib/topupCapture.ts +3 -4
  590. package/src/modules/billing/lib/topupReceipt.ts +70 -103
  591. package/src/modules/billing/lib/usageRater.ts +1 -1
  592. package/src/modules/billing/lib/usageRunner.ts +17 -5
  593. package/src/modules/billing/lib/vat.ts +56 -0
  594. package/src/modules/billing/migrations/Migration20261114000000_billing_customer_kind.ts +25 -0
  595. package/src/modules/billing/migrations/Migration20261114100000_billing_cycle_semantics.ts +37 -0
  596. package/src/modules/billing/migrations/Migration20261115000000_billing_invoice_ledger.ts +132 -0
  597. package/src/modules/billing/migrations/Migration20261116000000_billing_invoice_documents.ts +58 -0
  598. package/src/modules/billing/migrations/Migration20261117000000_billing_payments.ts +97 -0
  599. package/src/modules/billing/migrations/Migration20261118000000_billing_memos.ts +21 -0
  600. package/src/modules/billing/migrations/Migration20261119000000_billing_operator_feedback.ts +39 -0
  601. package/src/modules/billing/migrations/Migration20261120000000_billing_allocation_scope_indexes.ts +35 -0
  602. package/src/modules/billing/setup.ts +11 -237
  603. package/src/modules/billing/subscribers/credit-memo-auto-send.ts +15 -0
  604. package/src/modules/billing/subscribers/debit-memo-apply-credit.ts +15 -0
  605. package/src/modules/billing/subscribers/debit-memo-auto-send.ts +15 -0
  606. package/src/modules/billing/subscribers/invoice-apply-credit.ts +39 -0
  607. package/src/modules/billing/subscribers/invoice-auto-send.ts +46 -0
  608. package/src/modules/billing/subscribers/payment-captured-to-paid.ts +84 -62
  609. package/src/modules/billing/subscribers/prepaid-topup-captured.ts +4 -8
  610. package/src/modules/billing/workers/reap-stale-bill-runs.ts +4 -4
  611. package/dist/modules/billing/lib/invoiceStatus.js +0 -38
  612. package/dist/modules/billing/lib/invoiceStatus.js.map +0 -7
  613. package/src/modules/billing/__tests__/lib/invoiceStatus.test.ts +0 -97
  614. package/src/modules/billing/lib/invoiceStatus.ts +0 -61
@@ -15,10 +15,10 @@ import { metadata } from '../index'
15
15
 
16
16
  const PACKAGE_ROOT = path.resolve(__dirname, '..')
17
17
 
18
- // Must mirror peerDependencies in packages/billing/package.json (plus
19
- // relatives + node builtins). Adding a prefix here without adding it to
20
- // peerDependencies = silent runtime failure for consumers that don't have
21
- // the dep transitively.
18
+ // Must mirror peerDependencies + dependencies in packages/billing/package.json
19
+ // (plus relatives + node builtins). Adding a prefix here without adding it to
20
+ // package.json = silent runtime failure for consumers that don't have the dep
21
+ // transitively. `pdf-lib` / `@pdf-lib/` are regular dependencies (Spec B PDF).
22
22
  const ALLOWED_IMPORT_PREFIXES = [
23
23
  './',
24
24
  '../',
@@ -36,6 +36,8 @@ const ALLOWED_IMPORT_PREFIXES = [
36
36
  '@dainamite/',
37
37
  'node:',
38
38
  '@tanstack/',
39
+ 'pdf-lib',
40
+ '@pdf-lib/',
39
41
  ]
40
42
 
41
43
  const NODE_BUILTINS = new Set([
@@ -128,10 +130,22 @@ describe('@dainamite/billing package isolation', () => {
128
130
  }
129
131
  })
130
132
 
131
- it('declares all required modules in metadata.requires', () => {
132
- expect(metadata.requires).toEqual(
133
- expect.arrayContaining(['auth', 'directory', 'dictionaries', 'configs', 'sales']),
134
- )
133
+ it('requires only platform modules (Spec 0: no core business modules; Spec B: attachments)', () => {
134
+ expect(metadata.requires).toEqual(['auth', 'directory', 'attachments'])
135
+ })
136
+
137
+ it('never imports core sales / configs / dictionaries / payment_gateways (Spec 0)', () => {
138
+ const banned = new Set(['sales', 'configs', 'dictionaries', 'payment_gateways'])
139
+ const violations: string[] = []
140
+ for (const [file, specs] of importsByFile) {
141
+ for (const spec of specs) {
142
+ const subModule = extractCoreModuleSubpath(spec)
143
+ if (subModule && banned.has(subModule)) violations.push(` ${path.relative(PACKAGE_ROOT, file)} → ${spec}`)
144
+ }
145
+ }
146
+ if (violations.length > 0) {
147
+ throw new Error(`Billing must not depend on core business modules:\n${violations.join('\n')}`)
148
+ }
135
149
  })
136
150
 
137
151
  it('does not import from sibling app modules', () => {
@@ -16,9 +16,17 @@ import setup from '../setup'
16
16
  const featureIds = new Set<string>(features.map((f) => f.id))
17
17
 
18
18
  describe('billing setup — contract', () => {
19
- it('exports onTenantCreated and seedDefaults hooks', () => {
20
- expect(typeof setup.onTenantCreated).toBe('function')
19
+ it('exports a seedDefaults hook (billing settings) and no core-config tenant hook', () => {
21
20
  expect(typeof setup.seedDefaults).toBe('function')
21
+ expect(setup.onTenantCreated).toBeUndefined()
22
+ })
23
+
24
+ it('seedDefaults warms up the organization billing settings row', async () => {
25
+ const row = { id: 's-1' }
26
+ const em = { findOne: jest.fn(async () => row), execute: jest.fn() }
27
+ await setup.seedDefaults!({ em, tenantId: 't-1', organizationId: 'o-1' } as never)
28
+ expect(em.findOne).toHaveBeenCalledTimes(1)
29
+ expect(em.execute).not.toHaveBeenCalled()
22
30
  })
23
31
 
24
32
  it('does not declare seedExamples (billing ships no demo data)', () => {
@@ -77,8 +85,8 @@ describe('billing setup — contract', () => {
77
85
  })
78
86
 
79
87
  describe('billing acl — surface', () => {
80
- it('exports exactly 19 features (12 Phase 0 + 7 SPEC-002 prepaid)', () => {
81
- expect(features).toHaveLength(19)
88
+ it('exports exactly 27 features (12 Phase 0 + 7 SPEC-002 prepaid + 2 Spec 0 settings + 1 Spec B send + 3 Spec C payments + 1 Spec D memos + 1 Spec F run delete)', () => {
89
+ expect(features).toHaveLength(27)
82
90
  })
83
91
 
84
92
  it('all feature IDs are prefixed `billing.` (no leaking module boundary)', () => {
@@ -98,6 +106,7 @@ describe('billing acl — surface', () => {
98
106
  'billing.run.trigger',
99
107
  'billing.run.dry_run',
100
108
  'billing.run.view',
109
+ 'billing.run.delete',
101
110
  'billing.invoice.post',
102
111
  'billing.invoice.edit_draft',
103
112
  'billing.invoice.view',
@@ -20,6 +20,7 @@ import {
20
20
  rateJsonUsageVolume,
21
21
  validateRateJson,
22
22
  } from '../data/validators'
23
+ import { DEFAULT_INVOICE_LANGUAGE, SUPPORTED_INVOICE_LANGUAGES } from '../lib/invoiceLanguages'
23
24
 
24
25
  describe('rate_json — one_time', () => {
25
26
  it('accepts a positive amount', () => {
@@ -293,9 +294,6 @@ describe('exported enums', () => {
293
294
  ])
294
295
  })
295
296
 
296
- it('INVOICE_STATUSES matches the dictionary entries seeded by setup', () => {
297
- expect([...INVOICE_STATUSES]).toEqual(['draft', 'posted', 'paid', 'void'])
298
- })
299
297
  })
300
298
 
301
299
  // ─── Phase 1 — CRUD payload schemas ────────────────────────────────
@@ -304,6 +302,11 @@ import {
304
302
  billingAccountCreateSchema,
305
303
  billingAccountListQuerySchema,
306
304
  billingAccountUpdateSchema,
305
+ billingItemBulkCreateSchema,
306
+ billingRunTriggerSchema,
307
+ CHARGE_TIMING_RECURRING_ONLY_MESSAGE,
308
+ billingInvoiceListQuerySchema,
309
+ billingSettingsUpdateSchema,
307
310
  billingItemCreateSchema,
308
311
  billingItemListQuerySchema,
309
312
  billingItemUpdateSchema,
@@ -367,6 +370,45 @@ describe('billingAccountCreateSchema', () => {
367
370
  expect(() => billingAccountCreateSchema.parse(withoutTenant)).toThrow()
368
371
  void tenantId
369
372
  })
373
+ // Spec E — B2C accounts + invoice-language picklist.
374
+ it('defaults customerKind to company', () => {
375
+ expect(billingAccountCreateSchema.parse(validAccountCreate).customerKind).toBe('company')
376
+ })
377
+
378
+ it('accepts customerKind person', () => {
379
+ const parsed = billingAccountCreateSchema.parse({ ...validAccountCreate, customerKind: 'person' })
380
+ expect(parsed.customerKind).toBe('person')
381
+ })
382
+
383
+ it('rejects an unknown customerKind', () => {
384
+ expect(() =>
385
+ billingAccountCreateSchema.parse({ ...validAccountCreate, customerKind: 'household' }),
386
+ ).toThrow()
387
+ })
388
+
389
+ it('accepts every template-supported invoice language, case/space tolerant', () => {
390
+ for (const { code } of SUPPORTED_INVOICE_LANGUAGES) {
391
+ const parsed = billingAccountCreateSchema.parse({
392
+ ...validAccountCreate,
393
+ invoiceLanguage: ` ${code.toUpperCase()} `,
394
+ })
395
+ expect(parsed.invoiceLanguage).toBe(code)
396
+ }
397
+ })
398
+
399
+ it('rejects an invoice language the template does not support', () => {
400
+ expect(() =>
401
+ billingAccountCreateSchema.parse({ ...validAccountCreate, invoiceLanguage: 'de' }),
402
+ ).toThrow()
403
+ })
404
+
405
+ it('defaults invoiceLanguage when omitted', () => {
406
+ const { invoiceLanguage, ...withoutLanguage } = validAccountCreate
407
+ void invoiceLanguage
408
+ expect(billingAccountCreateSchema.parse(withoutLanguage).invoiceLanguage).toBe(
409
+ DEFAULT_INVOICE_LANGUAGE,
410
+ )
411
+ })
370
412
  })
371
413
 
372
414
  describe('billingAccountUpdateSchema', () => {
@@ -397,6 +439,16 @@ describe('billingAccountUpdateSchema', () => {
397
439
  it('does not declare customerId (immutable per spec)', () => {
398
440
  expect('customerId' in billingAccountUpdateSchema.shape).toBe(false)
399
441
  })
442
+
443
+ it('does not declare customerKind (immutable per spec)', () => {
444
+ expect('customerKind' in billingAccountUpdateSchema.shape).toBe(false)
445
+ })
446
+
447
+ it('validates invoiceLanguage against supported languages', () => {
448
+ const base = { tenantId: TENANT, organizationId: ORG, id: ACCOUNT }
449
+ expect(billingAccountUpdateSchema.parse({ ...base, invoiceLanguage: 'PL' }).invoiceLanguage).toBe('pl')
450
+ expect(() => billingAccountUpdateSchema.parse({ ...base, invoiceLanguage: 'fr' })).toThrow()
451
+ })
400
452
  })
401
453
 
402
454
  describe('billingAccountListQuerySchema', () => {
@@ -415,6 +467,11 @@ describe('billingAccountListQuerySchema', () => {
415
467
  expect(parsed.page).toBe(1)
416
468
  expect(parsed.pageSize).toBe(50)
417
469
  })
470
+
471
+ it('accepts a customerKind filter and rejects unknown kinds', () => {
472
+ expect(billingAccountListQuerySchema.parse({ customerKind: 'person' }).customerKind).toBe('person')
473
+ expect(() => billingAccountListQuerySchema.parse({ customerKind: 'robot' })).toThrow()
474
+ })
418
475
  })
419
476
 
420
477
  const validItemRecurring = {
@@ -592,3 +649,136 @@ describe('billingUsageListQuerySchema', () => {
592
649
  expect(() => billingUsageListQuerySchema.parse({ pageSize: '101' })).toThrow()
593
650
  })
594
651
  })
652
+
653
+ // ─── Spec A — charge timing, proration, no catch-up flag ─────────
654
+
655
+ describe('Spec A validators', () => {
656
+ const recurring = {
657
+ tenantId: TENANT,
658
+ organizationId: ORG,
659
+ billAccountId: ACCOUNT,
660
+ type: 'recurring' as const,
661
+ billStartDate: '2026-11-14',
662
+ description: 'Internet 300',
663
+ rateJson: { unit_price: 79 },
664
+ }
665
+
666
+ it('accepts chargeTiming / prorate on recurring items and leaves defaults to the command', () => {
667
+ expect(billingItemCreateSchema.parse(recurring)).not.toHaveProperty('chargeTiming')
668
+ const parsed = billingItemCreateSchema.parse({ ...recurring, chargeTiming: 'in_arrears', prorate: false })
669
+ expect(parsed).toMatchObject({ chargeTiming: 'in_arrears', prorate: false })
670
+ })
671
+
672
+ it('rejects an unknown charge timing', () => {
673
+ expect(() => billingItemCreateSchema.parse({ ...recurring, chargeTiming: 'whenever' })).toThrow()
674
+ })
675
+
676
+ it('rejects non-default timing / proration on non-recurring items', () => {
677
+ const oneTime = { ...recurring, type: 'one_time' as const, rateJson: { amount: 10 } }
678
+ expect(billingItemCreateSchema.parse({ ...oneTime, chargeTiming: 'in_advance', prorate: true })).toBeTruthy()
679
+ expect(() => billingItemCreateSchema.parse({ ...oneTime, chargeTiming: 'in_arrears' })).toThrow(
680
+ CHARGE_TIMING_RECURRING_ONLY_MESSAGE,
681
+ )
682
+ expect(() => billingItemCreateSchema.parse({ ...oneTime, prorate: false })).toThrow(
683
+ CHARGE_TIMING_RECURRING_ONLY_MESSAGE,
684
+ )
685
+ })
686
+
687
+ it('applies the same rule to bulk entries and allows both on update', () => {
688
+ const { tenantId, organizationId, ...entry } = recurring
689
+ expect(() =>
690
+ billingItemBulkCreateSchema.parse({
691
+ tenantId,
692
+ organizationId,
693
+ items: [{ ...entry, type: 'usage', uomCode: 'gb', rateJson: { unit_price: 1 }, prorate: false }],
694
+ }),
695
+ ).toThrow()
696
+ expect(
697
+ billingItemUpdateSchema.parse({ tenantId, organizationId, id: ACCOUNT, chargeTiming: 'in_arrears', prorate: false }),
698
+ ).toMatchObject({ chargeTiming: 'in_arrears', prorate: false })
699
+ })
700
+
701
+ it('strips a legacy catchUp flag from the run trigger', () => {
702
+ const parsed = billingRunTriggerSchema.parse({ tenantId: TENANT, organizationId: ORG, catchUp: true })
703
+ expect(parsed).not.toHaveProperty('catchUp')
704
+ expect(parsed.mode).toBe('real')
705
+ })
706
+ })
707
+
708
+ // ─── Spec 0 — ledger validators ──────────────────────────────────
709
+
710
+ describe('Spec 0 validators', () => {
711
+ it('invoice statuses drop void and add partially_paid / credited', () => {
712
+ expect(INVOICE_STATUSES).toEqual(['draft', 'posted', 'partially_paid', 'paid', 'credited'])
713
+ })
714
+
715
+ it('parses testRun literally (false stays false)', () => {
716
+ expect(billingInvoiceListQuerySchema.parse({ testRun: 'false' }).testRun).toBe(false)
717
+ expect(billingInvoiceListQuerySchema.parse({ testRun: 'true' }).testRun).toBe(true)
718
+ expect(billingInvoiceListQuerySchema.parse({}).testRun).toBeUndefined()
719
+ expect(() => billingInvoiceListQuerySchema.parse({ status: 'void' })).toThrow()
720
+ })
721
+
722
+ it('validates number masks on settings update', () => {
723
+ const base = { tenantId: TENANT, organizationId: ORG }
724
+ expect(
725
+ billingSettingsUpdateSchema.parse({ ...base, numberMasks: { invoice: 'FV/{YYYY}/{SEQUENCE_NUM_YEAR:5}' } }).numberMasks,
726
+ ).toEqual({ invoice: 'FV/{YYYY}/{SEQUENCE_NUM_YEAR:5}' })
727
+ expect(() => billingSettingsUpdateSchema.parse({ ...base, numberMasks: { invoice: 'FV/{SEQUENCE_NUM_MONTH}' } })).toThrow(
728
+ 'mask_month_scope_needs_year_and_month',
729
+ )
730
+ expect(() => billingSettingsUpdateSchema.parse({ ...base, numberMasks: { bogus: 'X{SEQUENCE_NUM}' } })).toThrow()
731
+ expect(() => billingSettingsUpdateSchema.parse({ ...base, topupTaxRate: 120 })).toThrow()
732
+ })
733
+ })
734
+
735
+ describe('Spec B validators', () => {
736
+ const base = { tenantId: TENANT, organizationId: ORG }
737
+ const item = {
738
+ ...base,
739
+ billAccountId: ACCOUNT,
740
+ type: 'recurring' as const,
741
+ billStartDate: '2026-11-14',
742
+ description: 'Internet 300',
743
+ rateJson: { unit_price: 79 },
744
+ }
745
+
746
+ it('item taxRate is optional on create (the command fills the default) and bounded 0–100', () => {
747
+ expect(billingItemCreateSchema.parse(item)).not.toHaveProperty('taxRate')
748
+ expect(billingItemCreateSchema.parse({ ...item, taxRate: '8' }).taxRate).toBe(8)
749
+ expect(() => billingItemCreateSchema.parse({ ...item, taxRate: -1 })).toThrow()
750
+ expect(() => billingItemCreateSchema.parse({ ...item, taxRate: 101 })).toThrow()
751
+ })
752
+
753
+ it('normalizes and checksum-validates the seller IBAN; empty clears it', () => {
754
+ expect(billingSettingsUpdateSchema.parse({ ...base, iban: 'pl61 1090 1014 0000 0712 1981 2874' }).iban).toBe(
755
+ 'PL61109010140000071219812874',
756
+ )
757
+ expect(billingSettingsUpdateSchema.parse({ ...base, iban: '' }).iban).toBeNull()
758
+ expect(() => billingSettingsUpdateSchema.parse({ ...base, iban: 'PL61109010140000071219812875' })).toThrow(
759
+ 'billing.settings.error.iban_invalid',
760
+ )
761
+ expect(() => billingSettingsUpdateSchema.parse({ ...base, bic: 'XX' })).toThrow('billing.settings.error.bic_invalid')
762
+ })
763
+
764
+ it('validates seller address, terms and default rate', () => {
765
+ const parsed = billingSettingsUpdateSchema.parse({
766
+ ...base,
767
+ legalName: ' Seller ',
768
+ taxId: '',
769
+ sellerAddress: { line1: 'ul. A 1', city: 'Kraków', postal_code: '30-001', country: 'PL' },
770
+ defaultPaymentTermsDays: '30',
771
+ defaultTaxRate: 23,
772
+ })
773
+ expect(parsed).toMatchObject({ legalName: 'Seller', taxId: null, defaultPaymentTermsDays: 30, defaultTaxRate: 23 })
774
+ expect(() => billingSettingsUpdateSchema.parse({ ...base, sellerAddress: { line1: 'x' } })).toThrow()
775
+ expect(() => billingSettingsUpdateSchema.parse({ ...base, defaultPaymentTermsDays: 400 })).toThrow()
776
+ })
777
+
778
+ it('accepts overdue / due-date filters on the invoice list', () => {
779
+ const parsed = billingInvoiceListQuerySchema.parse({ overdue: 'true', dueFrom: '2026-11-01', dueTo: '2026-11-30' })
780
+ expect(parsed).toMatchObject({ overdue: true, dueFrom: '2026-11-01', dueTo: '2026-11-30' })
781
+ expect(() => billingInvoiceListQuerySchema.parse({ dueFrom: '01.11.2026' })).toThrow()
782
+ })
783
+ })
784
+
@@ -8,9 +8,18 @@ export const features = [
8
8
  { id: 'billing.run.trigger', title: 'Trigger Bill Run', module: 'billing' },
9
9
  { id: 'billing.run.dry_run', title: 'Trigger Bill Run (dry-run)', module: 'billing' },
10
10
  { id: 'billing.run.view', title: 'View Bill Run History', module: 'billing' },
11
+ // Spec F — delete test / dry runs (real runs are never deleted)
12
+ { id: 'billing.run.delete', title: 'Delete Test / Dry Bill Runs', module: 'billing' },
11
13
  { id: 'billing.invoice.post', title: 'Post Draft Invoice', module: 'billing' },
12
14
  { id: 'billing.invoice.edit_draft', title: 'Edit Draft Invoice', module: 'billing' },
13
15
  { id: 'billing.invoice.view', title: 'View Billing Invoices', module: 'billing' },
16
+ { id: 'billing.invoice.send', title: 'Email Billing Invoices', module: 'billing' },
17
+ // Spec D — corrective documents
18
+ { id: 'billing.invoice.correct', title: 'Create Credit / Debit Memos', module: 'billing' },
19
+ // Spec C — payments
20
+ { id: 'billing.payment.view', title: 'View Billing Payments', module: 'billing' },
21
+ { id: 'billing.payment.manage', title: 'Manage Billing Payments (assign, allocate, ignore, convert)', module: 'billing' },
22
+ { id: 'billing.payment.import', title: 'Import Bank Payments (CSV)', module: 'billing' },
14
23
  // ─── Prepaid balance billing (SPEC-002) ──────────────────────
15
24
  { id: 'billing.balance.view', title: 'View Balance & Transactions', module: 'billing' },
16
25
  { id: 'billing.balance.adjust', title: 'Adjust Balance (manual credit/debit)', module: 'billing' },
@@ -19,6 +28,9 @@ export const features = [
19
28
  { id: 'billing.statement.view', title: 'View Consumption Statements', module: 'billing' },
20
29
  { id: 'billing.statement.generate', title: 'Generate Consumption Statement', module: 'billing' },
21
30
  { id: 'billing.credit.view', title: 'View Account Credit Status', module: 'billing' },
31
+ // ─── Billing settings (Spec 0) ───────────────────────────────
32
+ { id: 'billing.settings.view', title: 'View Billing Settings', module: 'billing' },
33
+ { id: 'billing.settings.manage', title: 'Manage Billing Settings', module: 'billing' },
22
34
  ] as const
23
35
 
24
36
  export default features
@@ -0,0 +1,62 @@
1
+ import { NextResponse } from 'next/server'
2
+ import type { EntityManager } from '@mikro-orm/postgresql'
3
+ import { createRequestContainer } from '@open-mercato/shared/lib/di/container'
4
+ import { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'
5
+ import { BillingAccount } from '../../../../data/entities'
6
+ import { getAccountWorkspaceSummary } from '../../../../lib/accountSummary'
7
+
8
+ /**
9
+ * `GET /api/billing/accounts/[id]/summary` — what the customer owes (Spec B
10
+ * AR summary; Spec E extends the same endpoint for the account workspace).
11
+ * One aggregate query; see `lib/accountSummary.ts`.
12
+ */
13
+
14
+ export const metadata = {
15
+ GET: { requireAuth: true, requireFeatures: ['billing.account.view'] },
16
+ }
17
+
18
+ export async function GET(req: Request, { params }: { params: Promise<{ id: string }> }) {
19
+ try {
20
+ const container = await createRequestContainer()
21
+ const auth = await getAuthFromRequest(req)
22
+ if (!auth || !auth.tenantId) {
23
+ return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
24
+ }
25
+ const organizationId = (auth as { orgId?: string }).orgId ?? null
26
+ if (!organizationId) {
27
+ return NextResponse.json({ error: 'Organization scope required' }, { status: 403 })
28
+ }
29
+ const { id: accountId } = await params
30
+ const em = (container.resolve('em') as EntityManager).fork()
31
+ const account = await em.findOne(BillingAccount, {
32
+ id: accountId,
33
+ tenantId: auth.tenantId,
34
+ organizationId,
35
+ deletedAt: null,
36
+ })
37
+ if (!account) {
38
+ return NextResponse.json({ error: 'Account not found' }, { status: 404 })
39
+ }
40
+ return NextResponse.json(await getAccountWorkspaceSummary(em, account))
41
+ } catch (err) {
42
+ console.error('[billing/accounts/summary.GET]', err)
43
+ return NextResponse.json({ error: 'Internal error' }, { status: 500 })
44
+ }
45
+ }
46
+
47
+ export const openApi = {
48
+ methods: {
49
+ GET: {
50
+ tags: ['Billing'],
51
+ summary: 'Get a billing account receivables summary',
52
+ parameters: [{ name: 'id', in: 'path', required: true, schema: { type: 'string', format: 'uuid' } }],
53
+ description:
54
+ 'Returns `{ bill_account_id, currency_code, open_amount, overdue_amount, overdue_count, ' +
55
+ 'credit_amount }` over posted / partially paid invoices and debit memos (test runs excluded). ' +
56
+ 'Overdue = past due date with outstanding > 0. `credit_amount` = unallocated payments + open credit memos. ' +
57
+ 'Spec F (account workspace) adds `billing_mode`, `bill_cycle`, `next_bill_date`, `last_invoice` ' +
58
+ '(`{ id, number, issue_date, total_gross }` or null) and, for prepaid accounts, `prepaid { balance, ' +
59
+ 'balance_status, credit_limit, last_statement }` (null for postpaid).',
60
+ },
61
+ },
62
+ }
@@ -2,7 +2,13 @@ import { z } from 'zod'
2
2
  import { makeCrudRoute } from '@open-mercato/shared/lib/crud/factory'
3
3
  import { withScopedPayload } from '@open-mercato/shared/lib/api/scoped'
4
4
  import { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'
5
+ import type { EntityManager } from '@mikro-orm/postgresql'
6
+ import type { AwilixContainer } from 'awilix'
5
7
  import { BillingAccount } from '../../data/entities'
8
+ import { fetchAccountFinancials, fetchOverdueAccountIds, financialsOrZero } from '../../lib/accountFinancials'
9
+
10
+ /** A uuid no row has — narrows an `$in` filter to nothing. */
11
+ const NO_MATCH_ID = '00000000-0000-4000-8000-000000000000'
6
12
  import { billingEntityIds } from '../../data/entityIds'
7
13
  import {
8
14
  billingAccountCreateSchema,
@@ -33,6 +39,7 @@ export const metadata = routeMetadata
33
39
  const billingAccountListItemSchema = z.object({
34
40
  id: z.string().uuid(),
35
41
  customer_id: z.string(),
42
+ customer_kind: z.enum(['company', 'person']),
36
43
  name: z.string(),
37
44
  currency_code: z.string(),
38
45
  bill_cycle: z.string(),
@@ -45,6 +52,11 @@ const billingAccountListItemSchema = z.object({
45
52
  last_bill_date: z.string().nullable(),
46
53
  billing_mode: z.string(),
47
54
  credit_limit: z.string(),
55
+ payment_terms_days: z.number().int().nullable(),
56
+ auto_send_invoice: z.boolean(),
57
+ /** Spec F (F8): Σ outstanding of open receivables and its overdue subset (batched per page). */
58
+ balance_due: z.string(),
59
+ overdue_amount: z.string(),
48
60
  is_active: z.boolean(),
49
61
  organization_id: z.string().uuid(),
50
62
  tenant_id: z.string().uuid(),
@@ -71,6 +83,7 @@ const crud = makeCrudRoute({
71
83
  fields: [
72
84
  'id',
73
85
  'customer_id',
86
+ 'customer_kind',
74
87
  'name',
75
88
  'currency_code',
76
89
  'bill_cycle',
@@ -83,6 +96,8 @@ const crud = makeCrudRoute({
83
96
  'last_bill_date',
84
97
  'billing_mode',
85
98
  'credit_limit',
99
+ 'payment_terms_days',
100
+ 'auto_send_invoice',
86
101
  'is_active',
87
102
  'organization_id',
88
103
  'tenant_id',
@@ -95,16 +110,28 @@ const crud = makeCrudRoute({
95
110
  updatedAt: 'updated_at',
96
111
  nextBillDate: 'next_bill_date',
97
112
  },
98
- buildFilters: async (query) => {
113
+ buildFilters: async (query, ctx) => {
99
114
  const filters: Record<string, unknown> = {}
115
+ // Spec F (F8): accounts with an overdue receivable — one indexed
116
+ // DISTINCT over billing_invoices, intersected with any `id` filter.
117
+ if (query.hasOverdue === true && ctx.auth?.tenantId) {
118
+ const organizationIds = ctx.organizationIds ?? (ctx.selectedOrganizationId ? [ctx.selectedOrganizationId] : [])
119
+ const em = ctx.container.resolve<EntityManager>('em')
120
+ const overdueIds = await fetchOverdueAccountIds(em, { tenantId: ctx.auth.tenantId, organizationIds })
121
+ filters.id = { $in: overdueIds.length > 0 ? overdueIds : [NO_MATCH_ID] }
122
+ }
100
123
  // `?id=<uuid>` narrows the list to one row — the detail page
101
124
  // reads a single account through this filter.
102
125
  if (typeof query.id === 'string' && query.id) {
103
- filters.id = { $eq: query.id }
126
+ const current = filters.id as { $in?: string[] } | undefined
127
+ filters.id = current?.$in ? { $in: current.$in.includes(query.id) ? [query.id] : [NO_MATCH_ID] } : { $eq: query.id }
104
128
  }
105
129
  if (typeof query.customerId === 'string' && query.customerId) {
106
130
  filters.customer_id = { $eq: query.customerId }
107
131
  }
132
+ if (typeof query.customerKind === 'string' && query.customerKind) {
133
+ filters.customer_kind = { $eq: query.customerKind }
134
+ }
108
135
  if (typeof query.currencyCode === 'string' && query.currencyCode) {
109
136
  filters.currency_code = { $eq: query.currencyCode.toUpperCase() }
110
137
  }
@@ -124,6 +151,30 @@ const crud = makeCrudRoute({
124
151
  return filters
125
152
  },
126
153
  },
154
+ hooks: {
155
+ // Spec F (F8): balance due / overdue per row — one GROUP BY for the page.
156
+ afterList: async (payload: unknown, ctx: unknown) => {
157
+ const items = ((payload as { items?: unknown[] } | null)?.items ?? []) as Array<Record<string, unknown>>
158
+ if (items.length === 0) return
159
+ const first = items[0]
160
+ const tenantId = typeof first.tenant_id === 'string' ? first.tenant_id : null
161
+ const organizationId = typeof first.organization_id === 'string' ? first.organization_id : null
162
+ const ids = items.map((row) => row.id).filter((id): id is string => typeof id === 'string')
163
+ const financials =
164
+ tenantId && organizationId
165
+ ? await fetchAccountFinancials(
166
+ (ctx as { container: AwilixContainer }).container.resolve<EntityManager>('em'),
167
+ { tenantId, organizationId },
168
+ ids,
169
+ )
170
+ : new Map()
171
+ for (const row of items) {
172
+ const values = financialsOrZero(financials, String(row.id))
173
+ row.balance_due = values.balance_due
174
+ row.overdue_amount = values.overdue_amount
175
+ }
176
+ },
177
+ },
127
178
  actions: {
128
179
  create: {
129
180
  commandId: 'billing.accounts.create',
@@ -190,12 +241,15 @@ export const openApi = createBillingCrudOpenApi({
190
241
  create: {
191
242
  schema: billingAccountCreateSchema,
192
243
  responseSchema: defaultCreateResponseSchema,
193
- description: 'Creates a new billing account for a customer.',
244
+ description:
245
+ 'Creates a new billing account for a customer — a company or a person (`customerKind`, default `company`). ' +
246
+ '`invoiceLanguage` must be a language supported by the invoice template (`en`, `pl`; default `en`).',
194
247
  },
195
248
  update: {
196
249
  schema: billingAccountUpdateSchema,
197
250
  responseSchema: defaultOkResponseSchema,
198
- description: 'Updates a billing account. `currencyCode` and `customerId` are immutable.',
251
+ description:
252
+ 'Updates a billing account. `currencyCode`, `customerId` and `customerKind` are immutable.',
199
253
  },
200
254
  del: {
201
255
  schema: z.object({ id: z.string().uuid() }),
@@ -10,8 +10,8 @@ import {
10
10
  BillingItem,
11
11
  BillingStatement,
12
12
  BillingTopup,
13
- BillRunOutcome,
14
- DraftInvoiceEdit,
13
+ BillingRunOutcome,
14
+ BillingDraftInvoiceEdit,
15
15
  } from '../../../../data/entities'
16
16
 
17
17
  /**
@@ -22,10 +22,9 @@ import {
22
22
  * - The account row itself.
23
23
  * - Every active + soft-deleted `BillingItem` for the account.
24
24
  * - Every `BillingAccountUsage` record.
25
- * - Every `BillRunOutcome` row referencing the account.
26
- * - Every `core/sales` invoice the engine emitted for the account
27
- * (matched via `metadata->>'bill_account_id'`).
28
- * - Every `DraftInvoiceEdit` audit row for those invoices.
25
+ * - Every `BillingRunOutcome` row referencing the account.
26
+ * - Every billing document (`billing_invoices`) of the account.
27
+ * - Every `BillingDraftInvoiceEdit` audit row for those invoices.
29
28
  *
30
29
  * Scope: the caller's auth tenant/organization is the authority — a
31
30
  * 404 is returned even for valid UUIDs that belong to a different
@@ -108,7 +107,7 @@ export async function GET(
108
107
  { limit: EXPORT_HARD_LIMIT, orderBy: { periodEnd: 'DESC' } },
109
108
  ),
110
109
  em.find(
111
- BillRunOutcome,
110
+ BillingRunOutcome,
112
111
  {
113
112
  tenantId,
114
113
  organizationId,
@@ -154,18 +153,18 @@ export async function GET(
154
153
  ),
155
154
  ])
156
155
 
157
- // Invoices created in the window. The `metadata->>'bill_account_id'`
158
- // predicate keeps non-billing core/sales invoices out.
156
+ // Billing documents created in the window (Spec 0: billing_invoices).
159
157
  const invoiceRows = (await em.execute(
160
- `SELECT id, invoice_number, status, status_entry_id, issue_date, due_date,
161
- currency_code, subtotal_net_amount, grand_total_net_amount,
162
- grand_total_gross_amount, paid_total_amount, outstanding_amount,
163
- metadata, created_at, updated_at, deleted_at
164
- FROM sales_invoices
158
+ `SELECT id, number, document_type, series, status, test_run, bill_run_id, bill_date,
159
+ period_start, period_end, issue_date, due_date, posted_at, currency_code,
160
+ subtotal_net, tax_total, total_gross, paid_total, credited_total, outstanding,
161
+ corrects_invoice_id, correction_reason, topup_id, buyer_snapshot, seller_snapshot,
162
+ metadata, created_at, updated_at
163
+ FROM billing_invoices
165
164
  WHERE tenant_id = ?
166
165
  AND organization_id = ?
167
166
  AND deleted_at IS NULL
168
- AND metadata->>'bill_account_id' = ?
167
+ AND bill_account_id = ?
169
168
  AND created_at >= ?
170
169
  AND created_at <= ?
171
170
  ORDER BY created_at DESC
@@ -177,7 +176,7 @@ export async function GET(
177
176
  const draftEdits =
178
177
  invoiceIds.length > 0
179
178
  ? await em.find(
180
- DraftInvoiceEdit,
179
+ BillingDraftInvoiceEdit,
181
180
  {
182
181
  tenantId,
183
182
  organizationId,
@@ -190,7 +189,10 @@ export async function GET(
190
189
  return NextResponse.json({
191
190
  exportedAt: new Date().toISOString(),
192
191
  // v2 adds prepaid balance / transactions / top-ups / statements (SPEC-002).
193
- schemaVersion: 2,
192
+ // v3 (Spec 0): invoices come from billing_invoices with billing field names.
193
+ // v4 (Spec B): items carry taxRate; the account carries paymentTermsDays /
194
+ // autoSendInvoice; invoice metadata may carry draft_number / deliveries.
195
+ schemaVersion: 4,
194
196
  tenantId,
195
197
  organizationId,
196
198
  window: {
@@ -272,7 +274,7 @@ export const openApi = {
272
274
  },
273
275
  ],
274
276
  description:
275
- "Returns a JSON dump of a single Billing Account: the account itself, every Billing Item (no time cap — items often outlive a single export window), and the Usage records / BillRunOutcomes / emitted core/sales invoices / DraftInvoiceEdit rows whose timestamps fall in the [since, until] window (defaults to the last 12 months). Each collection is independently capped by EXPORT_HARD_LIMIT = 50,000 rows. Lifetime dumps for outlier accounts need a follow-up chunked background-job approach — out of scope for this v1 endpoint.",
277
+ "Returns a JSON dump of a single Billing Account: the account itself, every Billing Item (no time cap — items often outlive a single export window), and the Usage records / BillRunOutcomes / emitted core/sales invoices / BillingDraftInvoiceEdit rows whose timestamps fall in the [since, until] window (defaults to the last 12 months). Each collection is independently capped by EXPORT_HARD_LIMIT = 50,000 rows. Lifetime dumps for outlier accounts need a follow-up chunked background-job approach — out of scope for this v1 endpoint.",
276
278
  },
277
279
  },
278
280
  }