Add SQL query for currency by date range

issue6944
review42851002
This commit is contained in:
Cédric Krier committed 2017-12-26 17:31:44 +01:00
1 parent c05180c993
commit dbc29df63b
3 files changed
+78 -1

No files matched your search

+1
View File
@@ -1,3 +1,4 @@
* Add SQL query for currency by date range
* Remove monetary formatting from currency
Version 4.6.0 - 2017-10-30
+37
View File
@@ -4,6 +4,9 @@ import datetime
from decimal import Decimal, ROUND_HALF_EVEN
from sql import Window
from sql.functions import NthValue
from trytond import backend
from trytond.model import ModelView, ModelSQL, fields, Unique, Check
from trytond.tools import datetime_strftime
@@ -175,6 +178,40 @@ class Currency(ModelSQL, ModelView):
else:
return amount * to_currency.rate / from_currency.rate
@classmethod
def currency_rate_sql(cls):
"Return a SQL query with currency, rate, start_date and end_date"
pool = Pool()
Rate = pool.get('currency.currency.rate')
transaction = Transaction()
database = transaction.database
rate = Rate.__table__()
if database.has_window_functions():
window = Window(
[rate.currency],
order_by=[rate.date.asc],
frame='ROWS', start=0, end=1)
# Use NthValue instead of LastValue to get NULL for the last row
end_date = NthValue(rate.date, 2, window=window)
else:
next_rate = Rate.__table__()
end_date = next_rate.select(
next_rate.date,
where=(next_rate.currency == rate.currency)
& (next_rate.date > rate.date),
order_by=[next_rate.date.asc],
limit=1)
query = (rate
.select(
rate.currency.as_('currency'),
rate.rate.as_('rate'),
rate.date.as_('start_date'),
end_date.as_('end_date'),
))
return query
class Rate(ModelSQL, ModelView):
'Rate'
+40 -1
View File
@@ -1,8 +1,10 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
import datetime
import unittest
from decimal import Decimal
import trytond.tests.test_tryton
from trytond.transaction import Transaction
from trytond.tests.test_tryton import ModuleTestCase, with_transaction
from trytond.pool import Pool
@@ -17,12 +19,15 @@ def create_currency(name):
}])[0]
def add_currency_rate(currency, rate):
def add_currency_rate(currency, rate, date=None):
pool = Pool()
Rate = pool.get('currency.currency.rate')
if date is None:
date = Rate.default_date()
return Rate.create([{
'currency': currency.id,
'rate': rate,
'date': date,
}])[0]
@@ -213,6 +218,40 @@ class CurrencyTestCase(ModuleTestCase):
)], 0, None, None)
self.assertFalse(rates)
@with_transaction()
def test_currency_rate_sql(self):
"Test currency rate SQL"
pool = Pool()
Currency = pool.get('currency.currency')
transaction = Transaction()
cursor = transaction.connection.cursor()
date = datetime.date
cu1 = create_currency('cu1')
for date_, rate in [
(date(2017, 1, 1), Decimal(1)),
(date(2017, 2, 1), Decimal(2)),
(date(2017, 3, 1), Decimal(3))]:
add_currency_rate(cu1, rate, date_)
cu2 = create_currency('cu2')
for date_, rate in [
(date(2017, 2, 1), Decimal(2)),
(date(2017, 4, 1), Decimal(4))]:
add_currency_rate(cu2, rate, date_)
query = Currency.currency_rate_sql()
cursor.execute(*query)
data = set(cursor.fetchall())
result = {
(cu1.id, Decimal(1), date(2017, 1, 1), date(2017, 2, 1)),
(cu1.id, Decimal(2), date(2017, 2, 1), date(2017, 3, 1)),
(cu1.id, Decimal(3), date(2017, 3, 1), None),
(cu2.id, Decimal(2), date(2017, 2, 1), date(2017, 4, 1)),
(cu2.id, Decimal(4), date(2017, 4, 1), None),
}
self.assertSetEqual(data, result)
def suite():
suite = trytond.tests.test_tryton.suite()