@fin.cx/skr 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/dist_ts/index.d.ts +10 -0
  2. package/dist_ts/index.js +11 -0
  3. package/dist_ts/plugins.d.ts +5 -0
  4. package/dist_ts/plugins.js +7 -0
  5. package/dist_ts/skr.api.d.ts +181 -0
  6. package/dist_ts/skr.api.js +402 -0
  7. package/dist_ts/skr.classes.account.d.ts +34 -0
  8. package/dist_ts/skr.classes.account.js +224 -0
  9. package/dist_ts/skr.classes.chartofaccounts.d.ts +99 -0
  10. package/dist_ts/skr.classes.chartofaccounts.js +377 -0
  11. package/dist_ts/skr.classes.journalentry.d.ts +33 -0
  12. package/dist_ts/skr.classes.journalentry.js +296 -0
  13. package/dist_ts/skr.classes.ledger.d.ts +61 -0
  14. package/dist_ts/skr.classes.ledger.js +363 -0
  15. package/dist_ts/skr.classes.reports.d.ts +55 -0
  16. package/dist_ts/skr.classes.reports.js +514 -0
  17. package/dist_ts/skr.classes.transaction.d.ts +37 -0
  18. package/dist_ts/skr.classes.transaction.js +263 -0
  19. package/dist_ts/skr.database.d.ts +5 -0
  20. package/dist_ts/skr.database.js +28 -0
  21. package/dist_ts/skr.types.d.ts +126 -0
  22. package/dist_ts/skr.types.js +2 -0
  23. package/dist_ts/skr03.data.d.ts +18 -0
  24. package/dist_ts/skr03.data.js +890 -0
  25. package/dist_ts/skr04.data.d.ts +18 -0
  26. package/dist_ts/skr04.data.js +912 -0
  27. package/npmextra.json +17 -0
  28. package/package.json +61 -0
  29. package/readme.hints.md +3 -0
  30. package/readme.md +409 -0
  31. package/readme.plan.md +243 -0
  32. package/ts/index.ts +10 -0
  33. package/ts/plugins.ts +7 -0
  34. package/ts/skr.api.ts +533 -0
  35. package/ts/skr.classes.account.ts +238 -0
  36. package/ts/skr.classes.chartofaccounts.ts +508 -0
  37. package/ts/skr.classes.journalentry.ts +318 -0
  38. package/ts/skr.classes.ledger.ts +528 -0
  39. package/ts/skr.classes.reports.ts +721 -0
  40. package/ts/skr.classes.transaction.ts +300 -0
  41. package/ts/skr.database.ts +39 -0
  42. package/ts/skr.types.ts +154 -0
  43. package/ts/skr03.data.ts +901 -0
  44. package/ts/skr04.data.ts +923 -0
@@ -0,0 +1,377 @@
1
+ import * as plugins from './plugins.js';
2
+ import { getDb, closeDb } from './skr.database.js';
3
+ import { Account } from './skr.classes.account.js';
4
+ import { Transaction } from './skr.classes.transaction.js';
5
+ import { JournalEntry } from './skr.classes.journalentry.js';
6
+ import { SKR03_ACCOUNTS, SKR03_ACCOUNT_CLASSES } from './skr03.data.js';
7
+ import { SKR04_ACCOUNTS, SKR04_ACCOUNT_CLASSES } from './skr04.data.js';
8
+ export class ChartOfAccounts {
9
+ constructor(config) {
10
+ this.config = config;
11
+ this.initialized = false;
12
+ this.skrType = null;
13
+ this.logger = new plugins.smartlog.Smartlog({
14
+ logContext: {
15
+ company: 'fin.cx',
16
+ companyunit: 'skr',
17
+ containerName: 'ChartOfAccounts',
18
+ environment: 'local',
19
+ runtime: 'node',
20
+ zone: 'local',
21
+ },
22
+ });
23
+ this.logger.enableConsole();
24
+ }
25
+ /**
26
+ * Initialize the database connection
27
+ */
28
+ async init() {
29
+ if (this.initialized) {
30
+ this.logger.log('info', 'ChartOfAccounts already initialized');
31
+ return;
32
+ }
33
+ if (!this.config) {
34
+ throw new Error('Database configuration required for initialization');
35
+ }
36
+ await getDb(this.config);
37
+ this.initialized = true;
38
+ this.logger.log('info', 'ChartOfAccounts initialized successfully');
39
+ }
40
+ /**
41
+ * Initialize SKR03 chart of accounts
42
+ */
43
+ async initializeSKR03() {
44
+ await this.init();
45
+ this.logger.log('info', 'Initializing SKR03 chart of accounts');
46
+ // Check if SKR03 accounts already exist
47
+ const existingAccounts = await Account.getInstances({ skrType: 'SKR03' });
48
+ if (existingAccounts.length > 0) {
49
+ this.logger.log('info', `SKR03 already initialized with ${existingAccounts.length} accounts`);
50
+ this.skrType = 'SKR03';
51
+ return;
52
+ }
53
+ // Create all SKR03 accounts
54
+ const accounts = [];
55
+ for (const accountData of SKR03_ACCOUNTS) {
56
+ const account = await Account.createAccount(accountData);
57
+ accounts.push(account);
58
+ }
59
+ this.skrType = 'SKR03';
60
+ this.logger.log('info', `Successfully initialized SKR03 with ${accounts.length} accounts`);
61
+ }
62
+ /**
63
+ * Initialize SKR04 chart of accounts
64
+ */
65
+ async initializeSKR04() {
66
+ await this.init();
67
+ this.logger.log('info', 'Initializing SKR04 chart of accounts');
68
+ // Check if SKR04 accounts already exist
69
+ const existingAccounts = await Account.getInstances({ skrType: 'SKR04' });
70
+ if (existingAccounts.length > 0) {
71
+ this.logger.log('info', `SKR04 already initialized with ${existingAccounts.length} accounts`);
72
+ this.skrType = 'SKR04';
73
+ return;
74
+ }
75
+ // Create all SKR04 accounts
76
+ const accounts = [];
77
+ for (const accountData of SKR04_ACCOUNTS) {
78
+ const account = await Account.createAccount(accountData);
79
+ accounts.push(account);
80
+ }
81
+ this.skrType = 'SKR04';
82
+ this.logger.log('info', `Successfully initialized SKR04 with ${accounts.length} accounts`);
83
+ }
84
+ /**
85
+ * Get the current SKR type
86
+ */
87
+ getSKRType() {
88
+ return this.skrType;
89
+ }
90
+ /**
91
+ * Set the active SKR type
92
+ */
93
+ setSKRType(skrType) {
94
+ this.skrType = skrType;
95
+ }
96
+ /**
97
+ * Get account by number
98
+ */
99
+ async getAccountByNumber(accountNumber) {
100
+ if (!this.skrType) {
101
+ throw new Error('SKR type not set. Initialize SKR03 or SKR04 first.');
102
+ }
103
+ return await Account.getAccountByNumber(accountNumber, this.skrType);
104
+ }
105
+ /**
106
+ * Get accounts by class
107
+ */
108
+ async getAccountsByClass(accountClass) {
109
+ if (!this.skrType) {
110
+ throw new Error('SKR type not set. Initialize SKR03 or SKR04 first.');
111
+ }
112
+ return await Account.getAccountsByClass(accountClass, this.skrType);
113
+ }
114
+ /**
115
+ * Get accounts by type
116
+ */
117
+ async getAccountsByType(accountType) {
118
+ if (!this.skrType) {
119
+ throw new Error('SKR type not set. Initialize SKR03 or SKR04 first.');
120
+ }
121
+ return await Account.getAccountsByType(accountType, this.skrType);
122
+ }
123
+ /**
124
+ * Create a custom account
125
+ */
126
+ async createCustomAccount(accountData) {
127
+ if (!this.skrType) {
128
+ throw new Error('SKR type not set. Initialize SKR03 or SKR04 first.');
129
+ }
130
+ // Ensure the account uses the current SKR type
131
+ const fullAccountData = {
132
+ accountNumber: accountData.accountNumber || '',
133
+ accountName: accountData.accountName || '',
134
+ accountClass: accountData.accountClass || 0,
135
+ accountType: accountData.accountType || 'asset',
136
+ skrType: this.skrType,
137
+ description: accountData.description,
138
+ vatRate: accountData.vatRate,
139
+ isActive: accountData.isActive !== undefined ? accountData.isActive : true,
140
+ };
141
+ // Validate account number doesn't already exist
142
+ const existing = await this.getAccountByNumber(fullAccountData.accountNumber);
143
+ if (existing) {
144
+ throw new Error(`Account ${fullAccountData.accountNumber} already exists`);
145
+ }
146
+ return await Account.createAccount(fullAccountData);
147
+ }
148
+ /**
149
+ * Update an existing account
150
+ */
151
+ async updateAccount(accountNumber, updates) {
152
+ const account = await this.getAccountByNumber(accountNumber);
153
+ if (!account) {
154
+ throw new Error(`Account ${accountNumber} not found`);
155
+ }
156
+ // Apply updates
157
+ if (updates.accountName !== undefined)
158
+ account.accountName = updates.accountName;
159
+ if (updates.description !== undefined)
160
+ account.description = updates.description;
161
+ if (updates.vatRate !== undefined)
162
+ account.vatRate = updates.vatRate;
163
+ if (updates.isActive !== undefined)
164
+ account.isActive = updates.isActive;
165
+ account.updatedAt = new Date();
166
+ await account.save();
167
+ return account;
168
+ }
169
+ /**
170
+ * Delete a custom account (only non-system accounts)
171
+ */
172
+ async deleteAccount(accountNumber) {
173
+ const account = await this.getAccountByNumber(accountNumber);
174
+ if (!account) {
175
+ throw new Error(`Account ${accountNumber} not found`);
176
+ }
177
+ if (account.isSystemAccount) {
178
+ throw new Error(`Cannot delete system account ${accountNumber}`);
179
+ }
180
+ // Check if account has transactions
181
+ const transactions = await Transaction.getTransactionsByAccount(accountNumber, account.skrType);
182
+ if (transactions.length > 0) {
183
+ throw new Error(`Cannot delete account ${accountNumber} with existing transactions`);
184
+ }
185
+ await account.delete();
186
+ }
187
+ /**
188
+ * Search accounts
189
+ */
190
+ async searchAccounts(searchTerm) {
191
+ return await Account.searchAccounts(searchTerm, this.skrType);
192
+ }
193
+ /**
194
+ * Get all accounts
195
+ */
196
+ async getAllAccounts(filter) {
197
+ const query = {};
198
+ if (this.skrType) {
199
+ query.skrType = this.skrType;
200
+ }
201
+ if (filter) {
202
+ if (filter.accountClass !== undefined)
203
+ query.accountClass = filter.accountClass;
204
+ if (filter.accountType !== undefined)
205
+ query.accountType = filter.accountType;
206
+ if (filter.isActive !== undefined)
207
+ query.isActive = filter.isActive;
208
+ }
209
+ const accounts = await Account.getInstances(query);
210
+ // Apply text search if provided
211
+ if (filter?.searchTerm) {
212
+ const lowerSearchTerm = filter.searchTerm.toLowerCase();
213
+ return accounts.filter((account) => account.accountNumber.includes(filter.searchTerm) ||
214
+ account.accountName.toLowerCase().includes(lowerSearchTerm) ||
215
+ account.description.toLowerCase().includes(lowerSearchTerm));
216
+ }
217
+ return accounts;
218
+ }
219
+ /**
220
+ * Post a simple transaction
221
+ */
222
+ async postTransaction(transactionData) {
223
+ if (!this.skrType) {
224
+ throw new Error('SKR type not set. Initialize SKR03 or SKR04 first.');
225
+ }
226
+ // Ensure the transaction uses the current SKR type
227
+ const fullTransactionData = {
228
+ ...transactionData,
229
+ skrType: this.skrType,
230
+ };
231
+ return await Transaction.createTransaction(fullTransactionData);
232
+ }
233
+ /**
234
+ * Post a journal entry
235
+ */
236
+ async postJournalEntry(journalData) {
237
+ if (!this.skrType) {
238
+ throw new Error('SKR type not set. Initialize SKR03 or SKR04 first.');
239
+ }
240
+ // Ensure the journal entry uses the current SKR type
241
+ const fullJournalData = {
242
+ ...journalData,
243
+ skrType: this.skrType,
244
+ };
245
+ const journalEntry = await JournalEntry.createJournalEntry(fullJournalData);
246
+ await journalEntry.post();
247
+ return journalEntry;
248
+ }
249
+ /**
250
+ * Get transactions for an account
251
+ */
252
+ async getAccountTransactions(accountNumber) {
253
+ if (!this.skrType) {
254
+ throw new Error('SKR type not set. Initialize SKR03 or SKR04 first.');
255
+ }
256
+ return await Transaction.getTransactionsByAccount(accountNumber, this.skrType);
257
+ }
258
+ /**
259
+ * Get transactions by filter
260
+ */
261
+ async getTransactions(filter) {
262
+ if (!this.skrType) {
263
+ throw new Error('SKR type not set. Initialize SKR03 or SKR04 first.');
264
+ }
265
+ const query = {
266
+ skrType: this.skrType,
267
+ status: 'posted',
268
+ };
269
+ if (filter) {
270
+ if (filter.dateFrom || filter.dateTo) {
271
+ query.date = {};
272
+ if (filter.dateFrom)
273
+ query.date.$gte = filter.dateFrom;
274
+ if (filter.dateTo)
275
+ query.date.$lte = filter.dateTo;
276
+ }
277
+ if (filter.accountNumber) {
278
+ query.$or = [
279
+ { debitAccount: filter.accountNumber },
280
+ { creditAccount: filter.accountNumber },
281
+ ];
282
+ }
283
+ if (filter.minAmount || filter.maxAmount) {
284
+ query.amount = {};
285
+ if (filter.minAmount)
286
+ query.amount.$gte = filter.minAmount;
287
+ if (filter.maxAmount)
288
+ query.amount.$lte = filter.maxAmount;
289
+ }
290
+ }
291
+ const transactions = await Transaction.getInstances(query);
292
+ // Apply text search if provided
293
+ if (filter?.searchTerm) {
294
+ const lowerSearchTerm = filter.searchTerm.toLowerCase();
295
+ return transactions.filter((transaction) => transaction.description.toLowerCase().includes(lowerSearchTerm) ||
296
+ transaction.reference.toLowerCase().includes(lowerSearchTerm));
297
+ }
298
+ return transactions;
299
+ }
300
+ /**
301
+ * Reverse a transaction
302
+ */
303
+ async reverseTransaction(transactionId) {
304
+ const transaction = await Transaction.getTransactionById(transactionId);
305
+ if (!transaction) {
306
+ throw new Error(`Transaction ${transactionId} not found`);
307
+ }
308
+ return await transaction.reverseTransaction();
309
+ }
310
+ /**
311
+ * Get account class description
312
+ */
313
+ getAccountClassDescription(accountClass) {
314
+ if (!this.skrType) {
315
+ throw new Error('SKR type not set. Initialize SKR03 or SKR04 first.');
316
+ }
317
+ const classes = this.skrType === 'SKR03' ? SKR03_ACCOUNT_CLASSES : SKR04_ACCOUNT_CLASSES;
318
+ return (classes[accountClass] || `Class ${accountClass}`);
319
+ }
320
+ /**
321
+ * Import accounts from CSV
322
+ */
323
+ async importAccountsFromCSV(csvContent) {
324
+ if (!this.skrType) {
325
+ throw new Error('SKR type not set. Initialize SKR03 or SKR04 first.');
326
+ }
327
+ const lines = csvContent.split('\n').filter((line) => line.trim());
328
+ let importedCount = 0;
329
+ for (const line of lines) {
330
+ // Parse CSV line (expecting format: "account";"name";"description";"type";"active")
331
+ const parts = line
332
+ .split(';')
333
+ .map((part) => part.replace(/"/g, '').trim());
334
+ if (parts.length >= 5) {
335
+ const accountData = {
336
+ accountNumber: parts[0],
337
+ accountName: parts[1],
338
+ accountClass: parseInt(parts[0][0]),
339
+ accountType: parts[3],
340
+ skrType: this.skrType,
341
+ description: parts[2],
342
+ isActive: parts[4].toLowerCase() === 'standard' ||
343
+ parts[4].toLowerCase() === 'active',
344
+ };
345
+ try {
346
+ await this.createCustomAccount(accountData);
347
+ importedCount++;
348
+ }
349
+ catch (error) {
350
+ this.logger.log('warn', `Failed to import account ${parts[0]}: ${error.message}`);
351
+ }
352
+ }
353
+ }
354
+ return importedCount;
355
+ }
356
+ /**
357
+ * Export accounts to CSV
358
+ */
359
+ async exportAccountsToCSV() {
360
+ const accounts = await this.getAllAccounts();
361
+ const csvLines = [];
362
+ csvLines.push('"Account";"Name";"Description";"Type";"Active"');
363
+ for (const account of accounts) {
364
+ csvLines.push(`"${account.accountNumber}";"${account.accountName}";"${account.description}";"${account.accountType}";"${account.isActive ? 'Active' : 'Inactive'}"`);
365
+ }
366
+ return csvLines.join('\n');
367
+ }
368
+ /**
369
+ * Close the database connection
370
+ */
371
+ async close() {
372
+ await closeDb();
373
+ this.initialized = false;
374
+ this.logger.log('info', 'ChartOfAccounts closed');
375
+ }
376
+ }
377
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2tyLmNsYXNzZXMuY2hhcnRvZmFjY291bnRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvc2tyLmNsYXNzZXMuY2hhcnRvZmFjY291bnRzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBQ3hDLE9BQU8sRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDbkQsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ25ELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDN0QsT0FBTyxFQUFFLGNBQWMsRUFBRSxxQkFBcUIsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3hFLE9BQU8sRUFBRSxjQUFjLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQVd4RSxNQUFNLE9BQU8sZUFBZTtJQUsxQixZQUFvQixNQUF3QjtRQUF4QixXQUFNLEdBQU4sTUFBTSxDQUFrQjtRQUhwQyxnQkFBVyxHQUFZLEtBQUssQ0FBQztRQUM3QixZQUFPLEdBQW9CLElBQUksQ0FBQztRQUd0QyxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksT0FBTyxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUM7WUFDMUMsVUFBVSxFQUFFO2dCQUNWLE9BQU8sRUFBRSxRQUFRO2dCQUNqQixXQUFXLEVBQUUsS0FBSztnQkFDbEIsYUFBYSxFQUFFLGlCQUFpQjtnQkFDaEMsV0FBVyxFQUFFLE9BQU87Z0JBQ3BCLE9BQU8sRUFBRSxNQUFNO2dCQUNmLElBQUksRUFBRSxPQUFPO2FBQ2Q7U0FDRixDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsRUFBRSxDQUFDO0lBQzlCLENBQUM7SUFFRDs7T0FFRztJQUNJLEtBQUssQ0FBQyxJQUFJ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
@@ -0,0 +1,33 @@
1
+ import * as plugins from './plugins.js';
2
+ import type { TSKRType, IJournalEntry, IJournalEntryLine } from './skr.types.js';
3
+ declare const SmartDataDbDoc: typeof plugins.smartdata.SmartDataDbDoc;
4
+ export declare class JournalEntry extends SmartDataDbDoc<JournalEntry, JournalEntry> {
5
+ id: string;
6
+ journalNumber: string;
7
+ date: Date;
8
+ description: string;
9
+ reference: string;
10
+ lines: IJournalEntryLine[];
11
+ skrType: TSKRType;
12
+ totalDebits: number;
13
+ totalCredits: number;
14
+ isBalanced: boolean;
15
+ status: 'draft' | 'posted' | 'reversed';
16
+ transactionIds: string[];
17
+ period: string;
18
+ fiscalYear: number;
19
+ createdAt: Date;
20
+ postedAt: Date;
21
+ createdBy: string;
22
+ constructor(data?: Partial<IJournalEntry>);
23
+ private generateJournalNumber;
24
+ private calculateTotals;
25
+ static createJournalEntry(data: IJournalEntry): Promise<JournalEntry>;
26
+ addLine(line: IJournalEntryLine): void;
27
+ removeLine(index: number): void;
28
+ validate(): Promise<void>;
29
+ post(): Promise<void>;
30
+ reverse(): Promise<JournalEntry>;
31
+ beforeSave(): Promise<void>;
32
+ }
33
+ export {};