diff --git a/addons/project/__openerp__.py b/addons/project/__openerp__.py
index 936c7d361fc..9132636b56f 100644
--- a/addons/project/__openerp__.py
+++ b/addons/project/__openerp__.py
@@ -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.
======================================================================================
diff --git a/addons/project/project.py b/addons/project/project.py
index 4b4e3079e38..1fc83771005 100644
--- a/addons/project/project.py
+++ b/addons/project/project.py
@@ -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):
diff --git a/addons/project/project_demo.xml b/addons/project/project_demo.xml
index f2ff9413063..ac4bc14c701 100644
--- a/addons/project/project_demo.xml
+++ b/addons/project/project_demo.xml
@@ -272,6 +272,7 @@
Study + Prototype
+
20
@@ -279,12 +280,14 @@
Specific Developments
+
30
Install, data import, configuration
+
@@ -292,7 +295,7 @@
38.0
38.0
-
+
BoM, After sales returns, interventions. Traceability.
Specific adaptation to MRP
@@ -302,8 +305,8 @@
16.0
16.0
+
-
Data importation + Doc
@@ -312,8 +315,8 @@
16.0
16.0
+
-
Modifications asked by the customer.
@@ -323,18 +326,17 @@
16.0
16.0
-
+
0
Customer analysis + Architecture
- 12-17-2011
15
8.0
8.0
-
+
Internal testing + Software Install
@@ -343,7 +345,7 @@
16.0
16.0
-
+
2
Analysis, Data Importation
@@ -354,7 +356,7 @@
20
16.0
16.0
-
+
Parameters
@@ -365,12 +367,16 @@
20
32.0
32.0
-
+
open
Start of the doc redaction + MRP
+
+
+
+
diff --git a/addons/project_long_term/project_long_term.py b/addons/project_long_term/project_long_term.py
index 8588b90f5a2..f7e23c29a58 100644
--- a/addons/project_long_term/project_long_term.py
+++ b/addons/project_long_term/project_long_term.py
@@ -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()