前言
使用此种计算方式前,需要知道当年已纳税总额度以及本月应纳税额度。这两个参数需要自行根据各自系统数据计算出来,此方法只实现个税计算算法。此外,需要打开PHP的bc扩展。
参数
方法传入两个参数即可,当月应纳税额度以及本年已纳税总额度(不含当月)。
- $lauwen_monthly_tax_amount:当月应纳税额度。
- $lauwen_taxed_amount:当年已纳税总额度(不含当月)。
实现
首先是确认两个层级,一个是本年已纳税总额度所在税率层级(不含当月),另一个是本月之后本年已纳税总额度所在税率层级(含当月);最后在计算个税时使用了两种计算方式,一种是分别计算在每个税率层级的税额;另一种是使用速算扣除数进行计算,按需使用就好。
分级计算核心代码
// 分级法计算 $tax = '0'; while ($new_key >= $old_key) { $level_amount = bcsub($lauwen_month_after_amount, $lauwen_tax_amounts[$new_key], 6); if ($new_key == $old_key) { $level_amount = bcsub($lauwen_month_after_amount, $lauwen_taxed_amount, 6); } $tax = bcadd($tax, bcmul($level_amount, $lauwen_tax_rates[$new_key]), 2); $lauwen_month_after_amount = $lauwen_tax_amounts[$new_key]; $new_key --; }
速算扣除计算核心代码
// 速算扣除法计算 $quickly_old_tax = bcsub(bcmul($lauwen_taxed_amount, $lauwen_tax_rates[$old_key], 6), $lauwen_tax_quickly[$old_key], 6); $quickly_new_tax = bcsub(bcmul($lauwen_month_after_amount, $lauwen_tax_rates[$new_key], 6), $lauwen_tax_quickly[$new_key], 6); $tax0 = bcsub($quickly_new_tax, $quickly_old_tax, 2);
全部代码
function personTax($lauwen_monthly_tax_amount, $lauwen_taxed_amount) { $lauwen_tax_amounts = ['0', '36000', '144000', '300000', '420000', '660000', '960000']; $lauwen_tax_rates = ['0.03', '0.1', '0.2', '0.25', '0.3', '0.35', '0.45']; $lauwen_tax_quickly = ['0', '2520', '16920', '31920', '52920', '85920', '181920']; $lauwen_taxed_amount = (string)$lauwen_taxed_amount; $lauwen_monthly_tax_amount = (string)$lauwen_monthly_tax_amount; $lauwen_month_after_amount = bcadd($lauwen_taxed_amount, $lauwen_monthly_tax_amount, 6); // 确定当月前当年已纳税总额度所属级别,以及当月之后当年已纳税总额度所属级别 $old_key = 0; // 当月前级别 $new_key = 0; // 当月后级别 $end_key = count($lauwen_tax_amounts) - 1; foreach ($lauwen_tax_amounts as $key => $val) { if ($key == $end_key) { // 最后一级 if (bccomp($lauwen_taxed_amount, $val, 2) == 1) { $old_key = $key; } if (bccomp($lauwen_month_after_amount, $val, 2) == 1) { $new_key = $key; } } else { // if (bccomp($lauwen_taxed_amount, $val, 2) == 1 && bccomp($lauwen_taxed_amount, $lauwen_tax_amounts[$key+1], 2) == -1) { $old_key = $key; } if (bccomp($lauwen_month_after_amount, $val, 2) == 1 && bccomp($lauwen_month_after_amount, $lauwen_tax_amounts[$key+1], 2) == -1) { $new_key = $key; break; } } } // 速算扣除法计算 $quickly_old_tax = bcsub(bcmul($lauwen_taxed_amount, $lauwen_tax_rates[$old_key], 6), $lauwen_tax_quickly[$old_key], 6); $quickly_new_tax = bcsub(bcmul($lauwen_month_after_amount, $lauwen_tax_rates[$new_key], 6), $lauwen_tax_quickly[$new_key], 6); $tax0 = bcsub($quickly_new_tax, $quickly_old_tax, 2); // 差额法计算 $tax = '0'; while ($new_key >= $old_key) { $level_amount = bcsub($lauwen_month_after_amount, $lauwen_tax_amounts[$new_key], 6); if ($new_key == $old_key) { $level_amount = bcsub($lauwen_month_after_amount, $lauwen_taxed_amount, 6); } $tax = bcadd($tax, bcmul($level_amount, $lauwen_tax_rates[$new_key]), 2); $lauwen_month_after_amount = $lauwen_tax_amounts[$new_key]; $new_key --; } return json_encode([ "normal" => $tax, "quickly" => $tax0, ]); }