@spaceinvoices/react-ui 0.4.4 → 0.4.6

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 (178) hide show
  1. package/cli/dist/index.js +1 -1
  2. package/package.json +1 -1
  3. package/src/components/advance-invoices/advance-invoices.hooks.ts +2 -2
  4. package/src/components/advance-invoices/create/create-advance-invoice-form.tsx +151 -45
  5. package/src/components/advance-invoices/create/locales/de.ts +20 -0
  6. package/src/components/advance-invoices/create/locales/es.ts +20 -0
  7. package/src/components/advance-invoices/create/locales/fr.ts +20 -0
  8. package/src/components/advance-invoices/create/locales/hr.ts +20 -0
  9. package/src/components/advance-invoices/create/locales/it.ts +20 -0
  10. package/src/components/advance-invoices/create/locales/nl.ts +20 -0
  11. package/src/components/advance-invoices/create/locales/pl.ts +20 -0
  12. package/src/components/advance-invoices/create/locales/pt.ts +20 -0
  13. package/src/components/advance-invoices/create/locales/sl.ts +20 -0
  14. package/src/components/advance-invoices/create/prepare-advance-invoice-submission.ts +5 -5
  15. package/src/components/advance-invoices/list/list-row-actions.tsx +48 -1
  16. package/src/components/advance-invoices/list/list-table.tsx +21 -1
  17. package/src/components/advance-invoices/list/locales/de.ts +4 -0
  18. package/src/components/advance-invoices/list/locales/en.ts +3 -0
  19. package/src/components/advance-invoices/list/locales/es.ts +4 -0
  20. package/src/components/advance-invoices/list/locales/fr.ts +4 -0
  21. package/src/components/advance-invoices/list/locales/hr.ts +3 -0
  22. package/src/components/advance-invoices/list/locales/it.ts +4 -0
  23. package/src/components/advance-invoices/list/locales/nl.ts +4 -0
  24. package/src/components/advance-invoices/list/locales/pl.ts +3 -0
  25. package/src/components/advance-invoices/list/locales/pt.ts +4 -0
  26. package/src/components/advance-invoices/list/locales/sl.ts +3 -0
  27. package/src/components/credit-notes/create/create-credit-note-form.tsx +161 -42
  28. package/src/components/credit-notes/create/locales/de.ts +21 -0
  29. package/src/components/credit-notes/create/locales/es.ts +21 -0
  30. package/src/components/credit-notes/create/locales/fr.ts +21 -0
  31. package/src/components/credit-notes/create/locales/hr.ts +21 -0
  32. package/src/components/credit-notes/create/locales/it.ts +21 -0
  33. package/src/components/credit-notes/create/locales/nl.ts +21 -0
  34. package/src/components/credit-notes/create/locales/pl.ts +21 -0
  35. package/src/components/credit-notes/create/locales/pt.ts +21 -0
  36. package/src/components/credit-notes/create/locales/sl.ts +22 -1
  37. package/src/components/credit-notes/credit-notes.hooks.ts +2 -2
  38. package/src/components/credit-notes/list/list-row-actions.tsx +44 -1
  39. package/src/components/credit-notes/list/list-table.tsx +16 -2
  40. package/src/components/credit-notes/list/locales/de.ts +2 -0
  41. package/src/components/credit-notes/list/locales/en.ts +2 -0
  42. package/src/components/credit-notes/list/locales/es.ts +2 -0
  43. package/src/components/credit-notes/list/locales/fr.ts +2 -0
  44. package/src/components/credit-notes/list/locales/hr.ts +2 -0
  45. package/src/components/credit-notes/list/locales/it.ts +2 -0
  46. package/src/components/credit-notes/list/locales/nl.ts +2 -0
  47. package/src/components/credit-notes/list/locales/pl.ts +2 -0
  48. package/src/components/credit-notes/list/locales/pt.ts +2 -0
  49. package/src/components/credit-notes/list/locales/sl.ts +2 -0
  50. package/src/components/dashboard/collection-rate-card/use-collection-rate.ts +48 -9
  51. package/src/components/dashboard/revenue-trend-chart/use-revenue-trend.ts +77 -48
  52. package/src/components/dashboard/shared/use-revenue-data.ts +77 -9
  53. package/src/components/delivery-notes/create/create-delivery-note-form.tsx +114 -7
  54. package/src/components/delivery-notes/create/locales/de.ts +21 -0
  55. package/src/components/delivery-notes/create/locales/es.ts +21 -0
  56. package/src/components/delivery-notes/create/locales/fr.ts +21 -0
  57. package/src/components/delivery-notes/create/locales/hr.ts +21 -0
  58. package/src/components/delivery-notes/create/locales/it.ts +21 -0
  59. package/src/components/delivery-notes/create/locales/nl.ts +21 -0
  60. package/src/components/delivery-notes/create/locales/pl.ts +21 -0
  61. package/src/components/delivery-notes/create/locales/pt.ts +21 -0
  62. package/src/components/delivery-notes/create/locales/sl.ts +22 -1
  63. package/src/components/delivery-notes/list/list-table.tsx +17 -8
  64. package/src/components/delivery-notes/list/locales/de.ts +32 -1
  65. package/src/components/delivery-notes/list/locales/en.ts +31 -0
  66. package/src/components/delivery-notes/list/locales/es.ts +32 -1
  67. package/src/components/delivery-notes/list/locales/fr.ts +32 -1
  68. package/src/components/delivery-notes/list/locales/hr.ts +32 -1
  69. package/src/components/delivery-notes/list/locales/it.ts +32 -1
  70. package/src/components/delivery-notes/list/locales/nl.ts +32 -1
  71. package/src/components/delivery-notes/list/locales/pl.ts +32 -1
  72. package/src/components/delivery-notes/list/locales/pt.ts +32 -1
  73. package/src/components/delivery-notes/list/locales/sl.ts +32 -1
  74. package/src/components/documents/create/document-add-item-form.tsx +70 -0
  75. package/src/components/documents/create/document-details-section.tsx +590 -344
  76. package/src/components/documents/create/document-items-section.tsx +21 -4
  77. package/src/components/documents/create/live-preview.tsx +24 -4
  78. package/src/components/documents/create/mark-as-paid-section.tsx +29 -20
  79. package/src/components/documents/create/prepare-document-submission.ts +22 -8
  80. package/src/components/documents/create/smart-code-insert-button.tsx +6 -0
  81. package/src/components/documents/shared/document-preview-display.tsx +3 -4
  82. package/src/components/documents/view/document-actions-bar.tsx +7 -27
  83. package/src/components/documents/view/document-details-card.tsx +32 -9
  84. package/src/components/documents/view/locales/de.ts +3 -0
  85. package/src/components/documents/view/locales/es.ts +3 -0
  86. package/src/components/documents/view/locales/fr.ts +3 -0
  87. package/src/components/documents/view/locales/hr.ts +3 -0
  88. package/src/components/documents/view/locales/it.ts +3 -0
  89. package/src/components/documents/view/locales/nl.ts +3 -0
  90. package/src/components/documents/view/locales/pl.ts +3 -0
  91. package/src/components/documents/view/locales/pt.ts +3 -0
  92. package/src/components/documents/view/locales/sl.ts +4 -1
  93. package/src/components/documents/view/use-document-download.ts +6 -3
  94. package/src/components/entities/create-entity-form.tsx +2 -1
  95. package/src/components/entities/entity-settings-form/email-template-variables-info.tsx +6 -0
  96. package/src/components/entities/entity-settings-form/input-with-preview.tsx +2 -117
  97. package/src/components/entities/entity-settings-form/locales/de.ts +5 -0
  98. package/src/components/entities/entity-settings-form/locales/es.ts +5 -0
  99. package/src/components/entities/entity-settings-form/locales/fr.ts +5 -0
  100. package/src/components/entities/entity-settings-form/locales/hr.ts +5 -0
  101. package/src/components/entities/entity-settings-form/locales/it.ts +5 -0
  102. package/src/components/entities/entity-settings-form/locales/nl.ts +5 -0
  103. package/src/components/entities/entity-settings-form/locales/pl.ts +5 -0
  104. package/src/components/entities/entity-settings-form/locales/pt.ts +5 -0
  105. package/src/components/entities/entity-settings-form/locales/sl.ts +5 -0
  106. package/src/components/entities/fina-settings-form/fina-settings-form.tsx +15 -0
  107. package/src/components/entities/fina-settings-form/fina-settings.hooks.ts +5 -1
  108. package/src/components/entities/fina-settings-form/locales/de.ts +3 -0
  109. package/src/components/entities/fina-settings-form/locales/en.ts +3 -0
  110. package/src/components/entities/fina-settings-form/locales/es.ts +3 -0
  111. package/src/components/entities/fina-settings-form/locales/fr.ts +3 -0
  112. package/src/components/entities/fina-settings-form/locales/hr.ts +3 -0
  113. package/src/components/entities/fina-settings-form/locales/it.ts +3 -0
  114. package/src/components/entities/fina-settings-form/locales/nl.ts +3 -0
  115. package/src/components/entities/fina-settings-form/locales/pl.ts +3 -0
  116. package/src/components/entities/fina-settings-form/locales/pt.ts +3 -0
  117. package/src/components/entities/fina-settings-form/locales/sl.ts +3 -0
  118. package/src/components/entities/fina-settings-form/sections/premises-management-section.tsx +4 -4
  119. package/src/components/entities/fina-settings-form/sections/register-premise-dialog.tsx +3 -3
  120. package/src/components/entities/settings/company-settings-form.tsx +173 -20
  121. package/src/components/entities/settings/defaults-settings-form.tsx +38 -1
  122. package/src/components/entities/settings/tax-rules-settings-form.tsx +1 -2
  123. package/src/components/estimates/create/create-estimate-form.tsx +107 -8
  124. package/src/components/estimates/create/locales/de.ts +21 -0
  125. package/src/components/estimates/create/locales/es.ts +21 -0
  126. package/src/components/estimates/create/locales/fr.ts +21 -0
  127. package/src/components/estimates/create/locales/hr.ts +21 -0
  128. package/src/components/estimates/create/locales/it.ts +21 -0
  129. package/src/components/estimates/create/locales/nl.ts +21 -0
  130. package/src/components/estimates/create/locales/pl.ts +21 -0
  131. package/src/components/estimates/create/locales/pt.ts +21 -0
  132. package/src/components/estimates/create/locales/sl.ts +22 -1
  133. package/src/components/estimates/list/list-table.tsx +11 -2
  134. package/src/components/estimates/list/locales/de.ts +1 -0
  135. package/src/components/estimates/list/locales/en.ts +1 -0
  136. package/src/components/estimates/list/locales/es.ts +1 -0
  137. package/src/components/estimates/list/locales/fr.ts +1 -0
  138. package/src/components/estimates/list/locales/hr.ts +1 -0
  139. package/src/components/estimates/list/locales/it.ts +1 -0
  140. package/src/components/estimates/list/locales/nl.ts +1 -0
  141. package/src/components/estimates/list/locales/pl.ts +1 -0
  142. package/src/components/estimates/list/locales/pt.ts +1 -0
  143. package/src/components/estimates/list/locales/sl.ts +1 -0
  144. package/src/components/export/document-export-form.tsx +46 -12
  145. package/src/components/invoices/create/create-invoice-form.tsx +186 -48
  146. package/src/components/invoices/create/locales/de.ts +28 -0
  147. package/src/components/invoices/create/locales/es.ts +28 -0
  148. package/src/components/invoices/create/locales/fr.ts +28 -0
  149. package/src/components/invoices/create/locales/hr.ts +28 -0
  150. package/src/components/invoices/create/locales/it.ts +28 -0
  151. package/src/components/invoices/create/locales/nl.ts +28 -0
  152. package/src/components/invoices/create/locales/pl.ts +28 -0
  153. package/src/components/invoices/create/locales/pt.ts +28 -0
  154. package/src/components/invoices/create/locales/sl.ts +29 -1
  155. package/src/components/invoices/create/prepare-invoice-submission.ts +5 -5
  156. package/src/components/invoices/invoices.hooks.ts +2 -2
  157. package/src/components/invoices/view/fiscalization-status-card.tsx +10 -8
  158. package/src/components/table/search-input.tsx +17 -0
  159. package/src/components/table/table-pagination.tsx +1 -1
  160. package/src/generated/schemas/advanceinvoice.ts +6 -2
  161. package/src/generated/schemas/creditnote.ts +3 -1
  162. package/src/generated/schemas/deliverynote.ts +3 -1
  163. package/src/generated/schemas/entity.ts +4 -4
  164. package/src/generated/schemas/entityapikey.ts +19 -0
  165. package/src/generated/schemas/estimate.ts +6 -2
  166. package/src/generated/schemas/index.ts +1 -0
  167. package/src/generated/schemas/invoice.ts +4 -1
  168. package/src/generated/schemas/renderadvanceinvoicepreview_body.ts +17 -23
  169. package/src/generated/schemas/rendercreditnotepreview_body.ts +17 -23
  170. package/src/generated/schemas/renderdeliverynotepreview_body.ts +17 -23
  171. package/src/generated/schemas/renderestimatepreview_body.ts +17 -23
  172. package/src/generated/schemas/renderinvoicepreview_body.ts +19 -23
  173. package/src/generated/schemas/startpdfexport_body.ts +14 -2
  174. package/src/generated/schemas/webhook.ts +4 -0
  175. package/src/hooks/use-duplicate-document.ts +16 -9
  176. package/src/hooks/use-vies-check.ts +3 -0
  177. package/src/lib/template-variables.tsx +167 -0
  178. package/src/providers/entities-context.tsx +2 -2
package/cli/dist/index.js CHANGED
@@ -870,7 +870,7 @@ async function list(options = {}) {
870
870
 
871
871
  // cli/src/index.ts
872
872
  var program = new Command();
873
- program.name("spaceinvoices-ui").description("CLI for adding Space Invoices React UI components to your project").version("0.4.4");
873
+ program.name("spaceinvoices-ui").description("CLI for adding Space Invoices React UI components to your project").version("0.4.6");
874
874
  program.option("--local <path>", "Use local registry from specified path (for development)");
875
875
  program.command("init").description("Initialize Space Invoices UI in your project").option("-y, --yes", "Skip prompts and use defaults").option("-f, --force", "Overwrite existing configuration").option("--cwd <path>", "Working directory (defaults to current directory)").action(async (options) => {
876
876
  const globalOpts = program.opts();
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@spaceinvoices/react-ui",
3
3
  "type": "module",
4
- "version": "0.4.4",
4
+ "version": "0.4.6",
5
5
  "private": false,
6
6
  "license": "MIT",
7
7
  "description": "Space Invoices UI components - copy-paste distribution with CLI support",
@@ -81,8 +81,8 @@ export function setLastUsedFursCombo(entityId: string, combo: FursCombo): void {
81
81
  const FINA_ADV_LAST_USED_KEY = "hr:fina:adv:last-used";
82
82
 
83
83
  export type FinaCombo = {
84
- premise_id: string;
85
- device_id: string;
84
+ business_premise_name: string;
85
+ electronic_device_name: string;
86
86
  };
87
87
 
88
88
  export function getLastUsedFinaCombo(entityId: string): FinaCombo | null {
@@ -19,7 +19,13 @@ import { createTranslation } from "@/ui/lib/translation";
19
19
  import { cn } from "@/ui/lib/utils";
20
20
  import { useEntities } from "@/ui/providers/entities-context";
21
21
  import { useFormFooterRegistration } from "@/ui/providers/form-footer-context";
22
- import { DocumentDetailsSection, DocumentNoteField } from "../../documents/create/document-details-section";
22
+ import {
23
+ DocumentDetailsSection,
24
+ DocumentFooterField,
25
+ DocumentNoteField,
26
+ DocumentSignatureField,
27
+ DocumentTaxClauseField,
28
+ } from "../../documents/create/document-details-section";
23
29
  import { DocumentItemsSection, type PriceModesMap } from "../../documents/create/document-items-section";
24
30
  import { DocumentRecipientSection } from "../../documents/create/document-recipient-section";
25
31
  import { MarkAsPaidSection } from "../../documents/create/mark-as-paid-section";
@@ -103,6 +109,7 @@ export default function CreateAdvanceInvoiceForm({
103
109
  // Get default note from entity settings (use invoice defaults)
104
110
  // Note: Advance invoices don't have payment terms - they are documents requesting payment
105
111
  const defaultNote = (activeEntity?.settings as any)?.default_invoice_note || "";
112
+ const defaultFooter = (activeEntity?.settings as any)?.document_footer || "";
106
113
 
107
114
  // ============================================================================
108
115
  // FURS Settings & Premises
@@ -139,11 +146,11 @@ export default function CreateAdvanceInvoiceForm({
139
146
  const hasFinaPremises = activeFinaPremises.length > 0;
140
147
 
141
148
  // FINA premise/device selection state (no skip - all FINA invoices must be fiscalized)
142
- const [selectedFinaPremiseId, setSelectedFinaPremiseId] = useState<string | undefined>();
143
- const [selectedFinaDeviceId, setSelectedFinaDeviceId] = useState<string | undefined>();
149
+ const [selectedFinaBusinessPremiseName, setSelectedFinaBusinessPremiseName] = useState<string | undefined>();
150
+ const [selectedFinaElectronicDeviceName, setSelectedFinaElectronicDeviceName] = useState<string | undefined>();
144
151
 
145
152
  // UI-only state (not part of API schema)
146
- const [markAsPaid, setMarkAsPaid] = useState(false);
153
+ const [markAsPaid, setMarkAsPaid] = useState(true);
147
154
  const [paymentTypes, setPaymentTypes] = useState<string[]>(["bank_transfer"]);
148
155
  const [isDraftPending, setIsDraftPending] = useState(false);
149
156
 
@@ -235,22 +242,24 @@ export default function CreateAdvanceInvoiceForm({
235
242
 
236
243
  // Get active FINA devices for selected premise
237
244
  const activeFinaDevices = useMemo(() => {
238
- if (!selectedFinaPremiseId) return [];
239
- const premise = activeFinaPremises.find((p: any) => p.premise_id === selectedFinaPremiseId);
245
+ if (!selectedFinaBusinessPremiseName) return [];
246
+ const premise = activeFinaPremises.find((p: any) => p.business_premise_name === selectedFinaBusinessPremiseName);
240
247
  return premise?.Devices?.filter((d: any) => d.is_active) || [];
241
- }, [activeFinaPremises, selectedFinaPremiseId]);
248
+ }, [activeFinaPremises, selectedFinaBusinessPremiseName]);
242
249
 
243
250
  // Initialize FINA selection from localStorage or first active combo
244
251
  useEffect(() => {
245
- if (!isFinaEnabled || !hasFinaPremises || selectedFinaPremiseId) return;
252
+ if (!isFinaEnabled || !hasFinaPremises || selectedFinaBusinessPremiseName) return;
246
253
 
247
254
  const lastUsed = getLastUsedFinaCombo(entityId);
248
255
  if (lastUsed) {
249
- const premise = activeFinaPremises.find((p: any) => p.premise_id === lastUsed.premise_id);
250
- const device = premise?.Devices?.find((d: any) => d.device_id === lastUsed.device_id && d.is_active);
256
+ const premise = activeFinaPremises.find((p: any) => p.business_premise_name === lastUsed.business_premise_name);
257
+ const device = premise?.Devices?.find(
258
+ (d: any) => d.electronic_device_name === lastUsed.electronic_device_name && d.is_active,
259
+ );
251
260
  if (premise && device) {
252
- setSelectedFinaPremiseId(lastUsed.premise_id);
253
- setSelectedFinaDeviceId(lastUsed.device_id);
261
+ setSelectedFinaBusinessPremiseName(lastUsed.business_premise_name);
262
+ setSelectedFinaElectronicDeviceName(lastUsed.electronic_device_name);
254
263
  return;
255
264
  }
256
265
  }
@@ -258,25 +267,25 @@ export default function CreateAdvanceInvoiceForm({
258
267
  const firstPremise = activeFinaPremises[0];
259
268
  const firstDevice = firstPremise?.Devices?.find((d: any) => d.is_active);
260
269
  if (firstPremise && firstDevice) {
261
- setSelectedFinaPremiseId(firstPremise.premise_id);
262
- setSelectedFinaDeviceId(firstDevice.device_id);
270
+ setSelectedFinaBusinessPremiseName(firstPremise.business_premise_name);
271
+ setSelectedFinaElectronicDeviceName(firstDevice.electronic_device_name);
263
272
  }
264
- }, [isFinaEnabled, hasFinaPremises, activeFinaPremises, entityId, selectedFinaPremiseId]);
273
+ }, [isFinaEnabled, hasFinaPremises, activeFinaPremises, entityId, selectedFinaBusinessPremiseName]);
265
274
 
266
275
  // When FINA premise changes, select first active device
267
276
  useEffect(() => {
268
- if (!selectedFinaPremiseId) return;
269
- const premise = activeFinaPremises.find((p: any) => p.premise_id === selectedFinaPremiseId);
277
+ if (!selectedFinaBusinessPremiseName) return;
278
+ const premise = activeFinaPremises.find((p: any) => p.business_premise_name === selectedFinaBusinessPremiseName);
270
279
  const firstDevice = premise?.Devices?.find((d: any) => d.is_active);
271
- if (firstDevice && selectedFinaDeviceId !== firstDevice.device_id) {
280
+ if (firstDevice && selectedFinaElectronicDeviceName !== firstDevice.electronic_device_name) {
272
281
  const currentDeviceInPremise = premise?.Devices?.find(
273
- (d: any) => d.device_id === selectedFinaDeviceId && d.is_active,
282
+ (d: any) => d.electronic_device_name === selectedFinaElectronicDeviceName && d.is_active,
274
283
  );
275
284
  if (!currentDeviceInPremise) {
276
- setSelectedFinaDeviceId(firstDevice.device_id);
285
+ setSelectedFinaElectronicDeviceName(firstDevice.electronic_device_name);
277
286
  }
278
287
  }
279
- }, [selectedFinaPremiseId, activeFinaPremises, selectedFinaDeviceId]);
288
+ }, [selectedFinaBusinessPremiseName, activeFinaPremises, selectedFinaElectronicDeviceName]);
280
289
 
281
290
  const form = useForm<CreateAdvanceInvoiceFormValues>({
282
291
  // Cast resolver to accept extended form type (includes UI-only fields)
@@ -288,13 +297,18 @@ export default function CreateAdvanceInvoiceForm({
288
297
  // Cast customer to form schema type (API type may have additional fields)
289
298
  customer: (initialValues?.customer as CreateAdvanceInvoiceFormValues["customer"]) ?? undefined,
290
299
  items: initialValues?.items?.length
291
- ? initialValues.items.map((item) => ({
300
+ ? initialValues.items.map((item: any) => ({
301
+ type: item.type,
292
302
  name: item.name || "",
293
303
  description: item.description || "",
294
- quantity: item.quantity ?? 1,
295
- // Use gross_price if set, otherwise use price
296
- price: item.gross_price ?? item.price,
297
- taxes: item.taxes || [],
304
+ ...(item.type !== "separator"
305
+ ? {
306
+ quantity: item.quantity ?? 1,
307
+ // Use gross_price if set, otherwise use price
308
+ price: item.gross_price ?? item.price,
309
+ taxes: item.taxes || [],
310
+ }
311
+ : {}),
298
312
  }))
299
313
  : [
300
314
  {
@@ -306,7 +320,10 @@ export default function CreateAdvanceInvoiceForm({
306
320
  },
307
321
  ],
308
322
  currency_code: initialValues?.currency_code || activeEntity?.currency_code || "EUR",
323
+ reference: (initialValues as any)?.reference ?? "",
309
324
  note: initialValues?.note ?? defaultNote,
325
+ tax_clause: "",
326
+ footer: (initialValues as any)?.footer ?? defaultFooter,
310
327
  },
311
328
  });
312
329
 
@@ -329,8 +346,9 @@ export default function CreateAdvanceInvoiceForm({
329
346
 
330
347
  // FINA selection ready and active checks
331
348
  const isFinaSelectionReady =
332
- !isFinaEnabled || !hasFinaPremises || (!!selectedFinaPremiseId && !!selectedFinaDeviceId);
333
- const isFinaActive = isFinaEnabled && hasFinaPremises && selectedFinaPremiseId && selectedFinaDeviceId;
349
+ !isFinaEnabled || !hasFinaPremises || (!!selectedFinaBusinessPremiseName && !!selectedFinaElectronicDeviceName);
350
+ const isFinaActive =
351
+ isFinaEnabled && hasFinaPremises && selectedFinaBusinessPremiseName && selectedFinaElectronicDeviceName;
334
352
 
335
353
  // ============================================================================
336
354
  // Next Advance Invoice Number Preview
@@ -468,7 +486,13 @@ export default function CreateAdvanceInvoiceForm({
468
486
  // ============================================================================
469
487
  // VIES Check - determine if reverse charge applies
470
488
  // ============================================================================
471
- const { reverseChargeApplies, warning: viesWarning } = useViesCheck({
489
+ const {
490
+ reverseChargeApplies,
491
+ transactionType,
492
+ customerCountryCode: viesCustomerCountryCode,
493
+ isFetching: isViesFetching,
494
+ warning: viesWarning,
495
+ } = useViesCheck({
472
496
  issuerCountryCode: activeEntity?.country_code,
473
497
  isTaxSubject: activeEntity?.is_tax_subject ?? true,
474
498
  customerCountry: formValues.customer?.country,
@@ -477,6 +501,23 @@ export default function CreateAdvanceInvoiceForm({
477
501
  enabled: !!activeEntity,
478
502
  });
479
503
 
504
+ // FINA non-domestic guard: hide FINA selectors for non-domestic transactions
505
+ const isFinaNonDomestic = isFinaEnabled && viesCustomerCountryCode != null && viesCustomerCountryCode !== "HR";
506
+
507
+ // Auto-populate tax_clause from entity settings when transaction type changes
508
+ const effectiveTransactionType = transactionType ?? "domestic";
509
+ const prevTransactionTypeRef = useRef<string | undefined>(undefined);
510
+ useEffect(() => {
511
+ if (effectiveTransactionType === prevTransactionTypeRef.current) return;
512
+ prevTransactionTypeRef.current = effectiveTransactionType;
513
+
514
+ const taxClauseDefaults = (activeEntity?.settings as any)?.tax_clause_defaults;
515
+ if (!taxClauseDefaults) return;
516
+
517
+ const clause = taxClauseDefaults[effectiveTransactionType] ?? "";
518
+ form.setValue("tax_clause", clause);
519
+ }, [effectiveTransactionType, activeEntity, form]);
520
+
480
521
  // Customer form management
481
522
  const {
482
523
  originalCustomer,
@@ -498,10 +539,10 @@ export default function CreateAdvanceInvoiceForm({
498
539
  electronic_device_name: selectedDeviceName,
499
540
  });
500
541
  }
501
- if (isFinaActive && selectedFinaPremiseId && selectedFinaDeviceId) {
542
+ if (isFinaActive && selectedFinaBusinessPremiseName && selectedFinaElectronicDeviceName) {
502
543
  setLastUsedFinaCombo(entityId, {
503
- premise_id: selectedFinaPremiseId,
504
- device_id: selectedFinaDeviceId,
544
+ business_premise_name: selectedFinaBusinessPremiseName,
545
+ electronic_device_name: selectedFinaElectronicDeviceName,
505
546
  });
506
547
  }
507
548
  onSuccess?.(data);
@@ -547,8 +588,16 @@ export default function CreateAdvanceInvoiceForm({
547
588
 
548
589
  // Build FINA options (skip for drafts; FINA can't be skipped)
549
590
  const finaOptions =
550
- !isDraft && isFinaEnabled && selectedFinaPremiseId && selectedFinaDeviceId
551
- ? { premise_id: selectedFinaPremiseId, device_id: selectedFinaDeviceId, payment_type: paymentTypes[0] }
591
+ !isDraft &&
592
+ isFinaEnabled &&
593
+ !isFinaNonDomestic &&
594
+ selectedFinaBusinessPremiseName &&
595
+ selectedFinaElectronicDeviceName
596
+ ? {
597
+ business_premise_name: selectedFinaBusinessPremiseName,
598
+ electronic_device_name: selectedFinaElectronicDeviceName,
599
+ payment_type: paymentTypes[0],
600
+ }
552
601
  : undefined;
553
602
 
554
603
  const payload = prepareAdvanceInvoiceSubmission(values, {
@@ -573,13 +622,14 @@ export default function CreateAdvanceInvoiceForm({
573
622
  isEslogAvailable,
574
623
  isFursEnabled,
575
624
  isFinaEnabled,
625
+ isFinaNonDomestic,
576
626
  markAsPaid,
577
627
  originalCustomer,
578
628
  paymentTypes,
579
629
  selectedDeviceName,
580
630
  selectedPremiseName,
581
- selectedFinaPremiseId,
582
- selectedFinaDeviceId,
631
+ selectedFinaBusinessPremiseName,
632
+ selectedFinaElectronicDeviceName,
583
633
  showCustomerForm,
584
634
  skipFiscalization,
585
635
  ],
@@ -602,7 +652,7 @@ export default function CreateAdvanceInvoiceForm({
602
652
  useFormFooterRegistration({
603
653
  formId: "create-advance-invoice-form",
604
654
  isPending,
605
- isDirty: form.formState.isDirty,
655
+ isDirty: form.formState.isDirty || !!initialValues,
606
656
  label: t("Save"),
607
657
  secondaryAction: {
608
658
  label: t("Save as Draft"),
@@ -611,12 +661,20 @@ export default function CreateAdvanceInvoiceForm({
611
661
  },
612
662
  });
613
663
 
614
- // Set default note from entity settings (advance invoices don't have payment terms)
664
+ // Set default note, footer, and signature from entity settings (advance invoices don't have payment terms)
615
665
  useEffect(() => {
616
666
  const entityDefaultNote = (activeEntity?.settings as any)?.default_invoice_note;
617
667
  if (entityDefaultNote && !form.getValues("note")) {
618
668
  form.setValue("note", entityDefaultNote);
619
669
  }
670
+ const entityDefaultFooter = (activeEntity?.settings as any)?.document_footer;
671
+ if (entityDefaultFooter && !form.getValues("footer")) {
672
+ form.setValue("footer", entityDefaultFooter);
673
+ }
674
+ const entityDefaultSignature = (activeEntity?.settings as any)?.default_document_signature;
675
+ if (entityDefaultSignature && !form.getValues("signature")) {
676
+ form.setValue("signature", entityDefaultSignature);
677
+ }
620
678
  }, [activeEntity, form]);
621
679
 
622
680
  // Auto-add tax field for tax subject entities
@@ -650,7 +708,9 @@ export default function CreateAdvanceInvoiceForm({
650
708
  customer: formValues.customer,
651
709
  items: transformedItems,
652
710
  currency_code: formValues.currency_code,
711
+ reference: formValues.reference,
653
712
  note: formValues.note,
713
+ signature: formValues.signature,
654
714
  };
655
715
  onChange(payload);
656
716
  }
@@ -761,14 +821,20 @@ export default function CreateAdvanceInvoiceForm({
761
821
  : undefined
762
822
  }
763
823
  finaInline={
764
- isFinaEnabled && hasFinaPremises
824
+ isFinaEnabled && hasFinaPremises && !isFinaNonDomestic
765
825
  ? {
766
- premises: activeFinaPremises.map((p: any) => ({ id: p.id, premise_id: p.premise_id })),
767
- devices: activeFinaDevices.map((d: any) => ({ id: d.id, device_id: d.device_id })),
768
- selectedPremise: selectedFinaPremiseId,
769
- selectedDevice: selectedFinaDeviceId,
770
- onPremiseChange: setSelectedFinaPremiseId,
771
- onDeviceChange: setSelectedFinaDeviceId,
826
+ premises: activeFinaPremises.map((p: any) => ({
827
+ id: p.id,
828
+ business_premise_name: p.business_premise_name,
829
+ })),
830
+ devices: activeFinaDevices.map((d: any) => ({
831
+ id: d.id,
832
+ electronic_device_name: d.electronic_device_name,
833
+ })),
834
+ selectedPremise: selectedFinaBusinessPremiseName,
835
+ selectedDevice: selectedFinaElectronicDeviceName,
836
+ onPremiseChange: setSelectedFinaBusinessPremiseName,
837
+ onDeviceChange: setSelectedFinaElectronicDeviceName,
772
838
  }
773
839
  : undefined
774
840
  }
@@ -781,6 +847,7 @@ export default function CreateAdvanceInvoiceForm({
781
847
  onPaymentTypesChange={setPaymentTypes}
782
848
  t={t}
783
849
  alwaysShowPaymentType={!!isFinaActive}
850
+ forced
784
851
  />
785
852
  </DocumentDetailsSection>
786
853
  </div>
@@ -814,6 +881,45 @@ export default function CreateAdvanceInvoiceForm({
814
881
  customer: formValues.customer as any,
815
882
  }}
816
883
  />
884
+
885
+ <DocumentTaxClauseField
886
+ control={form.control}
887
+ t={t}
888
+ entity={activeEntity}
889
+ document={{
890
+ number: formValues.number,
891
+ date: formValues.date,
892
+ currency_code: formValues.currency_code,
893
+ customer: formValues.customer as any,
894
+ }}
895
+ transactionType={transactionType}
896
+ isTransactionTypeFetching={isViesFetching}
897
+ isFinaNonDomestic={isFinaNonDomestic}
898
+ />
899
+
900
+ <DocumentSignatureField
901
+ control={form.control}
902
+ t={t}
903
+ entity={activeEntity}
904
+ document={{
905
+ number: formValues.number,
906
+ date: formValues.date,
907
+ currency_code: formValues.currency_code,
908
+ customer: formValues.customer as any,
909
+ }}
910
+ />
911
+
912
+ <DocumentFooterField
913
+ control={form.control}
914
+ t={t}
915
+ entity={activeEntity}
916
+ document={{
917
+ number: formValues.number,
918
+ date: formValues.date,
919
+ currency_code: formValues.currency_code,
920
+ customer: formValues.customer as any,
921
+ }}
922
+ />
817
923
  </form>
818
924
  </Form>
819
925
  );
@@ -30,4 +30,24 @@ export default {
30
30
  Device: "Gerät",
31
31
  "FINA fiscalized invoices always use the current date":
32
32
  "FINA-fiskalisierte Dokumente verwenden immer das aktuelle Datum",
33
+ // Signature field
34
+ Signature: "Unterschrift",
35
+ "Add signature text...": "Unterschriftstext hinzufügen...",
36
+ // Separator items
37
+ "Add separator": "Trennzeile hinzufügen",
38
+ "Section header": "Abschnittsüberschrift",
39
+ "Section title...": "Abschnittstitel...",
40
+ // Transaction type
41
+ "Transaction type": "Transaktionstyp",
42
+ Domestic: "Inland",
43
+ "EU B2B": "EU B2B",
44
+ "EU B2C": "EU B2C",
45
+ Export: "Export",
46
+ "Determining transaction type...": "Transaktionstyp wird ermittelt...",
47
+ "This invoice will not be fiscalized (non-domestic transaction)":
48
+ "Diese Rechnung wird nicht fiskalisiert (nicht-inländische Transaktion)",
49
+ "Tax Clause": "Steuerklausel",
50
+ "Add tax clause...": "Steuerklausel hinzufügen...",
51
+ Footer: "Fußzeile",
52
+ "Add document footer...": "Dokumentfußzeile hinzufügen...",
33
53
  } as const;
@@ -30,4 +30,24 @@ export default {
30
30
  Device: "Dispositivo",
31
31
  "FINA fiscalized invoices always use the current date":
32
32
  "Los documentos fiscalizados con FINA siempre usan la fecha actual",
33
+ // Signature field
34
+ Signature: "Firma",
35
+ "Add signature text...": "Añadir texto de firma...",
36
+ // Separator items
37
+ "Add separator": "Añadir separador",
38
+ "Section header": "Encabezado de sección",
39
+ "Section title...": "Título de sección...",
40
+ // Transaction type
41
+ "Transaction type": "Tipo de transacción",
42
+ Domestic: "Nacional",
43
+ "EU B2B": "EU B2B",
44
+ "EU B2C": "EU B2C",
45
+ Export: "Exportación",
46
+ "Determining transaction type...": "Determinando tipo de transacción...",
47
+ "This invoice will not be fiscalized (non-domestic transaction)":
48
+ "Esta factura no será fiscalizada (transacción no nacional)",
49
+ "Tax Clause": "Cláusula fiscal",
50
+ "Add tax clause...": "Agregar cláusula fiscal...",
51
+ Footer: "Pie de página",
52
+ "Add document footer...": "Añadir pie de página del documento...",
33
53
  } as const;
@@ -29,4 +29,24 @@ export default {
29
29
  Device: "Appareil",
30
30
  "FINA fiscalized invoices always use the current date":
31
31
  "Les documents fiscalisés FINA utilisent toujours la date actuelle",
32
+ // Signature field
33
+ Signature: "Signature",
34
+ "Add signature text...": "Ajouter un texte de signature...",
35
+ // Separator items
36
+ "Add separator": "Ajouter un séparateur",
37
+ "Section header": "En-tête de section",
38
+ "Section title...": "Titre de section...",
39
+ // Transaction type
40
+ "Transaction type": "Type de transaction",
41
+ Domestic: "Nationale",
42
+ "EU B2B": "EU B2B",
43
+ "EU B2C": "EU B2C",
44
+ Export: "Exportation",
45
+ "Determining transaction type...": "Détermination du type de transaction...",
46
+ "This invoice will not be fiscalized (non-domestic transaction)":
47
+ "Cette facture ne sera pas fiscalisée (transaction non nationale)",
48
+ "Tax Clause": "Clause fiscale",
49
+ "Add tax clause...": "Ajouter une clause fiscale...",
50
+ Footer: "Pied de page",
51
+ "Add document footer...": "Ajouter un pied de page...",
32
52
  } as const;
@@ -27,4 +27,24 @@ export default {
27
27
  Premise: "Prostor",
28
28
  Device: "Uredaj",
29
29
  "FINA fiscalized invoices always use the current date": "FINA fiskalizirani dokumenti uvijek koriste trenutni datum",
30
+ // Signature field
31
+ Signature: "Potpis",
32
+ "Add signature text...": "Dodaj tekst potpisa...",
33
+ // Separator items
34
+ "Add separator": "Dodaj separator",
35
+ "Section header": "Naslov odjeljka",
36
+ "Section title...": "Naslov odjeljka...",
37
+ // Transaction type
38
+ "Transaction type": "Vrsta transakcije",
39
+ Domestic: "Domaća",
40
+ "EU B2B": "EU B2B",
41
+ "EU B2C": "EU B2C",
42
+ Export: "Izvoz",
43
+ "Determining transaction type...": "Određivanje vrste transakcije...",
44
+ "This invoice will not be fiscalized (non-domestic transaction)":
45
+ "Ovaj račun neće biti fiskaliziran (nedomaća transakcija)",
46
+ "Tax Clause": "Porezna klauzula",
47
+ "Add tax clause...": "Dodajte poreznu klauzulu...",
48
+ Footer: "Podnožje",
49
+ "Add document footer...": "Dodajte podnožje dokumenta...",
30
50
  } as const;
@@ -30,4 +30,24 @@ export default {
30
30
  Device: "Dispositivo",
31
31
  "FINA fiscalized invoices always use the current date":
32
32
  "I documenti fiscalizzati FINA utilizzano sempre la data corrente",
33
+ // Signature field
34
+ Signature: "Firma",
35
+ "Add signature text...": "Aggiungi testo della firma...",
36
+ // Separator items
37
+ "Add separator": "Aggiungi separatore",
38
+ "Section header": "Intestazione sezione",
39
+ "Section title...": "Titolo sezione...",
40
+ // Transaction type
41
+ "Transaction type": "Tipo di transazione",
42
+ Domestic: "Nazionale",
43
+ "EU B2B": "EU B2B",
44
+ "EU B2C": "EU B2C",
45
+ Export: "Esportazione",
46
+ "Determining transaction type...": "Determinazione tipo di transazione...",
47
+ "This invoice will not be fiscalized (non-domestic transaction)":
48
+ "Questa fattura non sarà fiscalizzata (transazione non nazionale)",
49
+ "Tax Clause": "Clausola fiscale",
50
+ "Add tax clause...": "Aggiungi clausola fiscale...",
51
+ Footer: "Piè di pagina",
52
+ "Add document footer...": "Aggiungi piè di pagina del documento...",
33
53
  } as const;
@@ -29,4 +29,24 @@ export default {
29
29
  Device: "Apparaat",
30
30
  "FINA fiscalized invoices always use the current date":
31
31
  "FINA-gefiscaliseerde documenten gebruiken altijd de huidige datum",
32
+ // Signature field
33
+ Signature: "Handtekening",
34
+ "Add signature text...": "Handtekeningtekst toevoegen...",
35
+ // Separator items
36
+ "Add separator": "Scheidingslijn toevoegen",
37
+ "Section header": "Sectiekop",
38
+ "Section title...": "Sectietitel...",
39
+ // Transaction type
40
+ "Transaction type": "Transactietype",
41
+ Domestic: "Binnenland",
42
+ "EU B2B": "EU B2B",
43
+ "EU B2C": "EU B2C",
44
+ Export: "Export",
45
+ "Determining transaction type...": "Transactietype bepalen...",
46
+ "This invoice will not be fiscalized (non-domestic transaction)":
47
+ "Deze factuur wordt niet gefiscaliseerd (niet-binnenlandse transactie)",
48
+ "Tax Clause": "Belastingclausule",
49
+ "Add tax clause...": "Belastingclausule toevoegen...",
50
+ Footer: "Voettekst",
51
+ "Add document footer...": "Documentvoettekst toevoegen...",
32
52
  } as const;
@@ -28,4 +28,24 @@ export default {
28
28
  Premise: "Lokal",
29
29
  Device: "Urządzenie",
30
30
  "FINA fiscalized invoices always use the current date": "Dokumenty fiskalizowane FINA zawsze używają bieżącej daty",
31
+ // Signature field
32
+ Signature: "Podpis",
33
+ "Add signature text...": "Dodaj tekst podpisu...",
34
+ // Separator items
35
+ "Add separator": "Dodaj separator",
36
+ "Section header": "Nagłówek sekcji",
37
+ "Section title...": "Tytuł sekcji...",
38
+ // Transaction type
39
+ "Transaction type": "Typ transakcji",
40
+ Domestic: "Krajowa",
41
+ "EU B2B": "EU B2B",
42
+ "EU B2C": "EU B2C",
43
+ Export: "Eksport",
44
+ "Determining transaction type...": "Określanie typu transakcji...",
45
+ "This invoice will not be fiscalized (non-domestic transaction)":
46
+ "Ta faktura nie będzie fiskalizowana (transakcja niekrajowa)",
47
+ "Tax Clause": "Klauzula podatkowa",
48
+ "Add tax clause...": "Dodaj klauzulę podatkową...",
49
+ Footer: "Stopka",
50
+ "Add document footer...": "Dodaj stopkę dokumentu...",
31
51
  } as const;
@@ -29,4 +29,24 @@ export default {
29
29
  Premise: "Estabelecimento",
30
30
  Device: "Dispositivo",
31
31
  "FINA fiscalized invoices always use the current date": "Os documentos fiscalizados FINA usam sempre a data atual",
32
+ // Signature field
33
+ Signature: "Assinatura",
34
+ "Add signature text...": "Adicionar texto de assinatura...",
35
+ // Separator items
36
+ "Add separator": "Adicionar separador",
37
+ "Section header": "Cabeçalho da secção",
38
+ "Section title...": "Título da secção...",
39
+ // Transaction type
40
+ "Transaction type": "Tipo de transação",
41
+ Domestic: "Nacional",
42
+ "EU B2B": "EU B2B",
43
+ "EU B2C": "EU B2C",
44
+ Export: "Exportação",
45
+ "Determining transaction type...": "Determinando tipo de transação...",
46
+ "This invoice will not be fiscalized (non-domestic transaction)":
47
+ "Esta fatura não será fiscalizada (transação não nacional)",
48
+ "Tax Clause": "Cláusula fiscal",
49
+ "Add tax clause...": "Adicionar cláusula fiscal...",
50
+ Footer: "Rodapé",
51
+ "Add document footer...": "Adicionar rodapé do documento...",
32
52
  } as const;
@@ -25,4 +25,24 @@ export default {
25
25
  Premise: "Poslovni prostor",
26
26
  Device: "Naprava",
27
27
  "FINA fiscalized invoices always use the current date": "FINA fiskalizirani dokumenti vedno uporabijo trenutni datum",
28
+ // Signature field
29
+ Signature: "Podpis",
30
+ "Add signature text...": "Dodaj besedilo podpisa...",
31
+ // Separator items
32
+ "Add separator": "Dodaj ločilnik",
33
+ "Section header": "Naslov razdelka",
34
+ "Section title...": "Naslov razdelka...",
35
+ // Transaction type
36
+ "Transaction type": "Vrsta transakcije",
37
+ Domestic: "Domača",
38
+ "EU B2B": "EU B2B",
39
+ "EU B2C": "EU B2C",
40
+ Export: "Izvoz",
41
+ "Determining transaction type...": "Določanje vrste transakcije...",
42
+ "This invoice will not be fiscalized (non-domestic transaction)":
43
+ "Ta račun ne bo fiskaliziran (nedomača transakcija)",
44
+ "Tax Clause": "Davčna klavzula",
45
+ "Add tax clause...": "Dodajte davčno klavzulo...",
46
+ Footer: "Noga dokumenta",
47
+ "Add document footer...": "Dodajte nogo dokumenta...",
28
48
  } as const;
@@ -9,8 +9,8 @@ type FursData = {
9
9
  };
10
10
 
11
11
  type FinaData = {
12
- premise_id?: string;
13
- device_id?: string;
12
+ business_premise_name?: string;
13
+ electronic_device_name?: string;
14
14
  payment_type?: string;
15
15
  };
16
16
 
@@ -71,10 +71,10 @@ export function prepareAdvanceInvoiceSubmission(
71
71
  }
72
72
 
73
73
  // Add FINA data if provided (FINA can't be skipped - all invoices must be fiscalized)
74
- if (options.fina?.premise_id && options.fina.device_id) {
74
+ if (options.fina?.business_premise_name && options.fina.electronic_device_name) {
75
75
  (payload as any).fina = {
76
- premise_id: options.fina.premise_id,
77
- device_id: options.fina.device_id,
76
+ business_premise_name: options.fina.business_premise_name,
77
+ electronic_device_name: options.fina.electronic_device_name,
78
78
  ...(options.fina.payment_type && { payment_type: options.fina.payment_type }),
79
79
  };
80
80
  }