/** * Verifierad datauppsättning för hela den offentliga förvaltningen (S.13) i Sverige. * * Källa: Eurostat (ESTAT) – tabellerna gov_10a_taxag (skatter och sociala avgifter), * gov_10a_main (totala inkomster/utgifter/finansiellt sparande), gov_10a_exp * (utgifter efter ändamål, COFOG) samt nama_10_gdp (BNP, ersättning till anställda D1, * löner och kollektiva avgifter D11, driftsöverskott, hushållens konsumtion, * BNP-deflator). Eurostat bygger dessa serier på SCB:s nationalräkenskaper enligt * ENS 2010. Uttag: 2026-09-16, kompletterat med D11 2026-09-22. Rådata sparas * oförändrad i eurostat-se-2026-09-22.json. * * Enhet i rådata: miljoner kronor, löpande priser. Vi räknar om till miljarder kronor. * Interna överföringar mellan stat, kommuner, regioner och trygghetssystem är redan * konsoliderade bort av nationalräkenskaperna för sektorn offentlig förvaltning. */ import raw from "./eurostat-se-2026-09-22.json"; import sectorRaw from "./eurostat-sektorer-se-2026-09-23.json"; export const DATA_VERSION = "eurostat-se-2026-09-22"; /** Sektorsräkenskaper (nasa_10_nf_tr), uttag 2026-09-23. Används för avgränsningen * av marknadssektorernas lönesumma och överskott från modellversion m3.3.0. */ export const SECTOR_DATA_VERSION = "eurostat-sektorer-se-2026-09-23"; export const SECTOR_SOURCE = { table: "nasa_10_nf_tr", title: "Eurostat, Non-financial transactions – annual data (sektorsräkenskaper)", url: "https://ec.europa.eu/eurostat/databrowser/view/nasa_10_nf_tr/default/table", retrieved: "2026-09-23", datasetUpdated: (sectorRaw as { datasetUpdated: string }).datasetUpdated, }; export const DATA_EXTRACTED = "2026-09-16 (D11: 2026-09-22)"; /** * Statusmärkning som används genomgående i gränssnittet, så att officiell * statistik aldrig blandas samman med bearbetningar eller antaganden. */ export type SourceStatus = | "officiellt utfall" | "bearbetad fördelning" | "modellantagande" | "ditt antagande"; type Rec = Record>; const tax = raw.tax as Rec; const main = raw.main as Rec; const exp = raw.exp as Rec; const macro = raw.macro as Rec; const deflator = raw.deflator2015 as Record; const mdr = (v: number | undefined) => (v ? v / 1000 : 0); export type TaxGroupId = | "labour_income" | "payroll" | "social_contrib" | "corporate" | "household_capital" | "vat" | "excise" | "property_other"; export type ExpGroupId = | "health_care" | "social_protection" | "education" | "defence_justice" | "infrastructure" | "other"; export const TAX_GROUPS: { id: TaxGroupId; label: string; what: string; mapping: string; /** Status för själva beloppet i historiken. */ status: SourceStatus; /** Kommentar när modellens koppling till ett skatteunderlag är en bearbetning. */ caveat?: string; /** Etikett för skattereglaget, när reglaget omfattar mer än den historiska posten. */ policyLabel?: string; }[] = [ { id: "labour_income", label: "Skatt på hushållens inkomster (löner, pension, transfereringar)", what: "Kommunal och statlig inkomstskatt som hushållen betalar på löner, pensioner och andra skattepliktiga ersättningar.", mapping: "Eurostat gov_10a_taxag, kod D51A (löpande skatt på hushållens inkomster).", status: "officiellt utfall", caveat: "D51A är en enda officiell post. Den innehåller skatt på arbetsinkomster, pensioner och transfereringar samt statlig skatt på kapitalinkomster: utdelningar, räntor, realiserade kapitalvinster och schablonintäkten på investeringssparkonto. Modellens fördelning 74/4/22 mellan arbete, kapital och pension/transfereringar är en bearbetad fördelning (redaktionellt antagande), inte uppmätt statistik. Kapitaldelen styrs av reglaget för kapitalinkomster och sparande.", policyLabel: "Skatt på hushållens inkomster av arbete, pension och transfereringar", }, { id: "payroll", label: "Arbetsgivaravgifter och övriga produktionsskatter", what: "Avgifter och skatter som arbetsgivare betalar på lönesumman, samt övriga skatter på produktion.", mapping: "Eurostat gov_10a_taxag, kod D29 (övriga produktionsskatter). I Sverige redovisas huvuddelen av arbetsgivaravgifterna och den allmänna löneavgiften här, enligt EU-kommissionens Taxation Trends-indelning efter ekonomisk funktion (skatt på arbete, betald av arbetsgivare).", status: "officiellt utfall", caveat: "D29 innehåller även produktionsskatter som inte beror på lönesumman, till exempel fastighetsskatt på näringsfastighet och särskilda produktionsskatter. Modellen låter därför bara en angiven andel av D29 följa lönesumman; resten följer BNP.", }, { id: "social_contrib", label: "Sociala avgifter (netto, utöver produktionsskatterna)", what: "Avgifter till trygghetssystem som i nationalräkenskaperna redovisas som sociala avgifter i stället för skatt.", mapping: "Eurostat gov_10a_taxag, kod D61 (netto sociala avgifter).", status: "officiellt utfall", }, { id: "corporate", label: "Skatt på bolagsvinster", what: "Bolagsskatt på företagens vinster.", mapping: "Eurostat gov_10a_taxag, kod D51B (skatt på bolagens inkomster och vinster).", status: "officiellt utfall", caveat: "Modellen använder driftsöverskott och blandinkomst (B2A3G) som proxy för beskattningsbar vinst. Det är inte samma sak som skattemässigt resultat: avdrag för räntor och avskrivningar, underskott, koncernbidrag och internationell vinstförflyttning ingår inte.", }, { id: "household_capital", label: "Avkastningsskatt på pensions- och försäkringssparande", what: "Schablonskatt på avkastningen i pensionssparande och kapitalförsäkringar (avkastningsskatt enligt lagen om skatt på avkastning av pensionsmedel).", mapping: "Eurostat gov_10a_taxag, kod D51C. I Eurostats detaljerade skattelista (fliken SE) består Sveriges D51C-post av avkastningsskatt på pensions- och försäkringssparande – inte av skatt på hushållens realiserade kapitalvinster, som ingår i D51A.", status: "officiellt utfall", caveat: "Avkastningsskatten beräknas på kapitalunderlag gånger statslåneränta och följer varken lönesumman eller årets vinster. Dataunderlaget saknar en serie för sparkapitalet, så modellen låter nivån följa BNP (uttrycklig, försiktig förenkling). Nya vinster, utdelningar och kapitalvinster bokförs aldrig här.", policyLabel: "Skatt på kapitalinkomster och sparande (kapitaldelen av D51A samt D51C)", }, { id: "vat", label: "Moms", what: "Mervärdesskatt på varor och tjänster.", mapping: "Eurostat gov_10a_taxag, kod D211 (mervärdesskatt).", status: "officiellt utfall", }, { id: "excise", label: "Övriga konsumtionsskatter", what: "Energi- och drivmedelsskatt, alkohol- och tobaksskatt, fordonsskatt med mera.", mapping: "Eurostat gov_10a_taxag, kod D214 (skatter på produkter utom moms och importskatter).", status: "officiellt utfall", }, { id: "property_other", label: "Fastighetsrelaterade och övriga skatter", what: "Fastighetsavgift, stämpelskatt och den restpost av skatter som inte ingår i grupperna ovan.", mapping: "Eurostat gov_10a_taxag: D59 + D91 + restpost (bland annat importskatter D212 och avdrag för osäkra skattefordringar), så att grupperna exakt summerar till totalposten D2+D5+D91+D61 efter avdrag för osäkra skattefordringar.", status: "bearbetad fördelning", caveat: "Gruppen är beräknad som skillnaden mellan den officiella totalposten och summan av de övriga grupperna. Den är alltså korrekt på totalen men innehåller en restpost som inte är en enskild officiell serie.", }, ]; export const EXP_GROUPS: { id: ExpGroupId; label: string; what: string; mapping: string; status: SourceStatus; caveat?: string; }[] = [ { id: "health_care", label: "Hälso- och sjukvård", what: "Sjukvård, primärvård, läkemedel, sjukhus och medicinska tjänster.", mapping: "COFOG GF07 (hälso- och sjukvård) i Eurostat gov_10a_exp.", status: "officiellt utfall", caveat: "Äldreomsorg och funktionshinderomsorg räknas i COFOG till socialt skydd (GF10), inte till hälso- och sjukvård. Gruppen är därför mindre än vad som i svenskt tal ofta kallas vård och omsorg.", }, { id: "social_protection", label: "Socialt skydd: pensioner, försäkringar och omsorg", what: "Ålderspension, sjuk- och föräldraförsäkring, arbetslöshetsstöd, ekonomiskt bistånd samt äldreomsorg och funktionshinderomsorg.", mapping: "COFOG GF10 (socialt skydd) i Eurostat gov_10a_exp.", status: "officiellt utfall", caveat: "Innehåller både kontantförmåner och omsorgstjänster i natura. Ingen post ingår samtidigt i hälso- och sjukvård.", }, { id: "education", label: "Utbildning", what: "Förskola till högskola, vuxenutbildning och forskning inom utbildningsområdet.", mapping: "COFOG GF09 (utbildning).", status: "officiellt utfall", }, { id: "defence_justice", label: "Försvar och rättsväsende", what: "Försvar, polis, domstolar, kriminalvård och räddningstjänst.", mapping: "COFOG GF02 + GF03.", status: "officiellt utfall", }, { id: "infrastructure", label: "Infrastruktur, näringsliv och miljö", what: "Vägar, järnväg, energi, bostäder, miljöskydd och näringslivsstöd.", mapping: "COFOG GF04 + GF05 + GF06.", status: "officiellt utfall", }, { id: "other", label: "Övrigt: allmän förvaltning, räntor, kultur", what: "Allmän offentlig förvaltning, statsskuldsräntor, kultur och fritid.", mapping: "COFOG GF01 + GF08.", status: "officiellt utfall", }, ]; export type YearData = { year: number; /** miljarder kronor, löpande priser */ taxes: Record; taxTotal: number; otherRevenue: number; revenueTotal: number; expenditure: Record; expenditureTotal: number; balance: number; gdp: number; /** ersättning till anställda, dvs. lön inkl. arbetsgivaravgifter (D1) */ compensation: number; /** löner och kollektiva avgifter före skatt, hushållens löneinkomst (D11) */ wages: number; /** brutto driftsöverskott och blandinkomst (B2A3G) */ operatingSurplus: number; /** hushållens konsumtionsutgifter (P31_S14) */ householdConsumption: number; /** offentlig konsumtion (P3 för S.13) */ publicConsumption: number; /** offentliga sociala förmåner i kontanter (D62PAY), inte förmåner i natura (D632) */ socialBenefits: number; /** BNP-deflator, index 2015 = 100 */ deflator: number; /** * Marknadssektorernas andel av D1: icke-finansiella bolag (S.11), finansiella * bolag (S.12) och hushåll som arbetsgivare (S.14), dividerat med hela ekonomin * (S.1). Offentlig sektor (S.13) och ideella organisationer (S.15) ingår inte. * Bearbetad uppgift ur sektorsräkenskaperna, null om uppgift saknas. */ marketShareOfCompensation: number | null; /** * Marknadssektorernas andel av B2A3G: driftsöverskott S.11 + S.12 och blandinkomst * för hushållens näringsverksamhet (B3G, S.14), dividerat med B2A3G för S.1. * Offentlig sektors driftsöverskott (i praktiken kapitalförslitning), hushållens * driftsöverskott B2G (främst egnahem, beräknad boendetjänst) och S.15 ingår inte. * Bearbetad uppgift ur sektorsräkenskaperna, null om uppgift saknas. */ marketShareOfSurplus: number | null; }; const sector = (sectorRaw as { series: Record> }).series; function sectorShares(y: string) { const g = (k: string) => sector[k]?.[y]; const d1 = [g("S1.D1"), g("S11.D1"), g("S12.D1"), g("S14.D1")]; const sp = [g("S1.B2A3G"), g("S11.B2A3G"), g("S12.B2A3G"), g("S14.B3G")]; const ok = (a: (number | undefined)[]): a is number[] => a.every((v) => typeof v === "number") && a[0]! > 0; return { marketShareOfCompensation: ok(d1) ? (d1[1]! + d1[2]! + d1[3]!) / d1[0]! : null, marketShareOfSurplus: ok(sp) ? (sp[1]! + sp[2]! + sp[3]!) / sp[0]! : null, }; } function build(year: number): YearData | null { const y = String(year); const t = tax[y]; const m = main[y]; const e = exp[y]; const mc = macro[y]; if (!t || !m || !e || !mc) return null; const taxAndContrib = mdr(t["D2_D5_D91_D61_M_D995"]); const groups: Record = { labour_income: mdr(t["D51A"]), payroll: mdr(t["D29"]), social_contrib: mdr(t["D61"]), corporate: mdr(t["D51B"]), household_capital: mdr(t["D51C"]), vat: mdr(t["D211"]), excise: mdr(t["D214"]), property_other: 0, }; const sumKnown = Object.values(groups).reduce((a, b) => a + b, 0); // Restpost = D59, D91, importskatter (D212) och avdrag för osäkra skattefordringar. groups.property_other = Math.max(0, taxAndContrib - sumKnown); const taxTotal = Object.values(groups).reduce((a, b) => a + b, 0); const revenueTotal = mdr(m["TR"]); const expenditure: Record = { health_care: mdr(e["GF07"]), social_protection: mdr(e["GF10"]), education: mdr(e["GF09"]), defence_justice: mdr(e["GF02"]) + mdr(e["GF03"]), infrastructure: mdr(e["GF04"]) + mdr(e["GF05"]) + mdr(e["GF06"]), other: mdr(e["GF01"]) + mdr(e["GF08"]), }; const expenditureTotal = Object.values(expenditure).reduce((a, b) => a + b, 0); return { year, taxes: groups, taxTotal, otherRevenue: revenueTotal - taxTotal, revenueTotal, expenditure, expenditureTotal, balance: revenueTotal - expenditureTotal, gdp: mdr(mc["B1GQ"]), compensation: mdr(mc["D1"]), wages: mdr(mc["D11"]), operatingSurplus: mdr(mc["B2A3G"]), householdConsumption: mdr(mc["P31_S14"]), publicConsumption: mdr(m["P3"]), socialBenefits: mdr(m["D62PAY"]), deflator: deflator[y] ?? 100, ...sectorShares(y), }; } export const YEARS: number[] = Object.keys(tax) .map(Number) .filter((y) => build(y) !== null) .sort((a, b) => a - b); export const DATA: Record = Object.fromEntries( YEARS.map((y) => [y, build(y)!]), ) as Record; export const LATEST_YEAR = YEARS[YEARS.length - 1]!; /** Räknar om löpande kronor till ett gemensamt penningvärde med BNP-deflatorn. */ export function toPriceLevel(amount: number, fromYear: number, toYear: number): number { const a = DATA[fromYear]?.deflator ?? 100; const b = DATA[toYear]?.deflator ?? 100; return (amount * b) / a; }