Merge lp:~openerp-dev/openobject-addons/trunk-form-v2-project-chs into lp:~openerp-dev/openobject-addons/trunk-form-v2-fme
- trunk-form-v2-project-chs
- Merge into trunk-form-v2-fme
Proposed by
Christophe Simonis (OpenERP)
Status: | Needs review |
---|---|
Proposed branch: | lp:~openerp-dev/openobject-addons/trunk-form-v2-project-chs |
Merge into: | lp:~openerp-dev/openobject-addons/trunk-form-v2-fme |
Diff against target: |
1100 lines (+812/-11) 17 files modified
project/__openerp__.py (+3/-1) project/project.py (+39/-1) project/project_view.xml (+91/-6) project/static/src/css/project.css (+231/-0) project/static/src/js/dropdown.js (+92/-0) project/static/src/js/project.js (+71/-0) project_issue/__openerp__.py (+1/-0) project_issue/project_issue.py (+49/-2) project_issue/project_issue_menu.xml (+1/-0) project_issue/project_issue_view.xml (+25/-0) project_issue/static/src/js/project_issue.js (+14/-0) project_long_term/project_long_term.py (+39/-1) project_long_term/project_long_term_view.xml (+32/-0) project_timesheet/__openerp__.py (+1/-0) project_timesheet/project_timesheet.py (+60/-0) project_timesheet/project_timesheet_view.xml (+42/-0) project_timesheet/static/src/js/project_timesheet.js (+21/-0) |
To merge this branch: | bzr merge lp:~openerp-dev/openobject-addons/trunk-form-v2-project-chs |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Antony Lesuisse (OpenERP) | Needs Fixing | ||
Review via email: mp+101402@code.launchpad.net |
Commit message
Description of the change
mergeable ?
To post a comment you must log in.
- 6722. By Christophe Simonis (OpenERP)
-
[~IMP] project_*: simplify open_* actions for project kanban view
Revision history for this message
Antony Lesuisse (OpenERP) (al-openerp) wrote : | # |
review:
Needs Fixing
Revision history for this message
Antony Lesuisse (OpenERP) (al-openerp) wrote : | # |
The merge should now target trunk.
Unmerged revisions
- 6722. By Christophe Simonis (OpenERP)
-
[~IMP] project_*: simplify open_* actions for project kanban view
- 6721. By Christophe Simonis (OpenERP)
-
[~FIX] project: correct kanban css
- 6720. By Christophe Simonis (OpenERP)
-
[MERGE] lp:~openerp-dev/openobject-addons/trunk-project-gallery-apa
- 6719. By Christophe Simonis (OpenERP)
-
[FIX] project: remove dependence to wiki module
- 6718. By Christophe Simonis (OpenERP)
-
[FIX] project: correct dependencies
- 6717. By Christophe Simonis (OpenERP)
-
[FIX] remove Antony's shit
- 6716. By Quentin (OpenERP) <email address hidden>
-
[IMP] sale: applied changes in sale order form view as per last trunk
- 6715. By Quentin (OpenERP) <email address hidden>
-
[FIX] base_setup: resolved tag mismatch
- 6714. By Antony Lesuisse (OpenERP)
-
crm.lead
- 6713. By Antony Lesuisse (OpenERP)
-
sale html to form
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'project/__openerp__.py' |
2 | --- project/__openerp__.py 2012-04-10 12:09:38 +0000 |
3 | +++ project/__openerp__.py 2012-04-10 16:40:13 +0000 |
4 | @@ -29,7 +29,7 @@ |
5 | "sequence": 8, |
6 | 'complexity': "easy", |
7 | "images": ["images/gantt.png", "images/project_dashboard.jpeg","images/project_task_tree.jpeg","images/project_task.jpeg","images/project.jpeg","images/task_analysis.jpeg"], |
8 | - "depends": ["base_setup", "product", "analytic", "board", "mail", "resource"], |
9 | + "depends": ["base_setup", "product", "analytic", "board", "mail", "resource","web_kanban"], |
10 | "description": """ |
11 | Project management module tracks multi-level projects, tasks, work done on tasks, eso. |
12 | ====================================================================================== |
13 | @@ -70,6 +70,8 @@ |
14 | 'installable': True, |
15 | 'auto_install': False, |
16 | 'application': True, |
17 | + 'css': ['static/src/css/project.css'], |
18 | + 'js': ['static/src/js/dropdown.js','static/src/js/project.js'], |
19 | 'certificate': '0075116868317', |
20 | } |
21 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |
22 | |
23 | === modified file 'project/project.py' |
24 | --- project/project.py 2012-04-03 17:21:08 +0000 |
25 | +++ project/project.py 2012-04-10 16:40:13 +0000 |
26 | @@ -154,6 +154,14 @@ |
27 | if proj.tasks: |
28 | raise osv.except_osv(_('Operation Not Permitted !'), _('You cannot delete a project containing tasks. I suggest you to desactivate it.')) |
29 | return super(project, self).unlink(cr, uid, ids, *args, **kwargs) |
30 | + |
31 | + def _open_task(self, cr, uid, ids, field_name, arg, context=None): |
32 | + open_task={} |
33 | + task_pool=self.pool.get('project.task') |
34 | + for id in ids: |
35 | + task_ids = task_pool.search(cr, uid, [('project_id', '=', id)]) |
36 | + open_task[id] = len(task_ids) |
37 | + return open_task |
38 | |
39 | _columns = { |
40 | 'complete_name': fields.function(_complete_name, string="Project Name", type='char', size=250), |
41 | @@ -191,7 +199,35 @@ |
42 | 'warn_header': fields.text('Mail Header', help="Header added at the beginning of the email for the warning message sent to the customer when a task is closed.", states={'close':[('readonly',True)], 'cancelled':[('readonly',True)]}), |
43 | 'warn_footer': fields.text('Mail Footer', help="Footer added at the beginning of the email for the warning message sent to the customer when a task is closed.", states={'close':[('readonly',True)], 'cancelled':[('readonly',True)]}), |
44 | 'type_ids': fields.many2many('project.task.type', 'project_task_type_rel', 'project_id', 'type_id', 'Tasks Stages', states={'close':[('readonly',True)], 'cancelled':[('readonly',True)]}), |
45 | + 'task': fields.boolean('Task',help = "If you check this field tasks appears in kanban view"), |
46 | + 'open_task': fields.function(_open_task , type='integer',string="Open Tasks"), |
47 | + 'color': fields.integer('Color Index'), |
48 | } |
49 | + def dummy(self, cr, uid, ids, context=None): |
50 | + return False |
51 | + |
52 | + def open_tasks(self, cr, uid, ids, context=None): |
53 | + #Open the View for the Tasks for the project |
54 | + """ |
55 | + This opens Tasks views |
56 | + @return :Dictionary value for task view |
57 | + """ |
58 | + if context is None: |
59 | + context = {} |
60 | + if ids: |
61 | + context = dict(context, search_default_project_id=ids[0]) |
62 | + return { |
63 | + 'name': _('Task'), |
64 | + 'context': context, |
65 | + 'view_type': 'form', |
66 | + 'view_mode': 'kanban,tree,calendar,form', |
67 | + 'res_model': 'project.task', |
68 | + 'view_id': False, |
69 | + 'domain':[('project_id','in',ids)], |
70 | + 'type': 'ir.actions.act_window', |
71 | + 'nodestroy': True |
72 | + } |
73 | + |
74 | def _get_type_common(self, cr, uid, context): |
75 | ids = self.pool.get('project.task.type').search(cr, uid, [('project_default','=',1)], context=context) |
76 | return ids |
77 | @@ -201,7 +237,8 @@ |
78 | 'active': True, |
79 | 'priority': 1, |
80 | 'sequence': 10, |
81 | - 'type_ids': _get_type_common |
82 | + 'type_ids': _get_type_common, |
83 | + 'task' : True, |
84 | } |
85 | |
86 | # TODO: Why not using a SQL contraints ? |
87 | @@ -720,6 +757,7 @@ |
88 | 'sequence': 10, |
89 | 'active': True, |
90 | 'user_id': lambda obj, cr, uid, context: uid, |
91 | + 'project_id':lambda self, cr, uid, context: context.get('active_id',False), |
92 | 'company_id': lambda self, cr, uid, c: self.pool.get('res.company')._company_default_get(cr, uid, 'project.task', context=c) |
93 | } |
94 | |
95 | |
96 | === modified file 'project/project_view.xml' |
97 | --- project/project_view.xml 2012-04-10 12:09:38 +0000 |
98 | +++ project/project_view.xml 2012-04-10 16:40:13 +0000 |
99 | @@ -19,7 +19,7 @@ |
100 | <field name="type">form</field> |
101 | <field name="arch" type="xml"> |
102 | <form string="Project"> |
103 | - <group colspan="6" col="6"> |
104 | + <group colspan="4" col="6"> |
105 | <field name="name" string="Project Name" select="1"/> |
106 | <field name="analytic_account_id" invisible="1" required="0"/> |
107 | <field name="parent_id" string="Parent" domain="[('id','!=',analytic_account_id)]" context="{'current_model': 'project.project'}"/> |
108 | @@ -30,12 +30,17 @@ |
109 | </group> |
110 | <notebook colspan="4"> |
111 | <page string="Administration"> |
112 | + <group col="2" colspan="2" name="kanban"> |
113 | + <separator colspan="2" string="Project Management"/> |
114 | + <field name="task"/> |
115 | + </group> |
116 | <group col="2" colspan="2"> |
117 | - <separator colspan="2" string="Performance"/> |
118 | + <separator colspan="4" string="Performance"/> |
119 | <field name="planned_hours" widget="float_time"/> |
120 | <field name="effective_hours" widget="float_time" /> |
121 | <field name="resource_calendar_id"/> |
122 | </group> |
123 | + <newline/> |
124 | <group col="2" colspan="2" name="misc"> |
125 | <separator colspan="4" string="Miscelleanous"/> |
126 | <field name="company_id" select="1" groups="base.group_multi_company" widget="selection" required="1"/> |
127 | @@ -154,6 +159,86 @@ |
128 | </tree> |
129 | </field> |
130 | </record> |
131 | + |
132 | + <record model="ir.ui.view" id="view_project_kanban"> |
133 | + <field name="name">project.project.kanban</field> |
134 | + <field name="model">project.project</field> |
135 | + <field name="type">kanban</field> |
136 | + <field name="arch" type="xml"> |
137 | + <kanban> |
138 | + <field name="effective_hours"/> |
139 | + <field name="total_hours"/> |
140 | + <field name="date"/> |
141 | + <field name="name"/> |
142 | + <field name="members"/> |
143 | + <field name="task"/> |
144 | + <field name="user_id"/> |
145 | + <field name="date"/> |
146 | + <field name="color"/> |
147 | + <field name="open_task"/> |
148 | + <templates> |
149 | + <t t-name="kanban-box"> |
150 | + <div class="project_vignettes"> |
151 | + <li t-attf-class="oe_project_kanban_vignette #{kanban_color(record.color.raw_value)}"> |
152 | + <a href="#" class="oe_project_kanban_action dropdown-toggle"><span class="oe_i">B</span></a> |
153 | + <ul class="dropdown-menu"> |
154 | + <li ><a type="edit" >Edit...</a></li> |
155 | + <li ><a type="delete">Delete</a></li> |
156 | + <!--li> |
157 | + <ul class="color-chooser"> |
158 | + <li><a t-att-id="record.id.value" class="bgcolor_steelblue"><span class="steelblue square"></span></a></li> |
159 | + <li><a t-att-id="record.id.value" class="bgcolor_firebrick"><span class="firebrick square"></span></a></li> |
160 | + <li><a t-att-id="record.id.value" class="bgcolor_khaki"><span class="khaki square"></span></a></li> |
161 | + <li><a t-att-id="record.id.value" class="bgcolor_thistle"><span class="thistle square"></span></a></li> |
162 | + <li><a t-att-id="record.id.value" class="bgcolor_orange"><span class="orange square"></span></a></li> |
163 | + </ul> |
164 | + </li--> |
165 | + </ul> |
166 | + <h4><t t-esc="record.name.value.substr(0,32)"/><t t-if="record.name.value.length > 32">...</t></h4> |
167 | + <h4 id="list" height="10px"> |
168 | + <a id="1"> |
169 | + <t t-if="record.task.raw_value"> |
170 | + <button name="open_tasks" id = "open_tasks" class="oe_project_buttons" type="object"><t t-if="record.open_task.value <= 1"> Task</t><t t-if="record.open_task.value > 1"> Tasks</t>(<t t-esc="record.open_task.value"/>)</button> |
171 | + </t> |
172 | + </a> |
173 | + </h4> |
174 | + <br /> |
175 | + <button class="click_button" type="object"> |
176 | + <table class="project_fields"> |
177 | + <tr id="deadline" t-if="record.date.raw_value"> |
178 | + <th align="left">Deadline</th> |
179 | + <td align="left"> |
180 | + <t t-esc="record.date.raw_value.toString('MMMM')"/> |
181 | + <t t-esc="record.date.raw_value.getDate()"/>, |
182 | + <t t-esc="record.date.raw_value.getFullYear()"/> |
183 | + </td> |
184 | + </tr> |
185 | + <tr> |
186 | + <th align="left" width="70px">Progress</th> |
187 | + <td align="left"> |
188 | + <t t-esc="Math.round(record.effective_hours.raw_value/24)"/>/<t t-esc="Math.round(record.total_hours.raw_value/24)"/> days |
189 | + </td> |
190 | + </tr> |
191 | + </table> |
192 | + <t t-if="record.members.raw_value.length > 7"> |
193 | + <t t-foreach="record.members.raw_value" t-as="member"> |
194 | + <img t-att-src="kanban_image('res.users', 'avatar', member)" t-att-id="member" class="project_avatar"/> |
195 | + </t> |
196 | + </t> |
197 | + <t t-if="record.members.raw_value.length <= 7"> |
198 | + <br/><br/> |
199 | + <t t-foreach="record.members.raw_value" t-as="member"> |
200 | + <img t-att-src="kanban_image('res.users', 'avatar', member)" t-att-id="member" class="project_avatar"/> |
201 | + </t> |
202 | + </t> |
203 | + </button> |
204 | + </li> |
205 | + </div> |
206 | + </t> |
207 | + </templates> |
208 | + </kanban> |
209 | + </field> |
210 | + </record> |
211 | |
212 | <record id="view_project_project_gantt" model="ir.ui.view"> |
213 | <field name="name">project.project.gantt</field> |
214 | @@ -170,8 +255,8 @@ |
215 | <field name="res_model">project.project</field> |
216 | <field name="view_type">form</field> |
217 | <field name="domain">[]</field> |
218 | - <field name="view_mode">tree,form,gantt</field> |
219 | - <field name="view_id" ref="view_project"/> |
220 | + <field name="view_mode">kanban,tree,form,gantt</field> |
221 | + <field name="view_id" ref="view_project_kanban"/> |
222 | <field name="search_view_id" ref="view_project_project_filter"/> |
223 | <field name="context">{}</field> |
224 | <field name="help">A project contains a set of tasks or issues that will be performed by your resources assigned to it. A project can be hierarchically structured, as a child of a Parent Project. This allows you to design large project structures with different phases spread over the project duration cycle. Each user can set his default project in his own preferences to automatically filter the tasks or issues he usually works on. If you choose to invoice the time spent on a project task, you can find project tasks to be invoiced in the billing section.</field> |
225 | @@ -621,10 +706,10 @@ |
226 | |
227 | <menuitem id="menu_tasks_config" name="GTD" parent="project.menu_definitions" sequence="1"/> |
228 | |
229 | - <menuitem id="menu_project_config_project" name="Projects and Stages" parent="menu_definitions" sequence="1"/> |
230 | + <menuitem id="menu_project_config_project" name="Stages" parent="menu_definitions" sequence="1"/> |
231 | |
232 | <menuitem action="open_task_type_form" id="menu_task_types_view" parent="menu_project_config_project" sequence="2" groups="base.group_no_one"/> |
233 | - <menuitem action="open_view_project_all" id="menu_open_view_project_all" parent="menu_project_config_project" sequence="1" groups="base.group_no_one"/> |
234 | + <menuitem action="open_view_project_all" id="menu_projects" name="Projects" parent="menu_project_management" sequence="1"/> |
235 | |
236 | <act_window context="{'search_default_user_id': [active_id], 'default_user_id': active_id}" id="act_res_users_2_project_project" name="User's projects" res_model="project.project" src_model="res.users" view_mode="tree,form" view_type="form"/> |
237 | |
238 | |
239 | === added directory 'project/static/src/css' |
240 | === added file 'project/static/src/css/project.css' |
241 | --- project/static/src/css/project.css 1970-01-01 00:00:00 +0000 |
242 | +++ project/static/src/css/project.css 2012-04-10 16:40:13 +0000 |
243 | @@ -0,0 +1,231 @@ |
244 | +.project_fields { |
245 | + margin-top: 1px; |
246 | + margin-bottom: 1px; |
247 | + font-size: 11px; |
248 | + } |
249 | +.project_fields td { |
250 | + border: none; |
251 | + padding: 2px 0 2px 8px; } |
252 | +.project_fields th { |
253 | + padding: 0; |
254 | + border-right: 1px solid #dddddd; |
255 | + vertical-align: top; |
256 | + margin-right: 8px; } |
257 | + |
258 | + .project_vignettes li { |
259 | + float: left; } |
260 | + .project_vignettes .project_avatar { |
261 | + width: 28px; |
262 | + height: 28px; } |
263 | + .project_vignettes .project_fields { |
264 | + width: 100%; } |
265 | + .project_vignettes .project_fields th { |
266 | + font-weight: normal; } |
267 | + .project_vignettes .project_fields td { |
268 | + color: #888888; } |
269 | + .project_vignettes h4 a { |
270 | + color: #4c4c4c; } |
271 | + |
272 | + |
273 | + .project_vignettes > li h4 { |
274 | + margin-bottom: 2px; } |
275 | + |
276 | +.oe_project_buttons { |
277 | + padding: 0px 0px !important; |
278 | + background: none !important; |
279 | + background-color: transparent !important; |
280 | + border: hidden !important; |
281 | + color: #8A89BA !important; |
282 | + |
283 | +} |
284 | + |
285 | +.oe_project_buttons:hover { |
286 | + cursor: pointer; |
287 | + color: #0000FF; |
288 | +} |
289 | + |
290 | +.project_avatar { |
291 | + -moz-border-radius: 4px; |
292 | + -webkit-border-radius: 4px; |
293 | + border-radius: 4px; |
294 | + -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); |
295 | + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); |
296 | + -box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); } |
297 | + |
298 | + |
299 | +.click_button { |
300 | + background: none !important; |
301 | + background-color: transparent !important; |
302 | + border: hidden !important; |
303 | + min-height: 155px; |
304 | + min-width: 265px; |
305 | + border: hidden; |
306 | + margin-left: 6px !important; |
307 | + margin-top: 3px !important; |
308 | + text-align: left; |
309 | + vertical-align: super; |
310 | + font-size: 11px; |
311 | +} |
312 | + |
313 | +.dropdown-menu { |
314 | + display: none; |
315 | + position: absolute; } |
316 | + |
317 | +.dropdown { |
318 | + position: relative; } |
319 | + |
320 | +.dropdown-toggle:after { |
321 | + width: 0; |
322 | + height: 0; |
323 | + display: inline-block; |
324 | + content: "&darr"; |
325 | + text-indent: -99999px; |
326 | + vertical-align: top; |
327 | + margin-top: 8px; |
328 | + margin-left: 4px; |
329 | + border-left: 4px solid transparent; |
330 | + border-right: 4px solid transparent; |
331 | + border-top: 4px solid white; |
332 | + filter: alpha(opacity=50); |
333 | + -khtml-opacity: 0.5; |
334 | + -moz-opacity: 0.5; |
335 | + opacity: 0.5; } |
336 | + |
337 | + |
338 | + .oe_project_kanban_vignette .dropdown-menu .color-chooser { |
339 | + padding: 0 3px; } |
340 | + .oe_project_kanban_vignette .dropdown-menu .color-chooser li { |
341 | + float: left; } |
342 | + .oe_project_kanban_vignette .dropdown-menu .color-chooser li a { |
343 | + padding: 2px; } |
344 | +a.oe_project_kanban_action { |
345 | + position: absolute; |
346 | + right: 0; |
347 | + display: none; |
348 | + } |
349 | + a.oe_project_kanban_action:hover { |
350 | + text-decoration: none; } |
351 | + a.oe_project_kanban_action .oe_i { |
352 | + color: #4c4c4c; } |
353 | +.square { |
354 | + display: inline-block; |
355 | + width: 18px; |
356 | + height: 18px; } |
357 | + |
358 | +.oe_kanban_color_1 { |
359 | + background: steelblue; |
360 | +} |
361 | +.oe_kanban_color_2 { |
362 | + background: firebrick; |
363 | +} |
364 | +.oe_kanban_color_3 { |
365 | + background: khaki; |
366 | +} |
367 | +.oe_kanban_color_4 { |
368 | + background: thistle; |
369 | +} |
370 | +.oe_kanban_color_5 { |
371 | + background: orange; |
372 | +} |
373 | + |
374 | + |
375 | +.steelblue { |
376 | + background: steelblue; } |
377 | + |
378 | +.firebrick { |
379 | + background: firebrick; } |
380 | + |
381 | +.khaki { |
382 | + background: khaki; } |
383 | + |
384 | +.thistle { |
385 | + background: thistle; } |
386 | + |
387 | +.orange { |
388 | + background: orange; } |
389 | +.open { |
390 | + display: block; |
391 | + } |
392 | + .open .dropdown-menu { |
393 | + display: block; } |
394 | + |
395 | + |
396 | +a.oe_project_kanban_action { |
397 | + position: absolute; |
398 | + right: 0; |
399 | + } |
400 | + a.oe_project_kanban_action:hover { |
401 | + text-decoration: none; |
402 | + } |
403 | + a.oe_project_kanban_action .eo_i { |
404 | + color: #4c4c4c; } |
405 | + |
406 | + |
407 | +.oe_project_kanban_vignette { |
408 | + position: relative; |
409 | + min-height: 50px; |
410 | + background: white; |
411 | + border: 1px solid #d8d8d8; |
412 | + border-bottom-color: #b9b9b9; |
413 | + padding: 6px; |
414 | + margin: 6px 0; |
415 | + display: inline-block; |
416 | + -moz-border-radius: 4px; |
417 | + -webkit-border-radius: 4px; |
418 | + border-radius: 4px; |
419 | + |
420 | +} |
421 | + .oe_project_kanban_vignette:last-child { |
422 | + margin-bottom: 0; } |
423 | + .oe_project_kanban_vignette:hover { |
424 | + -moz-box-shadow: 0 0 3px rgba(0, 0, 0, 0.6); |
425 | + -webkit-box-shadow: 0 0 3px rgba(0, 0, 0, 0.6); |
426 | + -box-shadow: 0 0 3px rgba(0, 0, 0, 0.6); } |
427 | + .oe_project_kanban_vignette h4 { |
428 | + margin: 0 0 2px; } |
429 | + |
430 | + |
431 | +.oe_project_kanban_vignette .dropdown-menu { |
432 | + top: 30px; |
433 | + right: -140px; |
434 | + padding: 4px; |
435 | + border: 1px solid #afafb6; |
436 | + width: 160px; |
437 | + overflow-x: hidden; |
438 | + z-index: 900; |
439 | + background: white; |
440 | + -moz-border-radius: 3px; |
441 | + -webkit-border-radius: 3px; |
442 | + border-radius: 3px; |
443 | + -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3); |
444 | + -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3); |
445 | + -box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3); } |
446 | + .oe_project_kanban_vignette .dropdown-menu p { |
447 | + margin-left: 12px; } |
448 | + .oe_project_kanban_vignette .dropdown-menu li { |
449 | + float: none; |
450 | + display: block; |
451 | + background-color: none; } |
452 | + .oe_project_kanban_vignette .dropdown-menu li a { |
453 | + display: block; |
454 | + padding: 3px 6px; |
455 | + clear: both; |
456 | + font-weight: normal; |
457 | + line-height: 14px; |
458 | + color: #4c4c4c; |
459 | + text-decoration: none; } |
460 | + .oe_project_kanban_vignette .dropdown-menu li a:hover { |
461 | + background: #f0f0fa; |
462 | + background: -moz-linear-gradient(#f0f0fa, #eeeef6); |
463 | + background: -webkit-gradient(linear, left top, left bottom, from(#f0f0fa), to(#eeeef6)); |
464 | + background: -webkit-linear-gradient(#f0f0fa, #eeeef6); |
465 | + -moz-box-shadow: none; |
466 | + -webkit-box-shadow: none; |
467 | + -box-shadow: none; } |
468 | + |
469 | +.oe_project_kanban_vignette .dropdown-menu .color-chooser { |
470 | + padding: 0 3px; } |
471 | + .oe_project_kanban_vignette .dropdown-menu .color-chooser li { |
472 | + float: left; } |
473 | + .oe_project_kanban_vignette .dropdown-menu .color-chooser li a { |
474 | + padding: 2px; } |
475 | |
476 | === added file 'project/static/src/img/tasks_icon.png' |
477 | Binary files project/static/src/img/tasks_icon.png 1970-01-01 00:00:00 +0000 and project/static/src/img/tasks_icon.png 2012-04-10 16:40:13 +0000 differ |
478 | === added directory 'project/static/src/js' |
479 | === added file 'project/static/src/js/dropdown.js' |
480 | --- project/static/src/js/dropdown.js 1970-01-01 00:00:00 +0000 |
481 | +++ project/static/src/js/dropdown.js 2012-04-10 16:40:13 +0000 |
482 | @@ -0,0 +1,92 @@ |
483 | +/* ============================================================ |
484 | + * bootstrap-dropdown.js v2.0.2 |
485 | + * http://twitter.github.com/bootstrap/javascript.html#dropdowns |
486 | + * ============================================================ |
487 | + * Copyright 2012 Twitter, Inc. |
488 | + * |
489 | + * Licensed under the Apache License, Version 2.0 (the "License"); |
490 | + * you may not use this file except in compliance with the License. |
491 | + * You may obtain a copy of the License at |
492 | + * |
493 | + * http://www.apache.org/licenses/LICENSE-2.0 |
494 | + * |
495 | + * Unless required by applicable law or agreed to in writing, software |
496 | + * distributed under the License is distributed on an "AS IS" BASIS, |
497 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
498 | + * See the License for the specific language governing permissions and |
499 | + * limitations under the License. |
500 | + * ============================================================ */ |
501 | + |
502 | + |
503 | +!function( $ ){ |
504 | + |
505 | + "use strict" |
506 | + |
507 | + /* DROPDOWN CLASS DEFINITION |
508 | + * ========================= */ |
509 | + |
510 | + var toggle = '[data-toggle="dropdown"]' |
511 | + , Dropdown = function ( element ) { |
512 | + var $el = $(element).on('click.dropdown.data-api', this.toggle) |
513 | + $('html').on('click.dropdown.data-api', function () { |
514 | + $el.parent().removeClass('open') |
515 | + }) |
516 | + } |
517 | + |
518 | + Dropdown.prototype = { |
519 | + |
520 | + constructor: Dropdown |
521 | + |
522 | + , toggle: function ( e ) { |
523 | + var $this = $(this) |
524 | + , selector = $this.attr('data-target') |
525 | + , $parent |
526 | + , isActive |
527 | + |
528 | + if (!selector) { |
529 | + selector = $this.attr('href') |
530 | + selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 |
531 | + } |
532 | + |
533 | + $parent = $(selector) |
534 | + $parent.length || ($parent = $this.parent()) |
535 | + |
536 | + isActive = $parent.hasClass('open') |
537 | + |
538 | + clearMenus() |
539 | + !isActive && $parent.toggleClass('open') |
540 | + |
541 | + return false |
542 | + } |
543 | + |
544 | + } |
545 | + |
546 | + function clearMenus() { |
547 | + $(toggle).parent().removeClass('open') |
548 | + } |
549 | + |
550 | + |
551 | + /* DROPDOWN PLUGIN DEFINITION |
552 | + * ========================== */ |
553 | + |
554 | + $.fn.dropdown = function ( option ) { |
555 | + return this.each(function () { |
556 | + var $this = $(this) |
557 | + , data = $this.data('dropdown') |
558 | + if (!data) $this.data('dropdown', (data = new Dropdown(this))) |
559 | + if (typeof option == 'string') data[option].call($this) |
560 | + }) |
561 | + } |
562 | + |
563 | + $.fn.dropdown.Constructor = Dropdown |
564 | + |
565 | + |
566 | + /* APPLY TO STANDARD DROPDOWN ELEMENTS |
567 | + * =================================== */ |
568 | + |
569 | + $(function () { |
570 | + $('html').on('click.dropdown.data-api', clearMenus) |
571 | + $('body').on('click.dropdown.data-api', toggle, Dropdown.prototype.toggle) |
572 | + }) |
573 | + |
574 | +}( window.jQuery ); |
575 | \ No newline at end of file |
576 | |
577 | === added file 'project/static/src/js/project.js' |
578 | --- project/static/src/js/project.js 1970-01-01 00:00:00 +0000 |
579 | +++ project/static/src/js/project.js 2012-04-10 16:40:13 +0000 |
580 | @@ -0,0 +1,71 @@ |
581 | +openerp.project = function(openerp) { |
582 | + openerp.web_kanban.ProjectKanban = openerp.web_kanban.KanbanRecord.include({ |
583 | + |
584 | + bind_events: function() { |
585 | + self = this; |
586 | + if(this.view.dataset.model == 'project.project') { |
587 | + //open dropdwon when click on the icon. |
588 | + $('.dropdown-toggle').dropdown(); |
589 | + |
590 | + //show and hide the dropdown icon when mouseover and mouseour. |
591 | + $('.oe_project_kanban_vignette').mouseover(function() { |
592 | + return $(this).find('.oe_project_kanban_action').show(); |
593 | + }).mouseout(function() { |
594 | + return $(this).find('.oe_project_kanban_action').hide(); |
595 | + }); |
596 | + |
597 | + //set avatar title for members. |
598 | + _.each($(this.$element).find('.project_avatar'),function(avatar){ |
599 | + var dataset = new openerp.web.DataSetSearch(this, 'res.users', self.session.context, [['id','=',avatar.id]]); |
600 | + dataset.read_slice(['name']).then(function(result){ |
601 | + avatar.setAttribute("title",result[0].name) |
602 | + }); |
603 | + }); |
604 | + |
605 | + //if task is true , then open the task when click on the anywhere in the box. |
606 | + if(this.record.task.raw_value)$(this.$element).find('.click_button').attr('data-name','open_tasks'); |
607 | + if(!this.record.task.raw_value)$(this.$element).find('.click_button').attr('data-name','dummy'); |
608 | + |
609 | + // set sequence like Tasks,Issues,Timesheets and Phases |
610 | + my_list = $("#list a") |
611 | + my_list.sort(function (a, b) { |
612 | + var aValue = parseInt(a.id); |
613 | + var bValue = parseInt(b.id); |
614 | + // ASC |
615 | + //return aValue == bValue ? 0 : aValue < bValue ? -1 : 1; |
616 | + // DESC |
617 | + return aValue == bValue ? 0 : aValue < bValue ? -1 : 1; |
618 | + }); |
619 | + $('#list').replaceWith(my_list); |
620 | + |
621 | + // set background color |
622 | + this.$element.find('.bgcolor_steelblue').click(function(){ |
623 | + $(this).closest('li.oe_project_kanban_vignette').removeClass().addClass('oe_project_kanban_vignette ' + self.kanban_color(1)); |
624 | + self.view.dataset.write(parseInt(this.id), {color:1}); |
625 | + }); |
626 | + |
627 | + this.$element.find('.bgcolor_firebrick').click(function(){ |
628 | + $(this).closest('li.oe_project_kanban_vignette').removeClass().addClass('oe_project_kanban_vignette ' + self.kanban_color(2)); |
629 | + self.view.dataset.write(parseInt(this.id), {color:2}); |
630 | + }); |
631 | + |
632 | + this.$element.find('.bgcolor_khaki').click(function(){ |
633 | + $(this).closest('li.oe_project_kanban_vignette').removeClass().addClass('oe_project_kanban_vignette ' + self.kanban_color(3)); |
634 | + self.view.dataset.write(parseInt(this.id), {color:3}); |
635 | + }); |
636 | + |
637 | + this.$element.find('.bgcolor_thistle').click(function(){ |
638 | + $(this).closest('li.oe_project_kanban_vignette').removeClass().addClass('oe_project_kanban_vignette ' + self.kanban_color(4)); |
639 | + self.view.dataset.write(parseInt(this.id), {color:4}); |
640 | + }); |
641 | + |
642 | + this.$element.find('.bgcolor_orange').click(function(){ |
643 | + $(this).closest('li.oe_project_kanban_vignette').removeClass().addClass('oe_project_kanban_vignette ' + self.kanban_color(5)); |
644 | + self.view.dataset.write(parseInt(this.id), {color:5}); |
645 | + }); |
646 | + |
647 | + }; |
648 | + self._super(); |
649 | + } |
650 | + }); |
651 | +} |
652 | |
653 | === modified file 'project_issue/__openerp__.py' |
654 | --- project_issue/__openerp__.py 2012-03-14 12:32:06 +0000 |
655 | +++ project_issue/__openerp__.py 2012-04-10 16:40:13 +0000 |
656 | @@ -64,6 +64,7 @@ |
657 | 'installable': True, |
658 | 'auto_install': False, |
659 | 'application': True, |
660 | + 'js': ['static/src/js/project_issue.js'], |
661 | 'certificate' : '001236490750848623845', |
662 | } |
663 | |
664 | |
665 | === modified file 'project_issue/project_issue.py' |
666 | --- project_issue/project_issue.py 2012-04-03 17:21:08 +0000 |
667 | +++ project_issue/project_issue.py 2012-04-10 16:40:13 +0000 |
668 | @@ -222,6 +222,16 @@ |
669 | }), |
670 | } |
671 | |
672 | + def _get_project(self, cr, uid, context=None): |
673 | + user = self.pool.get('res.users').browse(cr, uid, uid, context=context) |
674 | + if user.context_project_id: |
675 | + return user.context_project_id.id |
676 | + else: |
677 | + project_id = context.get('active_id',False) |
678 | + return project_id |
679 | + |
680 | + def on_change_project(self, cr, uid, ids, project_id, context=None): |
681 | + return {} |
682 | |
683 | _defaults = { |
684 | 'active': 1, |
685 | @@ -506,10 +516,47 @@ |
686 | |
687 | class project(osv.osv): |
688 | _inherit = "project.project" |
689 | + |
690 | + def _compute_issue(self, cr, uid, ids, field_name, arg, context=None): |
691 | + res={} |
692 | + issue_pool=self.pool.get('project.issue') |
693 | + for project in self.browse(cr, uid, ids, context=context): |
694 | + issues = issue_pool.search(cr, uid, [('project_id','=',project.id)]) |
695 | + res[project.id] = len(issues) |
696 | + return res |
697 | + |
698 | _columns = { |
699 | 'project_escalation_id' : fields.many2one('project.project','Project Escalation', help='If any issue is escalated from the current Project, it will be listed under the project selected here.', states={'close':[('readonly',True)], 'cancelled':[('readonly',True)]}), |
700 | - 'reply_to' : fields.char('Reply-To Email Address', size=256) |
701 | - } |
702 | + 'reply_to' : fields.char('Reply-To Email Address', size=256), |
703 | + 'issues' : fields.boolean('Issues',help = "If you check this field issues are appears in kanban view"), |
704 | + 'total_issues': fields.function(_compute_issue , type='integer',string="Issue"), |
705 | + } |
706 | + |
707 | + _defaults = { |
708 | + 'issues' : True, |
709 | + } |
710 | + |
711 | + def open_issues(self, cr, uid, ids, context=None): |
712 | + #Open the View for the Tasks for the project |
713 | + """ |
714 | + This opens Issues views |
715 | + @return :Dictionary value for issue view |
716 | + """ |
717 | + if context is None: |
718 | + context = {} |
719 | + if ids: |
720 | + context = dict(context, search_default_project_id=ids[0]) |
721 | + return { |
722 | + 'name': _('Issue'), |
723 | + 'view_type': 'form', |
724 | + 'view_mode': 'kanban,tree,calendar,form', |
725 | + 'res_model': 'project.issue', |
726 | + 'view_id': False, |
727 | + 'domain':[('project_id','in',ids)], |
728 | + 'context': context, |
729 | + 'type': 'ir.actions.act_window', |
730 | + 'nodestroy': True |
731 | + } |
732 | |
733 | def _check_escalation(self, cr, uid, ids, context=None): |
734 | project_obj = self.browse(cr, uid, ids[0], context=context) |
735 | |
736 | === modified file 'project_issue/project_issue_menu.xml' |
737 | --- project_issue/project_issue_menu.xml 2012-04-05 16:55:29 +0000 |
738 | +++ project_issue/project_issue_menu.xml 2012-04-10 16:40:13 +0000 |
739 | @@ -54,6 +54,7 @@ |
740 | view_mode="tree,form,calendar,graph" |
741 | view_type="form"/> |
742 | |
743 | + |
744 | <menuitem name="Issues" id="menu_project_issue_track" parent="project.menu_project_management" |
745 | action="project_issue_categ_act0" sequence="15"/> |
746 | </data> |
747 | |
748 | === modified file 'project_issue/project_issue_view.xml' |
749 | --- project_issue/project_issue_view.xml 2012-04-03 10:24:08 +0000 |
750 | +++ project_issue/project_issue_view.xml 2012-04-10 16:40:13 +0000 |
751 | @@ -343,12 +343,37 @@ |
752 | <field name="type">form</field> |
753 | <field name="inherit_id" ref="project.edit_project"/> |
754 | <field name="arch" type="xml"> |
755 | + <xpath expr="//field[@name='task']" position="after"> |
756 | + <field name="issues"/> |
757 | + </xpath> |
758 | <field name="priority" position="before"> |
759 | <field name="project_escalation_id"/> |
760 | <field name="reply_to"/> |
761 | </field> |
762 | </field> |
763 | </record> |
764 | + |
765 | + <record id="view_project_kanban_inherited" model="ir.ui.view"> |
766 | + <field name="name">project.project.kanban.inherited</field> |
767 | + <field name="model">project.project</field> |
768 | + <field name="type">kanban</field> |
769 | + <field name="inherit_id" ref="project.view_project_kanban"/> |
770 | + <field name="arch" type="xml"> |
771 | + <field name="task" position="after"> |
772 | + <field name="issues"/> |
773 | + <field name="total_issues" invisible="1"/> |
774 | + </field> |
775 | + <xpath expr="//h4[@id='list']" position="inside"> |
776 | + <a id="2"> |
777 | + <t t-if="record.issues.raw_value"> |
778 | + <button name="open_issues" class="oe_project_buttons" type="object"><t t-if="record.total_issues.value <= 1"> Issue</t><t t-if="record.total_issues.value > 1"> Issues</t>(<t t-esc="record.total_issues.value"/>)</button> |
779 | + </t> |
780 | + </a> |
781 | + </xpath> |
782 | + </field> |
783 | + </record> |
784 | + |
785 | + |
786 | |
787 | </data> |
788 | </openerp> |
789 | |
790 | === added file 'project_issue/static/src/img/issue_icon.png' |
791 | Binary files project_issue/static/src/img/issue_icon.png 1970-01-01 00:00:00 +0000 and project_issue/static/src/img/issue_icon.png 2012-04-10 16:40:13 +0000 differ |
792 | === added directory 'project_issue/static/src/js' |
793 | === added file 'project_issue/static/src/js/project_issue.js' |
794 | --- project_issue/static/src/js/project_issue.js 1970-01-01 00:00:00 +0000 |
795 | +++ project_issue/static/src/js/project_issue.js 2012-04-10 16:40:13 +0000 |
796 | @@ -0,0 +1,14 @@ |
797 | +openerp.project_issue = function(openerp) { |
798 | + openerp.web_kanban.ProjectIssueKanban = openerp.web_kanban.KanbanRecord.include({ |
799 | + bind_events: function() { |
800 | + self = this; |
801 | + self._super(); |
802 | + if(this.view.dataset.model == 'project.project') { |
803 | + if(this.record.task.raw_value && this.record.issues.raw_value)$(this.$element).find('.click_button').attr('data-name','open_tasks'); |
804 | + if(!this.record.task.raw_value && this.record.issues.raw_value)$(this.$element).find('.click_button').attr('data-name','open_issues'); |
805 | + //if(!this.record.task.raw_value)$(this.$element).find('.click_button').attr('data-name','dummy'); |
806 | + }; |
807 | + |
808 | + } |
809 | + }); |
810 | +} |
811 | |
812 | === modified file 'project_long_term/project_long_term.py' |
813 | --- project_long_term/project_long_term.py 2012-01-31 13:36:57 +0000 |
814 | +++ project_long_term/project_long_term.py 2012-04-10 16:40:13 +0000 |
815 | @@ -123,6 +123,7 @@ |
816 | _defaults = { |
817 | 'state': 'draft', |
818 | 'sequence': 10, |
819 | + 'project_id':lambda self, cr, uid, context: context.get('active_id',False), |
820 | 'product_uom': lambda self,cr,uid,c: self.pool.get('product.uom').search(cr, uid, [('name', '=', _('Day'))], context=c)[0] |
821 | } |
822 | _order = "project_id, date_start, sequence" |
823 | @@ -215,9 +216,46 @@ |
824 | |
825 | class project(osv.osv): |
826 | _inherit = "project.project" |
827 | + |
828 | + def _open_phase(self, cr, uid, ids, field_name, arg, context=None): |
829 | + open_phase={} |
830 | + phase_pool=self.pool.get('project.phase') |
831 | + for id in ids: |
832 | + phase_ids = phase_pool.search(cr, uid, [('project_id', '=', id)]) |
833 | + open_phase[id] = len(phase_ids) |
834 | + return open_phase |
835 | + |
836 | _columns = { |
837 | 'phase_ids': fields.one2many('project.phase', 'project_id', "Project Phases"), |
838 | - } |
839 | + 'phases' : fields.boolean('Phase',help = "If you check this field Phases are appears in kanban view"), |
840 | + 'open_phases' : fields.function(_open_phase , type='integer',string="Open Phases"), |
841 | + |
842 | + } |
843 | + _defaults = { |
844 | + 'phases' : True, |
845 | + } |
846 | + def open_phase(self, cr, uid, ids, context=None): |
847 | + #Open the View for the Tasks for the project |
848 | + """ |
849 | + This opens Tasks views |
850 | + @return :Dictionary value for task view |
851 | + """ |
852 | + if context is None: |
853 | + context = {} |
854 | + if ids: |
855 | + context = dict(context, search_default_project_id=ids[0]) |
856 | + return { |
857 | + 'name': _('Phase'), |
858 | + 'view_type': 'form', |
859 | + 'view_mode': 'tree,calendar,form', |
860 | + 'res_model': 'project.phase', |
861 | + 'view_id': False, |
862 | + 'domain':[('project_id','in',ids)], |
863 | + 'context': context, |
864 | + 'type': 'ir.actions.act_window', |
865 | + 'nodestroy': True |
866 | + } |
867 | + |
868 | def schedule_phases(self, cr, uid, ids, context=None): |
869 | context = context or {} |
870 | if type(ids) in (long, int,): |
871 | |
872 | === modified file 'project_long_term/project_long_term_view.xml' |
873 | --- project_long_term/project_long_term_view.xml 2012-03-05 09:57:29 +0000 |
874 | +++ project_long_term/project_long_term_view.xml 2012-04-10 16:40:13 +0000 |
875 | @@ -98,6 +98,38 @@ |
876 | # Project Phase |
877 | # ------------------------------------------------------ |
878 | |
879 | + <record id="project_phase_form" model="ir.ui.view"> |
880 | + <field name="name">Inherit project form : Phase</field> |
881 | + <field name="model">project.project</field> |
882 | + <field name="type">form</field> |
883 | + <field name="inherit_id" ref="project.edit_project"/> |
884 | + <field name="arch" type="xml"> |
885 | + <xpath expr="//field[@name='task']" position="after"> |
886 | + <field name="phases"/> |
887 | + </xpath> |
888 | + </field> |
889 | + </record> |
890 | + |
891 | + <record id="view_project_kanban_phase" model="ir.ui.view"> |
892 | + <field name="name">project.project.kanban.inherited</field> |
893 | + <field name="model">project.project</field> |
894 | + <field name="type">kanban</field> |
895 | + <field name="inherit_id" ref="project.view_project_kanban"/> |
896 | + <field name="arch" type="xml"> |
897 | + <field name="task" position="after"> |
898 | + <field name="phases"/> |
899 | + <field name="open_phases"/> |
900 | + </field> |
901 | + <xpath expr="//h4[@id='list']" position="inside"> |
902 | + <a id="4"> |
903 | + <t t-if="record.phases.raw_value"> |
904 | + <button name="open_phase" class="oe_project_buttons" type="object"><t t-if="record.open_phases.value <= 1"> Phase</t><t t-if="record.open_phases.value > 1"> Phases</t>(<t t-esc="record.open_phases.value"/>)</button> |
905 | + </t> |
906 | + </a> |
907 | + </xpath> |
908 | + </field> |
909 | + </record> |
910 | + |
911 | <record id="view_project_phase_form" model="ir.ui.view"> |
912 | <field name="name">project.phase.form</field> |
913 | <field name="model">project.phase</field> |
914 | |
915 | === added directory 'project_long_term/static' |
916 | === added directory 'project_long_term/static/src' |
917 | === added directory 'project_long_term/static/src/img' |
918 | === added file 'project_long_term/static/src/img/phases_icon.jpg' |
919 | Binary files project_long_term/static/src/img/phases_icon.jpg 1970-01-01 00:00:00 +0000 and project_long_term/static/src/img/phases_icon.jpg 2012-04-10 16:40:13 +0000 differ |
920 | === modified file 'project_timesheet/__openerp__.py' |
921 | --- project_timesheet/__openerp__.py 2012-01-31 13:36:57 +0000 |
922 | +++ project_timesheet/__openerp__.py 2012-04-10 16:40:13 +0000 |
923 | @@ -44,6 +44,7 @@ |
924 | ], |
925 | 'installable': True, |
926 | 'auto_install': False, |
927 | + 'js': ['static/src/js/project_timesheet.js'], |
928 | 'certificate': '0075123647453', |
929 | } |
930 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |
931 | |
932 | === modified file 'project_timesheet/project_timesheet.py' |
933 | --- project_timesheet/project_timesheet.py 2012-01-31 13:36:57 +0000 |
934 | +++ project_timesheet/project_timesheet.py 2012-04-10 16:40:13 +0000 |
935 | @@ -29,6 +29,43 @@ |
936 | class project_project(osv.osv): |
937 | _inherit = 'project.project' |
938 | |
939 | + def _to_invoice(self, cr, uid, ids,field_name, arg, context=None): |
940 | + res = {} |
941 | + aal_pool = self.pool.get("account.analytic.line") |
942 | + for project in self.browse(cr,uid,ids,context=context): |
943 | + line_ids = aal_pool.search(cr, uid, [('account_id','=',project.analytic_account_id.id),('to_invoice','=',1),('invoice_id','=',False)]) |
944 | + res[project.id] = { |
945 | + 'amt_to_invoice': 0.0, |
946 | + 'hrs_to_invoice': 0.0, |
947 | + } |
948 | + if line_ids: |
949 | + amt_to_invoice,hrs_to_invoice = 0.0,0.0 |
950 | + for line in aal_pool.browse(cr,uid,line_ids,context=context): |
951 | + amt_to_invoice += line.amount |
952 | + hrs_to_invoice += line.unit_amount |
953 | + res[project.id]['amt_to_invoice'] = (amt_to_invoice)*-1 |
954 | + res[project.id]['hrs_to_invoice'] = hrs_to_invoice |
955 | + |
956 | + return res |
957 | + |
958 | + def _compute_timesheet(self, cr, uid, ids, field_name, arg, context=None): |
959 | + res={} |
960 | + aal_pool=self.pool.get('account.analytic.line') |
961 | + for project in self.browse(cr, uid, ids, context=context): |
962 | + timesheet = aal_pool.search(cr, uid, [("account_id","=", project.analytic_account_id.id)]) |
963 | + res[project.id] = len(timesheet) |
964 | + return res |
965 | + |
966 | + _columns = { |
967 | + 'timesheets' : fields.boolean('Timesheets',help = "If you check this field timesheets appears in kanban view"), |
968 | + 'amt_to_invoice': fields.function(_to_invoice,string="Amount to Invoice",multi="sums"), |
969 | + 'hrs_to_invoice': fields.function(_to_invoice,string="Hours to Invoice",multi="sums"), |
970 | + 'total_timesheet': fields.function(_compute_timesheet , type='integer',string="Issue"), |
971 | + } |
972 | + _defaults = { |
973 | + 'timesheets' : True, |
974 | + } |
975 | + |
976 | def onchange_partner_id(self, cr, uid, ids, part=False, context=None): |
977 | res = super(project_project, self).onchange_partner_id(cr, uid, ids, part, context) |
978 | if part and res and ('value' in res): |
979 | @@ -40,6 +77,29 @@ |
980 | res['value'].update({'to_invoice': factor_id}) |
981 | return res |
982 | |
983 | + def open_timesheets(self, cr, uid, ids, context=None): |
984 | + #Open the View for the Timesheet of the project |
985 | + """ |
986 | + This opens Timesheets views |
987 | + @return :Dictionary value for timesheet view |
988 | + """ |
989 | + if context is None: |
990 | + context = {} |
991 | + if ids: |
992 | + project = self.browse(cr, uid, ids[0], context=context) |
993 | + context = dict(context, search_default_account_id=project.analytic_account_id.id) |
994 | + |
995 | + return { |
996 | + 'name': _('Bill Tasks Works'), |
997 | + 'context': context, |
998 | + 'view_type': 'form', |
999 | + 'view_mode': 'tree,form', |
1000 | + 'res_model': 'account.analytic.line', |
1001 | + 'view_id': False, |
1002 | + 'type': 'ir.actions.act_window', |
1003 | + 'nodestroy': True |
1004 | + } |
1005 | + |
1006 | project_project() |
1007 | |
1008 | class project_work(osv.osv): |
1009 | |
1010 | === modified file 'project_timesheet/project_timesheet_view.xml' |
1011 | --- project_timesheet/project_timesheet_view.xml 2012-04-03 08:27:56 +0000 |
1012 | +++ project_timesheet/project_timesheet_view.xml 2012-04-10 16:40:13 +0000 |
1013 | @@ -7,6 +7,12 @@ |
1014 | <field name="type">form</field> |
1015 | <field name="inherit_id" ref="project.edit_project"/> |
1016 | <field name="arch" type="xml"> |
1017 | + <xpath expr="//field[@name='task']" position='after'> |
1018 | + <field name="timesheets"/> |
1019 | + <field name="amt_to_invoice" invisible="True"/> |
1020 | + <field name="hrs_to_invoice" invisible="True"/> |
1021 | + </xpath> |
1022 | + |
1023 | <field name="warn_customer" position="after"> |
1024 | <group colspan="4" col="4"> |
1025 | <separator colspan="4" string="Invoicing Data"/> |
1026 | @@ -19,6 +25,42 @@ |
1027 | </field> |
1028 | </record> |
1029 | |
1030 | + <record id="view_project_kanban_inherited" model="ir.ui.view"> |
1031 | + <field name="name">project.project.kanban.inherited</field> |
1032 | + <field name="model">project.project</field> |
1033 | + <field name="type">kanban</field> |
1034 | + <field name="inherit_id" ref="project.view_project_kanban"/> |
1035 | + <field name="arch" type="xml"> |
1036 | + <field name="task" position="after"> |
1037 | + <field name="timesheets"/> |
1038 | + <field name="total_timesheet"/> |
1039 | + <field name="currency_id"/> |
1040 | + </field> |
1041 | + <xpath expr="//h4[@id='list']" position="inside"> |
1042 | + <a id="3"> |
1043 | + <t t-if="record.timesheets.raw_value"> |
1044 | + <button name="open_timesheets" class="oe_project_buttons" type="object"><t t-if="record.total_timesheet.value <= 1"> Timesheet</t><t t-if="record.total_timesheet.value > 1"> Timesheets</t>(<t t-esc="record.total_timesheet.value"/>)</button> |
1045 | + </t> |
1046 | + </a> |
1047 | + </xpath> |
1048 | + |
1049 | + <xpath expr="//tr[@id='deadline']" position="before"> |
1050 | + <tr > |
1051 | + <th align="left">To invoice</th> |
1052 | + <td align="left"> |
1053 | + <field name="amt_to_invoice"/> <t t-esc="record.currency_id.raw_value[1].split(' ')[1][1]"/> |
1054 | + </td> |
1055 | + </tr> |
1056 | + <tr> |
1057 | + <th align="left">To hours</th> |
1058 | + <td align="left"> |
1059 | + <field name="hrs_to_invoice"/> h |
1060 | + </td> |
1061 | + </tr> |
1062 | + </xpath> |
1063 | + </field> |
1064 | + </record> |
1065 | + |
1066 | <record id="project_invoice_form_cutomer" model="ir.ui.view"> |
1067 | <field name="name">Inherit project form : Customer</field> |
1068 | <field name="model">project.project</field> |
1069 | |
1070 | === added directory 'project_timesheet/static' |
1071 | === added directory 'project_timesheet/static/src' |
1072 | === added directory 'project_timesheet/static/src/img' |
1073 | === added file 'project_timesheet/static/src/img/timesheet_icon.png' |
1074 | Binary files project_timesheet/static/src/img/timesheet_icon.png 1970-01-01 00:00:00 +0000 and project_timesheet/static/src/img/timesheet_icon.png 2012-04-10 16:40:13 +0000 differ |
1075 | === added directory 'project_timesheet/static/src/js' |
1076 | === added file 'project_timesheet/static/src/js/project_timesheet.js' |
1077 | --- project_timesheet/static/src/js/project_timesheet.js 1970-01-01 00:00:00 +0000 |
1078 | +++ project_timesheet/static/src/js/project_timesheet.js 2012-04-10 16:40:13 +0000 |
1079 | @@ -0,0 +1,21 @@ |
1080 | +openerp.project_timesheet = function(openerp) { |
1081 | + openerp.web_kanban.ProjectTimeSheetKanban = openerp.web_kanban.KanbanRecord.include({ |
1082 | + bind_events: function() { |
1083 | + self = this; |
1084 | + self._super(); |
1085 | + if(this.view.dataset.model == 'project.project') { |
1086 | + function include(arr, obj) { |
1087 | + for(var i=0; i<arr.length; i++) { |
1088 | + if (arr[i] == obj) return true; |
1089 | + } |
1090 | + } |
1091 | + if(include(this.view.fields_keys,"issues")) |
1092 | + { |
1093 | + if(!this.record.task.raw_value && !this.record.issues.raw_value && this.record.timesheets.raw_value)$(this.$element).find('.click_button').attr('data-name','open_timesheets'); |
1094 | + //if(!this.record.task.raw_value)$(this.$element).find('.click_button').attr('data-name','dummy'); |
1095 | + }; |
1096 | + if(this.record.task.raw_value && this.record.timesheets.raw_value)$(this.$element).find('.click_button').attr('data-name','open_tasks'); |
1097 | + }; |
1098 | + } |
1099 | + }); |
1100 | +} |
Nope need cleanups [rco].