Esketit - Add Net Return to Statement

Proving to others that it's important

// ==UserScript==
// @name         Esketit - Add Net Return to Statement
// @namespace    http://esketit.com/
// @version      2024-10-17
// @description  Proving to others that it's important
// @author       rs232
// @match        https://esketit.com/investor/account-statement
// @icon         https://www.google.com/s2/favicons?sz=32&domain_url=https%3A%2F%2Fwww.esketit.com
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // Store previous values to track changes
    let previousValues = {
        interestReceived: "0,00",
        bonusReceived: "0,00",
        referralBonusReceived: "0,00",
        secondaryMarketIncome: "0,00",
        secondaryMarketExpense: "0,00"
    };

    // Function to check if any value has changed
    function checkValues() {
        let interestReceived = document.querySelector(".panel-row:nth-child(10) > .text-right");
        let bonusReceived = document.querySelector(".panel-row:nth-child(11) > .text-right");
        let referralBonusReceived = document.querySelector(".panel-row:nth-child(12) > .text-right");
        let secondaryMarketIncome = document.querySelector(".panel-row:nth-child(13) > .text-right");
        let secondaryMarketExpense = document.querySelector(".panel-row:nth-child(14) > .text-right");

        // Check if any of the values have changed from their previous state
        if (
            (interestReceived && interestReceived.textContent.trim() !== previousValues.interestReceived) ||
            (bonusReceived && bonusReceived.textContent.trim() !== previousValues.bonusReceived) ||
            (referralBonusReceived && referralBonusReceived.textContent.trim() !== previousValues.referralBonusReceived) ||
            (secondaryMarketIncome && secondaryMarketIncome.textContent.trim() !== previousValues.secondaryMarketIncome) ||
            (secondaryMarketExpense && secondaryMarketExpense.textContent.trim() !== previousValues.secondaryMarketExpense)
        ) {
            // Delay to allow for data stabilization
            setTimeout(doMe, 500); // Adjust the timeout as needed

            // Update previous values after displaying alerts
            previousValues.interestReceived = interestReceived ? interestReceived.textContent.trim() : "0,00";
            previousValues.bonusReceived = bonusReceived ? bonusReceived.textContent.trim() : "0,00";
            previousValues.referralBonusReceived = referralBonusReceived ? referralBonusReceived.textContent.trim() : "0,00";
            previousValues.secondaryMarketIncome = secondaryMarketIncome ? secondaryMarketIncome.textContent.trim() : "0,00";
            previousValues.secondaryMarketExpense = secondaryMarketExpense ? secondaryMarketExpense.textContent.trim() : "0,00";
        }
    }

    function formatCurrency(value) {
        // Format the number with dots as thousand separators and two decimal places
        return value.toString().replace('.', ',').replace(/\B(?=(\d{3})+(?!\d))/g, '.');
    }

    function doMe() {
        // Get values and strip out the Euro sign and unwanted spaces
        let interestReceived = parseFloat(document.querySelector(".panel-row:nth-child(10) > .text-right").textContent.replace('€', '').replace(/\s/g, '').replace(',', '.')) || 0;
        let bonusReceived = parseFloat(document.querySelector(".panel-row:nth-child(11) > .text-right").textContent.replace('€', '').replace(/\s/g, '').replace(',', '.')) || 0;
        let referralBonusReceived = parseFloat(document.querySelector(".panel-row:nth-child(12) > .text-right").textContent.replace('€', '').replace(/\s/g, '').replace(',', '.')) || 0;
        let secondaryMarketIncome = parseFloat(document.querySelector(".panel-row:nth-child(13) > .text-right").textContent.replace('€', '').replace(/\s/g, '').replace(',', '.')) || 0;

        // For secondary market expense, we assume it's already a negative number
        let secondaryMarketExpense = parseFloat(document.querySelector(".panel-row:nth-child(14) > .text-right").textContent.replace('€', '').replace(/\s/g, '').replace(',', '.')) || 0;

        // Calculate Net Interest (adding all variables including negative expense)
        let netInterest = interestReceived + bonusReceived + referralBonusReceived + secondaryMarketIncome + secondaryMarketExpense;

        // Format the net interest for display
        const formattedNetInterest = formatCurrency(netInterest.toFixed(2));

        // Create or update the Net Interest display div
        let netInterestDiv = document.getElementById('net-interest-display');

        if (!netInterestDiv) {
            // Create new div if it doesn't exist
            netInterestDiv = document.createElement('div');
            netInterestDiv.id = 'net-interest-display';
            netInterestDiv.style.display = 'flex'; // Use flexbox for layout
            netInterestDiv.style.justifyContent = 'space-between'; // Space between items
            netInterestDiv.style.marginTop = '10px'; // Add some spacing above
            netInterestDiv.style.color = 'darkgreen'; // Set text color to dark green
            netInterestDiv.style.fontWeight = 'bold'; // Make text bold

            const referenceLabel = document.createElement('div');
            referenceLabel.innerText = 'Net Interest';

            const valueLabel = document.createElement('div');
            valueLabel.innerText = `€ ${formattedNetInterest}`;

            netInterestDiv.appendChild(referenceLabel);
            netInterestDiv.appendChild(valueLabel);

            // Insert the new div after the specified element
            const targetElement = document.querySelector('.mt-3');
            targetElement.parentNode.insertBefore(netInterestDiv, targetElement.nextSibling);

        } else {
            // Update existing div with new Net Interest value
            netInterestDiv.children[1].innerText = `€ ${formattedNetInterest}`;
        }

        // Call colorize function after updating values
        colorizeFigures();
    }

    function colorizeFigures() {
        const elementsToColorizeGreen = [
            ".panel-row:nth-child(10) > .text-right", // Interest received
            ".panel-row:nth-child(11) > .text-right", // Bonus received
            ".panel-row:nth-child(12) > .text-right", // Referral bonus received
            ".panel-row:nth-child(13) > .text-right" // Secondary market income
        ];

        elementsToColorizeGreen.forEach(selector => {
            const element = document.querySelector(selector);

            if (element) {
                const amountText = element.textContent.replace('€', '').replace(/\s/g, '').replace(',', '.');
                const amountValue = parseFloat(amountText);

                if (amountValue > 0) {
                    element.style.color = 'green'; // Apply green color for positive amounts
                } else {
                    element.style.color = ''; // Reset color if not greater than zero
                }
            }
        });

        // Colorize the secondary market expense in red if not € 0,00
        const expenseElement = document.querySelector(".panel-row:nth-child(14) > .text-right");

        if (expenseElement) {
            const expenseText = expenseElement.textContent.replace('€', '').replace(/\s/g, '').replace(',', '.');
            const expenseValue = parseFloat(expenseText);

            if (expenseValue !== 0.00) {
                expenseElement.style.color = 'red'; // Apply red color for non-zero amounts
            } else {
                expenseElement.style.color = ''; // Reset color if it is zero
            }
        }
    }

    const targetElement = document.body; // Observe the whole body for changes

    // Create a MutationObserver to watch for changes in the target element
    const observer = new MutationObserver((mutationsList) => {
        mutationsList.forEach(mutation => {
            checkValues(); // Call checkValues whenever there is a mutation
        });
    });

    // Configure the observer to watch for child nodes and character data changes
    observer.observe(targetElement, {
        childList: true,
        subtree: true,
        characterData: true
    });

    // Initial check when the page loads
    window.addEventListener('load', () => {
      checkValues();
      doMe(); // Ensure that Net Interest is displayed on load.
      colorizeFigures(); // Initial call to set colors on load as well.
    });
})();