1
##############################################################################
3
# Copyright (c) 2005-2006 TINY SPRL. (http://tiny.be) All Rights Reserved.
5
# $Id: project.py 1011 2005-07-26 08:11:45Z nicoe $
7
# WARNING: This program as such is intended to be used by professional
8
# programmers who take the whole responsability of assessing all potential
9
# consequences resulting from its eventual inadequacies and bugs
10
# End users who are looking for a ready-to-use solution with commercial
11
# garantees and support are strongly adviced to contract a Free Software
14
# This program is Free Software; you can redistribute it and/or
15
# modify it under the terms of the GNU General Public License
16
# as published by the Free Software Foundation; either version 2
17
# of the License, or (at your option) any later version.
19
# This program is distributed in the hope that it will be useful,
20
# but WITHOUT ANY WARRANTY; without even the implied warranty of
21
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22
# GNU General Public License for more details.
24
# You should have received a copy of the GNU General Public License
25
# along with this program; if not, write to the Free Software
26
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28
##############################################################################
33
from mx import DateTime
34
from mx.DateTime import now
38
from osv import fields, osv
42
class one2many_mod(fields.one2many):
43
def get(self, cr, obj, ids, name, user=None, offset=0, context=None, values=None):
48
for obj in obj.browse(cr, user, ids, context=context):
50
v = getattr(obj,'context'+num+'_id').id
52
ids2 = obj.pool.get(self._obj).search(cr, user, [(self._fields_id,'=',obj.id),('context_id','=',v)], limit=self._limit)
53
for r in obj.pool.get(self._obj)._read_flat(cr, user, ids2, [self._fields_id], context=context, load='_classic_write'):
54
res[r[self._fields_id]].append( r['id'] )
57
class project_gtd_context(osv.osv):
58
_name = "project.gtd.context"
60
'name': fields.char('Context', size=64, required=True, select=1),
61
'sequence': fields.integer('Sequence'),
62
'project_default_id': fields.many2one('project.project', 'Default Project', required=True),
65
'sequence': lambda *args: 1
67
_order = "sequence, name"
71
class project_gtd_timebox(osv.osv):
72
_name = "project.gtd.timebox"
74
'name': fields.char('Timebox', size=64, required=True, select=1),
75
'user_id': fields.many2one('res.users', 'User', required=True, select=1),
76
'child_ids': fields.one2many('project.gtd.timebox', 'parent_id', 'Childs Timebox'),
77
'parent_id': fields.many2one('project.gtd.timebox', 'Parent Timebox'),
78
'task_ids': fields.one2many('project.task', 'timebox_id', 'Tasks'),
79
'type': fields.selection([('daily','Daily'),('weekly','Weekly'),('monthly','Monthly'),('other','Other')], 'Type', required=True),
80
'task1_ids': one2many_mod('project.task', 'timebox_id', 'Tasks'),
81
'task2_ids': one2many_mod('project.task', 'timebox_id', 'Tasks'),
82
'task3_ids': one2many_mod('project.task', 'timebox_id', 'Tasks'),
83
'task4_ids': one2many_mod('project.task', 'timebox_id', 'Tasks'),
84
'task5_ids': one2many_mod('project.task', 'timebox_id', 'Tasks'),
85
'task6_ids': one2many_mod('project.task', 'timebox_id', 'Tasks'),
86
'context1_id': fields.many2one('project.gtd.context', 'Context 1', required=True),
87
'context2_id': fields.many2one('project.gtd.context', 'Context 2'),
88
'context3_id': fields.many2one('project.gtd.context', 'Context 3'),
89
'context4_id': fields.many2one('project.gtd.context', 'Context 4'),
90
'context5_id': fields.many2one('project.gtd.context', 'Context 5'),
91
'context6_id': fields.many2one('project.gtd.context', 'Context 6'),
92
'col_project': fields.boolean('Project'),
93
'col_date_start': fields.boolean('Date Start'),
94
'col_priority': fields.boolean('Priority'),
95
'col_deadline': fields.boolean('Deadline'),
96
'col_planned_hours': fields.boolean('Planned Hours'),
97
'col_effective_hours': fields.boolean('Effective Hours'),
99
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False):
100
res = super(project_gtd_timebox,self).fields_view_get(cr, uid, view_id, view_type, context, toolbar)
101
if (res['type']=='form') and ('record_id' in context):
102
if context['record_id']:
103
rec = self.browse(cr, uid, int(context['record_id']), context)
105
iids = self.search(cr,uid, [('user_id','=',uid),('parent_id','=',False)], context=context)
107
rec = self.browse(cr, uid, int(iids[0]), context=context)
111
<form string="Daily Timebox">
112
<field name="name" readonly="1"/>
113
<notebook position="top">
116
if not getattr(rec, 'context%d_id'%i):
120
<field name="%s" colspan="4" nolabel="1">
121
<tree editable="bottom" colors="grey:state in ('done','pending');red:state=='cancelled'" string="Tasks">
123
""" % (getattr(rec, 'context%d_id'%(i,)).name, 'task%d_ids'%(i,))
125
res['arch'] += '<field name="project_id" required="1"/>\n'
126
if rec.col_date_start:
127
res['arch'] += '<field name="date_start"/>\n'
129
res['arch'] += '<field name="priority"/>\n'
131
res['arch'] += '<field name="date_deadline"/>\n'
132
if rec.col_planned_hours:
133
res['arch'] += '<field name="planned_hours" widget="float_time" sum="Est. Hours"/>\n'
134
if rec.col_effective_hours:
135
res['arch'] += '<field name="effective_hours" widget="float_time" sum="Eff. Hours"/>\n'
137
<field name="state" readonly="1"/>
147
doc = dom.minidom.parseString(res['arch'])
148
xarch, xfields = self._view_look_dom_arch(cr, uid, doc, context=context)
150
res['fields'] = xfields
153
'type': lambda *args: 'daily',
154
'col_project': lambda *args: True,
155
'col_date_start': lambda *args: True,
156
'col_priority': lambda *args: True,
157
'col_deadline': lambda *args: False,
158
'col_planned_hours': lambda *args: True,
159
'col_effective_hours': lambda *args: False
161
project_gtd_timebox()
163
class project_task(osv.osv):
164
_inherit = "project.task"
166
'timebox_id': fields.many2one('project.gtd.timebox', "Timebox"),
167
'context_id': fields.many2one('project.gtd.context', "Context"),
169
def copy(self, cr, uid, id, default=None, context=None):
172
default['timebox_id']=False
173
default['context_id']=False
174
return super(project_task,self).copy(cr, uid, id, default, context)
175
def _get_context(self,cr, uid, ctx):
176
ids = self.pool.get('project.gtd.context').search(cr, uid, [], context=ctx)
177
return ids and ids[0] or False
179
'context_id': _get_context
181
# Override read for using this method if context set !!!
182
_order = "((55-ascii(coalesce(priority,'2')))*2 + coalesce((date_start::date-current_date)/2,8))"