summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfw-bot <otis@odoo.com>2020-01-10 09:13:46 +0000
committeroco-odoo <oco@odoo.com>2020-01-10 15:16:58 +0000
commiteeac89f0555b75459b2b14978897767df29e06bf (patch)
tree3f6a34b15ab0f6320ad35e1956af825c192dffe4
parentdce3a4323b07505f3db468be5ba6f97b0bfb7e4c (diff)
[FIX] account: Manage group of taxes everytime
Before the merge of account.invoice with account.move, a group of taxes was expanded on journal items and not on invoice lines. Since both are now the same thing, we only get the group of taxes when using the 'tax_ids' field. To correctly handle this new behavior, we need to call 'flatten_taxes_hierarchy' every time we use the 'tax_ids' field to get the children taxes instead of the group of taxes itself. [FIX] account: Wrong unit price with included tax and fiscal position Steps to reproduce the bug: Let's consider a sale included tax T1 of 10% and a sale excluded tax T2 of 0% Let's consider a product P with T1 and a sale price of 110€ Let's consider a fiscal position FP that mappes T1 to T2 Let's consider a customer C with FP as fiscal position Create a customer invoice for C Add P on the first line and T1 is replaced by T2 Bug: The unit price of P was still 110€ instead of 100€ because the included tax was not removed from the base price of P. Same behavior as in 11.0 and 12.0 opw:2150564 closes odoo/odoo#43100 Co-author: simongoffin (sig@odoo.com) Forward-port-of: #42926 Forward-port-of: #42188 Signed-off-by: oco-odoo <oco-odoo@users.noreply.github.com>
-rw-r--r--addons/account/models/account_move.py57
-rw-r--r--addons/account/tests/test_account_move_in_invoice.py288
-rw-r--r--addons/account/tests/test_account_move_out_invoice.py288
3 files changed, 621 insertions, 12 deletions
diff --git a/addons/account/models/account_move.py b/addons/account/models/account_move.py
index 482075fd5f4..2ffbf3be651 100644
--- a/addons/account/models/account_move.py
+++ b/addons/account/models/account_move.py
@@ -1941,7 +1941,7 @@ class AccountMove(models.Model):
account_id = line_vals['account_id']
else:
tax = invoice_repartition_line.invoice_tax_id
- base_line = self.line_ids.filtered(lambda line: tax in line.tax_ids)[0]
+ base_line = self.line_ids.filtered(lambda line: tax in line.tax_ids.flatten_taxes_hierarchy())[0]
account_id = base_line.account_id.id
line_vals.update({
@@ -2585,10 +2585,6 @@ class AccountMoveLine(models.Model):
if self.product_uom_id != self.product_id.uom_id:
price_unit = self.product_id.uom_id._compute_price(price_unit, self.product_uom_id)
- company = self.move_id.company_id
- if self.move_id.currency_id != company.currency_id:
- price_unit = company.currency_id._convert(
- price_unit, self.move_id.currency_id, company, self.move_id.date)
return price_unit
def _get_computed_account(self):
@@ -2636,7 +2632,7 @@ class AccountMoveLine(models.Model):
if self.company_id and tax_ids:
tax_ids = tax_ids.filtered(lambda tax: tax.company_id == self.company_id)
- return self.move_id.fiscal_position_id.map_tax(tax_ids, partner=self.partner_id)
+ return tax_ids
def _get_computed_uom(self):
self.ensure_one()
@@ -2835,10 +2831,40 @@ class AccountMoveLine(models.Model):
line.product_uom_id = line._get_computed_uom()
line.price_unit = line._get_computed_price_unit()
+ # Manage the fiscal position after that and adapt the price_unit.
+ # E.g. mapping a price-included-tax to a price-excluded-tax must
+ # remove the tax amount from the price_unit.
+ # However, mapping a price-included tax to another price-included tax must preserve the balance but
+ # adapt the price_unit to the new tax.
+ # E.g. mapping a 10% price-included tax to a 20% price-included tax for a price_unit of 110 should preserve
+ # 100 as balance but set 120 as price_unit.
+ if line.tax_ids and line.move_id.fiscal_position_id:
+ line.price_unit = line._get_price_total_and_subtotal()['price_subtotal']
+ line.tax_ids = line.move_id.fiscal_position_id.map_tax(line.tax_ids._origin, partner=line.move_id.partner_id)
+ accounting_vals = line._get_fields_onchange_subtotal(price_subtotal=line.price_unit, currency=line.move_id.company_currency_id)
+ balance = accounting_vals['debit'] - accounting_vals['credit']
+ line.price_unit = line._get_fields_onchange_balance(balance=balance).get('price_unit', line.price_unit)
+
+ # Convert the unit price to the invoice's currency.
+ company = line.move_id.company_id
+ line.price_unit = company.currency_id._convert(line.price_unit, line.move_id.currency_id, company, line.move_id.date)
+
@api.onchange('product_uom_id')
def _onchange_uom_id(self):
''' Recompute the 'price_unit' depending of the unit of measure. '''
- self.price_unit = self._get_computed_price_unit()
+ price_unit = self._get_computed_price_unit()
+
+ # See '_onchange_product_id' for details.
+ taxes = self._get_computed_taxes()
+ if taxes and self.move_id.fiscal_position_id:
+ price_subtotal = self._get_price_total_and_subtotal(price_unit=price_unit, taxes=taxes)['price_subtotal']
+ accounting_vals = self._get_fields_onchange_subtotal(price_subtotal=price_subtotal, currency=self.move_id.company_currency_id)
+ balance = accounting_vals['debit'] - accounting_vals['credit']
+ price_unit = self._get_fields_onchange_balance(balance=balance).get('price_unit', price_unit)
+
+ # Convert the unit price to the invoice's currency.
+ company = self.move_id.company_id
+ self.price_unit = company.currency_id._convert(price_unit, self.move_id.currency_id, company, self.move_id.date)
@api.onchange('account_id')
def _onchange_account_id(self):
@@ -2846,7 +2872,12 @@ class AccountMoveLine(models.Model):
/!\ Don't remove existing taxes if there is no explicit taxes set on the account.
'''
if not self.display_type and (self.account_id.tax_ids or not self.tax_ids):
- self.tax_ids = self._get_computed_taxes()
+ taxes = self._get_computed_taxes()
+
+ if taxes and self.move_id.fiscal_position_id:
+ taxes = self.move_id.fiscal_position_id.map_tax(taxes, partner=self.partner_id)
+
+ self.tax_ids = taxes
def _onchange_balance(self):
for line in self:
@@ -3150,8 +3181,9 @@ class AccountMoveLine(models.Model):
tax = repartition_line.invoice_tax_id or repartition_line.refund_tax_id
vals['tax_exigible'] = tax.tax_exigibility == 'on_invoice'
elif vals.get('tax_ids'):
- taxes = self.resolve_2many_commands('tax_ids', vals['tax_ids'])
- vals['tax_exigible'] = not any([tax['tax_exigibility'] == 'on_payment' for tax in taxes])
+ tax_ids = [v['id'] for v in self.resolve_2many_commands('tax_ids', vals['tax_ids'], fields=['id'])]
+ taxes = self.env['account.tax'].browse(tax_ids).flatten_taxes_hierarchy()
+ vals['tax_exigible'] = not any(tax.tax_exigibility == 'on_payment' for tax in taxes)
lines = super(AccountMoveLine, self).create(vals_list)
@@ -4182,11 +4214,12 @@ class AccountPartialReconcile(models.Model):
to_clear_aml |= line
to_clear_aml.reconcile()
- if any([tax.tax_exigibility == 'on_payment' for tax in line.tax_ids]):
+ taxes_payment_exigible = line.tax_ids.flatten_taxes_hierarchy().filtered(lambda tax: tax.tax_exigibility == 'on_payment')
+ if taxes_payment_exigible:
if not newly_created_move:
newly_created_move = self._create_tax_basis_move()
#create cash basis entry for the base
- for tax in line.tax_ids.filtered(lambda t: t.tax_exigibility == 'on_payment'):
+ for tax in taxes_payment_exigible:
account_id = self._get_tax_cash_basis_base_account(line, tax)
self.env['account.move.line'].with_context(check_move_validity=False).create({
'name': line.name,
diff --git a/addons/account/tests/test_account_move_in_invoice.py b/addons/account/tests/test_account_move_in_invoice.py
index 5080aea470f..a92109b40aa 100644
--- a/addons/account/tests/test_account_move_in_invoice.py
+++ b/addons/account/tests/test_account_move_in_invoice.py
@@ -186,6 +186,294 @@ class TestAccountMoveInInvoiceOnchanges(AccountTestInvoicingCommon):
'amount_total': 416.0,
})
+ def test_in_invoice_line_onchange_product_2_with_fiscal_pos(self):
+ ''' Test mapping a price-included tax (10%) with a price-excluded tax (20%) on a price_unit of 110.0.
+ The price_unit should be 100.0 after applying the fiscal position.
+ '''
+ tax_price_include = self.env['account.tax'].create({
+ 'name': '10% incl',
+ 'type_tax_use': 'purchase',
+ 'amount_type': 'percent',
+ 'amount': 10,
+ 'price_include': True,
+ 'include_base_amount': True,
+ })
+ tax_price_exclude = self.env['account.tax'].create({
+ 'name': '15% excl',
+ 'type_tax_use': 'purchase',
+ 'amount_type': 'percent',
+ 'amount': 15,
+ })
+
+ fiscal_position = self.env['account.fiscal.position'].create({
+ 'name': 'fiscal_pos_a',
+ 'tax_ids': [
+ (0, None, {
+ 'tax_src_id': tax_price_include.id,
+ 'tax_dest_id': tax_price_exclude.id,
+ }),
+ ],
+ })
+
+ product = self.env['product.product'].create({
+ 'name': 'product',
+ 'uom_id': self.env.ref('uom.product_uom_unit').id,
+ 'standard_price': 110.0,
+ 'supplier_taxes_id': [(6, 0, tax_price_include.ids)],
+ })
+
+ move_form = Form(self.env['account.move'].with_context(default_type='in_invoice'))
+ move_form.partner_id = self.partner_a
+ move_form.invoice_date = fields.Date.from_string('2019-01-01')
+ move_form.currency_id = self.currency_data['currency']
+ move_form.fiscal_position_id = fiscal_position
+ with move_form.invoice_line_ids.new() as line_form:
+ line_form.product_id = product
+ invoice = move_form.save()
+
+ self.assertInvoiceValues(invoice, [
+ {
+ 'product_id': product.id,
+ 'price_unit': 200.0,
+ 'price_subtotal': 200.0,
+ 'price_total': 230.0,
+ 'tax_ids': tax_price_exclude.ids,
+ 'tax_line_id': False,
+ 'currency_id': self.currency_data['currency'].id,
+ 'amount_currency': 200.0,
+ 'debit': 100.0,
+ 'credit': 0.0,
+ },
+ {
+ 'product_id': False,
+ 'price_unit': 30.0,
+ 'price_subtotal': 30.0,
+ 'price_total': 30.0,
+ 'tax_ids': [],
+ 'tax_line_id': tax_price_exclude.id,
+ 'currency_id': self.currency_data['currency'].id,
+ 'amount_currency': 30.0,
+ 'debit': 15.0,
+ 'credit': 0.0,
+ },
+ {
+ 'product_id': False,
+ 'price_unit': -230.0,
+ 'price_subtotal': -230.0,
+ 'price_total': -230.0,
+ 'tax_ids': [],
+ 'tax_line_id': False,
+ 'currency_id': self.currency_data['currency'].id,
+ 'amount_currency': -230.0,
+ 'debit': 0.0,
+ 'credit': 115.0,
+ },
+ ], {
+ 'currency_id': self.currency_data['currency'].id,
+ 'fiscal_position_id': fiscal_position.id,
+ 'amount_untaxed': 200.0,
+ 'amount_tax': 30.0,
+ 'amount_total': 230.0,
+ })
+
+ uom_dozen = self.env.ref('uom.product_uom_dozen')
+ with Form(invoice) as move_form:
+ with move_form.invoice_line_ids.edit(0) as line_form:
+ line_form.product_uom_id = uom_dozen
+
+ self.assertInvoiceValues(invoice, [
+ {
+ 'product_id': product.id,
+ 'product_uom_id': uom_dozen.id,
+ 'price_unit': 2400.0,
+ 'price_subtotal': 2400.0,
+ 'price_total': 2760.0,
+ 'tax_ids': tax_price_exclude.ids,
+ 'tax_line_id': False,
+ 'currency_id': self.currency_data['currency'].id,
+ 'amount_currency': 2400.0,
+ 'debit': 1200.0,
+ 'credit': 0.0,
+ },
+ {
+ 'product_id': False,
+ 'product_uom_id': False,
+ 'price_unit': 360.0,
+ 'price_subtotal': 360.0,
+ 'price_total': 360.0,
+ 'tax_ids': [],
+ 'tax_line_id': tax_price_exclude.id,
+ 'currency_id': self.currency_data['currency'].id,
+ 'amount_currency': 360.0,
+ 'debit': 180.0,
+ 'credit': 0.0,
+ },
+ {
+ 'product_id': False,
+ 'product_uom_id': False,
+ 'price_unit': -2760.0,
+ 'price_subtotal': -2760.0,
+ 'price_total': -2760.0,
+ 'tax_ids': [],
+ 'tax_line_id': False,
+ 'currency_id': self.currency_data['currency'].id,
+ 'amount_currency': -2760.0,
+ 'debit': 0.0,
+ 'credit': 1380.0,
+ },
+ ], {
+ 'currency_id': self.currency_data['currency'].id,
+ 'fiscal_position_id': fiscal_position.id,
+ 'amount_untaxed': 2400.0,
+ 'amount_tax': 360.0,
+ 'amount_total': 2760.0,
+ })
+
+ def test_in_invoice_line_onchange_product_2_with_fiscal_pos_2(self):
+ ''' Test mapping a price-included tax (10%) with another price-included tax (20%) on a price_unit of 110.0.
+ The price_unit should be 120.0 after applying the fiscal position.
+ '''
+ tax_price_include_1 = self.env['account.tax'].create({
+ 'name': '10% incl',
+ 'type_tax_use': 'purchase',
+ 'amount_type': 'percent',
+ 'amount': 10,
+ 'price_include': True,
+ 'include_base_amount': True,
+ })
+ tax_price_include_2 = self.env['account.tax'].create({
+ 'name': '20% incl',
+ 'type_tax_use': 'purchase',
+ 'amount_type': 'percent',
+ 'amount': 20,
+ 'price_include': True,
+ 'include_base_amount': True,
+ })
+
+ fiscal_position = self.env['account.fiscal.position'].create({
+ 'name': 'fiscal_pos_a',
+ 'tax_ids': [
+ (0, None, {
+ 'tax_src_id': tax_price_include_1.id,
+ 'tax_dest_id': tax_price_include_2.id,
+ }),
+ ],
+ })
+
+ product = self.env['product.product'].create({
+ 'name': 'product',
+ 'uom_id': self.env.ref('uom.product_uom_unit').id,
+ 'standard_price': 110.0,
+ 'supplier_taxes_id': [(6, 0, tax_price_include_1.ids)],
+ })
+
+ move_form = Form(self.env['account.move'].with_context(default_type='in_invoice'))
+ move_form.partner_id = self.partner_a
+ move_form.invoice_date = fields.Date.from_string('2019-01-01')
+ move_form.currency_id = self.currency_data['currency']
+ move_form.fiscal_position_id = fiscal_position
+ with move_form.invoice_line_ids.new() as line_form:
+ line_form.product_id = product
+ invoice = move_form.save()
+
+ self.assertInvoiceValues(invoice, [
+ {
+ 'product_id': product.id,
+ 'price_unit': 240.0,
+ 'price_subtotal': 200.0,
+ 'price_total': 240.0,
+ 'tax_ids': tax_price_include_2.ids,
+ 'tax_line_id': False,
+ 'currency_id': self.currency_data['currency'].id,
+ 'amount_currency': 200.0,
+ 'debit': 100.0,
+ 'credit': 0.0,
+ },
+ {
+ 'product_id': False,
+ 'price_unit': 40.0,
+ 'price_subtotal': 40.0,
+ 'price_total': 40.0,
+ 'tax_ids': [],
+ 'tax_line_id': tax_price_include_2.id,
+ 'currency_id': self.currency_data['currency'].id,
+ 'amount_currency': 40.0,
+ 'debit': 20.0,
+ 'credit': 0.0,
+ },
+ {
+ 'product_id': False,
+ 'price_unit': -240.0,
+ 'price_subtotal': -240.0,
+ 'price_total': -240.0,
+ 'tax_ids': [],
+ 'tax_line_id': False,
+ 'currency_id': self.currency_data['currency'].id,
+ 'amount_currency': -240.0,
+ 'debit': 0.0,
+ 'credit': 120.0,
+ },
+ ], {
+ 'currency_id': self.currency_data['currency'].id,
+ 'fiscal_position_id': fiscal_position.id,
+ 'amount_untaxed': 200.0,
+ 'amount_tax': 40.0,
+ 'amount_total': 240.0,
+ })
+
+ uom_dozen = self.env.ref('uom.product_uom_dozen')
+ with Form(invoice) as move_form:
+ with move_form.invoice_line_ids.edit(0) as line_form:
+ line_form.product_uom_id = uom_dozen
+
+ self.assertInvoiceValues(invoice, [
+ {
+ 'product_id': product.id,
+ 'product_uom_id': uom_dozen.id,
+ 'price_unit': 2880.0,
+ 'price_subtotal': 2400.0,
+ 'price_total': 2880.0,
+ 'tax_ids': tax_price_include_2.ids,
+ 'tax_line_id': False,
+ 'currency_id': self.currency_data['currency'].id,
+ 'amount_currency': 2400.0,
+ 'debit': 1200.0,
+ 'credit': 0.0,
+ },
+ {
+ 'product_id': False,
+ 'product_uom_id': False,
+ 'price_unit': 480.0,
+ 'price_subtotal': 480.0,
+ 'price_total': 480.0,
+ 'tax_ids': [],
+ 'tax_line_id': tax_price_include_2.id,
+ 'currency_id': self.currency_data['currency'].id,
+ 'amount_currency': 480.0,
+ 'debit': 240.0,
+ 'credit': 0.0,
+ },
+ {
+ 'product_id': False,
+ 'product_uom_id': False,
+ 'price_unit': -2880.0,
+ 'price_subtotal': -2880.0,
+ 'price_total': -2880.0,
+ 'tax_ids': [],
+ 'tax_line_id': False,
+ 'currency_id': self.currency_data['currency'].id,
+ 'amount_currency': -2880.0,
+ 'debit': 0.0,
+ 'credit': 1440.0,
+ },
+ ], {
+ 'currency_id': self.currency_data['currency'].id,
+ 'fiscal_position_id': fiscal_position.id,
+ 'amount_untaxed': 2400.0,
+ 'amount_tax': 480.0,
+ 'amount_total': 2880.0,
+ })
+
def test_in_invoice_line_onchange_business_fields_1(self):
move_form = Form(self.invoice)
with move_form.invoice_line_ids.edit(0) as line_form:
diff --git a/addons/account/tests/test_account_move_out_invoice.py b/addons/account/tests/test_account_move_out_invoice.py
index 12837cc065c..b047a3a2fd3 100644
--- a/addons/account/tests/test_account_move_out_invoice.py
+++ b/addons/account/tests/test_account_move_out_invoice.py
@@ -188,6 +188,294 @@ class TestAccountMoveOutInvoiceOnchanges(AccountTestInvoicingCommon):
'amount_total': 520.0,
})
+ def test_out_invoice_line_onchange_product_2_with_fiscal_pos_1(self):
+ ''' Test mapping a price-included tax (10%) with a price-excluded tax (20%) on a price_unit of 110.0.
+ The price_unit should be 100.0 after applying the fiscal position.
+ '''
+ tax_price_include = self.env['account.tax'].create({
+ 'name': '10% incl',
+ 'type_tax_use': 'sale',
+ 'amount_type': 'percent',
+ 'amount': 10,
+ 'price_include': True,
+ 'include_base_amount': True,
+ })
+ tax_price_exclude = self.env['account.tax'].create({
+ 'name': '15% excl',
+ 'type_tax_use': 'sale',
+ 'amount_type': 'percent',
+ 'amount': 15,
+ })
+
+ fiscal_position = self.env['account.fiscal.position'].create({
+ 'name': 'fiscal_pos_a',
+ 'tax_ids': [
+ (0, None, {
+ 'tax_src_id': tax_price_include.id,
+ 'tax_dest_id': tax_price_exclude.id,
+ }),
+ ],
+ })
+
+ product = self.env['product.product'].create({
+ 'name': 'product',
+ 'uom_id': self.env.ref('uom.product_uom_unit').id,
+ 'lst_price': 110.0,
+ 'taxes_id': [(6, 0, tax_price_include.ids)],
+ })
+
+ move_form = Form(self.env['account.move'].with_context(default_type='out_invoice'))
+ move_form.partner_id = self.partner_a
+ move_form.invoice_date = fields.Date.from_string('2019-01-01')
+ move_form.currency_id = self.currency_data['currency']
+ move_form.fiscal_position_id = fiscal_position
+ with move_form.invoice_line_ids.new() as line_form:
+ line_form.product_id = product
+ invoice = move_form.save()
+
+ self.assertInvoiceValues(invoice, [
+ {
+ 'product_id': product.id,
+ 'price_unit': 200.0,
+ 'price_subtotal': 200.0,
+ 'price_total': 230.0,
+ 'tax_ids': tax_price_exclude.ids,
+ 'tax_line_id': False,
+ 'currency_id': self.currency_data['currency'].id,
+ 'amount_currency': -200.0,
+ 'debit': 0.0,
+ 'credit': 100.0,
+ },
+ {
+ 'product_id': False,
+ 'price_unit': 30.0,
+ 'price_subtotal': 30.0,
+ 'price_total': 30.0,
+ 'tax_ids': [],
+ 'tax_line_id': tax_price_exclude.id,
+ 'currency_id': self.currency_data['currency'].id,
+ 'amount_currency': -30.0,
+ 'debit': 0.0,
+ 'credit': 15.0,
+ },
+ {
+ 'product_id': False,
+ 'price_unit': -230.0,
+ 'price_subtotal': -230.0,
+ 'price_total': -230.0,
+ 'tax_ids': [],
+ 'tax_line_id': False,
+ 'currency_id': self.currency_data['currency'].id,
+ 'amount_currency': 230.0,
+ 'debit': 115.0,
+ 'credit': 0.0,
+ },
+ ], {
+ 'currency_id': self.currency_data['currency'].id,
+ 'fiscal_position_id': fiscal_position.id,
+ 'amount_untaxed': 200.0,
+ 'amount_tax': 30.0,
+ 'amount_total': 230.0,
+ })
+
+ uom_dozen = self.env.ref('uom.product_uom_dozen')
+ with Form(invoice) as move_form:
+ with move_form.invoice_line_ids.edit(0) as line_form:
+ line_form.product_uom_id = uom_dozen
+
+ self.assertInvoiceValues(invoice, [
+ {
+ 'product_id': product.id,
+ 'product_uom_id': uom_dozen.id,
+ 'price_unit': 2400.0,
+ 'price_subtotal': 2400.0,
+ 'price_total': 2760.0,
+ 'tax_ids': tax_price_exclude.ids,
+ 'tax_line_id': False,
+ 'currency_id': self.currency_data['currency'].id,
+ 'amount_currency': -2400.0,
+ 'debit': 0.0,
+ 'credit': 1200.0,
+ },
+ {
+ 'product_id': False,
+ 'product_uom_id': False,
+ 'price_unit': 360.0,
+ 'price_subtotal': 360.0,
+ 'price_total': 360.0,
+ 'tax_ids': [],
+ 'tax_line_id': tax_price_exclude.id,
+ 'currency_id': self.currency_data['currency'].id,
+ 'amount_currency': -360.0,
+ 'debit': 0.0,
+ 'credit': 180.0,
+ },
+ {
+ 'product_id': False,
+ 'product_uom_id': False,
+ 'price_unit': -2760.0,
+ 'price_subtotal': -2760.0,
+ 'price_total': -2760.0,
+ 'tax_ids': [],
+ 'tax_line_id': False,
+ 'currency_id': self.currency_data['currency'].id,
+ 'amount_currency': 2760.0,
+ 'debit': 1380.0,
+ 'credit': 0.0,
+ },
+ ], {
+ 'currency_id': self.currency_data['currency'].id,
+ 'fiscal_position_id': fiscal_position.id,
+ 'amount_untaxed': 2400.0,
+ 'amount_tax': 360.0,
+ 'amount_total': 2760.0,
+ })
+
+ def test_out_invoice_line_onchange_product_2_with_fiscal_pos_2(self):
+ ''' Test mapping a price-included tax (10%) with another price-included tax (20%) on a price_unit of 110.0.
+ The price_unit should be 120.0 after applying the fiscal position.
+ '''
+ tax_price_include_1 = self.env['account.tax'].create({
+ 'name': '10% incl',
+ 'type_tax_use': 'sale',
+ 'amount_type': 'percent',
+ 'amount': 10,
+ 'price_include': True,
+ 'include_base_amount': True,
+ })
+ tax_price_include_2 = self.env['account.tax'].create({
+ 'name': '20% incl',
+ 'type_tax_use': 'sale',
+ 'amount_type': 'percent',
+ 'amount': 20,
+ 'price_include': True,
+ 'include_base_amount': True,
+ })
+
+ fiscal_position = self.env['account.fiscal.position'].create({
+ 'name': 'fiscal_pos_a',
+ 'tax_ids': [
+ (0, None, {
+ 'tax_src_id': tax_price_include_1.id,
+ 'tax_dest_id': tax_price_include_2.id,
+ }),
+ ],
+ })
+
+ product = self.env['product.product'].create({
+ 'name': 'product',
+ 'uom_id': self.env.ref('uom.product_uom_unit').id,
+ 'lst_price': 110.0,
+ 'taxes_id': [(6, 0, tax_price_include_1.ids)],
+ })
+
+ move_form = Form(self.env['account.move'].with_context(default_type='out_invoice'))
+ move_form.partner_id = self.partner_a
+ move_form.invoice_date = fields.Date.from_string('2019-01-01')
+ move_form.currency_id = self.currency_data['currency']
+ move_form.fiscal_position_id = fiscal_position
+ with move_form.invoice_line_ids.new() as line_form:
+ line_form.product_id = product
+ invoice = move_form.save()
+
+ self.assertInvoiceValues(invoice, [
+ {
+ 'product_id': product.id,
+ 'price_unit': 240.0,
+ 'price_subtotal': 200.0,
+ 'price_total': 240.0,
+ 'tax_ids': tax_price_include_2.ids,
+ 'tax_line_id': False,
+ 'currency_id': self.currency_data['currency'].id,
+ 'amount_currency': -200.0,
+ 'debit': 0.0,
+ 'credit': 100.0,
+ },
+ {
+ 'product_id': False,
+ 'price_unit': 40.0,
+ 'price_subtotal': 40.0,
+ 'price_total': 40.0,
+ 'tax_ids': [],
+ 'tax_line_id': tax_price_include_2.id,
+ 'currency_id': self.currency_data['currency'].id,
+ 'amount_currency': -40.0,
+ 'debit': 0.0,
+ 'credit': 20.0,
+ },
+ {
+ 'product_id': False,
+ 'price_unit': -240.0,
+ 'price_subtotal': -240.0,
+ 'price_total': -240.0,
+ 'tax_ids': [],
+ 'tax_line_id': False,
+ 'currency_id': self.currency_data['currency'].id,
+ 'amount_currency': 240.0,
+ 'debit': 120.0,
+ 'credit': 0.0,
+ },
+ ], {
+ 'currency_id': self.currency_data['currency'].id,
+ 'fiscal_position_id': fiscal_position.id,
+ 'amount_untaxed': 200.0,
+ 'amount_tax': 40.0,
+ 'amount_total': 240.0,
+ })
+
+ uom_dozen = self.env.ref('uom.product_uom_dozen')
+ with Form(invoice) as move_form:
+ with move_form.invoice_line_ids.edit(0) as line_form:
+ line_form.product_uom_id = uom_dozen
+
+ self.assertInvoiceValues(invoice, [
+ {
+ 'product_id': product.id,
+ 'product_uom_id': uom_dozen.id,
+ 'price_unit': 2880.0,
+ 'price_subtotal': 2400.0,
+ 'price_total': 2880.0,
+ 'tax_ids': tax_price_include_2.ids,
+ 'tax_line_id': False,
+ 'currency_id': self.currency_data['currency'].id,
+ 'amount_currency': -2400.0,
+ 'debit': 0.0,
+ 'credit': 1200.0,
+ },
+ {
+ 'product_id': False,
+ 'product_uom_id': False,
+ 'price_unit': 480.0,
+ 'price_subtotal': 480.0,
+ 'price_total': 480.0,
+ 'tax_ids': [],
+ 'tax_line_id': tax_price_include_2.id,
+ 'currency_id': self.currency_data['currency'].id,
+ 'amount_currency': -480.0,
+ 'debit': 0.0,
+ 'credit': 240.0,
+ },
+ {
+ 'product_id': False,
+ 'product_uom_id': False,
+ 'price_unit': -2880.0,
+ 'price_subtotal': -2880.0,
+ 'price_total': -2880.0,
+ 'tax_ids': [],
+ 'tax_line_id': False,
+ 'currency_id': self.currency_data['currency'].id,
+ 'amount_currency': 2880.0,
+ 'debit': 1440.0,
+ 'credit': 0.0,
+ },
+ ], {
+ 'currency_id': self.currency_data['currency'].id,
+ 'fiscal_position_id': fiscal_position.id,
+ 'amount_untaxed': 2400.0,
+ 'amount_tax': 480.0,
+ 'amount_total': 2880.0,
+ })
+
def test_out_invoice_line_onchange_business_fields_1(self):
move_form = Form(self.invoice)
with move_form.invoice_line_ids.edit(0) as line_form: