Skip to content

Commit

Permalink
[FIX] account: apply correct tags to move lines when using cash rounding
Browse files Browse the repository at this point in the history
To reproduce:
1- Configure a 0.05 cash rounding modifying the tax amount

2- Create an invoice using this rounding, for 3€, with a 21% tax (configured with some tags related on tax repartition; a Belgian one for example). => This will create a 0.02 tax rounding move line, for a total tax amount of 0.63 + 0.02 = 0.65

3- Check the tax report => Only 0.63 appears

This is wrong and leads to inconsistencies with the tax closing (which will consider 0.65 because of the tax account used), or the generic tax report (which only considers tax_line_id field, not tag_ids). The tags should be copied from the line we intend to modify the tax amounts of.

OPW 2714411

closes #83058

X-original-commit: d132c8d
Signed-off-by: Laurent Smet <las@odoo.com>
Signed-off-by: Olivier Colson <oco@odoo.com>
  • Loading branch information
oco-odoo committed Jan 20, 2022
1 parent 398070e commit e8e4b0f
Show file tree
Hide file tree
Showing 5 changed files with 241 additions and 32 deletions.
1 change: 1 addition & 0 deletions addons/account/models/account_move.py
Expand Up @@ -891,6 +891,7 @@ def _apply_cash_rounding(self, diff_balance, diff_amount_currency, cash_rounding
'name': _('%s (rounding)', biggest_tax_line.name),
'account_id': biggest_tax_line.account_id.id,
'tax_repartition_line_id': biggest_tax_line.tax_repartition_line_id.id,
'tax_tag_ids': [(6, 0, biggest_tax_line.tax_tag_ids.ids)],
'exclude_from_invoice_tab': True,
})

Expand Down
68 changes: 60 additions & 8 deletions addons/account/tests/test_account_move_in_invoice.py
Expand Up @@ -848,6 +848,7 @@ def test_in_invoice_line_onchange_taxes_1(self):
})

def test_in_invoice_line_onchange_cash_rounding_1(self):
# Test 'add_invoice_line' rounding
move_form = Form(self.invoice)
# Add a cash rounding having 'add_invoice_line'.
move_form.invoice_cash_rounding_id = self.cash_rounding_a
Expand Down Expand Up @@ -901,23 +902,70 @@ def test_in_invoice_line_onchange_cash_rounding_1(self):
self.term_line_vals_1,
], self.move_vals)

move_form = Form(self.invoice)
# Change the cash rounding to one having 'biggest_tax'.
move_form.invoice_cash_rounding_id = self.cash_rounding_b
move_form.save()
# Test 'biggest_tax' rounding

self.assertInvoiceValues(self.invoice, [
self.company_data['company'].country_id = self.env.ref('base.us')

# Add a tag to product_a's default tax
tax_line_tag = self.env['account.account.tag'].create({
'name': "Tax tag",
'applicability': 'taxes',
'country_id': self.company_data['company'].country_id.id,
})

repartition_line = self.tax_purchase_a.invoice_repartition_line_ids.filtered(lambda x: x.repartition_type == 'tax')
repartition_line.write({'tag_ids': [(4, tax_line_tag.id, 0)]})

# Create the invoice
biggest_tax_invoice = self.env['account.move'].create({
'move_type': 'in_invoice',
'invoice_date': '2019-01-01',
'partner_id': self.partner_a.id,
'invoice_cash_rounding_id': self.cash_rounding_b.id,
'invoice_payment_term_id': self.pay_terms_a.id,
'invoice_line_ids': [
(0, 0, {
'product_id': self.product_a.id,
'price_unit': 799.99,
'tax_ids': [(6, 0, self.product_a.supplier_taxes_id.ids)],
'product_uom_id': self.product_a.uom_id.id,
}),

(0, 0, {
'product_id': self.product_b.id,
'price_unit': self.product_b.standard_price,
'tax_ids': [(6, 0, self.product_b.supplier_taxes_id.ids)],
'product_uom_id': self.product_b.uom_id.id,
}),
],
})

self.assertInvoiceValues(biggest_tax_invoice, [
{
**self.product_line_vals_1,
'price_unit': 799.99,
'price_subtotal': 799.99,
'price_total': 919.99,
'amount_currency': 799.99,
'debit': 799.99,
'tax_repartition_line_id': None,
'tax_tag_ids': [],
},
{
**self.product_line_vals_2,
'tax_repartition_line_id': None,
'tax_tag_ids': [],
},
{
**self.tax_line_vals_1,
'tax_repartition_line_id': repartition_line.id,
'tax_tag_ids': tax_line_tag.ids,
},
{
**self.tax_line_vals_2,
'tax_repartition_line_id': self.tax_purchase_b.invoice_repartition_line_ids.filtered(lambda x: x.repartition_type == 'tax').id,
'tax_tag_ids': [],
},
self.product_line_vals_2,
self.tax_line_vals_1,
self.tax_line_vals_2,
{
'name': '%s (rounding)' % self.tax_purchase_a.name,
'product_id': False,
Expand All @@ -931,6 +979,8 @@ def test_in_invoice_line_onchange_cash_rounding_1(self):
'price_total': -0.04,
'tax_ids': [],
'tax_line_id': self.tax_purchase_a.id,
'tax_repartition_line_id': repartition_line.id,
'tax_tag_ids': tax_line_tag.ids,
'currency_id': self.company_data['currency'].id,
'amount_currency': -0.04,
'debit': 0.0,
Expand All @@ -944,6 +994,8 @@ def test_in_invoice_line_onchange_cash_rounding_1(self):
'price_total': -1127.95,
'amount_currency': -1127.95,
'credit': 1127.95,
'tax_repartition_line_id': None,
'tax_tag_ids': [],
},
], {
**self.move_vals,
Expand Down
68 changes: 60 additions & 8 deletions addons/account/tests/test_account_move_in_refund.py
Expand Up @@ -531,6 +531,7 @@ def test_in_refund_line_onchange_taxes_1(self):
})

def test_in_refund_line_onchange_cash_rounding_1(self):
# Test 'add_invoice_line' rounding
move_form = Form(self.invoice)
# Add a cash rounding having 'add_invoice_line'.
move_form.invoice_cash_rounding_id = self.cash_rounding_a
Expand Down Expand Up @@ -584,23 +585,70 @@ def test_in_refund_line_onchange_cash_rounding_1(self):
self.term_line_vals_1,
], self.move_vals)

move_form = Form(self.invoice)
# Change the cash rounding to one having 'biggest_tax'.
move_form.invoice_cash_rounding_id = self.cash_rounding_b
move_form.save()
# Test 'biggest_tax' rounding

self.assertInvoiceValues(self.invoice, [
self.company_data['company'].country_id = self.env.ref('base.us')

# Add a tag to product_a's default tax
tax_line_tag = self.env['account.account.tag'].create({
'name': "Tax tag",
'applicability': 'taxes',
'country_id': self.company_data['company'].country_id.id,
})

repartition_line = self.tax_purchase_a.refund_repartition_line_ids.filtered(lambda x: x.repartition_type == 'tax')
repartition_line.write({'tag_ids': [(4, tax_line_tag.id, 0)]})

# Create the invoice
biggest_tax_invoice = self.env['account.move'].create({
'move_type': 'in_refund',
'invoice_date': '2019-01-01',
'partner_id': self.partner_a.id,
'invoice_cash_rounding_id': self.cash_rounding_b.id,
'invoice_payment_term_id': self.pay_terms_a.id,
'invoice_line_ids': [
(0, 0, {
'product_id': self.product_a.id,
'price_unit': 799.99,
'tax_ids': [(6, 0, self.product_a.supplier_taxes_id.ids)],
'product_uom_id': self.product_a.uom_id.id,
}),

(0, 0, {
'product_id': self.product_b.id,
'price_unit': self.product_b.standard_price,
'tax_ids': [(6, 0, self.product_b.supplier_taxes_id.ids)],
'product_uom_id': self.product_b.uom_id.id,
}),
],
})

self.assertInvoiceValues(biggest_tax_invoice, [
{
**self.product_line_vals_1,
'price_unit': 799.99,
'price_subtotal': 799.99,
'price_total': 919.99,
'amount_currency': -799.99,
'credit': 799.99,
'tax_repartition_line_id': None,
'tax_tag_ids': [],
},
{
**self.product_line_vals_2,
'tax_repartition_line_id': None,
'tax_tag_ids': [],
},
{
**self.tax_line_vals_1,
'tax_repartition_line_id': repartition_line.id,
'tax_tag_ids': tax_line_tag.ids,
},
{
**self.tax_line_vals_2,
'tax_repartition_line_id': self.tax_purchase_b.refund_repartition_line_ids.filtered(lambda x: x.repartition_type == 'tax').id,
'tax_tag_ids': [],
},
self.product_line_vals_2,
self.tax_line_vals_1,
self.tax_line_vals_2,
{
'name': '%s (rounding)' % self.tax_purchase_a.name,
'product_id': False,
Expand All @@ -614,6 +662,8 @@ def test_in_refund_line_onchange_cash_rounding_1(self):
'price_total': -0.04,
'tax_ids': [],
'tax_line_id': self.tax_purchase_a.id,
'tax_repartition_line_id': repartition_line.id,
'tax_tag_ids': tax_line_tag.ids,
'currency_id': self.company_data['currency'].id,
'amount_currency': 0.04,
'debit': 0.04,
Expand All @@ -627,6 +677,8 @@ def test_in_refund_line_onchange_cash_rounding_1(self):
'price_total': -1127.95,
'amount_currency': 1127.95,
'debit': 1127.95,
'tax_repartition_line_id': None,
'tax_tag_ids': [],
},
], {
**self.move_vals,
Expand Down
68 changes: 60 additions & 8 deletions addons/account/tests/test_account_move_out_invoice.py
Expand Up @@ -1450,6 +1450,7 @@ def test_out_invoice_line_onchange_analytic_2(self):
])

def test_out_invoice_line_onchange_cash_rounding_1(self):
# Test 'add_invoice_line' rounding
move_form = Form(self.invoice)
# Add a cash rounding having 'add_invoice_line'.
move_form.invoice_cash_rounding_id = self.cash_rounding_a
Expand Down Expand Up @@ -1503,23 +1504,70 @@ def test_out_invoice_line_onchange_cash_rounding_1(self):
self.term_line_vals_1,
], self.move_vals)

move_form = Form(self.invoice)
# Change the cash rounding to one having 'biggest_tax'.
move_form.invoice_cash_rounding_id = self.cash_rounding_b
move_form.save()
# Test 'biggest_tax' rounding

self.assertInvoiceValues(self.invoice, [
self.company_data['company'].country_id = self.env.ref('base.us')

# Add a tag to product_a's default tax
tax_line_tag = self.env['account.account.tag'].create({
'name': "Tax tag",
'applicability': 'taxes',
'country_id': self.company_data['company'].country_id.id,
})

repartition_line = self.tax_sale_a.invoice_repartition_line_ids.filtered(lambda x: x.repartition_type == 'tax')
repartition_line.write({'tag_ids': [(4, tax_line_tag.id, 0)]})

# Create the invoice
biggest_tax_invoice = self.env['account.move'].create({
'move_type': 'out_invoice',
'invoice_date': '2019-01-01',
'partner_id': self.partner_a.id,
'invoice_cash_rounding_id': self.cash_rounding_b.id,
'invoice_payment_term_id': self.pay_terms_a.id,
'invoice_line_ids': [
(0, 0, {
'product_id': self.product_a.id,
'price_unit': 999.99,
'tax_ids': [(6, 0, self.product_a.taxes_id.ids)],
'product_uom_id': self.product_a.uom_id.id,
}),

(0, 0, {
'product_id': self.product_b.id,
'price_unit': self.product_b.lst_price,
'tax_ids': [(6, 0, self.product_b.taxes_id.ids)],
'product_uom_id': self.product_b.uom_id.id,
}),
],
})

self.assertInvoiceValues(biggest_tax_invoice, [
{
**self.product_line_vals_1,
'price_unit': 999.99,
'price_subtotal': 999.99,
'price_total': 1149.99,
'amount_currency': -999.99,
'credit': 999.99,
'tax_repartition_line_id': None,
'tax_tag_ids': [],
},
{
**self.product_line_vals_2,
'tax_repartition_line_id': None,
'tax_tag_ids': [],
},
{
**self.tax_line_vals_1,
'tax_repartition_line_id': repartition_line.id,
'tax_tag_ids': tax_line_tag.ids,
},
{
**self.tax_line_vals_2,
'tax_repartition_line_id': self.tax_sale_b.invoice_repartition_line_ids.filtered(lambda x: x.repartition_type == 'tax').id,
'tax_tag_ids': [],
},
self.product_line_vals_2,
self.tax_line_vals_1,
self.tax_line_vals_2,
{
'name': '%s (rounding)' % self.tax_sale_a.name,
'product_id': False,
Expand All @@ -1533,6 +1581,8 @@ def test_out_invoice_line_onchange_cash_rounding_1(self):
'price_total': -0.04,
'tax_ids': [],
'tax_line_id': self.tax_sale_a.id,
'tax_repartition_line_id': repartition_line.id,
'tax_tag_ids': tax_line_tag.ids,
'currency_id': self.company_data['currency'].id,
'amount_currency': 0.04,
'debit': 0.04,
Expand All @@ -1546,6 +1596,8 @@ def test_out_invoice_line_onchange_cash_rounding_1(self):
'price_total': -1409.95,
'amount_currency': 1409.95,
'debit': 1409.95,
'tax_repartition_line_id': None,
'tax_tag_ids': [],
},
], {
**self.move_vals,
Expand Down

0 comments on commit e8e4b0f

Please sign in to comment.