commit
b9c552892b
|
@ -705,17 +705,12 @@ def GetSearchText(txtProcessor,*args):
|
|||
b = check()
|
||||
if not b:
|
||||
return
|
||||
# Get the selected mail and set the default value for search_text_control to mail.SenderEmailAddress
|
||||
ex = txtProcessor.window.manager.outlook.ActiveExplorer()
|
||||
assert ex.Selection.Count == 1
|
||||
mail = ex.Selection.Item(1)
|
||||
try:
|
||||
global objects_with_match
|
||||
list_hwnd = win32gui.GetDlgItem(txtProcessor.window.hwnd, txtProcessor.other_ids[1])
|
||||
objects_with_match = NewConn.SearchPartners()
|
||||
setList(list_hwnd)
|
||||
except Exception,e:
|
||||
msg=getMessage(e)
|
||||
win32ui.MessageBox('Document can not be loaded.\n'+str(e), "Push", flag_error)
|
||||
txtProcessor.init_done=True
|
||||
|
||||
|
|
|
@ -104,19 +104,19 @@ class XMLRpcConn(object):
|
|||
return db_list
|
||||
|
||||
def login(self,dbname, user, pwd):
|
||||
self._dbname = dbname
|
||||
self._uname = user
|
||||
self._pwd = pwd
|
||||
conn = xmlrpclib.ServerProxy(str(self._uri) + '/xmlrpc/common')
|
||||
uid = execute(conn,'login',dbname, ustr(user), ustr(pwd))
|
||||
return uid
|
||||
self._dbname = dbname
|
||||
self._uname = user
|
||||
self._pwd = pwd
|
||||
conn = xmlrpclib.ServerProxy(str(self._uri) + '/xmlrpc/common')
|
||||
uid = execute(conn,'login',dbname, ustr(user), ustr(pwd))
|
||||
return uid
|
||||
|
||||
def GetAllObjects(self):
|
||||
conn = xmlrpclib.ServerProxy(self._uri+ '/xmlrpc/object')
|
||||
ids = execute(conn,'execute',self._dbname,int(self._uid),self._pwd,'ir.model','search',[])
|
||||
objects = execute(conn,'execute',self._dbname,int(self._uid),self._pwd,'ir.model','read',ids,['model'])
|
||||
obj_list = [item['model'] for item in objects]
|
||||
return obj_list
|
||||
conn = xmlrpclib.ServerProxy(self._uri+ '/xmlrpc/object')
|
||||
ids = execute(conn,'execute',self._dbname,int(self._uid),self._pwd,'ir.model','search',[])
|
||||
objects = execute(conn,'execute',self._dbname,int(self._uid),self._pwd,'ir.model','read',ids,['model'])
|
||||
obj_list = [item['model'] for item in objects]
|
||||
return obj_list
|
||||
|
||||
def GetObjList(self):
|
||||
self._obj_list=list(self._obj_list)
|
||||
|
|
|
@ -23,8 +23,11 @@ from datetime import datetime, timedelta
|
|||
from dateutil.relativedelta import relativedelta
|
||||
from tools.translate import _
|
||||
from osv import fields, osv
|
||||
from resource.faces import task as Task
|
||||
from resource.faces import task as Task
|
||||
import operator
|
||||
from new import classobj
|
||||
import types
|
||||
import new
|
||||
|
||||
class project_phase(osv.osv):
|
||||
_name = "project.phase"
|
||||
|
@ -216,23 +219,59 @@ class project_phase(osv.osv):
|
|||
"""
|
||||
Return a list of Resource Class objects for the resources allocated to the phase.
|
||||
"""
|
||||
|
||||
res = {}
|
||||
resource_pool = self.pool.get('resource.resource')
|
||||
for phase in self.browse(cr, uid, ids, context=context):
|
||||
user_ids = map(lambda x:x.resource_id.user_id.id, phase.resource_ids)
|
||||
|
||||
project = phase.project_id
|
||||
calendar_id = project.resource_calendar_id and project.resource_calendar_id.id or False
|
||||
resource_objs = resource_pool.generate_resources(cr, uid, user_ids, calendar_id, context=context)
|
||||
resource_objs = map(lambda x:x.resource_id.name, phase.resource_ids)
|
||||
res[phase.id] = resource_objs
|
||||
return res
|
||||
|
||||
def generate_schedule(self, cr, uid, ids, start_date=False, calendar_id=False, context=None):
|
||||
def generate_phase(self, cr, uid, ids, f, parent=False, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
phase_ids = []
|
||||
resource_pool = self.pool.get('resource.resource')
|
||||
data_pool = self.pool.get('ir.model.data')
|
||||
resource_allocation_pool = self.pool.get('project.resource.allocation')
|
||||
uom_pool = self.pool.get('product.uom')
|
||||
data_model, day_uom_id = data_pool.get_object_reference(cr, uid, 'product', 'uom_day')
|
||||
for phase in self.browse(cr, uid, ids, context=context)[::-1]:
|
||||
avg_days = uom_pool._compute_qty(cr, uid, phase.product_uom.id, phase.duration, day_uom_id)
|
||||
duration = str(avg_days) + 'd'
|
||||
# Create a new project for each phase
|
||||
str_resource = ('%s,'*len(phase.resource_ids))[:-1]
|
||||
str_vals = str_resource % tuple(map(lambda x: 'Resource_%s'%x.resource_id.id, phase.resource_ids))
|
||||
# Phases Defination for the Project
|
||||
s = '''
|
||||
def Phase_%s():
|
||||
effort = \'%s\'
|
||||
resource = %s
|
||||
'''%(phase.id, duration, str_vals or False)
|
||||
if parent:
|
||||
start = 'up.Phase_%s.end' % (parent.id)
|
||||
s += '''
|
||||
start = %s
|
||||
'''%(start)
|
||||
f += s + '\n'
|
||||
phase_ids.append(phase.id)
|
||||
# Recursive call till all the next phases scheduled
|
||||
for next_phase in phase.next_phase_ids:
|
||||
if next_phase.state in ['draft', 'open', 'pending']:
|
||||
rf, rphase_ids = self.generate_phase(cr, uid, [next_phase.id], f = '', parent=phase, context=context)
|
||||
f += rf +'\n'
|
||||
phase_ids += rphase_ids
|
||||
else:
|
||||
continue
|
||||
return f, phase_ids
|
||||
|
||||
def generate_schedule(self, cr, uid, root_phase, start_date=False, calendar_id=False, context=None):
|
||||
"""
|
||||
Schedule phase with the start date till all the next phases are completed.
|
||||
@param: start_date (datetime.datetime) : start date for the phase. It would be either Start date of phase or start date of project or system current date
|
||||
@param: calendar_id : working calendar of the project
|
||||
"""
|
||||
func_str = ''
|
||||
if context is None:
|
||||
context = {}
|
||||
resource_pool = self.pool.get('resource.resource')
|
||||
|
@ -240,73 +279,100 @@ class project_phase(osv.osv):
|
|||
resource_allocation_pool = self.pool.get('project.resource.allocation')
|
||||
uom_pool = self.pool.get('product.uom')
|
||||
data_model, day_uom_id = data_pool.get_object_reference(cr, uid, 'product', 'uom_day')
|
||||
for phase in self.browse(cr, uid, ids, context=context):
|
||||
if not phase.previous_phase_ids:
|
||||
start_date = False
|
||||
if not phase.responsible_id:
|
||||
raise osv.except_osv(_('No responsible person assigned !'),_("You must assign a responsible person for phase '%s' !") % (phase.name,))
|
||||
if not start_date:
|
||||
start_date = phase.project_id.date_start or phase.date_start or datetime.now().strftime("%Y-%m-%d")
|
||||
start_date = datetime.strftime((datetime.strptime(start_date, "%Y-%m-%d")), "%Y-%m-%d")
|
||||
phase_resource_obj = self.generate_resources(cr, uid, [phase.id], context=context)[phase.id]
|
||||
avg_days = uom_pool._compute_qty(cr, uid, phase.product_uom.id, phase.duration, day_uom_id)
|
||||
if not phase_resource_obj: #TOCHECK: why need this ?
|
||||
avg_days = avg_days - 1
|
||||
duration = str(avg_days) + 'd'
|
||||
# Create a new project for each phase
|
||||
def Project():
|
||||
# If project has working calendar then that
|
||||
# else the default one would be considered
|
||||
start = start_date
|
||||
minimum_time_unit = 1
|
||||
resource = phase_resource_obj
|
||||
working_hours_per_day = 24
|
||||
vacation = []
|
||||
if calendar_id:
|
||||
working_hours_per_day = 8 #TODO: it should be come from calendars
|
||||
vacation = tuple(resource_pool.compute_vacation(cr, uid, calendar_id))
|
||||
working_days = resource_pool.compute_working_calendar(cr, uid, calendar_id, context=context)
|
||||
def phase():
|
||||
effort = duration
|
||||
|
||||
|
||||
project = Task.BalancedProject(Project)
|
||||
if not start_date:
|
||||
start_date = root_phase.project_id.date_start or root_phase.date_start or datetime.now().strftime("%Y-%m-%d")
|
||||
start_date = datetime.strftime((datetime.strptime(start_date, "%Y-%m-%d")), "%Y-%m-%d")
|
||||
|
||||
s_date = project.phase.start.to_datetime()
|
||||
e_date = project.phase.end.to_datetime()
|
||||
start = start_date
|
||||
minimum_time_unit = 1
|
||||
working_hours_per_day = 24
|
||||
working_days_per_week = 7
|
||||
working_days_per_month = 30
|
||||
working_days_per_year = 365
|
||||
|
||||
vacation = []
|
||||
if calendar_id:
|
||||
working_hours_per_day = 8 #TODO: it should be come from calendars
|
||||
working_days_per_week = 5
|
||||
working_days_per_month = 20
|
||||
working_days_per_year = 200
|
||||
vacation = tuple(resource_pool.compute_vacation(cr, uid, calendar_id))
|
||||
working_days = resource_pool.compute_working_calendar(cr, uid, calendar_id, context=context)
|
||||
|
||||
#Creating resources using the member of the Project
|
||||
u_ids = [i.id for i in root_phase.project_id.members]
|
||||
resource_objs = resource_pool.generate_resources(cr, uid, u_ids, calendar_id, context=context)
|
||||
cls_str = ''
|
||||
# Creating Resources for the Project
|
||||
for key, vals in resource_objs.items():
|
||||
cls_str +='''
|
||||
class Resource_%s(Resource):
|
||||
vacation = %s
|
||||
efficiency = %s
|
||||
'''%(key, vals.get('vacation', False), vals.get('efficiency', False))
|
||||
|
||||
# Create a new project for each phase
|
||||
func_str += '''
|
||||
|
||||
def Project_%d():
|
||||
# If project has working calendar then that
|
||||
# else the default one would be considered
|
||||
start = \'%s\'
|
||||
minimum_time_unit = %s
|
||||
working_hours_per_day = %s
|
||||
working_days_per_week = %s
|
||||
working_days_per_month = %s
|
||||
working_days_per_year = %s
|
||||
vacation = %s
|
||||
working_days = %s
|
||||
from resource.faces import Resource
|
||||
'''%(root_phase.project_id.id, start, minimum_time_unit, working_hours_per_day, working_days_per_week, working_days_per_month, working_days_per_year, vacation, working_days )
|
||||
func_str += cls_str
|
||||
phases, phase_ids = self.generate_phase(cr, uid, [root_phase.id], func_str, context=context)
|
||||
#Temp File to test the Code for the Allocation
|
||||
# fn = '/home/tiny/Desktop/plt.py'
|
||||
# fp = open(fn, 'w')
|
||||
# fp.writelines(phases)
|
||||
# fp.close()
|
||||
# Allocating Memory for the required Project and Pahses and Resources
|
||||
exec(phases)
|
||||
Project = eval('Project_%d' % root_phase.project_id.id)
|
||||
project = Task.BalancedProject(Project)
|
||||
|
||||
for phase_id in phase_ids:
|
||||
phase = eval("project.Phase_%d" % phase_id)
|
||||
start_date = phase.start.to_datetime()
|
||||
end_date = phase.end.to_datetime()
|
||||
# print phase_id,"\n\n****Phases *********", phase.resource
|
||||
# Recalculate date_start and date_end
|
||||
# according to constraints on date start and date end on phase
|
||||
if phase.constraint_date_start and str(s_date) < phase.constraint_date_start:
|
||||
start_date = datetime.strptime(phase.constraint_date_start, '%Y-%m-%d')
|
||||
else:
|
||||
start_date = s_date
|
||||
|
||||
if phase.constraint_date_end and str(e_date) > phase.constraint_date_end:
|
||||
end_date= datetime.strptime(phase.constraint_date_end, '%Y-%m-%d')
|
||||
date_start = phase.constraint_date_end
|
||||
else:
|
||||
end_date = e_date
|
||||
date_start = end_date
|
||||
# Write the calculated dates back
|
||||
ctx = context.copy()
|
||||
ctx.update({'scheduler': True})
|
||||
self.write(cr, uid, [phase.id], {
|
||||
|
||||
# if phase.constraint_date_start and str(s_date) < phase.constraint_date_start:
|
||||
# start_date = datetime.strptime(phase.constraint_date_start, '%Y-%m-%d')
|
||||
# else:
|
||||
# start_date = s_date
|
||||
# if phase.constraint_date_end and str(e_date) > phase.constraint_date_end:
|
||||
# end_date= datetime.strptime(phase.constraint_date_end, '%Y-%m-%d')
|
||||
# date_start = phase.constraint_date_end
|
||||
# else:
|
||||
# end_date = e_date
|
||||
# date_start = end_date
|
||||
# # Write the calculated dates back
|
||||
# ctx = context.copy()
|
||||
# ctx.update({'scheduler': True})
|
||||
self.write(cr, uid, [phase_id], {
|
||||
'date_start': start_date.strftime('%Y-%m-%d'),
|
||||
'date_end': end_date.strftime('%Y-%m-%d')
|
||||
}, context=ctx)
|
||||
}, context=context)
|
||||
# write dates into Resources Allocation
|
||||
for resource in phase.resource_ids:
|
||||
resource_allocation_pool.write(cr, uid, [resource.id], {
|
||||
'date_start': start_date.strftime('%Y-%m-%d'),
|
||||
'date_end': end_date.strftime('%Y-%m-%d')
|
||||
}, context=ctx)
|
||||
# Recursive call till all the next phases scheduled
|
||||
for next_phase in phase.next_phase_ids:
|
||||
if next_phase.state in ['draft', 'open', 'pending']:
|
||||
id_cal = next_phase.project_id.resource_calendar_id and next_phase.project_id.resource_calendar_id.id or False
|
||||
self.generate_schedule(cr, uid, [next_phase.id], date_start+timedelta(days=1), id_cal, context=context)
|
||||
else:
|
||||
continue
|
||||
return True
|
||||
# for resource in phase.resource_ids:
|
||||
# resource_allocation_pool.write(cr, uid, [resource.id], {
|
||||
# 'date_start': start_date.strftime('%Y-%m-%d'),
|
||||
# 'date_end': end_date.strftime('%Y-%m-%d')
|
||||
# }, context=context)
|
||||
# # Recursive call till all the next phases scheduled
|
||||
|
||||
def schedule_tasks(self, cr, uid, ids, context=None):
|
||||
"""
|
||||
|
@ -398,7 +464,8 @@ class project(osv.osv):
|
|||
])
|
||||
calendar_id = project.resource_calendar_id and project.resource_calendar_id.id or False
|
||||
start_date = False
|
||||
phase_pool.generate_schedule(cr, uid, phase_ids, start_date, calendar_id, context=context)
|
||||
for phase in phase_pool.browse(cr, uid, phase_ids, context=context):
|
||||
phase_pool.generate_schedule(cr, uid, phase, start_date, calendar_id, context=context)
|
||||
return True
|
||||
|
||||
def schedule_tasks(self, cr, uid, ids, context=None):
|
||||
|
@ -492,9 +559,15 @@ class project_task(osv.osv):
|
|||
raise osv.except_osv(_('Error'), _('Resources should be allocated to your phases and Members should be assigned to your Project!'))
|
||||
minimum_time_unit = 1
|
||||
working_hours_per_day = 24
|
||||
working_days_per_week = 7
|
||||
working_days_per_month = 30
|
||||
working_days_per_year = 365
|
||||
vacation = []
|
||||
if calendar_id:
|
||||
working_hours_per_day = 8 #TODO: it should be come from calendars
|
||||
working_days_per_week = 5
|
||||
working_days_per_month = 20
|
||||
working_days_per_year = 200
|
||||
vacation = tuple(resource_pool.compute_vacation(cr, uid, calendar_id, context=context))
|
||||
working_days = resource_pool.compute_working_calendar(cr, uid, calendar_id, context=context)
|
||||
# Dynamic creation of tasks
|
||||
|
|
|
@ -4,7 +4,14 @@
|
|||
!record {model: project.project, id: project_project_worldbanksproject0}:
|
||||
name: "World Bank's Project"
|
||||
priority: 4
|
||||
|
||||
members:
|
||||
- project.res_users_analyst
|
||||
- project.res_users_project_manager
|
||||
- project.res_users_technical_leader
|
||||
- project.res_users_developer
|
||||
- project.res_users_designer
|
||||
- project.res_users_tester
|
||||
|
||||
-
|
||||
Create a project phase 'Defining Client's Basic Idea of Project'
|
||||
-
|
||||
|
@ -14,8 +21,7 @@
|
|||
name: "Defining Client's Basic Idea of Project"
|
||||
product_uom: product.uom_day
|
||||
project_id: project_project_worldbanksproject0
|
||||
|
||||
|
||||
|
||||
-
|
||||
Create project phase 'Establishing Project Feasibility'
|
||||
-
|
||||
|
@ -25,7 +31,21 @@
|
|||
name: Establishing Project Feasibility
|
||||
product_uom: product.uom_day
|
||||
project_id: project_project_worldbanksproject0
|
||||
|
||||
-
|
||||
Resource1
|
||||
-
|
||||
!record {model: project.resource.allocation, id: res_phase0}:
|
||||
resource_id: project_long_term.resource_project_manager
|
||||
phase_id: project_phase_definingclientsbasicideaofproject0
|
||||
|
||||
-
|
||||
Resource2
|
||||
-
|
||||
!record {model: project.resource.allocation, id: res_phase2}:
|
||||
resource_id: project_long_term.resource_analyst
|
||||
phase_id: project_phase_definingclientsbasicideaofproject0
|
||||
|
||||
-
|
||||
Create project phase 'Preparation of Engineering Designs'
|
||||
-
|
||||
|
|
|
@ -250,7 +250,7 @@ class resource_resource(osv.osv):
|
|||
"""
|
||||
Return a list of Resource Class objects for the resources allocated to the phase.
|
||||
"""
|
||||
resource_objs = []
|
||||
resource_objs = {}
|
||||
user_pool = self.pool.get('res.users')
|
||||
for user in user_pool.browse(cr, uid, user_ids, context=context):
|
||||
resource_ids = self.search(cr, uid, [('user_id', '=', user.id)], context=context)
|
||||
|
@ -264,12 +264,17 @@ class resource_resource(osv.osv):
|
|||
resource_cal = resource.calendar_id.id
|
||||
if resource_cal:
|
||||
leaves = self.compute_vacation(cr, uid, calendar_id, resource.id, resource_cal, context=context)
|
||||
resource_objs.append(classobj(str(user.name), (Resource,),{
|
||||
'__doc__': user.name,
|
||||
'__name__': user.name,
|
||||
'vacation': tuple(leaves),
|
||||
'efficiency': resource_eff,
|
||||
}))
|
||||
temp = {
|
||||
'vacation': tuple(leaves),
|
||||
'efficiency': resource_eff,
|
||||
}
|
||||
resource_objs[resource_id] = temp
|
||||
# resource_objs.append(classobj(str(user.name), (Resource,),{
|
||||
# '__doc__': user.name,
|
||||
# '__name__': user.name,
|
||||
# 'vacation': tuple(leaves),
|
||||
# 'efficiency': resource_eff,
|
||||
# }))
|
||||
return resource_objs
|
||||
|
||||
def compute_vacation(self, cr, uid, calendar_id, resource_id=False, resource_calendar=False, context=None):
|
||||
|
|
Loading…
Reference in New Issue