NAME
    Business::Tax::ID::PPH21 - Routines to help calculate Indonesian income
    tax article 21 (PPh pasal 21)

VERSION
    This document describes version 0.068 of Business::Tax::ID::PPH21 (from
    Perl distribution Business-Tax-ID-PPH21), released on 2025-04-11.

SYNOPSIS
DESCRIPTION
  Notes about laws/regulations
   PP 55/2022
    Regarding PPh Pasal 21, this law only regulates the taxing of "natura"
    (non-cash benefits given to employees, such as laptops, phones, etc). PP
    55/2022 does not change PTKP or tax brackets.

   UU HPP 7/2021
   UU 36/2008
   UU 7/1983
    The law ("undang-undang") for income tax ("pajak penghasilan") in
    Indonesia is UU 7/1983 (along with its several amendments, the latest
    two of which are UU 36/2008, UU HPP 7/2021, and PP 55/2022). This law is
    comprised of several articles ("pasal"). Article 21 ("pasal 21")
    regulates earned income, which is income generated by
    individual/statutory bodies from performed work/services, including:
    employment (salary and benefits, as well as severance pay), freelance
    work, business, pension, and "jaminan hari tua" (life insurance paid to
    dependents when a worker is deceased). Article 21 also regulates some
    types of passive income, which is income generated from capital or other
    non-work sources, including: savings interests, gifts/lotteries,
    royalties.

    Some other passive income like rent and dividends are regulated in
    article 23 ("pasal 23") instead of article 21. And some articles
    regulate other aspects or special cases, e.g. income tax for sales to
    government agencies/import/specific industries ("pasal 22"), rules
    regarding monthly tax payments ("pasal 25"), or rules regarding work
    earned in Indonesia by non-citizens ("pasal 26").

    This module contains several routines to help calculate income tax
    article 21.

FUNCTIONS
  calc_net_income_from_pph21_op
    Usage:

     calc_net_income_from_pph21_op(%args) -> [$status_code, $reason, $payload, \%result_meta]

    Given that someone pays a certain amount of PPh 21 op, calculate her
    yearly net income.

    Examples:

    *   Someone who doesn't pay PPh 21 op earns at or below PTKP:

         calc_net_income_from_pph21_op(year => 2016, pph21_op => 0, tp_status => "TK/0"); # -> [200, "OK", 54000000, {}]

    *   Example #2:

         calc_net_income_from_pph21_op(year => 2016, pph21_op => 20000000, tp_status => "K/2");

        Result:

         [200, "OK", 234166666.666667, {}]

    If pph21_op is 0, will return the PTKP amount. Actually one can earn
    between zero and the full PTKP amount to pay zero PPh 21 op.

    This function is not exported by default, but exportable.

    Arguments ('*' denotes required arguments):

    *   monthly => *bool*

        Instead of yearly, return monthly net income.

    *   pph21_op* => *float*

        Amount of PPh 21 op paid.

    *   tp_status* => *str*

        Taxypayer status.

        Taypayer status reflects his/her marital status and affects the
        amount of his/her non-taxable income.

    *   year => *int*

        (No description)

    Returns an enveloped result (an array).

    First element ($status_code) is an integer containing HTTP-like status
    code (200 means OK, 4xx caller error, 5xx function error). Second
    element ($reason) is a string containing error message, or something
    like "OK" if status is 200. Third element ($payload) is the actual
    result, but usually not present when enveloped result is an error
    response ($status_code is not 2xx). Fourth element (%result_meta) is
    called result metadata and is optional, a hash that contains extra
    information, much like how HTTP response headers provide additional
    metadata.

    Return value: (any)

  calc_pph21_op
    Usage:

     calc_pph21_op(%args) -> [$status_code, $reason, $payload, \%result_meta]

    Calculate PPh 21 for individuals ("OP", "orang pribadi").

    Examples:

    *   Someone who earns below PTKP:

         calc_pph21_op(year => 2015, net_income => 30000000, tp_status => "TK/0"); # -> [200, "OK", 0, {}]

    *   Example #2:

         calc_pph21_op(year => 2015, net_income => 300000000, tp_status => "K/2");

        Result:

         [200, "OK", 33750000, {}]

    This function is not exported by default, but exportable.

    Arguments ('*' denotes required arguments):

    *   net_income* => *float*

        Yearly net income.

    *   tp_status* => *str*

        Taxypayer status.

        Taypayer status reflects his/her marital status and affects the
        amount of his/her non-taxable income.

    *   year => *int*

        (No description)

    Returns an enveloped result (an array).

    First element ($status_code) is an integer containing HTTP-like status
    code (200 means OK, 4xx caller error, 5xx function error). Second
    element ($reason) is a string containing error message, or something
    like "OK" if status is 200. Third element ($payload) is the actual
    result, but usually not present when enveloped result is an error
    response ($status_code is not 2xx). Fourth element (%result_meta) is
    called result metadata and is optional, a hash that contains extra
    information, much like how HTTP response headers provide additional
    metadata.

    Return value: (any)

  get_pph21_op_ptkp
    Usage:

     get_pph21_op_ptkp(%args) -> [$status_code, $reason, $payload, \%result_meta]

    Get PPh21 non-taxable income amount ("PTKP") for individuals.

    Examples:

    *   Example #1:

         get_pph21_op_ptkp(year => 2016);

        Result:

         [
           200,
           "OK",
           {
             "K/0"   => 58500000,
             "K/1"   => 63000000,
             "K/2"   => 67500000,
             "K/3"   => 72000000,
             "K/I/0" => 112500000,
             "K/I/1" => 117000000,
             "K/I/2" => 121500000,
             "K/I/3" => 126000000,
             "TK/0"  => 54000000,
             "TK/1"  => 58500000,
             "TK/2"  => 63000000,
             "TK/3"  => 67500000,
           },
           {},
         ]

    When calculating individual income tax, the net income is subtracted by
    this amount first. This means that if a person has income below this
    amount, he/she does not need to pay income tax.

    This function is not exported by default, but exportable.

    Arguments ('*' denotes required arguments):

    *   year => *int*

        (No description)

    Returns an enveloped result (an array).

    First element ($status_code) is an integer containing HTTP-like status
    code (200 means OK, 4xx caller error, 5xx function error). Second
    element ($reason) is a string containing error message, or something
    like "OK" if status is 200. Third element ($payload) is the actual
    result, but usually not present when enveloped result is an error
    response ($status_code is not 2xx). Fourth element (%result_meta) is
    called result metadata and is optional, a hash that contains extra
    information, much like how HTTP response headers provide additional
    metadata.

    Return value: (any)

  get_pph21_op_rates
    Usage:

     get_pph21_op_rates(%args) -> [$status_code, $reason, $payload, \%result_meta]

    Get tax rates for PPh21 for individuals ("OP", "orang pribadi").

    Examples:

    *   Example #1:

         get_pph21_op_rates(year => 2022);

        Result:

         [
           200,
           "OK",
           [
             { max => 60000000, rate => 0.05 },
             { xmin => 60000000, max => 250000000, rate => 0.15 },
             { xmin => 250000000, max => 500000000, rate => 0.25 },
             { xmin => 500000000, max => 5000000000, rate => 0.3 },
             { xmin => 5000000000, rate => 0.35 },
           ],
           {
             "table.field_formats" => [undef, undef, ["percent", { sprintf => "%3.0f%%" }]],
             "table.fields"        => ["xmin", "max", "rate"],
           },
         ]

    PPh21 differentiates rates between individuals ("OP", "orang pribadi")
    and statutory bodies ("badan"). Both are progressive. This routine
    returns the tax rates for individuals.

    Keywords: tax rates, tax brackets.

    This function is not exported by default, but exportable.

    Arguments ('*' denotes required arguments):

    *   year => *int*

        (No description)

    Returns an enveloped result (an array).

    First element ($status_code) is an integer containing HTTP-like status
    code (200 means OK, 4xx caller error, 5xx function error). Second
    element ($reason) is a string containing error message, or something
    like "OK" if status is 200. Third element ($payload) is the actual
    result, but usually not present when enveloped result is an error
    response ($status_code is not 2xx). Fourth element (%result_meta) is
    called result metadata and is optional, a hash that contains extra
    information, much like how HTTP response headers provide additional
    metadata.

    Return value: (any)

HOMEPAGE
    Please visit the project's homepage at
    <https://metacpan.org/release/Business-Tax-ID-PPH21>.

SOURCE
    Source repository is at
    <https://github.com/perlancar/perl-Business-Tax-ID-PPH21>.

SEE ALSO
AUTHOR
    perlancar <perlancar@cpan.org>

CONTRIBUTING
    To contribute, you can send patches by email/via RT, or send pull
    requests on GitHub.

    Most of the time, you don't need to build the distribution yourself. You
    can simply modify the code, then test via:

     % prove -l

    If you want to build the distribution (e.g. to try to install it locally
    on your system), you can install Dist::Zilla,
    Dist::Zilla::PluginBundle::Author::PERLANCAR,
    Pod::Weaver::PluginBundle::Author::PERLANCAR, and sometimes one or two
    other Dist::Zilla- and/or Pod::Weaver plugins. Any additional steps
    required beyond that are considered a bug and can be reported to me.

COPYRIGHT AND LICENSE
    This software is copyright (c) 2025 by perlancar <perlancar@cpan.org>.

    This is free software; you can redistribute it and/or modify it under
    the same terms as the Perl 5 programming language system itself.

BUGS
    Please report any bugs or feature requests on the bugtracker website
    <https://rt.cpan.org/Public/Dist/Display.html?Name=Business-Tax-ID-PPH21
    >

    When submitting a bug or request, please include a test-file or a patch
    to an existing test-file that illustrates the bug or desired feature.

