[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 <rco@odoo.com>
This commit is contained in:
@@ -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):
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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():
|
||||
|
||||
@@ -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 {}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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':
|
||||
|
||||
@@ -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})
|
||||
|
||||
Reference in New Issue
Block a user