diff options
| author | jam-openerp <jam@tinyerp.com> | 2011-01-04 19:23:15 +0530 |
|---|---|---|
| committer | jam-openerp <jam@tinyerp.com> | 2011-01-04 19:23:15 +0530 |
| commit | b9c552892b69b116ddfc36d05ddc5b0706f61b85 (patch) | |
| tree | 2c79febda3291e442f2e1ef5dbb802b3c86ebcf2 /addons/project_long_term/project_long_term.py | |
| parent | b1fa3dee7d5a7f3c439375f934d6f7762e9ffd02 (diff) | |
| parent | 926e3de1e2ba53834bb7a006ef48b5161d9c1918 (diff) | |
MERGE
bzr revid: jam@tinyerp.com-20110104135315-1ptskxpahgtkwhru
Diffstat (limited to 'addons/project_long_term/project_long_term.py')
| -rw-r--r-- | addons/project_long_term/project_long_term.py | 213 |
1 files changed, 143 insertions, 70 deletions
diff --git a/addons/project_long_term/project_long_term.py b/addons/project_long_term/project_long_term.py index da4b256f82f..7a23586ffbc 100644 --- a/addons/project_long_term/project_long_term.py +++ b/addons/project_long_term/project_long_term.py @@ -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) - - s_date = project.phase.start.to_datetime() - e_date = project.phase.end.to_datetime() + + + 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") + + 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 |
