@spaceinvoices/react-ui 0.4.3 → 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/common/autocomplete.tsx +18 -2
- package/src/components/advance-invoices/create/create-advance-invoice-form.tsx +61 -12
- package/src/components/advance-invoices/create/locales/de.ts +17 -0
- package/src/components/advance-invoices/create/locales/es.ts +17 -0
- package/src/components/advance-invoices/create/locales/fr.ts +17 -0
- package/src/components/advance-invoices/create/locales/hr.ts +16 -0
- package/src/components/advance-invoices/create/locales/it.ts +17 -0
- package/src/components/advance-invoices/create/locales/nl.ts +17 -0
- package/src/components/advance-invoices/create/locales/pl.ts +16 -0
- package/src/components/advance-invoices/create/locales/pt.ts +16 -0
- package/src/components/advance-invoices/create/locales/sl.ts +16 -0
- package/src/components/advance-invoices/create/prepare-advance-invoice-submission.ts +0 -1
- package/src/components/advance-invoices/list/list-row-actions.tsx +48 -1
- package/src/components/advance-invoices/list/list-table.tsx +100 -50
- package/src/components/advance-invoices/list/locales/de.ts +9 -0
- package/src/components/advance-invoices/list/locales/en.ts +7 -0
- package/src/components/advance-invoices/list/locales/es.ts +9 -0
- package/src/components/advance-invoices/list/locales/fr.ts +9 -0
- package/src/components/advance-invoices/list/locales/hr.ts +8 -0
- package/src/components/advance-invoices/list/locales/it.ts +9 -0
- package/src/components/advance-invoices/list/locales/nl.ts +9 -0
- package/src/components/advance-invoices/list/locales/pl.ts +8 -0
- package/src/components/advance-invoices/list/locales/pt.ts +9 -0
- package/src/components/advance-invoices/list/locales/sl.ts +8 -0
- package/src/components/credit-notes/create/create-credit-note-form.tsx +185 -11
- package/src/components/credit-notes/create/locales/de.ts +18 -0
- package/src/components/credit-notes/create/locales/es.ts +18 -0
- package/src/components/credit-notes/create/locales/fr.ts +18 -0
- package/src/components/credit-notes/create/locales/hr.ts +17 -0
- package/src/components/credit-notes/create/locales/it.ts +18 -0
- package/src/components/credit-notes/create/locales/nl.ts +18 -0
- package/src/components/credit-notes/create/locales/pl.ts +17 -0
- package/src/components/credit-notes/create/locales/pt.ts +17 -0
- package/src/components/credit-notes/create/locales/sl.ts +18 -1
- package/src/components/credit-notes/credit-notes.hooks.ts +30 -0
- package/src/components/credit-notes/list/list-row-actions.tsx +44 -1
- package/src/components/credit-notes/list/list-table.tsx +93 -32
- package/src/components/credit-notes/list/locales/de.ts +7 -0
- package/src/components/credit-notes/list/locales/en.ts +6 -0
- package/src/components/credit-notes/list/locales/es.ts +7 -0
- package/src/components/credit-notes/list/locales/fr.ts +7 -0
- package/src/components/credit-notes/list/locales/hr.ts +7 -0
- package/src/components/credit-notes/list/locales/it.ts +7 -0
- package/src/components/credit-notes/list/locales/nl.ts +7 -0
- package/src/components/credit-notes/list/locales/pl.ts +7 -0
- package/src/components/credit-notes/list/locales/pt.ts +7 -0
- package/src/components/credit-notes/list/locales/sl.ts +7 -0
- package/src/components/customers/customer-list-table/customer-list-table.tsx +0 -3
- package/src/components/customers/customer-list-table/locales/de.ts +1 -0
- package/src/components/customers/customer-list-table/locales/es.ts +1 -0
- package/src/components/customers/customer-list-table/locales/fr.ts +1 -0
- package/src/components/customers/customer-list-table/locales/hr.ts +1 -0
- package/src/components/customers/customer-list-table/locales/it.ts +1 -0
- package/src/components/customers/customer-list-table/locales/nl.ts +1 -0
- package/src/components/customers/customer-list-table/locales/pl.ts +1 -0
- package/src/components/customers/customer-list-table/locales/pt.ts +1 -0
- package/src/components/customers/customer-list-table/locales/sl.ts +1 -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-row-actions.tsx +20 -1
- package/src/components/delivery-notes/list/list-table.tsx +50 -8
- package/src/components/delivery-notes/list/locales/de.ts +35 -0
- package/src/components/delivery-notes/list/locales/en.ts +33 -0
- package/src/components/delivery-notes/list/locales/es.ts +35 -0
- package/src/components/delivery-notes/list/locales/fr.ts +35 -0
- package/src/components/delivery-notes/list/locales/hr.ts +35 -0
- package/src/components/delivery-notes/list/locales/it.ts +35 -0
- package/src/components/delivery-notes/list/locales/nl.ts +35 -0
- package/src/components/delivery-notes/list/locales/pl.ts +35 -0
- package/src/components/delivery-notes/list/locales/pt.ts +35 -0
- package/src/components/delivery-notes/list/locales/sl.ts +35 -0
- package/src/components/documents/create/document-add-item-form.tsx +70 -0
- package/src/components/documents/create/document-details-section.tsx +163 -29
- package/src/components/documents/create/document-items-section.tsx +21 -4
- package/src/components/documents/create/linked-documents-info.tsx +82 -0
- package/src/components/documents/create/live-preview.tsx +25 -5
- 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/types.ts +2 -2
- package/src/components/documents/view/document-actions-bar.tsx +7 -27
- package/src/components/documents/view/document-activities-list.tsx +65 -47
- package/src/components/documents/view/document-details-card.tsx +118 -76
- package/src/components/documents/view/document-payments-list.tsx +99 -65
- package/src/components/documents/view/document-relations-list.tsx +43 -28
- package/src/components/documents/view/document-sidebar.tsx +151 -0
- package/src/components/documents/view/index.ts +2 -0
- package/src/components/documents/view/locales/de.ts +4 -0
- package/src/components/documents/view/locales/es.ts +4 -0
- package/src/components/documents/view/locales/fr.ts +4 -0
- package/src/components/documents/view/locales/hr.ts +4 -0
- package/src/components/documents/view/locales/it.ts +4 -0
- package/src/components/documents/view/locales/nl.ts +4 -0
- package/src/components/documents/view/locales/pl.ts +4 -0
- package/src/components/documents/view/locales/pt.ts +4 -0
- package/src/components/documents/view/locales/sl.ts +5 -1
- package/src/components/documents/view/use-document-download.ts +7 -3
- package/src/components/entities/create-entity-form.tsx +166 -13
- package/src/components/entities/entity-settings-form/entity-settings-form.tsx +101 -1
- package/src/components/entities/entity-settings-form/input-with-preview.tsx +30 -2
- package/src/components/entities/entity-settings-form/locales/de.ts +10 -0
- package/src/components/entities/entity-settings-form/locales/es.ts +10 -0
- package/src/components/entities/entity-settings-form/locales/fr.ts +10 -0
- package/src/components/entities/entity-settings-form/locales/hr.ts +10 -0
- package/src/components/entities/entity-settings-form/locales/it.ts +10 -0
- package/src/components/entities/entity-settings-form/locales/nl.ts +10 -0
- package/src/components/entities/entity-settings-form/locales/pl.ts +10 -0
- package/src/components/entities/entity-settings-form/locales/pt.ts +10 -0
- package/src/components/entities/entity-settings-form/locales/sl.ts +10 -0
- package/src/components/entities/fina-settings-form/fina-settings-form.tsx +6 -6
- package/src/components/entities/fina-settings-form/locales/de.ts +2 -2
- package/src/components/entities/fina-settings-form/locales/en.ts +2 -2
- package/src/components/entities/fina-settings-form/locales/es.ts +2 -2
- package/src/components/entities/fina-settings-form/locales/fr.ts +2 -2
- package/src/components/entities/fina-settings-form/locales/hr.ts +2 -2
- package/src/components/entities/fina-settings-form/locales/it.ts +2 -2
- package/src/components/entities/fina-settings-form/locales/nl.ts +2 -2
- package/src/components/entities/fina-settings-form/locales/pl.ts +2 -2
- package/src/components/entities/fina-settings-form/locales/pt.ts +2 -2
- package/src/components/entities/fina-settings-form/locales/sl.ts +2 -2
- package/src/components/entities/furs-settings-form/locales/en.ts +0 -1
- package/src/components/entities/settings/company-settings-form.tsx +173 -20
- package/src/components/entities/settings/pdf-template-selector/locales/de.ts +3 -1
- package/src/components/entities/settings/pdf-template-selector/locales/es.ts +3 -1
- package/src/components/entities/settings/pdf-template-selector/locales/fr.ts +4 -1
- package/src/components/entities/settings/pdf-template-selector/locales/hr.ts +4 -1
- package/src/components/entities/settings/pdf-template-selector/locales/it.ts +3 -1
- package/src/components/entities/settings/pdf-template-selector/locales/nl.ts +3 -1
- package/src/components/entities/settings/pdf-template-selector/locales/pl.ts +3 -1
- package/src/components/entities/settings/pdf-template-selector/locales/pt.ts +3 -1
- package/src/components/entities/settings/pdf-template-selector/locales/sl.ts +3 -1
- package/src/components/entities/settings/pdf-template-selector/pdf-template-cards.tsx +1 -0
- package/src/components/estimates/create/create-estimate-form.tsx +93 -8
- 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 +14 -8
- package/src/components/estimates/list/locales/de.ts +2 -0
- package/src/components/estimates/list/locales/en.ts +1 -0
- package/src/components/estimates/list/locales/es.ts +2 -0
- package/src/components/estimates/list/locales/fr.ts +2 -0
- package/src/components/estimates/list/locales/hr.ts +2 -0
- package/src/components/estimates/list/locales/it.ts +2 -0
- package/src/components/estimates/list/locales/nl.ts +2 -0
- package/src/components/estimates/list/locales/pl.ts +2 -0
- package/src/components/estimates/list/locales/pt.ts +2 -0
- package/src/components/estimates/list/locales/sl.ts +2 -0
- package/src/components/export/document-export-form.tsx +55 -14
- package/src/components/export/index.ts +2 -0
- package/src/components/export/sales-per-item-export-form.tsx +223 -0
- package/src/components/invoices/create/create-invoice-form.tsx +106 -11
- package/src/components/invoices/create/locales/de.ts +26 -0
- package/src/components/invoices/create/locales/es.ts +26 -0
- package/src/components/invoices/create/locales/fr.ts +26 -0
- package/src/components/invoices/create/locales/hr.ts +25 -0
- package/src/components/invoices/create/locales/it.ts +26 -0
- package/src/components/invoices/create/locales/nl.ts +26 -0
- package/src/components/invoices/create/locales/pl.ts +25 -0
- package/src/components/invoices/create/locales/pt.ts +25 -0
- package/src/components/invoices/create/locales/sl.ts +26 -1
- package/src/components/invoices/invoices-furs.hooks.ts +4 -1
- package/src/components/invoices/list/list-table.tsx +77 -31
- package/src/components/invoices/list/locales/de.ts +5 -0
- package/src/components/invoices/list/locales/en.ts +4 -0
- package/src/components/invoices/list/locales/es.ts +5 -0
- package/src/components/invoices/list/locales/fr.ts +5 -0
- package/src/components/invoices/list/locales/hr.ts +5 -0
- package/src/components/invoices/list/locales/it.ts +5 -0
- package/src/components/invoices/list/locales/nl.ts +5 -0
- package/src/components/invoices/list/locales/pl.ts +5 -0
- package/src/components/invoices/list/locales/pt.ts +5 -0
- package/src/components/invoices/list/locales/sl.ts +5 -0
- package/src/components/invoices/view/fiscalization-status-card.tsx +44 -24
- package/src/components/items/item-combobox.tsx +5 -3
- package/src/components/items/item-list-table/item-list-header.tsx +4 -17
- package/src/components/items/item-list-table/item-list-table.tsx +3 -3
- package/src/components/items/item-list-table/locales/de.ts +1 -0
- package/src/components/items/item-list-table/locales/es.ts +1 -0
- package/src/components/items/item-list-table/locales/fr.ts +1 -0
- package/src/components/items/item-list-table/locales/hr.ts +1 -0
- package/src/components/items/item-list-table/locales/it.ts +1 -0
- package/src/components/items/item-list-table/locales/nl.ts +1 -0
- package/src/components/items/item-list-table/locales/pl.ts +1 -0
- package/src/components/items/item-list-table/locales/pt.ts +1 -0
- package/src/components/items/item-list-table/locales/sl.ts +1 -0
- package/src/components/payments/list/list-table.tsx +0 -4
- package/src/components/payments/list/locales/de.ts +1 -0
- package/src/components/payments/list/locales/es.ts +1 -0
- package/src/components/payments/list/locales/fr.ts +1 -0
- package/src/components/payments/list/locales/hr.ts +1 -0
- package/src/components/payments/list/locales/it.ts +1 -0
- package/src/components/payments/list/locales/nl.ts +1 -0
- package/src/components/payments/list/locales/pl.ts +1 -0
- package/src/components/payments/list/locales/pt.ts +1 -0
- package/src/components/payments/list/locales/sl.ts +1 -0
- package/src/components/recurring-invoices/list/list-table.tsx +0 -7
- package/src/components/recurring-invoices/list/locales/de.ts +1 -0
- package/src/components/recurring-invoices/list/locales/es.ts +1 -0
- package/src/components/recurring-invoices/list/locales/fr.ts +1 -0
- package/src/components/recurring-invoices/list/locales/hr.ts +1 -0
- package/src/components/recurring-invoices/list/locales/it.ts +1 -0
- package/src/components/recurring-invoices/list/locales/nl.ts +1 -0
- package/src/components/recurring-invoices/list/locales/pl.ts +1 -0
- package/src/components/recurring-invoices/list/locales/pt.ts +1 -0
- package/src/components/recurring-invoices/list/locales/sl.ts +1 -0
- package/src/components/request-logs/request-log-list-table.tsx +0 -3
- package/src/components/table/README.md +14 -121
- package/src/components/table/data-table.tsx +22 -37
- package/src/components/table/hooks/use-table-state.ts +3 -27
- package/src/components/table/index.ts +0 -2
- package/src/components/table/search-input.tsx +17 -0
- package/src/components/table/selection-toolbar.tsx +35 -1
- package/src/components/table/table-empty-state.tsx +6 -3
- package/src/components/table/table-no-results.tsx +10 -5
- package/src/components/table/types.ts +0 -5
- package/src/components/taxes/tax-list-table/locales/de.ts +1 -0
- package/src/components/taxes/tax-list-table/locales/es.ts +1 -0
- package/src/components/taxes/tax-list-table/locales/fr.ts +1 -0
- package/src/components/taxes/tax-list-table/locales/hr.ts +1 -0
- package/src/components/taxes/tax-list-table/locales/it.ts +1 -0
- package/src/components/taxes/tax-list-table/locales/nl.ts +1 -0
- package/src/components/taxes/tax-list-table/locales/pl.ts +1 -0
- package/src/components/taxes/tax-list-table/locales/pt.ts +1 -0
- package/src/components/taxes/tax-list-table/locales/sl.ts +1 -0
- package/src/components/taxes/tax-list-table/tax-list-header.tsx +3 -14
- package/src/components/taxes/tax-list-table/tax-list-table.tsx +3 -3
- package/src/components/ui/popover.tsx +3 -1
- package/src/components/ui/tooltip.tsx +3 -1
- 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/index.ts +1 -1
- 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 +56 -14
- package/src/hooks/use-vies-check.ts +3 -0
- package/src/lib/fiscalization.ts +12 -0
- package/src/lib/schemas/advance-invoice.ts +0 -1
- package/src/components/table/sortable-header.tsx +0 -56
|
@@ -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";
|
|
@@ -26,7 +28,14 @@ import { prepareDocumentSubmission } from "../../documents/create/prepare-docume
|
|
|
26
28
|
import { useDocumentCustomerForm } from "../../documents/create/use-document-customer-form";
|
|
27
29
|
import type { DocumentTypes } from "../../documents/types";
|
|
28
30
|
import { useFinaPremises, useFinaSettings } from "../../entities/fina-settings-form/fina-settings.hooks";
|
|
29
|
-
import {
|
|
31
|
+
import { useFursPremises, useFursSettings } from "../../entities/furs-settings-form/furs-settings.hooks";
|
|
32
|
+
import {
|
|
33
|
+
getLastUsedFinaCombo,
|
|
34
|
+
getLastUsedFursCombo,
|
|
35
|
+
setLastUsedFinaCombo,
|
|
36
|
+
setLastUsedFursCombo,
|
|
37
|
+
useCreateCreditNote,
|
|
38
|
+
} from "../credit-notes.hooks";
|
|
30
39
|
import de from "./locales/de";
|
|
31
40
|
import es from "./locales/es";
|
|
32
41
|
import fr from "./locales/fr";
|
|
@@ -90,6 +99,23 @@ export default function CreateCreditNoteForm({
|
|
|
90
99
|
const { activeEntity } = useEntities();
|
|
91
100
|
const queryClient = useQueryClient();
|
|
92
101
|
|
|
102
|
+
// ============================================================================
|
|
103
|
+
// FURS Settings & Premises
|
|
104
|
+
// ============================================================================
|
|
105
|
+
const { data: fursSettings, isLoading: isFursSettingsLoading } = useFursSettings(entityId);
|
|
106
|
+
const { data: fursPremises, isLoading: isFursPremisesLoading } = useFursPremises(entityId, {
|
|
107
|
+
enabled: fursSettings?.enabled === true,
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
const isFursLoading = isFursSettingsLoading || (fursSettings?.enabled && isFursPremisesLoading);
|
|
111
|
+
const isFursEnabled = fursSettings?.enabled === true;
|
|
112
|
+
const activePremises = useMemo(() => fursPremises?.filter((p) => p.is_active) || [], [fursPremises]);
|
|
113
|
+
const hasFursPremises = activePremises.length > 0;
|
|
114
|
+
|
|
115
|
+
// FURS premise/device selection state
|
|
116
|
+
const [selectedPremiseName, setSelectedPremiseName] = useState<string | undefined>();
|
|
117
|
+
const [selectedDeviceName, setSelectedDeviceName] = useState<string | undefined>();
|
|
118
|
+
|
|
93
119
|
// ============================================================================
|
|
94
120
|
// FINA Settings & Premises
|
|
95
121
|
// ============================================================================
|
|
@@ -122,6 +148,57 @@ export default function CreateCreditNoteForm({
|
|
|
122
148
|
}, [initialValues?.items]);
|
|
123
149
|
const priceModesRef = useRef<PriceModesMap>(initialPriceModes);
|
|
124
150
|
|
|
151
|
+
// Get active FURS devices for selected premise
|
|
152
|
+
const activeDevices = useMemo(() => {
|
|
153
|
+
if (!selectedPremiseName) return [];
|
|
154
|
+
const premise = activePremises.find((p) => p.business_premise_name === selectedPremiseName);
|
|
155
|
+
return premise?.Devices?.filter((d) => d.is_active) || [];
|
|
156
|
+
}, [activePremises, selectedPremiseName]);
|
|
157
|
+
|
|
158
|
+
// Initialize FURS selection from localStorage or first active combo
|
|
159
|
+
useEffect(() => {
|
|
160
|
+
if (!isFursEnabled || !hasFursPremises || selectedPremiseName) return;
|
|
161
|
+
|
|
162
|
+
const lastUsed = getLastUsedFursCombo(entityId);
|
|
163
|
+
if (lastUsed) {
|
|
164
|
+
const premise = activePremises.find((p) => p.business_premise_name === lastUsed.business_premise_name);
|
|
165
|
+
const device = premise?.Devices?.find(
|
|
166
|
+
(d) => d.electronic_device_name === lastUsed.electronic_device_name && d.is_active,
|
|
167
|
+
);
|
|
168
|
+
if (premise && device) {
|
|
169
|
+
setSelectedPremiseName(lastUsed.business_premise_name);
|
|
170
|
+
setSelectedDeviceName(lastUsed.electronic_device_name);
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const firstPremise = activePremises[0];
|
|
176
|
+
const firstDevice = firstPremise?.Devices?.find((d) => d.is_active);
|
|
177
|
+
if (firstPremise && firstDevice) {
|
|
178
|
+
setSelectedPremiseName(firstPremise.business_premise_name);
|
|
179
|
+
setSelectedDeviceName(firstDevice.electronic_device_name);
|
|
180
|
+
}
|
|
181
|
+
}, [isFursEnabled, hasFursPremises, activePremises, entityId, selectedPremiseName]);
|
|
182
|
+
|
|
183
|
+
// When FURS premise changes, select first active device
|
|
184
|
+
useEffect(() => {
|
|
185
|
+
if (!selectedPremiseName) return;
|
|
186
|
+
const premise = activePremises.find((p) => p.business_premise_name === selectedPremiseName);
|
|
187
|
+
const firstDevice = premise?.Devices?.find((d) => d.is_active);
|
|
188
|
+
if (firstDevice && selectedDeviceName !== firstDevice.electronic_device_name) {
|
|
189
|
+
const currentDeviceInPremise = premise?.Devices?.find(
|
|
190
|
+
(d) => d.electronic_device_name === selectedDeviceName && d.is_active,
|
|
191
|
+
);
|
|
192
|
+
if (!currentDeviceInPremise) {
|
|
193
|
+
setSelectedDeviceName(firstDevice.electronic_device_name);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}, [selectedPremiseName, activePremises, selectedDeviceName]);
|
|
197
|
+
|
|
198
|
+
// FURS selection ready and active checks
|
|
199
|
+
const isFursSelectionReady = !isFursEnabled || !hasFursPremises || (!!selectedPremiseName && !!selectedDeviceName);
|
|
200
|
+
const isFursActive = isFursEnabled && hasFursPremises && selectedPremiseName && selectedDeviceName;
|
|
201
|
+
|
|
125
202
|
// Get active FINA devices for selected premise
|
|
126
203
|
const activeFinaDevices = useMemo(() => {
|
|
127
204
|
if (!selectedFinaPremiseId) return [];
|
|
@@ -176,11 +253,14 @@ export default function CreateCreditNoteForm({
|
|
|
176
253
|
// Next Credit Note Number Preview
|
|
177
254
|
// ============================================================================
|
|
178
255
|
const { data: nextNumberData, isLoading: isNextNumberLoading } = useNextDocumentNumber(entityId, "credit_note", {
|
|
179
|
-
|
|
256
|
+
businessPremiseName: isFursActive ? selectedPremiseName : undefined,
|
|
257
|
+
electronicDeviceName: isFursActive ? selectedDeviceName : undefined,
|
|
258
|
+
enabled: !!entityId && !isFursLoading && isFursSelectionReady && !isFinaLoading && isFinaSelectionReady,
|
|
180
259
|
});
|
|
181
260
|
|
|
182
261
|
// Overall loading state
|
|
183
|
-
const isFormDataLoading =
|
|
262
|
+
const isFormDataLoading =
|
|
263
|
+
isFursLoading || !isFursSelectionReady || isFinaLoading || !isFinaSelectionReady || isNextNumberLoading;
|
|
184
264
|
|
|
185
265
|
// No header action for credit notes - FINA can't be skipped
|
|
186
266
|
|
|
@@ -197,13 +277,18 @@ export default function CreateCreditNoteForm({
|
|
|
197
277
|
// Cast customer to form schema type (API type may have additional fields)
|
|
198
278
|
customer: (initialValues?.customer as CreateCreditNoteFormValues["customer"]) ?? undefined,
|
|
199
279
|
items: initialValues?.items?.length
|
|
200
|
-
? initialValues.items.map((item) => ({
|
|
280
|
+
? initialValues.items.map((item: any) => ({
|
|
281
|
+
type: item.type,
|
|
201
282
|
name: item.name || "",
|
|
202
283
|
description: item.description || "",
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
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
|
+
: {}),
|
|
207
292
|
}))
|
|
208
293
|
: [
|
|
209
294
|
{
|
|
@@ -216,6 +301,7 @@ export default function CreateCreditNoteForm({
|
|
|
216
301
|
],
|
|
217
302
|
currency_code: initialValues?.currency_code || activeEntity?.currency_code || "EUR",
|
|
218
303
|
note: initialValues?.note ?? "",
|
|
304
|
+
tax_clause: (initialValues as any)?.tax_clause ?? "",
|
|
219
305
|
payment_terms: initialValues?.payment_terms ?? defaultPaymentTerms,
|
|
220
306
|
},
|
|
221
307
|
});
|
|
@@ -224,6 +310,41 @@ export default function CreateCreditNoteForm({
|
|
|
224
310
|
control: form.control,
|
|
225
311
|
});
|
|
226
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
|
+
|
|
227
348
|
// Extract customer management logic into a shared hook
|
|
228
349
|
const {
|
|
229
350
|
originalCustomer,
|
|
@@ -245,6 +366,13 @@ export default function CreateCreditNoteForm({
|
|
|
245
366
|
const { mutate: createCreditNote, isPending } = useCreateCreditNote({
|
|
246
367
|
entityId,
|
|
247
368
|
onSuccess: (data) => {
|
|
369
|
+
// Save FURS combo to localStorage on successful creation
|
|
370
|
+
if (isFursActive && selectedPremiseName && selectedDeviceName) {
|
|
371
|
+
setLastUsedFursCombo(entityId, {
|
|
372
|
+
business_premise_name: selectedPremiseName,
|
|
373
|
+
electronic_device_name: selectedDeviceName,
|
|
374
|
+
});
|
|
375
|
+
}
|
|
248
376
|
// Save FINA combo to localStorage on successful creation
|
|
249
377
|
if (isFinaActive && selectedFinaPremiseId && selectedFinaDeviceId) {
|
|
250
378
|
setLastUsedFinaCombo(entityId, {
|
|
@@ -264,9 +392,15 @@ export default function CreateCreditNoteForm({
|
|
|
264
392
|
// Shared submit logic for both regular save and save as draft
|
|
265
393
|
const submitCreditNote = useCallback(
|
|
266
394
|
(values: CreateCreditNoteFormValues, isDraft: boolean) => {
|
|
395
|
+
// Build FURS options (skip for drafts; no skip toggle for credit notes)
|
|
396
|
+
const fursOptions =
|
|
397
|
+
!isDraft && isFursEnabled && selectedPremiseName && selectedDeviceName
|
|
398
|
+
? { business_premise_name: selectedPremiseName, electronic_device_name: selectedDeviceName }
|
|
399
|
+
: undefined;
|
|
400
|
+
|
|
267
401
|
// Build FINA options (skip for drafts; FINA can't be skipped)
|
|
268
402
|
const finaOptions =
|
|
269
|
-
!isDraft && isFinaEnabled && selectedFinaPremiseId && selectedFinaDeviceId
|
|
403
|
+
!isDraft && isFinaEnabled && !isFinaNonDomestic && selectedFinaPremiseId && selectedFinaDeviceId
|
|
270
404
|
? { premise_id: selectedFinaPremiseId, device_id: selectedFinaDeviceId, payment_type: paymentTypes[0] }
|
|
271
405
|
: undefined;
|
|
272
406
|
|
|
@@ -280,6 +414,11 @@ export default function CreateCreditNoteForm({
|
|
|
280
414
|
isDraft,
|
|
281
415
|
});
|
|
282
416
|
|
|
417
|
+
// Add FURS data to payload
|
|
418
|
+
if (fursOptions) {
|
|
419
|
+
(payload as any).furs = fursOptions;
|
|
420
|
+
}
|
|
421
|
+
|
|
283
422
|
// Add FINA data to payload
|
|
284
423
|
if (finaOptions) {
|
|
285
424
|
(payload as any).fina = finaOptions;
|
|
@@ -289,12 +428,16 @@ export default function CreateCreditNoteForm({
|
|
|
289
428
|
},
|
|
290
429
|
[
|
|
291
430
|
createCreditNote,
|
|
431
|
+
isFursEnabled,
|
|
292
432
|
isFinaEnabled,
|
|
433
|
+
isFinaNonDomestic,
|
|
293
434
|
markAsPaid,
|
|
294
435
|
originalCustomer,
|
|
295
436
|
paymentTypes,
|
|
437
|
+
selectedDeviceName,
|
|
296
438
|
selectedFinaDeviceId,
|
|
297
439
|
selectedFinaPremiseId,
|
|
440
|
+
selectedPremiseName,
|
|
298
441
|
showCustomerForm,
|
|
299
442
|
],
|
|
300
443
|
);
|
|
@@ -316,7 +459,7 @@ export default function CreateCreditNoteForm({
|
|
|
316
459
|
useFormFooterRegistration({
|
|
317
460
|
formId: "create-credit-note-form",
|
|
318
461
|
isPending,
|
|
319
|
-
isDirty: form.formState.isDirty,
|
|
462
|
+
isDirty: form.formState.isDirty || !!initialValues,
|
|
320
463
|
label: t("Save"),
|
|
321
464
|
secondaryAction: {
|
|
322
465
|
label: t("Save as Draft"),
|
|
@@ -449,8 +592,20 @@ export default function CreateCreditNoteForm({
|
|
|
449
592
|
control={form.control}
|
|
450
593
|
documentType={_type}
|
|
451
594
|
t={t}
|
|
595
|
+
fursInline={
|
|
596
|
+
isFursEnabled && hasFursPremises
|
|
597
|
+
? {
|
|
598
|
+
premises: activePremises.map((p) => ({ id: p.id, business_premise_name: p.business_premise_name })),
|
|
599
|
+
devices: activeDevices.map((d) => ({ id: d.id, electronic_device_name: d.electronic_device_name })),
|
|
600
|
+
selectedPremise: selectedPremiseName,
|
|
601
|
+
selectedDevice: selectedDeviceName,
|
|
602
|
+
onPremiseChange: setSelectedPremiseName,
|
|
603
|
+
onDeviceChange: setSelectedDeviceName,
|
|
604
|
+
}
|
|
605
|
+
: undefined
|
|
606
|
+
}
|
|
452
607
|
finaInline={
|
|
453
|
-
isFinaEnabled && hasFinaPremises
|
|
608
|
+
isFinaEnabled && hasFinaPremises && !isFinaNonDomestic
|
|
454
609
|
? {
|
|
455
610
|
premises: activeFinaPremises.map((p: any) => ({ id: p.id, premise_id: p.premise_id })),
|
|
456
611
|
devices: activeFinaDevices.map((d: any) => ({ id: d.id, device_id: d.device_id })),
|
|
@@ -486,6 +641,10 @@ export default function CreateCreditNoteForm({
|
|
|
486
641
|
maxTaxesPerItem={activeEntity?.country_rules?.max_taxes_per_item}
|
|
487
642
|
priceModesRef={priceModesRef}
|
|
488
643
|
initialPriceModes={initialPriceModes}
|
|
644
|
+
taxesDisabled={reverseChargeApplies}
|
|
645
|
+
taxesDisabledMessage={
|
|
646
|
+
reverseChargeApplies ? t("Reverse charge - tax exempt EU B2B sale") : viesWarning ? viesWarning : undefined
|
|
647
|
+
}
|
|
489
648
|
/>
|
|
490
649
|
|
|
491
650
|
<DocumentNoteField
|
|
@@ -500,6 +659,21 @@ export default function CreateCreditNoteForm({
|
|
|
500
659
|
}}
|
|
501
660
|
/>
|
|
502
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
|
+
|
|
503
677
|
<DocumentPaymentTermsField
|
|
504
678
|
control={form.control}
|
|
505
679
|
t={t}
|
|
@@ -74,4 +74,22 @@ export default {
|
|
|
74
74
|
"Cannot skip fiscalization for cash payments": "Fiskalisierung kann für Barzahlungen nicht übersprungen werden",
|
|
75
75
|
Premise: "Geschäftsräume",
|
|
76
76
|
Device: "Gerät",
|
|
77
|
+
"FINA fiscalized invoices always use the current date":
|
|
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",
|
|
77
95
|
} as const;
|
|
@@ -73,4 +73,22 @@ export default {
|
|
|
73
73
|
"Cannot skip fiscalization for cash payments": "No se puede omitir la fiscalizacion para pagos en efectivo",
|
|
74
74
|
Premise: "Local",
|
|
75
75
|
Device: "Dispositivo",
|
|
76
|
+
"FINA fiscalized invoices always use the current date":
|
|
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",
|
|
76
94
|
} as const;
|
|
@@ -73,4 +73,22 @@ export default {
|
|
|
73
73
|
"Cannot skip fiscalization for cash payments": "Impossible d'ignorer la fiscalisation pour les paiements en especes",
|
|
74
74
|
Premise: "Local",
|
|
75
75
|
Device: "Appareil",
|
|
76
|
+
"FINA fiscalized invoices always use the current date":
|
|
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",
|
|
76
94
|
} as const;
|
|
@@ -72,4 +72,21 @@ export default {
|
|
|
72
72
|
"Cannot skip fiscalization for cash payments": "Za gotovinska placanja nije moguce preskociti fiskalizaciju",
|
|
73
73
|
Premise: "Prostor",
|
|
74
74
|
Device: "Uredaj",
|
|
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",
|
|
75
92
|
} as const;
|
|
@@ -74,4 +74,22 @@ export default {
|
|
|
74
74
|
"Non e possibile saltare la fiscalizzazione per i pagamenti in contanti",
|
|
75
75
|
Premise: "Locale",
|
|
76
76
|
Device: "Dispositivo",
|
|
77
|
+
"FINA fiscalized invoices always use the current date":
|
|
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",
|
|
77
95
|
} as const;
|
|
@@ -73,4 +73,22 @@ export default {
|
|
|
73
73
|
"Cannot skip fiscalization for cash payments": "Fiscalisatie kan niet worden overgeslagen voor contante betalingen",
|
|
74
74
|
Premise: "Bedrijfsruimte",
|
|
75
75
|
Device: "Apparaat",
|
|
76
|
+
"FINA fiscalized invoices always use the current date":
|
|
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",
|
|
76
94
|
} as const;
|
|
@@ -72,4 +72,21 @@ export default {
|
|
|
72
72
|
"Cannot skip fiscalization for cash payments": "Nie mozna pominac fiskalizacji dla platnosci gotowkowych",
|
|
73
73
|
Premise: "Lokal",
|
|
74
74
|
Device: "Urządzenie",
|
|
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",
|
|
75
92
|
} as const;
|
|
@@ -72,4 +72,21 @@ export default {
|
|
|
72
72
|
"Cannot skip fiscalization for cash payments": "Nao e possivel ignorar a fiscalizacao para pagamentos em dinheiro",
|
|
73
73
|
Premise: "Estabelecimento",
|
|
74
74
|
Device: "Dispositivo",
|
|
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",
|
|
75
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...",
|
|
@@ -71,4 +71,21 @@ export default {
|
|
|
71
71
|
"Cannot skip fiscalization for cash payments": "Za gotovinska plačila ni mogoče preskočiti davčnega potrjevanja",
|
|
72
72
|
Premise: "Poslovni prostor",
|
|
73
73
|
Device: "Naprava",
|
|
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",
|
|
74
91
|
} as const;
|
|
@@ -21,6 +21,36 @@ const {
|
|
|
21
21
|
|
|
22
22
|
export { useCreateCreditNote, useUpdateCreditNote, useDeleteCreditNote };
|
|
23
23
|
|
|
24
|
+
// ============================================================================
|
|
25
|
+
// FURS Last-Used Combo (localStorage) for credit notes
|
|
26
|
+
// ============================================================================
|
|
27
|
+
|
|
28
|
+
const FURS_CN_LAST_USED_KEY = "si:furs:cn:last-used";
|
|
29
|
+
|
|
30
|
+
export type FursCombo = {
|
|
31
|
+
business_premise_name: string;
|
|
32
|
+
electronic_device_name: string;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export function getLastUsedFursCombo(entityId: string): FursCombo | null {
|
|
36
|
+
if (typeof window === "undefined") return null;
|
|
37
|
+
try {
|
|
38
|
+
const stored = localStorage.getItem(`${FURS_CN_LAST_USED_KEY}:${entityId}`);
|
|
39
|
+
return stored ? JSON.parse(stored) : null;
|
|
40
|
+
} catch {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function setLastUsedFursCombo(entityId: string, combo: FursCombo): void {
|
|
46
|
+
if (typeof window === "undefined") return;
|
|
47
|
+
try {
|
|
48
|
+
localStorage.setItem(`${FURS_CN_LAST_USED_KEY}:${entityId}`, JSON.stringify(combo));
|
|
49
|
+
} catch {
|
|
50
|
+
// Ignore localStorage errors
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
24
54
|
// ============================================================================
|
|
25
55
|
// FINA Last-Used Combo (localStorage) for credit notes
|
|
26
56
|
// ============================================================================
|
|
@@ -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
|
);
|