import { tap, expect } from '@git.zone/tstest/tapbundle'; import * as skr from '../ts/index.js'; let api: skr.SkrApi; tap.test('should initialize SKR04 API', async () => { api = new skr.SkrApi({ mongoDbUrl: 'mongodb://localhost:27017', dbName: 'test_skr04', }); await api.initialize('SKR04'); expect(api.getSKRType()).toEqual('SKR04'); }); tap.test('should have SKR04 accounts initialized', async () => { const accounts = await api.listAccounts(); expect(accounts.length).toBeGreaterThan(50); // Check specific SKR04 accounts exist const kasse = await api.getAccount('1000'); expect(kasse).not.toBeNull(); expect(kasse.accountName).toEqual('Kasse'); expect(kasse.accountType).toEqual('asset'); const umsatz = await api.getAccount('4000'); expect(umsatz).not.toBeNull(); expect(umsatz.accountName).toEqual('Umsatzerlöse'); expect(umsatz.accountType).toEqual('revenue'); }); tap.test('should verify SKR04 financial classification principle', async () => { // SKR04 organizes accounts by financial statement structure // Class 2: Expenses Part 1 // Class 3: Expenses Part 2 // Class 4: Revenues Part 1 // Class 5: Revenues Part 2 const class2 = await api.getAccountsByClass(2); expect(class2.length).toBeGreaterThan(0); expect(class2[0].accountType).toEqual('expense'); const class3 = await api.getAccountsByClass(3); expect(class3.length).toBeGreaterThan(0); expect(class3[0].accountType).toEqual('expense'); const class4 = await api.getAccountsByClass(4); expect(class4.length).toBeGreaterThan(0); expect(class4[0].accountType).toEqual('revenue'); const class5 = await api.getAccountsByClass(5); expect(class5.length).toBeGreaterThan(0); expect(class5[0].accountType).toEqual('revenue'); }); tap.test('should handle Class 8 as free for use in SKR04', async () => { // Class 8 in SKR04 is reserved for custom use const class8 = await api.getAccountsByClass(8); for (const account of class8) { expect(account.accountName).toEqual('frei'); expect(account.description).toInclude('custom use'); } }); tap.test('should post complex transaction in SKR04', async () => { const transaction = await api.postTransaction({ date: new Date(), debitAccount: '5400', // Goods with 19% VAT creditAccount: '1600', // Trade payables amount: 119, description: 'Purchase with VAT', reference: 'BILL-001', skrType: 'SKR04', vatAmount: 19, }); expect(transaction.status).toEqual('posted'); expect(transaction.vatAmount).toEqual(19); expect(transaction.skrType).toEqual('SKR04'); }); tap.test('should reverse transaction in SKR04', async () => { // First create a transaction const originalTransaction = await api.postTransaction({ date: new Date(), debitAccount: '3000', // Rent expense creditAccount: '1200', // Bank amount: 500, description: 'Rent payment', reference: 'RENT-001', skrType: 'SKR04', }); // Then reverse it const reversalTransaction = await api.reverseTransaction( originalTransaction.id, ); expect(reversalTransaction.reversalOf).toEqual(originalTransaction.id); expect(reversalTransaction.debitAccount).toEqual( originalTransaction.creditAccount, ); expect(reversalTransaction.creditAccount).toEqual( originalTransaction.debitAccount, ); expect(reversalTransaction.amount).toEqual(originalTransaction.amount); }); tap.test('should calculate correct balances in SKR04', async () => { // Post several transactions await api.postTransaction({ date: new Date(), debitAccount: '1200', // Bank creditAccount: '4300', // Revenue 19% VAT amount: 1190, description: 'Sale with VAT', skrType: 'SKR04', vatAmount: 190, }); await api.postTransaction({ date: new Date(), debitAccount: '2300', // Wages expense creditAccount: '1200', // Bank amount: 3000, description: 'Salary payment', skrType: 'SKR04', }); // Check bank account balance const bankBalance = await api.getAccountBalance('1200'); expect(bankBalance.accountNumber).toEqual('1200'); expect(bankBalance.balance).toEqual( bankBalance.debitTotal - bankBalance.creditTotal, ); }); tap.test('should export trial balance to CSV for SKR04', async () => { const csv = await api.exportReportToCSV('trial_balance'); expect(csv).toInclude( '"Account Number";"Account Name";"Debit";"Credit";"Balance"', ); expect(csv).toInclude('TOTAL'); }); tap.test('should handle pagination for SKR04 accounts', async () => { const page1 = await api.getAccountsPaginated(1, 10); expect(page1.data.length).toBeLessThanOrEqual(10); expect(page1.page).toEqual(1); expect(page1.pageSize).toEqual(10); expect(page1.total).toBeGreaterThan(50); expect(page1.totalPages).toBeGreaterThan(5); // Get second page const page2 = await api.getAccountsPaginated(2, 10); expect(page2.data[0].accountNumber).not.toEqual(page1.data[0].accountNumber); }); tap.test('should validate double-entry rules', async () => { const isValid1 = api.validateDoubleEntry(100, 100); expect(isValid1).toBeTrue(); const isValid2 = api.validateDoubleEntry(100, 99); expect(isValid2).toBeFalse(); const isValid3 = api.validateDoubleEntry(100.0, 100.001); expect(isValid3).toBeTrue(); // Small rounding differences are acceptable }); tap.test('should generate DATEV export for SKR04', async () => { const datevExport = await api.exportToDATEV(); expect(datevExport).toInclude('EXTF'); expect(datevExport).toInclude('Buchungsstapel'); }); tap.test('should close API connection', async () => { await api.close(); // Verify API requires reinitialization let errorThrown = false; try { await api.listAccounts(); } catch (error) { errorThrown = true; expect(error.message).toInclude('not initialized'); } expect(errorThrown).toBeTrue(); }); export default tap.start();