summaryrefslogtreecommitdiff
path: root/addons/account/models/account_move.py
diff options
context:
space:
mode:
Diffstat (limited to 'addons/account/models/account_move.py')
-rw-r--r--addons/account/models/account_move.py98
1 files changed, 69 insertions, 29 deletions
diff --git a/addons/account/models/account_move.py b/addons/account/models/account_move.py
index 64b17d98d52..1fa1b0e30af 100644
--- a/addons/account/models/account_move.py
+++ b/addons/account/models/account_move.py
@@ -3157,23 +3157,75 @@ class AccountMoveLine(models.Model):
return '\n'.join(values)
def _get_computed_price_unit(self):
+ ''' Helper to get the default price unit based on the product by taking care of the taxes
+ set on the product and the fiscal position.
+ :return: The price unit.
+ '''
self.ensure_one()
if not self.product_id:
- return self.price_unit
- elif self.move_id.is_sale_document(include_receipts=True):
- # Out invoice.
- price_unit = self.product_id.lst_price
+ return 0.0
+
+ company = self.move_id.company_id
+ currency = self.move_id.currency_id
+ company_currency = company.currency_id
+ product_uom = self.product_id.uom_id
+ fiscal_position = self.move_id.fiscal_position_id
+ is_refund_document = self.move_id.move_type in ('out_refund', 'in_refund')
+ move_date = self.move_id.date or fields.Date.context_today(self)
+
+ if self.move_id.is_sale_document(include_receipts=True):
+ product_price_unit = self.product_id.lst_price
+ product_taxes = self.product_id.taxes_id
elif self.move_id.is_purchase_document(include_receipts=True):
- # In invoice.
- price_unit = self.product_id.standard_price
+ product_price_unit = self.product_id.standard_price
+ product_taxes = self.product_id.supplier_taxes_id
else:
- return self.price_unit
+ return 0.0
+ product_taxes = product_taxes.filtered(lambda tax: tax.company_id == company)
+
+ # Apply unit of measure.
+ if self.product_uom_id and self.product_uom_id != product_uom:
+ product_price_unit = product_uom._compute_price(product_price_unit, self.product_uom_id)
+
+ # Apply fiscal position.
+ if product_taxes and fiscal_position:
+ product_taxes_after_fp = fiscal_position.map_tax(product_taxes, partner=self.partner_id)
+
+ if set(product_taxes.ids) != set(product_taxes_after_fp.ids):
+ flattened_taxes_before_fp = product_taxes._origin.flatten_taxes_hierarchy()
+ if any(tax.price_include for tax in flattened_taxes_before_fp):
+ taxes_res = flattened_taxes_before_fp.compute_all(
+ product_price_unit,
+ quantity=1.0,
+ currency=company_currency,
+ product=self.product_id,
+ partner=self.partner_id,
+ is_refund=is_refund_document,
+ )
+ product_price_unit = company_currency.round(taxes_res['total_excluded'])
+
+ flattened_taxes_after_fp = product_taxes_after_fp._origin.flatten_taxes_hierarchy()
+ if any(tax.price_include for tax in flattened_taxes_after_fp):
+ taxes_res = flattened_taxes_after_fp.compute_all(
+ product_price_unit,
+ quantity=1.0,
+ currency=company_currency,
+ product=self.product_id,
+ partner=self.partner_id,
+ is_refund=is_refund_document,
+ handle_price_include=False,
+ )
+ for tax_res in taxes_res['taxes']:
+ tax = self.env['account.tax'].browse(tax_res['id'])
+ if tax.price_include:
+ product_price_unit += tax_res['amount']
- 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)
+ # Apply currency rate.
+ if currency and currency != company_currency:
+ product_price_unit = company_currency._convert(product_price_unit, currency, company, move_date)
- return price_unit
+ return product_price_unit
def _get_computed_account(self):
self.ensure_one()
@@ -3474,33 +3526,21 @@ class AccountMoveLine(models.Model):
line.name = line._get_computed_name()
line.account_id = line._get_computed_account()
- line.tax_ids = line._get_computed_taxes()
+ taxes = line._get_computed_taxes()
+ if taxes and line.move_id.fiscal_position_id:
+ taxes = line.move_id.fiscal_position_id.map_tax(taxes, partner=line.partner_id)
+ line.tax_ids = taxes
line.product_uom_id = line._get_computed_uom()
line.price_unit = line._get_computed_price_unit()
- # price_unit and taxes may need to be adapted following Fiscal Position
- line._set_price_and_tax_after_fpos()
-
- # 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, round=False)
-
@api.onchange('product_uom_id')
def _onchange_uom_id(self):
''' Recompute the 'price_unit' depending of the unit of measure. '''
- 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)
- amount_currency = accounting_vals['amount_currency']
- price_unit = self._get_fields_onchange_balance(amount_currency=amount_currency, force_computation=True).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, round=False)
+ taxes = self.move_id.fiscal_position_id.map_tax(taxes, partner=self.partner_id)
+ self.tax_ids = taxes
+ self.price_unit = self._get_computed_price_unit()
@api.onchange('account_id')
def _onchange_account_id(self):