@spaceinvoices/react-ui 0.4.1 → 0.4.3

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 (245) hide show
  1. package/cli/dist/index.js +1 -1
  2. package/package.json +1 -1
  3. package/registry.json +25 -0
  4. package/src/components/advance-invoices/advance-invoices.hooks.ts +32 -2
  5. package/src/components/advance-invoices/create/create-advance-invoice-form.tsx +109 -4
  6. package/src/components/advance-invoices/create/locales/de.ts +2 -0
  7. package/src/components/advance-invoices/create/locales/es.ts +2 -0
  8. package/src/components/advance-invoices/create/locales/fr.ts +2 -0
  9. package/src/components/advance-invoices/create/locales/hr.ts +2 -0
  10. package/src/components/advance-invoices/create/locales/it.ts +2 -0
  11. package/src/components/advance-invoices/create/locales/nl.ts +2 -0
  12. package/src/components/advance-invoices/create/locales/pl.ts +2 -0
  13. package/src/components/advance-invoices/create/locales/pt.ts +2 -0
  14. package/src/components/advance-invoices/create/locales/sl.ts +2 -0
  15. package/src/components/advance-invoices/create/prepare-advance-invoice-submission.ts +17 -0
  16. package/src/components/advance-invoices/list/list-row-actions.tsx +3 -6
  17. package/src/components/advance-invoices/list/list-table.tsx +105 -2
  18. package/src/components/advance-invoices/list/locales/de.ts +4 -0
  19. package/src/components/advance-invoices/list/locales/en.ts +4 -0
  20. package/src/components/advance-invoices/list/locales/es.ts +4 -0
  21. package/src/components/advance-invoices/list/locales/fr.ts +4 -0
  22. package/src/components/advance-invoices/list/locales/hr.ts +4 -0
  23. package/src/components/advance-invoices/list/locales/it.ts +4 -0
  24. package/src/components/advance-invoices/list/locales/nl.ts +4 -0
  25. package/src/components/advance-invoices/list/locales/pl.ts +4 -0
  26. package/src/components/advance-invoices/list/locales/pt.ts +4 -0
  27. package/src/components/advance-invoices/list/locales/sl.ts +4 -0
  28. package/src/components/credit-notes/create/create-credit-note-form.tsx +177 -6
  29. package/src/components/credit-notes/create/locales/de.ts +8 -0
  30. package/src/components/credit-notes/create/locales/es.ts +8 -0
  31. package/src/components/credit-notes/create/locales/fr.ts +7 -0
  32. package/src/components/credit-notes/create/locales/hr.ts +7 -0
  33. package/src/components/credit-notes/create/locales/it.ts +9 -0
  34. package/src/components/credit-notes/create/locales/nl.ts +7 -0
  35. package/src/components/credit-notes/create/locales/pl.ts +7 -0
  36. package/src/components/credit-notes/create/locales/pt.ts +7 -0
  37. package/src/components/credit-notes/create/locales/sl.ts +7 -0
  38. package/src/components/credit-notes/credit-notes.hooks.ts +30 -0
  39. package/src/components/credit-notes/list/list-row-actions.tsx +3 -6
  40. package/src/components/credit-notes/list/list-table.tsx +79 -8
  41. package/src/components/credit-notes/list/locales/de.ts +4 -1
  42. package/src/components/credit-notes/list/locales/en.ts +5 -0
  43. package/src/components/credit-notes/list/locales/es.ts +4 -1
  44. package/src/components/credit-notes/list/locales/fr.ts +4 -1
  45. package/src/components/credit-notes/list/locales/hr.ts +4 -1
  46. package/src/components/credit-notes/list/locales/it.ts +4 -1
  47. package/src/components/credit-notes/list/locales/nl.ts +4 -1
  48. package/src/components/credit-notes/list/locales/pl.ts +4 -1
  49. package/src/components/credit-notes/list/locales/pt.ts +4 -1
  50. package/src/components/credit-notes/list/locales/sl.ts +4 -1
  51. package/src/components/customers/create-customer-form/create-customer-form.tsx +0 -1
  52. package/src/components/dashboard/collection-rate-card/use-collection-rate.ts +2 -2
  53. package/src/components/dashboard/invoice-status-chart/use-invoice-status.ts +3 -3
  54. package/src/components/dashboard/payment-methods-chart/use-payment-methods.ts +1 -1
  55. package/src/components/dashboard/payment-trend-chart/use-payment-trend.ts +1 -1
  56. package/src/components/dashboard/revenue-trend-chart/use-revenue-trend.ts +1 -1
  57. package/src/components/dashboard/shared/use-revenue-data.ts +4 -4
  58. package/src/components/dashboard/shared/use-stats-counts.ts +4 -4
  59. package/src/components/dashboard/shared/use-stats-query.ts +1 -1
  60. package/src/components/dashboard/tax-collected-card/use-tax-collected.ts +2 -2
  61. package/src/components/dashboard/top-customers-chart/use-top-customers.ts +1 -1
  62. package/src/components/delivery-notes/create/create-delivery-note-form.tsx +332 -0
  63. package/src/components/delivery-notes/create/locales/de.ts +50 -0
  64. package/src/components/delivery-notes/create/locales/es.ts +49 -0
  65. package/src/components/delivery-notes/create/locales/fr.ts +50 -0
  66. package/src/components/delivery-notes/create/locales/hr.ts +49 -0
  67. package/src/components/delivery-notes/create/locales/it.ts +49 -0
  68. package/src/components/delivery-notes/create/locales/nl.ts +50 -0
  69. package/src/components/delivery-notes/create/locales/pl.ts +49 -0
  70. package/src/components/delivery-notes/create/locales/pt.ts +50 -0
  71. package/src/components/delivery-notes/create/locales/sl.ts +49 -0
  72. package/src/components/delivery-notes/create/prepare-delivery-note-submission.ts +38 -0
  73. package/src/components/delivery-notes/create/use-delivery-note-customer-form.ts +1 -0
  74. package/src/components/delivery-notes/delivery-notes.hooks.ts +15 -0
  75. package/src/components/delivery-notes/list/index.ts +3 -0
  76. package/src/components/delivery-notes/list/list-row-actions.tsx +103 -0
  77. package/src/components/delivery-notes/list/list-table.tsx +214 -0
  78. package/src/components/delivery-notes/list/locales/de.ts +9 -0
  79. package/src/components/delivery-notes/list/locales/en.ts +11 -0
  80. package/src/components/delivery-notes/list/locales/es.ts +9 -0
  81. package/src/components/delivery-notes/list/locales/fr.ts +9 -0
  82. package/src/components/delivery-notes/list/locales/hr.ts +9 -0
  83. package/src/components/delivery-notes/list/locales/it.ts +9 -0
  84. package/src/components/delivery-notes/list/locales/nl.ts +9 -0
  85. package/src/components/delivery-notes/list/locales/pl.ts +9 -0
  86. package/src/components/delivery-notes/list/locales/pt.ts +9 -0
  87. package/src/components/delivery-notes/list/locales/sl.ts +9 -0
  88. package/src/components/delivery-notes/list/use-delivery-note-download.ts +63 -0
  89. package/src/components/documents/create/document-details-section.tsx +103 -33
  90. package/src/components/documents/create/live-preview.tsx +37 -10
  91. package/src/components/documents/create/mark-as-paid-section.tsx +11 -2
  92. package/src/components/documents/create/prepare-document-submission.ts +1 -1
  93. package/src/components/documents/documents.hooks.ts +2 -1
  94. package/src/components/documents/shared/document-preview-display.tsx +12 -5
  95. package/src/components/documents/types.ts +10 -1
  96. package/src/components/documents/view/document-actions-bar.tsx +30 -0
  97. package/src/components/documents/view/document-details-card.tsx +3 -3
  98. package/src/components/documents/view/document-payments-list.tsx +3 -3
  99. package/src/components/documents/view/document-relations-list.tsx +105 -0
  100. package/src/components/documents/view/locales/de.ts +26 -0
  101. package/src/components/documents/view/locales/es.ts +26 -0
  102. package/src/components/documents/view/locales/fr.ts +26 -0
  103. package/src/components/documents/view/locales/hr.ts +26 -0
  104. package/src/components/documents/view/locales/it.ts +26 -0
  105. package/src/components/documents/view/locales/nl.ts +26 -0
  106. package/src/components/documents/view/locales/pl.ts +26 -0
  107. package/src/components/documents/view/locales/pt.ts +26 -0
  108. package/src/components/documents/view/locales/sl.ts +26 -0
  109. package/src/components/documents/view/use-document-download.ts +5 -3
  110. package/src/components/entities/create-entity-form.tsx +1 -1
  111. package/src/components/entities/entity-settings-form/entity-settings-form.tsx +2 -3
  112. package/src/components/entities/entity-settings-form/locales/es.ts +2 -0
  113. package/src/components/entities/entity-settings-form/locales/fr.ts +2 -0
  114. package/src/components/entities/entity-settings-form/locales/hr.ts +2 -0
  115. package/src/components/entities/entity-settings-form/locales/it.ts +2 -0
  116. package/src/components/entities/entity-settings-form/locales/nl.ts +2 -0
  117. package/src/components/entities/entity-settings-form/locales/pl.ts +2 -0
  118. package/src/components/entities/entity-settings-form/locales/pt.ts +2 -0
  119. package/src/components/entities/fina-settings-form/fina-operator-required-dialog.tsx +109 -0
  120. package/src/components/entities/fina-settings-form/fina-settings-form.tsx +377 -35
  121. package/src/components/entities/fina-settings-form/fina-settings.hooks.ts +106 -20
  122. package/src/components/entities/fina-settings-form/index.ts +1 -0
  123. package/src/components/entities/fina-settings-form/locales/de.ts +54 -34
  124. package/src/components/entities/fina-settings-form/locales/en.ts +51 -34
  125. package/src/components/entities/fina-settings-form/locales/es.ts +50 -34
  126. package/src/components/entities/fina-settings-form/locales/fr.ts +50 -34
  127. package/src/components/entities/fina-settings-form/locales/hr.ts +50 -34
  128. package/src/components/entities/fina-settings-form/locales/it.ts +50 -34
  129. package/src/components/entities/fina-settings-form/locales/nl.ts +50 -34
  130. package/src/components/entities/fina-settings-form/locales/pl.ts +50 -34
  131. package/src/components/entities/fina-settings-form/locales/pt.ts +50 -34
  132. package/src/components/entities/fina-settings-form/locales/sl.ts +50 -34
  133. package/src/components/entities/fina-settings-form/sections/certificate-settings-section.tsx +18 -0
  134. package/src/components/entities/fina-settings-form/sections/premises-management-section.tsx +64 -89
  135. package/src/components/entities/fina-settings-form/sections/register-premise-dialog.tsx +51 -323
  136. package/src/components/entities/furs-settings-form/furs-operator-required-dialog.tsx +106 -0
  137. package/src/components/entities/furs-settings-form/furs-settings-form.tsx +33 -10
  138. package/src/components/entities/furs-settings-form/furs-settings.hooks.ts +12 -11
  139. package/src/components/entities/furs-settings-form/index.ts +1 -0
  140. package/src/components/entities/furs-settings-form/locales/de.ts +27 -3
  141. package/src/components/entities/furs-settings-form/locales/en.ts +17 -3
  142. package/src/components/entities/furs-settings-form/locales/es.ts +26 -3
  143. package/src/components/entities/furs-settings-form/locales/fr.ts +26 -3
  144. package/src/components/entities/furs-settings-form/locales/hr.ts +26 -3
  145. package/src/components/entities/furs-settings-form/locales/it.ts +26 -3
  146. package/src/components/entities/furs-settings-form/locales/nl.ts +26 -3
  147. package/src/components/entities/furs-settings-form/locales/pl.ts +26 -3
  148. package/src/components/entities/furs-settings-form/locales/pt.ts +26 -3
  149. package/src/components/entities/furs-settings-form/locales/sl.ts +16 -3
  150. package/src/components/entities/furs-settings-form/sections/certificate-settings-section.tsx +22 -0
  151. package/src/components/entities/furs-settings-form/sections/general-settings-section.tsx +26 -5
  152. package/src/components/entities/furs-settings-form/sections/register-premise-dialog.tsx +14 -2
  153. package/src/components/entities/settings/tax-rules-settings-form.tsx +4 -4
  154. package/src/components/estimates/list/list-row-actions.tsx +3 -7
  155. package/src/components/estimates/list/list-table.tsx +35 -2
  156. package/src/components/estimates/list/locales/de.ts +3 -0
  157. package/src/components/estimates/list/locales/en.ts +3 -0
  158. package/src/components/estimates/list/locales/es.ts +3 -0
  159. package/src/components/estimates/list/locales/fr.ts +3 -0
  160. package/src/components/estimates/list/locales/hr.ts +3 -0
  161. package/src/components/estimates/list/locales/it.ts +3 -0
  162. package/src/components/estimates/list/locales/nl.ts +3 -0
  163. package/src/components/estimates/list/locales/pl.ts +3 -0
  164. package/src/components/estimates/list/locales/pt.ts +3 -0
  165. package/src/components/estimates/list/locales/sl.ts +3 -0
  166. package/src/components/export/document-export-form.tsx +34 -34
  167. package/src/components/invoices/create/create-invoice-form.tsx +107 -5
  168. package/src/components/invoices/create/prepare-invoice-submission.ts +17 -0
  169. package/src/components/invoices/invoices-furs.hooks.ts +24 -9
  170. package/src/components/invoices/invoices.hooks.ts +32 -2
  171. package/src/components/invoices/list/list-row-actions.tsx +26 -11
  172. package/src/components/invoices/list/list-table.tsx +121 -5
  173. package/src/components/invoices/list/locales/de.ts +5 -0
  174. package/src/components/invoices/list/locales/en.ts +5 -0
  175. package/src/components/invoices/list/locales/es.ts +5 -0
  176. package/src/components/invoices/list/locales/fr.ts +5 -0
  177. package/src/components/invoices/list/locales/hr.ts +5 -0
  178. package/src/components/invoices/list/locales/it.ts +5 -0
  179. package/src/components/invoices/list/locales/nl.ts +5 -0
  180. package/src/components/invoices/list/locales/pl.ts +5 -0
  181. package/src/components/invoices/list/locales/pt.ts +5 -0
  182. package/src/components/invoices/list/locales/sl.ts +5 -0
  183. package/src/components/invoices/view/fiscalization-status-card.tsx +4 -1
  184. package/src/components/items/item-list-table/item-list-row-actions.tsx +5 -8
  185. package/src/components/items/item-list-table/item-list-row.tsx +5 -3
  186. package/src/components/items/item-list-table/item-list-table.tsx +5 -1
  187. package/src/components/recurring-invoices/create-recurring-invoice-form/create-recurring-invoice-form.tsx +418 -0
  188. package/src/components/recurring-invoices/create-recurring-invoice-form/locales/de.ts +45 -0
  189. package/src/components/recurring-invoices/create-recurring-invoice-form/locales/es.ts +44 -0
  190. package/src/components/recurring-invoices/create-recurring-invoice-form/locales/fr.ts +44 -0
  191. package/src/components/recurring-invoices/create-recurring-invoice-form/locales/hr.ts +44 -0
  192. package/src/components/recurring-invoices/create-recurring-invoice-form/locales/it.ts +44 -0
  193. package/src/components/recurring-invoices/create-recurring-invoice-form/locales/nl.ts +44 -0
  194. package/src/components/recurring-invoices/create-recurring-invoice-form/locales/pl.ts +44 -0
  195. package/src/components/recurring-invoices/create-recurring-invoice-form/locales/pt.ts +44 -0
  196. package/src/components/recurring-invoices/create-recurring-invoice-form/locales/sl.ts +44 -0
  197. package/src/components/recurring-invoices/index.ts +3 -0
  198. package/src/components/recurring-invoices/list/index.ts +2 -0
  199. package/src/components/recurring-invoices/list/list-row-actions.tsx +139 -0
  200. package/src/components/recurring-invoices/list/list-table.tsx +179 -0
  201. package/src/components/recurring-invoices/list/locales/de.ts +27 -0
  202. package/src/components/recurring-invoices/list/locales/en.ts +5 -0
  203. package/src/components/recurring-invoices/list/locales/es.ts +27 -0
  204. package/src/components/recurring-invoices/list/locales/fr.ts +27 -0
  205. package/src/components/recurring-invoices/list/locales/hr.ts +27 -0
  206. package/src/components/recurring-invoices/list/locales/it.ts +27 -0
  207. package/src/components/recurring-invoices/list/locales/nl.ts +27 -0
  208. package/src/components/recurring-invoices/list/locales/pl.ts +27 -0
  209. package/src/components/recurring-invoices/list/locales/pt.ts +27 -0
  210. package/src/components/recurring-invoices/list/locales/sl.ts +27 -0
  211. package/src/components/recurring-invoices/recurring-invoices.hooks.ts +28 -0
  212. package/src/components/table/data-table.tsx +122 -5
  213. package/src/components/table/selection-toolbar.tsx +36 -0
  214. package/src/components/tax-reports/kir-export-form.tsx +75 -55
  215. package/src/components/taxes/tax-list-table/tax-list-row-actions.tsx +3 -6
  216. package/src/components/taxes/tax-list-table/tax-list-row.tsx +3 -2
  217. package/src/components/taxes/tax-list-table/tax-list-table.tsx +5 -1
  218. package/src/components/ui/checkbox.tsx +5 -5
  219. package/src/generate-schemas.ts +45 -18
  220. package/src/generated/schemas/authorizeshopify_body.ts +22 -0
  221. package/src/generated/schemas/creditnote.ts +0 -2
  222. package/src/generated/schemas/deliverynote.ts +134 -0
  223. package/src/generated/schemas/entity.ts +5 -1
  224. package/src/generated/schemas/index.ts +42 -28
  225. package/src/generated/schemas/order.ts +129 -0
  226. package/src/generated/schemas/orderintegration.ts +51 -0
  227. package/src/generated/schemas/payment.ts +24 -2
  228. package/src/generated/schemas/recurringinvoice.ts +61 -0
  229. package/src/generated/schemas/renderadvanceinvoicepreview_body.ts +108 -140
  230. package/src/generated/schemas/rendercreditnotepreview_body.ts +109 -141
  231. package/src/generated/schemas/renderdeliverynotepreview_body.ts +185 -0
  232. package/src/generated/schemas/renderestimatepreview_body.ts +79 -82
  233. package/src/generated/schemas/renderinvoicepreview_body.ts +109 -141
  234. package/src/generated/schemas/startpdfexport_body.ts +18 -2
  235. package/src/generated/schemas/userfinasettings.ts +19 -0
  236. package/src/generated/schemas/webhook.ts +54 -0
  237. package/src/hooks/use-duplicate-document.ts +11 -3
  238. package/src/hooks/use-next-document-number.ts +2 -2
  239. package/src/lib/furs-error-utils.ts +36 -0
  240. package/src/lib/schemas/advance-invoice.ts +3 -3
  241. package/src/lib/schemas/credit-note.ts +3 -3
  242. package/src/lib/schemas/estimate.ts +3 -3
  243. package/src/lib/schemas/invoice.ts +3 -3
  244. package/src/providers/sdk-provider.tsx +5 -7
  245. package/src/providers/white-label-provider.tsx +3 -0
@@ -44,7 +44,7 @@ export type DocumentExportFormProps = {
44
44
  t: TFunction;
45
45
  onSuccess?: (fileName: string) => void;
46
46
  onError?: (error: Error) => void;
47
- onPdfExportStarted?: () => void;
47
+ onPdfExportStarted?: (jobId: string) => void;
48
48
  onLoadingChange?: (isLoading: boolean, toastId: string | number | null) => void;
49
49
  };
50
50
 
@@ -105,7 +105,8 @@ export function DocumentExportForm({
105
105
  throw new Error(error.error || `Export failed: ${response.statusText}`);
106
106
  }
107
107
 
108
- onPdfExportStarted?.();
108
+ const data = await response.json();
109
+ onPdfExportStarted?.(data.id);
109
110
  } catch (error) {
110
111
  onError?.(error instanceof Error ? error : new Error("Unknown error"));
111
112
  } finally {
@@ -175,40 +176,39 @@ export function DocumentExportForm({
175
176
 
176
177
  return (
177
178
  <div className="space-y-6">
178
- <p className="text-muted-foreground">{t("export-page.description")}</p>
179
-
180
- {/* Document Type */}
181
- <div className="space-y-2">
182
- <Label htmlFor="document-type">{t("export-page.document-type")}</Label>
183
- <Select value={documentType} onValueChange={(v) => setDocumentType(v as DocumentType)}>
184
- <SelectTrigger id="document-type">
185
- <SelectValue />
186
- </SelectTrigger>
187
- <SelectContent>
188
- <SelectItem value="invoice">{t("export-page.types.invoice")}</SelectItem>
189
- <SelectItem value="estimate">{t("export-page.types.estimate")}</SelectItem>
190
- <SelectItem value="credit_note">{t("export-page.types.credit_note")}</SelectItem>
191
- </SelectContent>
192
- </Select>
193
- </div>
179
+ {/* Document Type + Export Format */}
180
+ <div className="grid grid-cols-2 gap-4">
181
+ <div className="space-y-2">
182
+ <Label htmlFor="document-type">{t("export-page.document-type")}</Label>
183
+ <Select value={documentType} onValueChange={(v) => setDocumentType(v as DocumentType)}>
184
+ <SelectTrigger id="document-type">
185
+ <SelectValue />
186
+ </SelectTrigger>
187
+ <SelectContent>
188
+ <SelectItem value="invoice">{t("export-page.types.invoice")}</SelectItem>
189
+ <SelectItem value="estimate">{t("export-page.types.estimate")}</SelectItem>
190
+ <SelectItem value="credit_note">{t("export-page.types.credit_note")}</SelectItem>
191
+ </SelectContent>
192
+ </Select>
193
+ </div>
194
194
 
195
- {/* Export Format */}
196
- <div className="space-y-2">
197
- <Label htmlFor="export-format">{t("export-page.format")}</Label>
198
- <Select value={exportFormat} onValueChange={(v) => setExportFormat(v as ExportFormat)}>
199
- <SelectTrigger id="export-format">
200
- <SelectValue />
201
- </SelectTrigger>
202
- <SelectContent>
203
- <SelectItem value="xlsx">{t("export-page.formats.xlsx")}</SelectItem>
204
- <SelectItem value="csv">{t("export-page.formats.csv")}</SelectItem>
205
- <SelectItem value="pdf_zip">{t("export-page.formats.pdf_zip")}</SelectItem>
206
- </SelectContent>
207
- </Select>
208
- {exportFormat === "pdf_zip" && (
209
- <p className="text-muted-foreground text-sm">{t("export-page.pdf-export-info")}</p>
210
- )}
195
+ <div className="space-y-2">
196
+ <Label htmlFor="export-format">{t("export-page.format")}</Label>
197
+ <Select value={exportFormat} onValueChange={(v) => setExportFormat(v as ExportFormat)}>
198
+ <SelectTrigger id="export-format">
199
+ <SelectValue />
200
+ </SelectTrigger>
201
+ <SelectContent>
202
+ <SelectItem value="xlsx">{t("export-page.formats.xlsx")}</SelectItem>
203
+ <SelectItem value="csv">{t("export-page.formats.csv")}</SelectItem>
204
+ <SelectItem value="pdf_zip">{t("export-page.formats.pdf_zip")}</SelectItem>
205
+ </SelectContent>
206
+ </Select>
207
+ </div>
211
208
  </div>
209
+ {exportFormat === "pdf_zip" && (
210
+ <p className="text-muted-foreground text-sm">{t("export-page.pdf-export-info")}</p>
211
+ )}
212
212
 
213
213
  {/* Date Range */}
214
214
  <div className="grid grid-cols-2 gap-4">
@@ -29,9 +29,12 @@ import { DocumentItemsSection, type PriceModesMap } from "../../documents/create
29
29
  import { DocumentRecipientSection } from "../../documents/create/document-recipient-section";
30
30
  import { MarkAsPaidSection } from "../../documents/create/mark-as-paid-section";
31
31
  import type { DocumentTypes } from "../../documents/types";
32
+ import { useFinaPremises, useFinaSettings } from "../../entities/fina-settings-form/fina-settings.hooks";
32
33
  import { useFursPremises, useFursSettings } from "../../entities/furs-settings-form/furs-settings.hooks";
33
34
  import {
35
+ getLastUsedFinaCombo,
34
36
  getLastUsedFursCombo,
37
+ setLastUsedFinaCombo,
35
38
  setLastUsedFursCombo,
36
39
  useCreateInvoice,
37
40
  useNextInvoiceNumber,
@@ -137,6 +140,23 @@ export default function CreateInvoiceForm({
137
140
  const [selectedDeviceName, setSelectedDeviceName] = useState<string | undefined>();
138
141
  const [skipFiscalization, setSkipFiscalization] = useState(false);
139
142
 
143
+ // ============================================================================
144
+ // FINA Settings & Premises
145
+ // ============================================================================
146
+ const { data: finaSettings, isLoading: isFinaSettingsLoading } = useFinaSettings(entityId);
147
+ const { data: finaPremises, isLoading: isFinaPremisesLoading } = useFinaPremises(entityId, {
148
+ enabled: finaSettings?.enabled === true,
149
+ });
150
+
151
+ const isFinaLoading = isFinaSettingsLoading || (finaSettings?.enabled && isFinaPremisesLoading);
152
+ const isFinaEnabled = finaSettings?.enabled === true;
153
+ const activeFinaPremises = useMemo(() => finaPremises?.filter((p: any) => p.is_active) || [], [finaPremises]);
154
+ const hasFinaPremises = activeFinaPremises.length > 0;
155
+
156
+ // FINA premise/device selection state (no skip - all FINA invoices must be fiscalized)
157
+ const [selectedFinaPremiseId, setSelectedFinaPremiseId] = useState<string | undefined>();
158
+ const [selectedFinaDeviceId, setSelectedFinaDeviceId] = useState<string | undefined>();
159
+
140
160
  // UI-only state (not part of API schema)
141
161
  const [markAsPaid, setMarkAsPaid] = useState(false);
142
162
  const [paymentTypes, setPaymentTypes] = useState<string[]>(["bank_transfer"]);
@@ -232,6 +252,51 @@ export default function CreateInvoiceForm({
232
252
  }
233
253
  }, [selectedPremiseName, activePremises, selectedDeviceName]);
234
254
 
255
+ // Get active FINA devices for selected premise
256
+ const activeFinaDevices = useMemo(() => {
257
+ if (!selectedFinaPremiseId) return [];
258
+ const premise = activeFinaPremises.find((p: any) => p.premise_id === selectedFinaPremiseId);
259
+ return premise?.Devices?.filter((d: any) => d.is_active) || [];
260
+ }, [activeFinaPremises, selectedFinaPremiseId]);
261
+
262
+ // Initialize FINA selection from localStorage or first active combo
263
+ useEffect(() => {
264
+ if (!isFinaEnabled || !hasFinaPremises || selectedFinaPremiseId) return;
265
+
266
+ const lastUsed = getLastUsedFinaCombo(entityId);
267
+ if (lastUsed) {
268
+ const premise = activeFinaPremises.find((p: any) => p.premise_id === lastUsed.premise_id);
269
+ const device = premise?.Devices?.find((d: any) => d.device_id === lastUsed.device_id && d.is_active);
270
+ if (premise && device) {
271
+ setSelectedFinaPremiseId(lastUsed.premise_id);
272
+ setSelectedFinaDeviceId(lastUsed.device_id);
273
+ return;
274
+ }
275
+ }
276
+
277
+ const firstPremise = activeFinaPremises[0];
278
+ const firstDevice = firstPremise?.Devices?.find((d: any) => d.is_active);
279
+ if (firstPremise && firstDevice) {
280
+ setSelectedFinaPremiseId(firstPremise.premise_id);
281
+ setSelectedFinaDeviceId(firstDevice.device_id);
282
+ }
283
+ }, [isFinaEnabled, hasFinaPremises, activeFinaPremises, entityId, selectedFinaPremiseId]);
284
+
285
+ // When FINA premise changes, select first active device
286
+ useEffect(() => {
287
+ if (!selectedFinaPremiseId) return;
288
+ const premise = activeFinaPremises.find((p: any) => p.premise_id === selectedFinaPremiseId);
289
+ const firstDevice = premise?.Devices?.find((d: any) => d.is_active);
290
+ if (firstDevice && selectedFinaDeviceId !== firstDevice.device_id) {
291
+ const currentDeviceInPremise = premise?.Devices?.find(
292
+ (d: any) => d.device_id === selectedFinaDeviceId && d.is_active,
293
+ );
294
+ if (!currentDeviceInPremise) {
295
+ setSelectedFinaDeviceId(firstDevice.device_id);
296
+ }
297
+ }
298
+ }, [selectedFinaPremiseId, activeFinaPremises, selectedFinaDeviceId]);
299
+
235
300
  const form = useForm<CreateInvoiceFormValues>({
236
301
  // Cast resolver to accept extended form type (includes UI-only fields)
237
302
  resolver: zodResolver(createInvoiceSchema) as Resolver<CreateInvoiceFormValues>,
@@ -291,6 +356,11 @@ export default function CreateInvoiceForm({
291
356
  const isFursActive =
292
357
  isFursEnabled && hasFursPremises && selectedPremiseName && selectedDeviceName && !skipFiscalization;
293
358
 
359
+ // FINA selection ready and active checks
360
+ const isFinaSelectionReady =
361
+ !isFinaEnabled || !hasFinaPremises || (!!selectedFinaPremiseId && !!selectedFinaDeviceId);
362
+ const isFinaActive = isFinaEnabled && hasFinaPremises && selectedFinaPremiseId && selectedFinaDeviceId;
363
+
294
364
  // ============================================================================
295
365
  // Next Invoice Number Preview
296
366
  // ============================================================================
@@ -299,20 +369,21 @@ export default function CreateInvoiceForm({
299
369
  const { data: nextNumberData, isLoading: isNextNumberLoading } = useNextInvoiceNumber(entityId, {
300
370
  business_premise_name: isFursActive ? selectedPremiseName : undefined,
301
371
  electronic_device_name: isFursActive ? selectedDeviceName : undefined,
302
- enabled: !!entityId && !isFursLoading && isFursSelectionReady && !isEditMode,
372
+ enabled:
373
+ !!entityId && !isFursLoading && isFursSelectionReady && !isFinaLoading && isFinaSelectionReady && !isEditMode,
303
374
  });
304
375
 
305
- // Overall loading state - wait until we have FURS data, selection ready, and next number (only in create mode)
376
+ // Overall loading state - wait until we have FURS/FINA data, selection ready, and next number (only in create mode)
306
377
  const isFormDataLoading = isEditMode
307
378
  ? false // In edit mode, don't wait for next number
308
- : isFursLoading || !isFursSelectionReady || isNextNumberLoading;
379
+ : isFursLoading || !isFursSelectionReady || isFinaLoading || !isFinaSelectionReady || isNextNumberLoading;
309
380
 
310
381
  // Update header action with FURS and e-SLOG toggle buttons
311
382
  useEffect(() => {
312
383
  if (!onHeaderActionChange) return;
313
384
 
314
- // Don't set header action while loading or in edit mode (FURS/e-SLOG not editable)
315
- if (isFursLoading || isEditMode) {
385
+ // Don't set header action while loading or in edit mode (FURS/FINA/e-SLOG not editable)
386
+ if (isFursLoading || isFinaLoading || isEditMode) {
316
387
  onHeaderActionChange(null);
317
388
  return;
318
389
  }
@@ -406,6 +477,7 @@ export default function CreateInvoiceForm({
406
477
  }
407
478
  }, [
408
479
  isFursLoading,
480
+ isFinaLoading,
409
481
  isFursEnabled,
410
482
  hasFursPremises,
411
483
  skipFiscalization,
@@ -469,6 +541,13 @@ export default function CreateInvoiceForm({
469
541
  electronic_device_name: selectedDeviceName,
470
542
  });
471
543
  }
544
+ // Save FINA combo to localStorage on successful creation
545
+ if (isFinaActive && selectedFinaPremiseId && selectedFinaDeviceId) {
546
+ setLastUsedFinaCombo(entityId, {
547
+ premise_id: selectedFinaPremiseId,
548
+ device_id: selectedFinaDeviceId,
549
+ });
550
+ }
472
551
  // Invalidate customers cache when a customer was created/linked
473
552
  // This ensures the new customer appears in autocomplete for future documents
474
553
  if (data.customer_id) {
@@ -527,6 +606,12 @@ export default function CreateInvoiceForm({
527
606
  : undefined
528
607
  : undefined;
529
608
 
609
+ // Build FINA options (skip for drafts and edit mode; FINA can't be skipped)
610
+ const finaOptions =
611
+ !isDraft && !isEditMode && isFinaEnabled && selectedFinaPremiseId && selectedFinaDeviceId
612
+ ? { premise_id: selectedFinaPremiseId, device_id: selectedFinaDeviceId, payment_type: paymentTypes[0] }
613
+ : undefined;
614
+
530
615
  // Build e-SLOG options (skip for drafts and edit mode)
531
616
  const eslogOptions =
532
617
  !isDraft && !isEditMode && isEslogAvailable
@@ -539,6 +624,7 @@ export default function CreateInvoiceForm({
539
624
  markAsPaid: isDraft || isEditMode ? false : markAsPaid,
540
625
  paymentTypes,
541
626
  furs: fursOptions,
627
+ fina: finaOptions,
542
628
  eslog: eslogOptions,
543
629
  priceModes: priceModesRef.current,
544
630
  isDraft,
@@ -563,11 +649,14 @@ export default function CreateInvoiceForm({
563
649
  isEditMode,
564
650
  isEslogAvailable,
565
651
  isFursEnabled,
652
+ isFinaEnabled,
566
653
  markAsPaid,
567
654
  originalCustomer,
568
655
  paymentTypes,
569
656
  selectedDeviceName,
570
657
  selectedPremiseName,
658
+ selectedFinaPremiseId,
659
+ selectedFinaDeviceId,
571
660
  showCustomerForm,
572
661
  skipFiscalization,
573
662
  ],
@@ -798,6 +887,18 @@ export default function CreateInvoiceForm({
798
887
  }
799
888
  : undefined
800
889
  }
890
+ finaInline={
891
+ !isEditMode && isFinaEnabled && hasFinaPremises
892
+ ? {
893
+ premises: activeFinaPremises.map((p: any) => ({ id: p.id, premise_id: p.premise_id })),
894
+ devices: activeFinaDevices.map((d: any) => ({ id: d.id, device_id: d.device_id })),
895
+ selectedPremise: selectedFinaPremiseId,
896
+ selectedDevice: selectedFinaDeviceId,
897
+ onPremiseChange: setSelectedFinaPremiseId,
898
+ onDeviceChange: setSelectedFinaDeviceId,
899
+ }
900
+ : undefined
901
+ }
801
902
  serviceDate={{
802
903
  dateType: serviceDateType,
803
904
  onDateTypeChange: setServiceDateType,
@@ -812,6 +913,7 @@ export default function CreateInvoiceForm({
812
913
  paymentTypes={paymentTypes}
813
914
  onPaymentTypesChange={setPaymentTypes}
814
915
  t={t}
916
+ alwaysShowPaymentType={!!isFinaActive}
815
917
  />
816
918
  )}
817
919
  </DocumentDetailsSection>
@@ -8,6 +8,12 @@ type FursData = {
8
8
  skip?: boolean;
9
9
  };
10
10
 
11
+ type FinaData = {
12
+ premise_id?: string;
13
+ device_id?: string;
14
+ payment_type?: string;
15
+ };
16
+
11
17
  type EslogData = {
12
18
  validation_enabled?: boolean;
13
19
  };
@@ -22,6 +28,8 @@ type PrepareOptions = {
22
28
  paymentTypes?: string[];
23
29
  /** FURS fiscalization data (for Slovenia) */
24
30
  furs?: FursData;
31
+ /** FINA fiscalization data (for Croatia) */
32
+ fina?: FinaData;
25
33
  /** e-SLOG validation data (for Slovenia) */
26
34
  eslog?: EslogData;
27
35
  /** Map of item index to gross price mode (collected from component state) */
@@ -68,6 +76,15 @@ export function prepareInvoiceSubmission(values: CreateInvoiceSchema, options: P
68
76
  }
69
77
  }
70
78
 
79
+ // Add FINA data if provided (FINA can't be skipped - all invoices must be fiscalized)
80
+ if (options.fina?.premise_id && options.fina.device_id) {
81
+ (payload as any).fina = {
82
+ premise_id: options.fina.premise_id,
83
+ device_id: options.fina.device_id,
84
+ ...(options.fina.payment_type && { payment_type: options.fina.payment_type }),
85
+ };
86
+ }
87
+
71
88
  // Add e-SLOG data if provided
72
89
  if (options.eslog !== undefined) {
73
90
  (payload as any).eslog = {
@@ -1,28 +1,43 @@
1
1
  import { useMutation, useQueryClient } from "@tanstack/react-query";
2
2
  import { useSDK } from "@/ui/providers/sdk-provider";
3
3
 
4
- interface VoidInvoiceParams {
5
- invoiceId: string;
4
+ interface VoidDocumentParams {
5
+ documentId: string;
6
+ documentType: "invoice" | "credit_note" | "advance_invoice";
6
7
  entityId: string;
7
8
  reason?: string;
8
9
  }
9
10
 
10
11
  /**
11
- * Hook to void an invoice
12
- * Automatically handles FURS technical cancellation for fiscalized invoices
12
+ * Hook to void a document (invoice, credit note, or advance invoice)
13
+ * Automatically handles FURS/FINA technical cancellation for fiscalized documents
13
14
  */
14
- export function useVoidInvoice() {
15
+ export function useVoidDocument() {
15
16
  const { sdk } = useSDK();
16
17
  const queryClient = useQueryClient();
17
18
 
18
19
  return useMutation({
19
- mutationFn: async ({ invoiceId, entityId, reason }: VoidInvoiceParams) => {
20
- return sdk.invoices.void(invoiceId, { reason: reason || undefined }, { entity_id: entityId });
20
+ mutationFn: async ({ documentId, documentType, entityId, reason }: VoidDocumentParams) => {
21
+ const body = { reason: reason || undefined };
22
+ const opts = { entity_id: entityId };
23
+
24
+ switch (documentType) {
25
+ case "invoice":
26
+ return sdk.invoices.void(documentId, body, opts);
27
+ case "credit_note":
28
+ return sdk.creditNotes.void(documentId, body, opts);
29
+ case "advance_invoice":
30
+ return sdk.advanceInvoices.void(documentId, body, opts);
31
+ }
21
32
  },
22
33
  onSuccess: (_, variables) => {
23
- // Invalidate invoice queries to refresh the data
24
34
  queryClient.invalidateQueries({ queryKey: ["invoices"] });
25
- queryClient.invalidateQueries({ queryKey: ["documents", "invoice", variables.invoiceId] });
35
+ queryClient.invalidateQueries({ queryKey: ["credit-notes"] });
36
+ queryClient.invalidateQueries({ queryKey: ["advance-invoices"] });
37
+ queryClient.invalidateQueries({ queryKey: ["documents", variables.documentType, variables.documentId] });
26
38
  },
27
39
  });
28
40
  }
41
+
42
+ /** @deprecated Use useVoidDocument instead */
43
+ export const useVoidInvoice = useVoidDocument;
@@ -1,4 +1,4 @@
1
- import type { CreateInvoice201, CreateInvoiceBody } from "@spaceinvoices/js-sdk";
1
+ import type { CreateInvoice, Invoice } from "@spaceinvoices/js-sdk";
2
2
  import { useQuery } from "@tanstack/react-query";
3
3
 
4
4
  import { createResourceHooks } from "@/ui/hooks/create-resource-hooks";
@@ -13,7 +13,7 @@ const {
13
13
  useCreateResource: useCreateInvoice,
14
14
  useUpdateResource: useUpdateInvoice,
15
15
  useDeleteResource: useDeleteInvoice,
16
- } = createResourceHooks<CreateInvoice201, CreateInvoiceBody>("invoices", INVOICES_CACHE_KEY);
16
+ } = createResourceHooks<Invoice, CreateInvoice>("invoices", INVOICES_CACHE_KEY);
17
17
 
18
18
  export { useCreateInvoice, useUpdateInvoice, useDeleteInvoice };
19
19
 
@@ -108,3 +108,33 @@ export function setLastUsedFursCombo(entityId: string, combo: FursCombo): void {
108
108
  // Ignore localStorage errors (quota exceeded, etc.)
109
109
  }
110
110
  }
111
+
112
+ // ============================================================================
113
+ // FINA Last-Used Combo (localStorage)
114
+ // ============================================================================
115
+
116
+ const FINA_LAST_USED_KEY = "hr:fina:last-used";
117
+
118
+ export type FinaCombo = {
119
+ premise_id: string;
120
+ device_id: string;
121
+ };
122
+
123
+ export function getLastUsedFinaCombo(entityId: string): FinaCombo | null {
124
+ if (typeof window === "undefined") return null;
125
+ try {
126
+ const stored = localStorage.getItem(`${FINA_LAST_USED_KEY}:${entityId}`);
127
+ return stored ? JSON.parse(stored) : null;
128
+ } catch {
129
+ return null;
130
+ }
131
+ }
132
+
133
+ export function setLastUsedFinaCombo(entityId: string, combo: FinaCombo): void {
134
+ if (typeof window === "undefined") return;
135
+ try {
136
+ localStorage.setItem(`${FINA_LAST_USED_KEY}:${entityId}`, JSON.stringify(combo));
137
+ } catch {
138
+ // Ignore localStorage errors (quota exceeded, etc.)
139
+ }
140
+ }
@@ -1,7 +1,7 @@
1
1
  import type { Invoice } from "@spaceinvoices/js-sdk";
2
2
 
3
- import { Copy, Download, Eye, Link2Off, Loader2, Mail, MoreHorizontal, Plus } from "lucide-react";
4
- import { useState } from "react";
3
+ import { Ban, Copy, Download, Eye, Link2Off, Loader2, Mail, MoreHorizontal, Plus } from "lucide-react";
4
+ import { memo, useState } from "react";
5
5
  import { Button } from "@/ui/components/ui/button";
6
6
  import {
7
7
  DropdownMenu,
@@ -19,6 +19,7 @@ import { useInvoiceDownload } from "./use-invoice-download";
19
19
 
20
20
  type InvoiceListRowActionsProps = {
21
21
  invoice: Invoice;
22
+ onView?: (invoice: Invoice) => void;
22
23
  onAddPayment?: (invoice: Invoice) => void;
23
24
  onDuplicate?: (invoice: Invoice) => void;
24
25
  onDownloadStart?: () => void;
@@ -26,10 +27,13 @@ type InvoiceListRowActionsProps = {
26
27
  onDownloadError?: (error: string) => void;
27
28
  onUnshare?: (invoice: Invoice) => Promise<void>;
28
29
  isUnsharing?: boolean;
30
+ onVoid?: (invoice: Invoice) => void;
31
+ isVoiding?: boolean;
29
32
  } & ComponentTranslationProps;
30
33
 
31
- export default function InvoiceListRowActions({
34
+ export default memo(function InvoiceListRowActions({
32
35
  invoice,
36
+ onView,
33
37
  onAddPayment,
34
38
  onDuplicate,
35
39
  onDownloadStart,
@@ -37,6 +41,8 @@ export default function InvoiceListRowActions({
37
41
  onDownloadError,
38
42
  onUnshare,
39
43
  isUnsharing,
44
+ onVoid,
45
+ isVoiding,
40
46
  ...i18nProps
41
47
  }: InvoiceListRowActionsProps) {
42
48
  const t = createTranslation(i18nProps);
@@ -67,13 +73,7 @@ export default function InvoiceListRowActions({
67
73
  </DropdownMenuGroup>
68
74
  <DropdownMenuSeparator />
69
75
  <DropdownMenuGroup>
70
- <DropdownMenuItem
71
- className="cursor-pointer"
72
- onClick={() => {
73
- // TODO: Use router
74
- window.location.href = `/app/documents/view/${invoice.id}`;
75
- }}
76
- >
76
+ <DropdownMenuItem className="cursor-pointer" onClick={() => onView?.(invoice)}>
77
77
  <Eye className="h-4 w-4" />
78
78
  {t("View invoice")}
79
79
  </DropdownMenuItem>
@@ -118,6 +118,21 @@ export default function InvoiceListRowActions({
118
118
  </DropdownMenuGroup>
119
119
  </>
120
120
  )}
121
+ {onVoid && !invoice.voided_at && !(invoice as any).is_draft && (
122
+ <>
123
+ <DropdownMenuSeparator />
124
+ <DropdownMenuGroup>
125
+ <DropdownMenuItem
126
+ className="cursor-pointer text-destructive focus:text-destructive"
127
+ onClick={() => onVoid(invoice)}
128
+ disabled={isVoiding}
129
+ >
130
+ {isVoiding ? <Loader2 className="h-4 w-4 animate-spin" /> : <Ban className="h-4 w-4" />}
131
+ {t("Void")}
132
+ </DropdownMenuItem>
133
+ </DropdownMenuGroup>
134
+ </>
135
+ )}
121
136
  </DropdownMenuContent>
122
137
  </DropdownMenu>
123
138
  <SendEmailDialog
@@ -129,4 +144,4 @@ export default function InvoiceListRowActions({
129
144
  />
130
145
  </>
131
146
  );
132
- }
147
+ });