Indonesia Tax System changes in 2025

Hi all i am from Indonesia.

There has been a recent change in the tax system here where they change the VAT to be 12% from the old 11%.

However essentially is the same 11%, just that value of taxable supply changes.

Old regulation:
Sub-total of Invoice = 100
value of taxable supply (DPP) = 100
VAT 11% = 11
total = 111

New regulation:
Sub-total of Invoice = 100
value of taxable supply (DPP) = 11/12 x Sub-total = 91.666
VAT 12% = 11
total = 111

Now many of my customers (soon perhaps all) require us to have this value of taxable supply (DPP) amount printed on the invoice.

can we have that in manager??

1 Like

oh wow sorry for not looking thorougly, seems like someone brought it up already!

will check on it thanks!

can you help revise the code and it’s shown like this.

  1. remove Rp. and remove decimal
  2. location of the DPP should be before the tax?

Can you share a screenshot of your Edit Form, I’m a little confused by the invoice you showed.

here it is

custom field

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

Perfect!! i tried it and still got the decimals going, then i set the min and max fraction from 2 to 0. and its perfect.

thanks so much!

Luckily we have @Mabaega as an Indonesian and a programmer that always up to date to the Manager system and tax system. You do a great job bro @Mabaega :grin::ok_hand::+1:

2 Likes

@Mabaega maybe consider changing that part of the code to:

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

Thus for Indonesia (id-ID), we set both minimumFractionDigits and maximumFractionDigits to 0, thus no decimal places will be shown, and for the US (en-US), we keep minimumFractionDigits and maximumFractionDigits set to 2, ensuring that 2 decimal places are always shown.

1 Like

Thanks for the update both of you! @eko @Mabaega you guys are awesome!

By the way i tried changing this code. but then it’s still reverting back to 2 digits.

i may not understand completely what is this id-ID and en-US means? is this related to the language of manager it’s shown as?

@yhart

I don’t understand why you choose to use numbers without decimals on your invoices. As far as I know, in the CoreTax system all numbers use two Decimal Places.

For your needs, you can change this section, replacing 2 with 0.

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

to

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

id-ID stand for Indonesian language and country code, respectively. en-US for English and United States. These codes are used in internationalization (i18n) functions like Intl.NumberFormat() to apply locale-specific formatting rules, such as number formatting, currency symbols, and date/time formats.

my customer’s requirements invoices to be without decimals.