@fast-white-cat/integration-ksef-direct 0.1.0
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/README.md +36 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +7 -0
- package/dist/modules/integration_ksef_direct/acl.js +13 -0
- package/dist/modules/integration_ksef_direct/acl.js.map +7 -0
- package/dist/modules/integration_ksef_direct/api/get/integration-ksef-direct/documents/[id].js +92 -0
- package/dist/modules/integration_ksef_direct/api/get/integration-ksef-direct/documents/[id].js.map +7 -0
- package/dist/modules/integration_ksef_direct/api/get/integration-ksef-direct/documents.js +105 -0
- package/dist/modules/integration_ksef_direct/api/get/integration-ksef-direct/documents.js.map +7 -0
- package/dist/modules/integration_ksef_direct/api/get/integration-ksef-direct/health.js +158 -0
- package/dist/modules/integration_ksef_direct/api/get/integration-ksef-direct/health.js.map +7 -0
- package/dist/modules/integration_ksef_direct/api/get/integration-ksef-direct/received-documents/[id].js +86 -0
- package/dist/modules/integration_ksef_direct/api/get/integration-ksef-direct/received-documents/[id].js.map +7 -0
- package/dist/modules/integration_ksef_direct/api/get/integration-ksef-direct/received-documents.js +112 -0
- package/dist/modules/integration_ksef_direct/api/get/integration-ksef-direct/received-documents.js.map +7 -0
- package/dist/modules/integration_ksef_direct/api/get/integration-ksef-direct/seller-info.js +54 -0
- package/dist/modules/integration_ksef_direct/api/get/integration-ksef-direct/seller-info.js.map +7 -0
- package/dist/modules/integration_ksef_direct/api/post/integration-ksef-direct/documents/[id]/send.js +64 -0
- package/dist/modules/integration_ksef_direct/api/post/integration-ksef-direct/documents/[id]/send.js.map +7 -0
- package/dist/modules/integration_ksef_direct/api/post/integration-ksef-direct/documents.js +104 -0
- package/dist/modules/integration_ksef_direct/api/post/integration-ksef-direct/documents.js.map +7 -0
- package/dist/modules/integration_ksef_direct/api/post/integration-ksef-direct/invoice-numbers.js +41 -0
- package/dist/modules/integration_ksef_direct/api/post/integration-ksef-direct/invoice-numbers.js.map +7 -0
- package/dist/modules/integration_ksef_direct/api/post/integration-ksef-direct/received-documents/fetch.js +172 -0
- package/dist/modules/integration_ksef_direct/api/post/integration-ksef-direct/received-documents/fetch.js.map +7 -0
- package/dist/modules/integration_ksef_direct/api/post/integration-ksef-direct/received-documents/sync.js +80 -0
- package/dist/modules/integration_ksef_direct/api/post/integration-ksef-direct/received-documents/sync.js.map +7 -0
- package/dist/modules/integration_ksef_direct/backend/integration-ksef-direct/documents/new/page.js +441 -0
- package/dist/modules/integration_ksef_direct/backend/integration-ksef-direct/documents/new/page.js.map +7 -0
- package/dist/modules/integration_ksef_direct/backend/integration-ksef-direct/documents/new/page.meta.js +8 -0
- package/dist/modules/integration_ksef_direct/backend/integration-ksef-direct/documents/new/page.meta.js.map +7 -0
- package/dist/modules/integration_ksef_direct/backend/integration-ksef-direct/documents/page.js +193 -0
- package/dist/modules/integration_ksef_direct/backend/integration-ksef-direct/documents/page.js.map +7 -0
- package/dist/modules/integration_ksef_direct/backend/integration-ksef-direct/received-documents/page.js +314 -0
- package/dist/modules/integration_ksef_direct/backend/integration-ksef-direct/received-documents/page.js.map +7 -0
- package/dist/modules/integration_ksef_direct/backend/page.js +154 -0
- package/dist/modules/integration_ksef_direct/backend/page.js.map +7 -0
- package/dist/modules/integration_ksef_direct/commands/create-ksef-direct-document.js +80 -0
- package/dist/modules/integration_ksef_direct/commands/create-ksef-direct-document.js.map +7 -0
- package/dist/modules/integration_ksef_direct/commands/enqueue-ksef-direct-document.js +43 -0
- package/dist/modules/integration_ksef_direct/commands/enqueue-ksef-direct-document.js.map +7 -0
- package/dist/modules/integration_ksef_direct/data/entities.js +224 -0
- package/dist/modules/integration_ksef_direct/data/entities.js.map +7 -0
- package/dist/modules/integration_ksef_direct/data/validators.js +103 -0
- package/dist/modules/integration_ksef_direct/data/validators.js.map +7 -0
- package/dist/modules/integration_ksef_direct/di.js +11 -0
- package/dist/modules/integration_ksef_direct/di.js.map +7 -0
- package/dist/modules/integration_ksef_direct/events.js +21 -0
- package/dist/modules/integration_ksef_direct/events.js.map +7 -0
- package/dist/modules/integration_ksef_direct/index.js +10 -0
- package/dist/modules/integration_ksef_direct/index.js.map +7 -0
- package/dist/modules/integration_ksef_direct/integration.js +56 -0
- package/dist/modules/integration_ksef_direct/integration.js.map +7 -0
- package/dist/modules/integration_ksef_direct/lib/health.js +32 -0
- package/dist/modules/integration_ksef_direct/lib/health.js.map +7 -0
- package/dist/modules/integration_ksef_direct/lib/invoiceNumberFormat.js +23 -0
- package/dist/modules/integration_ksef_direct/lib/invoiceNumberFormat.js.map +7 -0
- package/dist/modules/integration_ksef_direct/lib/ksefClient.js +523 -0
- package/dist/modules/integration_ksef_direct/lib/ksefClient.js.map +7 -0
- package/dist/modules/integration_ksef_direct/lib/ksefCrypto.js +103 -0
- package/dist/modules/integration_ksef_direct/lib/ksefCrypto.js.map +7 -0
- package/dist/modules/integration_ksef_direct/lib/ksefFa2Xml.js +123 -0
- package/dist/modules/integration_ksef_direct/lib/ksefFa2Xml.js.map +7 -0
- package/dist/modules/integration_ksef_direct/lib/ksefXmlParser.js +76 -0
- package/dist/modules/integration_ksef_direct/lib/ksefXmlParser.js.map +7 -0
- package/dist/modules/integration_ksef_direct/migrations/Migration20260519210000_integration_ksef_direct.js +15 -0
- package/dist/modules/integration_ksef_direct/migrations/Migration20260519210000_integration_ksef_direct.js.map +7 -0
- package/dist/modules/integration_ksef_direct/migrations/Migration20260520120000_ksef_direct_documents.js +17 -0
- package/dist/modules/integration_ksef_direct/migrations/Migration20260520120000_ksef_direct_documents.js.map +7 -0
- package/dist/modules/integration_ksef_direct/migrations/Migration20260520220000_ksef_direct_send_queue.js +15 -0
- package/dist/modules/integration_ksef_direct/migrations/Migration20260520220000_ksef_direct_send_queue.js.map +7 -0
- package/dist/modules/integration_ksef_direct/migrations/Migration20260520230000_ksef_direct_seller_per_document.js +17 -0
- package/dist/modules/integration_ksef_direct/migrations/Migration20260520230000_ksef_direct_seller_per_document.js.map +7 -0
- package/dist/modules/integration_ksef_direct/migrations/Migration20260521120000_ksef_direct_received_documents.js +16 -0
- package/dist/modules/integration_ksef_direct/migrations/Migration20260521120000_ksef_direct_received_documents.js.map +7 -0
- package/dist/modules/integration_ksef_direct/migrations/Migration20260521130000_ksef_received_download_urls.js +15 -0
- package/dist/modules/integration_ksef_direct/migrations/Migration20260521130000_ksef_received_download_urls.js.map +7 -0
- package/dist/modules/integration_ksef_direct/setup.js +11 -0
- package/dist/modules/integration_ksef_direct/setup.js.map +7 -0
- package/dist/modules/integration_ksef_direct/subscribers/auto-enqueue-ksef-document.js +19 -0
- package/dist/modules/integration_ksef_direct/subscribers/auto-enqueue-ksef-document.js.map +7 -0
- package/dist/modules/integration_ksef_direct/workers/check-ksef-document-status.js +103 -0
- package/dist/modules/integration_ksef_direct/workers/check-ksef-document-status.js.map +7 -0
- package/dist/modules/integration_ksef_direct/workers/send-ksef-document.js +104 -0
- package/dist/modules/integration_ksef_direct/workers/send-ksef-document.js.map +7 -0
- package/dist/modules/integration_ksef_direct/workers/sync-received-documents.js +137 -0
- package/dist/modules/integration_ksef_direct/workers/sync-received-documents.js.map +7 -0
- package/dist/types/declarations.d.js +1 -0
- package/dist/types/declarations.d.js.map +7 -0
- package/package.json +98 -0
- package/src/index.ts +1 -0
- package/src/modules/integration_ksef_direct/__tests__/invoiceNumberFormat.test.ts +42 -0
- package/src/modules/integration_ksef_direct/__tests__/ksefFa2Xml.test.ts +407 -0
- package/src/modules/integration_ksef_direct/__tests__/ksefXmlParser.test.ts +230 -0
- package/src/modules/integration_ksef_direct/acl.ts +9 -0
- package/src/modules/integration_ksef_direct/api/get/integration-ksef-direct/documents/[id].ts +94 -0
- package/src/modules/integration_ksef_direct/api/get/integration-ksef-direct/documents.ts +111 -0
- package/src/modules/integration_ksef_direct/api/get/integration-ksef-direct/health.ts +194 -0
- package/src/modules/integration_ksef_direct/api/get/integration-ksef-direct/received-documents/[id].ts +88 -0
- package/src/modules/integration_ksef_direct/api/get/integration-ksef-direct/received-documents.ts +119 -0
- package/src/modules/integration_ksef_direct/api/get/integration-ksef-direct/seller-info.ts +62 -0
- package/src/modules/integration_ksef_direct/api/post/integration-ksef-direct/documents/[id]/send.ts +64 -0
- package/src/modules/integration_ksef_direct/api/post/integration-ksef-direct/documents.ts +109 -0
- package/src/modules/integration_ksef_direct/api/post/integration-ksef-direct/invoice-numbers.ts +40 -0
- package/src/modules/integration_ksef_direct/api/post/integration-ksef-direct/received-documents/fetch.ts +185 -0
- package/src/modules/integration_ksef_direct/api/post/integration-ksef-direct/received-documents/sync.ts +86 -0
- package/src/modules/integration_ksef_direct/backend/integration-ksef-direct/documents/new/page.meta.ts +4 -0
- package/src/modules/integration_ksef_direct/backend/integration-ksef-direct/documents/new/page.tsx +470 -0
- package/src/modules/integration_ksef_direct/backend/integration-ksef-direct/documents/page.tsx +233 -0
- package/src/modules/integration_ksef_direct/backend/integration-ksef-direct/received-documents/page.tsx +415 -0
- package/src/modules/integration_ksef_direct/backend/page.tsx +183 -0
- package/src/modules/integration_ksef_direct/commands/create-ksef-direct-document.ts +93 -0
- package/src/modules/integration_ksef_direct/commands/enqueue-ksef-direct-document.ts +57 -0
- package/src/modules/integration_ksef_direct/data/entities.ts +195 -0
- package/src/modules/integration_ksef_direct/data/validators.ts +115 -0
- package/src/modules/integration_ksef_direct/di.ts +9 -0
- package/src/modules/integration_ksef_direct/events.ts +18 -0
- package/src/modules/integration_ksef_direct/i18n/en.json +115 -0
- package/src/modules/integration_ksef_direct/i18n/pl.json +115 -0
- package/src/modules/integration_ksef_direct/index.ts +6 -0
- package/src/modules/integration_ksef_direct/integration.ts +54 -0
- package/src/modules/integration_ksef_direct/lib/health.ts +43 -0
- package/src/modules/integration_ksef_direct/lib/invoiceNumberFormat.ts +23 -0
- package/src/modules/integration_ksef_direct/lib/ksefClient.ts +668 -0
- package/src/modules/integration_ksef_direct/lib/ksefCrypto.ts +138 -0
- package/src/modules/integration_ksef_direct/lib/ksefFa2Xml.ts +147 -0
- package/src/modules/integration_ksef_direct/lib/ksefXmlParser.ts +97 -0
- package/src/modules/integration_ksef_direct/migrations/.snapshot-open-mercato.json +1028 -0
- package/src/modules/integration_ksef_direct/migrations/Migration20260519210000_integration_ksef_direct.ts +15 -0
- package/src/modules/integration_ksef_direct/migrations/Migration20260520120000_ksef_direct_documents.ts +17 -0
- package/src/modules/integration_ksef_direct/migrations/Migration20260520220000_ksef_direct_send_queue.ts +15 -0
- package/src/modules/integration_ksef_direct/migrations/Migration20260520230000_ksef_direct_seller_per_document.ts +17 -0
- package/src/modules/integration_ksef_direct/migrations/Migration20260521120000_ksef_direct_received_documents.ts +16 -0
- package/src/modules/integration_ksef_direct/migrations/Migration20260521130000_ksef_received_download_urls.ts +15 -0
- package/src/modules/integration_ksef_direct/setup.ts +9 -0
- package/src/modules/integration_ksef_direct/subscribers/auto-enqueue-ksef-document.ts +21 -0
- package/src/modules/integration_ksef_direct/workers/check-ksef-document-status.ts +129 -0
- package/src/modules/integration_ksef_direct/workers/send-ksef-document.ts +137 -0
- package/src/modules/integration_ksef_direct/workers/sync-received-documents.ts +171 -0
- package/src/types/declarations.d.ts +1 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../../src/modules/integration_ksef_direct/backend/integration-ksef-direct/documents/new/page.tsx"],
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { useRouter } from 'next/navigation'\nimport { Plus, RefreshCw, Trash2 } from 'lucide-react'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { SectionHeader } from '@open-mercato/ui/backend/SectionHeader'\nimport { FormField } from '@open-mercato/ui/primitives/form-field'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { IconButton } from '@open-mercato/ui/primitives/icon-button'\nimport { Alert, AlertDescription } from '@open-mercato/ui/primitives/alert'\nimport { Spinner } from '@open-mercato/ui/primitives/spinner'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\n\nexport const pageMetadata = { features: ['integration_ksef_direct.documents.create'], navHidden: true }\n\nconst VAT_RATES = ['0', '5', '8', '23', 'ZW', 'NP'] as const\nconst CURRENCIES = ['PLN', 'EUR', 'USD', 'GBP'] as const\nconst VAT_RATE_MULTIPLIERS: Record<string, number> = { '0': 0, '5': 5, '8': 8, '23': 23, ZW: 0, NP: 0 }\n\ntype LineItemState = {\n description: string\n quantity: string\n unit: string\n unitNetPrice: string\n vatRate: string\n}\n\ntype Totals = { net: number; vat: number; gross: number }\n\nfunction round2(v: number) { return Math.round(v * 100) / 100 }\n\nfunction computeTotals(items: LineItemState[]): Totals {\n let net = 0, vat = 0\n for (const item of items) {\n const qty = parseFloat(item.quantity) || 0\n const price = parseFloat(item.unitNetPrice) || 0\n const lineNet = round2(qty * price)\n const rate = VAT_RATE_MULTIPLIERS[item.vatRate] ?? 0\n const lineVat = round2(lineNet * rate / 100)\n net += lineNet\n vat += lineVat\n }\n net = round2(net)\n vat = round2(vat)\n return { net, vat, gross: round2(net + vat) }\n}\n\nfunction emptyLine(): LineItemState {\n return { description: '', quantity: '1', unit: 'szt', unitNetPrice: '0.00', vatRate: '23' }\n}\n\nexport default function NewKsefDirectDocumentPage() {\n const t = useT()\n const router = useRouter()\n\n const [buyerNip, setBuyerNip] = React.useState('')\n const [buyerName, setBuyerName] = React.useState('')\n const [invoiceNumber, setInvoiceNumber] = React.useState('')\n const today = new Date().toISOString().split('T')[0]\n const [issueDate, setIssueDate] = React.useState(today)\n const [saleDate, setSaleDate] = React.useState(today)\n const [currency, setCurrency] = React.useState('PLN')\n const [lineItems, setLineItems] = React.useState<LineItemState[]>([emptyLine()])\n const [notes, setNotes] = React.useState('')\n const [sellerNip, setSellerNip] = React.useState<string | null>(null)\n const [sellerName, setSellerName] = React.useState('')\n const [isGeneratingNumber, setIsGeneratingNumber] = React.useState(false)\n const [sellerAddressL1, setSellerAddressL1] = React.useState('')\n const [sellerCity, setSellerCity] = React.useState('')\n const [sellerCountry, setSellerCountry] = React.useState('PL')\n const [submitError, setSubmitError] = React.useState<string | null>(null)\n const [isMutating, setIsMutating] = React.useState(false)\n\n const { runMutation } = useGuardedMutation<{ entityType: string }>({\n contextId: 'integration_ksef_direct:new-document',\n })\n\n React.useEffect(() => {\n apiCall('/api/integration-ksef-direct/seller-info')\n .then((res) => {\n if (!res.ok) return\n const data = res.result as { sellerNip: string | null; sellerName: string | null }\n if (data.sellerNip !== undefined) setSellerNip(data.sellerNip)\n if (data.sellerName && !sellerName) setSellerName(data.sellerName)\n })\n .catch(() => {\n flash(t('integration_ksef_direct.documents.form.seller_info_error', 'Failed to load seller info'), 'error')\n })\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n const totals = React.useMemo(() => computeTotals(lineItems), [lineItems])\n\n React.useEffect(() => {\n function onKeyDown(e: KeyboardEvent) {\n if ((e.metaKey || e.ctrlKey) && e.key === 'Enter') {\n e.preventDefault()\n void handleSubmit()\n }\n if (e.key === 'Escape') router.back()\n }\n window.addEventListener('keydown', onKeyDown)\n return () => window.removeEventListener('keydown', onKeyDown)\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [router, buyerNip, buyerName, invoiceNumber, issueDate, saleDate, currency, lineItems, notes, sellerName, sellerAddressL1, sellerCity, sellerCountry])\n\n function addLine() {\n setLineItems((prev) => [...prev, emptyLine()])\n }\n\n function removeLine(index: number) {\n if (lineItems.length <= 1) return\n setLineItems((prev) => prev.filter((_, i) => i !== index))\n }\n\n function updateLine(index: number, field: keyof LineItemState, value: string) {\n setLineItems((prev) => prev.map((item, i) => i === index ? { ...item, [field]: value } : item))\n }\n\n async function handleGenerateNumber() {\n setIsGeneratingNumber(true)\n try {\n const result = await apiCall('/api/integration-ksef-direct/invoice-numbers', { method: 'POST' })\n if (result.ok) {\n const data = result.result as { number: string }\n setInvoiceNumber(data.number)\n } else {\n flash(t('integration_ksef_direct.documents.form.generate_number_error', 'Failed to generate invoice number'), 'error')\n }\n } catch {\n flash(t('integration_ksef_direct.documents.form.generate_number_error', 'Failed to generate invoice number'), 'error')\n } finally {\n setIsGeneratingNumber(false)\n }\n }\n\n async function handleSubmit() {\n setSubmitError(null)\n if (!sellerAddressL1.trim() || !sellerCity.trim()) {\n setSubmitError(t('integration_ksef_direct.documents.form.error_seller_address_required', 'Seller street and city are required.'))\n return\n }\n setIsMutating(true)\n const body = {\n buyerNip,\n buyerName: buyerName || undefined,\n invoiceNumber,\n issueDate,\n saleDate: saleDate || undefined,\n currency,\n lineItems: lineItems.map((item) => ({\n description: item.description,\n quantity: parseFloat(item.quantity) || 0,\n unit: item.unit,\n unitNetPrice: parseFloat(item.unitNetPrice) || 0,\n vatRate: item.vatRate,\n })),\n notes: notes || undefined,\n sellerName: sellerName || undefined,\n sellerAddressL1,\n sellerCity,\n sellerCountry: sellerCountry || undefined,\n }\n\n try {\n await runMutation({\n operation: async () => {\n const result = await apiCall('/api/integration-ksef-direct/documents', {\n method: 'POST',\n body: JSON.stringify(body),\n headers: { 'Content-Type': 'application/json' },\n })\n if (!result.ok) {\n const err = (result.result as Record<string, unknown>)?.error\n throw new Error(typeof err === 'string' ? err : t('integration_ksef_direct.documents.form.error', 'Submission failed'))\n }\n return result.result\n },\n context: { entityType: 'integration_ksef_direct.document' },\n mutationPayload: { entityType: 'integration_ksef_direct.document' },\n })\n flash(t('integration_ksef_direct.documents.form.success', 'Document created successfully.'), 'success')\n router.push('/backend/integration-ksef-direct/documents')\n } catch (err) {\n setSubmitError(err instanceof Error ? err.message : t('integration_ksef_direct.documents.form.error', 'Submission failed'))\n } finally {\n setIsMutating(false)\n }\n }\n\n return (\n <Page>\n <PageBody>\n <h1 className=\"text-xl font-semibold mb-6\">\n {t('integration_ksef_direct.documents.form.title_new', 'New KSeF Document')}\n </h1>\n\n {submitError && (\n <Alert variant=\"destructive\" className=\"mb-6\">\n <AlertDescription>{submitError}</AlertDescription>\n </Alert>\n )}\n\n <SectionHeader title={t('integration_ksef_direct.documents.form.section.buyer', 'Buyer')} />\n <div className=\"grid grid-cols-2 gap-4 mb-6\">\n <FormField label={t('integration_ksef_direct.documents.form.buyer_nip', 'Buyer NIP')} required>\n <input\n type=\"text\"\n className=\"w-full border border-input rounded-md px-3 py-2 text-sm\"\n value={buyerNip}\n onChange={(e) => setBuyerNip(e.target.value)}\n placeholder=\"1234567890\"\n maxLength={10}\n />\n </FormField>\n <FormField label={t('integration_ksef_direct.documents.form.buyer_name', 'Buyer Name')}>\n <input\n type=\"text\"\n className=\"w-full border border-input rounded-md px-3 py-2 text-sm\"\n value={buyerName}\n onChange={(e) => setBuyerName(e.target.value)}\n />\n </FormField>\n </div>\n\n <SectionHeader title={t('integration_ksef_direct.documents.form.section.invoice', 'Invoice Details')} />\n <div className=\"grid grid-cols-2 gap-4 mb-6\">\n <FormField label={t('integration_ksef_direct.documents.form.invoice_number', 'Invoice Number')} required>\n <div className=\"flex gap-2 items-center\">\n <input\n type=\"text\"\n className=\"flex-1 border border-input rounded-md px-3 py-2 text-sm\"\n value={invoiceNumber}\n onChange={(e) => setInvoiceNumber(e.target.value)}\n />\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={() => void handleGenerateNumber()}\n disabled={isGeneratingNumber}\n className=\"shrink-0\"\n >\n {isGeneratingNumber\n ? <><Spinner className=\"size-4 mr-2\" />{t('integration_ksef_direct.documents.form.generating', 'Generating...')}</>\n : <><RefreshCw className=\"size-4 mr-2\" aria-hidden />{t('integration_ksef_direct.documents.form.generate_number', 'Generate number')}</>\n }\n </Button>\n </div>\n </FormField>\n <FormField label={t('integration_ksef_direct.documents.form.currency', 'Currency')}>\n <select\n className=\"w-full border border-input rounded-md px-3 py-2 text-sm\"\n value={currency}\n onChange={(e) => setCurrency(e.target.value)}\n >\n {CURRENCIES.map((c) => <option key={c} value={c}>{c}</option>)}\n </select>\n </FormField>\n <FormField label={t('integration_ksef_direct.documents.form.issue_date', 'Issue Date')} required>\n <input\n type=\"date\"\n className=\"w-full border border-input rounded-md px-3 py-2 text-sm\"\n value={issueDate}\n onChange={(e) => setIssueDate(e.target.value)}\n />\n </FormField>\n <FormField label={t('integration_ksef_direct.documents.form.sale_date', 'Sale Date')}>\n <input\n type=\"date\"\n className=\"w-full border border-input rounded-md px-3 py-2 text-sm\"\n value={saleDate}\n onChange={(e) => setSaleDate(e.target.value)}\n />\n </FormField>\n </div>\n\n <SectionHeader\n title={`${t('integration_ksef_direct.documents.form.line_items', 'Line Items')} (${lineItems.length})`}\n className=\"mt-6\"\n />\n <div className=\"space-y-3 mb-4\">\n {lineItems.map((item, index) => (\n <div key={index} className=\"grid grid-cols-12 gap-2 items-end border border-border rounded-md p-3\">\n <div className=\"col-span-4\">\n <FormField label={t('integration_ksef_direct.documents.form.line_items.description', 'Description')} required>\n <input\n type=\"text\"\n className=\"w-full border border-input rounded-md px-3 py-2 text-sm\"\n value={item.description}\n onChange={(e) => updateLine(index, 'description', e.target.value)}\n />\n </FormField>\n </div>\n <div className=\"col-span-2\">\n <FormField label={t('integration_ksef_direct.documents.form.line_items.quantity', 'Qty')}>\n <input\n type=\"number\"\n min=\"0.001\"\n step=\"any\"\n className=\"w-full border border-input rounded-md px-3 py-2 text-sm\"\n value={item.quantity}\n onChange={(e) => updateLine(index, 'quantity', e.target.value)}\n />\n </FormField>\n </div>\n <div className=\"col-span-1\">\n <FormField label={t('integration_ksef_direct.documents.form.line_items.unit', 'Unit')}>\n <input\n type=\"text\"\n className=\"w-full border border-input rounded-md px-3 py-2 text-sm\"\n value={item.unit}\n onChange={(e) => updateLine(index, 'unit', e.target.value)}\n />\n </FormField>\n </div>\n <div className=\"col-span-2\">\n <FormField label={t('integration_ksef_direct.documents.form.line_items.unit_net_price', 'Net Price')}>\n <input\n type=\"number\"\n min=\"0\"\n step=\"0.01\"\n className=\"w-full border border-input rounded-md px-3 py-2 text-sm\"\n value={item.unitNetPrice}\n onChange={(e) => updateLine(index, 'unitNetPrice', e.target.value)}\n />\n </FormField>\n </div>\n <div className=\"col-span-2\">\n <FormField label={t('integration_ksef_direct.documents.form.line_items.vat_rate', 'VAT')}>\n <select\n className=\"w-full border border-input rounded-md px-3 py-2 text-sm\"\n value={item.vatRate}\n onChange={(e) => updateLine(index, 'vatRate', e.target.value)}\n >\n {VAT_RATES.map((r) => <option key={r} value={r}>{r}%</option>)}\n </select>\n </FormField>\n </div>\n <div className=\"col-span-1 flex justify-end pb-1\">\n <IconButton\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n aria-label={t('integration_ksef_direct.documents.form.line_items.remove', 'Remove line')}\n onClick={() => removeLine(index)}\n disabled={lineItems.length <= 1}\n >\n <Trash2 className=\"size-4\" />\n </IconButton>\n </div>\n </div>\n ))}\n </div>\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={addLine} className=\"mb-6\">\n <Plus className=\"size-4 mr-2\" aria-hidden />\n {t('integration_ksef_direct.documents.form.line_items.add', 'Add Line')}\n </Button>\n\n <SectionHeader title={t('integration_ksef_direct.documents.form.section.summary', 'Summary')} />\n <div className=\"grid grid-cols-3 gap-4 mb-6\">\n <FormField label={t('integration_ksef_direct.documents.form.net_amount', 'Net Amount')}>\n <input\n type=\"text\"\n readOnly\n className=\"w-full border border-input rounded-md px-3 py-2 text-sm bg-muted\"\n value={`${totals.net.toFixed(2)} ${currency}`}\n />\n </FormField>\n <FormField label={t('integration_ksef_direct.documents.form.vat_amount', 'VAT Amount')}>\n <input\n type=\"text\"\n readOnly\n className=\"w-full border border-input rounded-md px-3 py-2 text-sm bg-muted\"\n value={`${totals.vat.toFixed(2)} ${currency}`}\n />\n </FormField>\n <FormField label={t('integration_ksef_direct.documents.form.gross_amount', 'Gross Amount')}>\n <input\n type=\"text\"\n readOnly\n className=\"w-full border border-input rounded-md px-3 py-2 text-sm bg-muted font-semibold\"\n value={`${totals.gross.toFixed(2)} ${currency}`}\n />\n </FormField>\n </div>\n\n <SectionHeader title={t('integration_ksef_direct.documents.form.section.seller', 'Seller')} className=\"mt-6\" />\n <div className=\"grid grid-cols-2 gap-4 mb-4\">\n <FormField label={t('integration_ksef_direct.documents.form.seller_nip', 'Seller NIP')}>\n <input\n type=\"text\"\n disabled\n className=\"w-full border border-input rounded-md px-3 py-2 text-sm bg-muted text-muted-foreground cursor-not-allowed\"\n value={sellerNip ?? ''}\n placeholder={sellerNip === null ? t('integration_ksef_direct.documents.form.seller_nip_placeholder', 'KSeF not configured') : ''}\n />\n </FormField>\n <FormField label={t('integration_ksef_direct.documents.form.seller_name', 'Seller Name')} required>\n <input\n type=\"text\"\n className=\"w-full border border-input rounded-md px-3 py-2 text-sm\"\n value={sellerName}\n onChange={(e) => setSellerName(e.target.value)}\n maxLength={512}\n />\n </FormField>\n </div>\n\n <SectionHeader title={t('integration_ksef_direct.documents.form.section.seller_address', 'Seller Address')} className=\"mt-0\" />\n <div className=\"grid grid-cols-2 gap-4 mb-6\">\n <FormField label={t('integration_ksef_direct.documents.form.seller_address_l1', 'Street and number')} required>\n <input\n type=\"text\"\n className=\"w-full border border-input rounded-md px-3 py-2 text-sm\"\n value={sellerAddressL1}\n onChange={(e) => setSellerAddressL1(e.target.value)}\n maxLength={512}\n />\n </FormField>\n <FormField label={t('integration_ksef_direct.documents.form.seller_city', 'City')} required>\n <input\n type=\"text\"\n className=\"w-full border border-input rounded-md px-3 py-2 text-sm\"\n value={sellerCity}\n onChange={(e) => setSellerCity(e.target.value)}\n maxLength={256}\n />\n </FormField>\n <FormField label={t('integration_ksef_direct.documents.form.seller_country', 'Country')}>\n <input\n type=\"text\"\n className=\"w-full border border-input rounded-md px-3 py-2 text-sm\"\n value={sellerCountry}\n onChange={(e) => setSellerCountry(e.target.value)}\n maxLength={2}\n placeholder=\"PL\"\n />\n </FormField>\n </div>\n\n <FormField label={t('integration_ksef_direct.documents.form.notes', 'Notes')} className=\"mb-6\">\n <textarea\n rows={3}\n className=\"w-full border border-input rounded-md px-3 py-2 text-sm\"\n value={notes}\n onChange={(e) => setNotes(e.target.value)}\n />\n </FormField>\n\n <div className=\"flex gap-3\">\n <Button\n type=\"button\"\n onClick={() => void handleSubmit()}\n disabled={isMutating}\n >\n {t('integration_ksef_direct.documents.form.submit', 'Save Document')}\n </Button>\n <Button type=\"button\" variant=\"outline\" onClick={() => router.back()}>\n {t('common.cancel', 'Cancel')}\n </Button>\n </div>\n </PageBody>\n </Page>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../../src/modules/integration_ksef_direct/backend/integration-ksef-direct/documents/new/page.meta.ts"],
|
|
4
|
+
"sourcesContent": ["export const metadata = {\n navHidden: true,\n requireFeatures: ['integration_ksef_direct.documents.create'],\n}\n"],
|
|
5
|
+
"mappings": "AAAO,MAAM,WAAW;AAAA,EACtB,WAAW;AAAA,EACX,iBAAiB,CAAC,0CAA0C;AAC9D;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/modules/integration_ksef_direct/backend/integration-ksef-direct/documents/page.js
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import Link from "next/link";
|
|
5
|
+
import { Plus, Send, RefreshCw } from "lucide-react";
|
|
6
|
+
import { Page, PageBody } from "@open-mercato/ui/backend/Page";
|
|
7
|
+
import { DataTable } from "@open-mercato/ui/backend/DataTable";
|
|
8
|
+
import { StatusBadge } from "@open-mercato/ui/primitives/status-badge";
|
|
9
|
+
import { Button } from "@open-mercato/ui/primitives/button";
|
|
10
|
+
import { flash } from "@open-mercato/ui/backend/FlashMessages";
|
|
11
|
+
import { apiCall } from "@open-mercato/ui/backend/utils/apiCall";
|
|
12
|
+
import { useGuardedMutation } from "@open-mercato/ui/backend/injection/useGuardedMutation";
|
|
13
|
+
import { useOrganizationScopeVersion } from "@open-mercato/shared/lib/frontend/useOrganizationScope";
|
|
14
|
+
import { useT } from "@open-mercato/shared/lib/i18n/context";
|
|
15
|
+
import { useAppEvent } from "@open-mercato/ui/backend/injection/useAppEvent";
|
|
16
|
+
const PAGE_SIZE = 50;
|
|
17
|
+
const STATUS_VARIANT = {
|
|
18
|
+
draft: "neutral",
|
|
19
|
+
queued: "warning",
|
|
20
|
+
sending: "warning",
|
|
21
|
+
sent: "success",
|
|
22
|
+
failed: "error"
|
|
23
|
+
};
|
|
24
|
+
const pageMetadata = {
|
|
25
|
+
features: ["integration_ksef_direct.documents.view"]
|
|
26
|
+
};
|
|
27
|
+
function KsefDirectDocumentsPage() {
|
|
28
|
+
const t = useT();
|
|
29
|
+
const scopeVersion = useOrganizationScopeVersion();
|
|
30
|
+
const [rows, setRows] = React.useState([]);
|
|
31
|
+
const [page, setPage] = React.useState(1);
|
|
32
|
+
const [total, setTotal] = React.useState(0);
|
|
33
|
+
const [totalPages, setTotalPages] = React.useState(1);
|
|
34
|
+
const [isLoading, setLoading] = React.useState(false);
|
|
35
|
+
const [sendingId, setSendingId] = React.useState(null);
|
|
36
|
+
const { runMutation } = useGuardedMutation({
|
|
37
|
+
contextId: "integration_ksef_direct:send-document"
|
|
38
|
+
});
|
|
39
|
+
const fetchData = React.useCallback(async () => {
|
|
40
|
+
setLoading(true);
|
|
41
|
+
try {
|
|
42
|
+
const result = await apiCall(
|
|
43
|
+
`/api/integration-ksef-direct/documents?page=${page}&pageSize=${PAGE_SIZE}`
|
|
44
|
+
);
|
|
45
|
+
if (result.ok && result.result) {
|
|
46
|
+
setRows(result.result.items);
|
|
47
|
+
setTotal(result.result.total);
|
|
48
|
+
setTotalPages(Math.max(1, Math.ceil(result.result.total / PAGE_SIZE)));
|
|
49
|
+
} else {
|
|
50
|
+
setRows([]);
|
|
51
|
+
setTotal(0);
|
|
52
|
+
setTotalPages(1);
|
|
53
|
+
}
|
|
54
|
+
} catch {
|
|
55
|
+
setRows([]);
|
|
56
|
+
setTotal(0);
|
|
57
|
+
setTotalPages(1);
|
|
58
|
+
} finally {
|
|
59
|
+
setLoading(false);
|
|
60
|
+
}
|
|
61
|
+
}, [page]);
|
|
62
|
+
React.useEffect(() => {
|
|
63
|
+
void fetchData();
|
|
64
|
+
}, [fetchData, scopeVersion]);
|
|
65
|
+
useAppEvent("ksef_direct.document.*", () => {
|
|
66
|
+
void fetchData();
|
|
67
|
+
}, [fetchData]);
|
|
68
|
+
const handleSend = React.useCallback(async (documentId) => {
|
|
69
|
+
setSendingId(documentId);
|
|
70
|
+
try {
|
|
71
|
+
await runMutation({
|
|
72
|
+
operation: async () => {
|
|
73
|
+
const result = await apiCall(`/api/integration-ksef-direct/documents/${documentId}/send`, {
|
|
74
|
+
method: "POST"
|
|
75
|
+
});
|
|
76
|
+
if (!result.ok) {
|
|
77
|
+
const err = result.result?.error;
|
|
78
|
+
throw new Error(typeof err === "string" ? err : t("integration_ksef_direct.documents.errors.send_failed", "Send failed"));
|
|
79
|
+
}
|
|
80
|
+
return result.result;
|
|
81
|
+
},
|
|
82
|
+
context: { entityType: "integration_ksef_direct.document" },
|
|
83
|
+
mutationPayload: { entityType: "integration_ksef_direct.document" }
|
|
84
|
+
});
|
|
85
|
+
flash(t("integration_ksef_direct.documents.send_success", "Document queued for sending"), "success");
|
|
86
|
+
void fetchData();
|
|
87
|
+
} catch (err) {
|
|
88
|
+
flash(err instanceof Error ? err.message : t("integration_ksef_direct.documents.errors.send_failed", "Send failed"), "error");
|
|
89
|
+
} finally {
|
|
90
|
+
setSendingId(null);
|
|
91
|
+
}
|
|
92
|
+
}, [runMutation, t, fetchData]);
|
|
93
|
+
const columns = React.useMemo(() => [
|
|
94
|
+
{
|
|
95
|
+
id: "invoiceNumber",
|
|
96
|
+
accessorKey: "invoiceNumber",
|
|
97
|
+
header: t("integration_ksef_direct.documents.columns.invoiceNumber", "Invoice Number"),
|
|
98
|
+
cell: ({ row }) => /* @__PURE__ */ jsx("span", { className: "font-medium", children: row.original.invoiceNumber })
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
id: "buyer",
|
|
102
|
+
header: t("integration_ksef_direct.documents.columns.buyer", "Buyer"),
|
|
103
|
+
cell: ({ row }) => /* @__PURE__ */ jsx("span", { children: row.original.buyerName ? `${row.original.buyerName} (${row.original.buyerNip})` : row.original.buyerNip })
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
id: "issueDate",
|
|
107
|
+
accessorKey: "issueDate",
|
|
108
|
+
header: t("integration_ksef_direct.documents.columns.issueDate", "Issue Date"),
|
|
109
|
+
cell: ({ row }) => new Date(row.original.issueDate).toLocaleDateString()
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
id: "grossAmount",
|
|
113
|
+
accessorKey: "grossAmount",
|
|
114
|
+
header: t("integration_ksef_direct.documents.columns.grossAmount", "Gross Amount"),
|
|
115
|
+
cell: ({ row }) => /* @__PURE__ */ jsxs("span", { className: "tabular-nums", children: [
|
|
116
|
+
parseFloat(row.original.grossAmount).toLocaleString("pl-PL", { minimumFractionDigits: 2 }),
|
|
117
|
+
" ",
|
|
118
|
+
row.original.currency
|
|
119
|
+
] })
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
id: "status",
|
|
123
|
+
accessorKey: "status",
|
|
124
|
+
header: t("integration_ksef_direct.documents.columns.status", "Status"),
|
|
125
|
+
cell: ({ row }) => /* @__PURE__ */ jsx(StatusBadge, { variant: STATUS_VARIANT[row.original.status] ?? "neutral", children: t(`integration_ksef_direct.documents.status.${row.original.status}`, row.original.status) })
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
id: "ksefReferenceNumber",
|
|
129
|
+
header: t("integration_ksef_direct.documents.ksef_reference_number", "KSeF Number"),
|
|
130
|
+
cell: ({ row }) => row.original.ksefReferenceNumber ? /* @__PURE__ */ jsx("span", { className: "font-mono text-sm", children: row.original.ksefReferenceNumber }) : null
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
id: "actions",
|
|
134
|
+
header: "",
|
|
135
|
+
cell: ({ row }) => {
|
|
136
|
+
const { id, status } = row.original;
|
|
137
|
+
const isSending = sendingId === id;
|
|
138
|
+
if (status === "draft") {
|
|
139
|
+
return /* @__PURE__ */ jsxs(
|
|
140
|
+
Button,
|
|
141
|
+
{
|
|
142
|
+
size: "sm",
|
|
143
|
+
variant: "ghost",
|
|
144
|
+
disabled: isSending,
|
|
145
|
+
onClick: () => void handleSend(id),
|
|
146
|
+
"aria-label": t("integration_ksef_direct.documents.send_button", "Send to KSeF"),
|
|
147
|
+
children: [
|
|
148
|
+
/* @__PURE__ */ jsx(Send, { className: "h-4 w-4 mr-1" }),
|
|
149
|
+
t("integration_ksef_direct.documents.send_button", "Send to KSeF")
|
|
150
|
+
]
|
|
151
|
+
}
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
if (status === "failed") {
|
|
155
|
+
return /* @__PURE__ */ jsxs(
|
|
156
|
+
Button,
|
|
157
|
+
{
|
|
158
|
+
size: "sm",
|
|
159
|
+
variant: "ghost",
|
|
160
|
+
disabled: isSending,
|
|
161
|
+
onClick: () => void handleSend(id),
|
|
162
|
+
"aria-label": t("integration_ksef_direct.documents.retry_button", "Retry send"),
|
|
163
|
+
children: [
|
|
164
|
+
/* @__PURE__ */ jsx(RefreshCw, { className: "h-4 w-4 mr-1" }),
|
|
165
|
+
t("integration_ksef_direct.documents.retry_button", "Retry")
|
|
166
|
+
]
|
|
167
|
+
}
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
return null;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
], [t, sendingId, handleSend]);
|
|
174
|
+
return /* @__PURE__ */ jsx(Page, { children: /* @__PURE__ */ jsx(PageBody, { children: /* @__PURE__ */ jsx(
|
|
175
|
+
DataTable,
|
|
176
|
+
{
|
|
177
|
+
columns,
|
|
178
|
+
data: rows,
|
|
179
|
+
isLoading,
|
|
180
|
+
actions: /* @__PURE__ */ jsx(Button, { asChild: true, children: /* @__PURE__ */ jsxs(Link, { href: "/backend/integration-ksef-direct/documents/new", children: [
|
|
181
|
+
/* @__PURE__ */ jsx(Plus, { className: "h-4 w-4 mr-2" }),
|
|
182
|
+
t("integration_ksef_direct.documents.list.actions.new", "New Document")
|
|
183
|
+
] }) }),
|
|
184
|
+
emptyState: t("integration_ksef_direct.documents.empty.title", "No KSeF documents yet"),
|
|
185
|
+
pagination: { page, pageSize: PAGE_SIZE, total, totalPages, onPageChange: setPage }
|
|
186
|
+
}
|
|
187
|
+
) }) });
|
|
188
|
+
}
|
|
189
|
+
export {
|
|
190
|
+
KsefDirectDocumentsPage as default,
|
|
191
|
+
pageMetadata
|
|
192
|
+
};
|
|
193
|
+
//# sourceMappingURL=page.js.map
|
package/dist/modules/integration_ksef_direct/backend/integration-ksef-direct/documents/page.js.map
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../src/modules/integration_ksef_direct/backend/integration-ksef-direct/documents/page.tsx"],
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { Plus, Send, RefreshCw } from 'lucide-react'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { DataTable } from '@open-mercato/ui/backend/DataTable'\nimport type { ColumnDef } from '@tanstack/react-table'\nimport { StatusBadge } from '@open-mercato/ui/primitives/status-badge'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useAppEvent } from '@open-mercato/ui/backend/injection/useAppEvent'\n\nconst PAGE_SIZE = 50\n\nconst STATUS_VARIANT: Record<string, 'success' | 'error' | 'warning' | 'neutral'> = {\n draft: 'neutral',\n queued: 'warning',\n sending: 'warning',\n sent: 'success',\n failed: 'error',\n}\n\nexport const pageMetadata = {\n features: ['integration_ksef_direct.documents.view'],\n}\n\ntype DocumentRow = {\n id: string\n source: string\n status: string\n invoiceNumber: string\n buyerNip: string\n buyerName: string | null\n issueDate: string\n grossAmount: string\n currency: string\n ksefReferenceNumber: string | null\n createdAt: string\n}\n\ntype ApiResponse = {\n items: DocumentRow[]\n total: number\n page: number\n pageSize: number\n}\n\nexport default function KsefDirectDocumentsPage() {\n const t = useT()\n const scopeVersion = useOrganizationScopeVersion()\n const [rows, setRows] = React.useState<DocumentRow[]>([])\n const [page, setPage] = React.useState(1)\n const [total, setTotal] = React.useState(0)\n const [totalPages, setTotalPages] = React.useState(1)\n const [isLoading, setLoading] = React.useState(false)\n const [sendingId, setSendingId] = React.useState<string | null>(null)\n\n const { runMutation } = useGuardedMutation<{ entityType: string }>({\n contextId: 'integration_ksef_direct:send-document',\n })\n\n const fetchData = React.useCallback(async () => {\n setLoading(true)\n try {\n const result = await apiCall<ApiResponse>(\n `/api/integration-ksef-direct/documents?page=${page}&pageSize=${PAGE_SIZE}`,\n )\n if (result.ok && result.result) {\n setRows(result.result.items)\n setTotal(result.result.total)\n setTotalPages(Math.max(1, Math.ceil(result.result.total / PAGE_SIZE)))\n } else {\n setRows([])\n setTotal(0)\n setTotalPages(1)\n }\n } catch {\n setRows([])\n setTotal(0)\n setTotalPages(1)\n } finally {\n setLoading(false)\n }\n }, [page])\n\n React.useEffect(() => { void fetchData() }, [fetchData, scopeVersion])\n\n useAppEvent('ksef_direct.document.*', () => { void fetchData() }, [fetchData])\n\n const handleSend = React.useCallback(async (documentId: string) => {\n setSendingId(documentId)\n try {\n await runMutation({\n operation: async () => {\n const result = await apiCall(`/api/integration-ksef-direct/documents/${documentId}/send`, {\n method: 'POST',\n })\n if (!result.ok) {\n const err = (result.result as Record<string, unknown>)?.error\n throw new Error(typeof err === 'string' ? err : t('integration_ksef_direct.documents.errors.send_failed', 'Send failed'))\n }\n return result.result\n },\n context: { entityType: 'integration_ksef_direct.document' },\n mutationPayload: { entityType: 'integration_ksef_direct.document' },\n })\n flash(t('integration_ksef_direct.documents.send_success', 'Document queued for sending'), 'success')\n void fetchData()\n } catch (err) {\n flash(err instanceof Error ? err.message : t('integration_ksef_direct.documents.errors.send_failed', 'Send failed'), 'error')\n } finally {\n setSendingId(null)\n }\n }, [runMutation, t, fetchData])\n\n const columns = React.useMemo<ColumnDef<DocumentRow, unknown>[]>(() => [\n {\n id: 'invoiceNumber',\n accessorKey: 'invoiceNumber',\n header: t('integration_ksef_direct.documents.columns.invoiceNumber', 'Invoice Number'),\n cell: ({ row }) => <span className=\"font-medium\">{row.original.invoiceNumber}</span>,\n },\n {\n id: 'buyer',\n header: t('integration_ksef_direct.documents.columns.buyer', 'Buyer'),\n cell: ({ row }) => (\n <span>\n {row.original.buyerName\n ? `${row.original.buyerName} (${row.original.buyerNip})`\n : row.original.buyerNip}\n </span>\n ),\n },\n {\n id: 'issueDate',\n accessorKey: 'issueDate',\n header: t('integration_ksef_direct.documents.columns.issueDate', 'Issue Date'),\n cell: ({ row }) => new Date(row.original.issueDate).toLocaleDateString(),\n },\n {\n id: 'grossAmount',\n accessorKey: 'grossAmount',\n header: t('integration_ksef_direct.documents.columns.grossAmount', 'Gross Amount'),\n cell: ({ row }) => (\n <span className=\"tabular-nums\">\n {parseFloat(row.original.grossAmount).toLocaleString('pl-PL', { minimumFractionDigits: 2 })}{' '}\n {row.original.currency}\n </span>\n ),\n },\n {\n id: 'status',\n accessorKey: 'status',\n header: t('integration_ksef_direct.documents.columns.status', 'Status'),\n cell: ({ row }) => (\n <StatusBadge variant={STATUS_VARIANT[row.original.status] ?? 'neutral'}>\n {t(`integration_ksef_direct.documents.status.${row.original.status}`, row.original.status)}\n </StatusBadge>\n ),\n },\n {\n id: 'ksefReferenceNumber',\n header: t('integration_ksef_direct.documents.ksef_reference_number', 'KSeF Number'),\n cell: ({ row }) => row.original.ksefReferenceNumber\n ? <span className=\"font-mono text-sm\">{row.original.ksefReferenceNumber}</span>\n : null,\n },\n {\n id: 'actions',\n header: '',\n cell: ({ row }) => {\n const { id, status } = row.original\n const isSending = sendingId === id\n if (status === 'draft') {\n return (\n <Button\n size=\"sm\"\n variant=\"ghost\"\n disabled={isSending}\n onClick={() => void handleSend(id)}\n aria-label={t('integration_ksef_direct.documents.send_button', 'Send to KSeF')}\n >\n <Send className=\"h-4 w-4 mr-1\" />\n {t('integration_ksef_direct.documents.send_button', 'Send to KSeF')}\n </Button>\n )\n }\n if (status === 'failed') {\n return (\n <Button\n size=\"sm\"\n variant=\"ghost\"\n disabled={isSending}\n onClick={() => void handleSend(id)}\n aria-label={t('integration_ksef_direct.documents.retry_button', 'Retry send')}\n >\n <RefreshCw className=\"h-4 w-4 mr-1\" />\n {t('integration_ksef_direct.documents.retry_button', 'Retry')}\n </Button>\n )\n }\n return null\n },\n },\n ], [t, sendingId, handleSend])\n\n return (\n <Page>\n <PageBody>\n <DataTable<DocumentRow>\n columns={columns}\n data={rows}\n isLoading={isLoading}\n actions={(\n <Button asChild>\n <Link href=\"/backend/integration-ksef-direct/documents/new\">\n <Plus className=\"h-4 w-4 mr-2\" />\n {t('integration_ksef_direct.documents.list.actions.new', 'New Document')}\n </Link>\n </Button>\n )}\n emptyState={t('integration_ksef_direct.documents.empty.title', 'No KSeF documents yet')}\n pagination={{ page, pageSize: PAGE_SIZE, total, totalPages, onPageChange: setPage }}\n />\n </PageBody>\n </Page>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { Copy, Search } from "lucide-react";
|
|
5
|
+
import { Page, PageBody } from "@open-mercato/ui/backend/Page";
|
|
6
|
+
import { DataTable } from "@open-mercato/ui/backend/DataTable";
|
|
7
|
+
import { StatusBadge } from "@open-mercato/ui/primitives/status-badge";
|
|
8
|
+
import { Button } from "@open-mercato/ui/primitives/button";
|
|
9
|
+
import { Input } from "@open-mercato/ui/primitives/input";
|
|
10
|
+
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "@open-mercato/ui/primitives/dialog";
|
|
11
|
+
import { FormField } from "@open-mercato/ui/primitives/form-field";
|
|
12
|
+
import { Alert, AlertDescription } from "@open-mercato/ui/primitives/alert";
|
|
13
|
+
import { flash } from "@open-mercato/ui/backend/FlashMessages";
|
|
14
|
+
import { apiCall } from "@open-mercato/ui/backend/utils/apiCall";
|
|
15
|
+
import { useGuardedMutation } from "@open-mercato/ui/backend/injection/useGuardedMutation";
|
|
16
|
+
import { useOrganizationScopeVersion } from "@open-mercato/shared/lib/frontend/useOrganizationScope";
|
|
17
|
+
import { useT } from "@open-mercato/shared/lib/i18n/context";
|
|
18
|
+
const pageMetadata = {
|
|
19
|
+
requireAuth: true,
|
|
20
|
+
requireFeatures: ["integration_ksef_direct.received_documents.view"],
|
|
21
|
+
pageTitleKey: "integration_ksef_direct.received_documents.title"
|
|
22
|
+
};
|
|
23
|
+
const PAGE_SIZE = 50;
|
|
24
|
+
const STATUS_VARIANT = {
|
|
25
|
+
pending_download: "warning",
|
|
26
|
+
downloaded: "success",
|
|
27
|
+
failed: "error"
|
|
28
|
+
};
|
|
29
|
+
function DetailModal({
|
|
30
|
+
documentId,
|
|
31
|
+
onClose
|
|
32
|
+
}) {
|
|
33
|
+
const t = useT();
|
|
34
|
+
const [doc, setDoc] = React.useState(null);
|
|
35
|
+
const [loading, setLoading] = React.useState(true);
|
|
36
|
+
const [copied, setCopied] = React.useState(false);
|
|
37
|
+
React.useEffect(() => {
|
|
38
|
+
let cancelled = false;
|
|
39
|
+
setLoading(true);
|
|
40
|
+
apiCall(`/api/integration-ksef-direct/received-documents/${documentId}`).then((res) => {
|
|
41
|
+
if (!cancelled && res.ok && res.result) setDoc(res.result);
|
|
42
|
+
}).catch(() => {
|
|
43
|
+
}).finally(() => {
|
|
44
|
+
if (!cancelled) setLoading(false);
|
|
45
|
+
});
|
|
46
|
+
return () => {
|
|
47
|
+
cancelled = true;
|
|
48
|
+
};
|
|
49
|
+
}, [documentId]);
|
|
50
|
+
React.useEffect(() => {
|
|
51
|
+
const handler = (e) => {
|
|
52
|
+
if (e.key === "Escape") onClose();
|
|
53
|
+
};
|
|
54
|
+
window.addEventListener("keydown", handler);
|
|
55
|
+
return () => window.removeEventListener("keydown", handler);
|
|
56
|
+
}, [onClose]);
|
|
57
|
+
async function handleCopy() {
|
|
58
|
+
if (!doc?.rawXml) return;
|
|
59
|
+
try {
|
|
60
|
+
await navigator.clipboard.writeText(doc.rawXml);
|
|
61
|
+
setCopied(true);
|
|
62
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
63
|
+
} catch {
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return /* @__PURE__ */ jsx(Dialog, { open: true, onOpenChange: (open) => {
|
|
67
|
+
if (!open) onClose();
|
|
68
|
+
}, children: /* @__PURE__ */ jsxs(DialogContent, { className: "max-w-3xl max-h-[90vh] flex flex-col", children: [
|
|
69
|
+
/* @__PURE__ */ jsx(DialogHeader, { children: /* @__PURE__ */ jsx(DialogTitle, { children: doc?.invoiceNumber ?? doc?.ksefReferenceNumber ?? t("integration_ksef_direct.received_documents.title", "Received Document") }) }),
|
|
70
|
+
loading && /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground py-4", children: t("integration_ksef_direct.received_documents.loading", "Loading...") }),
|
|
71
|
+
doc && !loading && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4 overflow-y-auto", children: [
|
|
72
|
+
/* @__PURE__ */ jsxs("dl", { className: "grid grid-cols-2 gap-x-6 gap-y-2 text-sm", children: [
|
|
73
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
74
|
+
/* @__PURE__ */ jsx("dt", { className: "text-muted-foreground", children: t("integration_ksef_direct.received_documents.column.ksef_reference", "KSeF Ref.") }),
|
|
75
|
+
/* @__PURE__ */ jsx("dd", { className: "font-mono break-all", children: doc.ksefReferenceNumber })
|
|
76
|
+
] }),
|
|
77
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
78
|
+
/* @__PURE__ */ jsx("dt", { className: "text-muted-foreground", children: t("integration_ksef_direct.received_documents.column.invoice_number", "Invoice No.") }),
|
|
79
|
+
/* @__PURE__ */ jsx("dd", { children: doc.invoiceNumber ?? "\u2014" })
|
|
80
|
+
] }),
|
|
81
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
82
|
+
/* @__PURE__ */ jsx("dt", { className: "text-muted-foreground", children: t("integration_ksef_direct.received_documents.column.seller_nip", "Seller NIP") }),
|
|
83
|
+
/* @__PURE__ */ jsx("dd", { children: doc.sellerNip ?? "\u2014" })
|
|
84
|
+
] }),
|
|
85
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
86
|
+
/* @__PURE__ */ jsx("dt", { className: "text-muted-foreground", children: t("integration_ksef_direct.received_documents.column.seller_name", "Seller") }),
|
|
87
|
+
/* @__PURE__ */ jsx("dd", { children: doc.sellerName ?? "\u2014" })
|
|
88
|
+
] }),
|
|
89
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
90
|
+
/* @__PURE__ */ jsx("dt", { className: "text-muted-foreground", children: t("integration_ksef_direct.received_documents.column.issue_date", "Issue Date") }),
|
|
91
|
+
/* @__PURE__ */ jsx("dd", { children: doc.issueDate ?? "\u2014" })
|
|
92
|
+
] }),
|
|
93
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
94
|
+
/* @__PURE__ */ jsx("dt", { className: "text-muted-foreground", children: t("integration_ksef_direct.received_documents.column.gross_amount", "Gross Amount") }),
|
|
95
|
+
/* @__PURE__ */ jsx("dd", { children: doc.grossAmount != null ? `${parseFloat(doc.grossAmount).toLocaleString("pl-PL", { minimumFractionDigits: 2 })} ${doc.currency ?? "PLN"}` : "\u2014" })
|
|
96
|
+
] }),
|
|
97
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
98
|
+
/* @__PURE__ */ jsx("dt", { className: "text-muted-foreground", children: t("integration_ksef_direct.received_documents.column.status", "Status") }),
|
|
99
|
+
/* @__PURE__ */ jsx("dd", { children: /* @__PURE__ */ jsx(StatusBadge, { variant: STATUS_VARIANT[doc.status] ?? "warning", children: t(`integration_ksef_direct.received_documents.status.${doc.status}`, doc.status) }) })
|
|
100
|
+
] }),
|
|
101
|
+
doc.errorMessage && /* @__PURE__ */ jsxs("div", { className: "col-span-2", children: [
|
|
102
|
+
/* @__PURE__ */ jsx("dt", { className: "text-muted-foreground", children: "Error" }),
|
|
103
|
+
/* @__PURE__ */ jsx("dd", { className: "text-status-destructive-text", children: doc.errorMessage })
|
|
104
|
+
] })
|
|
105
|
+
] }),
|
|
106
|
+
doc.rawXml && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
107
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
108
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: "XML" }),
|
|
109
|
+
/* @__PURE__ */ jsxs(Button, { size: "sm", variant: "ghost", onClick: handleCopy, "aria-label": "Copy XML", children: [
|
|
110
|
+
/* @__PURE__ */ jsx(Copy, { className: "size-4 mr-1" }),
|
|
111
|
+
copied ? t("integration_ksef_direct.received_documents.xml_copied", "Copied") : t("integration_ksef_direct.received_documents.copy_xml", "Copy XML")
|
|
112
|
+
] })
|
|
113
|
+
] }),
|
|
114
|
+
/* @__PURE__ */ jsx("pre", { className: "text-xs font-mono bg-muted rounded p-3 overflow-auto max-h-64 whitespace-pre-wrap break-all", children: doc.rawXml })
|
|
115
|
+
] })
|
|
116
|
+
] })
|
|
117
|
+
] }) });
|
|
118
|
+
}
|
|
119
|
+
function FetchDialog({ onClose, onSuccess }) {
|
|
120
|
+
const t = useT();
|
|
121
|
+
const [reference, setReference] = React.useState("");
|
|
122
|
+
const [error, setError] = React.useState(null);
|
|
123
|
+
const [isSubmitting, setSubmitting] = React.useState(false);
|
|
124
|
+
const { runMutation } = useGuardedMutation({
|
|
125
|
+
contextId: "integration_ksef_direct:fetch-received-document"
|
|
126
|
+
});
|
|
127
|
+
React.useEffect(() => {
|
|
128
|
+
const handler = (e) => {
|
|
129
|
+
if (e.key === "Escape") onClose();
|
|
130
|
+
if ((e.metaKey || e.ctrlKey) && e.key === "Enter") void handleSubmit();
|
|
131
|
+
};
|
|
132
|
+
window.addEventListener("keydown", handler);
|
|
133
|
+
return () => window.removeEventListener("keydown", handler);
|
|
134
|
+
});
|
|
135
|
+
async function handleSubmit() {
|
|
136
|
+
setError(null);
|
|
137
|
+
setSubmitting(true);
|
|
138
|
+
try {
|
|
139
|
+
await runMutation({
|
|
140
|
+
operation: async () => {
|
|
141
|
+
const result = await apiCall("/api/integration-ksef-direct/received-documents/fetch", {
|
|
142
|
+
method: "POST",
|
|
143
|
+
body: JSON.stringify({ ksefReferenceNumber: reference })
|
|
144
|
+
});
|
|
145
|
+
if (!result.ok) {
|
|
146
|
+
const body = result.result;
|
|
147
|
+
throw new Error(typeof body?.error === "string" ? body.error : "Error");
|
|
148
|
+
}
|
|
149
|
+
return result.result;
|
|
150
|
+
},
|
|
151
|
+
context: { entityType: "integration_ksef_direct.received_document" },
|
|
152
|
+
mutationPayload: { entityType: "integration_ksef_direct.received_document" }
|
|
153
|
+
});
|
|
154
|
+
flash(t("integration_ksef_direct.received_documents.fetch_success", "Document fetched successfully."), "success");
|
|
155
|
+
onClose();
|
|
156
|
+
onSuccess();
|
|
157
|
+
} catch (err) {
|
|
158
|
+
setError(err instanceof Error ? err.message : "Error");
|
|
159
|
+
} finally {
|
|
160
|
+
setSubmitting(false);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return /* @__PURE__ */ jsx(Dialog, { open: true, onOpenChange: (open) => {
|
|
164
|
+
if (!open) onClose();
|
|
165
|
+
}, children: /* @__PURE__ */ jsxs(DialogContent, { className: "max-w-md", children: [
|
|
166
|
+
/* @__PURE__ */ jsx(DialogHeader, { children: /* @__PURE__ */ jsx(DialogTitle, { children: t("integration_ksef_direct.received_documents.dialog_fetch.title", "Fetch Document by KSeF Reference") }) }),
|
|
167
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4", children: [
|
|
168
|
+
error && /* @__PURE__ */ jsx(Alert, { variant: "destructive", children: /* @__PURE__ */ jsx(AlertDescription, { children: error }) }),
|
|
169
|
+
/* @__PURE__ */ jsx(FormField, { label: t("integration_ksef_direct.received_documents.column.ksef_reference", "KSeF Reference Number"), required: true, children: /* @__PURE__ */ jsx(
|
|
170
|
+
Input,
|
|
171
|
+
{
|
|
172
|
+
value: reference,
|
|
173
|
+
onChange: (e) => setReference(e.target.value),
|
|
174
|
+
placeholder: "e.g. 1234567890...",
|
|
175
|
+
className: "font-mono"
|
|
176
|
+
}
|
|
177
|
+
) })
|
|
178
|
+
] }),
|
|
179
|
+
/* @__PURE__ */ jsxs(DialogFooter, { children: [
|
|
180
|
+
/* @__PURE__ */ jsx(Button, { variant: "outline", onClick: onClose, type: "button", children: t("integration_ksef_direct.received_documents.cancel", "Cancel") }),
|
|
181
|
+
/* @__PURE__ */ jsx(Button, { onClick: handleSubmit, disabled: isSubmitting || !reference.trim(), type: "button", children: t("integration_ksef_direct.received_documents.dialog_fetch.submit", "Fetch") })
|
|
182
|
+
] })
|
|
183
|
+
] }) });
|
|
184
|
+
}
|
|
185
|
+
function ReceivedDocumentsPage() {
|
|
186
|
+
const t = useT();
|
|
187
|
+
const scopeVersion = useOrganizationScopeVersion();
|
|
188
|
+
const [rows, setRows] = React.useState([]);
|
|
189
|
+
const [page, setPage] = React.useState(1);
|
|
190
|
+
const [total, setTotal] = React.useState(0);
|
|
191
|
+
const [totalPages, setTotalPages] = React.useState(1);
|
|
192
|
+
const [isLoading, setLoading] = React.useState(false);
|
|
193
|
+
const [fetchDialogOpen, setFetchDialogOpen] = React.useState(false);
|
|
194
|
+
const [detailId, setDetailId] = React.useState(null);
|
|
195
|
+
const fetchData = React.useCallback(async () => {
|
|
196
|
+
setLoading(true);
|
|
197
|
+
try {
|
|
198
|
+
const result = await apiCall(
|
|
199
|
+
`/api/integration-ksef-direct/received-documents?page=${page}&pageSize=${PAGE_SIZE}`
|
|
200
|
+
);
|
|
201
|
+
if (result.ok && result.result) {
|
|
202
|
+
setRows(result.result.items);
|
|
203
|
+
setTotal(result.result.total);
|
|
204
|
+
setTotalPages(Math.max(1, Math.ceil(result.result.total / PAGE_SIZE)));
|
|
205
|
+
} else {
|
|
206
|
+
setRows([]);
|
|
207
|
+
setTotal(0);
|
|
208
|
+
setTotalPages(1);
|
|
209
|
+
}
|
|
210
|
+
} catch {
|
|
211
|
+
setRows([]);
|
|
212
|
+
setTotal(0);
|
|
213
|
+
setTotalPages(1);
|
|
214
|
+
} finally {
|
|
215
|
+
setLoading(false);
|
|
216
|
+
}
|
|
217
|
+
}, [page]);
|
|
218
|
+
React.useEffect(() => {
|
|
219
|
+
void fetchData();
|
|
220
|
+
}, [fetchData, scopeVersion]);
|
|
221
|
+
const columns = React.useMemo(() => [
|
|
222
|
+
{
|
|
223
|
+
id: "sellerNip",
|
|
224
|
+
accessorKey: "sellerNip",
|
|
225
|
+
header: t("integration_ksef_direct.received_documents.column.seller_nip", "Seller NIP"),
|
|
226
|
+
cell: ({ row }) => row.original.sellerNip ?? "\u2014"
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
id: "sellerName",
|
|
230
|
+
accessorKey: "sellerName",
|
|
231
|
+
header: t("integration_ksef_direct.received_documents.column.seller_name", "Seller"),
|
|
232
|
+
cell: ({ row }) => row.original.sellerName ?? "\u2014"
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
id: "invoiceNumber",
|
|
236
|
+
accessorKey: "invoiceNumber",
|
|
237
|
+
header: t("integration_ksef_direct.received_documents.column.invoice_number", "Invoice No."),
|
|
238
|
+
cell: ({ row }) => row.original.invoiceNumber ?? "\u2014"
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
id: "issueDate",
|
|
242
|
+
accessorKey: "issueDate",
|
|
243
|
+
header: t("integration_ksef_direct.received_documents.column.issue_date", "Issue Date"),
|
|
244
|
+
cell: ({ row }) => row.original.issueDate ?? "\u2014"
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
id: "grossAmount",
|
|
248
|
+
header: t("integration_ksef_direct.received_documents.column.gross_amount", "Gross Amount"),
|
|
249
|
+
cell: ({ row }) => row.original.grossAmount != null ? /* @__PURE__ */ jsxs("span", { className: "tabular-nums", children: [
|
|
250
|
+
parseFloat(row.original.grossAmount).toLocaleString("pl-PL", { minimumFractionDigits: 2 }),
|
|
251
|
+
" ",
|
|
252
|
+
row.original.currency ?? "PLN"
|
|
253
|
+
] }) : "\u2014"
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
id: "status",
|
|
257
|
+
accessorKey: "status",
|
|
258
|
+
header: t("integration_ksef_direct.received_documents.column.status", "Status"),
|
|
259
|
+
cell: ({ row }) => /* @__PURE__ */ jsx(StatusBadge, { variant: STATUS_VARIANT[row.original.status] ?? "warning", children: t(`integration_ksef_direct.received_documents.status.${row.original.status}`, row.original.status) })
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
id: "ksefReferenceNumber",
|
|
263
|
+
accessorKey: "ksefReferenceNumber",
|
|
264
|
+
header: t("integration_ksef_direct.received_documents.column.ksef_reference", "KSeF Ref."),
|
|
265
|
+
cell: ({ row }) => /* @__PURE__ */ jsx("span", { className: "font-mono text-sm truncate max-w-48 block", title: row.original.ksefReferenceNumber, children: row.original.ksefReferenceNumber })
|
|
266
|
+
}
|
|
267
|
+
], [t]);
|
|
268
|
+
const toolbar = /* @__PURE__ */ jsxs(
|
|
269
|
+
Button,
|
|
270
|
+
{
|
|
271
|
+
variant: "outline",
|
|
272
|
+
size: "sm",
|
|
273
|
+
onClick: () => setFetchDialogOpen(true),
|
|
274
|
+
children: [
|
|
275
|
+
/* @__PURE__ */ jsx(Search, { className: "size-4 mr-2" }),
|
|
276
|
+
t("integration_ksef_direct.received_documents.fetch_button", "Fetch by reference")
|
|
277
|
+
]
|
|
278
|
+
}
|
|
279
|
+
);
|
|
280
|
+
return /* @__PURE__ */ jsxs(Page, { children: [
|
|
281
|
+
/* @__PURE__ */ jsx(PageBody, { children: /* @__PURE__ */ jsx(
|
|
282
|
+
DataTable,
|
|
283
|
+
{
|
|
284
|
+
entityId: "ksef_direct_received_document",
|
|
285
|
+
columns,
|
|
286
|
+
data: rows,
|
|
287
|
+
isLoading,
|
|
288
|
+
actions: toolbar,
|
|
289
|
+
emptyState: t("integration_ksef_direct.received_documents.empty", "No received documents found."),
|
|
290
|
+
pagination: { page, pageSize: PAGE_SIZE, total, totalPages, onPageChange: setPage },
|
|
291
|
+
onRowClick: (row) => setDetailId(row.id)
|
|
292
|
+
}
|
|
293
|
+
) }),
|
|
294
|
+
fetchDialogOpen && /* @__PURE__ */ jsx(
|
|
295
|
+
FetchDialog,
|
|
296
|
+
{
|
|
297
|
+
onClose: () => setFetchDialogOpen(false),
|
|
298
|
+
onSuccess: () => void fetchData()
|
|
299
|
+
}
|
|
300
|
+
),
|
|
301
|
+
detailId && /* @__PURE__ */ jsx(
|
|
302
|
+
DetailModal,
|
|
303
|
+
{
|
|
304
|
+
documentId: detailId,
|
|
305
|
+
onClose: () => setDetailId(null)
|
|
306
|
+
}
|
|
307
|
+
)
|
|
308
|
+
] });
|
|
309
|
+
}
|
|
310
|
+
export {
|
|
311
|
+
ReceivedDocumentsPage as default,
|
|
312
|
+
pageMetadata
|
|
313
|
+
};
|
|
314
|
+
//# sourceMappingURL=page.js.map
|