@fin.cx/skr 1.2.1 → 1.2.2
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/{npmextra.json → .smartconfig.json} +12 -6
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/index.d.ts +21 -15
- package/dist_ts/index.js +16 -16
- package/dist_ts/plugins.d.ts +15 -5
- package/dist_ts/plugins.js +42 -6
- package/dist_ts/skr.api.js +20 -13
- package/dist_ts/skr.classes.account.d.ts +8 -3
- package/dist_ts/skr.classes.account.js +358 -285
- package/dist_ts/skr.classes.chartofaccounts.d.ts +1 -1
- package/dist_ts/skr.classes.chartofaccounts.js +13 -6
- package/dist_ts/skr.classes.journalentry.d.ts +9 -4
- package/dist_ts/skr.classes.journalentry.js +424 -355
- package/dist_ts/skr.classes.ledger.js +3 -1
- package/dist_ts/skr.classes.reports.js +4 -1
- package/dist_ts/skr.classes.transaction.d.ts +9 -4
- package/dist_ts/skr.classes.transaction.js +315 -244
- package/dist_ts/skr.export.accounts.js +3 -2
- package/dist_ts/skr.export.balances.js +4 -2
- package/dist_ts/skr.export.js +6 -3
- package/dist_ts/skr.export.ledger.js +4 -3
- package/dist_ts/skr.export.pdf.js +6 -3
- package/dist_ts/skr.invoice.adapter.d.ts +2 -0
- package/dist_ts/skr.invoice.adapter.js +22 -10
- package/dist_ts/skr.invoice.booking.js +8 -3
- package/dist_ts/skr.invoice.mapper.js +84 -82
- package/dist_ts/skr.invoice.storage.js +10 -5
- package/dist_ts/skr.security.js +24 -21
- package/license.md +21 -0
- package/package.json +31 -23
- package/readme.md +215 -632
- package/readme.plan.md +1 -1
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/index.ts +43 -15
- package/ts/plugins.ts +52 -15
- package/ts/skr.api.ts +9 -5
- package/ts/skr.classes.account.ts +39 -21
- package/ts/skr.classes.chartofaccounts.ts +8 -3
- package/ts/skr.classes.journalentry.ts +40 -22
- package/ts/skr.classes.reports.ts +22 -2
- package/ts/skr.classes.transaction.ts +40 -22
- package/ts/skr.export.pdf.ts +4 -3
- package/ts/skr.invoice.adapter.ts +31 -11
- package/ts/skr.invoice.booking.ts +5 -3
- package/ts/skr.invoice.storage.ts +3 -2
- package/ts/skr.security.ts +23 -22
package/readme.plan.md
CHANGED
|
@@ -18,7 +18,7 @@ TypeScript module implementing SKR03 and SKR04 German accounting standards for d
|
|
|
18
18
|
- [ ] @push.rocks/smartdata
|
|
19
19
|
- [ ] @git.zone/tstest (dev dependency)
|
|
20
20
|
- [ ] Create tsconfig.json based on @push.rocks/smarthash pattern
|
|
21
|
-
- [ ] Create
|
|
21
|
+
- [ ] Create .smartconfig.json for additional configuration
|
|
22
22
|
- [ ] Create .gitignore file
|
|
23
23
|
- [ ] Create directory structure
|
|
24
24
|
- [ ] ts/ directory for source code
|
package/ts/00_commitinfo_data.ts
CHANGED
package/ts/index.ts
CHANGED
|
@@ -1,16 +1,44 @@
|
|
|
1
1
|
export * from './skr.types.js';
|
|
2
|
-
export
|
|
3
|
-
export
|
|
4
|
-
export
|
|
5
|
-
export
|
|
6
|
-
export
|
|
7
|
-
export
|
|
8
|
-
export
|
|
9
|
-
export
|
|
10
|
-
export
|
|
11
|
-
export
|
|
12
|
-
export
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
2
|
+
export { Account } from './skr.classes.account.js';
|
|
3
|
+
export { Transaction } from './skr.classes.transaction.js';
|
|
4
|
+
export { JournalEntry } from './skr.classes.journalentry.js';
|
|
5
|
+
export { ChartOfAccounts } from './skr.classes.chartofaccounts.js';
|
|
6
|
+
export { Ledger } from './skr.classes.ledger.js';
|
|
7
|
+
export { Reports } from './skr.classes.reports.js';
|
|
8
|
+
export { SkrApi } from './skr.api.js';
|
|
9
|
+
export { SKR03_ACCOUNTS, SKR03_ACCOUNT_CLASSES } from './skr03.data.js';
|
|
10
|
+
export { SKR04_ACCOUNTS, SKR04_ACCOUNT_CLASSES } from './skr04.data.js';
|
|
11
|
+
export { SkrExport } from './skr.export.js';
|
|
12
|
+
export type {
|
|
13
|
+
IExportOptions,
|
|
14
|
+
IExportMetadata,
|
|
15
|
+
IBagItManifest,
|
|
16
|
+
IDocumentIndex,
|
|
17
|
+
} from './skr.export.js';
|
|
18
|
+
export { LedgerExporter } from './skr.export.ledger.js';
|
|
19
|
+
export type {
|
|
20
|
+
ITransactionDataExport,
|
|
21
|
+
IJournalEntryExport,
|
|
22
|
+
IJournalEntryLineExport,
|
|
23
|
+
ILedgerEntry,
|
|
24
|
+
ILedgerLine,
|
|
25
|
+
IDocumentRef,
|
|
26
|
+
} from './skr.export.ledger.js';
|
|
27
|
+
export { AccountsExporter } from './skr.export.accounts.js';
|
|
28
|
+
export type {
|
|
29
|
+
IAccountDataExport,
|
|
30
|
+
IAccountExportRow,
|
|
31
|
+
} from './skr.export.accounts.js';
|
|
32
|
+
export { BalancesExporter } from './skr.export.balances.js';
|
|
33
|
+
export type {
|
|
34
|
+
IAccountBalanceExport,
|
|
35
|
+
IBalanceExportRow,
|
|
36
|
+
} from './skr.export.balances.js';
|
|
37
|
+
export { PdfReportGenerator } from './skr.export.pdf.js';
|
|
38
|
+
export type { IPdfReportOptions } from './skr.export.pdf.js';
|
|
39
|
+
export { SecurityManager } from './skr.security.js';
|
|
40
|
+
export type {
|
|
41
|
+
ISigningOptions,
|
|
42
|
+
ISignatureResult,
|
|
43
|
+
ITimestampResponse,
|
|
44
|
+
} from './skr.security.js';
|
package/ts/plugins.ts
CHANGED
|
@@ -3,26 +3,63 @@ import * as smartdata from '@push.rocks/smartdata';
|
|
|
3
3
|
import * as smartunique from '@push.rocks/smartunique';
|
|
4
4
|
import * as smarttime from '@push.rocks/smarttime';
|
|
5
5
|
import * as smartlog from '@push.rocks/smartlog';
|
|
6
|
-
import * as
|
|
6
|
+
import * as smartfsModule from '@push.rocks/smartfs';
|
|
7
7
|
import * as smarthash from '@push.rocks/smarthash';
|
|
8
8
|
import * as smartpath from '@push.rocks/smartpath';
|
|
9
|
-
import * as
|
|
9
|
+
import * as path from 'path';
|
|
10
10
|
|
|
11
11
|
// third party
|
|
12
|
-
import * as nodeForge from 'node-forge';
|
|
13
12
|
import { MerkleTree } from 'merkletreejs';
|
|
14
|
-
import * as einvoice from '@fin.cx/einvoice';
|
|
15
13
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
14
|
+
const smartfs = new smartfsModule.SmartFs(
|
|
15
|
+
new smartfsModule.SmartFsProviderNode(),
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
const smartfile = {
|
|
19
|
+
fs: {
|
|
20
|
+
ensureDir: async (dirPath: string): Promise<void> => {
|
|
21
|
+
await smartfs.directory(dirPath).create();
|
|
22
|
+
},
|
|
23
|
+
toBuffer: async (filePath: string): Promise<Buffer> => {
|
|
24
|
+
return (await smartfs.file(filePath).read()) as Buffer;
|
|
25
|
+
},
|
|
26
|
+
toStringSync: async (filePath: string): Promise<string> => {
|
|
27
|
+
return (await smartfs.file(filePath).encoding('utf8').read()) as string;
|
|
28
|
+
},
|
|
29
|
+
fileExists: async (filePath: string): Promise<boolean> => {
|
|
30
|
+
return await smartfs.file(filePath).exists();
|
|
31
|
+
},
|
|
32
|
+
listFileTree: async (dirPath: string, pattern: string): Promise<string[]> => {
|
|
33
|
+
const suffix = pattern.replace(/^\*\*\/\*/, '');
|
|
34
|
+
try {
|
|
35
|
+
const entries = await smartfs.directory(dirPath).recursive().list();
|
|
36
|
+
return entries
|
|
37
|
+
.filter((entry) => entry.isFile && entry.path.endsWith(suffix))
|
|
38
|
+
.map((entry) => path.relative(dirPath, entry.path));
|
|
39
|
+
} catch (error) {
|
|
40
|
+
if (error instanceof Error && error.message.includes('ENOENT')) {
|
|
41
|
+
return [];
|
|
42
|
+
}
|
|
43
|
+
throw error;
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
memory: {
|
|
48
|
+
toFs: async (content: string | Buffer, filePath: string): Promise<void> => {
|
|
49
|
+
await smartfs.directory(path.dirname(filePath)).create();
|
|
50
|
+
await smartfs.file(filePath).write(content);
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export {
|
|
56
|
+
smartdata,
|
|
57
|
+
smartunique,
|
|
58
|
+
smarttime,
|
|
59
|
+
smartlog,
|
|
60
|
+
smartfs,
|
|
61
|
+
smartfile,
|
|
62
|
+
smarthash,
|
|
63
|
+
smartpath,
|
|
26
64
|
MerkleTree,
|
|
27
|
-
einvoice
|
|
28
65
|
};
|
package/ts/skr.api.ts
CHANGED
|
@@ -534,6 +534,10 @@ export class SkrApi {
|
|
|
534
534
|
*/
|
|
535
535
|
private async generatePdfReports(exporter: SkrExport, options: IExportOptions): Promise<void> {
|
|
536
536
|
if (!this.reports) throw new Error('Reports not initialized');
|
|
537
|
+
const skrType = this.currentSKRType;
|
|
538
|
+
if (!skrType) {
|
|
539
|
+
throw new Error('API not initialized. Call initialize() first.');
|
|
540
|
+
}
|
|
537
541
|
|
|
538
542
|
const pdfOptions: IPdfReportOptions = {
|
|
539
543
|
companyName: options.companyInfo?.name || 'Unternehmen',
|
|
@@ -554,19 +558,19 @@ export class SkrApi {
|
|
|
554
558
|
const trialBalance = await this.reports.getTrialBalance({
|
|
555
559
|
dateFrom: options.dateFrom,
|
|
556
560
|
dateTo: options.dateTo,
|
|
557
|
-
skrType
|
|
561
|
+
skrType,
|
|
558
562
|
});
|
|
559
563
|
|
|
560
564
|
const incomeStatement = await this.reports.getIncomeStatement({
|
|
561
565
|
dateFrom: options.dateFrom,
|
|
562
566
|
dateTo: options.dateTo,
|
|
563
|
-
skrType
|
|
567
|
+
skrType,
|
|
564
568
|
});
|
|
565
569
|
|
|
566
570
|
const balanceSheet = await this.reports.getBalanceSheet({
|
|
567
571
|
dateFrom: options.dateFrom,
|
|
568
572
|
dateTo: options.dateTo,
|
|
569
|
-
skrType
|
|
573
|
+
skrType,
|
|
570
574
|
});
|
|
571
575
|
|
|
572
576
|
// Generate PDFs
|
|
@@ -702,7 +706,7 @@ export class SkrApi {
|
|
|
702
706
|
const transaction = await this.postTransaction(transactions[i]);
|
|
703
707
|
results.push(transaction);
|
|
704
708
|
} catch (error) {
|
|
705
|
-
errors.push({ index: i, error: error.message });
|
|
709
|
+
errors.push({ index: i, error: error instanceof Error ? error.message : String(error) });
|
|
706
710
|
}
|
|
707
711
|
}
|
|
708
712
|
|
|
@@ -735,7 +739,7 @@ export class SkrApi {
|
|
|
735
739
|
const account = await this.createAccount(accounts[i]);
|
|
736
740
|
results.push(account);
|
|
737
741
|
} catch (error) {
|
|
738
|
-
errors.push({ index: i, error: error.message });
|
|
742
|
+
errors.push({ index: i, error: error instanceof Error ? error.message : String(error) });
|
|
739
743
|
}
|
|
740
744
|
}
|
|
741
745
|
|
|
@@ -2,68 +2,86 @@ import * as plugins from './plugins.js';
|
|
|
2
2
|
import { getDb, getDbSync } from './skr.database.js';
|
|
3
3
|
import type { TAccountType, TSKRType, IAccountData } from './skr.types.js';
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
declare abstract class SmartDataDbDocBase {
|
|
6
|
+
public save(): Promise<void>;
|
|
7
|
+
public delete(): Promise<void>;
|
|
8
|
+
public static getInstance<T>(
|
|
9
|
+
this: new (...args: any[]) => T,
|
|
10
|
+
query: Record<string, any>,
|
|
11
|
+
): Promise<T | null>;
|
|
12
|
+
public static getInstances<T>(
|
|
13
|
+
this: new (...args: any[]) => T,
|
|
14
|
+
query: Record<string, any>,
|
|
15
|
+
): Promise<T[]>;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const SmartDataDbDoc = plugins.smartdata.SmartDataDbDoc as unknown as typeof SmartDataDbDocBase;
|
|
19
|
+
const Collection = plugins.smartdata.Collection as any;
|
|
20
|
+
const svDb = plugins.smartdata.svDb as any;
|
|
21
|
+
const unI = plugins.smartdata.unI as any;
|
|
22
|
+
const index = plugins.smartdata.index as any;
|
|
23
|
+
const searchable = plugins.smartdata.searchable as any;
|
|
6
24
|
|
|
7
|
-
@
|
|
8
|
-
export class Account extends SmartDataDbDoc
|
|
25
|
+
@Collection(() => getDbSync())
|
|
26
|
+
export class Account extends SmartDataDbDoc {
|
|
9
27
|
@unI()
|
|
10
|
-
public id
|
|
28
|
+
public id!: string;
|
|
11
29
|
|
|
12
30
|
@svDb()
|
|
13
31
|
@index()
|
|
14
|
-
public accountNumber
|
|
32
|
+
public accountNumber!: string;
|
|
15
33
|
|
|
16
34
|
@svDb()
|
|
17
35
|
@searchable()
|
|
18
|
-
public accountName
|
|
36
|
+
public accountName!: string;
|
|
19
37
|
|
|
20
38
|
@svDb()
|
|
21
39
|
@index()
|
|
22
|
-
public accountClass
|
|
40
|
+
public accountClass!: number;
|
|
23
41
|
|
|
24
42
|
@svDb()
|
|
25
|
-
public accountGroup
|
|
43
|
+
public accountGroup!: number;
|
|
26
44
|
|
|
27
45
|
@svDb()
|
|
28
|
-
public accountSubgroup
|
|
46
|
+
public accountSubgroup!: number;
|
|
29
47
|
|
|
30
48
|
@svDb()
|
|
31
|
-
public accountType
|
|
49
|
+
public accountType!: TAccountType;
|
|
32
50
|
|
|
33
51
|
@svDb()
|
|
34
52
|
@index()
|
|
35
|
-
public skrType
|
|
53
|
+
public skrType!: TSKRType;
|
|
36
54
|
|
|
37
55
|
@svDb()
|
|
38
56
|
@searchable()
|
|
39
|
-
public description
|
|
57
|
+
public description!: string;
|
|
40
58
|
|
|
41
59
|
@svDb()
|
|
42
|
-
public vatRate
|
|
60
|
+
public vatRate!: number;
|
|
43
61
|
|
|
44
62
|
@svDb()
|
|
45
|
-
public balance
|
|
63
|
+
public balance!: number;
|
|
46
64
|
|
|
47
65
|
@svDb()
|
|
48
|
-
public debitTotal
|
|
66
|
+
public debitTotal!: number;
|
|
49
67
|
|
|
50
68
|
@svDb()
|
|
51
|
-
public creditTotal
|
|
69
|
+
public creditTotal!: number;
|
|
52
70
|
|
|
53
71
|
@svDb()
|
|
54
|
-
public isActive
|
|
72
|
+
public isActive!: boolean;
|
|
55
73
|
|
|
56
74
|
@svDb()
|
|
57
|
-
public isSystemAccount
|
|
75
|
+
public isSystemAccount!: boolean;
|
|
58
76
|
|
|
59
77
|
@svDb()
|
|
60
|
-
public isAutomaticAccount
|
|
78
|
+
public isAutomaticAccount!: boolean;
|
|
61
79
|
|
|
62
80
|
@svDb()
|
|
63
|
-
public createdAt
|
|
81
|
+
public createdAt!: Date;
|
|
64
82
|
|
|
65
83
|
@svDb()
|
|
66
|
-
public updatedAt
|
|
84
|
+
public updatedAt!: Date;
|
|
67
85
|
|
|
68
86
|
constructor(data?: Partial<IAccountData>) {
|
|
69
87
|
super();
|
|
@@ -262,6 +262,9 @@ export class ChartOfAccounts {
|
|
|
262
262
|
* Search accounts
|
|
263
263
|
*/
|
|
264
264
|
public async searchAccounts(searchTerm: string): Promise<Account[]> {
|
|
265
|
+
if (!this.skrType) {
|
|
266
|
+
throw new Error('SKR type not set. Initialize SKR03 or SKR04 first.');
|
|
267
|
+
}
|
|
265
268
|
return await Account.searchAccounts(searchTerm, this.skrType);
|
|
266
269
|
}
|
|
267
270
|
|
|
@@ -287,10 +290,11 @@ export class ChartOfAccounts {
|
|
|
287
290
|
|
|
288
291
|
// Apply text search if provided
|
|
289
292
|
if (filter?.searchTerm) {
|
|
290
|
-
const
|
|
293
|
+
const searchTerm = filter.searchTerm;
|
|
294
|
+
const lowerSearchTerm = searchTerm.toLowerCase();
|
|
291
295
|
return accounts.filter(
|
|
292
296
|
(account) =>
|
|
293
|
-
account.accountNumber.includes(
|
|
297
|
+
account.accountNumber.includes(searchTerm) ||
|
|
294
298
|
account.accountName.toLowerCase().includes(lowerSearchTerm) ||
|
|
295
299
|
account.description.toLowerCase().includes(lowerSearchTerm),
|
|
296
300
|
);
|
|
@@ -468,9 +472,10 @@ export class ChartOfAccounts {
|
|
|
468
472
|
await this.createCustomAccount(accountData);
|
|
469
473
|
importedCount++;
|
|
470
474
|
} catch (error) {
|
|
475
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
471
476
|
this.logger.log(
|
|
472
477
|
'warn',
|
|
473
|
-
`Failed to import account ${parts[0]}: ${
|
|
478
|
+
`Failed to import account ${parts[0]}: ${errorMessage}`,
|
|
474
479
|
);
|
|
475
480
|
}
|
|
476
481
|
}
|
|
@@ -13,67 +13,85 @@ import type {
|
|
|
13
13
|
IJournalEntryLine,
|
|
14
14
|
} from './skr.types.js';
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
declare abstract class SmartDataDbDocBase {
|
|
17
|
+
public save(): Promise<void>;
|
|
18
|
+
public delete(): Promise<void>;
|
|
19
|
+
public static getInstance<T>(
|
|
20
|
+
this: new (...args: any[]) => T,
|
|
21
|
+
query: Record<string, any>,
|
|
22
|
+
): Promise<T | null>;
|
|
23
|
+
public static getInstances<T>(
|
|
24
|
+
this: new (...args: any[]) => T,
|
|
25
|
+
query: Record<string, any>,
|
|
26
|
+
): Promise<T[]>;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const SmartDataDbDoc = plugins.smartdata.SmartDataDbDoc as unknown as typeof SmartDataDbDocBase;
|
|
30
|
+
const Collection = plugins.smartdata.Collection as any;
|
|
31
|
+
const svDb = plugins.smartdata.svDb as any;
|
|
32
|
+
const unI = plugins.smartdata.unI as any;
|
|
33
|
+
const index = plugins.smartdata.index as any;
|
|
34
|
+
const searchable = plugins.smartdata.searchable as any;
|
|
17
35
|
|
|
18
|
-
@
|
|
19
|
-
export class JournalEntry extends SmartDataDbDoc
|
|
36
|
+
@Collection(() => getDbSync())
|
|
37
|
+
export class JournalEntry extends SmartDataDbDoc {
|
|
20
38
|
@unI()
|
|
21
|
-
public id
|
|
39
|
+
public id!: string;
|
|
22
40
|
|
|
23
41
|
@svDb()
|
|
24
42
|
@index()
|
|
25
|
-
public journalNumber
|
|
43
|
+
public journalNumber!: string;
|
|
26
44
|
|
|
27
45
|
@svDb()
|
|
28
46
|
@index()
|
|
29
|
-
public date
|
|
47
|
+
public date!: Date;
|
|
30
48
|
|
|
31
49
|
@svDb()
|
|
32
50
|
@searchable()
|
|
33
|
-
public description
|
|
51
|
+
public description!: string;
|
|
34
52
|
|
|
35
53
|
@svDb()
|
|
36
54
|
@index()
|
|
37
|
-
public reference
|
|
55
|
+
public reference!: string;
|
|
38
56
|
|
|
39
57
|
@svDb()
|
|
40
|
-
public lines
|
|
58
|
+
public lines!: IJournalEntryLine[];
|
|
41
59
|
|
|
42
60
|
@svDb()
|
|
43
61
|
@index()
|
|
44
|
-
public skrType
|
|
62
|
+
public skrType!: TSKRType;
|
|
45
63
|
|
|
46
64
|
@svDb()
|
|
47
|
-
public totalDebits
|
|
65
|
+
public totalDebits!: number;
|
|
48
66
|
|
|
49
67
|
@svDb()
|
|
50
|
-
public totalCredits
|
|
68
|
+
public totalCredits!: number;
|
|
51
69
|
|
|
52
70
|
@svDb()
|
|
53
|
-
public isBalanced
|
|
71
|
+
public isBalanced!: boolean;
|
|
54
72
|
|
|
55
73
|
@svDb()
|
|
56
74
|
@index()
|
|
57
|
-
public status
|
|
75
|
+
public status!: 'draft' | 'posted' | 'reversed';
|
|
58
76
|
|
|
59
77
|
@svDb()
|
|
60
|
-
public transactionIds
|
|
78
|
+
public transactionIds!: string[];
|
|
61
79
|
|
|
62
80
|
@svDb()
|
|
63
81
|
@index()
|
|
64
|
-
public period
|
|
82
|
+
public period!: string;
|
|
65
83
|
|
|
66
84
|
@svDb()
|
|
67
|
-
public fiscalYear
|
|
85
|
+
public fiscalYear!: number;
|
|
68
86
|
|
|
69
87
|
@svDb()
|
|
70
|
-
public createdAt
|
|
88
|
+
public createdAt!: Date;
|
|
71
89
|
|
|
72
90
|
@svDb()
|
|
73
|
-
public postedAt
|
|
91
|
+
public postedAt!: Date | null;
|
|
74
92
|
|
|
75
93
|
@svDb()
|
|
76
|
-
public createdBy
|
|
94
|
+
public createdBy!: string;
|
|
77
95
|
|
|
78
96
|
constructor(data?: Partial<IJournalEntry>) {
|
|
79
97
|
super();
|
|
@@ -240,7 +258,7 @@ export class JournalEntry extends SmartDataDbDoc<JournalEntry, JournalEntry> {
|
|
|
240
258
|
try {
|
|
241
259
|
await Account.validateAccountForPosting(line.accountNumber, this.skrType);
|
|
242
260
|
} catch (error) {
|
|
243
|
-
validationErrors.push(error.message);
|
|
261
|
+
validationErrors.push(error instanceof Error ? error.message : String(error));
|
|
244
262
|
continue; // Skip further validation for this line
|
|
245
263
|
}
|
|
246
264
|
|
|
@@ -329,7 +347,7 @@ export class JournalEntry extends SmartDataDbDoc<JournalEntry, JournalEntry> {
|
|
|
329
347
|
date: this.date,
|
|
330
348
|
debitAccount: debitLines[0].accountNumber,
|
|
331
349
|
creditAccount: creditLines[0].accountNumber,
|
|
332
|
-
amount: debitLines[0].debit,
|
|
350
|
+
amount: debitLines[0].debit || 0,
|
|
333
351
|
description: this.description,
|
|
334
352
|
reference: this.reference,
|
|
335
353
|
skrType: this.skrType,
|
|
@@ -410,7 +410,20 @@ export class Reports {
|
|
|
410
410
|
isActive: true,
|
|
411
411
|
});
|
|
412
412
|
|
|
413
|
-
const ledgerEntries
|
|
413
|
+
const ledgerEntries: Array<{
|
|
414
|
+
accountNumber: string;
|
|
415
|
+
accountName: string;
|
|
416
|
+
accountType: string;
|
|
417
|
+
entries: Array<{
|
|
418
|
+
date: Date;
|
|
419
|
+
reference: string;
|
|
420
|
+
description: string;
|
|
421
|
+
debit: number;
|
|
422
|
+
credit: number;
|
|
423
|
+
balance: number;
|
|
424
|
+
}>;
|
|
425
|
+
finalBalance: number;
|
|
426
|
+
}> = [];
|
|
414
427
|
|
|
415
428
|
for (const account of accounts) {
|
|
416
429
|
const transactions = await this.getAccountTransactions(
|
|
@@ -420,7 +433,14 @@ export class Reports {
|
|
|
420
433
|
|
|
421
434
|
if (transactions.length > 0) {
|
|
422
435
|
let runningBalance = 0;
|
|
423
|
-
const accountEntries
|
|
436
|
+
const accountEntries: Array<{
|
|
437
|
+
date: Date;
|
|
438
|
+
reference: string;
|
|
439
|
+
description: string;
|
|
440
|
+
debit: number;
|
|
441
|
+
credit: number;
|
|
442
|
+
balance: number;
|
|
443
|
+
}> = [];
|
|
424
444
|
|
|
425
445
|
for (const transaction of transactions) {
|
|
426
446
|
const isDebit = transaction.debitAccount === account.accountNumber;
|
|
@@ -7,75 +7,93 @@ import type {
|
|
|
7
7
|
ITransactionData,
|
|
8
8
|
} from './skr.types.js';
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
declare abstract class SmartDataDbDocBase {
|
|
11
|
+
public save(): Promise<void>;
|
|
12
|
+
public delete(): Promise<void>;
|
|
13
|
+
public static getInstance<T>(
|
|
14
|
+
this: new (...args: any[]) => T,
|
|
15
|
+
query: Record<string, any>,
|
|
16
|
+
): Promise<T | null>;
|
|
17
|
+
public static getInstances<T>(
|
|
18
|
+
this: new (...args: any[]) => T,
|
|
19
|
+
query: Record<string, any>,
|
|
20
|
+
): Promise<T[]>;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const SmartDataDbDoc = plugins.smartdata.SmartDataDbDoc as unknown as typeof SmartDataDbDocBase;
|
|
24
|
+
const Collection = plugins.smartdata.Collection as any;
|
|
25
|
+
const svDb = plugins.smartdata.svDb as any;
|
|
26
|
+
const unI = plugins.smartdata.unI as any;
|
|
27
|
+
const index = plugins.smartdata.index as any;
|
|
28
|
+
const searchable = plugins.smartdata.searchable as any;
|
|
11
29
|
|
|
12
|
-
@
|
|
13
|
-
export class Transaction extends SmartDataDbDoc
|
|
30
|
+
@Collection(() => getDbSync())
|
|
31
|
+
export class Transaction extends SmartDataDbDoc {
|
|
14
32
|
@unI()
|
|
15
|
-
public id
|
|
33
|
+
public id!: string;
|
|
16
34
|
|
|
17
35
|
@svDb()
|
|
18
36
|
@index()
|
|
19
|
-
public transactionNumber
|
|
37
|
+
public transactionNumber!: string;
|
|
20
38
|
|
|
21
39
|
@svDb()
|
|
22
40
|
@index()
|
|
23
|
-
public date
|
|
41
|
+
public date!: Date;
|
|
24
42
|
|
|
25
43
|
@svDb()
|
|
26
44
|
@index()
|
|
27
|
-
public debitAccount
|
|
45
|
+
public debitAccount!: string;
|
|
28
46
|
|
|
29
47
|
@svDb()
|
|
30
48
|
@index()
|
|
31
|
-
public creditAccount
|
|
49
|
+
public creditAccount!: string;
|
|
32
50
|
|
|
33
51
|
@svDb()
|
|
34
|
-
public amount
|
|
52
|
+
public amount!: number;
|
|
35
53
|
|
|
36
54
|
@svDb()
|
|
37
55
|
@searchable()
|
|
38
|
-
public description
|
|
56
|
+
public description!: string;
|
|
39
57
|
|
|
40
58
|
@svDb()
|
|
41
59
|
@index()
|
|
42
|
-
public reference
|
|
60
|
+
public reference!: string;
|
|
43
61
|
|
|
44
62
|
@svDb()
|
|
45
63
|
@index()
|
|
46
|
-
public skrType
|
|
64
|
+
public skrType!: TSKRType;
|
|
47
65
|
|
|
48
66
|
@svDb()
|
|
49
|
-
public vatAmount
|
|
67
|
+
public vatAmount!: number;
|
|
50
68
|
|
|
51
69
|
@svDb()
|
|
52
|
-
public costCenter
|
|
70
|
+
public costCenter!: string;
|
|
53
71
|
|
|
54
72
|
@svDb()
|
|
55
73
|
@index()
|
|
56
|
-
public status
|
|
74
|
+
public status!: TTransactionStatus;
|
|
57
75
|
|
|
58
76
|
@svDb()
|
|
59
|
-
public reversalOf
|
|
77
|
+
public reversalOf!: string;
|
|
60
78
|
|
|
61
79
|
@svDb()
|
|
62
|
-
public reversedBy
|
|
80
|
+
public reversedBy!: string;
|
|
63
81
|
|
|
64
82
|
@svDb()
|
|
65
83
|
@index()
|
|
66
|
-
public period
|
|
84
|
+
public period!: string; // Format: YYYY-MM
|
|
67
85
|
|
|
68
86
|
@svDb()
|
|
69
|
-
public fiscalYear
|
|
87
|
+
public fiscalYear!: number;
|
|
70
88
|
|
|
71
89
|
@svDb()
|
|
72
|
-
public createdAt
|
|
90
|
+
public createdAt!: Date;
|
|
73
91
|
|
|
74
92
|
@svDb()
|
|
75
|
-
public postedAt
|
|
93
|
+
public postedAt!: Date | null;
|
|
76
94
|
|
|
77
95
|
@svDb()
|
|
78
|
-
public createdBy
|
|
96
|
+
public createdBy!: string;
|
|
79
97
|
|
|
80
98
|
constructor(data?: Partial<ITransactionData>) {
|
|
81
99
|
super();
|
package/ts/skr.export.pdf.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as plugins from './plugins.js';
|
|
2
2
|
import * as path from 'path';
|
|
3
|
+
import { SmartPdf } from '@push.rocks/smartpdf';
|
|
3
4
|
import type { ITrialBalanceReport, IIncomeStatement, IBalanceSheet } from './skr.types.js';
|
|
4
5
|
|
|
5
6
|
export interface IPdfReportOptions {
|
|
@@ -17,7 +18,7 @@ export interface IPdfReportOptions {
|
|
|
17
18
|
export class PdfReportGenerator {
|
|
18
19
|
private exportPath: string;
|
|
19
20
|
private options: IPdfReportOptions;
|
|
20
|
-
private pdfInstance:
|
|
21
|
+
private pdfInstance: SmartPdf | null = null;
|
|
21
22
|
|
|
22
23
|
constructor(exportPath: string, options: IPdfReportOptions) {
|
|
23
24
|
this.exportPath = exportPath;
|
|
@@ -28,7 +29,7 @@ export class PdfReportGenerator {
|
|
|
28
29
|
* Initializes the PDF generator
|
|
29
30
|
*/
|
|
30
31
|
public async initialize(): Promise<void> {
|
|
31
|
-
this.pdfInstance = new
|
|
32
|
+
this.pdfInstance = new SmartPdf();
|
|
32
33
|
await this.pdfInstance.start();
|
|
33
34
|
}
|
|
34
35
|
|
|
@@ -598,4 +599,4 @@ export class PdfReportGenerator {
|
|
|
598
599
|
this.pdfInstance = null;
|
|
599
600
|
}
|
|
600
601
|
}
|
|
601
|
-
}
|
|
602
|
+
}
|