[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
This commit is contained in:
Denis Ledoux
2016-02-10 15:53:21 +01:00
parent fbf6f2cd9b
commit 47bb1bd225
4 changed files with 27 additions and 30 deletions
@@ -158,23 +158,16 @@ class AccountInvoiceReport(models.Model):
# self._table = account_invoice_report # self._table = account_invoice_report
tools.drop_view_if_exists(cr, self._table) tools.drop_view_if_exists(cr, self._table)
cr.execute("""CREATE or REPLACE VIEW %s as ( cr.execute("""CREATE or REPLACE VIEW %s as (
WITH currency_rate (currency_id, rate, date_start, date_end) AS ( WITH currency_rate AS (%s)
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
)
%s %s
FROM ( FROM (
%s %s %s %s %s %s
) AS sub ) AS sub
LEFT JOIN currency_rate cr ON LEFT JOIN currency_rate cr ON
(cr.currency_id = sub.currency_id AND (cr.currency_id = sub.currency_id AND
cr.company_id = sub.company_id AND
cr.date_start <= COALESCE(sub.date, NOW()) AND cr.date_start <= COALESCE(sub.date, NOW()) AND
(cr.date_end IS NULL OR cr.date_end > COALESCE(sub.date, NOW()))) (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())) self._select(), self._sub_select(), self._from(), self._group_by()))
+3 -10
View File
@@ -49,15 +49,7 @@ class purchase_report(osv.osv):
tools.sql.drop_view_if_exists(cr, 'purchase_report') tools.sql.drop_view_if_exists(cr, 'purchase_report')
cr.execute(""" cr.execute("""
create or replace view purchase_report as ( create or replace view purchase_report as (
WITH currency_rate (currency_id, rate, date_start, date_end) AS ( WITH currency_rate as (%s)
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
)
select select
min(l.id) as id, min(l.id) as id,
s.date_order as date, 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 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 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 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_start <= coalesce(s.date_order, now()) and
(cr.date_end is null or cr.date_end > coalesce(s.date_order, now()))) (cr.date_end is null or cr.date_end > coalesce(s.date_order, now())))
group by group by
@@ -125,4 +118,4 @@ class purchase_report(osv.osv):
partner.commercial_partner_id, partner.commercial_partner_id,
analytic_account.id analytic_account.id
) )
""") """ % self.pool['res.currency']._select_companies_rates())
+3 -10
View File
@@ -43,15 +43,7 @@ class sale_report(osv.osv):
def _select(self): def _select(self):
select_str = """ select_str = """
WITH currency_rate (currency_id, rate, date_start, date_end) AS ( WITH currency_rate as (%s)
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
)
SELECT min(l.id) as id, SELECT min(l.id) as id,
l.product_id as product_id, l.product_id as product_id,
t.uom_id as product_uom, t.uom_id as product_uom,
@@ -75,7 +67,7 @@ class sale_report(osv.osv):
p.product_tmpl_id, p.product_tmpl_id,
partner.country_id as country_id, partner.country_id as country_id,
partner.commercial_partner_id as commercial_partner_id partner.commercial_partner_id as commercial_partner_id
""" """ % self.pool['res.currency']._select_companies_rates()
return select_str return select_str
def _from(self): 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_uom u2 on (u2.id=t.uom_id)
left join product_pricelist pp on (s.pricelist_id = pp.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 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_start <= coalesce(s.date_order, now()) and
(cr.date_end is null or cr.date_end > coalesce(s.date_order, now()))) (cr.date_end is null or cr.date_end > coalesce(s.date_order, now())))
""" """
+18
View File
@@ -262,6 +262,24 @@ class res_currency(osv.osv):
function = "if (arguments[1] === false || arguments[1] === undefined) {" + company_currency_format + " }" + function function = "if (arguments[1] === false || arguments[1] === undefined) {" + company_currency_format + " }" + function
return 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): class res_currency_rate(osv.osv):
_name = "res.currency.rate" _name = "res.currency.rate"
_description = "Currency Rate" _description = "Currency Rate"