[IMP] Clean demo data of project and project long term using scheduler
bzr revid: fp@tinyerp.com-20111113154052-gh2a8y2tqkdv2ll9
This commit is contained in:
parent
7e785ced6b
commit
14874a989e
|
@ -28,7 +28,7 @@
|
|||
"category": "Project Management",
|
||||
'complexity': "easy",
|
||||
"images": ["images/gantt.png", "images/project_dashboard.jpeg","images/project_task_tree.jpeg","images/project_task.jpeg","images/project.jpeg","images/task_analysis.jpeg"],
|
||||
"depends": ["base_setup", "product", "analytic", "board", "mail"],
|
||||
"depends": ["base_setup", "product", "analytic", "board", "mail", "resource"],
|
||||
"description": """
|
||||
Project management module tracks multi-level projects, tasks, work done on tasks, eso.
|
||||
======================================================================================
|
||||
|
|
|
@ -25,6 +25,7 @@ from datetime import datetime, date
|
|||
|
||||
from tools.translate import _
|
||||
from osv import fields, osv
|
||||
from resource.faces import task as Task
|
||||
|
||||
# I think we can remove this in v6.1 since VMT's improvements in the framework ?
|
||||
#class project_project(osv.osv):
|
||||
|
@ -139,6 +140,7 @@ class project(osv.osv):
|
|||
'project.task': (_get_project_task, ['planned_hours', 'effective_hours', 'remaining_hours', 'total_hours', 'progress', 'delay_hours','state'], 10),
|
||||
}),
|
||||
'effective_hours': fields.function(_progress_rate, multi="progress", string='Time Spent', help="Sum of spent hours of all tasks related to this project and its child projects."),
|
||||
'resource_calendar_id': fields.many2one('resource.calendar', 'Working Time', help="Timetable working hours to adjust the gantt diagram report", states={'close':[('readonly',True)]} ),
|
||||
'total_hours': fields.function(_progress_rate, multi="progress", string='Total Time', help="Sum of total hours of all tasks related to this project and its child projects.",
|
||||
store = {
|
||||
'project.project': (lambda self, cr, uid, ids, c={}: ids, ['tasks'], 10),
|
||||
|
@ -305,6 +307,105 @@ class project(osv.osv):
|
|||
self.setActive(cr, uid, child_ids, value, context=None)
|
||||
return True
|
||||
|
||||
def _schedule_header(self, cr, uid, ids, force_members=True, context=None):
|
||||
context = context or {}
|
||||
if type(ids) in (long, int,):
|
||||
ids = [ids]
|
||||
projects = self.browse(cr, uid, ids, context=context)
|
||||
|
||||
for project in projects:
|
||||
if (not project.members) and force_members:
|
||||
raise osv.except_osv(_('Warning !'),_("You must assign members on the project '%s' !") % (project.name,))
|
||||
|
||||
resource_pool = self.pool.get('resource.resource')
|
||||
|
||||
result = "from resource.faces import *\n"
|
||||
result += "import datetime\n"
|
||||
for project in self.browse(cr, uid, ids, context=context):
|
||||
u_ids = [i.id for i in project.members]
|
||||
if project.user_id and (project.user_id.id not in u_ids):
|
||||
u_ids.append(project.user_id.id)
|
||||
for task in project.tasks:
|
||||
if task.state in ('done','cancelled'):
|
||||
continue
|
||||
if task.user_id and (task.user_id.id not in u_ids):
|
||||
u_ids.append(task.user_id.id)
|
||||
calendar_id = project.resource_calendar_id and project.resource_calendar_id.id or False
|
||||
resource_objs = resource_pool.generate_resources(cr, uid, u_ids, calendar_id, context=context)
|
||||
for key, vals in resource_objs.items():
|
||||
result +='''
|
||||
class User_%s(Resource):
|
||||
efficiency = %s
|
||||
''' % (key, vals.get('efficiency', False))
|
||||
|
||||
result += '''
|
||||
def Project():
|
||||
'''
|
||||
return result
|
||||
|
||||
def _schedule_project(self, cr, uid, project, context=None):
|
||||
resource_pool = self.pool.get('resource.resource')
|
||||
calendar_id = project.resource_calendar_id and project.resource_calendar_id.id or False
|
||||
working_days = resource_pool.compute_working_calendar(cr, uid, calendar_id, context=context)
|
||||
# TODO: check if we need working_..., default values are ok.
|
||||
puids = [x.id for x in project.members]
|
||||
if project.user_id:
|
||||
puids.append(project.user_id.id)
|
||||
result = """
|
||||
def Project_%d():
|
||||
start = \'%s\'
|
||||
working_days = %s
|
||||
resource = %s
|
||||
""" % (
|
||||
project.id,
|
||||
project.date_start, working_days,
|
||||
'|'.join(['User_'+str(x) for x in puids])
|
||||
)
|
||||
vacation = calendar_id and tuple(resource_pool.compute_vacation(cr, uid, calendar_id, context=context)) or False
|
||||
if vacation:
|
||||
result+= """
|
||||
vacation = %s
|
||||
""" % ( vacation, )
|
||||
return result
|
||||
|
||||
#TODO: DO Resource allocation and compute availability
|
||||
def compute_allocation(self, rc, uid, ids, start_date, end_date, context=None):
|
||||
if context == None:
|
||||
context = {}
|
||||
allocation = {}
|
||||
return allocation
|
||||
|
||||
def schedule_tasks(self, cr, uid, ids, context=None):
|
||||
context = context or {}
|
||||
if type(ids) in (long, int,):
|
||||
ids = [ids]
|
||||
projects = self.browse(cr, uid, ids, context=context)
|
||||
result = self._schedule_header(cr, uid, ids, False, context=context)
|
||||
for project in projects:
|
||||
result += self._schedule_project(cr, uid, project, context=context)
|
||||
result += self.pool.get('project.task')._generate_task(cr, uid, project.tasks, ident=4, context=context)
|
||||
|
||||
local_dict = {}
|
||||
exec result in local_dict
|
||||
projects_gantt = Task.BalancedProject(local_dict['Project'])
|
||||
|
||||
for project in projects:
|
||||
project_gantt = getattr(projects_gantt, 'Project_%d' % (project.id,))
|
||||
for task in project.tasks:
|
||||
if task.state in ('done','cancelled'):
|
||||
continue
|
||||
|
||||
p = getattr(project_gantt, 'Task_%d' % (task.id,))
|
||||
|
||||
self.pool.get('project.task').write(cr, uid, [task.id], {
|
||||
'date_start': p.start.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
'date_end': p.end.strftime('%Y-%m-%d %H:%M:%S')
|
||||
}, context=context)
|
||||
if (not task.user_id) and (p.booked_resource):
|
||||
self.pool.get('project.task').write(cr, uid, [task.id], {
|
||||
'user_id': int(p.booked_resource[0].name[5:]),
|
||||
}, context=context)
|
||||
return True
|
||||
project()
|
||||
|
||||
class users(osv.osv):
|
||||
|
@ -836,6 +937,33 @@ class task(osv.osv):
|
|||
res = super(task, self).unlink(cr, uid, ids, context)
|
||||
return res
|
||||
|
||||
def _generate_task(self, cr, uid, tasks, ident=4, context=None):
|
||||
context = context or {}
|
||||
result = ""
|
||||
ident = ' '*ident
|
||||
for task in tasks:
|
||||
if task.state in ('done','cancelled'):
|
||||
continue
|
||||
result += '''
|
||||
%sdef Task_%s():
|
||||
%s todo = \"%.2fH\"
|
||||
%s effort = \"%.2fH\"''' % (ident,task.id, ident,task.remaining_hours, ident,task.total_hours)
|
||||
start = []
|
||||
for t2 in task.parent_ids:
|
||||
start.append("up.Task_%s.end" % (t2.id,))
|
||||
if start:
|
||||
result += '''
|
||||
%s start = max(%s)
|
||||
''' % (ident,','.join(start))
|
||||
|
||||
if task.user_id:
|
||||
result += '''
|
||||
%s resource = %s
|
||||
''' % (ident, 'User_'+str(task.user_id.id))
|
||||
|
||||
result += "\n"
|
||||
return result
|
||||
|
||||
task()
|
||||
|
||||
class project_work(osv.osv):
|
||||
|
|
|
@ -272,6 +272,7 @@
|
|||
<field name="name">Study + Prototype</field>
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
<field eval="[(6, 0, [ref('project_tt_specification'),ref('project_tt_development')])]" name="type_ids"/>
|
||||
<field eval="[(6, 0, [ref('base.user_root'),ref('base.user_demo')])]" name="members"/>
|
||||
</record>
|
||||
<record id="project_project_22" model="project.project">
|
||||
<field name="priority">20</field>
|
||||
|
@ -279,12 +280,14 @@
|
|||
<field name="name">Specific Developments</field>
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
<field eval="[(6, 0, [ref('project_tt_specification'), ref('project_tt_development')])]" name="type_ids"/>
|
||||
<field eval="[(6, 0, [ref('base.user_root'),ref('base.user_demo')])]" name="members"/>
|
||||
</record>
|
||||
<record id="project_project_23" model="project.project">
|
||||
<field name="priority">30</field>
|
||||
<field name="parent_id" ref="all_projects_account"/>
|
||||
<field name="name">Install, data import, configuration</field>
|
||||
<field eval="[(6, 0, [ref('project_tt_development')])]" name="type_ids"/>
|
||||
<field eval="[(6, 0, [ref('base.user_root'),ref('base.user_demo')])]" name="members"/>
|
||||
</record>
|
||||
|
||||
<!-- Tasks -->
|
||||
|
@ -292,7 +295,7 @@
|
|||
<field name="planned_hours">38.0</field>
|
||||
<field name="remaining_hours">38.0</field>
|
||||
<field name="type_id" ref="project_tt_development"/>
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
<field name="user_id" eval="False"/>
|
||||
<field name="project_id" ref="project_project_22"/>
|
||||
<field name="description">BoM, After sales returns, interventions. Traceability.</field>
|
||||
<field name="name">Specific adaptation to MRP</field>
|
||||
|
@ -302,8 +305,8 @@
|
|||
<record id="project_task_130" model="project.task">
|
||||
<field name="planned_hours">16.0</field>
|
||||
<field name="remaining_hours">16.0</field>
|
||||
<field name="user_id" eval="False"/>
|
||||
<field name="type_id" 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>
|
||||
</record>
|
||||
|
@ -312,8 +315,8 @@
|
|||
<record id="project_task_131" model="project.task">
|
||||
<field name="planned_hours">16.0</field>
|
||||
<field name="remaining_hours">16.0</field>
|
||||
<field name="user_id" eval="False"/>
|
||||
<field name="type_id" 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>
|
||||
</record>
|
||||
|
@ -323,18 +326,17 @@
|
|||
<field name="planned_hours">16.0</field>
|
||||
<field name="remaining_hours">16.0</field>
|
||||
<field name="type_id" ref="project_tt_testing"/>
|
||||
<field model="res.users" name="user_id" search="[('login','=','demo')]"/>
|
||||
<field name="user_id" eval="False"/>
|
||||
<field name="priority">0</field>
|
||||
<field name="project_id" ref="project_project_21"/>
|
||||
<field name="name">Customer analysis + Architecture</field>
|
||||
<field name="date_start">12-17-2011</field>
|
||||
</record>
|
||||
<record id="project_task_186" model="project.task">
|
||||
<field name="sequence">15</field>
|
||||
<field name="planned_hours">8.0</field>
|
||||
<field name="remaining_hours">8.0</field>
|
||||
<field name="type_id" ref="project_tt_testing"/>
|
||||
<field model="res.users" name="user_id" search="[('login','=','demo')]"/>
|
||||
<field name="user_id" eval="False"/>
|
||||
<field name="project_id" ref="project_project_21"/>
|
||||
<field name="name">Internal testing + Software Install</field>
|
||||
</record>
|
||||
|
@ -343,7 +345,7 @@
|
|||
<field name="planned_hours">16.0</field>
|
||||
<field name="remaining_hours">16.0</field>
|
||||
<field name="type_id" ref="project_tt_development"/>
|
||||
<field model="res.users" name="user_id" search="[('login','=','demo')]"/>
|
||||
<field name="user_id" eval="False"/>
|
||||
<field name="priority">2</field>
|
||||
<field name="project_id" ref="project_project_21"/>
|
||||
<field name="name">Analysis, Data Importation</field>
|
||||
|
@ -354,7 +356,7 @@
|
|||
<field name="sequence">20</field>
|
||||
<field name="planned_hours">16.0</field>
|
||||
<field name="remaining_hours">16.0</field>
|
||||
<field model="res.users" name="user_id" search="[('login','=','demo')]"/>
|
||||
<field name="user_id" eval="False"/>
|
||||
<field name="project_id" ref="project_project_23"/>
|
||||
<field name="name">Parameters</field>
|
||||
<field name="type_id" ref="project_tt_specification"/>
|
||||
|
@ -365,12 +367,16 @@
|
|||
<field name="sequence">20</field>
|
||||
<field name="planned_hours">32.0</field>
|
||||
<field name="remaining_hours">32.0</field>
|
||||
<field model="res.users" name="user_id" search="[('login','=','demo')]"/>
|
||||
<field name="user_id" eval="False"/>
|
||||
<field name="state">open</field>
|
||||
<field name="project_id" ref="project_project_21"/>
|
||||
<field name="name">Start of the doc redaction + MRP</field>
|
||||
<field name="type_id" ref="project_tt_testing"/>
|
||||
</record>
|
||||
|
||||
<!-- Schedule tasks to assign users and dates -->
|
||||
|
||||
<function model="project.project" name="schedule_tasks" eval="[[ref('project_project_21'), ref('project_project_22'), ref('project_project_23')]]"/>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -23,7 +23,6 @@ from datetime import datetime
|
|||
from tools.translate import _
|
||||
from osv import fields, osv
|
||||
from resource.faces import task as Task
|
||||
from operator import itemgetter
|
||||
|
||||
class project_phase(osv.osv):
|
||||
_name = "project.phase"
|
||||
|
@ -223,65 +222,7 @@ class project(osv.osv):
|
|||
_inherit = "project.project"
|
||||
_columns = {
|
||||
'phase_ids': fields.one2many('project.phase', 'project_id', "Project Phases"),
|
||||
'resource_calendar_id': fields.many2one('resource.calendar', 'Working Time', help="Timetable working hours to adjust the gantt diagram report", states={'close':[('readonly',True)]} ),
|
||||
}
|
||||
def _schedule_header(self, cr, uid, ids, context=None):
|
||||
context = context or {}
|
||||
if type(ids) in (long, int,):
|
||||
ids = [ids]
|
||||
projects = self.browse(cr, uid, ids, context=context)
|
||||
|
||||
for project in projects:
|
||||
if not project.members:
|
||||
raise osv.except_osv(_('Warning !'),_("You must assign members on the project '%s' !") % (project.name,))
|
||||
|
||||
resource_pool = self.pool.get('resource.resource')
|
||||
|
||||
result = "from resource.faces import *\n"
|
||||
result += "import datetime\n"
|
||||
for project in self.browse(cr, uid, ids, context=context):
|
||||
u_ids = [i.id for i in project.members]
|
||||
for task in project.tasks:
|
||||
if task.state in ('done','cancelled'):
|
||||
continue
|
||||
if task.user_id and (task.user_id.id not in u_ids):
|
||||
u_ids.append(task.user_id.id)
|
||||
calendar_id = project.resource_calendar_id and project.resource_calendar_id.id or False
|
||||
resource_objs = resource_pool.generate_resources(cr, uid, u_ids, calendar_id, context=context)
|
||||
for key, vals in resource_objs.items():
|
||||
result +='''
|
||||
class User_%s(Resource):
|
||||
efficiency = %s
|
||||
''' % (key, vals.get('efficiency', False))
|
||||
|
||||
result += '''
|
||||
def Project():
|
||||
'''
|
||||
return result
|
||||
|
||||
def _schedule_project(self, cr, uid, project, context=None):
|
||||
resource_pool = self.pool.get('resource.resource')
|
||||
calendar_id = project.resource_calendar_id and project.resource_calendar_id.id or False
|
||||
working_days = resource_pool.compute_working_calendar(cr, uid, calendar_id, context=context)
|
||||
# TODO: check if we need working_..., default values are ok.
|
||||
result = """
|
||||
def Project_%d():
|
||||
start = \'%s\'
|
||||
working_days = %s
|
||||
resource = %s
|
||||
""" % (
|
||||
project.id,
|
||||
project.date_start, working_days,
|
||||
'|'.join(['User_'+str(x.id) for x in project.members])
|
||||
)
|
||||
vacation = calendar_id and tuple(resource_pool.compute_vacation(cr, uid, calendar_id, context=context)) or False
|
||||
if vacation:
|
||||
result+= """
|
||||
vacation = %s
|
||||
""" % ( vacation, )
|
||||
return result
|
||||
|
||||
|
||||
def schedule_phases(self, cr, uid, ids, context=None):
|
||||
context = context or {}
|
||||
if type(ids) in (long, int,):
|
||||
|
@ -321,45 +262,6 @@ def Project():
|
|||
'date_end': p.end.strftime('%Y-%m-%d %H:%M:%S')
|
||||
}, context=context)
|
||||
return True
|
||||
|
||||
#TODO: DO Resource allocation and compute availability
|
||||
def compute_allocation(self, rc, uid, ids, start_date, end_date, context=None):
|
||||
if context == None:
|
||||
context = {}
|
||||
allocation = {}
|
||||
return allocation
|
||||
|
||||
def schedule_tasks(self, cr, uid, ids, context=None):
|
||||
context = context or {}
|
||||
if type(ids) in (long, int,):
|
||||
ids = [ids]
|
||||
projects = self.browse(cr, uid, ids, context=context)
|
||||
result = self._schedule_header(cr, uid, ids, context=context)
|
||||
for project in projects:
|
||||
result += self._schedule_project(cr, uid, project, context=context)
|
||||
result += self.pool.get('project.task')._generate_task(cr, uid, project.tasks, ident=4, context=context)
|
||||
|
||||
local_dict = {}
|
||||
exec result in local_dict
|
||||
projects_gantt = Task.BalancedProject(local_dict['Project'])
|
||||
|
||||
for project in projects:
|
||||
project_gantt = getattr(projects_gantt, 'Project_%d' % (project.id,))
|
||||
for task in project.tasks:
|
||||
if task.state in ('done','cancelled'):
|
||||
continue
|
||||
|
||||
p = getattr(project_gantt, 'Task_%d' % (task.id,))
|
||||
|
||||
self.pool.get('project.task').write(cr, uid, [task.id], {
|
||||
'date_start': p.start.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
'date_end': p.end.strftime('%Y-%m-%d %H:%M:%S')
|
||||
}, context=context)
|
||||
if (not task.user_id) and (p.booked_resource):
|
||||
self.pool.get('project.task').write(cr, uid, [task.id], {
|
||||
'user_id': int(p.booked_resource[0].name[5:]),
|
||||
}, context=context)
|
||||
return True
|
||||
project()
|
||||
|
||||
class project_task(osv.osv):
|
||||
|
@ -367,30 +269,4 @@ class project_task(osv.osv):
|
|||
_columns = {
|
||||
'phase_id': fields.many2one('project.phase', 'Project Phase'),
|
||||
}
|
||||
def _generate_task(self, cr, uid, tasks, ident=4, context=None):
|
||||
context = context or {}
|
||||
result = ""
|
||||
ident = ' '*ident
|
||||
for task in tasks:
|
||||
if task.state in ('done','cancelled'):
|
||||
continue
|
||||
result += '''
|
||||
%sdef Task_%s():
|
||||
%s todo = \"%.2fH\"
|
||||
%s effort = \"%.2fH\"''' % (ident,task.id, ident,task.remaining_hours, ident,task.total_hours)
|
||||
start = []
|
||||
for t2 in task.parent_ids:
|
||||
start.append("up.Task_%s.end" % (t2.id,))
|
||||
if start:
|
||||
result += '''
|
||||
%s start = max(%s)
|
||||
''' % (ident,','.join(start))
|
||||
|
||||
if task.user_id:
|
||||
result += '''
|
||||
%s resource = %s
|
||||
''' % (ident, 'User_'+str(task.user_id.id))
|
||||
|
||||
result += "\n"
|
||||
return result
|
||||
project_task()
|
||||
|
|
Loading…
Reference in New Issue