680a2db67312504ee97143c8cb1821651a311287
[odoo/odoo.git] / addons / project_gtd / project_gtd.py
1 # -*- coding: utf-8 -*-
2 ##############################################################################
3 #    
4 #    OpenERP, Open Source Management Solution
5 #    Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
6 #
7 #    This program is free software: you can redistribute it and/or modify
8 #    it under the terms of the GNU Affero General Public License as
9 #    published by the Free Software Foundation, either version 3 of the
10 #    License, or (at your option) any later version.
11 #
12 #    This program is distributed in the hope that it will be useful,
13 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
14 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 #    GNU Affero General Public License for more details.
16 #
17 #    You should have received a copy of the GNU Affero General Public License
18 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.     
19 #
20 ##############################################################################
21
22 from xml import dom
23 from lxml import etree
24
25 from mx import DateTime
26 from mx.DateTime import now
27 import time
28 import tools
29 import netsvc
30 from osv import fields, osv
31 import ir
32
33 class project_gtd_context(osv.osv):
34     _name = "project.gtd.context"
35     _description = "Contexts"
36     _columns = {
37         'name': fields.char('Context', size=64, required=True, select=1),
38         'sequence': fields.integer('Sequence'),
39         'project_default_id': fields.many2one('project.project', 'Default Project', required=True),
40     }
41     _defaults = {
42         'sequence': lambda *args: 1
43     }
44     _order = "sequence, name"
45     
46 project_gtd_context()
47
48
49 class project_gtd_timebox(osv.osv):
50     _name = "project.gtd.timebox"
51     _order = "sequence"
52     _columns = {
53         'name': fields.char('Timebox', size=64, required=True, select=1),
54         'sequence': fields.integer('Sequence'),
55         'icon': fields.selection(tools.icons, 'Icon', size=64),
56     }
57     
58     def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
59         res = super(project_gtd_timebox,self).fields_view_get(cr, uid, view_id, view_type, context, toolbar=toolbar, submenu=submenu)
60         if (res['type']=='form') and ('record_id' in context):
61             if context['record_id']:
62                 rec = self.browse(cr, uid, int(context['record_id']), context)
63             else:
64                 iids = self.search(cr,uid, [('user_id','=',uid),('parent_id','=',False)], context=context)
65                 if len(iids):
66                     rec = self.browse(cr, uid, int(iids[0]), context=context)
67                 else:
68                     return res
69             res['arch'] = """
70     <form string="Daily Timebox">
71         <field name="name" readonly="1"/>
72         <notebook position="top">
73             """
74             for i in range(1,7):
75                 if not getattr(rec, 'context%d_id'%i):
76                     continue
77                 res['arch']+= """
78             <page string="%s">
79                 <field name="%s" colspan="4" nolabel="1">
80                     <tree editable="bottom" colors="grey:state in ('done','pending');red:state=='cancelled'" string="Tasks">
81                         <field name="name"/>
82                 """ % (getattr(rec, 'context%d_id'%(i,)).name.encode('utf-8'), 'task%d_ids'%(i,))
83                 if rec.col_project:
84                     res['arch'] += '<field name="project_id" required="1"/>\n'
85                 if rec.col_date_start:
86                     res['arch'] += '<field name="date_start"/>\n'
87                 if rec.col_priority:
88                     res['arch'] += '<field name="priority"/>\n'
89                 if rec.col_deadline:
90                     res['arch'] += '<field name="date_deadline"/>\n'
91                 if rec.col_planned_hours:
92                     res['arch'] += '<field name="planned_hours"  widget="float_time" sum="Est. Hours"/>\n'
93                 if rec.col_effective_hours:
94                     res['arch'] += '<field name="effective_hours"  widget="float_time" sum="%s"/>\n' % (_('Eff. Hours'),)
95                 res['arch'] += """
96                         <field name="state" readonly="1"/>
97                     </tree>
98                 </field>
99             </page>
100                 """
101             res['arch']+="""
102         </notebook>
103     </form>
104             """
105         doc = etree.XML(res['arch'])
106         xarch, xfields = self._view_look_dom_arch(cr, uid, doc, view_id, context=context)
107         res['arch'] = xarch
108         res['fields'] = xfields
109         return res
110
111 project_gtd_timebox()
112
113 class project_task(osv.osv):
114     _inherit = "project.task"
115     _columns = {
116         'timebox_id': fields.many2one('project.gtd.timebox', "Timebox"),
117         'context_id': fields.many2one('project.gtd.context', "Context"),
118      }
119     
120     def copy_data(self, cr, uid, id, default=None, context=None):
121         if not default:
122             default = {}
123         default['timebox_id']=False
124         default['context_id']=False
125         return super(project_task,self).copy_data(cr, uid, id, default, context)
126     
127     def _get_context(self,cr, uid, ctx):
128         ids = self.pool.get('project.gtd.context').search(cr, uid, [], context=ctx)
129         return ids and ids[0] or False
130     _defaults = {
131         'context_id': _get_context
132     }
133     
134     def next_timebox(self, cr, uid, ids, *args):
135         timebox_obj = self.pool.get('project.gtd.timebox')
136         timebox_ids = timebox_obj.search(cr,uid,[])
137         for task in self.browse(cr,uid,ids):
138             timebox = task.timebox_id.id
139             if timebox and  timebox_ids.index(timebox) != len(timebox_ids)-1 :
140                 index = timebox_ids.index(timebox)
141             else:
142                 index = -1
143             self.write(cr, uid, task.id, {'timebox_id': timebox_ids[index+1]})
144         return True
145
146     def prev_timebox(self, cr, uid, ids, *args):
147         timebox_obj = self.pool.get('project.gtd.timebox')
148         timebox_ids = timebox_obj.search(cr,uid,[])
149         for task in self.browse(cr,uid,ids):
150             timebox = task.timebox_id.id
151             if timebox and  timebox_ids.index(timebox) != 0 :
152                 index = timebox_ids.index(timebox)
153             else:
154                 index = len(timebox_ids)
155             self.write(cr, uid, task.id, {'timebox_id': timebox_ids[index - 1]})
156         return True
157     
158     def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
159         res = super(project_task,self).fields_view_get(cr, uid, view_id, view_type, context, toolbar=toolbar, submenu=submenu)
160         search_extended = False
161         if res['type'] == 'search':
162             search_extended ='''<newline/> <group colspan="2">'''
163             timebox_obj = self.pool.get('project.gtd.timebox')
164             for time in timebox_obj.browse(cr, uid, timebox_obj.search(cr,uid,[])):
165                 if time.icon:
166                     icon = time.icon
167                 else :
168                     icon=""
169                 search_extended += ''' <filter domain="[('timebox_id','=', ''' + str(time.id) + ''')]" help = "Task Related to ''' +  time.name  + ''' Timeboxs" icon="''' + icon + '''" string="''' + time.name + '''"/>'''
170             search_extended += '''</group>
171             <group colspan="2">
172             <field name="context_id" select="1" widget="selection"/> 
173             <field name="priority" select="1"/>
174             </group>
175             </search> '''
176         if search_extended:
177             res['arch'] = res['arch'].replace('</search>',search_extended)
178             attrs_sel = self.pool.get('project.gtd.context').name_search(cr, uid, '', [], context=context)
179             context_id_info = self.pool.get('project.task').fields_get(cr, uid, ['context_id'])
180             context_id_info['context_id']['selection'] = attrs_sel
181             res['fields'].update(context_id_info)
182         return res
183  
184     # Override read for using this method if context set !!!
185     #_order = "((55-ascii(coalesce(priority,'2')))*2 +  coalesce((date_start::date-current_date)/2,8))"
186 project_task()
187
188 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
189