245 lines
9.9 KiB
Python
245 lines
9.9 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
from odoo import Command
|
|
from odoo.addons.account.tests.common import AccountTestInvoicingCommon
|
|
from odoo.tests import tagged
|
|
from odoo.exceptions import UserError
|
|
|
|
|
|
@tagged('post_install', '-at_install')
|
|
class TestAccountTax(AccountTestInvoicingCommon):
|
|
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
super().setUpClass()
|
|
cls.company_data_2 = cls.setup_other_company()
|
|
|
|
@classmethod
|
|
def default_env_context(cls):
|
|
# OVERRIDE
|
|
return {}
|
|
|
|
def set_up_and_use_tax(self):
|
|
|
|
self.env['account.move'].create({
|
|
'move_type': 'out_invoice',
|
|
'date': '2023-01-01',
|
|
'invoice_line_ids': [
|
|
Command.create({
|
|
'name': 'invoice_line',
|
|
'quantity': 1.0,
|
|
'price_unit': 100.0,
|
|
'tax_ids': [Command.set(self.company_data['default_tax_sale'].ids)],
|
|
}),
|
|
],
|
|
})
|
|
|
|
# Create two lines after creating the move so that those lines are not used in the move
|
|
self.company_data['default_tax_sale'].write({
|
|
'invoice_repartition_line_ids': [
|
|
Command.create({'repartition_type': 'tax', 'factor_percent': 0.0}),
|
|
],
|
|
'refund_repartition_line_ids': [
|
|
Command.create({'repartition_type': 'tax', 'factor_percent': 0.0}),
|
|
],
|
|
})
|
|
|
|
self.flush_tracking()
|
|
self.assertTrue(self.company_data['default_tax_sale'].is_used)
|
|
|
|
def flush_tracking(self):
|
|
""" Force the creation of tracking values. """
|
|
self.env.flush_all()
|
|
self.cr.flush()
|
|
|
|
def test_changing_tax_company(self):
|
|
''' Ensure you can't change the company of an account.tax if there are some journal entries '''
|
|
|
|
# Avoid duplicate key value violates unique constraint "account_tax_name_company_uniq".
|
|
self.company_data['default_tax_sale'].name = 'test_changing_account_company'
|
|
|
|
self.env['account.move'].create({
|
|
'move_type': 'out_invoice',
|
|
'date': '2019-01-01',
|
|
'invoice_line_ids': [
|
|
(0, 0, {
|
|
'name': 'invoice_line',
|
|
'quantity': 1.0,
|
|
'price_unit': 100.0,
|
|
'tax_ids': [(6, 0, self.company_data['default_tax_sale'].ids)],
|
|
}),
|
|
],
|
|
})
|
|
|
|
with self.assertRaises(UserError), self.cr.savepoint():
|
|
self.company_data['default_tax_sale'].company_id = self.company_data_2['company']
|
|
|
|
def test_logging_of_tax_update_when_tax_is_used(self):
|
|
""" Modifications of a used tax should be logged. """
|
|
|
|
self.set_up_and_use_tax()
|
|
|
|
self.company_data['default_tax_sale'].write({
|
|
'name': self.company_data['default_tax_sale'].name + ' MODIFIED',
|
|
'amount': 21,
|
|
'amount_type': 'fixed',
|
|
'type_tax_use': 'purchase',
|
|
'price_include_override': 'tax_included',
|
|
'include_base_amount': True,
|
|
'is_base_affected': False,
|
|
})
|
|
self.flush_tracking()
|
|
self.assertEqual(len(self.company_data['default_tax_sale'].message_ids), 1,
|
|
"Only 1 message should have been created when updating all the values.")
|
|
# There are 7 tracked values in account.tax and we update each of them, each on should be included in the message
|
|
self.assertEqual(len(self.company_data['default_tax_sale'].message_ids.tracking_value_ids), 7,
|
|
"The number of updated value should be 7.")
|
|
|
|
def test_logging_of_repartition_lines_addition_when_tax_is_used(self):
|
|
""" Adding repartition lines in a used tax should be logged. """
|
|
|
|
self.set_up_and_use_tax()
|
|
|
|
self.company_data['default_tax_sale'].write({
|
|
'invoice_repartition_line_ids': [
|
|
Command.create({'repartition_type': 'tax', 'factor_percent': -100.0}),
|
|
],
|
|
'refund_repartition_line_ids': [
|
|
Command.create({'repartition_type': 'tax', 'factor_percent': -100.0}),
|
|
],
|
|
})
|
|
self.flush_tracking()
|
|
|
|
previews = self.company_data['default_tax_sale'].message_ids.mapped('preview')
|
|
self.assertIn(
|
|
"New Invoice repartition line 4: -100.0 (Factor Percent) None (Account) None (Tax Grids) False (Use in tax closing)",
|
|
previews
|
|
)
|
|
self.assertIn(
|
|
"New Refund repartition line 4: -100.0 (Factor Percent) None (Account) None (Tax Grids) False (Use in tax closing)",
|
|
previews
|
|
)
|
|
|
|
def test_logging_of_repartition_lines_update_when_tax_is_used(self):
|
|
""" Updating repartition lines in a used tax should be logged. """
|
|
|
|
self.set_up_and_use_tax()
|
|
|
|
last_invoice_rep_line = self.company_data['default_tax_sale'].invoice_repartition_line_ids\
|
|
.filtered(lambda tax_rep: not tax_rep.factor_percent)
|
|
last_refund_rep_line = self.company_data['default_tax_sale'].refund_repartition_line_ids\
|
|
.filtered(lambda tax_rep: not tax_rep.factor_percent)
|
|
|
|
self.company_data['default_tax_sale'].write({
|
|
"invoice_repartition_line_ids": [
|
|
Command.update(last_invoice_rep_line.id, {
|
|
'factor_percent': -100,
|
|
'tag_ids': [Command.create({'name': 'TaxTag12345'})]
|
|
}),
|
|
],
|
|
"refund_repartition_line_ids": [
|
|
Command.update(last_refund_rep_line.id, {
|
|
'factor_percent': -100,
|
|
'account_id': self.company_data['default_account_tax_purchase'].id,
|
|
}),
|
|
],
|
|
})
|
|
self.flush_tracking()
|
|
|
|
previews = self.company_data['default_tax_sale'].message_ids.mapped('preview')
|
|
self.assertIn("Invoice repartition line 3: 0.0 -100.0 (Factor Percent) None ['TaxTag12345'] (Tax Grids)", previews)
|
|
self.assertIn("Refund repartition line 3: 0.0 -100.0 (Factor Percent) None 131000 Tax Paid (Account) False True (Use in tax closing)", previews)
|
|
|
|
def test_logging_of_repartition_lines_reordering_when_tax_is_used(self):
|
|
""" Reordering repartition lines in a used tax should be logged. """
|
|
|
|
self.set_up_and_use_tax()
|
|
|
|
last_invoice_rep_line = self.company_data['default_tax_sale'].invoice_repartition_line_ids\
|
|
.filtered(lambda tax_rep: not tax_rep.factor_percent)
|
|
last_refund_rep_line = self.company_data['default_tax_sale'].refund_repartition_line_ids\
|
|
.filtered(lambda tax_rep: not tax_rep.factor_percent)
|
|
|
|
self.company_data['default_tax_sale'].write({
|
|
"invoice_repartition_line_ids": [
|
|
Command.update(last_invoice_rep_line.id, {'sequence': 0}),
|
|
],
|
|
"refund_repartition_line_ids": [
|
|
Command.update(last_refund_rep_line.id, {'sequence': 0}),
|
|
],
|
|
})
|
|
self.flush_tracking()
|
|
|
|
previews = self.company_data['default_tax_sale'].message_ids.mapped('preview')
|
|
self.assertIn("Invoice repartition line 1: 100.0 0.0 (Factor Percent)", previews)
|
|
self.assertIn("Invoice repartition line 3: 0.0 100.0 (Factor Percent) None 251000 Tax Received (Account) False True (Use in tax closing)", previews)
|
|
|
|
def test_logging_of_repartition_lines_removal_when_tax_is_used(self):
|
|
""" Deleting repartition lines in a used tax should be logged. """
|
|
|
|
self.set_up_and_use_tax()
|
|
|
|
last_invoice_rep_line = self.company_data['default_tax_sale'].invoice_repartition_line_ids.sorted(key=lambda r: r.sequence)[-1]
|
|
last_refund_rep_line = self.company_data['default_tax_sale'].refund_repartition_line_ids.sorted(key=lambda r: r.sequence)[-1]
|
|
|
|
self.company_data['default_tax_sale'].write({
|
|
"invoice_repartition_line_ids": [
|
|
Command.delete(last_invoice_rep_line.id),
|
|
],
|
|
"refund_repartition_line_ids": [
|
|
Command.delete(last_refund_rep_line.id),
|
|
],
|
|
})
|
|
self.flush_tracking()
|
|
|
|
previews = self.company_data['default_tax_sale'].message_ids.mapped('preview')
|
|
self.assertIn(
|
|
"Removed Invoice repartition line 3: 0.0 (Factor Percent) None (Account) None (Tax Grids) False (Use in tax closing)",
|
|
previews
|
|
)
|
|
self.assertIn(
|
|
"Removed Refund repartition line 3: 0.0 (Factor Percent) None (Account) None (Tax Grids) False (Use in tax closing)",
|
|
previews
|
|
)
|
|
|
|
def test_tax_is_used_when_in_transactions(self):
|
|
''' Ensures that a tax is set to used when it is part of some transactions '''
|
|
|
|
# Account.move is one type of transaction
|
|
tax_invoice = self.env['account.tax'].create({
|
|
'name': 'test_is_used_invoice',
|
|
'amount': '100',
|
|
})
|
|
|
|
self.env['account.move'].create({
|
|
'move_type': 'out_invoice',
|
|
'date': '2023-01-01',
|
|
'invoice_line_ids': [
|
|
Command.create({
|
|
'name': 'invoice_line',
|
|
'quantity': 1.0,
|
|
'price_unit': 100.0,
|
|
'tax_ids': [Command.set(tax_invoice.ids)],
|
|
}),
|
|
],
|
|
})
|
|
tax_invoice.invalidate_model(fnames=['is_used'])
|
|
self.assertTrue(tax_invoice.is_used)
|
|
|
|
# Account.reconcile is another of transaction
|
|
tax_reconciliation = self.env['account.tax'].create({
|
|
'name': 'test_is_used_reconcilition',
|
|
'amount': '100',
|
|
})
|
|
self.env['account.reconcile.model'].create({
|
|
'name': "test_tax_is_used",
|
|
'rule_type': 'writeoff_suggestion',
|
|
'auto_reconcile': False,
|
|
'line_ids': [Command.create({
|
|
'account_id': self.company_data['default_account_revenue'].id,
|
|
'tax_ids': [Command.set(tax_reconciliation.ids)],
|
|
})],
|
|
})
|
|
tax_reconciliation.invalidate_model(fnames=['is_used'])
|
|
self.assertTrue(tax_reconciliation.is_used)
|