|
// ==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'); |
Minor update due to the following: