[IMP] server changes required for new graph view (mainly read_group method in orm.py)

bzr revid: ged@openerp.com-20140127161125-2br49sy5bnyuen7f
This commit is contained in:
Gery Debongnie
2014-01-27 17:11:25 +01:00
3 changed files with 48 additions and 56 deletions
+1
View File
@@ -590,6 +590,7 @@
<rng:optional><rng:attribute name="filters"/></rng:optional>
<rng:optional><rng:attribute name="statusbar_visible"/></rng:optional>
<rng:optional><rng:attribute name="statusbar_colors"/></rng:optional>
<rng:optional><rng:attribute name="interval" /></rng:optional>
<!-- Widget *static* options defined as an arbitrary JSON dict, with
widget-dependent parameters. To be ignored if widget/client does
not support them. -->
+43 -41
View File
@@ -2613,21 +2613,14 @@ class BaseModel(object):
:param uid: current user id
:param domain: list specifying search criteria [['field_name', 'operator', 'value'], ...]
:param list fields: list of fields present in the list view specified on the object
:param list groupby: fields by which the records will be grouped
:param list groupby: list of groupby descriptions by which the records will be grouped.
A groupby description is either a field (then it will be grouped by that field)
or a string 'field:groupby_function'. Right now, the only functions supported
are 'day', 'week', 'month', 'quarter' or 'year', and they only make sense for
date/datetime fields.
:param int offset: optional number of records to skip
:param int limit: optional max number of records to return
:param dict context: context arguments, like lang, time zone. A special
context key exist for datetime fields : ``datetime_format``.
context[``datetime_format``] = {
'field_name': {
groupby_format: format for to_char (default: yyyy-mm)
display_format: format for displaying the value
in the result (default: MMM yyyy)
interval: day, month or year; used for begin
and end date of group_by intervals
computation (default: month)
}
}
:param dict context: context arguments, like lang, time zone.
:param list orderby: optional ``order by`` specification, for
overriding the natural sort ordering of the
groups, see also :py:meth:`~osv.osv.osv.search`
@@ -2656,6 +2649,12 @@ class BaseModel(object):
if groupby:
if isinstance(groupby, list):
groupby = groupby[0]
splitted_groupby = groupby.split(':')
if len(splitted_groupby) == 2:
groupby = splitted_groupby[0]
groupby_function = splitted_groupby[1]
else:
groupby_function = False
qualified_groupby_field = self._inherits_join_calc(groupby, query)
if groupby:
@@ -2672,21 +2671,23 @@ class BaseModel(object):
if fget.get(groupby):
groupby_type = fget[groupby]['type']
if groupby_type in ('date', 'datetime'):
if context.get('datetime_format') and isinstance(context['datetime_format'], dict) \
and context['datetime_format'].get(groupby) and isinstance(context['datetime_format'][groupby], dict):
groupby_format = context['datetime_format'][groupby].get('groupby_format', 'yyyy-mm')
display_format = context['datetime_format'][groupby].get('display_format', 'MMMM yyyy')
interval = context['datetime_format'][groupby].get('interval', 'month')
if groupby_function:
interval = groupby_function
else:
groupby_format = 'yyyy-mm'
display_format = 'MMMM yyyy'
interval = 'month'
group_by_params = {
'groupby_format': groupby_format,
'display_format': display_format,
'interval': interval,
}
qualified_groupby_field = "to_char(%s,%%s)" % qualified_groupby_field
if interval == 'day':
display_format = 'dd MMMM YYYY'
elif interval == 'week':
display_format = "'W'w"
elif interval == 'month':
display_format = 'MMMM'
elif interval == 'quarter':
display_format = 'QQQ'
elif interval == 'year':
display_format = 'YYYY'
qualified_groupby_field = "date_trunc('%s',%s)" % (interval, qualified_groupby_field)
flist = "%s as %s " % (qualified_groupby_field, groupby)
elif groupby_type == 'boolean':
qualified_groupby_field = "coalesce(%s,false)" % qualified_groupby_field
@@ -2713,8 +2714,6 @@ class BaseModel(object):
gb = groupby and (' GROUP BY ' + qualified_groupby_field) or ''
from_clause, where_clause, where_clause_params = query.get_sql()
if group_by_params and group_by_params.get('groupby_format'):
where_clause_params = [group_by_params['groupby_format']] + where_clause_params + [group_by_params['groupby_format']]
where_clause = where_clause and ' WHERE ' + where_clause
limit_str = limit and ' limit %d' % limit or ''
offset_str = offset and ' offset %d' % offset or ''
@@ -2751,21 +2750,24 @@ class BaseModel(object):
d['__context'] = {'group_by': groupby_list[1:]}
if groupby and groupby in fget:
if d[groupby] and fget[groupby]['type'] in ('date', 'datetime'):
_default = datetime.datetime(1970, 1, 1) # force starts of month
groupby_datetime = dateutil.parser.parse(alldata[d['id']][groupby], default=_default)
groupby_datetime = alldata[d['id']][groupby]
if isinstance(groupby_datetime, basestring):
_default = datetime.datetime(1970, 1, 1) # force starts of month
groupby_datetime = dateutil.parser.parse(groupby_datetime, default=_default)
d[groupby] = babel.dates.format_date(
groupby_datetime, format=group_by_params.get('display_format', 'MMMM yyyy'), locale=context.get('lang', 'en_US'))
if group_by_params.get('interval') == 'month':
days = calendar.monthrange(groupby_datetime.year, groupby_datetime.month)[1]
domain_dt_begin = groupby_datetime.replace(day=1)
domain_dt_end = groupby_datetime.replace(day=days)
elif group_by_params.get('interval') == 'day':
domain_dt_begin = groupby_datetime.replace(hour=0, minute=0)
domain_dt_end = groupby_datetime.replace(hour=23, minute=59, second=59)
groupby_datetime, format=display_format, locale=context.get('lang', 'en_US'))
domain_dt_begin = groupby_datetime
if interval == 'quarter':
domain_dt_end = groupby_datetime + dateutil.relativedelta.relativedelta(months=3)
elif interval == 'month':
domain_dt_end = groupby_datetime + dateutil.relativedelta.relativedelta(months=1)
elif interval == 'week':
domain_dt_end = groupby_datetime + datetime.timedelta(days=7)
elif interval == 'day':
domain_dt_end = groupby_datetime + datetime.timedelta(days=1)
else:
domain_dt_begin = groupby_datetime.replace(month=1, day=1)
domain_dt_end = groupby_datetime.replace(month=12, day=31)
d['__domain'] = [(groupby, '>=', domain_dt_begin.strftime('%Y-%m-%d')), (groupby, '<=', domain_dt_end.strftime('%Y-%m-%d'))] + domain
domain_dt_end = groupby_datetime + dateutil.relativedelta.relativedelta(years=1)
d['__domain'] = [(groupby, '>=', domain_dt_begin.strftime('%Y-%m-%d')), (groupby, '<', domain_dt_end.strftime('%Y-%m-%d'))] + domain
del alldata[d['id']][groupby]
d.update(alldata[d['id']])
del d['id']
+4 -15
View File
@@ -131,26 +131,15 @@ class TestORM(common.TransactionCase):
else:
domain = main_domain
display_format, groupby_format = {
'year': ('YYYY', 'yyyy'),
'month': ('YYYY-MM', 'yyyy-mm'),
'day': ('yyyy-MM-dd', 'yyyy-mm-dd'),
}[interval]
datetime_format = {
'date': dict(interval=interval, display_format=display_format, groupby_format=groupby_format)
}
context = dict(datetime_format=datetime_format)
rg = self.partner.read_group(self.cr, self.uid, domain, ['date'], 'date', context=context)
rg = self.partner.read_group(self.cr, self.uid, domain, ['date'], 'date' + ':' + interval)
result = {}
for r in rg:
result[r['date']] = set(self.partner.search(self.cr, self.uid, r['__domain']))
return result
self.assertDictEqual(read_group('day'), partners_by_day)
self.assertDictEqual(read_group('month'), partners_by_month)
self.assertDictEqual(read_group('year'), partners_by_year)
self.assertEqual(len(read_group('day')), len(partners_by_day))
self.assertEqual(len(read_group('month')), len(partners_by_month))
self.assertEqual(len(read_group('year')), len(partners_by_year))
class TestInherits(common.TransactionCase):