diff options
Diffstat (limited to 'addons/account/models')
| -rw-r--r-- | addons/account/models/account_move.py | 98 |
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): |
