Merge lp:~camptocamp/hr-timesheet/7.0-hr_timesheet_reminder-migr into lp:~hr-core-editors/hr-timesheet/7.0

Proposed by Guewen Baconnier @ Camptocamp
Status: Merged
Merged at revision: 40
Proposed branch: lp:~camptocamp/hr-timesheet/7.0-hr_timesheet_reminder-migr
Merge into: lp:~hr-core-editors/hr-timesheet/7.0
Diff against target: 1734 lines (+626/-669)
14 files modified
hr_timesheet_reminder/__init__.py (+15/-26)
hr_timesheet_reminder/__openerp__.py (+41/-43)
hr_timesheet_reminder/company.py (+50/-57)
hr_timesheet_reminder/hr_employee.py (+42/-53)
hr_timesheet_reminder/hr_employee_view.xml (+0/-1)
hr_timesheet_reminder/reminder.py (+100/-88)
hr_timesheet_reminder/report/__init__.py (+16/-25)
hr_timesheet_reminder/report/timesheet_status.py (+63/-65)
hr_timesheet_reminder/report/timesheet_status.rml (+157/-163)
hr_timesheet_reminder/timesheet_report.xml (+10/-10)
hr_timesheet_reminder/wizard/reminder_config.py (+37/-45)
hr_timesheet_reminder/wizard/reminder_config_view.xml (+38/-28)
hr_timesheet_reminder/wizard/reminder_status.py (+35/-44)
hr_timesheet_reminder/wizard/reminder_status_view.xml (+22/-21)
To merge this branch: bzr merge lp:~camptocamp/hr-timesheet/7.0-hr_timesheet_reminder-migr
Reviewer Review Type Date Requested Status
Alexandre Fayolle - camptocamp code review, no test Approve
Review via email: mp+139655@code.launchpad.net

Commit message

[MIGR] migration of hr_timesheet_reminder to OpenERP v7

Description of the change

Migration to OpenERP version 7 of the addon hr_timesheet_reminder.

 * change of license from GPLv2 to AGPLv3
 * replace openerp.tools.email_send by 'mail.mail'
 * the dates were not displayed on the report
 * migrate the views using the new layout
 * formatting and styling
 * fix bug: lp:1089390
 * fix a small issue on the nextcall of the cron which was initialized not 'tomorrow' but approximately the next day of the server date

To post a comment you must log in.
47. By Guewen Baconnier @ Camptocamp <email address hidden>

[MRG] from lp:hr-timesheet/7.0

48. By Guewen Baconnier @ Camptocamp <email address hidden>

[MIGR] set installable to True

49. By Guewen Baconnier @ Camptocamp <email address hidden>

[FIX] license in timesheet_status.rml, formatting

Revision history for this message
Alexandre Fayolle - camptocamp (alexandre-fayolle-c2c) wrote :

line 263: if status in ['Missing', 'Draft'] and employee.receive_timesheet_alerts
The second part of the test should be moved out to the outer loop (just after line 253) or even better to the search domain (line 243) : that way we don't make further queries for employees who don't recevie timesheet alerts (or am I missing something?)

653 + def _cron_nextcall():
654 + now = datetime.today() + timedelta(days=1)
655 + return time.strftime(
656 + DEFAULT_SERVER_DATETIME_FORMAT,
657 + now.timetuple())

1 -> I'd rename 'now' to 'tomorrow' or 'when'
2. why not use now.strftime(DEFAULT_SERVER_DATETIME_FORMAT) (or tomorrow.strftime...) instead of time.strftime(...) ?

There are probably a number of 'import time' which can be removed (pylint will tell you about unused imports)

607 + 'body_html': '<pre>%s</pre>' % message_data.message,

I expect mail clients to be fairly tolerant in what they accept, but this makes me uncomfortable.

Have you tested what happens if the user has typed in:

* html (e.g. "fill your timesheet <b>now!</b>")
* a raw text message with HTML special chars inside (e.g: "I'm very disapointed you did not fill your timesheet <:-( I'll make sure your manager is notified & takes proper action.

Best chance would be to allow the edition of the body of the message with a rich text editor. Is there such widget available in the oerp7 client ?

803 -# Author: Arnaud WÃŒst

-> Mojibake! (but you fixed it)

1638 + 'date': time.strftime('%Y-%m-%d'),
Is there not a constant defining this format?

review: Needs Information (a few suggestions from code quick read)
50. By Guewen Baconnier @ Camptocamp <email address hidden>

[FIX] use a correct name for a local variable, use tomorrow.strftime instead of time.strftime, so get rid of 'import time'

51. By Guewen Baconnier @ Camptocamp <email address hidden>

[FIX] use fields.date.today() instead of time.strftime() for a default date

52. By Guewen Baconnier @ Camptocamp <email address hidden>

[IMP] use a html field instead of a text field for the message

53. By Guewen Baconnier @ Camptocamp <email address hidden>

[FIX] skip earlier the employees who do not receive the timesheet alerts, avoid unecessary computations/queries

54. By Guewen Baconnier @ Camptocamp <email address hidden>

[FIX] remove unused import

Revision history for this message
Guewen Baconnier @ Camptocamp (gbaconnier-c2c) wrote :

You are right on all the points. I fixed them in my proposal.

Some comments:

 * There is now a fields.html. I use it now for the message. As a bonus, we gain a rich editing of the reminder message (yippee, 'Please take time to complete and confirm your timesheet' in *bold*).

 * Learned the word Mojibake today :-)

 * there is a constant for '%Y-%m-%d' but there is even better for the default values of date and datetime:
   fields.date.today() and fields.datetime.now() (there is also fields.date.context_today() and fields.date.context_timestamp() converted to the client timezone)

Revision history for this message
Alexandre Fayolle - camptocamp (alexandre-fayolle-c2c) wrote :

Yay !

<off-topic>
Mojibake (pronounce modjibaké in fr_FR) is one of these useful words I enjoy sharing :-)

For other illustrated funny / rare french words, you may want to check out http://brouillaminiscribbles.tumblr.com/
</off-topic>

review: Approve (code review, no test)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'hr_timesheet_reminder/__init__.py'
2--- hr_timesheet_reminder/__init__.py 2011-08-12 12:53:16 +0000
3+++ hr_timesheet_reminder/__init__.py 2012-12-13 17:06:20 +0000
4@@ -1,32 +1,21 @@
5 # -*- coding: utf-8 -*-
6 ##############################################################################
7 #
8-# Copyright (c) 2011 Camptocamp SA (http://www.camptocamp.com)
9-# All Right Reserved
10-#
11-# Author : Arnaud Wüst (Camptocamp)
12-# Author : Guewen Baconnier (Camptocamp)
13-#
14-# WARNING: This program as such is intended to be used by professional
15-# programmers who take the whole responsability of assessing all potential
16-# consequences resulting from its eventual inadequacies and bugs
17-# End users who are looking for a ready-to-use solution with commercial
18-# garantees and support are strongly adviced to contract a Free Software
19-# Service Company
20-#
21-# This program is Free Software; you can redistribute it and/or
22-# modify it under the terms of the GNU General Public License
23-# as published by the Free Software Foundation; either version 2
24-# of the License, or (at your option) any later version.
25-#
26-# This program is distributed in the hope that it will be useful,
27-# but WITHOUT ANY WARRANTY; without even the implied warranty of
28-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29-# GNU General Public License for more details.
30-#
31-# You should have received a copy of the GNU General Public License
32-# along with this program; if not, write to the Free Software
33-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
34+# Author: Arnaud Wüst (Camptocamp)
35+# Copyright 2011-2012 Camptocamp SA
36+#
37+# This program is free software: you can redistribute it and/or modify
38+# it under the terms of the GNU Affero General Public License as
39+# published by the Free Software Foundation, either version 3 of the
40+# License, or (at your option) any later version.
41+#
42+# This program is distributed in the hope that it will be useful,
43+# but WITHOUT ANY WARRANTY; without even the implied warranty of
44+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
45+# GNU Affero General Public License for more details.
46+#
47+# You should have received a copy of the GNU Affero General Public License
48+# along with this program. If not, see <http://www.gnu.org/licenses/>.
49 #
50 ##############################################################################
51
52
53=== modified file 'hr_timesheet_reminder/__openerp__.py'
54--- hr_timesheet_reminder/__openerp__.py 2012-12-13 12:20:12 +0000
55+++ hr_timesheet_reminder/__openerp__.py 2012-12-13 17:06:20 +0000
56@@ -1,54 +1,52 @@
57 # -*- coding: utf-8 -*-
58 ##############################################################################
59 #
60-# Copyright (c) 2011 Camptocamp SA (http://www.camptocamp.com)
61-# All Right Reserved
62-#
63-# Author : Arnaud Wüst (Camptocamp)
64-# Author : Nicolas Bessi (Camptocamp)
65-# Author : Guewen Baconnier (Camptocamp)
66-#
67-# WARNING: This program as such is intended to be used by professional
68-# programmers who take the whole responsability of assessing all potential
69-# consequences resulting from its eventual inadequacies and bugs
70-# End users who are looking for a ready-to-use solution with commercial
71-# garantees and support are strongly adviced to contract a Free Software
72-# Service Company
73-#
74-# This program is Free Software; you can redistribute it and/or
75-# modify it under the terms of the GNU General Public License
76-# as published by the Free Software Foundation; either version 2
77-# of the License, or (at your option) any later version.
78-#
79-# This program is distributed in the hope that it will be useful,
80-# but WITHOUT ANY WARRANTY; without even the implied warranty of
81-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
82-# GNU General Public License for more details.
83-#
84-# You should have received a copy of the GNU General Public License
85-# along with this program; if not, write to the Free Software
86-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
87+# Author: Arnaud Wüst (Camptocamp)
88+# Author: Nicolas Bessi (Camptocamp)
89+# Author: Guewen Baconnier (Camptocamp) (port to v7)
90+# Copyright 2011-2012 Camptocamp SA
91+#
92+# This program is free software: you can redistribute it and/or modify
93+# it under the terms of the GNU Affero General Public License as
94+# published by the Free Software Foundation, either version 3 of the
95+# License, or (at your option) any later version.
96+#
97+# This program is distributed in the hope that it will be useful,
98+# but WITHOUT ANY WARRANTY; without even the implied warranty of
99+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
100+# GNU Affero General Public License for more details.
101+#
102+# You should have received a copy of the GNU Affero General Public License
103+# along with this program. If not, see <http://www.gnu.org/licenses/>.
104 #
105 ##############################################################################
106
107-
108 {
109- "name" : "Timesheet Reminder",
110- "version" : "2.0",
111- "author" : "Camptocamp",
112- "category" : "",
113- "website" : "http://www.camptocamp.com",
114+ "name": "Timesheet Reminder",
115+ "version": "2.0",
116+ "author": "Camptocamp",
117+ "license": 'AGPL-3',
118+ "category": "",
119+ "website": "http://www.camptocamp.com",
120 "description": """
121-Timesheet Reports Module:
122- * Add a menu in Human Resources / Configuration / Timesheet Reminder. It allows to send automatic emails to those who did not complete their timesheet in the last 5 weeks.
123- * Per employee, you can choose to send the reminder or not.
124- * Add a report in Human Resources / Reporting / Timesheet / Timesheet Status which displays the state of the last 5 timesheets for all users per company.
125-
126-This module replaces the modules c2c_timesheet_reports in TinyERP 4 and OpenERP 5.
127+Timesheet Reports Module
128+========================
129+
130+ * Add a menu in `Human Resources / Configuration
131+ / Timesheet Reminder`.
132+ It allows to send automatic emails to those who did
133+ not complete their timesheet in the last 5 weeks.
134+ * Per employee, you can choose to send the reminder or not.
135+ * Add a report in `Human Resources / Reporting / Timesheet
136+ / Timesheet Status` which displays the state of the last
137+ 5 timesheets for all users per company.
138+
139+This module replaces the modules c2c_timesheet_reports
140+of TinyERP 4 and OpenERP 5.
141 """,
142- "depends" : ["hr_timesheet_sheet"],
143- "init_xml" : [],
144- "update_xml" : [
145+ "depends": ["hr_timesheet_sheet"],
146+ "init_xml": [],
147+ "update_xml": [
148 'security/ir.model.access.csv',
149 'wizard/reminder_config_view.xml',
150 'wizard/reminder_status_view.xml',
151@@ -56,5 +54,5 @@
152 'timesheet_report.xml',
153 ],
154 "active": False,
155- 'installable': False
156+ 'installable': True
157 }
158
159=== modified file 'hr_timesheet_reminder/company.py'
160--- hr_timesheet_reminder/company.py 2011-09-01 13:44:19 +0000
161+++ hr_timesheet_reminder/company.py 2012-12-13 17:06:20 +0000
162@@ -1,57 +1,50 @@
163 # -*- coding: utf-8 -*-
164 ##############################################################################
165 #
166-# Copyright (c) 2011 Camptocamp SA (http://www.camptocamp.com)
167-# All Right Reserved
168-#
169-# Author : Arnaud Wüst (Camptocamp)
170-# Author : Guewen Baconnier (Camptocamp)
171-#
172-# WARNING: This program as such is intended to be used by professional
173-# programmers who take the whole responsability of assessing all potential
174-# consequences resulting from its eventual inadequacies and bugs
175-# End users who are looking for a ready-to-use solution with commercial
176-# garantees and support are strongly adviced to contract a Free Software
177-# Service Company
178-#
179-# This program is Free Software; you can redistribute it and/or
180-# modify it under the terms of the GNU General Public License
181-# as published by the Free Software Foundation; either version 2
182-# of the License, or (at your option) any later version.
183-#
184-# This program is distributed in the hope that it will be useful,
185-# but WITHOUT ANY WARRANTY; without even the implied warranty of
186-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
187-# GNU General Public License for more details.
188-#
189-# You should have received a copy of the GNU General Public License
190-# along with this program; if not, write to the Free Software
191-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
192+# Author: Arnaud Wüst (Camptocamp)
193+# Author: Guewen Baconnier (Camptocamp)
194+# Copyright 2011-2012 Camptocamp SA
195+#
196+# This program is free software: you can redistribute it and/or modify
197+# it under the terms of the GNU Affero General Public License as
198+# published by the Free Software Foundation, either version 3 of the
199+# License, or (at your option) any later version.
200+#
201+# This program is distributed in the hope that it will be useful,
202+# but WITHOUT ANY WARRANTY; without even the implied warranty of
203+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
204+# GNU Affero General Public License for more details.
205+#
206+# You should have received a copy of the GNU Affero General Public License
207+# along with this program. If not, see <http://www.gnu.org/licenses/>.
208 #
209 ##############################################################################
210
211-
212-from datetime import date, datetime
213-from dateutil.relativedelta import *
214-from osv import fields, osv
215-from tools.translate import _
216-
217-
218-class res_company(osv.osv):
219+from datetime import datetime
220+from dateutil.relativedelta import relativedelta, MO, SU
221+from openerp.osv import osv, orm
222+from openerp.tools.translate import _
223+
224+
225+class res_company(orm.Model):
226 _inherit = 'res.company'
227
228 def get_reminder_recipients(self, cr, uid, ids, context=None):
229 """Return the list of users that must receive the email"""
230- res = {}.fromkeys(ids, [])
231+ res = dict((company_id, []) for company_id in ids)
232+
233 employee_obj = self.pool.get('hr.employee')
234
235- companies = self.browse(cr, uid, ids, context=context)
236-
237- for company in companies:
238- employee_ids = employee_obj.search(cr, uid,
239- [('company_id', '=', company.id),
240- ('active', '=', True)],
241- context=context)
242+ for company in self.browse(cr, uid, ids, context=context):
243+ employee_ids = employee_obj.search(
244+ cr, uid,
245+ [('company_id', '=', company.id),
246+ ('receive_timesheet_alerts', '=', True)],
247+ context=context)
248+
249+ if not employee_ids:
250+ continue
251+
252 employees = employee_obj.browse(cr, uid, employee_ids, context=context)
253
254 #periods
255@@ -62,24 +55,26 @@
256 # for each employee
257 for employee in employees:
258 # is timesheet for a period not confirmed ?
259- for p_index in range(len(periods)):
260- period = periods[p_index]
261+ for period in periods:
262 status = employee_obj.compute_timesheet_status(cr, uid, employee.id, period, context)
263
264 # if there is a missing sheet or a draft sheet
265 # and the user can receive alerts
266 # then we must alert the user
267- if status in ['Missing', 'Draft'] and employee.receive_timesheet_alerts:
268+ if status in ['Missing', 'Draft']:
269 res[company.id].append(employee)
270- break # no need to go further for this user, he is now added in the list, go to the next one
271+ # no need to go further for this user,
272+ # he is now added in the list, go to the next one
273+ break
274 return res
275
276 def compute_timesheet_periods(self, cr, uid, company, date, periods_number=5, context=None):
277 """ return the timeranges to display. This is the 5 last timesheets"""
278 periods = []
279- last_start_date, last_end_date = self.get_last_period_dates(cr, uid, company, date, context=context)
280+ last_start_date, last_end_date = self.get_last_period_dates(
281+ cr, uid, company, date, context=context)
282 for cpt in range(periods_number):
283- #find the delta between last_XXX_date to XXX_date
284+ # find the delta between last_XXX_date to XXX_date
285 if company.timesheet_range == 'month':
286 delta = relativedelta(months=-cpt)
287 elif company.timesheet_range == 'week':
288@@ -87,7 +82,9 @@
289 elif company.timesheet_range == 'year':
290 delta = relativedelta(years=-cpt)
291 else:
292- raise osv.except_osv(_('Error'), _('Unknow timesheet range: %s') % (company.timesheet_range,))
293+ raise osv.except_osv(
294+ _('Error'),
295+ _('Unknow timesheet range: %s') % company.timesheet_range)
296
297 start_date = last_start_date + delta
298 end_date = last_end_date + delta
299@@ -97,26 +94,22 @@
300
301 def get_last_period_dates(self, cr, uid, company, date, context=None):
302 """ return the start date and end date of the last period to display """
303-
304+
305 # return the first day and last day of the month
306 if company.timesheet_range == 'month':
307 start_date = date
308- end_date = start_date + relativedelta(months = +1)
309+ end_date = start_date + relativedelta(months=+1)
310
311 #return the first and last days of the week
312 elif company.timesheet_range == 'week':
313 # get monday of current week
314 start_date = date + relativedelta(weekday=MO(-1))
315- # get sunday of current week
316+ # get sunday of current week
317 end_date = date + relativedelta(weekday=SU(+1))
318
319 # return the first and last days of the year
320 else:
321- start_date = datetime(date.year, 1, 1)
322+ start_date = datetime(date.year, 1, 1)
323 end_date = datetime(date.year, 12, 31)
324
325-
326 return start_date, end_date
327-
328-
329-res_company()
330
331=== modified file 'hr_timesheet_reminder/hr_employee.py'
332--- hr_timesheet_reminder/hr_employee.py 2011-09-01 13:44:19 +0000
333+++ hr_timesheet_reminder/hr_employee.py 2012-12-13 17:06:20 +0000
334@@ -1,47 +1,38 @@
335 # -*- coding: utf-8 -*-
336 ##############################################################################
337 #
338-# Copyright (c) 2011 Camptocamp SA (http://www.camptocamp.com)
339-# All Right Reserved
340-#
341-# Author : Arnaud Wüst (Camptocamp)
342-# Author : Guewen Baconnier (Camptocamp)
343-#
344-# WARNING: This program as such is intended to be used by professional
345-# programmers who take the whole responsability of assessing all potential
346-# consequences resulting from its eventual inadequacies and bugs
347-# End users who are looking for a ready-to-use solution with commercial
348-# garantees and support are strongly adviced to contract a Free Software
349-# Service Company
350-#
351-# This program is Free Software; you can redistribute it and/or
352-# modify it under the terms of the GNU General Public License
353-# as published by the Free Software Foundation; either version 2
354-# of the License, or (at your option) any later version.
355-#
356-# This program is distributed in the hope that it will be useful,
357-# but WITHOUT ANY WARRANTY; without even the implied warranty of
358-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
359-# GNU General Public License for more details.
360-#
361-# You should have received a copy of the GNU General Public License
362-# along with this program; if not, write to the Free Software
363-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
364+# Author: Arnaud Wüst (Camptocamp)
365+# Author: Guewen Baconnier (Camptocamp) (port to v7)
366+# Copyright 2011-2012 Camptocamp SA
367+#
368+# This program is free software: you can redistribute it and/or modify
369+# it under the terms of the GNU Affero General Public License as
370+# published by the Free Software Foundation, either version 3 of the
371+# License, or (at your option) any later version.
372+#
373+# This program is distributed in the hope that it will be useful,
374+# but WITHOUT ANY WARRANTY; without even the implied warranty of
375+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
376+# GNU Affero General Public License for more details.
377+#
378+# You should have received a copy of the GNU Affero General Public License
379+# along with this program. If not, see <http://www.gnu.org/licenses/>.
380 #
381 ##############################################################################
382-from datetime import *
383-
384-from osv import fields, osv
385-
386-
387-class hr_employee(osv.osv):
388+
389+from openerp.osv import fields, orm
390+from openerp.tools import DEFAULT_SERVER_DATE_FORMAT
391+
392+
393+class hr_employee(orm.Model):
394 _inherit = 'hr.employee'
395+
396 _columns = {
397- 'receive_timesheet_alerts': fields.boolean('Receive Timesheet Alerts'),
398+ 'receive_timesheet_alerts': fields.boolean('Receive Timesheet Alerts'),
399 }
400
401 _defaults = {
402- 'receive_timesheet_alerts': lambda *a: True,
403+ 'receive_timesheet_alerts': True,
404 }
405
406 def compute_timesheet_status(self, cr, uid, ids, period, context):
407@@ -50,35 +41,33 @@
408 status = 'Error'
409
410 if isinstance(ids, list):
411+ assert len(ids) == 1, "Only 1 ID expected"
412 ids = ids[0]
413
414 employee = self.browse(cr, uid, ids, context=context)
415
416- time_from = period[0]
417- time_to = period[1]
418-
419- # does the timesheet exsists in db and what is its status?
420- timeformat = "%Y-%m-%d"
421- str_date_from = time_from.strftime(timeformat)
422- str_date_to = time_to.strftime(timeformat)
423-
424- cr.execute("""SELECT state, date_from, date_to
425- FROM hr_timesheet_sheet_sheet
426- WHERE employee_id = %s
427- AND date_from >= %s
428- AND date_to <= %s""",
429+ time_from, time_to = period
430+
431+ # does the timesheet exists in db and what is its status?
432+ str_date_from = time_from.strftime(DEFAULT_SERVER_DATE_FORMAT)
433+ str_date_to = time_to.strftime(DEFAULT_SERVER_DATE_FORMAT)
434+
435+ cr.execute(
436+ """SELECT state, date_from, date_to
437+ FROM hr_timesheet_sheet_sheet
438+ WHERE employee_id = %s
439+ AND date_from >= %s
440+ AND date_to <= %s""",
441 (employee.id, str_date_from, str_date_to))
442 sheets = cr.dictfetchall()
443
444- #the timesheet does not exists in db
445+ # the timesheet does not exists in db
446 if not sheets:
447 status = 'Missing'
448
449- if len(sheets) > 0:
450+ else:
451 status = 'Confirmed'
452- for s in sheets:
453- if s['state'] == 'draft':
454+ for sheet in sheets:
455+ if sheet['state'] == 'draft':
456 status = 'Draft'
457 return status
458-
459-hr_employee()
460
461=== modified file 'hr_timesheet_reminder/hr_employee_view.xml'
462--- hr_timesheet_reminder/hr_employee_view.xml 2011-08-12 12:53:16 +0000
463+++ hr_timesheet_reminder/hr_employee_view.xml 2012-12-13 17:06:20 +0000
464@@ -5,7 +5,6 @@
465 <field name="name">hr.timesheet.employee.rmnd_form</field>
466 <field name="inherit_id" ref="hr_timesheet.hr_timesheet_employee_extd_form"/>
467 <field name="model">hr.employee</field>
468- <field name="type">form</field>
469 <field name="arch" type="xml">
470 <field name="journal_id" widget="selection" position="after">
471 <field name="receive_timesheet_alerts"/>
472
473=== modified file 'hr_timesheet_reminder/reminder.py'
474--- hr_timesheet_reminder/reminder.py 2011-09-01 13:44:19 +0000
475+++ hr_timesheet_reminder/reminder.py 2012-12-13 17:06:20 +0000
476@@ -1,157 +1,170 @@
477 # -*- coding: utf-8 -*-
478 ##############################################################################
479 #
480-# Copyright (c) 2011 Camptocamp SA (http://www.camptocamp.com)
481-# All Right Reserved
482-#
483-# Author : Arnaud Wüst (Camptocamp)
484-# Author : Guewen Baconnier (Camptocamp)
485-#
486-# WARNING: This program as such is intended to be used by professional
487-# programmers who take the whole responsability of assessing all potential
488-# consequences resulting from its eventual inadequacies and bugs
489-# End users who are looking for a ready-to-use solution with commercial
490-# garantees and support are strongly adviced to contract a Free Software
491-# Service Company
492-#
493-# This program is Free Software; you can redistribute it and/or
494-# modify it under the terms of the GNU General Public License
495-# as published by the Free Software Foundation; either version 2
496-# of the License, or (at your option) any later version.
497-#
498-# This program is distributed in the hope that it will be useful,
499-# but WITHOUT ANY WARRANTY; without even the implied warranty of
500-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
501-# GNU General Public License for more details.
502-#
503-# You should have received a copy of the GNU General Public License
504-# along with this program; if not, write to the Free Software
505-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
506+# Author: Arnaud Wüst (Camptocamp)
507+# Author: Guewen Baconnier (Camptocamp) (port to v7)
508+# Copyright 2011-2012 Camptocamp SA
509+#
510+# This program is free software: you can redistribute it and/or modify
511+# it under the terms of the GNU Affero General Public License as
512+# published by the Free Software Foundation, either version 3 of the
513+# License, or (at your option) any later version.
514+#
515+# This program is distributed in the hope that it will be useful,
516+# but WITHOUT ANY WARRANTY; without even the implied warranty of
517+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
518+# GNU Affero General Public License for more details.
519+#
520+# You should have received a copy of the GNU Affero General Public License
521+# along with this program. If not, see <http://www.gnu.org/licenses/>.
522 #
523 ##############################################################################
524
525-import tools
526-import time
527-
528 from datetime import datetime, timedelta
529-from osv import fields, osv
530-from tools.translate import _
531-
532-class reminder(osv.osv):
533+from openerp.osv import fields, orm
534+from openerp.tools.translate import _
535+from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT
536+
537+
538+class reminder(orm.Model):
539 _name = "hr.timesheet.reminder"
540 _description = "Handle the scheduling of timesheet reminders"
541
542 _columns = {
543- 'reply_to': fields.char('Reply To', size=100),
544- 'message': fields.text('Message'),
545- 'subject': fields.char('Subject', size=200),
546+ 'reply_to': fields.char('Reply To'),
547+ 'message': fields.html('Message'),
548+ 'subject': fields.char('Subject'),
549 }
550
551- #default cron (the one created if missing)
552+ # default cron (the one created if missing)
553 cron = {'active': False,
554 'priority': 1,
555 'interval_number': 1,
556 'interval_type': 'weeks',
557- 'nextcall': time.strftime("%Y-%m-%d %H:%M:%S",
558- (datetime.today()
559- + timedelta(days=1)).timetuple()), # tomorrow same time
560+ 'nextcall': False, # to set on the creation of the cron
561 'numbercall': -1,
562- 'doall': True,
563+ 'doall': False,
564 'model': 'hr.timesheet.reminder',
565 'function': 'run',
566 'args': '()',
567 }
568
569- #default message (the one created if missing)
570+ # default message (the one created if missing)
571 message = {'reply_to': 'spam@camptocamp.com'}
572
573 def run(self, cr, uid, context=None):
574 """ find the reminder recipients and send them an email """
575- context = context or {}
576-
577 company_obj = self.pool.get('res.company')
578- #get all companies
579+ # get all companies
580 company_ids = company_obj.search(cr, uid, [], context=context)
581
582- #for each company, get all recipients
583+ # for each company, get all recipients
584 recipients = []
585- company_recipients = company_obj.get_reminder_recipients(cr, uid, company_ids, context=context)
586- for company_id, rec in company_recipients.iteritems():
587+ company_recipients = company_obj.get_reminder_recipients(
588+ cr, uid, company_ids, context=context)
589+ for rec in company_recipients.itervalues():
590 recipients += rec
591
592- #get the message to send
593+ # get the message to send
594 message_id = self.get_message_id(cr, uid, context)
595 message_data = self.browse(cr, uid, message_id, context=context)
596
597- #send them email if they have an email defined
598- emails = []
599+ # send them email if they have an email defined
600 for employee in recipients:
601- if employee.work_email:
602- emails.append(employee.work_email)
603-
604- if emails:
605- tools.email_send(message_data.reply_to, [], message_data.subject, message_data.message, email_bcc=emails)
606-
607- def get_cron_id(self, cr, uid, context):
608+ if not employee.work_email:
609+ continue
610+ vals = {
611+ 'state': 'outgoing',
612+ 'subject': message_data.subject,
613+ 'body_html': message_data.message,
614+ 'email_to': employee.work_email,
615+ 'email_from': message_data.reply_to,
616+ }
617+ self.pool.get('mail.mail').create(cr, uid, vals, context=context)
618+
619+ return True
620+
621+ def get_cron_id(self, cr, uid, context=None):
622 """return the reminder cron's id. Create one if the cron does not exists """
623+ if context is None:
624+ context = {}
625 cron_obj = self.pool.get('ir.cron')
626 # find the cron that send messages
627- cron_id = cron_obj.search(cr, uid, [('function', 'ilike', self.cron['function']),
628- ('model', 'ilike', self.cron['model'])],
629- context={'active_test': False})
630- if cron_id:
631- cron_id = cron_id[0]
632+ ctx = dict(context, active_test=False)
633+ cron_ids = cron_obj.search(
634+ cr, uid,
635+ [('function', 'ilike', self.cron['function']),
636+ ('model', 'ilike', self.cron['model'])],
637+ context=ctx)
638+
639+ cron_id = None
640+ if cron_ids:
641+ cron_id = cron_ids[0]
642
643 # the cron does not exists
644- if not cron_id:
645- self.cron['name'] = _('timesheet status reminder')
646- cron_id = cron_obj.create(cr, uid, self.cron, context)
647+ if cron_id is None:
648+ vals = dict(self.cron,
649+ name=_('timesheet status reminder'),
650+ nextcall=self._cron_nextcall())
651+
652+ cron_id = cron_obj.create(cr, uid, vals, context=context)
653
654 return cron_id
655
656- def get_message_id(self, cr, uid, context):
657- """ return the message'id. create one if the message does not exists """
658+ @staticmethod
659+ def _cron_nextcall():
660+ tomorrow = datetime.today() + timedelta(days=1)
661+ return tomorrow.strftime(DEFAULT_SERVER_DATETIME_FORMAT)
662+
663+ def get_message_id(self, cr, uid, context=None):
664+ """ return the message's id. create one if the message does not exists """
665 #there is only one line in db, let's get it
666- message_id = self.search(cr, uid, [], limit=1, context=context)
667+ message_ids = self.search(cr, uid, [], limit=1, context=context)
668
669- if message_id:
670- message_id = message_id[0]
671+ message_id = None
672+ if message_ids:
673+ message_id = message_ids[0]
674
675 #the message does not exists
676- if not message_id:
677- #translate
678- self.message['subject'] = _('Timesheet Reminder')
679- self.message['message'] = _('At least one of your last timesheets is still in draft or is missing. Please take time to complete and confirm it.')
680+ if message_id is None:
681+ vals = dict(self.message,
682+ subject=_('Timesheet Reminder'),
683+ message=_(
684+ 'At least one of your last timesheets is still '
685+ 'in draft or is missing. Please take time to '
686+ 'complete and confirm it.'))
687
688- message_id = self.create(cr, uid, self.message, context)
689+ message_id = self.create(cr, uid, vals, context)
690
691 return message_id
692
693- def get_config(self, cr, uid, context):
694+ def get_config(self, cr, uid, context=None):
695 """return the reminder config from the db """
696
697 cron_id = self.get_cron_id(cr, uid, context)
698
699- cron_data = self.pool.get('ir.cron').browse(cr, uid, cron_id)
700+ cron_data = self.pool.get('ir.cron').browse(
701+ cr, uid, cron_id, context=context)
702
703- #there is only one line in db, let's get it
704- message_id = self.get_message_id(cr, uid, context)
705- message_data = self.browse(cr, uid, message_id)
706+ # there is only one line in db, let's get it
707+ message_id = self.get_message_id(cr, uid, context=context)
708+ message_data = self.browse(cr, uid, message_id, context=context)
709 return {'reminder_active': cron_data.active,
710 'interval_type': cron_data.interval_type,
711 'interval_number': cron_data.interval_number,
712 'reply_to': message_data.reply_to,
713 'message': message_data.message,
714 'subject': message_data.subject,
715- 'nextcall': cron_data.nextcall,
716+ 'nextcall': self._cron_nextcall(),
717 }
718
719- def save_config(self, cr, uid, ids, datas, context):
720+ def save_config(self, cr, uid, ids, datas, context=None):
721 """save the reminder config """
722
723 #modify the cron
724- cron_id = self.get_cron_id(cr, uid, context)
725- self.pool.get('ir.cron').write(cr, uid, [cron_id],
726+ cron_id = self.get_cron_id(cr, uid, context=context)
727+ self.pool.get('ir.cron').write(
728+ cr, uid, [cron_id],
729 {'active': datas['reminder_active'],
730 'interval_number': datas['interval_number'],
731 'interval_type': datas['interval_type'],
732@@ -159,11 +172,10 @@
733 context=context)
734 #modify the message
735 message_id = ids or self.get_message_id(cr, uid, context)
736- self.write(cr, uid, [message_id],
737+ self.write(
738+ cr, uid, [message_id],
739 {'reply_to': datas['reply_to'],
740 'message': datas['message'],
741 'subject': datas['subject'],
742 }, context=context)
743 return True
744-
745-reminder()
746
747=== modified file 'hr_timesheet_reminder/report/__init__.py'
748--- hr_timesheet_reminder/report/__init__.py 2011-08-12 12:53:16 +0000
749+++ hr_timesheet_reminder/report/__init__.py 2012-12-13 17:06:20 +0000
750@@ -1,31 +1,22 @@
751 # -*- coding: utf-8 -*-
752 ##############################################################################
753 #
754-# Copyright (c) Camptocamp SA
755-# Author: Arnaud WÃŒst
756-#
757-#
758-#
759-# WARNING: This program as such is intended to be used by professional
760-# programmers who take the whole responsability of assessing all potential
761-# consequences resulting from its eventual inadequacies and bugs
762-# End users who are looking for a ready-to-use solution with commercial
763-# garantees and support are strongly adviced to contract a Free Software
764-# Service Company
765-#
766-# This program is Free Software; you can redistribute it and/or
767-# modify it under the terms of the GNU General Public License
768-# as published by the Free Software Foundation; either version 2
769-# of the License, or (at your option) any later version.
770-#
771-# This program is distributed in the hope that it will be useful,
772-# but WITHOUT ANY WARRANTY; without even the implied warranty of
773-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
774-# GNU General Public License for more details.
775-#
776-# You should have received a copy of the GNU General Public License
777-# along with this program; if not, write to the Free Software
778-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
779+# Author: Arnaud Wüst (Camptocamp)
780+# Copyright 2011-2012 Camptocamp SA
781+#
782+# This program is free software: you can redistribute it and/or modify
783+# it under the terms of the GNU Affero General Public License as
784+# published by the Free Software Foundation, either version 3 of the
785+# License, or (at your option) any later version.
786+#
787+# This program is distributed in the hope that it will be useful,
788+# but WITHOUT ANY WARRANTY; without even the implied warranty of
789+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
790+# GNU Affero General Public License for more details.
791+#
792+# You should have received a copy of the GNU Affero General Public License
793+# along with this program. If not, see <http://www.gnu.org/licenses/>.
794 #
795 ##############################################################################
796+
797 import timesheet_status
798
799=== modified file 'hr_timesheet_reminder/report/timesheet_status.py'
800--- hr_timesheet_reminder/report/timesheet_status.py 2011-09-01 13:44:19 +0000
801+++ hr_timesheet_reminder/report/timesheet_status.py 2012-12-13 17:06:20 +0000
802@@ -1,47 +1,40 @@
803 # -*- coding: utf-8 -*-
804 ##############################################################################
805 #
806-# Copyright (c) Camptocamp SA
807-# Author: Arnaud WÃŒst
808-# Author: Guewen Baconnier
809-#
810-#
811-#
812-# WARNING: This program as such is intended to be used by professional
813-# programmers who take the whole responsability of assessing all potential
814-# consequences resulting from its eventual inadequacies and bugs
815-# End users who are looking for a ready-to-use solution with commercial
816-# garantees and support are strongly adviced to contract a Free Software
817-# Service Company
818-#
819-# This program is Free Software; you can redistribute it and/or
820-# modify it under the terms of the GNU General Public License
821-# as published by the Free Software Foundation; either version 2
822-# of the License, or (at your option) any later version.
823-#
824-# This program is distributed in the hope that it will be useful,
825-# but WITHOUT ANY WARRANTY; without even the implied warranty of
826-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
827-# GNU General Public License for more details.
828-#
829-# You should have received a copy of the GNU General Public License
830-# along with this program; if not, write to the Free Software
831-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
832+# Author: Arnaud Wüst (Camptocamp)
833+# Author: Guewen Baconnier (Camptocamp) (port to v7)
834+# Copyright 2011-2012 Camptocamp SA
835+#
836+# This program is free software: you can redistribute it and/or modify
837+# it under the terms of the GNU Affero General Public License as
838+# published by the Free Software Foundation, either version 3 of the
839+# License, or (at your option) any later version.
840+#
841+# This program is distributed in the hope that it will be useful,
842+# but WITHOUT ANY WARRANTY; without even the implied warranty of
843+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
844+# GNU Affero General Public License for more details.
845+#
846+# You should have received a copy of the GNU Affero General Public License
847+# along with this program. If not, see <http://www.gnu.org/licenses/>.
848 #
849 ##############################################################################
850
851 import time
852
853 from datetime import datetime
854-from report import report_sxw
855+from openerp.report import report_sxw
856+from openerp.tools import DEFAULT_SERVER_DATE_FORMAT
857+from openerp.tools.translate import _
858
859
860 class timesheet_status(report_sxw.rml_parse):
861 _name = 'report.timesheet.reminder.status'
862
863- def __init__(self, cr, uid, name, context):
864- super(timesheet_status, self).__init__(cr, uid, name, context)
865+ def __init__(self, cr, uid, name, context=None):
866+ super(timesheet_status, self).__init__(cr, uid, name, context=context)
867 self.data = {}
868+ self.end_date = None
869 self.localcontext.update({
870 'compute': self.compute,
871 'time': time,
872@@ -60,64 +53,65 @@
873 """compute all datas and do all the calculations before to start the rml rendering
874 - objects are companies
875 """
876- #init the data array
877+ # init the data array
878 self.data = {}
879 for o in objects:
880 self.data[o.id] = {}
881- #get the list of employees ids to treat
882+ # get the list of employees ids to treat
883 for o in objects:
884 self.data[o.id]['employees'] = self._compute_employees_list(o)
885
886- #get the time range for each company
887+ # get the time range for each company
888+ end_date = datetime.strptime(self.end_date, DEFAULT_SERVER_DATE_FORMAT)
889 for o in objects:
890- self.data[o.id]['time_ranges'] = \
891- self._compute_periods(o, datetime.strptime(self.end_date, "%Y-%m-%d"))
892+ self.data[o.id]['time_ranges'] = self._compute_periods(o, end_date)
893
894- #get the status of each timesheet for each employee
895+ # get the status of each timesheet for each employee
896 for o in objects:
897 self.data[o.id]['sheet_status'] = self._compute_all_status(o)
898
899 def _compute_employees_list(self, company):
900- """ return a dictionnary of lists of employees ids linked to the companies (param company) """
901+ """ return a dictionnary of lists of employees ids linked
902+ to the companies (param company) """
903 employee_obj = self.pool.get('hr.employee')
904 employee_ids = employee_obj.search(self.cr, self.uid,
905 [('company_id', '=', company.id),
906 ('active', '=', True)],
907 context=self.localcontext)
908- return employee_obj.browse(self.cr, self.uid, employee_ids, context=self.localcontext)
909+ return employee_obj.browse(
910+ self.cr, self.uid, employee_ids, context=self.localcontext)
911
912 def _get_last_period_dates(self, company, date):
913 """ return the start date of the last period to display """
914- return self.pool.get('res.company').\
915- get_last_period_dates(self.cr, self.uid, company, date, context=self.localcontext)
916+ return self.pool.get('res.company').get_last_period_dates(
917+ self.cr,
918+ self.uid,
919+ company,
920+ date,
921+ context=self.localcontext)
922
923 def _compute_periods(self, company, date):
924 """ return the timeranges to display. This is the 5 last timesheets """
925- return self.pool.get('res.company').\
926- compute_timesheet_periods(self.cr, self.uid, company, date, context=self.localcontext)
927+ return self.pool.get('res.company').compute_timesheet_periods(
928+ self.cr,
929+ self.uid,
930+ company,
931+ date,
932+ context=self.localcontext)
933
934 def get_title(self, obj):
935 """ return the title of the main table """
936- last_id = len(self.data[obj.id]['time_ranges']) - 1
937- start_date = time.strptime(str(self.data[obj.id]['time_ranges'][last_id][0]),
938- "%Y-%m-%d %H:%M:%S")
939- start_date = time.strftime("%d.%m.%Y", start_date)
940-
941- end_date = time.strptime(str(self.data[obj.id]['time_ranges'][0][1]),
942- "%Y-%m-%d %H:%M:%S")
943- end_date = time.strftime("%d.%m.%Y", end_date)
944-
945- return obj.name + ", " + start_date + " to " + end_date
946+ timerange = self.data[obj.id]['time_ranges']
947+ start_date = self.formatLang(timerange[-1][0], date=True)
948+ end_date = self.formatLang(timerange[0][1], date=True)
949+
950+ return obj.name + ", " + start_date + _(" to ") + end_date
951
952 def get_timerange_title(self, obj, cpt):
953 """ return a header text for a periods column """
954- start_date = self.data[obj.id]['time_ranges'][cpt][0]
955- start_date = time.strptime(str(start_date), "%Y-%m-%d %H:%M:%S")
956- start_date = time.strftime("%d.%m.%Y", start_date)
957-
958- end_date = self.data[obj.id]['time_ranges'][cpt][1]
959- end_date = time.strptime(str(end_date), "%Y-%m-%d %H:%M:%S")
960- end_date = time.strftime("%d.%m.%Y", end_date)
961+ timerange = self.data[obj.id]['time_ranges'][cpt]
962+ start_date = self.formatLang(timerange[0], date=True)
963+ end_date = self.formatLang(timerange[1], date=True)
964
965 return start_date + "\n " + end_date
966
967@@ -131,21 +125,25 @@
968
969 def _compute_timesheet_status(self, employee_id, period):
970 """ return the timesheet status for a user and a period """
971- return self.pool.get('hr.employee').\
972- compute_timesheet_status(self.cr, self.uid, employee_id, period, context=self.localcontext)
973+ return self.pool.get('hr.employee').compute_timesheet_status(
974+ self.cr,
975+ self.uid,
976+ employee_id,
977+ period,
978+ context=self.localcontext)
979
980- def _compute_all_status(self, o):
981+ def _compute_all_status(self, obj):
982 """ compute all status for all employees for all periods """
983 result = {}
984
985 #for each periods
986- for p_index in range(len(self.data[o.id]['time_ranges'])):
987+ for p_index, period in enumerate(self.data[obj.id]['time_ranges']):
988 result[p_index] = {}
989- period = self.data[o.id]['time_ranges'][p_index]
990 #for each employees
991- for employee in self.data[o.id]['employees']:
992+ for employee in self.data[obj.id]['employees']:
993 #compute the status
994- result[p_index][employee.id] = self._compute_timesheet_status(employee.id, period)
995+ result[p_index][employee.id] = self._compute_timesheet_status(
996+ employee.id, period)
997
998 return result
999
1000
1001=== modified file 'hr_timesheet_reminder/report/timesheet_status.rml'
1002--- hr_timesheet_reminder/report/timesheet_status.rml 2011-08-12 12:53:16 +0000
1003+++ hr_timesheet_reminder/report/timesheet_status.rml 2012-12-13 17:06:20 +0000
1004@@ -1,165 +1,159 @@
1005 <?xml version="1.0"?>
1006 <document filename="timesheet_status.pdf">
1007-##############################################################################
1008-#
1009-# Copyright (c) Camptocamp SA
1010-# Author: Arnaud Wüst
1011-#
1012-#
1013-# WARNING: This program as such is intended to be used by professional
1014-# programmers who take the whole responsability of assessing all potential
1015-# consequences resulting from its eventual inadequacies and bugs
1016-# End users who are looking for a ready-to-use solution with commercial
1017-# garantees and support are strongly adviced to contract a Free Software
1018-# Service Company
1019-#
1020-# This program is Free Software; you can redistribute it and/or
1021-# modify it under the terms of the GNU General Public License
1022-# as published by the Free Software Foundation; either version 2
1023-# of the License, or (at your option) any later version.
1024-#
1025-# This program is distributed in the hope that it will be useful,
1026-# but WITHOUT ANY WARRANTY; without even the implied warranty of
1027-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1028-# GNU General Public License for more details.
1029-#
1030-# You should have received a copy of the GNU General Public License
1031-# along with this program; if not, write to the Free Software
1032-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
1033-#
1034-##############################################################################
1035-
1036- <!-- Process all datas -->
1037- <template pageSize="(21cm,29.7cm)" title="Timesheet Status" author="Camptocamp" allowSplitting="20">
1038-
1039-
1040- <!-- PAGE: template of all pages (= all pages except first and last if defined)-->
1041- <pageTemplate id="all">
1042- <pageGraphics>
1043- <setFont name="Helvetica-Bold" size="9"/>
1044-
1045- <!--Header-->
1046- <drawString x="1.2cm" y="28.1cm">[[ company.name ]]</drawString>
1047- <drawString x="17.0cm" y="28.1cm">Timesheet Status</drawString>
1048-
1049- <lineMode width="0.7"/>
1050- <lines>1.2cm 28.0cm 19.8cm 28.0cm</lines>
1051-
1052- <!-- Footer -->
1053- <setFont name="Helvetica" size="9"/>
1054- <drawString x="1.2cm" y="1.3cm"> [[ time.strftime("%m-%d-%y %H:%M", time.localtime()) ]]</drawString>
1055- <drawString x="18.8cm" y="1.3cm">Page <pageNumber/></drawString>
1056-
1057- </pageGraphics>
1058- <frame id="all" x1="1.2cm" y1="1.7cm" width="18.6cm" height="25.8cm"/>
1059- </pageTemplate>
1060-
1061- </template>
1062- <stylesheet>
1063-
1064- <!--TABLE: standard table type "columns" (which means there is a title, a header of fields names and then lines of values) -->
1065- <blockTableStyle id="std">
1066- <blockAlignment value="LEFT"/>
1067- <blockValign value="TOP"/>
1068- <blockBottomPadding length="4"/>
1069- <blockFont name="Helvetica" size="9" start="0,0" stop="-1,-1"/>
1070-
1071- <!-- first line: table name, fake as it was only one cell. grey bg -->
1072- <lineStyle kind="BOX" colorName="black" start="0,0" stop="-1,0"/>
1073- <blockBackground colorName="#cccccc" start="0,0" stop="-1,0"/>
1074- <blockFont name="Helvetica" size="9" start="0,0" stop="-1,0"/>
1075- <!-- second line: header of columns -->
1076- <lineStyle kind="GRID" colorName="black" start="0,1" stop="-1,1"/>
1077- <blockFont name="Helvetica-Oblique" start="0,1" stop="-1,1"/>
1078- <!-- next lines: light grey lines, strong black columns separator, reduce padding to write more data in cells -->
1079- <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="0,2" stop="-1,-1"/>
1080- <lineStyle kind="LINEAFTER" colorName="black" start="0,2" stop="-1,-1"/>
1081- <!-- last line: line below -->
1082- <lineStyle kind="OUTLINE" colorName="black" start="0,0" stop="-1,-1"/>
1083- <!-- all columns centered except the first two (1 system columns + employee) -->
1084- <blockAlignment value="CENTER" start="2,1" stop="-1,-1" />
1085-
1086- </blockTableStyle>
1087-
1088- <!-- default para in tables -->
1089- <paraStyle name="std"
1090- fontName="Helvetica"
1091- fontSize="9"
1092- alignment="LEFT"
1093- />
1094-
1095- <paraStyle name="Confirmed"
1096- fontName="Helvetica"
1097- fontSize="9"
1098- alignment="CENTER"
1099- backColor="green"
1100- textColor="white"
1101- />
1102-
1103- <paraStyle name="Missing"
1104- fontName="Helvetica"
1105- fontSize="9"
1106- alignment="CENTER"
1107- backColor="red"
1108- textColor="white"
1109- />
1110-
1111- <paraStyle name="Draft"
1112- fontName="Helvetica"
1113- fontSize="9"
1114- alignment="CENTER"
1115- backColor="orange"
1116- textColor="black"
1117- />
1118-
1119- <paraStyle name="Error"
1120- fontName="Helvetica"
1121- fontSize="9"
1122- alignment="CENTER"
1123- textColor="red"
1124- />
1125-
1126- <paraStyle name="Not in Company"
1127- fontName="Helvetica"
1128- fontSize="9"
1129- alignment="CENTER"
1130- textColor="lightgrey"
1131- />
1132-
1133-
1134- </stylesheet>
1135-
1136- <story>
1137-
1138- [[repeatIn(objects, 'o')]]
1139- <blockTable style="std" repeatRows="2" colWidths="0,5cm,2.7cm,2.7cm,2.7cm,2.7cm,2.7cm" >
1140-
1141- <tr>
1142- <td/>
1143- <td>[[get_title(o)]]</td>
1144- </tr>
1145-
1146- <tr>
1147- <td/>
1148- <td>Employees</td>
1149- <td>[[ get_timerange_title(o, 4) ]]</td>
1150- <td>[[ get_timerange_title(o, 3) ]]</td>
1151- <td>[[ get_timerange_title(o, 2) ]]</td>
1152- <td>[[ get_timerange_title(o, 1) ]]</td>
1153- <td>[[ get_timerange_title(o, 0) ]]</td>
1154- </tr>
1155-
1156- <tr>
1157- <td>[[repeatIn(get_user_list(o),'u')]]</td>
1158- <td><para style="std">[[ u.name ]]</para></td>
1159- <td><para>[[ setTag('para','para',{'style':get_timesheet_status(o, u, 4)}) ]][[ get_timesheet_status(o, u, 4) ]]</para></td>
1160- <td><para>[[ setTag('para','para',{'style':get_timesheet_status(o, u, 3)}) ]][[ get_timesheet_status(o, u, 3) ]]</para></td>
1161- <td><para>[[ setTag('para','para',{'style':get_timesheet_status(o, u, 2)}) ]][[ get_timesheet_status(o, u, 2) ]]</para></td>
1162- <td><para>[[ setTag('para','para',{'style':get_timesheet_status(o, u, 1)}) ]][[ get_timesheet_status(o, u, 1) ]]</para></td>
1163- <td><para>[[ setTag('para','para',{'style':get_timesheet_status(o, u, 0)}) ]][[ get_timesheet_status(o, u, 0) ]]</para></td>
1164- </tr>
1165-
1166- </blockTable>
1167-
1168- </story>
1169- </document>
1170+ <!--
1171+ ##############################################################################
1172+ #
1173+ # Author: Arnaud Wüst (Camptocamp)
1174+ # Copyright 2011-2012 Camptocamp SA
1175+ #
1176+ # This program is free software: you can redistribute it and/or modify
1177+ # it under the terms of the GNU Affero General Public License as
1178+ # published by the Free Software Foundation, either version 3 of the
1179+ # License, or (at your option) any later version.
1180+ #
1181+ # This program is distributed in the hope that it will be useful,
1182+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
1183+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1184+ # GNU Affero General Public License for more details.
1185+ #
1186+ # You should have received a copy of the GNU Affero General Public License
1187+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
1188+ #
1189+ ##############################################################################
1190+ -->
1191+
1192+
1193+ <!-- Process all datas -->
1194+ <template pageSize="(21cm,29.7cm)" title="Timesheet Status" author="Camptocamp" allowSplitting="20">
1195+
1196+
1197+ <!-- PAGE: template of all pages (= all pages except first and last if defined)-->
1198+ <pageTemplate id="all">
1199+ <pageGraphics>
1200+ <setFont name="Helvetica-Bold" size="9"/>
1201+
1202+ <!--Header-->
1203+ <drawString x="1.2cm" y="28.1cm">[[ company.name ]]</drawString>
1204+ <drawString x="17.0cm" y="28.1cm">Timesheet Status</drawString>
1205+
1206+ <lineMode width="0.7"/>
1207+ <lines>1.2cm 28.0cm 19.8cm 28.0cm</lines>
1208+
1209+ <!-- Footer -->
1210+ <setFont name="Helvetica" size="9"/>
1211+ <drawString x="1.2cm" y="1.3cm"> [[ time.strftime("%m-%d-%y %H:%M", time.localtime()) ]]</drawString>
1212+ <drawString x="18.8cm" y="1.3cm">Page <pageNumber/></drawString>
1213+
1214+ </pageGraphics>
1215+ <frame id="all" x1="1.2cm" y1="1.7cm" width="18.6cm" height="25.8cm"/>
1216+ </pageTemplate>
1217+
1218+ </template>
1219+ <stylesheet>
1220+
1221+ <!--TABLE: standard table type "columns" (which means there is a title, a header of fields names and then lines of values) -->
1222+ <blockTableStyle id="std">
1223+ <blockAlignment value="LEFT"/>
1224+ <blockValign value="TOP"/>
1225+ <blockBottomPadding length="4"/>
1226+ <blockFont name="Helvetica" size="9" start="0,0" stop="-1,-1"/>
1227+
1228+ <!-- first line: table name, fake as it was only one cell. grey bg -->
1229+ <lineStyle kind="BOX" colorName="black" start="0,0" stop="-1,0"/>
1230+ <blockBackground colorName="#cccccc" start="0,0" stop="-1,0"/>
1231+ <blockFont name="Helvetica" size="9" start="0,0" stop="-1,0"/>
1232+ <!-- second line: header of columns -->
1233+ <lineStyle kind="GRID" colorName="black" start="0,1" stop="-1,1"/>
1234+ <blockFont name="Helvetica-Oblique" start="0,1" stop="-1,1"/>
1235+ <!-- next lines: light grey lines, strong black columns separator, reduce padding to write more data in cells -->
1236+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="0,2" stop="-1,-1"/>
1237+ <lineStyle kind="LINEAFTER" colorName="black" start="0,2" stop="-1,-1"/>
1238+ <!-- last line: line below -->
1239+ <lineStyle kind="OUTLINE" colorName="black" start="0,0" stop="-1,-1"/>
1240+ <!-- all columns centered except the first two (1 system columns + employee) -->
1241+ <blockAlignment value="CENTER" start="2,1" stop="-1,-1" />
1242+
1243+ </blockTableStyle>
1244+
1245+ <!-- default para in tables -->
1246+ <paraStyle name="std"
1247+ fontName="Helvetica"
1248+ fontSize="9"
1249+ alignment="LEFT"
1250+ />
1251+
1252+ <paraStyle name="Confirmed"
1253+ fontName="Helvetica"
1254+ fontSize="9"
1255+ alignment="CENTER"
1256+ backColor="green"
1257+ textColor="white"
1258+ />
1259+
1260+ <paraStyle name="Missing"
1261+ fontName="Helvetica"
1262+ fontSize="9"
1263+ alignment="CENTER"
1264+ backColor="red"
1265+ textColor="white"
1266+ />
1267+
1268+ <paraStyle name="Draft"
1269+ fontName="Helvetica"
1270+ fontSize="9"
1271+ alignment="CENTER"
1272+ backColor="orange"
1273+ textColor="black"
1274+ />
1275+
1276+ <paraStyle name="Error"
1277+ fontName="Helvetica"
1278+ fontSize="9"
1279+ alignment="CENTER"
1280+ textColor="red"
1281+ />
1282+
1283+ <paraStyle name="Not in Company"
1284+ fontName="Helvetica"
1285+ fontSize="9"
1286+ alignment="CENTER"
1287+ textColor="lightgrey"
1288+ />
1289+
1290+
1291+ </stylesheet>
1292+
1293+ <story>
1294+
1295+ [[repeatIn(objects, 'o')]]
1296+ <blockTable style="std" repeatRows="2" colWidths="0,5cm,2.7cm,2.7cm,2.7cm,2.7cm,2.7cm" >
1297+
1298+ <tr>
1299+ <td/>
1300+ <td>[[get_title(o)]]</td>
1301+ </tr>
1302+
1303+ <tr>
1304+ <td/>
1305+ <td>Employees</td>
1306+ <td>[[ get_timerange_title(o, 4) ]]</td>
1307+ <td>[[ get_timerange_title(o, 3) ]]</td>
1308+ <td>[[ get_timerange_title(o, 2) ]]</td>
1309+ <td>[[ get_timerange_title(o, 1) ]]</td>
1310+ <td>[[ get_timerange_title(o, 0) ]]</td>
1311+ </tr>
1312+
1313+ <tr>
1314+ <td>[[repeatIn(get_user_list(o),'u')]]</td>
1315+ <td><para style="std">[[ u.name ]]</para></td>
1316+ <td><para>[[ setTag('para', 'para', {'style': get_timesheet_status(o, u, 4)}) ]][[ get_timesheet_status(o, u, 4) ]]</para></td>
1317+ <td><para>[[ setTag('para', 'para', {'style': get_timesheet_status(o, u, 3)}) ]][[ get_timesheet_status(o, u, 3) ]]</para></td>
1318+ <td><para>[[ setTag('para', 'para', {'style': get_timesheet_status(o, u, 2)}) ]][[ get_timesheet_status(o, u, 2) ]]</para></td>
1319+ <td><para>[[ setTag('para', 'para', {'style': get_timesheet_status(o, u, 1)}) ]][[ get_timesheet_status(o, u, 1) ]]</para></td>
1320+ <td><para>[[ setTag('para', 'para', {'style': get_timesheet_status(o, u, 0)}) ]][[ get_timesheet_status(o, u, 0) ]]</para></td>
1321+ </tr>
1322+
1323+ </blockTable>
1324+
1325+ </story>
1326+</document>
1327
1328=== modified file 'hr_timesheet_reminder/timesheet_report.xml'
1329--- hr_timesheet_reminder/timesheet_report.xml 2011-08-12 12:53:16 +0000
1330+++ hr_timesheet_reminder/timesheet_report.xml 2012-12-13 17:06:20 +0000
1331@@ -1,15 +1,15 @@
1332 <?xml version="1.0"?>
1333 <openerp>
1334- <data>
1335- <report
1336- id="timesheet_status"
1337- string="Timesheet Status"
1338- model="res.company"
1339- name="timesheet.reminder.status"
1340- rml="hr_timesheet_reminder/report/timesheet_status.rml"
1341- auto="False"
1342+ <data>
1343+ <report
1344+ id="timesheet_status"
1345+ string="Timesheet Status"
1346+ model="res.company"
1347+ name="timesheet.reminder.status"
1348+ rml="hr_timesheet_reminder/report/timesheet_status.rml"
1349+ auto="False"
1350 header="True"
1351 menu="False"/>
1352-
1353- </data>
1354+
1355+ </data>
1356 </openerp>
1357
1358=== modified file 'hr_timesheet_reminder/wizard/reminder_config.py'
1359--- hr_timesheet_reminder/wizard/reminder_config.py 2011-08-12 12:53:16 +0000
1360+++ hr_timesheet_reminder/wizard/reminder_config.py 2012-12-13 17:06:20 +0000
1361@@ -1,53 +1,48 @@
1362 # -*- coding: utf-8 -*-
1363 ##############################################################################
1364 #
1365-# Copyright (c) 2011 Camptocamp SA (http://www.camptocamp.com)
1366-# All Right Reserved
1367-#
1368-# Author : Guewen Baconnier (Camptocamp)
1369-# Author : Arnaud Wüst (Camptocamp)
1370-#
1371-# WARNING: This program as such is intended to be used by professional
1372-# programmers who take the whole responsability of assessing all potential
1373-# consequences resulting from its eventual inadequacies and bugs
1374-# End users who are looking for a ready-to-use solution with commercial
1375-# garantees and support are strongly adviced to contract a Free Software
1376-# Service Company
1377-#
1378-# This program is Free Software; you can redistribute it and/or
1379-# modify it under the terms of the GNU General Public License
1380-# as published by the Free Software Foundation; either version 2
1381-# of the License, or (at your option) any later version.
1382-#
1383-# This program is distributed in the hope that it will be useful,
1384-# but WITHOUT ANY WARRANTY; without even the implied warranty of
1385-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1386-# GNU General Public License for more details.
1387-#
1388-# You should have received a copy of the GNU General Public License
1389-# along with this program; if not, write to the Free Software
1390-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
1391+# Author: Arnaud Wüst (Camptocamp)
1392+# Author: Guewen Baconnier (Camptocamp) (port to v7)
1393+# Copyright 2011-2012 Camptocamp SA
1394+#
1395+# This program is free software: you can redistribute it and/or modify
1396+# it under the terms of the GNU Affero General Public License as
1397+# published by the Free Software Foundation, either version 3 of the
1398+# License, or (at your option) any later version.
1399+#
1400+# This program is distributed in the hope that it will be useful,
1401+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1402+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1403+# GNU Affero General Public License for more details.
1404+#
1405+# You should have received a copy of the GNU Affero General Public License
1406+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1407 #
1408 ##############################################################################
1409
1410-from osv import osv, fields
1411-
1412-
1413-class reminder_config(osv.osv_memory):
1414+from openerp.osv import orm, fields
1415+
1416+
1417+class reminder_config(orm.TransientModel):
1418 _name = 'hr.timesheet.reminder.config'
1419
1420 _columns = {
1421 'reminder_active': fields.boolean('Reminder Active'),
1422- 'interval_type': fields.selection([('days','Day(s)'), ('weeks', 'Week(s)'), ('months', 'Month(s)')],
1423- 'Periodicity Unit',),
1424- 'interval_number': fields.integer('Periodicity Quantity',),
1425- 'nextcall': fields.datetime('Next Run',),
1426- 'message': fields.text('Message', required=True),
1427- 'subject': fields.char('Subject', size=200, required=True),
1428- 'reply_to': fields.char('Reply To', size=100, required=True),
1429+ 'interval_type': fields.selection(
1430+ [('days', 'Day(s)'),
1431+ ('weeks', 'Week(s)'),
1432+ ('months', 'Month(s)')],
1433+ 'Periodicity Unit'),
1434+ 'interval_number': fields.integer('Periodicity Quantity'),
1435+ 'nextcall': fields.datetime('Next Run'),
1436+ 'message': fields.html('Message', required=True),
1437+ 'subject': fields.char('Subject', required=True),
1438+ 'reply_to': fields.char('Reply To', required=True),
1439 }
1440
1441 def _check_interval_number(self, cr, uid, ids, context=None):
1442+ """This constraint should always have 1 id, we are in a TransientModel"""
1443+ assert len(ids) == 1, "Only 1 ID expected"
1444 obj = self.browse(cr, uid, ids[0], context=context)
1445 if obj.interval_number < 1:
1446 return False
1447@@ -60,23 +55,22 @@
1448 def default_get(self, cr, uid, fields, context=None):
1449 res = super(reminder_config, self).default_get(cr, uid, fields, context=context)
1450 data = self.pool.get('hr.timesheet.reminder').\
1451- get_config(cr, uid, context)
1452+ get_config(cr, uid, context=context)
1453 res.update(data)
1454 return res
1455
1456- def run(self, cr, uid, ids, context):
1457+ def run(self, cr, uid, ids, context=None):
1458 """ execute the timesheets check and send emails """
1459 reminder_obj = self.pool.get('hr.timesheet.reminder')
1460 reminder_obj.run(cr, uid, context=context)
1461 return {'type': 'ir.actions.act_window_close'}
1462
1463- def save(self, cr, uid, ids, context):
1464+ def save(self, cr, uid, ids, context=None):
1465 """ save defined settings in db """
1466-
1467 # get the wizard datas
1468- wizard = self.browse(cr, uid, ids, context=context)[0]
1469+ wizard = self.browse(cr, uid, ids[0], context=context)
1470
1471- #retrieve the default cron values
1472+ # retrieve the default cron values
1473 reminder_obj = self.pool.get('hr.timesheet.reminder')
1474
1475 values = {}.fromkeys(wizard._columns.keys(), False)
1476@@ -85,5 +79,3 @@
1477
1478 reminder_obj.save_config(cr, uid, False, values, context=context)
1479 return {'type': 'ir.actions.act_window_close'}
1480-
1481-reminder_config()
1482
1483=== modified file 'hr_timesheet_reminder/wizard/reminder_config_view.xml'
1484--- hr_timesheet_reminder/wizard/reminder_config_view.xml 2011-08-12 12:53:16 +0000
1485+++ hr_timesheet_reminder/wizard/reminder_config_view.xml 2012-12-13 17:06:20 +0000
1486@@ -5,29 +5,39 @@
1487 <record id="view_hr_timesheet_reminder_config_form" model="ir.ui.view">
1488 <field name="name">hr.timesheet.reminder.config.form</field>
1489 <field name="model">hr.timesheet.reminder.config</field>
1490- <field name="type">form</field>
1491 <field name="arch" type="xml">
1492- <form string="Timesheet Reminder">
1493- <group colspan="4" col="4" string="Periodicity" >
1494- <field name="reminder_active" />
1495- <newline/>
1496- <field name="nextcall" attrs="{'required':[('reminder_active','==',True)]}"/>
1497- <newline/>
1498- <field name="interval_number" string="Then send message every" attrs="{'required':[('reminder_active','==',True)]}"/>
1499- <field name="interval_type" nolabel="1" attrs="{'required':[('reminder_active','==',True)]}"/>
1500- </group>
1501-
1502- <group colspan="4" col="2" string="Message">
1503- <field name="reply_to"/>
1504- <field name="subject"/>
1505- <field name="message" height="200"/>
1506- </group>
1507-
1508- <group colspan="4" col="6">
1509- <button icon="gtk-cancel" special="cancel" string="Cancel"/>
1510- <button icon="gtk-ok" string="Save configuration" name="save" type="object"/>
1511- <button icon="gtk-ok" string="Run now" name="run" type="object"/>
1512- </group>
1513+ <form string="Timesheet Reminder" version="7.0">
1514+ <sheet>
1515+ <group>
1516+ <separator string="Periodicity" colspan="4"/>
1517+ <field name="reminder_active" />
1518+ <newline/>
1519+ <field name="nextcall" attrs="{'required':[('reminder_active','==',True)]}"/>
1520+ <newline/>
1521+ <label for="interval_number" string="Then send message every"/>
1522+ <div>
1523+ <field name="interval_number" class="oe_inline"
1524+ attrs="{'required':[('reminder_active','==',True)]}"/>
1525+ <field name="interval_type" nolabel="1" class="oe_inline"
1526+ attrs="{'required':[('reminder_active','==',True)]}"/>
1527+ </div>
1528+ </group>
1529+
1530+ <group col="2">
1531+ <separator string="Message" colspan="4"/>
1532+ <field name="reply_to"/>
1533+ <field name="subject"/>
1534+ <field name="message" height="200"/>
1535+ </group>
1536+ </sheet>
1537+
1538+ <footer>
1539+ <button name="save" string="Save configuration" colspan="1"
1540+ type="object" class="oe_highlight"/> or
1541+ <button name="run" string="Run now" colspan="1"
1542+ type="object" class="oe_highlight"/> or
1543+ <button special="cancel" string="Cancel" class="oe_link"/>
1544+ </footer>
1545 </form>
1546 </field>
1547 </record>
1548@@ -42,11 +52,11 @@
1549 </record>
1550
1551 <menuitem id="menu_hr_timesheet_reminder_config"
1552- icon="STOCK_PRINT"
1553- action="action_hr_timesheet_reminder_config"
1554- parent="hr.menu_hr_configuration"
1555- name="Timesheet Reminder"
1556- groups="base.group_hr_manager"/>
1557+ icon="STOCK_PRINT"
1558+ action="action_hr_timesheet_reminder_config"
1559+ parent="hr.menu_hr_configuration"
1560+ name="Timesheet Reminder"
1561+ groups="base.group_hr_manager"/>
1562
1563-</data>
1564+ </data>
1565 </openerp>
1566
1567=== modified file 'hr_timesheet_reminder/wizard/reminder_status.py'
1568--- hr_timesheet_reminder/wizard/reminder_status.py 2011-11-07 13:58:29 +0000
1569+++ hr_timesheet_reminder/wizard/reminder_status.py 2012-12-13 17:06:20 +0000
1570@@ -1,67 +1,58 @@
1571 # -*- coding: utf-8 -*-
1572 ##############################################################################
1573 #
1574-# Copyright (c) 2011 Camptocamp SA (http://www.camptocamp.com)
1575-# All Right Reserved
1576-#
1577-# Author : Guewen Baconnier (Camptocamp)
1578-#
1579-# WARNING: This program as such is intended to be used by professional
1580-# programmers who take the whole responsability of assessing all potential
1581-# consequences resulting from its eventual inadequacies and bugs
1582-# End users who are looking for a ready-to-use solution with commercial
1583-# garantees and support are strongly adviced to contract a Free Software
1584-# Service Company
1585-#
1586-# This program is Free Software; you can redistribute it and/or
1587-# modify it under the terms of the GNU General Public License
1588-# as published by the Free Software Foundation; either version 2
1589-# of the License, or (at your option) any later version.
1590-#
1591-# This program is distributed in the hope that it will be useful,
1592-# but WITHOUT ANY WARRANTY; without even the implied warranty of
1593-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1594-# GNU General Public License for more details.
1595-#
1596-# You should have received a copy of the GNU General Public License
1597-# along with this program; if not, write to the Free Software
1598-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
1599+# Author: Arnaud Wüst (Camptocamp)
1600+# Author: Guewen Baconnier (Camptocamp) (port to v7)
1601+# Copyright 2011-2012 Camptocamp SA
1602+#
1603+# This program is free software: you can redistribute it and/or modify
1604+# it under the terms of the GNU Affero General Public License as
1605+# published by the Free Software Foundation, either version 3 of the
1606+# License, or (at your option) any later version.
1607+#
1608+# This program is distributed in the hope that it will be useful,
1609+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1610+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1611+# GNU Affero General Public License for more details.
1612+#
1613+# You should have received a copy of the GNU Affero General Public License
1614+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1615 #
1616 ##############################################################################
1617
1618-import time
1619-
1620-from osv import osv, fields
1621-
1622-
1623-class reminder_status(osv.osv_memory):
1624+from openerp.osv import orm, fields
1625+
1626+
1627+class reminder_status(orm.TransientModel):
1628 _name = 'hr.timesheet.reminder.status'
1629
1630 _columns = {
1631- 'company_ids': fields.many2many('res.company', 'reminder_company_rel', 'wid', 'rid', 'Company'),
1632+ 'company_ids': fields.many2many(
1633+ 'res.company',
1634+ 'reminder_company_rel',
1635+ 'wid',
1636+ 'rid',
1637+ string='Company'),
1638 'date': fields.date('End Date', required=True),
1639 }
1640
1641 _defaults = {
1642- 'date': lambda *a: time.strftime('%Y-%m-%d'),
1643+ 'date': lambda *a: fields.date.today(),
1644 }
1645
1646- def print_report(self, cr, uid, ids, context):
1647- if context is None:
1648- context = {}
1649-
1650- form_values = self.read(cr, uid, ids, ['company_ids', 'date'])[0]
1651-
1652+ def print_report(self, cr, uid, ids, context=None):
1653+ form_values = self.read(
1654+ cr, uid, ids[0], ['company_ids', 'date'], context=context)
1655+
1656+ # when no company is selected, select them all
1657 if not form_values['company_ids']:
1658 form_values['company_ids'] = self.pool.get('res.company').\
1659- search(cr, uid, [], context=context)
1660+ search(cr, uid, [], context=context)
1661+
1662 data = {'ids': form_values['company_ids'],
1663 'model': 'res.company',
1664- 'form': {}}
1665- data['form'].update(form_values)
1666+ 'form': form_values}
1667
1668 return {'type': 'ir.actions.report.xml',
1669 'report_name': 'timesheet.reminder.status',
1670 'datas': data}
1671-
1672-reminder_status()
1673
1674=== modified file 'hr_timesheet_reminder/wizard/reminder_status_view.xml'
1675--- hr_timesheet_reminder/wizard/reminder_status_view.xml 2011-08-12 12:53:16 +0000
1676+++ hr_timesheet_reminder/wizard/reminder_status_view.xml 2012-12-13 17:06:20 +0000
1677@@ -5,23 +5,24 @@
1678 <record id="view_hr_timesheet_reminder_status_form" model="ir.ui.view">
1679 <field name="name">hr.timesheet.reminder.status.form</field>
1680 <field name="model">hr.timesheet.reminder.status</field>
1681- <field name="type">form</field>
1682 <field name="arch" type="xml">
1683- <form string="Reminder Status">
1684- <group colspan="4" col="4" string="Parameter">
1685- <separator string="End Date (display the 5 timesheets previous to this date)" colspan="4"/>
1686- <field name="date" colspan="4" nolabel="1" width="400" />
1687- </group>
1688+ <form string="Reminder Status" version="7.0">
1689+ <sheet>
1690+ <group>
1691+ <label for="date" string="End Date (display the 5 timesheets previous to this date)"/>
1692+ <field name="date" colspan="4" nolabel="1" width="400" />
1693+ </group>
1694
1695- <group colspan="4" col="4" string="Filter">
1696- <separator string="Filter by a Company (leave empty to select all companies)" colspan="4"/>
1697- <field name="company_ids" colspan="4" nolabel="1"/>
1698- <newline/>
1699- </group>
1700- <group colspan="4" col="6">
1701- <button icon="gtk-cancel" special="cancel" string="Cancel"/>
1702- <button icon="gtk-print" string="Print" name="print_report" type="object" colspan="2" default_focus="1" />
1703- </group>
1704+ <group>
1705+ <separator string="Companies" colspan="4"/>
1706+ <label for="company_ids" colspan="4" string="Filter by a Company (leave empty to select all companies)"/>
1707+ <field name="company_ids" colspan="4" nolabel="1"/>
1708+ </group>
1709+ </sheet>
1710+ <footer>
1711+ <button name="print_report" string="Print" colspan="1" type="object" class="oe_highlight"/> or
1712+ <button special="cancel" string="Cancel" class="oe_link"/>
1713+ </footer>
1714 </form>
1715 </field>
1716 </record>
1717@@ -36,11 +37,11 @@
1718 </record>
1719
1720 <menuitem id="menu_hr_timesheet_reminder_status"
1721- icon="STOCK_PRINT"
1722- action="action_hr_timesheet_reminder_status"
1723- parent="hr_timesheet.menu_hr_reporting_timesheet"
1724- name="Timesheet Status"
1725- groups="base.group_hr_manager"/>
1726+ icon="STOCK_PRINT"
1727+ action="action_hr_timesheet_reminder_status"
1728+ parent="hr.menu_hr_reporting_timesheet"
1729+ name="Timesheet Status"
1730+ groups="base.group_hr_manager"/>
1731
1732-</data>
1733+ </data>
1734 </openerp>

Subscribers

People subscribed via source and target branches