import * as plugins from './plugins.js'; import * as path from 'path'; import type { IAccountData, TSKRType } from './skr.types.js'; // Extended interface for export with additional fields export interface IAccountDataExport extends IAccountData { parentAccount?: string; defaultTaxCode?: string; activeFrom?: Date | string; activeTo?: Date | string; } export interface IAccountExportRow { account_code: string; name: string; type: string; class: number; parent?: string; skr_set: TSKRType; tax_code_default?: string; active_from?: string; active_to?: string; description?: string; is_active: boolean; } export class AccountsExporter { private exportPath: string; private accounts: IAccountExportRow[] = []; constructor(exportPath: string) { this.exportPath = exportPath; } /** * Adds an account to the export */ public addAccount(account: IAccountDataExport): void { const exportRow: IAccountExportRow = { account_code: account.accountNumber, name: account.accountName, type: account.accountType, class: account.accountClass, parent: account.parentAccount, skr_set: account.skrType, tax_code_default: account.defaultTaxCode, active_from: account.activeFrom ? this.formatDate(account.activeFrom) : undefined, active_to: account.activeTo ? this.formatDate(account.activeTo) : undefined, description: account.description, is_active: account.isActive !== false }; this.accounts.push(exportRow); } /** * Exports accounts to CSV format */ public async exportToCSV(): Promise { const csvPath = path.join(this.exportPath, 'data', 'accounting', 'accounts.csv'); await plugins.smartfile.fs.ensureDir(path.dirname(csvPath)); // Create CSV header const headers = [ 'account_code', 'name', 'type', 'class', 'parent', 'skr_set', 'tax_code_default', 'active_from', 'active_to', 'description', 'is_active' ]; let csvContent = headers.join(',') + '\n'; // Add account rows for (const account of this.accounts) { const row = [ this.escapeCSV(account.account_code), this.escapeCSV(account.name), this.escapeCSV(account.type), account.class.toString(), this.escapeCSV(account.parent || ''), this.escapeCSV(account.skr_set), this.escapeCSV(account.tax_code_default || ''), this.escapeCSV(account.active_from || ''), this.escapeCSV(account.active_to || ''), this.escapeCSV(account.description || ''), account.is_active.toString() ]; csvContent += row.join(',') + '\n'; } await plugins.smartfile.memory.toFs(csvContent, csvPath); } /** * Exports accounts to JSON format (alternative) */ public async exportToJSON(): Promise { const jsonPath = path.join(this.exportPath, 'data', 'accounting', 'accounts.json'); await plugins.smartfile.fs.ensureDir(path.dirname(jsonPath)); const jsonData = { schema_version: '1.0', export_date: new Date().toISOString(), accounts: this.accounts }; await plugins.smartfile.memory.toFs( JSON.stringify(jsonData, null, 2), jsonPath ); } /** * Escapes CSV values */ private escapeCSV(value: string): string { if (value.includes(',') || value.includes('"') || value.includes('\n')) { return `"${value.replace(/"/g, '""')}"`; } return value; } /** * Formats a date to ISO date string */ private formatDate(date: Date | string): string { if (typeof date === 'string') { return date.split('T')[0]; } return date.toISOString().split('T')[0]; } /** * Gets the number of accounts */ public getAccountCount(): number { return this.accounts.length; } /** * Clears the accounts list */ public clear(): void { this.accounts = []; } }