@dainamite/billing 0.20.0 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (604) hide show
  1. package/CHANGELOG.md +103 -0
  2. package/dist/modules/billing/acl.js +13 -1
  3. package/dist/modules/billing/acl.js.map +2 -2
  4. package/dist/modules/billing/api/accounts/[id]/summary/route.js +52 -0
  5. package/dist/modules/billing/api/accounts/[id]/summary/route.js.map +7 -0
  6. package/dist/modules/billing/api/accounts/route.js +47 -4
  7. package/dist/modules/billing/api/accounts/route.js.map +2 -2
  8. package/dist/modules/billing/api/export/account/[id]/route.js +11 -7
  9. package/dist/modules/billing/api/export/account/[id]/route.js.map +2 -2
  10. package/dist/modules/billing/api/invoices/[id]/memos/route.js +54 -0
  11. package/dist/modules/billing/api/invoices/[id]/memos/route.js.map +7 -0
  12. package/dist/modules/billing/api/invoices/[id]/pdf/route.js +70 -0
  13. package/dist/modules/billing/api/invoices/[id]/pdf/route.js.map +7 -0
  14. package/dist/modules/billing/api/invoices/[id]/route.js +44 -24
  15. package/dist/modules/billing/api/invoices/[id]/route.js.map +2 -2
  16. package/dist/modules/billing/api/invoices/[id]/send/route.js +107 -0
  17. package/dist/modules/billing/api/invoices/[id]/send/route.js.map +7 -0
  18. package/dist/modules/billing/api/invoices/add-line/route.js +2 -2
  19. package/dist/modules/billing/api/invoices/add-line/route.js.map +2 -2
  20. package/dist/modules/billing/api/invoices/delete-draft/route.js +33 -0
  21. package/dist/modules/billing/api/invoices/delete-draft/route.js.map +7 -0
  22. package/dist/modules/billing/api/invoices/edit-line/route.js +2 -2
  23. package/dist/modules/billing/api/invoices/edit-line/route.js.map +2 -2
  24. package/dist/modules/billing/api/invoices/post/route.js +2 -2
  25. package/dist/modules/billing/api/invoices/post/route.js.map +2 -2
  26. package/dist/modules/billing/api/invoices/remove-line/route.js +2 -2
  27. package/dist/modules/billing/api/invoices/remove-line/route.js.map +2 -2
  28. package/dist/modules/billing/api/invoices/route.js +45 -46
  29. package/dist/modules/billing/api/invoices/route.js.map +2 -2
  30. package/dist/modules/billing/api/items/bulk/route.js +1 -1
  31. package/dist/modules/billing/api/items/bulk/route.js.map +2 -2
  32. package/dist/modules/billing/api/items/change-price/route.js +44 -0
  33. package/dist/modules/billing/api/items/change-price/route.js.map +7 -0
  34. package/dist/modules/billing/api/items/route.js +19 -7
  35. package/dist/modules/billing/api/items/route.js.map +2 -2
  36. package/dist/modules/billing/api/payment-imports/[id]/route.js +49 -0
  37. package/dist/modules/billing/api/payment-imports/[id]/route.js.map +7 -0
  38. package/dist/modules/billing/api/payment-imports/route.js +57 -0
  39. package/dist/modules/billing/api/payment-imports/route.js.map +7 -0
  40. package/dist/modules/billing/api/payments/[id]/route.js +60 -0
  41. package/dist/modules/billing/api/payments/[id]/route.js.map +7 -0
  42. package/dist/modules/billing/api/payments/allocate/route.js +35 -0
  43. package/dist/modules/billing/api/payments/allocate/route.js.map +7 -0
  44. package/dist/modules/billing/api/payments/assign/route.js +36 -0
  45. package/dist/modules/billing/api/payments/assign/route.js.map +7 -0
  46. package/dist/modules/billing/api/payments/convert-to-topup/route.js +35 -0
  47. package/dist/modules/billing/api/payments/convert-to-topup/route.js.map +7 -0
  48. package/dist/modules/billing/api/payments/ignore/route.js +35 -0
  49. package/dist/modules/billing/api/payments/ignore/route.js.map +7 -0
  50. package/dist/modules/billing/api/payments/import/route.js +63 -0
  51. package/dist/modules/billing/api/payments/import/route.js.map +7 -0
  52. package/dist/modules/billing/api/payments/restore/route.js +35 -0
  53. package/dist/modules/billing/api/payments/restore/route.js.map +7 -0
  54. package/dist/modules/billing/api/payments/route.js +114 -0
  55. package/dist/modules/billing/api/payments/route.js.map +7 -0
  56. package/dist/modules/billing/api/payments/unallocate/route.js +35 -0
  57. package/dist/modules/billing/api/payments/unallocate/route.js.map +7 -0
  58. package/dist/modules/billing/api/payments/unassign/route.js +35 -0
  59. package/dist/modules/billing/api/payments/unassign/route.js.map +7 -0
  60. package/dist/modules/billing/api/run-outcomes/route.js +43 -6
  61. package/dist/modules/billing/api/run-outcomes/route.js.map +2 -2
  62. package/dist/modules/billing/api/runs/[id]/post-drafts/route.js +61 -0
  63. package/dist/modules/billing/api/runs/[id]/post-drafts/route.js.map +7 -0
  64. package/dist/modules/billing/api/runs/[id]/route.js +53 -0
  65. package/dist/modules/billing/api/runs/[id]/route.js.map +7 -0
  66. package/dist/modules/billing/api/runs/retry-failed/route.js +1 -1
  67. package/dist/modules/billing/api/runs/retry-failed/route.js.map +2 -2
  68. package/dist/modules/billing/api/runs/route.js +9 -3
  69. package/dist/modules/billing/api/runs/route.js.map +2 -2
  70. package/dist/modules/billing/api/settings/number-preview/route.js +42 -0
  71. package/dist/modules/billing/api/settings/number-preview/route.js.map +7 -0
  72. package/dist/modules/billing/api/settings/route.js +92 -0
  73. package/dist/modules/billing/api/settings/route.js.map +7 -0
  74. package/dist/modules/billing/api/statements/route.js +3 -0
  75. package/dist/modules/billing/api/statements/route.js.map +2 -2
  76. package/dist/modules/billing/api/test-invoices/wipe/route.js +2 -2
  77. package/dist/modules/billing/api/test-invoices/wipe/route.js.map +2 -2
  78. package/dist/modules/billing/backend/billing/accounts/[id]/page.js +121 -232
  79. package/dist/modules/billing/backend/billing/accounts/[id]/page.js.map +2 -2
  80. package/dist/modules/billing/backend/billing/accounts/create/page.js +6 -0
  81. package/dist/modules/billing/backend/billing/accounts/create/page.js.map +2 -2
  82. package/dist/modules/billing/backend/billing/accounts/page.js +63 -4
  83. package/dist/modules/billing/backend/billing/accounts/page.js.map +2 -2
  84. package/dist/modules/billing/backend/billing/invoices/[id]/page.js +297 -65
  85. package/dist/modules/billing/backend/billing/invoices/[id]/page.js.map +3 -3
  86. package/dist/modules/billing/backend/billing/invoices/page.js +6 -172
  87. package/dist/modules/billing/backend/billing/invoices/page.js.map +2 -2
  88. package/dist/modules/billing/backend/billing/items/[id]/page.js +51 -7
  89. package/dist/modules/billing/backend/billing/items/[id]/page.js.map +2 -2
  90. package/dist/modules/billing/backend/billing/items/create/page.js +9 -6
  91. package/dist/modules/billing/backend/billing/items/create/page.js.map +2 -2
  92. package/dist/modules/billing/backend/billing/items/page.js +8 -2
  93. package/dist/modules/billing/backend/billing/items/page.js.map +2 -2
  94. package/dist/modules/billing/backend/billing/payments/[id]/page.js +297 -0
  95. package/dist/modules/billing/backend/billing/payments/[id]/page.js.map +7 -0
  96. package/dist/modules/billing/backend/billing/payments/[id]/page.meta.js +21 -0
  97. package/dist/modules/billing/backend/billing/payments/[id]/page.meta.js.map +7 -0
  98. package/dist/modules/billing/backend/billing/payments/imports/[id]/page.js +74 -0
  99. package/dist/modules/billing/backend/billing/payments/imports/[id]/page.js.map +7 -0
  100. package/dist/modules/billing/backend/billing/payments/imports/[id]/page.meta.js +21 -0
  101. package/dist/modules/billing/backend/billing/payments/imports/[id]/page.meta.js.map +7 -0
  102. package/dist/modules/billing/backend/billing/payments/page.js +58 -0
  103. package/dist/modules/billing/backend/billing/payments/page.js.map +7 -0
  104. package/dist/modules/billing/backend/billing/payments/page.meta.js +18 -0
  105. package/dist/modules/billing/backend/billing/payments/page.meta.js.map +7 -0
  106. package/dist/modules/billing/backend/billing/runs/[id]/page.js +49 -14
  107. package/dist/modules/billing/backend/billing/runs/[id]/page.js.map +2 -2
  108. package/dist/modules/billing/backend/billing/runs/page.js +58 -7
  109. package/dist/modules/billing/backend/billing/runs/page.js.map +2 -2
  110. package/dist/modules/billing/backend/billing/statements/[id]/page.js +61 -6
  111. package/dist/modules/billing/backend/billing/statements/[id]/page.js.map +2 -2
  112. package/dist/modules/billing/backend/billing/statements/page.js +1 -1
  113. package/dist/modules/billing/backend/billing/statements/page.js.map +2 -2
  114. package/dist/modules/billing/backend/billing/topups/page.js +1 -1
  115. package/dist/modules/billing/backend/billing/topups/page.js.map +2 -2
  116. package/dist/modules/billing/backend/billing/transactions/page.js +1 -1
  117. package/dist/modules/billing/backend/billing/transactions/page.js.map +2 -2
  118. package/dist/modules/billing/backend/billing/usage/create/page.js +3 -2
  119. package/dist/modules/billing/backend/billing/usage/create/page.js.map +2 -2
  120. package/dist/modules/billing/backend/config/billing/page.js +472 -0
  121. package/dist/modules/billing/backend/config/billing/page.js.map +7 -0
  122. package/dist/modules/billing/backend/config/billing/page.meta.js +19 -0
  123. package/dist/modules/billing/backend/config/billing/page.meta.js.map +7 -0
  124. package/dist/modules/billing/cli.js +22 -1
  125. package/dist/modules/billing/cli.js.map +2 -2
  126. package/dist/modules/billing/commands/accounts.js +6 -0
  127. package/dist/modules/billing/commands/accounts.js.map +2 -2
  128. package/dist/modules/billing/commands/index.js +3 -0
  129. package/dist/modules/billing/commands/index.js.map +2 -2
  130. package/dist/modules/billing/commands/invoices.js +269 -167
  131. package/dist/modules/billing/commands/invoices.js.map +2 -2
  132. package/dist/modules/billing/commands/items.js +108 -0
  133. package/dist/modules/billing/commands/items.js.map +2 -2
  134. package/dist/modules/billing/commands/memos.js +179 -0
  135. package/dist/modules/billing/commands/memos.js.map +7 -0
  136. package/dist/modules/billing/commands/payments.js +379 -0
  137. package/dist/modules/billing/commands/payments.js.map +7 -0
  138. package/dist/modules/billing/commands/runs.js +151 -4
  139. package/dist/modules/billing/commands/runs.js.map +2 -2
  140. package/dist/modules/billing/commands/settings.js +59 -0
  141. package/dist/modules/billing/commands/settings.js.map +7 -0
  142. package/dist/modules/billing/commands/topups.js +9 -2
  143. package/dist/modules/billing/commands/topups.js.map +2 -2
  144. package/dist/modules/billing/commands/transactions.js +2 -2
  145. package/dist/modules/billing/commands/transactions.js.map +2 -2
  146. package/dist/modules/billing/components/AccountForm.js +149 -42
  147. package/dist/modules/billing/components/AccountForm.js.map +2 -2
  148. package/dist/modules/billing/components/AccountInvoicesSection.js +64 -0
  149. package/dist/modules/billing/components/AccountInvoicesSection.js.map +7 -0
  150. package/dist/modules/billing/components/AccountPaymentsSection.js +43 -0
  151. package/dist/modules/billing/components/AccountPaymentsSection.js.map +7 -0
  152. package/dist/modules/billing/components/AccountPicker.js +56 -0
  153. package/dist/modules/billing/components/AccountPicker.js.map +7 -0
  154. package/dist/modules/billing/components/AllocatePaymentDialog.js +134 -0
  155. package/dist/modules/billing/components/AllocatePaymentDialog.js.map +7 -0
  156. package/dist/modules/billing/components/BillingDataTable.js +21 -0
  157. package/dist/modules/billing/components/BillingDataTable.js.map +7 -0
  158. package/dist/modules/billing/components/BillingSettingsLink.js +19 -0
  159. package/dist/modules/billing/components/BillingSettingsLink.js.map +7 -0
  160. package/dist/modules/billing/components/ChangeItemPriceDialog.js +158 -0
  161. package/dist/modules/billing/components/ChangeItemPriceDialog.js.map +7 -0
  162. package/dist/modules/billing/components/CreateMemoDialog.js +200 -0
  163. package/dist/modules/billing/components/CreateMemoDialog.js.map +7 -0
  164. package/dist/modules/billing/components/CustomerLabel.js +33 -0
  165. package/dist/modules/billing/components/CustomerLabel.js.map +7 -0
  166. package/dist/modules/billing/components/InvoicesTable.js +270 -0
  167. package/dist/modules/billing/components/InvoicesTable.js.map +7 -0
  168. package/dist/modules/billing/components/ItemForm.js +176 -44
  169. package/dist/modules/billing/components/ItemForm.js.map +2 -2
  170. package/dist/modules/billing/components/ItemPriceField.js +46 -0
  171. package/dist/modules/billing/components/ItemPriceField.js.map +7 -0
  172. package/dist/modules/billing/components/LineFormDialog.js +25 -2
  173. package/dist/modules/billing/components/LineFormDialog.js.map +2 -2
  174. package/dist/modules/billing/components/ManualPaymentDialog.js +122 -0
  175. package/dist/modules/billing/components/ManualPaymentDialog.js.map +7 -0
  176. package/dist/modules/billing/components/MoneyInput.js +14 -0
  177. package/dist/modules/billing/components/MoneyInput.js.map +7 -0
  178. package/dist/modules/billing/components/PaymentUploadDialog.js +115 -0
  179. package/dist/modules/billing/components/PaymentUploadDialog.js.map +7 -0
  180. package/dist/modules/billing/components/PaymentsTable.js +171 -0
  181. package/dist/modules/billing/components/PaymentsTable.js.map +7 -0
  182. package/dist/modules/billing/components/PostRunDraftsButton.js +105 -0
  183. package/dist/modules/billing/components/PostRunDraftsButton.js.map +7 -0
  184. package/dist/modules/billing/components/PrepaidPanel.js +14 -4
  185. package/dist/modules/billing/components/PrepaidPanel.js.map +2 -2
  186. package/dist/modules/billing/components/RunCyclesSection.js +209 -0
  187. package/dist/modules/billing/components/RunCyclesSection.js.map +7 -0
  188. package/dist/modules/billing/components/TestRunActions.js +127 -0
  189. package/dist/modules/billing/components/TestRunActions.js.map +7 -0
  190. package/dist/modules/billing/components/account/AccountItemsTab.js +157 -0
  191. package/dist/modules/billing/components/account/AccountItemsTab.js.map +7 -0
  192. package/dist/modules/billing/components/account/AccountRunBillingDialog.js +122 -0
  193. package/dist/modules/billing/components/account/AccountRunBillingDialog.js.map +7 -0
  194. package/dist/modules/billing/components/account/AccountRunsTab.js +152 -0
  195. package/dist/modules/billing/components/account/AccountRunsTab.js.map +7 -0
  196. package/dist/modules/billing/components/account/AccountStatementsTab.js +98 -0
  197. package/dist/modules/billing/components/account/AccountStatementsTab.js.map +7 -0
  198. package/dist/modules/billing/components/account/AccountSummaryCards.js +125 -0
  199. package/dist/modules/billing/components/account/AccountSummaryCards.js.map +7 -0
  200. package/dist/modules/billing/components/account/AccountUsageTab.js +91 -0
  201. package/dist/modules/billing/components/account/AccountUsageTab.js.map +7 -0
  202. package/dist/modules/billing/components/account/AccountView.js +73 -0
  203. package/dist/modules/billing/components/account/AccountView.js.map +7 -0
  204. package/dist/modules/billing/components/account/accountRow.js +39 -0
  205. package/dist/modules/billing/components/account/accountRow.js.map +7 -0
  206. package/dist/modules/billing/components/customerNames.js +42 -0
  207. package/dist/modules/billing/components/customerNames.js.map +7 -0
  208. package/dist/modules/billing/data/entities.js +560 -4
  209. package/dist/modules/billing/data/entities.js.map +2 -2
  210. package/dist/modules/billing/data/entityIds.js +10 -1
  211. package/dist/modules/billing/data/entityIds.js.map +2 -2
  212. package/dist/modules/billing/data/validators.js +269 -15
  213. package/dist/modules/billing/data/validators.js.map +2 -2
  214. package/dist/modules/billing/events.js +50 -0
  215. package/dist/modules/billing/events.js.map +2 -2
  216. package/dist/modules/billing/i18n/de.json +880 -0
  217. package/dist/modules/billing/i18n/en.json +457 -21
  218. package/dist/modules/billing/i18n/es.json +880 -0
  219. package/dist/modules/billing/i18n/pl.json +458 -22
  220. package/dist/modules/billing/index.js +6 -2
  221. package/dist/modules/billing/index.js.map +2 -2
  222. package/dist/modules/billing/lib/accountFinancials.js +58 -0
  223. package/dist/modules/billing/lib/accountFinancials.js.map +7 -0
  224. package/dist/modules/billing/lib/accountLock.js +14 -0
  225. package/dist/modules/billing/lib/accountLock.js.map +7 -0
  226. package/dist/modules/billing/lib/accountStatus.js +9 -7
  227. package/dist/modules/billing/lib/accountStatus.js.map +2 -2
  228. package/dist/modules/billing/lib/accountSummary.js +106 -0
  229. package/dist/modules/billing/lib/accountSummary.js.map +7 -0
  230. package/dist/modules/billing/lib/allocation.js +356 -0
  231. package/dist/modules/billing/lib/allocation.js.map +7 -0
  232. package/dist/modules/billing/lib/allocationEvents.js +22 -0
  233. package/dist/modules/billing/lib/allocationEvents.js.map +7 -0
  234. package/dist/modules/billing/lib/billPeriod.js +15 -1
  235. package/dist/modules/billing/lib/billPeriod.js.map +2 -2
  236. package/dist/modules/billing/lib/billRunEngine.js +237 -102
  237. package/dist/modules/billing/lib/billRunEngine.js.map +2 -2
  238. package/dist/modules/billing/lib/billingSettings.js +116 -0
  239. package/dist/modules/billing/lib/billingSettings.js.map +7 -0
  240. package/dist/modules/billing/lib/commandRoute.js +81 -0
  241. package/dist/modules/billing/lib/commandRoute.js.map +7 -0
  242. package/dist/modules/billing/lib/customerLookup.js +97 -0
  243. package/dist/modules/billing/lib/customerLookup.js.map +7 -0
  244. package/dist/modules/billing/lib/dateOnly.js +13 -0
  245. package/dist/modules/billing/lib/dateOnly.js.map +7 -0
  246. package/dist/modules/billing/lib/documentParties.js +16 -0
  247. package/dist/modules/billing/lib/documentParties.js.map +7 -0
  248. package/dist/modules/billing/lib/documentTypes.js +27 -0
  249. package/dist/modules/billing/lib/documentTypes.js.map +7 -0
  250. package/dist/modules/billing/lib/dueDate.js +18 -0
  251. package/dist/modules/billing/lib/dueDate.js.map +7 -0
  252. package/dist/modules/billing/lib/iban.js +29 -0
  253. package/dist/modules/billing/lib/iban.js.map +7 -0
  254. package/dist/modules/billing/lib/invoiceDelivery.js +133 -0
  255. package/dist/modules/billing/lib/invoiceDelivery.js.map +7 -0
  256. package/dist/modules/billing/lib/invoiceLanguages.js +28 -0
  257. package/dist/modules/billing/lib/invoiceLanguages.js.map +7 -0
  258. package/dist/modules/billing/lib/invoiceWriter.js +107 -99
  259. package/dist/modules/billing/lib/invoiceWriter.js.map +2 -2
  260. package/dist/modules/billing/lib/itemBillingState.js +27 -0
  261. package/dist/modules/billing/lib/itemBillingState.js.map +7 -0
  262. package/dist/modules/billing/lib/itemPriceChange.js +18 -0
  263. package/dist/modules/billing/lib/itemPriceChange.js.map +7 -0
  264. package/dist/modules/billing/lib/itemSelector.js.map +2 -2
  265. package/dist/modules/billing/lib/lineAmounts.js +32 -0
  266. package/dist/modules/billing/lib/lineAmounts.js.map +7 -0
  267. package/dist/modules/billing/lib/memoGuards.js +25 -0
  268. package/dist/modules/billing/lib/memoGuards.js.map +7 -0
  269. package/dist/modules/billing/lib/navigation.js +48 -0
  270. package/dist/modules/billing/lib/navigation.js.map +7 -0
  271. package/dist/modules/billing/lib/numbering.js +120 -0
  272. package/dist/modules/billing/lib/numbering.js.map +7 -0
  273. package/dist/modules/billing/lib/overdue.js +36 -0
  274. package/dist/modules/billing/lib/overdue.js.map +7 -0
  275. package/dist/modules/billing/lib/paymentCsv.js +125 -0
  276. package/dist/modules/billing/lib/paymentCsv.js.map +7 -0
  277. package/dist/modules/billing/lib/paymentGateway.js +15 -0
  278. package/dist/modules/billing/lib/paymentGateway.js.map +7 -0
  279. package/dist/modules/billing/lib/paymentImport.js +164 -0
  280. package/dist/modules/billing/lib/paymentImport.js.map +7 -0
  281. package/dist/modules/billing/lib/paymentMatcher.js +36 -0
  282. package/dist/modules/billing/lib/paymentMatcher.js.map +7 -0
  283. package/dist/modules/billing/lib/pdf/attachmentStore.js +46 -0
  284. package/dist/modules/billing/lib/pdf/attachmentStore.js.map +7 -0
  285. package/dist/modules/billing/lib/pdf/fonts/embeddedFonts.js +7 -0
  286. package/dist/modules/billing/lib/pdf/fonts/embeddedFonts.js.map +7 -0
  287. package/dist/modules/billing/lib/pdf/invoiceModel.js +194 -0
  288. package/dist/modules/billing/lib/pdf/invoiceModel.js.map +7 -0
  289. package/dist/modules/billing/lib/pdf/invoicePdf.js +165 -0
  290. package/dist/modules/billing/lib/pdf/invoicePdf.js.map +7 -0
  291. package/dist/modules/billing/lib/pdf/invoiceTemplate.js +276 -0
  292. package/dist/modules/billing/lib/pdf/invoiceTemplate.js.map +7 -0
  293. package/dist/modules/billing/lib/prepaidConfig.js +17 -25
  294. package/dist/modules/billing/lib/prepaidConfig.js.map +2 -2
  295. package/dist/modules/billing/lib/prepaidConsume.js +26 -7
  296. package/dist/modules/billing/lib/prepaidConsume.js.map +2 -2
  297. package/dist/modules/billing/lib/prepaidPeriodClose.js +277 -158
  298. package/dist/modules/billing/lib/prepaidPeriodClose.js.map +2 -2
  299. package/dist/modules/billing/lib/prepaidTaxPoint.js +37 -0
  300. package/dist/modules/billing/lib/prepaidTaxPoint.js.map +7 -0
  301. package/dist/modules/billing/lib/seeds/demo.js +51 -3
  302. package/dist/modules/billing/lib/seeds/demo.js.map +2 -2
  303. package/dist/modules/billing/lib/seeds/paymentsSample.js +93 -0
  304. package/dist/modules/billing/lib/seeds/paymentsSample.js.map +7 -0
  305. package/dist/modules/billing/lib/seeds/sellerSettings.js +41 -0
  306. package/dist/modules/billing/lib/seeds/sellerSettings.js.map +7 -0
  307. package/dist/modules/billing/lib/servicePeriods.js +121 -0
  308. package/dist/modules/billing/lib/servicePeriods.js.map +7 -0
  309. package/dist/modules/billing/lib/testRunCleanup.js +24 -0
  310. package/dist/modules/billing/lib/testRunCleanup.js.map +7 -0
  311. package/dist/modules/billing/lib/topupCapture.js +2 -2
  312. package/dist/modules/billing/lib/topupCapture.js.map +2 -2
  313. package/dist/modules/billing/lib/topupReceipt.js +58 -79
  314. package/dist/modules/billing/lib/topupReceipt.js.map +2 -2
  315. package/dist/modules/billing/lib/usageRater.js.map +1 -1
  316. package/dist/modules/billing/lib/usageRunner.js +14 -6
  317. package/dist/modules/billing/lib/usageRunner.js.map +2 -2
  318. package/dist/modules/billing/lib/vat.js +39 -0
  319. package/dist/modules/billing/lib/vat.js.map +7 -0
  320. package/dist/modules/billing/migrations/Migration20261114000000_billing_customer_kind.js +15 -0
  321. package/dist/modules/billing/migrations/Migration20261114000000_billing_customer_kind.js.map +7 -0
  322. package/dist/modules/billing/migrations/Migration20261114100000_billing_cycle_semantics.js +25 -0
  323. package/dist/modules/billing/migrations/Migration20261114100000_billing_cycle_semantics.js.map +7 -0
  324. package/dist/modules/billing/migrations/Migration20261115000000_billing_invoice_ledger.js +115 -0
  325. package/dist/modules/billing/migrations/Migration20261115000000_billing_invoice_ledger.js.map +7 -0
  326. package/dist/modules/billing/migrations/Migration20261116000000_billing_invoice_documents.js +47 -0
  327. package/dist/modules/billing/migrations/Migration20261116000000_billing_invoice_documents.js.map +7 -0
  328. package/dist/modules/billing/migrations/Migration20261117000000_billing_payments.js +89 -0
  329. package/dist/modules/billing/migrations/Migration20261117000000_billing_payments.js.map +7 -0
  330. package/dist/modules/billing/migrations/Migration20261118000000_billing_memos.js +17 -0
  331. package/dist/modules/billing/migrations/Migration20261118000000_billing_memos.js.map +7 -0
  332. package/dist/modules/billing/migrations/Migration20261119000000_billing_operator_feedback.js +27 -0
  333. package/dist/modules/billing/migrations/Migration20261119000000_billing_operator_feedback.js.map +7 -0
  334. package/dist/modules/billing/migrations/Migration20261120000000_billing_allocation_scope_indexes.js +29 -0
  335. package/dist/modules/billing/migrations/Migration20261120000000_billing_allocation_scope_indexes.js.map +7 -0
  336. package/dist/modules/billing/setup.js +7 -184
  337. package/dist/modules/billing/setup.js.map +2 -2
  338. package/dist/modules/billing/subscribers/credit-memo-auto-send.js +16 -0
  339. package/dist/modules/billing/subscribers/credit-memo-auto-send.js.map +7 -0
  340. package/dist/modules/billing/subscribers/debit-memo-apply-credit.js +16 -0
  341. package/dist/modules/billing/subscribers/debit-memo-apply-credit.js.map +7 -0
  342. package/dist/modules/billing/subscribers/debit-memo-auto-send.js +16 -0
  343. package/dist/modules/billing/subscribers/debit-memo-auto-send.js.map +7 -0
  344. package/dist/modules/billing/subscribers/invoice-apply-credit.js +34 -0
  345. package/dist/modules/billing/subscribers/invoice-apply-credit.js.map +7 -0
  346. package/dist/modules/billing/subscribers/invoice-auto-send.js +30 -0
  347. package/dist/modules/billing/subscribers/invoice-auto-send.js.map +7 -0
  348. package/dist/modules/billing/subscribers/payment-captured-to-paid.js +69 -33
  349. package/dist/modules/billing/subscribers/payment-captured-to-paid.js.map +2 -2
  350. package/dist/modules/billing/subscribers/prepaid-topup-captured.js +4 -6
  351. package/dist/modules/billing/subscribers/prepaid-topup-captured.js.map +2 -2
  352. package/generated/entities/billing_account/index.ts +3 -0
  353. package/generated/entities/billing_allocation/index.ts +18 -0
  354. package/generated/entities/billing_document_sequence/index.ts +11 -0
  355. package/generated/entities/billing_invoice/index.ts +38 -0
  356. package/generated/entities/billing_invoice_line/index.ts +24 -0
  357. package/generated/entities/billing_item/index.ts +4 -0
  358. package/generated/entities/billing_payment/index.ts +25 -0
  359. package/generated/entities/billing_payment_import/index.ts +14 -0
  360. package/generated/entities/billing_run/index.ts +0 -1
  361. package/generated/entities/billing_run_outcome/index.ts +1 -0
  362. package/generated/entities/billing_settings/index.ts +26 -0
  363. package/generated/entities/billing_statement/index.ts +1 -0
  364. package/generated/entities.ids.generated.ts +7 -0
  365. package/package.json +5 -1
  366. package/src/modules/billing/__integration__/TC-BILL-004.spec.ts +171 -0
  367. package/src/modules/billing/__integration__/TC-BILL-005.spec.ts +134 -0
  368. package/src/modules/billing/__integration__/TC-BILL-006.spec.ts +101 -0
  369. package/src/modules/billing/__integration__/TC-BILL-007.spec.ts +140 -0
  370. package/src/modules/billing/__integration__/TC-BILL-008.spec.ts +108 -0
  371. package/src/modules/billing/__integration__/TC-BILL-009.spec.ts +113 -0
  372. package/src/modules/billing/__integration__/TC-BILL-010.spec.ts +118 -0
  373. package/src/modules/billing/__integration__/TC-BILL-011.spec.ts +142 -0
  374. package/src/modules/billing/__integration__/TC-BILL-012.spec.ts +115 -0
  375. package/src/modules/billing/__integration__/TC-BILL-013.spec.ts +118 -0
  376. package/src/modules/billing/__integration__/sellerSettings.ts +24 -0
  377. package/src/modules/billing/__tests__/commands/invoices.test.ts +436 -354
  378. package/src/modules/billing/__tests__/commands/itemsBulk.test.ts +33 -0
  379. package/src/modules/billing/__tests__/commands/memos.test.ts +205 -0
  380. package/src/modules/billing/__tests__/commands/payments.test.ts +241 -0
  381. package/src/modules/billing/__tests__/commands/runsDelete.test.ts +146 -0
  382. package/src/modules/billing/__tests__/commands/runsPostDrafts.test.ts +106 -0
  383. package/src/modules/billing/__tests__/commands/topups.test.ts +11 -0
  384. package/src/modules/billing/__tests__/entityRegistry.test.ts +8 -1
  385. package/src/modules/billing/__tests__/helpers/prepaidMockEm.ts +28 -11
  386. package/src/modules/billing/__tests__/i18n/dictionaries.test.ts +64 -0
  387. package/src/modules/billing/__tests__/lib/accountFinancials.test.ts +53 -0
  388. package/src/modules/billing/__tests__/lib/accountSummary.test.ts +97 -0
  389. package/src/modules/billing/__tests__/lib/allocation.test.ts +319 -0
  390. package/src/modules/billing/__tests__/lib/billRunEngine.test.ts +228 -17
  391. package/src/modules/billing/__tests__/lib/billingSettings.test.ts +109 -0
  392. package/src/modules/billing/__tests__/lib/customerLookup.test.ts +156 -0
  393. package/src/modules/billing/__tests__/lib/dueDate.test.ts +35 -0
  394. package/src/modules/billing/__tests__/lib/iban.test.ts +38 -0
  395. package/src/modules/billing/__tests__/lib/invoiceDelivery.test.ts +206 -0
  396. package/src/modules/billing/__tests__/lib/invoiceLanguages.test.ts +49 -0
  397. package/src/modules/billing/__tests__/lib/invoiceWriter.test.ts +212 -10
  398. package/src/modules/billing/__tests__/lib/itemBillingState.test.ts +42 -0
  399. package/src/modules/billing/__tests__/lib/itemPriceChange.test.ts +165 -0
  400. package/src/modules/billing/__tests__/lib/lineAmounts.test.ts +86 -0
  401. package/src/modules/billing/__tests__/lib/navigation.test.ts +71 -0
  402. package/src/modules/billing/__tests__/lib/numbering.test.ts +91 -0
  403. package/src/modules/billing/__tests__/lib/overdue.test.ts +36 -0
  404. package/src/modules/billing/__tests__/lib/paymentCsv.test.ts +148 -0
  405. package/src/modules/billing/__tests__/lib/paymentImport.test.ts +113 -0
  406. package/src/modules/billing/__tests__/lib/paymentsSample.test.ts +73 -0
  407. package/src/modules/billing/__tests__/lib/pdf/invoicePdf.test.ts +269 -0
  408. package/src/modules/billing/__tests__/lib/pdf/invoicePdfService.test.ts +147 -0
  409. package/src/modules/billing/__tests__/lib/prepaidPeriodClose.test.ts +374 -98
  410. package/src/modules/billing/__tests__/lib/prepaidTaxPoint.test.ts +118 -0
  411. package/src/modules/billing/__tests__/lib/seedsDemo.test.ts +53 -2
  412. package/src/modules/billing/__tests__/lib/sellerSettings.test.ts +28 -0
  413. package/src/modules/billing/__tests__/lib/servicePeriods.test.ts +190 -0
  414. package/src/modules/billing/__tests__/lib/topupCapture.test.ts +6 -28
  415. package/src/modules/billing/__tests__/lib/topupReceipt.test.ts +21 -52
  416. package/src/modules/billing/__tests__/lib/vat.test.ts +51 -0
  417. package/src/modules/billing/__tests__/package-isolation.test.ts +22 -8
  418. package/src/modules/billing/__tests__/setup.test.ts +13 -4
  419. package/src/modules/billing/__tests__/validators.test.ts +197 -3
  420. package/src/modules/billing/acl.ts +12 -0
  421. package/src/modules/billing/api/accounts/[id]/summary/route.ts +62 -0
  422. package/src/modules/billing/api/accounts/route.ts +59 -4
  423. package/src/modules/billing/api/export/account/[id]/route.ts +13 -11
  424. package/src/modules/billing/api/invoices/[id]/memos/route.ts +63 -0
  425. package/src/modules/billing/api/invoices/[id]/pdf/route.ts +80 -0
  426. package/src/modules/billing/api/invoices/[id]/route.ts +57 -70
  427. package/src/modules/billing/api/invoices/[id]/send/route.ts +127 -0
  428. package/src/modules/billing/api/invoices/add-line/route.ts +2 -2
  429. package/src/modules/billing/api/invoices/delete-draft/route.ts +33 -0
  430. package/src/modules/billing/api/invoices/edit-line/route.ts +2 -2
  431. package/src/modules/billing/api/invoices/post/route.ts +7 -6
  432. package/src/modules/billing/api/invoices/remove-line/route.ts +2 -2
  433. package/src/modules/billing/api/invoices/route.ts +81 -86
  434. package/src/modules/billing/api/items/bulk/route.ts +2 -1
  435. package/src/modules/billing/api/items/change-price/route.ts +54 -0
  436. package/src/modules/billing/api/items/route.ts +23 -7
  437. package/src/modules/billing/api/payment-imports/[id]/route.ts +49 -0
  438. package/src/modules/billing/api/payment-imports/route.ts +57 -0
  439. package/src/modules/billing/api/payments/[id]/route.ts +63 -0
  440. package/src/modules/billing/api/payments/allocate/route.ts +35 -0
  441. package/src/modules/billing/api/payments/assign/route.ts +36 -0
  442. package/src/modules/billing/api/payments/convert-to-topup/route.ts +35 -0
  443. package/src/modules/billing/api/payments/ignore/route.ts +35 -0
  444. package/src/modules/billing/api/payments/import/route.ts +72 -0
  445. package/src/modules/billing/api/payments/restore/route.ts +35 -0
  446. package/src/modules/billing/api/payments/route.ts +147 -0
  447. package/src/modules/billing/api/payments/unallocate/route.ts +35 -0
  448. package/src/modules/billing/api/payments/unassign/route.ts +35 -0
  449. package/src/modules/billing/api/run-outcomes/route.ts +49 -6
  450. package/src/modules/billing/api/runs/[id]/post-drafts/route.ts +71 -0
  451. package/src/modules/billing/api/runs/[id]/route.ts +59 -0
  452. package/src/modules/billing/api/runs/retry-failed/route.ts +2 -1
  453. package/src/modules/billing/api/runs/route.ts +15 -7
  454. package/src/modules/billing/api/settings/number-preview/route.ts +46 -0
  455. package/src/modules/billing/api/settings/route.ts +116 -0
  456. package/src/modules/billing/api/statements/route.ts +5 -0
  457. package/src/modules/billing/api/test-invoices/wipe/route.ts +2 -2
  458. package/src/modules/billing/backend/billing/accounts/[id]/page.tsx +151 -372
  459. package/src/modules/billing/backend/billing/accounts/create/page.tsx +6 -0
  460. package/src/modules/billing/backend/billing/accounts/page.tsx +70 -4
  461. package/src/modules/billing/backend/billing/invoices/[id]/page.tsx +444 -95
  462. package/src/modules/billing/backend/billing/invoices/page.tsx +8 -227
  463. package/src/modules/billing/backend/billing/items/[id]/page.tsx +75 -6
  464. package/src/modules/billing/backend/billing/items/create/page.tsx +13 -8
  465. package/src/modules/billing/backend/billing/items/page.tsx +18 -2
  466. package/src/modules/billing/backend/billing/payments/[id]/page.meta.ts +19 -0
  467. package/src/modules/billing/backend/billing/payments/[id]/page.tsx +415 -0
  468. package/src/modules/billing/backend/billing/payments/imports/[id]/page.meta.ts +19 -0
  469. package/src/modules/billing/backend/billing/payments/imports/[id]/page.tsx +106 -0
  470. package/src/modules/billing/backend/billing/payments/page.meta.ts +16 -0
  471. package/src/modules/billing/backend/billing/payments/page.tsx +56 -0
  472. package/src/modules/billing/backend/billing/runs/[id]/page.tsx +49 -18
  473. package/src/modules/billing/backend/billing/runs/page.tsx +59 -8
  474. package/src/modules/billing/backend/billing/statements/[id]/page.tsx +86 -5
  475. package/src/modules/billing/backend/billing/statements/page.tsx +1 -1
  476. package/src/modules/billing/backend/billing/topups/page.tsx +1 -1
  477. package/src/modules/billing/backend/billing/transactions/page.tsx +1 -1
  478. package/src/modules/billing/backend/billing/usage/create/page.tsx +3 -2
  479. package/src/modules/billing/backend/config/billing/page.meta.ts +21 -0
  480. package/src/modules/billing/backend/config/billing/page.tsx +549 -0
  481. package/src/modules/billing/cli.ts +31 -1
  482. package/src/modules/billing/commands/accounts.ts +6 -0
  483. package/src/modules/billing/commands/index.ts +3 -0
  484. package/src/modules/billing/commands/invoices.ts +364 -231
  485. package/src/modules/billing/commands/items.ts +143 -0
  486. package/src/modules/billing/commands/memos.ts +218 -0
  487. package/src/modules/billing/commands/payments.ts +428 -0
  488. package/src/modules/billing/commands/runs.ts +205 -3
  489. package/src/modules/billing/commands/settings.ts +77 -0
  490. package/src/modules/billing/commands/topups.ts +12 -3
  491. package/src/modules/billing/commands/transactions.ts +2 -2
  492. package/src/modules/billing/components/AccountForm.tsx +199 -53
  493. package/src/modules/billing/components/AccountInvoicesSection.tsx +75 -0
  494. package/src/modules/billing/components/AccountPaymentsSection.tsx +42 -0
  495. package/src/modules/billing/components/AccountPicker.tsx +70 -0
  496. package/src/modules/billing/components/AllocatePaymentDialog.tsx +167 -0
  497. package/src/modules/billing/components/BillingDataTable.tsx +34 -0
  498. package/src/modules/billing/components/BillingSettingsLink.tsx +25 -0
  499. package/src/modules/billing/components/ChangeItemPriceDialog.tsx +180 -0
  500. package/src/modules/billing/components/CreateMemoDialog.tsx +232 -0
  501. package/src/modules/billing/components/CustomerLabel.tsx +53 -0
  502. package/src/modules/billing/components/InvoicesTable.tsx +344 -0
  503. package/src/modules/billing/components/ItemForm.tsx +233 -44
  504. package/src/modules/billing/components/ItemPriceField.tsx +81 -0
  505. package/src/modules/billing/components/LineFormDialog.tsx +25 -1
  506. package/src/modules/billing/components/ManualPaymentDialog.tsx +140 -0
  507. package/src/modules/billing/components/MoneyInput.tsx +26 -0
  508. package/src/modules/billing/components/PaymentUploadDialog.tsx +148 -0
  509. package/src/modules/billing/components/PaymentsTable.tsx +213 -0
  510. package/src/modules/billing/components/PostRunDraftsButton.tsx +129 -0
  511. package/src/modules/billing/components/PrepaidPanel.tsx +19 -6
  512. package/src/modules/billing/components/RunCyclesSection.tsx +298 -0
  513. package/src/modules/billing/components/TestRunActions.tsx +152 -0
  514. package/src/modules/billing/components/account/AccountItemsTab.tsx +192 -0
  515. package/src/modules/billing/components/account/AccountRunBillingDialog.tsx +147 -0
  516. package/src/modules/billing/components/account/AccountRunsTab.tsx +201 -0
  517. package/src/modules/billing/components/account/AccountStatementsTab.tsx +120 -0
  518. package/src/modules/billing/components/account/AccountSummaryCards.tsx +153 -0
  519. package/src/modules/billing/components/account/AccountUsageTab.tsx +122 -0
  520. package/src/modules/billing/components/account/AccountView.tsx +101 -0
  521. package/src/modules/billing/components/account/accountRow.ts +70 -0
  522. package/src/modules/billing/components/customerNames.ts +62 -0
  523. package/src/modules/billing/data/entities.ts +656 -6
  524. package/src/modules/billing/data/entityIds.ts +9 -0
  525. package/src/modules/billing/data/validators.ts +388 -8
  526. package/src/modules/billing/events.ts +56 -3
  527. package/src/modules/billing/i18n/de.json +880 -0
  528. package/src/modules/billing/i18n/en.json +457 -21
  529. package/src/modules/billing/i18n/es.json +880 -0
  530. package/src/modules/billing/i18n/pl.json +458 -22
  531. package/src/modules/billing/index.ts +6 -2
  532. package/src/modules/billing/lib/accountFinancials.ts +84 -0
  533. package/src/modules/billing/lib/accountLock.ts +32 -0
  534. package/src/modules/billing/lib/accountStatus.ts +11 -9
  535. package/src/modules/billing/lib/accountSummary.ts +172 -0
  536. package/src/modules/billing/lib/allocation.ts +515 -0
  537. package/src/modules/billing/lib/allocationEvents.ts +26 -0
  538. package/src/modules/billing/lib/billPeriod.ts +19 -0
  539. package/src/modules/billing/lib/billRunEngine.ts +350 -150
  540. package/src/modules/billing/lib/billingSettings.ts +145 -0
  541. package/src/modules/billing/lib/commandRoute.ts +112 -0
  542. package/src/modules/billing/lib/customerLookup.ts +157 -0
  543. package/src/modules/billing/lib/dateOnly.ts +22 -0
  544. package/src/modules/billing/lib/documentParties.ts +23 -0
  545. package/src/modules/billing/lib/documentTypes.ts +37 -0
  546. package/src/modules/billing/lib/dueDate.ts +26 -0
  547. package/src/modules/billing/lib/iban.ts +36 -0
  548. package/src/modules/billing/lib/invoiceDelivery.ts +196 -0
  549. package/src/modules/billing/lib/invoiceLanguages.ts +57 -0
  550. package/src/modules/billing/lib/invoiceWriter.ts +162 -148
  551. package/src/modules/billing/lib/itemBillingState.ts +67 -0
  552. package/src/modules/billing/lib/itemPriceChange.ts +56 -0
  553. package/src/modules/billing/lib/itemSelector.ts +4 -1
  554. package/src/modules/billing/lib/lineAmounts.ts +61 -0
  555. package/src/modules/billing/lib/memoGuards.ts +41 -0
  556. package/src/modules/billing/lib/navigation.ts +64 -0
  557. package/src/modules/billing/lib/numbering.ts +174 -0
  558. package/src/modules/billing/lib/overdue.ts +60 -0
  559. package/src/modules/billing/lib/paymentCsv.ts +171 -0
  560. package/src/modules/billing/lib/paymentGateway.ts +52 -0
  561. package/src/modules/billing/lib/paymentImport.ts +228 -0
  562. package/src/modules/billing/lib/paymentMatcher.ts +88 -0
  563. package/src/modules/billing/lib/pdf/attachmentStore.ts +60 -0
  564. package/src/modules/billing/lib/pdf/fonts/NotoSans-Bold.ttf +0 -0
  565. package/src/modules/billing/lib/pdf/fonts/NotoSans-Regular.ttf +0 -0
  566. package/src/modules/billing/lib/pdf/fonts/OFL.txt +93 -0
  567. package/src/modules/billing/lib/pdf/fonts/embeddedFonts.ts +9 -0
  568. package/src/modules/billing/lib/pdf/invoiceModel.ts +329 -0
  569. package/src/modules/billing/lib/pdf/invoicePdf.ts +220 -0
  570. package/src/modules/billing/lib/pdf/invoiceTemplate.ts +338 -0
  571. package/src/modules/billing/lib/prepaidConfig.ts +27 -36
  572. package/src/modules/billing/lib/prepaidConsume.ts +29 -6
  573. package/src/modules/billing/lib/prepaidPeriodClose.ts +407 -239
  574. package/src/modules/billing/lib/prepaidTaxPoint.ts +76 -0
  575. package/src/modules/billing/lib/seeds/demo.ts +79 -6
  576. package/src/modules/billing/lib/seeds/paymentsSample.ts +136 -0
  577. package/src/modules/billing/lib/seeds/sellerSettings.ts +78 -0
  578. package/src/modules/billing/lib/servicePeriods.ts +226 -0
  579. package/src/modules/billing/lib/testRunCleanup.ts +42 -0
  580. package/src/modules/billing/lib/topupCapture.ts +3 -4
  581. package/src/modules/billing/lib/topupReceipt.ts +70 -103
  582. package/src/modules/billing/lib/usageRater.ts +1 -1
  583. package/src/modules/billing/lib/usageRunner.ts +17 -5
  584. package/src/modules/billing/lib/vat.ts +56 -0
  585. package/src/modules/billing/migrations/Migration20261114000000_billing_customer_kind.ts +25 -0
  586. package/src/modules/billing/migrations/Migration20261114100000_billing_cycle_semantics.ts +37 -0
  587. package/src/modules/billing/migrations/Migration20261115000000_billing_invoice_ledger.ts +132 -0
  588. package/src/modules/billing/migrations/Migration20261116000000_billing_invoice_documents.ts +58 -0
  589. package/src/modules/billing/migrations/Migration20261117000000_billing_payments.ts +97 -0
  590. package/src/modules/billing/migrations/Migration20261118000000_billing_memos.ts +21 -0
  591. package/src/modules/billing/migrations/Migration20261119000000_billing_operator_feedback.ts +39 -0
  592. package/src/modules/billing/migrations/Migration20261120000000_billing_allocation_scope_indexes.ts +35 -0
  593. package/src/modules/billing/setup.ts +11 -237
  594. package/src/modules/billing/subscribers/credit-memo-auto-send.ts +15 -0
  595. package/src/modules/billing/subscribers/debit-memo-apply-credit.ts +15 -0
  596. package/src/modules/billing/subscribers/debit-memo-auto-send.ts +15 -0
  597. package/src/modules/billing/subscribers/invoice-apply-credit.ts +39 -0
  598. package/src/modules/billing/subscribers/invoice-auto-send.ts +46 -0
  599. package/src/modules/billing/subscribers/payment-captured-to-paid.ts +84 -62
  600. package/src/modules/billing/subscribers/prepaid-topup-captured.ts +4 -8
  601. package/dist/modules/billing/lib/invoiceStatus.js +0 -38
  602. package/dist/modules/billing/lib/invoiceStatus.js.map +0 -7
  603. package/src/modules/billing/__tests__/lib/invoiceStatus.test.ts +0 -97
  604. package/src/modules/billing/lib/invoiceStatus.ts +0 -61
@@ -13,6 +13,12 @@ import {
13
13
  import { Switch } from '@open-mercato/ui/primitives/switch'
14
14
  import { Kbd, KbdShortcut } from '@open-mercato/ui/primitives/kbd'
15
15
  import { useT } from '@open-mercato/shared/lib/i18n/context'
16
+ import Link from 'next/link'
17
+ import { SegmentedControl, SegmentedControlItem } from '@open-mercato/ui/primitives/segmented-control'
18
+ import { apiCall } from '@open-mercato/ui/backend/utils/apiCall'
19
+ import { ItemPriceField } from './ItemPriceField'
20
+ import { BILLING_SETTINGS_HREF } from './BillingSettingsLink'
21
+ import { counterpartAmount, type PriceBasis } from '../lib/lineAmounts'
16
22
 
17
23
  /**
18
24
  * Shared form for Billing Item create + edit.
@@ -52,6 +58,13 @@ export type ItemFormValues = {
52
58
  subscriptionId: string
53
59
  subscriptionItemId: string
54
60
  isActive: boolean
61
+ // Spec A — recurring only.
62
+ chargeTiming: 'in_advance' | 'in_arrears'
63
+ prorate: boolean
64
+ // Spec B — VAT %. Empty on create → the organization default.
65
+ taxRate: string
66
+ // Spec F (F-D2) — the basis the price inputs are entered on.
67
+ priceBasis: PriceBasis
55
68
  }
56
69
 
57
70
  // The accounts list API (`/api/billing/accounts`) returns snake_case
@@ -62,6 +75,7 @@ export type AccountOption = {
62
75
  name: string
63
76
  customer_id: string
64
77
  currency_code: string
78
+ billing_mode?: 'postpaid' | 'prepaid'
65
79
  }
66
80
 
67
81
  export type ItemFormProps = {
@@ -69,6 +83,10 @@ export type ItemFormProps = {
69
83
  /** For create mode: full list of accounts the operator can attach to. */
70
84
  accountOptions?: AccountOption[]
71
85
  initial?: Partial<ItemFormValues>
86
+ /** Edit mode: the item's account mode (prepaid tax-point rules, Spec F). */
87
+ accountBillingMode?: 'postpaid' | 'prepaid'
88
+ /** Edit mode: the item's account currency, shown next to the rate (Spec F, F2). */
89
+ accountCurrency?: string
72
90
  submitting?: boolean
73
91
  /** Returns the assembled payload (with rate_json built). */
74
92
  onSubmit: (assembled: AssembledItemPayload) => Promise<void> | void
@@ -86,6 +104,10 @@ export type AssembledItemPayload = {
86
104
  subscriptionId?: string
87
105
  subscriptionItemId?: string
88
106
  isActive?: boolean
107
+ chargeTiming?: 'in_advance' | 'in_arrears'
108
+ prorate?: boolean
109
+ taxRate?: number
110
+ priceBasis?: PriceBasis
89
111
  }
90
112
 
91
113
  const EMPTY_VALUES: ItemFormValues = {
@@ -103,6 +125,10 @@ const EMPTY_VALUES: ItemFormValues = {
103
125
  subscriptionId: '',
104
126
  subscriptionItemId: '',
105
127
  isActive: true,
128
+ chargeTiming: 'in_advance',
129
+ prorate: true,
130
+ taxRate: '',
131
+ priceBasis: 'net',
106
132
  }
107
133
 
108
134
  function todayIso(): string {
@@ -127,12 +153,18 @@ export function ItemForm({
127
153
  mode,
128
154
  accountOptions,
129
155
  initial,
156
+ accountBillingMode,
157
+ accountCurrency,
130
158
  submitting = false,
131
159
  onSubmit,
132
160
  onCancel,
133
161
  }: ItemFormProps) {
134
162
  const t = useT()
135
163
  const [values, setValues] = React.useState<ItemFormValues>(() => mergeInitial(initial))
164
+ const selectedAccount = accountOptions?.find((option) => option.id === values.billAccountId)
165
+ const isPrepaidAccount = accountBillingMode === 'prepaid' || selectedAccount?.billing_mode === 'prepaid'
166
+ // Read-only: the currency always comes from the parent account.
167
+ const currencyCode = accountCurrency ?? selectedAccount?.currency_code ?? ''
136
168
  const [error, setError] = React.useState<string | null>(null)
137
169
  const isEdit = mode === 'edit'
138
170
 
@@ -141,6 +173,63 @@ export function ItemForm({
141
173
  setValues(mergeInitial(initial))
142
174
  }, [initialKey, initial])
143
175
 
176
+ // Spec B: prefill the VAT rate with the organization default on create.
177
+ // Spec F (F-D3): the prepaid tax point decides whether VAT applies to
178
+ // prepaid charges at all. Best effort — without settings access the server
179
+ // applies the default rate and the form assumes the `topup` default.
180
+ const [prepaidTaxPoint, setPrepaidTaxPoint] = React.useState<'topup' | 'consumption'>('topup')
181
+ React.useEffect(() => {
182
+ let cancelled = false
183
+ void apiCall<{ settings?: { defaultTaxRate?: number; prepaidTaxPoint?: 'topup' | 'consumption' } }>(
184
+ '/api/billing/settings',
185
+ ).then((call) => {
186
+ if (cancelled || !call.ok) return
187
+ const settings = call.result?.settings
188
+ if (settings?.prepaidTaxPoint === 'consumption') setPrepaidTaxPoint('consumption')
189
+ const rate = settings?.defaultTaxRate
190
+ if (!isEdit && typeof rate === 'number') {
191
+ setValues((prev) => (prev.taxRate === '' ? { ...prev, taxRate: String(rate) } : prev))
192
+ }
193
+ })
194
+ return () => {
195
+ cancelled = true
196
+ }
197
+ }, [isEdit])
198
+
199
+ // Prepaid + tax at top-up: VAT was charged on the receipt, so the item
200
+ // price is debited as entered — the VAT rate and basis do not apply.
201
+ const taxLocked = isPrepaidAccount && prepaidTaxPoint === 'topup'
202
+ // Tiered usage rates are always net (P-D4).
203
+ const basisForcedNet = values.type === 'usage' && values.usageMode === 'tiered'
204
+ const effectiveBasis: PriceBasis = basisForcedNet ? 'net' : values.priceBasis
205
+
206
+ // Switching the basis converts the typed prices, so the price stays the same.
207
+ const handleBasisChange = React.useCallback((next: string) => {
208
+ const target: PriceBasis = next === 'gross' ? 'gross' : 'net'
209
+ setValues((prev) => {
210
+ if (prev.priceBasis === target) return prev
211
+ const rate = toNumber(prev.taxRate) ?? 0
212
+ const convert = (raw: string, decimals: number): string => {
213
+ const amount = toNumber(raw)
214
+ if (amount === null) return raw
215
+ const converted =
216
+ decimals > 2
217
+ ? prev.priceBasis === 'gross'
218
+ ? amount / (1 + rate / 100)
219
+ : amount * (1 + rate / 100)
220
+ : counterpartAmount(amount, prev.priceBasis, rate)
221
+ return String(Number(converted.toFixed(decimals)))
222
+ }
223
+ return {
224
+ ...prev,
225
+ priceBasis: target,
226
+ oneTimeAmount: convert(prev.oneTimeAmount, 2),
227
+ recurringUnitPrice: convert(prev.recurringUnitPrice, 2),
228
+ usageUnitPrice: convert(prev.usageUnitPrice, 6),
229
+ }
230
+ })
231
+ }, [])
232
+
144
233
  const set = React.useCallback(
145
234
  <K extends keyof ItemFormValues>(key: K, value: ItemFormValues[K]) => {
146
235
  setValues((prev) => ({ ...prev, [key]: value }))
@@ -235,6 +324,11 @@ export function ItemForm({
235
324
  setError(t('billing.items.form.error.uom_required', 'UoM code is required for usage items'))
236
325
  return
237
326
  }
327
+ const taxRate = toNumber(values.taxRate)
328
+ if (values.taxRate.trim() !== '' && (taxRate == null || taxRate < 0 || taxRate > 100)) {
329
+ setError(t('billing.items.form.error.tax_rate_invalid', 'VAT rate must be between 0 and 100'))
330
+ return
331
+ }
238
332
  const rateJsonResult = buildRateJson()
239
333
  if (typeof rateJsonResult === 'string') {
240
334
  // builder returned an error message
@@ -258,18 +352,27 @@ export function ItemForm({
258
352
  if (values.subscriptionItemId.trim()) {
259
353
  payload.subscriptionItemId = values.subscriptionItemId.trim()
260
354
  }
355
+ if (values.type === 'recurring') {
356
+ payload.chargeTiming = values.chargeTiming
357
+ payload.prorate = values.prorate
358
+ }
359
+ if (taxRate != null) payload.taxRate = taxRate
360
+ payload.priceBasis = effectiveBasis
261
361
  if (isEdit) payload.isActive = values.isActive
262
362
  await onSubmit(payload)
263
- }, [buildRateJson, isEdit, onSubmit, t, values])
363
+ }, [buildRateJson, effectiveBasis, isEdit, onSubmit, t, values])
264
364
 
265
365
  const handleKeyDown = React.useCallback(
266
366
  (event: React.KeyboardEvent<HTMLDivElement>) => {
267
367
  if ((event.metaKey || event.ctrlKey) && event.key === 'Enter') {
268
368
  event.preventDefault()
269
369
  void handleSubmit()
370
+ } else if (event.key === 'Escape') {
371
+ event.preventDefault()
372
+ onCancel()
270
373
  }
271
374
  },
272
- [handleSubmit],
375
+ [handleSubmit, onCancel],
273
376
  )
274
377
 
275
378
  return (
@@ -369,44 +472,138 @@ export function ItemForm({
369
472
  </label>
370
473
  </div>
371
474
 
372
- <h3 className="text-sm font-semibold mt-6 mb-2">
373
- {t('billing.items.form.rate.title', 'Rate')}
374
- </h3>
475
+ <div className="mt-6 mb-2 flex flex-wrap items-center justify-between gap-3">
476
+ <h3 className="text-sm font-semibold">{t('billing.items.form.rate.title', 'Rate')}</h3>
477
+ <SegmentedControl
478
+ value={effectiveBasis}
479
+ onValueChange={handleBasisChange}
480
+ disabled={taxLocked || basisForcedNet}
481
+ aria-label={t('billing.items.form.price_basis', 'Price entered as')}
482
+ >
483
+ <SegmentedControlItem value="net">{t('billing.items.price_basis.net', 'Net')}</SegmentedControlItem>
484
+ <SegmentedControlItem value="gross">{t('billing.items.price_basis.gross', 'Gross')}</SegmentedControlItem>
485
+ </SegmentedControl>
486
+ </div>
487
+ {basisForcedNet && !taxLocked ? (
488
+ <p className="mb-2 text-xs text-muted-foreground">
489
+ {t('billing.items.form.price_basis.tiered_net', 'Tiered rates are always entered net.')}
490
+ </p>
491
+ ) : null}
375
492
  <div className="grid grid-cols-2 gap-4">
376
493
  {values.type === 'one_time' ? (
494
+ <ItemPriceField
495
+ label={t('billing.items.form.rate.amount', 'Amount')}
496
+ value={values.oneTimeAmount}
497
+ onChange={(next) => set('oneTimeAmount', next)}
498
+ step="0.01"
499
+ currencyCode={currencyCode}
500
+ priceBasis={effectiveBasis}
501
+ taxRate={values.taxRate}
502
+ showCounterpart={!taxLocked}
503
+ help={t('billing.items.form.rate.amount.help', 'Negative allowed for refunds / credits / proration credits.')}
504
+ />
505
+ ) : null}
506
+
507
+ {values.type === 'recurring' ? (
508
+ <ItemPriceField
509
+ label={t('billing.items.form.rate.unit_price_recurring', 'Unit price per cycle')}
510
+ value={values.recurringUnitPrice}
511
+ onChange={(next) => set('recurringUnitPrice', next)}
512
+ step="0.01"
513
+ currencyCode={currencyCode}
514
+ priceBasis={effectiveBasis}
515
+ taxRate={values.taxRate}
516
+ showCounterpart={!taxLocked}
517
+ />
518
+ ) : null}
519
+
520
+ {values.type === 'usage' && values.usageMode === 'simple' ? (
521
+ <ItemPriceField
522
+ label={t('billing.items.form.rate.unit_price_usage', 'Unit price per unit consumed')}
523
+ value={values.usageUnitPrice}
524
+ onChange={(next) => set('usageUnitPrice', next)}
525
+ step="0.000001"
526
+ currencyCode={currencyCode}
527
+ priceBasis={effectiveBasis}
528
+ taxRate={values.taxRate}
529
+ showCounterpart={!taxLocked}
530
+ precision={6}
531
+ />
532
+ ) : null}
533
+
534
+ <label className="flex flex-col gap-1 text-sm">
535
+ <span className="text-muted-foreground">{t('billing.items.form.tax_rate', 'VAT rate (%)')}</span>
536
+ <Input
537
+ type="number"
538
+ min="0"
539
+ max="100"
540
+ step="0.01"
541
+ value={values.taxRate}
542
+ disabled={taxLocked}
543
+ onChange={(event) => set('taxRate', event.currentTarget.value)}
544
+ />
545
+ <span className="text-xs text-muted-foreground">
546
+ {taxLocked ? (
547
+ <>
548
+ {t('billing.items.form.tax_rate.prepaid_topup', 'For prepaid accounts, tax is allocated at top-up.')}{' '}
549
+ <Link href={BILLING_SETTINGS_HREF} className="text-primary hover:underline">
550
+ {t('billing.settings.link', 'Billing settings')}
551
+ </Link>
552
+ </>
553
+ ) : isPrepaidAccount ? (
554
+ t('billing.items.form.tax_rate.prepaid_consumption', 'Charged from the balance including VAT.')
555
+ ) : isEdit ? (
556
+ t('billing.items.form.tax_rate.help_edit', 'Applies to future invoices; posted invoices keep their rate.')
557
+ ) : (
558
+ t('billing.items.form.tax_rate.help', 'Defaults to the organization VAT rate from billing settings.')
559
+ )}
560
+ </span>
561
+ </label>
562
+
563
+ {values.type === 'recurring' ? (
377
564
  <label className="flex flex-col gap-1 text-sm">
378
565
  <span className="text-muted-foreground">
379
- {t('billing.items.form.rate.amount', 'Amount')}
380
- <span className="text-destructive"> *</span>
566
+ {t('billing.items.form.charge_timing', 'Charge timing')}
381
567
  </span>
382
- <Input
383
- type="number"
384
- step="0.0001"
385
- value={values.oneTimeAmount}
386
- onChange={(event) => set('oneTimeAmount', event.currentTarget.value)}
387
- />
568
+ <Select
569
+ value={values.chargeTiming}
570
+ onValueChange={(next) => set('chargeTiming', next === 'in_arrears' ? 'in_arrears' : 'in_advance')}
571
+ >
572
+ <SelectTrigger>
573
+ <SelectValue />
574
+ </SelectTrigger>
575
+ <SelectContent>
576
+ <SelectItem value="in_advance">
577
+ {t('billing.items.charge_timing.in_advance', 'In advance')}
578
+ </SelectItem>
579
+ <SelectItem value="in_arrears">
580
+ {t('billing.items.charge_timing.in_arrears', 'In arrears')}
581
+ </SelectItem>
582
+ </SelectContent>
583
+ </Select>
388
584
  <span className="text-xs text-muted-foreground">
389
- {t(
390
- 'billing.items.form.rate.amount.help',
391
- 'Negative allowed for refunds / credits / proration credits.',
392
- )}
585
+ {values.chargeTiming === 'in_arrears'
586
+ ? t('billing.items.form.charge_timing.help_arrears', 'Each bill date charges the period that just ended.')
587
+ : t('billing.items.form.charge_timing.help_advance', 'Each bill date charges the coming period.')}
393
588
  </span>
394
589
  </label>
395
590
  ) : null}
396
591
 
397
592
  {values.type === 'recurring' ? (
398
- <label className="flex flex-col gap-1 text-sm">
399
- <span className="text-muted-foreground">
400
- {t('billing.items.form.rate.unit_price_recurring', 'Unit price per cycle')}
401
- <span className="text-destructive"> *</span>
402
- </span>
403
- <Input
404
- type="number"
405
- step="0.0001"
406
- value={values.recurringUnitPrice}
407
- onChange={(event) => set('recurringUnitPrice', event.currentTarget.value)}
408
- />
409
- </label>
593
+ <div className="flex items-center justify-between gap-3 text-sm">
594
+ <div>
595
+ <div className="font-medium">
596
+ {t('billing.items.form.prorate', 'Prorate partial periods')}
597
+ </div>
598
+ <div className="text-xs text-muted-foreground">
599
+ {t(
600
+ 'billing.items.form.prorate.help',
601
+ 'Charge by calendar days when the item starts or ends mid-period, and credit unused days if it ends after being billed in advance.',
602
+ )}
603
+ </div>
604
+ </div>
605
+ <Switch checked={values.prorate} onCheckedChange={(next) => set('prorate', next)} />
606
+ </div>
410
607
  ) : null}
411
608
 
412
609
  {values.type === 'usage' ? (
@@ -433,20 +630,7 @@ export function ItemForm({
433
630
  </Select>
434
631
  </label>
435
632
 
436
- {values.usageMode === 'simple' ? (
437
- <label className="flex flex-col gap-1 text-sm">
438
- <span className="text-muted-foreground">
439
- {t('billing.items.form.rate.unit_price_usage', 'Unit price per unit consumed')}
440
- <span className="text-destructive"> *</span>
441
- </span>
442
- <Input
443
- type="number"
444
- step="0.000001"
445
- value={values.usageUnitPrice}
446
- onChange={(event) => set('usageUnitPrice', event.currentTarget.value)}
447
- />
448
- </label>
449
- ) : (
633
+ {values.usageMode === 'tiered' ? (
450
634
  <label className="flex flex-col gap-1 text-sm col-span-2">
451
635
  <span className="text-muted-foreground">
452
636
  {t('billing.items.form.rate.tiered_json', 'Tiered rate JSON')}
@@ -458,6 +642,11 @@ export function ItemForm({
458
642
  placeholder='{ "model": "graduated", "tiers": [{ "up_to": 10000, "unit_price": 0 }, { "up_to": null, "unit_price": 0.001 }] }'
459
643
  onChange={(event) => set('usageTieredJson', event.currentTarget.value)}
460
644
  />
645
+ {currencyCode ? (
646
+ <span className="text-xs text-muted-foreground">
647
+ {t('billing.items.form.rate.prices_in', 'Prices in')} <span className="font-medium">{currencyCode}</span>
648
+ </span>
649
+ ) : null}
461
650
  <span className="text-xs text-muted-foreground">
462
651
  {t(
463
652
  'billing.items.form.rate.tiered_json.help',
@@ -465,7 +654,7 @@ export function ItemForm({
465
654
  )}
466
655
  </span>
467
656
  </label>
468
- )}
657
+ ) : null}
469
658
 
470
659
  <label className="flex flex-col gap-1 text-sm">
471
660
  <span className="text-muted-foreground">
@@ -0,0 +1,81 @@
1
+ "use client"
2
+ import * as React from 'react'
3
+ import { useT } from '@open-mercato/shared/lib/i18n/context'
4
+ import { MoneyInput } from './MoneyInput'
5
+ import { counterpartAmount, type PriceBasis } from '../lib/lineAmounts'
6
+
7
+ export type ItemPriceFieldProps = {
8
+ label: string
9
+ value: string
10
+ onChange: (next: string) => void
11
+ step: string
12
+ currencyCode: string
13
+ priceBasis: PriceBasis
14
+ /** VAT rate in percent as typed in the form ('' = unknown). */
15
+ taxRate: string
16
+ /** False when VAT does not apply to this price (prepaid, tax at top-up). */
17
+ showCounterpart: boolean
18
+ /**
19
+ * Decimals of the preview. 2 = the line rule (`lineVat`). Higher values are
20
+ * for per-unit usage prices, where 2 dp would read as 0.00; those are
21
+ * indicative only — the invoice rounds the extended line once.
22
+ */
23
+ precision?: number
24
+ help?: React.ReactNode
25
+ }
26
+
27
+ function parse(raw: string): number | null {
28
+ if (raw.trim() === '') return null
29
+ const n = Number.parseFloat(raw)
30
+ return Number.isFinite(n) ? n : null
31
+ }
32
+
33
+ /**
34
+ * One item price input (Spec F, F2 + F3): the currency suffix from the
35
+ * account, and below it the other side of the price, computed with the same
36
+ * `lineVat` rule the invoice uses ("Gross 60.27 EUR" / "Net 49.00 EUR").
37
+ */
38
+ export function ItemPriceField({
39
+ label,
40
+ value,
41
+ onChange,
42
+ step,
43
+ currencyCode,
44
+ priceBasis,
45
+ taxRate,
46
+ showCounterpart,
47
+ precision = 2,
48
+ help,
49
+ }: ItemPriceFieldProps) {
50
+ const t = useT()
51
+ const amount = parse(value)
52
+ const rate = parse(taxRate) ?? 0
53
+ const counterpart =
54
+ showCounterpart && amount !== null
55
+ ? precision > 2
56
+ ? priceBasis === 'gross'
57
+ ? amount / (1 + rate / 100)
58
+ : amount * (1 + rate / 100)
59
+ : counterpartAmount(amount, priceBasis, rate)
60
+ : null
61
+ return (
62
+ <label className="flex flex-col gap-1 text-sm">
63
+ <span className="text-muted-foreground">
64
+ {label}
65
+ <span className="text-destructive"> *</span>
66
+ </span>
67
+ <MoneyInput currencyCode={currencyCode} step={step} value={value} onChange={(event) => onChange(event.currentTarget.value)} />
68
+ {counterpart !== null ? (
69
+ <span className="text-xs text-muted-foreground tabular-nums">
70
+ {priceBasis === 'gross'
71
+ ? t('billing.items.form.price.net_preview', 'Net')
72
+ : t('billing.items.form.price.gross_preview', 'Gross')}{' '}
73
+ <span className="font-medium text-foreground">{counterpart.toFixed(precision)}</span>
74
+ {currencyCode ? ` ${currencyCode}` : ''}
75
+ {` · ${t('billing.items.form.price.vat_preview', 'VAT')} ${rate} %`}
76
+ </span>
77
+ ) : null}
78
+ {help ? <span className="text-xs text-muted-foreground">{help}</span> : null}
79
+ </label>
80
+ )
81
+ }
@@ -40,6 +40,8 @@ export type LineFormValues = {
40
40
  unitPriceNet: number
41
41
  /** Optional explicit total override (operator "I know better" path). */
42
42
  totalNetAmount?: number
43
+ /** Spec B: VAT %. Omitted on add → the organization default rate. */
44
+ taxRate?: number
43
45
  }
44
46
 
45
47
  export type LineFormDialogProps = {
@@ -77,6 +79,7 @@ export function LineFormDialog({
77
79
  const [totalOverride, setTotalOverride] = React.useState(
78
80
  initial?.totalNetAmount != null ? String(initial.totalNetAmount) : '',
79
81
  )
82
+ const [taxRate, setTaxRate] = React.useState(initial?.taxRate != null ? String(initial.taxRate) : '')
80
83
  const [error, setError] = React.useState<string | null>(null)
81
84
 
82
85
  React.useEffect(() => {
@@ -85,6 +88,7 @@ export function LineFormDialog({
85
88
  setQuantity(initial?.quantity != null ? String(initial.quantity) : '')
86
89
  setUnitPriceNet(initial?.unitPriceNet != null ? String(initial.unitPriceNet) : '')
87
90
  setTotalOverride(initial?.totalNetAmount != null ? String(initial.totalNetAmount) : '')
91
+ setTaxRate(initial?.taxRate != null ? String(initial.taxRate) : '')
88
92
  setError(null)
89
93
  }
90
94
  }, [open, initial])
@@ -115,14 +119,20 @@ export function LineFormDialog({
115
119
  }
116
120
  totalOverrideValue = parsed
117
121
  }
122
+ const taxRateValue = toNumber(taxRate)
123
+ if (taxRate.trim() !== '' && (taxRateValue == null || taxRateValue < 0 || taxRateValue > 100)) {
124
+ setError(t('billing.invoices.lines.form.error.tax_rate_invalid', 'VAT rate must be between 0 and 100'))
125
+ return
126
+ }
118
127
  setError(null)
119
128
  await onSubmit({
120
129
  description: trimmedDescription,
121
130
  quantity: quantityValue,
122
131
  unitPriceNet: unitPriceValue,
123
132
  totalNetAmount: totalOverrideValue,
133
+ taxRate: taxRateValue ?? undefined,
124
134
  })
125
- }, [description, onSubmit, quantity, t, totalOverride, unitPriceNet])
135
+ }, [description, onSubmit, quantity, t, taxRate, totalOverride, unitPriceNet])
126
136
 
127
137
  const handleKeyDown = React.useCallback(
128
138
  (event: React.KeyboardEvent<HTMLDivElement>) => {
@@ -196,6 +206,20 @@ export function LineFormDialog({
196
206
  />
197
207
  </label>
198
208
  </div>
209
+ <label className="flex flex-col gap-1 text-sm">
210
+ <span className="text-muted-foreground">
211
+ {t('billing.invoices.lines.form.tax_rate', 'VAT rate (%)')}
212
+ </span>
213
+ <Input
214
+ type="number"
215
+ value={taxRate}
216
+ min="0"
217
+ max="100"
218
+ step="0.01"
219
+ placeholder={mode === 'add' ? t('billing.invoices.lines.form.tax_rate.default', 'Organization default') : ''}
220
+ onChange={(event) => setTaxRate(event.currentTarget.value)}
221
+ />
222
+ </label>
199
223
  <label className="flex flex-col gap-1 text-sm">
200
224
  <span className="text-muted-foreground">
201
225
  {t('billing.invoices.lines.form.total_override', 'Total override (optional)')}