UNPKG

@fin.cx/skr

Version:

SKR03 and SKR04 German accounting standards for double-entry bookkeeping

164 lines 12.8 kB
import * as plugins from './plugins.js'; import * as path from 'path'; import { createWriteStream } from 'fs'; export class LedgerExporter { constructor(exportPath) { this.stream = null; this.entryCount = 0; this.exportPath = exportPath; } /** * Initializes the NDJSON export stream */ async initialize() { const ledgerPath = path.join(this.exportPath, 'data', 'accounting', 'ledger.ndjson'); await plugins.smartfile.fs.ensureDir(path.dirname(ledgerPath)); this.stream = createWriteStream(ledgerPath, { encoding: 'utf8', flags: 'w' }); } /** * Exports a transaction as a ledger entry */ async exportTransaction(transaction) { if (!this.stream) { throw new Error('Ledger exporter not initialized'); } const entry = { schema_version: '1.0', entry_id: transaction._id || plugins.smartunique.shortId(), booking_date: this.formatDate(transaction.date), posting_date: this.formatDate(transaction.postingDate || transaction.date), currency: transaction.currency || 'EUR', journal: 'GL', description: transaction.description, reference: transaction.reference, lines: [], created_at: transaction.createdAt ? new Date(transaction.createdAt).toISOString() : new Date().toISOString(), modified_at: transaction.modifiedAt ? new Date(transaction.modifiedAt).toISOString() : undefined, reversal_of: transaction.reversalOf, reversed_by: transaction.reversedBy }; // Add debit line if (transaction.amount > 0) { entry.lines.push({ posting_id: `${entry.entry_id}-1`, account_code: transaction.debitAccount, debit: transaction.amount.toFixed(2), credit: '0.00', tax_code: transaction.taxCode, cost_center: transaction.costCenter, project: transaction.project }); // Add credit line entry.lines.push({ posting_id: `${entry.entry_id}-2`, account_code: transaction.creditAccount, debit: '0.00', credit: transaction.amount.toFixed(2) }); } // Add VAT lines if applicable if (transaction.vatAmount && transaction.vatAmount > 0) { entry.lines.push({ posting_id: `${entry.entry_id}-3`, account_code: transaction.vatAccount || '1576', // Default VAT account debit: transaction.vatAmount.toFixed(2), credit: '0.00', description: 'Vorsteuer' }); } await this.writeLine(entry); } /** * Exports a journal entry */ async exportJournalEntry(journalEntry) { if (!this.stream) { throw new Error('Ledger exporter not initialized'); } const entry = { schema_version: '1.0', entry_id: journalEntry._id || plugins.smartunique.shortId(), booking_date: this.formatDate(journalEntry.date), posting_date: this.formatDate(journalEntry.postingDate || journalEntry.date), currency: journalEntry.currency || 'EUR', journal: journalEntry.journal || 'GL', description: journalEntry.description, reference: journalEntry.reference, lines: [], created_at: journalEntry.createdAt ? new Date(journalEntry.createdAt).toISOString() : new Date().toISOString(), modified_at: journalEntry.modifiedAt ? new Date(journalEntry.modifiedAt).toISOString() : undefined, reversal_of: journalEntry.reversalOf, reversed_by: journalEntry.reversedBy }; // Convert journal entry lines journalEntry.lines.forEach((line, index) => { const extLine = line; entry.lines.push({ posting_id: `${entry.entry_id}-${index + 1}`, account_code: line.accountNumber, debit: (line.debit || 0).toFixed(2), credit: (line.credit || 0).toFixed(2), tax_code: extLine.taxCode, cost_center: line.costCenter, project: extLine.project, description: line.description }); }); await this.writeLine(entry); } /** * Writes a single NDJSON line */ async writeLine(entry) { return new Promise((resolve, reject) => { if (!this.stream) { reject(new Error('Stream not initialized')); return; } const line = JSON.stringify(entry) + '\n'; this.stream.write(line, (error) => { if (error) { reject(error); } else { this.entryCount++; resolve(); } }); }); } /** * Formats a date to ISO date string */ formatDate(date) { if (typeof date === 'string') { return date.split('T')[0]; } return date.toISOString().split('T')[0]; } /** * Closes the export stream */ async close() { return new Promise((resolve) => { if (this.stream) { this.stream.end(() => { resolve(this.entryCount); }); } else { resolve(this.entryCount); } }); } /** * Gets the number of exported entries */ getEntryCount() { return this.entryCount; } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2tyLmV4cG9ydC5sZWRnZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9za3IuZXhwb3J0LmxlZGdlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUN4QyxPQUFPLEtBQUssSUFBSSxNQUFNLE1BQU0sQ0FBQztBQUU3QixPQUFPLEVBQUUsaUJBQWlCLEVBQW9CLE1BQU0sSUFBSSxDQUFDO0FBcUV6RCxNQUFNLE9BQU8sY0FBYztJQUt6QixZQUFZLFVBQWtCO1FBSHRCLFdBQU0sR0FBdUIsSUFBSSxDQUFDO1FBQ2xDLGVBQVUsR0FBVyxDQUFDLENBQUM7UUFHN0IsSUFBSSxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUM7SUFDL0IsQ0FBQztJQUVEOztPQUVHO0lBQ0ksS0FBSyxDQUFDLFVBQVU7UUFDckIsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQUUsZUFBZSxDQUFDLENBQUM7UUFDckYsTUFBTSxPQUFPLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO1FBRS9ELElBQUksQ0FBQyxNQUFNLEdBQUcsaUJBQWlCLENBQUMsVUFBVSxFQUFFO1lBQzFDLFFBQVEsRUFBRSxNQUFNO1lBQ2hCLEtBQUssRUFBRSxHQUFHO1NBQ1gsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVEOztPQUVHO0lBQ0ksS0FBSyxDQUFDLGlCQUFpQixDQUFDLFdBQW1DO1FBQ2hFLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDakIsTUFBTSxJQUFJLEtBQUssQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFDO1FBQ3JELENBQUM7UUFFRCxNQUFNLEtBQUssR0FBaUI7WUFDMUIsY0FBYyxFQUFFLEtBQUs7WUFDckIsUUFBUSxFQUFFLFdBQVcsQ0FBQyxHQUFHLElBQUksT0FBTyxDQUFDLFdBQVcsQ0FBQyxPQUFPLEVBQUU7WUFDMUQsWUFBWSxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQztZQUMvQyxZQUFZLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxXQUFXLENBQUMsV0FBVyxJQUFJLFdBQVcsQ0FBQyxJQUFJLENBQUM7WUFDMUUsUUFBUSxFQUFFLFdBQVcsQ0FBQyxRQUFRLElBQUksS0FBSztZQUN2QyxPQUFPLEVBQUUsSUFBSTtZQUNiLFdBQVcsRUFBRSxXQUFXLENBQUMsV0FBVztZQUNwQyxTQUFTLEVBQUUsV0FBVyxDQUFDLFNBQVM7WUFDaEMsS0FBSyxFQUFFLEVBQUU7WUFDVCxVQUFVLEVBQUUsV0FBVyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsV0FBVyxDQUFDLFNBQVMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRTtZQUM1RyxXQUFXLEVBQUUsV0FBVyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsV0FBVyxDQUFDLFVBQVUsQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUMsQ0FBQyxTQUFTO1lBQ2hHLFdBQVcsRUFBRSxXQUFXLENBQUMsVUFBVTtZQUNuQyxXQUFXLEVBQUUsV0FBVyxDQUFDLFVBQVU7U0FDcEMsQ0FBQztRQUVGLGlCQUFpQjtRQUNqQixJQUFJLFdBQVcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDM0IsS0FBSyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUM7Z0JBQ2YsVUFBVSxFQUFFLEdBQUcsS0FBSyxDQUFDLFFBQVEsSUFBSTtnQkFDakMsWUFBWSxFQUFFLFdBQVcsQ0FBQyxZQUFZO2dCQUN0QyxLQUFLLEVBQUUsV0FBVyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO2dCQUNwQyxNQUFNLEVBQUUsTUFBTTtnQkFDZCxRQUFRLEVBQUUsV0FBVyxDQUFDLE9BQU87Z0JBQzdCLFdBQVcsRUFBRSxXQUFXLENBQUMsVUFBVTtnQkFDbkMsT0FBTyxFQUFFLFdBQVcsQ0FBQyxPQUFPO2FBQzdCLENBQUMsQ0FBQztZQUVILGtCQUFrQjtZQUNsQixLQUFLLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQztnQkFDZixVQUFVLEVBQUUsR0FBRyxLQUFLLENBQUMsUUFBUSxJQUFJO2dCQUNqQyxZQUFZLEVBQUUsV0FBVyxDQUFDLGFBQWE7Z0JBQ3ZDLEtBQUssRUFBRSxNQUFNO2dCQUNiLE1BQU0sRUFBRSxXQUFXLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7YUFDdEMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUVELDhCQUE4QjtRQUM5QixJQUFJLFdBQVcsQ0FBQyxTQUFTLElBQUksV0FBVyxDQUFDLFNBQVMsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN2RCxLQUFLLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQztnQkFDZixVQUFVLEVBQUUsR0FBRyxLQUFLLENBQUMsUUFBUSxJQUFJO2dCQUNqQyxZQUFZLEVBQUUsV0FBVyxDQUFDLFVBQVUsSUFBSSxNQUFNLEVBQUUsc0JBQXNCO2dCQUN0RSxLQUFLLEVBQUUsV0FBVyxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO2dCQUN2QyxNQUFNLEVBQUUsTUFBTTtnQkFDZCxXQUFXLEVBQUUsV0FBVzthQUN6QixDQUFDLENBQUM7UUFDTCxDQUFDO1FBRUQsTUFBTSxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzlCLENBQUM7SUFFRDs7T0FFRztJQUNJLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxZQUFpQztRQUMvRCxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ2pCLE1BQU0sSUFBSSxLQUFLLENBQUMsaUNBQWlDLENBQUMsQ0FBQztRQUNyRCxDQUFDO1FBRUQsTUFBTSxLQUFLLEdBQWlCO1lBQzFCLGNBQWMsRUFBRSxLQUFLO1lBQ3JCLFFBQVEsRUFBRSxZQUFZLENBQUMsR0FBRyxJQUFJLE9BQU8sQ0FBQyxXQUFXLENBQUMsT0FBTyxFQUFFO1lBQzNELFlBQVksRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUM7WUFDaEQsWUFBWSxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsWUFBWSxDQUFDLFdBQVcsSUFBSSxZQUFZLENBQUMsSUFBSSxDQUFDO1lBQzVFLFFBQVEsRUFBRSxZQUFZLENBQUMsUUFBUSxJQUFJLEtBQUs7WUFDeEMsT0FBTyxFQUFFLFlBQVksQ0FBQyxPQUFPLElBQUksSUFBSTtZQUNyQyxXQUFXLEVBQUUsWUFBWSxDQUFDLFdBQVc7WUFDckMsU0FBUyxFQUFFLFlBQVksQ0FBQyxTQUFTO1lBQ2pDLEtBQUssRUFBRSxFQUFFO1lBQ1QsVUFBVSxFQUFFLFlBQVksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLFlBQVksQ0FBQyxTQUFTLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQyxXQUFXLEVBQUU7WUFDOUcsV0FBVyxFQUFFLFlBQVksQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLFlBQVksQ0FBQyxVQUFVLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDLENBQUMsU0FBUztZQUNsRyxXQUFXLEVBQUUsWUFBWSxDQUFDLFVBQVU7WUFDcEMsV0FBVyxFQUFFLFlBQVksQ0FBQyxVQUFVO1NBQ3JDLENBQUM7UUFFRiw4QkFBOEI7UUFDOUIsWUFBWSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLEVBQUU7WUFDekMsTUFBTSxPQUFPLEdBQUcsSUFBK0IsQ0FBQztZQUNoRCxLQUFLLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQztnQkFDZixVQUFVLEVBQUUsR0FBRyxLQUFLLENBQUMsUUFBUSxJQUFJLEtBQUssR0FBRyxDQUFDLEVBQUU7Z0JBQzVDLFlBQVksRUFBRSxJQUFJLENBQUMsYUFBYTtnQkFDaEMsS0FBSyxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO2dCQUNuQyxNQUFNLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxJQUFJLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7Z0JBQ3JDLFFBQVEsRUFBRSxPQUFPLENBQUMsT0FBTztnQkFDekIsV0FBVyxFQUFFLElBQUksQ0FBQyxVQUFVO2dCQUM1QixPQUFPLEVBQUUsT0FBTyxDQUFDLE9BQU87Z0JBQ3hCLFdBQVcsRUFBRSxJQUFJLENBQUMsV0FBVzthQUM5QixDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztRQUVILE1BQU0sSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUM5QixDQUFDO0lBRUQ7O09BRUc7SUFDSyxLQUFLLENBQUMsU0FBUyxDQUFDLEtBQW1CO1FBQ3pDLE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7WUFDckMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDakIsTUFBTSxDQUFDLElBQUksS0FBSyxDQUFDLHdCQUF3QixDQUFDLENBQUMsQ0FBQztnQkFDNUMsT0FBTztZQUNULENBQUM7WUFFRCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxHQUFHLElBQUksQ0FBQztZQUMxQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxLQUFLLEVBQUUsRUFBRTtnQkFDaEMsSUFBSSxLQUFLLEVBQUUsQ0FBQztvQkFDVixNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQ2hCLENBQUM7cUJBQU0sQ0FBQztvQkFDTixJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7b0JBQ2xCLE9BQU8sRUFBRSxDQUFDO2dCQUNaLENBQUM7WUFDSCxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVEOztPQUVHO0lBQ0ssVUFBVSxDQUFDLElBQW1CO1FBQ3BDLElBQUksT0FBTyxJQUFJLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDN0IsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzVCLENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDMUMsQ0FBQztJQUVEOztPQUVHO0lBQ0ksS0FBSyxDQUFDLEtBQUs7UUFDaEIsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFO1lBQzdCLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUNoQixJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUU7b0JBQ25CLE9BQU8sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7Z0JBQzNCLENBQUMsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLE9BQU8sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDM0IsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVEOztPQUVHO0lBQ0ksYUFBYTtRQUNsQixPQUFPLElBQUksQ0FBQyxVQUFVLENBQUM7SUFDekIsQ0FBQztDQUNGIn0=