@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
package/ts/skr.api.ts
ADDED
|
@@ -0,0 +1,533 @@
|
|
|
1
|
+
import * as plugins from './plugins.js';
|
|
2
|
+
import { ChartOfAccounts } from './skr.classes.chartofaccounts.js';
|
|
3
|
+
import { Ledger } from './skr.classes.ledger.js';
|
|
4
|
+
import { Reports } from './skr.classes.reports.js';
|
|
5
|
+
import { Account } from './skr.classes.account.js';
|
|
6
|
+
import { Transaction } from './skr.classes.transaction.js';
|
|
7
|
+
import { JournalEntry } from './skr.classes.journalentry.js';
|
|
8
|
+
import type {
|
|
9
|
+
IDatabaseConfig,
|
|
10
|
+
TSKRType,
|
|
11
|
+
IAccountData,
|
|
12
|
+
IAccountFilter,
|
|
13
|
+
ITransactionData,
|
|
14
|
+
ITransactionFilter,
|
|
15
|
+
IJournalEntry,
|
|
16
|
+
IReportParams,
|
|
17
|
+
ITrialBalanceReport,
|
|
18
|
+
IIncomeStatement,
|
|
19
|
+
IBalanceSheet,
|
|
20
|
+
} from './skr.types.js';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Main API class for SKR accounting operations
|
|
24
|
+
*/
|
|
25
|
+
export class SkrApi {
|
|
26
|
+
private chartOfAccounts: ChartOfAccounts;
|
|
27
|
+
private ledger: Ledger | null = null;
|
|
28
|
+
private reports: Reports | null = null;
|
|
29
|
+
private logger: plugins.smartlog.Smartlog;
|
|
30
|
+
private initialized: boolean = false;
|
|
31
|
+
private currentSKRType: TSKRType | null = null;
|
|
32
|
+
|
|
33
|
+
constructor(private config: IDatabaseConfig) {
|
|
34
|
+
this.chartOfAccounts = new ChartOfAccounts(config);
|
|
35
|
+
this.logger = new plugins.smartlog.Smartlog({
|
|
36
|
+
logContext: {
|
|
37
|
+
company: 'fin.cx',
|
|
38
|
+
companyunit: 'skr',
|
|
39
|
+
containerName: 'SkrApi',
|
|
40
|
+
environment: 'local',
|
|
41
|
+
runtime: 'node',
|
|
42
|
+
zone: 'local',
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Initialize the API with specified SKR type
|
|
49
|
+
*/
|
|
50
|
+
public async initialize(skrType: TSKRType): Promise<void> {
|
|
51
|
+
this.logger.log('info', `Initializing SKR API with ${skrType}`);
|
|
52
|
+
|
|
53
|
+
// Initialize chart of accounts
|
|
54
|
+
if (skrType === 'SKR03') {
|
|
55
|
+
await this.chartOfAccounts.initializeSKR03();
|
|
56
|
+
} else if (skrType === 'SKR04') {
|
|
57
|
+
await this.chartOfAccounts.initializeSKR04();
|
|
58
|
+
} else {
|
|
59
|
+
throw new Error(`Invalid SKR type: ${skrType}`);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
this.currentSKRType = skrType;
|
|
63
|
+
this.ledger = new Ledger(skrType);
|
|
64
|
+
this.reports = new Reports(skrType);
|
|
65
|
+
this.initialized = true;
|
|
66
|
+
|
|
67
|
+
this.logger.log('info', 'SKR API initialized successfully');
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Ensure API is initialized
|
|
72
|
+
*/
|
|
73
|
+
private ensureInitialized(): void {
|
|
74
|
+
if (!this.initialized || !this.currentSKRType) {
|
|
75
|
+
throw new Error('API not initialized. Call initialize() first.');
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// ========== Account Management ==========
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Create a new account
|
|
83
|
+
*/
|
|
84
|
+
public async createAccount(
|
|
85
|
+
accountData: Partial<IAccountData>,
|
|
86
|
+
): Promise<Account> {
|
|
87
|
+
this.ensureInitialized();
|
|
88
|
+
return await this.chartOfAccounts.createCustomAccount(accountData);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Get account by number
|
|
93
|
+
*/
|
|
94
|
+
public async getAccount(accountNumber: string): Promise<Account | null> {
|
|
95
|
+
this.ensureInitialized();
|
|
96
|
+
return await this.chartOfAccounts.getAccountByNumber(accountNumber);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Update an account
|
|
101
|
+
*/
|
|
102
|
+
public async updateAccount(
|
|
103
|
+
accountNumber: string,
|
|
104
|
+
updates: Partial<IAccountData>,
|
|
105
|
+
): Promise<Account> {
|
|
106
|
+
this.ensureInitialized();
|
|
107
|
+
return await this.chartOfAccounts.updateAccount(accountNumber, updates);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Delete an account
|
|
112
|
+
*/
|
|
113
|
+
public async deleteAccount(accountNumber: string): Promise<void> {
|
|
114
|
+
this.ensureInitialized();
|
|
115
|
+
await this.chartOfAccounts.deleteAccount(accountNumber);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* List accounts with optional filter
|
|
120
|
+
*/
|
|
121
|
+
public async listAccounts(filter?: IAccountFilter): Promise<Account[]> {
|
|
122
|
+
this.ensureInitialized();
|
|
123
|
+
return await this.chartOfAccounts.getAllAccounts(filter);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Search accounts by term
|
|
128
|
+
*/
|
|
129
|
+
public async searchAccounts(searchTerm: string): Promise<Account[]> {
|
|
130
|
+
this.ensureInitialized();
|
|
131
|
+
return await this.chartOfAccounts.searchAccounts(searchTerm);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Get accounts by class
|
|
136
|
+
*/
|
|
137
|
+
public async getAccountsByClass(accountClass: number): Promise<Account[]> {
|
|
138
|
+
this.ensureInitialized();
|
|
139
|
+
return await this.chartOfAccounts.getAccountsByClass(accountClass);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Get accounts by type
|
|
144
|
+
*/
|
|
145
|
+
public async getAccountsByType(
|
|
146
|
+
accountType: IAccountData['accountType'],
|
|
147
|
+
): Promise<Account[]> {
|
|
148
|
+
this.ensureInitialized();
|
|
149
|
+
return await this.chartOfAccounts.getAccountsByType(accountType);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// ========== Transaction Management ==========
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Post a simple transaction
|
|
156
|
+
*/
|
|
157
|
+
public async postTransaction(
|
|
158
|
+
transactionData: ITransactionData,
|
|
159
|
+
): Promise<Transaction> {
|
|
160
|
+
this.ensureInitialized();
|
|
161
|
+
return await this.chartOfAccounts.postTransaction(transactionData);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Post a journal entry
|
|
166
|
+
*/
|
|
167
|
+
public async postJournalEntry(
|
|
168
|
+
journalData: IJournalEntry,
|
|
169
|
+
): Promise<JournalEntry> {
|
|
170
|
+
this.ensureInitialized();
|
|
171
|
+
return await this.chartOfAccounts.postJournalEntry(journalData);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Get transaction by ID
|
|
176
|
+
*/
|
|
177
|
+
public async getTransaction(
|
|
178
|
+
transactionId: string,
|
|
179
|
+
): Promise<Transaction | null> {
|
|
180
|
+
this.ensureInitialized();
|
|
181
|
+
return await Transaction.getTransactionById(transactionId);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* List transactions with optional filter
|
|
186
|
+
*/
|
|
187
|
+
public async listTransactions(
|
|
188
|
+
filter?: ITransactionFilter,
|
|
189
|
+
): Promise<Transaction[]> {
|
|
190
|
+
this.ensureInitialized();
|
|
191
|
+
return await this.chartOfAccounts.getTransactions(filter);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Get transactions for specific account
|
|
196
|
+
*/
|
|
197
|
+
public async getAccountTransactions(
|
|
198
|
+
accountNumber: string,
|
|
199
|
+
): Promise<Transaction[]> {
|
|
200
|
+
this.ensureInitialized();
|
|
201
|
+
return await this.chartOfAccounts.getAccountTransactions(accountNumber);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Reverse a transaction
|
|
206
|
+
*/
|
|
207
|
+
public async reverseTransaction(transactionId: string): Promise<Transaction> {
|
|
208
|
+
this.ensureInitialized();
|
|
209
|
+
return await this.chartOfAccounts.reverseTransaction(transactionId);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Reverse a journal entry
|
|
214
|
+
*/
|
|
215
|
+
public async reverseJournalEntry(journalId: string): Promise<JournalEntry> {
|
|
216
|
+
this.ensureInitialized();
|
|
217
|
+
if (!this.ledger) throw new Error('Ledger not initialized');
|
|
218
|
+
return await this.ledger.reverseJournalEntry(journalId);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// ========== Reporting ==========
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Generate trial balance
|
|
225
|
+
*/
|
|
226
|
+
public async generateTrialBalance(
|
|
227
|
+
params?: IReportParams,
|
|
228
|
+
): Promise<ITrialBalanceReport> {
|
|
229
|
+
this.ensureInitialized();
|
|
230
|
+
if (!this.reports) throw new Error('Reports not initialized');
|
|
231
|
+
return await this.reports.getTrialBalance(params);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Generate income statement
|
|
236
|
+
*/
|
|
237
|
+
public async generateIncomeStatement(
|
|
238
|
+
params?: IReportParams,
|
|
239
|
+
): Promise<IIncomeStatement> {
|
|
240
|
+
this.ensureInitialized();
|
|
241
|
+
if (!this.reports) throw new Error('Reports not initialized');
|
|
242
|
+
return await this.reports.getIncomeStatement(params);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Generate balance sheet
|
|
247
|
+
*/
|
|
248
|
+
public async generateBalanceSheet(
|
|
249
|
+
params?: IReportParams,
|
|
250
|
+
): Promise<IBalanceSheet> {
|
|
251
|
+
this.ensureInitialized();
|
|
252
|
+
if (!this.reports) throw new Error('Reports not initialized');
|
|
253
|
+
return await this.reports.getBalanceSheet(params);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Generate general ledger
|
|
258
|
+
*/
|
|
259
|
+
public async generateGeneralLedger(params?: IReportParams): Promise<any> {
|
|
260
|
+
this.ensureInitialized();
|
|
261
|
+
if (!this.reports) throw new Error('Reports not initialized');
|
|
262
|
+
return await this.reports.getGeneralLedger(params);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Generate cash flow statement
|
|
267
|
+
*/
|
|
268
|
+
public async generateCashFlowStatement(params?: IReportParams): Promise<any> {
|
|
269
|
+
this.ensureInitialized();
|
|
270
|
+
if (!this.reports) throw new Error('Reports not initialized');
|
|
271
|
+
return await this.reports.getCashFlowStatement(params);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Export report to CSV
|
|
276
|
+
*/
|
|
277
|
+
public async exportReportToCSV(
|
|
278
|
+
reportType: 'trial_balance' | 'income_statement' | 'balance_sheet',
|
|
279
|
+
params?: IReportParams,
|
|
280
|
+
): Promise<string> {
|
|
281
|
+
this.ensureInitialized();
|
|
282
|
+
if (!this.reports) throw new Error('Reports not initialized');
|
|
283
|
+
return await this.reports.exportToCSV(reportType, params);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Export to DATEV format
|
|
288
|
+
*/
|
|
289
|
+
public async exportToDATEV(params?: IReportParams): Promise<string> {
|
|
290
|
+
this.ensureInitialized();
|
|
291
|
+
if (!this.reports) throw new Error('Reports not initialized');
|
|
292
|
+
return await this.reports.exportToDATEV(params);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// ========== Period Management ==========
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Close accounting period
|
|
299
|
+
*/
|
|
300
|
+
public async closePeriod(
|
|
301
|
+
period: string,
|
|
302
|
+
closingAccountNumber?: string,
|
|
303
|
+
): Promise<JournalEntry[]> {
|
|
304
|
+
this.ensureInitialized();
|
|
305
|
+
if (!this.ledger) throw new Error('Ledger not initialized');
|
|
306
|
+
return await this.ledger.closeAccountingPeriod(
|
|
307
|
+
period,
|
|
308
|
+
closingAccountNumber,
|
|
309
|
+
);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Get account balance
|
|
314
|
+
*/
|
|
315
|
+
public async getAccountBalance(
|
|
316
|
+
accountNumber: string,
|
|
317
|
+
asOfDate?: Date,
|
|
318
|
+
): Promise<any> {
|
|
319
|
+
this.ensureInitialized();
|
|
320
|
+
if (!this.ledger) throw new Error('Ledger not initialized');
|
|
321
|
+
return await this.ledger.getAccountBalance(accountNumber, asOfDate);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* Recalculate all account balances
|
|
326
|
+
*/
|
|
327
|
+
public async recalculateBalances(): Promise<void> {
|
|
328
|
+
this.ensureInitialized();
|
|
329
|
+
if (!this.ledger) throw new Error('Ledger not initialized');
|
|
330
|
+
await this.ledger.recalculateAllBalances();
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// ========== Import/Export ==========
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Import accounts from CSV
|
|
337
|
+
*/
|
|
338
|
+
public async importAccountsFromCSV(csvContent: string): Promise<number> {
|
|
339
|
+
this.ensureInitialized();
|
|
340
|
+
return await this.chartOfAccounts.importAccountsFromCSV(csvContent);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* Export accounts to CSV
|
|
345
|
+
*/
|
|
346
|
+
public async exportAccountsToCSV(): Promise<string> {
|
|
347
|
+
this.ensureInitialized();
|
|
348
|
+
return await this.chartOfAccounts.exportAccountsToCSV();
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
// ========== Utility Methods ==========
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Get current SKR type
|
|
355
|
+
*/
|
|
356
|
+
public getSKRType(): TSKRType | null {
|
|
357
|
+
return this.currentSKRType;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* Get account class description
|
|
362
|
+
*/
|
|
363
|
+
public getAccountClassDescription(accountClass: number): string {
|
|
364
|
+
this.ensureInitialized();
|
|
365
|
+
return this.chartOfAccounts.getAccountClassDescription(accountClass);
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* Validate double-entry rules
|
|
370
|
+
*/
|
|
371
|
+
public validateDoubleEntry(
|
|
372
|
+
debitAmount: number,
|
|
373
|
+
creditAmount: number,
|
|
374
|
+
): boolean {
|
|
375
|
+
if (!this.ledger) throw new Error('Ledger not initialized');
|
|
376
|
+
return this.ledger.validateDoubleEntry(debitAmount, creditAmount);
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* Get unbalanced transactions (for audit)
|
|
381
|
+
*/
|
|
382
|
+
public async getUnbalancedTransactions(): Promise<Transaction[]> {
|
|
383
|
+
this.ensureInitialized();
|
|
384
|
+
if (!this.ledger) throw new Error('Ledger not initialized');
|
|
385
|
+
return await this.ledger.getUnbalancedTransactions();
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* Close the API and database connection
|
|
390
|
+
*/
|
|
391
|
+
public async close(): Promise<void> {
|
|
392
|
+
await this.chartOfAccounts.close();
|
|
393
|
+
this.initialized = false;
|
|
394
|
+
this.currentSKRType = null;
|
|
395
|
+
this.ledger = null;
|
|
396
|
+
this.reports = null;
|
|
397
|
+
this.logger.log('info', 'SKR API closed');
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// ========== Batch Operations ==========
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* Post multiple transactions
|
|
404
|
+
*/
|
|
405
|
+
public async postBatchTransactions(
|
|
406
|
+
transactions: ITransactionData[],
|
|
407
|
+
): Promise<Transaction[]> {
|
|
408
|
+
this.ensureInitialized();
|
|
409
|
+
|
|
410
|
+
const results: Transaction[] = [];
|
|
411
|
+
const errors: Array<{ index: number; error: string }> = [];
|
|
412
|
+
|
|
413
|
+
for (let i = 0; i < transactions.length; i++) {
|
|
414
|
+
try {
|
|
415
|
+
const transaction = await this.postTransaction(transactions[i]);
|
|
416
|
+
results.push(transaction);
|
|
417
|
+
} catch (error) {
|
|
418
|
+
errors.push({ index: i, error: error.message });
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
if (errors.length > 0) {
|
|
423
|
+
this.logger.log(
|
|
424
|
+
'warn',
|
|
425
|
+
`Batch transaction posting completed with ${errors.length} errors`,
|
|
426
|
+
);
|
|
427
|
+
throw new Error(
|
|
428
|
+
`Batch posting failed for ${errors.length} transactions: ${JSON.stringify(errors)}`,
|
|
429
|
+
);
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
return results;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/**
|
|
436
|
+
* Create multiple accounts
|
|
437
|
+
*/
|
|
438
|
+
public async createBatchAccounts(
|
|
439
|
+
accounts: IAccountData[],
|
|
440
|
+
): Promise<Account[]> {
|
|
441
|
+
this.ensureInitialized();
|
|
442
|
+
|
|
443
|
+
const results: Account[] = [];
|
|
444
|
+
const errors: Array<{ index: number; error: string }> = [];
|
|
445
|
+
|
|
446
|
+
for (let i = 0; i < accounts.length; i++) {
|
|
447
|
+
try {
|
|
448
|
+
const account = await this.createAccount(accounts[i]);
|
|
449
|
+
results.push(account);
|
|
450
|
+
} catch (error) {
|
|
451
|
+
errors.push({ index: i, error: error.message });
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
if (errors.length > 0) {
|
|
456
|
+
this.logger.log(
|
|
457
|
+
'warn',
|
|
458
|
+
`Batch account creation completed with ${errors.length} errors`,
|
|
459
|
+
);
|
|
460
|
+
throw new Error(
|
|
461
|
+
`Batch creation failed for ${errors.length} accounts: ${JSON.stringify(errors)}`,
|
|
462
|
+
);
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
return results;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
// ========== Pagination Support ==========
|
|
469
|
+
|
|
470
|
+
/**
|
|
471
|
+
* Get paginated accounts
|
|
472
|
+
*/
|
|
473
|
+
public async getAccountsPaginated(
|
|
474
|
+
page: number = 1,
|
|
475
|
+
pageSize: number = 50,
|
|
476
|
+
filter?: IAccountFilter,
|
|
477
|
+
): Promise<{
|
|
478
|
+
data: Account[];
|
|
479
|
+
total: number;
|
|
480
|
+
page: number;
|
|
481
|
+
pageSize: number;
|
|
482
|
+
totalPages: number;
|
|
483
|
+
}> {
|
|
484
|
+
this.ensureInitialized();
|
|
485
|
+
|
|
486
|
+
const allAccounts = await this.listAccounts(filter);
|
|
487
|
+
const total = allAccounts.length;
|
|
488
|
+
const totalPages = Math.ceil(total / pageSize);
|
|
489
|
+
const start = (page - 1) * pageSize;
|
|
490
|
+
const end = start + pageSize;
|
|
491
|
+
const data = allAccounts.slice(start, end);
|
|
492
|
+
|
|
493
|
+
return {
|
|
494
|
+
data,
|
|
495
|
+
total,
|
|
496
|
+
page,
|
|
497
|
+
pageSize,
|
|
498
|
+
totalPages,
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
/**
|
|
503
|
+
* Get paginated transactions
|
|
504
|
+
*/
|
|
505
|
+
public async getTransactionsPaginated(
|
|
506
|
+
page: number = 1,
|
|
507
|
+
pageSize: number = 50,
|
|
508
|
+
filter?: ITransactionFilter,
|
|
509
|
+
): Promise<{
|
|
510
|
+
data: Transaction[];
|
|
511
|
+
total: number;
|
|
512
|
+
page: number;
|
|
513
|
+
pageSize: number;
|
|
514
|
+
totalPages: number;
|
|
515
|
+
}> {
|
|
516
|
+
this.ensureInitialized();
|
|
517
|
+
|
|
518
|
+
const allTransactions = await this.listTransactions(filter);
|
|
519
|
+
const total = allTransactions.length;
|
|
520
|
+
const totalPages = Math.ceil(total / pageSize);
|
|
521
|
+
const start = (page - 1) * pageSize;
|
|
522
|
+
const end = start + pageSize;
|
|
523
|
+
const data = allTransactions.slice(start, end);
|
|
524
|
+
|
|
525
|
+
return {
|
|
526
|
+
data,
|
|
527
|
+
total,
|
|
528
|
+
page,
|
|
529
|
+
pageSize,
|
|
530
|
+
totalPages,
|
|
531
|
+
};
|
|
532
|
+
}
|
|
533
|
+
}
|