9c0df36e16
* style: enforce sorting of imports * style: alphabetize imports * style: merge duplicated imports
118 lines
2.5 KiB
JavaScript
118 lines
2.5 KiB
JavaScript
import csv2json from 'csv-parse/lib/sync';
|
|
|
|
import fs from '../../platform/server/fs';
|
|
import { dayFromDate } from '../../shared/months';
|
|
import { looselyParseAmount } from '../../shared/util';
|
|
import qif2json from './qif2json';
|
|
|
|
export function parseFile(filepath, options) {
|
|
let errors = [];
|
|
let m = filepath.match(/\.[^.]*$/);
|
|
|
|
if (m) {
|
|
let ext = m[0];
|
|
|
|
switch (ext.toLowerCase()) {
|
|
case '.qif':
|
|
return parseQIF(filepath);
|
|
case '.csv':
|
|
return parseCSV(filepath, options);
|
|
case '.ofx':
|
|
case '.qfx':
|
|
return parseOFX(filepath);
|
|
default:
|
|
}
|
|
}
|
|
|
|
errors.push({
|
|
message: 'Invalid file type',
|
|
internal: ''
|
|
});
|
|
return { errors };
|
|
}
|
|
|
|
async function parseCSV(filepath, options = {}) {
|
|
let errors = [];
|
|
let contents = await fs.readFile(filepath);
|
|
|
|
let data;
|
|
try {
|
|
data = csv2json(contents, {
|
|
columns: true,
|
|
bom: true,
|
|
delimiter: options.delimiter || ',',
|
|
quote: '"',
|
|
trim: true,
|
|
relax_column_count: true
|
|
});
|
|
} catch (err) {
|
|
errors.push({
|
|
message: 'Failed parsing: ' + err.message,
|
|
internal: err.message
|
|
});
|
|
return { errors, transactions: [] };
|
|
}
|
|
|
|
return { errors, transactions: data };
|
|
}
|
|
|
|
async function parseQIF(filepath) {
|
|
let errors = [];
|
|
let contents = await fs.readFile(filepath);
|
|
|
|
let data;
|
|
try {
|
|
data = qif2json(contents);
|
|
} catch (err) {
|
|
errors.push({
|
|
message: "Failed parsing: doesn't look like a valid QIF file.",
|
|
internal: err.stack
|
|
});
|
|
return { errors, transactions: [] };
|
|
}
|
|
|
|
return {
|
|
errors,
|
|
transactions: data.transactions.map(trans => ({
|
|
amount: trans.amount != null ? looselyParseAmount(trans.amount) : null,
|
|
date: trans.date,
|
|
payee_name: trans.payee,
|
|
imported_payee: trans.payee,
|
|
notes: trans.memo || null
|
|
}))
|
|
};
|
|
}
|
|
|
|
async function parseOFX(filepath) {
|
|
let { getOFXTransactions, initModule } = await import(
|
|
/* webpackChunkName: 'xfo' */ 'node-libofx'
|
|
);
|
|
await initModule();
|
|
|
|
let errors = [];
|
|
let contents = await fs.readFile(filepath);
|
|
|
|
let data;
|
|
try {
|
|
data = getOFXTransactions(contents);
|
|
} catch (err) {
|
|
errors.push({
|
|
message: 'Failed importing file',
|
|
internal: err.stack
|
|
});
|
|
return { errors };
|
|
}
|
|
|
|
return {
|
|
errors,
|
|
transactions: data.map(trans => ({
|
|
amount: trans.amount,
|
|
imported_id: trans.fi_id,
|
|
date: trans.date ? dayFromDate(trans.date * 1000) : null,
|
|
payee_name: trans.name,
|
|
imported_payee: trans.name,
|
|
notes: trans.memo || null
|
|
}))
|
|
};
|
|
}
|