Indonesia Tax System changes in 2025

Script Updated to support :

  • Business data without Base Currency,
  • Sales with Withholding Tax,
  • Indonesian and English Language,
  • en_US and id_ID Number Format,

<script id="script-wrapper">
    document.addEventListener("DOMContentLoaded", processSubtotal);

    function processSubtotal() {
        // Cari semua sel di kolom pertama yang mungkin mengandung "Subtotal" atau "Sub-total"
        const subtotalCell = [...document.querySelectorAll("tbody td:first-child")]
            .find(td => ["subtotal", "sub-total"].includes(td.textContent.trim().toLowerCase()));

        if (!subtotalCell) return;

        // Ambil baris tempat Subtotal ditemukan
        const firstSubtotalRow = subtotalCell.closest("tr");
        const subtotalValueCell = firstSubtotalRow.querySelector("td[data-value]") || firstSubtotalRow.querySelector("td:last-child");

        if (!subtotalValueCell) return;

        // Ambil nilai Subtotal
        const rawValue = subtotalValueCell.dataset.value || subtotalValueCell.textContent.trim();
        const isIdLocale = /,\d{2}$/.test(rawValue);
        const isEnLocale = /\.\d{2}$/.test(rawValue);

        let subtotalValue = isIdLocale 
            ? parseFloat(rawValue.replace(/\./g, "").replace(",", ".")) 
            : parseFloat(rawValue.replace(/,/g, ""));

        if (isNaN(subtotalValue) || subtotalValue === 0) return;

        // Hitung DPP Nilai Lain
        let dppNilaiLain = Math.round((11 / 12) * subtotalValue * 100) / 100;

        // Kloning baris Subtotal dan ubah menjadi DPP Nilai Lain
        const dppRow = firstSubtotalRow.cloneNode(true);
        const dppLabelCell = dppRow.querySelector("td[colspan]") || dppRow.querySelector("td:first-child");
        const dppValueCell = dppRow.querySelector("td[data-value]") || dppRow.querySelector("td:last-child");

        if (!dppLabelCell || !dppValueCell) return;

        dppLabelCell.textContent = "DPP Nilai Lain";
        const includeCurrencySymbol = subtotalValueCell.textContent.trim().includes("Rp");

        // Format angka sesuai locale
        const numberFormatter = new Intl.NumberFormat(isIdLocale ? "id-ID" : "en-US", {
            minimumFractionDigits: 2,
            maximumFractionDigits: 2
        });

        dppValueCell.textContent = includeCurrencySymbol
            ? `Rp ${numberFormatter.format(dppNilaiLain)}`
            : numberFormatter.format(dppNilaiLain);

        dppValueCell.setAttribute("data-value", dppNilaiLain.toFixed(2).replace(".", isIdLocale ? "," : "."));

        // Sisipkan baris setelah Subtotal pertama
        firstSubtotalRow.insertAdjacentElement("afterend", dppRow);

        // Hapus script setelah eksekusi
        document.getElementById("script-wrapper")?.remove();
    }
</script>

Script optimization as suggested by @eko. Thanks for the advice! :slight_smile:

4 Likes