Skip to content

Instantly share code, notes, and snippets.

@weiserr
Last active June 22, 2024 13:17
Show Gist options
  • Save weiserr/bc0745d3145b29f02b1d to your computer and use it in GitHub Desktop.
Save weiserr/bc0745d3145b29f02b1d to your computer and use it in GitHub Desktop.
Postfinance YNAB Export

PostFinance YNAB 4 Export

This scripts allows the export of PostFinance account flow data for YNAB 4 using Tampermonkey. The export is not based on the CSV generated by the Post as it does not adhere to the standard but makes use of the data loaded on the client side for doing said CSV export.

Installation

If Tampermonkey is installed you can click on the RAW view of the postfinance-ynab.user.js file of this Gist. Tampermonkey should ask you whether or not you would like to install this script.

Usage

Tip: if you have a lot of transactions make sure to increase the shown amount from 25 to 100 somewhere in the settings.

Navigate to the account flow data in PostFinance (Konto -> Bewegungen) and:

  1. Click on the YNAB Export button.
  2. Hit the import button in the YNAB account view.
// ==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 12
// @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
const result = rows.map((row, index) => index > 0 ? sanitizeRow(row) : 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');
@weiserr
Copy link
Author

weiserr commented Jul 17, 2018

Adapted the script to:

  • Support proper updating
  • Support text with carriage returns in the payee (Avisierungstext)

@pgailloud
Copy link

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.

@weiserr
Copy link
Author

weiserr commented Sep 7, 2018

@pgailloud I will check that. It still worked two months ago...

@weiserr
Copy link
Author

weiserr commented Dec 28, 2018

@pgailloud sorry for the long delay - which version of YNAB are you using? (I am on v4.843). Currently the Outflow column is used for all outflows adding the - character at the end. For inflows the Inflow column is simply used.

@weiserr
Copy link
Author

weiserr commented Dec 28, 2018

Adapted v8 to support the , character in the description (Memo column). (The original CSV export is now even more broken as using the , as a regular char violates the CSV definition)

@weiserr
Copy link
Author

weiserr commented Dec 28, 2018

@Arsim100 finally managed to add a README.

...as there are no notifiactions for comments in Gists my response time might seem "a bit off". (Now checking before doing own budget :-) ).

@cormoran42
Copy link

cormoran42 commented May 20, 2019

Hi @weiserr
the script dosen't work anymore since a week ago. Payee is in the date column. Can you check please? It's so usefull!
Thanks!

@weiserr
Copy link
Author

weiserr commented Mar 8, 2022

Will look to providing an update now that PostFinance has changed its UI. (Hopefully somewhen this week)

@weiserr
Copy link
Author

weiserr commented Mar 8, 2022

Updated the script to work with the new UI. Here are the mini-change notes:

  • Make sure to perform a reload when using this script on the page (see the README.md in that regard)
  • The data is now completely scraped from the existing UI which has the nice effect of not needing to clicke the "regular" export button beforehand anymore
  • The outflows do not have a - suffix at the end anymore (as suggested by @pgailloud )

...please let me know if something breaks / can be optimized.

@weiserr
Copy link
Author

weiserr commented Mar 14, 2022

Minor update due to the following issue:

Changing accounts in the "Konto -> Bewegungen" screen does not change the URL (not deeplinkable) which also means that performing a page refresh resets the selected account to the first one thus making it impossible to export YNAB data for all accounts but the first one.

--> This has now been fixed. The script will monitor changes to the UI and if the "Konto -> Bewegungen" page is browsed and will add the "YNAB Export" button if it has not yet been added to the action buttons.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment