|
// ==UserScript== |
|
// @name Postfinance CSV Export |
|
// @namespace http://death-knight.com |
|
// @include https://www.postfinance.ch/ap/ba/ob/html/finance/* |
|
// @updateURL https://gist.github.com/weiserr/bc0745d3145b29f02b1d/raw/postfinance-ynab.user.js |
|
// @downloadURL https://gist.github.com/weiserr/bc0745d3145b29f02b1d/raw/postfinance-ynab.user.js |
|
// @version 13 |
|
// @grant none |
|
// ==/UserScript== |
|
|
|
// Function definitions |
|
function createGenerateButton() { |
|
let input = document.createElement("button"); |
|
input.type = "button"; |
|
input.className = "ynab-button fpui-button text-sm fpui-button--primary fpui-button--normal"; |
|
input.textContent = "YNAP Export"; |
|
input.onclick = createExportButton; |
|
|
|
document.querySelectorAll('fpui-actions').forEach(elem => {if(elem.querySelectorAll(".ynab-button").length < 1) {elem.appendChild(input)}}); |
|
} |
|
|
|
function createExportButton() { |
|
const csv = createCSV(); |
|
const date = new Date(); |
|
const year = date.getFullYear(); |
|
const month = date.getMonth() + 1; |
|
const day = date.getDate(); |
|
const filename = "ynab-" + year + "-" + month + "-" + day + ".csv"; |
|
|
|
// create a temporary download link |
|
let input = document.createElement("a"); |
|
input.setAttribute('href', 'data:text/csv;charset=UTF-8,' + encodeURIComponent(csv)); |
|
input.setAttribute('download', filename); |
|
input.style.display = 'none'; |
|
|
|
// ...and click it to trigger the download |
|
document.body.appendChild(input); |
|
input.click(); |
|
document.body.removeChild(input); |
|
} |
|
|
|
function createCSV() { |
|
// acquire the data computed by the Post |
|
const rows = Array.from(document.querySelector('[data-cy="movements-table"] > tbody').querySelectorAll("tr")); |
|
|
|
// process the content |
|
let result = rows.map((row, index) => sanitizeRow(row)); |
|
|
|
// add the header |
|
result.unshift(createHeader()); |
|
|
|
// join the results into a single string |
|
return result.join("\n"); |
|
} |
|
|
|
function createHeader() { |
|
return 'Date,Payee,Category,Memo,Outflow,Inflow'; |
|
} |
|
|
|
function sanitizeRow(row) { |
|
const date = row.querySelector('[data-cy="date"] > span:nth-child(2)').textContent; |
|
const payee = row.querySelector('[data-cy="shortText"] > span:nth-child(2)').textContent.replace(/\"/gi, '').replace(/\n/gi, ' ').replace(/,/gi, '; ').trim(); |
|
const category = ''; |
|
const memo = ''; |
|
const outflow = row.querySelector('[data-cy="debit"] > span:nth-child(2) > fpui-amount > span:nth-child(1)')?.textContent?.replace(/[^\d\.]/g, '')?.trim() ?? ''; |
|
const inflow = row.querySelector('[data-cy="credit"] > span:nth-child(2) > fpui-amount > span:nth-child(1)')?.textContent?.replace(/[^\d\.]/g, '')?.trim() ?? ''; |
|
|
|
let line = []; |
|
line.push(date); |
|
line.push(payee); |
|
line.push(category); |
|
line.push(memo); |
|
line.push(outflow); |
|
line.push(inflow); |
|
|
|
return line.join(','); |
|
} |
|
|
|
function waitForElem(selector) { |
|
if (document.URL == "https://www.postfinance.ch/ap/ba/ob/html/finance/assets/movements-overview" && document.querySelector(selector)) { |
|
createGenerateButton(); |
|
} |
|
|
|
const observer = new MutationObserver((mutations) => { |
|
if (document.URL == "https://www.postfinance.ch/ap/ba/ob/html/finance/assets/movements-overview" && document.querySelector(selector)) { |
|
createGenerateButton(); |
|
} |
|
}); |
|
|
|
observer.observe(document.body, { |
|
childList: true, |
|
subtree: true, |
|
}); |
|
} |
|
|
|
|
|
waitForElem('fpui-actions'); |
Hi, there is a bug, every transactions goes to the inflow column of YNAB. VNAB understand that value with minus at the end should be swaped so either leave all transaction in the inflow column with the minus for the outflow transactions, either put the outflow transaction in the outflow colum and remove the minus on the value.