Add SQL query for currency by date range
issue6944 review42851002
This commit is contained in:
1 parent
c05180c993
commit
dbc29df63b
3 files changed
+78
-1
No files matched your search
@@ -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
@@ -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
@@ -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()
|
||||
|
||||
Reference in new issue
Block a user