Frontend: - API mutations for accounts, bank connections, customers, invoices - Document processing API - Shared components (PageHeader, EmptyState, etc.) - Pages: Admin, Fakturaer, Kunder, Ordrer, Produkter, etc. - Hooks and stores Config: - CLAUDE.md project instructions - Beads issue tracking config - Git attributes Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
209 lines
6.4 KiB
TypeScript
209 lines
6.4 KiB
TypeScript
import { useState } from 'react';
|
|
import {
|
|
Typography,
|
|
Card,
|
|
Row,
|
|
Col,
|
|
Form,
|
|
Select,
|
|
Button,
|
|
Tag,
|
|
Alert,
|
|
Spin,
|
|
} from 'antd';
|
|
import { showSuccess, showError } from '@/lib/errorHandling';
|
|
import { DownloadOutlined, FileTextOutlined } from '@ant-design/icons';
|
|
import { useCompany } from '@/hooks/useCompany';
|
|
import { useFiscalYears } from '@/api/queries/fiscalYearQueries';
|
|
import { useExportSaft, downloadSaftFile } from '@/api/mutations/saftMutations';
|
|
import { formatDate } from '@/lib/formatters';
|
|
import { spacing } from '@/styles/designTokens';
|
|
|
|
const { Title, Text, Paragraph } = Typography;
|
|
|
|
export default function Eksport() {
|
|
const { company } = useCompany();
|
|
const { data: fiscalYears, isLoading: fiscalYearsLoading } = useFiscalYears(company?.id);
|
|
const exportSaft = useExportSaft();
|
|
const [selectedFiscalYear, setSelectedFiscalYear] = useState<string>();
|
|
|
|
const handleExportSaft = async () => {
|
|
if (!company?.id || !selectedFiscalYear) {
|
|
showError('Vælg venligst et regnskabsår');
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const result = await exportSaft.mutateAsync({
|
|
companyId: company.id,
|
|
fiscalYearId: selectedFiscalYear,
|
|
});
|
|
|
|
if (result.success) {
|
|
downloadSaftFile(result);
|
|
showSuccess(`SAF-T fil downloadet: ${result.fileName}`);
|
|
} else {
|
|
showError(result.errorMessage || 'Kunne ikke generere SAF-T fil');
|
|
}
|
|
} catch (error) {
|
|
showError('Der opstod en fejl under eksport');
|
|
console.error('SAF-T export error:', error);
|
|
}
|
|
};
|
|
|
|
if (fiscalYearsLoading) {
|
|
return (
|
|
<div style={{ textAlign: 'center', padding: spacing.xl }}>
|
|
<Spin size="large" />
|
|
</div>
|
|
);
|
|
}
|
|
|
|
const selectedYear = fiscalYears?.find(fy => fy.id === selectedFiscalYear);
|
|
|
|
return (
|
|
<div>
|
|
<Title level={4}>Eksporter data</Title>
|
|
<Paragraph type="secondary">
|
|
Eksporter regnskabsdata til forskellige formater for compliance og rapportering.
|
|
</Paragraph>
|
|
|
|
<Row gutter={[spacing.lg, spacing.lg]}>
|
|
{/* SAF-T Export Card */}
|
|
<Col xs={24} md={12}>
|
|
<Card
|
|
title={
|
|
<span>
|
|
<FileTextOutlined style={{ marginRight: 8 }} />
|
|
SAF-T (Standard Audit File for Tax)
|
|
</span>
|
|
}
|
|
>
|
|
<Paragraph type="secondary">
|
|
Eksporter regnskabsdata i SAF-T format til SKAT.
|
|
Dette er det danske standardformat for digital indberetning af regnskabsdata.
|
|
</Paragraph>
|
|
|
|
<Alert
|
|
message="Lovkrav fra 1. januar 2027"
|
|
description="SAF-T eksport bliver obligatorisk for alle virksomheder med omsætning over 300.000 DKK."
|
|
type="info"
|
|
showIcon
|
|
style={{ marginBottom: spacing.md }}
|
|
/>
|
|
|
|
<Form layout="vertical">
|
|
<Form.Item
|
|
label="Regnskabsår"
|
|
required
|
|
help={selectedYear ? `${formatDate(selectedYear.startDate)} - ${formatDate(selectedYear.endDate)}` : undefined}
|
|
>
|
|
<Select
|
|
placeholder="Vælg regnskabsår"
|
|
value={selectedFiscalYear}
|
|
onChange={setSelectedFiscalYear}
|
|
loading={fiscalYearsLoading}
|
|
options={fiscalYears?.map(fy => ({
|
|
value: fy.id,
|
|
label: (
|
|
<span>
|
|
{fy.name}
|
|
{fy.status === 'locked' && (
|
|
<Tag color="red" style={{ marginLeft: 8 }}>Låst</Tag>
|
|
)}
|
|
{fy.status === 'closed' && (
|
|
<Tag color="orange" style={{ marginLeft: 8 }}>Afsluttet</Tag>
|
|
)}
|
|
</span>
|
|
),
|
|
}))}
|
|
style={{ width: '100%' }}
|
|
/>
|
|
</Form.Item>
|
|
|
|
<Button
|
|
type="primary"
|
|
icon={<DownloadOutlined />}
|
|
onClick={handleExportSaft}
|
|
loading={exportSaft.isPending}
|
|
disabled={!selectedFiscalYear}
|
|
block
|
|
>
|
|
Download SAF-T XML
|
|
</Button>
|
|
</Form>
|
|
|
|
<div style={{ marginTop: spacing.md }}>
|
|
<Text type="secondary" style={{ fontSize: 12 }}>
|
|
Filen inkluderer: Kontoplan, kunder, leverandører og alle posteringer for perioden.
|
|
</Text>
|
|
</div>
|
|
</Card>
|
|
</Col>
|
|
|
|
{/* CSV Export Card (Coming Soon) */}
|
|
<Col xs={24} md={12}>
|
|
<Card
|
|
title={
|
|
<span>
|
|
<FileTextOutlined style={{ marginRight: 8 }} />
|
|
CSV Eksport
|
|
</span>
|
|
}
|
|
extra={<Tag>Kommer snart</Tag>}
|
|
>
|
|
<Paragraph type="secondary">
|
|
Eksporter kontoplan, posteringer eller kunder som CSV-filer til brug i regneark.
|
|
</Paragraph>
|
|
|
|
<Button disabled block>
|
|
Ikke tilgængelig endnu
|
|
</Button>
|
|
</Card>
|
|
</Col>
|
|
|
|
{/* PDF Report Card (Coming Soon) */}
|
|
<Col xs={24} md={12}>
|
|
<Card
|
|
title={
|
|
<span>
|
|
<FileTextOutlined style={{ marginRight: 8 }} />
|
|
Årsrapport (PDF)
|
|
</span>
|
|
}
|
|
extra={<Tag>Kommer snart</Tag>}
|
|
>
|
|
<Paragraph type="secondary">
|
|
Generér årsrapport i PDF format med resultatopgørelse og balance.
|
|
</Paragraph>
|
|
|
|
<Button disabled block>
|
|
Ikke tilgængelig endnu
|
|
</Button>
|
|
</Card>
|
|
</Col>
|
|
|
|
{/* Backup Card (Coming Soon) */}
|
|
<Col xs={24} md={12}>
|
|
<Card
|
|
title={
|
|
<span>
|
|
<FileTextOutlined style={{ marginRight: 8 }} />
|
|
Fuld backup
|
|
</span>
|
|
}
|
|
extra={<Tag>Kommer snart</Tag>}
|
|
>
|
|
<Paragraph type="secondary">
|
|
Download en komplet backup af alle virksomhedens data i JSON format.
|
|
</Paragraph>
|
|
|
|
<Button disabled block>
|
|
Ikke tilgængelig endnu
|
|
</Button>
|
|
</Card>
|
|
</Col>
|
|
</Row>
|
|
</div>
|
|
);
|
|
}
|