Skip to content

Latest commit

 

History

History
212 lines (159 loc) · 7.26 KB

File metadata and controls

212 lines (159 loc) · 7.26 KB

german-accounting

Machine-readable SKR03/SKR04 chart of accounts with MCC-to-account mapping for German SME accounting. MIT licensed — code and data.

The only open source dataset combining enriched SKR03/SKR04 metadata with ISO 18245 MCC codes mapped to specific German accounts. Use it from any language: download the JSON files directly or install the npm package for a typed TypeScript API.

npm install german-accounting

Quick start

import { SKR03, suggestAccount } from "german-accounting";

// Look up an account
const konto = SKR03.get("4650");
// { konto: "4650", name: "Bewirtungskosten", klasse: 4, typ: "aufwand",
//   ust_relevant: true, steuerschluessel: [9], skr04: "6640", ... }

// Categorize a card transaction by MCC
const suggestion = suggestAccount("5812"); // restaurant
// {
//   mcc: "5812",
//   mcc_name: "Eating Places, Restaurants",
//   primary: { konto: "4650", confidence: "high", condition: null },
//   alternatives: [{ konto: "1800", condition: "If private meal" }],
//   needs_beleg: true,
//   ust_abzug: true
// }

// SaaS subscriptions (GitHub, Slack, Notion, Figma...)
suggestAccount("5817").primary.konto; // "4964" — zeitlich befristete Überlassung von Rechten (Lizenzen)

// Target SKR04 instead of SKR03
suggestAccount("5812", "SKR04").primary.konto; // "6640"

// Returns undefined for unknown MCCs — no throws
suggestAccount("9999"); // undefined

API

SKR03 / SKR04

Pre-loaded chart-of-accounts singletons. Both are instances of Kontenrahmen.

SKR03.get("4650")           // → Konto | undefined
SKR03.search("Reisekosten") // → readonly Konto[]  (case-insensitive substring)
SKR03.klasse(4)             // → readonly Konto[]  (all Klasse 4 expense accounts)
SKR03.exists("4650")        // → boolean
SKR03.size                  // → number

suggestAccount(mcc, skr?)

suggestAccount(mcc: string, skr?: "SKR03" | "SKR04"): MCCSuggestion | undefined

MCC range entries (airlines 3000–3350, car rentals 3351–3500, lodging 3501–3999) are expanded at load time. Any code in those ranges resolves correctly.

When skr = "SKR04", the primary account is the skr04_primary value. name is null and alternatives is empty (no SKR04 name data in v0.1).

Types

interface Konto {
  konto: string;                                   // "4650"
  name: string;                                    // "Bewirtungskosten"
  klasse: number;                                  // 4
  typ: "aufwand" | "ertrag" | "aktiv" | "passiv";
  gruppe: string;
  untergruppe?: string;
  ust_relevant: boolean;
  steuerschluessel: readonly number[];
  skr04?: string | null;   // cross-ref to SKR04 account (SKR03 only)
  skr03?: string | null;   // back-ref to SKR03 account (SKR04 only)
  notes?: string | null;
}

interface MCCSuggestion {
  mcc: string;
  mcc_name: string;
  category: string;
  primary: AccountSuggestion;
  alternatives: readonly AccountSuggestion[];
  needs_beleg: boolean;
  ust_abzug: boolean;
  notes: string | null;
}

interface AccountSuggestion {
  konto: string;
  name: string | null;
  confidence: "high" | "medium" | "low";
  condition: string | null;
}

Data files

The JSON files are the primary product. Download them from GitHub Releases to use without Node.

File Contents
src/data/skr03.json 289 SKR03 accounts with enriched metadata and SKR04 cross-references
src/data/skr04.json 254 SKR04 accounts derived from SKR03 cross-references
src/data/mcc_skr_mapping.json 230 MCC mappings with confidence levels and alternatives

JSON Schemas are in schemas/ and validated by CI on every push.

Verifying against the official DATEV charts

Every account number and designation can be verified deterministically against the official DATEV chart PDFs (which are copyrighted and therefore not part of this repository):

npm run verify:datev -- datev/skr03-2026.pdf datev/skr04-2026.pdf

See docs/datev-verification.md for where to download the charts, what the script checks, and the workflow for upgrading to a new chart year.

Data schema — skr03.json

{
  "meta": { "version": "2026.1", "last_updated": "2026-04-03", ... },
  "klassen": [{ "klasse": 0, "name": "Anlage- und Kapitalkonten" }, ...],
  "konten": [
    {
      "konto": "4650",
      "name": "Bewirtungskosten",
      "klasse": 4,
      "typ": "aufwand",
      "gruppe": "Betriebliche Aufwendungen",
      "ust_relevant": true,
      "steuerschluessel": [9, 8],
      "skr04": "6640"
    }
  ]
}

Data schema — mcc_skr_mapping.json

{
  "meta": { "version": "2026.1", ... },
  "mappings": [
    {
      "mcc": "5812",
      "mcc_name": "Eating Places, Restaurants",
      "category": "Food & Beverage",
      "skr03": { "primary": "4650", "confidence": "high" },
      "skr04_primary": "6640",
      "alternatives": [
        { "konto": "1800", "condition": "If private meal" }
      ],
      "needs_beleg": true,
      "ust_abzug": true
    }
  ]
}

MCC source and currency

The MCC data is a curated set of accounting suggestions, not a complete reproduction of the MCC catalogue. Code definitions are checked against ISO 18245:2023 and the public Mastercard Quick Reference Booklet — Merchant Edition (25 February 2025). The exact source URLs and the last verification date are also recorded in src/data/mcc_skr_mapping.json.

Card networks can introduce or regionally assign MCCs after the recorded review date. Treat an unknown MCC as unmapped and verify it with the applicable network documentation before adding an accounting suggestion.


Contributing

Add or fix an MCC mapping

  1. Edit mcc_skr_mapping.json. Required fields: mcc, mcc_name, category, skr03.primary, skr03.confidence, skr04_primary, needs_beleg, ust_abzug.
  2. Run npm test — CI gate verifies that all referenced accounts exist in skr03.json.
  3. Open a PR using the MCC mapping template. Include the account number, confidence level, your rationale, and your source (DATEV docs, Steuerberater guidance, SKR documentation).

Confidence guidelines:

  • high — the MCC strongly implies a specific account with no real ambiguity (e.g., fuel stations → Kfz-Betriebskosten)
  • medium — likely correct but depends on context (e.g., office supply store → could be Bürobedarf or a larger asset)
  • low — genuinely ambiguous; the mapping is a reasonable default but alternatives are common

Add or fix SKR03 accounts

Edit skr03.json directly. All fields from the schema are required. Run npm test to verify referential integrity before opening a PR.


Versioning

Data is versioned independently from the package using a year-based scheme (2026.1, 2026.2, ...). The package version tracks the API.


License

MIT — code and data.