bkper-js 2.27.0 → 2.29.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/CHANGELOG.md +35 -10
- package/lib/builders/AccountsDataTableBuilder.js +247 -0
- package/lib/{model → builders}/BalancesDataTableBuilder.js +36 -13
- package/lib/builders/BooksDataTableBuilder.js +127 -0
- package/lib/builders/GroupsDataTableBuilder.js +193 -0
- package/lib/builders/TransactionsDataTableBuilder.js +359 -0
- package/lib/index.d.ts +375 -0
- package/lib/index.js +31 -27
- package/lib/model/BalancesContainerAccount.js +4 -4
- package/lib/model/BalancesContainerGroup.js +5 -5
- package/lib/model/BalancesReport.js +3 -3
- package/lib/model/Billing.js +2 -0
- package/lib/model/Book.js +104 -60
- package/lib/model/Enums.js +24 -0
- package/lib/model/Transaction.js +46 -35
- package/lib/model/User.js +8 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,7 +4,30 @@ See what's new and what has changed in bkper-js
|
|
|
4
4
|
|
|
5
5
|
## 2026
|
|
6
6
|
|
|
7
|
+
**February 2026**
|
|
8
|
+
|
|
9
|
+
- Added `User.getGivenName`
|
|
10
|
+
- Added `BooksDataTableBuilder`
|
|
11
|
+
- Added `AccountsDataTableBuilder`
|
|
12
|
+
- Added `GroupsDataTableBuilder`
|
|
13
|
+
- Added `TransactionsDataTableBuilder`
|
|
14
|
+
- Added `Book.createAccountsDataTable`
|
|
15
|
+
- Added `Book.createGroupsDataTable`
|
|
16
|
+
- Added `Book.createTransactionsDataTable`
|
|
17
|
+
- Added `TransactionsDataTableBuilder.ids`
|
|
18
|
+
- Added `TransactionsDataTableBuilder.properties`
|
|
19
|
+
- Added `TransactionsDataTableBuilder.urls`
|
|
20
|
+
- Added `TransactionsDataTableBuilder.recordedAt`
|
|
21
|
+
- Added `AccountsDataTableBuilder.hiddenProperties`
|
|
22
|
+
- Added `BooksDataTableBuilder.hiddenProperties`
|
|
23
|
+
- Added `GroupsDataTableBuilder.hiddenProperties`
|
|
24
|
+
- Added `GroupsDataTableBuilder.tree`
|
|
25
|
+
- Added `TransactionsDataTableBuilder.hiddenProperties`
|
|
26
|
+
- Added `BalancesDataTableBuilder.hiddenProperties`
|
|
27
|
+
|
|
28
|
+
|
|
7
29
|
**January 2026**
|
|
30
|
+
|
|
8
31
|
- Added `App.setUsers`
|
|
9
32
|
- Added `App.getUsers`
|
|
10
33
|
- Added `App.setDevelopers`
|
|
@@ -38,16 +61,18 @@ See what's new and what has changed in bkper-js
|
|
|
38
61
|
## 2025
|
|
39
62
|
|
|
40
63
|
**December 2025**
|
|
64
|
+
|
|
41
65
|
- Added `File.update`
|
|
42
66
|
- Added `EventType.FILE_UPDATED`
|
|
43
67
|
|
|
44
68
|
**November 2025**
|
|
69
|
+
|
|
45
70
|
- **v2.15.2 - INTERNAL REFACTOR:**
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
71
|
+
- Introduced `ResourceProperty` abstract class for model entities that support custom properties
|
|
72
|
+
- Moved shared property methods to ResourceProperty
|
|
73
|
+
- Refactor 7 model classes to extend ResourceProperty instead of Resource
|
|
74
|
+
- Eliminate ~350 lines of duplicated property management code
|
|
75
|
+
- Maintained full backward compatibility - no breaking changes to existing APIs
|
|
51
76
|
- Added `ResourceProperty.setVisibleProperty`
|
|
52
77
|
- Added `ResourceProperty.setVisibleProperties`
|
|
53
78
|
- Added `ResourceProperty.getVisibleProperties`
|
|
@@ -63,11 +88,11 @@ See what's new and what has changed in bkper-js
|
|
|
63
88
|
**September 2025**
|
|
64
89
|
|
|
65
90
|
- **v2.8.0 - INTERNAL REFACTOR:**
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
91
|
+
- Introduced abstract `Resource` class for all model entities
|
|
92
|
+
- Improved config management with `getConfig()` pattern for config resolution
|
|
93
|
+
- Enhanced type safety with explicit Config type usage throughout
|
|
94
|
+
- Standardized `json()` method across resources for consistent JSON serialization
|
|
95
|
+
- Maintained full backward compatibility - no breaking changes to existing APIs
|
|
71
96
|
- Added `Account.isBalanceVerified`
|
|
72
97
|
- Added `App.getOwnerWebsiteUrl`
|
|
73
98
|
- Added `App.getReadme`
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { AccountType } from '../model/Enums.js';
|
|
11
|
+
import { convertInMatrix } from '../utils.js';
|
|
12
|
+
/**
|
|
13
|
+
* A AccountsDataTableBuilder is used to setup and build two-dimensional arrays containing accounts.
|
|
14
|
+
*
|
|
15
|
+
* @public
|
|
16
|
+
*/
|
|
17
|
+
export class AccountsDataTableBuilder {
|
|
18
|
+
constructor(accounts) {
|
|
19
|
+
this.accounts = accounts;
|
|
20
|
+
this.shouldIncludeArchived = false;
|
|
21
|
+
this.shouldAddGroups = false;
|
|
22
|
+
this.shouldAddProperties = false;
|
|
23
|
+
this.shouldAddIds = false;
|
|
24
|
+
this.shouldAddHiddenProperties = false;
|
|
25
|
+
this.propertyKeys = [];
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Defines whether the archived accounts should be included.
|
|
29
|
+
*
|
|
30
|
+
* @param include - Whether to include archived accounts
|
|
31
|
+
*
|
|
32
|
+
* @returns This builder with respective include archived option, for chaining.
|
|
33
|
+
*/
|
|
34
|
+
archived(include) {
|
|
35
|
+
this.shouldIncludeArchived = include;
|
|
36
|
+
return this;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Defines whether include account groups.
|
|
40
|
+
*
|
|
41
|
+
* @param include - Whether to include groups
|
|
42
|
+
*
|
|
43
|
+
* @returns This builder with respective include groups option, for chaining.
|
|
44
|
+
*/
|
|
45
|
+
groups(include) {
|
|
46
|
+
this.shouldAddGroups = include;
|
|
47
|
+
return this;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Defines whether include custom account properties.
|
|
51
|
+
*
|
|
52
|
+
* @param include - Whether to include properties
|
|
53
|
+
*
|
|
54
|
+
* @returns This builder with respective include properties option, for chaining.
|
|
55
|
+
*/
|
|
56
|
+
properties(include) {
|
|
57
|
+
this.shouldAddProperties = include;
|
|
58
|
+
return this;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Defines whether include account ids.
|
|
62
|
+
*
|
|
63
|
+
* @param include - Whether to include ids
|
|
64
|
+
*
|
|
65
|
+
* @returns This builder with respective include ids option, for chaining.
|
|
66
|
+
*/
|
|
67
|
+
ids(include) {
|
|
68
|
+
this.shouldAddIds = include;
|
|
69
|
+
return this;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Defines whether to include hidden properties (keys ending with underscore "_").
|
|
73
|
+
* Only relevant when {@link properties} is enabled.
|
|
74
|
+
* Default is false — hidden properties are excluded.
|
|
75
|
+
*
|
|
76
|
+
* @param include - Whether to include hidden properties
|
|
77
|
+
*
|
|
78
|
+
* @returns This builder with respective option, for chaining.
|
|
79
|
+
*/
|
|
80
|
+
hiddenProperties(include) {
|
|
81
|
+
this.shouldAddHiddenProperties = include;
|
|
82
|
+
return this;
|
|
83
|
+
}
|
|
84
|
+
getPropertyKeys() {
|
|
85
|
+
if (this.propertyKeys.length === 0) {
|
|
86
|
+
for (const account of this.accounts) {
|
|
87
|
+
for (const key of account.getPropertyKeys()) {
|
|
88
|
+
if (!this.shouldAddHiddenProperties && key.endsWith('_')) {
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
if (this.propertyKeys.indexOf(key) <= -1) {
|
|
92
|
+
this.propertyKeys.push(key);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
this.propertyKeys = this.propertyKeys.sort();
|
|
97
|
+
}
|
|
98
|
+
return this.propertyKeys;
|
|
99
|
+
}
|
|
100
|
+
getTypeIndex(type) {
|
|
101
|
+
if (type === AccountType.ASSET) {
|
|
102
|
+
return 0;
|
|
103
|
+
}
|
|
104
|
+
if (type === AccountType.LIABILITY) {
|
|
105
|
+
return 1;
|
|
106
|
+
}
|
|
107
|
+
if (type === AccountType.INCOMING) {
|
|
108
|
+
return 2;
|
|
109
|
+
}
|
|
110
|
+
return 3;
|
|
111
|
+
}
|
|
112
|
+
getMaxNumberOfGroups() {
|
|
113
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
114
|
+
let maxNumberOfGroups = 0;
|
|
115
|
+
for (const account of this.accounts) {
|
|
116
|
+
const groups = yield account.getGroups();
|
|
117
|
+
if (groups.length > maxNumberOfGroups) {
|
|
118
|
+
maxNumberOfGroups = groups.length;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return maxNumberOfGroups;
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Sorts groups for an account in hierarchy-path order:
|
|
126
|
+
* 1. Hierarchical groups (those with parent or children) come first, ordered by:
|
|
127
|
+
* - Root group name (alphabetically)
|
|
128
|
+
* - Depth within the hierarchy (parent before child)
|
|
129
|
+
* 2. Free groups (no parent and no children) come last, sorted alphabetically
|
|
130
|
+
*/
|
|
131
|
+
sortGroupsHierarchyPath_(groups) {
|
|
132
|
+
// Partition into hierarchical vs free groups
|
|
133
|
+
const hierarchicalGroups = [];
|
|
134
|
+
const freeGroups = [];
|
|
135
|
+
for (const group of groups) {
|
|
136
|
+
if (group.getParent() != null || group.hasChildren()) {
|
|
137
|
+
hierarchicalGroups.push(group);
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
freeGroups.push(group);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
// Group hierarchical groups by their root
|
|
144
|
+
const byRoot = new Map();
|
|
145
|
+
for (const group of hierarchicalGroups) {
|
|
146
|
+
const root = group.getRoot();
|
|
147
|
+
const rootId = root.getId() || '';
|
|
148
|
+
if (!byRoot.has(rootId)) {
|
|
149
|
+
byRoot.set(rootId, []);
|
|
150
|
+
}
|
|
151
|
+
byRoot.get(rootId).push(group);
|
|
152
|
+
}
|
|
153
|
+
// Sort chains: first by root name alphabetically, then by depth within each chain
|
|
154
|
+
const sortedChains = Array.from(byRoot.entries())
|
|
155
|
+
.sort((a, b) => {
|
|
156
|
+
const rootA = a[1][0].getRoot();
|
|
157
|
+
const rootB = b[1][0].getRoot();
|
|
158
|
+
return rootA.getNormalizedName().localeCompare(rootB.getNormalizedName());
|
|
159
|
+
})
|
|
160
|
+
.map(([_, chainGroups]) => chainGroups.sort((a, b) => a.getDepth() - b.getDepth()));
|
|
161
|
+
// Sort free groups alphabetically
|
|
162
|
+
freeGroups.sort((a, b) => a.getNormalizedName().localeCompare(b.getNormalizedName()));
|
|
163
|
+
// Combine: hierarchical chains first, then free groups
|
|
164
|
+
const result = [];
|
|
165
|
+
for (const chain of sortedChains) {
|
|
166
|
+
result.push(...chain);
|
|
167
|
+
}
|
|
168
|
+
result.push(...freeGroups);
|
|
169
|
+
return result;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Builds a two-dimensional array containing all accounts.
|
|
173
|
+
*
|
|
174
|
+
* @returns A promise resolving to a two-dimensional array containing all accounts
|
|
175
|
+
*/
|
|
176
|
+
build() {
|
|
177
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
178
|
+
let table = new Array();
|
|
179
|
+
let accounts = this.accounts;
|
|
180
|
+
if (!this.shouldIncludeArchived) {
|
|
181
|
+
accounts = this.accounts.filter(a => !a.isArchived());
|
|
182
|
+
}
|
|
183
|
+
let headers = [];
|
|
184
|
+
if (this.shouldAddIds) {
|
|
185
|
+
headers.push('Account Id');
|
|
186
|
+
}
|
|
187
|
+
headers.push('Name');
|
|
188
|
+
headers.push('Type');
|
|
189
|
+
if (this.shouldAddGroups) {
|
|
190
|
+
const maxGroups = yield this.getMaxNumberOfGroups();
|
|
191
|
+
for (let i = 0; i < maxGroups; i++) {
|
|
192
|
+
headers.push('Group');
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
accounts.sort((a1, a2) => {
|
|
196
|
+
let ret = this.getTypeIndex(a1.getType()) - this.getTypeIndex(a2.getType());
|
|
197
|
+
if (ret === 0) {
|
|
198
|
+
ret = a1.getNormalizedName().localeCompare(a2.getNormalizedName());
|
|
199
|
+
}
|
|
200
|
+
return ret;
|
|
201
|
+
});
|
|
202
|
+
let propertyKeys = [];
|
|
203
|
+
if (this.shouldAddProperties) {
|
|
204
|
+
propertyKeys = this.getPropertyKeys();
|
|
205
|
+
}
|
|
206
|
+
for (const account of accounts) {
|
|
207
|
+
const line = [];
|
|
208
|
+
if (this.shouldAddIds) {
|
|
209
|
+
line.push(account.getId());
|
|
210
|
+
}
|
|
211
|
+
line.push(account.getName());
|
|
212
|
+
line.push(account.getType());
|
|
213
|
+
if (this.shouldAddGroups) {
|
|
214
|
+
const groups = this.sortGroupsHierarchyPath_(yield account.getGroups());
|
|
215
|
+
for (const group of groups) {
|
|
216
|
+
line.push(group.getName());
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
if (this.shouldAddGroups && this.shouldAddProperties) {
|
|
220
|
+
const numOfBlankCells = headers.length - line.length;
|
|
221
|
+
for (let i = 0; i < numOfBlankCells; i++) {
|
|
222
|
+
line.push('');
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
if (this.shouldAddProperties) {
|
|
226
|
+
const properties = account.getProperties();
|
|
227
|
+
for (const key of propertyKeys) {
|
|
228
|
+
const propertyValue = properties[key];
|
|
229
|
+
if (propertyValue) {
|
|
230
|
+
line.push(propertyValue);
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
line.push('');
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
table.push(line);
|
|
237
|
+
}
|
|
238
|
+
if (this.shouldAddProperties) {
|
|
239
|
+
headers = headers.concat(propertyKeys);
|
|
240
|
+
}
|
|
241
|
+
table.unshift(headers);
|
|
242
|
+
convertInMatrix(table);
|
|
243
|
+
return table;
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
//# sourceMappingURL=AccountsDataTableBuilder.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Amount } from
|
|
2
|
-
import { BalanceType } from
|
|
1
|
+
import { Amount } from '../model/Amount.js';
|
|
2
|
+
import { BalanceType } from '../model/Enums.js';
|
|
3
3
|
import * as Utils from '../utils.js';
|
|
4
4
|
/**
|
|
5
5
|
* A BalancesDataTableBuilder is used to setup and build two-dimensional arrays containing balance information.
|
|
@@ -25,6 +25,7 @@ export class BalancesDataTableBuilder {
|
|
|
25
25
|
this.shouldPeriod = false;
|
|
26
26
|
this.shouldRaw = false;
|
|
27
27
|
this.shouldAddProperties = false;
|
|
28
|
+
this.shouldAddHiddenProperties = false;
|
|
28
29
|
}
|
|
29
30
|
getBalance(balance, permanent) {
|
|
30
31
|
return this.getRepresentativeBalance(balance, permanent).toNumber();
|
|
@@ -73,7 +74,7 @@ export class BalancesDataTableBuilder {
|
|
|
73
74
|
* @returns This builder with respective expanded option, for chaining.
|
|
74
75
|
*/
|
|
75
76
|
expanded(expanded) {
|
|
76
|
-
if (typeof expanded ==
|
|
77
|
+
if (typeof expanded == 'boolean' && expanded == true) {
|
|
77
78
|
this.maxDepth = 1;
|
|
78
79
|
this.skipRoot = true;
|
|
79
80
|
}
|
|
@@ -83,7 +84,7 @@ export class BalancesDataTableBuilder {
|
|
|
83
84
|
else if (expanded == -2) {
|
|
84
85
|
this.expandAllAccounts = true;
|
|
85
86
|
}
|
|
86
|
-
else if (typeof expanded ==
|
|
87
|
+
else if (typeof expanded == 'number' && expanded > 0) {
|
|
87
88
|
this.maxDepth = expanded;
|
|
88
89
|
}
|
|
89
90
|
return this;
|
|
@@ -188,6 +189,19 @@ export class BalancesDataTableBuilder {
|
|
|
188
189
|
this.shouldAddProperties = include;
|
|
189
190
|
return this;
|
|
190
191
|
}
|
|
192
|
+
/**
|
|
193
|
+
* Defines whether to include hidden properties (keys ending with underscore "_").
|
|
194
|
+
* Only relevant when {@link properties} is enabled.
|
|
195
|
+
* Default is false — hidden properties are excluded.
|
|
196
|
+
*
|
|
197
|
+
* @param include - Whether to include hidden properties
|
|
198
|
+
*
|
|
199
|
+
* @returns This builder with respective option, for chaining.
|
|
200
|
+
*/
|
|
201
|
+
hiddenProperties(include) {
|
|
202
|
+
this.shouldAddHiddenProperties = include;
|
|
203
|
+
return this;
|
|
204
|
+
}
|
|
191
205
|
/**
|
|
192
206
|
* Defines whether should split **TOTAL** [[BalanceType]] into debit and credit.
|
|
193
207
|
*
|
|
@@ -231,6 +245,9 @@ export class BalancesDataTableBuilder {
|
|
|
231
245
|
////////////////////////
|
|
232
246
|
addPropertyKeys(propertyKeys, container) {
|
|
233
247
|
for (const key of container.getPropertyKeys()) {
|
|
248
|
+
if (!this.shouldAddHiddenProperties && key.endsWith('_')) {
|
|
249
|
+
continue;
|
|
250
|
+
}
|
|
234
251
|
if (propertyKeys.indexOf(key) <= -1) {
|
|
235
252
|
propertyKeys.push(key);
|
|
236
253
|
}
|
|
@@ -309,7 +326,8 @@ export class BalancesDataTableBuilder {
|
|
|
309
326
|
let depth = container.getDepth();
|
|
310
327
|
if (depth <= this.maxDepth) {
|
|
311
328
|
if (!this.skipRoot && !this.shouldTranspose) {
|
|
312
|
-
container.payload.name =
|
|
329
|
+
container.payload.name =
|
|
330
|
+
Utils.repeatString(' ', depth * 4) + container.payload.name;
|
|
313
331
|
}
|
|
314
332
|
if (!this.skipRoot || depth != 0) {
|
|
315
333
|
containersFlat.push(container);
|
|
@@ -330,7 +348,8 @@ export class BalancesDataTableBuilder {
|
|
|
330
348
|
if (container.isFromGroup()) {
|
|
331
349
|
if (!this.shouldTranspose) {
|
|
332
350
|
let depth = container.getDepth();
|
|
333
|
-
container.payload.name =
|
|
351
|
+
container.payload.name =
|
|
352
|
+
Utils.repeatString(' ', depth * 4) + container.payload.name;
|
|
334
353
|
}
|
|
335
354
|
containersFlat.push(container);
|
|
336
355
|
if (this.shouldAddProperties) {
|
|
@@ -460,7 +479,7 @@ export class BalancesDataTableBuilder {
|
|
|
460
479
|
var dataIndexMap = new Object();
|
|
461
480
|
var cumulativeBalance = this.balanceType == BalanceType.CUMULATIVE;
|
|
462
481
|
var header = new Array();
|
|
463
|
-
header.push(
|
|
482
|
+
header.push('');
|
|
464
483
|
if (this.balancesContainers == null) {
|
|
465
484
|
return table;
|
|
466
485
|
}
|
|
@@ -486,7 +505,9 @@ export class BalancesDataTableBuilder {
|
|
|
486
505
|
else {
|
|
487
506
|
amount = balance.getPeriodBalanceRaw();
|
|
488
507
|
}
|
|
489
|
-
indexEntry[container.getName()] = this.shouldRaw
|
|
508
|
+
indexEntry[container.getName()] = this.shouldRaw
|
|
509
|
+
? amount
|
|
510
|
+
: this.getRepresentativeBalance(amount, container.isPermanent());
|
|
490
511
|
}
|
|
491
512
|
}
|
|
492
513
|
}
|
|
@@ -499,7 +520,7 @@ export class BalancesDataTableBuilder {
|
|
|
499
520
|
for (const container of containers) {
|
|
500
521
|
var amount = rowObject[container.getName()];
|
|
501
522
|
if (amount == null) {
|
|
502
|
-
amount =
|
|
523
|
+
amount = 'null_amount';
|
|
503
524
|
}
|
|
504
525
|
else {
|
|
505
526
|
amount = new Amount(amount);
|
|
@@ -514,7 +535,9 @@ export class BalancesDataTableBuilder {
|
|
|
514
535
|
}
|
|
515
536
|
rows.push(row);
|
|
516
537
|
}
|
|
517
|
-
rows.sort(function (a, b) {
|
|
538
|
+
rows.sort(function (a, b) {
|
|
539
|
+
return a[0].getTime() - b[0].getTime();
|
|
540
|
+
});
|
|
518
541
|
var lastRow = null;
|
|
519
542
|
for (var i = 0; i < rows.length; i++) {
|
|
520
543
|
var row = rows[i];
|
|
@@ -522,7 +545,7 @@ export class BalancesDataTableBuilder {
|
|
|
522
545
|
//first row, all null values will be 0
|
|
523
546
|
for (var j = 1; j < row.length; j++) {
|
|
524
547
|
var cell = row[j];
|
|
525
|
-
if (cell ==
|
|
548
|
+
if (cell == 'null_amount') {
|
|
526
549
|
var amount = new Amount(0);
|
|
527
550
|
if (this.shouldFormatValue) {
|
|
528
551
|
amount = Utils.formatValue(amount, this.book.getDecimalSeparator(), this.book.getFractionDigits());
|
|
@@ -537,12 +560,12 @@ export class BalancesDataTableBuilder {
|
|
|
537
560
|
else {
|
|
538
561
|
for (var j = 1; j < row.length; j++) {
|
|
539
562
|
var cell = row[j];
|
|
540
|
-
if (cell ==
|
|
563
|
+
if (cell == 'null_amount' && cumulativeBalance) {
|
|
541
564
|
if (lastRow) {
|
|
542
565
|
row[j] = lastRow[j];
|
|
543
566
|
}
|
|
544
567
|
}
|
|
545
|
-
else if (cell ==
|
|
568
|
+
else if (cell == 'null_amount') {
|
|
546
569
|
var amount = new Amount(0);
|
|
547
570
|
if (this.shouldFormatValue) {
|
|
548
571
|
amount = Utils.formatValue(amount, this.book.getDecimalSeparator(), this.book.getFractionDigits());
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { convertInMatrix } from '../utils.js';
|
|
2
|
+
/**
|
|
3
|
+
* A BooksDataTableBuilder is used to setup and build two-dimensional arrays containing books.
|
|
4
|
+
*
|
|
5
|
+
* @public
|
|
6
|
+
*/
|
|
7
|
+
export class BooksDataTableBuilder {
|
|
8
|
+
constructor(books) {
|
|
9
|
+
this.shouldAddProperties = false;
|
|
10
|
+
this.shouldAddIds = false;
|
|
11
|
+
this.shouldAddHiddenProperties = false;
|
|
12
|
+
this.propertyKeys = [];
|
|
13
|
+
this.books = books;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Defines whether to include custom book properties.
|
|
17
|
+
*
|
|
18
|
+
* @param include - Whether to include properties
|
|
19
|
+
*
|
|
20
|
+
* @returns This builder with respective include properties option, for chaining.
|
|
21
|
+
*/
|
|
22
|
+
properties(include) {
|
|
23
|
+
this.shouldAddProperties = include;
|
|
24
|
+
return this;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Defines whether to include book ids.
|
|
28
|
+
*
|
|
29
|
+
* @param include - Whether to include ids
|
|
30
|
+
*
|
|
31
|
+
* @returns This builder with respective include ids option, for chaining.
|
|
32
|
+
*/
|
|
33
|
+
ids(include) {
|
|
34
|
+
this.shouldAddIds = include;
|
|
35
|
+
return this;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Defines whether to include hidden properties (keys ending with underscore "_").
|
|
39
|
+
* Only relevant when {@link properties} is enabled.
|
|
40
|
+
* Default is false — hidden properties are excluded.
|
|
41
|
+
*
|
|
42
|
+
* @param include - Whether to include hidden properties
|
|
43
|
+
*
|
|
44
|
+
* @returns This builder with respective option, for chaining.
|
|
45
|
+
*/
|
|
46
|
+
hiddenProperties(include) {
|
|
47
|
+
this.shouldAddHiddenProperties = include;
|
|
48
|
+
return this;
|
|
49
|
+
}
|
|
50
|
+
mapPropertyKeys() {
|
|
51
|
+
this.propertyKeys = [];
|
|
52
|
+
for (const book of this.books) {
|
|
53
|
+
for (const key of book.getPropertyKeys()) {
|
|
54
|
+
if (!this.shouldAddHiddenProperties && key.endsWith('_')) {
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
if (this.propertyKeys.indexOf(key) <= -1) {
|
|
58
|
+
this.propertyKeys.push(key);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
this.propertyKeys = this.propertyKeys.sort();
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Builds a two-dimensional array containing all Books.
|
|
66
|
+
*
|
|
67
|
+
* @returns A two-dimensional array containing all Books
|
|
68
|
+
*/
|
|
69
|
+
build() {
|
|
70
|
+
var _a, _b;
|
|
71
|
+
const table = new Array();
|
|
72
|
+
this.books.sort((a, b) => {
|
|
73
|
+
var _a, _b;
|
|
74
|
+
const collA = (_a = a.getCollection()) === null || _a === void 0 ? void 0 : _a.getName();
|
|
75
|
+
const collB = (_b = b.getCollection()) === null || _b === void 0 ? void 0 : _b.getName();
|
|
76
|
+
// Books with collection before books without
|
|
77
|
+
if (collA && !collB)
|
|
78
|
+
return -1;
|
|
79
|
+
if (!collA && collB)
|
|
80
|
+
return 1;
|
|
81
|
+
let ret = (collA || '').localeCompare(collB || '');
|
|
82
|
+
if (ret === 0) {
|
|
83
|
+
ret = (a.getName() || '').localeCompare(b.getName() || '');
|
|
84
|
+
}
|
|
85
|
+
return ret;
|
|
86
|
+
});
|
|
87
|
+
let headers = [];
|
|
88
|
+
if (this.shouldAddIds) {
|
|
89
|
+
headers.push('Book Id');
|
|
90
|
+
}
|
|
91
|
+
headers.push('Name');
|
|
92
|
+
headers.push('Collection');
|
|
93
|
+
headers.push('Date Pattern');
|
|
94
|
+
headers.push('Decimal Separator');
|
|
95
|
+
headers.push('Fraction Digits');
|
|
96
|
+
headers.push('Period');
|
|
97
|
+
headers.push('Owner');
|
|
98
|
+
if (this.shouldAddProperties) {
|
|
99
|
+
this.mapPropertyKeys();
|
|
100
|
+
headers = headers.concat(this.propertyKeys);
|
|
101
|
+
}
|
|
102
|
+
for (const book of this.books) {
|
|
103
|
+
const line = [];
|
|
104
|
+
if (this.shouldAddIds) {
|
|
105
|
+
line.push(book.getId());
|
|
106
|
+
}
|
|
107
|
+
line.push(book.getName() || '');
|
|
108
|
+
line.push(((_a = book.getCollection()) === null || _a === void 0 ? void 0 : _a.getName()) || '');
|
|
109
|
+
line.push(book.getDatePattern() || '');
|
|
110
|
+
line.push(book.getDecimalSeparator() || '');
|
|
111
|
+
line.push((_b = book.getFractionDigits()) !== null && _b !== void 0 ? _b : '');
|
|
112
|
+
line.push(book.getPeriod() || '');
|
|
113
|
+
line.push(book.getOwnerName() || '');
|
|
114
|
+
if (this.shouldAddProperties) {
|
|
115
|
+
const properties = book.getProperties();
|
|
116
|
+
for (const key of this.propertyKeys) {
|
|
117
|
+
line.push(properties[key] || '');
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
table.push(line);
|
|
121
|
+
}
|
|
122
|
+
table.unshift(headers);
|
|
123
|
+
convertInMatrix(table);
|
|
124
|
+
return table;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=BooksDataTableBuilder.js.map
|