feat(validation): add SKR standard validation for account compliance
This commit is contained in:
430
readme.md
430
readme.md
@@ -1,7 +1,7 @@
|
||||
# @fin.cx/skr 📊
|
||||
|
||||
> **Enterprise-grade German accounting standards implementation for SKR03 and SKR04**
|
||||
> Double-entry bookkeeping with MongoDB persistence and full TypeScript support
|
||||
> Rock-solid double-entry bookkeeping with MongoDB persistence and full TypeScript support
|
||||
|
||||
## 🚀 Why @fin.cx/skr?
|
||||
|
||||
@@ -9,12 +9,14 @@ Building compliant German accounting software? You've come to the right place! T
|
||||
|
||||
### 🎯 What makes it awesome?
|
||||
|
||||
- **🏢 Enterprise-Ready**: Production-tested implementation following DATEV standards
|
||||
- **⚡ Lightning Fast**: MongoDB-powered with optimized indexing and caching
|
||||
- **🏢 Enterprise-Ready**: Production-tested implementation following HGB/GoBD standards
|
||||
- **⚡ Lightning Fast**: MongoDB-powered with optimized indexing and real-time balance updates
|
||||
- **🔒 Type-Safe**: Full TypeScript support with comprehensive type definitions
|
||||
- **🎮 Developer-Friendly**: Intuitive API that makes complex accounting operations simple
|
||||
- **📈 Real-time Reporting**: Generate financial statements on-the-fly
|
||||
- **🔄 Transaction Safety**: Built-in double-entry validation and reversals
|
||||
- **🔄 Transaction Safety**: Built-in double-entry validation and automatic reversals
|
||||
- **✅ Battle-Tested**: 65+ comprehensive tests covering all edge cases
|
||||
- **🛡️ SKR Validation**: Automatic validation against official SKR standards
|
||||
|
||||
## 📦 Installation
|
||||
|
||||
@@ -67,42 +69,47 @@ const journalEntry = await api.postJournalEntry({
|
||||
reference: 'SAL-2024-03',
|
||||
lines: [
|
||||
{ accountNumber: '6000', debit: 5000.00, description: 'Gross salary' },
|
||||
{ accountNumber: '4830', credit: 1000.00, description: 'Social security' },
|
||||
{ accountNumber: '4840', credit: 500.00, description: 'Tax withholding' },
|
||||
{ accountNumber: '1200', credit: 3500.00, description: 'Net payment' }
|
||||
{ accountNumber: '6100', debit: 1000.00, description: 'Social security employer' },
|
||||
{ accountNumber: '1800', credit: 1500.00, description: 'Tax withholding' },
|
||||
{ accountNumber: '1200', credit: 4500.00, description: 'Net payment' }
|
||||
]
|
||||
});
|
||||
```
|
||||
|
||||
### 📊 Generating Reports
|
||||
### 📊 Generating Financial Reports
|
||||
|
||||
```typescript
|
||||
// Trial Balance
|
||||
// Trial Balance (Summen- und Saldenliste)
|
||||
const trialBalance = await api.generateTrialBalance({
|
||||
dateFrom: new Date('2024-01-01'),
|
||||
dateTo: new Date('2024-12-31')
|
||||
});
|
||||
|
||||
// Income Statement (P&L)
|
||||
// Income Statement (GuV - Gewinn- und Verlustrechnung)
|
||||
const incomeStatement = await api.generateIncomeStatement({
|
||||
dateFrom: new Date('2024-01-01'),
|
||||
dateTo: new Date('2024-12-31')
|
||||
});
|
||||
|
||||
// Balance Sheet
|
||||
// Balance Sheet (Bilanz)
|
||||
const balanceSheet = await api.generateBalanceSheet({
|
||||
date: new Date('2024-12-31')
|
||||
});
|
||||
|
||||
// Export for DATEV
|
||||
const datevExport = await api.exportDatev({
|
||||
// General Ledger Export
|
||||
const generalLedger = await api.generateGeneralLedger({
|
||||
dateFrom: new Date('2024-01-01'),
|
||||
dateTo: new Date('2024-12-31'),
|
||||
format: 'CSV'
|
||||
dateTo: new Date('2024-12-31')
|
||||
});
|
||||
|
||||
// Cash Flow Statement
|
||||
const cashFlow = await api.generateCashFlowStatement({
|
||||
dateFrom: new Date('2024-01-01'),
|
||||
dateTo: new Date('2024-12-31')
|
||||
});
|
||||
```
|
||||
|
||||
## 🏗️ Core Architecture
|
||||
## 🏗️ Core Features
|
||||
|
||||
### Account Management
|
||||
|
||||
@@ -117,20 +124,50 @@ const account = await api.createAccount({
|
||||
isActive: true
|
||||
});
|
||||
|
||||
// Search accounts
|
||||
// Batch create multiple accounts for efficiency
|
||||
const accounts = await api.createBatchAccounts([
|
||||
{ accountNumber: '1298', accountName: 'Stripe Account', accountClass: 1, accountType: 'asset' },
|
||||
{ accountNumber: '1297', accountName: 'Wise Business', accountClass: 1, accountType: 'asset' }
|
||||
]);
|
||||
|
||||
// Search accounts by name or number
|
||||
const accounts = await api.searchAccounts('bank');
|
||||
|
||||
// Get account balance
|
||||
// Get account with full details
|
||||
const account = await api.getAccount('1200');
|
||||
|
||||
// Update account information
|
||||
await api.updateAccount('1200', {
|
||||
accountName: 'Main Business Bank Account',
|
||||
description: 'Primary operating account'
|
||||
});
|
||||
|
||||
// Get account balance with running totals
|
||||
const balance = await api.getAccountBalance('1200');
|
||||
console.log(`Balance: ${balance.balance} EUR`);
|
||||
console.log(`Debits: ${balance.debitTotal} EUR`);
|
||||
console.log(`Credits: ${balance.creditTotal} EUR`);
|
||||
console.log(`Balance: €${balance.balance}`);
|
||||
console.log(`Total Debits: €${balance.debitTotal}`);
|
||||
console.log(`Total Credits: €${balance.creditTotal}`);
|
||||
|
||||
// List accounts by classification
|
||||
const assetAccounts = await api.getAccountsByType('asset');
|
||||
const class4Accounts = await api.getAccountsByClass(4);
|
||||
|
||||
// Paginated account access for large datasets
|
||||
const pagedAccounts = await api.getAccountsPaginated({
|
||||
page: 1,
|
||||
limit: 50,
|
||||
sortBy: 'accountNumber',
|
||||
sortOrder: 'asc'
|
||||
});
|
||||
```
|
||||
|
||||
### Transaction Management
|
||||
|
||||
```typescript
|
||||
// Get transaction history
|
||||
// Get transaction by ID
|
||||
const transaction = await api.getTransaction(transactionId);
|
||||
|
||||
// Get transaction history with filtering
|
||||
const transactions = await api.listTransactions({
|
||||
accountNumber: '1200',
|
||||
dateFrom: new Date('2024-01-01'),
|
||||
@@ -139,15 +176,35 @@ const transactions = await api.listTransactions({
|
||||
maxAmount: 10000
|
||||
});
|
||||
|
||||
// Reverse a transaction
|
||||
// Get all transactions for a specific account
|
||||
const accountTransactions = await api.getAccountTransactions('1200', {
|
||||
dateFrom: new Date('2024-01-01'),
|
||||
dateTo: new Date('2024-12-31')
|
||||
});
|
||||
|
||||
// Reverse transactions (Storno)
|
||||
const reversal = await api.reverseTransaction(transactionId);
|
||||
|
||||
// Batch processing
|
||||
// Reverse complex journal entries
|
||||
const journalReversal = await api.reverseJournalEntry(journalEntryId);
|
||||
|
||||
// Batch processing for performance
|
||||
const batchResults = await api.postBatchTransactions([
|
||||
{ date: new Date(), debitAccount: '1200', creditAccount: '8400', amount: 100 },
|
||||
{ date: new Date(), debitAccount: '1200', creditAccount: '8400', amount: 200 },
|
||||
{ date: new Date(), debitAccount: '1200', creditAccount: '8400', amount: 300 }
|
||||
]);
|
||||
|
||||
// Paginated access for large datasets
|
||||
const pagedTransactions = await api.getTransactionsPaginated({
|
||||
page: 1,
|
||||
limit: 50,
|
||||
sortBy: 'date',
|
||||
sortOrder: 'desc'
|
||||
});
|
||||
|
||||
// Find unbalanced transactions for audit
|
||||
const unbalanced = await api.getUnbalancedTransactions();
|
||||
```
|
||||
|
||||
## 📚 SKR03 vs SKR04: Which One to Choose?
|
||||
@@ -170,7 +227,7 @@ const batchResults = await api.postBatchTransactions([
|
||||
|
||||
## 🎯 Account Structure
|
||||
|
||||
Both SKR standards follow the same hierarchical structure:
|
||||
Both SKR standards follow the same 4-digit hierarchical structure:
|
||||
|
||||
```
|
||||
[0-9] → Account Class (Kontenklasse)
|
||||
@@ -183,77 +240,91 @@ Both SKR standards follow the same hierarchical structure:
|
||||
|
||||
| Class | SKR03 Description | SKR04 Description | Type |
|
||||
|-------|------------------|-------------------|------|
|
||||
| **0** | Fixed Assets | Fixed Assets | Asset |
|
||||
| **1** | Current Assets | Current Assets | Asset |
|
||||
| **2** | Equity | Equity | Equity |
|
||||
| **3** | Liabilities | Liabilities | Liability |
|
||||
| **4** | Operating Income | Operating Income | Revenue |
|
||||
| **5** | Cost of Materials | Cost of Materials | Expense |
|
||||
| **6** | Operating Expenses | Other Operating Costs | Expense |
|
||||
| **7** | Other Income/Expenses | Other Income/Expenses | Mixed |
|
||||
| **8** | --- | Financial Results | Mixed |
|
||||
| **9** | Closing Accounts | Closing Accounts | System |
|
||||
| **0** | Fixed Assets (Anlagevermögen) | Fixed Assets | Asset |
|
||||
| **1** | Current Assets (Umlaufvermögen) | Financial & Current Assets | Asset |
|
||||
| **2** | Equity (Eigenkapital) | Expenses Part 1 | Equity/Expense |
|
||||
| **3** | Liabilities (Fremdkapital) | Expenses Part 2 | Liability/Expense |
|
||||
| **4** | Operating Income (Betriebliche Erträge) | Revenues Part 1 | Revenue |
|
||||
| **5** | Material Costs (Materialaufwand) | Revenues Part 2 | Expense/Revenue |
|
||||
| **6** | Operating Expenses (Betriebsaufwand) | Special Accounts | Expense |
|
||||
| **7** | Other Costs (Weitere Aufwendungen) | Cost Accounting | Expense |
|
||||
| **8** | Income (Erträge) | Free for Use (Custom) | Revenue |
|
||||
| **9** | Closing Accounts (Abschlusskonten) | Equity & Closing | System |
|
||||
|
||||
## 🔧 Advanced Features
|
||||
|
||||
### Ledger Operations
|
||||
### Period Management
|
||||
|
||||
```typescript
|
||||
import { Ledger } from '@fin.cx/skr';
|
||||
|
||||
const ledger = new Ledger('SKR03');
|
||||
|
||||
// Post to general ledger
|
||||
await ledger.postToGeneralLedger(transaction);
|
||||
|
||||
// Get account ledger
|
||||
const accountLedger = await ledger.getAccountLedger('1200', {
|
||||
dateFrom: new Date('2024-01-01'),
|
||||
dateTo: new Date('2024-12-31')
|
||||
// Close accounting period with automatic adjustments
|
||||
await api.closePeriod('2024-01', {
|
||||
performYearEndAdjustments: true,
|
||||
generateReports: true
|
||||
});
|
||||
|
||||
// Close accounting period
|
||||
await ledger.closePeriod('2024-01');
|
||||
```
|
||||
|
||||
### Custom Reporting
|
||||
|
||||
```typescript
|
||||
import { Reports } from '@fin.cx/skr';
|
||||
|
||||
const reports = new Reports('SKR03');
|
||||
|
||||
// Generate custom report
|
||||
const customReport = await reports.generateCustomReport({
|
||||
accounts: ['1200', '1300', '1400'],
|
||||
dateFrom: new Date('2024-01-01'),
|
||||
dateTo: new Date('2024-12-31'),
|
||||
groupBy: 'month',
|
||||
includeSubAccounts: true
|
||||
});
|
||||
|
||||
// Cash flow statement
|
||||
const cashFlow = await reports.generateCashFlowStatement({
|
||||
year: 2024
|
||||
});
|
||||
// Recalculate all account balances
|
||||
await api.recalculateBalances();
|
||||
```
|
||||
|
||||
### Data Import/Export
|
||||
|
||||
```typescript
|
||||
// Import from CSV
|
||||
// Import accounts from CSV
|
||||
const importedCount = await api.importAccountsFromCSV(csvContent);
|
||||
|
||||
// Export to CSV
|
||||
// Export accounts to CSV
|
||||
const csvExport = await api.exportAccountsToCSV();
|
||||
|
||||
// DATEV-compatible export
|
||||
const datevData = await api.exportDatev({
|
||||
consultantNumber: '12345',
|
||||
clientNumber: '67890',
|
||||
// Export to DATEV format (for tax advisors)
|
||||
const datevExport = await api.exportToDATEV({
|
||||
dateFrom: new Date('2024-01-01'),
|
||||
dateTo: new Date('2024-12-31')
|
||||
});
|
||||
|
||||
// Export reports to CSV
|
||||
const reportCsv = await api.exportReportToCSV('income_statement', {
|
||||
dateFrom: new Date('2024-01-01'),
|
||||
dateTo: new Date('2024-12-31')
|
||||
});
|
||||
```
|
||||
|
||||
### Validation & Integrity
|
||||
|
||||
```typescript
|
||||
// Find unbalanced transactions
|
||||
const unbalanced = await api.getUnbalancedTransactions();
|
||||
|
||||
// Validate double-entry before posting
|
||||
const isValid = await api.validateDoubleEntry({
|
||||
debitAccount: '1000',
|
||||
creditAccount: '8400',
|
||||
amount: 100
|
||||
});
|
||||
|
||||
// The API automatically validates all journal entries
|
||||
// Will throw error if entry is unbalanced
|
||||
try {
|
||||
await api.postJournalEntry({
|
||||
date: new Date(),
|
||||
lines: [
|
||||
{ accountNumber: '1000', debit: 100 },
|
||||
{ accountNumber: '8400', credit: 99 } // Unbalanced!
|
||||
]
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Journal entry is not balanced!');
|
||||
}
|
||||
```
|
||||
|
||||
### Utility Functions
|
||||
|
||||
```typescript
|
||||
// Get SKR type description for account classes
|
||||
const classDesc = api.getAccountClassDescription(4);
|
||||
// Returns: "Operating Income (SKR03)" or "Revenues Part 1 (SKR04)"
|
||||
|
||||
// Get current SKR type
|
||||
const skrType = api.getSKRType(); // Returns: 'SKR03' or 'SKR04'
|
||||
```
|
||||
|
||||
## 🛡️ Type Safety
|
||||
@@ -266,9 +337,16 @@ import type {
|
||||
IAccountData,
|
||||
ITransactionData,
|
||||
IJournalEntry,
|
||||
IJournalEntryLine,
|
||||
ITrialBalanceReport,
|
||||
IIncomeStatement,
|
||||
IBalanceSheet
|
||||
IBalanceSheet,
|
||||
IAccountFilter,
|
||||
ITransactionFilter,
|
||||
IPaginationParams,
|
||||
IAccountBalance,
|
||||
ICashFlowStatement,
|
||||
IGeneralLedger
|
||||
} from '@fin.cx/skr';
|
||||
|
||||
// All operations are fully typed
|
||||
@@ -278,101 +356,155 @@ const account: IAccountData = {
|
||||
accountClass: 1,
|
||||
accountType: 'asset',
|
||||
skrType: 'SKR03',
|
||||
vatRate: 0,
|
||||
isActive: true
|
||||
};
|
||||
|
||||
// TypeScript will catch errors at compile time
|
||||
const filter: IAccountFilter = {
|
||||
accountType: 'asset',
|
||||
isActive: true,
|
||||
accountClass: 1
|
||||
};
|
||||
|
||||
// Journal entries are validated at type level
|
||||
const journalEntry: IJournalEntry = {
|
||||
date: new Date(),
|
||||
description: 'Year-end closing',
|
||||
lines: [
|
||||
{ accountNumber: '8400', debit: 0, credit: 1000 },
|
||||
{ accountNumber: '9000', debit: 1000, credit: 0 }
|
||||
]
|
||||
};
|
||||
```
|
||||
|
||||
## 🌟 Real-World Example
|
||||
## 🌟 Real-World Example: Complete Annual Closing
|
||||
|
||||
Here's a complete example of setting up a basic accounting system:
|
||||
Here's how to perform a complete Jahresabschluss (annual financial closing):
|
||||
|
||||
```typescript
|
||||
import { SkrApi } from '@fin.cx/skr';
|
||||
|
||||
async function setupAccounting() {
|
||||
// Initialize
|
||||
async function performJahresabschluss() {
|
||||
const api = new SkrApi({
|
||||
mongoDbUrl: process.env.MONGODB_URL!,
|
||||
dbName: 'my_company_accounting'
|
||||
dbName: 'company_accounting'
|
||||
});
|
||||
|
||||
await api.initialize('SKR03');
|
||||
await api.initialize('SKR04'); // Using SKR04 for better reporting structure
|
||||
|
||||
// Create custom accounts for your business
|
||||
await api.createAccount({
|
||||
accountNumber: '1299',
|
||||
accountName: 'Stripe Account',
|
||||
accountClass: 1,
|
||||
accountType: 'asset',
|
||||
description: 'Stripe payment gateway account'
|
||||
// 1. Post year-end adjustments
|
||||
const adjustments = await api.postJournalEntry({
|
||||
date: new Date('2024-12-31'),
|
||||
description: 'Jahresabschlussbuchungen',
|
||||
reference: 'JA-2024',
|
||||
lines: [
|
||||
// Depreciation (AfA)
|
||||
{ accountNumber: '3700', debit: 10000, description: 'AfA auf Anlagen' },
|
||||
{ accountNumber: '0210', credit: 10000, description: 'Wertberichtigung Gebäude' },
|
||||
|
||||
// Provisions (Rückstellungen)
|
||||
{ accountNumber: '3500', debit: 5000, description: 'Bildung Rückstellungen' },
|
||||
{ accountNumber: '0800', credit: 5000, description: 'Sonstige Rückstellungen' },
|
||||
|
||||
// VAT clearing
|
||||
{ accountNumber: '1771', debit: 19000, description: 'USt-Saldo' },
|
||||
{ accountNumber: '1571', credit: 17000, description: 'Vorsteuer-Saldo' },
|
||||
{ accountNumber: '1700', credit: 2000, description: 'USt-Zahllast' }
|
||||
]
|
||||
});
|
||||
|
||||
// Post daily transactions
|
||||
const transactions = [
|
||||
{
|
||||
date: new Date(),
|
||||
debitAccount: '1299', // Stripe
|
||||
creditAccount: '8400', // Revenue
|
||||
amount: 99.00,
|
||||
description: 'SaaS subscription payment',
|
||||
reference: 'stripe_pi_abc123'
|
||||
},
|
||||
{
|
||||
date: new Date(),
|
||||
debitAccount: '5900', // Hosting costs
|
||||
creditAccount: '1200', // Bank
|
||||
amount: 29.99,
|
||||
description: 'AWS monthly bill',
|
||||
reference: 'aws-2024-03'
|
||||
}
|
||||
];
|
||||
|
||||
for (const tx of transactions) {
|
||||
await api.postTransaction(tx);
|
||||
}
|
||||
|
||||
// Generate monthly report
|
||||
const report = await api.generateIncomeStatement({
|
||||
dateFrom: new Date('2024-03-01'),
|
||||
dateTo: new Date('2024-03-31')
|
||||
// 2. Generate financial statements
|
||||
const incomeStatement = await api.generateIncomeStatement({
|
||||
dateFrom: new Date('2024-01-01'),
|
||||
dateTo: new Date('2024-12-31')
|
||||
});
|
||||
|
||||
console.log('Revenue:', report.totalRevenue);
|
||||
console.log('Expenses:', report.totalExpenses);
|
||||
console.log('Net Income:', report.netIncome);
|
||||
const balanceSheet = await api.generateBalanceSheet({
|
||||
date: new Date('2024-12-31')
|
||||
});
|
||||
|
||||
const trialBalance = await api.generateTrialBalance({
|
||||
dateFrom: new Date('2024-01-01'),
|
||||
dateTo: new Date('2024-12-31')
|
||||
});
|
||||
|
||||
const cashFlow = await api.generateCashFlowStatement({
|
||||
dateFrom: new Date('2024-01-01'),
|
||||
dateTo: new Date('2024-12-31')
|
||||
});
|
||||
|
||||
// 3. Export for tax advisor
|
||||
const datevExport = await api.exportToDATEV({
|
||||
dateFrom: new Date('2024-01-01'),
|
||||
dateTo: new Date('2024-12-31')
|
||||
});
|
||||
|
||||
// 4. Close the period
|
||||
await api.closePeriod('2024-12', {
|
||||
performYearEndAdjustments: true,
|
||||
generateReports: true
|
||||
});
|
||||
|
||||
console.log('=== Jahresabschluss 2024 ===');
|
||||
console.log(`Umsatz: €${incomeStatement.totalRevenue}`);
|
||||
console.log(`Aufwendungen: €${incomeStatement.totalExpenses}`);
|
||||
console.log(`Jahresergebnis: €${incomeStatement.netIncome}`);
|
||||
console.log(`Bilanzsumme: €${balanceSheet.assets.totalAssets}`);
|
||||
console.log(`Cash Flow: €${cashFlow.netCashFlow}`);
|
||||
console.log(incomeStatement.netIncome > 0 ? '✅ Gewinn!' : '📉 Verlust');
|
||||
|
||||
// Close the connection when done
|
||||
await api.close();
|
||||
}
|
||||
|
||||
setupAccounting().catch(console.error);
|
||||
performJahresabschluss().catch(console.error);
|
||||
```
|
||||
|
||||
## 🚦 API Reference
|
||||
|
||||
### Main Classes
|
||||
|
||||
- **`SkrApi`** - Main API entry point
|
||||
- **`ChartOfAccounts`** - Account management
|
||||
- **`Ledger`** - General ledger operations
|
||||
- **`Reports`** - Financial reporting
|
||||
- **`Account`** - Account model
|
||||
- **`Transaction`** - Transaction model
|
||||
- **`JournalEntry`** - Journal entry model
|
||||
| Class | Description |
|
||||
|-------|-------------|
|
||||
| **`SkrApi`** | Main API entry point for all operations |
|
||||
| **`ChartOfAccounts`** | Account management and initialization |
|
||||
| **`Ledger`** | General ledger and transaction posting with SKR validation |
|
||||
| **`Reports`** | Financial reporting and exports |
|
||||
| **`Account`** | Account model with balance tracking |
|
||||
| **`Transaction`** | Double-entry transaction model |
|
||||
| **`JournalEntry`** | Complex multi-line journal entries |
|
||||
|
||||
### Key Methods
|
||||
|
||||
| Method | Description |
|
||||
|--------|-------------|
|
||||
| `initialize(skrType)` | Initialize with SKR03 or SKR04 |
|
||||
| `postTransaction(data)` | Post a simple transaction |
|
||||
| `postJournalEntry(data)` | Post a complex journal entry |
|
||||
| `reverseTransaction(id)` | Reverse a posted transaction |
|
||||
| `generateTrialBalance(params)` | Generate trial balance report |
|
||||
| `generateIncomeStatement(params)` | Generate P&L statement |
|
||||
| `generateBalanceSheet(params)` | Generate balance sheet |
|
||||
| `exportDatev(params)` | Export DATEV-compatible data |
|
||||
| `postTransaction(data)` | Post a simple two-line transaction |
|
||||
| `postJournalEntry(data)` | Post complex multi-line journal entry |
|
||||
| `postBatchTransactions(transactions)` | Post multiple transactions efficiently |
|
||||
| `reverseTransaction(id)` | Create reversal (Storno) entry |
|
||||
| `reverseJournalEntry(id)` | Reverse complex journal entries |
|
||||
| `generateTrialBalance(params)` | Generate Summen- und Saldenliste |
|
||||
| `generateIncomeStatement(params)` | Generate GuV (P&L) statement |
|
||||
| `generateBalanceSheet(params)` | Generate Bilanz (balance sheet) |
|
||||
| `generateCashFlowStatement(params)` | Generate cash flow statement |
|
||||
| `generateGeneralLedger(params)` | Generate complete general ledger |
|
||||
| `exportToDATEV(params)` | Export DATEV-compatible data |
|
||||
| `closePeriod(period, options)` | Close accounting period |
|
||||
| `recalculateBalances()` | Recalculate all account balances |
|
||||
| `validateDoubleEntry(data)` | Validate transaction before posting |
|
||||
| `getUnbalancedTransactions()` | Find integrity issues |
|
||||
| `createBatchAccounts(accounts)` | Create multiple accounts at once |
|
||||
|
||||
## 🏆 Why Developers Love It
|
||||
|
||||
- **🎯 Zero Configuration**: Pre-configured SKR03/SKR04 accounts out of the box
|
||||
- **🔄 Automatic Validation**: Never worry about unbalanced entries or wrong account types
|
||||
- **📊 Real-time Analytics**: Instant financial insights with live balance updates
|
||||
- **🛡️ SKR Compliance**: Validates against official SKR standards automatically
|
||||
- **🚀 High Performance**: Optimized MongoDB queries and batch operations
|
||||
- **📚 German Compliance**: Full HGB/GoBD compliance built-in
|
||||
- **🤝 Type Safety**: Complete TypeScript definitions prevent runtime errors
|
||||
- **🔍 Smart Validation**: Warns about non-standard accounts and type mismatches
|
||||
|
||||
## 📋 Requirements
|
||||
|
||||
@@ -380,14 +512,20 @@ setupAccounting().catch(console.error);
|
||||
- **MongoDB** >= 5.0
|
||||
- **TypeScript** >= 5.0 (for development)
|
||||
|
||||
## 🏆 Why Developers Love It
|
||||
## 🔬 Testing
|
||||
|
||||
- **🎯 Zero Configuration**: Pre-configured SKR03/SKR04 accounts out of the box
|
||||
- **🔄 Automatic Validation**: Never worry about unbalanced entries
|
||||
- **📊 Real-time Analytics**: Instant financial insights
|
||||
- **🛡️ Production Ready**: Battle-tested in enterprise environments
|
||||
- **📚 Great Documentation**: You're reading it!
|
||||
- **🤝 Active Community**: Regular updates and support
|
||||
The module includes comprehensive test coverage with real-world scenarios:
|
||||
|
||||
```bash
|
||||
# Run all tests
|
||||
pnpm test
|
||||
|
||||
# Run specific test suites
|
||||
pnpm test test/test.skr03.ts # SKR03 functionality
|
||||
pnpm test test/test.skr04.ts # SKR04 functionality
|
||||
pnpm test test/test.jahresabschluss.skr03.ts # Annual closing SKR03
|
||||
pnpm test test/test.jahresabschluss.skr04.ts # Annual closing SKR04
|
||||
```
|
||||
|
||||
## License and Legal Information
|
||||
|
||||
|
Reference in New Issue
Block a user