@spaceinvoices/react-ui 0.4.1 → 0.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli/dist/index.js +1 -1
- package/package.json +1 -1
- package/registry.json +25 -0
- package/src/components/advance-invoices/advance-invoices.hooks.ts +32 -2
- package/src/components/advance-invoices/create/create-advance-invoice-form.tsx +109 -4
- package/src/components/advance-invoices/create/locales/de.ts +2 -0
- package/src/components/advance-invoices/create/locales/es.ts +2 -0
- package/src/components/advance-invoices/create/locales/fr.ts +2 -0
- package/src/components/advance-invoices/create/locales/hr.ts +2 -0
- package/src/components/advance-invoices/create/locales/it.ts +2 -0
- package/src/components/advance-invoices/create/locales/nl.ts +2 -0
- package/src/components/advance-invoices/create/locales/pl.ts +2 -0
- package/src/components/advance-invoices/create/locales/pt.ts +2 -0
- package/src/components/advance-invoices/create/locales/sl.ts +2 -0
- package/src/components/advance-invoices/create/prepare-advance-invoice-submission.ts +17 -0
- package/src/components/advance-invoices/list/list-row-actions.tsx +3 -6
- package/src/components/advance-invoices/list/list-table.tsx +105 -2
- package/src/components/advance-invoices/list/locales/de.ts +4 -0
- package/src/components/advance-invoices/list/locales/en.ts +4 -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 +4 -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 +4 -0
- package/src/components/advance-invoices/list/locales/pt.ts +4 -0
- package/src/components/advance-invoices/list/locales/sl.ts +4 -0
- package/src/components/credit-notes/create/create-credit-note-form.tsx +177 -6
- package/src/components/credit-notes/create/locales/de.ts +8 -0
- package/src/components/credit-notes/create/locales/es.ts +8 -0
- package/src/components/credit-notes/create/locales/fr.ts +7 -0
- package/src/components/credit-notes/create/locales/hr.ts +7 -0
- package/src/components/credit-notes/create/locales/it.ts +9 -0
- package/src/components/credit-notes/create/locales/nl.ts +7 -0
- package/src/components/credit-notes/create/locales/pl.ts +7 -0
- package/src/components/credit-notes/create/locales/pt.ts +7 -0
- package/src/components/credit-notes/create/locales/sl.ts +7 -0
- package/src/components/credit-notes/credit-notes.hooks.ts +30 -0
- package/src/components/credit-notes/list/list-row-actions.tsx +3 -6
- package/src/components/credit-notes/list/list-table.tsx +79 -8
- package/src/components/credit-notes/list/locales/de.ts +4 -1
- package/src/components/credit-notes/list/locales/en.ts +5 -0
- package/src/components/credit-notes/list/locales/es.ts +4 -1
- package/src/components/credit-notes/list/locales/fr.ts +4 -1
- package/src/components/credit-notes/list/locales/hr.ts +4 -1
- package/src/components/credit-notes/list/locales/it.ts +4 -1
- package/src/components/credit-notes/list/locales/nl.ts +4 -1
- package/src/components/credit-notes/list/locales/pl.ts +4 -1
- package/src/components/credit-notes/list/locales/pt.ts +4 -1
- package/src/components/credit-notes/list/locales/sl.ts +4 -1
- package/src/components/customers/create-customer-form/create-customer-form.tsx +0 -1
- package/src/components/dashboard/collection-rate-card/use-collection-rate.ts +2 -2
- package/src/components/dashboard/invoice-status-chart/use-invoice-status.ts +3 -3
- package/src/components/dashboard/payment-methods-chart/use-payment-methods.ts +1 -1
- package/src/components/dashboard/payment-trend-chart/use-payment-trend.ts +1 -1
- package/src/components/dashboard/revenue-trend-chart/use-revenue-trend.ts +1 -1
- package/src/components/dashboard/shared/use-revenue-data.ts +4 -4
- package/src/components/dashboard/shared/use-stats-counts.ts +4 -4
- package/src/components/dashboard/shared/use-stats-query.ts +1 -1
- package/src/components/dashboard/tax-collected-card/use-tax-collected.ts +2 -2
- package/src/components/dashboard/top-customers-chart/use-top-customers.ts +1 -1
- package/src/components/delivery-notes/create/create-delivery-note-form.tsx +332 -0
- package/src/components/delivery-notes/create/locales/de.ts +50 -0
- package/src/components/delivery-notes/create/locales/es.ts +49 -0
- package/src/components/delivery-notes/create/locales/fr.ts +50 -0
- package/src/components/delivery-notes/create/locales/hr.ts +49 -0
- package/src/components/delivery-notes/create/locales/it.ts +49 -0
- package/src/components/delivery-notes/create/locales/nl.ts +50 -0
- package/src/components/delivery-notes/create/locales/pl.ts +49 -0
- package/src/components/delivery-notes/create/locales/pt.ts +50 -0
- package/src/components/delivery-notes/create/locales/sl.ts +49 -0
- package/src/components/delivery-notes/create/prepare-delivery-note-submission.ts +38 -0
- package/src/components/delivery-notes/create/use-delivery-note-customer-form.ts +1 -0
- package/src/components/delivery-notes/delivery-notes.hooks.ts +15 -0
- package/src/components/delivery-notes/list/index.ts +3 -0
- package/src/components/delivery-notes/list/list-row-actions.tsx +103 -0
- package/src/components/delivery-notes/list/list-table.tsx +214 -0
- package/src/components/delivery-notes/list/locales/de.ts +9 -0
- package/src/components/delivery-notes/list/locales/en.ts +11 -0
- package/src/components/delivery-notes/list/locales/es.ts +9 -0
- package/src/components/delivery-notes/list/locales/fr.ts +9 -0
- package/src/components/delivery-notes/list/locales/hr.ts +9 -0
- package/src/components/delivery-notes/list/locales/it.ts +9 -0
- package/src/components/delivery-notes/list/locales/nl.ts +9 -0
- package/src/components/delivery-notes/list/locales/pl.ts +9 -0
- package/src/components/delivery-notes/list/locales/pt.ts +9 -0
- package/src/components/delivery-notes/list/locales/sl.ts +9 -0
- package/src/components/delivery-notes/list/use-delivery-note-download.ts +63 -0
- package/src/components/documents/create/document-details-section.tsx +103 -33
- package/src/components/documents/create/live-preview.tsx +37 -10
- package/src/components/documents/create/mark-as-paid-section.tsx +11 -2
- package/src/components/documents/create/prepare-document-submission.ts +1 -1
- package/src/components/documents/documents.hooks.ts +2 -1
- package/src/components/documents/shared/document-preview-display.tsx +12 -5
- package/src/components/documents/types.ts +10 -1
- package/src/components/documents/view/document-actions-bar.tsx +30 -0
- package/src/components/documents/view/document-details-card.tsx +3 -3
- package/src/components/documents/view/document-payments-list.tsx +3 -3
- package/src/components/documents/view/document-relations-list.tsx +105 -0
- package/src/components/documents/view/locales/de.ts +26 -0
- package/src/components/documents/view/locales/es.ts +26 -0
- package/src/components/documents/view/locales/fr.ts +26 -0
- package/src/components/documents/view/locales/hr.ts +26 -0
- package/src/components/documents/view/locales/it.ts +26 -0
- package/src/components/documents/view/locales/nl.ts +26 -0
- package/src/components/documents/view/locales/pl.ts +26 -0
- package/src/components/documents/view/locales/pt.ts +26 -0
- package/src/components/documents/view/locales/sl.ts +26 -0
- package/src/components/documents/view/use-document-download.ts +5 -3
- package/src/components/entities/create-entity-form.tsx +1 -1
- package/src/components/entities/entity-settings-form/entity-settings-form.tsx +2 -3
- package/src/components/entities/entity-settings-form/locales/es.ts +2 -0
- package/src/components/entities/entity-settings-form/locales/fr.ts +2 -0
- package/src/components/entities/entity-settings-form/locales/hr.ts +2 -0
- package/src/components/entities/entity-settings-form/locales/it.ts +2 -0
- package/src/components/entities/entity-settings-form/locales/nl.ts +2 -0
- package/src/components/entities/entity-settings-form/locales/pl.ts +2 -0
- package/src/components/entities/entity-settings-form/locales/pt.ts +2 -0
- package/src/components/entities/fina-settings-form/fina-operator-required-dialog.tsx +109 -0
- package/src/components/entities/fina-settings-form/fina-settings-form.tsx +377 -35
- package/src/components/entities/fina-settings-form/fina-settings.hooks.ts +106 -20
- package/src/components/entities/fina-settings-form/index.ts +1 -0
- package/src/components/entities/fina-settings-form/locales/de.ts +54 -34
- package/src/components/entities/fina-settings-form/locales/en.ts +51 -34
- package/src/components/entities/fina-settings-form/locales/es.ts +50 -34
- package/src/components/entities/fina-settings-form/locales/fr.ts +50 -34
- package/src/components/entities/fina-settings-form/locales/hr.ts +50 -34
- package/src/components/entities/fina-settings-form/locales/it.ts +50 -34
- package/src/components/entities/fina-settings-form/locales/nl.ts +50 -34
- package/src/components/entities/fina-settings-form/locales/pl.ts +50 -34
- package/src/components/entities/fina-settings-form/locales/pt.ts +50 -34
- package/src/components/entities/fina-settings-form/locales/sl.ts +50 -34
- package/src/components/entities/fina-settings-form/sections/certificate-settings-section.tsx +18 -0
- package/src/components/entities/fina-settings-form/sections/premises-management-section.tsx +64 -89
- package/src/components/entities/fina-settings-form/sections/register-premise-dialog.tsx +51 -323
- package/src/components/entities/furs-settings-form/furs-operator-required-dialog.tsx +106 -0
- package/src/components/entities/furs-settings-form/furs-settings-form.tsx +33 -10
- package/src/components/entities/furs-settings-form/furs-settings.hooks.ts +12 -11
- package/src/components/entities/furs-settings-form/index.ts +1 -0
- package/src/components/entities/furs-settings-form/locales/de.ts +27 -3
- package/src/components/entities/furs-settings-form/locales/en.ts +17 -3
- package/src/components/entities/furs-settings-form/locales/es.ts +26 -3
- package/src/components/entities/furs-settings-form/locales/fr.ts +26 -3
- package/src/components/entities/furs-settings-form/locales/hr.ts +26 -3
- package/src/components/entities/furs-settings-form/locales/it.ts +26 -3
- package/src/components/entities/furs-settings-form/locales/nl.ts +26 -3
- package/src/components/entities/furs-settings-form/locales/pl.ts +26 -3
- package/src/components/entities/furs-settings-form/locales/pt.ts +26 -3
- package/src/components/entities/furs-settings-form/locales/sl.ts +16 -3
- package/src/components/entities/furs-settings-form/sections/certificate-settings-section.tsx +22 -0
- package/src/components/entities/furs-settings-form/sections/general-settings-section.tsx +26 -5
- package/src/components/entities/furs-settings-form/sections/register-premise-dialog.tsx +14 -2
- package/src/components/entities/settings/tax-rules-settings-form.tsx +4 -4
- package/src/components/estimates/list/list-row-actions.tsx +3 -7
- package/src/components/estimates/list/list-table.tsx +35 -2
- package/src/components/estimates/list/locales/de.ts +3 -0
- package/src/components/estimates/list/locales/en.ts +3 -0
- package/src/components/estimates/list/locales/es.ts +3 -0
- package/src/components/estimates/list/locales/fr.ts +3 -0
- package/src/components/estimates/list/locales/hr.ts +3 -0
- package/src/components/estimates/list/locales/it.ts +3 -0
- package/src/components/estimates/list/locales/nl.ts +3 -0
- package/src/components/estimates/list/locales/pl.ts +3 -0
- package/src/components/estimates/list/locales/pt.ts +3 -0
- package/src/components/estimates/list/locales/sl.ts +3 -0
- package/src/components/export/document-export-form.tsx +34 -34
- package/src/components/invoices/create/create-invoice-form.tsx +107 -5
- package/src/components/invoices/create/prepare-invoice-submission.ts +17 -0
- package/src/components/invoices/invoices-furs.hooks.ts +24 -9
- package/src/components/invoices/invoices.hooks.ts +32 -2
- package/src/components/invoices/list/list-row-actions.tsx +26 -11
- package/src/components/invoices/list/list-table.tsx +121 -5
- package/src/components/invoices/list/locales/de.ts +5 -0
- package/src/components/invoices/list/locales/en.ts +5 -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 +4 -1
- package/src/components/items/item-list-table/item-list-row-actions.tsx +5 -8
- package/src/components/items/item-list-table/item-list-row.tsx +5 -3
- package/src/components/items/item-list-table/item-list-table.tsx +5 -1
- package/src/components/recurring-invoices/create-recurring-invoice-form/create-recurring-invoice-form.tsx +418 -0
- package/src/components/recurring-invoices/create-recurring-invoice-form/locales/de.ts +45 -0
- package/src/components/recurring-invoices/create-recurring-invoice-form/locales/es.ts +44 -0
- package/src/components/recurring-invoices/create-recurring-invoice-form/locales/fr.ts +44 -0
- package/src/components/recurring-invoices/create-recurring-invoice-form/locales/hr.ts +44 -0
- package/src/components/recurring-invoices/create-recurring-invoice-form/locales/it.ts +44 -0
- package/src/components/recurring-invoices/create-recurring-invoice-form/locales/nl.ts +44 -0
- package/src/components/recurring-invoices/create-recurring-invoice-form/locales/pl.ts +44 -0
- package/src/components/recurring-invoices/create-recurring-invoice-form/locales/pt.ts +44 -0
- package/src/components/recurring-invoices/create-recurring-invoice-form/locales/sl.ts +44 -0
- package/src/components/recurring-invoices/index.ts +3 -0
- package/src/components/recurring-invoices/list/index.ts +2 -0
- package/src/components/recurring-invoices/list/list-row-actions.tsx +139 -0
- package/src/components/recurring-invoices/list/list-table.tsx +179 -0
- package/src/components/recurring-invoices/list/locales/de.ts +27 -0
- package/src/components/recurring-invoices/list/locales/en.ts +5 -0
- package/src/components/recurring-invoices/list/locales/es.ts +27 -0
- package/src/components/recurring-invoices/list/locales/fr.ts +27 -0
- package/src/components/recurring-invoices/list/locales/hr.ts +27 -0
- package/src/components/recurring-invoices/list/locales/it.ts +27 -0
- package/src/components/recurring-invoices/list/locales/nl.ts +27 -0
- package/src/components/recurring-invoices/list/locales/pl.ts +27 -0
- package/src/components/recurring-invoices/list/locales/pt.ts +27 -0
- package/src/components/recurring-invoices/list/locales/sl.ts +27 -0
- package/src/components/recurring-invoices/recurring-invoices.hooks.ts +28 -0
- package/src/components/table/data-table.tsx +122 -5
- package/src/components/table/selection-toolbar.tsx +36 -0
- package/src/components/tax-reports/kir-export-form.tsx +75 -55
- package/src/components/taxes/tax-list-table/tax-list-row-actions.tsx +3 -6
- package/src/components/taxes/tax-list-table/tax-list-row.tsx +3 -2
- package/src/components/taxes/tax-list-table/tax-list-table.tsx +5 -1
- package/src/components/ui/checkbox.tsx +5 -5
- package/src/generate-schemas.ts +45 -18
- package/src/generated/schemas/authorizeshopify_body.ts +22 -0
- package/src/generated/schemas/creditnote.ts +0 -2
- package/src/generated/schemas/deliverynote.ts +134 -0
- package/src/generated/schemas/entity.ts +5 -1
- package/src/generated/schemas/index.ts +42 -28
- package/src/generated/schemas/order.ts +129 -0
- package/src/generated/schemas/orderintegration.ts +51 -0
- package/src/generated/schemas/payment.ts +24 -2
- package/src/generated/schemas/recurringinvoice.ts +61 -0
- package/src/generated/schemas/renderadvanceinvoicepreview_body.ts +108 -140
- package/src/generated/schemas/rendercreditnotepreview_body.ts +109 -141
- package/src/generated/schemas/renderdeliverynotepreview_body.ts +185 -0
- package/src/generated/schemas/renderestimatepreview_body.ts +79 -82
- package/src/generated/schemas/renderinvoicepreview_body.ts +109 -141
- package/src/generated/schemas/startpdfexport_body.ts +18 -2
- package/src/generated/schemas/userfinasettings.ts +19 -0
- package/src/generated/schemas/webhook.ts +54 -0
- package/src/hooks/use-duplicate-document.ts +11 -3
- package/src/hooks/use-next-document-number.ts +2 -2
- package/src/lib/furs-error-utils.ts +36 -0
- package/src/lib/schemas/advance-invoice.ts +3 -3
- package/src/lib/schemas/credit-note.ts +3 -3
- package/src/lib/schemas/estimate.ts +3 -3
- package/src/lib/schemas/invoice.ts +3 -3
- package/src/providers/sdk-provider.tsx +5 -7
- package/src/providers/white-label-provider.tsx +3 -0
|
@@ -38,4 +38,8 @@ export default {
|
|
|
38
38
|
"No results found": "Nije pronadjen nijedan avansni racun",
|
|
39
39
|
"Try adjusting your search criteria": "Pokusajte prilagoditi kriterije pretrazivanja",
|
|
40
40
|
"Clear search": "Ocisti pretragu",
|
|
41
|
+
selected: "odabranih",
|
|
42
|
+
"Export PDFs": "Izvezi PDF-ove",
|
|
43
|
+
"Deselect all": "Poništi odabir",
|
|
44
|
+
"Partially Paid": "Djelomično plaćeno",
|
|
41
45
|
} as const;
|
|
@@ -38,4 +38,8 @@ export default {
|
|
|
38
38
|
"No results found": "Nessuna fattura anticipata trovata",
|
|
39
39
|
"Try adjusting your search criteria": "Prova a modificare i criteri di ricerca",
|
|
40
40
|
"Clear search": "Cancella ricerca",
|
|
41
|
+
selected: "selezionati",
|
|
42
|
+
"Export PDFs": "Esporta PDF",
|
|
43
|
+
"Deselect all": "Deseleziona tutto",
|
|
44
|
+
"Partially Paid": "Parzialmente pagato",
|
|
41
45
|
} as const;
|
|
@@ -38,4 +38,8 @@ export default {
|
|
|
38
38
|
"No results found": "Geen voorschotfacturen gevonden",
|
|
39
39
|
"Try adjusting your search criteria": "Probeer uw zoekcriteria aan te passen",
|
|
40
40
|
"Clear search": "Zoekopdracht wissen",
|
|
41
|
+
selected: "geselecteerd",
|
|
42
|
+
"Export PDFs": "PDFs exporteren",
|
|
43
|
+
"Deselect all": "Alles deselecteren",
|
|
44
|
+
"Partially Paid": "Gedeeltelijk betaald",
|
|
41
45
|
} as const;
|
|
@@ -38,4 +38,8 @@ export default {
|
|
|
38
38
|
"No results found": "Nie znaleziono faktur zaliczkowych",
|
|
39
39
|
"Try adjusting your search criteria": "Sprobuj dostosowac kryteria wyszukiwania",
|
|
40
40
|
"Clear search": "Wyczysc wyszukiwanie",
|
|
41
|
+
selected: "wybranych",
|
|
42
|
+
"Export PDFs": "Eksportuj PDF-y",
|
|
43
|
+
"Deselect all": "Odznacz wszystko",
|
|
44
|
+
"Partially Paid": "Częściowo opłacona",
|
|
41
45
|
} as const;
|
|
@@ -38,4 +38,8 @@ export default {
|
|
|
38
38
|
"No results found": "Nenhuma fatura antecipada encontrada",
|
|
39
39
|
"Try adjusting your search criteria": "Tente ajustar os seus criterios de pesquisa",
|
|
40
40
|
"Clear search": "Limpar pesquisa",
|
|
41
|
+
selected: "selecionados",
|
|
42
|
+
"Export PDFs": "Exportar PDFs",
|
|
43
|
+
"Deselect all": "Desselecionar tudo",
|
|
44
|
+
"Partially Paid": "Parcialmente pago",
|
|
41
45
|
} as const;
|
|
@@ -38,4 +38,8 @@ export default {
|
|
|
38
38
|
"No results found": "Ni najdenih avansnih računov",
|
|
39
39
|
"Try adjusting your search criteria": "Poskusite prilagoditi iskalne kriterije",
|
|
40
40
|
"Clear search": "Počisti iskanje",
|
|
41
|
+
selected: "izbranih",
|
|
42
|
+
"Export PDFs": "Izvozi PDF-je",
|
|
43
|
+
"Deselect all": "Počisti izbiro",
|
|
44
|
+
"Partially Paid": "Delno plačano",
|
|
41
45
|
} as const;
|
|
@@ -6,6 +6,7 @@ import type { Resolver } from "react-hook-form";
|
|
|
6
6
|
import { useForm, useWatch } from "react-hook-form";
|
|
7
7
|
import type { z } from "zod";
|
|
8
8
|
import { Form } from "@/ui/components/ui/form";
|
|
9
|
+
import { Skeleton } from "@/ui/components/ui/skeleton";
|
|
9
10
|
import { createCreditNoteSchema } from "@/ui/generated/schemas";
|
|
10
11
|
import { useNextDocumentNumber } from "@/ui/hooks/use-next-document-number";
|
|
11
12
|
import type { ComponentTranslationProps } from "@/ui/lib/translation";
|
|
@@ -24,7 +25,8 @@ import { MarkAsPaidSection } from "../../documents/create/mark-as-paid-section";
|
|
|
24
25
|
import { prepareDocumentSubmission } from "../../documents/create/prepare-document-submission";
|
|
25
26
|
import { useDocumentCustomerForm } from "../../documents/create/use-document-customer-form";
|
|
26
27
|
import type { DocumentTypes } from "../../documents/types";
|
|
27
|
-
import {
|
|
28
|
+
import { useFinaPremises, useFinaSettings } from "../../entities/fina-settings-form/fina-settings.hooks";
|
|
29
|
+
import { getLastUsedFinaCombo, setLastUsedFinaCombo, useCreateCreditNote } from "../credit-notes.hooks";
|
|
28
30
|
import de from "./locales/de";
|
|
29
31
|
import es from "./locales/es";
|
|
30
32
|
import fr from "./locales/fr";
|
|
@@ -88,11 +90,23 @@ export default function CreateCreditNoteForm({
|
|
|
88
90
|
const { activeEntity } = useEntities();
|
|
89
91
|
const queryClient = useQueryClient();
|
|
90
92
|
|
|
91
|
-
//
|
|
92
|
-
|
|
93
|
-
|
|
93
|
+
// ============================================================================
|
|
94
|
+
// FINA Settings & Premises
|
|
95
|
+
// ============================================================================
|
|
96
|
+
const { data: finaSettings, isLoading: isFinaSettingsLoading } = useFinaSettings(entityId);
|
|
97
|
+
const { data: finaPremises, isLoading: isFinaPremisesLoading } = useFinaPremises(entityId, {
|
|
98
|
+
enabled: finaSettings?.enabled === true,
|
|
94
99
|
});
|
|
95
100
|
|
|
101
|
+
const isFinaLoading = isFinaSettingsLoading || (finaSettings?.enabled && isFinaPremisesLoading);
|
|
102
|
+
const isFinaEnabled = finaSettings?.enabled === true;
|
|
103
|
+
const activeFinaPremises = useMemo(() => finaPremises?.filter((p: any) => p.is_active) || [], [finaPremises]);
|
|
104
|
+
const hasFinaPremises = activeFinaPremises.length > 0;
|
|
105
|
+
|
|
106
|
+
// FINA premise/device selection state (no skip - all FINA credit notes must be fiscalized)
|
|
107
|
+
const [selectedFinaPremiseId, setSelectedFinaPremiseId] = useState<string | undefined>();
|
|
108
|
+
const [selectedFinaDeviceId, setSelectedFinaDeviceId] = useState<string | undefined>();
|
|
109
|
+
|
|
96
110
|
// UI-only state (not part of API schema)
|
|
97
111
|
const [markAsPaid, setMarkAsPaid] = useState(false);
|
|
98
112
|
const [paymentTypes, setPaymentTypes] = useState<string[]>(["bank_transfer"]);
|
|
@@ -108,6 +122,68 @@ export default function CreateCreditNoteForm({
|
|
|
108
122
|
}, [initialValues?.items]);
|
|
109
123
|
const priceModesRef = useRef<PriceModesMap>(initialPriceModes);
|
|
110
124
|
|
|
125
|
+
// Get active FINA devices for selected premise
|
|
126
|
+
const activeFinaDevices = useMemo(() => {
|
|
127
|
+
if (!selectedFinaPremiseId) return [];
|
|
128
|
+
const premise = activeFinaPremises.find((p: any) => p.premise_id === selectedFinaPremiseId);
|
|
129
|
+
return premise?.Devices?.filter((d: any) => d.is_active) || [];
|
|
130
|
+
}, [activeFinaPremises, selectedFinaPremiseId]);
|
|
131
|
+
|
|
132
|
+
// Initialize FINA selection from localStorage or first active combo
|
|
133
|
+
useEffect(() => {
|
|
134
|
+
if (!isFinaEnabled || !hasFinaPremises || selectedFinaPremiseId) return;
|
|
135
|
+
|
|
136
|
+
const lastUsed = getLastUsedFinaCombo(entityId);
|
|
137
|
+
if (lastUsed) {
|
|
138
|
+
const premise = activeFinaPremises.find((p: any) => p.premise_id === lastUsed.premise_id);
|
|
139
|
+
const device = premise?.Devices?.find((d: any) => d.device_id === lastUsed.device_id && d.is_active);
|
|
140
|
+
if (premise && device) {
|
|
141
|
+
setSelectedFinaPremiseId(lastUsed.premise_id);
|
|
142
|
+
setSelectedFinaDeviceId(lastUsed.device_id);
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const firstPremise = activeFinaPremises[0];
|
|
148
|
+
const firstDevice = firstPremise?.Devices?.find((d: any) => d.is_active);
|
|
149
|
+
if (firstPremise && firstDevice) {
|
|
150
|
+
setSelectedFinaPremiseId(firstPremise.premise_id);
|
|
151
|
+
setSelectedFinaDeviceId(firstDevice.device_id);
|
|
152
|
+
}
|
|
153
|
+
}, [isFinaEnabled, hasFinaPremises, activeFinaPremises, entityId, selectedFinaPremiseId]);
|
|
154
|
+
|
|
155
|
+
// When FINA premise changes, select first active device
|
|
156
|
+
useEffect(() => {
|
|
157
|
+
if (!selectedFinaPremiseId) return;
|
|
158
|
+
const premise = activeFinaPremises.find((p: any) => p.premise_id === selectedFinaPremiseId);
|
|
159
|
+
const firstDevice = premise?.Devices?.find((d: any) => d.is_active);
|
|
160
|
+
if (firstDevice && selectedFinaDeviceId !== firstDevice.device_id) {
|
|
161
|
+
const currentDeviceInPremise = premise?.Devices?.find(
|
|
162
|
+
(d: any) => d.device_id === selectedFinaDeviceId && d.is_active,
|
|
163
|
+
);
|
|
164
|
+
if (!currentDeviceInPremise) {
|
|
165
|
+
setSelectedFinaDeviceId(firstDevice.device_id);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}, [selectedFinaPremiseId, activeFinaPremises, selectedFinaDeviceId]);
|
|
169
|
+
|
|
170
|
+
// FINA selection ready and active checks
|
|
171
|
+
const isFinaSelectionReady =
|
|
172
|
+
!isFinaEnabled || !hasFinaPremises || (!!selectedFinaPremiseId && !!selectedFinaDeviceId);
|
|
173
|
+
const isFinaActive = isFinaEnabled && hasFinaPremises && selectedFinaPremiseId && selectedFinaDeviceId;
|
|
174
|
+
|
|
175
|
+
// ============================================================================
|
|
176
|
+
// Next Credit Note Number Preview
|
|
177
|
+
// ============================================================================
|
|
178
|
+
const { data: nextNumberData, isLoading: isNextNumberLoading } = useNextDocumentNumber(entityId, "credit_note", {
|
|
179
|
+
enabled: !!entityId && !isFinaLoading && isFinaSelectionReady,
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
// Overall loading state
|
|
183
|
+
const isFormDataLoading = isFinaLoading || !isFinaSelectionReady || isNextNumberLoading;
|
|
184
|
+
|
|
185
|
+
// No header action for credit notes - FINA can't be skipped
|
|
186
|
+
|
|
111
187
|
// Get default payment terms from entity settings
|
|
112
188
|
const defaultPaymentTerms = (activeEntity?.settings as any)?.default_credit_note_payment_terms || "";
|
|
113
189
|
|
|
@@ -169,6 +245,13 @@ export default function CreateCreditNoteForm({
|
|
|
169
245
|
const { mutate: createCreditNote, isPending } = useCreateCreditNote({
|
|
170
246
|
entityId,
|
|
171
247
|
onSuccess: (data) => {
|
|
248
|
+
// Save FINA combo to localStorage on successful creation
|
|
249
|
+
if (isFinaActive && selectedFinaPremiseId && selectedFinaDeviceId) {
|
|
250
|
+
setLastUsedFinaCombo(entityId, {
|
|
251
|
+
premise_id: selectedFinaPremiseId,
|
|
252
|
+
device_id: selectedFinaDeviceId,
|
|
253
|
+
});
|
|
254
|
+
}
|
|
172
255
|
// Invalidate customers cache when a customer was created/linked
|
|
173
256
|
if (data.customer_id) {
|
|
174
257
|
queryClient.invalidateQueries({ queryKey: [CUSTOMERS_CACHE_KEY] });
|
|
@@ -181,6 +264,12 @@ export default function CreateCreditNoteForm({
|
|
|
181
264
|
// Shared submit logic for both regular save and save as draft
|
|
182
265
|
const submitCreditNote = useCallback(
|
|
183
266
|
(values: CreateCreditNoteFormValues, isDraft: boolean) => {
|
|
267
|
+
// Build FINA options (skip for drafts; FINA can't be skipped)
|
|
268
|
+
const finaOptions =
|
|
269
|
+
!isDraft && isFinaEnabled && selectedFinaPremiseId && selectedFinaDeviceId
|
|
270
|
+
? { premise_id: selectedFinaPremiseId, device_id: selectedFinaDeviceId, payment_type: paymentTypes[0] }
|
|
271
|
+
: undefined;
|
|
272
|
+
|
|
184
273
|
const payload = prepareDocumentSubmission(values, {
|
|
185
274
|
originalCustomer,
|
|
186
275
|
wasCustomerFormShown: showCustomerForm,
|
|
@@ -190,9 +279,24 @@ export default function CreateCreditNoteForm({
|
|
|
190
279
|
priceModes: priceModesRef.current,
|
|
191
280
|
isDraft,
|
|
192
281
|
});
|
|
282
|
+
|
|
283
|
+
// Add FINA data to payload
|
|
284
|
+
if (finaOptions) {
|
|
285
|
+
(payload as any).fina = finaOptions;
|
|
286
|
+
}
|
|
287
|
+
|
|
193
288
|
createCreditNote(payload as CreateCreditNoteRequest);
|
|
194
289
|
},
|
|
195
|
-
[
|
|
290
|
+
[
|
|
291
|
+
createCreditNote,
|
|
292
|
+
isFinaEnabled,
|
|
293
|
+
markAsPaid,
|
|
294
|
+
originalCustomer,
|
|
295
|
+
paymentTypes,
|
|
296
|
+
selectedFinaDeviceId,
|
|
297
|
+
selectedFinaPremiseId,
|
|
298
|
+
showCustomerForm,
|
|
299
|
+
],
|
|
196
300
|
);
|
|
197
301
|
|
|
198
302
|
// Handle save as draft
|
|
@@ -276,6 +380,56 @@ export default function CreateCreditNoteForm({
|
|
|
276
380
|
submitCreditNote(values, false);
|
|
277
381
|
};
|
|
278
382
|
|
|
383
|
+
// Show skeleton while loading
|
|
384
|
+
if (isFormDataLoading) {
|
|
385
|
+
return (
|
|
386
|
+
<div className="space-y-8">
|
|
387
|
+
<div className="flex w-full flex-col md:flex-row md:gap-6">
|
|
388
|
+
<div className="flex-1 space-y-4">
|
|
389
|
+
<Skeleton className="h-7 w-24" />
|
|
390
|
+
<Skeleton className="h-10 w-full" />
|
|
391
|
+
</div>
|
|
392
|
+
<div className="flex-1 space-y-4">
|
|
393
|
+
<Skeleton className="h-7 w-20" />
|
|
394
|
+
<Skeleton className="h-5 w-16" />
|
|
395
|
+
<Skeleton className="h-10 w-full" />
|
|
396
|
+
<Skeleton className="h-5 w-12" />
|
|
397
|
+
<Skeleton className="h-10 w-full" />
|
|
398
|
+
<Skeleton className="h-5 w-16" />
|
|
399
|
+
<Skeleton className="h-10 w-full" />
|
|
400
|
+
<Skeleton className="h-5 w-20" />
|
|
401
|
+
<Skeleton className="h-10 w-full" />
|
|
402
|
+
<div className="space-y-3 rounded-md border p-4">
|
|
403
|
+
<div className="flex items-center gap-3">
|
|
404
|
+
<Skeleton className="h-4 w-4 rounded" />
|
|
405
|
+
<Skeleton className="h-5 w-28" />
|
|
406
|
+
</div>
|
|
407
|
+
</div>
|
|
408
|
+
</div>
|
|
409
|
+
</div>
|
|
410
|
+
|
|
411
|
+
<div className="space-y-4">
|
|
412
|
+
<Skeleton className="h-7 w-16" />
|
|
413
|
+
<div className="space-y-4 rounded-lg border p-4">
|
|
414
|
+
<Skeleton className="h-10 w-full" />
|
|
415
|
+
<div className="flex gap-4">
|
|
416
|
+
<Skeleton className="h-10 w-24" />
|
|
417
|
+
<Skeleton className="h-10 flex-1" />
|
|
418
|
+
</div>
|
|
419
|
+
</div>
|
|
420
|
+
<Skeleton className="h-9 w-24" />
|
|
421
|
+
</div>
|
|
422
|
+
|
|
423
|
+
<div className="space-y-2">
|
|
424
|
+
<Skeleton className="h-5 w-12" />
|
|
425
|
+
<Skeleton className="h-24 w-full" />
|
|
426
|
+
</div>
|
|
427
|
+
|
|
428
|
+
<Skeleton className="h-10 w-24" />
|
|
429
|
+
</div>
|
|
430
|
+
);
|
|
431
|
+
}
|
|
432
|
+
|
|
279
433
|
return (
|
|
280
434
|
<Form {...form}>
|
|
281
435
|
<form id="create-credit-note-form" onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
|
|
@@ -291,7 +445,23 @@ export default function CreateCreditNoteForm({
|
|
|
291
445
|
initialCustomerName={initialCustomerName}
|
|
292
446
|
t={t}
|
|
293
447
|
/>
|
|
294
|
-
<DocumentDetailsSection
|
|
448
|
+
<DocumentDetailsSection
|
|
449
|
+
control={form.control}
|
|
450
|
+
documentType={_type}
|
|
451
|
+
t={t}
|
|
452
|
+
finaInline={
|
|
453
|
+
isFinaEnabled && hasFinaPremises
|
|
454
|
+
? {
|
|
455
|
+
premises: activeFinaPremises.map((p: any) => ({ id: p.id, premise_id: p.premise_id })),
|
|
456
|
+
devices: activeFinaDevices.map((d: any) => ({ id: d.id, device_id: d.device_id })),
|
|
457
|
+
selectedPremise: selectedFinaPremiseId,
|
|
458
|
+
selectedDevice: selectedFinaDeviceId,
|
|
459
|
+
onPremiseChange: setSelectedFinaPremiseId,
|
|
460
|
+
onDeviceChange: setSelectedFinaDeviceId,
|
|
461
|
+
}
|
|
462
|
+
: undefined
|
|
463
|
+
}
|
|
464
|
+
>
|
|
295
465
|
{/* Credit note specific: Mark as paid section (UI-only state, not in form schema) */}
|
|
296
466
|
<MarkAsPaidSection
|
|
297
467
|
checked={markAsPaid}
|
|
@@ -299,6 +469,7 @@ export default function CreateCreditNoteForm({
|
|
|
299
469
|
paymentTypes={paymentTypes}
|
|
300
470
|
onPaymentTypesChange={setPaymentTypes}
|
|
301
471
|
t={t}
|
|
472
|
+
alwaysShowPaymentType={!!isFinaActive}
|
|
302
473
|
/>
|
|
303
474
|
</DocumentDetailsSection>
|
|
304
475
|
</div>
|
|
@@ -66,4 +66,12 @@ export default {
|
|
|
66
66
|
"Net price": "Nettopreis",
|
|
67
67
|
"Gross price (tax included)": "Bruttopreis (inkl. MwSt.)",
|
|
68
68
|
"Net price (before tax)": "Nettopreis (exkl. MwSt.)",
|
|
69
|
+
// FINA fiscalization
|
|
70
|
+
"Fiscally verify": "Steuerlich bestätigen",
|
|
71
|
+
"Click to skip fiscalization for this credit note":
|
|
72
|
+
"Klicken, um die Fiskalisierung für diese Gutschrift zu überspringen",
|
|
73
|
+
"Click to enable fiscalization": "Klicken, um die Fiskalisierung zu aktivieren",
|
|
74
|
+
"Cannot skip fiscalization for cash payments": "Fiskalisierung kann für Barzahlungen nicht übersprungen werden",
|
|
75
|
+
Premise: "Geschäftsräume",
|
|
76
|
+
Device: "Gerät",
|
|
69
77
|
} as const;
|
|
@@ -65,4 +65,12 @@ export default {
|
|
|
65
65
|
"Net price": "Precio neto",
|
|
66
66
|
"Gross price (tax included)": "Precio bruto (impuestos incluidos)",
|
|
67
67
|
"Net price (before tax)": "Precio neto (antes de impuestos)",
|
|
68
|
+
// FINA fiscalization
|
|
69
|
+
"Fiscally verify": "Verificar fiscalmente",
|
|
70
|
+
"Click to skip fiscalization for this credit note":
|
|
71
|
+
"Haga clic para omitir la fiscalizacion para esta nota de credito",
|
|
72
|
+
"Click to enable fiscalization": "Haga clic para habilitar la fiscalizacion",
|
|
73
|
+
"Cannot skip fiscalization for cash payments": "No se puede omitir la fiscalizacion para pagos en efectivo",
|
|
74
|
+
Premise: "Local",
|
|
75
|
+
Device: "Dispositivo",
|
|
68
76
|
} as const;
|
|
@@ -66,4 +66,11 @@ export default {
|
|
|
66
66
|
"Net price": "Prix net",
|
|
67
67
|
"Gross price (tax included)": "Prix brut (taxes comprises)",
|
|
68
68
|
"Net price (before tax)": "Prix net (hors taxes)",
|
|
69
|
+
// FINA fiscalization
|
|
70
|
+
"Fiscally verify": "Verification fiscale",
|
|
71
|
+
"Click to skip fiscalization for this credit note": "Cliquez pour ignorer la fiscalisation pour cet avoir",
|
|
72
|
+
"Click to enable fiscalization": "Cliquez pour activer la fiscalisation",
|
|
73
|
+
"Cannot skip fiscalization for cash payments": "Impossible d'ignorer la fiscalisation pour les paiements en especes",
|
|
74
|
+
Premise: "Local",
|
|
75
|
+
Device: "Appareil",
|
|
69
76
|
} as const;
|
|
@@ -65,4 +65,11 @@ export default {
|
|
|
65
65
|
"Net price": "Neto cijena",
|
|
66
66
|
"Gross price (tax included)": "Bruto cijena (s porezom)",
|
|
67
67
|
"Net price (before tax)": "Neto cijena (bez poreza)",
|
|
68
|
+
// FINA fiscalization
|
|
69
|
+
"Fiscally verify": "Fiskalno potvrdi",
|
|
70
|
+
"Click to skip fiscalization for this credit note": "Kliknite za preskakanje fiskalizacije za ovo odobrenje",
|
|
71
|
+
"Click to enable fiscalization": "Kliknite za ukljucivanje fiskalizacije",
|
|
72
|
+
"Cannot skip fiscalization for cash payments": "Za gotovinska placanja nije moguce preskociti fiskalizaciju",
|
|
73
|
+
Premise: "Prostor",
|
|
74
|
+
Device: "Uredaj",
|
|
68
75
|
} as const;
|
|
@@ -65,4 +65,13 @@ export default {
|
|
|
65
65
|
"Net price": "Prezzo netto",
|
|
66
66
|
"Gross price (tax included)": "Prezzo lordo (imposte incluse)",
|
|
67
67
|
"Net price (before tax)": "Prezzo netto (prima delle imposte)",
|
|
68
|
+
// FINA fiscalization
|
|
69
|
+
"Fiscally verify": "Verifica fiscale",
|
|
70
|
+
"Click to skip fiscalization for this credit note":
|
|
71
|
+
"Clicca per saltare la fiscalizzazione per questa nota di credito",
|
|
72
|
+
"Click to enable fiscalization": "Clicca per abilitare la fiscalizzazione",
|
|
73
|
+
"Cannot skip fiscalization for cash payments":
|
|
74
|
+
"Non e possibile saltare la fiscalizzazione per i pagamenti in contanti",
|
|
75
|
+
Premise: "Locale",
|
|
76
|
+
Device: "Dispositivo",
|
|
68
77
|
} as const;
|
|
@@ -66,4 +66,11 @@ export default {
|
|
|
66
66
|
"Net price": "Nettoprijs",
|
|
67
67
|
"Gross price (tax included)": "Brutoprijs (btw inbegrepen)",
|
|
68
68
|
"Net price (before tax)": "Nettoprijs (exclusief btw)",
|
|
69
|
+
// FINA fiscalization
|
|
70
|
+
"Fiscally verify": "Fiscaal verifieren",
|
|
71
|
+
"Click to skip fiscalization for this credit note": "Klik om fiscalisatie voor deze creditnota over te slaan",
|
|
72
|
+
"Click to enable fiscalization": "Klik om fiscalisatie in te schakelen",
|
|
73
|
+
"Cannot skip fiscalization for cash payments": "Fiscalisatie kan niet worden overgeslagen voor contante betalingen",
|
|
74
|
+
Premise: "Bedrijfsruimte",
|
|
75
|
+
Device: "Apparaat",
|
|
69
76
|
} as const;
|
|
@@ -65,4 +65,11 @@ export default {
|
|
|
65
65
|
"Net price": "Cena netto",
|
|
66
66
|
"Gross price (tax included)": "Cena brutto (z podatkiem)",
|
|
67
67
|
"Net price (before tax)": "Cena netto (przed podatkiem)",
|
|
68
|
+
// FINA fiscalization
|
|
69
|
+
"Fiscally verify": "Zweryfikuj fiskalnie",
|
|
70
|
+
"Click to skip fiscalization for this credit note": "Kliknij, aby pominac fiskalizacje dla tej noty kredytowej",
|
|
71
|
+
"Click to enable fiscalization": "Kliknij, aby wlaczyc fiskalizacje",
|
|
72
|
+
"Cannot skip fiscalization for cash payments": "Nie mozna pominac fiskalizacji dla platnosci gotowkowych",
|
|
73
|
+
Premise: "Lokal",
|
|
74
|
+
Device: "Urządzenie",
|
|
68
75
|
} as const;
|
|
@@ -65,4 +65,11 @@ export default {
|
|
|
65
65
|
"Net price": "Preco liquido",
|
|
66
66
|
"Gross price (tax included)": "Preco bruto (com imposto)",
|
|
67
67
|
"Net price (before tax)": "Preco liquido (sem imposto)",
|
|
68
|
+
// FINA fiscalization
|
|
69
|
+
"Fiscally verify": "Verificar fiscalmente",
|
|
70
|
+
"Click to skip fiscalization for this credit note": "Clique para ignorar a fiscalizacao para esta nota de credito",
|
|
71
|
+
"Click to enable fiscalization": "Clique para ativar a fiscalizacao",
|
|
72
|
+
"Cannot skip fiscalization for cash payments": "Nao e possivel ignorar a fiscalizacao para pagamentos em dinheiro",
|
|
73
|
+
Premise: "Estabelecimento",
|
|
74
|
+
Device: "Dispositivo",
|
|
68
75
|
} as const;
|
|
@@ -64,4 +64,11 @@ export default {
|
|
|
64
64
|
"Net price": "Neto cena",
|
|
65
65
|
"Gross price (tax included)": "Bruto cena (z davkom)",
|
|
66
66
|
"Net price (before tax)": "Neto cena (brez davka)",
|
|
67
|
+
// FINA fiscalization
|
|
68
|
+
"Fiscally verify": "Davčno potrdi",
|
|
69
|
+
"Click to skip fiscalization for this credit note": "Klikni za preskok davčnega potrjevanja za ta dobropis",
|
|
70
|
+
"Click to enable fiscalization": "Klikni za vključitev davčnega potrjevanja",
|
|
71
|
+
"Cannot skip fiscalization for cash payments": "Za gotovinska plačila ni mogoče preskočiti davčnega potrjevanja",
|
|
72
|
+
Premise: "Poslovni prostor",
|
|
73
|
+
Device: "Naprava",
|
|
67
74
|
} as const;
|
|
@@ -20,3 +20,33 @@ const {
|
|
|
20
20
|
} = createResourceHooks<CreditNote, CreateCreditNoteRequest>("creditNotes", CREDIT_NOTES_CACHE_KEY);
|
|
21
21
|
|
|
22
22
|
export { useCreateCreditNote, useUpdateCreditNote, useDeleteCreditNote };
|
|
23
|
+
|
|
24
|
+
// ============================================================================
|
|
25
|
+
// FINA Last-Used Combo (localStorage) for credit notes
|
|
26
|
+
// ============================================================================
|
|
27
|
+
|
|
28
|
+
const FINA_CN_LAST_USED_KEY = "hr:fina:cn:last-used";
|
|
29
|
+
|
|
30
|
+
export type FinaCombo = {
|
|
31
|
+
premise_id: string;
|
|
32
|
+
device_id: string;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export function getLastUsedFinaCombo(entityId: string): FinaCombo | null {
|
|
36
|
+
if (typeof window === "undefined") return null;
|
|
37
|
+
try {
|
|
38
|
+
const stored = localStorage.getItem(`${FINA_CN_LAST_USED_KEY}:${entityId}`);
|
|
39
|
+
return stored ? JSON.parse(stored) : null;
|
|
40
|
+
} catch {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function setLastUsedFinaCombo(entityId: string, combo: FinaCombo): void {
|
|
46
|
+
if (typeof window === "undefined") return;
|
|
47
|
+
try {
|
|
48
|
+
localStorage.setItem(`${FINA_CN_LAST_USED_KEY}:${entityId}`, JSON.stringify(combo));
|
|
49
|
+
} catch {
|
|
50
|
+
// Ignore localStorage errors
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -18,6 +18,7 @@ type CreditNote = any;
|
|
|
18
18
|
|
|
19
19
|
type CreditNoteListRowActionsProps = {
|
|
20
20
|
creditNote: CreditNote;
|
|
21
|
+
onView?: (creditNote: CreditNote) => void;
|
|
21
22
|
onAddPayment?: (creditNote: CreditNote) => void;
|
|
22
23
|
onDuplicate?: (creditNote: CreditNote) => void;
|
|
23
24
|
onDownloadStart?: () => void;
|
|
@@ -29,6 +30,7 @@ type CreditNoteListRowActionsProps = {
|
|
|
29
30
|
|
|
30
31
|
export default function CreditNoteListRowActions({
|
|
31
32
|
creditNote,
|
|
33
|
+
onView,
|
|
32
34
|
onAddPayment,
|
|
33
35
|
onDuplicate,
|
|
34
36
|
onDownloadStart,
|
|
@@ -64,12 +66,7 @@ export default function CreditNoteListRowActions({
|
|
|
64
66
|
</DropdownMenuGroup>
|
|
65
67
|
<DropdownMenuSeparator />
|
|
66
68
|
<DropdownMenuGroup>
|
|
67
|
-
<DropdownMenuItem
|
|
68
|
-
className="cursor-pointer"
|
|
69
|
-
onClick={() => {
|
|
70
|
-
window.location.href = `/app/documents/view/${creditNote.id}`;
|
|
71
|
-
}}
|
|
72
|
-
>
|
|
69
|
+
<DropdownMenuItem className="cursor-pointer" onClick={() => onView?.(creditNote)}>
|
|
73
70
|
<Eye className="h-4 w-4" />
|
|
74
71
|
{t("View credit note")}
|
|
75
72
|
</DropdownMenuItem>
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { CreditNote } from "@spaceinvoices/js-sdk";
|
|
2
|
-
import { useMemo } from "react";
|
|
2
|
+
import { useCallback, useMemo, useState } from "react";
|
|
3
3
|
import { DataTable } from "@/ui/components/table/data-table";
|
|
4
4
|
import { FormattedDate } from "@/ui/components/table/date-cell";
|
|
5
5
|
import { useTableFetch } from "@/ui/components/table/hooks/use-table-fetch";
|
|
6
|
+
import { SelectionToolbar } from "@/ui/components/table/selection-toolbar";
|
|
6
7
|
import type {
|
|
7
8
|
Column,
|
|
8
9
|
FilterConfig,
|
|
@@ -45,16 +46,19 @@ type CreditNoteListTableProps = {
|
|
|
45
46
|
namespace?: string;
|
|
46
47
|
locale?: string;
|
|
47
48
|
entityId?: string;
|
|
49
|
+
onView?: (creditNote: CreditNote) => void;
|
|
48
50
|
onAddPayment?: (creditNote: CreditNote) => void;
|
|
49
51
|
onDuplicate?: (creditNote: CreditNote) => void;
|
|
50
52
|
onDownloadStart?: () => void;
|
|
51
53
|
onDownloadSuccess?: (fileName: string) => void;
|
|
52
54
|
onDownloadError?: (error: string) => void;
|
|
55
|
+
onExportSelected?: (documentIds: string[]) => void;
|
|
53
56
|
} & ListTableProps<CreditNote>;
|
|
54
57
|
|
|
55
58
|
export default function CreditNoteListTable({
|
|
56
59
|
queryParams,
|
|
57
60
|
onRowClick,
|
|
61
|
+
onView,
|
|
58
62
|
onAddPayment,
|
|
59
63
|
onDuplicate,
|
|
60
64
|
onChangeParams,
|
|
@@ -62,6 +66,7 @@ export default function CreditNoteListTable({
|
|
|
62
66
|
onDownloadStart,
|
|
63
67
|
onDownloadSuccess,
|
|
64
68
|
onDownloadError,
|
|
69
|
+
onExportSelected,
|
|
65
70
|
...i18nProps
|
|
66
71
|
}: CreditNoteListTableProps) {
|
|
67
72
|
const t = createTranslation({
|
|
@@ -70,6 +75,7 @@ export default function CreditNoteListTable({
|
|
|
70
75
|
});
|
|
71
76
|
|
|
72
77
|
const { sdk } = useSDK();
|
|
78
|
+
const [selectedIds, setSelectedIds] = useState<Set<string>>(new Set());
|
|
73
79
|
|
|
74
80
|
const handleFetch = useTableFetch(async (params: TableQueryParams) => {
|
|
75
81
|
if (!sdk) throw new Error("SDK not initialized");
|
|
@@ -98,6 +104,28 @@ export default function CreditNoteListTable({
|
|
|
98
104
|
[t],
|
|
99
105
|
);
|
|
100
106
|
|
|
107
|
+
const handleExportPdfs = useCallback(() => {
|
|
108
|
+
if (selectedIds.size > 0 && onExportSelected) {
|
|
109
|
+
onExportSelected(Array.from(selectedIds));
|
|
110
|
+
}
|
|
111
|
+
}, [selectedIds, onExportSelected]);
|
|
112
|
+
|
|
113
|
+
const handleDeselectAll = useCallback(() => {
|
|
114
|
+
setSelectedIds(new Set());
|
|
115
|
+
}, []);
|
|
116
|
+
|
|
117
|
+
const selectionToolbar = useCallback(
|
|
118
|
+
(count: number) => (
|
|
119
|
+
<SelectionToolbar
|
|
120
|
+
selectedCount={count}
|
|
121
|
+
onExportPdfs={onExportSelected ? handleExportPdfs : undefined}
|
|
122
|
+
onDeselectAll={handleDeselectAll}
|
|
123
|
+
t={t}
|
|
124
|
+
/>
|
|
125
|
+
),
|
|
126
|
+
[handleExportPdfs, handleDeselectAll, onExportSelected, t],
|
|
127
|
+
);
|
|
128
|
+
|
|
101
129
|
const columns: Column<CreditNote>[] = useMemo(
|
|
102
130
|
() => [
|
|
103
131
|
{
|
|
@@ -148,7 +176,7 @@ export default function CreditNoteListTable({
|
|
|
148
176
|
{
|
|
149
177
|
id: "status",
|
|
150
178
|
header: t("Status"),
|
|
151
|
-
cell: (creditNote) => <
|
|
179
|
+
cell: (creditNote) => <CreditNoteStatusBadge creditNote={creditNote} t={t} />,
|
|
152
180
|
},
|
|
153
181
|
{
|
|
154
182
|
id: "actions",
|
|
@@ -157,6 +185,7 @@ export default function CreditNoteListTable({
|
|
|
157
185
|
cell: (creditNote) => (
|
|
158
186
|
<CreditNoteListRowActions
|
|
159
187
|
creditNote={creditNote}
|
|
188
|
+
onView={onView}
|
|
160
189
|
onAddPayment={onAddPayment}
|
|
161
190
|
onDuplicate={onDuplicate}
|
|
162
191
|
onDownloadStart={onDownloadStart}
|
|
@@ -168,7 +197,17 @@ export default function CreditNoteListTable({
|
|
|
168
197
|
),
|
|
169
198
|
},
|
|
170
199
|
],
|
|
171
|
-
[
|
|
200
|
+
[
|
|
201
|
+
t,
|
|
202
|
+
onRowClick,
|
|
203
|
+
onView,
|
|
204
|
+
onAddPayment,
|
|
205
|
+
onDuplicate,
|
|
206
|
+
onDownloadStart,
|
|
207
|
+
onDownloadSuccess,
|
|
208
|
+
onDownloadError,
|
|
209
|
+
i18nProps.locale,
|
|
210
|
+
],
|
|
172
211
|
);
|
|
173
212
|
|
|
174
213
|
return (
|
|
@@ -184,17 +223,49 @@ export default function CreditNoteListTable({
|
|
|
184
223
|
filterConfig={filterConfig}
|
|
185
224
|
t={t}
|
|
186
225
|
locale={i18nProps.locale}
|
|
226
|
+
selectable={!!onExportSelected}
|
|
227
|
+
selectedIds={selectedIds}
|
|
228
|
+
onSelectionChange={setSelectedIds}
|
|
229
|
+
selectionToolbar={selectionToolbar}
|
|
187
230
|
/>
|
|
188
231
|
);
|
|
189
232
|
}
|
|
190
233
|
|
|
191
|
-
/**
|
|
192
|
-
function
|
|
234
|
+
/** Status badge for credit notes */
|
|
235
|
+
function CreditNoteStatusBadge({ creditNote, t }: { creditNote: CreditNote; t: (key: string) => string }) {
|
|
236
|
+
if ((creditNote as any).voided_at) {
|
|
237
|
+
return (
|
|
238
|
+
<Badge variant="outline" className="border-red-500 bg-red-50 text-red-700 dark:bg-red-950 dark:text-red-400">
|
|
239
|
+
{t("Voided")}
|
|
240
|
+
</Badge>
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
if ((creditNote as any).is_draft) {
|
|
244
|
+
return null;
|
|
245
|
+
}
|
|
193
246
|
if (creditNote.paid_in_full) {
|
|
194
|
-
return
|
|
247
|
+
return (
|
|
248
|
+
<Badge
|
|
249
|
+
variant="outline"
|
|
250
|
+
className="border-green-500 bg-green-50 text-green-700 dark:bg-green-950 dark:text-green-400"
|
|
251
|
+
>
|
|
252
|
+
{t("Paid")}
|
|
253
|
+
</Badge>
|
|
254
|
+
);
|
|
195
255
|
}
|
|
196
256
|
if (creditNote.total_paid > 0) {
|
|
197
|
-
return
|
|
257
|
+
return (
|
|
258
|
+
<Badge
|
|
259
|
+
variant="outline"
|
|
260
|
+
className="border-yellow-500 bg-yellow-50 text-yellow-700 dark:bg-yellow-950 dark:text-yellow-400"
|
|
261
|
+
>
|
|
262
|
+
{t("Partially Paid")}
|
|
263
|
+
</Badge>
|
|
264
|
+
);
|
|
198
265
|
}
|
|
199
|
-
return
|
|
266
|
+
return (
|
|
267
|
+
<Badge variant="outline" className="border-gray-500 bg-gray-50 text-gray-700 dark:bg-gray-800 dark:text-gray-400">
|
|
268
|
+
{t("Unpaid")}
|
|
269
|
+
</Badge>
|
|
270
|
+
);
|
|
200
271
|
}
|