[REF] purchase: search view of purchase order and form view of merge order wizard
[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-2010 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 mx import DateTime
23 from mx.DateTime import now
24 import time
25 import tools
26 import netsvc
27 from osv import fields, osv
28 import ir
29 from tools.translate import _
30
31 import sys
32 from tools.translate import _
33
34 try:
35     from lxml import etree
36 except ImportError:
37     sys.stderr.write("ERROR: Import lxml module\n")
38     sys.stderr.write("ERROR: Try to install the python-lxml package\n")
39
40 class project_gtd_context(osv.osv):
41     _name = "project.gtd.context"
42     _description = "Contexts"
43     _columns = {
44         'name': fields.char('Context', size=64, required=True, select=1),
45         'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of contexts."),
46         'project_default_id': fields.many2one('project.project', 'Default Project', required=True),
47     }
48     _defaults = {
49         'sequence': lambda *args: 1
50     }
51     _order = "sequence, name"
52
53 project_gtd_context()
54
55
56 class project_gtd_timebox(osv.osv):
57     _name = "project.gtd.timebox"
58     _order = "sequence"
59     _columns = {
60         'name': fields.char('Timebox', size=64, required=True, select=1),
61         'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of timebox."),
62         'icon': fields.selection(tools.icons, 'Icon', size=64),
63     }
64
65     def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
66         res = super(project_gtd_timebox,self).fields_view_get(cr, uid, view_id, view_type, context, toolbar=toolbar, submenu=submenu)
67         if (res['type']=='form') and ('record_id' in context):
68             if context['record_id']:
69                 rec = self.browse(cr, uid, int(context['record_id']), context)
70             else:
71                 iids = self.search(cr,uid, [('user_id','=',uid),('parent_id','=',False)], context=context)
72                 if len(iids):
73                     rec = self.browse(cr, uid, int(iids[0]), context=context)
74                 else:
75                     return res
76             res['arch'] = """
77     <form string="Daily Timebox">
78         <field name="name" readonly="1"/>
79         <notebook position="top">
80             """
81             for i in range(1,7):
82                 if not getattr(rec, 'context%d_id'%i):
83                     continue
84                 res['arch']+= """
85             <page string="%s">
86                 <field name="%s" colspan="4" nolabel="1">
87                     <tree editable="bottom" colors="grey:state in ('done','pending');red:state=='cancelled'" string="Tasks">
88                         <field name="name"/>
89                 """ % (getattr(rec, 'context%d_id'%(i,)).name.encode('utf-8'), 'task%d_ids'%(i,))
90                 if rec.col_project:
91                     res['arch'] += '<field name="project_id" required="1"/>\n'
92                 if rec.col_date_start:
93                     res['arch'] += '<field name="date_start"/>\n'
94                 if rec.col_priority:
95                     res['arch'] += '<field name="priority"/>\n'
96                 if rec.col_deadline:
97                     res['arch'] += '<field name="date_deadline"/>\n'
98                 if rec.col_planned_hours:
99                     res['arch'] += '<field name="planned_hours"  widget="float_time" sum="Est. Hours"/>\n'
100                 if rec.col_effective_hours:
101                     res['arch'] += '<field name="effective_hours"  widget="float_time" sum="%s"/>\n' % (_('Eff. Hours'),)
102                 res['arch'] += """
103                         <field name="state" readonly="1"/>
104                     </tree>
105                 </field>
106             </page>
107                 """
108             res['arch']+="""
109         </notebook>
110     </form>
111             """
112         doc = etree.XML(res['arch'])
113         xarch, xfields = self._view_look_dom_arch(cr, uid, doc, view_id, context=context)
114         res['arch'] = xarch
115         res['fields'] = xfields
116         return res
117
118 project_gtd_timebox()
119
120 class project_task(osv.osv):
121     _inherit = "project.task"
122     _columns = {
123         'timebox_id': fields.many2one('project.gtd.timebox', "Timebox"),
124         'context_id': fields.many2one('project.gtd.context', "Context"),
125      }
126
127     def copy_data(self, cr, uid, id, default=None, context=None):
128         if not default:
129             default = {}
130         default['timebox_id']=False
131         default['context_id']=False
132         return super(project_task,self).copy_data(cr, uid, id, default, context)
133
134     def _get_context(self,cr, uid, ctx):
135         ids = self.pool.get('project.gtd.context').search(cr, uid, [], context=ctx)
136         return ids and ids[0] or False
137     _defaults = {
138         'context_id': _get_context
139     }
140     def next_timebox(self, cr, uid, ids, *args):
141         timebox_obj = self.pool.get('project.gtd.timebox')
142         timebox_ids = timebox_obj.search(cr,uid,[])
143         if not timebox_ids: return True
144         for task in self.browse(cr,uid,ids):
145             timebox = task.timebox_id.id
146             if not timebox:
147                 self.write(cr, uid, task.id, {'timebox_id': timebox_ids[0]})
148             elif timebox_ids.index(timebox) != len(timebox_ids)-1:
149                 index = timebox_ids.index(timebox)
150                 self.write(cr, uid, task.id, {'timebox_id': timebox_ids[index+1]})
151         return True
152
153     def prev_timebox(self, cr, uid, ids, *args):
154         timebox_obj = self.pool.get('project.gtd.timebox')
155         timebox_ids = timebox_obj.search(cr,uid,[])
156         for task in self.browse(cr,uid,ids):
157             timebox = task.timebox_id.id
158             if timebox:
159                 if timebox_ids.index(timebox):
160                     index = timebox_ids.index(timebox)
161                     self.write(cr, uid, task.id, {'timebox_id': timebox_ids[index - 1]})
162                 else:
163                     self.write(cr, uid, task.id, {'timebox_id': False})
164         return True
165
166     def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
167         res = super(project_task,self).fields_view_get(cr, uid, view_id, view_type, context, toolbar=toolbar, submenu=submenu)
168         search_extended = False
169         timebox_obj = self.pool.get('project.gtd.timebox')
170         if res['type'] == 'search':
171             tt = timebox_obj.browse(cr, uid, timebox_obj.search(cr,uid,[]))
172             search_extended ='''<newline/><group col="%d" expand="1" string="%s" groups="project_gtd.group_project_getting">''' % (len(tt)+7,_('Getting Things Done'))
173             search_extended += '''<filter domain="[('timebox_id','=', False)]" context="{'set_editable':True,'set_visible':True}" icon="gtk-new" string="%s"/>''' % (_('Inbox'),)
174             search_extended += '''<filter domain="[('state', 'in', ('draft','open','pending'))]" context="{'set_editable':True,'set_visible':True}" icon="gtk-new" string="%s"/>''' % (_('All'),)
175             search_extended += '''<separator orientation="vertical"/>'''
176             for time in tt:
177                 if time.icon:
178                     icon = time.icon
179                 else :
180                     icon=""
181                 search_extended += '''<filter domain="[('timebox_id','=', ''' + str(time.id) + ''')]" icon="''' + icon + '''" string="''' + time.name + '''" context="{'set_visible':True}"/>'''
182             search_extended += '''
183             <separator orientation="vertical"/>
184             <field name="context_id" select="1" widget="selection" />
185             <field name="priority" select="1" />
186             </group>
187             </search> '''
188         if search_extended:
189             res['arch'] = res['arch'].replace('</search>',search_extended)
190             attrs_sel = self.pool.get('project.gtd.context').name_search(cr, uid, '', [], context=context)
191             context_id_info = self.pool.get('project.task').fields_get(cr, uid, ['context_id'])
192             context_id_info['context_id']['selection'] = attrs_sel
193             res['fields'].update(context_id_info)
194         return res
195 project_task()
196
197 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
198