@tasenor/common-plugins 1.9.32 → 1.9.34
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 +4 -0
- package/.turbo/turbo-ci.log +3 -7
- package/data/PluginIndex.mjs +27 -0
- package/dist/CoinAPI/backend/index.d.ts +22 -0
- package/dist/CoinAPI/backend/index.js +91 -0
- package/dist/CoinAPI/backend/index.js.map +1 -0
- package/dist/CoinbaseImport/backend/CoinbaseHandler.d.ts +12 -0
- package/dist/CoinbaseImport/backend/CoinbaseHandler.js +33 -0
- package/dist/CoinbaseImport/backend/CoinbaseHandler.js.map +1 -0
- package/dist/CoinbaseImport/backend/index.d.ts +5 -0
- package/dist/CoinbaseImport/backend/index.js +18 -0
- package/dist/CoinbaseImport/backend/index.js.map +1 -0
- package/dist/DocumentCleaner/ui/index.d.ts +43 -0
- package/dist/DocumentCleaner/ui/index.js +139 -0
- package/dist/DocumentCleaner/ui/index.js.map +1 -0
- package/dist/Euro/ui/index.d.ts +15 -0
- package/dist/Euro/ui/index.js +22 -0
- package/dist/Euro/ui/index.js.map +1 -0
- package/dist/Finnish/ui/finnish.json +341 -0
- package/dist/Finnish/ui/index.d.ts +17 -0
- package/dist/Finnish/ui/index.js +47 -0
- package/dist/Finnish/ui/index.js.map +1 -0
- package/dist/FinnishBalanceSheetReport/backend/index.d.ts +18 -0
- package/dist/FinnishBalanceSheetReport/backend/index.js +96 -0
- package/dist/FinnishBalanceSheetReport/backend/index.js.map +1 -0
- package/dist/FinnishBalanceSheetReportInvestment/backend/index.d.ts +18 -0
- package/dist/FinnishBalanceSheetReportInvestment/backend/index.js +96 -0
- package/dist/FinnishBalanceSheetReportInvestment/backend/index.js.map +1 -0
- package/dist/FinnishBalanceSheetReportLite/backend/index.d.ts +19 -0
- package/dist/FinnishBalanceSheetReportLite/backend/index.js +109 -0
- package/dist/FinnishBalanceSheetReportLite/backend/index.js.map +1 -0
- package/dist/FinnishIncomeStatementReport/backend/index.d.ts +26 -0
- package/dist/FinnishIncomeStatementReport/backend/index.js +190 -0
- package/dist/FinnishIncomeStatementReport/backend/index.js.map +1 -0
- package/dist/FinnishIncomeStatementReportInvestment/backend/index.d.ts +26 -0
- package/dist/FinnishIncomeStatementReportInvestment/backend/index.js +190 -0
- package/dist/FinnishIncomeStatementReportInvestment/backend/index.js.map +1 -0
- package/dist/FinnishIncomeStatementReportLite/backend/index.d.ts +26 -0
- package/dist/FinnishIncomeStatementReportLite/backend/index.js +188 -0
- package/dist/FinnishIncomeStatementReportLite/backend/index.js.map +1 -0
- package/dist/FinnishInvestmentCompany/backend/index.d.ts +10 -0
- package/dist/FinnishInvestmentCompany/backend/index.js +36 -0
- package/dist/FinnishInvestmentCompany/backend/index.js.map +1 -0
- package/dist/FinnishInvestmentCompany/ui/index.d.ts +16 -0
- package/dist/FinnishInvestmentCompany/ui/index.js +22 -0
- package/dist/FinnishInvestmentCompany/ui/index.js.map +1 -0
- package/dist/FinnishLimitedCompanyComplete/backend/index.d.ts +10 -0
- package/dist/FinnishLimitedCompanyComplete/backend/index.js +36 -0
- package/dist/FinnishLimitedCompanyComplete/backend/index.js.map +1 -0
- package/dist/FinnishLimitedCompanyComplete/ui/index.d.ts +16 -0
- package/dist/FinnishLimitedCompanyComplete/ui/index.js +22 -0
- package/dist/FinnishLimitedCompanyComplete/ui/index.js.map +1 -0
- package/dist/FinnishLimitedCompanyLite/backend/index.d.ts +10 -0
- package/dist/FinnishLimitedCompanyLite/backend/index.js +43 -0
- package/dist/FinnishLimitedCompanyLite/backend/index.js.map +1 -0
- package/dist/FinnishLimitedCompanyLite/ui/index.d.ts +16 -0
- package/dist/FinnishLimitedCompanyLite/ui/index.js +24 -0
- package/dist/FinnishLimitedCompanyLite/ui/index.js.map +1 -0
- package/dist/GitBackup/backend/index.d.ts +26 -0
- package/dist/GitBackup/backend/index.js +91 -0
- package/dist/GitBackup/backend/index.js.map +1 -0
- package/dist/GitBackup/ui/index.d.ts +44 -0
- package/dist/GitBackup/ui/index.js +114 -0
- package/dist/GitBackup/ui/index.js.map +1 -0
- package/dist/IncomeAndExpenses/backend/index.d.ts +5 -0
- package/dist/IncomeAndExpenses/backend/index.js +350 -0
- package/dist/IncomeAndExpenses/backend/index.js.map +1 -0
- package/dist/JournalReport/backend/index.d.ts +15 -0
- package/dist/JournalReport/backend/index.js +143 -0
- package/dist/JournalReport/backend/index.js.map +1 -0
- package/dist/KrakenImport/backend/KrakenHandler.d.ts +24 -0
- package/dist/KrakenImport/backend/KrakenHandler.js +86 -0
- package/dist/KrakenImport/backend/KrakenHandler.js.map +1 -0
- package/dist/KrakenImport/backend/index.d.ts +5 -0
- package/dist/KrakenImport/backend/index.js +18 -0
- package/dist/KrakenImport/backend/index.js.map +1 -0
- package/dist/LedgerReport/backend/index.d.ts +15 -0
- package/dist/LedgerReport/backend/index.js +150 -0
- package/dist/LedgerReport/backend/index.js.map +1 -0
- package/dist/LynxImport/backend/LynxHandler.d.ts +29 -0
- package/dist/LynxImport/backend/LynxHandler.js +343 -0
- package/dist/LynxImport/backend/LynxHandler.js.map +1 -0
- package/dist/LynxImport/backend/index.d.ts +5 -0
- package/dist/LynxImport/backend/index.js +18 -0
- package/dist/LynxImport/backend/index.js.map +1 -0
- package/dist/NordeaImport/backend/NordeaHandler.d.ts +12 -0
- package/dist/NordeaImport/backend/NordeaHandler.js +42 -0
- package/dist/NordeaImport/backend/NordeaHandler.js.map +1 -0
- package/dist/NordeaImport/backend/index.d.ts +5 -0
- package/dist/NordeaImport/backend/index.js +18 -0
- package/dist/NordeaImport/backend/index.js.map +1 -0
- package/dist/NordnetImport/backend/NordnetHandler.d.ts +18 -0
- package/dist/NordnetImport/backend/NordnetHandler.js +69 -0
- package/dist/NordnetImport/backend/NordnetHandler.js.map +1 -0
- package/dist/NordnetImport/backend/index.d.ts +5 -0
- package/dist/NordnetImport/backend/index.js +18 -0
- package/dist/NordnetImport/backend/index.js.map +1 -0
- package/dist/Rand/ui/index.d.ts +15 -0
- package/dist/Rand/ui/index.js +22 -0
- package/dist/Rand/ui/index.js.map +1 -0
- package/dist/RapidAPI/backend/index.d.ts +22 -0
- package/dist/RapidAPI/backend/index.js +119 -0
- package/dist/RapidAPI/backend/index.js.map +1 -0
- package/dist/TITOImport/backend/TITOHandler.d.ts +14 -0
- package/dist/TITOImport/backend/TITOHandler.js +244 -0
- package/dist/TITOImport/backend/TITOHandler.js.map +1 -0
- package/dist/TITOImport/backend/index.d.ts +5 -0
- package/dist/TITOImport/backend/index.js +18 -0
- package/dist/TITOImport/backend/index.js.map +1 -0
- package/dist/TagEditor/ui/index.d.ts +31 -0
- package/dist/TagEditor/ui/index.js +349 -0
- package/dist/TagEditor/ui/index.js.map +1 -0
- package/dist/USDollar/ui/index.d.ts +15 -0
- package/dist/USDollar/ui/index.js +22 -0
- package/dist/USDollar/ui/index.js.map +1 -0
- package/dist/VAT/ui/index.d.ts +69 -0
- package/dist/VAT/ui/index.js +509 -0
- package/dist/VAT/ui/index.js.map +1 -0
- package/dist/VATFinland/backend/index.d.ts +5 -0
- package/dist/VATFinland/backend/index.js +17 -0
- package/dist/VATFinland/backend/index.js.map +1 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -0
- package/package.json +8 -5
- package/src/CoinbaseImport/backend/CoinbaseHandler.ts +5 -1
- package/src/KrakenImport/backend/KrakenHandler.ts +5 -1
- package/src/LynxImport/backend/LynxHandler.ts +5 -1
- package/src/NordeaImport/backend/NordeaHandler.ts +5 -1
- package/src/NordnetImport/backend/NordnetHandler.ts +5 -1
- package/src/TITOImport/backend/TITOHandler.ts +5 -1
- package/src/index.ts +28 -0
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
import { NO_SEGMENT, warning, month, ucfirst } from '@tasenor/common';
|
|
2
|
+
import { InvalidFile, TransactionImportHandler } from '@tasenor/common-node';
|
|
3
|
+
// Matcher for ticker and ISIN code.
|
|
4
|
+
const TICKER_ISIN_REGEX = /^\s*([-A-Za-z0-9 .]+)\(([A-Z0-9]+)\)/;
|
|
5
|
+
// If set, pick only transactions concerning this ticker.
|
|
6
|
+
const DEBUG_TICKER = null;
|
|
7
|
+
// If set, pick only transactions from this section in CSV file:
|
|
8
|
+
// 'Deposits & Withdrawals', 'Interest', 'Trades', 'Corporate Actions', 'Dividends', 'Withholding Tax', 'Fees'.
|
|
9
|
+
const DEBUG_TYPE = null;
|
|
10
|
+
/**
|
|
11
|
+
* Import implementation for Lynx CSV format.
|
|
12
|
+
*/
|
|
13
|
+
export class LynxHandler extends TransactionImportHandler {
|
|
14
|
+
constructor() {
|
|
15
|
+
super('LynxImport');
|
|
16
|
+
this.importOptions = {
|
|
17
|
+
parser: 'custom',
|
|
18
|
+
requiredFields: ['Amount', 'Quantity'],
|
|
19
|
+
numericFields: ['Amount', 'Quantity', 'Proceeds', 'T. Price', 'MTM in Currency', 'Comm/Fee', 'PerAsset', 'Value'],
|
|
20
|
+
textField: null,
|
|
21
|
+
totalAmountField: null,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
get path() {
|
|
25
|
+
return __dirname;
|
|
26
|
+
}
|
|
27
|
+
canHandle(file) {
|
|
28
|
+
const header = 'Statement,Header,Field Name,Field Value\n';
|
|
29
|
+
const str = file.decode();
|
|
30
|
+
return str.charCodeAt(0) === 0xfeff &&
|
|
31
|
+
str.substr(1, header.length) === header;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Special pre-processing for Lynx semi CSV-format. Collect headers and map content of interest to columns.
|
|
35
|
+
* @param state
|
|
36
|
+
* @returns
|
|
37
|
+
*/
|
|
38
|
+
async parse(state, config) {
|
|
39
|
+
const language = config.language;
|
|
40
|
+
const sectionsOfInterest = new Set([
|
|
41
|
+
'Fees',
|
|
42
|
+
'Interest',
|
|
43
|
+
'Trades',
|
|
44
|
+
'Deposits & Withdrawals',
|
|
45
|
+
'Withholding Tax',
|
|
46
|
+
'Dividends',
|
|
47
|
+
'Corporate Actions'
|
|
48
|
+
]);
|
|
49
|
+
// Map headers of different sections to the data content and costruct columns.
|
|
50
|
+
for (const fileName of Object.keys(state.files)) {
|
|
51
|
+
const file = state.files[fileName];
|
|
52
|
+
let headers = [];
|
|
53
|
+
for (let n = 0; n < file.lines.length; n++) {
|
|
54
|
+
// Some info lines has bad quotes, so ignore errors.
|
|
55
|
+
const columns = await this.parseCsvLine(file.lines[n].text, { columnSeparator: ',', skipErrors: true });
|
|
56
|
+
if (!columns || !sectionsOfInterest.has(columns[0])) {
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
// Pick headers.
|
|
60
|
+
if (columns[1] === 'Header') {
|
|
61
|
+
headers = columns;
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
// Skip summaries and notes.
|
|
65
|
+
if (columns[1] === 'Total' || columns[1] === 'SubTotal' || columns[1] === 'Notes') {
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
if (columns[2] && columns[2].startsWith('Total')) {
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
// Skip dividend section with `Code` to avoid duplicate dividends.
|
|
72
|
+
if (headers[0] === 'Dividends' && headers[6] === 'Code') {
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
if (DEBUG_TICKER) {
|
|
76
|
+
if (columns[0] === 'Deposits & Withdrawals' || columns[0] === 'Interest')
|
|
77
|
+
continue;
|
|
78
|
+
if (columns[0] === 'Trades' && columns[5] !== DEBUG_TICKER)
|
|
79
|
+
continue;
|
|
80
|
+
if (columns[0] === 'Corporate Actions' && !columns[6].startsWith(DEBUG_TICKER))
|
|
81
|
+
continue;
|
|
82
|
+
if (columns[0] === 'Dividends' && !columns[4].startsWith(DEBUG_TICKER))
|
|
83
|
+
continue;
|
|
84
|
+
if (columns[0] === 'Withholding Tax' && !columns[4].startsWith(DEBUG_TICKER))
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
if (DEBUG_TYPE) {
|
|
88
|
+
if (columns[0] !== DEBUG_TYPE)
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
const values = { Type: headers[0], Subtype: '', Description: '' };
|
|
92
|
+
for (let i = 2; i < columns.length; i++) {
|
|
93
|
+
values[headers[i] || `Column${i}`] = columns[i];
|
|
94
|
+
}
|
|
95
|
+
// Add ISIN and Ticker for dividends and tax
|
|
96
|
+
if (['Dividends', 'Withholding Tax'].includes(values.Type)) {
|
|
97
|
+
const match = TICKER_ISIN_REGEX.exec(values.Description);
|
|
98
|
+
if (!match) {
|
|
99
|
+
throw new InvalidFile(`Failed to extract ticker and ISIN from a line '${values.Description}'.`);
|
|
100
|
+
}
|
|
101
|
+
values.Ticker = match[1].trim();
|
|
102
|
+
values.ISIN = match[2];
|
|
103
|
+
// Parse more fields from dividend.
|
|
104
|
+
if (values.Type === 'Dividends') {
|
|
105
|
+
let text = values.Description.replace(TICKER_ISIN_REGEX, '').trim();
|
|
106
|
+
text = text.replace(values.Ticker, '');
|
|
107
|
+
text = text.replace(/\(\s*\)/g, '');
|
|
108
|
+
text = text.replace(/\s\s+/g, ' ');
|
|
109
|
+
let perAsset = /\b([0-9.]+)\s+per\s+share\b/i.exec(text);
|
|
110
|
+
if (!perAsset) {
|
|
111
|
+
const regex = new RegExp(`${values.Currency}\\s+([0-9.]+)\\s`);
|
|
112
|
+
perAsset = regex.exec(text);
|
|
113
|
+
}
|
|
114
|
+
if (perAsset) {
|
|
115
|
+
values.PerAsset = perAsset[1];
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
warning(`Failed to find per share dividend from a line '${values.Description}'.`);
|
|
119
|
+
values.PerAsset = undefined;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// Add ISIN and Ticker for corporate actions and try to extract some info.
|
|
124
|
+
if (values.Type === 'Corporate Actions') {
|
|
125
|
+
let match = TICKER_ISIN_REGEX.exec(values.Description);
|
|
126
|
+
if (!match) {
|
|
127
|
+
throw new InvalidFile(`Failed to extract ticker and ISIN from a line '${values.Description}'.`);
|
|
128
|
+
}
|
|
129
|
+
values.Ticker = match[1].trim();
|
|
130
|
+
values.ISIN = match[2];
|
|
131
|
+
let text = values.Description.replace(TICKER_ISIN_REGEX, '').trim();
|
|
132
|
+
if (text.startsWith('CUSIP/ISIN Change to ')) {
|
|
133
|
+
values.Action = 'Renaming';
|
|
134
|
+
text = text.substring(21);
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
match = /^(\w+)/.exec(text);
|
|
138
|
+
if (!match) {
|
|
139
|
+
throw new InvalidFile(`Cannot extract corporate action from a line '${values.Description}'.`);
|
|
140
|
+
}
|
|
141
|
+
values.Action = ucfirst(match[1]);
|
|
142
|
+
text = text.replace(/^\w+/, '').trim();
|
|
143
|
+
}
|
|
144
|
+
match = /^\((\w+)\)/.exec(text);
|
|
145
|
+
values.SubAction = match ? ucfirst(match[1]) : '';
|
|
146
|
+
text = text.replace(/^\((\w+)\)/, '').trim();
|
|
147
|
+
match = /\b(\d+)\s+for\s+(\d+)\s/i.exec(text);
|
|
148
|
+
if (match) {
|
|
149
|
+
values.Ratio = `${parseInt(match[1])}/${parseInt(match[2])}`;
|
|
150
|
+
values.RatioDecimal = `${parseInt(match[1]) / parseInt(match[2])}`;
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
values.Ratio = '';
|
|
154
|
+
values.RatioDecimal = '';
|
|
155
|
+
}
|
|
156
|
+
match = /.*\(([A-Z0-9 .]+),\s+.*?\)/.exec(text);
|
|
157
|
+
values.TickerInText = match ? match[1] : '';
|
|
158
|
+
}
|
|
159
|
+
// Rename some currency dependent fields.
|
|
160
|
+
if (values[`Comm in ${config.currency}`] !== undefined) {
|
|
161
|
+
values['Comm in Currency'] = values[`Comm in ${config.currency}`];
|
|
162
|
+
delete values[`Comm in ${config.currency}`];
|
|
163
|
+
}
|
|
164
|
+
if (values[`MTM in ${config.currency}`] !== undefined) {
|
|
165
|
+
values['MTM in Currency'] = values[`MTM in ${config.currency}`];
|
|
166
|
+
delete values[`MTM in ${config.currency}`];
|
|
167
|
+
}
|
|
168
|
+
// Trim the quantity's confusing desimal point.
|
|
169
|
+
if (values.Quantity && values.Type === 'Trades') {
|
|
170
|
+
values.Quantity = values.Quantity.replace(/,(\d\d\d)$/g, '$1');
|
|
171
|
+
}
|
|
172
|
+
// Fix Date/Time.
|
|
173
|
+
if (values['Date/Time']) {
|
|
174
|
+
values['Date/Time'] = values['Date/Time'].replace(',', '');
|
|
175
|
+
}
|
|
176
|
+
// Pick interest period.
|
|
177
|
+
if (values.Type === 'Interest') {
|
|
178
|
+
const re = /\s([A-Z][a-z][a-z])-(\d\d\d\d)$/.exec(values.Description);
|
|
179
|
+
values.Month = re ? ucfirst(await this.getTranslation(month(re[1]) || '', language)) : '';
|
|
180
|
+
values.Year = re ? re[2] : '';
|
|
181
|
+
}
|
|
182
|
+
// Ensure at least empty `Action` for easier processing in rules.
|
|
183
|
+
values.Action = values.Action || '';
|
|
184
|
+
file.lines[n].columns = values;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
const newState = {
|
|
188
|
+
...state,
|
|
189
|
+
stage: 'segmented'
|
|
190
|
+
};
|
|
191
|
+
return newState;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Resolve date string for column data extracted.
|
|
195
|
+
* @param columns
|
|
196
|
+
*/
|
|
197
|
+
date(columns) {
|
|
198
|
+
// Mapping from types to date fields.
|
|
199
|
+
const dateField = {
|
|
200
|
+
Fees: 'Date',
|
|
201
|
+
Interest: 'Date',
|
|
202
|
+
Dividends: 'Date',
|
|
203
|
+
Trades: 'Date/Time',
|
|
204
|
+
'Corporate Actions': 'Date/Time',
|
|
205
|
+
'Deposits & Withdrawals': 'Settle Date',
|
|
206
|
+
'Withholding Tax': 'Date'
|
|
207
|
+
};
|
|
208
|
+
let date = columns[dateField[columns.Type]];
|
|
209
|
+
if (!date) {
|
|
210
|
+
throw new InvalidFile(`Unable to determine timestamp from ${JSON.stringify(columns)}.`);
|
|
211
|
+
}
|
|
212
|
+
if (date.length < 12) {
|
|
213
|
+
date += 'T00:00:00Z';
|
|
214
|
+
}
|
|
215
|
+
return date;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Pair dividends and witholding taxes. Other lines are kept as they are.
|
|
219
|
+
* @param process
|
|
220
|
+
* @param state
|
|
221
|
+
* @param files
|
|
222
|
+
* @returns
|
|
223
|
+
*/
|
|
224
|
+
async segmentation(process, state) {
|
|
225
|
+
// Parse to get column content.
|
|
226
|
+
const parsed = await this.parse(state, process.config);
|
|
227
|
+
parsed.segments = {};
|
|
228
|
+
// Collect dividend line numbers per ISIN + date combination.
|
|
229
|
+
const actionLines = {};
|
|
230
|
+
const dividendSegments = {};
|
|
231
|
+
for (const fileName of Object.keys(parsed.files)) {
|
|
232
|
+
const file = parsed.files[fileName];
|
|
233
|
+
for (let n = 0; n < file.lines.length; n++) {
|
|
234
|
+
const { Type, ISIN } = file.lines[n].columns;
|
|
235
|
+
if (Type === 'Dividends') {
|
|
236
|
+
const date = this.date(file.lines[n].columns);
|
|
237
|
+
const key = `${date} ${ISIN}`;
|
|
238
|
+
if (dividendSegments[key] === undefined) {
|
|
239
|
+
const segmentId = this.segmentId(file.lines[n]);
|
|
240
|
+
if (segmentId === NO_SEGMENT) {
|
|
241
|
+
throw new InvalidFile(`Failed to find segment for ${JSON.stringify(file.lines[n].columns)}`);
|
|
242
|
+
}
|
|
243
|
+
dividendSegments[key] = segmentId;
|
|
244
|
+
}
|
|
245
|
+
file.lines[n].segmentId = dividendSegments[key];
|
|
246
|
+
const segmentId = dividendSegments[key];
|
|
247
|
+
parsed.segments[segmentId] = parsed.segments[segmentId] || { id: segmentId, time: new Date(date), lines: [] };
|
|
248
|
+
parsed.segments[segmentId].lines.push({ number: n, file: fileName });
|
|
249
|
+
}
|
|
250
|
+
else if (Type === 'Corporate Actions') {
|
|
251
|
+
const Date = this.date(file.lines[n].columns);
|
|
252
|
+
const key = `${Date} ${ISIN}`;
|
|
253
|
+
actionLines[key] = actionLines[key] || [];
|
|
254
|
+
actionLines[key].push(n);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
// Go through withholding taxes and share the segment ID with the dividend and the tax.
|
|
259
|
+
// Recognize tax adjustments and collect them for further processing.
|
|
260
|
+
// For other lines, get own segment ID.
|
|
261
|
+
const taxFixSegments = {};
|
|
262
|
+
for (const fileName of Object.keys(parsed.files)) {
|
|
263
|
+
const file = parsed.files[fileName];
|
|
264
|
+
for (let n = 0; n < file.lines.length; n++) {
|
|
265
|
+
const { Type, ISIN, Description } = file.lines[n].columns;
|
|
266
|
+
if (!Type) {
|
|
267
|
+
continue;
|
|
268
|
+
}
|
|
269
|
+
// Get the timestamp.
|
|
270
|
+
const date = this.date(file.lines[n].columns);
|
|
271
|
+
const time = new Date(date);
|
|
272
|
+
if (Type === 'Withholding Tax') {
|
|
273
|
+
// Group withholding tax entries with the corresponding dividend, if possible.
|
|
274
|
+
const key = `${date} ${ISIN}`;
|
|
275
|
+
let segmentId;
|
|
276
|
+
if (dividendSegments[key] === undefined) {
|
|
277
|
+
// Sometimes there are corrections afterwards. Let us then just adjust withholding taxes.
|
|
278
|
+
segmentId = taxFixSegments[key] || this.segmentId(file.lines[n]);
|
|
279
|
+
if (segmentId === NO_SEGMENT) {
|
|
280
|
+
throw new InvalidFile(`Failed to find segment for ${JSON.stringify(file.lines[n].columns)}`);
|
|
281
|
+
}
|
|
282
|
+
taxFixSegments[key] = segmentId;
|
|
283
|
+
file.lines[n].columns.Subtype = 'Adjustment';
|
|
284
|
+
}
|
|
285
|
+
else {
|
|
286
|
+
segmentId = dividendSegments[key];
|
|
287
|
+
file.lines[n].columns.Subtype = 'Tax';
|
|
288
|
+
}
|
|
289
|
+
file.lines[n].segmentId = segmentId;
|
|
290
|
+
parsed.segments[segmentId] = parsed.segments[segmentId] || { id: segmentId, time, lines: [] };
|
|
291
|
+
parsed.segments[segmentId].lines.push({ number: n, file: fileName });
|
|
292
|
+
}
|
|
293
|
+
else if (Type === 'Corporate Actions') {
|
|
294
|
+
const key = `${date} ${ISIN}`;
|
|
295
|
+
if (!actionLines[key]) {
|
|
296
|
+
throw new InvalidFile(`Unable to find matching corporate action for a line '${Description}.`);
|
|
297
|
+
}
|
|
298
|
+
// Use the first segmentId for all lines.
|
|
299
|
+
let segmentId;
|
|
300
|
+
for (const line of actionLines[key]) {
|
|
301
|
+
if (file.lines[line].segmentId) {
|
|
302
|
+
continue;
|
|
303
|
+
}
|
|
304
|
+
if (!segmentId) {
|
|
305
|
+
segmentId = this.segmentId(file.lines[n]);
|
|
306
|
+
parsed.segments[segmentId] = { id: segmentId, time, lines: [] };
|
|
307
|
+
}
|
|
308
|
+
file.lines[line].segmentId = segmentId;
|
|
309
|
+
parsed.segments[segmentId].lines.push({ number: line, file: fileName });
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
else if (Type === 'Deposits & Withdrawals') {
|
|
313
|
+
// Determine subtype for the line.
|
|
314
|
+
if (/Electronic Fund Transfer/.test(Description)) {
|
|
315
|
+
file.lines[n].columns.Subtype = 'Deposit';
|
|
316
|
+
}
|
|
317
|
+
else if (/Disbursement Initiated by/.test(Description)) {
|
|
318
|
+
file.lines[n].columns.Subtype = 'Withdrawal';
|
|
319
|
+
}
|
|
320
|
+
else if (/^Adjustment:/.test(Description)) {
|
|
321
|
+
file.lines[n].columns.Subtype = 'Adjustment';
|
|
322
|
+
}
|
|
323
|
+
else {
|
|
324
|
+
warning(`Unable to determine subtype for Deposits & Withdrawals '${Description}'.`);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
// For those not yet assigned, just record a single line segment.
|
|
328
|
+
if (!file.lines[n].segmentId) {
|
|
329
|
+
const segmentId = this.segmentId(file.lines[n]);
|
|
330
|
+
if (segmentId !== NO_SEGMENT) {
|
|
331
|
+
file.lines[n].segmentId = segmentId;
|
|
332
|
+
parsed.segments[segmentId] = parsed.segments[segmentId] || { id: segmentId, time, lines: [] };
|
|
333
|
+
parsed.segments[segmentId].lines.push({ number: n, file: fileName });
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
const final = await this.segmentationPostProcess(parsed);
|
|
339
|
+
this.debugSegmentation(final);
|
|
340
|
+
return final;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
//# sourceMappingURL=LynxHandler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LynxHandler.js","sourceRoot":"","sources":["../../../src/LynxImport/backend/LynxHandler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ImportPlugin } from '@tasenor/common-node';
|
|
2
|
+
import { LynxHandler } from './LynxHandler';
|
|
3
|
+
class LynxImportPlugin extends ImportPlugin {
|
|
4
|
+
constructor() {
|
|
5
|
+
super(new LynxHandler());
|
|
6
|
+
this.code = 'LynxImport';
|
|
7
|
+
this.title = 'Import for Lynx';
|
|
8
|
+
this.version = '1.0.36';
|
|
9
|
+
this.icon = '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M5 6.99h3V14h2V6.99h3L9 3zM14 10v7.01h-3L15 21l4-3.99h-3V10z"/></svg>';
|
|
10
|
+
this.releaseDate = '2023-05-03';
|
|
11
|
+
this.use = 'backend';
|
|
12
|
+
this.type = 'import';
|
|
13
|
+
this.description = 'Import plugin for importing transaction data in CSV format provided by Lynx.';
|
|
14
|
+
this.languages = this.getLanguages();
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export default LynxImportPlugin;
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/LynxImport/backend/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAEnD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAE3C,MAAM,gBAAiB,SAAQ,YAAY;IAEzC;QACE,KAAK,CAAC,IAAI,WAAW,EAAE,CAAC,CAAA;QAExB,IAAI,CAAC,IAAI,GAAG,YAA0B,CAAA;QACtC,IAAI,CAAC,KAAK,GAAG,iBAAiB,CAAA;QAC9B,IAAI,CAAC,OAAO,GAAG,QAAmB,CAAA;QAClC,IAAI,CAAC,IAAI,GAAG,6NAA6N,CAAA;QACzO,IAAI,CAAC,WAAW,GAAG,YAAY,CAAA;QAC/B,IAAI,CAAC,GAAG,GAAG,SAAS,CAAA;QACpB,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAA;QACpB,IAAI,CAAC,WAAW,GAAG,8EAA8E,CAAA;QAEjG,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,YAAY,EAAE,CAAA;IACtC,CAAC;CAEF;AAED,eAAe,gBAAgB,CAAA"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { DirectoryPath, NO_SEGMENT, SegmentId, TextFileLine } from '@tasenor/common';
|
|
2
|
+
import { ProcessFile, TransactionImportHandler } from '@tasenor/common-node';
|
|
3
|
+
/**
|
|
4
|
+
* Import implementation for Nordea CSV format.
|
|
5
|
+
*/
|
|
6
|
+
export declare class NordeaHandler extends TransactionImportHandler {
|
|
7
|
+
constructor();
|
|
8
|
+
get path(): DirectoryPath;
|
|
9
|
+
canHandle(file: ProcessFile): boolean;
|
|
10
|
+
segmentId(line: TextFileLine): SegmentId | typeof NO_SEGMENT;
|
|
11
|
+
time(line: TextFileLine): Date | undefined;
|
|
12
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { NO_SEGMENT } from '@tasenor/common';
|
|
2
|
+
import { TransactionImportHandler } from '@tasenor/common-node';
|
|
3
|
+
/**
|
|
4
|
+
* Import implementation for Nordea CSV format.
|
|
5
|
+
*/
|
|
6
|
+
export class NordeaHandler extends TransactionImportHandler {
|
|
7
|
+
constructor() {
|
|
8
|
+
super('NordeaImport');
|
|
9
|
+
this.importOptions = {
|
|
10
|
+
parser: 'csv',
|
|
11
|
+
numericFields: ['Määrä'],
|
|
12
|
+
requiredFields: ['Viesti'],
|
|
13
|
+
insignificantFields: ['Arvopäivä', 'Maksupäivä', 'Maksajan viite', 'Kirjauspäivä', 'Tapahtuma', 'Kuitti', 'BIC'],
|
|
14
|
+
textField: 'Viesti',
|
|
15
|
+
totalAmountField: 'Määrä',
|
|
16
|
+
csv: {
|
|
17
|
+
trimLines: true,
|
|
18
|
+
cutFromBeginning: 2,
|
|
19
|
+
useFirstLineHeadings: true,
|
|
20
|
+
columnSeparator: '\t'
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
get path() {
|
|
25
|
+
return __dirname;
|
|
26
|
+
}
|
|
27
|
+
canHandle(file) {
|
|
28
|
+
return file.firstLineMatch(/^Tilinumero\tFI\d+$/) && file.thirdLineMatch(/^Kirjauspäivä\tArvopäivä\tMaksupäivä\tMäärä\tSaaja\/Maksaja\tTilinumero\tBIC\tTapahtuma\tViite\tMaksajan viite\tViesti\tKortinnumero\tKuitti$/);
|
|
29
|
+
}
|
|
30
|
+
segmentId(line) {
|
|
31
|
+
return line.columns ? this.hash(line) : NO_SEGMENT;
|
|
32
|
+
}
|
|
33
|
+
time(line) {
|
|
34
|
+
const match = /(\d+)\.(\d+)\.(\d+)/.exec(line.columns['Maksupäivä']);
|
|
35
|
+
if (match) {
|
|
36
|
+
const stamp = match[3] + '-' + match[2] + '-' + match[1] + 'T12:00:00.000Z';
|
|
37
|
+
return new Date(stamp);
|
|
38
|
+
}
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=NordeaHandler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NordeaHandler.js","sourceRoot":"","sources":["../../../src/NordeaImport/backend/NordeaHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,UAAU,EAA2B,MAAM,iBAAiB,CAAA;AACpF,OAAO,EAAe,wBAAwB,EAAE,MAAM,sBAAsB,CAAA;AAE5E;;GAEG;AACH,MAAM,OAAO,aAAc,SAAQ,wBAAwB;IAEzD;QACE,KAAK,CAAC,cAAc,CAAC,CAAA;QAErB,IAAI,CAAC,aAAa,GAAG;YACnB,MAAM,EAAE,KAAK;YACb,aAAa,EAAE,CAAC,OAAO,CAAC;YACxB,cAAc,EAAE,CAAC,QAAQ,CAAC;YAC1B,mBAAmB,EAAE,CAAC,WAAW,EAAE,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,WAAW,EAAE,QAAQ,EAAE,KAAK,CAAC;YAChH,SAAS,EAAE,QAAQ;YACnB,gBAAgB,EAAE,OAAO;YACzB,GAAG,EAAE;gBACH,SAAS,EAAE,IAAI;gBACf,gBAAgB,EAAE,CAAC;gBACnB,oBAAoB,EAAE,IAAI;gBAC1B,eAAe,EAAE,IAAI;aACtB;SACF,CAAA;IACH,CAAC;IAED,IAAI,IAAI;QACN,OAAO,SAA0B,CAAA;IACnC,CAAC;IAED,SAAS,CAAC,IAAiB;QACzB,OAAO,IAAI,CAAC,cAAc,CAAC,qBAAqB,CAAC,IAAI,IAAI,CAAC,cAAc,CAAC,+IAA+I,CAAC,CAAA;IAC3N,CAAC;IAED,SAAS,CAAC,IAAkB;QAC1B,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAA;IACpD,CAAC;IAED,IAAI,CAAC,IAAkB;QACrB,MAAM,KAAK,GAAG,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAA;QACpE,IAAI,KAAK,EAAE;YACT,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,gBAAgB,CAAA;YAC3E,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,CAAA;SACvB;QACD,OAAO,SAAS,CAAA;IAClB,CAAC;CACF"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ImportPlugin } from '@tasenor/common-node';
|
|
2
|
+
import { NordeaHandler } from './NordeaHandler';
|
|
3
|
+
class NordeaImportPlugin extends ImportPlugin {
|
|
4
|
+
constructor() {
|
|
5
|
+
super(new NordeaHandler());
|
|
6
|
+
this.code = 'NordeaImport';
|
|
7
|
+
this.title = 'Import for Nordea';
|
|
8
|
+
this.version = '1.0.27';
|
|
9
|
+
this.icon = '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M5 6.99h3V14h2V6.99h3L9 3zM14 10v7.01h-3L15 21l4-3.99h-3V10z"/></svg>';
|
|
10
|
+
this.releaseDate = '2022-10-24';
|
|
11
|
+
this.use = 'backend';
|
|
12
|
+
this.type = 'import';
|
|
13
|
+
this.description = 'Import plugin for importing transaction data in CSV format provided by Nordea bank.';
|
|
14
|
+
this.languages = this.getLanguages();
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export default NordeaImportPlugin;
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/NordeaImport/backend/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAEnD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAE/C,MAAM,kBAAmB,SAAQ,YAAY;IAE3C;QACE,KAAK,CAAC,IAAI,aAAa,EAAE,CAAC,CAAA;QAE1B,IAAI,CAAC,IAAI,GAAG,cAA4B,CAAA;QACxC,IAAI,CAAC,KAAK,GAAG,mBAAmB,CAAA;QAChC,IAAI,CAAC,OAAO,GAAG,QAAmB,CAAA;QAClC,IAAI,CAAC,IAAI,GAAG,6NAA6N,CAAA;QACzO,IAAI,CAAC,WAAW,GAAG,YAAY,CAAA;QAC/B,IAAI,CAAC,GAAG,GAAG,SAAS,CAAA;QACpB,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAA;QACpB,IAAI,CAAC,WAAW,GAAG,qFAAqF,CAAA;QAExG,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,YAAY,EAAE,CAAA;IACtC,CAAC;CAEF;AAED,eAAe,kBAAkB,CAAA"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { DirectoryPath, ImportStateText, NO_SEGMENT, SegmentId, TextFileLine } from '@tasenor/common';
|
|
2
|
+
import { Process, ProcessFile, TransactionImportHandler } from '@tasenor/common-node';
|
|
3
|
+
/**
|
|
4
|
+
* Import implementation for Coinbase CSV format.
|
|
5
|
+
*/
|
|
6
|
+
export declare class NordnetHandler extends TransactionImportHandler {
|
|
7
|
+
constructor();
|
|
8
|
+
get path(): DirectoryPath;
|
|
9
|
+
canHandle(file: ProcessFile): boolean;
|
|
10
|
+
segmentId(line: TextFileLine): SegmentId | typeof NO_SEGMENT;
|
|
11
|
+
time(line: TextFileLine): Date | undefined;
|
|
12
|
+
/**
|
|
13
|
+
* Convert typical punctuations to parseable number and return numeric value.
|
|
14
|
+
* @param s
|
|
15
|
+
*/
|
|
16
|
+
num(str: string): number;
|
|
17
|
+
segmentation(process: Process, state: ImportStateText<'initial'>, files: ProcessFile[]): Promise<ImportStateText<'segmented'>>;
|
|
18
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { NotImplemented, TransactionImportHandler } from '@tasenor/common-node';
|
|
2
|
+
/**
|
|
3
|
+
* Import implementation for Coinbase CSV format.
|
|
4
|
+
*/
|
|
5
|
+
export class NordnetHandler extends TransactionImportHandler {
|
|
6
|
+
constructor() {
|
|
7
|
+
super('NordnetImport');
|
|
8
|
+
this.importOptions = {
|
|
9
|
+
parser: 'csv',
|
|
10
|
+
numericFields: ['Summa', 'Kurssi', 'Määrä', 'Kokonaiskulut'],
|
|
11
|
+
requiredFields: [],
|
|
12
|
+
textField: 'Tapahtumatyyppi',
|
|
13
|
+
totalAmountField: 'Summa',
|
|
14
|
+
csv: { useFirstLineHeadings: true, columnSeparator: '\t' }
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
get path() {
|
|
18
|
+
return __dirname;
|
|
19
|
+
}
|
|
20
|
+
canHandle(file) {
|
|
21
|
+
return file.firstLineMatch(/^\s*Id\tKirjausp.iv.\sKauppap.iv.\sMaksup.iv./);
|
|
22
|
+
}
|
|
23
|
+
segmentId(line) {
|
|
24
|
+
if (['LAINAKORKO'].includes(line.columns.Tapahtumatyyppi)) {
|
|
25
|
+
return super.segmentId(line, ['Salkku', 'Summa', 'Saldo', 'Maksupäivä', 'Kauppapäivä', 'Kirjauspäivä', 'Valuutta', 'Vaihtokurssi']);
|
|
26
|
+
}
|
|
27
|
+
if (line.columns.Vahvistusnumero) {
|
|
28
|
+
return line.columns.Vahvistusnumero;
|
|
29
|
+
}
|
|
30
|
+
throw new NotImplemented(`Importer does not yet recognize ${JSON.stringify(line.columns)}.`);
|
|
31
|
+
// return NO_SEGMENT
|
|
32
|
+
}
|
|
33
|
+
time(line) {
|
|
34
|
+
return line.columns['Kirjauspäivä'] ? new Date(line.columns['Kirjauspäivä']) : undefined;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Convert typical punctuations to parseable number and return numeric value.
|
|
38
|
+
* @param s
|
|
39
|
+
*/
|
|
40
|
+
num(str) {
|
|
41
|
+
return parseFloat(str.replace(',', '.').replace(/ /g, ''));
|
|
42
|
+
}
|
|
43
|
+
async segmentation(process, state, files) {
|
|
44
|
+
const result = await this.segmentationCSV(process, state, files);
|
|
45
|
+
// Fix missing currencies.
|
|
46
|
+
for (const fileName of Object.keys(result.files)) {
|
|
47
|
+
const file = result.files[fileName];
|
|
48
|
+
for (let n = 0; n < file.lines.length; n++) {
|
|
49
|
+
const { columns } = file.lines[n];
|
|
50
|
+
if (columns.Valuutta === '') {
|
|
51
|
+
if (columns.Valuuttakurssi === '1' || columns.Vaihtokurssi === '1') {
|
|
52
|
+
columns.Valuutta = process.config.currency;
|
|
53
|
+
}
|
|
54
|
+
if (columns.Tapahtumatyyppi === 'OSINKO') {
|
|
55
|
+
const match = / ([A-Z]{3})\/OSAKE$/.exec(columns.Tapahtumateksti);
|
|
56
|
+
if (match) {
|
|
57
|
+
columns.Valuutta = match[1];
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (columns.Kokonaiskulut && !columns['Kokonaiskulut Valuutta']) {
|
|
62
|
+
columns['Kokonaiskulut Valuutta'] = columns.Valuutta;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return this.segmentationPostProcess(result);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=NordnetHandler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NordnetHandler.js","sourceRoot":"","sources":["../../../src/NordnetImport/backend/NordnetHandler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ImportPlugin } from '@tasenor/common-node';
|
|
2
|
+
import { NordnetHandler } from './NordnetHandler';
|
|
3
|
+
class NordnetImportPlugin extends ImportPlugin {
|
|
4
|
+
constructor() {
|
|
5
|
+
super(new NordnetHandler());
|
|
6
|
+
this.code = 'NordnetImport';
|
|
7
|
+
this.title = 'Import for Nordnet';
|
|
8
|
+
this.version = '1.0.48';
|
|
9
|
+
this.icon = '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M5 6.99h3V14h2V6.99h3L9 3zM14 10v7.01h-3L15 21l4-3.99h-3V10z"/></svg>';
|
|
10
|
+
this.releaseDate = '2023-05-31';
|
|
11
|
+
this.use = 'backend';
|
|
12
|
+
this.type = 'import';
|
|
13
|
+
this.description = 'Import plugin for importing transaction data in CSV format provided by Nordnet.';
|
|
14
|
+
this.languages = this.getLanguages();
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export default NordnetImportPlugin;
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/NordnetImport/backend/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAEnD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAEjD,MAAM,mBAAoB,SAAQ,YAAY;IAE5C;QACE,KAAK,CAAC,IAAI,cAAc,EAAE,CAAC,CAAA;QAE3B,IAAI,CAAC,IAAI,GAAG,eAA6B,CAAA;QACzC,IAAI,CAAC,KAAK,GAAG,oBAAoB,CAAA;QACjC,IAAI,CAAC,OAAO,GAAG,QAAmB,CAAA;QAClC,IAAI,CAAC,IAAI,GAAG,6NAA6N,CAAA;QACzO,IAAI,CAAC,WAAW,GAAG,YAAY,CAAA;QAC/B,IAAI,CAAC,GAAG,GAAG,SAAS,CAAA;QACpB,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAA;QACpB,IAAI,CAAC,WAAW,GAAG,iFAAiF,CAAA;QAEpG,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,YAAY,EAAE,CAAA;IACtC,CAAC;CAEF;AAED,eAAe,mBAAmB,CAAA"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { CurrencyPlugin } from '@tasenor/common-ui';
|
|
2
|
+
declare class Rand extends CurrencyPlugin {
|
|
3
|
+
static code: string;
|
|
4
|
+
static title: string;
|
|
5
|
+
static version: string;
|
|
6
|
+
static icon: string;
|
|
7
|
+
static releaseDate: string;
|
|
8
|
+
static use: string;
|
|
9
|
+
static type: string;
|
|
10
|
+
static description: string;
|
|
11
|
+
getCurrencySymbol(): string;
|
|
12
|
+
getCurrencyCode(): string;
|
|
13
|
+
money2str(cents: any): string;
|
|
14
|
+
}
|
|
15
|
+
export default Rand;
|