diff --git a/config/labor_expense_table.php b/config/labor_expense_table.php index 03486e22..26132eb0 100644 --- a/config/labor_expense_table.php +++ b/config/labor_expense_table.php @@ -38,8 +38,8 @@ return [ ['key' => 'Y', 'label' => '年度速算扣除数', 'group' => 'fund', 'kind' => 'formula_number', 'formula' => '=IF(W#=0,"",IF(W#<=0,0,IF(W#<=36000,0,IF(W#<=144000,2520,IF(W#<=300000,16920,IF(W#<=420000,31920,IF(W#<=660000,52920,IF(W#<=960000,85920,181920))))))))'], ['key' => 'Z', 'label' => '全年个税', 'group' => 'fund', 'kind' => 'formula_number', 'formula' => '=W#*X#-Y#'], ['key' => 'AA', 'label' => '单月应纳税所得额区间', 'group' => 'salary_parttime', 'kind' => 'formula_number', 'formula' => '=IF(T#<=0.03,0,IF(T#<=0.1,3000,12000))'], - ['key' => 'AB', 'label' => '福利费', 'group' => 'salary_parttime', 'kind' => 'number'], - ['key' => 'AC', 'label' => '现金', 'group' => 'salary_parttime', 'kind' => 'number'], + ['key' => 'AB', 'label' => '福利费', 'group' => 'salary_parttime', 'kind' => 'formula_number', 'formula' => '=IF(F#<=0,0,IF(O#=10000,IF(S#-AA#>5000,S#-AA#,0),IF(O#=12000,S#-AA#,0)))'], + ['key' => 'AC', 'label' => '现金', 'group' => 'salary_parttime', 'kind' => 'formula_number', 'formula' => '=IF(F#<=0,0,IF(O#=5025,IF(F#<=5025,0,F#-O#),IF(O#=8000,IF(T#<=0.03,0,S#-AA#),IF(O#=10000,IF(S#-AA#<=5000,S#-AA#,0),0))))'], ['key' => 'AD', 'label' => '兼职工资合计', 'group' => 'salary_parttime', 'kind' => 'formula_number', 'formula' => '=AB#+AC#'], ['key' => 'AE', 'label' => '新8月工资应发', 'group' => 'salary_parttime', 'kind' => 'formula_number', 'formula' => '=F#-AD#'], ['key' => 'AF', 'label' => '新月度应纳税所得额', 'group' => 'salary_parttime', 'kind' => 'formula_number', 'formula' => '=AE#-G#-I#-P#-R#'], diff --git a/resources/views/business/pages/financial-operations/labor-expenses.blade.php b/resources/views/business/pages/financial-operations/labor-expenses.blade.php index 40e8145b..060410af 100644 --- a/resources/views/business/pages/financial-operations/labor-expenses.blade.php +++ b/resources/views/business/pages/financial-operations/labor-expenses.blade.php @@ -569,10 +569,6 @@ ? null : originalTaxable * originalMonthlyBracket.rate - originalMonthlyBracket.deduction; const originalAnnualTax = originalMonthlyTax === null ? null : originalMonthlyTax * 12; - const parttimeSalary = v('AB') + v('AC'); - const newSalary = v('F') - parttimeSalary; - const salaryTaxable = newSalary - v('G') - monthlyBasicDeduction - - numeric(newEmployerHousingFund) - numeric(excessHousingFundWithholding); const newMonthlyBracket = monthlyWageBracket(newMonthlyTaxable); const newMonthlyTax = newMonthlyBracket === null ? null @@ -580,6 +576,28 @@ const taxableRange = newMonthlyBracket === null || newMonthlyBracket.rate <= 0.03 ? 0 : (newMonthlyBracket.rate <= 0.1 ? 3000 : 12000); + const taxableRangeDifference = newMonthlyTaxable - taxableRange; + let cashAmount = 0; + let welfareAmount = 0; + if (newHousingFundBase === 5025) { + cashAmount = v('F') > 5025 ? v('F') - 5025 : 0; + } else if (newHousingFundBase === 8000) { + cashAmount = newMonthlyBracket === null || newMonthlyBracket.rate <= 0.03 + ? 0 + : taxableRangeDifference; + } else if (newHousingFundBase === 10000) { + if (taxableRangeDifference <= 5000) { + cashAmount = taxableRangeDifference; + } else { + welfareAmount = taxableRangeDifference; + } + } else if (newHousingFundBase === 12000) { + welfareAmount = taxableRangeDifference; + } + const parttimeSalary = welfareAmount + cashAmount; + const newSalary = v('F') - parttimeSalary; + const salaryTaxable = newSalary - v('G') - monthlyBasicDeduction + - numeric(newEmployerHousingFund) - numeric(excessHousingFundWithholding); const salaryMonthlyBracket = monthlyWageBracket(salaryTaxable); const salaryAnnualTaxable = salaryTaxable * 12; const salaryBracket = annualBracket(salaryAnnualTaxable); @@ -639,6 +657,8 @@ S: newMonthlyTaxable, V: newMonthlyTax, AA: taxableRange, + AB: welfareAmount, + AC: cashAmount, W: newAnnualTaxable, X: originalRate, Y: originalDeduction, diff --git a/tests/Feature/Business/LaborExpensePageAccessTest.php b/tests/Feature/Business/LaborExpensePageAccessTest.php index 39608248..b5f5057b 100644 --- a/tests/Feature/Business/LaborExpensePageAccessTest.php +++ b/tests/Feature/Business/LaborExpensePageAccessTest.php @@ -73,7 +73,7 @@ class LaborExpensePageAccessTest extends FeatureTestCase ); $this->assertCount(61, $fields); - $this->assertCount(48, $formulaFields); + $this->assertCount(50, $formulaFields); $response = $this->loginAs($chenxi)->get(route('business.pages.show', [ 'section' => 'financial-operations', @@ -97,11 +97,13 @@ class LaborExpensePageAccessTest extends FeatureTestCase ->assertSee('=Q#-H#', false) ->assertSee('=S#*T#-U#', false) ->assertSee('=IF(T#<=0.03,0,IF(T#<=0.1,3000,12000))', false) + ->assertSee('=IF(F#<=0,0,IF(O#=10000', false) + ->assertSee('=IF(F#<=0,0,IF(O#=5025', false) ->assertDontSee('data-labor-row="0"', false); $html = $response->getContent(); $this->assertSame(61, substr_count($html, 'data-labor-header="')); - $this->assertSame(48, substr_count($html, 'class="labor-expense-formula"')); + $this->assertSame(50, substr_count($html, 'class="labor-expense-formula"')); } public function test_basic_deduction_tax_amount_and_housing_fund_base_are_formula_driven(): void @@ -129,6 +131,16 @@ class LaborExpensePageAccessTest extends FeatureTestCase $this->assertSame('formula_number', $fields['AA']['kind']); $this->assertSame('=IF(T#<=0.03,0,IF(T#<=0.1,3000,12000))', $fields['AA']['formula']); + $this->assertSame('formula_number', $fields['AB']['kind']); + $this->assertSame( + '=IF(F#<=0,0,IF(O#=10000,IF(S#-AA#>5000,S#-AA#,0),IF(O#=12000,S#-AA#,0)))', + $fields['AB']['formula'] + ); + $this->assertSame('formula_number', $fields['AC']['kind']); + $this->assertSame( + '=IF(F#<=0,0,IF(O#=5025,IF(F#<=5025,0,F#-O#),IF(O#=8000,IF(T#<=0.03,0,S#-AA#),IF(O#=10000,IF(S#-AA#<=5000,S#-AA#,0),0))))', + $fields['AC']['formula'] + ); } public function test_monthly_and_annual_tax_quick_deductions_are_formula_driven(): void