From 8baf16f25e2f0c158f75527105ba1a712677e0f8 Mon Sep 17 00:00:00 2001 From: Fabien Pinckaers Date: Sat, 12 Jun 2010 18:21:54 +0200 Subject: [IMP] access rights. Remove bad stuff on point of sale bzr revid: fp@tinyerp.com-20100612162154-f9dgju8wsmn79gq0 --- addons/project_long_term/project_long_term.py | 108 -------------------------- 1 file changed, 108 deletions(-) (limited to 'addons/project_long_term/project_long_term.py') diff --git a/addons/project_long_term/project_long_term.py b/addons/project_long_term/project_long_term.py index 212af8a30dc..57fbd1abb5f 100644 --- a/addons/project_long_term/project_long_term.py +++ b/addons/project_long_term/project_long_term.py @@ -256,115 +256,7 @@ class task(osv.osv): _inherit = "project.task" _columns = { 'phase_id': fields.many2one('project.phase', 'Project Phase'), - 'occupation_rate': fields.float('Occupation Rate', help='The occupation rate fields indicates how much of his time a user is working on a task. A 100% occupation rate means the user works full time on the tasks. The ending date of a task is computed like this: Starting Date + Duration / Occupation Rate.'), - 'planned_hours': fields.float('Planned Hours', required=True, help='Estimated time to do the task, usually set by the project manager when the task is in draft state.'), } - _defaults = { - 'occupation_rate': '1' - } - - def onchange_planned(self, cr, uid, ids, project, user_id=False, planned=0.0, effective=0.0, date_start=None, occupation_rate=0.0): - result = {} - resource = False - resource_obj = self.pool.get('resource.resource') - project_pool = self.pool.get('project.project') - resource_calendar = self.pool.get('resource.calendar') - if not project: - return {'value' : result} - if date_start: - hrs = float(planned / float(occupation_rate)) - calendar_id = project_pool.browse(cr, uid, project).resource_calendar_id.id - dt_start = mx.DateTime.strptime(date_start, '%Y-%m-%d %H:%M:%S') - resource_id = resource_obj.search(cr, uid, [('user_id','=',user_id)]) - if resource_id: - resource_data = resource_obj.browse(cr, uid, resource_id)[0] - resource = resource_data.id - hrs = planned / (float(occupation_rate) * resource_data.time_efficiency) - if resource_data.calendar_id.id: - calendar_id = resource_data.calendar_id.id - work_times = resource_calendar.interval_get(cr, uid, calendar_id, dt_start, hrs or 0.0, resource or False) - if work_times: - result['date_end'] = work_times[-1][1].strftime('%Y-%m-%d %H:%M:%S') - result['remaining_hours'] = planned - effective - return {'value' : result} - - def _check_date_start(self, cr, uid, task, date_end, context={}): - """ - Check And Compute date_end of task if change in date_start < older time. - """ - resource_calendar_obj = self.pool.get('resource.calendar') - resource_obj = self.pool.get('resource.resource') - calendar_id = task.project_id.resource_calendar_id and task.project_id.resource_calendar_id.id or False - hours = task.planned_hours / task.occupation_rate - resource_id = resource_obj.search(cr, uid, [('user_id', '=', task.user_id.id)], context=context) - if resource_id: - resource = resource_obj.browse(cr, uid, resource_id[0], context=context) - if resource.calendar_id.id: - calendar_id = resource.calendar_id and resource.calendar_id.id or False - hours = task.planned_hours / (float(task.occupation_rate) * resource.time_efficiency) - work_times = resource_calendar_obj.interval_min_get(cr, uid, calendar_id, date_end, hours or 0.0, resource_id and resource_id[0] or False) - dt_start = work_times[0][0].strftime('%Y-%m-%d %H:%M:%S') - self.write(cr, uid, [task.id], {'date_start' : dt_start,'date_end' : date_end.strftime('%Y-%m-%d %H:%M:%S')}) - - def _check_date_end(self, cr, uid, task, date_start, context={}): - """ - Check And Compute date_end of task if change in date_end > older time. - """ - resource_calendar_obj = self.pool.get('resource.calendar') - resource_obj = self.pool.get('resource.resource') - calendar_id = task.project_id.resource_calendar_id and task.project_id.resource_calendar_id.id or False - hours = task.planned_hours / task.occupation_rate - resource_id = resource_obj.search(cr,uid,[('user_id', '=', task.user_id.id)], context=context) - if resource_id: - resource = resource_obj.browse(cr, uid, resource_id[0], context=context) - if resource.calendar_id.id: - calendar_id = resource.calendar_id and resource.calendar_id.id or False - hours = task.planned_hours / (float(task.occupation_rate) * resource.time_efficiency) - work_times = resource_calendar_obj.interval_get(cr, uid, calendar_id, date_start, hours or 0.0, resource_id and resource_id[0] or False) - dt_end = work_times[-1][1].strftime('%Y-%m-%d %H:%M:%S') - self.write(cr, uid, [task.id], {'date_start': date_start.strftime('%Y-%m-%d %H:%M:%S'),'date_end' : dt_end}, context=context) - - def write(self, cr, uid, ids, vals, context={}): - resource_calendar_obj = self.pool.get('resource.calendar') - resource_obj = self.pool.get('resource.resource') - if not context: - context = {} - if context.get('scheduler',False): - return super(task, self).write(cr, uid, ids, vals, context=context) - - # Consider calendar and efficiency if the task is performed by a resource - # otherwise consider the project's working calendar - task_id = ids - if isinstance(ids, list): - task_id = ids[0] - task_rec = self.browse(cr, uid, task_id, context=context) - calendar_id = task_rec.project_id.resource_calendar_id and task_rec.project_id.resource_calendar_id.id or False - hrs = task_rec.planned_hours / task_rec.occupation_rate - resource_id = resource_obj.search(cr, uid, [('user_id', '=', task_rec.user_id.id)], context=context) - if resource_id: - resource = resource_obj.browse(cr, uid, resource_id[0], context=context) - if resource.calendar_id.id: - calendar_id = resource.calendar_id and resource.calendar_id.id or False - hrs = task_rec.planned_hours / (float(task_rec.occupation_rate) * resource.time_efficiency) - - # Change the date_start and date_end - # for previous and next tasks respectively based on valid condition - if vals.get('date_start', False) and vals['date_start'] < task_rec.date_start: - dt_start = mx.DateTime.strptime(vals['date_start'], '%Y-%m-%d %H:%M:%S') - work_times = resource_calendar_obj.interval_get(cr, uid, calendar_id, dt_start, hrs or 0.0, resource.id or False) - if work_times: - vals['date_end'] = work_times[-1][1].strftime('%Y-%m-%d %H:%M:%S') - for prv_task in task_rec.parent_ids: - self._check_date_start(cr, uid, prv_task, dt_start) - if vals.get('date_end', False) and vals['date_end'] > task_rec.date_end: - dt_end = mx.DateTime.strptime(vals['date_end'], '%Y-%m-%d %H:%M:%S') - work_times = resource_calendar_obj.interval_min_get(cr, uid, calendar_id, dt_end, hrs or 0.0, resource.id or False) - if work_times: - vals['date_start'] = work_times[0][0].strftime('%Y-%m-%d %H:%M:%S') - for next_task in task_rec.child_ids: - self._check_date_end(cr, uid, next_task, dt_end) - - return super(task, self).write(cr, uid, ids, vals, context=context) task() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: -- cgit v1.2.3 From bf8d2a73c06154918874220b8bfb1251dc614088 Mon Sep 17 00:00:00 2001 From: vra Date: Wed, 16 Jun 2010 17:21:39 +0530 Subject: [IMP][REF] Sql-injection changes, remove print statement, some space improvement. bzr revid: vra@tinyerp.com-20100616115139-cql5oiqf622spa6p --- addons/project_long_term/project_long_term.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'addons/project_long_term/project_long_term.py') diff --git a/addons/project_long_term/project_long_term.py b/addons/project_long_term/project_long_term.py index 57fbd1abb5f..f1c40a4c8ba 100644 --- a/addons/project_long_term/project_long_term.py +++ b/addons/project_long_term/project_long_term.py @@ -45,7 +45,7 @@ class project_phase(osv.osv): next_ids = [rec.id for rec in next_ids] # iter prev_ids while prev_ids: - cr.execute('select distinct prv_phase_id from project_phase_rel where next_phase_id in ('+','.join(map(str, prev_ids))+')') + cr.execute('select distinct prv_phase_id from project_phase_rel where next_phase_id IN %s',(tuple(prev_ids),)) prv_phase_ids = filter(None, map(lambda x: x[0], cr.fetchall())) if data_phase.id in prv_phase_ids: return False @@ -55,7 +55,7 @@ class project_phase(osv.osv): prev_ids = prv_phase_ids # iter next_ids while next_ids: - cr.execute('select distinct next_phase_id from project_phase_rel where prv_phase_id in ('+','.join(map(str, next_ids))+')') + cr.execute('select distinct next_phase_id from project_phase_rel where prv_phase_id IN %s',(tuple(next_ids),)) next_phase_ids = filter(None, map(lambda x: x[0], cr.fetchall())) if data_phase.id in next_phase_ids: return False -- cgit v1.2.3 From 5477d0de864d9919dc8578a8b3bea172a27a1618 Mon Sep 17 00:00:00 2001 From: Mustufa Rangwala Date: Fri, 2 Jul 2010 19:45:50 +0530 Subject: [IMP] clean project_* code (ARA) bzr revid: mra@mra-laptop-20100702141550-05xl1o45ophjl23t --- addons/project_long_term/project_long_term.py | 35 ++++++++++++++++----------- 1 file changed, 21 insertions(+), 14 deletions(-) (limited to 'addons/project_long_term/project_long_term.py') diff --git a/addons/project_long_term/project_long_term.py b/addons/project_long_term/project_long_term.py index f1c40a4c8ba..4520e798f4e 100644 --- a/addons/project_long_term/project_long_term.py +++ b/addons/project_long_term/project_long_term.py @@ -29,7 +29,10 @@ class project_phase(osv.osv): _name = "project.phase" _description = "Project Phase" - def _check_recursion(self, cr, uid, ids, context={}): + def _check_recursion(self, cr, uid, ids, context=None): + if context is None: + context = {} + data_phase = self.browse(cr, uid, ids[0], context=context) prev_ids = data_phase.previous_phase_ids next_ids = data_phase.next_phase_ids @@ -45,7 +48,7 @@ class project_phase(osv.osv): next_ids = [rec.id for rec in next_ids] # iter prev_ids while prev_ids: - cr.execute('select distinct prv_phase_id from project_phase_rel where next_phase_id IN %s',(tuple(prev_ids),)) + cr.execute('SELECT distinct prv_phase_id FROM project_phase_rel WHERE next_phase_id IN %s', (tuple(prev_ids),)) prv_phase_ids = filter(None, map(lambda x: x[0], cr.fetchall())) if data_phase.id in prv_phase_ids: return False @@ -55,7 +58,7 @@ class project_phase(osv.osv): prev_ids = prv_phase_ids # iter next_ids while next_ids: - cr.execute('select distinct next_phase_id from project_phase_rel where prv_phase_id IN %s',(tuple(next_ids),)) + cr.execute('SELECT distinct next_phase_id FROM project_phase_rel WHERE prv_phase_id IN %s', (tuple(next_ids),)) next_phase_ids = filter(None, map(lambda x: x[0], cr.fetchall())) if data_phase.id in next_phase_ids: return False @@ -65,19 +68,19 @@ class project_phase(osv.osv): next_ids = next_phase_ids return True - def _check_dates(self, cr, uid, ids, context={}): + def _check_dates(self, cr, uid, ids, context=None): for phase in self.read(cr, uid, ids, ['date_start', 'date_end'], context=context): if phase['date_start'] and phase['date_end'] and phase['date_start'] > phase['date_end']: return False return True - def _check_constraint_start(self, cr, uid, ids, context={}): + def _check_constraint_start(self, cr, uid, ids, context=None): phase = self.read(cr, uid, ids[0], ['date_start', 'constraint_date_start'], context=context) if phase['date_start'] and phase['constraint_date_start'] and phase['date_start'] < phase['constraint_date_start']: return False return True - def _check_constraint_end(self, cr, uid, ids, context={}): + def _check_constraint_end(self, cr, uid, ids, context=None): phase = self.read(cr, uid, ids[0], ['date_end', 'constraint_date_end'], context=context) if phase['date_end'] and phase['constraint_date_end'] and phase['date_end'] > phase['constraint_date_end']: return False @@ -97,7 +100,7 @@ class project_phase(osv.osv): 'product_uom': fields.many2one('product.uom', 'Duration UoM', required=True, help="UoM (Unit of Measure) is the unit of measurement for Duration"), 'task_ids': fields.one2many('project.task', 'phase_id', "Project Tasks"), 'resource_ids': fields.one2many('project.resource.allocation', 'phase_id', "Project Resources"), - 'responsible_id':fields.many2one('res.users', 'Responsible'), + 'responsible_id': fields.many2one('res.users', 'Responsible'), 'state': fields.selection([('draft', 'Draft'), ('open', 'In Progress'), ('pending', 'Pending'), ('cancelled', 'Cancelled'), ('done', 'Done')], 'State', readonly=True, required=True, help='If the phase is created the state \'Draft\'.\n If the phase is started, the state becomes \'In Progress\'.\n If review is needed the phase is in \'Pending\' state.\ \n If the phase is over, the states is set to \'Done\'.') @@ -116,7 +119,7 @@ class project_phase(osv.osv): #(_check_constraint_end, 'Phase must end-before constraint end Date.', ['date_end', 'constraint_date_end']), ] - def onchange_project(self, cr, uid, ids, project, context={}): + def onchange_project(self, cr, uid, ids, project, context=None): result = {} project_obj = self.pool.get('project.project') if project: @@ -126,7 +129,9 @@ class project_phase(osv.osv): return {'value': result} return {'value': {'date_start': []}} - def _check_date_start(self, cr, uid, phase, date_end, context={}): + def _check_date_start(self, cr, uid, phase, date_end, context=None): + if context is None: + context = {} """ Check And Compute date_end of phase if change in date_start < older time. """ @@ -147,7 +152,9 @@ class project_phase(osv.osv): dt_start = work_times[0][0].strftime('%Y-%m-%d %H:%M:%S') self.write(cr, uid, [phase.id], {'date_start': dt_start, 'date_end': date_end.strftime('%Y-%m-%d %H:%M:%S')}, context=context) - def _check_date_end(self, cr, uid, phase, date_start, context={}): + def _check_date_end(self, cr, uid, phase, date_start, context=None): + if context is None: + context = {} """ Check And Compute date_end of phase if change in date_end > older time. """ @@ -168,11 +175,11 @@ class project_phase(osv.osv): dt_end = work_times[-1][1].strftime('%Y-%m-%d %H:%M:%S') self.write(cr, uid, [phase.id], {'date_start': date_start.strftime('%Y-%m-%d %H:%M:%S'), 'date_end': dt_end}, context=context) - def write(self, cr, uid, ids, vals, context={}): + def write(self, cr, uid, ids, vals, context=None): resource_calendar_obj = self.pool.get('resource.calendar') resource_obj = self.pool.get('resource.resource') uom_obj = self.pool.get('product.uom') - if not context: + if context is None: context = {} if context.get('scheduler',False): return super(project_phase, self).write(cr, uid, ids, vals, context=context) @@ -191,7 +198,7 @@ class project_phase(osv.osv): # Change the date_start and date_end # for previous and next phases respectively based on valid condition if vals.get('date_start', False) and vals['date_start'] < phase.date_start: - dt_start = mx.DateTime.strptime(vals['date_start'],'%Y-%m-%d %H:%M:%S') + dt_start = mx.DateTime.strptime(vals['date_start'], '%Y-%m-%d %H:%M:%S') work_times = resource_calendar_obj.interval_get(cr, uid, calendar_id, dt_start, avg_hours or 0.0, resource_id and resource_id[0] or False) if work_times: vals['date_end'] = work_times[-1][1].strftime('%Y-%m-%d %H:%M:%S') @@ -214,7 +221,7 @@ class project_phase(osv.osv): self.write(cr, uid, ids, {'state': 'open'}) return True - def set_pending(self, cr, uid, ids,*args): + def set_pending(self, cr, uid, ids, *args): self.write(cr, uid, ids, {'state': 'pending'}) return True -- cgit v1.2.3 From ebcb4b9c01f067208b7ede24ee6b6fc413f9f870 Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Thu, 8 Jul 2010 10:43:51 +0200 Subject: [IMP] project_long_term: use xml_id to retrieve 'hour' uom instead of name search bzr revid: odo@openerp.com-20100708084351-acqc02wodltguooa --- addons/project_long_term/project_long_term.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'addons/project_long_term/project_long_term.py') diff --git a/addons/project_long_term/project_long_term.py b/addons/project_long_term/project_long_term.py index 4520e798f4e..a6fbcb22ab7 100644 --- a/addons/project_long_term/project_long_term.py +++ b/addons/project_long_term/project_long_term.py @@ -137,6 +137,7 @@ class project_phase(osv.osv): """ uom_obj = self.pool.get('product.uom') resource_obj = self.pool.get('resource.resource') + model_data_obj = self.pool.get('ir.model.data') cal_obj = self.pool.get('resource.calendar') calendar_id = phase.project_id.resource_calendar_id and phase.project_id.resource_calendar_id.id or False resource_id = resource_obj.search(cr, uid, [('user_id', '=', phase.responsible_id.id)]) @@ -146,7 +147,7 @@ class project_phase(osv.osv): cal_id = res.get('calendar_id', False) and res.get('calendar_id')[0] or False if cal_id: calendar_id = cal_id - default_uom_id = uom_obj.search(cr, uid, [('name', '=', 'Hour')], context=context)[0] + default_uom_id = model_data_obj._get_id(cr, uid, 'product', 'uom_hour') avg_hours = uom_obj._compute_qty(cr, uid, phase.product_uom.id, phase.duration, default_uom_id) work_times = cal_obj.interval_min_get(cr, uid, calendar_id, date_end, avg_hours or 0.0, resource_id and resource_id[0] or False) dt_start = work_times[0][0].strftime('%Y-%m-%d %H:%M:%S') @@ -159,6 +160,7 @@ class project_phase(osv.osv): Check And Compute date_end of phase if change in date_end > older time. """ uom_obj = self.pool.get('product.uom') + model_data_obj = self.pool.get('ir.model.data') resource_obj = self.pool.get('resource.resource') cal_obj = self.pool.get('resource.calendar') calendar_id = phase.project_id.resource_calendar_id and phase.project_id.resource_calendar_id.id or False @@ -169,7 +171,7 @@ class project_phase(osv.osv): cal_id = res.get('calendar_id', False) and res.get('calendar_id')[0] or False if cal_id: calendar_id = cal_id - default_uom_id = uom_obj.search(cr, uid, [('name', '=', 'Hour')], context=context)[0] + default_uom_id = model_data_obj._get_id(cr, uid, 'product', 'uom_hour') avg_hours = uom_obj._compute_qty(cr, uid, phase.product_uom.id, phase.duration, default_uom_id) work_times = cal_obj.interval_get(cr, uid, calendar_id, date_start, avg_hours or 0.0, resource_id and resource_id[0] or False) dt_end = work_times[-1][1].strftime('%Y-%m-%d %H:%M:%S') @@ -179,6 +181,7 @@ class project_phase(osv.osv): resource_calendar_obj = self.pool.get('resource.calendar') resource_obj = self.pool.get('resource.resource') uom_obj = self.pool.get('product.uom') + model_data_obj = self.pool.get('ir.model.data') if context is None: context = {} if context.get('scheduler',False): @@ -192,7 +195,7 @@ class project_phase(osv.osv): cal_id = resource_obj.browse(cr, uid, resource_id[0], context=context).calendar_id.id if cal_id: calendar_id = cal_id - default_uom_id = uom_obj.search(cr, uid, [('name', '=', 'Hour')])[0] + default_uom_id = model_data_obj._get_id(cr, uid, 'product', 'uom_hour') avg_hours = uom_obj._compute_qty(cr, uid, phase.product_uom.id, phase.duration, default_uom_id) # Change the date_start and date_end -- cgit v1.2.3 From 5047a630455b3ef9f58f834396085f0881cae7bd Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Thu, 8 Jul 2010 14:53:59 +0200 Subject: [FIX/REF] project_long_term: better way to obtain default uom unit bzr revid: odo@openerp.com-20100708125359-ov7z0d8bjgtm4gxs --- addons/project_long_term/project_long_term.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'addons/project_long_term/project_long_term.py') diff --git a/addons/project_long_term/project_long_term.py b/addons/project_long_term/project_long_term.py index a6fbcb22ab7..6cba9bc55d0 100644 --- a/addons/project_long_term/project_long_term.py +++ b/addons/project_long_term/project_long_term.py @@ -86,6 +86,11 @@ class project_phase(osv.osv): return False return True + def _get_default_uom_id(self, cr, uid): + model_data_obj = self.pool.get('ir.model.data') + model_data_id = model_data_obj._get_id(cr, uid, 'product', 'uom_hour') + return model_data_obj.read(cr, uid, [model_data_id], ['res_id'])[0]['res_id'] + _columns = { 'name': fields.char("Name", size=64, required=True), 'date_start': fields.datetime('Start Date', help="Starting Date of the phase"), @@ -137,7 +142,6 @@ class project_phase(osv.osv): """ uom_obj = self.pool.get('product.uom') resource_obj = self.pool.get('resource.resource') - model_data_obj = self.pool.get('ir.model.data') cal_obj = self.pool.get('resource.calendar') calendar_id = phase.project_id.resource_calendar_id and phase.project_id.resource_calendar_id.id or False resource_id = resource_obj.search(cr, uid, [('user_id', '=', phase.responsible_id.id)]) @@ -147,7 +151,7 @@ class project_phase(osv.osv): cal_id = res.get('calendar_id', False) and res.get('calendar_id')[0] or False if cal_id: calendar_id = cal_id - default_uom_id = model_data_obj._get_id(cr, uid, 'product', 'uom_hour') + default_uom_id = self._get_default_uom_id(cr, uid) avg_hours = uom_obj._compute_qty(cr, uid, phase.product_uom.id, phase.duration, default_uom_id) work_times = cal_obj.interval_min_get(cr, uid, calendar_id, date_end, avg_hours or 0.0, resource_id and resource_id[0] or False) dt_start = work_times[0][0].strftime('%Y-%m-%d %H:%M:%S') @@ -160,7 +164,6 @@ class project_phase(osv.osv): Check And Compute date_end of phase if change in date_end > older time. """ uom_obj = self.pool.get('product.uom') - model_data_obj = self.pool.get('ir.model.data') resource_obj = self.pool.get('resource.resource') cal_obj = self.pool.get('resource.calendar') calendar_id = phase.project_id.resource_calendar_id and phase.project_id.resource_calendar_id.id or False @@ -171,7 +174,7 @@ class project_phase(osv.osv): cal_id = res.get('calendar_id', False) and res.get('calendar_id')[0] or False if cal_id: calendar_id = cal_id - default_uom_id = model_data_obj._get_id(cr, uid, 'product', 'uom_hour') + default_uom_id = self._get_default_uom_id(cr, uid) avg_hours = uom_obj._compute_qty(cr, uid, phase.product_uom.id, phase.duration, default_uom_id) work_times = cal_obj.interval_get(cr, uid, calendar_id, date_start, avg_hours or 0.0, resource_id and resource_id[0] or False) dt_end = work_times[-1][1].strftime('%Y-%m-%d %H:%M:%S') @@ -181,7 +184,6 @@ class project_phase(osv.osv): resource_calendar_obj = self.pool.get('resource.calendar') resource_obj = self.pool.get('resource.resource') uom_obj = self.pool.get('product.uom') - model_data_obj = self.pool.get('ir.model.data') if context is None: context = {} if context.get('scheduler',False): @@ -195,7 +197,7 @@ class project_phase(osv.osv): cal_id = resource_obj.browse(cr, uid, resource_id[0], context=context).calendar_id.id if cal_id: calendar_id = cal_id - default_uom_id = model_data_obj._get_id(cr, uid, 'product', 'uom_hour') + default_uom_id = self._get_default_uom_id(cr, uid) avg_hours = uom_obj._compute_qty(cr, uid, phase.product_uom.id, phase.duration, default_uom_id) # Change the date_start and date_end -- cgit v1.2.3 From b079e0fb2b5225f2f3a169cbf6c01f9b53577d03 Mon Sep 17 00:00:00 2001 From: "pap (openerp)" Date: Fri, 9 Jul 2010 14:15:01 +0530 Subject: [FIX]: Day to day in project_long_term.py bzr revid: pap@tinyerp.co.in-20100709084501-25dwdtdokqcj0woc --- addons/project_long_term/project_long_term.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'addons/project_long_term/project_long_term.py') diff --git a/addons/project_long_term/project_long_term.py b/addons/project_long_term/project_long_term.py index 6cba9bc55d0..f76ab413e23 100644 --- a/addons/project_long_term/project_long_term.py +++ b/addons/project_long_term/project_long_term.py @@ -114,7 +114,7 @@ class project_phase(osv.osv): 'responsible_id': lambda obj,cr,uid,context: uid, 'state': 'draft', 'sequence': 10, - 'product_uom': lambda self,cr,uid,c: self.pool.get('product.uom').search(cr, uid, [('name', '=', 'Day')], context=c)[0] + 'product_uom': lambda self,cr,uid,c: self.pool.get('product.uom').search(cr, uid, [('name', '=', 'day')], context=c)[0] } _order = "name" _constraints = [ -- cgit v1.2.3 From 466c37fe3ead791a009d999c60401ca46aa34148 Mon Sep 17 00:00:00 2001 From: "qdp-launchpad@tinyerp.com" <> Date: Wed, 14 Jul 2010 04:51:26 +0530 Subject: [IMP] project_long_term: gantt view of resource allocation bzr revid: qdp-launchpad@tinyerp.com-20100713232126-kkryzm2ku8pqzthn --- addons/project_long_term/project_long_term.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'addons/project_long_term/project_long_term.py') diff --git a/addons/project_long_term/project_long_term.py b/addons/project_long_term/project_long_term.py index f76ab413e23..f1b4ab804c9 100644 --- a/addons/project_long_term/project_long_term.py +++ b/addons/project_long_term/project_long_term.py @@ -247,6 +247,8 @@ class project_resource_allocation(osv.osv): _columns = { 'resource_id': fields.many2one('resource.resource', 'Resource', required=True), 'phase_id': fields.many2one('project.phase', 'Project Phase', required=True), + 'phase_id_date_start': fields.related('phase_id', 'date_start', type='date', string='Starting Date of the phase'), + 'phase_id_date_end': fields.related('phase_id', 'date_end', type='date', string='Ending Date of the phase'), 'useability': fields.float('Usability', help="Usability of this resource for this project phase in percentage (=50%)"), } _defaults = { -- cgit v1.2.3 From c4afa3c7715ea1df11a663d02ed0914b0fa4b3cf Mon Sep 17 00:00:00 2001 From: "qdp-launchpad@tinyerp.com" <> Date: Wed, 14 Jul 2010 14:34:50 +0530 Subject: [IMP] project_long_term: gantt view + small bugfix bzr revid: qdp-launchpad@tinyerp.com-20100714090450-0la05jgw3pf59e5c --- addons/project_long_term/project_long_term.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'addons/project_long_term/project_long_term.py') diff --git a/addons/project_long_term/project_long_term.py b/addons/project_long_term/project_long_term.py index f1b4ab804c9..e1233bc413e 100644 --- a/addons/project_long_term/project_long_term.py +++ b/addons/project_long_term/project_long_term.py @@ -93,8 +93,8 @@ class project_phase(osv.osv): _columns = { 'name': fields.char("Name", size=64, required=True), - 'date_start': fields.datetime('Start Date', help="Starting Date of the phase"), - 'date_end': fields.datetime('End Date', help="Ending Date of the phase"), + 'date_start': fields.date('Start Date', help="Starting Date of the phase"), + 'date_end': fields.date('End Date', help="Ending Date of the phase"), 'constraint_date_start': fields.datetime('Start Date', help='force the phase to start after this date'), 'constraint_date_end': fields.datetime('End Date', help='force the phase to finish before this date'), 'project_id': fields.many2one('project.project', 'Project', required=True), @@ -114,7 +114,7 @@ class project_phase(osv.osv): 'responsible_id': lambda obj,cr,uid,context: uid, 'state': 'draft', 'sequence': 10, - 'product_uom': lambda self,cr,uid,c: self.pool.get('product.uom').search(cr, uid, [('name', '=', 'day')], context=c)[0] + 'product_uom': lambda self,cr,uid,c: self.pool.get('product.uom').search(cr, uid, [('name', '=', _('Day'))], context=c)[0] } _order = "name" _constraints = [ -- cgit v1.2.3 From f5707955cdf4beee85a0b02e96e56a4746b9504e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Valyi?= Date: Fri, 23 Jul 2010 13:08:54 -0300 Subject: [FIX] project_long_term: deleting a phase should delete its affected resources! bzr revid: rvalyi@gmail.com-20100723160854-jdjopucvsl4x2af2 --- addons/project_long_term/project_long_term.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'addons/project_long_term/project_long_term.py') diff --git a/addons/project_long_term/project_long_term.py b/addons/project_long_term/project_long_term.py index 0ecdcc69a2e..56e2ff9b3d8 100644 --- a/addons/project_long_term/project_long_term.py +++ b/addons/project_long_term/project_long_term.py @@ -245,7 +245,7 @@ class project_resource_allocation(osv.osv): _description = 'Project Resource Allocation' _rec_name = 'resource_id' _columns = { - 'resource_id': fields.many2one('resource.resource', 'Resource', required=True), + 'resource_id': fields.many2one('resource.resource', 'Resource', ondelete='cascade', required=True), 'phase_id': fields.many2one('project.phase', 'Project Phase', required=True), 'phase_id_date_start': fields.related('phase_id', 'date_start', type='date', string='Starting Date of the phase'), 'phase_id_date_end': fields.related('phase_id', 'date_end', type='date', string='Ending Date of the phase'), -- cgit v1.2.3 From 717c7c5b11fb0a4bd6821abc8f774bf6f4d5ceb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Valyi?= Date: Sun, 25 Jul 2010 12:55:48 -0300 Subject: [FIX] project_long_term: it's phase_id that should be ondelete='cascade'; fixed write if only one id provided as it is usually permitted bzr revid: rvalyi@gmail.com-20100725155548-fss28s73p0gvxjrj --- addons/project_long_term/project_long_term.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'addons/project_long_term/project_long_term.py') diff --git a/addons/project_long_term/project_long_term.py b/addons/project_long_term/project_long_term.py index 56e2ff9b3d8..fc1fea91311 100644 --- a/addons/project_long_term/project_long_term.py +++ b/addons/project_long_term/project_long_term.py @@ -190,6 +190,8 @@ class project_phase(osv.osv): return super(project_phase, self).write(cr, uid, ids, vals, context=context) # Consider calendar and efficiency if the phase is performed by a resource # otherwise consider the project's working calendar + if type(ids) == int: + ids = [ids] phase = self.browse(cr, uid, ids[0], context=context) calendar_id = phase.project_id.resource_calendar_id and phase.project_id.resource_calendar_id.id or False resource_id = resource_obj.search(cr, uid, [('user_id', '=', phase.responsible_id.id)],context=context) @@ -245,8 +247,8 @@ class project_resource_allocation(osv.osv): _description = 'Project Resource Allocation' _rec_name = 'resource_id' _columns = { - 'resource_id': fields.many2one('resource.resource', 'Resource', ondelete='cascade', required=True), - 'phase_id': fields.many2one('project.phase', 'Project Phase', required=True), + 'resource_id': fields.many2one('resource.resource', 'Resource', required=True), + 'phase_id': fields.many2one('project.phase', 'Project Phase', ondelete='cascade', required=True), 'phase_id_date_start': fields.related('phase_id', 'date_start', type='date', string='Starting Date of the phase'), 'phase_id_date_end': fields.related('phase_id', 'date_end', type='date', string='Ending Date of the phase'), 'useability': fields.float('Usability', help="Usability of this resource for this project phase in percentage (=50%)"), -- cgit v1.2.3 From 3bc25fb07ef8aa959d2c7df0b9515e6a3147c0c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Valyi?= Date: Sun, 25 Jul 2010 13:58:26 -0300 Subject: [REF] clean up before merge (clean double work diffs) bzr revid: rvalyi@gmail.com-20100725165826-etg68lktjnt9ih5l --- addons/project_long_term/project_long_term.py | 2 -- 1 file changed, 2 deletions(-) (limited to 'addons/project_long_term/project_long_term.py') diff --git a/addons/project_long_term/project_long_term.py b/addons/project_long_term/project_long_term.py index fc1fea91311..9371232745b 100644 --- a/addons/project_long_term/project_long_term.py +++ b/addons/project_long_term/project_long_term.py @@ -252,8 +252,6 @@ class project_resource_allocation(osv.osv): 'phase_id_date_start': fields.related('phase_id', 'date_start', type='date', string='Starting Date of the phase'), 'phase_id_date_end': fields.related('phase_id', 'date_end', type='date', string='Ending Date of the phase'), 'useability': fields.float('Usability', help="Usability of this resource for this project phase in percentage (=50%)"), - 'date_start': fields.related('phase_id', 'date_start', type='datetime', string='Start Date'), - 'date_end': fields.related('phase_id', 'date_end', type='datetime', string='End Date'), } _defaults = { 'useability': 100, -- cgit v1.2.3 From 9bd6693f6d7c870d910e27b75f99397815b0ef73 Mon Sep 17 00:00:00 2001 From: "pap (openerp)" Date: Thu, 29 Jul 2010 11:01:04 +0530 Subject: [IMP]: imp in project, project_log_term - changed type of all the dates in project phase from datetime to date - improved send mail wizard on closing a task based on projects warn_customer, war_manager fields improved yaml and demo data fields set to readonly when project, phases or tasks in done state bzr revid: pap@tinyerp.co.in-20100729053104-vx94tzk051896frz --- addons/project_long_term/project_long_term.py | 46 +++++++++++++-------------- 1 file changed, 23 insertions(+), 23 deletions(-) (limited to 'addons/project_long_term/project_long_term.py') diff --git a/addons/project_long_term/project_long_term.py b/addons/project_long_term/project_long_term.py index e1233bc413e..03b8ae8edc8 100644 --- a/addons/project_long_term/project_long_term.py +++ b/addons/project_long_term/project_long_term.py @@ -93,19 +93,19 @@ class project_phase(osv.osv): _columns = { 'name': fields.char("Name", size=64, required=True), - 'date_start': fields.date('Start Date', help="Starting Date of the phase"), - 'date_end': fields.date('End Date', help="Ending Date of the phase"), - 'constraint_date_start': fields.datetime('Start Date', help='force the phase to start after this date'), - 'constraint_date_end': fields.datetime('End Date', help='force the phase to finish before this date'), + 'date_start': fields.date('Start Date', help="Starting Date of the phase", states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}), + 'date_end': fields.date('End Date', help="Ending Date of the phase", states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}), + 'constraint_date_start': fields.date('Start Date', help='force the phase to start after this date', states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}), + 'constraint_date_end': fields.date('End Date', help='force the phase to finish before this date', states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}), 'project_id': fields.many2one('project.project', 'Project', required=True), - 'next_phase_ids': fields.many2many('project.phase', 'project_phase_rel', 'prv_phase_id', 'next_phase_id', 'Next Phases'), - 'previous_phase_ids': fields.many2many('project.phase', 'project_phase_rel', 'next_phase_id', 'prv_phase_id', 'Previous Phases'), + 'next_phase_ids': fields.many2many('project.phase', 'project_phase_rel', 'prv_phase_id', 'next_phase_id', 'Next Phases', states={'cancelled':[('readonly',True)]}), + 'previous_phase_ids': fields.many2many('project.phase', 'project_phase_rel', 'next_phase_id', 'prv_phase_id', 'Previous Phases', states={'cancelled':[('readonly',True)]}), 'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of phases."), - 'duration': fields.float('Duration', required=True, help="By default in days"), - 'product_uom': fields.many2one('product.uom', 'Duration UoM', required=True, help="UoM (Unit of Measure) is the unit of measurement for Duration"), - 'task_ids': fields.one2many('project.task', 'phase_id', "Project Tasks"), - 'resource_ids': fields.one2many('project.resource.allocation', 'phase_id', "Project Resources"), - 'responsible_id': fields.many2one('res.users', 'Responsible'), + 'duration': fields.float('Duration', required=True, help="By default in days", states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}), + 'product_uom': fields.many2one('product.uom', 'Duration UoM', required=True, help="UoM (Unit of Measure) is the unit of measurement for Duration", states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}), + 'task_ids': fields.one2many('project.task', 'phase_id', "Project Tasks", states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}), + 'resource_ids': fields.one2many('project.resource.allocation', 'phase_id', "Project Resources",states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}), + 'responsible_id': fields.many2one('res.users', 'Responsible', states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}), 'state': fields.selection([('draft', 'Draft'), ('open', 'In Progress'), ('pending', 'Pending'), ('cancelled', 'Cancelled'), ('done', 'Done')], 'State', readonly=True, required=True, help='If the phase is created the state \'Draft\'.\n If the phase is started, the state becomes \'In Progress\'.\n If review is needed the phase is in \'Pending\' state.\ \n If the phase is over, the states is set to \'Done\'.') @@ -130,7 +130,7 @@ class project_phase(osv.osv): if project: project_id = project_obj.browse(cr, uid, project, context=context) if project_id.date_start: - result['date_start'] = mx.DateTime.strptime(project_id.date_start, "%Y-%m-%d").strftime('%Y-%m-%d %H:%M:%S') + result['date_start'] = mx.DateTime.strptime(project_id.date_start, "%Y-%m-%d").strftime('%Y-%m-%d') return {'value': result} return {'value': {'date_start': []}} @@ -147,15 +147,15 @@ class project_phase(osv.osv): resource_id = resource_obj.search(cr, uid, [('user_id', '=', phase.responsible_id.id)]) if resource_id: # cal_id = resource_obj.browse(cr, uid, resource_id[0], context=context).calendar_id.id - res = resource_obj.read(cr, uid, resource_id[0], ['calendar_id'], context=context)[0] + res = resource_obj.read(cr, uid, resource_id, ['calendar_id'], context=context)[0] cal_id = res.get('calendar_id', False) and res.get('calendar_id')[0] or False if cal_id: calendar_id = cal_id default_uom_id = self._get_default_uom_id(cr, uid) avg_hours = uom_obj._compute_qty(cr, uid, phase.product_uom.id, phase.duration, default_uom_id) work_times = cal_obj.interval_min_get(cr, uid, calendar_id, date_end, avg_hours or 0.0, resource_id and resource_id[0] or False) - dt_start = work_times[0][0].strftime('%Y-%m-%d %H:%M:%S') - self.write(cr, uid, [phase.id], {'date_start': dt_start, 'date_end': date_end.strftime('%Y-%m-%d %H:%M:%S')}, context=context) + dt_start = work_times[0][0].strftime('%Y-%m-%d') + self.write(cr, uid, [phase.id], {'date_start': dt_start, 'date_end': date_end.strftime('%Y-%m-%d')}, context=context) def _check_date_end(self, cr, uid, phase, date_start, context=None): if context is None: @@ -170,15 +170,15 @@ class project_phase(osv.osv): resource_id = resource_obj.search(cr, uid, [('user_id', '=', phase.responsible_id.id)], context=context) if resource_id: # cal_id = resource_obj.browse(cr, uid, resource_id[0], context=context).calendar_id.id - res = resource_obj.read(cr, uid, resource_id[0], ['calendar_id'], context=context)[0] + res = resource_obj.read(cr, uid, resource_id, ['calendar_id'], context=context)[0] cal_id = res.get('calendar_id', False) and res.get('calendar_id')[0] or False if cal_id: calendar_id = cal_id default_uom_id = self._get_default_uom_id(cr, uid) avg_hours = uom_obj._compute_qty(cr, uid, phase.product_uom.id, phase.duration, default_uom_id) work_times = cal_obj.interval_get(cr, uid, calendar_id, date_start, avg_hours or 0.0, resource_id and resource_id[0] or False) - dt_end = work_times[-1][1].strftime('%Y-%m-%d %H:%M:%S') - self.write(cr, uid, [phase.id], {'date_start': date_start.strftime('%Y-%m-%d %H:%M:%S'), 'date_end': dt_end}, context=context) + dt_end = work_times[-1][1].strftime('%Y-%m-%d') + self.write(cr, uid, [phase.id], {'date_start': date_start.strftime('%Y-%m-%d'), 'date_end': dt_end}, context=context) def write(self, cr, uid, ids, vals, context=None): resource_calendar_obj = self.pool.get('resource.calendar') @@ -203,17 +203,17 @@ class project_phase(osv.osv): # Change the date_start and date_end # for previous and next phases respectively based on valid condition if vals.get('date_start', False) and vals['date_start'] < phase.date_start: - dt_start = mx.DateTime.strptime(vals['date_start'], '%Y-%m-%d %H:%M:%S') + dt_start = mx.DateTime.strptime(vals['date_start'], '%Y-%m-%d') work_times = resource_calendar_obj.interval_get(cr, uid, calendar_id, dt_start, avg_hours or 0.0, resource_id and resource_id[0] or False) if work_times: - vals['date_end'] = work_times[-1][1].strftime('%Y-%m-%d %H:%M:%S') + vals['date_end'] = work_times[-1][1].strftime('%Y-%m-%d') for prv_phase in phase.previous_phase_ids: self._check_date_start(cr, uid, prv_phase, dt_start, context=context) if vals.get('date_end', False) and vals['date_end'] > phase.date_end: - dt_end = mx.DateTime.strptime(vals['date_end'],'%Y-%m-%d %H:%M:%S') + dt_end = mx.DateTime.strptime(vals['date_end'],'%Y-%m-%d') work_times = resource_calendar_obj.interval_min_get(cr, uid, calendar_id, dt_end, avg_hours or 0.0, resource_id and resource_id[0] or False) if work_times: - vals['date_start'] = work_times[0][0].strftime('%Y-%m-%d %H:%M:%S') + vals['date_start'] = work_times[0][0].strftime('%Y-%m-%d') for next_phase in phase.next_phase_ids: self._check_date_end(cr, uid, next_phase, dt_end, context=context) return super(project_phase, self).write(cr, uid, ids, vals, context=context) @@ -261,7 +261,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"), + 'resource_calendar_id': fields.many2one('resource.calendar', 'Working Time', help="Timetable working hours to adjust the gantt diagram report", states={'close':[('readonly',True)]} ), } project() -- cgit v1.2.3 From ac56c74c8cbb3293ac937849c7f6b905b69fbd30 Mon Sep 17 00:00:00 2001 From: Stephane Wirtel Date: Fri, 30 Jul 2010 14:35:21 +0200 Subject: [FIX] project_long_term: Use the isinstance built-in function instead of type bzr revid: stephane@openerp.com-20100730123521-79aal4640kzetw57 --- addons/project_long_term/project_long_term.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'addons/project_long_term/project_long_term.py') diff --git a/addons/project_long_term/project_long_term.py b/addons/project_long_term/project_long_term.py index e87512d0c75..f4ae126ee67 100644 --- a/addons/project_long_term/project_long_term.py +++ b/addons/project_long_term/project_long_term.py @@ -190,7 +190,7 @@ class project_phase(osv.osv): return super(project_phase, self).write(cr, uid, ids, vals, context=context) # Consider calendar and efficiency if the phase is performed by a resource # otherwise consider the project's working calendar - if type(ids) == int: + if isinstance(ids, (int, long)): ids = [ids] phase = self.browse(cr, uid, ids[0], context=context) calendar_id = phase.project_id.resource_calendar_id and phase.project_id.resource_calendar_id.id or False -- cgit v1.2.3 From c75affcd1c21ea5191dd57ade5ab045ff8e6de6f Mon Sep 17 00:00:00 2001 From: "PAP(OpenERP)" <> Date: Thu, 12 Aug 2010 13:01:45 +0530 Subject: [IMP] project & its related module with removing of mx.datetime dependancy bzr revid: mra@mra-laptop-20100812073145-h57aft3vbcxsmvu7 --- addons/project_long_term/project_long_term.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'addons/project_long_term/project_long_term.py') diff --git a/addons/project_long_term/project_long_term.py b/addons/project_long_term/project_long_term.py index f4ae126ee67..1bb2510064b 100644 --- a/addons/project_long_term/project_long_term.py +++ b/addons/project_long_term/project_long_term.py @@ -18,9 +18,9 @@ # along with this program. If not, see . # ############################################################################## -from lxml import etree -import mx.DateTime + import time +from datetime import date, datetime, timedelta from tools.translate import _ from osv import fields, osv @@ -126,13 +126,12 @@ class project_phase(osv.osv): def onchange_project(self, cr, uid, ids, project, context=None): result = {} + result['date_start'] = False project_obj = self.pool.get('project.project') if project: project_id = project_obj.browse(cr, uid, project, context=context) - if project_id.date_start: - result['date_start'] = mx.DateTime.strptime(project_id.date_start, "%Y-%m-%d").strftime('%Y-%m-%d') - return {'value': result} - return {'value': {'date_start': []}} + result['date_start'] = project_id.date_start + return {'value': result} def _check_date_start(self, cr, uid, phase, date_end, context=None): if context is None: @@ -201,18 +200,17 @@ class project_phase(osv.osv): calendar_id = cal_id default_uom_id = self._get_default_uom_id(cr, uid) avg_hours = uom_obj._compute_qty(cr, uid, phase.product_uom.id, phase.duration, default_uom_id) - # Change the date_start and date_end # for previous and next phases respectively based on valid condition if vals.get('date_start', False) and vals['date_start'] < phase.date_start: - dt_start = mx.DateTime.strptime(vals['date_start'], '%Y-%m-%d') + dt_start = datetime.strptime(vals['date_start'], '%Y-%m-%d') work_times = resource_calendar_obj.interval_get(cr, uid, calendar_id, dt_start, avg_hours or 0.0, resource_id and resource_id[0] or False) if work_times: vals['date_end'] = work_times[-1][1].strftime('%Y-%m-%d') for prv_phase in phase.previous_phase_ids: self._check_date_start(cr, uid, prv_phase, dt_start, context=context) if vals.get('date_end', False) and vals['date_end'] > phase.date_end: - dt_end = mx.DateTime.strptime(vals['date_end'],'%Y-%m-%d') + dt_end = datetime.strptime(vals['date_end'], '%Y-%m-%d') work_times = resource_calendar_obj.interval_min_get(cr, uid, calendar_id, dt_end, avg_hours or 0.0, resource_id and resource_id[0] or False) if work_times: vals['date_start'] = work_times[0][0].strftime('%Y-%m-%d') -- cgit v1.2.3 From 45a8d54f185be7fbc54476109500897928709756 Mon Sep 17 00:00:00 2001 From: "Rvo (Open ERP)" Date: Fri, 13 Aug 2010 17:50:05 +0530 Subject: [CLEAN]: removed commented code, fixed proper indentation in dictionary and removed extra spaces at few places bzr revid: rvo@tinyerp.co.in-20100813122005-qj1l1iumkfmocyvk --- addons/project_long_term/project_long_term.py | 4 ---- 1 file changed, 4 deletions(-) (limited to 'addons/project_long_term/project_long_term.py') diff --git a/addons/project_long_term/project_long_term.py b/addons/project_long_term/project_long_term.py index 1bb2510064b..04fde75342e 100644 --- a/addons/project_long_term/project_long_term.py +++ b/addons/project_long_term/project_long_term.py @@ -120,8 +120,6 @@ class project_phase(osv.osv): _constraints = [ (_check_recursion,'Loops in phases not allowed',['next_phase_ids', 'previous_phase_ids']), (_check_dates, 'Phase start-date must be lower than phase end-date.', ['date_start', 'date_end']), - #(_check_constraint_start, 'Phase must start-after constraint start Date.', ['date_start', 'constraint_date_start']), - #(_check_constraint_end, 'Phase must end-before constraint end Date.', ['date_end', 'constraint_date_end']), ] def onchange_project(self, cr, uid, ids, project, context=None): @@ -145,7 +143,6 @@ class project_phase(osv.osv): calendar_id = phase.project_id.resource_calendar_id and phase.project_id.resource_calendar_id.id or False resource_id = resource_obj.search(cr, uid, [('user_id', '=', phase.responsible_id.id)]) if resource_id: -# cal_id = resource_obj.browse(cr, uid, resource_id[0], context=context).calendar_id.id res = resource_obj.read(cr, uid, resource_id, ['calendar_id'], context=context)[0] cal_id = res.get('calendar_id', False) and res.get('calendar_id')[0] or False if cal_id: @@ -168,7 +165,6 @@ class project_phase(osv.osv): calendar_id = phase.project_id.resource_calendar_id and phase.project_id.resource_calendar_id.id or False resource_id = resource_obj.search(cr, uid, [('user_id', '=', phase.responsible_id.id)], context=context) if resource_id: -# cal_id = resource_obj.browse(cr, uid, resource_id[0], context=context).calendar_id.id res = resource_obj.read(cr, uid, resource_id, ['calendar_id'], context=context)[0] cal_id = res.get('calendar_id', False) and res.get('calendar_id')[0] or False if cal_id: -- cgit v1.2.3 From 0cb1ed9f96b2f313b649c542540fa9ec269d35a2 Mon Sep 17 00:00:00 2001 From: "Raphael Valyi(Akretion)" <> Date: Tue, 14 Sep 2010 18:27:44 +0530 Subject: [FIX] Project_long_term : Better ordering on phase lp bug: https://launchpad.net/bugs/629735 fixed bzr revid: jvo@tinyerp.com-20100914125744-78lz9uaby27z4a07 --- addons/project_long_term/project_long_term.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'addons/project_long_term/project_long_term.py') diff --git a/addons/project_long_term/project_long_term.py b/addons/project_long_term/project_long_term.py index 04fde75342e..79baff679cc 100644 --- a/addons/project_long_term/project_long_term.py +++ b/addons/project_long_term/project_long_term.py @@ -116,7 +116,7 @@ class project_phase(osv.osv): 'sequence': 10, 'product_uom': lambda self,cr,uid,c: self.pool.get('product.uom').search(cr, uid, [('name', '=', _('Day'))], context=c)[0] } - _order = "name" + _order = "project_id, date_start, sequence, name" _constraints = [ (_check_recursion,'Loops in phases not allowed',['next_phase_ids', 'previous_phase_ids']), (_check_dates, 'Phase start-date must be lower than phase end-date.', ['date_start', 'date_end']), -- cgit v1.2.3 From 050344d175dc19e6b3cfa306bb2c01ddc977100a Mon Sep 17 00:00:00 2001 From: "Rvo (Open ERP)" Date: Sat, 18 Sep 2010 11:22:11 +0530 Subject: [IMP]: Usability Improvements bzr revid: rvo@tinyerp.co.in-20100918055211-3kuyw3k8nagxvb7t --- addons/project_long_term/project_long_term.py | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'addons/project_long_term/project_long_term.py') diff --git a/addons/project_long_term/project_long_term.py b/addons/project_long_term/project_long_term.py index 79baff679cc..b795dda557e 100644 --- a/addons/project_long_term/project_long_term.py +++ b/addons/project_long_term/project_long_term.py @@ -214,6 +214,13 @@ class project_phase(osv.osv): self._check_date_end(cr, uid, next_phase, dt_end, context=context) return super(project_phase, self).write(cr, uid, ids, vals, context=context) + def copy(self, cr, uid, id, default=None, context=None): + if default is None: + default = {} + if not default.get('name', False): + default['name'] = self.browse(cr, uid, id, context=context).name + _(' (copy)') + return super(project_phase, self).copy(cr, uid, id, default, context) + def set_draft(self, cr, uid, ids, *args): self.write(cr, uid, ids, {'state': 'draft'}) return True -- cgit v1.2.3 From fb383d75e475900d105a853f00063438e9d5be02 Mon Sep 17 00:00:00 2001 From: "Harry (OpenERP)" Date: Fri, 24 Sep 2010 14:56:14 +0530 Subject: [REF] project_long_term: Refactor code to compute tasks and phases bzr revid: hmo@tinyerp.com-20100924092614-kxmx5r8cox7hg4ry --- addons/project_long_term/project_long_term.py | 308 ++++++++++++++++++++++++-- 1 file changed, 293 insertions(+), 15 deletions(-) (limited to 'addons/project_long_term/project_long_term.py') diff --git a/addons/project_long_term/project_long_term.py b/addons/project_long_term/project_long_term.py index b795dda557e..05eca01887c 100644 --- a/addons/project_long_term/project_long_term.py +++ b/addons/project_long_term/project_long_term.py @@ -21,9 +21,10 @@ import time from datetime import date, datetime, timedelta - from tools.translate import _ from osv import fields, osv +from resource.faces import task as Task +import operator class project_phase(osv.osv): _name = "project.phase" @@ -181,38 +182,48 @@ class project_phase(osv.osv): uom_obj = self.pool.get('product.uom') if context is None: context = {} + res = super(project_phase, self).write(cr, uid, ids, vals, context=context) if context.get('scheduler',False): - return super(project_phase, self).write(cr, uid, ids, vals, context=context) + return res # Consider calendar and efficiency if the phase is performed by a resource # otherwise consider the project's working calendar + + #TOCHECK : why need this ? if isinstance(ids, (int, long)): ids = [ids] - phase = self.browse(cr, uid, ids[0], context=context) - calendar_id = phase.project_id.resource_calendar_id and phase.project_id.resource_calendar_id.id or False - resource_id = resource_obj.search(cr, uid, [('user_id', '=', phase.responsible_id.id)],context=context) - if resource_id: + default_uom_id = self._get_default_uom_id(cr, uid) + for phase in self.browse(cr, uid, ids, context=context): + calendar_id = phase.project_id.resource_calendar_id and phase.project_id.resource_calendar_id.id or False + resource_id = resource_obj.search(cr, uid, [('user_id', '=', phase.responsible_id.id)],context=context) + if resource_id: cal_id = resource_obj.browse(cr, uid, resource_id[0], context=context).calendar_id.id if cal_id: calendar_id = cal_id - default_uom_id = self._get_default_uom_id(cr, uid) - avg_hours = uom_obj._compute_qty(cr, uid, phase.product_uom.id, phase.duration, default_uom_id) - # Change the date_start and date_end - # for previous and next phases respectively based on valid condition - if vals.get('date_start', False) and vals['date_start'] < phase.date_start: + + avg_hours = uom_obj._compute_qty(cr, uid, phase.product_uom.id, phase.duration, default_uom_id) + # Change the date_start and date_end + # for previous and next phases respectively based on valid condition + if vals.get('date_start', False) and vals['date_start'] < phase.date_start: dt_start = datetime.strptime(vals['date_start'], '%Y-%m-%d') work_times = resource_calendar_obj.interval_get(cr, uid, calendar_id, dt_start, avg_hours or 0.0, resource_id and resource_id[0] or False) if work_times: vals['date_end'] = work_times[-1][1].strftime('%Y-%m-%d') for prv_phase in phase.previous_phase_ids: + if prv_phase.id == phase.id: + continue self._check_date_start(cr, uid, prv_phase, dt_start, context=context) - if vals.get('date_end', False) and vals['date_end'] > phase.date_end: + + if vals.get('date_end', False) and vals['date_end'] > phase.date_end: dt_end = datetime.strptime(vals['date_end'], '%Y-%m-%d') work_times = resource_calendar_obj.interval_min_get(cr, uid, calendar_id, dt_end, avg_hours or 0.0, resource_id and resource_id[0] or False) if work_times: vals['date_start'] = work_times[0][0].strftime('%Y-%m-%d') for next_phase in phase.next_phase_ids: + if next_phase.id == phase.id: + continue self._check_date_end(cr, uid, next_phase, dt_end, context=context) - return super(project_phase, self).write(cr, uid, ids, vals, context=context) + + return res def copy(self, cr, uid, id, default=None, context=None): if default is None: @@ -241,6 +252,118 @@ class project_phase(osv.osv): self.write(cr, uid, ids, {'state': 'done'}) return True + def generate_resources(self, cr, uid, ids, context=None): + """ + Return a list of Resource Class objects for the resources allocated to the phase. + """ + res = {} + if context is None: + context = {} + 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) + res[phase.id] = resource_objs + return res + + def generate_schedule(self, cr, uid, ids, start_date, calendar_id=False, context=None): + """ + Schedule phase with the start date till all the next phases are completed. + @param: start_dsate : start date for the phase + @param: calendar_id : working calendar of the project + """ + if context is None: + context = {} + resource_pool = self.pool.get('resource.resource') + uom_pool = self.pool.get('product.uom') + phase_resource = False + if context is None: + context = {} + default_uom_id = self._get_default_uom_id(cr, uid) + for phase in self.browse(cr, uid, ids, context=context): + if not phase.responsible_id: + raise osv.except_osv(_('No responsible person assigned !'),_("You must assign a responsible person for phase '%s' !") % (phase.name,)) + + phase_resource_obj = resource_pool.generate_resources(cr, uid, [phase.responsible_id.id], calendar_id, context=context) + avg_hours = uom_pool._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 = resource_pool.compute_working_calendar(cr, uid, calendar_id, context=context) + vacation = tuple(resource_pool.compute_vacation(cr, uid, calendar_id)) + + def phase(): + effort = duration + + project = Task.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.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) + + # 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.generate_schedule(cr, uid, [phase.id], date_start, id_cal, context=context) + else: + continue + return True + + def schedule_tasks(self, cr, uid, ids, context=None): + """ + Schedule the tasks according to resource available and priority. + """ + task_pool = self.pool.get('project.task') + resource_pool = self.pool.get('resource.resource') + if context is None: + context = {} + resources_list = self.generate_resources(cr, uid, ids, context=context) + return_msg = {} + for phase in self.browse(cr, uid, ids, context=context): + start_date = phase.date_start + if not start_date and phase.project_id.date_start: + start_date = phase.project_id.date_start + if not start_date: + start_date = datetime.now().strftime("%Y-%m-%d") + resources = resources_list.get(phase.id, []) + calendar_id = phase.project_id.resource_calendar_id.id + task_ids = map(lambda x : x.id, (filter(lambda x : x.state in ['open', 'draft', 'pending'] , phase.task_ids))) + if task_ids: + task_pool.generate_schedule(cr, uid, task_ids, resources, calendar_id, start_date, context=context) + + if not task_ids: + warning_msg = _("No tasks to compute for Phase '%s'.") % (phase.name) + if "warning" not in return_msg: + return_msg["warning"] = warning_msg + else: + return_msg["warning"] = return_msg["warning"] + "\n" + warning_msg + return return_msg project_phase() class project_resource_allocation(osv.osv): @@ -266,14 +389,169 @@ class project(osv.osv): '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 generate_members(self, cr, uid, ids, context=None): + """ + Return a list of Resource Class objects for the resources allocated to the phase. + """ + res = {} + resource_pool = self.pool.get('resource.resource') + if context is None: + context = {} + for project in self.browse(cr, uid, ids, context=context): + user_ids = map(lambda x:x.id, project.members) + 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) + res[project.id] = resource_objs + return res + + def schedule_phases(self, cr, uid, ids, context=None): + """ + Schedule the phases. + """ + if context is None: + context = {} + if type(ids) in (long, int,): + ids = [ids] + phase_pool = self.pool.get('project.phase') + for project in self.browse(cr, uid, ids, context=context): + phase_ids = phase_pool.search(cr, uid, [('project_id', '=', project.id), + ('state', 'in', ['draft', 'open', 'pending']), + ('previous_phase_ids', '=', False) + ]) + start_date = project.date_start + if not start_date: + start_date = datetime.now().strftime("%Y-%m-%d") + start_dt = datetime.strftime((datetime.strptime(start_date, "%Y-%m-%d")), "%Y-%m-%d %H:%M") + calendar_id = project.resource_calendar_id and project.resource_calendar_id.id or False + phase_pool.generate_schedule(cr, uid, phase_ids, start_dt, calendar_id, context=context) + return True + + def schedule_tasks(self, cr, uid, ids, context=None): + """ + Schedule the tasks according to resource available and priority. + """ + if type(ids) in (long, int,): + ids = [ids] + user_pool = self.pool.get('res.users') + task_pool = self.pool.get('project.task') + resource_pool = self.pool.get('resource.resource') + if context is None: + context = {} + + resources_list = self.generate_members(cr, uid, ids, context=context) + return_msg = {} + for project in self.browse(cr, uid, ids, context=context): + start_date = project.date_start + if not start_date: + start_date = datetime.now().strftime("%Y-%m-%d") + resources = resources_list.get(project.id, []) + calendar_id = project.resource_calendar_id.id + task_ids = task_pool.search(cr, uid, [('project_id', '=', project.id), + ('state', 'in', ['draft', 'open', 'pending']) + ]) + + + if task_ids: + task_pool.generate_schedule(cr, uid, task_ids, resources, calendar_id, start_date, context=context) + else: + warning_msg = _("No tasks to compute for Project '%s'.") % (project.name) + if "warning" not in return_msg: + return_msg["warning"] = warning_msg + else: + return_msg["warning"] = return_msg["warning"] + "\n" + warning_msg + + return return_msg project() -class task(osv.osv): +class resource_resource(osv.osv): + _inherit = "resource.resource" + def search(self, cr, uid, args, offset=0, limit=None, order=None, context=None, count=False): + if context is None: + context = {} + if context.get('project_id',False): + project_pool = self.pool.get('project.project') + project_rec = project_pool.browse(cr, uid, context['project_id']) + user_ids = [user_id.id for user_id in project_rec.members] + args.append(('user_id','in',user_ids)) + return super(resource_resource, self).search(cr, uid, args, offset, limit, order, context, count) + +resource_resource() + +class project_task(osv.osv): _inherit = "project.task" _columns = { 'phase_id': fields.many2one('project.phase', 'Project Phase'), } + + def generate_schedule(self, cr, uid, ids, resources, calendar_id, start_date, context=None): + """ + Schedule the tasks according to resource available and priority. + """ + if not ids: + return False + if context is None: + context = {} + user_pool = self.pool.get('res.users') + project_pool = self.pool.get('project.project') + priority_dict = {'0': 1000, '1': 800, '2': 500, '3': 300, '4': 100} + # Create dynamic no of tasks with the resource specified + def create_tasks(task_number, eff, priorty=500, obj=False): + def task(): + """ + task is a dynamic method! + """ + effort = eff + if obj: + resource = obj + priority = priorty + task.__doc__ = "TaskNO%d" %task_number + task.__name__ = "task%d" %task_number + return task + + # Create a 'Faces' project with all the tasks and resources + def Project(): + title = "Project" + start = datetime.strftime(datetime.strptime(start_date, "%Y-%m-%d"), "%Y-%m-%d %H:%M") + resource = reduce(operator.or_, resources) + minimum_time_unit = 1 + if calendar_id: # If project has working calendar + working_days = resource_pool.compute_working_calendar(cr, uid, calendar_id, context=context) + vacation = tuple(resource_pool.compute_vacation(cr, uid, calendar_id, context=context)) + # Dynamic creation of tasks + task_number = 0 + for openobect_task in self.browse(cr, uid, ids, context=context): + hours = str(openobect_task.planned_hours )+ 'H' + if openobect_task.priority in priority_dict.keys(): + priorty = priority_dict[openobect_task.priority] + real_resource = False + if openobect_task.user_id: + for task_resource in resources: + if task_resource.__name__ == task_resource: + real_resource = task_resource + break + + task = create_tasks(task_number, hours, priorty, real_resource) + task_number += 1 + -task() + face_projects = Task.BalancedProject(Project) + loop_no = 0 + # Write back the computed dates + for face_project in face_projects: + s_date = face_project.start.to_datetime() + e_date = face_project.end.to_datetime() + if loop_no > 0: + ctx = context.copy() + ctx.update({'scheduler': True}) + user_id = user_pool.search(cr, uid, [('name', '=', face_project.booked_resource[0].__name__)]) + self.write(cr, uid, [ids[loop_no-1]], { + 'date_start': s_date.strftime('%Y-%m-%d %H:%M:%S'), + 'date_end': e_date.strftime('%Y-%m-%d %H:%M:%S'), + 'user_id': user_id[0] + }, context=ctx) + + loop_no += 1 + return True +project_task() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: -- cgit v1.2.3 From 621f24aee4ded5f4982e4c16c0f8cb46f1a3607a Mon Sep 17 00:00:00 2001 From: "Harry (OpenERP)" Date: Fri, 24 Sep 2010 15:17:12 +0530 Subject: [FIX] project_long_term: fix if not resource allocation or project member bzr revid: hmo@tinyerp.com-20100924094712-f7cl79s1zaw3vtuq --- addons/project_long_term/project_long_term.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'addons/project_long_term/project_long_term.py') diff --git a/addons/project_long_term/project_long_term.py b/addons/project_long_term/project_long_term.py index 05eca01887c..79837416d97 100644 --- a/addons/project_long_term/project_long_term.py +++ b/addons/project_long_term/project_long_term.py @@ -513,7 +513,10 @@ class project_task(osv.osv): def Project(): title = "Project" start = datetime.strftime(datetime.strptime(start_date, "%Y-%m-%d"), "%Y-%m-%d %H:%M") - resource = reduce(operator.or_, resources) + try: + resource = reduce(operator.or_, resources) + except: + raise osv.except_osv(_('Error'), _('Should have Resources Allocation or Project Members!')) minimum_time_unit = 1 if calendar_id: # If project has working calendar working_days = resource_pool.compute_working_calendar(cr, uid, calendar_id, context=context) -- cgit v1.2.3 From 71a3990a041696c4003b03a7e072cb50185b15ef Mon Sep 17 00:00:00 2001 From: "rpa (Open ERP)" Date: Mon, 27 Sep 2010 19:14:03 +0530 Subject: [FIX]: Fixed pylint warnings bzr revid: rpa@tinyerp.com-20100927134403-d0xv04c0kkfkn724 --- addons/project_long_term/project_long_term.py | 30 ++++++++------------------- 1 file changed, 9 insertions(+), 21 deletions(-) (limited to 'addons/project_long_term/project_long_term.py') diff --git a/addons/project_long_term/project_long_term.py b/addons/project_long_term/project_long_term.py index 79837416d97..be0eb07bd47 100644 --- a/addons/project_long_term/project_long_term.py +++ b/addons/project_long_term/project_long_term.py @@ -19,8 +19,7 @@ # ############################################################################## -import time -from datetime import date, datetime, timedelta +from datetime import datetime from tools.translate import _ from osv import fields, osv from resource.faces import task as Task @@ -292,16 +291,11 @@ class project_phase(osv.osv): # 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 = resource_pool.compute_working_calendar(cr, uid, calendar_id, context=context) - vacation = tuple(resource_pool.compute_vacation(cr, uid, calendar_id)) - - def phase(): - effort = duration + resource_pool.compute_working_calendar(cr, uid, calendar_id, context=context) + resource_pool.compute_vacation(cr, uid, calendar_id) project = Task.BalancedProject(Project) s_date = project.phase.start.to_datetime() @@ -340,7 +334,6 @@ class project_phase(osv.osv): Schedule the tasks according to resource available and priority. """ task_pool = self.pool.get('project.task') - resource_pool = self.pool.get('resource.resource') if context is None: context = {} resources_list = self.generate_resources(cr, uid, ids, context=context) @@ -432,9 +425,7 @@ class project(osv.osv): """ if type(ids) in (long, int,): ids = [ids] - user_pool = self.pool.get('res.users') task_pool = self.pool.get('project.task') - resource_pool = self.pool.get('resource.resource') if context is None: context = {} @@ -493,7 +484,7 @@ class project_task(osv.osv): if context is None: context = {} user_pool = self.pool.get('res.users') - project_pool = self.pool.get('project.project') + resource_pool = self.pool.get('resource.resource') priority_dict = {'0': 1000, '1': 800, '2': 500, '3': 300, '4': 100} # Create dynamic no of tasks with the resource specified def create_tasks(task_number, eff, priorty=500, obj=False): @@ -501,28 +492,23 @@ class project_task(osv.osv): """ task is a dynamic method! """ - effort = eff if obj: resource = obj - priority = priorty task.__doc__ = "TaskNO%d" %task_number task.__name__ = "task%d" %task_number return task # Create a 'Faces' project with all the tasks and resources def Project(): - title = "Project" - start = datetime.strftime(datetime.strptime(start_date, "%Y-%m-%d"), "%Y-%m-%d %H:%M") try: resource = reduce(operator.or_, resources) except: raise osv.except_osv(_('Error'), _('Should have Resources Allocation or Project Members!')) - minimum_time_unit = 1 + if calendar_id: # If project has working calendar - working_days = resource_pool.compute_working_calendar(cr, uid, calendar_id, context=context) - vacation = tuple(resource_pool.compute_vacation(cr, uid, calendar_id, context=context)) + resource_pool.compute_working_calendar(cr, uid, calendar_id, context=context) + resource_pool.compute_vacation(cr, uid, calendar_id, context=context) # Dynamic creation of tasks - task_number = 0 for openobect_task in self.browse(cr, uid, ids, context=context): hours = str(openobect_task.planned_hours )+ 'H' if openobect_task.priority in priority_dict.keys(): @@ -556,5 +542,7 @@ class project_task(osv.osv): loop_no += 1 return True + project_task() + # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: -- cgit v1.2.3 From 91ace29a8aa15492de8857b4a2f9f0bba6de869e Mon Sep 17 00:00:00 2001 From: "rpa (Open ERP)" Date: Tue, 28 Sep 2010 10:37:11 +0530 Subject: [FIX]: project_long_term: Fixed pylint warnings bzr revid: rpa@tinyerp.com-20100928050711-x7czhl7jwku3s8kl --- addons/project_long_term/project_long_term.py | 4 ---- 1 file changed, 4 deletions(-) (limited to 'addons/project_long_term/project_long_term.py') diff --git a/addons/project_long_term/project_long_term.py b/addons/project_long_term/project_long_term.py index a535015d067..dba58e1789f 100644 --- a/addons/project_long_term/project_long_term.py +++ b/addons/project_long_term/project_long_term.py @@ -277,7 +277,6 @@ class project_phase(osv.osv): context = {} resource_pool = self.pool.get('resource.resource') uom_pool = self.pool.get('product.uom') - phase_resource = False if context is None: context = {} default_uom_id = self._get_default_uom_id(cr, uid) @@ -290,9 +289,6 @@ class project_phase(osv.osv): 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: -- cgit v1.2.3 From 4356a354e448f160f81ea1890ff93c16b0c56125 Mon Sep 17 00:00:00 2001 From: "Harry (OpenERP)" Date: Tue, 28 Sep 2010 19:22:54 +0530 Subject: [FIX] project_long_term: resolve regression on scheduling task bzr revid: hmo@tinyerp.com-20100928135254-2fux2qn5lozzs2nd --- addons/project_long_term/project_long_term.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'addons/project_long_term/project_long_term.py') diff --git a/addons/project_long_term/project_long_term.py b/addons/project_long_term/project_long_term.py index dba58e1789f..9f8f5bf8d56 100644 --- a/addons/project_long_term/project_long_term.py +++ b/addons/project_long_term/project_long_term.py @@ -291,6 +291,9 @@ class project_phase(osv.osv): 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 if calendar_id: working_days = resource_pool.compute_working_calendar(cr, uid, calendar_id, context=context) vacation = tuple(resource_pool.compute_vacation(cr, uid, calendar_id)) -- cgit v1.2.3 From 7f728b9e802834694b15b6c65235d2f6e108b57d Mon Sep 17 00:00:00 2001 From: gpa Date: Wed, 29 Sep 2010 20:37:02 +0530 Subject: added changes for project bzr revid: gpa@tinyerp.com-20100929150702-209fgqoz1am8n4cb --- addons/project_long_term/project_long_term.py | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) (limited to 'addons/project_long_term/project_long_term.py') diff --git a/addons/project_long_term/project_long_term.py b/addons/project_long_term/project_long_term.py index a535015d067..a831750c8f3 100644 --- a/addons/project_long_term/project_long_term.py +++ b/addons/project_long_term/project_long_term.py @@ -24,6 +24,7 @@ from tools.translate import _ from osv import fields, osv from resource.faces import task as Task import operator +from mx import DateTime class project_phase(osv.osv): _name = "project.phase" @@ -90,6 +91,19 @@ class project_phase(osv.osv): model_data_obj = self.pool.get('ir.model.data') model_data_id = model_data_obj._get_id(cr, uid, 'product', 'uom_hour') return model_data_obj.read(cr, uid, [model_data_id], ['res_id'])[0]['res_id'] + + def _compute(self, cr, uid, ids, context=None): + res = {} + if not ids: + return res + for phase in self.browse(cr, uid, ids, context=context): + tot = 0.0 + for task in phase.task_ids: + tot += task.planned_hours + res[phase.id] = { + 'total_hours' : tot + } + return res _columns = { 'name': fields.char("Name", size=64, required=True), @@ -108,7 +122,8 @@ class project_phase(osv.osv): 'responsible_id': fields.many2one('res.users', 'Responsible', states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}), 'state': fields.selection([('draft', 'Draft'), ('open', 'In Progress'), ('pending', 'Pending'), ('cancelled', 'Cancelled'), ('done', 'Done')], 'State', readonly=True, required=True, help='If the phase is created the state \'Draft\'.\n If the phase is started, the state becomes \'In Progress\'.\n If review is needed the phase is in \'Pending\' state.\ - \n If the phase is over, the states is set to \'Done\'.') + \n If the phase is over, the states is set to \'Done\'.'), + 'total_hours': fields.function(_compute, method=True, string='Total Hours'), } _defaults = { 'responsible_id': lambda obj,cr,uid,context: uid, @@ -130,6 +145,14 @@ class project_phase(osv.osv): project_id = project_obj.browse(cr, uid, project, context=context) result['date_start'] = project_id.date_start return {'value': result} + + def onchange_days(self, cr, uid, ids, project, context=None): + result = {} + for id in ids: + project_id = self.browse(cr, uid, id, context=context) + newdate = DateTime.strptime(project_id.date_start, '%Y-%m-%d') + DateTime.RelativeDateTime(days=project_id.duration or 0.0) + result['date_end'] = newdate.strftime('%Y-%m-%d') + return {'value': result} def _check_date_start(self, cr, uid, phase, date_end, context=None): if context is None: -- cgit v1.2.3 From 0994368ae173e6569ae31b09dda90ab78fa765bb Mon Sep 17 00:00:00 2001 From: "Harry (OpenERP)" Date: Thu, 30 Sep 2010 20:11:19 +0530 Subject: [IMP] project bzr revid: hmo@tinyerp.com-20100930144119-rqcos1j0xumt4h6t --- addons/project_long_term/project_long_term.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'addons/project_long_term/project_long_term.py') diff --git a/addons/project_long_term/project_long_term.py b/addons/project_long_term/project_long_term.py index d1df71630f8..2caf36766b0 100644 --- a/addons/project_long_term/project_long_term.py +++ b/addons/project_long_term/project_long_term.py @@ -109,8 +109,8 @@ class project_phase(osv.osv): 'name': fields.char("Name", size=64, required=True), 'date_start': fields.date('Start Date', help="Starting Date of the phase", states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}), 'date_end': fields.date('End Date', help="Ending Date of the phase", states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}), - 'constraint_date_start': fields.date('Start Date', help='force the phase to start after this date', states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}), - 'constraint_date_end': fields.date('End Date', help='force the phase to finish before this date', states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}), + 'constraint_date_start': fields.date('Minimum Start Date', help='force the phase to start after this date', states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}), + 'constraint_date_end': fields.date('Deadline', help='force the phase to finish before this date', states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}), 'project_id': fields.many2one('project.project', 'Project', required=True), 'next_phase_ids': fields.many2many('project.phase', 'project_phase_rel', 'prv_phase_id', 'next_phase_id', 'Next Phases', states={'cancelled':[('readonly',True)]}), 'previous_phase_ids': fields.many2many('project.phase', 'project_phase_rel', 'next_phase_id', 'prv_phase_id', 'Previous Phases', states={'cancelled':[('readonly',True)]}), @@ -394,8 +394,10 @@ class project_resource_allocation(osv.osv): _columns = { 'resource_id': fields.many2one('resource.resource', 'Resource', required=True), 'phase_id': fields.many2one('project.phase', 'Project Phase', ondelete='cascade', required=True), - 'phase_id_date_start': fields.related('phase_id', 'date_start', type='date', string='Starting Date of the phase'), - 'phase_id_date_end': fields.related('phase_id', 'date_end', type='date', string='Ending Date of the phase'), + 'project_id': fields.related('phase_id', 'project_id', type='many2one', relation="project.project", string='Project', store=True), + 'user_id': fields.related('resource_id', 'user_id', type='many2one', relation="res.users", string='User'), + 'date_start': fields.date('Start Date', help="Starting Date"), + 'date_end': fields.date('End Date', help="Ending Date"), 'useability': fields.float('Usability', help="Usability of this resource for this project phase in percentage (=50%)"), } _defaults = { -- cgit v1.2.3 From 622e39465b006df40574f02cf70d9e7008d10ac7 Mon Sep 17 00:00:00 2001 From: "Vianney,Anup(OpenERP)" <> Date: Wed, 6 Oct 2010 16:42:47 +0530 Subject: [FIX] project_long_term : _compute() method corrected and view of project phase corrected. lp bug: https://launchpad.net/bugs/655316 fixed bzr revid: ach@tinyerp.com-20101006111247-53h19u0qw8z97u4u --- addons/project_long_term/project_long_term.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'addons/project_long_term/project_long_term.py') diff --git a/addons/project_long_term/project_long_term.py b/addons/project_long_term/project_long_term.py index 2caf36766b0..0c31c485753 100644 --- a/addons/project_long_term/project_long_term.py +++ b/addons/project_long_term/project_long_term.py @@ -92,7 +92,7 @@ class project_phase(osv.osv): model_data_id = model_data_obj._get_id(cr, uid, 'product', 'uom_hour') return model_data_obj.read(cr, uid, [model_data_id], ['res_id'])[0]['res_id'] - def _compute(self, cr, uid, ids, context=None): + def _compute(self, cr, uid, ids,field_name, arg, context=None): res = {} if not ids: return res @@ -100,9 +100,7 @@ class project_phase(osv.osv): tot = 0.0 for task in phase.task_ids: tot += task.planned_hours - res[phase.id] = { - 'total_hours' : tot - } + res[phase.id] = tot return res _columns = { -- cgit v1.2.3 From 802541e5c78daac2cfc2a1273780193306ba5522 Mon Sep 17 00:00:00 2001 From: "ron@tinyerp.com" <> Date: Tue, 12 Oct 2010 18:51:51 +0530 Subject: [IMP] Project->Long Term Planning--Changes Demo data for user:Projects Phases--Useability should be availablity,rename group by user into responsible and default group on project,top area field arrange:Resources Allocations--change icon in group by Project and resource bzr revid: ron@tinyerp.com-20101012132151-39z9a08pwj71c7pt --- addons/project_long_term/project_long_term.py | 32 +++++++++++++-------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'addons/project_long_term/project_long_term.py') diff --git a/addons/project_long_term/project_long_term.py b/addons/project_long_term/project_long_term.py index 2caf36766b0..e843c6952a7 100644 --- a/addons/project_long_term/project_long_term.py +++ b/addons/project_long_term/project_long_term.py @@ -91,7 +91,7 @@ class project_phase(osv.osv): model_data_obj = self.pool.get('ir.model.data') model_data_id = model_data_obj._get_id(cr, uid, 'product', 'uom_hour') return model_data_obj.read(cr, uid, [model_data_id], ['res_id'])[0]['res_id'] - + def _compute(self, cr, uid, ids, context=None): res = {} if not ids: @@ -145,7 +145,7 @@ class project_phase(osv.osv): project_id = project_obj.browse(cr, uid, project, context=context) result['date_start'] = project_id.date_start return {'value': result} - + def onchange_days(self, cr, uid, ids, project, context=None): result = {} for id in ids: @@ -221,7 +221,7 @@ class project_phase(osv.osv): cal_id = resource_obj.browse(cr, uid, resource_id[0], context=context).calendar_id.id if cal_id: calendar_id = cal_id - + avg_hours = uom_obj._compute_qty(cr, uid, phase.product_uom.id, phase.duration, default_uom_id) # Change the date_start and date_end # for previous and next phases respectively based on valid condition @@ -234,7 +234,7 @@ class project_phase(osv.osv): if prv_phase.id == phase.id: continue self._check_date_start(cr, uid, prv_phase, dt_start, context=context) - + if vals.get('date_end', False) and vals['date_end'] > phase.date_end: dt_end = datetime.strptime(vals['date_end'], '%Y-%m-%d') work_times = resource_calendar_obj.interval_min_get(cr, uid, calendar_id, dt_end, avg_hours or 0.0, resource_id and resource_id[0] or False) @@ -244,7 +244,7 @@ class project_phase(osv.osv): if next_phase.id == phase.id: continue self._check_date_end(cr, uid, next_phase, dt_end, context=context) - + return res def copy(self, cr, uid, id, default=None, context=None): @@ -295,7 +295,7 @@ class project_phase(osv.osv): Schedule phase with the start date till all the next phases are completed. @param: start_dsate : start date for the phase @param: calendar_id : working calendar of the project - """ + """ if context is None: context = {} resource_pool = self.pool.get('resource.resource') @@ -306,7 +306,7 @@ class project_phase(osv.osv): for phase in self.browse(cr, uid, ids, context=context): if not phase.responsible_id: raise osv.except_osv(_('No responsible person assigned !'),_("You must assign a responsible person for phase '%s' !") % (phase.name,)) - + phase_resource_obj = resource_pool.generate_resources(cr, uid, [phase.responsible_id.id], calendar_id, context=context) avg_hours = uom_pool._compute_qty(cr, uid, phase.product_uom.id, phase.duration, default_uom_id) duration = str(avg_hours) + 'H' @@ -371,7 +371,7 @@ class project_phase(osv.osv): if not start_date and phase.project_id.date_start: start_date = phase.project_id.date_start if not start_date: - start_date = datetime.now().strftime("%Y-%m-%d") + start_date = datetime.now().strftime("%Y-%m-%d") resources = resources_list.get(phase.id, []) calendar_id = phase.project_id.resource_calendar_id.id task_ids = map(lambda x : x.id, (filter(lambda x : x.state in ['open', 'draft', 'pending'] , phase.task_ids))) @@ -398,7 +398,7 @@ class project_resource_allocation(osv.osv): 'user_id': fields.related('resource_id', 'user_id', type='many2one', relation="res.users", string='User'), 'date_start': fields.date('Start Date', help="Starting Date"), 'date_end': fields.date('End Date', help="Ending Date"), - 'useability': fields.float('Usability', help="Usability of this resource for this project phase in percentage (=50%)"), + 'useability': fields.float('Availability', help="Usability of this resource for this project phase in percentage (=50%)"), } _defaults = { 'useability': 100, @@ -460,19 +460,19 @@ class project(osv.osv): resource_pool = self.pool.get('resource.resource') if context is None: context = {} - + resources_list = self.generate_members(cr, uid, ids, context=context) return_msg = {} for project in self.browse(cr, uid, ids, context=context): start_date = project.date_start if not start_date: - start_date = datetime.now().strftime("%Y-%m-%d") + start_date = datetime.now().strftime("%Y-%m-%d") resources = resources_list.get(project.id, []) calendar_id = project.resource_calendar_id.id task_ids = task_pool.search(cr, uid, [('project_id', '=', project.id), ('state', 'in', ['draft', 'open', 'pending']) ]) - + if task_ids: task_pool.generate_schedule(cr, uid, task_ids, resources, calendar_id, start_date, context=context) @@ -483,7 +483,7 @@ class project(osv.osv): else: return_msg["warning"] = return_msg["warning"] + "\n" + warning_msg - return return_msg + return return_msg project() @@ -506,7 +506,7 @@ class project_task(osv.osv): _columns = { 'phase_id': fields.many2one('project.phase', 'Project Phase'), } - + def generate_schedule(self, cr, uid, ids, resources, calendar_id, start_date, context=None): """ Schedule the tasks according to resource available and priority. @@ -556,10 +556,10 @@ class project_task(osv.osv): if task_resource.__name__ == task_resource: real_resource = task_resource break - + task = create_tasks(task_number, hours, priorty, real_resource) task_number += 1 - + face_projects = Task.BalancedProject(Project) loop_no = 0 -- cgit v1.2.3 From c000866aa34de54bdc9f90c0ea9b82b540bba578 Mon Sep 17 00:00:00 2001 From: "Harry (OpenERP)" Date: Wed, 13 Oct 2010 17:55:19 +0530 Subject: [IMP] project: view improvement on delegrate wizard bzr revid: hmo@tinyerp.com-20101013122519-8f2gjt5lzxzgr23q --- addons/project_long_term/project_long_term.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'addons/project_long_term/project_long_term.py') diff --git a/addons/project_long_term/project_long_term.py b/addons/project_long_term/project_long_term.py index 903dbb3b17e..e6f65ba1fa9 100644 --- a/addons/project_long_term/project_long_term.py +++ b/addons/project_long_term/project_long_term.py @@ -396,7 +396,7 @@ class project_resource_allocation(osv.osv): 'user_id': fields.related('resource_id', 'user_id', type='many2one', relation="res.users", string='User'), 'date_start': fields.date('Start Date', help="Starting Date"), 'date_end': fields.date('End Date', help="Ending Date"), - 'useability': fields.float('Availability', help="Usability of this resource for this project phase in percentage (=50%)"), + 'useability': fields.float('Availability', help="Availability of this resource for this project phase in percentage (=50%)"), } _defaults = { 'useability': 100, -- cgit v1.2.3 From 10ecb719bd9f013765cbb69d1c36b9e093edadf2 Mon Sep 17 00:00:00 2001 From: "Harry (OpenERP)" Date: Thu, 14 Oct 2010 15:56:54 +0530 Subject: [IMP] project_long_term: improve gantt view bzr revid: hmo@tinyerp.com-20101014102654-e3wkawf339sc9ido --- addons/project_long_term/project_long_term.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'addons/project_long_term/project_long_term.py') diff --git a/addons/project_long_term/project_long_term.py b/addons/project_long_term/project_long_term.py index e6f65ba1fa9..d6d43f83c5d 100644 --- a/addons/project_long_term/project_long_term.py +++ b/addons/project_long_term/project_long_term.py @@ -297,6 +297,7 @@ class project_phase(osv.osv): if context is None: context = {} resource_pool = self.pool.get('resource.resource') + resource_allocation_pool = self.pool.get('project.resource.allocation') uom_pool = self.pool.get('product.uom') if context is None: context = {} @@ -344,7 +345,12 @@ class project_phase(osv.osv): 'date_start': start_date.strftime('%Y-%m-%d'), 'date_end': end_date.strftime('%Y-%m-%d') }, context=ctx) - + # 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 phase in phase.next_phase_ids: if phase.state in ['draft', 'open', 'pending']: -- cgit v1.2.3 From 3ce6888e424f45cbc6c6c0148cc7686057c81ac7 Mon Sep 17 00:00:00 2001 From: "Harry (OpenERP)" Date: Fri, 15 Oct 2010 21:17:01 +0530 Subject: [IMP] project_long_term: improve gantt view of resource allocation bzr revid: hmo@tinyerp.com-20101015154701-6fw3rbkjfpilagji --- addons/project_long_term/project_long_term.py | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'addons/project_long_term/project_long_term.py') diff --git a/addons/project_long_term/project_long_term.py b/addons/project_long_term/project_long_term.py index d6d43f83c5d..cfe4ff4f283 100644 --- a/addons/project_long_term/project_long_term.py +++ b/addons/project_long_term/project_long_term.py @@ -395,7 +395,18 @@ class project_resource_allocation(osv.osv): _name = 'project.resource.allocation' _description = 'Project Resource Allocation' _rec_name = 'resource_id' + + def get_name(self, cr, uid, ids, field_name, arg, context=None): + res = {} + for allocation in self.browse(cr, uid, ids, context=context): + name = allocation.resource_id.name + if allocation.user_id: + name = '%s' %(allocation.user_id.name) + name += ' (%s%%)' %(allocation.useability) + res[allocation.id] = name + return res _columns = { + 'name': fields.function(get_name, method=True, type='char', size=256), 'resource_id': fields.many2one('resource.resource', 'Resource', required=True), 'phase_id': fields.many2one('project.phase', 'Project Phase', ondelete='cascade', required=True), 'project_id': fields.related('phase_id', 'project_id', type='many2one', relation="project.project", string='Project', store=True), -- cgit v1.2.3 From db6ee299b9bda8561074d6b70f4327b3341ec96d Mon Sep 17 00:00:00 2001 From: fp Date: Sat, 16 Oct 2010 00:01:00 +0200 Subject: fix bzr revid: fp@fp-laptop-20101015220100-h9a9m5zkfnyfpx9e --- addons/project_long_term/project_long_term.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'addons/project_long_term/project_long_term.py') diff --git a/addons/project_long_term/project_long_term.py b/addons/project_long_term/project_long_term.py index cfe4ff4f283..faea0916906 100644 --- a/addons/project_long_term/project_long_term.py +++ b/addons/project_long_term/project_long_term.py @@ -399,9 +399,7 @@ class project_resource_allocation(osv.osv): def get_name(self, cr, uid, ids, field_name, arg, context=None): res = {} for allocation in self.browse(cr, uid, ids, context=context): - name = allocation.resource_id.name - if allocation.user_id: - name = '%s' %(allocation.user_id.name) + name = allocation.phase_id.name name += ' (%s%%)' %(allocation.useability) res[allocation.id] = name return res -- cgit v1.2.3