Merge lp:~therp-nl/web-addons/7.0-web_relativedelta into lp:~webaddons-core-editors/web-addons/7.0

Proposed by Holger Brunn (Therp)
Status: Rejected
Rejected by: Holger Brunn (Therp)
Proposed branch: lp:~therp-nl/web-addons/7.0-web_relativedelta
Merge into: lp:~webaddons-core-editors/web-addons/7.0
Prerequisite: lp:~therp-nl/web-addons/7.0-web_relativedelta_momentjs
Diff against target: 377 lines (+352/-0)
4 files modified
web_relativedelta/__init__.py (+20/-0)
web_relativedelta/__openerp__.py (+77/-0)
web_relativedelta/static/src/js/web_relativedelta.js (+179/-0)
web_relativedelta/static/test/web_relativedelta.js (+76/-0)
To merge this branch: bzr merge lp:~therp-nl/web-addons/7.0-web_relativedelta
Reviewer Review Type Date Requested Status
Holger Brunn (Therp) Needs Resubmitting
Stefan Rijnhart (Opener) Needs Information
Review via email: mp+217653@code.launchpad.net

Description of the change

Reimplementation of relativedelta for use in client side domains in the hope that it sucks less than the one provided in upstream.

This uses http://momentjs.com which was committed separately to simplify the review.

To post a comment you must log in.
Revision history for this message
Stefan Rijnhart (Opener) (stefan-opener) wrote :

Thanks! Code looks clean enough. But I was wondering about the rationale. Can you give an example how to use this in a custom module (I assume)? Why do you 'hope' it sucks less, I mean, what is bad about the standard implementation in the OpenERP web client? Why not propose this into upstream OpenERP web client trunk then?

review: Needs Information
Revision history for this message
Holger Brunn (Therp) (hbrunn) wrote :

The hope part is modesty and the fact that I'm not sure that the day= parameter is handled correctly.

What is bad about the standard implementation:
- no weekday, so there's no chance to have filters for the current (calendar) week, next week, etc
- no datetimes, only date
- no hours, minute, second
- negative days are not properly implemented

For an example:
Just use relativedelta as usual, but without the drawbacks as described above

36. By Holger Brunn (Therp)

[IMP] sanitize input for absolute values
[IMP] handle day parameter correctly (don't cross month boundaries)

Revision history for this message
Holger Brunn (Therp) (hbrunn) wrote :
37. By Holger Brunn (Therp)

[FIX] actually use relativedelta's semantics for weekdays

38. By Holger Brunn (Therp)

[ADD] tests
[ADD] more detail in manifest

39. By Holger Brunn (Therp)

[ADD] actually add tests

Revision history for this message
Holger Brunn (Therp) (hbrunn) wrote :

This project is now hosted on https://github.com/OCA/web. Please move your proposal there. This guide may help you https://github.com/OCA/maintainers-tools/wiki/How-to-move-a-Merge-Proposal-to-GitHub

review: Needs Resubmitting
Revision history for this message
Holger Brunn (Therp) (hbrunn) wrote :

Unmerged revisions

39. By Holger Brunn (Therp)

[ADD] actually add tests

38. By Holger Brunn (Therp)

[ADD] tests
[ADD] more detail in manifest

37. By Holger Brunn (Therp)

[FIX] actually use relativedelta's semantics for weekdays

36. By Holger Brunn (Therp)

[IMP] sanitize input for absolute values
[IMP] handle day parameter correctly (don't cross month boundaries)

35. By Holger Brunn (Therp)

[ADD] web_relativedelta

34. By Holger Brunn (Therp)

[ADD] moment.js

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added file 'web_relativedelta/__init__.py'
--- web_relativedelta/__init__.py 1970-01-01 00:00:00 +0000
+++ web_relativedelta/__init__.py 2014-07-01 06:33:47 +0000
@@ -0,0 +1,20 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# This module copyright (C) 2014 Therp BV (<http://therp.nl>).
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
021
=== added file 'web_relativedelta/__openerp__.py'
--- web_relativedelta/__openerp__.py 1970-01-01 00:00:00 +0000
+++ web_relativedelta/__openerp__.py 2014-07-01 06:33:47 +0000
@@ -0,0 +1,77 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# This module copyright (C) 2014 Therp BV (<http://therp.nl>).
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21{
22 "name": "More pythonic relativedelta",
23 "version": "1.0",
24 "author": "Therp BV",
25 "license": "AGPL-3",
26 "complexity": "normal",
27 "description": """
28Introduction
29============
30
31This addon provides a reimplementation of OpenERP's pyjs relativedelta class
32using Moment.js (http://momentjs.com).
33
34On top of what you can do with the original, you can use
35
36- datetime objects
37- relativedelta(hour=0-23, hours=0-23)
38- relativedelta(minute=0-59, minutes=0-59)
39- relativedelta(seconds=0-59, seconds=0-59)
40- relativedelta(weekday=0) [MO] ... weekday=6 [SU]
41
42 - there's no MO(+n) syntax, but that can be simulated by
43 relativedelta(weeks=+(n-1), days=1, weekday=0), this week's monday would
44 be relativedelta(weeks=-1, days=1, weekday=0) etc.
45
46- all of them together in a predictable manner as detailed in https://labix.org/python-dateutil#head-72c4689ec5608067d118b9143cef6bdffb6dad4e
47
48Usage
49=====
50
51Simply depend on web_relativedelta and enjoy most of python's relativedelta
52functionality
53 """,
54 "category": "Dependency",
55 "depends": [
56 'web',
57 ],
58 "data": [
59 ],
60 "js": [
61 'static/lib/moment.js',
62 'static/src/js/web_relativedelta.js'
63 ],
64 "css": [
65 ],
66 "qweb": [
67 ],
68 "test": [
69 'static/test/web_relativedelta.js',
70 ],
71 "auto_install": False,
72 "installable": True,
73 "application": False,
74 "external_dependencies": {
75 'python': [],
76 },
77}
078
=== added directory 'web_relativedelta/static/src'
=== added directory 'web_relativedelta/static/src/img'
=== added file 'web_relativedelta/static/src/img/icon.png'
1Binary files web_relativedelta/static/src/img/icon.png 1970-01-01 00:00:00 +0000 and web_relativedelta/static/src/img/icon.png 2014-07-01 06:33:47 +0000 differ79Binary files web_relativedelta/static/src/img/icon.png 1970-01-01 00:00:00 +0000 and web_relativedelta/static/src/img/icon.png 2014-07-01 06:33:47 +0000 differ
=== added directory 'web_relativedelta/static/src/js'
=== added file 'web_relativedelta/static/src/js/web_relativedelta.js'
--- web_relativedelta/static/src/js/web_relativedelta.js 1970-01-01 00:00:00 +0000
+++ web_relativedelta/static/src/js/web_relativedelta.js 2014-07-01 06:33:47 +0000
@@ -0,0 +1,179 @@
1//-*- coding: utf-8 -*-
2//############################################################################
3//
4// OpenERP, Open Source Management Solution
5// This module copyright (C) 2014 Therp BV (<http://therp.nl>).
6//
7// This program is free software: you can redistribute it and/or modify
8// it under the terms of the GNU Affero General Public License as
9// published by the Free Software Foundation, either version 3 of the
10// License, or (at your option) any later version.
11//
12// This program is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15// GNU Affero General Public License for more details.
16//
17// You should have received a copy of the GNU Affero General Public License
18// along with this program. If not, see <http://www.gnu.org/licenses/>.
19//
20//############################################################################
21
22openerp.web_relativedelta = function(openerp)
23{
24 var relativedelta = py.type('relativedelta', null,
25 {
26 __init__: function()
27 {
28 this.ops = py.PY_parseArgs(
29 arguments,
30 [
31 ['year', null],
32 ['years', null],
33 ['month', null],
34 ['months', null],
35 ['day', null],
36 ['days', null],
37 ['hour', null],
38 ['hours', null],
39 ['minute', null],
40 ['minutes', null],
41 ['second', null],
42 ['seconds', null],
43 ['weeks', null],
44 ['weekday', null],
45 ]);
46 },
47 __add__: function(other)
48 {
49 if(other.__name__ != 'date' && other.__name__ != 'datetime')
50 {
51 return py.NotImplemented;
52 }
53
54 var result = moment({
55 year: other.year,
56 //january==0 in moment.js
57 month: other.month - 1,
58 day: other.day,
59 hour: other.hour,
60 minute: other.minute,
61 second: other.second});
62
63 if(this.ops.year)
64 {
65 result.year(Math.abs(this.ops.year._value));
66 }
67 if(this.ops.years)
68 {
69 result.add('years', this.ops.years._value);
70 }
71 if(this.ops.month)
72 {
73 //january==0 in moment.js
74 result.month(Math.abs(this.ops.month._value % 13) - 1);
75 }
76 if(this.ops.months)
77 {
78 result.add('months', this.ops.months._value);
79 }
80 if(this.ops.day)
81 {
82 result = result.clone()
83 .endOf('month')
84 .hours(result.hours())
85 .minutes(result.minutes())
86 .seconds(result.seconds())
87 .max(result.clone()
88 .date(Math.abs(this.ops.day._value)));
89 }
90 if(this.ops.days)
91 {
92 result.add('days', this.ops.days._value)
93 }
94 if(this.ops.weeks)
95 {
96 result.add('days', this.ops.weeks._value * 7);
97 }
98 if(this.ops.hour)
99 {
100 result.hour(Math.abs(this.ops.hour._value % 24));
101 }
102 if(this.ops.hours)
103 {
104 result.add('hours', this.ops.hours._value);
105 }
106 if(this.ops.minute)
107 {
108 result.minute(Math.abs(this.ops.minute._value % 60));
109 }
110 if(this.ops.minutes)
111 {
112 result.add('minutes', this.ops.minutes._value);
113 }
114 if(this.ops.second)
115 {
116 result.second(Math.abs(this.ops.second._value % 60));
117 }
118 if(this.ops.seconds)
119 {
120 result.add('seconds', this.ops.seconds._value);
121 }
122 if(this.ops.weekday)
123 {
124 //in relativedelta, 0=MO, but in iso, 1=MO
125 var isoWeekday = Math.abs(this.ops.weekday._value || 1) /
126 (this.ops.weekday._value || 1) *
127 (Math.abs(this.ops.weekday._value) + 1),
128 originalIsoWeekday = result.isoWeekday();
129 result.isoWeekday(isoWeekday).add(
130 'weeks', isoWeekday < originalIsoWeekday ? 1 : 0);
131 }
132
133 var args = [
134 result.year(),
135 //january==0 in moment.js
136 result.month() + 1,
137 result.date(),
138 ];
139 if(other.__name__ == 'datetime')
140 {
141 args.push(result.hour());
142 args.push(result.minute());
143 args.push(result.second());
144 }
145
146 return py.PY_call(Object.getPrototypeOf(other), args);
147 },
148 __radd__: function(other)
149 {
150 return this.__add__(other);
151 },
152 __sub__: function(other)
153 {
154 _.each(this.ops, function(op, name)
155 {
156 if(!op || name == 'weekday')
157 {
158 return;
159 }
160 op._value = -op._value;
161 });
162 return this.__add__(other);
163 },
164 __rsub__: function(other)
165 {
166 return this.__sub__(other);
167 },
168 });
169 var original_pyeval_context = openerp.web.pyeval.context;
170 openerp.web.pyeval.context = function ()
171 {
172 var ctx = original_pyeval_context();
173 return _.extend(
174 ctx,
175 {
176 relativedelta: relativedelta,
177 });
178 }
179}
0180
=== added directory 'web_relativedelta/static/test'
=== added file 'web_relativedelta/static/test/web_relativedelta.js'
--- web_relativedelta/static/test/web_relativedelta.js 1970-01-01 00:00:00 +0000
+++ web_relativedelta/static/test/web_relativedelta.js 2014-07-01 06:33:47 +0000
@@ -0,0 +1,76 @@
1//-*- coding: utf-8 -*-
2//############################################################################
3//
4// OpenERP, Open Source Management Solution
5// This module copyright (C) 2014 Therp BV (<http://therp.nl>).
6//
7// This program is free software: you can redistribute it and/or modify
8// it under the terms of the GNU Affero General Public License as
9// published by the Free Software Foundation, either version 3 of the
10// License, or (at your option) any later version.
11//
12// This program is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15// GNU Affero General Public License for more details.
16//
17// You should have received a copy of the GNU Affero General Public License
18// along with this program. If not, see <http://www.gnu.org/licenses/>.
19//
20//############################################################################
21
22openerp.testing.section(
23 'python_compatibility',
24 {dependencies: ['web.coresetup', 'web.pyeval']},
25 function(test)
26 {
27 test('basic deltas', function(instance)
28 {
29 openerp.web_relativedelta(instance);
30 var eval = function(expression)
31 {
32 var result_domain = instance.web.pyeval.eval(
33 'domain', "[['a', '=', " + expression + "]]", {}, {});
34 return result_domain[0][2];
35 }
36
37 var result;
38
39 result = eval(
40 "(datetime.date(2012, 12, 25) + relativedelta(days=7)).strftime('%Y-%m-%d')");
41 ok(result == '2013-01-01', "cross year");
42
43 result = eval(
44 //2012 is a leap year
45 "(datetime.date(2012, 01, 01) + relativedelta(days=366)).strftime('%Y-%m-%d')");
46 ok(result == '2013-01-01', "cross leap year");
47
48 result = eval(
49 "(datetime.date(2012, 02, 01) + relativedelta(day=366)).strftime('%Y-%m-%d')");
50 ok(result == '2012-02-29', "absolute day");
51
52 result = eval(
53 "(datetime.date(2012, 02, 01) + relativedelta(hours=-1)).strftime('%Y-%m-%d')");
54 ok(result == '2012-01-31', "negative hour");
55
56 result = eval(
57 "(datetime.date(2012, 01, 30) + relativedelta(weekday=0)).strftime('%Y-%m-%d')");
58 ok(result == '2012-01-30', "weekday=MO (on monday)");
59
60 result = eval(
61 "(datetime.date(2012, 01, 31) + relativedelta(weekday=0)).strftime('%Y-%m-%d')");
62 ok(result == '2012-02-06', "weekday=MO (on tuesday)");
63
64 result = eval(
65 "(datetime.date(2012, 01, 30) + relativedelta(weeks=-1, days=1, weekday=0)).strftime('%Y-%m-%d')");
66 ok(result == '2012-01-30', "last monday (on monday)");
67
68 result = eval(
69 "(datetime.date(2012, 01, 31) + relativedelta(weeks=-1, days=1, weekday=0)).strftime('%Y-%m-%d')");
70 ok(result == '2012-01-30', "last monday (on tuesday)");
71
72 result = eval(
73 "(datetime.date(2012, 02, 01) + relativedelta(weeks=-1, days=1, weekday=0)).strftime('%Y-%m-%d')");
74 ok(result == '2012-01-30', "last monday (on wednesday)");
75 });
76 });

Subscribers

People subscribed via source and target branches