account/tests/test_invoice_tax_totals.py

943 lines
33 KiB
Python
Raw Permalink Normal View History

# -*- coding: utf-8 -*-
from odoo.addons.account.tests.common import AccountTestInvoicingCommon
from odoo.fields import Command
from odoo.tests import tagged
@tagged('post_install', '-at_install')
class TestTaxTotals(AccountTestInvoicingCommon):
@classmethod
def setUpClass(cls, chart_template_ref=None):
super().setUpClass(chart_template_ref=chart_template_ref)
cls.tax_group1 = cls.env['account.tax.group'].create({
'name': '1',
'sequence': 1
})
cls.tax_group2 = cls.env['account.tax.group'].create({
'name': '2',
'sequence': 2
})
cls.tax_group_sub1 = cls.env['account.tax.group'].create({
'name': 'subtotals 1',
'preceding_subtotal': "PRE GROUP 1",
'sequence': 3
})
cls.tax_group_sub2 = cls.env['account.tax.group'].create({
'name': 'subtotals 2',
'preceding_subtotal': "PRE GROUP 2",
'sequence': 4
})
cls.tax_group_sub3 = cls.env['account.tax.group'].create({
'name': 'subtotals 3',
'preceding_subtotal': "PRE GROUP 1", # same as sub1, on purpose
'sequence': 5
})
cls.tax_16 = cls.env['account.tax'].create({
'name': "tax_16",
'amount_type': 'percent',
'amount': 16.0,
})
cls.tax_53 = cls.env['account.tax'].create({
'name': "tax_53",
'amount_type': 'percent',
'amount': 53.0,
})
cls.tax_17a = cls.env['account.tax'].create({
'name': "tax_17a",
'amount_type': 'percent',
'amount': 17.0,
})
cls.tax_17b = cls.tax_17a.copy({'name': "tax_17b"})
def assertTaxTotals(self, document, expected_values):
main_keys_to_ignore = {'formatted_amount_total', 'formatted_amount_untaxed'}
group_keys_to_ignore = {'group_key', 'formatted_tax_group_amount', 'formatted_tax_group_base_amount'}
subtotals_keys_to_ignore = {'formatted_amount'}
to_compare = document.tax_totals
for key in main_keys_to_ignore:
del to_compare[key]
for key in group_keys_to_ignore:
for groups in to_compare['groups_by_subtotal'].values():
for group in groups:
del group[key]
for key in subtotals_keys_to_ignore:
for subtotal in to_compare['subtotals']:
del subtotal[key]
self.assertEqual(to_compare, expected_values)
def _create_document_for_tax_totals_test(self, lines_data):
""" Creates and returns a new record of a model defining a tax_totals
field and using the related widget.
By default, this function creates an invoice, but it is overridden in sale
and purchase to create respectively a sale.order or a purchase.order. This way,
we can test the invoice_tax_totals from both these models in the same way as
account.move's.
:param lines_data: a list of tuple (amount, taxes), where amount is a base amount,
and taxes a recordset of account.tax objects corresponding
to the taxes to apply on this amount. Each element of the list
corresponds to a line of the document (invoice line, PO line, SO line).
"""
invoice_lines_vals = [
(0, 0, {
'name': 'line',
'display_type': 'product',
'account_id': self.company_data['default_account_revenue'].id,
'price_unit': amount,
'tax_ids': [(6, 0, taxes.ids)],
})
for amount, taxes in lines_data]
return self.env['account.move'].create({
'move_type': 'out_invoice',
'partner_id': self.partner_a.id,
'invoice_date': '2019-01-01',
'invoice_line_ids': invoice_lines_vals,
})
def test_multiple_tax_lines(self):
tax_10 = self.env['account.tax'].create({
'name': "tax_10",
'amount_type': 'percent',
'amount': 10.0,
'tax_group_id': self.tax_group1.id,
})
tax_20 = self.env['account.tax'].create({
'name': "tax_20",
'amount_type': 'percent',
'amount': 20.0,
'tax_group_id': self.tax_group2.id,
})
document = self._create_document_for_tax_totals_test([
(1000, tax_10 + tax_20),
(1000, tax_10),
(1000, tax_20),
])
self.assertTaxTotals(document, {
'amount_total': 3600,
'amount_untaxed': 3000,
'display_tax_base': True,
'groups_by_subtotal': {
'Untaxed Amount': [
{
'tax_group_name': self.tax_group1.name,
'tax_group_amount': 200,
'tax_group_base_amount': 2000,
'tax_group_id': self.tax_group1.id,
},
{
'tax_group_name': self.tax_group2.name,
'tax_group_amount': 400,
'tax_group_base_amount': 2000,
'tax_group_id': self.tax_group2.id,
},
],
},
'subtotals': [
{
'name': "Untaxed Amount",
'amount': 3000,
}
],
'subtotals_order': ["Untaxed Amount"],
})
# Same but both are sharing the same tax group.
tax_20.tax_group_id = self.tax_group1
document.invalidate_model(['tax_totals'])
self.assertTaxTotals(document, {
'amount_total': 3600,
'amount_untaxed': 3000,
'display_tax_base': False,
'groups_by_subtotal': {
'Untaxed Amount': [
{
'tax_group_name': self.tax_group1.name,
'tax_group_amount': 600,
'tax_group_base_amount': 3000,
'tax_group_id': self.tax_group1.id,
},
],
},
'subtotals': [
{
'name': "Untaxed Amount",
'amount': 3000,
}
],
'subtotals_order': ["Untaxed Amount"],
})
def test_zero_tax_lines(self):
tax_0 = self.env['account.tax'].create({
'name': "tax_0",
'amount_type': 'percent',
'amount': 0.0,
})
document = self._create_document_for_tax_totals_test([
(1000, tax_0),
])
self.assertTaxTotals(document, {
'amount_total': 1000,
'amount_untaxed': 1000,
'display_tax_base': False,
'groups_by_subtotal': {
'Untaxed Amount': [
{
'tax_group_name': tax_0.tax_group_id.name,
'tax_group_amount': 0,
'tax_group_base_amount': 1000,
'tax_group_id': tax_0.tax_group_id.id,
},
],
},
'subtotals': [
{
'name': "Untaxed Amount",
'amount': 1000,
}
],
'subtotals_order': ["Untaxed Amount"],
})
def test_tax_affect_base_1(self):
tax_10 = self.env['account.tax'].create({
'name': "tax_10",
'amount_type': 'percent',
'amount': 10.0,
'tax_group_id': self.tax_group1.id,
'price_include': True,
'include_base_amount': True,
})
tax_20 = self.env['account.tax'].create({
'name': "tax_20",
'amount_type': 'percent',
'amount': 20.0,
'tax_group_id': self.tax_group2.id,
})
document = self._create_document_for_tax_totals_test([
(1100, tax_10 + tax_20),
(1100, tax_10),
(1000, tax_20),
])
self.assertTaxTotals(document, {
'amount_total': 3620,
'amount_untaxed': 3000,
'display_tax_base': True,
'groups_by_subtotal': {
'Untaxed Amount': [
{
'tax_group_name': self.tax_group1.name,
'tax_group_amount': 200,
'tax_group_base_amount': 2000,
'tax_group_id': self.tax_group1.id,
},
{
'tax_group_name': self.tax_group2.name,
'tax_group_amount': 420,
'tax_group_base_amount': 2100,
'tax_group_id': self.tax_group2.id,
},
],
},
'subtotals': [
{
'name': "Untaxed Amount",
'amount': 3000,
}
],
'subtotals_order': ["Untaxed Amount"],
})
# Same but both are sharing the same tax group.
tax_20.tax_group_id = self.tax_group1
document.invalidate_model(['tax_totals'])
self.assertTaxTotals(document, {
'amount_total': 3620,
'amount_untaxed': 3000,
'display_tax_base': False,
'groups_by_subtotal': {
'Untaxed Amount': [
{
'tax_group_name': self.tax_group1.name,
'tax_group_amount': 620,
'tax_group_base_amount': 3000,
'tax_group_id': self.tax_group1.id,
},
],
},
'subtotals': [
{
'name': "Untaxed Amount",
'amount': 3000,
}
],
'subtotals_order': ["Untaxed Amount"],
})
def test_tax_affect_base_2(self):
tax_10 = self.env['account.tax'].create({
'name': "tax_10",
'amount_type': 'percent',
'amount': 10.0,
'tax_group_id': self.tax_group1.id,
'include_base_amount': True,
})
tax_20 = self.env['account.tax'].create({
'name': "tax_20",
'amount_type': 'percent',
'amount': 20.0,
'tax_group_id': self.tax_group1.id,
})
tax_30 = self.env['account.tax'].create({
'name': "tax_30",
'amount_type': 'percent',
'amount': 30.0,
'tax_group_id': self.tax_group2.id,
'include_base_amount': True,
})
document = self._create_document_for_tax_totals_test([
(1000, tax_10 + tax_20),
(1000, tax_30 + tax_10),
])
self.assertTaxTotals(document, {
'amount_total': 2750,
'amount_untaxed': 2000,
'display_tax_base': True,
'groups_by_subtotal': {
'Untaxed Amount': [
{
'tax_group_name': self.tax_group1.name,
'tax_group_amount': 450,
'tax_group_base_amount': 2300,
'tax_group_id': self.tax_group1.id,
},
{
'tax_group_name': self.tax_group2.name,
'tax_group_amount': 300,
'tax_group_base_amount': 1000,
'tax_group_id': self.tax_group2.id,
},
],
},
'subtotals': [
{
'name': "Untaxed Amount",
'amount': 2000,
}
],
'subtotals_order': ["Untaxed Amount"],
})
# Same but both are sharing the same tax group.
tax_30.tax_group_id = self.tax_group1
document.invalidate_model(['tax_totals'])
self.assertTaxTotals(document, {
'amount_total': 2750,
'amount_untaxed': 2000,
'display_tax_base': False,
'groups_by_subtotal': {
'Untaxed Amount': [
{
'tax_group_name': self.tax_group1.name,
'tax_group_amount': 750,
'tax_group_base_amount': 2000,
'tax_group_id': self.tax_group1.id,
},
],
},
'subtotals': [
{
'name': "Untaxed Amount",
'amount': 2000,
}
],
'subtotals_order': ["Untaxed Amount"],
})
def test_subtotals_basic(self):
tax_10 = self.env['account.tax'].create({
'name': "tax_10",
'amount_type': 'percent',
'amount': 10.0,
'tax_group_id': self.tax_group_sub1.id,
})
tax_25 = self.env['account.tax'].create({
'name': "tax_25",
'amount_type': 'percent',
'amount': 25.0,
'tax_group_id': self.tax_group_sub2.id,
})
tax_42 = self.env['account.tax'].create({
'name': "tax_42",
'amount_type': 'percent',
'amount': 42.0,
'tax_group_id': self.tax_group1.id,
})
document = self._create_document_for_tax_totals_test([
(1000, tax_10),
(1000, tax_25),
(100, tax_42),
(200, tax_42 + tax_10 + tax_25),
])
self.assertTaxTotals(document, {
'amount_total': 2846,
'amount_untaxed': 2300,
'display_tax_base': True,
'groups_by_subtotal': {
'Untaxed Amount': [
{
'tax_group_name': self.tax_group1.name,
'tax_group_amount': 126,
'tax_group_base_amount': 300,
'tax_group_id': self.tax_group1.id,
},
],
'PRE GROUP 1': [
{
'tax_group_name': self.tax_group_sub1.name,
'tax_group_amount': 120,
'tax_group_base_amount': 1200,
'tax_group_id': self.tax_group_sub1.id,
},
],
'PRE GROUP 2': [
{
'tax_group_name': self.tax_group_sub2.name,
'tax_group_amount': 300,
'tax_group_base_amount': 1200,
'tax_group_id': self.tax_group_sub2.id,
},
]
},
'subtotals': [
{
'name': "Untaxed Amount",
'amount': 2300,
},
{
'name': "PRE GROUP 1",
'amount': 2426,
},
{
'name': "PRE GROUP 2",
'amount': 2546,
},
],
'subtotals_order': ["Untaxed Amount", "PRE GROUP 1", "PRE GROUP 2"],
})
def test_after_total_mix(self):
tax_10 = self.env['account.tax'].create({
'name': "tax_10",
'amount_type': 'percent',
'amount': 10.0,
'tax_group_id': self.tax_group_sub3.id,
})
tax_25 = self.env['account.tax'].create({
'name': "tax_25",
'amount_type': 'percent',
'amount': -25.0,
'tax_group_id': self.tax_group_sub2.id,
})
tax_42 = self.env['account.tax'].create({
'name': "tax_42",
'amount_type': 'percent',
'amount': 42.0,
'tax_group_id': self.tax_group_sub1.id,
})
tax_30 = self.env['account.tax'].create({
'name': "tax_30",
'amount_type': 'percent',
'amount': 30.0,
'tax_group_id': self.tax_group1.id,
})
document = self._create_document_for_tax_totals_test([
(100, tax_10),
(100, tax_25 + tax_42 + tax_30),
(200, tax_10 + tax_25),
(1000, tax_30),
(100, tax_30 + tax_10)
])
self.assertTaxTotals(document, {
'amount_total': 1867,
'amount_untaxed': 1500,
'display_tax_base': True,
'groups_by_subtotal': {
'Untaxed Amount': [
{
'tax_group_name': self.tax_group1.name,
'tax_group_amount': 360,
'tax_group_base_amount': 1200,
'tax_group_id': self.tax_group1.id,
},
],
'PRE GROUP 1': [
{
'tax_group_name': self.tax_group_sub1.name,
'tax_group_amount': 42,
'tax_group_base_amount': 100,
'tax_group_id': self.tax_group_sub1.id,
},
{
'tax_group_name': self.tax_group_sub3.name,
'tax_group_amount': 40,
'tax_group_base_amount': 400,
'tax_group_id': self.tax_group_sub3.id,
},
],
'PRE GROUP 2': [
{
'tax_group_name': self.tax_group_sub2.name,
'tax_group_amount': -75,
'tax_group_base_amount': 300,
'tax_group_id': self.tax_group_sub2.id,
},
],
},
'subtotals': [
{
'name': "Untaxed Amount",
'amount': 1500,
},
{
'name': "PRE GROUP 1",
'amount': 1860,
},
{
'name': "PRE GROUP 2",
'amount': 1942,
},
],
'subtotals_order': ["Untaxed Amount", "PRE GROUP 1", "PRE GROUP 2"],
})
def test_discounted_tax(self):
tax_21_exempted = self.env['account.tax'].create({
'name': "tax_21_exempted",
'amount_type': 'group',
'amount': 2.0,
'tax_group_id': self.tax_group1.id,
'children_tax_ids': [
Command.create({
'name': "tax_exempt",
'amount_type': 'percent',
'amount': -2.0,
'include_base_amount': True,
'tax_group_id': self.tax_group_sub1.id,
'sequence': 1,
}),
Command.create({
'name': "tax_21",
'amount_type': 'percent',
'amount': 21.0,
'tax_group_id': self.tax_group_sub2.id,
'sequence': 2,
}),
Command.create({
'name': "tax_reapply",
'amount_type': 'percent',
'amount': 2.0,
'is_base_affected': False,
'tax_group_id': self.tax_group_sub3.id,
'sequence': 3,
}),
]
})
self.tax_group_sub1.preceding_subtotal = "Tax exemption"
self.tax_group_sub2.preceding_subtotal = "Tax application"
self.tax_group_sub3.preceding_subtotal = "Reapply amount"
document = self._create_document_for_tax_totals_test([
(1000 / 0.98, tax_21_exempted),
])
self.assertTaxTotals(document, {
'amount_total': 1230.41,
'amount_untaxed': 1020.41,
'display_tax_base': True,
'groups_by_subtotal': {
"Reapply amount": [{
'tax_group_name': self.tax_group_sub3.name,
'tax_group_amount': 20.41,
'tax_group_base_amount': 1020.41,
'tax_group_id': self.tax_group_sub3.id,
}],
"Tax application": [{
'tax_group_name': self.tax_group_sub2.name,
'tax_group_amount': 210.0,
'tax_group_base_amount': 1000.0,
'tax_group_id': self.tax_group_sub2.id,
}],
"Tax exemption": [{
'tax_group_name': self.tax_group_sub1.name,
'tax_group_amount': -20.41,
'tax_group_base_amount': 1020.41,
'tax_group_id': self.tax_group_sub1.id,
}],
},
'subtotals': [{
'name': "Tax exemption",
'amount': 1020.41,
}, {
'name': "Tax application",
'amount': 1000.00,
}, {
'name': "Reapply amount",
'amount': 1210.00,
}],
'subtotals_order': ["Tax exemption", "Tax application", "Reapply amount"],
})
def test_invoice_grouped_taxes_with_tax_group(self):
""" A tax of type group with a tax_group_id being the same as one of the children tax shouldn't affect the
result of the _prepare_tax_totals.
"""
tax_10_withheld = self.env['account.tax'].create({
'name': "tax_10_withheld",
'amount_type': 'group',
'tax_group_id': self.tax_group1.id,
'children_tax_ids': [
Command.create({
'name': "tax_withheld",
'amount_type': 'percent',
'amount': -47,
'tax_group_id': self.tax_group_sub1.id,
'sequence': 1,
}),
Command.create({
'name': "tax_10",
'amount_type': 'percent',
'amount': 10,
'tax_group_id': self.tax_group1.id,
'sequence': 2,
}),
]
})
self.tax_group_sub1.preceding_subtotal = "Tax withholding"
document = self._create_document_for_tax_totals_test([
(100, tax_10_withheld),
])
self.assertTaxTotals(document, {
'amount_total': 63,
'amount_untaxed': 100,
'display_tax_base': True,
'groups_by_subtotal': {
'Untaxed Amount': [{
'tax_group_name': self.tax_group1.name,
'tax_group_amount': 10,
'tax_group_base_amount': 100,
'tax_group_id': self.tax_group1.id,
}],
"Tax withholding": [{
'tax_group_name': self.tax_group_sub1.name,
'tax_group_amount': -47,
'tax_group_base_amount': 100,
'tax_group_id': self.tax_group_sub1.id,
}],
},
'subtotals': [{
'name': "Untaxed Amount",
'amount': 100,
}, {
'name': "Tax withholding",
'amount': 110,
}],
'subtotals_order': ["Untaxed Amount", "Tax withholding"],
})
def test_taxtotals_with_different_tax_rounding_methods(self):
def run_case(rounding_line, lines, expected_tax_group_amounts):
self.env.company.tax_calculation_rounding_method = rounding_line
document = self._create_document_for_tax_totals_test(lines)
tax_amounts = document.tax_totals['groups_by_subtotal']['Untaxed Amount']
if len(expected_tax_group_amounts) != len(tax_amounts):
self.fail("Wrong number of values to compare.")
for tax_amount, expected in zip(tax_amounts, expected_tax_group_amounts):
actual = tax_amount['tax_group_amount']
if document.currency_id.compare_amounts(actual, expected) != 0:
self.fail(f'{document.currency_id.round(actual)} != {expected}')
# one line, two taxes
lines = [
(100.41, self.tax_16 + self.tax_53),
]
run_case('round_per_line', lines, [69.29])
run_case('round_globally', lines, [69.29])
# two lines, different taxes
lines = [
(50.4, self.tax_17a),
(47.21, self.tax_17b),
]
run_case('round_per_line', lines, [16.60])
run_case('round_globally', lines, [16.60])
# two lines, same tax
lines = [
(50.4, self.tax_17a),
(47.21, self.tax_17a),
]
run_case('round_per_line', lines, [16.60])
run_case('round_globally', lines, [16.59])
def test_invoice_foreign_currency_tax_totals(self):
self.env['res.currency.rate'].create({
'name': '2018-01-01',
'rate': 0.2,
'currency_id': self.currency_data['currency'].id,
'company_id': self.env.company.id,
})
tax_10 = self.env['account.tax'].create({
'name': "tax_10",
'amount_type': 'percent',
'amount': 10.0,
'tax_group_id': self.tax_group1.id,
})
tax_20 = self.env['account.tax'].create({
'name': "tax_20",
'amount_type': 'percent',
'amount': 20.0,
'tax_group_id': self.tax_group2.id,
})
invoice = self.env['account.move'].create({
'move_type': 'out_invoice',
'partner_id': self.partner_a.id,
'invoice_date': '2019-01-01',
'currency_id': self.currency_data['currency'].id,
})
lines_data = [(100, tax_10), (300, tax_20)]
invoice_lines_vals = [
Command.create({
'name': 'line',
'display_type': 'product',
'account_id': self.company_data['default_account_revenue'].id,
'price_unit': amount,
'tax_ids': [Command.set(taxes.ids)],
})
for amount, taxes in lines_data
]
invoice['invoice_line_ids'] = invoice_lines_vals
self.assertTaxTotals(invoice, {
'amount_total': 470,
'amount_untaxed': 400,
'display_tax_base': True,
'groups_by_subtotal': {
'Untaxed Amount': [
{
'tax_group_name': self.tax_group1.name,
'tax_group_amount': 10,
'tax_group_base_amount': 100,
'tax_group_id': self.tax_group1.id,
'tax_group_amount_company_currency': 50,
'tax_group_base_amount_company_currency': 500,
},
{
'tax_group_name': self.tax_group2.name,
'tax_group_amount': 60,
'tax_group_base_amount': 300,
'tax_group_id': self.tax_group2.id,
'tax_group_amount_company_currency': 300,
'tax_group_base_amount_company_currency': 1500,
}
]
},
'subtotals': [
{
'name': "Untaxed Amount",
'amount': 400,
'amount_company_currency': 2000,
}
],
'subtotals_order': ["Untaxed Amount"],
})
def test_cash_rounding_amount_total_rounded(self):
tax_15 = self.env['account.tax'].create({
'name': "tax_15",
'amount_type': 'percent',
'tax_group_id': self.tax_group1.id,
'amount': 15.0,
})
tax_10 = self.env['account.tax'].create({
'name': "tax_10",
'amount_type': 'percent',
'tax_group_id': self.tax_group2.id,
'amount': 10.0,
})
cash_rounding_biggest_tax = self.env['account.cash.rounding'].create({
'name': 'biggest tax Rounding HALF-UP',
'rounding': 1,
'strategy': 'biggest_tax',
'rounding_method': 'HALF-UP',
})
cash_rounding_add_invoice_line = self.env['account.cash.rounding'].create({
'name': 'add invoice line Rounding HALF-UP',
'rounding': 1,
'strategy': 'add_invoice_line',
'profit_account_id': self.company_data['default_account_revenue'].id,
'loss_account_id': self.company_data['default_account_expense'].id,
'rounding_method': 'HALF-UP',
})
for move_type in ['out_invoice', 'in_invoice']:
move = self.env['account.move'].create({
'move_type': move_type,
'partner_id': self.partner_a.id,
'invoice_date': '2019-01-01',
'invoice_line_ids': [
Command.create({
'name': 'line',
'display_type': 'product',
'price_unit': 378,
'tax_ids': [Command.set(tax_15.ids)],
}),
Command.create({
'name': 'line',
'display_type': 'product',
'price_unit': 100,
'tax_ids': [Command.set(tax_10.ids)],
})
],
})
move.invoice_cash_rounding_id = cash_rounding_biggest_tax
self.assertEqual(move.tax_totals['groups_by_subtotal']['Untaxed Amount'][0]['tax_group_amount'], 57)
self.assertEqual(move.tax_totals['groups_by_subtotal']['Untaxed Amount'][1]['tax_group_amount'], 10)
self.assertEqual(move.tax_totals['amount_total'], 545)
move.invoice_cash_rounding_id = cash_rounding_add_invoice_line
self.assertEqual(move.tax_totals['groups_by_subtotal']['Untaxed Amount'][0]['tax_group_amount'], 56.7)
self.assertEqual(move.tax_totals['groups_by_subtotal']['Untaxed Amount'][1]['tax_group_amount'], 10)
self.assertEqual(move.tax_totals['rounding_amount'], 0.3)
self.assertEqual(move.tax_totals['amount_total'], 545)
def test_recompute_cash_rounding_lines(self):
# if rounding_method is changed then rounding shouldn't be recomputed in posted invoices
cash_rounding_add_invoice_line = self.env['account.cash.rounding'].create({
'name': 'Add invoice line Rounding UP',
'rounding': 1,
'strategy': 'add_invoice_line',
'profit_account_id': self.company_data['default_account_revenue'].id,
'loss_account_id': self.company_data['default_account_expense'].id,
'rounding_method': 'UP',
})
moves_rounding = {}
moves = self.env['account.move']
for move_type in ['out_invoice', 'in_invoice']:
move = self.env['account.move'].create({
'move_type': move_type,
'partner_id': self.partner_a.id,
'invoice_date': '2019-01-01',
'invoice_cash_rounding_id': cash_rounding_add_invoice_line.id,
'invoice_line_ids': [
Command.create({
'name': 'line',
'display_type': 'product',
'price_unit': 99.5,
})
],
})
moves_rounding[move] = sum(move.line_ids.filtered(lambda line: line.display_type == 'rounding').mapped('balance'))
moves += move
moves.action_post()
cash_rounding_add_invoice_line.rounding_method = 'DOWN'
# check if rounding is recomputed
moves.to_check = True
for move in moves_rounding:
self.assertEqual(sum(move.line_ids.filtered(lambda line: line.display_type == 'rounding').mapped('balance')), moves_rounding[move])
def test_cash_rounding_amount_total_rounded_foreign_currency(self):
tax_15 = self.env['account.tax'].create({
'name': "tax_15",
'amount_type': 'percent',
'amount': 15.0,
})
cash_rounding = self.env['account.cash.rounding'].create({
'name': 'Rounding HALF-UP',
'rounding': 10,
'strategy': 'biggest_tax',
'rounding_method': 'HALF-UP',
})
self.env['res.currency.rate'].create({
'name': '2023-01-01',
'rate': 0.2,
'currency_id': self.currency_data['currency'].id,
'company_id': self.env.company.id,
})
for move_type in ['out_invoice', 'in_invoice']:
move = self.env['account.move'].create({
'move_type': move_type,
'partner_id': self.partner_a.id,
'invoice_date': '2023-01-01',
'currency_id': self.currency_data['currency'].id,
'invoice_line_ids': [
Command.create({
'name': 'line',
'display_type': 'product',
'price_unit': 100,
'tax_ids': [tax_15.id],
})
]
})
move.invoice_cash_rounding_id = cash_rounding
self.assertEqual(move.tax_totals['amount_total'], 120)