feat: register export sector with 4 extension definitions
Add export & utrikeshandel sector to the extension system with BAS accounts (3105, 3108, 3109, 3521, 3522), sector metadata, icon imports, workspace registry entries, and design document. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1015,6 +1015,38 @@ export const BAS_REFERENCE: BASReferenceAccount[] = [
|
||||
sru_code: '7311',
|
||||
},
|
||||
|
||||
// 31 - Forsaljning varor utanfor Sverige
|
||||
{
|
||||
account_number: '3105',
|
||||
account_name: 'Forsaljning varor export utanfor EU',
|
||||
account_class: 3,
|
||||
account_group: '31',
|
||||
account_type: 'revenue',
|
||||
normal_balance: 'credit',
|
||||
description: 'Intakter fran forsaljning av varor till kunder utanfor EU. Momsfritt (momsdeklaration ruta 36).',
|
||||
sru_code: '7310',
|
||||
},
|
||||
{
|
||||
account_number: '3108',
|
||||
account_name: 'Forsaljning varor till annat EU-land',
|
||||
account_class: 3,
|
||||
account_group: '31',
|
||||
account_type: 'revenue',
|
||||
normal_balance: 'credit',
|
||||
description: 'Intakter fran forsaljning av varor till momsregistrerade foretag i andra EU-lander. Omvand skattskyldighet (momsdeklaration ruta 35).',
|
||||
sru_code: '7310',
|
||||
},
|
||||
{
|
||||
account_number: '3109',
|
||||
account_name: 'Forsaljning vid trepartshandel',
|
||||
account_class: 3,
|
||||
account_group: '31',
|
||||
account_type: 'revenue',
|
||||
normal_balance: 'credit',
|
||||
description: 'Mellanmans forsaljning av varor vid trepartshandel inom EU (momsdeklaration ruta 38).',
|
||||
sru_code: '7310',
|
||||
},
|
||||
|
||||
// 33 - Forsaljning tjanster utanfor Sverige
|
||||
{
|
||||
account_number: '3305',
|
||||
@@ -1037,6 +1069,28 @@ export const BAS_REFERENCE: BASReferenceAccount[] = [
|
||||
sru_code: '7310',
|
||||
},
|
||||
|
||||
// 35 - Fakturerade kostnader och frakter
|
||||
{
|
||||
account_number: '3521',
|
||||
account_name: 'Fakturerade frakter, EU-land',
|
||||
account_class: 3,
|
||||
account_group: '35',
|
||||
account_type: 'revenue',
|
||||
normal_balance: 'credit',
|
||||
description: 'Fraktkostnader som vidarefaktureras till kunder i andra EU-lander. Foljer varans momsbehandling.',
|
||||
sru_code: '7310',
|
||||
},
|
||||
{
|
||||
account_number: '3522',
|
||||
account_name: 'Fakturerade frakter, export',
|
||||
account_class: 3,
|
||||
account_group: '35',
|
||||
account_type: 'revenue',
|
||||
normal_balance: 'credit',
|
||||
description: 'Fraktkostnader som vidarefaktureras till kunder utanfor EU. Momsfritt (momsdeklaration ruta 36).',
|
||||
sru_code: '7310',
|
||||
},
|
||||
|
||||
// 35 - Fakturerade kostnader
|
||||
{
|
||||
account_number: '3510',
|
||||
|
||||
@@ -7,12 +7,12 @@ import {
|
||||
} from '../sectors'
|
||||
|
||||
describe('sectors registry', () => {
|
||||
it('should have 6 sectors', () => {
|
||||
expect(SECTORS.length).toBe(6)
|
||||
it('should have 7 sectors', () => {
|
||||
expect(SECTORS.length).toBe(7)
|
||||
})
|
||||
|
||||
it('should have 18 total extensions', () => {
|
||||
expect(getAllExtensions().length).toBe(18)
|
||||
it('should have 22 total extensions', () => {
|
||||
expect(getAllExtensions().length).toBe(22)
|
||||
})
|
||||
|
||||
it('should have unique slugs within each sector', () => {
|
||||
|
||||
@@ -23,6 +23,9 @@ import {
|
||||
BarChart3,
|
||||
Layers,
|
||||
Puzzle,
|
||||
Ship,
|
||||
FileText,
|
||||
Shield,
|
||||
type LucideIcon,
|
||||
} from 'lucide-react'
|
||||
|
||||
@@ -51,6 +54,9 @@ const ICON_MAP: Record<string, LucideIcon> = {
|
||||
BarChart3,
|
||||
Layers,
|
||||
Puzzle,
|
||||
Ship,
|
||||
FileText,
|
||||
Shield,
|
||||
}
|
||||
|
||||
export function resolveIcon(name: string): LucideIcon {
|
||||
|
||||
@@ -6,6 +6,10 @@ import { sruExportExtension } from '@/extensions/sru-export'
|
||||
import { neBilagaExtension } from '@/extensions/ne-bilaga'
|
||||
import { aiChatExtension } from '@/extensions/general/ai-chat'
|
||||
import { invoiceInboxExtension } from '@/extensions/general/invoice-inbox'
|
||||
import { euSalesListExtension } from '@/extensions/export/eu-sales-list'
|
||||
import { vatMonitorExtension } from '@/extensions/export/vat-monitor'
|
||||
import { intrastatExtension } from '@/extensions/export/intrastat'
|
||||
import { currencyReceivablesExtension } from '@/extensions/export/currency-receivables'
|
||||
import type { Extension } from './types'
|
||||
|
||||
// ── Enable Banking (PSD2) — opt-in extension ───────────────────────────
|
||||
@@ -29,6 +33,12 @@ const FIRST_PARTY_EXTENSIONS: Extension[] = [
|
||||
aiChatExtension,
|
||||
invoiceInboxExtension,
|
||||
// enableBankingExtension, // Uncomment to activate PSD2 bank sync
|
||||
|
||||
// ── Export sector ──────────────────────────────────────────
|
||||
euSalesListExtension,
|
||||
vatMonitorExtension,
|
||||
intrastatExtension,
|
||||
currencyReceivablesExtension,
|
||||
]
|
||||
|
||||
let loaded = false
|
||||
|
||||
@@ -292,6 +292,68 @@ export const SECTORS: Sector[] = [
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
// ── Export ──────────────────────────────────────────────
|
||||
{
|
||||
slug: 'export',
|
||||
name: 'Export & Utrikeshandel',
|
||||
icon: 'Ship',
|
||||
description: 'Verktyg för svenska företag som exporterar varor till EU och övriga världen',
|
||||
extensions: [
|
||||
{
|
||||
slug: 'eu-sales-list',
|
||||
name: 'Periodisk sammanställning',
|
||||
sector: 'export',
|
||||
category: 'accounting',
|
||||
icon: 'FileText',
|
||||
dataPattern: 'core',
|
||||
readsCoreTables: ['invoices', 'customers'],
|
||||
hasOwnData: false,
|
||||
description: 'Generera periodisk sammanställning (EC Sales List) för Skatteverket',
|
||||
longDescription:
|
||||
'Sammanställer automatiskt alla momsfria EU-försäljningar grupperat per kund och momsregistreringsnummer. Genererar nedladdningsbar fil (CSV/XML) för uppladdning till Skatteverket. Validerar kundernas VAT-nummer via VIES och flaggar saknade uppgifter. Korsvaliderar mot momsdeklarationens ruta 35 och 39.',
|
||||
},
|
||||
{
|
||||
slug: 'vat-monitor',
|
||||
name: 'Exportmoms-monitor',
|
||||
sector: 'export',
|
||||
category: 'reports',
|
||||
icon: 'Shield',
|
||||
dataPattern: 'core',
|
||||
readsCoreTables: ['journal_entry_lines', 'journal_entries', 'invoices'],
|
||||
hasOwnData: false,
|
||||
description: 'Övervaka momsbehandling för export och EU-handel',
|
||||
longDescription:
|
||||
'Visar intäkter uppdelat på inhemsk försäljning, EU B2B (reverse charge) och export utanför EU. Mappar automatiskt till rätt rutor i momsdeklarationen (ruta 05, 35, 36, 39, 40). Flaggar potentiella fel som saknat momsregistreringsnummer på EU-kunder eller felaktig momsbehandling.',
|
||||
},
|
||||
{
|
||||
slug: 'intrastat',
|
||||
name: 'Intrastat-generator',
|
||||
sector: 'export',
|
||||
category: 'accounting',
|
||||
icon: 'BarChart3',
|
||||
dataPattern: 'both',
|
||||
readsCoreTables: ['invoices', 'customers'],
|
||||
hasOwnData: true,
|
||||
description: 'Generera Intrastat-deklarationer för rapportering till SCB',
|
||||
longDescription:
|
||||
'Tagga produkter med CN-koder (Combined Nomenclature), vikt och ursprungsland. Genererar kompletta Intrastat-deklarationer i CSV-format för uppladdning till SCB:s IDEP.web. Övervakar tröskelvärdet på 12 MSEK för utförsel och varnar när rapporteringsskyldighet uppstår.',
|
||||
},
|
||||
{
|
||||
slug: 'currency-receivables',
|
||||
name: 'Valutafordringar',
|
||||
sector: 'export',
|
||||
category: 'reports',
|
||||
icon: 'TrendingUp',
|
||||
dataPattern: 'core',
|
||||
readsCoreTables: ['invoices', 'journal_entry_lines', 'transactions'],
|
||||
hasOwnData: false,
|
||||
description: 'Övervaka valutaexponering och orealiserade kursvinster/-förluster',
|
||||
longDescription:
|
||||
'Visar öppna kundfordringar per valuta med aktuellt SEK-värde baserat på Riksbankens dagskurser. Beräknar orealiserade valutakursvinster och -förluster. Visar realiserade kursdifferenser per period (konto 3960/7960). Ger en samlad bild av företagets valutarisk.',
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
// ============================================================
|
||||
|
||||
@@ -10,7 +10,7 @@ import type { EntityType, RawTransaction, IngestResult } from '@/types'
|
||||
export type ExtensionCategory = 'accounting' | 'reports' | 'import' | 'operations'
|
||||
|
||||
/** Sector slugs for extension organization */
|
||||
export type SectorSlug = 'general' | 'restaurant' | 'construction' | 'hotel' | 'tech' | 'ecommerce'
|
||||
export type SectorSlug = 'general' | 'restaurant' | 'construction' | 'hotel' | 'tech' | 'ecommerce' | 'export'
|
||||
|
||||
/** How an extension gets its data */
|
||||
export type ExtensionDataPattern = 'core' | 'manual' | 'both'
|
||||
|
||||
@@ -32,6 +32,11 @@ const WORKSPACES: Record<WorkspaceKey, ComponentType<WorkspaceComponentProps>> =
|
||||
// E-commerce
|
||||
'ecommerce/shopify-import': dynamic(() => import('@/components/extensions/ecommerce/ShopifyImportWorkspace')),
|
||||
'ecommerce/multichannel-revenue': dynamic(() => import('@/components/extensions/ecommerce/MultichannelRevenueWorkspace')),
|
||||
// Export
|
||||
'export/eu-sales-list': dynamic(() => import('@/components/extensions/export/EuSalesListWorkspace')),
|
||||
'export/vat-monitor': dynamic(() => import('@/components/extensions/export/VatMonitorWorkspace')),
|
||||
'export/intrastat': dynamic(() => import('@/components/extensions/export/IntrastatWorkspace')),
|
||||
'export/currency-receivables': dynamic(() => import('@/components/extensions/export/CurrencyReceivablesWorkspace')),
|
||||
}
|
||||
|
||||
export function getWorkspaceComponent(
|
||||
|
||||
Reference in New Issue
Block a user