# Part of Odoo. See LICENSE file for full copyright and licensing details. from odoo import api, fields, models, _ from odoo.exceptions import UserError class L10nInTdsComputationWizard(models.TransientModel): _name = 'l10n.in.tds.computation.wizard' _description = 'Indian Payroll: TDS computation' @api.model def default_get(self, fields): res = super().default_get(fields) if self.env.company.country_id.code != "IN": raise UserError(_('You must be logged in a Indian company to use this feature')) if not res.get('version_id') and self.env.context.get('active_id') and self.env.context.get('active_model') == 'hr.version': res['version_id'] = self.env.context['active_id'] version_id = self.env['hr.version'].browse(res['version_id']) res['payslip_id'] = self.env['hr.payslip'].search([ ('version_id', '=', version_id.id), ('employee_id', '=', version_id.employee_id.id), ('date_from', '>=', version_id.contract_date_start), ('state', 'in', ['validated', 'paid']), ], limit=1, order='date_from desc').id if not res.get('currency_id') and self.env.company.currency_id: res['currency_id'] = self.env.company.currency_id.id if not res.get('standard_deduction'): # Clearing the cache because the changes made to the parameter value are not being reflected here. self.env.registry.clear_cache() res['standard_deduction'] = self.env['hr.rule.parameter']._get_parameter_from_code('l10n_in_standard_deduction') return res version_id = fields.Many2one('hr.version') payslip_id = fields.Many2one('hr.payslip') currency_id = fields.Many2one("res.currency", string='Currency') total_income = fields.Float(string="Total Income(Year)", compute="_compute_total_income", readonly=False) standard_deduction = fields.Float(string="Standard Deduction", readonly=True) taxable_income = fields.Float(string="Taxable Income", compute="_compute_taxable_income") tax_on_taxable_income = fields.Float(string="Tax on Taxable Income", compute="_compute_taxable_income") rebate = fields.Float(string="Rebate Under Section 87A(a)", compute="_compute_taxable_income", help="Reduces tax liability for resident individuals with income up to ₹7 lakh (New Regime)") total_tax_on_income = fields.Float(string="Total Tax on Income", compute="_compute_taxable_income") surcharge = fields.Float(string="Surcharge", compute="_compute_taxable_income") cess = fields.Float(string="Health and Education Cess", compute="_compute_taxable_income", help="4% of Tax on Taxable Income + Surcharge") total_tax = fields.Float(string="Total Tax to be Paid", compute="_compute_taxable_income") net_monthly = fields.Float(string="Monthly Net Payable", compute="_compute_net_monthly") tds_monthly = fields.Float(string="Monthly TDS Payable", compute="_compute_tds_monthly", readonly=False, store=True) @api.depends('version_id', 'total_income') def _compute_net_monthly(self): for record in self: record.net_monthly = record.payslip_id.net_wage or record.total_income / 12 @api.depends('net_monthly') def _compute_total_income(self): for record in self: record.total_income = record.net_monthly * 12 @api.depends('total_income') def _compute_taxable_income(self): rule_parameter = self.env['hr.rule.parameter'] tax_slabs = rule_parameter._get_parameter_from_code('l10n_in_tds_rate_chart') tax_slabs_for_surcharge = rule_parameter._get_parameter_from_code('l10n_in_surcharge_rate') min_income_for_surcharge = rule_parameter._get_parameter_from_code('l10n_in_min_income_surcharge') min_income_for_rebate = rule_parameter._get_parameter_from_code('l10n_in_min_income_tax_rebate') for record in self: record.taxable_income = max(record.total_income - record.standard_deduction, 0) tax = 0 for rate, (lower, upper) in tax_slabs: if record.taxable_income <= lower: break taxable_amount = min(record.taxable_income, float(upper)) - lower tax += round(taxable_amount * rate) record.tax_on_taxable_income = tax if record.taxable_income >= min_income_for_rebate: marginal_income = record.taxable_income - min_income_for_rebate record.rebate = max(record.tax_on_taxable_income - marginal_income, 0) else: record.rebate = record.tax_on_taxable_income record.total_tax_on_income = record.tax_on_taxable_income - record.rebate if record.taxable_income > min_income_for_surcharge: surcharge = 0 for rate, amount in tax_slabs_for_surcharge: if record.taxable_income <= float(amount[1]): surcharge = record.total_tax_on_income * rate break max_tax_slabs = rule_parameter._get_parameter_from_code('l10n_in_max_surcharge_tax_rate') max_taxable_income, max_tax, max_surcharge = 0, 0, 0 for income, tax, surcharge_rate in max_tax_slabs: if record.taxable_income <= income: break else: max_taxable_income, max_tax, max_surcharge = income, tax, surcharge_rate excess_income = record.taxable_income - max_taxable_income max_tax_with_surcharge = max_tax + max_surcharge total_tax_with_surcharge = record.total_tax_on_income + surcharge excess_tax = total_tax_with_surcharge - max_tax_with_surcharge if excess_tax - excess_income > 0: record.surcharge = max_tax_with_surcharge + record.taxable_income - max_taxable_income - record.total_tax_on_income else: record.surcharge = surcharge else: record.surcharge = 0.0 record.cess = (record.total_tax_on_income + record.surcharge) * 0.04 record.total_tax = record.total_tax_on_income + record.cess + record.surcharge @api.depends('total_tax') def _compute_tds_monthly(self): for record in self: record.tds_monthly = record.total_tax / 12 def set_tds_on_contracts(self): for record in self: record.version_id.l10n_in_tds = record.tds_monthly