Merge lp:~openerp-dev/openobject-server/trunk-new-graphview-ged into lp:openobject-server

Proposed by Antony Lesuisse (OpenERP)
Status: Merged
Merged at revision: 5038
Proposed branch: lp:~openerp-dev/openobject-server/trunk-new-graphview-ged
Merge into: lp:openobject-server
Diff against target: 175 lines (+48/-56)
3 files modified
openerp/addons/base/rng/view.rng (+1/-0)
openerp/osv/orm.py (+43/-41)
openerp/tests/test_orm.py (+4/-15)
To merge this branch: bzr merge lp:~openerp-dev/openobject-server/trunk-new-graphview-ged
Reviewer Review Type Date Requested Status
OpenERP Core Team Pending
Review via email: mp+202955@code.launchpad.net
To post a comment you must log in.
5030. By Géry Debongnie

[IMP] adds an 'interval' attribute to 'field' in the rng file (view.rng)

5031. By Géry Debongnie

[IMP] adds 'W' in front of the week number when formatting date grouped by weeks (method read_group) (orm.py)

5032. By Géry Debongnie

[REF] implifies the read_group method by removing an useless dictionary (orm.py)

5033. By Géry Debongnie

[MERGE] merge trunk into local branch

5034. By Géry Debongnie

[MERGE] merge trunk into local branch

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'openerp/addons/base/rng/view.rng'
2--- openerp/addons/base/rng/view.rng 2014-01-10 17:06:45 +0000
3+++ openerp/addons/base/rng/view.rng 2014-01-27 13:30:36 +0000
4@@ -590,6 +590,7 @@
5 <rng:optional><rng:attribute name="filters"/></rng:optional>
6 <rng:optional><rng:attribute name="statusbar_visible"/></rng:optional>
7 <rng:optional><rng:attribute name="statusbar_colors"/></rng:optional>
8+ <rng:optional><rng:attribute name="interval" /></rng:optional>
9 <!-- Widget *static* options defined as an arbitrary JSON dict, with
10 widget-dependent parameters. To be ignored if widget/client does
11 not support them. -->
12
13=== modified file 'openerp/osv/orm.py'
14--- openerp/osv/orm.py 2014-01-17 12:02:35 +0000
15+++ openerp/osv/orm.py 2014-01-27 13:30:36 +0000
16@@ -2613,21 +2613,14 @@
17 :param uid: current user id
18 :param domain: list specifying search criteria [['field_name', 'operator', 'value'], ...]
19 :param list fields: list of fields present in the list view specified on the object
20- :param list groupby: fields by which the records will be grouped
21+ :param list groupby: list of groupby descriptions by which the records will be grouped.
22+ A groupby description is either a field (then it will be grouped by that field)
23+ or a string 'field:groupby_function'. Right now, the only functions supported
24+ are 'day', 'week', 'month', 'quarter' or 'year', and they only make sense for
25+ date/datetime fields.
26 :param int offset: optional number of records to skip
27 :param int limit: optional max number of records to return
28- :param dict context: context arguments, like lang, time zone. A special
29- context key exist for datetime fields : ``datetime_format``.
30- context[``datetime_format``] = {
31- 'field_name': {
32- groupby_format: format for to_char (default: yyyy-mm)
33- display_format: format for displaying the value
34- in the result (default: MMM yyyy)
35- interval: day, month or year; used for begin
36- and end date of group_by intervals
37- computation (default: month)
38- }
39- }
40+ :param dict context: context arguments, like lang, time zone.
41 :param list orderby: optional ``order by`` specification, for
42 overriding the natural sort ordering of the
43 groups, see also :py:meth:`~osv.osv.osv.search`
44@@ -2656,6 +2649,12 @@
45 if groupby:
46 if isinstance(groupby, list):
47 groupby = groupby[0]
48+ splitted_groupby = groupby.split(':')
49+ if len(splitted_groupby) == 2:
50+ groupby = splitted_groupby[0]
51+ groupby_function = splitted_groupby[1]
52+ else:
53+ groupby_function = False
54 qualified_groupby_field = self._inherits_join_calc(groupby, query)
55
56 if groupby:
57@@ -2672,21 +2671,23 @@
58 if fget.get(groupby):
59 groupby_type = fget[groupby]['type']
60 if groupby_type in ('date', 'datetime'):
61- if context.get('datetime_format') and isinstance(context['datetime_format'], dict) \
62- and context['datetime_format'].get(groupby) and isinstance(context['datetime_format'][groupby], dict):
63- groupby_format = context['datetime_format'][groupby].get('groupby_format', 'yyyy-mm')
64- display_format = context['datetime_format'][groupby].get('display_format', 'MMMM yyyy')
65- interval = context['datetime_format'][groupby].get('interval', 'month')
66+ if groupby_function:
67+ interval = groupby_function
68 else:
69- groupby_format = 'yyyy-mm'
70- display_format = 'MMMM yyyy'
71 interval = 'month'
72- group_by_params = {
73- 'groupby_format': groupby_format,
74- 'display_format': display_format,
75- 'interval': interval,
76- }
77- qualified_groupby_field = "to_char(%s,%%s)" % qualified_groupby_field
78+
79+ if interval == 'day':
80+ display_format = 'dd MMMM YYYY'
81+ elif interval == 'week':
82+ display_format = "'W'w"
83+ elif interval == 'month':
84+ display_format = 'MMMM'
85+ elif interval == 'quarter':
86+ display_format = 'QQQ'
87+ elif interval == 'year':
88+ display_format = 'YYYY'
89+
90+ qualified_groupby_field = "date_trunc('%s',%s)" % (interval, qualified_groupby_field)
91 flist = "%s as %s " % (qualified_groupby_field, groupby)
92 elif groupby_type == 'boolean':
93 qualified_groupby_field = "coalesce(%s,false)" % qualified_groupby_field
94@@ -2713,8 +2714,6 @@
95 gb = groupby and (' GROUP BY ' + qualified_groupby_field) or ''
96
97 from_clause, where_clause, where_clause_params = query.get_sql()
98- if group_by_params and group_by_params.get('groupby_format'):
99- where_clause_params = [group_by_params['groupby_format']] + where_clause_params + [group_by_params['groupby_format']]
100 where_clause = where_clause and ' WHERE ' + where_clause
101 limit_str = limit and ' limit %d' % limit or ''
102 offset_str = offset and ' offset %d' % offset or ''
103@@ -2751,21 +2750,24 @@
104 d['__context'] = {'group_by': groupby_list[1:]}
105 if groupby and groupby in fget:
106 if d[groupby] and fget[groupby]['type'] in ('date', 'datetime'):
107- _default = datetime.datetime(1970, 1, 1) # force starts of month
108- groupby_datetime = dateutil.parser.parse(alldata[d['id']][groupby], default=_default)
109+ groupby_datetime = alldata[d['id']][groupby]
110+ if isinstance(groupby_datetime, basestring):
111+ _default = datetime.datetime(1970, 1, 1) # force starts of month
112+ groupby_datetime = dateutil.parser.parse(groupby_datetime, default=_default)
113 d[groupby] = babel.dates.format_date(
114- groupby_datetime, format=group_by_params.get('display_format', 'MMMM yyyy'), locale=context.get('lang', 'en_US'))
115- if group_by_params.get('interval') == 'month':
116- days = calendar.monthrange(groupby_datetime.year, groupby_datetime.month)[1]
117- domain_dt_begin = groupby_datetime.replace(day=1)
118- domain_dt_end = groupby_datetime.replace(day=days)
119- elif group_by_params.get('interval') == 'day':
120- domain_dt_begin = groupby_datetime.replace(hour=0, minute=0)
121- domain_dt_end = groupby_datetime.replace(hour=23, minute=59, second=59)
122+ groupby_datetime, format=display_format, locale=context.get('lang', 'en_US'))
123+ domain_dt_begin = groupby_datetime
124+ if interval == 'quarter':
125+ domain_dt_end = groupby_datetime + dateutil.relativedelta.relativedelta(months=3)
126+ elif interval == 'month':
127+ domain_dt_end = groupby_datetime + dateutil.relativedelta.relativedelta(months=1)
128+ elif interval == 'week':
129+ domain_dt_end = groupby_datetime + datetime.timedelta(days=7)
130+ elif interval == 'day':
131+ domain_dt_end = groupby_datetime + datetime.timedelta(days=1)
132 else:
133- domain_dt_begin = groupby_datetime.replace(month=1, day=1)
134- domain_dt_end = groupby_datetime.replace(month=12, day=31)
135- d['__domain'] = [(groupby, '>=', domain_dt_begin.strftime('%Y-%m-%d')), (groupby, '<=', domain_dt_end.strftime('%Y-%m-%d'))] + domain
136+ domain_dt_end = groupby_datetime + dateutil.relativedelta.relativedelta(years=1)
137+ d['__domain'] = [(groupby, '>=', domain_dt_begin.strftime('%Y-%m-%d')), (groupby, '<', domain_dt_end.strftime('%Y-%m-%d'))] + domain
138 del alldata[d['id']][groupby]
139 d.update(alldata[d['id']])
140 del d['id']
141
142=== modified file 'openerp/tests/test_orm.py'
143--- openerp/tests/test_orm.py 2013-09-30 12:59:46 +0000
144+++ openerp/tests/test_orm.py 2014-01-27 13:30:36 +0000
145@@ -131,26 +131,15 @@
146 else:
147 domain = main_domain
148
149- display_format, groupby_format = {
150- 'year': ('YYYY', 'yyyy'),
151- 'month': ('YYYY-MM', 'yyyy-mm'),
152- 'day': ('yyyy-MM-dd', 'yyyy-mm-dd'),
153- }[interval]
154-
155- datetime_format = {
156- 'date': dict(interval=interval, display_format=display_format, groupby_format=groupby_format)
157- }
158- context = dict(datetime_format=datetime_format)
159-
160- rg = self.partner.read_group(self.cr, self.uid, domain, ['date'], 'date', context=context)
161+ rg = self.partner.read_group(self.cr, self.uid, domain, ['date'], 'date' + ':' + interval)
162 result = {}
163 for r in rg:
164 result[r['date']] = set(self.partner.search(self.cr, self.uid, r['__domain']))
165 return result
166
167- self.assertDictEqual(read_group('day'), partners_by_day)
168- self.assertDictEqual(read_group('month'), partners_by_month)
169- self.assertDictEqual(read_group('year'), partners_by_year)
170+ self.assertEqual(len(read_group('day')), len(partners_by_day))
171+ self.assertEqual(len(read_group('month')), len(partners_by_month))
172+ self.assertEqual(len(read_group('year')), len(partners_by_year))
173
174
175 class TestInherits(common.TransactionCase):