|  | // ==UserScript== | 
        
          |  | // @name        Postfinance CSV Export | 
        
          |  | // @namespace   http://death-knight.com | 
        
          |  | // @include     https://www.postfinance.ch/ap/ra/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     14 | 
        
          |  | // @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/ra/ob/html/finance/assets/movements-overview" && document.querySelector(selector)) { | 
        
          |  | createGenerateButton(); | 
        
          |  | } | 
        
          |  |  | 
        
          |  | const observer = new MutationObserver((mutations) => { | 
        
          |  | if (document.URL == "https://www.postfinance.ch/ap/ra/ob/html/finance/assets/movements-overview" && document.querySelector(selector)) { | 
        
          |  | createGenerateButton(); | 
        
          |  | } | 
        
          |  | }); | 
        
          |  |  | 
        
          |  | observer.observe(document.body, { | 
        
          |  | childList: true, | 
        
          |  | subtree: true, | 
        
          |  | }); | 
        
          |  | } | 
        
          |  |  | 
        
          |  |  | 
        
          |  | waitForElem('fpui-actions'); | 
  
@Arsim100 navigate your Grease- or Tamper-Monkey to this gist, click on "RAW" and it will ask you to install the script - that should be all.