From d8627c4e38ce9310197979dfbd5307810edf8201 Mon Sep 17 00:00:00 2001 From: william-andre Date: Thu, 5 Oct 2023 00:48:03 +0200 Subject: [PATCH] [REF] account,sale*: remove local cache for currency rates Since it is cached by the ORM (see parent commit), there is no need to manage the caching in the business code anymore. In most cases in addition to making the code shorter, it also makes it more readable by making the direction of the rate more obvious with the use of the `to_currency` parameter. closes odoo/odoo#137609 Signed-off-by: Raphael Collet --- .../models/account_journal_dashboard.py | 22 +++++----------- addons/account/models/account_move_line.py | 11 +------- .../wizard/account_payment_register.py | 25 ++++-------------- addons/account/wizard/accrued_orders.py | 6 ++--- .../project_account/models/project_project.py | 23 +++++++--------- .../models/project_project.py | 18 +++++-------- addons/project_mrp/models/project_project.py | 10 +------ .../models/project_project.py | 11 +++----- .../models/project_project.py | 26 +++++-------------- addons/sale/models/sale_order.py | 23 +++++----------- addons/sale_project/models/project.py | 20 +++++--------- addons/sale_timesheet/models/project.py | 9 +------ 12 files changed, 55 insertions(+), 149 deletions(-) diff --git a/addons/account/models/account_journal_dashboard.py b/addons/account/models/account_journal_dashboard.py index 28f2167ab9b..62f66cc73ae 100644 --- a/addons/account/models/account_journal_dashboard.py +++ b/addons/account/models/account_journal_dashboard.py @@ -458,14 +458,13 @@ class account_journal(models.Model): ) } - curr_cache = {} sale_purchase_journals._fill_dashboard_data_count(dashboard_data, 'account.move', 'entries_count', []) for journal in sale_purchase_journals: # User may have read access on the journal but not on the company currency = journal.currency_id or self.env['res.currency'].browse(journal.company_id.sudo().currency_id.id) - (number_waiting, sum_waiting) = self._count_results_and_sum_amounts(query_results_to_pay[journal.id], currency, curr_cache=curr_cache) - (number_draft, sum_draft) = self._count_results_and_sum_amounts(query_results_drafts[journal.id], currency, curr_cache=curr_cache) - (number_late, sum_late) = self._count_results_and_sum_amounts(late_query_results[journal.id], currency, curr_cache=curr_cache) + (number_waiting, sum_waiting) = self._count_results_and_sum_amounts(query_results_to_pay[journal.id], currency) + (number_draft, sum_draft) = self._count_results_and_sum_amounts(query_results_drafts[journal.id], currency) + (number_late, sum_late) = self._count_results_and_sum_amounts(late_query_results[journal.id], currency) amount_total_signed_sum, count = to_check_vals.get(journal.id, (0, 0)) dashboard_data[journal.id].update({ 'number_to_check': count, @@ -530,7 +529,7 @@ class account_journal(models.Model): ('move_type', 'in', self.env['account.move'].get_invoice_types(include_receipts=True)), ]) - def _count_results_and_sum_amounts(self, results_dict, target_currency, curr_cache=None): + def _count_results_and_sum_amounts(self, results_dict, target_currency): """ Loops on a query result to count the total number of invoices and sum their amount_total field (expressed in the given target currency). amount_total must be signed! @@ -538,22 +537,16 @@ class account_journal(models.Model): # Create a cache with currency rates to avoid unnecessary SQL requests. Do not copy # curr_cache on purpose, so the dictionary is modified and can be re-used for subsequent # calls of the method. - curr_cache = {} if curr_cache is None else curr_cache total_amount = 0 for result in results_dict: document_currency = self.env['res.currency'].browse(result.get('currency')) company = self.env['res.company'].browse(result.get('company_id')) or self.env.company date = result.get('invoice_date') or fields.Date.context_today(self) - if document_currency == target_currency: - total_amount += result.get('amount_total') or 0 - elif company.currency_id == target_currency: + if company.currency_id == target_currency: total_amount += result.get('amount_total_company') or 0 else: - key = (document_currency, target_currency, company, date) - if key not in curr_cache: - curr_cache[key] = self.env['res.currency']._get_conversion_rate(*key) - total_amount += (result.get('amount_total') or 0) * curr_cache[key] + total_amount += document_currency._convert(result.get('amount_total'), target_currency, company, date) return (len(results_dict), target_currency.round(total_amount)) def _get_journal_dashboard_bank_running_balance(self): @@ -617,11 +610,10 @@ class account_journal(models.Model): """, [self.ids]) query_result = group_by_journal(self.env.cr.dictfetchall()) result = {} - curr_cache = {} for journal in self: # User may have read access on the journal but not on the company currency = journal.currency_id or self.env['res.currency'].browse(journal.company_id.sudo().currency_id.id) - result[journal.id] = self._count_results_and_sum_amounts(query_result[journal.id], currency, curr_cache) + result[journal.id] = self._count_results_and_sum_amounts(query_result[journal.id], currency) return result def _get_move_action_context(self): diff --git a/addons/account/models/account_move_line.py b/addons/account/models/account_move_line.py index 7d3640789d2..15dd2aa6946 100644 --- a/addons/account/models/account_move_line.py +++ b/addons/account/models/account_move_line.py @@ -2,7 +2,6 @@ import ast from collections import defaultdict from contextlib import contextmanager from datetime import date, timedelta -from functools import lru_cache from odoo import api, fields, models, Command, _ from odoo.exceptions import ValidationError, UserError @@ -634,17 +633,9 @@ class AccountMoveLine(models.Model): @api.depends('currency_id', 'company_id', 'move_id.date') def _compute_currency_rate(self): - @lru_cache() - def get_rate(from_currency, to_currency, company, date): - return self.env['res.currency']._get_conversion_rate( - from_currency=from_currency, - to_currency=to_currency, - company=company, - date=date, - ) for line in self: if line.currency_id: - line.currency_rate = get_rate( + line.currency_rate = self.env['res.currency']._get_conversion_rate( from_currency=line.company_currency_id, to_currency=line.currency_id, company=line.company_id, diff --git a/addons/account/wizard/account_payment_register.py b/addons/account/wizard/account_payment_register.py index 6d6c4662790..46285766072 100644 --- a/addons/account/wizard/account_payment_register.py +++ b/addons/account/wizard/account_payment_register.py @@ -683,13 +683,6 @@ class AccountPaymentRegister(models.TransientModel): 'write_off_line_vals': [], } - conversion_rate = self.env['res.currency']._get_conversion_rate( - self.currency_id, - self.company_id.currency_id, - self.company_id, - self.payment_date, - ) - if self.payment_difference_handling == 'reconcile': if self.early_payment_discount_mode: epd_aml_values_list = [] @@ -698,11 +691,11 @@ class AccountPaymentRegister(models.TransientModel): epd_aml_values_list.append({ 'aml': aml, 'amount_currency': -aml.amount_residual_currency, - 'balance': aml.company_currency_id.round(-aml.amount_residual_currency * conversion_rate), + 'balance': aml.currency_id._convert(-aml.amount_residual_currency, aml.company_currency_id, date=self.payment_date), }) open_amount_currency = self.payment_difference * (-1 if self.payment_type == 'outbound' else 1) - open_balance = self.company_id.currency_id.round(open_amount_currency * conversion_rate) + open_balance = self.currency_id._convert(open_amount_currency, self.company_id.currency_id, self.company_id, self.payment_date) early_payment_values = self.env['account.move']._get_invoice_counterpart_amls_for_early_payment_discount(epd_aml_values_list, open_balance) for aml_values_list in early_payment_values.values(): payment_vals['write_off_line_vals'] += aml_values_list @@ -715,14 +708,13 @@ class AccountPaymentRegister(models.TransientModel): # Send money. write_off_amount_currency = -self.payment_difference - write_off_balance = self.company_id.currency_id.round(write_off_amount_currency * conversion_rate) payment_vals['write_off_line_vals'].append({ 'name': self.writeoff_label, 'account_id': self.writeoff_account_id.id, 'partner_id': self.partner_id.id, 'currency_id': self.currency_id.id, 'amount_currency': write_off_amount_currency, - 'balance': write_off_balance, + 'balance': self.currency_id._convert(write_off_amount_currency, self.company_id.currency_id, self.company_id, self.payment_date), }) return payment_vals @@ -760,24 +752,17 @@ class AccountPaymentRegister(models.TransientModel): if mode == 'early_payment': payment_vals['amount'] = total_amount - conversion_rate = self.env['res.currency']._get_conversion_rate( - currency, - self.company_id.currency_id, - self.company_id, - self.payment_date, - ) - epd_aml_values_list = [] for aml in batch_result['lines']: if aml.move_id._is_eligible_for_early_payment_discount(currency, self.payment_date): epd_aml_values_list.append({ 'aml': aml, 'amount_currency': -aml.amount_residual_currency, - 'balance': aml.company_currency_id.round(-aml.amount_residual_currency * conversion_rate), + 'balance': currency._convert(-aml.amount_residual_currency, aml.company_currency_id, self.company_id, self.payment_date), }) open_amount_currency = (batch_values['source_amount_currency'] - total_amount) * (-1 if batch_values['payment_type'] == 'outbound' else 1) - open_balance = self.company_id.currency_id.round(open_amount_currency * conversion_rate) + open_balance = currency._convert(open_amount_currency, aml.company_currency_id, self.company_id, self.payment_date) early_payment_values = self.env['account.move']\ ._get_invoice_counterpart_amls_for_early_payment_discount(epd_aml_values_list, open_balance) for aml_values_list in early_payment_values.values(): diff --git a/addons/account/wizard/accrued_orders.py b/addons/account/wizard/accrued_orders.py index e3164c8f3b6..0b1cc609f37 100644 --- a/addons/account/wizard/accrued_orders.py +++ b/addons/account/wizard/accrued_orders.py @@ -155,8 +155,6 @@ class AccruedExpenseRevenue(models.TransientModel): values = _get_aml_vals(order, self.amount, 0, account.id, label=_('Manual entry'), analytic_distribution=distribution) move_lines.append(Command.create(values)) else: - other_currency = self.company_id.currency_id != order.currency_id - rate = order.currency_id._get_rates(self.company_id, self.date).get(order.currency_id.id) if other_currency else 1.0 # create a virtual order that will allow to recompute the qty delivered/received (and dependancies) # without actually writing anything on the real record (field is computed and stored) o = order.new(origin=order) @@ -179,14 +177,14 @@ class AccruedExpenseRevenue(models.TransientModel): for order_line in lines: if is_purchase: account = self._get_computed_account(order, order_line.product_id, is_purchase) - amount = self.company_id.currency_id.round(order_line.qty_to_invoice * order_line.price_unit / rate) amount_currency = order_line.currency_id.round(order_line.qty_to_invoice * order_line.price_unit) + amount = order.currency_id._convert(amount_currency, self.company_id.currency_id, self.company_id) fnames = ['qty_to_invoice', 'qty_received', 'qty_invoiced', 'invoice_lines'] label = _('%s - %s; %s Billed, %s Received at %s each', order.name, _ellipsis(order_line.name, 20), order_line.qty_invoiced, order_line.qty_received, formatLang(self.env, order_line.price_unit, currency_obj=order.currency_id)) else: account = self._get_computed_account(order, order_line.product_id, is_purchase) - amount = self.company_id.currency_id.round(order_line.untaxed_amount_to_invoice / rate) amount_currency = order_line.untaxed_amount_to_invoice + amount = order.currency_id._convert(amount_currency, self.company_id.currency_id, self.company_id) fnames = ['qty_to_invoice', 'untaxed_amount_to_invoice', 'qty_invoiced', 'qty_delivered', 'invoice_lines'] label = _('%s - %s; %s Invoiced, %s Delivered at %s each', order.name, _ellipsis(order_line.name, 20), order_line.qty_invoiced, order_line.qty_delivered, formatLang(self.env, order_line.price_unit, currency_obj=order.currency_id)) distribution = order_line.analytic_distribution if order_line.analytic_distribution else {} diff --git a/addons/project_account/models/project_project.py b/addons/project_account/models/project_project.py index 1708f8722a1..8279aa4c440 100644 --- a/addons/project_account/models/project_project.py +++ b/addons/project_account/models/project_project.py @@ -4,7 +4,8 @@ import json from collections import defaultdict -from odoo import models, _lt, fields +from odoo import models, _lt +from odoo.tools.misc import OrderedSet class Project(models.Model): @@ -35,13 +36,13 @@ class Project(models.Model): bills_move_line_read = self._cr.dictfetchall() if bills_move_line_read: # Get conversion rate from currencies to currency of the current company - currency_ids = {bml['currency_id'] for bml in bills_move_line_read + [{'currency_id': self.currency_id.id}]} - rates = self.env['res.currency'].browse(list(currency_ids))._get_rates(self.company_id or self.env.company, fields.Date.context_today(self)) - conversion_rates = {cid: self.currency_id.rate / rate_from for cid, rate_from in rates.items()} + currency_ids = OrderedSet(bml['currency_id'] for bml in bills_move_line_read) amount_invoiced = amount_to_invoice = 0.0 move_ids = set() for moves_read in bills_move_line_read: - price_subtotal = self.currency_id.round(moves_read['price_subtotal'] * conversion_rates[moves_read['currency_id']]) + price_subtotal = self.env['res.currency'].browse(moves_read['currency_id']).with_prefetch(currency_ids)._convert( + from_amount=moves_read['price_subtotal'], to_currency=self.currency_id, + ) analytic_contribution = moves_read['analytic_distribution'][str(self.analytic_account_id.id)] / 100. move_ids.add(moves_read['move_id']) if moves_read['parent_state'] == 'draft': @@ -151,16 +152,10 @@ class Project(models.Model): revenue_ids.append(aal['id']) total_revenues = total_costs = 0.0 - rates_per_currency_id = self.env['res.currency'].browse(set_currency_ids)._get_rates(self.company_id or self.env.company, fields.Date.context_today(self)) - project_currency_rate = rates_per_currency_id[self.currency_id.id] for currency_id, dict_amounts in dict_amount_per_currency_id.items(): - if currency_id == self.currency_id.id: - total_revenues += dict_amounts['revenues'] - total_costs += dict_amounts['costs'] - continue - rate = project_currency_rate / rates_per_currency_id[currency_id] - total_revenues += self.currency_id.round(dict_amounts['revenues'] * rate) - total_costs += self.currency_id.round(dict_amounts['costs'] * rate) + currency = self.env['res.currency'].browse(currency_id).with_prefetch(dict_amount_per_currency_id) + total_revenues += currency._convert(dict_amounts['revenues'], self.currency_id, self.company_id) + total_costs += currency._convert(dict_amounts['costs'], self.currency_id, self.company_id) # we dont know what part of the numbers has already been billed or not, so we have no choice but to put everything under the billed/invoiced columns. # The to bill/to invoice ones will simply remain 0 diff --git a/addons/project_hr_expense/models/project_project.py b/addons/project_hr_expense/models/project_project.py index 0f5209aa6e9..58ca379a94d 100644 --- a/addons/project_hr_expense/models/project_project.py +++ b/addons/project_hr_expense/models/project_project.py @@ -97,21 +97,15 @@ class Project(models.Model): return {} expense_ids = [] amount_billed = 0.0 - dict_amount_per_currency = defaultdict(lambda: 0.0) - set_currency_ids = {self.currency_id.id} + all_currencies = {res['currency_id'] for res in expenses_read_group} for res in expenses_read_group: if can_see_expense: expense_ids.extend(res['ids']) - set_currency_ids.add(res['currency_id']) - dict_amount_per_currency[res['currency_id']] += res['untaxed_amount'] - rate_per_currency_id = self.env['res.currency'].browse(set_currency_ids)._get_rates(self.company_id or self.env.company, fields.Date.context_today(self)) - project_currency_rate = rate_per_currency_id[self.currency_id.id] - for currency_id, amount in dict_amount_per_currency.items(): - if currency_id == self.currency_id.id: - amount_billed += amount - continue - rate = project_currency_rate / rate_per_currency_id[currency_id] - amount_billed += self.currency_id.round(amount * rate) + amount_billed += self.env['res.currency'].browse(res['currency_id']).with_prefetch(all_currencies)._convert( + from_amount=res['untaxed_amount'], + to_currency=self.currency_id, + company=self.company_id, + ) section_id = 'expenses' expense_profitability_items = { diff --git a/addons/project_mrp/models/project_project.py b/addons/project_mrp/models/project_project.py index 108e7a4ee54..9645ea84d7a 100644 --- a/addons/project_mrp/models/project_project.py +++ b/addons/project_mrp/models/project_project.py @@ -73,16 +73,8 @@ class Project(models.Model): if mrp_aal_read_group: can_see_manufactoring_order = with_action and len(self) == 1 and self.user_has_groups('mrp.group_mrp_user') total_amount = 0 - currency_ids = {currency.id for currency, amount in mrp_aal_read_group} - currency_ids.add(self.currency_id.id) - rate_per_currency_id = self.env['res.currency'].browse(currency_ids)._get_rates(self.company_id or self.env.company, fields.Date.context_today(self)) - project_currency_rate = rate_per_currency_id[self.currency_id.id] for currency, amount_summed in mrp_aal_read_group: - if currency != self.currency_id: - rate = project_currency_rate / rate_per_currency_id[currency.id] - total_amount += self.currency_id.round(amount_summed * rate) - else: - total_amount += amount_summed + total_amount += currency._convert(amount_summed, self.currency_id, self.company_id) mrp_costs = { 'id': mrp_category, diff --git a/addons/project_purchase/models/project_project.py b/addons/project_purchase/models/project_project.py index c2b6d490628..93afb3c7b12 100644 --- a/addons/project_purchase/models/project_project.py +++ b/addons/project_purchase/models/project_project.py @@ -5,8 +5,8 @@ import json from odoo import api, fields, models, _, _lt from odoo.osv import expression +from odoo.tools.misc import OrderedSet -from datetime import date class Project(models.Model): _inherit = "project.project" @@ -139,17 +139,14 @@ class Project(models.Model): purchase_order_line_invoice_line_ids = self._get_already_included_profitability_invoice_line_ids() with_action = with_action and self.user_has_groups('purchase.group_purchase_user, account.group_account_invoice, account.group_account_readonly') if purchase_order_line_read: - # Get conversion rate from currencies to currency of the current company - convert_company = self.company_id or self.env.company - currency_ids = {pol['currency_id'] for pol in purchase_order_line_read + [{'currency_id': self.currency_id.id}]} - rates = self.env['res.currency'].browse(list(currency_ids))._get_rates(convert_company, date.today()) - conversion_rates = {cid: rates[self.currency_id.id] / rate_from for cid, rate_from in rates.items()} + currency_ids = OrderedSet(pol['currency_id'] for pol in purchase_order_line_read) amount_invoiced = amount_to_invoice = 0.0 purchase_order_line_ids = [] for pol_read in purchase_order_line_read: purchase_order_line_invoice_line_ids.extend(pol_read['invoice_lines'].ids) - price_unit = self.currency_id.round(pol_read['price_unit'] * conversion_rates[pol_read['currency_id']]) + currency = self.env['res.currency'].browse(pol_read['currency_id']).with_prefetch(currency_ids) + price_unit = currency._convert(pol_read['price_unit'], self.currency_id, self.company_id) analytic_contribution = pol_read['analytic_distribution'][str(self.analytic_account_id.id)] / 100. amount_invoiced -= price_unit * pol_read['qty_invoiced'] * analytic_contribution if pol_read['qty_invoiced'] > 0 else 0.0 if pol_read['qty_to_invoice'] > 0: diff --git a/addons/project_sale_expense/models/project_project.py b/addons/project_sale_expense/models/project_project.py index 472590595ee..5d74a08ecfa 100644 --- a/addons/project_sale_expense/models/project_project.py +++ b/addons/project_sale_expense/models/project_project.py @@ -24,9 +24,6 @@ class Project(models.Model): return {} expenses_per_so_id = {} expense_ids = [] - amount_billed = 0.0 - today = fields.Date.context_today(self) - convert_company = self.company_id or self.env.company dict_amount_per_currency = defaultdict(lambda: 0.0) for res in expenses_read_group: so_id = res['sale_order_id'] @@ -35,13 +32,11 @@ class Project(models.Model): if can_see_expense: expense_ids.extend(res['ids']) dict_amount_per_currency[res['currency_id']] += res['untaxed_amount_currency'] + + amount_billed = 0.0 for currency_id in dict_amount_per_currency: - if currency_id == self.currency_id.id: - amount_billed += dict_amount_per_currency[currency_id] - continue - currency = self.env['res.currency'].browse(currency_id) - rate = currency._get_conversion_rate(currency, self.currency_id, convert_company, today) - amount_billed += self.currency_id.round(dict_amount_per_currency[currency_id] * rate) + currency = self.env['res.currency'].browse(currency_id).with_prefetch(dict_amount_per_currency) + amount_billed += currency._convert(dict_amount_per_currency[currency_id], self.currency_id, self.company_id) sol_read_group = self.env['sale.order.line'].sudo()._read_group( [ @@ -65,18 +60,9 @@ class Project(models.Model): dict_invoices_amount_per_currency[currency]['to_invoice'] += untaxed_amount_to_invoice_sum dict_invoices_amount_per_currency[currency]['invoiced'] += untaxed_amount_invoiced_sum reinvoice_expense_ids += expense_data_per_product_id[product_id] - rate_per_currency_id = {self.currency_id.id: 1} - if len(set_currency_ids) > 1: - rate_per_currency_id = self.env['res.currency'].browse(set_currency_ids)._get_rates(self.company_id or self.env.company, today) - project_currency_rate = rate_per_currency_id[self.currency_id.id] for currency, revenues in dict_invoices_amount_per_currency.items(): - if currency.id == self.currency_id.id: - total_amount_expense_to_invoice += revenues['to_invoice'] - total_amount_expense_invoiced += revenues['invoiced'] - continue - rate = project_currency_rate / rate_per_currency_id[currency.id] - total_amount_expense_to_invoice += self.currency_id.round(revenues['to_invoice'] * rate) - total_amount_expense_invoiced += self.currency_id.round(revenues['invoiced'] * rate) + total_amount_expense_to_invoice += currency._convert(revenues['to_invoice'], self.currency_id, self.company_id) + total_amount_expense_invoiced += currency._convert(revenues['invoiced'], self.currency_id, self.company_id) section_id = 'expenses' sequence = self._get_profitability_sequence_per_invoice_type()[section_id] diff --git a/addons/sale/models/sale_order.py b/addons/sale/models/sale_order.py index 7736bd9e767..c2d559f42c6 100644 --- a/addons/sale/models/sale_order.py +++ b/addons/sale/models/sale_order.py @@ -401,24 +401,13 @@ class SaleOrder(models.Model): @api.depends('currency_id', 'date_order', 'company_id') def _compute_currency_rate(self): - cache = {} for order in self: - order_date = order.date_order.date() - if not order.company_id: - order.currency_rate = order.currency_id.with_context(date=order_date).rate or 1.0 - continue - elif not order.currency_id: - order.currency_rate = 1.0 - else: - key = (order.company_id.id, order_date, order.currency_id.id) - if key not in cache: - cache[key] = self.env['res.currency']._get_conversion_rate( - from_currency=order.company_id.currency_id, - to_currency=order.currency_id, - company=order.company_id, - date=order_date, - ) - order.currency_rate = cache[key] + order.currency_rate = self.env['res.currency']._get_conversion_rate( + from_currency=order.company_id.currency_id, + to_currency=order.currency_id, + company=order.company_id, + date=order.date_order.date(), + ) @api.depends('company_id') def _compute_has_active_pricelist(self): diff --git a/addons/sale_project/models/project.py b/addons/sale_project/models/project.py index 4ddc74a0f72..604404aa5d3 100755 --- a/addons/sale_project/models/project.py +++ b/addons/sale_project/models/project.py @@ -8,7 +8,7 @@ from datetime import date from odoo import api, fields, models, _, _lt from odoo.exceptions import ValidationError, AccessError from odoo.osv import expression -from odoo.tools import Query, SQL +from odoo.tools import Query, SQL, OrderedSet from odoo.addons.project.models.project_task import CLOSED_STATES @@ -444,20 +444,17 @@ class Project(models.Model): if sale_line_read_group: # Get conversion rate from currencies of the sale order lines to currency of project convert_company = self.company_id or self.env.company - currency_ids = list(set([currency_id.id for currency_id, *_ in sale_line_read_group] + [self.currency_id.id])) - rates = self.env['res.currency'].browse(currency_ids)._get_rates(convert_company, date.today()) - conversion_rates = {cid: rates[self.currency_id.id] / rate_from for cid, rate_from in rates.items()} sols_per_product = defaultdict(lambda: [0.0, 0.0, []]) downpayment_amount_invoiced = 0 downpayment_sol_ids = [] for currency, product, is_downpayment, sol_ids, untaxed_amount_to_invoice, untaxed_amount_invoiced in sale_line_read_group: if is_downpayment: - downpayment_amount_invoiced += untaxed_amount_invoiced * conversion_rates[currency.id] + downpayment_amount_invoiced += currency._convert(untaxed_amount_invoiced, convert_company.currency_id, convert_company, round=False) downpayment_sol_ids += sol_ids else: - sols_per_product[product.id][0] += convert_company.currency_id.round(untaxed_amount_to_invoice * conversion_rates[currency.id]) - sols_per_product[product.id][1] += convert_company.currency_id.round(untaxed_amount_invoiced * conversion_rates[currency.id]) + sols_per_product[product.id][0] += currency._convert(untaxed_amount_to_invoice, convert_company.currency_id, convert_company) + sols_per_product[product.id][1] += currency._convert(untaxed_amount_invoiced, convert_company.currency_id, convert_company) sols_per_product[product.id][2] += sol_ids if downpayment_amount_invoiced: downpayments_data = { @@ -567,15 +564,12 @@ class Project(models.Model): self._cr.execute(query_string, query_param) invoices_move_line_read = self._cr.dictfetchall() if invoices_move_line_read: - # Get conversion rate from currencies to currency of the current company - currency_ids = {iml['currency_id'] for iml in invoices_move_line_read + [{'currency_id': self.currency_id.id}]} - rates = self.env['res.currency'].browse(list(currency_ids))._get_rates(self.company_id or self.env.company, fields.Date.context_today(self)) - conversion_rates = {cid: rates[self.currency_id.id] / rate_from for cid, rate_from in rates.items()} - + currency_ids = OrderedSet(iml['currency_id'] for iml in invoices_move_line_read) move_ids = set() amount_invoiced = amount_to_invoice = 0.0 for moves_read in invoices_move_line_read: - price_subtotal = self.currency_id.round(moves_read['price_subtotal'] * conversion_rates[moves_read['currency_id']]) + currency = self.env['res.currency'].browse(moves_read['currency_id']).with_prefetch(currency_ids) + price_subtotal = currency._convert(moves_read['price_subtotal'], self.currency_id, self.company_id) analytic_contribution = moves_read['analytic_distribution'][str(self.analytic_account_id.id)] / 100. move_ids.add(moves_read['move_id']) if moves_read['parent_state'] == 'draft': diff --git a/addons/sale_timesheet/models/project.py b/addons/sale_timesheet/models/project.py index 338d6a0f7c3..ba47846ad59 100644 --- a/addons/sale_timesheet/models/project.py +++ b/addons/sale_timesheet/models/project.py @@ -425,16 +425,9 @@ class Project(models.Model): costs_dict = {} total_revenues = {'invoiced': 0.0, 'to_invoice': 0.0} total_costs = {'billed': 0.0, 'to_bill': 0.0} - dict_rate_per_currency = {} - today = fields.Date.context_today(self) convert_company = self.company_id or self.env.company for timesheet_invoice_type, dummy, currency, amount, ids in aa_line_read_group: - if currency != self.currency_id: - rate = dict_rate_per_currency.get(currency.id, False) - if not rate: - rate = currency._get_conversion_rate(currency, self.currency_id, convert_company, today) - dict_rate_per_currency[currency.id] = rate - amount = self.currency_id.round(amount * rate) + amount = currency._convert(amount, self.currency_id, convert_company) invoice_type = timesheet_invoice_type cost = costs_dict.setdefault(invoice_type, {'billed': 0.0, 'to_bill': 0.0}) revenue = revenues_dict.setdefault(invoice_type, {'invoiced': 0.0, 'to_invoice': 0.0})