@spaceinvoices/react-ui 0.4.4 → 0.4.5

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 (147) hide show
  1. package/cli/dist/index.js +1 -1
  2. package/package.json +1 -1
  3. package/src/components/advance-invoices/create/create-advance-invoice-form.tsx +61 -11
  4. package/src/components/advance-invoices/create/locales/de.ts +15 -0
  5. package/src/components/advance-invoices/create/locales/es.ts +15 -0
  6. package/src/components/advance-invoices/create/locales/fr.ts +15 -0
  7. package/src/components/advance-invoices/create/locales/hr.ts +15 -0
  8. package/src/components/advance-invoices/create/locales/it.ts +15 -0
  9. package/src/components/advance-invoices/create/locales/nl.ts +15 -0
  10. package/src/components/advance-invoices/create/locales/pl.ts +15 -0
  11. package/src/components/advance-invoices/create/locales/pt.ts +15 -0
  12. package/src/components/advance-invoices/create/locales/sl.ts +15 -0
  13. package/src/components/advance-invoices/list/list-row-actions.tsx +48 -1
  14. package/src/components/advance-invoices/list/list-table.tsx +21 -1
  15. package/src/components/advance-invoices/list/locales/de.ts +4 -0
  16. package/src/components/advance-invoices/list/locales/en.ts +3 -0
  17. package/src/components/advance-invoices/list/locales/es.ts +4 -0
  18. package/src/components/advance-invoices/list/locales/fr.ts +4 -0
  19. package/src/components/advance-invoices/list/locales/hr.ts +3 -0
  20. package/src/components/advance-invoices/list/locales/it.ts +4 -0
  21. package/src/components/advance-invoices/list/locales/nl.ts +4 -0
  22. package/src/components/advance-invoices/list/locales/pl.ts +3 -0
  23. package/src/components/advance-invoices/list/locales/pt.ts +4 -0
  24. package/src/components/advance-invoices/list/locales/sl.ts +3 -0
  25. package/src/components/credit-notes/create/create-credit-note-form.tsx +71 -8
  26. package/src/components/credit-notes/create/locales/de.ts +16 -0
  27. package/src/components/credit-notes/create/locales/es.ts +16 -0
  28. package/src/components/credit-notes/create/locales/fr.ts +16 -0
  29. package/src/components/credit-notes/create/locales/hr.ts +16 -0
  30. package/src/components/credit-notes/create/locales/it.ts +16 -0
  31. package/src/components/credit-notes/create/locales/nl.ts +16 -0
  32. package/src/components/credit-notes/create/locales/pl.ts +16 -0
  33. package/src/components/credit-notes/create/locales/pt.ts +16 -0
  34. package/src/components/credit-notes/create/locales/sl.ts +17 -1
  35. package/src/components/credit-notes/list/list-row-actions.tsx +44 -1
  36. package/src/components/credit-notes/list/list-table.tsx +16 -2
  37. package/src/components/credit-notes/list/locales/de.ts +2 -0
  38. package/src/components/credit-notes/list/locales/en.ts +2 -0
  39. package/src/components/credit-notes/list/locales/es.ts +2 -0
  40. package/src/components/credit-notes/list/locales/fr.ts +2 -0
  41. package/src/components/credit-notes/list/locales/hr.ts +2 -0
  42. package/src/components/credit-notes/list/locales/it.ts +2 -0
  43. package/src/components/credit-notes/list/locales/nl.ts +2 -0
  44. package/src/components/credit-notes/list/locales/pl.ts +2 -0
  45. package/src/components/credit-notes/list/locales/pt.ts +2 -0
  46. package/src/components/credit-notes/list/locales/sl.ts +2 -0
  47. package/src/components/dashboard/collection-rate-card/use-collection-rate.ts +48 -9
  48. package/src/components/dashboard/revenue-trend-chart/use-revenue-trend.ts +77 -48
  49. package/src/components/dashboard/shared/use-revenue-data.ts +77 -9
  50. package/src/components/delivery-notes/create/create-delivery-note-form.tsx +67 -7
  51. package/src/components/delivery-notes/create/locales/de.ts +16 -0
  52. package/src/components/delivery-notes/create/locales/es.ts +16 -0
  53. package/src/components/delivery-notes/create/locales/fr.ts +16 -0
  54. package/src/components/delivery-notes/create/locales/hr.ts +16 -0
  55. package/src/components/delivery-notes/create/locales/it.ts +16 -0
  56. package/src/components/delivery-notes/create/locales/nl.ts +16 -0
  57. package/src/components/delivery-notes/create/locales/pl.ts +16 -0
  58. package/src/components/delivery-notes/create/locales/pt.ts +16 -0
  59. package/src/components/delivery-notes/create/locales/sl.ts +17 -1
  60. package/src/components/delivery-notes/list/list-table.tsx +17 -8
  61. package/src/components/delivery-notes/list/locales/de.ts +32 -1
  62. package/src/components/delivery-notes/list/locales/en.ts +31 -0
  63. package/src/components/delivery-notes/list/locales/es.ts +32 -1
  64. package/src/components/delivery-notes/list/locales/fr.ts +32 -1
  65. package/src/components/delivery-notes/list/locales/hr.ts +32 -1
  66. package/src/components/delivery-notes/list/locales/it.ts +32 -1
  67. package/src/components/delivery-notes/list/locales/nl.ts +32 -1
  68. package/src/components/delivery-notes/list/locales/pl.ts +32 -1
  69. package/src/components/delivery-notes/list/locales/pt.ts +32 -1
  70. package/src/components/delivery-notes/list/locales/sl.ts +32 -1
  71. package/src/components/documents/create/document-add-item-form.tsx +70 -0
  72. package/src/components/documents/create/document-details-section.tsx +122 -2
  73. package/src/components/documents/create/document-items-section.tsx +21 -4
  74. package/src/components/documents/create/live-preview.tsx +24 -4
  75. package/src/components/documents/create/mark-as-paid-section.tsx +29 -20
  76. package/src/components/documents/create/prepare-document-submission.ts +19 -7
  77. package/src/components/documents/shared/document-preview-display.tsx +3 -4
  78. package/src/components/documents/view/document-actions-bar.tsx +7 -27
  79. package/src/components/documents/view/document-details-card.tsx +26 -9
  80. package/src/components/documents/view/locales/de.ts +2 -0
  81. package/src/components/documents/view/locales/es.ts +2 -0
  82. package/src/components/documents/view/locales/fr.ts +2 -0
  83. package/src/components/documents/view/locales/hr.ts +2 -0
  84. package/src/components/documents/view/locales/it.ts +2 -0
  85. package/src/components/documents/view/locales/nl.ts +2 -0
  86. package/src/components/documents/view/locales/pl.ts +2 -0
  87. package/src/components/documents/view/locales/pt.ts +2 -0
  88. package/src/components/documents/view/locales/sl.ts +3 -1
  89. package/src/components/documents/view/use-document-download.ts +6 -3
  90. package/src/components/entities/create-entity-form.tsx +2 -1
  91. package/src/components/entities/entity-settings-form/input-with-preview.tsx +30 -2
  92. package/src/components/entities/entity-settings-form/locales/de.ts +1 -0
  93. package/src/components/entities/entity-settings-form/locales/es.ts +1 -0
  94. package/src/components/entities/entity-settings-form/locales/fr.ts +1 -0
  95. package/src/components/entities/entity-settings-form/locales/hr.ts +1 -0
  96. package/src/components/entities/entity-settings-form/locales/it.ts +1 -0
  97. package/src/components/entities/entity-settings-form/locales/nl.ts +1 -0
  98. package/src/components/entities/entity-settings-form/locales/pl.ts +1 -0
  99. package/src/components/entities/entity-settings-form/locales/pt.ts +1 -0
  100. package/src/components/entities/entity-settings-form/locales/sl.ts +1 -0
  101. package/src/components/entities/settings/company-settings-form.tsx +173 -20
  102. package/src/components/estimates/create/create-estimate-form.tsx +64 -6
  103. package/src/components/estimates/create/locales/de.ts +16 -0
  104. package/src/components/estimates/create/locales/es.ts +16 -0
  105. package/src/components/estimates/create/locales/fr.ts +16 -0
  106. package/src/components/estimates/create/locales/hr.ts +16 -0
  107. package/src/components/estimates/create/locales/it.ts +16 -0
  108. package/src/components/estimates/create/locales/nl.ts +16 -0
  109. package/src/components/estimates/create/locales/pl.ts +16 -0
  110. package/src/components/estimates/create/locales/pt.ts +16 -0
  111. package/src/components/estimates/create/locales/sl.ts +17 -1
  112. package/src/components/estimates/list/list-table.tsx +11 -2
  113. package/src/components/estimates/list/locales/de.ts +1 -0
  114. package/src/components/estimates/list/locales/en.ts +1 -0
  115. package/src/components/estimates/list/locales/es.ts +1 -0
  116. package/src/components/estimates/list/locales/fr.ts +1 -0
  117. package/src/components/estimates/list/locales/hr.ts +1 -0
  118. package/src/components/estimates/list/locales/it.ts +1 -0
  119. package/src/components/estimates/list/locales/nl.ts +1 -0
  120. package/src/components/estimates/list/locales/pl.ts +1 -0
  121. package/src/components/estimates/list/locales/pt.ts +1 -0
  122. package/src/components/estimates/list/locales/sl.ts +1 -0
  123. package/src/components/export/document-export-form.tsx +46 -12
  124. package/src/components/invoices/create/create-invoice-form.tsx +58 -10
  125. package/src/components/invoices/create/locales/de.ts +15 -0
  126. package/src/components/invoices/create/locales/es.ts +15 -0
  127. package/src/components/invoices/create/locales/fr.ts +15 -0
  128. package/src/components/invoices/create/locales/hr.ts +15 -0
  129. package/src/components/invoices/create/locales/it.ts +15 -0
  130. package/src/components/invoices/create/locales/nl.ts +15 -0
  131. package/src/components/invoices/create/locales/pl.ts +15 -0
  132. package/src/components/invoices/create/locales/pt.ts +15 -0
  133. package/src/components/invoices/create/locales/sl.ts +16 -1
  134. package/src/components/invoices/view/fiscalization-status-card.tsx +10 -8
  135. package/src/components/table/search-input.tsx +17 -0
  136. package/src/generated/schemas/advanceinvoice.ts +4 -2
  137. package/src/generated/schemas/creditnote.ts +2 -1
  138. package/src/generated/schemas/deliverynote.ts +2 -1
  139. package/src/generated/schemas/estimate.ts +4 -2
  140. package/src/generated/schemas/invoice.ts +2 -1
  141. package/src/generated/schemas/renderadvanceinvoicepreview_body.ts +17 -23
  142. package/src/generated/schemas/rendercreditnotepreview_body.ts +17 -23
  143. package/src/generated/schemas/renderdeliverynotepreview_body.ts +17 -23
  144. package/src/generated/schemas/renderestimatepreview_body.ts +17 -23
  145. package/src/generated/schemas/renderinvoicepreview_body.ts +19 -23
  146. package/src/hooks/use-duplicate-document.ts +16 -9
  147. package/src/hooks/use-vies-check.ts +3 -0
@@ -54,4 +54,20 @@ export default {
54
54
  "Net price": "Prezzo netto",
55
55
  "Gross price (tax included)": "Prezzo lordo (imposte incluse)",
56
56
  "Net price (before tax)": "Prezzo netto (prima delle imposte)",
57
+ // Separator items
58
+ "Add separator": "Aggiungi separatore",
59
+ "Section header": "Intestazione sezione",
60
+ "Section title...": "Titolo sezione...",
61
+ // Transaction type
62
+ "Transaction type": "Tipo di transazione",
63
+ Domestic: "Nazionale",
64
+ "EU B2B": "EU B2B",
65
+ "EU B2C": "EU B2C",
66
+ Export: "Esportazione",
67
+ "Determining transaction type...": "Determinazione tipo di transazione...",
68
+ "This invoice will not be fiscalized (non-domestic transaction)":
69
+ "Questa fattura non sarà fiscalizzata (transazione non nazionale)",
70
+ "Tax Clause": "Clausola fiscale",
71
+ "Add tax clause...": "Aggiungi clausola fiscale...",
72
+ "Reverse charge - tax exempt EU B2B sale": "Inversione contabile - vendita B2B UE esente da imposta",
57
73
  } as const;
@@ -55,4 +55,20 @@ export default {
55
55
  "Net price": "Nettoprijs",
56
56
  "Gross price (tax included)": "Brutoprijs (inclusief belasting)",
57
57
  "Net price (before tax)": "Nettoprijs (exclusief belasting)",
58
+ // Separator items
59
+ "Add separator": "Scheidingslijn toevoegen",
60
+ "Section header": "Sectiekop",
61
+ "Section title...": "Sectietitel...",
62
+ // Transaction type
63
+ "Transaction type": "Transactietype",
64
+ Domestic: "Binnenland",
65
+ "EU B2B": "EU B2B",
66
+ "EU B2C": "EU B2C",
67
+ Export: "Export",
68
+ "Determining transaction type...": "Transactietype bepalen...",
69
+ "This invoice will not be fiscalized (non-domestic transaction)":
70
+ "Deze factuur wordt niet gefiscaliseerd (niet-binnenlandse transactie)",
71
+ "Tax Clause": "Belastingclausule",
72
+ "Add tax clause...": "Belastingclausule toevoegen...",
73
+ "Reverse charge - tax exempt EU B2B sale": "Verlegging - belastingvrijgestelde EU B2B verkoop",
58
74
  } as const;
@@ -54,4 +54,20 @@ export default {
54
54
  "Net price": "Cena netto",
55
55
  "Gross price (tax included)": "Cena brutto (z podatkiem)",
56
56
  "Net price (before tax)": "Cena netto (przed podatkiem)",
57
+ // Separator items
58
+ "Add separator": "Dodaj separator",
59
+ "Section header": "Nagłówek sekcji",
60
+ "Section title...": "Tytuł sekcji...",
61
+ // Transaction type
62
+ "Transaction type": "Typ transakcji",
63
+ Domestic: "Krajowa",
64
+ "EU B2B": "EU B2B",
65
+ "EU B2C": "EU B2C",
66
+ Export: "Eksport",
67
+ "Determining transaction type...": "Określanie typu transakcji...",
68
+ "This invoice will not be fiscalized (non-domestic transaction)":
69
+ "Ta faktura nie będzie fiskalizowana (transakcja niekrajowa)",
70
+ "Tax Clause": "Klauzula podatkowa",
71
+ "Add tax clause...": "Dodaj klauzulę podatkową...",
72
+ "Reverse charge - tax exempt EU B2B sale": "Odwrotne obciążenie - zwolniona z podatku sprzedaż EU B2B",
57
73
  } as const;
@@ -55,4 +55,20 @@ export default {
55
55
  "Net price": "Preço líquido",
56
56
  "Gross price (tax included)": "Preço bruto (impostos incluídos)",
57
57
  "Net price (before tax)": "Preço líquido (antes de impostos)",
58
+ // Separator items
59
+ "Add separator": "Adicionar separador",
60
+ "Section header": "Cabeçalho da secção",
61
+ "Section title...": "Título da secção...",
62
+ // Transaction type
63
+ "Transaction type": "Tipo de transação",
64
+ Domestic: "Nacional",
65
+ "EU B2B": "EU B2B",
66
+ "EU B2C": "EU B2C",
67
+ Export: "Exportação",
68
+ "Determining transaction type...": "Determinando tipo de transação...",
69
+ "This invoice will not be fiscalized (non-domestic transaction)":
70
+ "Esta fatura não será fiscalizada (transação não nacional)",
71
+ "Tax Clause": "Cláusula fiscal",
72
+ "Add tax clause...": "Adicionar cláusula fiscal...",
73
+ "Reverse charge - tax exempt EU B2B sale": "Autoliquidação - venda B2B UE isenta de imposto",
58
74
  } as const;
@@ -23,7 +23,7 @@ export default {
23
23
  "Tax Number": "Davčna številka",
24
24
  Items: "Postavke",
25
25
  "Add item": "Dodaj postavko",
26
- Tax: "Davek",
26
+ Tax: "DDV",
27
27
  "Tax rate": "Davčna stopnja",
28
28
  "Add tax": "Dodaj davek",
29
29
  "Select tax...": "Izberi davek...",
@@ -60,4 +60,20 @@ export default {
60
60
  "Net price": "Neto cena",
61
61
  "Gross price (tax included)": "Bruto cena (z davkom)",
62
62
  "Net price (before tax)": "Neto cena (brez davka)",
63
+ // Separator items
64
+ "Add separator": "Dodaj ločilnik",
65
+ "Section header": "Naslov razdelka",
66
+ "Section title...": "Naslov razdelka...",
67
+ // Transaction type
68
+ "Transaction type": "Vrsta transakcije",
69
+ Domestic: "Domača",
70
+ "EU B2B": "EU B2B",
71
+ "EU B2C": "EU B2C",
72
+ Export: "Izvoz",
73
+ "Determining transaction type...": "Določanje vrste transakcije...",
74
+ "This invoice will not be fiscalized (non-domestic transaction)":
75
+ "Ta račun ne bo fiskaliziran (nedomača transakcija)",
76
+ "Tax Clause": "Davčna klavzula",
77
+ "Add tax clause...": "Dodajte davčno klavzulo...",
78
+ "Reverse charge - tax exempt EU B2B sale": "Obrnjena davčna obveznost - davka oproščena EU B2B prodaja",
63
79
  } as const;
@@ -52,6 +52,7 @@ type EstimateListTableProps = {
52
52
  onDownloadSuccess?: (fileName: string) => void;
53
53
  onDownloadError?: (error: string) => void;
54
54
  onExportSelected?: (documentIds: string[]) => void;
55
+ onCopyToInvoice?: (documentIds: string[]) => void;
55
56
  onCreateNew?: () => void;
56
57
  } & ListTableProps<Estimate>;
57
58
 
@@ -66,6 +67,7 @@ export default function EstimateListTable({
66
67
  onDownloadSuccess,
67
68
  onDownloadError,
68
69
  onExportSelected,
70
+ onCopyToInvoice,
69
71
  onCreateNew,
70
72
  ...i18nProps
71
73
  }: EstimateListTableProps) {
@@ -110,6 +112,12 @@ export default function EstimateListTable({
110
112
  }
111
113
  }, [selectedIds, onExportSelected]);
112
114
 
115
+ const handleCopyToInvoice = useCallback(() => {
116
+ if (selectedIds.size > 0 && onCopyToInvoice) {
117
+ onCopyToInvoice(Array.from(selectedIds));
118
+ }
119
+ }, [selectedIds, onCopyToInvoice]);
120
+
113
121
  const handleDeselectAll = useCallback(() => {
114
122
  setSelectedIds(new Set());
115
123
  }, []);
@@ -119,11 +127,12 @@ export default function EstimateListTable({
119
127
  <SelectionToolbar
120
128
  selectedCount={count}
121
129
  onExportPdfs={onExportSelected ? handleExportPdfs : undefined}
130
+ onCopyToInvoice={onCopyToInvoice ? handleCopyToInvoice : undefined}
122
131
  onDeselectAll={handleDeselectAll}
123
132
  t={t}
124
133
  />
125
134
  ),
126
- [handleExportPdfs, handleDeselectAll, onExportSelected, t],
135
+ [handleExportPdfs, handleCopyToInvoice, handleDeselectAll, onExportSelected, onCopyToInvoice, t],
127
136
  );
128
137
 
129
138
  const columns: Column<Estimate>[] = useMemo(
@@ -209,7 +218,7 @@ export default function EstimateListTable({
209
218
  filterConfig={filterConfig}
210
219
  t={t}
211
220
  locale={i18nProps.locale}
212
- selectable={!!onExportSelected}
221
+ selectable={!!(onExportSelected || onCopyToInvoice)}
213
222
  selectedIds={selectedIds}
214
223
  onSelectionChange={setSelectedIds}
215
224
  selectionToolbar={selectionToolbar}
@@ -36,4 +36,5 @@ export default {
36
36
  selected: "ausgewählt",
37
37
  "Export PDFs": "PDFs exportieren",
38
38
  "Deselect all": "Auswahl aufheben",
39
+ "Copy to Invoice": "In Rechnung kopieren",
39
40
  } as const;
@@ -8,4 +8,5 @@ export default {
8
8
  selected: "selected",
9
9
  "Export PDFs": "Export PDFs",
10
10
  "Deselect all": "Deselect all",
11
+ "Copy to Invoice": "Copy to Invoice",
11
12
  } as const;
@@ -33,4 +33,5 @@ export default {
33
33
  selected: "seleccionados",
34
34
  "Export PDFs": "Exportar PDFs",
35
35
  "Deselect all": "Deseleccionar todo",
36
+ "Copy to Invoice": "Copiar a factura",
36
37
  } as const;
@@ -33,4 +33,5 @@ export default {
33
33
  selected: "sélectionnés",
34
34
  "Export PDFs": "Exporter les PDF",
35
35
  "Deselect all": "Tout désélectionner",
36
+ "Copy to Invoice": "Copier vers facture",
36
37
  } as const;
@@ -33,4 +33,5 @@ export default {
33
33
  selected: "odabranih",
34
34
  "Export PDFs": "Izvezi PDF-ove",
35
35
  "Deselect all": "Poništi odabir",
36
+ "Copy to Invoice": "Kopiraj u račun",
36
37
  } as const;
@@ -33,4 +33,5 @@ export default {
33
33
  selected: "selezionati",
34
34
  "Export PDFs": "Esporta PDF",
35
35
  "Deselect all": "Deseleziona tutto",
36
+ "Copy to Invoice": "Copia in fattura",
36
37
  } as const;
@@ -33,4 +33,5 @@ export default {
33
33
  selected: "geselecteerd",
34
34
  "Export PDFs": "PDFs exporteren",
35
35
  "Deselect all": "Alles deselecteren",
36
+ "Copy to Invoice": "Kopieer naar factuur",
36
37
  } as const;
@@ -33,4 +33,5 @@ export default {
33
33
  selected: "wybranych",
34
34
  "Export PDFs": "Eksportuj PDF-y",
35
35
  "Deselect all": "Odznacz wszystko",
36
+ "Copy to Invoice": "Kopiuj do faktury",
36
37
  } as const;
@@ -33,4 +33,5 @@ export default {
33
33
  selected: "selecionados",
34
34
  "Export PDFs": "Exportar PDFs",
35
35
  "Deselect all": "Desselecionar tudo",
36
+ "Copy to Invoice": "Copiar para fatura",
36
37
  } as const;
@@ -36,4 +36,5 @@ export default {
36
36
  selected: "izbranih",
37
37
  "Export PDFs": "Izvozi PDF-je",
38
38
  "Deselect all": "Počisti izbiro",
39
+ "Copy to Invoice": "Kopiraj v račun",
39
40
  } as const;
@@ -3,13 +3,16 @@ type TFunction = (key: string, options?: Record<string, unknown>) => string;
3
3
  import { Calendar, Download, Loader2 } from "lucide-react";
4
4
  import { useRef, useState } from "react";
5
5
  import { Button } from "../ui/button";
6
+ import { Checkbox } from "../ui/checkbox";
6
7
  import { Input } from "../ui/input";
7
8
  import { Label } from "../ui/label";
8
9
  import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "../ui/select";
9
10
 
10
- export type DocumentType = "invoice" | "estimate" | "credit_note";
11
+ export type DocumentType = "invoice" | "estimate" | "credit_note" | "advance_invoice" | "delivery_note";
11
12
  export type ExportFormat = "xlsx" | "csv" | "pdf_zip";
12
13
 
14
+ const ALL_DOCUMENT_TYPES: DocumentType[] = ["invoice", "estimate", "credit_note", "advance_invoice", "delivery_note"];
15
+
13
16
  // Maximum date range for export (1 year in milliseconds)
14
17
  const MAX_DATE_RANGE_MS = 365 * 24 * 60 * 60 * 1000;
15
18
 
@@ -65,6 +68,7 @@ export function DocumentExportForm({
65
68
  }: DocumentExportFormProps) {
66
69
  const defaultDates = getPreviousMonthRange();
67
70
  const [documentType, setDocumentType] = useState<DocumentType>("invoice");
71
+ const [selectedTypes, setSelectedTypes] = useState<DocumentType[]>(["invoice"]);
68
72
  const [exportFormat, setExportFormat] = useState<ExportFormat>("xlsx");
69
73
  const [dateFrom, setDateFrom] = useState(defaultDates.from);
70
74
  const [dateTo, setDateTo] = useState(defaultDates.to);
@@ -73,6 +77,17 @@ export function DocumentExportForm({
73
77
 
74
78
  const toastIdRef = useRef<string | number | null>(null);
75
79
 
80
+ const toggleType = (type: DocumentType) => {
81
+ setSelectedTypes((prev) => {
82
+ if (prev.includes(type)) {
83
+ // Don't allow deselecting the last type
84
+ if (prev.length === 1) return prev;
85
+ return prev.filter((t) => t !== type);
86
+ }
87
+ return [...prev, type];
88
+ });
89
+ };
90
+
76
91
  const validateDateRange = (from: string, to: string) => {
77
92
  const isValid = isDateRangeValid(from, to);
78
93
  setDateRangeError(!isValid);
@@ -100,7 +115,7 @@ export function DocumentExportForm({
100
115
  "Content-Type": "application/json",
101
116
  },
102
117
  body: JSON.stringify({
103
- type: documentType,
118
+ types: selectedTypes,
104
119
  date_from: dateFrom || undefined,
105
120
  date_to: dateTo || undefined,
106
121
  }),
@@ -187,16 +202,35 @@ export function DocumentExportForm({
187
202
  <div className="grid grid-cols-2 gap-4">
188
203
  <div className="space-y-2">
189
204
  <Label htmlFor="document-type">{t("export-page.document-type")}</Label>
190
- <Select value={documentType} onValueChange={(v) => setDocumentType(v as DocumentType)}>
191
- <SelectTrigger id="document-type">
192
- <SelectValue />
193
- </SelectTrigger>
194
- <SelectContent>
195
- <SelectItem value="invoice">{t("export-page.types.invoice")}</SelectItem>
196
- <SelectItem value="estimate">{t("export-page.types.estimate")}</SelectItem>
197
- <SelectItem value="credit_note">{t("export-page.types.credit_note")}</SelectItem>
198
- </SelectContent>
199
- </Select>
205
+ {exportFormat === "pdf_zip" ? (
206
+ <fieldset className="space-y-2 rounded-md border p-3">
207
+ {ALL_DOCUMENT_TYPES.map((type) => (
208
+ <div key={type} className="flex items-center gap-2">
209
+ <Checkbox
210
+ id={`type-${type}`}
211
+ checked={selectedTypes.includes(type)}
212
+ onCheckedChange={() => toggleType(type)}
213
+ />
214
+ <Label htmlFor={`type-${type}`} className="cursor-pointer font-normal">
215
+ {t(`export-page.types.${type}`)}
216
+ </Label>
217
+ </div>
218
+ ))}
219
+ </fieldset>
220
+ ) : (
221
+ <Select value={documentType} onValueChange={(v) => setDocumentType(v as DocumentType)}>
222
+ <SelectTrigger id="document-type">
223
+ <SelectValue />
224
+ </SelectTrigger>
225
+ <SelectContent>
226
+ <SelectItem value="invoice">{t("export-page.types.invoice")}</SelectItem>
227
+ <SelectItem value="estimate">{t("export-page.types.estimate")}</SelectItem>
228
+ <SelectItem value="credit_note">{t("export-page.types.credit_note")}</SelectItem>
229
+ <SelectItem value="advance_invoice">{t("export-page.types.advance_invoice")}</SelectItem>
230
+ <SelectItem value="delivery_note">{t("export-page.types.delivery_note")}</SelectItem>
231
+ </SelectContent>
232
+ </Select>
233
+ )}
200
234
  </div>
201
235
 
202
236
  <div className="space-y-2">
@@ -24,6 +24,7 @@ import {
24
24
  DocumentDetailsSection,
25
25
  DocumentNoteField,
26
26
  DocumentPaymentTermsField,
27
+ DocumentTaxClauseField,
27
28
  } from "../../documents/create/document-details-section";
28
29
  import { DocumentItemsSection, type PriceModesMap } from "../../documents/create/document-items-section";
29
30
  import { DocumentRecipientSection } from "../../documents/create/document-recipient-section";
@@ -321,13 +322,18 @@ export default function CreateInvoiceForm({
321
322
  // Cast customer to form schema type (API type may have additional fields)
322
323
  customer: (initialValues?.customer as CreateInvoiceFormValues["customer"]) ?? undefined,
323
324
  items: initialValues?.items?.length
324
- ? initialValues.items.map((item) => ({
325
+ ? initialValues.items.map((item: any) => ({
326
+ type: item.type,
325
327
  name: item.name || "",
326
328
  description: item.description || "",
327
- quantity: item.quantity ?? 1,
328
- // Use gross_price if set, otherwise use price
329
- price: item.gross_price ?? item.price,
330
- taxes: item.taxes || [],
329
+ ...(item.type !== "separator"
330
+ ? {
331
+ quantity: item.quantity ?? 1,
332
+ // Use gross_price if set, otherwise use price
333
+ price: item.gross_price ?? item.price,
334
+ taxes: item.taxes || [],
335
+ }
336
+ : {}),
331
337
  }))
332
338
  : [
333
339
  {
@@ -340,6 +346,7 @@ export default function CreateInvoiceForm({
340
346
  ],
341
347
  currency_code: initialValues?.currency_code || activeEntity?.currency_code || "EUR",
342
348
  note: initialValues?.note ?? defaultInvoiceNote,
349
+ tax_clause: (initialValues as any)?.tax_clause ?? "",
343
350
  payment_terms: initialValues?.payment_terms ?? defaultPaymentTerms,
344
351
  date_due:
345
352
  initialValues?.date_due ||
@@ -529,7 +536,13 @@ export default function CreateInvoiceForm({
529
536
  // ============================================================================
530
537
  // VIES Check - determine if reverse charge applies
531
538
  // ============================================================================
532
- const { reverseChargeApplies, warning: viesWarning } = useViesCheck({
539
+ const {
540
+ reverseChargeApplies,
541
+ transactionType,
542
+ customerCountryCode: viesCustomerCountryCode,
543
+ isFetching: isViesFetching,
544
+ warning: viesWarning,
545
+ } = useViesCheck({
533
546
  issuerCountryCode: activeEntity?.country_code,
534
547
  isTaxSubject: activeEntity?.is_tax_subject ?? true,
535
548
  customerCountry,
@@ -538,6 +551,23 @@ export default function CreateInvoiceForm({
538
551
  enabled: !!activeEntity,
539
552
  });
540
553
 
554
+ // FINA non-domestic guard: hide FINA selectors for non-domestic transactions
555
+ const isFinaNonDomestic = isFinaEnabled && viesCustomerCountryCode != null && viesCustomerCountryCode !== "HR";
556
+
557
+ // Auto-populate tax_clause from entity settings when transaction type changes
558
+ const effectiveTransactionType = transactionType ?? "domestic";
559
+ const prevTransactionTypeRef = useRef<string | undefined>(undefined);
560
+ useEffect(() => {
561
+ if (effectiveTransactionType === prevTransactionTypeRef.current) return;
562
+ prevTransactionTypeRef.current = effectiveTransactionType;
563
+
564
+ const taxClauseDefaults = (activeEntity?.settings as any)?.tax_clause_defaults;
565
+ if (!taxClauseDefaults) return;
566
+
567
+ const clause = taxClauseDefaults[effectiveTransactionType] ?? "";
568
+ form.setValue("tax_clause", clause);
569
+ }, [effectiveTransactionType, activeEntity, form]);
570
+
541
571
  // Extract customer management logic into a custom hook
542
572
  const {
543
573
  originalCustomer,
@@ -624,9 +654,9 @@ export default function CreateInvoiceForm({
624
654
  : undefined
625
655
  : undefined;
626
656
 
627
- // Build FINA options (skip for drafts and edit mode; FINA can't be skipped)
657
+ // Build FINA options (skip for drafts, edit mode, and non-domestic transactions)
628
658
  const finaOptions =
629
- !isDraft && !isEditMode && isFinaEnabled && selectedFinaPremiseId && selectedFinaDeviceId
659
+ !isDraft && !isEditMode && isFinaEnabled && !isFinaNonDomestic && selectedFinaPremiseId && selectedFinaDeviceId
630
660
  ? { premise_id: selectedFinaPremiseId, device_id: selectedFinaDeviceId, payment_type: paymentTypes[0] }
631
661
  : undefined;
632
662
 
@@ -674,6 +704,7 @@ export default function CreateInvoiceForm({
674
704
  isEslogAvailable,
675
705
  isFursEnabled,
676
706
  isFinaEnabled,
707
+ isFinaNonDomestic,
677
708
  markAsPaid,
678
709
  originalCustomer,
679
710
  paymentTypes,
@@ -717,7 +748,8 @@ export default function CreateInvoiceForm({
717
748
  );
718
749
 
719
750
  // Watch isDirty to get stable reference
720
- const isDirty = form.formState.isDirty;
751
+ // When form is pre-populated via initialValues (duplicate/merge), treat as dirty immediately
752
+ const isDirty = form.formState.isDirty || !!initialValues;
721
753
 
722
754
  useFormFooterRegistration({
723
755
  formId: "create-invoice-form",
@@ -931,7 +963,7 @@ export default function CreateInvoiceForm({
931
963
  : undefined
932
964
  }
933
965
  finaInline={
934
- !isEditMode && isFinaEnabled && hasFinaPremises
966
+ !isEditMode && isFinaEnabled && hasFinaPremises && !isFinaNonDomestic
935
967
  ? {
936
968
  premises: activeFinaPremises.map((p: any) => ({ id: p.id, premise_id: p.premise_id })),
937
969
  devices: activeFinaDevices.map((d: any) => ({ id: d.id, device_id: d.device_id })),
@@ -993,6 +1025,22 @@ export default function CreateInvoiceForm({
993
1025
  }}
994
1026
  />
995
1027
 
1028
+ <DocumentTaxClauseField
1029
+ control={form.control}
1030
+ t={t}
1031
+ entity={activeEntity}
1032
+ document={{
1033
+ number: watchedNumber,
1034
+ date: watchedDate,
1035
+ date_due: watchedDateDue,
1036
+ currency_code: watchedCurrencyCode,
1037
+ customer: watchedCustomer as any,
1038
+ }}
1039
+ transactionType={transactionType}
1040
+ isTransactionTypeFetching={isViesFetching}
1041
+ isFinaNonDomestic={isFinaNonDomestic}
1042
+ />
1043
+
996
1044
  <DocumentPaymentTermsField
997
1045
  control={form.control}
998
1046
  t={t}
@@ -126,4 +126,19 @@ export default {
126
126
  "Date Range": "Zeitraum",
127
127
  From: "Von",
128
128
  To: "Bis",
129
+ // Separator items
130
+ "Add separator": "Trennzeile hinzufügen",
131
+ "Section header": "Abschnittsüberschrift",
132
+ "Section title...": "Abschnittstitel...",
133
+ // Transaction type
134
+ "Transaction type": "Transaktionstyp",
135
+ Domestic: "Inland",
136
+ "EU B2B": "EU B2B",
137
+ "EU B2C": "EU B2C",
138
+ Export: "Export",
139
+ "Determining transaction type...": "Transaktionstyp wird ermittelt...",
140
+ "This invoice will not be fiscalized (non-domestic transaction)":
141
+ "Diese Rechnung wird nicht fiskalisiert (nicht-inländische Transaktion)",
142
+ "Tax Clause": "Steuerklausel",
143
+ "Add tax clause...": "Steuerklausel hinzufügen...",
129
144
  } as const;
@@ -111,4 +111,19 @@ export default {
111
111
  "Date Range": "Rango de fechas",
112
112
  From: "Desde",
113
113
  To: "Hasta",
114
+ // Separator items
115
+ "Add separator": "Añadir separador",
116
+ "Section header": "Encabezado de sección",
117
+ "Section title...": "Título de sección...",
118
+ // Transaction type
119
+ "Transaction type": "Tipo de transacción",
120
+ Domestic: "Nacional",
121
+ "EU B2B": "EU B2B",
122
+ "EU B2C": "EU B2C",
123
+ Export: "Exportación",
124
+ "Determining transaction type...": "Determinando tipo de transacción...",
125
+ "This invoice will not be fiscalized (non-domestic transaction)":
126
+ "Esta factura no será fiscalizada (transacción no nacional)",
127
+ "Tax Clause": "Cláusula fiscal",
128
+ "Add tax clause...": "Agregar cláusula fiscal...",
114
129
  } as const;
@@ -113,4 +113,19 @@ export default {
113
113
  "Date Range": "Plage de dates",
114
114
  From: "Du",
115
115
  To: "Au",
116
+ // Separator items
117
+ "Add separator": "Ajouter un séparateur",
118
+ "Section header": "En-tête de section",
119
+ "Section title...": "Titre de section...",
120
+ // Transaction type
121
+ "Transaction type": "Type de transaction",
122
+ Domestic: "Nationale",
123
+ "EU B2B": "EU B2B",
124
+ "EU B2C": "EU B2C",
125
+ Export: "Exportation",
126
+ "Determining transaction type...": "Détermination du type de transaction...",
127
+ "This invoice will not be fiscalized (non-domestic transaction)":
128
+ "Cette facture ne sera pas fiscalisée (transaction non nationale)",
129
+ "Tax Clause": "Clause fiscale",
130
+ "Add tax clause...": "Ajouter une clause fiscale...",
116
131
  } as const;
@@ -110,4 +110,19 @@ export default {
110
110
  "Date Range": "Raspon datuma",
111
111
  From: "Od",
112
112
  To: "Do",
113
+ // Separator items
114
+ "Add separator": "Dodaj separator",
115
+ "Section header": "Naslov odjeljka",
116
+ "Section title...": "Naslov odjeljka...",
117
+ // Transaction type
118
+ "Transaction type": "Vrsta transakcije",
119
+ Domestic: "Domaća",
120
+ "EU B2B": "EU B2B",
121
+ "EU B2C": "EU B2C",
122
+ Export: "Izvoz",
123
+ "Determining transaction type...": "Određivanje vrste transakcije...",
124
+ "This invoice will not be fiscalized (non-domestic transaction)":
125
+ "Ovaj račun neće biti fiskaliziran (nedomaća transakcija)",
126
+ "Tax Clause": "Porezna klauzula",
127
+ "Add tax clause...": "Dodajte poreznu klauzulu...",
113
128
  } as const;
@@ -113,4 +113,19 @@ export default {
113
113
  "Date Range": "Intervallo di date",
114
114
  From: "Da",
115
115
  To: "A",
116
+ // Separator items
117
+ "Add separator": "Aggiungi separatore",
118
+ "Section header": "Intestazione sezione",
119
+ "Section title...": "Titolo sezione...",
120
+ // Transaction type
121
+ "Transaction type": "Tipo di transazione",
122
+ Domestic: "Nazionale",
123
+ "EU B2B": "EU B2B",
124
+ "EU B2C": "EU B2C",
125
+ Export: "Esportazione",
126
+ "Determining transaction type...": "Determinazione tipo di transazione...",
127
+ "This invoice will not be fiscalized (non-domestic transaction)":
128
+ "Questa fattura non sarà fiscalizzata (transazione non nazionale)",
129
+ "Tax Clause": "Clausola fiscale",
130
+ "Add tax clause...": "Aggiungi clausola fiscale...",
116
131
  } as const;
@@ -112,4 +112,19 @@ export default {
112
112
  "Date Range": "Datumbereik",
113
113
  From: "Van",
114
114
  To: "Tot",
115
+ // Separator items
116
+ "Add separator": "Scheidingslijn toevoegen",
117
+ "Section header": "Sectiekop",
118
+ "Section title...": "Sectietitel...",
119
+ // Transaction type
120
+ "Transaction type": "Transactietype",
121
+ Domestic: "Binnenland",
122
+ "EU B2B": "EU B2B",
123
+ "EU B2C": "EU B2C",
124
+ Export: "Export",
125
+ "Determining transaction type...": "Transactietype bepalen...",
126
+ "This invoice will not be fiscalized (non-domestic transaction)":
127
+ "Deze factuur wordt niet gefiscaliseerd (niet-binnenlandse transactie)",
128
+ "Tax Clause": "Belastingclausule",
129
+ "Add tax clause...": "Belastingclausule toevoegen...",
115
130
  } as const;
@@ -111,4 +111,19 @@ export default {
111
111
  "Date Range": "Zakres dat",
112
112
  From: "Od",
113
113
  To: "Do",
114
+ // Separator items
115
+ "Add separator": "Dodaj separator",
116
+ "Section header": "Nagłówek sekcji",
117
+ "Section title...": "Tytuł sekcji...",
118
+ // Transaction type
119
+ "Transaction type": "Typ transakcji",
120
+ Domestic: "Krajowa",
121
+ "EU B2B": "EU B2B",
122
+ "EU B2C": "EU B2C",
123
+ Export: "Eksport",
124
+ "Determining transaction type...": "Określanie typu transakcji...",
125
+ "This invoice will not be fiscalized (non-domestic transaction)":
126
+ "Ta faktura nie będzie fiskalizowana (transakcja niekrajowa)",
127
+ "Tax Clause": "Klauzula podatkowa",
128
+ "Add tax clause...": "Dodaj klauzulę podatkową...",
114
129
  } as const;
@@ -112,4 +112,19 @@ export default {
112
112
  "Date Range": "Intervalo de datas",
113
113
  From: "De",
114
114
  To: "Até",
115
+ // Separator items
116
+ "Add separator": "Adicionar separador",
117
+ "Section header": "Cabeçalho da secção",
118
+ "Section title...": "Título da secção...",
119
+ // Transaction type
120
+ "Transaction type": "Tipo de transação",
121
+ Domestic: "Nacional",
122
+ "EU B2B": "EU B2B",
123
+ "EU B2C": "EU B2C",
124
+ Export: "Exportação",
125
+ "Determining transaction type...": "Determinando tipo de transação...",
126
+ "This invoice will not be fiscalized (non-domestic transaction)":
127
+ "Esta fatura não será fiscalizada (transação não nacional)",
128
+ "Tax Clause": "Cláusula fiscal",
129
+ "Add tax clause...": "Adicionar cláusula fiscal...",
115
130
  } as const;