Merge lp:~acsone-openerp/hr-timesheet/migration_hr_timesheet_taskV7 into lp:~hr-core-editors/hr-timesheet/7.0
- migration_hr_timesheet_taskV7
- Merge into 7.0
Status: | Merged |
---|---|
Approved by: | Guewen Baconnier @ Camptocamp |
Approved revision: | 49 |
Merged at revision: | 41 |
Proposed branch: | lp:~acsone-openerp/hr-timesheet/migration_hr_timesheet_taskV7 |
Merge into: | lp:~hr-core-editors/hr-timesheet/7.0 |
Diff against target: |
1428 lines (+712/-403) 19 files modified
hr_timesheet_task/__init__.py (+15/-25) hr_timesheet_task/__openerp__.py (+14/-10) hr_timesheet_task/hr_analytic_timesheet_view.xml (+14/-27) hr_timesheet_task/hr_timesheet_sheet_view.xml (+14/-12) hr_timesheet_task/i18n/fr.po (+42/-0) hr_timesheet_task/static/src/css/timesheet.css (+7/-0) hr_timesheet_task/static/src/js/timesheet.js (+252/-0) hr_timesheet_task/static/src/xml/timesheet.xml (+35/-0) hr_timesheet_task/wizard/__init__.py (+0/-3) hr_timesheet_task/wizard/associate_analytic_timesheet.py (+0/-48) hr_timesheet_task/wizard/dissociate_analytic_timesheet.py (+0/-47) hr_timesheet_task/wizard/hr_timesheet_invoice_create.py (+0/-46) hr_timesheet_task/wizard/wizard_actions.xml (+0/-34) timesheet_task/__init__.py (+15/-23) timesheet_task/__openerp__.py (+12/-13) timesheet_task/i18n/fr.po (+53/-0) timesheet_task/project_task.py (+36/-49) timesheet_task/project_task_view.xml (+203/-37) timesheet_task/tmp_file_for_project_indicator.py (+0/-29) |
To merge this branch: | bzr merge lp:~acsone-openerp/hr-timesheet/migration_hr_timesheet_taskV7 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Stéphane Bidoul (Acsone) (community) | code & test | Approve | |
Yannick Vaucher @ Camptocamp | code | Approve | |
Nicolas Bessi - Camptocamp (community) | Needs Fixing | ||
Review via email: mp+154433@code.launchpad.net |
Commit message
Description of the change
Migration of the module hr_timesheet_task and following improvement:
-Add task column in "My Current Timesheet" view (updating existing qweb/js/css).
-In hr_analytic_
-In task_id domain add ('project_
- 43. By Stéphane Bidoul (Acsone)
-
[FIX] restore filters and change their labels now that we have more room in the new search widget
- 44. By Stéphane Bidoul (Acsone)
-
[IMP] remove tabs and cleanup whitespace, clarify comments and rename a variable for clarity
Stéphane Bidoul (Acsone) (sbi) wrote : | # |
Yannick Vaucher @ Camptocamp (yvaucher-c2c) wrote : | # |
Hello,
There are some cleaning that could be done in .py files
-> Remove osv.memory
import orm and use orm.TransiantModel instead
from openerp.osv import osv, orm
class MyWizard(
-> Remove useless class instantiations
like on l516 remove the "ProjectTask()".
And in XML, it would better to use simpler relative xpath when possible
like l535 could be "///field[
Thanks
Yannick Vaucher @ Camptocamp (yvaucher-c2c) wrote : | # |
///field[
- 45. By Laetitia Gangloff (Acsone)
-
hr_timesheet_
task/timesheet_ task: replace some xpath by field in view. remove instanciation from project_task.py. Remove unused wizard and tmp_file. Rename aa_ids in timesheet_ids. Correct some issues with work_ids. Add french translation. - 46. By Laetitia Gangloff (Acsone)
-
timesheet_
task/hr_ timesheet_ task: correct label in translation. Cosmetic change in openerp.py
Laetitia Gangloff (Acsone) (laetitia-gangloff) wrote : | # |
Hello,
we remove wizard from hr_timesheet_task because it is never used (not in __init__.py), and tmp_file from timesheet_task.
We remove useless class instantiations in project_task.py.
we change xpath to have a more readable and maintainable view.
we correct some problems with the work_ids (renamed in timesheet_ids).
we add french translations.
Regards
Stéphane Bidoul (Acsone) (sbi) : | # |
Stéphane Bidoul (Acsone) (sbi) wrote : | # |
Hi Laetitia,
Can you add a comment to clarify the purpose and behavior of this code.
This looks tricky enough to warrant some comments :)
for col in ['effective_hours', 'planned_hours', 'total_hours', 'progress_rate']:
assert project.
project.
Nitpicking: redundant code in copy_data:
+ if default is None:
+ default = {}
+ default = default or {}
Nicolas Bessi - Camptocamp (nbessi-c2c-deactivatedaccount) wrote : | # |
The goal of timesheet_task is to replace projeck.task.work with aa lines.
In original __openerp__:
'description': """Replace project.task.work items linked to task
We do not want to add a new relation named timesheet_ids. The goal is replace this base behavior else you have to maintain two vision of working and add a second set of indicator. I do not say that keeping work done + timesheet line relation is not a valid approach but it does not fit the original goal of the addon who was to get rid of project.task.work by replacing the relation.
Stéphane Bidoul (Acsone) (sbi) wrote : | # |
Hi Nicolas,
The goal is not to add a new relation but indeed redefine work_ids to become a relation to hr.analytic.
In the previous version, this was done by redefining work_ids, but OpenERP 7.0 now complains about this (see comments from Laetitia there: https:/
This is the reason we have to create this new field (and sort-of depreate work_ids).
Best regards,
-sbi
Nicolas Bessi - Camptocamp (nbessi-c2c-deactivatedaccount) wrote : | # |
Hello,
Ok I see your point that is an annoying bug, I will propose to try to replace the view in XML instead of inheriting it and ensure it has a low priority. Eventually we can keep the inherit. I know it is a little nasty but I don't think there is a simple way to fix the root bug.
Regards
Nicolas
- 47. By Laetitia Gangloff (Acsone)
-
in timesheet_task replace XML view instead of inherited it.
Laetitia Gangloff (Acsone) (laetitia-gangloff) wrote : | # |
Hello,
as you suggested, I replace the view instead of inheritting it.
In addition, I kept work_ids instead of a timesheet_ids.
Thanks
Yannick Vaucher @ Camptocamp (yvaucher-c2c) wrote : | # |
Thanks for the work
I think you should just change the inheritances of deprecated alias osv.osv
On l864, l919, l928
And other to be removed as well if it exists
See osv.py
-----------------
# deprecated - for backward compatibility.
osv = Model
osv_memory = TransientModel
osv_abstract = AbstractModel # ;-)
-----------------
http://
So you need to use orm.Model and for me we are good there.
The license could also be changed to AGPL if you have the time to do it.
Otherwise it's look good
Thanks
- 48. By Laetitia Gangloff (Acsone)
-
in project_task used osv.Model instead of osv.osv. Update licence part.
- 49. By Laetitia Gangloff (Acsone)
-
in project_task used orm.Model instead of osv.Model.
Laetitia Gangloff (Acsone) (laetitia-gangloff) wrote : | # |
I use orm.Model instead of osv.osv and I try to update licence part.
Yannick Vaucher @ Camptocamp (yvaucher-c2c) wrote : | # |
Ok thanks for your changes
LGTM now :)
Stéphane Bidoul (Acsone) (sbi) : | # |
Stéphane Bidoul (Acsone) (sbi) wrote : | # |
If there are no more comments, can someone with commit rights merge this one?
We have some additional improvements we would like to propose, but these are separate from the v7 migration and will be part of another MP on top of this one.
Thanks,
-sbi
Guewen Baconnier @ Camptocamp (gbaconnier-c2c) wrote : | # |
Done
Preview Diff
1 | === modified file 'hr_timesheet_task/__init__.py' |
2 | --- hr_timesheet_task/__init__.py 2012-06-06 13:14:12 +0000 |
3 | +++ hr_timesheet_task/__init__.py 2013-04-03 11:31:22 +0000 |
4 | @@ -1,30 +1,20 @@ |
5 | # -*- coding: utf-8 -*- |
6 | ############################################################################## |
7 | # |
8 | -# Copyright (c) 2010 Camptocamp SA (http://www.camptocamp.com) |
9 | -# All Right Reserved |
10 | -# |
11 | -# Author : Joel Grand-guillaume (Camptocamp) |
12 | -# |
13 | -# WARNING: This program as such is intended to be used by professional |
14 | -# programmers who take the whole responsability of assessing all potential |
15 | -# consequences resulting from its eventual inadequacies and bugs |
16 | -# End users who are looking for a ready-to-use solution with commercial |
17 | -# garantees and support are strongly adviced to contract a Free Software |
18 | -# Service Company |
19 | -# |
20 | -# This program is Free Software; you can redistribute it and/or |
21 | -# modify it under the terms of the GNU General Public License |
22 | -# as published by the Free Software Foundation; either version 2 |
23 | -# of the License, or (at your option) any later version. |
24 | -# |
25 | -# This program is distributed in the hope that it will be useful, |
26 | -# but WITHOUT ANY WARRANTY; without even the implied warranty of |
27 | -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
28 | -# GNU General Public License for more details. |
29 | -# |
30 | -# You should have received a copy of the GNU General Public License |
31 | -# along with this program; if not, write to the Free Software |
32 | -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
33 | +# Author : Joel Grand-guillaume (Camptocamp) |
34 | +# Copyright 2013 Camptocamp SA |
35 | +# |
36 | +# This program is free software: you can redistribute it and/or modify |
37 | +# it under the terms of the GNU Affero General Public License as |
38 | +# published by the Free Software Foundation, either version 3 of the |
39 | +# License, or (at your option) any later version. |
40 | +# |
41 | +# This program is distributed in the hope that it will be useful, |
42 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
43 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
44 | +# GNU Affero General Public License for more details. |
45 | +# |
46 | +# You should have received a copy of the GNU Affero General Public License |
47 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
48 | # |
49 | ############################################################################## |
50 | |
51 | === modified file 'hr_timesheet_task/__openerp__.py' |
52 | --- hr_timesheet_task/__openerp__.py 2012-12-13 12:20:12 +0000 |
53 | +++ hr_timesheet_task/__openerp__.py 2013-04-03 11:31:22 +0000 |
54 | @@ -2,7 +2,7 @@ |
55 | ############################################################################## |
56 | # |
57 | # Author: Nicolas Bessi |
58 | -# Copyright 2012 Camptocamp SA |
59 | +# Copyright 2013 Camptocamp SA |
60 | # |
61 | # This program is free software: you can redistribute it and/or modify |
62 | # it under the terms of the GNU Affero General Public License as |
63 | @@ -19,21 +19,25 @@ |
64 | # |
65 | ############################################################################## |
66 | {'name' : 'Task in time sheet', |
67 | - 'version' : '0.1', |
68 | + 'version' : '0.2', |
69 | 'author' : 'Camptocamp', |
70 | - 'maintainer': 'Camptocamp', |
71 | + 'maintainer': 'Camptocamp - Acsone SA/NV', |
72 | 'category': 'Human Resources', |
73 | - 'complexity': "normal", #easy, normal, expert |
74 | 'depends' : ['timesheet_task', 'hr_timesheet_sheet'], |
75 | 'description': """Replace project.task.work items linked to task |
76 | with hr.analytic.timesheet""", |
77 | 'website': 'http://www.camptocamp.com', |
78 | - 'init_xml': [], |
79 | - 'update_xml': ['hr_timesheet_sheet_view.xml', 'hr_analytic_timesheet_view.xml'], |
80 | - 'demo_xml': [], |
81 | - 'tests': [], |
82 | - 'installable': False, |
83 | + 'data': ['hr_timesheet_sheet_view.xml', 'hr_analytic_timesheet_view.xml'], |
84 | + 'js' : ['static/src/js/timesheet.js'], |
85 | + 'css': ['static/src/css/timesheet.css',], |
86 | + 'qweb': ['static/src/xml/timesheet.xml'], |
87 | + 'demo': [], |
88 | + 'test': [], |
89 | + 'installable': True, |
90 | 'images' : [], |
91 | 'auto_install': False, |
92 | 'license': 'AGPL-3', |
93 | - 'application': True} |
94 | \ No newline at end of file |
95 | + 'application': True, |
96 | +} |
97 | + |
98 | +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |
99 | |
100 | === modified file 'hr_timesheet_task/hr_analytic_timesheet_view.xml' |
101 | --- hr_timesheet_task/hr_analytic_timesheet_view.xml 2012-10-23 15:06:03 +0000 |
102 | +++ hr_timesheet_task/hr_analytic_timesheet_view.xml 2013-04-03 11:31:22 +0000 |
103 | @@ -9,10 +9,10 @@ |
104 | <field name="type">form</field> |
105 | <field name="inherit_id" ref="hr_timesheet.hr_timesheet_line_form"/> |
106 | <field name="arch" type="xml"> |
107 | - <xpath expr="/form/group/field[@name='user_id']" position="after"> |
108 | + <field name="user_id" position="after"> |
109 | <field name="task_id" context="{ 'account_id' : account_id}" |
110 | - domain="[('state','=','open')]"/> |
111 | - </xpath> |
112 | + domain="[('state','=','open'), ('project_id.analytic_account_id','=',account_id)]"/> |
113 | + </field> |
114 | </field> |
115 | </record> |
116 | <record id="hr_timesheet.hr_timesheet_line_tree" model="ir.ui.view"> |
117 | @@ -25,7 +25,7 @@ |
118 | <field name="date" on_change="on_change_date(date)"/> |
119 | <field domain="[('type','=','normal')]" name="account_id"/> |
120 | <field name="task_id" context="{'account_id' : account_id}" |
121 | - domain="[('state','=','open')]"/> |
122 | + domain="[('state','=','open'), ('project_id.analytic_account_id','=',account_id)]"/> |
123 | <field name="name"/> |
124 | <field name="unit_amount" |
125 | on_change="on_change_unit_amount(product_id, unit_amount, False, product_uom_id, journal_id)" |
126 | @@ -52,9 +52,9 @@ |
127 | <field name="inherit_id" ref="hr_timesheet.hr_timesheet_line_search"/> |
128 | <field name="type">search</field> |
129 | <field name="arch" type="xml"> |
130 | - <xpath expr="/search/group/field[@name='date']" position="after"> |
131 | + <field name="date" position="after"> |
132 | <field name="task_id"/> |
133 | - </xpath> |
134 | + </field> |
135 | <xpath |
136 | expr="/search/group[@string='Group By...']/filter[@string='Analytic account']" |
137 | position="after"> |
138 | @@ -62,16 +62,17 @@ |
139 | /> |
140 | </xpath> |
141 | <!-- Add dates filter --> |
142 | - <xpath expr="/search/group/filter[@name='today']" position="before"> |
143 | - <filter icon="terp-go-year" string=" Year " |
144 | + <xpath expr="/search/group" position="before"> |
145 | + <separator orientation="vertical"/> |
146 | + <filter icon="terp-go-year" string="Current Year" |
147 | domain="[('date','<=', time.strftime('%%Y-%%m-%%d')),('date','>=',time.strftime('%%Y-01-01'))]" |
148 | help="Current Year"/> |
149 | - <filter icon="terp-go-month" string=" Month " name="month" |
150 | - domain="[('date','<=',(datetime.date.today()+relativedelta(day=31)).strftime('%%Y-%%m-%%d')),('date','>=',(datetime.date.today()-relativedelta(day=1)).strftime('%%Y-%%m-%%d'))]" |
151 | + <filter icon="terp-go-month" string="Current Month" name="month" |
152 | + domain="[('date','<=',(context_today()+relativedelta(day=31)).strftime('%%Y-%%m-%%d')),('date','>=',(context_today()-relativedelta(day=1)).strftime('%%Y-%%m-%%d'))]" |
153 | help="Current Month"/> |
154 | - <filter icon="terp-go-week" string=" Week " separator="1" name="week" |
155 | - domain="[('date','>=',(datetime.date.today()+relativedelta(days=-6,weekday=0)).strftime('%%Y-%%m-%%d')),('date','<=',(datetime.date.today()+relativedelta(weekday=6)).strftime('%%Y-%%m-%%d'))]" |
156 | - help="Current week"/> |
157 | + <filter icon="terp-go-week" string="Current Week" separator="1" name="week" |
158 | + domain="[('date','>=',(context_today()+relativedelta(days=-6,weekday=0)).strftime('%%Y-%%m-%%d')),('date','<=',(context_today()+relativedelta(weekday=6)).strftime('%%Y-%%m-%%d'))]" |
159 | + help="Current Week"/> |
160 | </xpath> |
161 | |
162 | </field> |
163 | @@ -80,19 +81,5 @@ |
164 | <record id="hr_timesheet.act_hr_timesheet_line_evry1_all_form" model="ir.actions.act_window"> |
165 | <field name="context">{"search_default_user_id":uid, "search_default_week":1}</field> |
166 | </record> |
167 | - <record id="hr_timesheet_line_search_to_invoice_filter" model="ir.ui.view"> |
168 | - <field name="name">hr.analytic.timesheet.search.toinvoice.filter</field> |
169 | - <field name="model">hr.analytic.timesheet</field> |
170 | - <field name="inherit_id" ref="hr_timesheet.hr_timesheet_line_search"/> |
171 | - <field name="type">search</field> |
172 | - <field name="arch" type="xml"> |
173 | - <xpath expr="/search/group[1]/filter[@name='today']" position="after"> |
174 | - <separator orientation="vertical"/> |
175 | - <filter name="to_invoice" string="To Invoice" context="{'to_invoice': 1}" |
176 | - domain="[('invoice_id','=',False),('to_invoice','<>',False)]" |
177 | - icon="terp-dolar"/> |
178 | - </xpath> |
179 | - </field> |
180 | - </record> |
181 | </data> |
182 | </openerp> |
183 | |
184 | === modified file 'hr_timesheet_task/hr_timesheet_sheet_view.xml' |
185 | --- hr_timesheet_task/hr_timesheet_sheet_view.xml 2012-10-23 15:06:03 +0000 |
186 | +++ hr_timesheet_task/hr_timesheet_sheet_view.xml 2013-04-03 11:31:22 +0000 |
187 | @@ -1,27 +1,29 @@ |
188 | <?xml version="1.0" encoding="utf-8"?> |
189 | <openerp> |
190 | <data> |
191 | + |
192 | <record id="view_hr_timesheet_sheet_filter_custom" model="ir.ui.view"> |
193 | <field name="name">hr_timesheet_sheet.sheet.filter</field> |
194 | <field name="model">hr_timesheet_sheet.sheet</field> |
195 | <field name="inherit_id" ref="hr_timesheet_sheet.view_hr_timesheet_sheet_filter"/> |
196 | <field name="type">search</field> |
197 | <field name="arch" type="xml"> |
198 | - <xpath expr="/search/group/filter[@string='To Approve']" position="after"> |
199 | + <filter name="to_approve" position="after"> |
200 | <separator orientation="vertical"/> |
201 | - <filter icon="terp-go-year" string=" Year " |
202 | + <filter icon="terp-go-year" string="Current Year" |
203 | domain="[('date_from','<=', time.strftime('%%Y-%%m-%%d')),('date_from','>=',time.strftime('%%Y-01-01'))]" |
204 | help="Current Year"/> |
205 | - <filter icon="terp-go-month" string=" Month " name="month" |
206 | - domain="[('date_from','<=',(datetime.date.today()+relativedelta(day=31)).strftime('%%Y-%%m-%%d')),('date_from','>=',(datetime.date.today()-relativedelta(day=1)).strftime('%%Y-%%m-%%d'))]" |
207 | + <filter icon="terp-go-month" string="Current Month" name="month" |
208 | + domain="[('date_from','<=',(context_today()+relativedelta(day=31)).strftime('%%Y-%%m-%%d')),('date_from','>=',(context_today()-relativedelta(day=1)).strftime('%%Y-%%m-%%d'))]" |
209 | help="Current Month"/> |
210 | - <filter icon="terp-go-week" string=" Week " separator="1" name="week" |
211 | - domain="[('date_from','>=',(datetime.date.today()+relativedelta(days=-6,weekday=0)).strftime('%%Y-%%m-%%d')),('date_from','<=',(datetime.date.today()+relativedelta(weekday=6)).strftime('%%Y-%%m-%%d'))]" |
212 | - help="Current week"/> |
213 | - </xpath> |
214 | + <filter icon="terp-go-week" string="Current Week" separator="1" name="week" |
215 | + domain="[('date_from','>=',(context_today()+relativedelta(days=-6,weekday=0)).strftime('%%Y-%%m-%%d')),('date_from','<=',(context_today()+relativedelta(weekday=6)).strftime('%%Y-%%m-%%d'))]" |
216 | + help="Current Week"/> |
217 | + </filter> |
218 | |
219 | </field> |
220 | </record> |
221 | + |
222 | <record id="hr_timesheet_sheet.act_hr_timesheet_sheet_form" model="ir.actions.act_window"> |
223 | <field name="context">{'search_default_my_timesheet':1}</field> |
224 | </record> |
225 | @@ -32,16 +34,16 @@ |
226 | <field name="inherit_id" ref="hr_timesheet_sheet.hr_timesheet_sheet_form"/> |
227 | <field name="arch" type="xml"> |
228 | <xpath |
229 | - expr="/form/notebook/page[@string='Daily']/field[@name='timesheet_ids']/tree[@string='Timesheet Lines']/field[@name='account_id']" |
230 | + expr="/form/sheet/notebook/page[@string='Details']/field[@name='timesheet_ids']/tree[@string='Timesheet Activities']/field[@name='account_id']" |
231 | position="after"> |
232 | <field name="task_id" context="{'account_id' : account_id}" |
233 | - domain="[('state','=','open')]"/> |
234 | + domain="[('state','=','open'), ('project_id.analytic_account_id','=',account_id)]"/> |
235 | </xpath> |
236 | <xpath |
237 | - expr="/form/notebook/page[@string='Daily']/field[@name='timesheet_ids']/form[@string='Timesheet Lines']/field[@name='account_id']" |
238 | + expr="/form/sheet/notebook/page[@string='Details']/field[@name='timesheet_ids']/form[@string='Timesheet Activities']/field[@name='account_id']" |
239 | position="after"> |
240 | <field name="task_id" context="{'account_id' : account_id}" |
241 | - domain="[('state','=','open')]"/> |
242 | + domain="[('state','=','open'), ('project_id.analytic_account_id','=',account_id)]"/> |
243 | </xpath> |
244 | </field> |
245 | </record> |
246 | |
247 | === added directory 'hr_timesheet_task/i18n' |
248 | === added file 'hr_timesheet_task/i18n/fr.po' |
249 | --- hr_timesheet_task/i18n/fr.po 1970-01-01 00:00:00 +0000 |
250 | +++ hr_timesheet_task/i18n/fr.po 2013-04-03 11:31:22 +0000 |
251 | @@ -0,0 +1,42 @@ |
252 | +# Translation of OpenERP Server. |
253 | +# This file contains the translation of the following modules: |
254 | +# * hr_timesheet_task |
255 | +# |
256 | +msgid "" |
257 | +msgstr "" |
258 | +"Project-Id-Version: OpenERP Server 7.0\n" |
259 | +"Report-Msgid-Bugs-To: \n" |
260 | +"POT-Creation-Date: 2013-03-28 15:37+0000\n" |
261 | +"PO-Revision-Date: 2013-03-28 15:37+0000\n" |
262 | +"Last-Translator: <>\n" |
263 | +"Language-Team: \n" |
264 | +"MIME-Version: 1.0\n" |
265 | +"Content-Type: text/plain; charset=UTF-8\n" |
266 | +"Content-Transfer-Encoding: \n" |
267 | +"Plural-Forms: \n" |
268 | + |
269 | +#. module: hr_timesheet_task |
270 | +#: view:hr.analytic.timesheet:0 |
271 | +#: view:hr_timesheet_sheet.sheet:0 |
272 | +msgid "Current Week" |
273 | +msgstr "Semaine en cours" |
274 | + |
275 | +#. module: hr_timesheet_task |
276 | +#: view:hr.analytic.timesheet:0 |
277 | +#: view:hr_timesheet_sheet.sheet:0 |
278 | +msgid "Current Year" |
279 | +msgstr "Année en cours" |
280 | + |
281 | +#. module: hr_timesheet_task |
282 | +#. openerp-web |
283 | +#: code:addons/hr_timesheet_task/static/src/xml/timesheet.xml:8 |
284 | +#: view:hr.analytic.timesheet:0 |
285 | +#, python-format |
286 | +msgid "Task" |
287 | +msgstr "Tâche" |
288 | + |
289 | +#. module: hr_timesheet_task |
290 | +#: view:hr.analytic.timesheet:0 |
291 | +#: view:hr_timesheet_sheet.sheet:0 |
292 | +msgid "Current Month" |
293 | +msgstr "Mois en cours" |
294 | |
295 | === added directory 'hr_timesheet_task/static' |
296 | === added directory 'hr_timesheet_task/static/src' |
297 | === added directory 'hr_timesheet_task/static/src/css' |
298 | === added file 'hr_timesheet_task/static/src/css/timesheet.css' |
299 | --- hr_timesheet_task/static/src/css/timesheet.css 1970-01-01 00:00:00 +0000 |
300 | +++ hr_timesheet_task/static/src/css/timesheet.css 2013-04-03 11:31:22 +0000 |
301 | @@ -0,0 +1,7 @@ |
302 | +@charset "utf-8"; |
303 | +.openerp .oe_timesheet_weekly .oe_timesheet_weekly_task { |
304 | + text-align: left; |
305 | +} |
306 | +.openerp .oe_timesheet_weekly .oe_timesheet_task_col { |
307 | + text-align: left; |
308 | +} |
309 | \ No newline at end of file |
310 | |
311 | === added directory 'hr_timesheet_task/static/src/js' |
312 | === added file 'hr_timesheet_task/static/src/js/timesheet.js' |
313 | --- hr_timesheet_task/static/src/js/timesheet.js 1970-01-01 00:00:00 +0000 |
314 | +++ hr_timesheet_task/static/src/js/timesheet.js 2013-04-03 11:31:22 +0000 |
315 | @@ -0,0 +1,252 @@ |
316 | +openerp.hr_timesheet_task = function(instance) { |
317 | + |
318 | + var module = instance.hr_timesheet_sheet |
319 | + |
320 | + module.WeeklyTimesheet.include({ |
321 | + events: { |
322 | + "click .oe_timesheet_weekly_account a": "go_to", |
323 | + "click .oe_timesheet_weekly_task a": "go_to_task", |
324 | + }, |
325 | + go_to_task : function(event) { |
326 | + var id = JSON.parse($(event.target).data("task-id")); |
327 | + this.do_action({ |
328 | + type: 'ir.actions.act_window', |
329 | + res_model: "project.task", |
330 | + res_id: id, |
331 | + views: [[false, 'form']], |
332 | + target: 'current' |
333 | + }); |
334 | + }, |
335 | + initialize_content: function() { |
336 | + var self = this; |
337 | + if (self.setting) |
338 | + return; |
339 | + // don't render anything until we have date_to and date_from |
340 | + if (!self.get("date_to") || !self.get("date_from")) |
341 | + return; |
342 | + this.destroy_content(); |
343 | + |
344 | + // it's important to use those vars to avoid race conditions |
345 | + var dates; |
346 | + var accounts; |
347 | + var account_names; |
348 | + var task_names; |
349 | + var default_get; |
350 | + return this.render_drop.add(new instance.web.Model("hr.analytic.timesheet").call("default_get", [ |
351 | + ['account_id','task_id','general_account_id','journal_id','date','name','user_id','product_id','product_uom_id','to_invoice','amount','unit_amount'], |
352 | + new instance.web.CompoundContext({'user_id': self.get('user_id')})]).then(function(result) { |
353 | + default_get = result; |
354 | + // calculating dates |
355 | + dates = []; |
356 | + var start = self.get("date_from"); |
357 | + var end = self.get("date_to"); |
358 | + while (start <= end) { |
359 | + dates.push(start); |
360 | + start = start.clone().addDays(1); |
361 | + } |
362 | + |
363 | + timesheet_lines = _(self.get("sheets")).chain() |
364 | + .map(function(el) { |
365 | + // much simpler to use only the id in all cases |
366 | + if (typeof(el.account_id) === "object") |
367 | + el.account_id = el.account_id[0]; |
368 | + if (typeof(el.task_id) === "object") |
369 | + el.task_id = el.task_id[0]; |
370 | + return el; |
371 | + }).value(); |
372 | + |
373 | + // group by account |
374 | + var timesheet_lines_by_account_id = _.groupBy(timesheet_lines, function(el) { |
375 | + return el.account_id; |
376 | + }); |
377 | + |
378 | + // group by account and task |
379 | + var timesheet_lines_by_account_id_task_id = _.groupBy(timesheet_lines, function(el) { |
380 | + return [el.account_id, el.task_id]; |
381 | + }); |
382 | + |
383 | + var account_ids = _.map(_.keys(timesheet_lines_by_account_id), function(el) { return el === "false" ? false : Number(el) }); |
384 | + |
385 | + return new instance.web.Model("hr.analytic.timesheet").call("multi_on_change_account_id", [[], account_ids, |
386 | + new instance.web.CompoundContext({'user_id': self.get('user_id')})]).then(function(accounts_defaults) { |
387 | + accounts = _(timesheet_lines_by_account_id_task_id).chain().map(function(lines, account_id_task_id) { |
388 | + account_defaults = _.extend({}, default_get, (accounts_defaults[lines[0].account_id] || {}).value || {}); |
389 | + // group by days |
390 | + var index = _.groupBy(lines, "date"); |
391 | + var days = _.map(dates, function(date) { |
392 | + var day = {day: date, lines: index[instance.web.date_to_str(date)] || []}; |
393 | + // add line where we will insert/remove hours |
394 | + var to_add = _.find(day.lines, function(line) { return line.name === self.description_line }); |
395 | + if (to_add) { |
396 | + day.lines = _.without(day.lines, to_add); |
397 | + day.lines.unshift(to_add); |
398 | + } else { |
399 | + day.lines.unshift(_.extend(_.clone(account_defaults), { |
400 | + name: self.description_line, |
401 | + unit_amount: 0, |
402 | + date: instance.web.date_to_str(date), |
403 | + account_id: lines[0].account_id, |
404 | + task_id: lines[0].task_id, |
405 | + })); |
406 | + } |
407 | + return day; |
408 | + }); |
409 | + return {account_task: account_id_task_id, account: lines[0].account_id, task: lines[0].task_id, days: days, account_defaults: account_defaults}; |
410 | + }).value(); |
411 | + |
412 | + // we need the name_get of the analytic accounts |
413 | + return new instance.web.Model("account.analytic.account").call("name_get", [_.pluck(accounts, "account"), |
414 | + new instance.web.CompoundContext()]).then(function(result) { |
415 | + account_names = {}; |
416 | + _.each(result, function(el) { |
417 | + account_names[el[0]] = el[1]; |
418 | + }); |
419 | + // we need the name_get of the tasks |
420 | + return new instance.web.Model("project.task").call("name_get", [_(accounts).chain().pluck("task").filter(function(el) { return el; }).value(), |
421 | + new instance.web.CompoundContext()]).then(function(result) { |
422 | + task_names = {}; |
423 | + _.each(result, function(el) { |
424 | + task_names[el[0]] = el[1]; |
425 | + }); |
426 | + accounts = _.sortBy(accounts, function(el) { |
427 | + return account_names[el.account]; |
428 | + }); |
429 | + }); |
430 | + }); |
431 | + }); |
432 | + })).then(function(result) { |
433 | + // we put all the gathered data in self, then we render |
434 | + self.dates = dates; |
435 | + self.accounts = accounts; |
436 | + self.account_names = account_names; |
437 | + self.task_names = task_names; |
438 | + self.default_get = default_get; |
439 | + //real rendering |
440 | + self.display_data(); |
441 | + }); |
442 | + }, |
443 | + init_add_account: function() { |
444 | + var self = this; |
445 | + if (self.dfm) |
446 | + return; |
447 | + self.$(".oe_timesheet_weekly_add_row").show(); |
448 | + self.dfm = new instance.web.form.DefaultFieldManager(self); |
449 | + self.dfm.extend_field_desc({ |
450 | + account: { |
451 | + relation: "account.analytic.account", |
452 | + }, |
453 | + task: { |
454 | + relation: "project.task", |
455 | + }, |
456 | + }); |
457 | + self.account_m2o = new instance.web.form.FieldMany2One(self.dfm, { |
458 | + attrs: { |
459 | + name: "account", |
460 | + type: "many2one", |
461 | + domain: [ |
462 | + ['type','in',['normal', 'contract']], |
463 | + ['state', '<>', 'close'], |
464 | + ['use_timesheets','=',1], |
465 | + ], |
466 | + context: { |
467 | + default_use_timesheets: 1, |
468 | + default_type: "contract", |
469 | + }, |
470 | + modifiers: '{"required": true}', |
471 | + }, |
472 | + }); |
473 | + self.task_m2o = new instance.web.form.FieldMany2One(self.dfm, { |
474 | + attrs: { |
475 | + name: "task", |
476 | + type: "many2one", |
477 | + domain: [ |
478 | + // at this moment, it is always an empty list |
479 | + ['project_id.analytic_account_id','=',self.account_m2o.get_value()] |
480 | + ], |
481 | + }, |
482 | + }); |
483 | + self.task_m2o.prependTo(self.$(".oe_timesheet_weekly_add_row td")); |
484 | + self.account_m2o.prependTo(self.$(".oe_timesheet_weekly_add_row td")); |
485 | + |
486 | + // when account_m2o loses focus, value can be changed, |
487 | + // update task_m2o to show only tasks related to the selected project |
488 | + self.account_m2o.$input.focusout(function(){ |
489 | + var account_id = self.account_m2o.get_value(); |
490 | + if (account_id === false) { return; } |
491 | + self.task_m2o.init(self.dfm, { |
492 | + attrs: { |
493 | + name: "task", |
494 | + type: "many2one", |
495 | + domain: [ |
496 | + ['state','=','open'], |
497 | + // show only tasks linked to the selected project |
498 | + ['project_id.analytic_account_id','=',account_id], |
499 | + // ignore tasks already in the timesheet |
500 | + ['id', 'not in', _.pluck(self.accounts, "task")], |
501 | + ], |
502 | + context: { |
503 | + 'account_id': account_id, |
504 | + }, |
505 | + }, |
506 | + }); |
507 | + }); |
508 | + |
509 | + self.$(".oe_timesheet_weekly_add_row button").click(function() { |
510 | + var id = self.account_m2o.get_value(); |
511 | + if (id === false) { |
512 | + self.dfm.set({display_invalid_fields: true}); |
513 | + return; |
514 | + } |
515 | + var ops = self.generate_o2m_value(); |
516 | + new instance.web.Model("hr.analytic.timesheet").call("on_change_account_id", [[], id]).then(function(res) { |
517 | + var def = _.extend({}, self.default_get, res.value, { |
518 | + name: self.description_line, |
519 | + unit_amount: 0, |
520 | + date: instance.web.date_to_str(self.dates[0]), |
521 | + account_id: id, |
522 | + task_id: self.task_m2o.get_value(), |
523 | + }); |
524 | + ops.push(def); |
525 | + self.set({"sheets": ops}); |
526 | + }); |
527 | + }); |
528 | + }, |
529 | + get_box: function(account, day_count) { |
530 | + return this.$('[data-account-task="' + account.account_task + '"][data-day-count="' + day_count + '"]'); |
531 | + }, |
532 | + get_total: function(account) { |
533 | + return this.$('[data-account-task-total="' + account.account_task + '"]'); |
534 | + }, |
535 | + generate_o2m_value: function() { |
536 | + var self = this; |
537 | + var ops = []; |
538 | + |
539 | + _.each(self.accounts, function(account) { |
540 | + var auth_keys = _.extend(_.clone(account.account_defaults), { |
541 | + name: true, unit_amount: true, date: true, account_id: true, task_id: true, |
542 | + }); |
543 | + _.each(account.days, function(day) { |
544 | + _.each(day.lines, function(line) { |
545 | + if (line.unit_amount !== 0) { |
546 | + var tmp = _.clone(line); |
547 | + tmp.id = undefined; |
548 | + _.each(line, function(v, k) { |
549 | + if (v instanceof Array) { |
550 | + tmp[k] = v[0]; |
551 | + } |
552 | + }); |
553 | + // we have to remove some keys, because analytic lines are shitty |
554 | + _.each(_.keys(tmp), function(key) { |
555 | + if (auth_keys[key] === undefined) { |
556 | + tmp[key] = undefined; |
557 | + } |
558 | + }); |
559 | + ops.push(tmp); |
560 | + } |
561 | + }); |
562 | + }); |
563 | + }); |
564 | + return ops; |
565 | + }, |
566 | + }); |
567 | +}; |
568 | |
569 | === added directory 'hr_timesheet_task/static/src/xml' |
570 | === added file 'hr_timesheet_task/static/src/xml/timesheet.xml' |
571 | --- hr_timesheet_task/static/src/xml/timesheet.xml 1970-01-01 00:00:00 +0000 |
572 | +++ hr_timesheet_task/static/src/xml/timesheet.xml 2013-04-03 11:31:22 +0000 |
573 | @@ -0,0 +1,35 @@ |
574 | +<?xml version="1.0" encoding="UTF-8"?> |
575 | + |
576 | +<templates> |
577 | + <t t-extend="hr_timesheet_sheet.WeeklyTimesheet"> |
578 | + |
579 | + <!-- Add a task column --> |
580 | + <t t-jquery="th.oe_timesheet_first_col" t-operation="after"> |
581 | + <th class="oe_timesheet_task_col">Task</th> |
582 | + </t> |
583 | + |
584 | + <!-- Replace all line created with the foreach to take account of task --> |
585 | + <t t-jquery="tr:not([class]):nth-child(n+2)" t-operation="replace"> |
586 | + <tr t-foreach="widget.accounts" t-as="account"> |
587 | + <td class="oe_timesheet_weekly_account"><a href="javascript:void(0)" t-att-data-id="JSON.stringify(account.account)"><t t-esc="widget.account_names[account.account]"/></a></td> |
588 | + <td class="oe_timesheet_weekly_task"><a href="javascript:void(0)" t-att-data-task-id="JSON.stringify(account.task)"><t t-esc="widget.task_names[account.task]" /></a></td> |
589 | + <t t-set="day_count" t-value="0"/> |
590 | + <t t-foreach="account.days" t-as="day"> |
591 | + <td t-att-class="(Date.compare(day.day, Date.today()) === 0 ? 'oe_timesheet_weekly_today' : '')"> |
592 | + <input t-if="!widget.get('effective_readonly')" class="oe_timesheet_weekly_input" |
593 | + t-att-data-account-task="account.account_task" t-att-data-day-count="day_count" type="text"/> |
594 | + <span t-if="widget.get('effective_readonly')" class="oe_timesheet_weekly_box" |
595 | + t-att-data-account-task="account.account_task" t-att-data-day-count="day_count"/> |
596 | + <t t-set="day_count" t-value="day_count + 1"/> |
597 | + </td> |
598 | + </t> |
599 | + <td t-att-data-account-task-total="account.account_task" class="oe_timesheet_total"> </td> |
600 | + </tr> |
601 | + </t> |
602 | + |
603 | + <!-- Add line in the last tr before the first element --> |
604 | + <t t-jquery="tr.oe_timesheet_total > td:first-child" t-operation="after"> |
605 | + <td> </td> |
606 | + </t> |
607 | + </t> |
608 | +</templates> |
609 | |
610 | === removed directory 'hr_timesheet_task/wizard' |
611 | === removed file 'hr_timesheet_task/wizard/__init__.py' |
612 | --- hr_timesheet_task/wizard/__init__.py 2011-08-12 12:53:16 +0000 |
613 | +++ hr_timesheet_task/wizard/__init__.py 1970-01-01 00:00:00 +0000 |
614 | @@ -1,3 +0,0 @@ |
615 | -import associate_analytic_timesheet |
616 | -import dissociate_analytic_timesheet |
617 | -import hr_timesheet_invoice_create |
618 | |
619 | === removed file 'hr_timesheet_task/wizard/associate_analytic_timesheet.py' |
620 | --- hr_timesheet_task/wizard/associate_analytic_timesheet.py 2011-08-12 12:53:16 +0000 |
621 | +++ hr_timesheet_task/wizard/associate_analytic_timesheet.py 1970-01-01 00:00:00 +0000 |
622 | @@ -1,48 +0,0 @@ |
623 | -# -*- coding: utf-8 -*- |
624 | -############################################################################## |
625 | -# |
626 | -# Author Guewen Baconnier. Copyright Camptocamp SA |
627 | -# |
628 | -############################################################################## |
629 | -# WARNING: This program as such is intended to be used by professional |
630 | -# programmers who take the whole responsability of assessing all potential |
631 | -# consequences resulting from its eventual inadequacies and bugs |
632 | -# End users who are looking for a ready-to-use solution with commercial |
633 | -# garantees and support are strongly adviced to contract a Free Software |
634 | -# Service Company |
635 | -# |
636 | -# This program is Free Software; you can redistribute it and/or |
637 | -# modify it under the terms of the GNU General Public License |
638 | -# as published by the Free Software Foundation; either version 2 |
639 | -# of the License, or (at your option) any later version. |
640 | -# |
641 | -# This program is distributed in the hope that it will be useful, |
642 | -# but WITHOUT ANY WARRANTY; without even the implied warranty of |
643 | -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
644 | -# GNU General Public License for more details. |
645 | -# |
646 | -# You should have received a copy of the GNU General Public License |
647 | -# along with this program; if not, write to the Free Software |
648 | -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
649 | -# |
650 | -############################################################################## |
651 | - |
652 | - |
653 | -from osv import osv |
654 | - |
655 | - |
656 | -class AssociateInvoice(osv.osv_memory): |
657 | - _inherit = 'associate.aal.to.invoice' |
658 | - |
659 | - def associate_aal(self, cr, uid, ids, context): |
660 | - """ If the wizard is called from hr.analytic.timesheet (inherits account.analytic.line) |
661 | - We get the account.analytic.line ids and call the wizard with them """ |
662 | - if context.get('active_model', False) == 'hr.analytic.timesheet': |
663 | - at_obj = self.pool.get('hr.analytic.timesheet') |
664 | - at_ids = context.get('active_ids', False) |
665 | - aal_ids = [at.line_id.id for at in at_obj.browse(cr, uid, at_ids, context)] |
666 | - context['active_ids'] = aal_ids |
667 | - |
668 | - return super(AssociateInvoice, self).associate_aal(cr, uid, ids, context) |
669 | - |
670 | -AssociateInvoice() |
671 | |
672 | === removed file 'hr_timesheet_task/wizard/dissociate_analytic_timesheet.py' |
673 | --- hr_timesheet_task/wizard/dissociate_analytic_timesheet.py 2011-08-12 12:53:16 +0000 |
674 | +++ hr_timesheet_task/wizard/dissociate_analytic_timesheet.py 1970-01-01 00:00:00 +0000 |
675 | @@ -1,47 +0,0 @@ |
676 | -# -*- coding: utf-8 -*- |
677 | -############################################################################## |
678 | -# |
679 | -# Author Guewen Baconnier. Copyright Camptocamp SA |
680 | -# |
681 | -############################################################################## |
682 | -# WARNING: This program as such is intended to be used by professional |
683 | -# programmers who take the whole responsability of assessing all potential |
684 | -# consequences resulting from its eventual inadequacies and bugs |
685 | -# End users who are looking for a ready-to-use solution with commercial |
686 | -# garantees and support are strongly adviced to contract a Free Software |
687 | -# Service Company |
688 | -# |
689 | -# This program is Free Software; you can redistribute it and/or |
690 | -# modify it under the terms of the GNU General Public License |
691 | -# as published by the Free Software Foundation; either version 2 |
692 | -# of the License, or (at your option) any later version. |
693 | -# |
694 | -# This program is distributed in the hope that it will be useful, |
695 | -# but WITHOUT ANY WARRANTY; without even the implied warranty of |
696 | -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
697 | -# GNU General Public License for more details. |
698 | -# |
699 | -# You should have received a copy of the GNU General Public License |
700 | -# along with this program; if not, write to the Free Software |
701 | -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
702 | -# |
703 | -############################################################################## |
704 | - |
705 | - |
706 | -from osv import osv |
707 | - |
708 | - |
709 | -class DissociateInvoice(osv.osv_memory): |
710 | - _inherit = 'dissociate.aal.to.invoice' |
711 | - |
712 | - def dissociate_aal(self, cr, uid, ids, context): |
713 | - """ If the wizard is called from hr.analytic.timesheet (inherits account.analytic.line) |
714 | - We get the account.analytic.line ids and call the wizard with them """ |
715 | - if context.get('active_model', False) == 'hr.analytic.timesheet': |
716 | - at_obj = self.pool.get('hr.analytic.timesheet') |
717 | - at_ids = context.get('active_ids', False) |
718 | - aal_ids = [at.line_id.id for at in at_obj.browse(cr, uid, at_ids, context)] |
719 | - context['active_ids'] = aal_ids |
720 | - return super(DissociateInvoice, self).dissociate_aal(cr, uid, ids, context) |
721 | - |
722 | -DissociateInvoice() |
723 | |
724 | === removed file 'hr_timesheet_task/wizard/hr_timesheet_invoice_create.py' |
725 | --- hr_timesheet_task/wizard/hr_timesheet_invoice_create.py 2011-08-12 12:53:16 +0000 |
726 | +++ hr_timesheet_task/wizard/hr_timesheet_invoice_create.py 1970-01-01 00:00:00 +0000 |
727 | @@ -1,46 +0,0 @@ |
728 | -# -*- coding: utf-8 -*- |
729 | -############################################################################## |
730 | -# |
731 | -# Author Guewen Baconnier. Copyright Camptocamp SA |
732 | -# |
733 | -############################################################################## |
734 | -# WARNING: This program as such is intended to be used by professional |
735 | -# programmers who take the whole responsability of assessing all potential |
736 | -# consequences resulting from its eventual inadequacies and bugs |
737 | -# End users who are looking for a ready-to-use solution with commercial |
738 | -# garantees and support are strongly adviced to contract a Free Software |
739 | -# Service Company |
740 | -# |
741 | -# This program is Free Software; you can redistribute it and/or |
742 | -# modify it under the terms of the GNU General Public License |
743 | -# as published by the Free Software Foundation; either version 2 |
744 | -# of the License, or (at your option) any later version. |
745 | -# |
746 | -# This program is distributed in the hope that it will be useful, |
747 | -# but WITHOUT ANY WARRANTY; without even the implied warranty of |
748 | -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
749 | -# GNU General Public License for more details. |
750 | -# |
751 | -# You should have received a copy of the GNU General Public License |
752 | -# along with this program; if not, write to the Free Software |
753 | -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
754 | -# |
755 | -############################################################################## |
756 | - |
757 | -from osv import osv |
758 | - |
759 | - |
760 | -class hr_timesheet_invoice_create(osv.osv_memory): |
761 | - _inherit = 'hr.timesheet.invoice.create' |
762 | - |
763 | - def do_create(self, cr, uid, ids, context=None): |
764 | - """ If the wizard is called from hr.analytic.timesheet (inherits account.analytic.line) |
765 | - We get the account.analytic.line ids and call the wizard with them """ |
766 | - if context.get('active_model', False) == 'hr.analytic.timesheet': |
767 | - at_obj = self.pool.get('hr.analytic.timesheet') |
768 | - at_ids = context.get('active_ids', False) |
769 | - aal_ids = [at.line_id.id for at in at_obj.browse(cr, uid, at_ids, context)] |
770 | - context['active_ids'] = aal_ids |
771 | - return super(hr_timesheet_invoice_create, self).do_create(cr, uid, ids, context) |
772 | - |
773 | -hr_timesheet_invoice_create() |
774 | |
775 | === removed file 'hr_timesheet_task/wizard/wizard_actions.xml' |
776 | --- hr_timesheet_task/wizard/wizard_actions.xml 2011-08-12 12:53:16 +0000 |
777 | +++ hr_timesheet_task/wizard/wizard_actions.xml 1970-01-01 00:00:00 +0000 |
778 | @@ -1,34 +0,0 @@ |
779 | -<?xml version="1.0" encoding="utf-8"?> |
780 | -<openerp> |
781 | -<data> |
782 | - |
783 | - <act_window name="Associate Analytic Lines" |
784 | - res_model="associate.aal.to.invoice" |
785 | - src_model="hr.analytic.timesheet" |
786 | - key2="client_action_multi" |
787 | - view_mode="form" |
788 | - view_type="form" |
789 | - target="new" |
790 | - id="action_associate_at_invoice"/> |
791 | - |
792 | - <act_window name="Dissociate Analytic Lines" |
793 | - res_model="dissociate.aal.to.invoice" |
794 | - src_model="hr.analytic.timesheet" |
795 | - key2="client_action_multi" |
796 | - view_mode="form" |
797 | - view_type="form" |
798 | - target="new" |
799 | - id="action_dissociate_at_invoice"/> |
800 | - |
801 | - <record model="ir.values" id="hr_analytic_timesheet_invoice_create_values"> |
802 | - <field name="model_id" ref="model_hr_analytic_timesheet" /> |
803 | - <field name="object" eval="1" /> |
804 | - <field name="name">Invoice analytic lines</field> |
805 | - <field name="key2">client_action_multi</field> |
806 | - <field name="value" eval="'ir.actions.act_window,' + str(ref('hr_timesheet_invoice.action_hr_timesheet_invoice_create'))" /> |
807 | - <field name="key">action</field> |
808 | - <field name="model">hr.analytic.timesheet</field> |
809 | - </record> |
810 | - |
811 | -</data> |
812 | -</openerp> |
813 | |
814 | === modified file 'timesheet_task/__init__.py' |
815 | --- timesheet_task/__init__.py 2012-06-06 13:14:12 +0000 |
816 | +++ timesheet_task/__init__.py 2013-04-03 11:31:22 +0000 |
817 | @@ -1,29 +1,21 @@ |
818 | # -*- coding: utf-8 -*- |
819 | ############################################################################## |
820 | # |
821 | -# author Nicolas Bessi |
822 | -# Copyright Camptocamp 2012 |
823 | -# |
824 | -# WARNING: This program as such is intended to be used by professional |
825 | -# programmers who take the whole responsability of assessing all potential |
826 | -# consequences resulting from its eventual inadequacies and bugs |
827 | -# End users who are looking for a ready-to-use solution with commercial |
828 | -# garantees and support are strongly adviced to contract a Free Software |
829 | -# Service Company |
830 | -# |
831 | -# This program is Free Software; you can redistribute it and/or |
832 | -# modify it under the terms of the GNU General Public License |
833 | -# as published by the Free Software Foundation; either version 2 |
834 | -# of the License, or (at your option) any later version. |
835 | -# |
836 | -# This program is distributed in the hope that it will be useful, |
837 | -# but WITHOUT ANY WARRANTY; without even the implied warranty of |
838 | -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
839 | -# GNU General Public License for more details. |
840 | -# |
841 | -# You should have received a copy of the GNU General Public License |
842 | -# along with this program; if not, write to the Free Software |
843 | -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
844 | +# Author: Nicolas Bessi |
845 | +# Copyright 2013 Camptocamp SA |
846 | +# |
847 | +# This program is free software: you can redistribute it and/or modify |
848 | +# it under the terms of the GNU Affero General Public License as |
849 | +# published by the Free Software Foundation, either version 3 of the |
850 | +# License, or (at your option) any later version. |
851 | +# |
852 | +# This program is distributed in the hope that it will be useful, |
853 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
854 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
855 | +# GNU Affero General Public License for more details. |
856 | +# |
857 | +# You should have received a copy of the GNU Affero General Public License |
858 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
859 | # |
860 | ############################################################################## |
861 | from . import project_task |
862 | \ No newline at end of file |
863 | |
864 | === modified file 'timesheet_task/__openerp__.py' |
865 | --- timesheet_task/__openerp__.py 2012-12-13 12:20:12 +0000 |
866 | +++ timesheet_task/__openerp__.py 2013-04-03 11:31:22 +0000 |
867 | @@ -2,7 +2,7 @@ |
868 | ############################################################################## |
869 | # |
870 | # Author: Nicolas Bessi |
871 | -# Copyright 2012 Camptocamp SA |
872 | +# Copyright 2013 Camptocamp SA |
873 | # |
874 | # This program is free software: you can redistribute it and/or modify |
875 | # it under the terms of the GNU Affero General Public License as |
876 | @@ -19,23 +19,22 @@ |
877 | # |
878 | ############################################################################## |
879 | {'name' : 'Analytic Task', |
880 | - 'version' : '0.1', |
881 | + 'version' : '0.2', |
882 | 'author' : 'Camptocamp', |
883 | - 'maintainer': 'Camptocamp', |
884 | + 'maintainer': 'Camptocamp - Acsone SA/NV', |
885 | 'category': 'Human Resources', |
886 | - 'complexity': "normal", #easy, normal, expert |
887 | - 'depends' : ['hr_timesheet', 'project', 'hr_timesheet_invoice'], |
888 | + 'depends' : ['project', 'hr_timesheet_invoice'], |
889 | 'description': """Replace project.task.work items linked to task |
890 | with hr.analytic.timesheet""", |
891 | 'website': 'http://www.camptocamp.com', |
892 | - 'init_xml': [], |
893 | - 'update_xml': ['project_task_view.xml'], |
894 | - 'demo_xml': [], |
895 | - 'tests': [], |
896 | - 'installable': False, |
897 | + 'data': ['project_task_view.xml'], |
898 | + 'demo': [], |
899 | + 'test': [], |
900 | + 'installable': True, |
901 | 'images' : [], |
902 | 'auto_install': False, |
903 | 'license': 'AGPL-3', |
904 | - 'application': True} |
905 | - #'icon': '/MODULE_NAME/static/src/images/XXX.png', |
906 | - |
907 | \ No newline at end of file |
908 | + 'application': True, |
909 | +} |
910 | + |
911 | +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |
912 | |
913 | === added directory 'timesheet_task/i18n' |
914 | === added file 'timesheet_task/i18n/fr.po' |
915 | --- timesheet_task/i18n/fr.po 1970-01-01 00:00:00 +0000 |
916 | +++ timesheet_task/i18n/fr.po 2013-04-03 11:31:22 +0000 |
917 | @@ -0,0 +1,53 @@ |
918 | +# Translation of OpenERP Server. |
919 | +# This file contains the translation of the following modules: |
920 | +# * timesheet_task |
921 | +# |
922 | +msgid "" |
923 | +msgstr "" |
924 | +"Project-Id-Version: OpenERP Server 7.0\n" |
925 | +"Report-Msgid-Bugs-To: \n" |
926 | +"POT-Creation-Date: 2013-03-28 15:26+0000\n" |
927 | +"PO-Revision-Date: 2013-03-28 15:26+0000\n" |
928 | +"Last-Translator: <>\n" |
929 | +"Language-Team: \n" |
930 | +"MIME-Version: 1.0\n" |
931 | +"Content-Type: text/plain; charset=UTF-8\n" |
932 | +"Content-Transfer-Encoding: \n" |
933 | +"Plural-Forms: \n" |
934 | + |
935 | +#. module: timesheet_task |
936 | +#: field:account.analytic.line,task_id:0 |
937 | +#: model:ir.model,name:timesheet_task.model_project_task |
938 | +msgid "Task" |
939 | +msgstr "Tâche" |
940 | + |
941 | +#. module: timesheet_task |
942 | +#: model:ir.model,name:timesheet_task.model_account_analytic_line |
943 | +msgid "Analytic Line" |
944 | +msgstr "Ligne analytique" |
945 | + |
946 | +#. module: timesheet_task |
947 | +#: view:project.task:0 |
948 | +msgid "Total time" |
949 | +msgstr "Temps total" |
950 | + |
951 | +#. module: timesheet_task |
952 | +#: view:project.task:0 |
953 | +msgid "Task Work" |
954 | +msgstr "Travail effectué" |
955 | + |
956 | +#. module: timesheet_task |
957 | +#: field:project.task,timesheet_ids:0 |
958 | +msgid "Work done" |
959 | +msgstr "Travail effectué" |
960 | + |
961 | +#. module: timesheet_task |
962 | +#: model:ir.model,name:timesheet_task.model_hr_analytic_timesheet |
963 | +msgid "Timesheet Line" |
964 | +msgstr "Ligne de prestation" |
965 | + |
966 | +#. module: timesheet_task |
967 | +#: view:project.task:0 |
968 | +msgid "Total cost" |
969 | +msgstr "Coût total" |
970 | + |
971 | |
972 | === modified file 'timesheet_task/project_task.py' |
973 | --- timesheet_task/project_task.py 2012-10-26 13:01:39 +0000 |
974 | +++ timesheet_task/project_task.py 2013-04-03 11:31:22 +0000 |
975 | @@ -1,38 +1,30 @@ |
976 | # -*- coding: utf-8 -*- |
977 | ############################################################################## |
978 | # |
979 | -# author Nicolas Bessi |
980 | -# Copyright Camptocamp 2012 |
981 | -# |
982 | -# WARNING: This program as such is intended to be used by professional |
983 | -# programmers who take the whole responsability of assessing all potential |
984 | -# consequences resulting from its eventual inadequacies and bugs |
985 | -# End users who are looking for a ready-to-use solution with commercial |
986 | -# garantees and support are strongly adviced to contract a Free Software |
987 | -# Service Company |
988 | -# |
989 | -# This program is Free Software; you can redistribute it and/or |
990 | -# modify it under the terms of the GNU General Public License |
991 | -# as published by the Free Software Foundation; either version 2 |
992 | -# of the License, or (at your option) any later version. |
993 | -# |
994 | -# This program is distributed in the hope that it will be useful, |
995 | -# but WITHOUT ANY WARRANTY; without even the implied warranty of |
996 | -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
997 | -# GNU General Public License for more details. |
998 | -# |
999 | -# You should have received a copy of the GNU General Public License |
1000 | -# along with this program; if not, write to the Free Software |
1001 | -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
1002 | +# Author: Nicolas Bessi |
1003 | +# Copyright 2013 Camptocamp SA |
1004 | +# |
1005 | +# This program is free software: you can redistribute it and/or modify |
1006 | +# it under the terms of the GNU Affero General Public License as |
1007 | +# published by the Free Software Foundation, either version 3 of the |
1008 | +# License, or (at your option) any later version. |
1009 | +# |
1010 | +# This program is distributed in the hope that it will be useful, |
1011 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
1012 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1013 | +# GNU Affero General Public License for more details. |
1014 | +# |
1015 | +# You should have received a copy of the GNU Affero General Public License |
1016 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
1017 | # |
1018 | ############################################################################## |
1019 | |
1020 | -from osv import osv, fields |
1021 | +from openerp.osv import orm, fields |
1022 | |
1023 | TASK_WATCHERS = ['work_ids', 'remaining_hours', 'planned_hours'] |
1024 | -AA_WATCHERS = ['unit_amount', 'product_uom_id', 'account_id', 'to_invoice', 'task_id'] |
1025 | +TIMESHEET_WATCHERS = ['unit_amount', 'product_uom_id', 'account_id', 'to_invoice', 'task_id'] |
1026 | |
1027 | -class ProjectTask(osv.osv): |
1028 | +class ProjectTask(orm.Model): |
1029 | _inherit = "project.task" |
1030 | _name = "project.task" |
1031 | |
1032 | @@ -53,8 +45,8 @@ |
1033 | res[task.id]['delay_hours'] = res[task.id]['total_hours'] - task.planned_hours |
1034 | res[task.id]['progress'] = 0.0 |
1035 | if (task.remaining_hours + hours.get(task.id, 0.0)): |
1036 | - res[task.id]['progress'] = round(min(100.0 * hours.get(task.id, 0.0) / res[task.id]['total_hours'], 99.99),2) |
1037 | - if task.state in ('done','cancelled'): |
1038 | + res[task.id]['progress'] = round(min(100.0 * hours.get(task.id, 0.0) / res[task.id]['total_hours'], 99.99), 2) |
1039 | + if task.state in ('done', 'cancelled'): |
1040 | res[task.id]['progress'] = 100.0 |
1041 | return res |
1042 | |
1043 | @@ -67,26 +59,27 @@ |
1044 | |
1045 | |
1046 | _columns = {'work_ids': fields.one2many('hr.analytic.timesheet', 'task_id', 'Work done'), |
1047 | + |
1048 | |
1049 | 'effective_hours': fields.function(_progress_rate, multi="progress", method=True, string='Time Spent', |
1050 | help="Sum of spent hours of all tasks related to this project and its child projects.", |
1051 | - store = {'project.task': (lambda self, cr, uid, ids, c={}: ids, TASK_WATCHERS, 20), |
1052 | - 'account.analytic.line': (_get_analytic_line, AA_WATCHERS, 20)}), |
1053 | + store={'project.task': (lambda self, cr, uid, ids, c={}: ids, TASK_WATCHERS, 20), |
1054 | + 'account.analytic.line': (_get_analytic_line, TIMESHEET_WATCHERS, 20)}), |
1055 | |
1056 | 'delay_hours': fields.function(_progress_rate, multi="progress", method=True, string='Deduced Hours', |
1057 | help="Sum of spent hours with invoice factor of all tasks related to this project and its child projects.", |
1058 | - store = {'project.task': (lambda self, cr, uid, ids, c={}: ids, TASK_WATCHERS, 20), |
1059 | - 'account.analytic.line': (_get_analytic_line, AA_WATCHERS, 20)}), |
1060 | + store={'project.task': (lambda self, cr, uid, ids, c={}: ids, TASK_WATCHERS, 20), |
1061 | + 'account.analytic.line': (_get_analytic_line, TIMESHEET_WATCHERS, 20)}), |
1062 | |
1063 | 'total_hours': fields.function(_progress_rate, multi="progress", method=True, string='Total Time', |
1064 | help="Sum of total hours of all tasks related to this project and its child projects.", |
1065 | - store = {'project.task': (lambda self, cr, uid, ids, c={}: ids, TASK_WATCHERS, 20), |
1066 | - 'account.analytic.line': (_get_analytic_line, AA_WATCHERS, 20)}), |
1067 | + store={'project.task': (lambda self, cr, uid, ids, c={}: ids, TASK_WATCHERS, 20), |
1068 | + 'account.analytic.line': (_get_analytic_line, TIMESHEET_WATCHERS, 20)}), |
1069 | |
1070 | 'progress': fields.function(_progress_rate, multi="progress", method=True, string='Progress', type='float', group_operator="avg", |
1071 | help="Percent of tasks closed according to the total of tasks todo.", |
1072 | - store = {'project.task': (lambda self, cr, uid, ids, c={}: ids, TASK_WATCHERS, 20), |
1073 | - 'account.analytic.line': (_get_analytic_line, AA_WATCHERS, 20)})} |
1074 | + store={'project.task': (lambda self, cr, uid, ids, c={}: ids, TASK_WATCHERS, 20), |
1075 | + 'account.analytic.line': (_get_analytic_line, TIMESHEET_WATCHERS, 20)})} |
1076 | |
1077 | def write(self, cr, uid, ids, vals, context=None): |
1078 | res = super(ProjectTask, self).write(cr, uid, ids, vals, context=context) |
1079 | @@ -99,9 +92,7 @@ |
1080 | ts_obj.write(cr, uid, [w.id for w in task.work_ids], {'account_id': account_id}, context=context) |
1081 | return res |
1082 | |
1083 | -ProjectTask() |
1084 | - |
1085 | -class HrAnalyticTimesheet(osv.osv): |
1086 | +class HrAnalyticTimesheet(orm.Model): |
1087 | _inherit = "hr.analytic.timesheet" |
1088 | _name = "hr.analytic.timesheet" |
1089 | |
1090 | @@ -125,9 +116,7 @@ |
1091 | res['value']['to_invoice'] = p.to_invoice.id |
1092 | return res |
1093 | |
1094 | -HrAnalyticTimesheet() |
1095 | - |
1096 | -class AccountAnalyticLine(osv.osv): |
1097 | +class AccountAnalyticLine(orm.Model): |
1098 | """We add task_id on AA and manage update of linked task indicators""" |
1099 | _inherit = "account.analytic.line" |
1100 | _name = "account.analytic.line" |
1101 | @@ -142,7 +131,7 @@ |
1102 | return 0.0 |
1103 | fact_obj = self.pool.get('hr_timesheet_invoice.factor') |
1104 | factor = 100.0 - float(fact_obj.browse(cr, uid, factor_id).factor) |
1105 | - return (float(hours)/100.00)*factor |
1106 | + return (float(hours) / 100.00) * factor |
1107 | |
1108 | def _set_remaining_hours_create(self, cr, uid, vals, context=None): |
1109 | if not vals.get('task_id'): |
1110 | @@ -161,9 +150,9 @@ |
1111 | for line in self.browse(cr, uid, ids): |
1112 | # in OpenERP if we set a value to nil vals become False |
1113 | old_task_id = line.task_id and line.task_id.id or None |
1114 | - new_task_id = vals.get('task_id', old_task_id) #if no task_id in vals we assume it is equal to old |
1115 | + new_task_id = vals.get('task_id', old_task_id) # if no task_id in vals we assume it is equal to old |
1116 | |
1117 | - #we look if value has changed |
1118 | + # we look if value has changed |
1119 | if (new_task_id != old_task_id) and old_task_id: |
1120 | self._set_remaining_hours_unlink(cr, uid, [line.id], context) |
1121 | if new_task_id: |
1122 | @@ -205,14 +194,12 @@ |
1123 | def create(self, cr, uid, vals, context=None): |
1124 | if vals.get('task_id'): |
1125 | self._set_remaining_hours_create(cr, uid, vals, context) |
1126 | - return super(AccountAnalyticLine,self).create(cr, uid, vals, context=context) |
1127 | + return super(AccountAnalyticLine, self).create(cr, uid, vals, context=context) |
1128 | |
1129 | def write(self, cr, uid, ids, vals, context=None): |
1130 | - self. _set_remaining_hours_write(cr, uid, ids, vals, context=context) |
1131 | + self._set_remaining_hours_write(cr, uid, ids, vals, context=context) |
1132 | return super(AccountAnalyticLine, self).write(cr, uid, ids, vals, context=context) |
1133 | |
1134 | def unlink(self, cr, uid, ids, context=None): |
1135 | self._set_remaining_hours_unlink(cr, uid, ids, context) |
1136 | return super(AccountAnalyticLine, self).unlink(cr, uid, ids, context=context) |
1137 | - |
1138 | -AccountAnalyticLine() |
1139 | |
1140 | === modified file 'timesheet_task/project_task_view.xml' |
1141 | --- timesheet_task/project_task_view.xml 2012-06-06 13:14:12 +0000 |
1142 | +++ timesheet_task/project_task_view.xml 2013-04-03 11:31:22 +0000 |
1143 | @@ -1,46 +1,212 @@ |
1144 | <openerp> |
1145 | <data> |
1146 | - #--------------------------------------------------------------------------------------------------------- |
1147 | - # Adapt task views |
1148 | - #--------------------------------------------------------------------------------------------------------- |
1149 | - <record id="view_task_form2" model="ir.ui.view"> |
1150 | + |
1151 | + #--------------------------------------------------------------------------------------------------------- |
1152 | + # Adapt task views |
1153 | + #--------------------------------------------------------------------------------------------------------- |
1154 | + <!-- Replace the view project.view_task_form2 instead of inheriting |
1155 | + it and set a low priority. This replacement is to avoid the following error: |
1156 | + |
1157 | + ERROR timesheet openerp.osv.orm: Can't find field 'hours' in the following view parts |
1158 | + composing the view of object model 'project.task': |
1159 | + * project.task.form |
1160 | + |
1161 | + Either you wrongly customized this view, or some modules bringing those views are not |
1162 | + compatible with your current data model ERROR timesheet openerp.addons.base.ir.ir_ui_view: |
1163 | + Can't render view for model: project.task --> |
1164 | + |
1165 | + <record id="project.view_task_form2" model="ir.ui.view"> |
1166 | <field name="name">project.task.form</field> |
1167 | <field name="model">project.task</field> |
1168 | - <field name="inherit_id" ref="project.view_task_form2"/> |
1169 | - <field name="type">form</field> |
1170 | + <field eval="1" name="priority" /> |
1171 | <field name="arch" type="xml"> |
1172 | - <xpath expr="/form/notebook/page/field[@name='work_ids']" position="replace"> |
1173 | - <field colspan="4" name="work_ids" nolabel="1" attrs="{'invisible':[('state','in',['draft'])],'readonly':[('state','=','done')]}"> |
1174 | - <tree string="Task Work" editable="top"> |
1175 | - <field name="user_id" on_change="on_change_user_id(user_id)" required="1" invisible="1"/> |
1176 | - <field name="name"/> |
1177 | - <field name="unit_amount" on_change="on_change_unit_amount(product_id, unit_amount, False, product_uom_id,journal_id, parent.id, to_invoice)" sum="Total time" widget="float_time"/> |
1178 | - <field name="date" on_change="on_change_date(date)"/> |
1179 | - <field name="journal_id" invisible="1"/> |
1180 | - <field domain="[('type','=','normal')]" name="account_id" invisible="1"/> |
1181 | - <field name="product_id" on_change="on_change_unit_amount(product_id, unit_amount, False, product_uom_id,journal_id, parent.id, to_invoice)" required="1" domain="[('type','=','service')]" invisible="1"/> |
1182 | - <field name="product_uom_id" on_change="on_change_unit_amount(product_id, unit_amount, False, product_uom_id,journal_id, parent.id, to_invoice)" invisible="1"/> |
1183 | - <field name="amount" sum="Total cost" invisible="1"/> |
1184 | - <field name="general_account_id" invisible="1"/> |
1185 | - <field name="to_invoice" /> |
1186 | - </tree> |
1187 | - <form string="Task Work" editable="top"> |
1188 | - <field name="user_id" on_change="on_change_user_id(user_id)" required="1"/> |
1189 | - <field name="name" default_focus="1"/> |
1190 | - <field name="unit_amount" on_change="on_change_unit_amount(product_id, unit_amount, False, product_uom_id,journal_id, parent.id, to_invoice)" sum="Total time" widget="float_time"/> |
1191 | - <field name="date" on_change="on_change_date(date)"/> |
1192 | - <field name="journal_id" invisible="1"/> |
1193 | - <field domain="[('type','=','normal')]" name="account_id" invisible="1"/> |
1194 | - <field name="product_id" on_change="on_change_unit_amount(product_id, unit_amount, False, product_uom_id,journal_id, parent.id, to_invoice)" required="1" domain="[('type','=','service')]" invisible="1"/> |
1195 | - <field name="product_uom_id" on_change="on_change_unit_amount(product_id, unit_amount, False, product_uom_id,journal_id, parent.id, to_invoice)" invisible="1"/> |
1196 | - <field name="amount" sum="Total cost" invisible="1"/> |
1197 | - <field name="general_account_id" invisible="1"/> |
1198 | - <field name="to_invoice" /> |
1199 | - </form> |
1200 | - </field> |
1201 | - </xpath> |
1202 | + <form string="Project" version="7.0"> |
1203 | + <header> |
1204 | + <!-- <button name="do_open" string="Start Task" type="object" |
1205 | + states="draft,pending" class="oe_highlight"/> <button name="do_draft" string="Draft" |
1206 | + type="object" states="cancel,done"/> --> |
1207 | + <button name="project_task_reevaluate" |
1208 | + string="Reactivate" type="object" states="cancelled,done" |
1209 | + context="{'button_reactivate':True}" groups="base.group_user" /> |
1210 | + <button name="action_close" string="Done" |
1211 | + type="object" states="draft,open,pending" |
1212 | + groups="base.group_user" /> |
1213 | + <button name="do_cancel" string="Cancel Task" |
1214 | + type="object" states="draft,open,pending" |
1215 | + groups="base.group_user" /> |
1216 | + <field name="stage_id" widget="statusbar" |
1217 | + clickable="True" /> |
1218 | + </header> |
1219 | + <sheet string="Task"> |
1220 | + <h1> |
1221 | + <field name="name" placeholder="Task summary..." /> |
1222 | + </h1> |
1223 | + <group> |
1224 | + <group> |
1225 | + <field name="project_id" |
1226 | + on_change="onchange_project(project_id)" |
1227 | + context="{'default_use_tasks':1}" /> |
1228 | + <field name="user_id" |
1229 | + attrs="{'readonly':[('state','in',['done', 'cancelled'])]}" |
1230 | + options='{"no_open": True}' /> |
1231 | + <field name="planned_hours" |
1232 | + widget="float_time" |
1233 | + groups="project.group_time_work_estimation_tasks" |
1234 | + on_change="onchange_planned(planned_hours, effective_hours)" /> |
1235 | + </group> |
1236 | + <group> |
1237 | + <field name="date_deadline" |
1238 | + attrs="{'readonly':[('state','in',['done', 'cancelled'])]}" /> |
1239 | + <field name="categ_ids" widget="many2many_tags" /> |
1240 | + <field name="progress" widget="progressbar" |
1241 | + groups="project.group_time_work_estimation_tasks" |
1242 | + attrs="{'invisible':[('state','=','cancelled')]}" /> |
1243 | + </group> |
1244 | + </group> |
1245 | + <notebook> |
1246 | + <page string="Description"> |
1247 | + <field name="description" |
1248 | + attrs="{'readonly':[('state','=','done')]}" |
1249 | + placeholder="Add a Description..." /> |
1250 | + <field name="work_ids"> |
1251 | + <tree string="Task Work" |
1252 | + editable="top"> |
1253 | + <field name="user_id" |
1254 | + on_change="on_change_user_id(user_id)" |
1255 | + required="1" invisible="1" /> |
1256 | + <field name="name" /> |
1257 | + <field name="unit_amount" |
1258 | + on_change="on_change_unit_amount(product_id, unit_amount, False, product_uom_id,journal_id, parent.id, to_invoice)" |
1259 | + sum="Total time" widget="float_time" /> |
1260 | + <field name="date" |
1261 | + on_change="on_change_date(date)" /> |
1262 | + <field name="journal_id" |
1263 | + invisible="1" /> |
1264 | + <field domain="[('type','=','normal')]" |
1265 | + name="account_id" invisible="1" /> |
1266 | + <field name="product_id" |
1267 | + on_change="on_change_unit_amount(product_id, unit_amount, False, product_uom_id,journal_id, parent.id, to_invoice)" |
1268 | + required="1" |
1269 | + domain="[('type','=','service')]" |
1270 | + invisible="1" /> |
1271 | + <field name="product_uom_id" |
1272 | + on_change="on_change_unit_amount(product_id, unit_amount, False, product_uom_id,journal_id, parent.id, to_invoice)" |
1273 | + invisible="1" /> |
1274 | + <field name="amount" sum="Total cost" |
1275 | + invisible="1" /> |
1276 | + <field name="general_account_id" |
1277 | + invisible="1" /> |
1278 | + <field name="to_invoice" /> |
1279 | + </tree> |
1280 | + <form string="Task Work" |
1281 | + editable="top"> |
1282 | + <field name="user_id" |
1283 | + on_change="on_change_user_id(user_id)" |
1284 | + required="1" /> |
1285 | + <field name="name" |
1286 | + default_focus="1" /> |
1287 | + <field name="unit_amount" |
1288 | + on_change="on_change_unit_amount(product_id, unit_amount, False, product_uom_id,journal_id, parent.id, to_invoice)" |
1289 | + sum="Total time" widget="float_time" /> |
1290 | + <field name="date" |
1291 | + on_change="on_change_date(date)" /> |
1292 | + <field name="journal_id" |
1293 | + invisible="1" /> |
1294 | + <field domain="[('type','=','normal')]" |
1295 | + name="account_id" invisible="1" /> |
1296 | + <field name="product_id" |
1297 | + on_change="on_change_unit_amount(product_id, unit_amount, False, product_uom_id,journal_id, parent.id, to_invoice)" |
1298 | + required="1" |
1299 | + domain="[('type','=','service')]" |
1300 | + invisible="1" /> |
1301 | + <field name="product_uom_id" |
1302 | + on_change="on_change_unit_amount(product_id, unit_amount, False, product_uom_id,journal_id, parent.id, to_invoice)" |
1303 | + invisible="1" /> |
1304 | + <field name="amount" sum="Total cost" |
1305 | + invisible="1" /> |
1306 | + <field name="general_account_id" |
1307 | + invisible="1" /> |
1308 | + <field name="to_invoice" /> |
1309 | + </form> |
1310 | + </field> |
1311 | + <group> |
1312 | + <group class="oe_subtotal_footer oe_right" |
1313 | + name="project_hours" |
1314 | + groups="project.group_time_work_estimation_tasks"> |
1315 | + <field name="effective_hours" |
1316 | + widget="float_time" /> |
1317 | + <label for="remaining_hours" |
1318 | + string="Remaining" |
1319 | + groups="project.group_time_work_estimation_tasks" /> |
1320 | + <div> |
1321 | + <field name="remaining_hours" |
1322 | + widget="float_time" |
1323 | + attrs="{'readonly':[('state','in',('done','cancelled'))]}" |
1324 | + groups="project.group_time_work_estimation_tasks" /> |
1325 | + </div> |
1326 | + <field name="total_hours" |
1327 | + widget="float_time" |
1328 | + class="oe_subtotal_footer_separator" /> |
1329 | + </group> |
1330 | + </group> |
1331 | + <div class="oe_clear" /> |
1332 | + </page> |
1333 | + <page string="Delegation" |
1334 | + groups="project.group_delegate_task"> |
1335 | + <button |
1336 | + name="%(project.action_project_task_delegate)d" |
1337 | + string="Delegate" type="action" |
1338 | + states="pending,open,draft" groups="project.group_delegate_task" /> |
1339 | + <separator string="Parent Tasks" /> |
1340 | + <field name="parent_ids" /> |
1341 | + <separator string="Delegated tasks" /> |
1342 | + <field name="child_ids"> |
1343 | + <tree string="Delegated tasks"> |
1344 | + <field name="name" /> |
1345 | + <field name="user_id" /> |
1346 | + <field name="stage_id" /> |
1347 | + <field name="state" |
1348 | + invisible="1" /> |
1349 | + <field name="effective_hours" |
1350 | + widget="float_time" /> |
1351 | + <field name="progress" |
1352 | + widget="progressbar" /> |
1353 | + <field name="remaining_hours" |
1354 | + widget="float_time" /> |
1355 | + <field name="date_deadline" /> |
1356 | + </tree> |
1357 | + </field> |
1358 | + </page> |
1359 | + <page string="Extra Info" |
1360 | + attrs="{'readonly':[('state','=','done')]}"> |
1361 | + <group col="4"> |
1362 | + <field name="priority" groups="base.group_user" /> |
1363 | + <field name="sequence" /> |
1364 | + <field name="partner_id" /> |
1365 | + <field name="state" invisible="1" /> |
1366 | + <field name="company_id" |
1367 | + groups="base.group_multi_company" |
1368 | + widget="selection" /> |
1369 | + </group> |
1370 | + <group> |
1371 | + <group string="Gantt View"> |
1372 | + <field name="date_start" /> |
1373 | + <field name="date_end" /> |
1374 | + </group> |
1375 | + <group> |
1376 | + </group> |
1377 | + </group> |
1378 | + </page> |
1379 | + </notebook> |
1380 | + </sheet> |
1381 | + <div class="oe_chatter"> |
1382 | + <field name="message_follower_ids" widget="mail_followers" |
1383 | + groups="base.group_user" /> |
1384 | + <field name="message_ids" widget="mail_thread" /> |
1385 | + </div> |
1386 | + </form> |
1387 | </field> |
1388 | </record> |
1389 | - |
1390 | + |
1391 | </data> |
1392 | </openerp> |
1393 | \ No newline at end of file |
1394 | |
1395 | === removed file 'timesheet_task/tmp_file_for_project_indicator.py' |
1396 | --- timesheet_task/tmp_file_for_project_indicator.py 2012-06-06 13:14:12 +0000 |
1397 | +++ timesheet_task/tmp_file_for_project_indicator.py 1970-01-01 00:00:00 +0000 |
1398 | @@ -1,29 +0,0 @@ |
1399 | -def _progress_rate(self, cr, uid, ids, names, arg, context=None): |
1400 | - """As OpenERP SA made a query for this function field (perf. reason obviously), |
1401 | - I must overide it all.""" |
1402 | - result = {}.fromkeys(ids, 0.0) |
1403 | - progress = {} |
1404 | - if not ids: |
1405 | - return res |
1406 | - cr.execute('''SELECT project_id, |
1407 | - sum(planned_hours) as sum_planned_hours, |
1408 | - sum(total_hours) as sum_total_hours, |
1409 | - sum(effective_hours) as sum_effective_hours, |
1410 | - sum(remaining_hours) as remaining_hours, |
1411 | - sum(deduced_hours) as deduced_hours |
1412 | - FROM project_task |
1413 | - WHERE project_id in %s |
1414 | - AND state<>'cancelled' |
1415 | - GROUP BY project_id''', (tuple(ids),)) |
1416 | - |
1417 | - res = cr.dictfetchall() |
1418 | - for stat in res: |
1419 | - project = self.browse(cr, uid, res['project_id'], context=context) |
1420 | - progr = (stat['sum_planned_hours'] and |
1421 | - round(100.0 * stat['sum_total_hours'] / stat['sum_planned_hours'], 2) or 0.0), |
1422 | - result[project.id] = {'planned_hours': stat['sum_planned_hours'], |
1423 | - 'effective_hours': stat['sum_effective_hours'], |
1424 | - 'total_hours': stat['sum_total_hours'], |
1425 | - 'progress_rate': progr, |
1426 | - 'deduced_hours': stat['sum_deduced_hours']} |
1427 | - return res |
1428 | \ No newline at end of file |
I pushed a fix to restore and slightly improve the Current Year/Month/Week filters.
I did manual testing and it works fine.
The code in timesheet.js is duplicating a lot of code of hr_timesheet_sheet, but there is no other way around unless proper hooks are inserted upstream.