Skip to content

Instantly share code, notes, and snippets.

@troggy
Created August 19, 2018 11:24
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save troggy/05639720a144363dcdffddc99f87ec86 to your computer and use it in GitHub Desktop.
Save troggy/05639720a144363dcdffddc99f87ec86 to your computer and use it in GitHub Desktop.
Drebedengi to Ledger conversion (very rough)
const fs = require('fs');
const worker = async (filename) => {
console.log(`Reading ${filename}`);
fs.readFile(filename, (err, data) => {
if (err) throw err;
const lines = data.toString().split('\n');
const currencies = {};
const accounts = {};
const openingBalances = [];
let records = [];
let i = 0, line, parts;
line = lines[i];
const fullname = (account, name) => {
if (account.parent > 0) {
return fullname(accounts[account.parent], accounts[account.parent].name + ':' + name);
} else {
let cat;
if (account.type === 2) cat = 'Income';
if (account.type === 3) cat = 'Expense';
if (account.type === 4 || account.type === 9) cat = 'Assets';
if (account.liab) cat = 'Liabilities';
return cat + ':' + name;
}
}
const sanitize = (str) => {
return str.replace(/"/g, '');
}
while (i < lines.length - 1) {
if (line.startsWith('[currency]')) {
line = lines[++i];
while (!line.startsWith('[') && i < lines.length) {
parts = line.split(';');
currencies[parts[0]] = { ticker: sanitize(parts[3]), name: sanitize(parts[1]) }
line = lines[++i];
}
} else if (line.startsWith('[objects]')) {
line = lines[++i];
while (!line.startsWith('[') && i < lines.length) {
parts = line.split(';');
accounts[parts[0]] = {
name: sanitize(parts[3]),
parent: parts[1],
type: parseInt(parts[2]),
liab: parts[7] === 't'
}
line = lines[++i];
}
} else if (line.startsWith('[records]')) {
Object.keys(accounts).map((k, i) => {
accounts[k].fullname = fullname(accounts[k], accounts[k].name);
});
line = lines[++i];
while (line && !line.startsWith('[') && i < lines.length) {
parts = line.split(';');
if (parts.length > 4 && !parts[2].startsWith("-1")) {
let account = accounts[parts[3]];
let to = accounts[parts[2]];
const amount = parseFloat(parts[0]) / 100;
if (to.type === 2 || (to.type === 3 && amount > 0) ) { // income or rebate
let sw = account;
account = to;
to = sw;
}
const isExpense = to.type === 3 && amount < 0;
const date = new Date(parts[4]);
const comment = sanitize(parts[5]);
const prevRecord = records[records.length - 1];
if (prevRecord
&& prevRecord.date.getTime() === date.getTime()
&& prevRecord.comment === comment
&& prevRecord.from === to.fullname && prevRecord.to === account.fullname
&& prevRecord.amount * amount < 0
) {
prevRecord.transfer = true;
if (prevRecord.amount > 0) {
prevRecord.inAmount = amount;
prevRecord.inCurrency = currencies[parts[1]].ticker;
const sw = prevRecord.from;
prevRecord.from = prevRecord.to;
prevRecord.to = sw;
} else {
prevRecord.inAmount = prevRecord.amount;
prevRecord.inCurrency = prevRecord.currency;
prevRecord.amount = amount;
prevRecord.currency = currencies[parts[1]].ticker;
}
} else {
records.push({
amount: isExpense ? Math.abs(amount) : amount,
date,
comment,
from: account.fullname,
to: to.fullname,
expense: isExpense,
currency: currencies[parts[1]].ticker
});
}
} else if (parts[2].startsWith("-1")) {
openingBalances.push({
amount: parseFloat(parts[0]) / 100,
acc: accounts[parts[3]].fullname,
currency: currencies[parts[1]].ticker,
date: new Date(parts[4])
});
}
line = lines[++i];
}
}
}
require('fs').writeFile('data.ledger', records.map(r => JSON.stringify(r, null, 2)).join('\n\r'), (err) => {
if (err) return console.log(err);
console.log(`Saved`);
});
const pad = (i) => {
if (i.toString().length == 1) return "0" + i;
return i;
}
ledgerRecords = records.reverse().map(r => {
let rec = `
${r.date.getFullYear()}/${pad(r.date.getMonth() + 1)}/${pad(r.date.getDate())} ${r.comment}
${r.to} ${r.amount} ${r.currency}
${r.from}`;
if (r.inAmount) {
rec += '\t\t\t\t' + `${r.inAmount} ${r.inCurrency}`;
}
return rec;
});
let ledgerOpening = openingBalances.map(b => {
return `
${b.acc} ${b.amount} ${b.currency}`;
});
ledgerOpening = `
2001/01/01 * Opening Balance`
+ ledgerOpening.join('') + `
Equity:Opening Balances`;
require('fs').writeFile('t.dat', ledgerOpening + '\n\r\n\r' + ledgerRecords.join('\n\r\n\r'), (err) => {
if (err) return console.log(err);
console.log(`Saved`);
});
});
}
worker(process.argv[2]);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment