@spaceinvoices/react-ui 0.1.1

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 (352) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +340 -0
  3. package/cli/dist/index.js +922 -0
  4. package/package.json +87 -0
  5. package/registry.json +600 -0
  6. package/spaceinvoices.schema.json +47 -0
  7. package/src/app.tsx +25 -0
  8. package/src/common/autocomplete.tsx +135 -0
  9. package/src/components/activities/activity-timeline.tsx +160 -0
  10. package/src/components/activities/index.ts +1 -0
  11. package/src/components/activities/locales/de.ts +30 -0
  12. package/src/components/activities/locales/sl.ts +30 -0
  13. package/src/components/advance-invoices/advance-invoices.hooks.ts +75 -0
  14. package/src/components/advance-invoices/create/create-advance-invoice-form.tsx +702 -0
  15. package/src/components/advance-invoices/create/locales/de.ts +29 -0
  16. package/src/components/advance-invoices/create/locales/sl.ts +25 -0
  17. package/src/components/advance-invoices/create/prepare-advance-invoice-submission.ts +74 -0
  18. package/src/components/advance-invoices/index.ts +5 -0
  19. package/src/components/advance-invoices/list/index.ts +3 -0
  20. package/src/components/advance-invoices/list/list-row-actions.tsx +119 -0
  21. package/src/components/advance-invoices/list/list-table.tsx +178 -0
  22. package/src/components/advance-invoices/list/locales/de.ts +32 -0
  23. package/src/components/advance-invoices/list/locales/sl.ts +32 -0
  24. package/src/components/advance-invoices/list/use-advance-invoice-download.ts +63 -0
  25. package/src/components/button-loader.tsx +11 -0
  26. package/src/components/combobox.tsx +96 -0
  27. package/src/components/company-registry/company-registry-autocomplete.tsx +151 -0
  28. package/src/components/company-registry/company-registry.hooks.ts +67 -0
  29. package/src/components/company-registry/index.ts +7 -0
  30. package/src/components/credit-notes/create/create-credit-note-form.tsx +332 -0
  31. package/src/components/credit-notes/create/index.ts +1 -0
  32. package/src/components/credit-notes/create/locales/de.ts +69 -0
  33. package/src/components/credit-notes/create/locales/sl.ts +67 -0
  34. package/src/components/credit-notes/credit-notes.hooks.ts +22 -0
  35. package/src/components/credit-notes/index.ts +10 -0
  36. package/src/components/credit-notes/list/index.ts +3 -0
  37. package/src/components/credit-notes/list/list-row-actions.tsx +116 -0
  38. package/src/components/credit-notes/list/list-table.tsx +183 -0
  39. package/src/components/credit-notes/list/locales/de.ts +33 -0
  40. package/src/components/credit-notes/list/locales/sl.ts +33 -0
  41. package/src/components/credit-notes/list/use-credit-note-download.ts +65 -0
  42. package/src/components/customers/create-customer-form/create-customer-form.tsx +134 -0
  43. package/src/components/customers/create-customer-form/locales/de.ts +20 -0
  44. package/src/components/customers/create-customer-form/locales/sl.ts +20 -0
  45. package/src/components/customers/customer-autocomplete.tsx +173 -0
  46. package/src/components/customers/customer-combobox.tsx +130 -0
  47. package/src/components/customers/customer-list-table/customer-list-row-actions.tsx +48 -0
  48. package/src/components/customers/customer-list-table/customer-list-table.tsx +124 -0
  49. package/src/components/customers/customer-list-table/index.ts +2 -0
  50. package/src/components/customers/customer-list-table/locales/de.ts +16 -0
  51. package/src/components/customers/customer-list-table/locales/sl.ts +16 -0
  52. package/src/components/customers/customers.hooks.test.ts +348 -0
  53. package/src/components/customers/customers.hooks.ts +57 -0
  54. package/src/components/customers/index.ts +5 -0
  55. package/src/components/dashboard/chart-empty-state.tsx +29 -0
  56. package/src/components/dashboard/collection-rate-card/collection-rate-card.tsx +80 -0
  57. package/src/components/dashboard/collection-rate-card/index.ts +4 -0
  58. package/src/components/dashboard/collection-rate-card/locales/sl.ts +3 -0
  59. package/src/components/dashboard/collection-rate-card/use-collection-rate.ts +74 -0
  60. package/src/components/dashboard/index.ts +54 -0
  61. package/src/components/dashboard/invoice-status-chart/index.ts +4 -0
  62. package/src/components/dashboard/invoice-status-chart/invoice-status-chart.tsx +130 -0
  63. package/src/components/dashboard/invoice-status-chart/locales/sl.ts +9 -0
  64. package/src/components/dashboard/invoice-status-chart/use-invoice-status.ts +105 -0
  65. package/src/components/dashboard/loading-card.tsx +19 -0
  66. package/src/components/dashboard/payment-methods-chart/index.ts +4 -0
  67. package/src/components/dashboard/payment-methods-chart/locales/sl.ts +12 -0
  68. package/src/components/dashboard/payment-methods-chart/payment-methods-chart.tsx +152 -0
  69. package/src/components/dashboard/payment-methods-chart/use-payment-methods.ts +50 -0
  70. package/src/components/dashboard/payment-trend-chart/index.ts +4 -0
  71. package/src/components/dashboard/payment-trend-chart/locales/sl.ts +5 -0
  72. package/src/components/dashboard/payment-trend-chart/payment-trend-chart.tsx +137 -0
  73. package/src/components/dashboard/payment-trend-chart/use-payment-trend.ts +92 -0
  74. package/src/components/dashboard/revenue-card.tsx +49 -0
  75. package/src/components/dashboard/revenue-trend-chart/index.ts +4 -0
  76. package/src/components/dashboard/revenue-trend-chart/locales/sl.ts +5 -0
  77. package/src/components/dashboard/revenue-trend-chart/revenue-trend-chart.tsx +137 -0
  78. package/src/components/dashboard/revenue-trend-chart/use-revenue-trend.ts +93 -0
  79. package/src/components/dashboard/shared/index.ts +5 -0
  80. package/src/components/dashboard/shared/use-revenue-data.ts +160 -0
  81. package/src/components/dashboard/shared/use-stats-counts.ts +89 -0
  82. package/src/components/dashboard/shared/use-stats-query.ts +38 -0
  83. package/src/components/dashboard/stat-card.tsx +41 -0
  84. package/src/components/dashboard/tax-collected-card/index.ts +2 -0
  85. package/src/components/dashboard/tax-collected-card/tax-collected-card.tsx +77 -0
  86. package/src/components/dashboard/tax-collected-card/use-tax-collected.ts +145 -0
  87. package/src/components/dashboard/top-customers-chart/index.ts +4 -0
  88. package/src/components/dashboard/top-customers-chart/locales/sl.ts +5 -0
  89. package/src/components/dashboard/top-customers-chart/top-customers-chart.tsx +130 -0
  90. package/src/components/dashboard/top-customers-chart/use-top-customers.ts +72 -0
  91. package/src/components/documents/create/document-add-item-form.tsx +379 -0
  92. package/src/components/documents/create/document-add-item-tax-rate-field.tsx +120 -0
  93. package/src/components/documents/create/document-details-section.tsx +597 -0
  94. package/src/components/documents/create/document-items-section.tsx +133 -0
  95. package/src/components/documents/create/document-recipient-section.tsx +101 -0
  96. package/src/components/documents/create/form-types.ts +36 -0
  97. package/src/components/documents/create/index.ts +9 -0
  98. package/src/components/documents/create/live-preview.tsx +235 -0
  99. package/src/components/documents/create/mark-as-paid-section.tsx +82 -0
  100. package/src/components/documents/create/prepare-document-submission.test.ts +132 -0
  101. package/src/components/documents/create/prepare-document-submission.ts +187 -0
  102. package/src/components/documents/create/prepare-preview-data.test.ts +155 -0
  103. package/src/components/documents/create/prepare-preview-data.ts +16 -0
  104. package/src/components/documents/create/smart-code-insert-button.tsx +139 -0
  105. package/src/components/documents/create/use-document-customer-form.ts +161 -0
  106. package/src/components/documents/document-preview.tsx +13 -0
  107. package/src/components/documents/documents.hooks.ts +146 -0
  108. package/src/components/documents/index.ts +23 -0
  109. package/src/components/documents/shared/document-preview-display.tsx +172 -0
  110. package/src/components/documents/shared/index.ts +3 -0
  111. package/src/components/documents/shared/scaled-document-preview.tsx +70 -0
  112. package/src/components/documents/shared/use-a4-scaling.ts +62 -0
  113. package/src/components/documents/types.ts +61 -0
  114. package/src/components/documents/view/document-actions-bar.tsx +328 -0
  115. package/src/components/documents/view/document-details-card.tsx +179 -0
  116. package/src/components/documents/view/document-payments-list.tsx +256 -0
  117. package/src/components/documents/view/index.ts +4 -0
  118. package/src/components/documents/view/locales/de.ts +85 -0
  119. package/src/components/documents/view/locales/sl.ts +84 -0
  120. package/src/components/documents/view/use-document-download.ts +125 -0
  121. package/src/components/entities/create-entity-form.tsx +105 -0
  122. package/src/components/entities/entities.hooks.ts +50 -0
  123. package/src/components/entities/entity-settings-form/email-template-variables-info.tsx +103 -0
  124. package/src/components/entities/entity-settings-form/entity-settings-form.tsx +1326 -0
  125. package/src/components/entities/entity-settings-form/image-upload-with-crop.tsx +222 -0
  126. package/src/components/entities/entity-settings-form/index.ts +2 -0
  127. package/src/components/entities/entity-settings-form/input-with-preview.tsx +190 -0
  128. package/src/components/entities/entity-settings-form/locales/de.ts +192 -0
  129. package/src/components/entities/entity-settings-form/locales/sl.ts +188 -0
  130. package/src/components/entities/furs-settings-form/furs-settings-form.tsx +410 -0
  131. package/src/components/entities/furs-settings-form/furs-settings.hooks.ts +320 -0
  132. package/src/components/entities/furs-settings-form/index.ts +3 -0
  133. package/src/components/entities/furs-settings-form/locales/de.ts +233 -0
  134. package/src/components/entities/furs-settings-form/locales/en.ts +194 -0
  135. package/src/components/entities/furs-settings-form/locales/sl.ts +196 -0
  136. package/src/components/entities/furs-settings-form/sections/certificate-settings-section.tsx +242 -0
  137. package/src/components/entities/furs-settings-form/sections/enable-fiscalization-section.tsx +139 -0
  138. package/src/components/entities/furs-settings-form/sections/general-settings-section.tsx +252 -0
  139. package/src/components/entities/furs-settings-form/sections/premises-management-section.tsx +370 -0
  140. package/src/components/entities/furs-settings-form/sections/register-premise-dialog.tsx +420 -0
  141. package/src/components/entities/keys.ts +2 -0
  142. package/src/components/entities/settings/branding-settings-form.tsx +274 -0
  143. package/src/components/entities/settings/company-settings-form.tsx +256 -0
  144. package/src/components/entities/settings/defaults-settings-form.tsx +501 -0
  145. package/src/components/entities/settings/email-settings-form.tsx +288 -0
  146. package/src/components/entities/settings/eslog-settings-form.tsx +113 -0
  147. package/src/components/entities/settings/index.ts +8 -0
  148. package/src/components/entities/settings/number-format-settings-form.tsx +244 -0
  149. package/src/components/entities/settings/pdf-template-selector/demo-invoice-data.ts +164 -0
  150. package/src/components/entities/settings/pdf-template-selector/index.ts +2 -0
  151. package/src/components/entities/settings/pdf-template-selector/locales/de.ts +18 -0
  152. package/src/components/entities/settings/pdf-template-selector/locales/sl.ts +18 -0
  153. package/src/components/entities/settings/pdf-template-selector/pdf-template-cards.tsx +49 -0
  154. package/src/components/entities/settings/settings-footer.tsx +16 -0
  155. package/src/components/entities/settings/tax-rules-settings-form.tsx +346 -0
  156. package/src/components/estimates/create/create-estimate-form.tsx +384 -0
  157. package/src/components/estimates/create/locales/de.ts +64 -0
  158. package/src/components/estimates/create/locales/sl.ts +63 -0
  159. package/src/components/estimates/create/prepare-estimate-submission.ts +39 -0
  160. package/src/components/estimates/create/use-estimate-customer-form.ts +5 -0
  161. package/src/components/estimates/estimates.hooks.ts +15 -0
  162. package/src/components/estimates/index.ts +6 -0
  163. package/src/components/estimates/list/index.ts +3 -0
  164. package/src/components/estimates/list/list-row-actions.tsx +103 -0
  165. package/src/components/estimates/list/list-table.tsx +171 -0
  166. package/src/components/estimates/list/locales/de.ts +26 -0
  167. package/src/components/estimates/list/locales/sl.ts +26 -0
  168. package/src/components/estimates/list/use-estimate-download.ts +63 -0
  169. package/src/components/export/document-export-form.tsx +288 -0
  170. package/src/components/export/index.ts +2 -0
  171. package/src/components/form/form-input.tsx +89 -0
  172. package/src/components/form/index.ts +1 -0
  173. package/src/components/invoices/create/create-invoice-form.tsx +852 -0
  174. package/src/components/invoices/create/eslog-validation.test.ts +242 -0
  175. package/src/components/invoices/create/eslog-validation.ts +208 -0
  176. package/src/components/invoices/create/locales/de.ts +118 -0
  177. package/src/components/invoices/create/locales/sl.ts +114 -0
  178. package/src/components/invoices/create/prepare-invoice-submission.test.ts +777 -0
  179. package/src/components/invoices/create/prepare-invoice-submission.ts +79 -0
  180. package/src/components/invoices/create/use-invoice-customer-form.ts +5 -0
  181. package/src/components/invoices/index.ts +9 -0
  182. package/src/components/invoices/invoices-furs.hooks.ts +28 -0
  183. package/src/components/invoices/invoices.hooks.ts +110 -0
  184. package/src/components/invoices/list/index.ts +3 -0
  185. package/src/components/invoices/list/list-row-actions.tsx +132 -0
  186. package/src/components/invoices/list/list-table.tsx +165 -0
  187. package/src/components/invoices/list/locales/de.ts +33 -0
  188. package/src/components/invoices/list/locales/sl.ts +33 -0
  189. package/src/components/invoices/list/use-invoice-download.ts +62 -0
  190. package/src/components/invoices/send-email-dialog/index.ts +1 -0
  191. package/src/components/invoices/send-email-dialog/locales/de.ts +18 -0
  192. package/src/components/invoices/send-email-dialog/locales/sl.ts +17 -0
  193. package/src/components/invoices/send-email-dialog/send-email-dialog.tsx +289 -0
  194. package/src/components/invoices/send-email-dialog.tsx +2 -0
  195. package/src/components/invoices/shared/index.ts +2 -0
  196. package/src/components/invoices/shared/scaled-document-preview.tsx +32 -0
  197. package/src/components/invoices/shared/use-a4-scaling.tsx +39 -0
  198. package/src/components/invoices/view/eslog-info-display.tsx +160 -0
  199. package/src/components/invoices/view/furs-info-display.tsx +213 -0
  200. package/src/components/items/create-item-form/create-item-form.tsx +155 -0
  201. package/src/components/items/create-item-form/locales/de.ts +14 -0
  202. package/src/components/items/create-item-form/locales/en.ts +9 -0
  203. package/src/components/items/create-item-form/locales/sl.ts +14 -0
  204. package/src/components/items/item-combobox.tsx +147 -0
  205. package/src/components/items/item-list-table/item-list-header.tsx +33 -0
  206. package/src/components/items/item-list-table/item-list-row-actions.tsx +48 -0
  207. package/src/components/items/item-list-table/item-list-row.tsx +32 -0
  208. package/src/components/items/item-list-table/item-list-table.tsx +76 -0
  209. package/src/components/items/item-list-table/locales/de.ts +10 -0
  210. package/src/components/items/item-list-table/locales/en.ts +10 -0
  211. package/src/components/items/item-list-table/locales/sl.ts +10 -0
  212. package/src/components/items/items.hooks.ts +63 -0
  213. package/src/components/loading-spinner.tsx +24 -0
  214. package/src/components/payments/create-payment-form/create-payment-form.tsx +222 -0
  215. package/src/components/payments/create-payment-form/locales/de.ts +20 -0
  216. package/src/components/payments/create-payment-form/locales/sl.ts +20 -0
  217. package/src/components/payments/edit-payment-form/edit-payment-form.tsx +230 -0
  218. package/src/components/payments/edit-payment-form/index.ts +1 -0
  219. package/src/components/payments/edit-payment-form/locales/de.ts +20 -0
  220. package/src/components/payments/edit-payment-form/locales/sl.ts +20 -0
  221. package/src/components/payments/index.ts +4 -0
  222. package/src/components/payments/list/index.ts +2 -0
  223. package/src/components/payments/list/list-row-actions.tsx +98 -0
  224. package/src/components/payments/list/list-table.tsx +186 -0
  225. package/src/components/payments/list/locales/de.ts +19 -0
  226. package/src/components/payments/list/locales/sl.ts +19 -0
  227. package/src/components/payments/payments.hooks.ts +15 -0
  228. package/src/components/request-logs/index.ts +3 -0
  229. package/src/components/request-logs/request-log-detail.tsx +242 -0
  230. package/src/components/request-logs/request-log-list-table.tsx +266 -0
  231. package/src/components/request-logs/request-logs-page.tsx +10 -0
  232. package/src/components/table/README.md +410 -0
  233. package/src/components/table/data-table.tsx +251 -0
  234. package/src/components/table/date-cell.tsx +35 -0
  235. package/src/components/table/filter-bar.tsx +114 -0
  236. package/src/components/table/filter-panel.tsx +407 -0
  237. package/src/components/table/hooks/use-table-fetch.ts +17 -0
  238. package/src/components/table/hooks/use-table-query.ts +36 -0
  239. package/src/components/table/hooks/use-table-state.ts +293 -0
  240. package/src/components/table/index.ts +35 -0
  241. package/src/components/table/search-input.tsx +85 -0
  242. package/src/components/table/sortable-header.tsx +56 -0
  243. package/src/components/table/table-empty-state.tsx +40 -0
  244. package/src/components/table/table-no-results.tsx +41 -0
  245. package/src/components/table/table-pagination.tsx +42 -0
  246. package/src/components/table/table-skeleton.tsx +54 -0
  247. package/src/components/table/types.ts +136 -0
  248. package/src/components/tax-reports/index.ts +1 -0
  249. package/src/components/tax-reports/kir-export-form.tsx +172 -0
  250. package/src/components/taxes/create-tax-form/create-tax-form.tsx +112 -0
  251. package/src/components/taxes/create-tax-form/locales/de.ts +8 -0
  252. package/src/components/taxes/create-tax-form/locales/en.ts +7 -0
  253. package/src/components/taxes/create-tax-form/locales/sl.ts +8 -0
  254. package/src/components/taxes/tax-list-table/locales/de.ts +11 -0
  255. package/src/components/taxes/tax-list-table/locales/en.ts +10 -0
  256. package/src/components/taxes/tax-list-table/locales/sl.ts +11 -0
  257. package/src/components/taxes/tax-list-table/tax-list-header.tsx +29 -0
  258. package/src/components/taxes/tax-list-table/tax-list-row-actions.tsx +43 -0
  259. package/src/components/taxes/tax-list-table/tax-list-row.tsx +46 -0
  260. package/src/components/taxes/tax-list-table/tax-list-table.tsx +59 -0
  261. package/src/components/taxes/taxes.hooks.ts +35 -0
  262. package/src/components/ui/alert-dialog.tsx +61 -0
  263. package/src/components/ui/alert.tsx +72 -0
  264. package/src/components/ui/badge.tsx +48 -0
  265. package/src/components/ui/breadcrumb.tsx +132 -0
  266. package/src/components/ui/button.tsx +61 -0
  267. package/src/components/ui/calendar.tsx +213 -0
  268. package/src/components/ui/card.tsx +94 -0
  269. package/src/components/ui/chart.tsx +380 -0
  270. package/src/components/ui/checkbox.tsx +27 -0
  271. package/src/components/ui/collapsible.tsx +56 -0
  272. package/src/components/ui/command.tsx +187 -0
  273. package/src/components/ui/dialog.tsx +187 -0
  274. package/src/components/ui/drawer.tsx +123 -0
  275. package/src/components/ui/dropdown-menu.tsx +291 -0
  276. package/src/components/ui/form.tsx +166 -0
  277. package/src/components/ui/input-group.tsx +149 -0
  278. package/src/components/ui/input.tsx +20 -0
  279. package/src/components/ui/label.tsx +18 -0
  280. package/src/components/ui/loading-spinner.tsx +16 -0
  281. package/src/components/ui/popover.tsx +108 -0
  282. package/src/components/ui/radio-group.tsx +37 -0
  283. package/src/components/ui/select.tsx +200 -0
  284. package/src/components/ui/separator.tsx +23 -0
  285. package/src/components/ui/sheet.tsx +145 -0
  286. package/src/components/ui/sidebar.tsx +771 -0
  287. package/src/components/ui/skeleton.tsx +13 -0
  288. package/src/components/ui/sonner.tsx +60 -0
  289. package/src/components/ui/spinner.tsx +10 -0
  290. package/src/components/ui/sticky-form-footer.tsx +55 -0
  291. package/src/components/ui/switch.tsx +30 -0
  292. package/src/components/ui/table.tsx +101 -0
  293. package/src/components/ui/tabs.tsx +80 -0
  294. package/src/components/ui/textarea.tsx +18 -0
  295. package/src/components/ui/tooltip.tsx +89 -0
  296. package/src/components/wl-subscription/index.ts +2 -0
  297. package/src/components/wl-subscription/locked-feature.tsx +173 -0
  298. package/src/components/wl-subscription/upgrade-modal.tsx +209 -0
  299. package/src/frontend.tsx +28 -0
  300. package/src/generate-schemas.ts +265 -0
  301. package/src/generated/schemas/advanceinvoice.ts +177 -0
  302. package/src/generated/schemas/creditnote.ts +187 -0
  303. package/src/generated/schemas/customer.ts +29 -0
  304. package/src/generated/schemas/entity.ts +252 -0
  305. package/src/generated/schemas/estimate.ts +159 -0
  306. package/src/generated/schemas/furssettings.ts +25 -0
  307. package/src/generated/schemas/index.ts +24 -0
  308. package/src/generated/schemas/invoice.ts +167 -0
  309. package/src/generated/schemas/item.ts +38 -0
  310. package/src/generated/schemas/payment.ts +44 -0
  311. package/src/generated/schemas/previewadvanceinvoice_body.ts +354 -0
  312. package/src/generated/schemas/previewestimate_body.ts +309 -0
  313. package/src/generated/schemas/registerfursmovablepremise_body.ts +22 -0
  314. package/src/generated/schemas/registerfursrealestatepremise_body.ts +32 -0
  315. package/src/generated/schemas/renderdocument_body.ts +594 -0
  316. package/src/generated/schemas/sendemail_body.ts +26 -0
  317. package/src/generated/schemas/startpdfexport_body.ts +20 -0
  318. package/src/generated/schemas/tax.ts +48 -0
  319. package/src/generated/schemas/uploadfile_body.ts +23 -0
  320. package/src/generated/schemas/uploadfurscertificate_body.ts +20 -0
  321. package/src/generated/schemas/userfurssettings.ts +19 -0
  322. package/src/hooks/create-resource-hooks.test.ts +483 -0
  323. package/src/hooks/create-resource-hooks.ts +300 -0
  324. package/src/hooks/use-debounce.ts +12 -0
  325. package/src/hooks/use-duplicate-document.ts +185 -0
  326. package/src/hooks/use-media-query.tsx +19 -0
  327. package/src/hooks/use-mobile.ts +39 -0
  328. package/src/hooks/use-next-document-number.ts +57 -0
  329. package/src/hooks/use-resource-mutation.ts +118 -0
  330. package/src/hooks/use-vies-check.ts +130 -0
  331. package/src/index.css +11 -0
  332. package/src/index.html +13 -0
  333. package/src/index.tsx +12 -0
  334. package/src/lib/auth.ts +4 -0
  335. package/src/lib/browser-cookies.ts +70 -0
  336. package/src/lib/constants.ts +287 -0
  337. package/src/lib/cookies.ts +36 -0
  338. package/src/lib/schemas/advance-invoice.ts +43 -0
  339. package/src/lib/schemas/credit-note.ts +32 -0
  340. package/src/lib/schemas/estimate.ts +31 -0
  341. package/src/lib/schemas/index.ts +18 -0
  342. package/src/lib/schemas/invoice.ts +43 -0
  343. package/src/lib/schemas/shared.ts +79 -0
  344. package/src/lib/translation.ts +38 -0
  345. package/src/lib/utils.ts +6 -0
  346. package/src/providers/entities-context.tsx +41 -0
  347. package/src/providers/entities-provider.tsx +201 -0
  348. package/src/providers/form-footer-context.tsx +72 -0
  349. package/src/providers/sdk-provider.tsx +164 -0
  350. package/src/providers/white-label-provider.tsx +91 -0
  351. package/src/providers/wl-subscription-provider.tsx +277 -0
  352. package/src/utils/string-helpers.ts +111 -0
@@ -0,0 +1,151 @@
1
+ import type { CompanyRegistryResult } from "@spaceinvoices/js-sdk";
2
+ import { Building2 } from "lucide-react";
3
+ import { useState } from "react";
4
+ import { Autocomplete } from "@/ui/common/autocomplete";
5
+ import { useCompanyRegistrySearch, useIsCountrySupported } from "./company-registry.hooks";
6
+
7
+ const MAX_TEXT_LENGTH = 80;
8
+
9
+ const truncateText = (text: string, maxLength: number = MAX_TEXT_LENGTH): string => {
10
+ return text.length > maxLength ? `${text.substring(0, maxLength)}...` : text;
11
+ };
12
+
13
+ type CompanyRegistryAutocompleteProps = {
14
+ /**
15
+ * ISO 3166-1 alpha-2 country code (e.g., "SI", "AT")
16
+ * Typically from the entity's country_code
17
+ */
18
+ countryCode: string;
19
+ /**
20
+ * Callback when a company is selected
21
+ * Use this to auto-fill customer form fields
22
+ */
23
+ onSelect?: (company: CompanyRegistryResult) => void;
24
+ /**
25
+ * Placeholder text for the search input
26
+ */
27
+ placeholder?: string;
28
+ /**
29
+ * Additional CSS classes
30
+ */
31
+ className?: string;
32
+ /**
33
+ * Whether the autocomplete is disabled
34
+ */
35
+ disabled?: boolean;
36
+ };
37
+
38
+ /**
39
+ * Company Registry Autocomplete
40
+ *
41
+ * Searches public company registries (e.g., AJPES for Slovenia) and allows
42
+ * users to select a company to auto-fill customer details.
43
+ *
44
+ * Features:
45
+ * - Searches by company name or tax number
46
+ * - Displays company address and legal form
47
+ * - Shows bank accounts if available
48
+ * - Only renders if country has registry data available
49
+ *
50
+ * Usage:
51
+ * ```tsx
52
+ * <CompanyRegistryAutocomplete
53
+ * countryCode={entity.country_code}
54
+ * onSelect={(company) => {
55
+ * form.setValue("name", company.name);
56
+ * form.setValue("address", company.address);
57
+ * form.setValue("tax_number", company.tax_number);
58
+ * // etc.
59
+ * }}
60
+ * />
61
+ * ```
62
+ */
63
+ export function CompanyRegistryAutocomplete({
64
+ countryCode,
65
+ onSelect,
66
+ placeholder = "Search company registry...",
67
+ className,
68
+ disabled,
69
+ }: CompanyRegistryAutocompleteProps) {
70
+ const [search, setSearch] = useState("");
71
+
72
+ const { isSupported, isLoading: isCheckingSupport } = useIsCountrySupported(countryCode);
73
+ const { data: searchData, isLoading: isSearching } = useCompanyRegistrySearch(countryCode, search);
74
+
75
+ const companies = searchData?.data || [];
76
+
77
+ // Don't render if country doesn't have registry data
78
+ if (isCheckingSupport) {
79
+ return null;
80
+ }
81
+
82
+ if (!isSupported) {
83
+ return null;
84
+ }
85
+
86
+ const options = companies.map((company) => {
87
+ const truncatedName = truncateText(company.name);
88
+ const addressParts = [company.address, company.city].filter(Boolean);
89
+ const address = addressParts.join(", ");
90
+ const truncatedAddress = truncateText(address);
91
+
92
+ // Build subtitle with legal form and bank account indicator
93
+ const subtitleParts: string[] = [];
94
+ if (company.legal_form) {
95
+ subtitleParts.push(company.legal_form);
96
+ }
97
+ if (company.tax_number) {
98
+ subtitleParts.push(`Tax: ${company.tax_number}`);
99
+ }
100
+ if (company.bank_accounts && company.bank_accounts.length > 0) {
101
+ subtitleParts.push(`${company.bank_accounts.length} bank account(s)`);
102
+ }
103
+ const subtitle = subtitleParts.join(" • ");
104
+
105
+ return {
106
+ value: company.id,
107
+ label: (
108
+ <div className="flex flex-col overflow-hidden py-1">
109
+ <span className="truncate font-medium">{truncatedName}</span>
110
+ {truncatedAddress && <span className="truncate text-muted-foreground text-xs">{truncatedAddress}</span>}
111
+ {subtitle && <span className="truncate text-muted-foreground text-xs">{subtitle}</span>}
112
+ </div>
113
+ ),
114
+ company, // Pass full company object for selection
115
+ };
116
+ });
117
+
118
+ const handleValueChange = (selectedValue: string) => {
119
+ const selectedOption = options.find((o) => o.value === selectedValue);
120
+ if (selectedOption?.company && onSelect) {
121
+ onSelect(selectedOption.company);
122
+ // Clear search after selection
123
+ setSearch("");
124
+ }
125
+ };
126
+
127
+ const handleSearch = (value: string) => {
128
+ setSearch(value);
129
+ };
130
+
131
+ return (
132
+ <div className={className}>
133
+ <div className="mb-2 flex items-center gap-2">
134
+ <Building2 className="size-4 text-muted-foreground" />
135
+ <span className="font-medium text-muted-foreground text-sm">Search {countryCode} company registry</span>
136
+ </div>
137
+ <Autocomplete
138
+ searchValue={search}
139
+ onSearch={handleSearch}
140
+ onValueChange={handleValueChange}
141
+ options={options}
142
+ placeholder={placeholder}
143
+ disabled={disabled}
144
+ loading={isSearching}
145
+ emptyText={search.length < 2 ? "Type at least 2 characters" : "No companies found"}
146
+ />
147
+ </div>
148
+ );
149
+ }
150
+
151
+ export default CompanyRegistryAutocomplete;
@@ -0,0 +1,67 @@
1
+ import type { CompanyRegistryResult } from "@spaceinvoices/js-sdk";
2
+ import { useQuery } from "@tanstack/react-query";
3
+ import { useDebounce } from "@/ui/hooks/use-debounce";
4
+ import { useSDK } from "@/ui/providers/sdk-provider";
5
+
6
+ // Cache key for company registry queries
7
+ export const COMPANY_REGISTRY_CACHE_KEY = "company-registry";
8
+
9
+ /**
10
+ * Search company registry for autocomplete
11
+ * Debounced to reduce API calls while typing
12
+ */
13
+ export function useCompanyRegistrySearch(countryCode: string, query: string) {
14
+ const { sdk } = useSDK();
15
+ const debouncedQuery = useDebounce(query, 300);
16
+
17
+ return useQuery({
18
+ queryKey: [COMPANY_REGISTRY_CACHE_KEY, "search", countryCode, debouncedQuery],
19
+ queryFn: async (): Promise<{ data: CompanyRegistryResult[] }> => {
20
+ if (!debouncedQuery || debouncedQuery.length < 2) {
21
+ return { data: [] };
22
+ }
23
+
24
+ // SDK auto-unwraps response - returns CompanyRegistrySearchResponse directly
25
+ const response = await sdk.companyRegistry.searchCompanyRegistry({
26
+ country_code: countryCode,
27
+ q: debouncedQuery,
28
+ limit: "10",
29
+ });
30
+
31
+ return { data: response.data };
32
+ },
33
+ enabled: Boolean(countryCode && debouncedQuery && debouncedQuery.length >= 2),
34
+ staleTime: 1000 * 60 * 5, // Cache for 5 minutes
35
+ });
36
+ }
37
+
38
+ /**
39
+ * Get list of countries that have company registry data available
40
+ */
41
+ export function useSupportedCountries() {
42
+ const { sdk } = useSDK();
43
+
44
+ return useQuery({
45
+ queryKey: [COMPANY_REGISTRY_CACHE_KEY, "countries"],
46
+ queryFn: async (): Promise<{ data: string[] }> => {
47
+ // SDK method renamed to `list`, auto-unwraps response
48
+ const response = await sdk.companyRegistry.list();
49
+ return { data: response.data };
50
+ },
51
+ staleTime: 1000 * 60 * 60, // Cache for 1 hour - doesn't change often
52
+ });
53
+ }
54
+
55
+ /**
56
+ * Check if company registry is available for a specific country
57
+ */
58
+ export function useIsCountrySupported(countryCode: string) {
59
+ const { data: countriesData, isLoading } = useSupportedCountries();
60
+
61
+ const isSupported = countriesData?.data?.includes(countryCode) ?? false;
62
+
63
+ return {
64
+ isSupported,
65
+ isLoading,
66
+ };
67
+ }
@@ -0,0 +1,7 @@
1
+ export {
2
+ COMPANY_REGISTRY_CACHE_KEY,
3
+ useCompanyRegistrySearch,
4
+ useIsCountrySupported,
5
+ useSupportedCountries,
6
+ } from "./company-registry.hooks";
7
+ export { CompanyRegistryAutocomplete } from "./company-registry-autocomplete";
@@ -0,0 +1,332 @@
1
+ import { zodResolver } from "@hookform/resolvers/zod";
2
+ import type { CreateCreditNoteRequest, CreditNote } from "@spaceinvoices/js-sdk";
3
+ import { useQueryClient } from "@tanstack/react-query";
4
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
5
+ import type { Resolver } from "react-hook-form";
6
+ import { useForm, useWatch } from "react-hook-form";
7
+ import type { z } from "zod";
8
+ import { Form } from "@/ui/components/ui/form";
9
+ import { createCreditNoteSchema } from "@/ui/generated/schemas";
10
+ import { useNextDocumentNumber } from "@/ui/hooks/use-next-document-number";
11
+ import type { ComponentTranslationProps } from "@/ui/lib/translation";
12
+ import { createTranslation } from "@/ui/lib/translation";
13
+ import { useEntities } from "@/ui/providers/entities-context";
14
+ import { useFormFooterRegistration } from "@/ui/providers/form-footer-context";
15
+ import { CUSTOMERS_CACHE_KEY } from "../../customers/customers.hooks";
16
+ import {
17
+ DocumentDetailsSection,
18
+ DocumentNoteField,
19
+ DocumentPaymentTermsField,
20
+ } from "../../documents/create/document-details-section";
21
+ import { DocumentItemsSection, type PriceModesMap } from "../../documents/create/document-items-section";
22
+ import { DocumentRecipientSection } from "../../documents/create/document-recipient-section";
23
+ import { MarkAsPaidSection } from "../../documents/create/mark-as-paid-section";
24
+ import { prepareDocumentSubmission } from "../../documents/create/prepare-document-submission";
25
+ import { useDocumentCustomerForm } from "../../documents/create/use-document-customer-form";
26
+ import type { DocumentTypes } from "../../documents/types";
27
+ import { useCreateCreditNote } from "../credit-notes.hooks";
28
+ import de from "./locales/de";
29
+ import sl from "./locales/sl";
30
+
31
+ const translations = {
32
+ sl,
33
+ de,
34
+ } as const;
35
+
36
+ // Form values: extend schema with local-only fields (number is for display, not sent to API)
37
+ type CreateCreditNoteFormValues = z.infer<typeof createCreditNoteSchema> & {
38
+ number?: string;
39
+ };
40
+
41
+ /** Preview payload extends request with display-only fields */
42
+ type CreditNotePreviewPayload = Partial<CreateCreditNoteRequest> & { number?: string };
43
+
44
+ type CreateCreditNoteFormProps = {
45
+ type: DocumentTypes;
46
+ entityId: string;
47
+ onSuccess?: (data: CreditNote) => void;
48
+ onError?: (error: unknown) => void;
49
+ onChange?: (data: CreditNotePreviewPayload) => void;
50
+ onAddNewTax?: () => void;
51
+ /** Initial values for form fields (used for document duplication) */
52
+ initialValues?: Partial<CreateCreditNoteRequest>;
53
+ } & ComponentTranslationProps;
54
+
55
+ export default function CreateCreditNoteForm({
56
+ type: _type,
57
+ entityId,
58
+ onSuccess,
59
+ onError,
60
+ onChange,
61
+ onAddNewTax,
62
+ initialValues,
63
+ t: translateProp,
64
+ namespace,
65
+ locale,
66
+ }: CreateCreditNoteFormProps) {
67
+ const t = createTranslation({
68
+ t: translateProp,
69
+ namespace,
70
+ locale,
71
+ translations,
72
+ });
73
+
74
+ const { activeEntity } = useEntities();
75
+ const queryClient = useQueryClient();
76
+
77
+ // Fetch next credit note number
78
+ const { data: nextNumberData } = useNextDocumentNumber(entityId, "credit_note", {
79
+ enabled: !!entityId,
80
+ });
81
+
82
+ // UI-only state (not part of API schema)
83
+ const [markAsPaid, setMarkAsPaid] = useState(false);
84
+ const [paymentType, setPaymentType] = useState("bank_transfer");
85
+ const [isDraftPending, setIsDraftPending] = useState(false);
86
+
87
+ // Price modes per item (gross vs net) - collected from component state at submit
88
+ const initialPriceModes = useMemo(() => {
89
+ if (!initialValues?.items) return {};
90
+ return initialValues.items.reduce((acc, item, index) => {
91
+ acc[index] = item.gross_price != null;
92
+ return acc;
93
+ }, {} as PriceModesMap);
94
+ }, [initialValues?.items]);
95
+ const priceModesRef = useRef<PriceModesMap>(initialPriceModes);
96
+
97
+ // Get default payment terms from entity settings
98
+ const defaultPaymentTerms = (activeEntity?.settings as any)?.default_credit_note_payment_terms || "";
99
+
100
+ const form = useForm<CreateCreditNoteFormValues>({
101
+ // Cast resolver to accept extended form type (includes UI-only fields)
102
+ resolver: zodResolver(createCreditNoteSchema) as Resolver<CreateCreditNoteFormValues>,
103
+ defaultValues: {
104
+ number: "",
105
+ date: initialValues?.date || new Date().toISOString(),
106
+ customer_id: initialValues?.customer_id ?? undefined,
107
+ // Cast customer to form schema type (API type may have additional fields)
108
+ customer: (initialValues?.customer as CreateCreditNoteFormValues["customer"]) ?? undefined,
109
+ items: initialValues?.items?.length
110
+ ? initialValues.items.map((item) => ({
111
+ name: item.name || "",
112
+ description: item.description || "",
113
+ quantity: item.quantity ?? 1,
114
+ // Use gross_price if set, otherwise use price
115
+ price: item.gross_price ?? item.price,
116
+ taxes: item.taxes || [],
117
+ }))
118
+ : [
119
+ {
120
+ name: "",
121
+ description: "",
122
+ quantity: 1,
123
+ price: undefined,
124
+ taxes: [],
125
+ },
126
+ ],
127
+ currency_code: initialValues?.currency_code || activeEntity?.currency_code || "EUR",
128
+ note: initialValues?.note ?? "",
129
+ payment_terms: initialValues?.payment_terms ?? defaultPaymentTerms,
130
+ },
131
+ });
132
+
133
+ const formValues = useWatch({
134
+ control: form.control,
135
+ });
136
+
137
+ // Extract customer management logic into a shared hook
138
+ const {
139
+ originalCustomer,
140
+ showCustomerForm,
141
+ shouldFocusName,
142
+ selectedCustomerId,
143
+ initialCustomerName,
144
+ handleCustomerSelect,
145
+ handleCustomerClear,
146
+ } = useDocumentCustomerForm(form);
147
+
148
+ // Pre-fill credit note number from preview
149
+ useEffect(() => {
150
+ if (nextNumberData?.number) {
151
+ form.setValue("number", nextNumberData.number);
152
+ }
153
+ }, [nextNumberData?.number, form]);
154
+
155
+ const { mutate: createCreditNote, isPending } = useCreateCreditNote({
156
+ entityId,
157
+ onSuccess: (data) => {
158
+ // Invalidate customers cache when a customer was created/linked
159
+ if (data.customer_id) {
160
+ queryClient.invalidateQueries({ queryKey: [CUSTOMERS_CACHE_KEY] });
161
+ }
162
+ onSuccess?.(data);
163
+ },
164
+ onError,
165
+ });
166
+
167
+ // Shared submit logic for both regular save and save as draft
168
+ const submitCreditNote = useCallback(
169
+ (values: CreateCreditNoteFormValues, isDraft: boolean) => {
170
+ const payload = prepareDocumentSubmission(values, {
171
+ originalCustomer,
172
+ wasCustomerFormShown: showCustomerForm,
173
+ markAsPaid: isDraft ? false : markAsPaid,
174
+ paymentType,
175
+ documentType: "credit_note",
176
+ priceModes: priceModesRef.current,
177
+ isDraft,
178
+ });
179
+ createCreditNote(payload as CreateCreditNoteRequest);
180
+ },
181
+ [createCreditNote, markAsPaid, originalCustomer, paymentType, showCustomerForm],
182
+ );
183
+
184
+ // Handle save as draft
185
+ const handleSaveAsDraft = useCallback(async () => {
186
+ setIsDraftPending(true);
187
+ try {
188
+ const isValid = await form.trigger();
189
+ if (isValid) {
190
+ const values = form.getValues();
191
+ submitCreditNote(values, true);
192
+ }
193
+ } finally {
194
+ setIsDraftPending(false);
195
+ }
196
+ }, [form, submitCreditNote]);
197
+
198
+ useFormFooterRegistration({
199
+ formId: "create-credit-note-form",
200
+ isPending,
201
+ isDirty: form.formState.isDirty,
202
+ label: t("Save"),
203
+ secondaryAction: {
204
+ label: t("Save as Draft"),
205
+ onClick: handleSaveAsDraft,
206
+ isPending: isDraftPending,
207
+ },
208
+ });
209
+
210
+ // Set default note and payment terms from entity settings when entity data is available
211
+ useEffect(() => {
212
+ const entityDefaultNote = (activeEntity?.settings as any)?.default_credit_note_note;
213
+ if (entityDefaultNote && !form.getValues("note")) {
214
+ form.setValue("note", entityDefaultNote);
215
+ }
216
+ const entityDefaultPaymentTerms = (activeEntity?.settings as any)?.default_credit_note_payment_terms;
217
+ if (entityDefaultPaymentTerms && !form.getValues("payment_terms")) {
218
+ form.setValue("payment_terms", entityDefaultPaymentTerms);
219
+ }
220
+ }, [activeEntity, form]);
221
+
222
+ // Auto-add tax field for tax subject entities
223
+ useEffect(() => {
224
+ if (activeEntity?.is_tax_subject) {
225
+ const items = form.getValues("items") || [];
226
+ if (items.length > 0 && (!items[0].taxes || items[0].taxes.length === 0)) {
227
+ form.setValue("items.0.taxes", [{ tax_id: undefined }]);
228
+ }
229
+ }
230
+ }, [activeEntity?.is_tax_subject, form]);
231
+
232
+ useEffect(() => {
233
+ if (onChange) {
234
+ const currentItems = form.getValues("items") || [];
235
+
236
+ // Transform items to use gross_price when price mode is gross
237
+ const transformedItems = currentItems.map((item: any, index: number) => {
238
+ const { price, ...rest } = item;
239
+ const isGross = priceModesRef.current[index] ?? false;
240
+ if (isGross) {
241
+ return { ...rest, gross_price: price };
242
+ }
243
+ return { ...rest, price };
244
+ });
245
+
246
+ // Build preview payload (includes number for display)
247
+ const payload: CreditNotePreviewPayload = {
248
+ number: formValues.number,
249
+ date: formValues.date,
250
+ customer_id: formValues.customer_id,
251
+ customer: formValues.customer,
252
+ items: transformedItems,
253
+ currency_code: formValues.currency_code,
254
+ note: formValues.note,
255
+ payment_terms: formValues.payment_terms,
256
+ };
257
+ onChange(payload);
258
+ }
259
+ }, [formValues, onChange, form]);
260
+
261
+ const onSubmit = (values: CreateCreditNoteFormValues) => {
262
+ submitCreditNote(values, false);
263
+ };
264
+
265
+ return (
266
+ <Form {...form}>
267
+ <form id="create-credit-note-form" onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
268
+ <div className="flex w-full flex-col md:flex-row md:gap-6">
269
+ <DocumentRecipientSection
270
+ control={form.control}
271
+ entityId={entityId}
272
+ onCustomerSelect={handleCustomerSelect}
273
+ onCustomerClear={handleCustomerClear}
274
+ showCustomerForm={showCustomerForm}
275
+ shouldFocusName={shouldFocusName}
276
+ selectedCustomerId={selectedCustomerId}
277
+ initialCustomerName={initialCustomerName}
278
+ t={t}
279
+ />
280
+ <DocumentDetailsSection control={form.control} documentType={_type} t={t}>
281
+ {/* Credit note specific: Mark as paid section (UI-only state, not in form schema) */}
282
+ <MarkAsPaidSection
283
+ checked={markAsPaid}
284
+ onCheckedChange={setMarkAsPaid}
285
+ paymentType={paymentType}
286
+ onPaymentTypeChange={setPaymentType}
287
+ t={t}
288
+ />
289
+ </DocumentDetailsSection>
290
+ </div>
291
+
292
+ <DocumentItemsSection
293
+ control={form.control}
294
+ watch={form.watch}
295
+ setValue={form.setValue}
296
+ getValues={form.getValues}
297
+ entityId={entityId}
298
+ currencyCode={activeEntity?.currency_code ?? undefined}
299
+ onAddNewTax={onAddNewTax}
300
+ t={t}
301
+ maxTaxesPerItem={activeEntity?.country_rules?.max_taxes_per_item}
302
+ priceModesRef={priceModesRef}
303
+ initialPriceModes={initialPriceModes}
304
+ />
305
+
306
+ <DocumentNoteField
307
+ control={form.control}
308
+ t={t}
309
+ entity={activeEntity}
310
+ document={{
311
+ number: formValues.number,
312
+ date: formValues.date,
313
+ currency_code: formValues.currency_code,
314
+ customer: formValues.customer as any,
315
+ }}
316
+ />
317
+
318
+ <DocumentPaymentTermsField
319
+ control={form.control}
320
+ t={t}
321
+ entity={activeEntity}
322
+ document={{
323
+ number: formValues.number,
324
+ date: formValues.date,
325
+ currency_code: formValues.currency_code,
326
+ customer: formValues.customer as any,
327
+ }}
328
+ />
329
+ </form>
330
+ </Form>
331
+ );
332
+ }
@@ -0,0 +1 @@
1
+ export { default as CreateCreditNoteForm } from "./create-credit-note-form";
@@ -0,0 +1,69 @@
1
+ export default {
2
+ Recipient: "Empfänger",
3
+ Name: "Name",
4
+ Details: "Details",
5
+ Number: "Nummer",
6
+ Date: "Datum",
7
+ "Pick a date": "Datum auswählen",
8
+ "Due Date": "Fälligkeitsdatum",
9
+ "Valid Until": "Gültig bis",
10
+ Items: "Artikel",
11
+ "Add item": "Artikel hinzufügen",
12
+ Save: "Speichern",
13
+ "Save as Draft": "Als Entwurf speichern",
14
+ Quantity: "Menge",
15
+ Price: "Preis",
16
+ Unit: "Einheit",
17
+ Discount: "Rabatt",
18
+ Tax: "Steuer",
19
+ "Tax rate": "Steuersatz",
20
+ "Add tax": "Steuer hinzufügen",
21
+ "Select tax...": "Steuer auswählen...",
22
+ "Loading...": "Laden...",
23
+ "No taxes found": "Keine Steuern gefunden",
24
+ "Add new tax...": "Neue Steuer hinzufügen...",
25
+ Description: "Beschreibung",
26
+ "Mark as Paid": "Als bezahlt markieren",
27
+ Paid: "Bezahlt",
28
+ "Credit note will be marked as fully paid upon creation":
29
+ "Gutschrift wird bei Erstellung als vollständig bezahlt markiert",
30
+ "Payment Type": "Zahlungsart",
31
+ "Select payment type": "Zahlungsart auswählen",
32
+ Cash: "Bargeld",
33
+ "Bank Transfer": "Banküberweisung",
34
+ Card: "Karte",
35
+ Check: "Scheck",
36
+ Other: "Andere",
37
+ // Note field
38
+ Note: "Notiz",
39
+ "Insert variable": "Variable einfügen",
40
+ "Add payment instructions, terms, or other notes...":
41
+ "Zahlungsanweisungen, Bedingungen oder andere Notizen hinzufügen...",
42
+ // Payment terms field
43
+ "Payment Terms": "Zahlungsbedingungen",
44
+ "Add payment terms...": "Zahlungsbedingungen hinzufügen...",
45
+ // Recipient fields
46
+ "Search or create customer...": "Kunde suchen oder erstellen...",
47
+ Clear: "Löschen",
48
+ Address: "Adresse",
49
+ "Address 2": "Adresse 2",
50
+ "Post Code": "Postleitzahl",
51
+ City: "Stadt",
52
+ State: "Bundesland",
53
+ Country: "Land",
54
+ "Tax Number": "Steuernummer",
55
+ // Currency
56
+ Currency: "Währung",
57
+ "Select currency": "Währung auswählen",
58
+ // Discount types
59
+ "Percentage discount": "Prozentualer Rabatt",
60
+ "Fixed amount discount": "Fester Rabatt",
61
+ Percentage: "Prozent",
62
+ "Fixed amount": "Fester Betrag",
63
+ "Taxes disabled": "Steuern deaktiviert",
64
+ // Gross price support
65
+ "Gross price": "Bruttopreis",
66
+ "Net price": "Nettopreis",
67
+ "Gross price (tax included)": "Bruttopreis (inkl. MwSt.)",
68
+ "Net price (before tax)": "Nettopreis (exkl. MwSt.)",
69
+ } as const;