Greasy Fork is available in English.

Fineco MyCards: Mostra soltanto le operazioni della carta di credito

Questo script aggiunge un bottone nella pagina "My Cards" di FinecoBank.com che consente di visualizzare la lista (e l'ammontare totale) delle sole operazioni con carta di credito.

// ==UserScript==
// @name           Fineco MyCards: Show only the credit card transactions
// @name:it        Fineco MyCards: Mostra soltanto le operazioni della carta di credito
// @description    This script adds a button in the page "My Cards" of FinecoBank.com that allows to show the list (and the total amount) of the only credit card transactions.
// @description:it Questo script aggiunge un bottone nella pagina "My Cards" di FinecoBank.com che consente di visualizzare la lista (e l'ammontare totale) delle sole operazioni con carta di credito.
// @match          https://finecobank.com/conto-e-carte/mycards*
// @grant          none
//// @run-at         document-start
// @version        1.1.5
// @author         Cyrano68
// @license        MIT
// @namespace https://greasyfork.org/users/788550
// ==/UserScript==

(function()
{
    "use strict";

    function console_log(text)
    {
        //let now = new Date().toISOString();
        let now = new Date().toLocaleString();
        console.log(`${now} ${text}`);
    }

    function setInterval2(callback, interval_ms)
    {
        console_log(`==> Fineco_MyCards_ShowOnlyCC: setInterval2 - STARTING TIMER - interval_ms=${interval_ms}`);
        let timerId = setInterval(callback, interval_ms);
        console_log(`==> Fineco_MyCards_ShowOnlyCC: setInterval2 - TIMER STARTED - timerId=${timerId}`);
        callback(timerId);
        return timerId;
    }

    console_log("==> Fineco_MyCards_ShowOnlyCC: HELLO! Loading script...");

    let timerId = 0;
    let interval_ms = 250;

    document.addEventListener("DOMContentLoaded", onDOMContentLoaded);
    window.addEventListener("load", onWindowLoaded);

    function onDOMContentLoaded()
    {
        console_log(`==> Fineco_MyCards_ShowOnlyCC: onDOMContentLoaded - document.readyState=${document.readyState}`);

        let myCSS = document.createElement("style");

        // SEE: https://getcssscan.com/css-buttons-examples
        myCSS.textContent = `
            .button-3 {
                appearance: none;
                background-color: #2ea44f;
                border: 1px solid rgba(27, 31, 35, .15);
                border-radius: 6px;
                box-shadow: rgba(27, 31, 35, .1) 0 1px 0;
                box-sizing: border-box;
                color: #fff;
                cursor: pointer;
                display: inline-block;
                font-family: -apple-system,system-ui,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";
                font-size: 14px;
                font-weight: 600;
                line-height: 20px;
                padding: 6px 16px;
                position: relative;
                text-align: center;
                text-decoration: none;
                user-select: none;
                -webkit-user-select: none;
                touch-action: manipulation;
                vertical-align: middle;
                white-space: nowrap;
            }
            .button-3:focus:not(:focus-visible):not(.focus-visible) {
                box-shadow: none;
                outline: none;
            }
            .button-3:hover {
                background-color: #2c974b;
            }
            .button-3:focus {
                box-shadow: rgba(46, 164, 79, .4) 0 0 0 3px;
                outline: none;
            }
            .button-3:disabled {
                background-color: #94d3a2;
                border-color: rgba(27, 31, 35, .1);
                color: rgba(255, 255, 255, .8);
                cursor: default;
            }
            .button-3:active {
                background-color: #298e46;
                box-shadow: rgba(20, 70, 32, .2) 0 1px 0 inset;
            }
        `;

        document.body.appendChild(myCSS);
        console_log(`==> Fineco_Inbox_DeleteAll: onDOMContentLoaded - myCSS.outerHTML='${myCSS.outerHTML}'`);
    }

    function onWindowLoaded()
    {
        console_log(`==> Fineco_MyCards_ShowOnlyCC: onWindowLoaded - document.readyState=${document.readyState}`);
        addMyButton();
    }

    function addMyButton()
    {
        console_log("==> Fineco_MyCards_ShowOnlyCC: addMyButton");

        let interval_ms = 250;
        let timerId = setInterval2((inputTimerId) =>
        {
            let effectiveTimerId = (inputTimerId === undefined) ? timerId : inputTimerId;
            console_log(`==> Fineco_MyCards_ShowOnlyCC: addMyButton - inputTimerId=${inputTimerId}, effectiveTimerId=${effectiveTimerId}`);

            let divMovimenti = document.querySelector("div.movimenti-container");
            console_log(`==> Fineco_MyCards_ShowOnlyCC: addMyButton - divMovimenti=${divMovimenti}`);
            if (divMovimenti !== null)
            {
                console_log("==> Fineco_MyCards_ShowOnlyCC: addMyButton - data READY");

                clearInterval(effectiveTimerId);
                console_log(`==> Fineco_MyCards_ShowOnlyCC: addMyButton - TIMER STOPPED - effectiveTimerId=${effectiveTimerId}`);

                // Create a new button that will allow to show only the credit card entries.
                let myButton = Object.assign(document.createElement("button"), {id: "myButton", textContent: "SHOW ONLY CREDIT CARD", className: "button-3"});
                myButton.addEventListener("click", showOnlyCC);
                console_log(`==> Fineco_MyCards_ShowOnlyCC: addMyButton - myButton.outerHTML='${myButton.outerHTML}'`);

                // The button is placed before the "divMovimenti".
                divMovimenti.before(myButton);

                console_log(`==> Fineco_MyCards_ShowOnlyCC: addMyButton - DONE`);
            }
            else
            {
                console_log("==> Fineco_MyCards_ShowOnlyCC: addMyButton - data NOT READY... wait");
            }
        }, interval_ms);
    }

    function showOnlyCC()
    {
        console_log("==> Fineco_MyCards_ShowOnlyCC: showOnlyCC");

        // First of all delete the span tag (eventually added in a previous click) that shows the total amount of the credit card transactions.
        let mySpan = document.querySelector("span#mySpan");
        console_log(`==> Fineco_MyCards_ShowOnlyCC: showOnlyCC - mySpan=${mySpan}`);
        if (mySpan !== null)
        {
            mySpan.remove();
        }

        // Then remove the bancomat entries.
        let bancomatEntries = document.querySelectorAll("div.movimenti-container div.text-right > img[src$='Bancomat.svg']");
        console_log(`==> Fineco_MyCards_ShowOnlyCC: showOnlyCC - bancomatEntries.length=${bancomatEntries.length}`);

        // Sometimes there was a problem when the bancomat entries were removed. In details, it happened when in the same day there was a visa entry and a bancomat entry.
        // After the bancomat entry was removed if I tried to expand the visa entry (in order to see the details of the transaction) an error was generated.
        // Therefore I decided to hide the bancomat entries instead of remove them.
        bancomatEntries.forEach((bancomatEntry, i) =>
        {
            // The bancomat entries will be hidden.
            let divAccordionWrapper = bancomatEntry.closest("div.accordionWrapper");
            console_log(`==> Fineco_MyCards_ShowOnlyCC: showOnlyCC - i=${i}, divAccordionWrapper=${divAccordionWrapper}`);
            if (divAccordionWrapper !== null)
            {
                divAccordionWrapper.style.display = "none";  // Hide node.
            }
        });

        // Finally calculate the total amount of the credit card transactions.
        calculateTotalCC();
    }

    function calculateTotalCC()
    {
        console_log(`==> Fineco_MyCards_ShowOnlyCC: calculateTotalCC`);

        let allEntries = document.querySelectorAll("div.accordionWrapper");
        console_log(`==> Fineco_MyCards_ShowOnlyCC: calculateTotalCC - allEntries.length=${allEntries.length}`);

        let ccEntries = Array.from(allEntries).filter((entry) => {return (entry.style.display !== "none");});
        console_log(`==> Fineco_MyCards_ShowOnlyCC: calculateTotalCC - ccEntries.length=${ccEntries.length}`);

        let totalCC = 0;
        ccEntries.forEach((ccEntry, i) =>
        {
            //console_log(`==> Fineco_MyCards_ShowOnlyCC: calculateTotalCC - i=${i}`);
            let spanAmount = ccEntry.querySelector("div.text-right.amountDetail > span.detailAmount");

            let amountText = spanAmount.textContent.slice(0,-4);
            let amountText2;

            // Try to understand the type of decimal point (dot or comma) used in the page (it is supposed that there are always two digits after the decimal point).
            if (amountText.slice(-3,-2) == ",")
            {
                // The decimal point is a comma (",")... therefore remove the "thousand" separators (".") and transform the comma decimal point in dot decimal point.
                amountText2 = amountText.replace(/\./g,"").replace(/\,/g,".");
            }
            else
            {
                // The decimal point is a dot (".")... Therefore only remove the "thousand" separators (",").
                amountText2 = amountText.replace(/\,/g,"");
            }

            // Now the variable "amountText2" is a string that contains numbers and at most the dot decimal point... i.e it can be parsed with "parseFloat".
            let amountValue = parseFloat(amountText2);
            totalCC += amountValue;
        });

        addMySpan(totalCC);
    }

    function addMySpan(totalCC)
    {
        console_log(`==> Fineco_MyCards_ShowOnlyCC: addMySpan - totalCC=${totalCC}`);

        // Add a span (next to the new button) that shows the total amount of the credit card transactions.
        let totalCCText = " TOTAL: " + Number(Math.abs(totalCC)).toLocaleString("it-IT", {style: "currency", currency: "EUR"});
        let mySpan = Object.assign(document.createElement("span"), {id: "mySpan", textContent: totalCCText, style: "color: blue; font-weight: bold; font-size: 16px"});
        console_log(`==> Fineco_MyCards_ShowOnlyCC: addMySpan - mySpan.outerHTML='${mySpan.outerHTML}'`);

        let myButton = document.querySelector("button#myButton");

        // The span is placed after the "myButton".
        myButton.after(mySpan);
    }

    console_log("==> Fineco_MyCards_ShowOnlyCC: Script loaded");
})();