Skip to content

Commit

Permalink
feat(velobank): add support for velobank CSV
Browse files Browse the repository at this point in the history
Velobank CSV is manually created from pdf
  • Loading branch information
Valdermeyder committed Dec 10, 2023
1 parent d13e880 commit 2e865e3
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 2 deletions.
29 changes: 29 additions & 0 deletions converters/velobankConverter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
const { parse } = require('csv-parse/sync')
const { transform } = require('stream-transform')
const categoryResolver = require('../categoryResolver')
const { sanitize } = require('../utils')

const columns = ['date', 'realDate', 'description', 'payer', 'amount', 'balance']

const parseAmount = amount => parseFloat(amount.replace(' ', '').replace(/w/, '').replace(',', '.'))

const parsePayer = payer => {
const payerWithoutLocation = payer.split(',')[0]
return payerWithoutLocation.replace('w ', '').trim()
}

const getExpenseManagerRecord = recordCategoryResolver => record => {
const payer = parsePayer(record[columns[3]]);
const amount = parseAmount(record[columns[4]])
const { category, subCategory } = recordCategoryResolver(payer, amount);
return record[columns[0]] + ','
+ amount + ',' + category + ',' + subCategory
+ ',Credit Card,,,' + sanitize(payer)
+ ',,,GetIn\n'
}

exports.convertCvsFileData = (input, categoriesMapping) => {
const getExpenseManagerWithMapping = getExpenseManagerRecord(categoryResolver.resolveCategory(categoriesMapping))
return transform(parse(input, { delimiter: ',', columns, relax: true, relax_column_count: true, bom: true }),
record => getExpenseManagerWithMapping(record))
}
31 changes: 31 additions & 0 deletions converters/velobankConverter.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const citiConverter = require('./velobankConverter')

const categoriesMapping = {
'Play': { category: 'Utilities', subCategory: 'Telephone' },
'Employer': { category: 'Income', subCategory: 'Salary' },
'Deposit': { category: 'Income', subCategory: 'Deposit' }
};

test('should be able to convert Velobank manually created CSV files format', (done) => {
const input = `30.10.2019,24.11.2023,"Przelew z rachunku: xxxxx,",Employer,"9 839,29 PLN","1 574,59 PLN"
28.10.2019,24.11.2023,"Operacja kartą na kwotę 17,99 PLN","w Play, GDANSK, PL","-10,00 PLN","2 374,59 PLN"`
const expected = `30.10.2019,9839.29,Income,Salary,Credit Card,,,Employer,,,GetIn
28.10.2019,-10,Utilities,Telephone,Credit Card,,,Play,,,GetIn
`
let transformedData = '';

const converter = citiConverter.convertCvsFileData(input, categoriesMapping)
.on('readable', () => {
let row = converter.read()
while (row) {
transformedData += row
row = converter.read()
}
})
.on('finish', () => {
setTimeout(() => {
expect(transformedData).toEqual(expected)
done()
})
})
})
14 changes: 14 additions & 0 deletions e2e/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,17 @@ test('should download converted csv without mapping for Santander', async t => {
await t.expect(file).eql('30.10.2019,9839.29,Income,,Credit Card,,,Employer,,,Santander\n28.10.2019,-10,,,Credit Card,,,Play,,,Santander\n')
})
.after(() => unlinkSync(expectedFile))

test('should download converted csv without mapping for Velobank', async t => {
expectedFile = join(`${homedir()}`, 'Downloads', 'testDataVelobank-converted.csv')
await t
.setFilesToUpload(Selector('#file'), 'testDataVelobank.csv')
.click(Selector('#velobank'))
.click(Selector('button'))

await waitForFile(expectedFile)
const file = readFileSync(expectedFile, 'utf-8')

await t.expect(file).eql('30.10.2019,9839.29,Income,,Credit Card,,,Employer,,,GetIn\n28.10.2019,-10,,,Credit Card,,,Play,,,GetIn\n')
})
.after(() => unlinkSync(expectedFile))
2 changes: 2 additions & 0 deletions e2e/testDataVelobank.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
30.10.2019,24.11.2023,"Przelew z rachunku: xxxxx,",Employer,"9 839,29 PLN","1 574,59 PLN"
28.10.2019,24.11.2023,"Operacja kartą na kwotę 17,99 PLN","w Play, GDANSK, PL","-10,00 PLN","2 374,59 PLN"
8 changes: 6 additions & 2 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,17 @@
<input type="radio" id="santander" name="bank" value="santander"/>
</div>
<div>
<label for="pekao">Pekao</label>
<input type="radio" id="pekao" name="bank" value="pekao"/>
<label for="velobank">Velobank</label>
<input type="radio" id="velobank" name="bank" value="velobank"/>
</div>
<div>
<label for="monobank">Monobank</label>
<input type="radio" id="monobank" name="bank" value="monobank"/>
</div>
<div>
<label for="pekao">Pekao</label>
<input type="radio" id="pekao" name="bank" value="pekao"/>
</div>
<div>
<label for="pko">PKO</label>
<input type="radio" id="pko" name="bank" value="pko"/>
Expand Down
3 changes: 3 additions & 0 deletions main.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const nestConverter = require("./converters/nestConverter");
const santanderConverter = require("./converters/santanderConverter");
const pekaoConverter = require("./converters/pekaoConverter");
const monobankConverter = require("./converters/monobankConverter");
const velobankConverter = require("./converters/velobankConverter");

const app = express();
const port = process.env.PORT || 3000;
Expand Down Expand Up @@ -39,6 +40,8 @@ function selectConverter(bank) {
return pekaoConverter;
case "monobank":
return monobankConverter;
case "velobank":
return velobankConverter;
default:
return cityConverter;
}
Expand Down

0 comments on commit 2e865e3

Please sign in to comment.