@dainamite/billing 0.20.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 (598) hide show
  1. package/CHANGELOG.md +90 -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 +46 -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 +69 -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/en.json +457 -21
  217. package/dist/modules/billing/i18n/pl.json +457 -21
  218. package/dist/modules/billing/index.js +6 -2
  219. package/dist/modules/billing/index.js.map +2 -2
  220. package/dist/modules/billing/lib/accountFinancials.js +58 -0
  221. package/dist/modules/billing/lib/accountFinancials.js.map +7 -0
  222. package/dist/modules/billing/lib/accountLock.js +14 -0
  223. package/dist/modules/billing/lib/accountLock.js.map +7 -0
  224. package/dist/modules/billing/lib/accountStatus.js +9 -7
  225. package/dist/modules/billing/lib/accountStatus.js.map +2 -2
  226. package/dist/modules/billing/lib/accountSummary.js +106 -0
  227. package/dist/modules/billing/lib/accountSummary.js.map +7 -0
  228. package/dist/modules/billing/lib/allocation.js +356 -0
  229. package/dist/modules/billing/lib/allocation.js.map +7 -0
  230. package/dist/modules/billing/lib/allocationEvents.js +22 -0
  231. package/dist/modules/billing/lib/allocationEvents.js.map +7 -0
  232. package/dist/modules/billing/lib/billPeriod.js +15 -1
  233. package/dist/modules/billing/lib/billPeriod.js.map +2 -2
  234. package/dist/modules/billing/lib/billRunEngine.js +237 -102
  235. package/dist/modules/billing/lib/billRunEngine.js.map +2 -2
  236. package/dist/modules/billing/lib/billingSettings.js +116 -0
  237. package/dist/modules/billing/lib/billingSettings.js.map +7 -0
  238. package/dist/modules/billing/lib/commandRoute.js +81 -0
  239. package/dist/modules/billing/lib/commandRoute.js.map +7 -0
  240. package/dist/modules/billing/lib/customerLookup.js +97 -0
  241. package/dist/modules/billing/lib/customerLookup.js.map +7 -0
  242. package/dist/modules/billing/lib/dateOnly.js +13 -0
  243. package/dist/modules/billing/lib/dateOnly.js.map +7 -0
  244. package/dist/modules/billing/lib/documentParties.js +16 -0
  245. package/dist/modules/billing/lib/documentParties.js.map +7 -0
  246. package/dist/modules/billing/lib/documentTypes.js +27 -0
  247. package/dist/modules/billing/lib/documentTypes.js.map +7 -0
  248. package/dist/modules/billing/lib/dueDate.js +18 -0
  249. package/dist/modules/billing/lib/dueDate.js.map +7 -0
  250. package/dist/modules/billing/lib/iban.js +29 -0
  251. package/dist/modules/billing/lib/iban.js.map +7 -0
  252. package/dist/modules/billing/lib/invoiceDelivery.js +131 -0
  253. package/dist/modules/billing/lib/invoiceDelivery.js.map +7 -0
  254. package/dist/modules/billing/lib/invoiceLanguages.js +16 -0
  255. package/dist/modules/billing/lib/invoiceLanguages.js.map +7 -0
  256. package/dist/modules/billing/lib/invoiceWriter.js +107 -99
  257. package/dist/modules/billing/lib/invoiceWriter.js.map +2 -2
  258. package/dist/modules/billing/lib/itemBillingState.js +27 -0
  259. package/dist/modules/billing/lib/itemBillingState.js.map +7 -0
  260. package/dist/modules/billing/lib/itemPriceChange.js +18 -0
  261. package/dist/modules/billing/lib/itemPriceChange.js.map +7 -0
  262. package/dist/modules/billing/lib/itemSelector.js.map +2 -2
  263. package/dist/modules/billing/lib/lineAmounts.js +32 -0
  264. package/dist/modules/billing/lib/lineAmounts.js.map +7 -0
  265. package/dist/modules/billing/lib/memoGuards.js +25 -0
  266. package/dist/modules/billing/lib/memoGuards.js.map +7 -0
  267. package/dist/modules/billing/lib/navigation.js +48 -0
  268. package/dist/modules/billing/lib/navigation.js.map +7 -0
  269. package/dist/modules/billing/lib/numbering.js +120 -0
  270. package/dist/modules/billing/lib/numbering.js.map +7 -0
  271. package/dist/modules/billing/lib/overdue.js +36 -0
  272. package/dist/modules/billing/lib/overdue.js.map +7 -0
  273. package/dist/modules/billing/lib/paymentCsv.js +125 -0
  274. package/dist/modules/billing/lib/paymentCsv.js.map +7 -0
  275. package/dist/modules/billing/lib/paymentGateway.js +15 -0
  276. package/dist/modules/billing/lib/paymentGateway.js.map +7 -0
  277. package/dist/modules/billing/lib/paymentImport.js +164 -0
  278. package/dist/modules/billing/lib/paymentImport.js.map +7 -0
  279. package/dist/modules/billing/lib/paymentMatcher.js +36 -0
  280. package/dist/modules/billing/lib/paymentMatcher.js.map +7 -0
  281. package/dist/modules/billing/lib/pdf/attachmentStore.js +46 -0
  282. package/dist/modules/billing/lib/pdf/attachmentStore.js.map +7 -0
  283. package/dist/modules/billing/lib/pdf/fonts/embeddedFonts.js +7 -0
  284. package/dist/modules/billing/lib/pdf/fonts/embeddedFonts.js.map +7 -0
  285. package/dist/modules/billing/lib/pdf/invoiceModel.js +194 -0
  286. package/dist/modules/billing/lib/pdf/invoiceModel.js.map +7 -0
  287. package/dist/modules/billing/lib/pdf/invoicePdf.js +165 -0
  288. package/dist/modules/billing/lib/pdf/invoicePdf.js.map +7 -0
  289. package/dist/modules/billing/lib/pdf/invoiceTemplate.js +274 -0
  290. package/dist/modules/billing/lib/pdf/invoiceTemplate.js.map +7 -0
  291. package/dist/modules/billing/lib/prepaidConfig.js +17 -25
  292. package/dist/modules/billing/lib/prepaidConfig.js.map +2 -2
  293. package/dist/modules/billing/lib/prepaidConsume.js +26 -7
  294. package/dist/modules/billing/lib/prepaidConsume.js.map +2 -2
  295. package/dist/modules/billing/lib/prepaidPeriodClose.js +277 -158
  296. package/dist/modules/billing/lib/prepaidPeriodClose.js.map +2 -2
  297. package/dist/modules/billing/lib/prepaidTaxPoint.js +37 -0
  298. package/dist/modules/billing/lib/prepaidTaxPoint.js.map +7 -0
  299. package/dist/modules/billing/lib/seeds/demo.js +51 -3
  300. package/dist/modules/billing/lib/seeds/demo.js.map +2 -2
  301. package/dist/modules/billing/lib/seeds/paymentsSample.js +93 -0
  302. package/dist/modules/billing/lib/seeds/paymentsSample.js.map +7 -0
  303. package/dist/modules/billing/lib/seeds/sellerSettings.js +41 -0
  304. package/dist/modules/billing/lib/seeds/sellerSettings.js.map +7 -0
  305. package/dist/modules/billing/lib/servicePeriods.js +121 -0
  306. package/dist/modules/billing/lib/servicePeriods.js.map +7 -0
  307. package/dist/modules/billing/lib/testRunCleanup.js +24 -0
  308. package/dist/modules/billing/lib/testRunCleanup.js.map +7 -0
  309. package/dist/modules/billing/lib/topupCapture.js +2 -2
  310. package/dist/modules/billing/lib/topupCapture.js.map +2 -2
  311. package/dist/modules/billing/lib/topupReceipt.js +58 -79
  312. package/dist/modules/billing/lib/topupReceipt.js.map +2 -2
  313. package/dist/modules/billing/lib/usageRater.js.map +1 -1
  314. package/dist/modules/billing/lib/usageRunner.js +14 -6
  315. package/dist/modules/billing/lib/usageRunner.js.map +2 -2
  316. package/dist/modules/billing/lib/vat.js +39 -0
  317. package/dist/modules/billing/lib/vat.js.map +7 -0
  318. package/dist/modules/billing/migrations/Migration20261114000000_billing_customer_kind.js +15 -0
  319. package/dist/modules/billing/migrations/Migration20261114000000_billing_customer_kind.js.map +7 -0
  320. package/dist/modules/billing/migrations/Migration20261114100000_billing_cycle_semantics.js +25 -0
  321. package/dist/modules/billing/migrations/Migration20261114100000_billing_cycle_semantics.js.map +7 -0
  322. package/dist/modules/billing/migrations/Migration20261115000000_billing_invoice_ledger.js +115 -0
  323. package/dist/modules/billing/migrations/Migration20261115000000_billing_invoice_ledger.js.map +7 -0
  324. package/dist/modules/billing/migrations/Migration20261116000000_billing_invoice_documents.js +47 -0
  325. package/dist/modules/billing/migrations/Migration20261116000000_billing_invoice_documents.js.map +7 -0
  326. package/dist/modules/billing/migrations/Migration20261117000000_billing_payments.js +89 -0
  327. package/dist/modules/billing/migrations/Migration20261117000000_billing_payments.js.map +7 -0
  328. package/dist/modules/billing/migrations/Migration20261118000000_billing_memos.js +17 -0
  329. package/dist/modules/billing/migrations/Migration20261118000000_billing_memos.js.map +7 -0
  330. package/dist/modules/billing/migrations/Migration20261119000000_billing_operator_feedback.js +27 -0
  331. package/dist/modules/billing/migrations/Migration20261119000000_billing_operator_feedback.js.map +7 -0
  332. package/dist/modules/billing/migrations/Migration20261120000000_billing_allocation_scope_indexes.js +29 -0
  333. package/dist/modules/billing/migrations/Migration20261120000000_billing_allocation_scope_indexes.js.map +7 -0
  334. package/dist/modules/billing/setup.js +7 -184
  335. package/dist/modules/billing/setup.js.map +2 -2
  336. package/dist/modules/billing/subscribers/credit-memo-auto-send.js +16 -0
  337. package/dist/modules/billing/subscribers/credit-memo-auto-send.js.map +7 -0
  338. package/dist/modules/billing/subscribers/debit-memo-apply-credit.js +16 -0
  339. package/dist/modules/billing/subscribers/debit-memo-apply-credit.js.map +7 -0
  340. package/dist/modules/billing/subscribers/debit-memo-auto-send.js +16 -0
  341. package/dist/modules/billing/subscribers/debit-memo-auto-send.js.map +7 -0
  342. package/dist/modules/billing/subscribers/invoice-apply-credit.js +34 -0
  343. package/dist/modules/billing/subscribers/invoice-apply-credit.js.map +7 -0
  344. package/dist/modules/billing/subscribers/invoice-auto-send.js +30 -0
  345. package/dist/modules/billing/subscribers/invoice-auto-send.js.map +7 -0
  346. package/dist/modules/billing/subscribers/payment-captured-to-paid.js +69 -33
  347. package/dist/modules/billing/subscribers/payment-captured-to-paid.js.map +2 -2
  348. package/dist/modules/billing/subscribers/prepaid-topup-captured.js +4 -6
  349. package/dist/modules/billing/subscribers/prepaid-topup-captured.js.map +2 -2
  350. package/generated/entities/billing_account/index.ts +3 -0
  351. package/generated/entities/billing_allocation/index.ts +18 -0
  352. package/generated/entities/billing_document_sequence/index.ts +11 -0
  353. package/generated/entities/billing_invoice/index.ts +38 -0
  354. package/generated/entities/billing_invoice_line/index.ts +24 -0
  355. package/generated/entities/billing_item/index.ts +4 -0
  356. package/generated/entities/billing_payment/index.ts +25 -0
  357. package/generated/entities/billing_payment_import/index.ts +14 -0
  358. package/generated/entities/billing_run/index.ts +0 -1
  359. package/generated/entities/billing_run_outcome/index.ts +1 -0
  360. package/generated/entities/billing_settings/index.ts +26 -0
  361. package/generated/entities/billing_statement/index.ts +1 -0
  362. package/generated/entities.ids.generated.ts +7 -0
  363. package/package.json +5 -1
  364. package/src/modules/billing/__integration__/TC-BILL-004.spec.ts +170 -0
  365. package/src/modules/billing/__integration__/TC-BILL-005.spec.ts +134 -0
  366. package/src/modules/billing/__integration__/TC-BILL-006.spec.ts +101 -0
  367. package/src/modules/billing/__integration__/TC-BILL-007.spec.ts +140 -0
  368. package/src/modules/billing/__integration__/TC-BILL-008.spec.ts +108 -0
  369. package/src/modules/billing/__integration__/TC-BILL-009.spec.ts +113 -0
  370. package/src/modules/billing/__integration__/TC-BILL-010.spec.ts +118 -0
  371. package/src/modules/billing/__integration__/TC-BILL-011.spec.ts +142 -0
  372. package/src/modules/billing/__integration__/TC-BILL-012.spec.ts +115 -0
  373. package/src/modules/billing/__integration__/TC-BILL-013.spec.ts +118 -0
  374. package/src/modules/billing/__integration__/sellerSettings.ts +24 -0
  375. package/src/modules/billing/__tests__/commands/invoices.test.ts +436 -354
  376. package/src/modules/billing/__tests__/commands/itemsBulk.test.ts +33 -0
  377. package/src/modules/billing/__tests__/commands/memos.test.ts +205 -0
  378. package/src/modules/billing/__tests__/commands/payments.test.ts +241 -0
  379. package/src/modules/billing/__tests__/commands/runsDelete.test.ts +146 -0
  380. package/src/modules/billing/__tests__/commands/runsPostDrafts.test.ts +106 -0
  381. package/src/modules/billing/__tests__/commands/topups.test.ts +11 -0
  382. package/src/modules/billing/__tests__/entityRegistry.test.ts +8 -1
  383. package/src/modules/billing/__tests__/helpers/prepaidMockEm.ts +28 -11
  384. package/src/modules/billing/__tests__/lib/accountFinancials.test.ts +53 -0
  385. package/src/modules/billing/__tests__/lib/accountSummary.test.ts +97 -0
  386. package/src/modules/billing/__tests__/lib/allocation.test.ts +319 -0
  387. package/src/modules/billing/__tests__/lib/billRunEngine.test.ts +228 -17
  388. package/src/modules/billing/__tests__/lib/billingSettings.test.ts +109 -0
  389. package/src/modules/billing/__tests__/lib/customerLookup.test.ts +156 -0
  390. package/src/modules/billing/__tests__/lib/dueDate.test.ts +35 -0
  391. package/src/modules/billing/__tests__/lib/iban.test.ts +38 -0
  392. package/src/modules/billing/__tests__/lib/invoiceDelivery.test.ts +189 -0
  393. package/src/modules/billing/__tests__/lib/invoiceWriter.test.ts +212 -10
  394. package/src/modules/billing/__tests__/lib/itemBillingState.test.ts +42 -0
  395. package/src/modules/billing/__tests__/lib/itemPriceChange.test.ts +165 -0
  396. package/src/modules/billing/__tests__/lib/lineAmounts.test.ts +86 -0
  397. package/src/modules/billing/__tests__/lib/navigation.test.ts +71 -0
  398. package/src/modules/billing/__tests__/lib/numbering.test.ts +91 -0
  399. package/src/modules/billing/__tests__/lib/overdue.test.ts +36 -0
  400. package/src/modules/billing/__tests__/lib/paymentCsv.test.ts +148 -0
  401. package/src/modules/billing/__tests__/lib/paymentImport.test.ts +113 -0
  402. package/src/modules/billing/__tests__/lib/paymentsSample.test.ts +73 -0
  403. package/src/modules/billing/__tests__/lib/pdf/invoicePdf.test.ts +199 -0
  404. package/src/modules/billing/__tests__/lib/pdf/invoicePdfService.test.ts +147 -0
  405. package/src/modules/billing/__tests__/lib/prepaidPeriodClose.test.ts +374 -98
  406. package/src/modules/billing/__tests__/lib/prepaidTaxPoint.test.ts +118 -0
  407. package/src/modules/billing/__tests__/lib/seedsDemo.test.ts +53 -2
  408. package/src/modules/billing/__tests__/lib/sellerSettings.test.ts +28 -0
  409. package/src/modules/billing/__tests__/lib/servicePeriods.test.ts +190 -0
  410. package/src/modules/billing/__tests__/lib/topupCapture.test.ts +6 -28
  411. package/src/modules/billing/__tests__/lib/topupReceipt.test.ts +21 -52
  412. package/src/modules/billing/__tests__/lib/vat.test.ts +51 -0
  413. package/src/modules/billing/__tests__/package-isolation.test.ts +22 -8
  414. package/src/modules/billing/__tests__/setup.test.ts +13 -4
  415. package/src/modules/billing/__tests__/validators.test.ts +193 -3
  416. package/src/modules/billing/acl.ts +12 -0
  417. package/src/modules/billing/api/accounts/[id]/summary/route.ts +62 -0
  418. package/src/modules/billing/api/accounts/route.ts +58 -4
  419. package/src/modules/billing/api/export/account/[id]/route.ts +13 -11
  420. package/src/modules/billing/api/invoices/[id]/memos/route.ts +63 -0
  421. package/src/modules/billing/api/invoices/[id]/pdf/route.ts +79 -0
  422. package/src/modules/billing/api/invoices/[id]/route.ts +57 -70
  423. package/src/modules/billing/api/invoices/[id]/send/route.ts +127 -0
  424. package/src/modules/billing/api/invoices/add-line/route.ts +2 -2
  425. package/src/modules/billing/api/invoices/delete-draft/route.ts +33 -0
  426. package/src/modules/billing/api/invoices/edit-line/route.ts +2 -2
  427. package/src/modules/billing/api/invoices/post/route.ts +7 -6
  428. package/src/modules/billing/api/invoices/remove-line/route.ts +2 -2
  429. package/src/modules/billing/api/invoices/route.ts +81 -86
  430. package/src/modules/billing/api/items/bulk/route.ts +2 -1
  431. package/src/modules/billing/api/items/change-price/route.ts +54 -0
  432. package/src/modules/billing/api/items/route.ts +23 -7
  433. package/src/modules/billing/api/payment-imports/[id]/route.ts +49 -0
  434. package/src/modules/billing/api/payment-imports/route.ts +57 -0
  435. package/src/modules/billing/api/payments/[id]/route.ts +63 -0
  436. package/src/modules/billing/api/payments/allocate/route.ts +35 -0
  437. package/src/modules/billing/api/payments/assign/route.ts +36 -0
  438. package/src/modules/billing/api/payments/convert-to-topup/route.ts +35 -0
  439. package/src/modules/billing/api/payments/ignore/route.ts +35 -0
  440. package/src/modules/billing/api/payments/import/route.ts +72 -0
  441. package/src/modules/billing/api/payments/restore/route.ts +35 -0
  442. package/src/modules/billing/api/payments/route.ts +147 -0
  443. package/src/modules/billing/api/payments/unallocate/route.ts +35 -0
  444. package/src/modules/billing/api/payments/unassign/route.ts +35 -0
  445. package/src/modules/billing/api/run-outcomes/route.ts +49 -6
  446. package/src/modules/billing/api/runs/[id]/post-drafts/route.ts +71 -0
  447. package/src/modules/billing/api/runs/[id]/route.ts +59 -0
  448. package/src/modules/billing/api/runs/retry-failed/route.ts +2 -1
  449. package/src/modules/billing/api/runs/route.ts +15 -7
  450. package/src/modules/billing/api/settings/number-preview/route.ts +46 -0
  451. package/src/modules/billing/api/settings/route.ts +116 -0
  452. package/src/modules/billing/api/statements/route.ts +5 -0
  453. package/src/modules/billing/api/test-invoices/wipe/route.ts +2 -2
  454. package/src/modules/billing/backend/billing/accounts/[id]/page.tsx +151 -372
  455. package/src/modules/billing/backend/billing/accounts/create/page.tsx +6 -0
  456. package/src/modules/billing/backend/billing/accounts/page.tsx +70 -4
  457. package/src/modules/billing/backend/billing/invoices/[id]/page.tsx +444 -95
  458. package/src/modules/billing/backend/billing/invoices/page.tsx +8 -227
  459. package/src/modules/billing/backend/billing/items/[id]/page.tsx +75 -6
  460. package/src/modules/billing/backend/billing/items/create/page.tsx +13 -8
  461. package/src/modules/billing/backend/billing/items/page.tsx +18 -2
  462. package/src/modules/billing/backend/billing/payments/[id]/page.meta.ts +19 -0
  463. package/src/modules/billing/backend/billing/payments/[id]/page.tsx +415 -0
  464. package/src/modules/billing/backend/billing/payments/imports/[id]/page.meta.ts +19 -0
  465. package/src/modules/billing/backend/billing/payments/imports/[id]/page.tsx +106 -0
  466. package/src/modules/billing/backend/billing/payments/page.meta.ts +16 -0
  467. package/src/modules/billing/backend/billing/payments/page.tsx +56 -0
  468. package/src/modules/billing/backend/billing/runs/[id]/page.tsx +49 -18
  469. package/src/modules/billing/backend/billing/runs/page.tsx +59 -8
  470. package/src/modules/billing/backend/billing/statements/[id]/page.tsx +86 -5
  471. package/src/modules/billing/backend/billing/statements/page.tsx +1 -1
  472. package/src/modules/billing/backend/billing/topups/page.tsx +1 -1
  473. package/src/modules/billing/backend/billing/transactions/page.tsx +1 -1
  474. package/src/modules/billing/backend/billing/usage/create/page.tsx +3 -2
  475. package/src/modules/billing/backend/config/billing/page.meta.ts +21 -0
  476. package/src/modules/billing/backend/config/billing/page.tsx +549 -0
  477. package/src/modules/billing/cli.ts +31 -1
  478. package/src/modules/billing/commands/accounts.ts +6 -0
  479. package/src/modules/billing/commands/index.ts +3 -0
  480. package/src/modules/billing/commands/invoices.ts +364 -231
  481. package/src/modules/billing/commands/items.ts +143 -0
  482. package/src/modules/billing/commands/memos.ts +218 -0
  483. package/src/modules/billing/commands/payments.ts +428 -0
  484. package/src/modules/billing/commands/runs.ts +205 -3
  485. package/src/modules/billing/commands/settings.ts +77 -0
  486. package/src/modules/billing/commands/topups.ts +12 -3
  487. package/src/modules/billing/commands/transactions.ts +2 -2
  488. package/src/modules/billing/components/AccountForm.tsx +199 -53
  489. package/src/modules/billing/components/AccountInvoicesSection.tsx +75 -0
  490. package/src/modules/billing/components/AccountPaymentsSection.tsx +42 -0
  491. package/src/modules/billing/components/AccountPicker.tsx +70 -0
  492. package/src/modules/billing/components/AllocatePaymentDialog.tsx +167 -0
  493. package/src/modules/billing/components/BillingDataTable.tsx +34 -0
  494. package/src/modules/billing/components/BillingSettingsLink.tsx +25 -0
  495. package/src/modules/billing/components/ChangeItemPriceDialog.tsx +180 -0
  496. package/src/modules/billing/components/CreateMemoDialog.tsx +232 -0
  497. package/src/modules/billing/components/CustomerLabel.tsx +53 -0
  498. package/src/modules/billing/components/InvoicesTable.tsx +344 -0
  499. package/src/modules/billing/components/ItemForm.tsx +233 -44
  500. package/src/modules/billing/components/ItemPriceField.tsx +81 -0
  501. package/src/modules/billing/components/LineFormDialog.tsx +25 -1
  502. package/src/modules/billing/components/ManualPaymentDialog.tsx +140 -0
  503. package/src/modules/billing/components/MoneyInput.tsx +26 -0
  504. package/src/modules/billing/components/PaymentUploadDialog.tsx +148 -0
  505. package/src/modules/billing/components/PaymentsTable.tsx +213 -0
  506. package/src/modules/billing/components/PostRunDraftsButton.tsx +129 -0
  507. package/src/modules/billing/components/PrepaidPanel.tsx +19 -6
  508. package/src/modules/billing/components/RunCyclesSection.tsx +298 -0
  509. package/src/modules/billing/components/TestRunActions.tsx +152 -0
  510. package/src/modules/billing/components/account/AccountItemsTab.tsx +192 -0
  511. package/src/modules/billing/components/account/AccountRunBillingDialog.tsx +147 -0
  512. package/src/modules/billing/components/account/AccountRunsTab.tsx +201 -0
  513. package/src/modules/billing/components/account/AccountStatementsTab.tsx +120 -0
  514. package/src/modules/billing/components/account/AccountSummaryCards.tsx +153 -0
  515. package/src/modules/billing/components/account/AccountUsageTab.tsx +122 -0
  516. package/src/modules/billing/components/account/AccountView.tsx +101 -0
  517. package/src/modules/billing/components/account/accountRow.ts +70 -0
  518. package/src/modules/billing/components/customerNames.ts +62 -0
  519. package/src/modules/billing/data/entities.ts +654 -5
  520. package/src/modules/billing/data/entityIds.ts +9 -0
  521. package/src/modules/billing/data/validators.ts +388 -8
  522. package/src/modules/billing/events.ts +56 -3
  523. package/src/modules/billing/i18n/en.json +457 -21
  524. package/src/modules/billing/i18n/pl.json +457 -21
  525. package/src/modules/billing/index.ts +6 -2
  526. package/src/modules/billing/lib/accountFinancials.ts +84 -0
  527. package/src/modules/billing/lib/accountLock.ts +32 -0
  528. package/src/modules/billing/lib/accountStatus.ts +11 -9
  529. package/src/modules/billing/lib/accountSummary.ts +172 -0
  530. package/src/modules/billing/lib/allocation.ts +515 -0
  531. package/src/modules/billing/lib/allocationEvents.ts +26 -0
  532. package/src/modules/billing/lib/billPeriod.ts +19 -0
  533. package/src/modules/billing/lib/billRunEngine.ts +350 -150
  534. package/src/modules/billing/lib/billingSettings.ts +145 -0
  535. package/src/modules/billing/lib/commandRoute.ts +112 -0
  536. package/src/modules/billing/lib/customerLookup.ts +157 -0
  537. package/src/modules/billing/lib/dateOnly.ts +22 -0
  538. package/src/modules/billing/lib/documentParties.ts +23 -0
  539. package/src/modules/billing/lib/documentTypes.ts +37 -0
  540. package/src/modules/billing/lib/dueDate.ts +26 -0
  541. package/src/modules/billing/lib/iban.ts +36 -0
  542. package/src/modules/billing/lib/invoiceDelivery.ts +197 -0
  543. package/src/modules/billing/lib/invoiceLanguages.ts +34 -0
  544. package/src/modules/billing/lib/invoiceWriter.ts +162 -148
  545. package/src/modules/billing/lib/itemBillingState.ts +67 -0
  546. package/src/modules/billing/lib/itemPriceChange.ts +56 -0
  547. package/src/modules/billing/lib/itemSelector.ts +4 -1
  548. package/src/modules/billing/lib/lineAmounts.ts +61 -0
  549. package/src/modules/billing/lib/memoGuards.ts +41 -0
  550. package/src/modules/billing/lib/navigation.ts +64 -0
  551. package/src/modules/billing/lib/numbering.ts +174 -0
  552. package/src/modules/billing/lib/overdue.ts +60 -0
  553. package/src/modules/billing/lib/paymentCsv.ts +171 -0
  554. package/src/modules/billing/lib/paymentGateway.ts +52 -0
  555. package/src/modules/billing/lib/paymentImport.ts +228 -0
  556. package/src/modules/billing/lib/paymentMatcher.ts +88 -0
  557. package/src/modules/billing/lib/pdf/attachmentStore.ts +60 -0
  558. package/src/modules/billing/lib/pdf/fonts/NotoSans-Bold.ttf +0 -0
  559. package/src/modules/billing/lib/pdf/fonts/NotoSans-Regular.ttf +0 -0
  560. package/src/modules/billing/lib/pdf/fonts/OFL.txt +93 -0
  561. package/src/modules/billing/lib/pdf/fonts/embeddedFonts.ts +9 -0
  562. package/src/modules/billing/lib/pdf/invoiceModel.ts +328 -0
  563. package/src/modules/billing/lib/pdf/invoicePdf.ts +216 -0
  564. package/src/modules/billing/lib/pdf/invoiceTemplate.ts +338 -0
  565. package/src/modules/billing/lib/prepaidConfig.ts +27 -36
  566. package/src/modules/billing/lib/prepaidConsume.ts +29 -6
  567. package/src/modules/billing/lib/prepaidPeriodClose.ts +407 -239
  568. package/src/modules/billing/lib/prepaidTaxPoint.ts +76 -0
  569. package/src/modules/billing/lib/seeds/demo.ts +79 -6
  570. package/src/modules/billing/lib/seeds/paymentsSample.ts +136 -0
  571. package/src/modules/billing/lib/seeds/sellerSettings.ts +78 -0
  572. package/src/modules/billing/lib/servicePeriods.ts +226 -0
  573. package/src/modules/billing/lib/testRunCleanup.ts +42 -0
  574. package/src/modules/billing/lib/topupCapture.ts +3 -4
  575. package/src/modules/billing/lib/topupReceipt.ts +70 -103
  576. package/src/modules/billing/lib/usageRater.ts +1 -1
  577. package/src/modules/billing/lib/usageRunner.ts +17 -5
  578. package/src/modules/billing/lib/vat.ts +56 -0
  579. package/src/modules/billing/migrations/Migration20261114000000_billing_customer_kind.ts +25 -0
  580. package/src/modules/billing/migrations/Migration20261114100000_billing_cycle_semantics.ts +37 -0
  581. package/src/modules/billing/migrations/Migration20261115000000_billing_invoice_ledger.ts +132 -0
  582. package/src/modules/billing/migrations/Migration20261116000000_billing_invoice_documents.ts +58 -0
  583. package/src/modules/billing/migrations/Migration20261117000000_billing_payments.ts +97 -0
  584. package/src/modules/billing/migrations/Migration20261118000000_billing_memos.ts +21 -0
  585. package/src/modules/billing/migrations/Migration20261119000000_billing_operator_feedback.ts +39 -0
  586. package/src/modules/billing/migrations/Migration20261120000000_billing_allocation_scope_indexes.ts +35 -0
  587. package/src/modules/billing/setup.ts +11 -237
  588. package/src/modules/billing/subscribers/credit-memo-auto-send.ts +15 -0
  589. package/src/modules/billing/subscribers/debit-memo-apply-credit.ts +15 -0
  590. package/src/modules/billing/subscribers/debit-memo-auto-send.ts +15 -0
  591. package/src/modules/billing/subscribers/invoice-apply-credit.ts +39 -0
  592. package/src/modules/billing/subscribers/invoice-auto-send.ts +46 -0
  593. package/src/modules/billing/subscribers/payment-captured-to-paid.ts +84 -62
  594. package/src/modules/billing/subscribers/prepaid-topup-captured.ts +4 -8
  595. package/dist/modules/billing/lib/invoiceStatus.js +0 -38
  596. package/dist/modules/billing/lib/invoiceStatus.js.map +0 -7
  597. package/src/modules/billing/__tests__/lib/invoiceStatus.test.ts +0 -97
  598. package/src/modules/billing/lib/invoiceStatus.ts +0 -61
@@ -0,0 +1,200 @@
1
+ "use client";
2
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "@open-mercato/ui/primitives/dialog";
5
+ import { Button } from "@open-mercato/ui/primitives/button";
6
+ import { Input } from "@open-mercato/ui/primitives/input";
7
+ import { Textarea } from "@open-mercato/ui/primitives/textarea";
8
+ import { Checkbox } from "@open-mercato/ui/primitives/checkbox";
9
+ import { Kbd, KbdShortcut } from "@open-mercato/ui/primitives/kbd";
10
+ import { useT } from "@open-mercato/shared/lib/i18n/context";
11
+ import { apiCallOrThrow } from "@open-mercato/ui/backend/utils/apiCall";
12
+ import { normalizeCrudServerError } from "@open-mercato/ui/backend/utils/serverErrors";
13
+ import { flash } from "@open-mercato/ui/backend/FlashMessages";
14
+ import { formatMoney } from "./InvoicesTable.js";
15
+ function round2(value) {
16
+ return Math.round((value + Number.EPSILON) * 100) / 100;
17
+ }
18
+ function CreateMemoDialog({
19
+ open,
20
+ type,
21
+ invoiceId,
22
+ invoiceNumber,
23
+ currencyCode,
24
+ lines,
25
+ onClose,
26
+ onCreated
27
+ }) {
28
+ const t = useT();
29
+ const [reason, setReason] = React.useState("");
30
+ const [state, setState] = React.useState({});
31
+ const [saving, setSaving] = React.useState(false);
32
+ const fullCredit = React.useCallback(() => {
33
+ setState(
34
+ Object.fromEntries(
35
+ lines.map((line) => [
36
+ line.id,
37
+ { selected: true, quantity: String(Number(line.quantity)), unitPriceNet: String(Math.abs(Number(line.unit_price_net))) }
38
+ ])
39
+ )
40
+ );
41
+ }, [lines]);
42
+ React.useEffect(() => {
43
+ if (!open) return;
44
+ setReason("");
45
+ if (type === "credit_memo") fullCredit();
46
+ else setState({});
47
+ }, [fullCredit, open, type]);
48
+ const selected = lines.filter((line) => state[line.id]?.selected);
49
+ const projected = selected.reduce(
50
+ (acc, line) => {
51
+ const s = state[line.id];
52
+ const net = round2((Number.parseFloat(s.quantity) || 0) * (Number.parseFloat(s.unitPriceNet) || 0));
53
+ const tax = round2(net * ((Number(line.tax_rate) || 0) / 100));
54
+ return { net: acc.net + net, tax: acc.tax + tax };
55
+ },
56
+ { net: 0, tax: 0 }
57
+ );
58
+ const update = (id, patch) => setState((prev) => ({ ...prev, [id]: { ...prev[id], ...patch } }));
59
+ const submit = React.useCallback(async () => {
60
+ if (saving) return;
61
+ if (!reason.trim()) {
62
+ flash(t("billing.memo.error.reason_required", "A reason is required"), "error");
63
+ return;
64
+ }
65
+ if (type === "credit_memo" && selected.length === 0) {
66
+ flash(t("billing.memo.error.no_lines", "Select at least one line to credit"), "error");
67
+ return;
68
+ }
69
+ setSaving(true);
70
+ try {
71
+ const body = type === "credit_memo" ? {
72
+ type,
73
+ reason: reason.trim(),
74
+ lines: selected.map((line) => ({
75
+ correctsLineId: line.id,
76
+ description: line.description ?? "",
77
+ quantity: Number.parseFloat(state[line.id].quantity),
78
+ unitPriceNet: Number.parseFloat(state[line.id].unitPriceNet)
79
+ }))
80
+ } : { type, reason: reason.trim() };
81
+ const call = await apiCallOrThrow(`/api/billing/invoices/${encodeURIComponent(invoiceId)}/memos`, {
82
+ method: "POST",
83
+ headers: { "Content-Type": "application/json" },
84
+ body: JSON.stringify(body)
85
+ });
86
+ flash(t("billing.memo.created", "Draft memo created"), "success");
87
+ onClose();
88
+ if (call.result?.memoId) onCreated(call.result.memoId);
89
+ } catch (err) {
90
+ const code = err?.body?.code;
91
+ flash(
92
+ code === "billing.memo.exceeds_invoice" ? t("billing.memo.error.exceeds", "The credit is more than what is left to credit on this invoice") : normalizeCrudServerError(err).message || t("billing.memo.error.create", "Could not create the memo"),
93
+ "error"
94
+ );
95
+ } finally {
96
+ setSaving(false);
97
+ }
98
+ }, [invoiceId, onClose, onCreated, reason, saving, selected, state, t, type]);
99
+ return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange: (next) => !next ? onClose() : void 0, children: /* @__PURE__ */ jsxs(
100
+ DialogContent,
101
+ {
102
+ className: "max-w-3xl",
103
+ onKeyDown: (event) => {
104
+ if ((event.metaKey || event.ctrlKey) && event.key === "Enter") {
105
+ event.preventDefault();
106
+ void submit();
107
+ }
108
+ },
109
+ children: [
110
+ /* @__PURE__ */ jsxs(DialogHeader, { children: [
111
+ /* @__PURE__ */ jsx(DialogTitle, { children: type === "credit_memo" ? t("billing.memo.create_credit.title", "Create credit memo") : t("billing.memo.create_debit.title", "Create debit memo") }),
112
+ /* @__PURE__ */ jsxs(DialogDescription, { children: [
113
+ t("billing.memo.corrects", "Corrects"),
114
+ " ",
115
+ invoiceNumber,
116
+ " \xB7",
117
+ " ",
118
+ t("billing.memo.hint", "Corrects this document only. Update the billing item to change future invoices.")
119
+ ] })
120
+ ] }),
121
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 py-2 text-sm", children: [
122
+ type === "credit_memo" ? /* @__PURE__ */ jsxs(Fragment, { children: [
123
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
124
+ /* @__PURE__ */ jsx("span", { className: "font-medium", children: t("billing.memo.lines", "Lines to credit") }),
125
+ /* @__PURE__ */ jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: fullCredit, children: t("billing.memo.full_credit", "Full credit") })
126
+ ] }),
127
+ /* @__PURE__ */ jsx("div", { className: "max-h-72 overflow-auto rounded-md border", children: lines.map((line) => {
128
+ const s = state[line.id] ?? { selected: false, quantity: "", unitPriceNet: "" };
129
+ return /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[24px_1fr_90px_110px_60px] items-center gap-2 border-b px-2 py-1 last:border-b-0", children: [
130
+ /* @__PURE__ */ jsx(Checkbox, { checked: s.selected, onCheckedChange: (next) => update(line.id, { selected: next === true }) }),
131
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: line.description }),
132
+ /* @__PURE__ */ jsx(
133
+ Input,
134
+ {
135
+ type: "number",
136
+ min: "0",
137
+ step: "0.0001",
138
+ value: s.quantity,
139
+ disabled: !s.selected,
140
+ onChange: (e) => update(line.id, { quantity: e.currentTarget.value })
141
+ }
142
+ ),
143
+ /* @__PURE__ */ jsx(
144
+ Input,
145
+ {
146
+ type: "number",
147
+ min: "0",
148
+ step: "0.01",
149
+ value: s.unitPriceNet,
150
+ disabled: !s.selected,
151
+ onChange: (e) => update(line.id, { unitPriceNet: e.currentTarget.value })
152
+ }
153
+ ),
154
+ /* @__PURE__ */ jsxs("span", { className: "text-right text-xs text-muted-foreground", children: [
155
+ Number(line.tax_rate ?? 0),
156
+ " %"
157
+ ] })
158
+ ] }, line.id);
159
+ }) }),
160
+ /* @__PURE__ */ jsxs("div", { className: "text-right text-muted-foreground", children: [
161
+ t("billing.memo.projected", "Credit"),
162
+ ": ",
163
+ formatMoney(String(projected.net), currencyCode),
164
+ " +",
165
+ " ",
166
+ t("billing.invoices.lines.columns.tax_amount", "VAT"),
167
+ " ",
168
+ formatMoney(String(projected.tax), currencyCode),
169
+ " =",
170
+ " ",
171
+ /* @__PURE__ */ jsx("span", { className: "font-medium text-foreground", children: formatMoney(String(projected.net + projected.tax), currencyCode) })
172
+ ] })
173
+ ] }) : null,
174
+ /* @__PURE__ */ jsxs("label", { className: "flex flex-col gap-1", children: [
175
+ /* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
176
+ t("billing.memo.reason", "Reason (printed on the document)"),
177
+ " *"
178
+ ] }),
179
+ /* @__PURE__ */ jsx(Textarea, { rows: 2, maxLength: 1e3, value: reason, onChange: (e) => setReason(e.currentTarget.value) })
180
+ ] })
181
+ ] }),
182
+ /* @__PURE__ */ jsx(DialogFooter, { children: /* @__PURE__ */ jsxs("div", { className: "flex w-full items-center justify-between gap-3", children: [
183
+ /* @__PURE__ */ jsxs("span", { className: "text-xs text-muted-foreground", children: [
184
+ /* @__PURE__ */ jsx(KbdShortcut, { keys: ["Ctrl/\u2318", "Enter"] }),
185
+ " \xB7 ",
186
+ /* @__PURE__ */ jsx(Kbd, { children: "Esc" })
187
+ ] }),
188
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
189
+ /* @__PURE__ */ jsx(Button, { type: "button", variant: "outline", onClick: onClose, children: t("billing.common.cancel", "Cancel") }),
190
+ /* @__PURE__ */ jsx(Button, { type: "button", onClick: () => void submit(), disabled: saving, children: t("billing.memo.create", "Create draft") })
191
+ ] })
192
+ ] }) })
193
+ ]
194
+ }
195
+ ) });
196
+ }
197
+ export {
198
+ CreateMemoDialog
199
+ };
200
+ //# sourceMappingURL=CreateMemoDialog.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/modules/billing/components/CreateMemoDialog.tsx"],
4
+ "sourcesContent": ["\"use client\"\nimport * as React from 'react'\nimport { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@open-mercato/ui/primitives/dialog'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Input } from '@open-mercato/ui/primitives/input'\nimport { Textarea } from '@open-mercato/ui/primitives/textarea'\nimport { Checkbox } from '@open-mercato/ui/primitives/checkbox'\nimport { Kbd, KbdShortcut } from '@open-mercato/ui/primitives/kbd'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { apiCallOrThrow } from '@open-mercato/ui/backend/utils/apiCall'\nimport { normalizeCrudServerError } from '@open-mercato/ui/backend/utils/serverErrors'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { formatMoney } from './InvoicesTable'\n\n/**\n * Create a credit or debit memo for a posted invoice (Spec D, D-D9).\n *\n * - credit memo: the original lines with a checkbox and editable quantity /\n * unit net (VAT rate stays the original's), a \"Full credit\" shortcut,\n * the required reason and the projected totals;\n * - debit memo: the reason only \u2014 lines are added on the draft.\n *\n * Creates a DRAFT memo and hands its id back (the page navigates to it).\n * Cmd/Ctrl+Enter submits, Escape cancels.\n */\n\nexport type MemoSourceLine = {\n id: string\n description: string | null\n quantity: string\n unit_price_net: string\n tax_rate: string | number | null\n}\n\ntype LineState = { selected: boolean; quantity: string; unitPriceNet: string }\n\nfunction round2(value: number): number {\n return Math.round((value + Number.EPSILON) * 100) / 100\n}\n\nexport function CreateMemoDialog({\n open,\n type,\n invoiceId,\n invoiceNumber,\n currencyCode,\n lines,\n onClose,\n onCreated,\n}: {\n open: boolean\n type: 'credit_memo' | 'debit_memo'\n invoiceId: string\n invoiceNumber: string\n currencyCode: string\n lines: MemoSourceLine[]\n onClose: () => void\n onCreated: (memoId: string) => void\n}) {\n const t = useT()\n const [reason, setReason] = React.useState('')\n const [state, setState] = React.useState<Record<string, LineState>>({})\n const [saving, setSaving] = React.useState(false)\n\n const fullCredit = React.useCallback(() => {\n setState(\n Object.fromEntries(\n lines.map((line) => [\n line.id,\n { selected: true, quantity: String(Number(line.quantity)), unitPriceNet: String(Math.abs(Number(line.unit_price_net))) },\n ]),\n ),\n )\n }, [lines])\n\n React.useEffect(() => {\n if (!open) return\n setReason('')\n if (type === 'credit_memo') fullCredit()\n else setState({})\n }, [fullCredit, open, type])\n\n const selected = lines.filter((line) => state[line.id]?.selected)\n const projected = selected.reduce(\n (acc, line) => {\n const s = state[line.id]\n const net = round2((Number.parseFloat(s.quantity) || 0) * (Number.parseFloat(s.unitPriceNet) || 0))\n const tax = round2(net * ((Number(line.tax_rate) || 0) / 100))\n return { net: acc.net + net, tax: acc.tax + tax }\n },\n { net: 0, tax: 0 },\n )\n\n const update = (id: string, patch: Partial<LineState>) =>\n setState((prev) => ({ ...prev, [id]: { ...prev[id], ...patch } }))\n\n const submit = React.useCallback(async () => {\n if (saving) return\n if (!reason.trim()) {\n flash(t('billing.memo.error.reason_required', 'A reason is required'), 'error')\n return\n }\n if (type === 'credit_memo' && selected.length === 0) {\n flash(t('billing.memo.error.no_lines', 'Select at least one line to credit'), 'error')\n return\n }\n setSaving(true)\n try {\n const body =\n type === 'credit_memo'\n ? {\n type,\n reason: reason.trim(),\n lines: selected.map((line) => ({\n correctsLineId: line.id,\n description: line.description ?? '',\n quantity: Number.parseFloat(state[line.id].quantity),\n unitPriceNet: Number.parseFloat(state[line.id].unitPriceNet),\n })),\n }\n : { type, reason: reason.trim() }\n const call = await apiCallOrThrow<{ memoId: string }>(`/api/billing/invoices/${encodeURIComponent(invoiceId)}/memos`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n })\n flash(t('billing.memo.created', 'Draft memo created'), 'success')\n onClose()\n if (call.result?.memoId) onCreated(call.result.memoId)\n } catch (err) {\n const code = (err as { body?: { code?: string } } | null)?.body?.code\n flash(\n code === 'billing.memo.exceeds_invoice'\n ? t('billing.memo.error.exceeds', 'The credit is more than what is left to credit on this invoice')\n : normalizeCrudServerError(err).message || t('billing.memo.error.create', 'Could not create the memo'),\n 'error',\n )\n } finally {\n setSaving(false)\n }\n }, [invoiceId, onClose, onCreated, reason, saving, selected, state, t, type])\n\n return (\n <Dialog open={open} onOpenChange={(next) => (!next ? onClose() : undefined)}>\n <DialogContent\n className=\"max-w-3xl\"\n onKeyDown={(event) => {\n if ((event.metaKey || event.ctrlKey) && event.key === 'Enter') {\n event.preventDefault()\n void submit()\n }\n }}\n >\n <DialogHeader>\n <DialogTitle>\n {type === 'credit_memo'\n ? t('billing.memo.create_credit.title', 'Create credit memo')\n : t('billing.memo.create_debit.title', 'Create debit memo')}\n </DialogTitle>\n <DialogDescription>\n {t('billing.memo.corrects', 'Corrects')} {invoiceNumber} \u00B7{' '}\n {t('billing.memo.hint', 'Corrects this document only. Update the billing item to change future invoices.')}\n </DialogDescription>\n </DialogHeader>\n <div className=\"flex flex-col gap-3 py-2 text-sm\">\n {type === 'credit_memo' ? (\n <>\n <div className=\"flex items-center justify-between\">\n <span className=\"font-medium\">{t('billing.memo.lines', 'Lines to credit')}</span>\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={fullCredit}>\n {t('billing.memo.full_credit', 'Full credit')}\n </Button>\n </div>\n <div className=\"max-h-72 overflow-auto rounded-md border\">\n {lines.map((line) => {\n const s = state[line.id] ?? { selected: false, quantity: '', unitPriceNet: '' }\n return (\n <div key={line.id} className=\"grid grid-cols-[24px_1fr_90px_110px_60px] items-center gap-2 border-b px-2 py-1 last:border-b-0\">\n <Checkbox checked={s.selected} onCheckedChange={(next) => update(line.id, { selected: next === true })} />\n <span className=\"truncate\">{line.description}</span>\n <Input\n type=\"number\"\n min=\"0\"\n step=\"0.0001\"\n value={s.quantity}\n disabled={!s.selected}\n onChange={(e) => update(line.id, { quantity: e.currentTarget.value })}\n />\n <Input\n type=\"number\"\n min=\"0\"\n step=\"0.01\"\n value={s.unitPriceNet}\n disabled={!s.selected}\n onChange={(e) => update(line.id, { unitPriceNet: e.currentTarget.value })}\n />\n <span className=\"text-right text-xs text-muted-foreground\">{Number(line.tax_rate ?? 0)} %</span>\n </div>\n )\n })}\n </div>\n <div className=\"text-right text-muted-foreground\">\n {t('billing.memo.projected', 'Credit')}: {formatMoney(String(projected.net), currencyCode)} +{' '}\n {t('billing.invoices.lines.columns.tax_amount', 'VAT')} {formatMoney(String(projected.tax), currencyCode)} ={' '}\n <span className=\"font-medium text-foreground\">{formatMoney(String(projected.net + projected.tax), currencyCode)}</span>\n </div>\n </>\n ) : null}\n <label className=\"flex flex-col gap-1\">\n <span className=\"text-muted-foreground\">{t('billing.memo.reason', 'Reason (printed on the document)')} *</span>\n <Textarea rows={2} maxLength={1000} value={reason} onChange={(e) => setReason(e.currentTarget.value)} />\n </label>\n </div>\n <DialogFooter>\n <div className=\"flex w-full items-center justify-between gap-3\">\n <span className=\"text-xs text-muted-foreground\">\n <KbdShortcut keys={['Ctrl/\u2318', 'Enter']} /> \u00B7 <Kbd>Esc</Kbd>\n </span>\n <div className=\"flex items-center gap-2\">\n <Button type=\"button\" variant=\"outline\" onClick={onClose}>\n {t('billing.common.cancel', 'Cancel')}\n </Button>\n <Button type=\"button\" onClick={() => void submit()} disabled={saving}>\n {t('billing.memo.create', 'Create draft')}\n </Button>\n </div>\n </div>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n )\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,33 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import Link from "next/link";
4
+ import { Building2, User } from "lucide-react";
5
+ import { useT } from "@open-mercato/shared/lib/i18n/context";
6
+ import { customerDetailHref } from "../lib/customerLookup.js";
7
+ function CustomerLabel({
8
+ customerId,
9
+ customerKind,
10
+ name,
11
+ linkToCustomer = false
12
+ }) {
13
+ const t = useT();
14
+ const kindLabel = customerKind === "person" ? t("billing.accounts.kind.person", "Person") : t("billing.accounts.kind.company", "Company");
15
+ const Icon = customerKind === "person" ? User : Building2;
16
+ const text = name ? /* @__PURE__ */ jsx("span", { children: name }) : /* @__PURE__ */ jsx("span", { className: "font-mono text-xs", children: customerId });
17
+ return /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1.5", title: kindLabel, children: [
18
+ /* @__PURE__ */ jsx(Icon, { size: 14, "aria-label": kindLabel, className: "shrink-0 text-muted-foreground" }),
19
+ linkToCustomer ? /* @__PURE__ */ jsx(
20
+ Link,
21
+ {
22
+ href: customerDetailHref(customerKind, customerId),
23
+ className: "underline-offset-2 hover:underline",
24
+ onClick: (event) => event.stopPropagation(),
25
+ children: text
26
+ }
27
+ ) : text
28
+ ] });
29
+ }
30
+ export {
31
+ CustomerLabel
32
+ };
33
+ //# sourceMappingURL=CustomerLabel.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/modules/billing/components/CustomerLabel.tsx"],
4
+ "sourcesContent": ["\"use client\"\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { Building2, User } from 'lucide-react'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport type { CustomerKind } from '../data/validators'\nimport { customerDetailHref } from '../lib/customerLookup'\n\n/**\n * Customer reference for billing views (Spec E): kind icon + resolved\n * display name, falling back to the raw id when the customers lookup is\n * unavailable. `linkToCustomer` turns the name into a link to the customer\n * record in the customers module.\n */\nexport function CustomerLabel({\n customerId,\n customerKind,\n name,\n linkToCustomer = false,\n}: {\n customerId: string\n customerKind: CustomerKind\n name?: string | null\n linkToCustomer?: boolean\n}) {\n const t = useT()\n const kindLabel =\n customerKind === 'person'\n ? t('billing.accounts.kind.person', 'Person')\n : t('billing.accounts.kind.company', 'Company')\n const Icon = customerKind === 'person' ? User : Building2\n const text = name ? (\n <span>{name}</span>\n ) : (\n <span className=\"font-mono text-xs\">{customerId}</span>\n )\n return (\n <span className=\"inline-flex items-center gap-1.5\" title={kindLabel}>\n <Icon size={14} aria-label={kindLabel} className=\"shrink-0 text-muted-foreground\" />\n {linkToCustomer ? (\n <Link\n href={customerDetailHref(customerKind, customerId)}\n className=\"underline-offset-2 hover:underline\"\n onClick={(event) => event.stopPropagation()}\n >\n {text}\n </Link>\n ) : (\n text\n )}\n </span>\n )\n}\n"],
5
+ "mappings": ";AAgCI,cAKA,YALA;AA9BJ,OAAO,UAAU;AACjB,SAAS,WAAW,YAAY;AAChC,SAAS,YAAY;AAErB,SAAS,0BAA0B;AAQ5B,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA,iBAAiB;AACnB,GAKG;AACD,QAAM,IAAI,KAAK;AACf,QAAM,YACJ,iBAAiB,WACb,EAAE,gCAAgC,QAAQ,IAC1C,EAAE,iCAAiC,SAAS;AAClD,QAAM,OAAO,iBAAiB,WAAW,OAAO;AAChD,QAAM,OAAO,OACX,oBAAC,UAAM,gBAAK,IAEZ,oBAAC,UAAK,WAAU,qBAAqB,sBAAW;AAElD,SACE,qBAAC,UAAK,WAAU,oCAAmC,OAAO,WACxD;AAAA,wBAAC,QAAK,MAAM,IAAI,cAAY,WAAW,WAAU,kCAAiC;AAAA,IACjF,iBACC;AAAA,MAAC;AAAA;AAAA,QACC,MAAM,mBAAmB,cAAc,UAAU;AAAA,QACjD,WAAU;AAAA,QACV,SAAS,CAAC,UAAU,MAAM,gBAAgB;AAAA,QAEzC;AAAA;AAAA,IACH,IAEA;AAAA,KAEJ;AAEJ;",
6
+ "names": []
7
+ }
@@ -0,0 +1,270 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import { useRouter } from "next/navigation";
5
+ import { useT } from "@open-mercato/shared/lib/i18n/context";
6
+ import { BillingDataTable as DataTable } from "./BillingDataTable.js";
7
+ import { RowActions } from "@open-mercato/ui/backend/RowActions";
8
+ import { Tag } from "@open-mercato/ui/primitives/tag";
9
+ import { readApiResultOrThrow } from "@open-mercato/ui/backend/utils/apiCall";
10
+ import { invoiceDetailHref, invoicePdfHref } from "../lib/navigation.js";
11
+ import { displaySign } from "../lib/documentTypes.js";
12
+ function formatDate(value) {
13
+ if (!value) return "\u2014";
14
+ const parsed = new Date(value);
15
+ return Number.isNaN(parsed.getTime()) ? value : parsed.toLocaleDateString();
16
+ }
17
+ function formatMoney(value, currency) {
18
+ const n = Number.parseFloat(value);
19
+ if (!Number.isFinite(n)) return value;
20
+ try {
21
+ return new Intl.NumberFormat(void 0, { style: "currency", currency }).format(n);
22
+ } catch {
23
+ return `${value} ${currency}`;
24
+ }
25
+ }
26
+ function invoiceStatusVariant(status) {
27
+ switch (status) {
28
+ case "paid":
29
+ case "credited":
30
+ return "success";
31
+ case "posted":
32
+ case "partially_paid":
33
+ return "warning";
34
+ case "draft":
35
+ default:
36
+ return "default";
37
+ }
38
+ }
39
+ function InvoicesTable({ title, billAccountId, tableId, pageSize = 25, actions }) {
40
+ const t = useT();
41
+ const router = useRouter();
42
+ const [rows, setRows] = React.useState([]);
43
+ const [page, setPage] = React.useState(1);
44
+ const [filters, setFilters] = React.useState({});
45
+ const [search, setSearch] = React.useState("");
46
+ const [total, setTotal] = React.useState(0);
47
+ const [totalPages, setTotalPages] = React.useState(1);
48
+ const [loading, setLoading] = React.useState(true);
49
+ const [error, setError] = React.useState(null);
50
+ const statusLabel = React.useCallback(
51
+ (status) => ({
52
+ draft: t("billing.invoices.status.draft", "Draft"),
53
+ posted: t("billing.invoices.status.posted", "Posted"),
54
+ partially_paid: t("billing.invoices.status.partially_paid", "Partially paid"),
55
+ paid: t("billing.invoices.status.paid", "Paid"),
56
+ credited: t("billing.invoices.status.credited", "Credited")
57
+ })[status] ?? status,
58
+ [t]
59
+ );
60
+ const filterDefs = React.useMemo(
61
+ () => [
62
+ {
63
+ id: "status",
64
+ label: t("billing.invoices.filters.status", "Status"),
65
+ type: "select",
66
+ options: ["draft", "posted", "partially_paid", "paid", "credited"].map((value) => ({
67
+ value,
68
+ label: statusLabel(value)
69
+ }))
70
+ },
71
+ {
72
+ id: "overdue",
73
+ label: t("billing.invoices.filters.overdue", "Overdue"),
74
+ type: "select",
75
+ options: [
76
+ { value: "true", label: t("billing.invoices.filters.overdue.only", "Only overdue") },
77
+ { value: "false", label: t("billing.invoices.filters.overdue.exclude", "Not overdue") }
78
+ ]
79
+ },
80
+ {
81
+ id: "documentType",
82
+ label: t("billing.invoices.filters.document_type", "Document type"),
83
+ type: "select",
84
+ options: [
85
+ { value: "invoice", label: t("billing.invoices.document_type.invoice", "Invoice") },
86
+ { value: "credit_memo", label: t("billing.invoices.document_type.credit_memo", "Credit memo") },
87
+ { value: "debit_memo", label: t("billing.invoices.document_type.debit_memo", "Debit memo") },
88
+ { value: "receipt", label: t("billing.invoices.document_type.receipt", "Top-up receipt") }
89
+ ]
90
+ },
91
+ {
92
+ id: "testRun",
93
+ label: t("billing.invoices.filters.test_run", "Test runs"),
94
+ type: "select",
95
+ options: [
96
+ { value: "true", label: t("billing.invoices.filters.test_run.only", "Only test") },
97
+ { value: "false", label: t("billing.invoices.filters.test_run.exclude", "Exclude test") }
98
+ ]
99
+ }
100
+ ],
101
+ [statusLabel, t]
102
+ );
103
+ const loadRows = React.useCallback(async () => {
104
+ setLoading(true);
105
+ setError(null);
106
+ try {
107
+ const params = new URLSearchParams({ page: String(page), pageSize: String(Math.min(pageSize, 100)) });
108
+ if (billAccountId) params.set("billAccountId", billAccountId);
109
+ if (search.trim()) params.set("search", search.trim());
110
+ for (const key of ["status", "documentType"]) {
111
+ const value = filters[key];
112
+ if (typeof value === "string" && value) params.set(key, value);
113
+ }
114
+ for (const key of ["testRun", "overdue"]) {
115
+ const value = filters[key];
116
+ if (value === "true" || value === "false") params.set(key, value);
117
+ }
118
+ const result = await readApiResultOrThrow(`/api/billing/invoices?${params.toString()}`);
119
+ setRows(result.items ?? []);
120
+ setTotal(result.total ?? 0);
121
+ setTotalPages(result.totalPages ?? 1);
122
+ } catch (err) {
123
+ setError(err instanceof Error ? err.message : t("billing.invoices.error.load", "Could not load invoices"));
124
+ } finally {
125
+ setLoading(false);
126
+ }
127
+ }, [billAccountId, filters, page, pageSize, search, t]);
128
+ React.useEffect(() => {
129
+ void loadRows();
130
+ }, [loadRows]);
131
+ const columns = React.useMemo(() => {
132
+ const cols = [
133
+ {
134
+ accessorKey: "number",
135
+ header: t("billing.invoices.columns.number", "Number"),
136
+ cell: ({ row }) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
137
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-primary", children: row.original.number }),
138
+ row.original.test_run ? /* @__PURE__ */ jsx(Tag, { variant: "warning", children: "TEST" }) : null
139
+ ] })
140
+ },
141
+ {
142
+ accessorKey: "document_type",
143
+ header: t("billing.invoices.columns.type", "Type"),
144
+ cell: ({ row }) => ({
145
+ invoice: t("billing.invoices.document_type.invoice", "Invoice"),
146
+ credit_memo: t("billing.invoices.document_type.credit_memo", "Credit memo"),
147
+ debit_memo: t("billing.invoices.document_type.debit_memo", "Debit memo"),
148
+ receipt: t("billing.invoices.document_type.receipt", "Top-up receipt")
149
+ })[row.original.document_type] ?? row.original.document_type
150
+ },
151
+ {
152
+ accessorKey: "status",
153
+ header: t("billing.invoices.columns.status", "Status"),
154
+ cell: ({ row }) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
155
+ /* @__PURE__ */ jsx(Tag, { variant: invoiceStatusVariant(row.original.status), children: statusLabel(row.original.status) }),
156
+ row.original.days_overdue > 0 ? /* @__PURE__ */ jsx(Tag, { variant: "error", children: t("billing.invoices.overdue", "Overdue") }) : null
157
+ ] })
158
+ }
159
+ ];
160
+ if (!billAccountId) {
161
+ cols.push({
162
+ accessorKey: "bill_account_name",
163
+ header: t("billing.invoices.columns.account", "Account"),
164
+ cell: ({ row }) => row.original.bill_account_name ?? "\u2014",
165
+ meta: { truncate: true, maxWidth: "220px" }
166
+ });
167
+ }
168
+ cols.push(
169
+ {
170
+ id: "period",
171
+ header: t("billing.invoices.columns.period", "Period"),
172
+ cell: ({ row }) => {
173
+ const start = row.original.period_start?.slice(0, 10);
174
+ const end = row.original.period_end?.slice(0, 10);
175
+ if (!start || !end) return "\u2014";
176
+ return /* @__PURE__ */ jsxs("span", { className: "text-xs", children: [
177
+ start,
178
+ " \u2192 ",
179
+ end
180
+ ] });
181
+ }
182
+ },
183
+ {
184
+ id: "total",
185
+ header: t("billing.invoices.columns.total", "Total"),
186
+ // Credit memos are stored positive (D-D5) and shown negative.
187
+ cell: ({ row }) => formatMoney(
188
+ String(displaySign(row.original.document_type) * Number.parseFloat(row.original.total_gross)),
189
+ row.original.currency_code
190
+ )
191
+ },
192
+ {
193
+ accessorKey: "outstanding",
194
+ header: t("billing.invoices.columns.outstanding", "Outstanding"),
195
+ cell: ({ row }) => formatMoney(row.original.outstanding, row.original.currency_code)
196
+ },
197
+ {
198
+ accessorKey: "issue_date",
199
+ header: t("billing.invoices.columns.issued", "Issued"),
200
+ cell: ({ row }) => formatDate(row.original.issue_date)
201
+ },
202
+ {
203
+ accessorKey: "due_date",
204
+ header: t("billing.invoices.columns.due", "Due"),
205
+ cell: ({ row }) => formatDate(row.original.due_date)
206
+ },
207
+ {
208
+ accessorKey: "days_overdue",
209
+ header: t("billing.invoices.columns.days_overdue", "Days overdue"),
210
+ cell: ({ row }) => row.original.days_overdue > 0 ? /* @__PURE__ */ jsx("span", { className: "font-medium text-status-error-text tabular-nums", children: row.original.days_overdue }) : /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "\u2014" })
211
+ }
212
+ );
213
+ return cols;
214
+ }, [billAccountId, statusLabel, t]);
215
+ return /* @__PURE__ */ jsx(
216
+ DataTable,
217
+ {
218
+ title,
219
+ actions,
220
+ refreshButton: { label: t("billing.common.refresh", "Refresh"), onRefresh: loadRows, isRefreshing: loading },
221
+ columnChooser: { auto: true },
222
+ perspective: { tableId },
223
+ columns,
224
+ data: rows,
225
+ error,
226
+ emptyState: t("billing.invoices.empty", "No invoices yet."),
227
+ onRowClick: (row) => router.push(invoiceDetailHref(row.id, { fromAccountId: billAccountId })),
228
+ rowActions: (row) => /* @__PURE__ */ jsx(
229
+ RowActions,
230
+ {
231
+ items: [
232
+ {
233
+ id: "open",
234
+ label: t("billing.invoices.actions.open", "Open"),
235
+ href: invoiceDetailHref(row.id, { fromAccountId: billAccountId })
236
+ },
237
+ {
238
+ id: "pdf",
239
+ label: row.status === "draft" ? t("billing.invoices.actions.pdf_preview", "Preview PDF") : t("billing.invoices.actions.pdf", "Download PDF"),
240
+ href: invoicePdfHref(row.id)
241
+ }
242
+ ]
243
+ }
244
+ ),
245
+ isLoading: loading,
246
+ pagination: { page, pageSize, total, totalPages, onPageChange: setPage },
247
+ filters: filterDefs,
248
+ filterValues: filters,
249
+ onFiltersApply: (next) => {
250
+ setPage(1);
251
+ setFilters(next);
252
+ },
253
+ onFiltersClear: () => {
254
+ setPage(1);
255
+ setFilters({});
256
+ },
257
+ searchValue: search,
258
+ onSearchChange: (next) => {
259
+ setPage(1);
260
+ setSearch(next);
261
+ }
262
+ }
263
+ );
264
+ }
265
+ export {
266
+ InvoicesTable,
267
+ formatMoney,
268
+ invoiceStatusVariant
269
+ };
270
+ //# sourceMappingURL=InvoicesTable.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/modules/billing/components/InvoicesTable.tsx"],
4
+ "sourcesContent": ["\"use client\"\nimport * as React from 'react'\nimport { useRouter } from 'next/navigation'\nimport type { LegacyColumnDef as ColumnDef } from '@tanstack/react-table/legacy'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport type { FilterDef, FilterValues } from '@open-mercato/ui/backend/FilterBar'\nimport { BillingDataTable as DataTable } from './BillingDataTable'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { Tag } from '@open-mercato/ui/primitives/tag'\nimport { readApiResultOrThrow } from '@open-mercato/ui/backend/utils/apiCall'\nimport { invoiceDetailHref, invoicePdfHref } from '../lib/navigation'\nimport { displaySign } from '../lib/documentTypes'\n\n/**\n * Billing documents table (Spec B) \u2014 shared by the global Invoices list and\n * the Invoices section of a billing account (and, later, Spec E's tab).\n *\n * - `billAccountId` pins the list to one account (no account column; rows\n * open the invoice with a return link to the account).\n * - Filters: status, overdue (computed server-side, B-D6), document type,\n * test runs. Columns include due date, outstanding and days overdue.\n * - Row action: download the PDF (frozen when posted, preview for drafts).\n *\n * Server-paginated via `GET /api/billing/invoices` (pageSize \u2264 100).\n */\n\nexport type BillingInvoiceRow = {\n id: string\n number: string\n document_type: 'invoice' | 'credit_memo' | 'debit_memo' | 'receipt'\n status: 'draft' | 'posted' | 'partially_paid' | 'paid' | 'credited'\n test_run: boolean\n bill_account_id: string\n bill_account_name: string | null\n bill_run_id: string | null\n bill_date: string | null\n period_start: string | null\n period_end: string | null\n currency_code: string\n issue_date: string | null\n due_date: string | null\n subtotal_net: string\n total_gross: string\n paid_total: string\n outstanding: string\n days_overdue: number\n created_at: string\n updated_at: string\n}\n\ntype ListResponse = {\n items: BillingInvoiceRow[]\n total: number\n totalPages: number\n}\n\nexport type InvoicesTableProps = {\n title: string\n /** Pin the table to one account (account Invoices section). */\n billAccountId?: string\n /** Stable perspective / extension id. */\n tableId: string\n pageSize?: number\n /** Extra header actions (e.g. the billing settings shortcut). */\n actions?: React.ReactNode\n}\n\nfunction formatDate(value: string | null | undefined): string {\n if (!value) return '\u2014'\n const parsed = new Date(value)\n return Number.isNaN(parsed.getTime()) ? value : parsed.toLocaleDateString()\n}\n\nexport function formatMoney(value: string, currency: string): string {\n const n = Number.parseFloat(value)\n if (!Number.isFinite(n)) return value\n try {\n return new Intl.NumberFormat(undefined, { style: 'currency', currency }).format(n)\n } catch {\n return `${value} ${currency}`\n }\n}\n\nexport function invoiceStatusVariant(status: BillingInvoiceRow['status']): 'default' | 'success' | 'warning' | 'error' {\n switch (status) {\n case 'paid':\n case 'credited':\n return 'success'\n case 'posted':\n case 'partially_paid':\n return 'warning'\n case 'draft':\n default:\n return 'default'\n }\n}\n\nexport function InvoicesTable({ title, billAccountId, tableId, pageSize = 25, actions }: InvoicesTableProps) {\n const t = useT()\n const router = useRouter()\n const [rows, setRows] = React.useState<BillingInvoiceRow[]>([])\n const [page, setPage] = React.useState(1)\n const [filters, setFilters] = React.useState<FilterValues>({})\n const [search, setSearch] = React.useState('')\n const [total, setTotal] = React.useState(0)\n const [totalPages, setTotalPages] = React.useState(1)\n const [loading, setLoading] = React.useState(true)\n const [error, setError] = React.useState<string | null>(null)\n\n const statusLabel = React.useCallback(\n (status: BillingInvoiceRow['status']) =>\n ({\n draft: t('billing.invoices.status.draft', 'Draft'),\n posted: t('billing.invoices.status.posted', 'Posted'),\n partially_paid: t('billing.invoices.status.partially_paid', 'Partially paid'),\n paid: t('billing.invoices.status.paid', 'Paid'),\n credited: t('billing.invoices.status.credited', 'Credited'),\n })[status] ?? status,\n [t],\n )\n\n const filterDefs = React.useMemo<FilterDef[]>(\n () => [\n {\n id: 'status',\n label: t('billing.invoices.filters.status', 'Status'),\n type: 'select',\n options: (['draft', 'posted', 'partially_paid', 'paid', 'credited'] as const).map((value) => ({\n value,\n label: statusLabel(value),\n })),\n },\n {\n id: 'overdue',\n label: t('billing.invoices.filters.overdue', 'Overdue'),\n type: 'select',\n options: [\n { value: 'true', label: t('billing.invoices.filters.overdue.only', 'Only overdue') },\n { value: 'false', label: t('billing.invoices.filters.overdue.exclude', 'Not overdue') },\n ],\n },\n {\n id: 'documentType',\n label: t('billing.invoices.filters.document_type', 'Document type'),\n type: 'select',\n options: [\n { value: 'invoice', label: t('billing.invoices.document_type.invoice', 'Invoice') },\n { value: 'credit_memo', label: t('billing.invoices.document_type.credit_memo', 'Credit memo') },\n { value: 'debit_memo', label: t('billing.invoices.document_type.debit_memo', 'Debit memo') },\n { value: 'receipt', label: t('billing.invoices.document_type.receipt', 'Top-up receipt') },\n ],\n },\n {\n id: 'testRun',\n label: t('billing.invoices.filters.test_run', 'Test runs'),\n type: 'select',\n options: [\n { value: 'true', label: t('billing.invoices.filters.test_run.only', 'Only test') },\n { value: 'false', label: t('billing.invoices.filters.test_run.exclude', 'Exclude test') },\n ],\n },\n ],\n [statusLabel, t],\n )\n\n const loadRows = React.useCallback(async () => {\n setLoading(true)\n setError(null)\n try {\n const params = new URLSearchParams({ page: String(page), pageSize: String(Math.min(pageSize, 100)) })\n if (billAccountId) params.set('billAccountId', billAccountId)\n if (search.trim()) params.set('search', search.trim())\n for (const key of ['status', 'documentType'] as const) {\n const value = filters[key]\n if (typeof value === 'string' && value) params.set(key, value)\n }\n for (const key of ['testRun', 'overdue'] as const) {\n const value = filters[key]\n if (value === 'true' || value === 'false') params.set(key, value)\n }\n const result = await readApiResultOrThrow<ListResponse>(`/api/billing/invoices?${params.toString()}`)\n setRows(result.items ?? [])\n setTotal(result.total ?? 0)\n setTotalPages(result.totalPages ?? 1)\n } catch (err) {\n setError(err instanceof Error ? err.message : t('billing.invoices.error.load', 'Could not load invoices'))\n } finally {\n setLoading(false)\n }\n }, [billAccountId, filters, page, pageSize, search, t])\n\n React.useEffect(() => {\n void loadRows()\n }, [loadRows])\n\n const columns = React.useMemo<ColumnDef<BillingInvoiceRow>[]>(() => {\n const cols: ColumnDef<BillingInvoiceRow>[] = [\n {\n accessorKey: 'number',\n header: t('billing.invoices.columns.number', 'Number'),\n cell: ({ row }) => (\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm font-medium text-primary\">{row.original.number}</span>\n {row.original.test_run ? <Tag variant=\"warning\">TEST</Tag> : null}\n </div>\n ),\n },\n {\n accessorKey: 'document_type',\n header: t('billing.invoices.columns.type', 'Type'),\n cell: ({ row }) =>\n ({\n invoice: t('billing.invoices.document_type.invoice', 'Invoice'),\n credit_memo: t('billing.invoices.document_type.credit_memo', 'Credit memo'),\n debit_memo: t('billing.invoices.document_type.debit_memo', 'Debit memo'),\n receipt: t('billing.invoices.document_type.receipt', 'Top-up receipt'),\n })[row.original.document_type] ?? row.original.document_type,\n },\n {\n accessorKey: 'status',\n header: t('billing.invoices.columns.status', 'Status'),\n cell: ({ row }) => (\n <div className=\"flex items-center gap-1\">\n <Tag variant={invoiceStatusVariant(row.original.status)}>{statusLabel(row.original.status)}</Tag>\n {row.original.days_overdue > 0 ? (\n <Tag variant=\"error\">{t('billing.invoices.overdue', 'Overdue')}</Tag>\n ) : null}\n </div>\n ),\n },\n ]\n if (!billAccountId) {\n cols.push({\n accessorKey: 'bill_account_name',\n header: t('billing.invoices.columns.account', 'Account'),\n cell: ({ row }) => row.original.bill_account_name ?? '\u2014',\n meta: { truncate: true, maxWidth: '220px' },\n })\n }\n cols.push(\n {\n id: 'period',\n header: t('billing.invoices.columns.period', 'Period'),\n cell: ({ row }) => {\n const start = row.original.period_start?.slice(0, 10)\n const end = row.original.period_end?.slice(0, 10)\n if (!start || !end) return '\u2014'\n return (\n <span className=\"text-xs\">\n {start} \u2192 {end}\n </span>\n )\n },\n },\n {\n id: 'total',\n header: t('billing.invoices.columns.total', 'Total'),\n // Credit memos are stored positive (D-D5) and shown negative.\n cell: ({ row }) =>\n formatMoney(\n String(displaySign(row.original.document_type) * Number.parseFloat(row.original.total_gross)),\n row.original.currency_code,\n ),\n },\n {\n accessorKey: 'outstanding',\n header: t('billing.invoices.columns.outstanding', 'Outstanding'),\n cell: ({ row }) => formatMoney(row.original.outstanding, row.original.currency_code),\n },\n {\n accessorKey: 'issue_date',\n header: t('billing.invoices.columns.issued', 'Issued'),\n cell: ({ row }) => formatDate(row.original.issue_date),\n },\n {\n accessorKey: 'due_date',\n header: t('billing.invoices.columns.due', 'Due'),\n cell: ({ row }) => formatDate(row.original.due_date),\n },\n {\n accessorKey: 'days_overdue',\n header: t('billing.invoices.columns.days_overdue', 'Days overdue'),\n cell: ({ row }) =>\n row.original.days_overdue > 0 ? (\n <span className=\"font-medium text-status-error-text tabular-nums\">{row.original.days_overdue}</span>\n ) : (\n <span className=\"text-muted-foreground\">\u2014</span>\n ),\n },\n )\n return cols\n }, [billAccountId, statusLabel, t])\n\n return (\n <DataTable\n title={title}\n actions={actions}\n refreshButton={{ label: t('billing.common.refresh', 'Refresh'), onRefresh: loadRows, isRefreshing: loading }}\n columnChooser={{ auto: true }}\n perspective={{ tableId }}\n columns={columns}\n data={rows}\n error={error}\n emptyState={t('billing.invoices.empty', 'No invoices yet.')}\n onRowClick={(row) => router.push(invoiceDetailHref(row.id, { fromAccountId: billAccountId }))}\n rowActions={(row) => (\n <RowActions\n items={[\n {\n id: 'open',\n label: t('billing.invoices.actions.open', 'Open'),\n href: invoiceDetailHref(row.id, { fromAccountId: billAccountId }),\n },\n {\n id: 'pdf',\n label:\n row.status === 'draft'\n ? t('billing.invoices.actions.pdf_preview', 'Preview PDF')\n : t('billing.invoices.actions.pdf', 'Download PDF'),\n href: invoicePdfHref(row.id),\n },\n ]}\n />\n )}\n isLoading={loading}\n pagination={{ page, pageSize, total, totalPages, onPageChange: setPage }}\n filters={filterDefs}\n filterValues={filters}\n onFiltersApply={(next) => {\n setPage(1)\n setFilters(next)\n }}\n onFiltersClear={() => {\n setPage(1)\n setFilters({})\n }}\n searchValue={search}\n onSearchChange={(next) => {\n setPage(1)\n setSearch(next)\n }}\n />\n )\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }