2025-08-10 17:11:53 +00:00
2025-08-10 17:11:53 +00:00

@fin.cx/skr

@fin.cx/skr is a TypeScript library for German double-entry bookkeeping with built-in SKR03 and SKR04 chart initialization, MongoDB-backed persistence, reporting, DATEV export, GoBD-oriented Jahresabschluss export, and e-invoice workflows.

It is built for developers who need a programmable accounting core instead of a pile of CSV glue code: initialize a chart of accounts, post validated transactions and journal entries, generate reports, and archive year-end data in a structured export format.

Issue Reporting and Security

For reporting bugs, issues, or security vulnerabilities, please visit community.foss.global/. This is the central community hub for all issue reporting. Developers who sign and comply with our contribution agreement and go through identification can also get a code.foss.global/ account to submit Pull Requests directly.

What This Library Does

  • Initializes SKR03 or SKR04 account sets in MongoDB
  • Enforces double-entry bookkeeping rules for transactions and journal entries
  • Supports DATEV posting keys and VAT-aware journal lines
  • Prevents direct posting to automatic accounts that require personal accounts
  • Generates trial balance, income statement, balance sheet, general ledger, and cash flow reports
  • Exports accounting data as CSV, DATEV, and GoBD-style Jahresabschluss packages
  • Imports, stores, searches, books, and exports EN16931-style e-invoices
  • Adds signing and timestamp helpers for audit-oriented export workflows

Why It Is Useful

  • You get a real accounting domain model, not just account lists
  • SKR03 and SKR04 are both supported behind one API
  • Tests cover initialization, posting, reversals, reports, pagination, DATEV export, and full year-end flows
  • The package exports the lower-level classes too, so you can stay high-level with SkrApi or build around the primitives

Requirements

  • Node.js 20+ with ESM support
  • A reachable MongoDB instance
  • pnpm

The test setup reads MongoDB connection details from .nogit/ via @push.rocks/qenv, but the runtime API only needs a mongoDbUrl and an optional dbName.

Installation

pnpm add @fin.cx/skr

Quick Start

import { SkrApi } from '@fin.cx/skr';

const api = new SkrApi({
  mongoDbUrl: 'mongodb://localhost:27017',
  dbName: 'accounting_demo',
});

await api.initialize('SKR03');

await api.postTransaction({
  date: new Date(),
  debitAccount: '1200',
  creditAccount: '4000',
  amount: 1000,
  description: 'Test sale',
  reference: 'INV-001',
  skrType: 'SKR03',
});

const trialBalance = await api.generateTrialBalance();

console.log(trialBalance.isBalanced);

await api.close();

SKR03 vs SKR04

initialize('SKR03') loads the process-oriented chart.

  • Class 4: operating income
  • Class 5: material costs
  • Class 6: personnel costs
  • Class 7: other operating expenses

initialize('SKR04') loads the financial-statement-oriented chart.

  • Class 2 and 3: expenses
  • Class 4 and 5: revenues
  • Class 8: reserved as frei for custom use

The test suite exercises both variants and includes full Jahresabschluss scenarios for each.

Posting Model

Simple postings use postTransaction().

await api.postTransaction({
  date: new Date(),
  debitAccount: '5400',
  creditAccount: '70001',
  amount: 119,
  description: 'Purchase including VAT',
  skrType: 'SKR03',
  vatAmount: 19,
  reference: 'VAT-001',
});

Complex bookings use postJournalEntry() with explicit DATEV posting keys.

await api.postJournalEntry({
  date: new Date(),
  description: 'Complex distribution',
  reference: 'COMPLEX-001',
  lines: [
    { accountNumber: '5000', debit: 500, description: 'Materials', postingKey: 40 },
    { accountNumber: '6000', debit: 300, description: 'Wages', postingKey: 40 },
    { accountNumber: '7100', debit: 200, description: 'Rent', postingKey: 40 },
    { accountNumber: '1200', credit: 1000, description: 'Bank payment', postingKey: 40 },
  ],
  skrType: 'SKR03',
});

Important behavior from the code and tests:

  • debit and credit totals must balance
  • debit and credit account cannot be the same in a simple transaction
  • inactive accounts cannot be posted to
  • automatic accounts such as debtor or creditor control accounts are meant to be replaced by personal accounts for direct postings

Common Workflows

Create custom accounts:

await api.createAccount({
  accountNumber: '4999',
  accountName: 'Custom Revenue Account',
  accountClass: 4,
  accountType: 'revenue',
  description: 'Test custom account',
});

Batch operations:

await api.createBatchAccounts([
  {
    accountNumber: '10001',
    accountName: 'Kunde Mustermann GmbH',
    accountClass: 1,
    accountType: 'asset',
    skrType: 'SKR03',
  },
  {
    accountNumber: '70001',
    accountName: 'Lieferant Test GmbH',
    accountClass: 7,
    accountType: 'liability',
    skrType: 'SKR03',
  },
]);

Pagination:

const page1 = await api.getAccountsPaginated(1, 10);
console.log(page1.total, page1.totalPages, page1.data.length);

Reversals and validation:

const ok = api.validateDoubleEntry(100, 100);
const reversed = await api.reverseTransaction(transactionId);

Reports And Exports

Available reporting methods on SkrApi:

  • generateTrialBalance()
  • generateIncomeStatement()
  • generateBalanceSheet()
  • generateGeneralLedger()
  • generateCashFlowStatement()
  • exportReportToCSV()
  • exportToDATEV()

Year-end archival export:

const exportPath = await api.exportJahresabschluss({
  exportPath: './exports',
  fiscalYear: 2024,
  dateFrom: new Date('2024-01-01'),
  dateTo: new Date('2024-12-31'),
  includeDocuments: true,
  generatePdfReports: true,
  signExport: false,
  timestampExport: false,
  companyInfo: {
    name: 'Example GmbH',
    taxId: 'DE123456789',
    registrationNumber: 'HRB 12345',
    address: 'Example Street 1, 28195 Bremen',
  },
});

console.log(exportPath);

The export code creates a BagIt-style folder structure with metadata, accounting data, report output, document storage, and manifest hashes.

E-Invoice Workflows

The package includes invoice types and API helpers for importing, storing, booking, searching, exporting, and generating e-invoices.

Supported invoice directions:

  • inbound
  • outbound

Supported formats in the invoice model:

  • xrechnung
  • zugferd
  • facturx
  • peppol
  • ubl

Example import and booking flow:

const invoice = await api.importInvoice('./fixtures/invoice.xml', 'inbound', {
  autoBook: true,
  confidenceThreshold: 80,
});

const hits = await api.searchInvoices({
  invoiceNumber: invoice.invoiceNumber,
});

const exported = await api.exportInvoice(invoice, {
  format: 'xrechnung',
  embedInPdf: true,
});

The API also exposes:

  • bookInvoice()
  • getInvoice()
  • getInvoiceStatistics()
  • createInvoiceComplianceReport()
  • generateInvoice()

Public Exports

Top-level exports include:

  • SkrApi
  • Account
  • Transaction
  • JournalEntry
  • ChartOfAccounts
  • Ledger
  • Reports
  • SkrExport
  • LedgerExporter
  • AccountsExporter
  • BalancesExporter
  • PdfReportGenerator
  • SecurityManager
  • SKR03_ACCOUNTS, SKR04_ACCOUNTS

This makes the package usable as both an application-facing API and a toolkit for custom accounting workflows.

Development

Build:

pnpm build

Test:

pnpm test

Current project checks include:

  • runtime tests for SKR03 and SKR04 flows
  • transaction and journal validation
  • report generation
  • DATEV export
  • published type consumption through test/fixtures/strict-consumer

This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the license file.

Please note: The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.

Trademarks

This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH or third parties, and are not included within the scope of the MIT license granted herein.

Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines or the guidelines of the respective third-party owners, and any usage must be approved in writing. Third-party trademarks used herein are the property of their respective owners and used only in a descriptive manner, e.g. for an implementation of an API or similar.

Company Information

Task Venture Capital GmbH
Registered at District Court Bremen HRB 35230 HB, Germany

For any legal inquiries or further information, please contact us via email at hello@task.vc.

By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.

S
Description
a module implementing german SKR03/SKR04 account structures.
Readme 539 KiB
Languages
TypeScript 94.2%
Shell 5.8%