@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.
- package/dist_ts/index.d.ts +10 -0
- package/dist_ts/index.js +11 -0
- package/dist_ts/plugins.d.ts +5 -0
- package/dist_ts/plugins.js +7 -0
- package/dist_ts/skr.api.d.ts +181 -0
- package/dist_ts/skr.api.js +402 -0
- package/dist_ts/skr.classes.account.d.ts +34 -0
- package/dist_ts/skr.classes.account.js +224 -0
- package/dist_ts/skr.classes.chartofaccounts.d.ts +99 -0
- package/dist_ts/skr.classes.chartofaccounts.js +377 -0
- package/dist_ts/skr.classes.journalentry.d.ts +33 -0
- package/dist_ts/skr.classes.journalentry.js +296 -0
- package/dist_ts/skr.classes.ledger.d.ts +61 -0
- package/dist_ts/skr.classes.ledger.js +363 -0
- package/dist_ts/skr.classes.reports.d.ts +55 -0
- package/dist_ts/skr.classes.reports.js +514 -0
- package/dist_ts/skr.classes.transaction.d.ts +37 -0
- package/dist_ts/skr.classes.transaction.js +263 -0
- package/dist_ts/skr.database.d.ts +5 -0
- package/dist_ts/skr.database.js +28 -0
- package/dist_ts/skr.types.d.ts +126 -0
- package/dist_ts/skr.types.js +2 -0
- package/dist_ts/skr03.data.d.ts +18 -0
- package/dist_ts/skr03.data.js +890 -0
- package/dist_ts/skr04.data.d.ts +18 -0
- package/dist_ts/skr04.data.js +912 -0
- package/npmextra.json +17 -0
- package/package.json +61 -0
- package/readme.hints.md +3 -0
- package/readme.md +409 -0
- package/readme.plan.md +243 -0
- package/ts/index.ts +10 -0
- package/ts/plugins.ts +7 -0
- package/ts/skr.api.ts +533 -0
- package/ts/skr.classes.account.ts +238 -0
- package/ts/skr.classes.chartofaccounts.ts +508 -0
- package/ts/skr.classes.journalentry.ts +318 -0
- package/ts/skr.classes.ledger.ts +528 -0
- package/ts/skr.classes.reports.ts +721 -0
- package/ts/skr.classes.transaction.ts +300 -0
- package/ts/skr.database.ts +39 -0
- package/ts/skr.types.ts +154 -0
- package/ts/skr03.data.ts +901 -0
- 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 {};
|