NAME Business::Tax::ID::PPH21 - Routines to help calculate Indonesian income tax article 21 (PPh pasal 21) VERSION This document describes version 0.066 of Business::Tax::ID::PPH21 (from Perl distribution Business-Tax-ID-PPH21), released on 2023-03-30. 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 . SOURCE Source repository is at . SEE ALSO AUTHOR perlancar 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) 2023, 2021, 2020, 2019, 2017, 2015 by perlancar . 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 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.