@tasenor/common-plugins 1.16.8 → 1.16.10
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/.turbo/turbo-build.log +1 -1
- package/.turbo/turbo-ci.log +2 -2
- package/data/FinnishIncomeStatementReportSociety.mjs +10 -0
- package/data/src/FinnishIncomeStatementReportSociety - income-statement-detailed-fi.tsv +73 -0
- package/data/src/FinnishIncomeStatementReportSociety - income-statement-fi.tsv +25 -0
- package/dist/FinnishIncomeStatementReportSociety/backend/index.d.ts +26 -0
- package/dist/FinnishIncomeStatementReportSociety/backend/index.js +220 -0
- package/dist/FinnishIncomeStatementReportSociety/backend/index.js.map +1 -0
- package/package.json +6 -6
- package/src/FinnishIncomeStatementReportSociety/backend/income-statement-society-detailed-fi.tsv +73 -0
- package/src/FinnishIncomeStatementReportSociety/backend/income-statement-society-fi.tsv +25 -0
- package/src/FinnishIncomeStatementReportSociety/backend/index.ts +235 -0
package/.turbo/turbo-build.log
CHANGED
package/.turbo/turbo-ci.log
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
|
|
2
|
-
> @tasenor/common-plugins@1.16.
|
|
2
|
+
> @tasenor/common-plugins@1.16.9 ci /home/ci/tasenor-qa/tasenor-bookkeeper/packages/tasenor-common-plugins
|
|
3
3
|
> pnpm run lint
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
> @tasenor/common-plugins@1.16.
|
|
6
|
+
> @tasenor/common-plugins@1.16.9 lint /home/ci/tasenor-qa/tasenor-bookkeeper/packages/tasenor-common-plugins
|
|
7
7
|
> eslint 'src/**/*.{ts,tsx}' 'data/**/*.mjs'
|
|
8
8
|
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env -S npx tsx
|
|
2
|
+
import commonNode from '@tasenor/common-node'
|
|
3
|
+
const { readFile, saveText, trimCRLF } = commonNode.dataUtils
|
|
4
|
+
|
|
5
|
+
let tsv
|
|
6
|
+
tsv = trimCRLF(readFile('FinnishIncomeStatementReportSociety - income-statement-fi.tsv'))
|
|
7
|
+
saveText('FinnishIncomeStatementReportSociety', 'income-statement-society-fi.tsv', tsv)
|
|
8
|
+
|
|
9
|
+
tsv = trimCRLF(readFile('FinnishIncomeStatementReportSociety - income-statement-detailed-fi.tsv'))
|
|
10
|
+
saveText('FinnishIncomeStatementReportSociety', 'income-statement-society-detailed-fi.tsv', tsv)
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# accounts title flags
|
|
2
|
+
3000-5000 8000-9000 Varsinainen toiminta HIDE_TOTAL REQUIRED BOLD
|
|
3
|
+
3000-4000 _Varsinainen toiminnan tuotot HIDE_TOTAL REQUIRED BOLD
|
|
4
|
+
3000-4000 __Varsinainen toiminnan tuotot DETAILS
|
|
5
|
+
3000-4000 _Varsinainen toiminnan tuotot yhteensä REQUIRED BOLD
|
|
6
|
+
4000-5000 _Varsinainen toiminnan kulut HIDE_TOTAL REQUIRED BOLD
|
|
7
|
+
4000-4200 __Henkilöstökulut HIDE_TOTAL BOLD
|
|
8
|
+
4000-4200 ___Henkilöstökulut DETAILS
|
|
9
|
+
4000-4200 __Henkilöstökulut yhteensä BOLD
|
|
10
|
+
8000-9000 __Poistot HIDE_TOTAL BOLD
|
|
11
|
+
8000-9000 ___Poistot DETAILS
|
|
12
|
+
8000-9000 __Poistot yhteensä BOLD
|
|
13
|
+
4200-5000 __Muut kulut HIDE_TOTAL BOLD
|
|
14
|
+
4200-4300 ___Toiminnan kulut HIDE_TOTAL BOLD
|
|
15
|
+
4200-4300 ____Toiminnan kulut DETAILS
|
|
16
|
+
4200-4300 ___Toiminnan kulut yhteensä BOLD
|
|
17
|
+
4300-4400 ___Henkilökunnan kulut HIDE_TOTAL BOLD
|
|
18
|
+
4300-4400 ____Henkilökunnan kulut DETAILS
|
|
19
|
+
4300-4400 ___Henkilökunnan kulut yhteensä BOLD
|
|
20
|
+
4400-4500 ___Toimitilakulut HIDE_TOTAL BOLD
|
|
21
|
+
4400-4500 ____Toimitilakulut DETAILS
|
|
22
|
+
4400-4500 ___Toimitilakulut yhteensä BOLD
|
|
23
|
+
4500-4600 ___Ajoneuvokulut HIDE_TOTAL BOLD
|
|
24
|
+
4500-4600 ____Ajoneuvokulut DETAILS
|
|
25
|
+
4500-4600 ___Ajoneuvokulut yhteensä BOLD
|
|
26
|
+
4600-4700 ___Kone- ja kalustokulut HIDE_TOTAL BOLD
|
|
27
|
+
4600-4700 ____Kone- ja kalustokulut DETAILS
|
|
28
|
+
4600-4700 ___Kone- ja kalustokulut yhteensä BOLD
|
|
29
|
+
4700-4800 ___Matkakulut HIDE_TOTAL BOLD
|
|
30
|
+
4700-4800 ____Matkakulut DETAILS
|
|
31
|
+
4700-4800 ___Matkakulut yhteensä BOLD
|
|
32
|
+
4800-4850 ___Markkinointikulut HIDE_TOTAL BOLD
|
|
33
|
+
4800-4850 ____Markkinointikulut DETAILS
|
|
34
|
+
4800-4850 ___Markkinointikulut yhteensä BOLD
|
|
35
|
+
4850-4900 ___Hallintopalvelut HIDE_TOTAL BOLD
|
|
36
|
+
4850-4900 ____Hallintopalvelut DETAILS
|
|
37
|
+
4850-4900 ___Hallintopalvelut yhteensä BOLD
|
|
38
|
+
4900-5000 ___Muut hallintokulut HIDE_TOTAL BOLD
|
|
39
|
+
4900-5000 ____Muut hallintokulut DETAILS
|
|
40
|
+
4900-5000 ___Muut hallintokulut yhteensä BOLD
|
|
41
|
+
4200-5000 __Muut kulut yhteensä BOLD
|
|
42
|
+
4000-5000 8000-9000 _Varsinainen toiminnan kulut yhteensä REQUIRED BOLD
|
|
43
|
+
3000-5000 8000-9000 Varsinainen toiminta yhteensä REQUIRED BOLD
|
|
44
|
+
3000-5000 8000-9000 Tuotto-/kulujäämä REQUIRED BOLD
|
|
45
|
+
5000-6000 Varainhankinta HIDE_TOTAL REQUIRED BOLD
|
|
46
|
+
5000-5050 _Varainhankinnan tuotot HIDE_TOTAL REQUIRED BOLD
|
|
47
|
+
5000-5050 __Varainhankinnan tuotot DETAILS
|
|
48
|
+
5000-5050 _Varainhankinnan tuotot yhteensä REQUIRED BOLD
|
|
49
|
+
5050-6000 _Varainhankinnan kulut HIDE_TOTAL REQUIRED BOLD
|
|
50
|
+
5050-6000 __Varainhankinnan kulut DETAILS
|
|
51
|
+
5050-6000 _Varainhankinnan kulut yhteensä REQUIRED BOLD
|
|
52
|
+
5000-6000 Varainhankinta yhteensä REQUIRED BOLD
|
|
53
|
+
3000-6000 8000-9000 Tuotto-/kulujäämä REQUIRED BOLD
|
|
54
|
+
6000-7000 Sijoitus- ja rahoitustoiminta HIDE_TOTAL REQUIRED BOLD
|
|
55
|
+
6000-7000 _Sijoitus- ja rahoitustoiminta DETAILS
|
|
56
|
+
6000-7000 Sijoitus- ja rahoitustoiminta yhteensä REQUIRED BOLD
|
|
57
|
+
3000-7000 8000-9000 Tuotto-/kulujäämä REQUIRED BOLD
|
|
58
|
+
7000-7500 Satunnaiset erät HIDE_TOTAL REQUIRED BOLD
|
|
59
|
+
7000-7500 _Satunnaiset erät DETAILS
|
|
60
|
+
7000-7500 Satunnaiset erät yhteensä REQUIRED BOLD
|
|
61
|
+
7500-8000 Yleisavustukset HIDE_TOTAL REQUIRED BOLD
|
|
62
|
+
7500-8000 _Yleisavustukset DETAILS
|
|
63
|
+
7500-8000 Yleisavustukset yhteensä REQUIRED BOLD
|
|
64
|
+
3000-9000 Tilikauden tulos REQUIRED BOLD
|
|
65
|
+
9000-9500 Tilinpäätössiirrot HIDE_TOTAL REQUIRED BOLD
|
|
66
|
+
9000-9010 _Poistoeron muutos HIDE_TOTAL BOLD
|
|
67
|
+
9000-9010 __Poistoeron muutos DETAILS
|
|
68
|
+
9000-9010 _Poistoeron muutos yhteensä BOLD
|
|
69
|
+
9010-9500 _Vapaaehtoisten varausten muutos HIDE_TOTAL BOLD
|
|
70
|
+
9010-9500 __Vapaaehtoisten varausten muutos DETAILS
|
|
71
|
+
9010-9500 _Vapaaehtoisten varausten muutos BOLD
|
|
72
|
+
9000-9500 Tilinpäätössiirrot yhteensä REQUIRED BOLD
|
|
73
|
+
3000-9999 Tilikauden ylijäämä (alijäämä) REQUIRED BOLD
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# accounts title flags
|
|
2
|
+
3000-5000 8000-9000 Varsinainen toiminta HIDE_TOTAL REQUIRED BOLD
|
|
3
|
+
3000-4000 _Tuotot REQUIRED
|
|
4
|
+
4000-5000 8000-9000 _Kulut REQUIRED
|
|
5
|
+
4000-4200 __Henkilöstökulut
|
|
6
|
+
8000-9000 __Poistot
|
|
7
|
+
4200-5000 __Muut kulut
|
|
8
|
+
3000-5000 8000-9000 Tuotto-/kulujäämä REQUIRED BOLD
|
|
9
|
+
5000-6000 Varainhankinta HIDE_TOTAL REQUIRED BOLD
|
|
10
|
+
5000-5050 _Tuotot REQUIRED
|
|
11
|
+
5050-6000 _Kulut REQUIRED
|
|
12
|
+
3000-6000 8000-9000 Tuotto-/kulujäämä REQUIRED BOLD
|
|
13
|
+
6000-7000 Sijoitus- ja rahoitustoiminta HIDE_TOTAL REQUIRED BOLD
|
|
14
|
+
6000-6100 _Tuotot REQUIRED
|
|
15
|
+
6100-7000 _Kulut REQUIRED
|
|
16
|
+
3000-7000 8000-9000 Tuotto-/kulujäämä REQUIRED BOLD
|
|
17
|
+
7000-7500 Satunnaiset erät HIDE_TOTAL REQUIRED BOLD
|
|
18
|
+
7000-7100 _Satunnaiset tuotot REQUIRED
|
|
19
|
+
7100-7500 _Satunnaiset kulut REQUIRED
|
|
20
|
+
7500-8000 Yleisavustukset REQUIRED BOLD
|
|
21
|
+
3000-9000 Tilikauden tulos REQUIRED BOLD
|
|
22
|
+
9000-9500 Tilinpäätössiirrot REQUIRED BOLD
|
|
23
|
+
9000-9010 _Poistoeron muutos REQUIRED
|
|
24
|
+
9010-9500 _Vapaaehtoisten varausten muutos REQUIRED
|
|
25
|
+
3000-9999 Tilikauden ylijäämä (alijäämä) REQUIRED BOLD
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Language, ReportOptions } from '@tasenor/common';
|
|
2
|
+
import { ReportPlugin } from '@tasenor/common-node';
|
|
3
|
+
declare class FinnishIncomeStatementReportSociety extends ReportPlugin {
|
|
4
|
+
constructor();
|
|
5
|
+
forceOptions(options: any): {
|
|
6
|
+
negateAssetAndProfit: boolean;
|
|
7
|
+
addPreviousPeriod: boolean;
|
|
8
|
+
};
|
|
9
|
+
getLanguages(): Language[];
|
|
10
|
+
getReportOptions(): ReportOptions;
|
|
11
|
+
/**
|
|
12
|
+
* Construct column title for period.
|
|
13
|
+
* @param formatName
|
|
14
|
+
* @param period
|
|
15
|
+
* @param settings
|
|
16
|
+
*/
|
|
17
|
+
columnTitle(id: any, period: any, options: any): string;
|
|
18
|
+
getColumns(id: any, entries: any, options: any, settings: any): Promise<any>;
|
|
19
|
+
preProcessByTags(id: any, entries: any, options: any, settings: any, columns: any): import("@tasenor/common").ReportLine[];
|
|
20
|
+
preProcess(id: any, entries: any, options: any, settings: any, columns: any): Promise<import("@tasenor/common").ReportLine[]>;
|
|
21
|
+
/**
|
|
22
|
+
* Remove empty columns if report made by tags.
|
|
23
|
+
*/
|
|
24
|
+
postProcess(id: any, data: any, options: any, settings: any, columns: any): Promise<any>;
|
|
25
|
+
}
|
|
26
|
+
export default FinnishIncomeStatementReportSociety;
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import { ReportPlugin } from '@tasenor/common-node';
|
|
2
|
+
import dayjs from 'dayjs';
|
|
3
|
+
import quarterOfYear from 'dayjs/plugin/quarterOfYear';
|
|
4
|
+
dayjs.extend(quarterOfYear);
|
|
5
|
+
class FinnishIncomeStatementReportSociety extends ReportPlugin {
|
|
6
|
+
constructor() {
|
|
7
|
+
super('income-statement-society-detailed', 'income-statement-society');
|
|
8
|
+
this.schemes = new Set(['FinnishSociety']);
|
|
9
|
+
this.code = 'FinnishIncomeStatementReportSociety';
|
|
10
|
+
this.title = 'Income Statement Report (Finnish - Society)';
|
|
11
|
+
this.version = '1.0.0';
|
|
12
|
+
this.icon = '<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><g><path d="M0,0h24v24H0V0z" fill="none"/></g><g><g><path d="M14,5H5v14h14v-9h-5V5z M8,17c-0.55,0-1-0.45-1-1s0.45-1,1-1s1,0.45,1,1S8.55,17,8,17z M8,13 c-0.55,0-1-0.45-1-1s0.45-1,1-1s1,0.45,1,1S8.55,13,8,13z M8,9C7.45,9,7,8.55,7,8s0.45-1,1-1s1,0.45,1,1S8.55,9,8,9z" opacity=".3"/><circle cx="8" cy="8" r="1"/><path d="M15,3H5C3.9,3,3.01,3.9,3.01,5L3,19c0,1.1,0.89,2,1.99,2H19c1.1,0,2-0.9,2-2V9L15,3z M19,19H5V5h9v5h5V19z"/><circle cx="8" cy="12" r="1"/><circle cx="8" cy="16" r="1"/></g></g></svg>';
|
|
13
|
+
this.releaseDate = '2025-11-27';
|
|
14
|
+
this.use = 'backend';
|
|
15
|
+
this.type = 'report';
|
|
16
|
+
this.description = 'Income statement report for Finnish societies, i.e. rekisteröity yhdistys.';
|
|
17
|
+
this.languages = {
|
|
18
|
+
en: {
|
|
19
|
+
'report-income-statement-society-detailed': 'Detailed income statement',
|
|
20
|
+
'report-income-statement-society': 'Income statement'
|
|
21
|
+
},
|
|
22
|
+
fi: {
|
|
23
|
+
'report-income-statement-society-detailed': 'Tuloslaskelma tilierittelyin',
|
|
24
|
+
'report-income-statement-society': 'Tuloslaskelma'
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
forceOptions(options) {
|
|
29
|
+
return {
|
|
30
|
+
negateAssetAndProfit: true,
|
|
31
|
+
addPreviousPeriod: !options.byTags
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
getLanguages() {
|
|
35
|
+
return ['fi'];
|
|
36
|
+
}
|
|
37
|
+
getReportOptions() {
|
|
38
|
+
return {
|
|
39
|
+
month1: 'radio:1',
|
|
40
|
+
month2: 'radio:1',
|
|
41
|
+
quarter1: 'radio:1',
|
|
42
|
+
month4: 'radio:1',
|
|
43
|
+
month5: 'radio:1',
|
|
44
|
+
quarter2: 'radio:1',
|
|
45
|
+
month7: 'radio:1',
|
|
46
|
+
month8: 'radio:1',
|
|
47
|
+
quarter3: 'radio:1',
|
|
48
|
+
month10: 'radio:1',
|
|
49
|
+
month11: 'radio:1',
|
|
50
|
+
full: 'radio:1:default',
|
|
51
|
+
byTags: 'boolean'
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Construct column title for period.
|
|
56
|
+
* @param formatName
|
|
57
|
+
* @param period
|
|
58
|
+
* @param settings
|
|
59
|
+
*/
|
|
60
|
+
columnTitle(id, period, options) {
|
|
61
|
+
const start = this.time2str(period.start_date);
|
|
62
|
+
const year = dayjs(period.start_date).year();
|
|
63
|
+
let end;
|
|
64
|
+
if (options.month1) {
|
|
65
|
+
end = `{${dayjs(`${year}-02-01`).subtract(1, 'day').format('YYYY-MM-DD')}}`;
|
|
66
|
+
}
|
|
67
|
+
else if (options.month2) {
|
|
68
|
+
end = `{${dayjs(`${year}-03-01`).subtract(1, 'day').format('YYYY-MM-DD')}}`;
|
|
69
|
+
}
|
|
70
|
+
else if (options.month4) {
|
|
71
|
+
end = `{${dayjs(`${year}-05-01`).subtract(1, 'day').format('YYYY-MM-DD')}}`;
|
|
72
|
+
}
|
|
73
|
+
else if (options.month5) {
|
|
74
|
+
end = `{${dayjs(`${year}-06-01`).subtract(1, 'day').format('YYYY-MM-DD')}}`;
|
|
75
|
+
}
|
|
76
|
+
else if (options.month7) {
|
|
77
|
+
end = `{${dayjs(`${year}-08-01`).subtract(1, 'day').format('YYYY-MM-DD')}}`;
|
|
78
|
+
}
|
|
79
|
+
else if (options.month8) {
|
|
80
|
+
end = `{${dayjs(`${year}-09-01`).subtract(1, 'day').format('YYYY-MM-DD')}}`;
|
|
81
|
+
}
|
|
82
|
+
else if (options.month10) {
|
|
83
|
+
end = `{${dayjs(`${year}-11-01`).subtract(1, 'day').format('YYYY-MM-DD')}}`;
|
|
84
|
+
}
|
|
85
|
+
else if (options.month11) {
|
|
86
|
+
end = `{${dayjs(`${year}-12-01`).subtract(1, 'day').format('YYYY-MM-DD')}}`;
|
|
87
|
+
}
|
|
88
|
+
else if (options.quarter1) {
|
|
89
|
+
end = `{${dayjs(`${year}-04-01`).subtract(1, 'day').format('YYYY-MM-DD')}}`;
|
|
90
|
+
}
|
|
91
|
+
else if (options.quarter2) {
|
|
92
|
+
end = `{${dayjs(`${year}-07-01`).subtract(1, 'day').format('YYYY-MM-DD')}}`;
|
|
93
|
+
}
|
|
94
|
+
else if (options.quarter3) {
|
|
95
|
+
end = `{${dayjs(`${year}-10-01`).subtract(1, 'day').format('YYYY-MM-DD')}}`;
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
end = `{${this.time2str(period.end_date)}}`;
|
|
99
|
+
}
|
|
100
|
+
return '{' + start + '} — {' + end + '}';
|
|
101
|
+
}
|
|
102
|
+
async getColumns(id, entries, options, settings) {
|
|
103
|
+
// Construct columns for each tag and extra column for non-tagged.
|
|
104
|
+
if (options.byTags) {
|
|
105
|
+
const columns = settings.tags.map((tag) => ({
|
|
106
|
+
type: 'currency',
|
|
107
|
+
name: `tag-${tag.tag}`,
|
|
108
|
+
title: tag.name
|
|
109
|
+
}));
|
|
110
|
+
columns.push({
|
|
111
|
+
type: 'currency',
|
|
112
|
+
name: 'other',
|
|
113
|
+
title: '{Other}'
|
|
114
|
+
});
|
|
115
|
+
columns.unshift({
|
|
116
|
+
name: 'title',
|
|
117
|
+
title: '',
|
|
118
|
+
type: 'name'
|
|
119
|
+
});
|
|
120
|
+
return columns;
|
|
121
|
+
}
|
|
122
|
+
return super.getColumns(id, entries, options, settings);
|
|
123
|
+
}
|
|
124
|
+
preProcessByTags(id, entries, options, settings, columns) {
|
|
125
|
+
// Prepapre.
|
|
126
|
+
const columnNames = columns.map((col) => col.name);
|
|
127
|
+
const tagSet = new Set(settings.tags.map(t => t.tag));
|
|
128
|
+
// Summarize all totals from the entries.
|
|
129
|
+
const totals = {};
|
|
130
|
+
columnNames.forEach((column) => (totals[column] = {}));
|
|
131
|
+
const accountNames = {};
|
|
132
|
+
const accountNumbers = new Set();
|
|
133
|
+
const regex = /^((\[\w+\])+)/;
|
|
134
|
+
entries.forEach((entry) => {
|
|
135
|
+
let shares = [];
|
|
136
|
+
const r = regex.exec(entry.description);
|
|
137
|
+
if (r) {
|
|
138
|
+
shares = r[1].substr(1, r[1].length - 2).split('][').filter(t => tagSet.has(t));
|
|
139
|
+
}
|
|
140
|
+
let amount = entry.amount;
|
|
141
|
+
if (shares.length) {
|
|
142
|
+
// Share the amount so that rounding errors are split.
|
|
143
|
+
const piece = amount < 0 ? Math.ceil(amount / shares.length) : Math.floor(amount / shares.length);
|
|
144
|
+
shares.forEach((tag) => {
|
|
145
|
+
const column = `tag-${tag}`;
|
|
146
|
+
totals[column][entry.number] = totals[column][entry.number] || 0;
|
|
147
|
+
totals[column][entry.number] += piece;
|
|
148
|
+
amount -= piece;
|
|
149
|
+
});
|
|
150
|
+
if (amount) {
|
|
151
|
+
// Make semi-random starting point and distribute cents.
|
|
152
|
+
let i = (entry.periodId) % shares.length;
|
|
153
|
+
const delta = amount < 0 ? -1 : 1;
|
|
154
|
+
for (let count = Math.abs(amount); count > 0; count--) {
|
|
155
|
+
const column = `tag-${shares[i]}`;
|
|
156
|
+
totals[column][entry.number] += delta;
|
|
157
|
+
amount -= delta;
|
|
158
|
+
i = (i + 1) % shares.length;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
if (amount) {
|
|
163
|
+
totals.other[entry.number] = totals.other[entry.number] || 0;
|
|
164
|
+
totals.other[entry.number] += amount;
|
|
165
|
+
}
|
|
166
|
+
accountNames[entry.number] = entry.name;
|
|
167
|
+
accountNumbers.add(entry.number);
|
|
168
|
+
});
|
|
169
|
+
return this.parseAndCombineReport([...accountNumbers], accountNames, columns, options.format, totals);
|
|
170
|
+
}
|
|
171
|
+
async preProcess(id, entries, options, settings, columns) {
|
|
172
|
+
if (options.byTags) {
|
|
173
|
+
return this.preProcessByTags(id, entries, options, settings, columns);
|
|
174
|
+
}
|
|
175
|
+
const columnNames = columns.map((col) => col.name);
|
|
176
|
+
// Summarize all totals from the entries.
|
|
177
|
+
const totals = {};
|
|
178
|
+
columnNames.forEach((column) => (totals[column] = {}));
|
|
179
|
+
const accountNames = {};
|
|
180
|
+
const accountNumbers = new Set();
|
|
181
|
+
entries.forEach((entry) => {
|
|
182
|
+
const column = 'period' + entry.periodId;
|
|
183
|
+
totals[column][entry.number] = totals[column][entry.number] || 0;
|
|
184
|
+
totals[column][entry.number] += entry.amount;
|
|
185
|
+
accountNames[entry.number] = entry.name;
|
|
186
|
+
accountNumbers.add(entry.number);
|
|
187
|
+
});
|
|
188
|
+
return this.parseAndCombineReport([...accountNumbers], accountNames, columns, options.format, totals);
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Remove empty columns if report made by tags.
|
|
192
|
+
*/
|
|
193
|
+
async postProcess(id, data, options, settings, columns) {
|
|
194
|
+
if (!options.byTags) {
|
|
195
|
+
return data;
|
|
196
|
+
}
|
|
197
|
+
// Find empty columns.
|
|
198
|
+
const found = new Set();
|
|
199
|
+
for (const line of data) {
|
|
200
|
+
if (!line.values) {
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
for (const [k, v] of Object.entries(line.values)) {
|
|
204
|
+
if (v !== null && !isNaN(v)) {
|
|
205
|
+
found.add(k);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
// Remove empty columns.
|
|
210
|
+
for (let i = 0; i < columns.length; i++) {
|
|
211
|
+
if ((columns[i].type === 'currency' || columns[i].type === 'numeric') && !found.has(columns[i].name)) {
|
|
212
|
+
columns.splice(i, 1);
|
|
213
|
+
i--;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return data;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
export default FinnishIncomeStatementReportSociety;
|
|
220
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/FinnishIncomeStatementReportSociety/backend/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tasenor/common-plugins",
|
|
3
|
-
"version": "1.16.
|
|
3
|
+
"version": "1.16.10",
|
|
4
4
|
"description": "Shared common plugins of Tasenor project",
|
|
5
5
|
"repository": "git@github.com:dataplugoy/tasenor-bookkeeper.git",
|
|
6
6
|
"author": "Tommi Ronkainen <tommi.ronkainen@gmail.com>",
|
|
@@ -13,9 +13,9 @@
|
|
|
13
13
|
"dayjs": "1.10.8",
|
|
14
14
|
"sprintf-js": "^1.1.2",
|
|
15
15
|
"tsx": "^4.7.0",
|
|
16
|
-
"@tasenor/common": "1.16.
|
|
17
|
-
"@tasenor/common
|
|
18
|
-
"@tasenor/common-ui": "1.16.
|
|
16
|
+
"@tasenor/common-node": "1.16.10",
|
|
17
|
+
"@tasenor/common": "1.16.10",
|
|
18
|
+
"@tasenor/common-ui": "1.16.10"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
21
|
"@mui/icons-material": "^5.14.1",
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
"react-i18next": "^14.0.5",
|
|
32
32
|
"react-router-dom": "^6.14.1",
|
|
33
33
|
"typescript": "^5.1.6",
|
|
34
|
-
"
|
|
35
|
-
"
|
|
34
|
+
"eslint-config-tasenor": "0.0.0",
|
|
35
|
+
"@tasenor/config": "1.16.10"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
38
|
"@mui/icons-material": "^5.14.1",
|
package/src/FinnishIncomeStatementReportSociety/backend/income-statement-society-detailed-fi.tsv
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# accounts title flags
|
|
2
|
+
3000-5000 8000-9000 Varsinainen toiminta HIDE_TOTAL REQUIRED BOLD
|
|
3
|
+
3000-4000 _Varsinainen toiminnan tuotot HIDE_TOTAL REQUIRED BOLD
|
|
4
|
+
3000-4000 __Varsinainen toiminnan tuotot DETAILS
|
|
5
|
+
3000-4000 _Varsinainen toiminnan tuotot yhteensä REQUIRED BOLD
|
|
6
|
+
4000-5000 _Varsinainen toiminnan kulut HIDE_TOTAL REQUIRED BOLD
|
|
7
|
+
4000-4200 __Henkilöstökulut HIDE_TOTAL BOLD
|
|
8
|
+
4000-4200 ___Henkilöstökulut DETAILS
|
|
9
|
+
4000-4200 __Henkilöstökulut yhteensä BOLD
|
|
10
|
+
8000-9000 __Poistot HIDE_TOTAL BOLD
|
|
11
|
+
8000-9000 ___Poistot DETAILS
|
|
12
|
+
8000-9000 __Poistot yhteensä BOLD
|
|
13
|
+
4200-5000 __Muut kulut HIDE_TOTAL BOLD
|
|
14
|
+
4200-4300 ___Toiminnan kulut HIDE_TOTAL BOLD
|
|
15
|
+
4200-4300 ____Toiminnan kulut DETAILS
|
|
16
|
+
4200-4300 ___Toiminnan kulut yhteensä BOLD
|
|
17
|
+
4300-4400 ___Henkilökunnan kulut HIDE_TOTAL BOLD
|
|
18
|
+
4300-4400 ____Henkilökunnan kulut DETAILS
|
|
19
|
+
4300-4400 ___Henkilökunnan kulut yhteensä BOLD
|
|
20
|
+
4400-4500 ___Toimitilakulut HIDE_TOTAL BOLD
|
|
21
|
+
4400-4500 ____Toimitilakulut DETAILS
|
|
22
|
+
4400-4500 ___Toimitilakulut yhteensä BOLD
|
|
23
|
+
4500-4600 ___Ajoneuvokulut HIDE_TOTAL BOLD
|
|
24
|
+
4500-4600 ____Ajoneuvokulut DETAILS
|
|
25
|
+
4500-4600 ___Ajoneuvokulut yhteensä BOLD
|
|
26
|
+
4600-4700 ___Kone- ja kalustokulut HIDE_TOTAL BOLD
|
|
27
|
+
4600-4700 ____Kone- ja kalustokulut DETAILS
|
|
28
|
+
4600-4700 ___Kone- ja kalustokulut yhteensä BOLD
|
|
29
|
+
4700-4800 ___Matkakulut HIDE_TOTAL BOLD
|
|
30
|
+
4700-4800 ____Matkakulut DETAILS
|
|
31
|
+
4700-4800 ___Matkakulut yhteensä BOLD
|
|
32
|
+
4800-4850 ___Markkinointikulut HIDE_TOTAL BOLD
|
|
33
|
+
4800-4850 ____Markkinointikulut DETAILS
|
|
34
|
+
4800-4850 ___Markkinointikulut yhteensä BOLD
|
|
35
|
+
4850-4900 ___Hallintopalvelut HIDE_TOTAL BOLD
|
|
36
|
+
4850-4900 ____Hallintopalvelut DETAILS
|
|
37
|
+
4850-4900 ___Hallintopalvelut yhteensä BOLD
|
|
38
|
+
4900-5000 ___Muut hallintokulut HIDE_TOTAL BOLD
|
|
39
|
+
4900-5000 ____Muut hallintokulut DETAILS
|
|
40
|
+
4900-5000 ___Muut hallintokulut yhteensä BOLD
|
|
41
|
+
4200-5000 __Muut kulut yhteensä BOLD
|
|
42
|
+
4000-5000 8000-9000 _Varsinainen toiminnan kulut yhteensä REQUIRED BOLD
|
|
43
|
+
3000-5000 8000-9000 Varsinainen toiminta yhteensä REQUIRED BOLD
|
|
44
|
+
3000-5000 8000-9000 Tuotto-/kulujäämä REQUIRED BOLD
|
|
45
|
+
5000-6000 Varainhankinta HIDE_TOTAL REQUIRED BOLD
|
|
46
|
+
5000-5050 _Varainhankinnan tuotot HIDE_TOTAL REQUIRED BOLD
|
|
47
|
+
5000-5050 __Varainhankinnan tuotot DETAILS
|
|
48
|
+
5000-5050 _Varainhankinnan tuotot yhteensä REQUIRED BOLD
|
|
49
|
+
5050-6000 _Varainhankinnan kulut HIDE_TOTAL REQUIRED BOLD
|
|
50
|
+
5050-6000 __Varainhankinnan kulut DETAILS
|
|
51
|
+
5050-6000 _Varainhankinnan kulut yhteensä REQUIRED BOLD
|
|
52
|
+
5000-6000 Varainhankinta yhteensä REQUIRED BOLD
|
|
53
|
+
3000-6000 8000-9000 Tuotto-/kulujäämä REQUIRED BOLD
|
|
54
|
+
6000-7000 Sijoitus- ja rahoitustoiminta HIDE_TOTAL REQUIRED BOLD
|
|
55
|
+
6000-7000 _Sijoitus- ja rahoitustoiminta DETAILS
|
|
56
|
+
6000-7000 Sijoitus- ja rahoitustoiminta yhteensä REQUIRED BOLD
|
|
57
|
+
3000-7000 8000-9000 Tuotto-/kulujäämä REQUIRED BOLD
|
|
58
|
+
7000-7500 Satunnaiset erät HIDE_TOTAL REQUIRED BOLD
|
|
59
|
+
7000-7500 _Satunnaiset erät DETAILS
|
|
60
|
+
7000-7500 Satunnaiset erät yhteensä REQUIRED BOLD
|
|
61
|
+
7500-8000 Yleisavustukset HIDE_TOTAL REQUIRED BOLD
|
|
62
|
+
7500-8000 _Yleisavustukset DETAILS
|
|
63
|
+
7500-8000 Yleisavustukset yhteensä REQUIRED BOLD
|
|
64
|
+
3000-9000 Tilikauden tulos REQUIRED BOLD
|
|
65
|
+
9000-9500 Tilinpäätössiirrot HIDE_TOTAL REQUIRED BOLD
|
|
66
|
+
9000-9010 _Poistoeron muutos HIDE_TOTAL BOLD
|
|
67
|
+
9000-9010 __Poistoeron muutos DETAILS
|
|
68
|
+
9000-9010 _Poistoeron muutos yhteensä BOLD
|
|
69
|
+
9010-9500 _Vapaaehtoisten varausten muutos HIDE_TOTAL BOLD
|
|
70
|
+
9010-9500 __Vapaaehtoisten varausten muutos DETAILS
|
|
71
|
+
9010-9500 _Vapaaehtoisten varausten muutos BOLD
|
|
72
|
+
9000-9500 Tilinpäätössiirrot yhteensä REQUIRED BOLD
|
|
73
|
+
3000-9999 Tilikauden ylijäämä (alijäämä) REQUIRED BOLD
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# accounts title flags
|
|
2
|
+
3000-5000 8000-9000 Varsinainen toiminta HIDE_TOTAL REQUIRED BOLD
|
|
3
|
+
3000-4000 _Tuotot REQUIRED
|
|
4
|
+
4000-5000 8000-9000 _Kulut REQUIRED
|
|
5
|
+
4000-4200 __Henkilöstökulut
|
|
6
|
+
8000-9000 __Poistot
|
|
7
|
+
4200-5000 __Muut kulut
|
|
8
|
+
3000-5000 8000-9000 Tuotto-/kulujäämä REQUIRED BOLD
|
|
9
|
+
5000-6000 Varainhankinta HIDE_TOTAL REQUIRED BOLD
|
|
10
|
+
5000-5050 _Tuotot REQUIRED
|
|
11
|
+
5050-6000 _Kulut REQUIRED
|
|
12
|
+
3000-6000 8000-9000 Tuotto-/kulujäämä REQUIRED BOLD
|
|
13
|
+
6000-7000 Sijoitus- ja rahoitustoiminta HIDE_TOTAL REQUIRED BOLD
|
|
14
|
+
6000-6100 _Tuotot REQUIRED
|
|
15
|
+
6100-7000 _Kulut REQUIRED
|
|
16
|
+
3000-7000 8000-9000 Tuotto-/kulujäämä REQUIRED BOLD
|
|
17
|
+
7000-7500 Satunnaiset erät HIDE_TOTAL REQUIRED BOLD
|
|
18
|
+
7000-7100 _Satunnaiset tuotot REQUIRED
|
|
19
|
+
7100-7500 _Satunnaiset kulut REQUIRED
|
|
20
|
+
7500-8000 Yleisavustukset REQUIRED BOLD
|
|
21
|
+
3000-9000 Tilikauden tulos REQUIRED BOLD
|
|
22
|
+
9000-9500 Tilinpäätössiirrot REQUIRED BOLD
|
|
23
|
+
9000-9010 _Poistoeron muutos REQUIRED
|
|
24
|
+
9010-9500 _Vapaaehtoisten varausten muutos REQUIRED
|
|
25
|
+
3000-9999 Tilikauden ylijäämä (alijäämä) REQUIRED BOLD
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import { AccountNumber, Language, PluginCode, ReportID, ReportOptions, Version } from '@tasenor/common'
|
|
2
|
+
import { ReportPlugin } from '@tasenor/common-node'
|
|
3
|
+
import dayjs from 'dayjs'
|
|
4
|
+
import quarterOfYear from 'dayjs/plugin/quarterOfYear'
|
|
5
|
+
dayjs.extend(quarterOfYear)
|
|
6
|
+
|
|
7
|
+
class FinnishIncomeStatementReportSociety extends ReportPlugin {
|
|
8
|
+
|
|
9
|
+
constructor() {
|
|
10
|
+
super('income-statement-society-detailed' as ReportID, 'income-statement-society' as ReportID)
|
|
11
|
+
|
|
12
|
+
this.schemes = new Set(['FinnishSociety'])
|
|
13
|
+
|
|
14
|
+
this.code = 'FinnishIncomeStatementReportSociety' as PluginCode
|
|
15
|
+
this.title = 'Income Statement Report (Finnish - Society)'
|
|
16
|
+
this.version = '1.0.0' as Version
|
|
17
|
+
this.icon = '<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><g><path d="M0,0h24v24H0V0z" fill="none"/></g><g><g><path d="M14,5H5v14h14v-9h-5V5z M8,17c-0.55,0-1-0.45-1-1s0.45-1,1-1s1,0.45,1,1S8.55,17,8,17z M8,13 c-0.55,0-1-0.45-1-1s0.45-1,1-1s1,0.45,1,1S8.55,13,8,13z M8,9C7.45,9,7,8.55,7,8s0.45-1,1-1s1,0.45,1,1S8.55,9,8,9z" opacity=".3"/><circle cx="8" cy="8" r="1"/><path d="M15,3H5C3.9,3,3.01,3.9,3.01,5L3,19c0,1.1,0.89,2,1.99,2H19c1.1,0,2-0.9,2-2V9L15,3z M19,19H5V5h9v5h5V19z"/><circle cx="8" cy="12" r="1"/><circle cx="8" cy="16" r="1"/></g></g></svg>'
|
|
18
|
+
this.releaseDate = '2025-11-27'
|
|
19
|
+
this.use = 'backend'
|
|
20
|
+
this.type = 'report'
|
|
21
|
+
this.description = 'Income statement report for Finnish societies, i.e. rekisteröity yhdistys.'
|
|
22
|
+
|
|
23
|
+
this.languages = {
|
|
24
|
+
en: {
|
|
25
|
+
'report-income-statement-society-detailed': 'Detailed income statement',
|
|
26
|
+
'report-income-statement-society': 'Income statement'
|
|
27
|
+
},
|
|
28
|
+
fi: {
|
|
29
|
+
'report-income-statement-society-detailed': 'Tuloslaskelma tilierittelyin',
|
|
30
|
+
'report-income-statement-society': 'Tuloslaskelma'
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
forceOptions(options) {
|
|
36
|
+
return {
|
|
37
|
+
negateAssetAndProfit: true,
|
|
38
|
+
addPreviousPeriod: !options.byTags
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
getLanguages(): Language[] {
|
|
43
|
+
return ['fi']
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
getReportOptions(): ReportOptions {
|
|
47
|
+
return {
|
|
48
|
+
month1: 'radio:1',
|
|
49
|
+
month2: 'radio:1',
|
|
50
|
+
quarter1: 'radio:1',
|
|
51
|
+
month4: 'radio:1',
|
|
52
|
+
month5: 'radio:1',
|
|
53
|
+
quarter2: 'radio:1',
|
|
54
|
+
month7: 'radio:1',
|
|
55
|
+
month8: 'radio:1',
|
|
56
|
+
quarter3: 'radio:1',
|
|
57
|
+
month10: 'radio:1',
|
|
58
|
+
month11: 'radio:1',
|
|
59
|
+
full: 'radio:1:default',
|
|
60
|
+
byTags: 'boolean'
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Construct column title for period.
|
|
66
|
+
* @param formatName
|
|
67
|
+
* @param period
|
|
68
|
+
* @param settings
|
|
69
|
+
*/
|
|
70
|
+
columnTitle(id, period, options) {
|
|
71
|
+
const start = this.time2str(period.start_date)
|
|
72
|
+
const year = dayjs(period.start_date).year()
|
|
73
|
+
let end
|
|
74
|
+
|
|
75
|
+
if (options.month1) {
|
|
76
|
+
end = `{${dayjs(`${year}-02-01`).subtract(1, 'day').format('YYYY-MM-DD')}}`
|
|
77
|
+
} else if (options.month2) {
|
|
78
|
+
end = `{${dayjs(`${year}-03-01`).subtract(1, 'day').format('YYYY-MM-DD')}}`
|
|
79
|
+
} else if (options.month4) {
|
|
80
|
+
end = `{${dayjs(`${year}-05-01`).subtract(1, 'day').format('YYYY-MM-DD')}}`
|
|
81
|
+
} else if (options.month5) {
|
|
82
|
+
end = `{${dayjs(`${year}-06-01`).subtract(1, 'day').format('YYYY-MM-DD')}}`
|
|
83
|
+
} else if (options.month7) {
|
|
84
|
+
end = `{${dayjs(`${year}-08-01`).subtract(1, 'day').format('YYYY-MM-DD')}}`
|
|
85
|
+
} else if (options.month8) {
|
|
86
|
+
end = `{${dayjs(`${year}-09-01`).subtract(1, 'day').format('YYYY-MM-DD')}}`
|
|
87
|
+
} else if (options.month10) {
|
|
88
|
+
end = `{${dayjs(`${year}-11-01`).subtract(1, 'day').format('YYYY-MM-DD')}}`
|
|
89
|
+
} else if (options.month11) {
|
|
90
|
+
end = `{${dayjs(`${year}-12-01`).subtract(1, 'day').format('YYYY-MM-DD')}}`
|
|
91
|
+
} else if (options.quarter1) {
|
|
92
|
+
end = `{${dayjs(`${year}-04-01`).subtract(1, 'day').format('YYYY-MM-DD')}}`
|
|
93
|
+
} else if (options.quarter2) {
|
|
94
|
+
end = `{${dayjs(`${year}-07-01`).subtract(1, 'day').format('YYYY-MM-DD')}}`
|
|
95
|
+
} else if (options.quarter3) {
|
|
96
|
+
end = `{${dayjs(`${year}-10-01`).subtract(1, 'day').format('YYYY-MM-DD')}}`
|
|
97
|
+
} else {
|
|
98
|
+
end = `{${this.time2str(period.end_date)}}`
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return '{' + start + '} — {' + end + '}'
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
async getColumns(id, entries, options, settings) {
|
|
105
|
+
// Construct columns for each tag and extra column for non-tagged.
|
|
106
|
+
if (options.byTags) {
|
|
107
|
+
const columns = settings.tags.map((tag) => ({
|
|
108
|
+
type: 'currency',
|
|
109
|
+
name: `tag-${tag.tag}`,
|
|
110
|
+
title: tag.name
|
|
111
|
+
}))
|
|
112
|
+
columns.push({
|
|
113
|
+
type: 'currency',
|
|
114
|
+
name: 'other',
|
|
115
|
+
title: '{Other}'
|
|
116
|
+
})
|
|
117
|
+
columns.unshift({
|
|
118
|
+
name: 'title',
|
|
119
|
+
title: '',
|
|
120
|
+
type: 'name'
|
|
121
|
+
})
|
|
122
|
+
return columns
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return super.getColumns(id, entries, options, settings)
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
preProcessByTags(id, entries, options, settings, columns) {
|
|
129
|
+
// Prepapre.
|
|
130
|
+
const columnNames = columns.map((col) => col.name)
|
|
131
|
+
const tagSet = new Set(settings.tags.map(t => t.tag))
|
|
132
|
+
|
|
133
|
+
// Summarize all totals from the entries.
|
|
134
|
+
const totals: Record<string, Record<string, number>> = {}
|
|
135
|
+
columnNames.forEach((column) => (totals[column] = {}))
|
|
136
|
+
const accountNames = {}
|
|
137
|
+
const accountNumbers = new Set<AccountNumber>()
|
|
138
|
+
const regex = /^((\[\w+\])+)/
|
|
139
|
+
entries.forEach((entry) => {
|
|
140
|
+
let shares: string[] = []
|
|
141
|
+
const r = regex.exec(entry.description)
|
|
142
|
+
if (r) {
|
|
143
|
+
shares = r[1].substr(1, r[1].length - 2).split('][').filter(t => tagSet.has(t))
|
|
144
|
+
}
|
|
145
|
+
let amount = entry.amount
|
|
146
|
+
if (shares.length) {
|
|
147
|
+
// Share the amount so that rounding errors are split.
|
|
148
|
+
const piece = amount < 0 ? Math.ceil(amount / shares.length) : Math.floor(amount / shares.length)
|
|
149
|
+
shares.forEach((tag) => {
|
|
150
|
+
const column = `tag-${tag}`
|
|
151
|
+
totals[column][entry.number] = totals[column][entry.number] || 0
|
|
152
|
+
totals[column][entry.number] += piece
|
|
153
|
+
amount -= piece
|
|
154
|
+
})
|
|
155
|
+
if (amount) {
|
|
156
|
+
// Make semi-random starting point and distribute cents.
|
|
157
|
+
let i = (entry.periodId) % shares.length
|
|
158
|
+
const delta = amount < 0 ? -1 : 1
|
|
159
|
+
for (let count = Math.abs(amount); count > 0; count--) {
|
|
160
|
+
const column = `tag-${shares[i]}`
|
|
161
|
+
totals[column][entry.number] += delta
|
|
162
|
+
amount -= delta
|
|
163
|
+
i = (i + 1) % shares.length
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
if (amount) {
|
|
169
|
+
totals.other[entry.number] = totals.other[entry.number] || 0
|
|
170
|
+
totals.other[entry.number] += amount
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
accountNames[entry.number] = entry.name
|
|
174
|
+
accountNumbers.add(entry.number)
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
return this.parseAndCombineReport([...accountNumbers], accountNames, columns, options.format, totals)
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
async preProcess(id, entries, options, settings, columns) {
|
|
181
|
+
if (options.byTags) {
|
|
182
|
+
return this.preProcessByTags(id, entries, options, settings, columns)
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const columnNames = columns.map((col) => col.name)
|
|
186
|
+
|
|
187
|
+
// Summarize all totals from the entries.
|
|
188
|
+
const totals = {}
|
|
189
|
+
columnNames.forEach((column) => (totals[column] = {}))
|
|
190
|
+
const accountNames = {}
|
|
191
|
+
const accountNumbers = new Set<AccountNumber>()
|
|
192
|
+
entries.forEach((entry) => {
|
|
193
|
+
const column = 'period' + entry.periodId
|
|
194
|
+
totals[column][entry.number] = totals[column][entry.number] || 0
|
|
195
|
+
totals[column][entry.number] += entry.amount
|
|
196
|
+
accountNames[entry.number] = entry.name
|
|
197
|
+
accountNumbers.add(entry.number)
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
return this.parseAndCombineReport([...accountNumbers], accountNames, columns, options.format, totals)
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Remove empty columns if report made by tags.
|
|
205
|
+
*/
|
|
206
|
+
async postProcess(id, data, options, settings, columns) {
|
|
207
|
+
if (!options.byTags) {
|
|
208
|
+
return data
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Find empty columns.
|
|
212
|
+
const found = new Set()
|
|
213
|
+
for (const line of data) {
|
|
214
|
+
if (!line.values) {
|
|
215
|
+
continue
|
|
216
|
+
}
|
|
217
|
+
for (const [k, v] of Object.entries(line.values)) {
|
|
218
|
+
if (v !== null && !isNaN(v as number)) {
|
|
219
|
+
found.add(k)
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// Remove empty columns.
|
|
225
|
+
for (let i = 0; i < columns.length; i++) {
|
|
226
|
+
if ((columns[i].type === 'currency' || columns[i].type === 'numeric') && !found.has(columns[i].name)) {
|
|
227
|
+
columns.splice(i, 1)
|
|
228
|
+
i--
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return data
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
export default FinnishIncomeStatementReportSociety
|