feat: Income tax slab (#21399)

* Feat: Multiple tax as per new taxation rule

* patch:for multiple tax slab, fix: payroll and exemption validation

* Test: Fixture

* feat: income tax slab with other charges and tax exempted deduction components

* fix: added missing init file

* fix: Patch fixed

* fix: Patch fixed

* fix: test fixes

* fix: validate duplicate exemption declaration

* fix: payment entry test case

Co-authored-by: Anurag Mishra <mishranaman123@gmail.com>
This commit is contained in:
Nabin Hait
2020-04-26 17:45:57 +05:30
committed by GitHub
parent 7e73473a65
commit 58ee6c1e08
38 changed files with 1298 additions and 1375 deletions

View File

@@ -5,8 +5,7 @@ def execute():
frappe.reload_doc('hr', 'doctype', 'salary_detail')
frappe.reload_doc('hr', 'doctype', 'salary_component')
frappe.db.sql("update `tabSalary Component` set is_payable=1, is_tax_applicable=1 where type='Earning'")
frappe.db.sql("update `tabSalary Component` set is_payable=0 where type='Deduction'")
frappe.db.sql("update `tabSalary Component` set is_tax_applicable=1 where type='Earning'")
frappe.db.sql("""update `tabSalary Component` set variable_based_on_taxable_salary=1
where type='Deduction' and name in ('TDS', 'Tax Deducted at Source')""")

View File

View File

@@ -0,0 +1,99 @@
# Copyright (c) 2019, Frappe and Contributors
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import frappe
from frappe.model.utils.rename_field import rename_field
def execute():
if not frappe.db.table_exists("Payroll Period"):
return
for doctype in ("income_tax_slab", "salary_structure_assignment", "employee_other_income"):
frappe.reload_doc("hr", "doctype", doctype)
for company in frappe.get_all("Company"):
payroll_periods = frappe.db.sql("""
SELECT
name, start_date, end_date, standard_tax_exemption_amount
FROM
`tabPayroll Period`
WHERE company=%s
ORDER BY start_date DESC
""", company.name, as_dict = 1)
for i, period in enumerate(payroll_periods):
income_tax_slab = frappe.new_doc("Income Tax Slab")
income_tax_slab.name = "Tax Slab:" + period.name
if i == 0:
income_tax_slab.disabled = 0
else:
income_tax_slab.disabled = 1
income_tax_slab.effective_from = period.start_date
income_tax_slab.company = company.name
income_tax_slab.allow_tax_exemption = 1
income_tax_slab.standard_tax_exemption_amount = period.standard_tax_exemption_amount
income_tax_slab.flags.ignore_mandatory = True
income_tax_slab.submit()
frappe.db.sql(
""" UPDATE `tabTaxable Salary Slab`
SET parent = %s , parentfield = 'slabs' , parenttype = "Income Tax Slab"
WHERE parent = %s
""", (income_tax_slab.name, period.name), as_dict = 1)
if i == 0:
frappe.db.sql("""
UPDATE
`tabSalary Structure Assignment`
set
income_tax_slab = %s
where
company = %s
and from_date >= %s
and docstatus < 2
""", (income_tax_slab.name, company.name, period.start_date))
# move other incomes to separate document
migrated = []
proofs = frappe.get_all("Employee Tax Exemption Proof Submission",
filters = {'docstatus': 1},
fields =['payroll_period', 'employee', 'company', 'income_from_other_sources']
)
for proof in proofs:
if proof.income_from_other_sources:
employee_other_income = frappe.new_doc("Employee Other Income")
employee_other_income.employee = proof.employee
employee_other_income.payroll_period = proof.payroll_period
employee_other_income.company = proof.company
employee_other_income.amount = proof.income_from_other_sources
try:
employee_other_income.submit()
migrated.append([proof.employee, proof.payroll_period])
except:
pass
declerations = frappe.get_all("Employee Tax Exemption Declaration",
filters = {'docstatus': 1},
fields =['payroll_period', 'employee', 'company', 'income_from_other_sources']
)
for declaration in declerations:
if declaration.income_from_other_sources \
and [declaration.employee, declaration.payroll_period] not in migrated:
employee_other_income = frappe.new_doc("Employee Other Income")
employee_other_income.employee = declaration.employee
employee_other_income.payroll_period = declaration.payroll_period
employee_other_income.company = declaration.company
employee_other_income.amount = declaration.income_from_other_sources
try:
employee_other_income.submit()
except:
pass