Odoo18-Base/addons/l10n_in_withholding/tests/test_tds_tcs_alert.py
2025-01-06 10:57:38 +07:00

609 lines
21 KiB
Python

from odoo import Command
from odoo.addons.l10n_in.tests.common import L10nInTestInvoicingCommon
from odoo.tests import tagged
@tagged('post_install_l10n', 'post_install', '-at_install')
class TestTdsTcsAlert(L10nInTestInvoicingCommon):
@classmethod
def setUpClass(cls):
super().setUpClass()
ChartTemplate = cls.env['account.chart.template']
# ==== Chart of Accounts ====
cls.purchase_account = ChartTemplate.ref('p2107')
cls.purchase_account.write({
'l10n_in_tds_tcs_section_id': cls.env.ref('l10n_in_withholding.tds_section_194c').id
})
cls.house_expense_account = ChartTemplate.ref('p2103')
cls.house_expense_account.write({
'l10n_in_tds_tcs_section_id': cls.env.ref('l10n_in_withholding.tds_section_194c').id
})
cls.internet_account = ChartTemplate.ref('p2105')
cls.internet_account.write({
'l10n_in_tds_tcs_section_id': cls.env.ref('l10n_in_withholding.tds_section_194j').id
})
cls.rent_account = ChartTemplate.ref('p2111')
cls.rent_account.write({
'l10n_in_tds_tcs_section_id': cls.env.ref('l10n_in_withholding.tds_section_194ib').id
})
cls.sale_account = ChartTemplate.ref('p20011')
cls.sale_account.write({
'l10n_in_tds_tcs_section_id': cls.env.ref('l10n_in_withholding.tcs_section_206c1g_r').id
})
cls.service_account = ChartTemplate.ref('p20021')
cls.creditors_account = ChartTemplate.ref('p11211')
# ==== Taxes ====
cls.tax_194c = ChartTemplate.ref('tds_20_us_194c')
cls.tax_194c.write({'l10n_in_section_id': cls.env.ref('l10n_in_withholding.tds_section_194c').id})
cls.tax_194j = ChartTemplate.ref('tds_10_us_194j')
cls.tax_194j.write({'l10n_in_section_id': cls.env.ref('l10n_in_withholding.tds_section_194j').id})
cls.tax_194ib = ChartTemplate.ref('tds_20_us_194ib')
cls.tax_194ib.write({'l10n_in_section_id': cls.env.ref('l10n_in_withholding.tds_section_194ib').id})
cls.tax_206c1g_r = ChartTemplate.ref('tcs_5_us_206c_1g_som')
cls.tax_206c1g_r.write({'l10n_in_section_id': cls.env.ref('l10n_in_withholding.tcs_section_206c1g_r').id})
country_in_id = cls.env.ref("base.in").id
# ==== Partners ====
cls.partner_a.write({
'l10n_in_pan': 'ABCPM8965E'
})
cls.partner_b.write({
'vat': '27ABCPM8965E1ZE',
'l10n_in_pan': 'ABCPM8965E'
})
cls.partner_foreign_2 = cls.partner_foreign.copy()
# ==== Company ====
cls.env.company.write({
'child_ids': [
Command.create({
'name': 'Branch A',
"state_id": cls.env.ref("base.state_in_gj").id,
'account_fiscal_country_id': country_in_id,
'country_id': country_in_id,
}),
Command.create({
'name': 'Branch B',
"state_id": cls.env.ref("base.state_in_mh").id,
'account_fiscal_country_id': country_in_id,
'country_id': country_in_id,
}),
Command.create({
'name': 'Branch C',
"state_id": cls.env.ref("base.state_in_mp").id,
'account_fiscal_country_id': country_in_id,
'country_id': country_in_id,
}),
],
})
cls.cr.precommit.run() # load the CoA
cls.branch_a, cls.branch_b, cls.branch_c = cls.env.company.child_ids
def create_invoice(self, move_type=None, partner=None, invoice_date=None, amounts=None, taxes=[], company=None, accounts=[], quantities=[]):
invoice = self.init_invoice(
move_type=move_type or 'in_invoice',
partner=partner,
invoice_date=invoice_date,
post=False,
amounts=amounts,
company=company
)
for i, account in enumerate(accounts):
invoice.invoice_line_ids[i].account_id = account
for i, quantity in enumerate(quantities):
invoice.invoice_line_ids[i].quantity = quantity
for i, tax in enumerate(taxes):
invoice.invoice_line_ids[i].tax_ids = tax
invoice.action_post()
return invoice
def tds_wizard_entry(self, move, lines):
tds_wizard = self.env['l10n_in.withhold.wizard'].with_context(active_model='account.move', active_ids=move.ids).create({
'journal_id': self.env['account.journal'].search([
('company_id', '=', self.env.company.id),
('type', '=', 'general')
], limit=1).id,
'date': move.invoice_date,
})
for tax, amount in lines:
self.env['l10n_in.withhold.wizard.line'].create({
'withhold_id': tds_wizard.id,
'tax_id': tax.id,
'base': amount
})
tds_wizard.action_create_and_post_withhold()
def reverse_move(self, move, date):
move_reversal = self.env['account.move.reversal'].with_context(active_model="account.move", active_ids=move.ids).create({
'date': date,
'reason': 'no reason',
'journal_id': move.journal_id.id,
})
return move_reversal.refund_moves()
def test_tcs_tds_warning(self):
'''
Test that if any of the limit is not exceeded.
'''
move = self.create_invoice(
partner=self.partner_a,
invoice_date='2024-06-05',
amounts=[29000],
company=self.branch_a,
accounts=[self.internet_account],
quantities=[1]
)
self.assertEqual(move.l10n_in_tcs_tds_warning, False)
def test_tcs_tds_warning_on_exceeded_per_transaction_limit(self):
'''
Test that if the per transaction limit is exceeded.
'''
move = self.create_invoice(
partner=self.partner_a,
invoice_date='2024-06-05',
amounts=[31000],
company=self.branch_a,
quantities=[1]
)
self.assertEqual(move.l10n_in_tcs_tds_warning, "It's advisable to deduct TDS u/s 194C on this transaction.")
move_1 = self.create_invoice(
partner=self.partner_b,
invoice_date='2024-06-05',
amounts=[31000],
company=self.branch_b,
quantities=[1]
)
self.assertEqual(move_1.l10n_in_tcs_tds_warning, "It's advisable to deduct TDS u/s 194C on this transaction.")
self.create_invoice(
partner=self.partner_b,
invoice_date='2024-06-05',
amounts=[31000],
company=self.branch_b,
quantities=[1]
)
move_3 = self.create_invoice(
partner=self.partner_b,
invoice_date='2024-06-05',
amounts=[31000],
company=self.branch_b,
quantities=[1]
)
self.assertEqual(move_3.l10n_in_tcs_tds_warning, "It's advisable to deduct TDS u/s 194C on this transaction.")
def test_tcs_tds_warning_on_monthly_aggregate_limit(self):
'''
Test the monthly aggregate limit, the warning
message should be set accordingly.
'''
move = self.create_invoice(
partner=self.partner_a,
invoice_date='2024-06-05',
amounts=[30000],
company=self.branch_a,
accounts=[self.rent_account]
)
self.assertEqual(move.l10n_in_tcs_tds_warning, False)
move_1 = self.create_invoice(
partner=self.partner_b,
invoice_date='2024-07-06',
amounts=[20000],
company=self.branch_b,
accounts=[self.rent_account]
)
self.assertEqual(move_1.l10n_in_tcs_tds_warning, False)
move_2 = self.create_invoice(
partner=self.partner_a,
invoice_date='2024-07-16',
amounts=[31000],
company=self.branch_c,
accounts=[self.rent_account]
)
self.assertEqual(move_2.l10n_in_tcs_tds_warning, "It's advisable to deduct TDS u/s 194IB on this transaction.")
move_3 = self.create_invoice(
partner=self.partner_a,
invoice_date='2024-09-06',
amounts=[50000],
company=self.branch_c,
accounts=[self.rent_account]
)
self.assertEqual(move_3.l10n_in_tcs_tds_warning, False)
move_4 = self.create_invoice(
partner=self.partner_a,
invoice_date='2024-09-16',
amounts=[50000],
company=self.branch_c,
accounts=[self.rent_account]
)
self.assertEqual(move_4.l10n_in_tcs_tds_warning, "It's advisable to deduct TDS u/s 194IB on this transaction.")
def test_tcs_tds_warning_partner_wiht_pan(self):
'''
Test the aggregate limit when partner don't have
pan number and having pan number.
'''
# no pan number
move = self.create_invoice(
partner=self.partner_foreign,
invoice_date='2024-06-05',
amounts=[30000],
company=self.branch_a,
accounts=[self.internet_account]
)
self.assertEqual(move.l10n_in_tcs_tds_warning, False)
move_1 = self.create_invoice(
partner=self.partner_foreign_2,
invoice_date='2024-06-05',
amounts=[30000],
company=self.branch_b,
accounts=[self.internet_account]
)
self.assertEqual(move_1.l10n_in_tcs_tds_warning, False)
# same pan number
move_2 = self.create_invoice(
partner=self.partner_a,
invoice_date='2024-06-05',
amounts=[30000],
company=self.branch_a,
accounts=[self.internet_account]
)
self.assertEqual(move_2.l10n_in_tcs_tds_warning, False)
move_3 = self.create_invoice(
partner=self.partner_b,
invoice_date='2024-06-05',
amounts=[30000],
company=self.branch_b,
accounts=[self.internet_account]
)
self.assertEqual(move_3.l10n_in_tcs_tds_warning, "It's advisable to deduct TDS u/s 194J on this transaction.")
def test_tcs_tds_warning_on_exceeded_aggregate_limit(self):
'''
Test that if the aggregate limit is exceeded.
'''
move = self.create_invoice(
partner=self.partner_a,
invoice_date='2024-06-05',
amounts=[20000],
company=self.branch_a,
)
self.assertEqual(move.l10n_in_tcs_tds_warning, False)
move_1 = self.create_invoice(
partner=self.partner_b,
invoice_date='2024-07-06',
amounts=[20000],
company=self.branch_b,
)
self.assertEqual(move_1.l10n_in_tcs_tds_warning, False)
move_2 = self.create_invoice(
partner=self.partner_a,
invoice_date='2024-08-06',
amounts=[31000],
company=self.branch_c,
)
self.assertEqual(move_2.l10n_in_tcs_tds_warning, "It's advisable to deduct TDS u/s 194C on this transaction.")
move_3 = self.create_invoice(
partner=self.partner_b,
invoice_date='2024-09-06',
amounts=[5000],
company=self.branch_a,
)
self.assertEqual(move_3.l10n_in_tcs_tds_warning, False)
move_4 = self.create_invoice(
partner=self.partner_a,
invoice_date='2024-10-07',
amounts=[20000],
company=self.branch_b,
)
self.assertEqual(move_4.l10n_in_tcs_tds_warning, False)
move_5 = self.create_invoice(
partner=self.partner_b,
invoice_date='2024-11-08',
amounts=[25000],
company=self.branch_c,
)
self.assertEqual(move_5.l10n_in_tcs_tds_warning, "It's advisable to deduct TDS u/s 194C on this transaction.")
def test_tcs_tds_warning_on_case_of_credit_note(self):
'''
Test that the aggregate limit in case of debit/credit note.
'''
move = self.create_invoice(
partner=self.partner_a,
invoice_date='2024-09-01',
amounts=[2000],
company=self.branch_a,
accounts=[self.internet_account]
)
self.assertEqual(move.l10n_in_tcs_tds_warning, False)
move_1 = self.create_invoice(
partner=self.partner_b,
invoice_date='2024-09-01',
amounts=[3000],
company=self.branch_a,
accounts=[self.internet_account]
)
self.reverse_move(move, '2024-09-01')
self.assertEqual(move_1.l10n_in_tcs_tds_warning, False)
move_2 = self.create_invoice(
partner=self.partner_a,
invoice_date='2024-09-01',
amounts=[2000],
company=self.branch_a,
accounts=[self.internet_account]
)
self.assertEqual(move_2.l10n_in_tcs_tds_warning, False)
def test_tcs_tds_warning_cleared_on_available_tax(self):
'''
Test when a tax is added to the move line with a similar tax group
as the account.
'''
move = self.create_invoice(
partner=self.partner_a,
move_type='out_invoice',
invoice_date='2022-12-12',
amounts=[710000],
taxes=[self.tax_206c1g_r],
company=self.branch_a,
)
self.assertEqual(move.l10n_in_tcs_tds_warning, False)
def test_tcs_tds_warning_for_multiple_accounts_in_lines(self):
'''
Test when there are multiple products in the move line and some of them
have different accounts which have the different tax group as the account.
'''
move = self.create_invoice(
partner=self.partner_a,
move_type='in_invoice',
invoice_date='2022-12-12',
amounts=[100000, 1100000, 710000],
company=self.branch_a,
accounts=[self.rent_account, self.internet_account, self.purchase_account],
quantities=[15, 16, 10]
)
self.assertTrue(move.l10n_in_tcs_tds_warning)
move_1 = self.create_invoice(
partner=self.partner_a,
move_type='in_invoice',
invoice_date='2022-12-12',
amounts=[1000000.0, 1100000.0, 710000],
company=self.branch_a,
accounts=[self.rent_account, self.internet_account, self.purchase_account],
)
self.tds_wizard_entry(move=move_1, lines=[(self.tax_194ib, 100000), (self.tax_194j, 100000), (self.tax_194c, 100000)])
move_1.button_draft()
move_1.action_post()
self.assertEqual(move_1.l10n_in_tcs_tds_warning, False)
def test_tcs_tds_warning_for_if_line_has_price_zero(self):
'''
Test when any invoice line has Zero
'''
move = self.create_invoice(
partner=self.partner_a,
invoice_date='2022-12-12',
amounts=[101000, 0],
company=self.branch_a,
)
self.assertEqual(move.l10n_in_tcs_tds_warning, "It's advisable to deduct TDS u/s 194C on this transaction.")
move_1 = self.create_invoice(
partner=self.partner_a,
invoice_date='2022-12-12',
amounts=[0],
company=self.branch_a,
)
self.assertEqual(move_1.l10n_in_tcs_tds_warning, False)
def test_tcs_tds_warning_for_all_lines_do_not_have_taxes(self):
'''
Test when tds entry created and warning will removed
'''
move = self.create_invoice(
partner=self.partner_a,
invoice_date='2022-12-12',
amounts=[1000, 6000],
company=self.branch_a,
accounts=[],
quantities=[15, 16]
)
self.assertEqual(move.l10n_in_tcs_tds_warning, "It's advisable to deduct TDS u/s 194C on this transaction.")
self.tds_wizard_entry(move=move, lines=[(self.tax_194c, 100000)])
move.button_draft()
move.action_post()
self.assertEqual(move.l10n_in_tcs_tds_warning, False)
def test_tcs_tds_warning_for_company_branches(self):
'''
Test when the aggregate limit is exceeded in case of multiple branches
of the company,the warning message should be set accordingly.
'''
self.create_invoice(
partner=self.partner_a,
invoice_date='2024-05-14',
amounts=[25000],
company=self.branch_a,
)
self.create_invoice(
partner=self.partner_b,
invoice_date='2024-05-14',
amounts=[25000],
company=self.branch_b,
)
self.create_invoice(
partner=self.partner_b,
invoice_date='2024-05-14',
amounts=[25000],
company=self.branch_c,
quantities=[25]
)
move = self.create_invoice(
partner=self.partner_a,
invoice_date='2024-05-14',
amounts=[28000],
company=self.branch_a,
)
self.assertEqual(move.l10n_in_tcs_tds_warning, "It's advisable to deduct TDS u/s 194C on this transaction.")
def test_tcs_tds_warning_tcs_use_in_bill(self):
'''
Test when tcs section is used in the bill creation.
'''
move = self.create_invoice(
partner=self.partner_a,
invoice_date='2024-05-29',
amounts=[1100000],
company=self.branch_a,
accounts=[self.sale_account]
)
self.assertEqual(move.l10n_in_tcs_tds_warning, False)
def test_tcs_tds_warning_tds_use_in_invoice(self):
'''
Test when tcs section is used in the bill creation.
'''
move = self.create_invoice(
move_type='out_invoice',
partner=self.partner_a,
invoice_date='2024-05-29',
amounts=[110000],
company=self.branch_a,
)
self.assertEqual(move.l10n_in_tcs_tds_warning, False)
def test_tcs_tds_warning_for_multiple_accounts_same_section_in_lines(self):
'''
Test when there are multiple products in the move line and some of them
have different accounts which have the same tax group as the account.
'''
move = self.create_invoice(
partner=self.partner_a,
invoice_date='2022-12-12',
amounts=[17000, 14000],
company=self.branch_a,
accounts=[self.house_expense_account, self.purchase_account],
)
self.assertEqual(move.l10n_in_tcs_tds_warning, "It's advisable to deduct TDS u/s 194C on this transaction.")
move_1 = self.create_invoice(
partner=self.partner_a,
invoice_date='2022-12-12',
amounts=[17000, 13000],
company=self.branch_a,
accounts=[self.house_expense_account, self.purchase_account],
)
self.assertEqual(move_1.l10n_in_tcs_tds_warning, False)
move_2 = self.create_invoice(
partner=self.partner_a,
invoice_date='2022-12-12',
amounts=[30000],
company=self.branch_a,
accounts=[self.house_expense_account],
)
self.assertEqual(move_2.l10n_in_tcs_tds_warning, False)
move_3 = self.create_invoice(
partner=self.partner_a,
invoice_date='2022-12-12',
amounts=[10000],
company=self.branch_a,
)
self.assertEqual(move_3.l10n_in_tcs_tds_warning, "It's advisable to deduct TDS u/s 194C on this transaction.")
def test_tcs_tds_warning_for_not_consider_draft_cancel_invoices_for_aggregate(self):
'''
Test to exclude draft and canceled invoices from aggregate
total calculation.
'''
move = self.create_invoice(
partner=self.partner_a,
invoice_date='2022-12-12',
amounts=[16000],
company=self.branch_a,
accounts=[self.purchase_account],
)
move.button_cancel()
self.assertEqual(move.l10n_in_tcs_tds_warning, False)
move_1 = self.create_invoice(
partner=self.partner_a,
invoice_date='2022-12-12',
amounts=[25000],
company=self.branch_a,
accounts=[self.purchase_account],
)
self.assertEqual(move_1.l10n_in_tcs_tds_warning, False)
move_2 = self.create_invoice(
partner=self.partner_a,
invoice_date='2022-12-12',
amounts=[85000],
company=self.branch_a,
accounts=[self.purchase_account],
)
self.assertEqual(move_2.l10n_in_tcs_tds_warning, "It's advisable to deduct TDS u/s 194C on this transaction.")
def test_tcs_tds_warning_if_some_lines_has_tax(self):
'''
Test when a tax is added to the some of the move line
'''
move = self.create_invoice(
partner=self.partner_a,
move_type='out_invoice',
invoice_date='2022-12-12',
amounts=[710000, 710000],
taxes=[self.tax_206c1g_r],
company=self.branch_a,
)
self.assertEqual(move.l10n_in_tcs_tds_warning, "It's advisable to collect TCS u/s 206C(1G) Remittance on this transaction.")