diff options
| author | Vir (Open ERP) <vir@tinyerp.com> | 2010-01-20 12:26:11 +0530 |
|---|---|---|
| committer | Vir (Open ERP) <vir@tinyerp.com> | 2010-01-20 12:26:11 +0530 |
| commit | ed6420b082a4e5e2fc0dae0aafbfaf0af5d34c07 (patch) | |
| tree | bd62c36d2627d0500619f506e8c395434c21cc02 /addons/project | |
| parent | 2a5ccc7f7fc2fb8dc963a49fa46ecfbd82824908 (diff) | |
| parent | d351065fb195ed7d20a5087a0f650fc37672f39e (diff) | |
Merge with trunk addons
bzr revid: vir@tinyerp.com-20100120065611-inrbplhiwq2p5tg5
Diffstat (limited to 'addons/project')
| -rw-r--r-- | addons/project/__terp__.py | 4 | ||||
| -rw-r--r-- | addons/project/project.py | 195 | ||||
| -rw-r--r-- | addons/project/project_demo.xml | 41 | ||||
| -rw-r--r-- | addons/project/project_view.xml | 188 | ||||
| -rw-r--r-- | addons/project/project_wizard.xml | 1 | ||||
| -rw-r--r-- | addons/project/report/_date_compute.py | 8 | ||||
| -rw-r--r-- | addons/project/wizard/__init__.py | 1 | ||||
| -rw-r--r-- | addons/project/wizard/task_attachment.py | 49 |
8 files changed, 228 insertions, 259 deletions
diff --git a/addons/project/__terp__.py b/addons/project/__terp__.py index 40d41a8fdd1..5c7030a8acb 100644 --- a/addons/project/__terp__.py +++ b/addons/project/__terp__.py @@ -41,7 +41,9 @@ works done on tasks, eso. It is able to render planning, order tasks, eso. "process/task_process.xml", "project_installer.xml", ], - 'demo_xml': ['project_demo.xml'], + 'demo_xml': [ + 'project_demo.xml' + ], 'installable': True, 'active': False, 'certificate': '0075116868317', diff --git a/addons/project/project.py b/addons/project/project.py index 8bd78c1c80f..815f69ecf3d 100644 --- a/addons/project/project.py +++ b/addons/project/project.py @@ -20,18 +20,32 @@ ############################################################################## from lxml import etree -from mx import DateTime -from mx.DateTime import now +import mx.DateTime +import datetime import time from tools.translate import _ - from osv import fields, osv from tools.translate import _ +class project_task_type(osv.osv): + _name = 'project.task.type' + _description = 'Project task type' + _columns = { + 'name': fields.char('Type', required=True, size=64, translate=True), + 'description': fields.text('Description'), + 'sequence': fields.integer('Sequence'), + } + _order = 'sequence' + + _defaults = { + 'sequence': lambda *args: 1 + } +project_task_type() + class project(osv.osv): _name = "project.project" _description = "Project" - + _inherits = {'account.analytic.account':"category_id"} def _complete_name(self, cr, uid, ids, name, args, context): res = {} for m in self.browse(cr, uid, ids, context=context): @@ -73,7 +87,7 @@ class project(osv.osv): tocompute = [project] while tocompute: p = tocompute.pop() - tocompute += p.child_id + tocompute += p.child_ids for i in range(3): s[i] += progress.get(p.id, (0.0,0.0,0.0))[i] res[project.id] = { @@ -90,51 +104,60 @@ class project(osv.osv): raise osv.except_osv(_('Operation Not Permitted !'), _('You can not delete a project with tasks. I suggest you to deactivate it.')) return super(project, self).unlink(cr, uid, ids, *args, **kwargs) _columns = { - 'name': fields.char("Project Name", size=128, required=True), - 'complete_name': fields.function(_complete_name, method=True, string="Project Name", type='char', size=128), +# 'name': fields.char("Project Name", size=128, required=True), +# 'complete_name': fields.function(_complete_name, method=True, string="Project Name", type='char', size=128), 'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the project without removing it."), 'category_id': fields.many2one('account.analytic.account','Analytic Account', help="Link this project to an analytic account if you need financial management on projects. It enables you to connect projects with budgets, planning, cost and revenue analysis, timesheets on projects, etc."), 'priority': fields.integer('Sequence'), - 'manager': fields.many2one('res.users', 'Project Manager'), +# 'manager': fields.many2one('res.users', 'Project Manager'), 'warn_manager': fields.boolean('Warn Manager', help="If you check this field, the project manager will receive a request each time a task is completed by his team."), - 'members': fields.many2many('res.users', 'project_user_rel', 'project_id', 'uid', 'Project Members', help="Project's member. Not used in any computation, just for information purpose."), + 'resource_ids': fields.many2many('resource.resource', 'project_resource_rel', 'project_id', 'resource_id', 'Project Members', help="Project's member. Not used in any computation, just for information purpose."), 'tasks': fields.one2many('project.task', 'project_id', "Project tasks"), - 'parent_id': fields.many2one('project.project', 'Parent Project',\ - help="If you have [?] in the name, it means there are no analytic account linked to project."), - 'child_id': fields.one2many('project.project', 'parent_id', 'Subproject'), +# 'parent_id': fields.many2one('project.project', 'Parent Project',\ +# help="If you have [?] in the name, it means there are no analytic account linked to project."), +# 'child_id': fields.one2many('project.project', 'parent_id', 'Subproject'), 'planned_hours': fields.function(_progress_rate, multi="progress", method=True, string='Planned Time', help="Sum of planned hours of all tasks related to this project."), 'effective_hours': fields.function(_progress_rate, multi="progress", method=True, string='Time Spent', help="Sum of spent hours of all tasks related to this project."), 'total_hours': fields.function(_progress_rate, multi="progress", method=True, string='Total Time', help="Sum of total hours of all tasks related to this project."), 'progress_rate': fields.function(_progress_rate, multi="progress", method=True, string='Progress', type='float', help="Percent of tasks closed according to the total of tasks todo."), - 'date_start': fields.date('Starting Date'), - 'date_end': fields.date('Expected End'), - 'partner_id': fields.many2one('res.partner', 'Partner'), - 'contact_id': fields.many2one('res.partner.address', 'Contact'), +# 'partner_id': fields.many2one('res.partner', 'Partner'), +# 'contact_id': fields.many2one('res.partner.address', 'Contact'), 'warn_customer': fields.boolean('Warn Partner', help="If you check this, the user will have a popup when closing a task that propose a message to send by email to the customer."), '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."), '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."), - 'notes': fields.text('Notes', help="Internal description of the project."), - 'timesheet_id': fields.many2one('hr.timesheet.group', 'Working Time', help="Timetable working hours to adjust the gantt diagram report"), - 'state': fields.selection([('template', 'Template'), ('open', 'Running'), ('pending', 'Pending'), ('cancelled', 'Cancelled'), ('done', 'Done')], 'State', required=True, readonly=True, - help='The project can be in either if the states \'Template\' and \'Running\'.\n If it is template then we can make projects based on the template projects. If its in \'Running\' state it is a normal project.\ - \n If it is to be reviewed then the state is \'Pending\'.\n When the project is completed the state is set to \'Done\'.'), - 'company_id': fields.many2one('res.company', 'Company'), +# 'notes': fields.text('Notes', help="Internal description of the project."), + 'resource_calendar_id': fields.many2one('resource.calendar', 'Working Time', help="Timetable working hours to adjust the gantt diagram report"), +# 'state': fields.selection([('template', 'Template'), ('open', 'Running'), ('pending', 'Pending'), ('cancelled', 'Cancelled'), ('done', 'Done')], 'State', required=True, readonly=True, +# help='The project can be in either if the states \'Template\' and \'Running\'.\n If it is template then we can make projects based on the template projects. If its in \'Running\' state it is a normal project.\ +# \n If it is to be reviewed then the state is \'Pending\'.\n When the project is completed the state is set to \'Done\'.'), +# 'company_id': fields.many2one('res.company', 'Company'), +# 'timesheet_id': fields.many2one('hr.timesheet.group', 'Working Time', help="Timetable working hours to adjust the gantt diagram report"), + 'type_ids': fields.many2many('project.task.type', 'project_task_type_rel', 'project_id', 'type_id', 'Allowed Task Types'), } _defaults = { 'active': lambda *a: True, - 'manager': lambda object,cr,uid,context: uid, +# 'manager': lambda object,cr,uid,context: uid, 'priority': lambda *a: 1, - 'date_start': lambda *a: time.strftime('%Y-%m-%d'), - 'state': lambda *a: 'open', - 'company_id': lambda self,cr,uid,c: self.pool.get('res.company')._company_default_get(cr, uid, 'project.project', context=c) +# 'state': lambda *a: 'open', +# 'company_id': lambda self,cr,uid,c: self.pool.get('res.company')._company_default_get(cr, uid, 'project.project', context=c) } + def _check_dates(self, cr, uid, ids): + leave = self.read(cr, uid, ids[0],['date_start','date']) + if leave['date_start'] and leave['date']: + if leave['date_start'] > leave['date']: + return False + return True - _order = "parent_id,priority,name" _constraints = [ - (check_recursion, 'Error ! You can not create recursive projects.', ['parent_id']) + (_check_dates, 'Error! project start-date must be lower then project end-date.', ['date_start', 'date']) ] +# _order = "parent_id,priority,name" +# _constraints = [ +# (check_recursion, 'Error ! You can not create recursive projects.', ['parent_id']) +# ] + # toggle activity of projects, their sub projects and their tasks def set_template(self, cr, uid, ids, context={}): res = self.setActive(cr, uid, ids, value=False, context=context) @@ -206,19 +229,33 @@ class project(osv.osv): return True project() -class project_task_type(osv.osv): - _name = 'project.task.type' - _description = 'Project task type' - _columns = { - 'name': fields.char('Type', required=True, size=64, translate=True), - 'description': fields.text('Description'), - } -project_task_type() - class task(osv.osv): _name = "project.task" _description = "Tasks" _date_name = "date_start" + +# def compute_date(self,cr,uid): +# project_id = self.pool.get('project.project').search(cr,uid,[]) +# for i in range(len(project_id)): +# task_ids = self.pool.get('project.task').search(cr,uid,[('project_id','=',project_id[i])]) +# if task_ids: +# task_obj = self.pool.get('project.task').browse(cr,uid,task_ids) +# task_1 = task_obj[0] +# task_1.date_start = self.pool.get('project.project').browse(cr,uid,project_id[i]).date_start +# dt = mx.DateTime.strptime(task_1.date_start,"%Y-%m-%d").strftime("%Y-%m-%d") +# def Project_1(): +# title = "New Project" +# start = dt +# +# def task1(): +# start = dt +# effort = task_1.planned_hours +# title = "Task 1" +## project_1 = BalancedProject(Project_1) +## for t in project_1: +## print 'details:::',t.indent_name(), t.start, t.end, t.effort + + def _str_get(self, task, level=0, border='***', context={}): return border+' '+(task.user_id and task.user_id.name.upper() or '')+(level and (': L'+str(level)) or '')+(' - %.1fh / %.1fh'%(task.effective_hours or 0.0,task.planned_hours))+' '+border+'\n'+ \ border[0]+' '+(task.name or '')+'\n'+ \ @@ -228,12 +265,12 @@ class task(osv.osv): result = {} for task in self.browse(cr, uid, ids, context=context): result[task.id] = self._str_get(task, border='===') - t2 = task.parent_id + t2 = task.parent_ids level = 0 while t2: level -= 1 result[task.id] = self._str_get(t2, level) + result[task.id] - t2 = t2.parent_id + t2 = t2.parent_ids t3 = map(lambda x: (x,1), task.child_ids) while t3: t2 = t3.pop(0) @@ -258,8 +295,19 @@ class task(osv.osv): res[task.id]['delay_hours'] = res[task.id]['total_hours'] - task.planned_hours return res - def onchange_planned(self, cr, uid, ids, planned, effective=0.0): - return {'value':{'remaining_hours': planned-effective}} + def onchange_planned(self, cr, uid, ids, planned, effective, date_start,occupation_rate=0.0): + result = {} + for res in self.browse(cr, uid, ids): + if date_start and planned: + resource_id = self.pool.get('resource.resource').search(cr,uid,[('user_id','=',res.user_id.id)]) + resource_obj = self.pool.get('resource.resource').browse(cr,uid,resource_id)[0] + d = mx.DateTime.strptime(date_start,'%Y-%m-%d %H:%M:%S') + hrs = (planned)/(occupation_rate) + work_times = self.pool.get('resource.calendar').interval_get(cr, uid, resource_obj.calendar_id.id or False, d, hrs or 0.0, resource_obj.id) + result['date_end'] = work_times[-1][1].strftime('%Y-%m-%d %H:%M:%S') + result['remaining_hours'] = planned-effective + return {'value':result} + def _default_project(self, cr, uid, context={}): if 'project_id' in context and context['project_id']: @@ -275,26 +323,34 @@ class task(osv.osv): default['work_ids'] = [] return super(task, self).copy_data(cr, uid, id, default, context) + def _check_date(self,cr,uid,ids): + for res in self.browse(cr,uid,ids): + if res.date_start and res.date_end: + if res.date_start > res.date_end: + return False + return True + _columns = { 'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the task without removing it."), - 'name': fields.char('Task summary', size=128, required=True), + 'name': fields.char('Task Summary', size=128, required=True), 'description': fields.text('Description'), 'priority' : fields.selection([('4','Very Low'), ('3','Low'), ('2','Medium'), ('1','Urgent'), ('0','Very urgent')], 'Importance'), 'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of tasks."), - 'type': fields.many2one('project.task.type', 'Type'), + 'type': fields.many2one('project.task.type', 'Type', readonly=True), 'state': fields.selection([('draft', 'Draft'),('open', 'In Progress'),('pending', 'Pending'), ('cancelled', 'Cancelled'), ('done', 'Done')], 'State', readonly=True, required=True, help='If the task is created the state \'Draft\'.\n If the task is started, the state becomes \'In Progress\'.\n If review is needed the task is in \'Pending\' state.\ \n If the task is over, the states is set to \'Done\'.'), 'date_start': fields.datetime('Starting Date'), + 'date_end': fields.datetime('Ending Date'), 'date_deadline': fields.datetime('Deadline'), 'date_close': fields.datetime('Date Closed', readonly=True), 'project_id': fields.many2one('project.project', 'Project', ondelete='cascade', help="If you have [?] in the project name, it means there are no analytic account linked to this project."), - 'parent_id': fields.many2one('project.task', 'Parent Task'), - 'child_ids': fields.one2many('project.task', 'parent_id', 'Delegated Tasks'), + 'parent_ids': fields.many2many('project.task', 'project_task_parent_rel', 'task_id', 'parent_id', 'Parent Tasks'), + 'child_ids': fields.many2many('project.task', 'project_task_child_rel', 'task_id', 'child_id', 'Delegated Tasks'), 'history': fields.function(_history_get, method=True, string="Task Details", type="text"), 'notes': fields.text('Notes'), - + 'occupation_rate': fields.float('Occupation Rate', help='The occupation rate fields indicates how much of his time a user is working on a task. A 100% occupation rate means the user works full time on the tasks. The ending date of a task is computed like this: Starting Date + Duration / Occupation Rate.'), 'planned_hours': fields.float('Planned Hours', required=True, help='Estimated time to do the task, usually set by the project manager when the task is in draft state.'), 'effective_hours': fields.function(_hours_get, method=True, string='Hours Spent', multi='hours', store=True, help="Computed using the sum of the task work done."), 'remaining_hours': fields.float('Remaining Hours', digits=(16,4), help="Total remaining time, can be re-estimated periodically by the assignee of the task."), @@ -318,6 +374,7 @@ class task(osv.osv): 'active': lambda *a: True, 'date_start': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'), 'project_id': _default_project, + 'occupation_rate':lambda *a: '1', 'company_id': lambda self,cr,uid,c: self.pool.get('res.company')._company_default_get(cr, uid, 'project.task', context=c) } _order = "sequence, priority, date_deadline, id" @@ -359,24 +416,24 @@ class task(osv.osv): for task in tasks: project = task.project_id if project: - if project.warn_manager and project.manager and (project.manager.id != uid): + if project.warn_manager and project.user_id and (project.user_id.id != uid): request.create(cr, uid, { 'name': _("Task '%s' closed") % task.name, 'state': 'waiting', 'act_from': uid, - 'act_to': project.manager.id, + 'act_to': project.user_id.id, 'ref_partner_id': task.partner_id.id, 'ref_doc1': 'project.task,%d'% (task.id,), 'ref_doc2': 'project.project,%d'% (project.id,), }) self.write(cr, uid, [task.id], {'state': 'done', 'date_close':time.strftime('%Y-%m-%d %H:%M:%S'), 'remaining_hours': 0.0}) - if task.parent_id and task.parent_id.state in ('pending','draft'): + if task.parent_ids and task.parent_ids.state in ('pending','draft'): reopen = True - for child in task.parent_id.child_ids: + for child in task.parent_ids.child_ids: if child.id != task.id and child.state not in ('done','cancelled'): reopen = False if reopen: - self.do_reopen(cr, uid, [task.parent_id.id]) + self.do_reopen(cr, uid, [task.parent_ids.id]) return True def do_reopen(self, cr, uid, ids, *args): @@ -384,12 +441,12 @@ class task(osv.osv): tasks = self.browse(cr, uid, ids) for task in tasks: project = task.project_id - if project and project.warn_manager and project.manager.id and (project.manager.id != uid): + if project and project.warn_manager and project.user_id.id and (project.user_id.id != uid): request.create(cr, uid, { 'name': _("Task '%s' set in progress") % task.name, 'state': 'waiting', 'act_from': uid, - 'act_to': project.manager.id, + 'act_to': project.user_id.id, 'ref_partner_id': task.partner_id.id, 'ref_doc1': 'project.task,%d' % task.id, 'ref_doc2': 'project.project,%d' % project.id, @@ -403,12 +460,12 @@ class task(osv.osv): tasks = self.browse(cr, uid, ids) for task in tasks: project = task.project_id - if project.warn_manager and project.manager and (project.manager.id != uid): + if project.warn_manager and project.user_id and (project.user_id.id != uid): request.create(cr, uid, { 'name': _("Task '%s' cancelled") % task.name, 'state': 'waiting', 'act_from': uid, - 'act_to': project.manager.id, + 'act_to': project.user_id.id, 'ref_partner_id': task.partner_id.id, 'ref_doc1': 'project.task,%d' % task.id, 'ref_doc2': 'project.project,%d' % project.id, @@ -431,6 +488,25 @@ class task(osv.osv): self.write(cr, uid, ids, {'state': 'pending'}) return True + def next_type(self, cr, uid, ids, *args): + for typ in self.browse(cr, uid, ids): + typeid = typ.type.id + types = map(lambda x:x.id, typ.project_id.type_ids) + if types: + if typeid and typeid in types and types.index(typeid) != len(types)-1 : + index = types.index(typeid) + self.write(cr, uid, typ.id, {'type': types[index+1]}) + return True + + def prev_type(self, cr, uid, ids, *args): + for typ in self.browse(cr, uid, ids): + typeid = typ.type.id + types = map(lambda x:x.id, typ.project_id.type_ids) + if types: + if typeid and typeid in types and types.index(typeid) != 0 : + index = types.index(typeid) + self.write(cr, uid, typ.id, {'type': types[index-1]}) + return True task() @@ -508,10 +584,13 @@ class message(osv.osv): message() def _project_get(self, cr, uid, context={}): + if uid==1: + ids = self.pool.get('project.project').search(cr, uid, []) + res = self.pool.get('project.project').read(cr, uid, ids, ['id','name'], context) + return [(str(r['id']),r['name']) for r in res] cr.execute("""SELECT to_char(id, '99999'),name FROM project_project where manager=%s OR id IN (SELECT project_id from project_user_rel where uid=%s)""" % (uid, uid)) - projects = cr.fetchall() - return projects + return cr.fetchall() class users(osv.osv): _inherit = 'res.users' @@ -522,4 +601,4 @@ class users(osv.osv): users() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
\ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/project/project_demo.xml b/addons/project/project_demo.xml index e762d3874ba..7b5d565fead 100644 --- a/addons/project/project_demo.xml +++ b/addons/project/project_demo.xml @@ -9,23 +9,30 @@ <field name="project_time_mode_id" ref="product.uom_hour"></field> </record> - <record id="project_tt_analysis" model="project.task.type"> - <field name="name">Analysis</field> + <!-- Task Types --> + <record id="project_tt_specification" model="project.task.type"> + <field name="sequence">1</field> + <field name="name">Specification</field> </record> - <record id="project_tt_feature" model="project.task.type"> - <field name="name">New Feature</field> + <record id="project_tt_development" model="project.task.type"> + <field name="sequence">2</field> + <field name="name">Development</field> </record> - <record id="project_tt_quote" model="project.task.type"> - <field name="name">Quotation</field> + <record id="project_tt_testing" model="project.task.type"> + <field name="sequence">3</field> + <field name="name">Testing</field> </record> - <record id="project_tt_bug" model="project.task.type"> - <field name="name">Bug</field> + <record id="project_tt_merge" model="project.task.type"> + <field name="sequence">4</field> + <field name="name">Merge</field> </record> - + + <!-- Projects --> <record id="project_project_9" model="project.project"> <field name="warn_manager">1</field> <field name="name">Open ERP Integration</field> <field name="manager" ref="base.user_root"/> + <field eval="[(6, 0, [ref('project_tt_specification'),ref('project_tt_development'),ref('project_tt_testing'),ref('project_tt_merge')])]" name="type_ids"/> </record> <record id="project_project_21" model="project.project"> <field name="warn_manager">1</field> @@ -34,6 +41,7 @@ <field name="name">Study + Prototype</field> <field model="account.analytic.account" name="category_id" search="[('name','=', 'Seagate P1')]"/> <field name="manager" ref="base.user_root"/> + <field eval="[(6, 0, [ref('project_tt_specification'),ref('project_tt_development')])]" name="type_ids"/> </record> <record id="project_project_22" model="project.project"> <field name="priority">20</field> @@ -41,6 +49,7 @@ <field name="name">Specific Developements</field> <field model="account.analytic.account" name="category_id" search="[('name','=', 'Seagate P1')]"/> <field name="manager" ref="base.user_root"/> + <field eval="[(6, 0, [ref('project_tt_specification'), ref('project_tt_development')])]" name="type_ids"/> </record> <record id="project_project_23" model="project.project"> <field name="priority">30</field> @@ -48,12 +57,14 @@ <field name="name">Install, data import, configuration</field> <field model="account.analytic.account" name="category_id" search="[('name','=', 'Seagate P1')]"/> <field name="manager" ref="base.user_root"/> + <field eval="[(6, 0, [ref('project_tt_development')])]" name="type_ids"/> </record> + <!-- Tasks --> <record id="project_task_116" model="project.task"> <field name="planned_hours">38.0</field> <field name="remaining_hours">38.0</field> - <field name="type" ref="project_tt_feature"/> + <field name="type" ref="project_tt_development"/> <field name="user_id" ref="base.user_root"/> <field name="project_id" ref="project_project_22"/> <field name="description">BoM, After sales returns, interventions. Tracability.</field> @@ -62,7 +73,7 @@ <record id="project_task_130" model="project.task"> <field name="planned_hours">16.0</field> <field name="remaining_hours">16.0</field> - <field name="type" ref="project_tt_feature"/> + <field name="type" ref="project_tt_development"/> <field model="res.users" name="user_id" search="[('login','=','demo')]"/> <field name="project_id" ref="project_project_23"/> <field name="name">Data importation + Doc</field> @@ -70,7 +81,7 @@ <record id="project_task_131" model="project.task"> <field name="planned_hours">16.0</field> <field name="remaining_hours">16.0</field> - <field name="type" ref="project_tt_feature"/> + <field name="type" ref="project_tt_development"/> <field model="res.users" name="user_id" search="[('login','=','demo')]"/> <field name="project_id" ref="project_project_23"/> <field name="name">Modifications asked by the customer.</field> @@ -78,7 +89,7 @@ <record id="project_task_184" model="project.task"> <field name="planned_hours">16.0</field> <field name="remaining_hours">16.0</field> - <field name="type" ref="project_tt_feature"/> + <field name="type" ref="project_tt_development"/> <field model="res.users" name="user_id" search="[('login','=','demo')]"/> <field name="priority">0</field> <field name="project_id" ref="project_project_21"/> @@ -88,7 +99,7 @@ <field name="sequence">15</field> <field name="planned_hours">8.0</field> <field name="remaining_hours">8.0</field> - <field name="type" ref="project_tt_feature"/> + <field name="type" ref="project_tt_development"/> <field model="res.users" name="user_id" search="[('login','=','demo')]"/> <field name="project_id" ref="project_project_21"/> <field name="name">Internal testing + Software Install</field> @@ -98,7 +109,7 @@ <field name="sequence">17</field> <field name="planned_hours">16.0</field> <field name="remaining_hours">16.0</field> - <field name="type" ref="project_tt_feature"/> + <field name="type" ref="project_tt_development"/> <field model="res.users" name="user_id" search="[('login','=','demo')]"/> <field name="priority">2</field> <field name="state">open</field> diff --git a/addons/project/project_view.xml b/addons/project/project_view.xml index c7cfee65d20..cee6d9ac2e2 100644 --- a/addons/project/project_view.xml +++ b/addons/project/project_view.xml @@ -30,11 +30,11 @@ <field name="arch" type="xml"> <form string="Project"> <group colspan="6" col="6"> - <field name="name" select="1"/> - <field name="parent_id"/> - <field name="manager" select="1"/> + <field name="name" string="Project Name" select="1"/> + <field name="parent_id" string="Parent Project"/> + <field name="user_id" string="Project Manager" select="1"/> <field name="date_start"/> - <field name="date_end"/> + <field name="date"/> <field name="progress_rate" widget="progressbar"/> </group> <notebook colspan="4"> @@ -42,14 +42,14 @@ <field name="warn_manager"/> <field name="company_id" select="1" groups="base.group_multi_company" widget="selection"/> <field name="priority"/> - <field name="timesheet_id"/> + <field name="resource_calendar_id"/> <field name="active" select="2"/> <field name="planned_hours" widget="float_time"/> <field name="effective_hours" widget="float_time"/> - <field name="category_id" select="2" context="{'default_name':name}"/> + <newline/> <separator colspan="4" string="Project's members"/> - <field colspan="4" name="members" nolabel="1"/> + <field colspan="4" name="resource_ids" nolabel="1"/> <group col="9" colspan="8"> <field name="state" select="1"/> <button name="set_template" string="Set as Template" type="object" states="open" icon="gtk-convert"/> @@ -83,25 +83,12 @@ <label string="Date Stop: %%(date_stop)s"/> </group> </page> - <page string="Tasks"> - <field name="tasks" nolabel="1" attrs="{'readonly':[('state','in',['cancelled','done'])]}"> - <tree colors="grey:state in ('cancelled','done');blue:remaining_hours<0;red:bool(date_deadline) and (date_deadline<current_date) and (state in ('draft','open'));black:state not in ('cancelled','done')" string="Tasks"> - <!-- <tree string="Tasks">--> - <field name="sequence"/> - <field name="name"/> - <field name="user_id"/> - <field name="date_deadline"/> - <field name="planned_hours" sum="Planned" widget="float_time"/> - <field name="delay_hours" sum="Delay" widget="float_time"/> - <field name="progress" widget="progressbar"/> - <field name="priority"/> - <field name="state"/> - <field name="remaining_hours" invisible="1"/> - </tree> - </field> + <page string="Tasks" groups="base.group_extended"> + <separator string="Task Types"/> + <field nolabel="1" name="type_ids" colspan="4"/> </page> <page string="Notes"> - <field colspan="4" name="notes" nolabel="1"/> + <field colspan="4" name="description" nolabel="1"/> </page> </notebook> <newline/> @@ -115,9 +102,9 @@ <field name="priority" eval="5"/> <field name="arch" type="xml"> <tree string="Projects"> - <field name="complete_name"/> - <field name="manager"/> - <field name="partner_id"/> + <field name="complete_name" string="Project Name"/> + <field name="user_id" string="Project Manager"/> + <field name="partner_id" string="Partner"/> <field name="effective_hours" widget="float_time"/> <field name="total_hours" widget="float_time"/> <field name="state"/> @@ -132,11 +119,11 @@ <field name="arch" type="xml"> <search string="Search Project"> <group col='8' colspan='4'> - <filter icon="terp-project" string="My Projects" domain="[('manager', '=', uid)]" help="My Projects"/> + <filter icon="terp-project" string="My Projects" domain="[('user_id', '=', uid)]" help="My Projects"/> <filter icon="terp-project" string="Templates" domain="[('state','=','template')]" help="Template Projects"/> <separator orientation="vertical"/> - <field name="name" select='1'/> - <field name="partner_id" select='1'/> + <field name="name" string="Project Name" select='1'/> + <field name="partner_id" string="Partner" select='1'/> <field name="state" select="1"/> </group> </search> @@ -147,12 +134,12 @@ <field name="name">project.project.tree</field> <field name="model">project.project</field> <field name="type">tree</field> - <field name="field_parent">child_id</field> + <field name="field_parent">child_ids</field> <field name="arch" type="xml"> <tree string="Projects"> - <field name="name"/> - <field name="manager"/> - <field name="partner_id"/> + <field name="name" string="Project Name"/> + <field name="user_id" string="Project Manager"/> + <field name="partner_id" string="Partner"/> <field name="planned_hours" widget="float_time"/> <field name="total_hours" widget="float_time"/> <field name="effective_hours" widget="float_time"/> @@ -216,11 +203,11 @@ <field name="name">project.project.tree</field> <field name="model">project.project</field> <field name="type">tree</field> - <field name="field_parent">child_id</field> + <field name="field_parent">child_ids</field> <field name="arch" type="xml"> <tree string="My projects"> - <field name="name"/> - <field name="partner_id"/> + <field name="name" string="Project Name"/> + <field name="partner_id" string="Partner"/> <field name="planned_hours" widget="float_time"/> <field name="effective_hours" widget="float_time"/> <field name="progress_rate" widget="progressbar"/> @@ -281,7 +268,10 @@ <field name="name" select="1"/> <field name="project_id" required="1" select="1"/> <field name="total_hours" widget="float_time"/> + <field name="date_start"/> <field name="date_deadline" select="2"/> + <field name="occupation_rate"/> + <field name="date_end"/> <field name="user_id" select="1"/> <field name="progress" widget="progressbar"/> </group> @@ -292,7 +282,7 @@ name="planned_hours" widget="float_time" attrs="{'readonly':[('state','!=','draft')]}" - on_change="onchange_planned(planned_hours,effective_hours)"/> + on_change="onchange_planned(planned_hours,effective_hours,date_start,occupation_rate)"/> <field name="remaining_hours" select="2" widget="float_time" attrs="{'readonly':[('state','!=','draft')]}" colspan="2"/> <button name="%(action_config_compute_remaining)d" string="Review" type="action" colspan="1" target="new" states="open,pending" icon="gtk-edit"/> </group> @@ -304,10 +294,10 @@ <field colspan="4" name="description" nolabel="1" select="2" attrs="{'readonly':[('state','=','done')]}" widget="text_wiki"/> <field colspan="4" name="work_ids" nolabel="1" attrs="{'readonly':[('state','in',['draft','done'])]}"> <tree string="Task Work" editable="top"> - <field name="date" /> - <field name="user_id" /> - <field name="hours" widget="float_time" /> <field name="name" /> + <field name="hours" widget="float_time" /> + <field name="user_id" /> + <field name="date" /> </tree> </field> <newline/> @@ -320,12 +310,12 @@ <button groups="base.group_extended" name="%(wizard_delegate_task)d" states="pending,open" string="Delegate" type="action" icon="gtk-sort-descending"/> <button name="%(wizard_close_task)d" states="pending,open" string="Done" type="action" icon="gtk-jump-to"/> <button name="do_cancel" states="draft,open,pending" string="Cancel" type="object" icon="gtk-cancel"/> - </group> </page> <page groups="base.group_extended" string="Delegations"> - <field name="parent_id"/> - <newline/> + <separator string="Parent Tasks" colspan="4"/> + <field colspan="4" height="150" name="parent_ids" nolabel="1"/> + <separator string="Delegated tasks" colspan="4"/> <field colspan="4" height="150" name="child_ids" nolabel="1" attrs="{'readonly':[('state','!=','draft')]}"> <tree string="Delegated tasks"> <field name="name"/> @@ -339,6 +329,7 @@ </field> <field colspan="4" name="history" nolabel="1"/> </page> + <page groups="base.group_extended" string="Extra Info" attrs="{'readonly':[('state','=','done')]}"> <group colspan="2" col="2"> <separator string="Planning" colspan="2"/> @@ -347,14 +338,17 @@ </group> <group colspan="2" col="2"> <separator string="Dates" colspan="2"/> - <field name="date_start" select="2"/> <field name="date_close" select="2"/> </group> <separator string="Miscelleanous" colspan="4"/> - <field name="type" widget="selection"/> + <field name="partner_id" select="2"/> <field name="company_id" select="1" groups="base.group_multi_company" widget="selection"/> + <group col="4" colspan="2"> + <field name="type" widget="selection" /> + <button name="prev_type" string="Previous" type="object" icon="gtk-go-back" help="Change to Previous Type"/> + <button name="next_type" string="Next" type="object" icon="gtk-go-forward" help="Change to Next Type"/> + </group> <field name="active" select="2"/> - <field name="partner_id" select="2"/> <separator colspan="4" string="Notes"/> <field colspan="4" name="notes" nolabel="1"/> </page> @@ -369,12 +363,14 @@ <field eval="2" name="priority"/> <field name="arch" type="xml"> <tree colors="grey:state in ('cancelled','done');blue:remaining_hours<0;red:bool(date_deadline) and (date_deadline<current_date) and (state in ('draft','open'));black:state not in ('cancelled','done')" string="Tasks"> - <field name="sequence" string="Seq."/> + <field name="sequence" invisible="1"/> <field name="name"/> <field name="project_id" icon="gtk-indent"/> <field name="user_id"/> <field name="date_deadline"/> <field name="remaining_hours" widget="float_time"/> + <field name="type"/> + <button name="next_type" states="draft,open,pending" string="Change Type" type="object" icon="gtk-go-forward" help="Change Type"/> <field name="progress" widget="progressbar"/> <field name="state"/> <button name="do_open" states="pending,draft" string="Start Task" type="object" icon="gtk-execute" help="For changing to open state"/> @@ -474,19 +470,21 @@ <field name="type">search</field> <field name="arch" type="xml"> <search string="Task Edition"> - <group col="8" colspan="4"> + <group col="20" colspan="4"> + <filter string="By Users" icon="terp-project" domain="[]" context="{'group_by':'user_id'}"/> + <filter string="By Project" icon="terp-project" domain="[]" context="{'group_by':'project_id'}"/> + <filter string="By Type" icon="terp-project" domain="[]" context="{'group_by':'type'}"/> + <separator orientation="vertical"/> <filter string="Draft" domain="[('state','=','draft')]" help="Draft Tasks" icon="terp-project"/> - <filter string="Open" domain="[('state','=','open')]" help="Open Tasks" icon="terp-project"/> + <filter string="In Progress" domain="[('state','=','open')]" help="Open Tasks" icon="terp-project"/> <filter string="Pending" domain="[('state','=','pending')]" help="Pending Tasks" icon="terp-project"/> <separator orientation="vertical"/> <field name="name" select="1"/> <field name="project_id" select="1" widget="selection"> <filter domain="[('manager_id','=',False)]" help="Unassigned Project" icon="terp-project"/> </field> - </group> - <group col="4" colspan="1"> <field name="user_id" select="1" widget="selection"> - <filter domain="[('user_id','=',uid)]" help="My Tasks" icon="gtk-execute"/> + <filter domain="[('user_id','=',uid)]" help="My Tasks" icon="gtk-execute" default="1"/> <filter domain="[('user_id','=',False)]" help="Unassigned Tasks" icon="gtk-execute" separator="1"/> </field> </group> @@ -495,70 +493,18 @@ </record> <record id="action_view_task" model="ir.actions.act_window"> - <field name="name">All Tasks</field> + <field name="name">Tasks</field> <field name="res_model">project.task</field> <field name="view_type">form</field> <field name="view_mode">tree,form,calendar,gantt,graph</field> <field eval="False" name="view_id"/> <field eval="True" name="filter"/> + <field name="view_id" ref="view_task_tree2"/> <field name="search_view_id" ref="view_task_search_form"/> </record> <!--<menuitem action="action_view_task" id="menu_action_view_task" parent="project.menu_tasks"/> --> <menuitem action="action_view_task" id="menu_action_view_task" parent="project.menu_project_management" name="Tasks"/> - <record id="action_view_task_department" model="ir.actions.act_window"> - <field name="name">My Department Tasks</field> - <field name="res_model">project.task</field> - <field name="view_type">form</field> - <field name="view_mode">tree,form,calendar,gantt,graph</field> - <field eval="True" name="filter"/> - <field name="domain">[('user_id', 'child_of', [uid])]</field> - <field eval="True" name="filter"/> - <field name="search_view_id" ref="view_task_search_form"/> - </record> - - <record id="action_view_task5_departments_pending" model="ir.actions.act_window"> - <field name="name">My Department's Pending Tasks</field> - <field name="res_model">project.task</field> - <field name="view_type">form</field> - <field name="view_mode">tree,form,calendar,graph</field> - <field name="domain">[('user_id', 'child_of', [uid]),('state','=','pending')]</field> - <field name="view_id" ref="my_pending_task"/> - <field name="filter" eval="True"/> - <field name="search_view_id" ref="view_task_search_form"/> - </record> - - <record id="action_view_task5_departments_prog" model="ir.actions.act_window"> - <field name="name">My Department's Current Tasks</field> - <field name="res_model">project.task</field> - <field name="view_type">form</field> - <field name="view_mode">tree,form,calendar,graph</field> - <field eval="True" name="filter"/> - <field name="domain">[('user_id', 'child_of', [uid]),('state','in',('open','draft'))]</field> - <field name="filter" eval="True"/> - <field name="search_view_id" ref="view_task_search_form"/> - </record> - - <record id="action_view_task5_departments_prog_prog" model="ir.actions.act_window"> - <field name="name">My Department's Tasks in Progress</field> - <field name="res_model">project.task</field> - <field name="view_type">form</field> - <field name="view_mode">tree,form,calendar,graph</field> - <field name="domain">[('user_id', 'child_of', [uid]),('state','=','open')]</field> - <field name="filter" eval="True"/> - <field name="search_view_id" ref="view_task_search_form"/> - </record> - - <record id="action_view_task5_departments_prog_draft" model="ir.actions.act_window"> - <field name="name">My Department's Draft Tasks</field> - <field name="res_model">project.task</field> - <field name="view_type">form</field> - <field name="view_mode">tree,form,calendar,graph</field> - <field name="domain">[('user_id', 'child_of', [uid]),('state','=','draft')]</field> - <field name="filter" eval="True"/> - <field name="search_view_id" ref="view_task_search_form"/> - </record> - <record id="action_view_task_overpassed_draft" model="ir.actions.act_window"> <field name="name">Overpassed Tasks</field> <field name="res_model">project.task</field> @@ -569,26 +515,6 @@ <field name="search_view_id" ref="view_task_search_form"/> </record> - <record id="action_view_task6_prog" model="ir.actions.act_window"> - <field name="name">Tasks in Progress</field> - <field name="res_model">project.task</field> - <field name="view_type">form</field> - <field name="view_mode">tree,form,calendar,graph,gantt</field> - <field name="filter" eval="True"/> - <field name="search_view_id" ref="view_task_search_form"/> - <field name="domain">[('state','=','open')]</field> - </record> -menu_main - <record id="action_view_task7" model="ir.actions.act_window"> - <field name="name">Unassigned Tasks</field> - <field name="res_model">project.task</field> - <field name="view_type">form</field> - <field name="view_mode">tree,form,calendar,graph,gantt</field> - <field name="domain">[('user_id', '=', False)]</field> - <field name="filter" eval="True"/> - <field name="search_view_id" ref="view_task_search_form"/> - </record> - <!-- Opening task when double clicking on project --> <record id="dblc_proj" model="ir.actions.act_window"> <field name="res_model">project.task</field> @@ -613,7 +539,8 @@ menu_main <field name="type">form</field> <field name="arch" type="xml"> <form string="Task type"> - <field colspan="4" name="name" select="1"/> + <field name="name" select="1"/> + <field name="sequence"/> <field colspan="4" name="description" select="1"/> </form> </field> @@ -624,6 +551,7 @@ menu_main <field name="type">tree</field> <field name="arch" type="xml"> <tree string="Task type"> + <field name="sequence"/> <field name="name"/> </tree> </field> @@ -636,7 +564,7 @@ menu_main </record> <menuitem action="open_task_type_form" id="menu_task_types" parent="project.menu_definitions"/> - <act_window domain="[('manager', '=', 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"/> + <act_window domain="[('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"/> <act_window domain="[('project_id', '=', active_id)]" @@ -650,7 +578,7 @@ menu_main <act_window domain="[('project_id', '=', active_id)]" id="act_project_project_2_project_task_all" - name="All Tasks" + name="Tasks" res_model="project.task" src_model="project.project" view_mode="tree,form,calendar,graph" diff --git a/addons/project/project_wizard.xml b/addons/project/project_wizard.xml index d86781ab4ab..3e441e3f8f0 100644 --- a/addons/project/project_wizard.xml +++ b/addons/project/project_wizard.xml @@ -3,6 +3,5 @@ <data> <wizard id="wizard_close_task" menu="False" model="project.task" name="project.task.close" string="Close Task"/> <wizard id="wizard_delegate_task" menu="False" model="project.task" name="project.task.delegate" string="Delegate Task"/> - <!-- <wizard id="wizard_attachment_task" model="project.task" name="project.task.attachment" string="All Attachments"/> --> </data> </openerp> diff --git a/addons/project/report/_date_compute.py b/addons/project/report/_date_compute.py index cf900d2d08b..1d44bd5c3cf 100644 --- a/addons/project/report/_date_compute.py +++ b/addons/project/report/_date_compute.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- ############################################################################## -# +# # OpenERP, Open Source Management Solution # Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>). # @@ -15,7 +15,7 @@ # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. +# along with this program. If not, see <http://www.gnu.org/licenses/>. # ############################################################################## @@ -58,7 +58,7 @@ def _compute_tasks(cr, uid, task_list, date_begin): # Compute the closing date of the task tasks[task.id] = [] - res = pooler.get_pool(cr.dbname).get('hr.timesheet.group').interval_get(cr, uid, task.project_id.timesheet_id.id, date_start, task.remaining_hours) + res = pooler.get_pool(cr.dbname).get('resource.calendar').interval_get(cr, uid, task.project_id.resource_calendar_id.id, date_start, task.remaining_hours) for (d1,d2) in res: tasks[task.id].append((d1, d2, task.name, task.user_id.login)) date_close = tasks[task.id][-1][1] @@ -72,7 +72,7 @@ def _compute_tasks(cr, uid, task_list, date_begin): def _compute_project(cr, uid, project, date_begin): tasks, last_date = _compute_tasks(cr, uid, project.tasks, date_begin) - for proj in project.child_id: + for proj in project.child_ids: d0 = DateTime.strptime(proj.date_start,'%Y-%m-%d') if d0 > last_date: last_date = d0 diff --git a/addons/project/wizard/__init__.py b/addons/project/wizard/__init__.py index 997b02c90f9..4618faf8463 100644 --- a/addons/project/wizard/__init__.py +++ b/addons/project/wizard/__init__.py @@ -21,7 +21,6 @@ import close_task import task_delegate -import task_attachment # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/project/wizard/task_attachment.py b/addons/project/wizard/task_attachment.py deleted file mode 100644 index 0d3c88e4874..00000000000 --- a/addons/project/wizard/task_attachment.py +++ /dev/null @@ -1,49 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>). -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. -# -############################################################################## - -import wizard -import pooler - -'''View the attachments of the parent + children tasks''' - -def _show_attachment(self, cr, uid, data, context): - task_obj = pooler.get_pool(cr.dbname).get('project.task') - task_browse_id = task_obj.browse(cr, uid, [data['id']], context)[0] - attachment_list = [child_id.id for child_id in task_browse_id.child_ids] - attachment_list.extend([task_browse_id.parent_id.id]) - value = { - 'domain': [('res_model','=',data['model']),('res_id','in',attachment_list)], - 'name': 'Attachments', - 'view_type': 'form', - 'view_mode': 'tree,form', - 'res_model': 'ir.attachment', - 'context': { }, - 'type': 'ir.actions.act_window' - } - return value -class wizard_attachment(wizard.interface): - states = { - 'init': { - 'actions': [], - 'result': {'type':'action', 'action':_show_attachment, 'state': 'end'}, - }, - } -wizard_attachment('project.task.attachment') |
