From 47bb1bd2257c7af5ae68b9bb23455dd1bd21644c Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Wed, 10 Feb 2016 14:32:16 +0100 Subject: [PATCH] [FIX] account, purchase, sale, currency: companies rates In Odoo 9.0, the field `company_id` has been moved from the `res.currency` model to the `res.currency.rate` model. The different reports applying the currency rates on the amount at date have not been updated according to this change. This includes the sales, purchases and invoices analysis report. Basically, before 9.0, there was one `res.currency` per existing currency per company. A simple `JOIN` on the `res_currency` table was therefore enough to apply the currency rate. From 9.0, the currency records are shared between companies. It's the rates (`res.currency.rate`) that can be set a on specific company. The simple `JOIN` on `res_currency` is therefore no longer enough: the company condition must be added. Only rates from the specific company (e.g the company of the invoice) must be considered, or rates without companies. We take the opportunity to factor out the method, so, if a correction must be done, it must be done in one place only. opw-669129 --- .../account/report/account_invoice_report.py | 13 +++---------- addons/purchase/report/purchase_report.py | 13 +++---------- addons/sale/report/sale_report.py | 13 +++---------- openerp/addons/base/res/res_currency.py | 18 ++++++++++++++++++ 4 files changed, 27 insertions(+), 30 deletions(-) diff --git a/addons/account/report/account_invoice_report.py b/addons/account/report/account_invoice_report.py index f2d0548819a..b2f2f0fa83c 100644 --- a/addons/account/report/account_invoice_report.py +++ b/addons/account/report/account_invoice_report.py @@ -158,23 +158,16 @@ class AccountInvoiceReport(models.Model): # self._table = account_invoice_report tools.drop_view_if_exists(cr, self._table) cr.execute("""CREATE or REPLACE VIEW %s as ( - WITH currency_rate (currency_id, rate, date_start, date_end) AS ( - SELECT r.currency_id, r.rate, r.name AS date_start, - (SELECT name FROM res_currency_rate r2 - WHERE r2.name > r.name AND - r2.currency_id = r.currency_id - ORDER BY r2.name ASC - LIMIT 1) AS date_end - FROM res_currency_rate r - ) + WITH currency_rate AS (%s) %s FROM ( %s %s %s ) AS sub LEFT JOIN currency_rate cr ON (cr.currency_id = sub.currency_id AND + cr.company_id = sub.company_id AND cr.date_start <= COALESCE(sub.date, NOW()) AND (cr.date_end IS NULL OR cr.date_end > COALESCE(sub.date, NOW()))) )""" % ( - self._table, + self._table, self.pool['res.currency']._select_companies_rates(), self._select(), self._sub_select(), self._from(), self._group_by())) diff --git a/addons/purchase/report/purchase_report.py b/addons/purchase/report/purchase_report.py index 4786e46a7b9..59381718b1b 100644 --- a/addons/purchase/report/purchase_report.py +++ b/addons/purchase/report/purchase_report.py @@ -49,15 +49,7 @@ class purchase_report(osv.osv): tools.sql.drop_view_if_exists(cr, 'purchase_report') cr.execute(""" create or replace view purchase_report as ( - WITH currency_rate (currency_id, rate, date_start, date_end) AS ( - SELECT r.currency_id, r.rate, r.name AS date_start, - (SELECT name FROM res_currency_rate r2 - WHERE r2.name > r.name AND - r2.currency_id = r.currency_id - ORDER BY r2.name ASC - LIMIT 1) AS date_end - FROM res_currency_rate r - ) + WITH currency_rate as (%s) select min(l.id) as id, s.date_order as date, @@ -96,6 +88,7 @@ class purchase_report(osv.osv): left join stock_picking_type spt on (spt.id=s.picking_type_id) left join account_analytic_account analytic_account on (l.account_analytic_id = analytic_account.id) left join currency_rate cr on (cr.currency_id = s.currency_id and + cr.company_id = s.company_id and cr.date_start <= coalesce(s.date_order, now()) and (cr.date_end is null or cr.date_end > coalesce(s.date_order, now()))) group by @@ -125,4 +118,4 @@ class purchase_report(osv.osv): partner.commercial_partner_id, analytic_account.id ) - """) + """ % self.pool['res.currency']._select_companies_rates()) diff --git a/addons/sale/report/sale_report.py b/addons/sale/report/sale_report.py index 68ec0b37b02..507a2560d9e 100644 --- a/addons/sale/report/sale_report.py +++ b/addons/sale/report/sale_report.py @@ -43,15 +43,7 @@ class sale_report(osv.osv): def _select(self): select_str = """ - WITH currency_rate (currency_id, rate, date_start, date_end) AS ( - SELECT r.currency_id, r.rate, r.name AS date_start, - (SELECT name FROM res_currency_rate r2 - WHERE r2.name > r.name AND - r2.currency_id = r.currency_id - ORDER BY r2.name ASC - LIMIT 1) AS date_end - FROM res_currency_rate r - ) + WITH currency_rate as (%s) SELECT min(l.id) as id, l.product_id as product_id, t.uom_id as product_uom, @@ -75,7 +67,7 @@ class sale_report(osv.osv): p.product_tmpl_id, partner.country_id as country_id, partner.commercial_partner_id as commercial_partner_id - """ + """ % self.pool['res.currency']._select_companies_rates() return select_str def _from(self): @@ -89,6 +81,7 @@ class sale_report(osv.osv): left join product_uom u2 on (u2.id=t.uom_id) left join product_pricelist pp on (s.pricelist_id = pp.id) left join currency_rate cr on (cr.currency_id = pp.currency_id and + cr.company_id = s.company_id and cr.date_start <= coalesce(s.date_order, now()) and (cr.date_end is null or cr.date_end > coalesce(s.date_order, now()))) """ diff --git a/openerp/addons/base/res/res_currency.py b/openerp/addons/base/res/res_currency.py index 85f383f7825..2517bbb316d 100644 --- a/openerp/addons/base/res/res_currency.py +++ b/openerp/addons/base/res/res_currency.py @@ -262,6 +262,24 @@ class res_currency(osv.osv): function = "if (arguments[1] === false || arguments[1] === undefined) {" + company_currency_format + " }" + function return function + def _select_companies_rates(self): + return """ + SELECT + r.currency_id, + COALESCE(r.company_id, c.id) as company_id, + r.rate, + r.name AS date_start, + (SELECT name FROM res_currency_rate r2 + WHERE r2.name > r.name AND + r2.currency_id = r.currency_id AND + (r2.company_id is null or r2.company_id = r.company_id) + ORDER BY r2.name ASC + LIMIT 1) AS date_end + FROM res_currency_rate r + JOIN res_company c ON (r.company_id is null or r.company_id = c.id) + """ + + class res_currency_rate(osv.osv): _name = "res.currency.rate" _description = "Currency Rate"