@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.
- package/cli/dist/index.js +1 -1
- package/package.json +1 -1
- package/src/components/advance-invoices/create/create-advance-invoice-form.tsx +61 -11
- package/src/components/advance-invoices/create/locales/de.ts +15 -0
- package/src/components/advance-invoices/create/locales/es.ts +15 -0
- package/src/components/advance-invoices/create/locales/fr.ts +15 -0
- package/src/components/advance-invoices/create/locales/hr.ts +15 -0
- package/src/components/advance-invoices/create/locales/it.ts +15 -0
- package/src/components/advance-invoices/create/locales/nl.ts +15 -0
- package/src/components/advance-invoices/create/locales/pl.ts +15 -0
- package/src/components/advance-invoices/create/locales/pt.ts +15 -0
- package/src/components/advance-invoices/create/locales/sl.ts +15 -0
- package/src/components/advance-invoices/list/list-row-actions.tsx +48 -1
- package/src/components/advance-invoices/list/list-table.tsx +21 -1
- package/src/components/advance-invoices/list/locales/de.ts +4 -0
- package/src/components/advance-invoices/list/locales/en.ts +3 -0
- package/src/components/advance-invoices/list/locales/es.ts +4 -0
- package/src/components/advance-invoices/list/locales/fr.ts +4 -0
- package/src/components/advance-invoices/list/locales/hr.ts +3 -0
- package/src/components/advance-invoices/list/locales/it.ts +4 -0
- package/src/components/advance-invoices/list/locales/nl.ts +4 -0
- package/src/components/advance-invoices/list/locales/pl.ts +3 -0
- package/src/components/advance-invoices/list/locales/pt.ts +4 -0
- package/src/components/advance-invoices/list/locales/sl.ts +3 -0
- package/src/components/credit-notes/create/create-credit-note-form.tsx +71 -8
- package/src/components/credit-notes/create/locales/de.ts +16 -0
- package/src/components/credit-notes/create/locales/es.ts +16 -0
- package/src/components/credit-notes/create/locales/fr.ts +16 -0
- package/src/components/credit-notes/create/locales/hr.ts +16 -0
- package/src/components/credit-notes/create/locales/it.ts +16 -0
- package/src/components/credit-notes/create/locales/nl.ts +16 -0
- package/src/components/credit-notes/create/locales/pl.ts +16 -0
- package/src/components/credit-notes/create/locales/pt.ts +16 -0
- package/src/components/credit-notes/create/locales/sl.ts +17 -1
- package/src/components/credit-notes/list/list-row-actions.tsx +44 -1
- package/src/components/credit-notes/list/list-table.tsx +16 -2
- package/src/components/credit-notes/list/locales/de.ts +2 -0
- package/src/components/credit-notes/list/locales/en.ts +2 -0
- package/src/components/credit-notes/list/locales/es.ts +2 -0
- package/src/components/credit-notes/list/locales/fr.ts +2 -0
- package/src/components/credit-notes/list/locales/hr.ts +2 -0
- package/src/components/credit-notes/list/locales/it.ts +2 -0
- package/src/components/credit-notes/list/locales/nl.ts +2 -0
- package/src/components/credit-notes/list/locales/pl.ts +2 -0
- package/src/components/credit-notes/list/locales/pt.ts +2 -0
- package/src/components/credit-notes/list/locales/sl.ts +2 -0
- package/src/components/dashboard/collection-rate-card/use-collection-rate.ts +48 -9
- package/src/components/dashboard/revenue-trend-chart/use-revenue-trend.ts +77 -48
- package/src/components/dashboard/shared/use-revenue-data.ts +77 -9
- package/src/components/delivery-notes/create/create-delivery-note-form.tsx +67 -7
- package/src/components/delivery-notes/create/locales/de.ts +16 -0
- package/src/components/delivery-notes/create/locales/es.ts +16 -0
- package/src/components/delivery-notes/create/locales/fr.ts +16 -0
- package/src/components/delivery-notes/create/locales/hr.ts +16 -0
- package/src/components/delivery-notes/create/locales/it.ts +16 -0
- package/src/components/delivery-notes/create/locales/nl.ts +16 -0
- package/src/components/delivery-notes/create/locales/pl.ts +16 -0
- package/src/components/delivery-notes/create/locales/pt.ts +16 -0
- package/src/components/delivery-notes/create/locales/sl.ts +17 -1
- package/src/components/delivery-notes/list/list-table.tsx +17 -8
- package/src/components/delivery-notes/list/locales/de.ts +32 -1
- package/src/components/delivery-notes/list/locales/en.ts +31 -0
- package/src/components/delivery-notes/list/locales/es.ts +32 -1
- package/src/components/delivery-notes/list/locales/fr.ts +32 -1
- package/src/components/delivery-notes/list/locales/hr.ts +32 -1
- package/src/components/delivery-notes/list/locales/it.ts +32 -1
- package/src/components/delivery-notes/list/locales/nl.ts +32 -1
- package/src/components/delivery-notes/list/locales/pl.ts +32 -1
- package/src/components/delivery-notes/list/locales/pt.ts +32 -1
- package/src/components/delivery-notes/list/locales/sl.ts +32 -1
- package/src/components/documents/create/document-add-item-form.tsx +70 -0
- package/src/components/documents/create/document-details-section.tsx +122 -2
- package/src/components/documents/create/document-items-section.tsx +21 -4
- package/src/components/documents/create/live-preview.tsx +24 -4
- package/src/components/documents/create/mark-as-paid-section.tsx +29 -20
- package/src/components/documents/create/prepare-document-submission.ts +19 -7
- package/src/components/documents/shared/document-preview-display.tsx +3 -4
- package/src/components/documents/view/document-actions-bar.tsx +7 -27
- package/src/components/documents/view/document-details-card.tsx +26 -9
- package/src/components/documents/view/locales/de.ts +2 -0
- package/src/components/documents/view/locales/es.ts +2 -0
- package/src/components/documents/view/locales/fr.ts +2 -0
- package/src/components/documents/view/locales/hr.ts +2 -0
- package/src/components/documents/view/locales/it.ts +2 -0
- package/src/components/documents/view/locales/nl.ts +2 -0
- package/src/components/documents/view/locales/pl.ts +2 -0
- package/src/components/documents/view/locales/pt.ts +2 -0
- package/src/components/documents/view/locales/sl.ts +3 -1
- package/src/components/documents/view/use-document-download.ts +6 -3
- package/src/components/entities/create-entity-form.tsx +2 -1
- package/src/components/entities/entity-settings-form/input-with-preview.tsx +30 -2
- package/src/components/entities/entity-settings-form/locales/de.ts +1 -0
- package/src/components/entities/entity-settings-form/locales/es.ts +1 -0
- package/src/components/entities/entity-settings-form/locales/fr.ts +1 -0
- package/src/components/entities/entity-settings-form/locales/hr.ts +1 -0
- package/src/components/entities/entity-settings-form/locales/it.ts +1 -0
- package/src/components/entities/entity-settings-form/locales/nl.ts +1 -0
- package/src/components/entities/entity-settings-form/locales/pl.ts +1 -0
- package/src/components/entities/entity-settings-form/locales/pt.ts +1 -0
- package/src/components/entities/entity-settings-form/locales/sl.ts +1 -0
- package/src/components/entities/settings/company-settings-form.tsx +173 -20
- package/src/components/estimates/create/create-estimate-form.tsx +64 -6
- package/src/components/estimates/create/locales/de.ts +16 -0
- package/src/components/estimates/create/locales/es.ts +16 -0
- package/src/components/estimates/create/locales/fr.ts +16 -0
- package/src/components/estimates/create/locales/hr.ts +16 -0
- package/src/components/estimates/create/locales/it.ts +16 -0
- package/src/components/estimates/create/locales/nl.ts +16 -0
- package/src/components/estimates/create/locales/pl.ts +16 -0
- package/src/components/estimates/create/locales/pt.ts +16 -0
- package/src/components/estimates/create/locales/sl.ts +17 -1
- package/src/components/estimates/list/list-table.tsx +11 -2
- package/src/components/estimates/list/locales/de.ts +1 -0
- package/src/components/estimates/list/locales/en.ts +1 -0
- package/src/components/estimates/list/locales/es.ts +1 -0
- package/src/components/estimates/list/locales/fr.ts +1 -0
- package/src/components/estimates/list/locales/hr.ts +1 -0
- package/src/components/estimates/list/locales/it.ts +1 -0
- package/src/components/estimates/list/locales/nl.ts +1 -0
- package/src/components/estimates/list/locales/pl.ts +1 -0
- package/src/components/estimates/list/locales/pt.ts +1 -0
- package/src/components/estimates/list/locales/sl.ts +1 -0
- package/src/components/export/document-export-form.tsx +46 -12
- package/src/components/invoices/create/create-invoice-form.tsx +58 -10
- package/src/components/invoices/create/locales/de.ts +15 -0
- package/src/components/invoices/create/locales/es.ts +15 -0
- package/src/components/invoices/create/locales/fr.ts +15 -0
- package/src/components/invoices/create/locales/hr.ts +15 -0
- package/src/components/invoices/create/locales/it.ts +15 -0
- package/src/components/invoices/create/locales/nl.ts +15 -0
- package/src/components/invoices/create/locales/pl.ts +15 -0
- package/src/components/invoices/create/locales/pt.ts +15 -0
- package/src/components/invoices/create/locales/sl.ts +16 -1
- package/src/components/invoices/view/fiscalization-status-card.tsx +10 -8
- package/src/components/table/search-input.tsx +17 -0
- package/src/generated/schemas/advanceinvoice.ts +4 -2
- package/src/generated/schemas/creditnote.ts +2 -1
- package/src/generated/schemas/deliverynote.ts +2 -1
- package/src/generated/schemas/estimate.ts +4 -2
- package/src/generated/schemas/invoice.ts +2 -1
- package/src/generated/schemas/renderadvanceinvoicepreview_body.ts +17 -23
- package/src/generated/schemas/rendercreditnotepreview_body.ts +17 -23
- package/src/generated/schemas/renderdeliverynotepreview_body.ts +17 -23
- package/src/generated/schemas/renderestimatepreview_body.ts +17 -23
- package/src/generated/schemas/renderinvoicepreview_body.ts +19 -23
- package/src/hooks/use-duplicate-document.ts +16 -9
- package/src/hooks/use-vies-check.ts +3 -0
|
@@ -9,6 +9,7 @@ import { Form } from "@/ui/components/ui/form";
|
|
|
9
9
|
import { Skeleton } from "@/ui/components/ui/skeleton";
|
|
10
10
|
import { createCreditNoteSchema } from "@/ui/generated/schemas";
|
|
11
11
|
import { useNextDocumentNumber } from "@/ui/hooks/use-next-document-number";
|
|
12
|
+
import { useViesCheck } from "@/ui/hooks/use-vies-check";
|
|
12
13
|
import type { ComponentTranslationProps } from "@/ui/lib/translation";
|
|
13
14
|
import { createTranslation } from "@/ui/lib/translation";
|
|
14
15
|
import { useEntities } from "@/ui/providers/entities-context";
|
|
@@ -18,6 +19,7 @@ import {
|
|
|
18
19
|
DocumentDetailsSection,
|
|
19
20
|
DocumentNoteField,
|
|
20
21
|
DocumentPaymentTermsField,
|
|
22
|
+
DocumentTaxClauseField,
|
|
21
23
|
} from "../../documents/create/document-details-section";
|
|
22
24
|
import { DocumentItemsSection, type PriceModesMap } from "../../documents/create/document-items-section";
|
|
23
25
|
import { DocumentRecipientSection } from "../../documents/create/document-recipient-section";
|
|
@@ -275,13 +277,18 @@ export default function CreateCreditNoteForm({
|
|
|
275
277
|
// Cast customer to form schema type (API type may have additional fields)
|
|
276
278
|
customer: (initialValues?.customer as CreateCreditNoteFormValues["customer"]) ?? undefined,
|
|
277
279
|
items: initialValues?.items?.length
|
|
278
|
-
? initialValues.items.map((item) => ({
|
|
280
|
+
? initialValues.items.map((item: any) => ({
|
|
281
|
+
type: item.type,
|
|
279
282
|
name: item.name || "",
|
|
280
283
|
description: item.description || "",
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
284
|
+
...(item.type !== "separator"
|
|
285
|
+
? {
|
|
286
|
+
quantity: item.quantity ?? 1,
|
|
287
|
+
// Use gross_price if set, otherwise use price
|
|
288
|
+
price: item.gross_price ?? item.price,
|
|
289
|
+
taxes: item.taxes || [],
|
|
290
|
+
}
|
|
291
|
+
: {}),
|
|
285
292
|
}))
|
|
286
293
|
: [
|
|
287
294
|
{
|
|
@@ -294,6 +301,7 @@ export default function CreateCreditNoteForm({
|
|
|
294
301
|
],
|
|
295
302
|
currency_code: initialValues?.currency_code || activeEntity?.currency_code || "EUR",
|
|
296
303
|
note: initialValues?.note ?? "",
|
|
304
|
+
tax_clause: (initialValues as any)?.tax_clause ?? "",
|
|
297
305
|
payment_terms: initialValues?.payment_terms ?? defaultPaymentTerms,
|
|
298
306
|
},
|
|
299
307
|
});
|
|
@@ -302,6 +310,41 @@ export default function CreateCreditNoteForm({
|
|
|
302
310
|
control: form.control,
|
|
303
311
|
});
|
|
304
312
|
|
|
313
|
+
// ============================================================================
|
|
314
|
+
// VIES Check - determine if reverse charge applies
|
|
315
|
+
// ============================================================================
|
|
316
|
+
const {
|
|
317
|
+
reverseChargeApplies,
|
|
318
|
+
transactionType,
|
|
319
|
+
customerCountryCode: viesCustomerCountryCode,
|
|
320
|
+
isFetching: isViesFetching,
|
|
321
|
+
warning: viesWarning,
|
|
322
|
+
} = useViesCheck({
|
|
323
|
+
issuerCountryCode: activeEntity?.country_code,
|
|
324
|
+
isTaxSubject: activeEntity?.is_tax_subject ?? true,
|
|
325
|
+
customerCountry: formValues.customer?.country,
|
|
326
|
+
customerCountryCode: formValues.customer?.country_code,
|
|
327
|
+
customerTaxNumber: formValues.customer?.tax_number,
|
|
328
|
+
enabled: !!activeEntity,
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
// FINA non-domestic guard: hide FINA selectors for non-domestic transactions
|
|
332
|
+
const isFinaNonDomestic = isFinaEnabled && viesCustomerCountryCode != null && viesCustomerCountryCode !== "HR";
|
|
333
|
+
|
|
334
|
+
// Auto-populate tax_clause from entity settings when transaction type changes
|
|
335
|
+
const effectiveTransactionType = transactionType ?? "domestic";
|
|
336
|
+
const prevTransactionTypeRef = useRef<string | undefined>(undefined);
|
|
337
|
+
useEffect(() => {
|
|
338
|
+
if (effectiveTransactionType === prevTransactionTypeRef.current) return;
|
|
339
|
+
prevTransactionTypeRef.current = effectiveTransactionType;
|
|
340
|
+
|
|
341
|
+
const taxClauseDefaults = (activeEntity?.settings as any)?.tax_clause_defaults;
|
|
342
|
+
if (!taxClauseDefaults) return;
|
|
343
|
+
|
|
344
|
+
const clause = taxClauseDefaults[effectiveTransactionType] ?? "";
|
|
345
|
+
form.setValue("tax_clause", clause);
|
|
346
|
+
}, [effectiveTransactionType, activeEntity, form]);
|
|
347
|
+
|
|
305
348
|
// Extract customer management logic into a shared hook
|
|
306
349
|
const {
|
|
307
350
|
originalCustomer,
|
|
@@ -357,7 +400,7 @@ export default function CreateCreditNoteForm({
|
|
|
357
400
|
|
|
358
401
|
// Build FINA options (skip for drafts; FINA can't be skipped)
|
|
359
402
|
const finaOptions =
|
|
360
|
-
!isDraft && isFinaEnabled && selectedFinaPremiseId && selectedFinaDeviceId
|
|
403
|
+
!isDraft && isFinaEnabled && !isFinaNonDomestic && selectedFinaPremiseId && selectedFinaDeviceId
|
|
361
404
|
? { premise_id: selectedFinaPremiseId, device_id: selectedFinaDeviceId, payment_type: paymentTypes[0] }
|
|
362
405
|
: undefined;
|
|
363
406
|
|
|
@@ -387,6 +430,7 @@ export default function CreateCreditNoteForm({
|
|
|
387
430
|
createCreditNote,
|
|
388
431
|
isFursEnabled,
|
|
389
432
|
isFinaEnabled,
|
|
433
|
+
isFinaNonDomestic,
|
|
390
434
|
markAsPaid,
|
|
391
435
|
originalCustomer,
|
|
392
436
|
paymentTypes,
|
|
@@ -415,7 +459,7 @@ export default function CreateCreditNoteForm({
|
|
|
415
459
|
useFormFooterRegistration({
|
|
416
460
|
formId: "create-credit-note-form",
|
|
417
461
|
isPending,
|
|
418
|
-
isDirty: form.formState.isDirty,
|
|
462
|
+
isDirty: form.formState.isDirty || !!initialValues,
|
|
419
463
|
label: t("Save"),
|
|
420
464
|
secondaryAction: {
|
|
421
465
|
label: t("Save as Draft"),
|
|
@@ -561,7 +605,7 @@ export default function CreateCreditNoteForm({
|
|
|
561
605
|
: undefined
|
|
562
606
|
}
|
|
563
607
|
finaInline={
|
|
564
|
-
isFinaEnabled && hasFinaPremises
|
|
608
|
+
isFinaEnabled && hasFinaPremises && !isFinaNonDomestic
|
|
565
609
|
? {
|
|
566
610
|
premises: activeFinaPremises.map((p: any) => ({ id: p.id, premise_id: p.premise_id })),
|
|
567
611
|
devices: activeFinaDevices.map((d: any) => ({ id: d.id, device_id: d.device_id })),
|
|
@@ -597,6 +641,10 @@ export default function CreateCreditNoteForm({
|
|
|
597
641
|
maxTaxesPerItem={activeEntity?.country_rules?.max_taxes_per_item}
|
|
598
642
|
priceModesRef={priceModesRef}
|
|
599
643
|
initialPriceModes={initialPriceModes}
|
|
644
|
+
taxesDisabled={reverseChargeApplies}
|
|
645
|
+
taxesDisabledMessage={
|
|
646
|
+
reverseChargeApplies ? t("Reverse charge - tax exempt EU B2B sale") : viesWarning ? viesWarning : undefined
|
|
647
|
+
}
|
|
600
648
|
/>
|
|
601
649
|
|
|
602
650
|
<DocumentNoteField
|
|
@@ -611,6 +659,21 @@ export default function CreateCreditNoteForm({
|
|
|
611
659
|
}}
|
|
612
660
|
/>
|
|
613
661
|
|
|
662
|
+
<DocumentTaxClauseField
|
|
663
|
+
control={form.control}
|
|
664
|
+
t={t}
|
|
665
|
+
entity={activeEntity}
|
|
666
|
+
document={{
|
|
667
|
+
number: formValues.number,
|
|
668
|
+
date: formValues.date,
|
|
669
|
+
currency_code: formValues.currency_code,
|
|
670
|
+
customer: formValues.customer as any,
|
|
671
|
+
}}
|
|
672
|
+
transactionType={transactionType}
|
|
673
|
+
isTransactionTypeFetching={isViesFetching}
|
|
674
|
+
isFinaNonDomestic={isFinaNonDomestic}
|
|
675
|
+
/>
|
|
676
|
+
|
|
614
677
|
<DocumentPaymentTermsField
|
|
615
678
|
control={form.control}
|
|
616
679
|
t={t}
|
|
@@ -76,4 +76,20 @@ export default {
|
|
|
76
76
|
Device: "Gerät",
|
|
77
77
|
"FINA fiscalized invoices always use the current date":
|
|
78
78
|
"FINA-fiskalisierte Dokumente verwenden immer das aktuelle Datum",
|
|
79
|
+
// Separator items
|
|
80
|
+
"Add separator": "Trennzeile hinzufügen",
|
|
81
|
+
"Section header": "Abschnittsüberschrift",
|
|
82
|
+
"Section title...": "Abschnittstitel...",
|
|
83
|
+
// Transaction type
|
|
84
|
+
"Transaction type": "Transaktionstyp",
|
|
85
|
+
Domestic: "Inland",
|
|
86
|
+
"EU B2B": "EU B2B",
|
|
87
|
+
"EU B2C": "EU B2C",
|
|
88
|
+
Export: "Export",
|
|
89
|
+
"Determining transaction type...": "Transaktionstyp wird ermittelt...",
|
|
90
|
+
"This invoice will not be fiscalized (non-domestic transaction)":
|
|
91
|
+
"Diese Rechnung wird nicht fiskalisiert (nicht-inländische Transaktion)",
|
|
92
|
+
"Tax Clause": "Steuerklausel",
|
|
93
|
+
"Add tax clause...": "Steuerklausel hinzufügen...",
|
|
94
|
+
"Reverse charge - tax exempt EU B2B sale": "Umkehrung der Steuerschuldnerschaft - steuerbefreiter EU B2B Verkauf",
|
|
79
95
|
} as const;
|
|
@@ -75,4 +75,20 @@ export default {
|
|
|
75
75
|
Device: "Dispositivo",
|
|
76
76
|
"FINA fiscalized invoices always use the current date":
|
|
77
77
|
"Los documentos fiscalizados con FINA siempre usan la fecha actual",
|
|
78
|
+
// Separator items
|
|
79
|
+
"Add separator": "Añadir separador",
|
|
80
|
+
"Section header": "Encabezado de sección",
|
|
81
|
+
"Section title...": "Título de sección...",
|
|
82
|
+
// Transaction type
|
|
83
|
+
"Transaction type": "Tipo de transacción",
|
|
84
|
+
Domestic: "Nacional",
|
|
85
|
+
"EU B2B": "EU B2B",
|
|
86
|
+
"EU B2C": "EU B2C",
|
|
87
|
+
Export: "Exportación",
|
|
88
|
+
"Determining transaction type...": "Determinando tipo de transacción...",
|
|
89
|
+
"This invoice will not be fiscalized (non-domestic transaction)":
|
|
90
|
+
"Esta factura no será fiscalizada (transacción no nacional)",
|
|
91
|
+
"Tax Clause": "Cláusula fiscal",
|
|
92
|
+
"Add tax clause...": "Agregar cláusula fiscal...",
|
|
93
|
+
"Reverse charge - tax exempt EU B2B sale": "Inversión del sujeto pasivo - venta EU B2B exenta de impuestos",
|
|
78
94
|
} as const;
|
|
@@ -75,4 +75,20 @@ export default {
|
|
|
75
75
|
Device: "Appareil",
|
|
76
76
|
"FINA fiscalized invoices always use the current date":
|
|
77
77
|
"Les documents fiscalisés FINA utilisent toujours la date actuelle",
|
|
78
|
+
// Separator items
|
|
79
|
+
"Add separator": "Ajouter un séparateur",
|
|
80
|
+
"Section header": "En-tête de section",
|
|
81
|
+
"Section title...": "Titre de section...",
|
|
82
|
+
// Transaction type
|
|
83
|
+
"Transaction type": "Type de transaction",
|
|
84
|
+
Domestic: "Nationale",
|
|
85
|
+
"EU B2B": "EU B2B",
|
|
86
|
+
"EU B2C": "EU B2C",
|
|
87
|
+
Export: "Exportation",
|
|
88
|
+
"Determining transaction type...": "Détermination du type de transaction...",
|
|
89
|
+
"This invoice will not be fiscalized (non-domestic transaction)":
|
|
90
|
+
"Cette facture ne sera pas fiscalisée (transaction non nationale)",
|
|
91
|
+
"Tax Clause": "Clause fiscale",
|
|
92
|
+
"Add tax clause...": "Ajouter une clause fiscale...",
|
|
93
|
+
"Reverse charge - tax exempt EU B2B sale": "Autoliquidation - vente B2B UE exonérée de taxe",
|
|
78
94
|
} as const;
|
|
@@ -73,4 +73,20 @@ export default {
|
|
|
73
73
|
Premise: "Prostor",
|
|
74
74
|
Device: "Uredaj",
|
|
75
75
|
"FINA fiscalized invoices always use the current date": "FINA fiskalizirani dokumenti uvijek koriste trenutni datum",
|
|
76
|
+
// Separator items
|
|
77
|
+
"Add separator": "Dodaj separator",
|
|
78
|
+
"Section header": "Naslov odjeljka",
|
|
79
|
+
"Section title...": "Naslov odjeljka...",
|
|
80
|
+
// Transaction type
|
|
81
|
+
"Transaction type": "Vrsta transakcije",
|
|
82
|
+
Domestic: "Domaća",
|
|
83
|
+
"EU B2B": "EU B2B",
|
|
84
|
+
"EU B2C": "EU B2C",
|
|
85
|
+
Export: "Izvoz",
|
|
86
|
+
"Determining transaction type...": "Određivanje vrste transakcije...",
|
|
87
|
+
"This invoice will not be fiscalized (non-domestic transaction)":
|
|
88
|
+
"Ovaj račun neće biti fiskaliziran (nedomaća transakcija)",
|
|
89
|
+
"Tax Clause": "Porezna klauzula",
|
|
90
|
+
"Add tax clause...": "Dodajte poreznu klauzulu...",
|
|
91
|
+
"Reverse charge - tax exempt EU B2B sale": "Prijenos porezne obveze - porezno oslobođena EU B2B prodaja",
|
|
76
92
|
} as const;
|
|
@@ -76,4 +76,20 @@ export default {
|
|
|
76
76
|
Device: "Dispositivo",
|
|
77
77
|
"FINA fiscalized invoices always use the current date":
|
|
78
78
|
"I documenti fiscalizzati FINA utilizzano sempre la data corrente",
|
|
79
|
+
// Separator items
|
|
80
|
+
"Add separator": "Aggiungi separatore",
|
|
81
|
+
"Section header": "Intestazione sezione",
|
|
82
|
+
"Section title...": "Titolo sezione...",
|
|
83
|
+
// Transaction type
|
|
84
|
+
"Transaction type": "Tipo di transazione",
|
|
85
|
+
Domestic: "Nazionale",
|
|
86
|
+
"EU B2B": "EU B2B",
|
|
87
|
+
"EU B2C": "EU B2C",
|
|
88
|
+
Export: "Esportazione",
|
|
89
|
+
"Determining transaction type...": "Determinazione tipo di transazione...",
|
|
90
|
+
"This invoice will not be fiscalized (non-domestic transaction)":
|
|
91
|
+
"Questa fattura non sarà fiscalizzata (transazione non nazionale)",
|
|
92
|
+
"Tax Clause": "Clausola fiscale",
|
|
93
|
+
"Add tax clause...": "Aggiungi clausola fiscale...",
|
|
94
|
+
"Reverse charge - tax exempt EU B2B sale": "Inversione contabile - vendita B2B UE esente da imposta",
|
|
79
95
|
} as const;
|
|
@@ -75,4 +75,20 @@ export default {
|
|
|
75
75
|
Device: "Apparaat",
|
|
76
76
|
"FINA fiscalized invoices always use the current date":
|
|
77
77
|
"FINA-gefiscaliseerde documenten gebruiken altijd de huidige datum",
|
|
78
|
+
// Separator items
|
|
79
|
+
"Add separator": "Scheidingslijn toevoegen",
|
|
80
|
+
"Section header": "Sectiekop",
|
|
81
|
+
"Section title...": "Sectietitel...",
|
|
82
|
+
// Transaction type
|
|
83
|
+
"Transaction type": "Transactietype",
|
|
84
|
+
Domestic: "Binnenland",
|
|
85
|
+
"EU B2B": "EU B2B",
|
|
86
|
+
"EU B2C": "EU B2C",
|
|
87
|
+
Export: "Export",
|
|
88
|
+
"Determining transaction type...": "Transactietype bepalen...",
|
|
89
|
+
"This invoice will not be fiscalized (non-domestic transaction)":
|
|
90
|
+
"Deze factuur wordt niet gefiscaliseerd (niet-binnenlandse transactie)",
|
|
91
|
+
"Tax Clause": "Belastingclausule",
|
|
92
|
+
"Add tax clause...": "Belastingclausule toevoegen...",
|
|
93
|
+
"Reverse charge - tax exempt EU B2B sale": "Verlegging - belastingvrijgestelde EU B2B verkoop",
|
|
78
94
|
} as const;
|
|
@@ -73,4 +73,20 @@ export default {
|
|
|
73
73
|
Premise: "Lokal",
|
|
74
74
|
Device: "Urządzenie",
|
|
75
75
|
"FINA fiscalized invoices always use the current date": "Dokumenty fiskalizowane FINA zawsze używają bieżącej daty",
|
|
76
|
+
// Separator items
|
|
77
|
+
"Add separator": "Dodaj separator",
|
|
78
|
+
"Section header": "Nagłówek sekcji",
|
|
79
|
+
"Section title...": "Tytuł sekcji...",
|
|
80
|
+
// Transaction type
|
|
81
|
+
"Transaction type": "Typ transakcji",
|
|
82
|
+
Domestic: "Krajowa",
|
|
83
|
+
"EU B2B": "EU B2B",
|
|
84
|
+
"EU B2C": "EU B2C",
|
|
85
|
+
Export: "Eksport",
|
|
86
|
+
"Determining transaction type...": "Określanie typu transakcji...",
|
|
87
|
+
"This invoice will not be fiscalized (non-domestic transaction)":
|
|
88
|
+
"Ta faktura nie będzie fiskalizowana (transakcja niekrajowa)",
|
|
89
|
+
"Tax Clause": "Klauzula podatkowa",
|
|
90
|
+
"Add tax clause...": "Dodaj klauzulę podatkową...",
|
|
91
|
+
"Reverse charge - tax exempt EU B2B sale": "Odwrotne obciążenie - zwolniona z podatku sprzedaż EU B2B",
|
|
76
92
|
} as const;
|
|
@@ -73,4 +73,20 @@ export default {
|
|
|
73
73
|
Premise: "Estabelecimento",
|
|
74
74
|
Device: "Dispositivo",
|
|
75
75
|
"FINA fiscalized invoices always use the current date": "Os documentos fiscalizados FINA usam sempre a data atual",
|
|
76
|
+
// Separator items
|
|
77
|
+
"Add separator": "Adicionar separador",
|
|
78
|
+
"Section header": "Cabeçalho da secção",
|
|
79
|
+
"Section title...": "Título da secção...",
|
|
80
|
+
// Transaction type
|
|
81
|
+
"Transaction type": "Tipo de transação",
|
|
82
|
+
Domestic: "Nacional",
|
|
83
|
+
"EU B2B": "EU B2B",
|
|
84
|
+
"EU B2C": "EU B2C",
|
|
85
|
+
Export: "Exportação",
|
|
86
|
+
"Determining transaction type...": "Determinando tipo de transação...",
|
|
87
|
+
"This invoice will not be fiscalized (non-domestic transaction)":
|
|
88
|
+
"Esta fatura não será fiscalizada (transação não nacional)",
|
|
89
|
+
"Tax Clause": "Cláusula fiscal",
|
|
90
|
+
"Add tax clause...": "Adicionar cláusula fiscal...",
|
|
91
|
+
"Reverse charge - tax exempt EU B2B sale": "Autoliquidação - venda B2B UE isenta de imposto",
|
|
76
92
|
} as const;
|
|
@@ -15,7 +15,7 @@ export default {
|
|
|
15
15
|
Price: "Cena",
|
|
16
16
|
Unit: "Enota",
|
|
17
17
|
Discount: "Popust",
|
|
18
|
-
Tax: "
|
|
18
|
+
Tax: "DDV",
|
|
19
19
|
"Tax rate": "Davčna stopnja",
|
|
20
20
|
"Add tax": "Dodaj davek",
|
|
21
21
|
"Select tax...": "Izberi davek...",
|
|
@@ -72,4 +72,20 @@ export default {
|
|
|
72
72
|
Premise: "Poslovni prostor",
|
|
73
73
|
Device: "Naprava",
|
|
74
74
|
"FINA fiscalized invoices always use the current date": "FINA fiskalizirani dokumenti vedno uporabijo trenutni datum",
|
|
75
|
+
// Separator items
|
|
76
|
+
"Add separator": "Dodaj ločilnik",
|
|
77
|
+
"Section header": "Naslov razdelka",
|
|
78
|
+
"Section title...": "Naslov razdelka...",
|
|
79
|
+
// Transaction type
|
|
80
|
+
"Transaction type": "Vrsta transakcije",
|
|
81
|
+
Domestic: "Domača",
|
|
82
|
+
"EU B2B": "EU B2B",
|
|
83
|
+
"EU B2C": "EU B2C",
|
|
84
|
+
Export: "Izvoz",
|
|
85
|
+
"Determining transaction type...": "Določanje vrste transakcije...",
|
|
86
|
+
"This invoice will not be fiscalized (non-domestic transaction)":
|
|
87
|
+
"Ta račun ne bo fiskaliziran (nedomača transakcija)",
|
|
88
|
+
"Tax Clause": "Davčna klavzula",
|
|
89
|
+
"Add tax clause...": "Dodajte davčno klavzulo...",
|
|
90
|
+
"Reverse charge - tax exempt EU B2B sale": "Obrnjena davčna obveznost - davka oproščena EU B2B prodaja",
|
|
75
91
|
} as const;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Copy, Download, Eye, Link2Off, Loader2, MoreHorizontal, Plus } from "lucide-react";
|
|
1
|
+
import { Ban, Copy, Download, Eye, Link2Off, Loader2, MoreHorizontal, Plus } from "lucide-react";
|
|
2
2
|
import { Button } from "@/ui/components/ui/button";
|
|
3
3
|
import {
|
|
4
4
|
DropdownMenu,
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
DropdownMenuSeparator,
|
|
10
10
|
DropdownMenuTrigger,
|
|
11
11
|
} from "@/ui/components/ui/dropdown-menu";
|
|
12
|
+
import { Tooltip, TooltipContent, TooltipTrigger } from "@/ui/components/ui/tooltip";
|
|
12
13
|
import type { ComponentTranslationProps } from "@/ui/lib/translation";
|
|
13
14
|
import { createTranslation } from "@/ui/lib/translation";
|
|
14
15
|
import { useCreditNoteDownload } from "./use-credit-note-download";
|
|
@@ -26,6 +27,8 @@ type CreditNoteListRowActionsProps = {
|
|
|
26
27
|
onDownloadError?: (error: string) => void;
|
|
27
28
|
onUnshare?: (creditNote: CreditNote) => Promise<void>;
|
|
28
29
|
isUnsharing?: boolean;
|
|
30
|
+
onVoid?: (creditNote: CreditNote) => void;
|
|
31
|
+
isVoiding?: boolean;
|
|
29
32
|
} & ComponentTranslationProps;
|
|
30
33
|
|
|
31
34
|
export default function CreditNoteListRowActions({
|
|
@@ -38,6 +41,8 @@ export default function CreditNoteListRowActions({
|
|
|
38
41
|
onDownloadError,
|
|
39
42
|
onUnshare,
|
|
40
43
|
isUnsharing,
|
|
44
|
+
onVoid,
|
|
45
|
+
isVoiding,
|
|
41
46
|
...i18nProps
|
|
42
47
|
}: CreditNoteListRowActionsProps) {
|
|
43
48
|
const t = createTranslation(i18nProps);
|
|
@@ -107,6 +112,44 @@ export default function CreditNoteListRowActions({
|
|
|
107
112
|
</DropdownMenuGroup>
|
|
108
113
|
</>
|
|
109
114
|
)}
|
|
115
|
+
{onVoid &&
|
|
116
|
+
!creditNote.voided_at &&
|
|
117
|
+
!creditNote.is_draft &&
|
|
118
|
+
(() => {
|
|
119
|
+
const isFiscalized = !!(creditNote.furs || creditNote.fina);
|
|
120
|
+
const voidDisabled = isVoiding || isFiscalized;
|
|
121
|
+
const voidItem = (
|
|
122
|
+
<DropdownMenuItem
|
|
123
|
+
className={
|
|
124
|
+
voidDisabled
|
|
125
|
+
? "text-destructive opacity-50"
|
|
126
|
+
: "cursor-pointer text-destructive focus:text-destructive"
|
|
127
|
+
}
|
|
128
|
+
onClick={() => !voidDisabled && onVoid(creditNote)}
|
|
129
|
+
disabled={voidDisabled}
|
|
130
|
+
>
|
|
131
|
+
{isVoiding ? <Loader2 className="h-4 w-4 animate-spin" /> : <Ban className="h-4 w-4" />}
|
|
132
|
+
{t("Void")}
|
|
133
|
+
</DropdownMenuItem>
|
|
134
|
+
);
|
|
135
|
+
return (
|
|
136
|
+
<>
|
|
137
|
+
<DropdownMenuSeparator />
|
|
138
|
+
<DropdownMenuGroup>
|
|
139
|
+
{isFiscalized ? (
|
|
140
|
+
<Tooltip>
|
|
141
|
+
<TooltipTrigger asChild>
|
|
142
|
+
<div>{voidItem}</div>
|
|
143
|
+
</TooltipTrigger>
|
|
144
|
+
<TooltipContent side="left">{t("Cannot void a fiscalized credit note")}</TooltipContent>
|
|
145
|
+
</Tooltip>
|
|
146
|
+
) : (
|
|
147
|
+
voidItem
|
|
148
|
+
)}
|
|
149
|
+
</DropdownMenuGroup>
|
|
150
|
+
</>
|
|
151
|
+
);
|
|
152
|
+
})()}
|
|
110
153
|
</DropdownMenuContent>
|
|
111
154
|
</DropdownMenu>
|
|
112
155
|
);
|
|
@@ -59,6 +59,8 @@ type CreditNoteListTableProps = {
|
|
|
59
59
|
onRetryFiscalization?: (documentIds: string[]) => void;
|
|
60
60
|
fiscalizationFeatures?: ("furs" | "fina")[];
|
|
61
61
|
onCreateNew?: () => void;
|
|
62
|
+
onVoid?: (creditNote: CreditNote) => void;
|
|
63
|
+
isVoiding?: boolean;
|
|
62
64
|
} & ListTableProps<CreditNote>;
|
|
63
65
|
|
|
64
66
|
export default function CreditNoteListTable({
|
|
@@ -76,6 +78,8 @@ export default function CreditNoteListTable({
|
|
|
76
78
|
onRetryFiscalization,
|
|
77
79
|
fiscalizationFeatures,
|
|
78
80
|
onCreateNew,
|
|
81
|
+
onVoid,
|
|
82
|
+
isVoiding,
|
|
79
83
|
...i18nProps
|
|
80
84
|
}: CreditNoteListTableProps) {
|
|
81
85
|
const t = createTranslation({
|
|
@@ -97,6 +101,7 @@ export default function CreditNoteListTable({
|
|
|
97
101
|
prev_cursor: params.prev_cursor,
|
|
98
102
|
search: params.search,
|
|
99
103
|
query: params.query,
|
|
104
|
+
include: "document_relations",
|
|
100
105
|
});
|
|
101
106
|
return response as unknown as TableQueryResponse<CreditNote>;
|
|
102
107
|
}, entityId);
|
|
@@ -210,13 +215,13 @@ export default function CreditNoteListTable({
|
|
|
210
215
|
id: "total",
|
|
211
216
|
header: t("Total"),
|
|
212
217
|
align: "right",
|
|
213
|
-
cell: (creditNote) => creditNote.total,
|
|
218
|
+
cell: (creditNote) => -creditNote.total,
|
|
214
219
|
},
|
|
215
220
|
{
|
|
216
221
|
id: "total_with_tax",
|
|
217
222
|
header: t("Total with Tax"),
|
|
218
223
|
align: "right",
|
|
219
|
-
cell: (creditNote) => creditNote.total_with_tax,
|
|
224
|
+
cell: (creditNote) => -creditNote.total_with_tax,
|
|
220
225
|
},
|
|
221
226
|
{
|
|
222
227
|
id: "status",
|
|
@@ -236,6 +241,8 @@ export default function CreditNoteListTable({
|
|
|
236
241
|
onDownloadStart={onDownloadStart}
|
|
237
242
|
onDownloadSuccess={onDownloadSuccess}
|
|
238
243
|
onDownloadError={onDownloadError}
|
|
244
|
+
onVoid={onVoid}
|
|
245
|
+
isVoiding={isVoiding}
|
|
239
246
|
t={t}
|
|
240
247
|
locale={i18nProps.locale}
|
|
241
248
|
/>
|
|
@@ -251,6 +258,8 @@ export default function CreditNoteListTable({
|
|
|
251
258
|
onDownloadStart,
|
|
252
259
|
onDownloadSuccess,
|
|
253
260
|
onDownloadError,
|
|
261
|
+
onVoid,
|
|
262
|
+
isVoiding,
|
|
254
263
|
i18nProps.locale,
|
|
255
264
|
fiscalizationFeatures,
|
|
256
265
|
],
|
|
@@ -290,6 +299,11 @@ function CreditNoteStatusBadge({ creditNote, t }: { creditNote: CreditNote; t: (
|
|
|
290
299
|
if ((creditNote as any).is_draft) {
|
|
291
300
|
return null;
|
|
292
301
|
}
|
|
302
|
+
// Hide payment badges for void-created credit notes (has "credit_for" relation)
|
|
303
|
+
const isVoidCreated = (creditNote as any).document_relations?.some((rel: any) => rel.relation_type === "credit_for");
|
|
304
|
+
if (isVoidCreated) {
|
|
305
|
+
return null;
|
|
306
|
+
}
|
|
293
307
|
if (creditNote.paid_in_full) {
|
|
294
308
|
return (
|
|
295
309
|
<Badge
|
|
@@ -46,4 +46,6 @@ export default {
|
|
|
46
46
|
"FINA fiscalization failed": "FINA fiscalization failed",
|
|
47
47
|
"Retry Fiscalization": "Retry Fiscalization",
|
|
48
48
|
"Some selected documents don't have failed fiscalization": "Some selected documents don't have failed fiscalization",
|
|
49
|
+
Void: "Stornieren",
|
|
50
|
+
"Cannot void a fiscalized credit note": "Stornierung einer fiskalisierten Gutschrift nicht möglich",
|
|
49
51
|
} as const;
|
|
@@ -14,4 +14,6 @@ export default {
|
|
|
14
14
|
"FINA fiscalization failed": "FINA fiscalization failed",
|
|
15
15
|
"Retry Fiscalization": "Retry Fiscalization",
|
|
16
16
|
"Some selected documents don't have failed fiscalization": "Some selected documents don't have failed fiscalization",
|
|
17
|
+
Void: "Void",
|
|
18
|
+
"Cannot void a fiscalized credit note": "Cannot void a fiscalized credit note",
|
|
17
19
|
} as const;
|
|
@@ -46,4 +46,6 @@ export default {
|
|
|
46
46
|
"FINA fiscalization failed": "FINA fiscalization failed",
|
|
47
47
|
"Retry Fiscalization": "Retry Fiscalization",
|
|
48
48
|
"Some selected documents don't have failed fiscalization": "Some selected documents don't have failed fiscalization",
|
|
49
|
+
Void: "Anular",
|
|
50
|
+
"Cannot void a fiscalized credit note": "No se puede anular una nota de crédito fiscalizada",
|
|
49
51
|
} as const;
|
|
@@ -46,4 +46,6 @@ export default {
|
|
|
46
46
|
"FINA fiscalization failed": "FINA fiscalization failed",
|
|
47
47
|
"Retry Fiscalization": "Retry Fiscalization",
|
|
48
48
|
"Some selected documents don't have failed fiscalization": "Some selected documents don't have failed fiscalization",
|
|
49
|
+
Void: "Annuler",
|
|
50
|
+
"Cannot void a fiscalized credit note": "Impossible d'annuler un avoir fiscalisé",
|
|
49
51
|
} as const;
|
|
@@ -46,4 +46,6 @@ export default {
|
|
|
46
46
|
"FINA fiscalization failed": "FINA fiskalizacija nije uspjela",
|
|
47
47
|
"Retry Fiscalization": "Ponovi fiskalizaciju",
|
|
48
48
|
"Some selected documents don't have failed fiscalization": "Neki odabrani dokumenti nemaju neuspjelu fiskalizaciju",
|
|
49
|
+
Void: "Storniraj",
|
|
50
|
+
"Cannot void a fiscalized credit note": "Nije moguće poništiti fiskalizirani dobropis",
|
|
49
51
|
} as const;
|
|
@@ -46,4 +46,6 @@ export default {
|
|
|
46
46
|
"FINA fiscalization failed": "FINA fiscalization failed",
|
|
47
47
|
"Retry Fiscalization": "Retry Fiscalization",
|
|
48
48
|
"Some selected documents don't have failed fiscalization": "Some selected documents don't have failed fiscalization",
|
|
49
|
+
Void: "Annulla",
|
|
50
|
+
"Cannot void a fiscalized credit note": "Impossibile annullare una nota di credito fiscalizzata",
|
|
49
51
|
} as const;
|
|
@@ -46,4 +46,6 @@ export default {
|
|
|
46
46
|
"FINA fiscalization failed": "FINA fiscalization failed",
|
|
47
47
|
"Retry Fiscalization": "Retry Fiscalization",
|
|
48
48
|
"Some selected documents don't have failed fiscalization": "Some selected documents don't have failed fiscalization",
|
|
49
|
+
Void: "Nietig verklaren",
|
|
50
|
+
"Cannot void a fiscalized credit note": "Kan een gefiscaliseerde creditnota niet ongeldig maken",
|
|
49
51
|
} as const;
|
|
@@ -46,4 +46,6 @@ export default {
|
|
|
46
46
|
"FINA fiscalization failed": "FINA fiscalization failed",
|
|
47
47
|
"Retry Fiscalization": "Retry Fiscalization",
|
|
48
48
|
"Some selected documents don't have failed fiscalization": "Some selected documents don't have failed fiscalization",
|
|
49
|
+
Void: "Anuluj",
|
|
50
|
+
"Cannot void a fiscalized credit note": "Nie można anulować zafiskalizowanej noty kredytowej",
|
|
49
51
|
} as const;
|
|
@@ -46,4 +46,6 @@ export default {
|
|
|
46
46
|
"FINA fiscalization failed": "FINA fiscalization failed",
|
|
47
47
|
"Retry Fiscalization": "Retry Fiscalization",
|
|
48
48
|
"Some selected documents don't have failed fiscalization": "Some selected documents don't have failed fiscalization",
|
|
49
|
+
Void: "Anular",
|
|
50
|
+
"Cannot void a fiscalized credit note": "Não é possível anular uma nota de crédito fiscalizada",
|
|
49
51
|
} as const;
|
|
@@ -46,4 +46,6 @@ export default {
|
|
|
46
46
|
"FINA fiscalization failed": "FINA fiskalizacija ni uspela",
|
|
47
47
|
"Retry Fiscalization": "Ponovi fiskalizacijo",
|
|
48
48
|
"Some selected documents don't have failed fiscalization": "Nekateri izbrani dokumenti nimajo neuspele fiskalizacije",
|
|
49
|
+
Void: "Storniraj",
|
|
50
|
+
"Cannot void a fiscalized credit note": "Ni mogoče razveljaviti fiskalizirane dobropisa",
|
|
49
51
|
} as const;
|