diff options
| author | mra (Open ERP) <mra@tinyerp.com> | 2010-04-06 15:48:27 +0530 |
|---|---|---|
| committer | mra (Open ERP) <mra@tinyerp.com> | 2010-04-06 15:48:27 +0530 |
| commit | 3ef0fea250076f6f4763886ea10dbba40f187829 (patch) | |
| tree | 9c57478c9a024dcf5430a293cc18e329fb568f33 /addons/project_long_term/wizard/project_compute_phases.py | |
| parent | 5ee2d53302ea6e67b372382904ee950cd98c76d7 (diff) | |
[ADD] Project_long_term: compute phase date wizard => osv memory convert
bzr revid: mra@tinyerp.com-20100406101827-6yhk7535fvxbhi2w
Diffstat (limited to 'addons/project_long_term/wizard/project_compute_phases.py')
| -rw-r--r-- | addons/project_long_term/wizard/project_compute_phases.py | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/addons/project_long_term/wizard/project_compute_phases.py b/addons/project_long_term/wizard/project_compute_phases.py new file mode 100644 index 00000000000..a9b800d20ce --- /dev/null +++ b/addons/project_long_term/wizard/project_compute_phases.py @@ -0,0 +1,162 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2009 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 datetime +from resource.faces import * +from new import classobj + +from tools.translate import _ +from osv import fields, osv + +import working_calendar as wkcal + +class project_compute_phases(osv.osv_memory): + + _name = 'project.compute.phases' + _description = 'Project Compute Phases' + _columns = { + 'project_id': fields.many2one('project.project', 'Project', help='If you do not specify project then it will take All projects with state=draft, open, pending') + } + + def _phase_schedule(self, cr, uid, phase, start_date, calendar_id=False, context={}): + + """Schedule phase with the start date till all the next phases are completed. + + Arguements: start_dsate -- start date for the phase + calendar_id -- working calendar of the project + + """ + phase_obj = self.pool.get('project.phase') + resource_obj = self.pool.get('resource.resource') + uom_obj = self.pool.get('product.uom') + phase_resource_obj = False + if phase: + leaves = [] + time_efficiency = 1.0 + resource_id = resource_obj.search(cr, uid, [('user_id', '=', phase.responsible_id.id)]) + + if resource_id: + # Create a new resource object with + # all the attributes of the Resource Class + resource = resource_obj.browse(cr, uid, resource_id, context=context)[0] + time_efficiency = resource.time_efficiency + leaves = wkcal.compute_leaves(cr, uid, calendar_id , resource.id, resource.calendar_id.id) + phase_resource_obj = classobj((phase.responsible_id.name.encode('utf8')), (Resource,), + {'__doc__': phase.responsible_id.name, + '__name__': phase.responsible_id.name, + 'vacation': tuple(leaves), + 'efficiency': time_efficiency + }) + default_uom_id = uom_obj.search(cr, uid, [('name','=','Hour')])[0] + avg_hours = uom_obj._compute_qty(cr, uid, phase.product_uom.id, phase.duration, default_uom_id) + duration = str(avg_hours) + 'H' + # Create a new project for each phase + def Project(): + start = start_date + minimum_time_unit = 1 + resource = phase_resource_obj + # If project has working calendar then that + # else the default one would be considered + if calendar_id: + working_days = wkcal.compute_working_calendar(cr, uid, calendar_id, context=context) + vacation = tuple(wkcal.compute_leaves(cr, uid, calendar_id)) + + def phase(): + effort = duration + + project = BalancedProject(Project) + s_date = project.phase.start.to_datetime() + e_date = project.phase.end.to_datetime() + # 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.datetime.strptime(phase.constraint_date_start, '%Y-%m-%d %H:%M:%S') + else: + start_date = s_date + if phase.constraint_date_end and str(e_date) > phase.constraint_date_end: + end_date= datetime.datetime.strptime(phase.constraint_date_end, '%Y-%m-%d %H:%M:%S') + date_start = phase.constraint_date_end[:-3] + else: + end_date = e_date + date_start = end_date + # Write the calculated dates back + ctx = context.copy() + ctx.update({'scheduler': True}) + phase_obj.write(cr, uid, [phase.id], {'date_start': start_date.strftime('%Y-%m-%d %H:%M:%S'), + 'date_end': end_date.strftime('%Y-%m-%d %H:%M:%S')}, + context=ctx) + # Recursive call till all the next phases scheduled + for phase in phase.next_phase_ids: + if phase.state in ['draft','open','pending']: + id_cal = phase.project_id.resource_calendar_id and phase.project_id.resource_calendar_id.id or False + self._phase_schedule(cr, uid, phase, date_start, id_cal, context=context) + else: + continue + + def compute_date(self, cr, uid, ids, context=None): + """ + Compute the phases for scheduling. + """ + + if context is None: + context = {} + project_obj = self.pool.get('project.project') + phase_obj = self.pool.get('project.phase') + data = self.read(cr, uid, ids, [], context=context)[0] + if data['project_id']: # If project mentioned find its phases + project_id = project_obj.browse(cr, uid, data['project_id'], context=context) + phase_ids = phase_obj.search(cr, uid, [('project_id', '=', project_id.id), + ('state', 'in', ['draft', 'open', 'pending']), + ('previous_phase_ids', '=', False) + ]) + else: # Else take all the draft,open,pending states phases + phase_ids = phase_obj.search(cr, uid,[('state', 'in', ['draft', 'open', 'pending']), + ('previous_phase_ids', '=', False) + ], context=context) + phase_ids.sort() + phases = phase_obj.browse(cr, uid, phase_ids, context=context) + for phase in phases: + start_date = phase.project_id.date_start + if not phase.project_id.date_start: + start_date = datetime.datetime.now().strftime("%Y-%m-%d") + start_dt = datetime.datetime.strftime((datetime.datetime.strptime(start_date, "%Y-%m-%d")), "%Y-%m-%d %H:%M") + calendar_id = phase.project_id.resource_calendar_id and phase.project_id.resource_calendar_id.id or False + self._phase_schedule(cr, uid, phase, start_dt, calendar_id, context=context) + return self._open_phases_list(cr, uid, data, context=context) + + def _open_phases_list(self, cr, uid, data, context=None): + """ + Return the scheduled phases list. + """ + if context is None: + context = {} + mod_obj = self.pool.get('ir.model.data') + act_obj = self.pool.get('ir.actions.act_window') + result = mod_obj._get_id(cr, uid, 'project_long_term', 'act_project_phase') + id = mod_obj.read(cr, uid, [result], ['res_id'])[0]['res_id'] + result = act_obj.read(cr, uid, [id], context=context)[0] + result['domain'] = [('state', 'not in', ['cancelled','done'])] + if data['project_id']: + result['domain'] = [('project_id', '=', data['project_id']), + ('state', 'not in', ['cancelled','done'])] + return result + +project_compute_phases() +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |
