1 # -*- coding: utf-8 -*-
2 ##############################################################################
4 # OpenERP, Open Source Management Solution
5 # Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
7 # This program is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU Affero General Public License as
9 # published by the Free Software Foundation, either version 3 of the
10 # License, or (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU Affero General Public License for more details.
17 # You should have received a copy of the GNU Affero General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20 ##############################################################################
22 from datetime import datetime, timedelta
23 from dateutil.relativedelta import relativedelta
24 from tools.translate import _
25 from osv import fields, osv
26 from resource.faces import task as Task
28 from new import classobj
32 class project_phase(osv.osv):
33 _name = "project.phase"
34 _description = "Project Phase"
36 def _check_recursion(self, cr, uid, ids, context=None):
40 data_phase = self.browse(cr, uid, ids[0], context=context)
41 prev_ids = data_phase.previous_phase_ids
42 next_ids = data_phase.next_phase_ids
43 # it should neither be in prev_ids nor in next_ids
44 if (data_phase in prev_ids) or (data_phase in next_ids):
46 ids = [id for id in prev_ids if id in next_ids]
47 # both prev_ids and next_ids must be unique
51 prev_ids = [rec.id for rec in prev_ids]
52 next_ids = [rec.id for rec in next_ids]
55 cr.execute('SELECT distinct prv_phase_id FROM project_phase_rel WHERE next_phase_id IN %s', (tuple(prev_ids),))
56 prv_phase_ids = filter(None, map(lambda x: x[0], cr.fetchall()))
57 if data_phase.id in prv_phase_ids:
59 ids = [id for id in prv_phase_ids if id in next_ids]
62 prev_ids = prv_phase_ids
65 cr.execute('SELECT distinct next_phase_id FROM project_phase_rel WHERE prv_phase_id IN %s', (tuple(next_ids),))
66 next_phase_ids = filter(None, map(lambda x: x[0], cr.fetchall()))
67 if data_phase.id in next_phase_ids:
69 ids = [id for id in next_phase_ids if id in prev_ids]
72 next_ids = next_phase_ids
75 def _check_dates(self, cr, uid, ids, context=None):
76 for phase in self.read(cr, uid, ids, ['date_start', 'date_end'], context=context):
77 if phase['date_start'] and phase['date_end'] and phase['date_start'] > phase['date_end']:
81 def _check_constraint_start(self, cr, uid, ids, context=None):
82 phase = self.read(cr, uid, ids[0], ['date_start', 'constraint_date_start'], context=context)
83 if phase['date_start'] and phase['constraint_date_start'] and phase['date_start'] < phase['constraint_date_start']:
87 def _check_constraint_end(self, cr, uid, ids, context=None):
88 phase = self.read(cr, uid, ids[0], ['date_end', 'constraint_date_end'], context=context)
89 if phase['date_end'] and phase['constraint_date_end'] and phase['date_end'] > phase['constraint_date_end']:
93 def _get_default_uom_id(self, cr, uid):
94 model_data_obj = self.pool.get('ir.model.data')
95 model_data_id = model_data_obj._get_id(cr, uid, 'product', 'uom_hour')
96 return model_data_obj.read(cr, uid, [model_data_id], ['res_id'])[0]['res_id']
98 def _compute(self, cr, uid, ids, field_name, arg, context=None):
102 for phase in self.browse(cr, uid, ids, context=context):
104 for task in phase.task_ids:
105 tot += task.planned_hours
110 'name': fields.char("Name", size=64, required=True),
111 'date_start': fields.date('Start Date', help="It's computed by the scheduler according the project date or the end date of the previous phase.", states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}),
112 'date_end': fields.date('End Date', help=" It's computed by the scheduler according to the start date and the duration.", states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}),
113 'constraint_date_start': fields.date('Minimum Start Date', help='force the phase to start after this date', states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}),
114 'constraint_date_end': fields.date('Deadline', help='force the phase to finish before this date', states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}),
115 'project_id': fields.many2one('project.project', 'Project', required=True),
116 'next_phase_ids': fields.many2many('project.phase', 'project_phase_rel', 'prv_phase_id', 'next_phase_id', 'Next Phases', states={'cancelled':[('readonly',True)]}),
117 'previous_phase_ids': fields.many2many('project.phase', 'project_phase_rel', 'next_phase_id', 'prv_phase_id', 'Previous Phases', states={'cancelled':[('readonly',True)]}),
118 'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of phases."),
119 'duration': fields.float('Duration', required=True, help="By default in days", states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}),
120 '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)]}),
121 'task_ids': fields.one2many('project.task', 'phase_id', "Project Tasks", states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}),
122 'resource_ids': fields.one2many('project.resource.allocation', 'phase_id', "Project Resources",states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}),
123 'responsible_id': fields.many2one('res.users', 'Responsible', states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}),
124 'state': fields.selection([('draft', 'Draft'), ('open', 'In Progress'), ('pending', 'Pending'), ('cancelled', 'Cancelled'), ('done', 'Done')], 'State', readonly=True, required=True,
125 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.\
126 \n If the phase is over, the states is set to \'Done\'.'),
127 'total_hours': fields.function(_compute, method=True, string='Total Hours'),
130 'responsible_id': lambda obj,cr,uid,context: uid,
133 'product_uom': lambda self,cr,uid,c: self.pool.get('product.uom').search(cr, uid, [('name', '=', _('Day'))], context=c)[0]
135 _order = "project_id, date_start, sequence, name"
137 (_check_recursion,'Loops in phases not allowed',['next_phase_ids', 'previous_phase_ids']),
138 (_check_dates, 'Phase start-date must be lower than phase end-date.', ['date_start', 'date_end']),
141 def onchange_project(self, cr, uid, ids, project, context=None):
143 result['date_start'] = False
144 project_obj = self.pool.get('project.project')
146 project_id = project_obj.browse(cr, uid, project, context=context)
147 result['date_start'] = project_id.date_start
148 return {'value': result}
151 def _check_date_start(self, cr, uid, phase, date_end, context=None):
153 Check And Compute date_end of phase if change in date_start < older time.
155 uom_obj = self.pool.get('product.uom')
156 resource_obj = self.pool.get('resource.resource')
157 cal_obj = self.pool.get('resource.calendar')
158 calendar_id = phase.project_id.resource_calendar_id and phase.project_id.resource_calendar_id.id or False
159 resource_id = resource_obj.search(cr, uid, [('user_id', '=', phase.responsible_id.id)])
161 res = resource_obj.read(cr, uid, resource_id, ['calendar_id'], context=context)[0]
162 cal_id = res.get('calendar_id', False) and res.get('calendar_id')[0] or False
165 default_uom_id = self._get_default_uom_id(cr, uid)
166 avg_hours = uom_obj._compute_qty(cr, uid, phase.product_uom.id, phase.duration, default_uom_id)
167 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)
168 dt_start = work_times[0][0].strftime('%Y-%m-%d')
169 self.write(cr, uid, [phase.id], {'date_start': dt_start, 'date_end': date_end.strftime('%Y-%m-%d')}, context=context)
171 def _check_date_end(self, cr, uid, phase, date_start, context=None):
173 Check And Compute date_end of phase if change in date_end > older time.
175 uom_obj = self.pool.get('product.uom')
176 resource_obj = self.pool.get('resource.resource')
177 cal_obj = self.pool.get('resource.calendar')
178 calendar_id = phase.project_id.resource_calendar_id and phase.project_id.resource_calendar_id.id or False
179 resource_id = resource_obj.search(cr, uid, [('user_id', '=', phase.responsible_id.id)], context=context)
181 res = resource_obj.read(cr, uid, resource_id, ['calendar_id'], context=context)[0]
182 cal_id = res.get('calendar_id', False) and res.get('calendar_id')[0] or False
185 default_uom_id = self._get_default_uom_id(cr, uid)
186 avg_hours = uom_obj._compute_qty(cr, uid, phase.product_uom.id, phase.duration, default_uom_id)
187 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)
188 dt_end = work_times[-1][1].strftime('%Y-%m-%d')
189 self.write(cr, uid, [phase.id], {'date_start': date_start.strftime('%Y-%m-%d'), 'date_end': dt_end}, context=context)
191 def copy(self, cr, uid, id, default=None, context=None):
194 if not default.get('name', False):
195 default['name'] = self.browse(cr, uid, id, context=context).name + _(' (copy)')
196 return super(project_phase, self).copy(cr, uid, id, default, context)
198 def set_draft(self, cr, uid, ids, *args):
199 self.write(cr, uid, ids, {'state': 'draft'})
202 def set_open(self, cr, uid, ids, *args):
203 self.write(cr, uid, ids, {'state': 'open'})
206 def set_pending(self, cr, uid, ids, *args):
207 self.write(cr, uid, ids, {'state': 'pending'})
210 def set_cancel(self, cr, uid, ids, *args):
211 self.write(cr, uid, ids, {'state': 'cancelled'})
214 def set_done(self, cr, uid, ids, *args):
215 self.write(cr, uid, ids, {'state': 'done'})
218 def generate_phase(self, cr, uid, ids, f, parent=False, context=None):
222 resource_pool = self.pool.get('resource.resource')
223 data_pool = self.pool.get('ir.model.data')
224 resource_allocation_pool = self.pool.get('project.resource.allocation')
225 uom_pool = self.pool.get('product.uom')
226 task_pool = self.pool.get('project.task')
227 data_model, day_uom_id = data_pool.get_object_reference(cr, uid, 'product', 'uom_day')
228 for phase in self.browse(cr, uid, ids, context=context):
229 avg_days = uom_pool._compute_qty(cr, uid, phase.product_uom.id, phase.duration, day_uom_id)
230 duration = str(avg_days) + 'd'
231 # Create a new project for each phase
232 str_resource = ('%s | '*len(phase.resource_ids))[:-2]
233 str_vals = str_resource % tuple(map(lambda x: 'Resource_%s'%x.resource_id.id, phase.resource_ids))
234 # Phases Defination for the Project
240 '''%(phase.id, phase.name, duration, str_vals or False)
242 start = 'up.Phase_%s.end' % (parent.id)
247 start = phase.project_id.date_start or phase.date_start
251 #start = datetime.strftime((datetime.strptime(start, "%Y-%m-%d")), "%Y-%m-%d")
253 phase_ids.append(phase.id)
256 todo_task_ids = task_pool.search(cr, uid, [('id', 'in', map(lambda x : x.id, phase.task_ids)),
257 ('state', 'in', ['draft', 'open', 'pending'])
259 for task in task_pool.browse(cr, uid, todo_task_ids, context=context):
260 s += task_pool.generate_task(cr, uid, task.id, parent=parent, flag=False, context=context)
263 task_ids.append(task.id)
266 # Recursive call till all the next phases scheduled
267 for next_phase in phase.next_phase_ids:
268 if next_phase.state in ['draft', 'open', 'pending']:
269 rf, rphase_ids = self.generate_phase(cr, uid, [next_phase.id], f = '', parent=phase, context=context)
271 phase_ids += rphase_ids
276 def schedule_tasks(self, cr, uid, ids, context=None):
278 Schedule tasks base on faces lib
282 if type(ids) in (long, int,):
284 task_pool = self.pool.get('project.task')
285 resource_pool = self.pool.get('resource.resource')
286 data_pool = self.pool.get('ir.model.data')
287 resource_allocation_pool = self.pool.get('project.resource.allocation')
289 for phase in self.browse(cr, uid, ids, context=context):
290 project = phase.project_id
291 calendar_id = project.resource_calendar_id and project.resource_calendar_id.id or False
292 start_date = project.date_start
293 #Creating resources using the member of the Project
294 u_ids = [i.id for i in project.members]
295 resource_objs = resource_pool.generate_resources(cr, uid, u_ids, calendar_id, context=context)
296 start_date = datetime.strftime((datetime.strptime(start_date, "%Y-%m-%d")), "%Y-%m-%d")
299 minimum_time_unit = 1
301 working_hours_per_day = 24
302 working_days_per_week = 7
303 working_days_per_month = 30
304 working_days_per_year = 365
308 working_hours_per_day = 8 #TODO: it should be come from calendars
309 working_days_per_week = 5
310 working_days_per_month = 20
311 working_days_per_year = 200
312 vacation = tuple(resource_pool.compute_vacation(cr, uid, calendar_id, context=context))
314 working_days = resource_pool.compute_working_calendar(cr, uid, calendar_id, context=context)
317 # Creating Resources for the Project
318 for key, vals in resource_objs.items():
320 class Resource_%s(Resource):
324 '''%(key, vals.get('name',False), vals.get('vacation', False), vals.get('efficiency', False))
326 # Create a new project for each phase
329 from resource.faces import Resource
332 minimum_time_unit = %s
333 working_hours_per_day = %s
334 working_days_per_week = %s
335 working_days_per_month = %s
336 working_days_per_year = %s
339 '''%(phase.id, phase.name, start, minimum_time_unit, working_hours_per_day, working_days_per_week, working_days_per_month, working_days_per_year, vacation, working_days )
343 todo_task_ids = task_pool.search(cr, uid, [('id', 'in', map(lambda x : x.id, phase.task_ids)),
344 ('state', 'in', ['draft', 'open', 'pending'])
346 for task in task_pool.browse(cr, uid, todo_task_ids, context=context):
347 func_str += task_pool.generate_task(cr, uid, task.id, parent=parent, flag=True, context=context)
350 task_ids.append(task.id)
352 #Temp File to test the Code for the Allocation
353 # fn = '/home/hmo/Desktop/plt.py'
355 # fp.writelines(func_str)
358 # Allocating Memory for the required Project and Pahses and Resources
360 Phase = eval('Phase_%d' % phase.id)
361 phase = Task.BalancedProject(Phase)
363 for task_id in task_ids:
364 task = eval("phase.Task_%d" % task_id)
365 start_date = task.start.to_datetime()
366 end_date = task.end.to_datetime()
368 task_pool.write(cr, uid, [task_id], {
369 'date_start': start_date.strftime('%Y-%m-%d'),
370 'date_end': end_date.strftime('%Y-%m-%d')
375 class project_resource_allocation(osv.osv):
376 _name = 'project.resource.allocation'
377 _description = 'Project Resource Allocation'
378 _rec_name = 'resource_id'
380 def get_name(self, cr, uid, ids, field_name, arg, context=None):
382 for allocation in self.browse(cr, uid, ids, context=context):
383 name = allocation.phase_id.name
384 name += ' (%s%%)' %(allocation.useability)
385 res[allocation.id] = name
388 'name': fields.function(get_name, method=True, type='char', size=256),
389 'resource_id': fields.many2one('resource.resource', 'Resource', required=True),
390 'phase_id': fields.many2one('project.phase', 'Project Phase', ondelete='cascade', required=True),
391 'project_id': fields.related('phase_id', 'project_id', type='many2one', relation="project.project", string='Project', store=True),
392 'user_id': fields.related('resource_id', 'user_id', type='many2one', relation="res.users", string='User'),
393 'date_start': fields.date('Start Date', help="Starting Date"),
394 'date_end': fields.date('End Date', help="Ending Date"),
395 'useability': fields.float('Availability', help="Availability of this resource for this project phase in percentage (=50%)"),
401 project_resource_allocation()
403 class project(osv.osv):
404 _inherit = "project.project"
406 'phase_ids': fields.one2many('project.phase', 'project_id', "Project Phases"),
407 'resource_calendar_id': fields.many2one('resource.calendar', 'Working Time', help="Timetable working hours to adjust the gantt diagram report", states={'close':[('readonly',True)]} ),
409 def generate_members(self, cr, uid, ids, context=None):
411 Return a list of Resource Class objects for the resources allocated to the phase.
414 resource_pool = self.pool.get('resource.resource')
415 for project in self.browse(cr, uid, ids, context=context):
416 user_ids = map(lambda x:x.id, project.members)
417 calendar_id = project.resource_calendar_id and project.resource_calendar_id.id or False
418 resource_objs = resource_pool.generate_resources(cr, uid, user_ids, calendar_id, context=context)
419 res[project.id] = resource_objs
422 def schedule_phases(self, cr, uid, ids, context=None):
424 Schedule phase base on faces lib
428 if type(ids) in (long, int,):
430 phase_pool = self.pool.get('project.phase')
431 task_pool = self.pool.get('project.task')
432 resource_pool = self.pool.get('resource.resource')
433 data_pool = self.pool.get('ir.model.data')
434 resource_allocation_pool = self.pool.get('project.resource.allocation')
435 uom_pool = self.pool.get('product.uom')
436 data_model, day_uom_id = data_pool.get_object_reference(cr, uid, 'product', 'uom_day')
438 for project in self.browse(cr, uid, ids, context=context):
439 root_phase_ids = phase_pool.search(cr, uid, [('project_id', '=', project.id),
440 ('state', 'in', ['draft', 'open', 'pending']),
441 ('previous_phase_ids', '=', False)
443 calendar_id = project.resource_calendar_id and project.resource_calendar_id.id or False
444 start_date = project.date_start
446 # start_date = datetime.strftime((datetime.strptime(start_date, "%Y-%m-%d")), "%Y-%m-%d")
447 #Creating resources using the member of the Project
448 u_ids = [i.id for i in project.members]
449 resource_objs = resource_pool.generate_resources(cr, uid, u_ids, calendar_id, context=context)
452 minimum_time_unit = 1
454 working_hours_per_day = 24
455 working_days_per_week = 7
456 working_days_per_month = 30
457 working_days_per_year = 365
461 working_hours_per_day = 8 #TODO: it should be come from calendars
462 working_days_per_week = 5
463 working_days_per_month = 20
464 working_days_per_year = 200
465 vacation = tuple(resource_pool.compute_vacation(cr, uid, calendar_id, context=context))
467 working_days = resource_pool.compute_working_calendar(cr, uid, calendar_id, context=context)
470 # Creating Resources for the Project
471 for key, vals in resource_objs.items():
473 class Resource_%s(Resource):
477 '''%(key, vals.get('name',False), vals.get('vacation', False), vals.get('efficiency', False))
479 # Create a new project for each phase
482 from resource.faces import Resource
485 minimum_time_unit = %s
486 working_hours_per_day = %s
487 working_days_per_week = %s
488 working_days_per_month = %s
489 working_days_per_year = %s
492 '''%(project.id, project.name, start, minimum_time_unit, working_hours_per_day, working_days_per_week, working_days_per_month, working_days_per_year, vacation, working_days )
495 for root_phase in phase_pool.browse(cr, uid, root_phase_ids, context=context):
496 phases, child_phase_ids = phase_pool.generate_phase(cr, uid, [root_phase.id], '', context=context)
498 phase_ids += child_phase_ids
499 #Temp File to test the Code for the Allocation
500 fn = '/home/tiny/Desktop/plt.py'
502 fp.writelines(func_str)
505 # Allocating Memory for the required Project and Pahses and Resources
507 Project = eval('Project_%d' % project.id)
508 project = Task.BalancedProject(Project)
510 for phase_id in phase_ids:
511 act_phase = phase_pool.browse(cr, uid, phase_id, context=context)
512 phase = eval("project.Phase_%d" % phase_id)
514 start_date = phase.start.to_datetime()
515 end_date = phase.end.to_datetime()
516 if act_phase.task_ids:
517 for task in act_phase.task_ids:
519 #Getting values of the Tasks
520 temp = eval("phase.Task_%s"%task.id)
521 vals.update({'date_start' : temp.start.strftime('%Y-%m-%d %H:%M:%S')})
522 # vals.update({'date_end' : temp.end.strftime('%Y-%m-%d %H:%M:%S')})
523 vals.update({'planned_hours' : str(temp._Task__calc_duration().strftime('%H.%M'))})
524 vals.update({'date_deadline' : str(temp._Task__calc_end().strftime('%Y-%m-%d %H:%M:%S'))})
525 task_pool.write(cr, uid, task.id, vals, context=context)
528 print "i**********", i,eval("project.Phase_%d.Task_%s.%s"%(phase_id,task.id,i))
529 print ">>>><<<<<<<<<<<<<<<<>",temp.booked_resource
531 # Recalculate date_start and date_end
532 # according to constraints on date start and date end on phase
534 #if phase.constraint_date_start and str(s_date) < phase.constraint_date_start:
535 # start_date = datetime.strptime(phase.constraint_date_start, '%Y-%m-%d')
537 # start_date = s_date
538 #if phase.constraint_date_end and str(e_date) > phase.constraint_date_end:
539 # end_date= datetime.strptime(phase.constraint_date_end, '%Y-%m-%d')
540 # date_start = phase.constraint_date_end
543 # date_start = end_date
545 # Write the calculated dates back
546 #ctx = context.copy()
547 #ctx.update({'scheduler': True})
548 phase_pool.write(cr, uid, [phase_id], {
549 'date_start': start_date.strftime('%Y-%m-%d'),
550 'date_end': end_date.strftime('%Y-%m-%d')
554 def schedule_tasks(self, cr, uid, ids, context=None):
556 Schedule task base on faces lib
560 if type(ids) in (long, int,):
562 task_pool = self.pool.get('project.task')
563 resource_pool = self.pool.get('resource.resource')
564 data_pool = self.pool.get('ir.model.data')
565 resource_allocation_pool = self.pool.get('project.resource.allocation')
566 uom_pool = self.pool.get('product.uom')
567 data_model, day_uom_id = data_pool.get_object_reference(cr, uid, 'product', 'uom_day')
569 for project in self.browse(cr, uid, ids, context=context):
570 calendar_id = project.resource_calendar_id and project.resource_calendar_id.id or False
571 start_date = project.date_start
572 #Creating resources using the member of the Project
573 u_ids = [i.id for i in project.members]
574 resource_objs = resource_pool.generate_resources(cr, uid, u_ids, calendar_id, context=context)
575 start_date = datetime.strftime((datetime.strptime(start_date, "%Y-%m-%d")), "%Y-%m-%d")
578 minimum_time_unit = 1
580 working_hours_per_day = 24
581 working_days_per_week = 7
582 working_days_per_month = 30
583 working_days_per_year = 365
587 working_hours_per_day = 8 #TODO: it should be come from calendars
588 working_days_per_week = 5
589 working_days_per_month = 20
590 working_days_per_year = 200
591 vacation = tuple(resource_pool.compute_vacation(cr, uid, calendar_id, context=context))
593 working_days = resource_pool.compute_working_calendar(cr, uid, calendar_id, context=context)
596 # Creating Resources for the Project
597 for key, vals in resource_objs.items():
599 class Resource_%s(Resource):
603 '''%(key, vals.get('name',False), vals.get('vacation', False), vals.get('efficiency', False))
605 # Create a new project for each phase
608 from resource.faces import Resource
611 minimum_time_unit = %s
612 working_hours_per_day = %s
613 working_days_per_week = %s
614 working_days_per_month = %s
615 working_days_per_year = %s
618 '''%(project.id, project.name, start, minimum_time_unit, working_hours_per_day, working_days_per_week, working_days_per_month, working_days_per_year, vacation, working_days )
622 todo_task_ids = task_pool.search(cr, uid, [('project_id', '=', project.id),
623 ('state', 'in', ['draft', 'open', 'pending'])
625 for task in task_pool.browse(cr, uid, todo_task_ids, context=context):
626 func_str += task_pool.generate_task(cr, uid, task.id, parent=parent, flag=True,context=context)
629 task_ids.append(task.id)
631 #Temp File to test the Code for the Allocation
632 # fn = '/home/hmo/Desktop/plt.py'
634 # fp.writelines(func_str)
638 # Allocating Memory for the required Project and Pahses and Resources
640 Project = eval('Project_%d' % project.id)
641 project = Task.BalancedProject(Project)
642 for task_id in task_ids:
643 task = eval("project.Task_%d" % task_id)
644 start_date = task.start.to_datetime()
645 end_date = task.end.to_datetime()
647 task_pool.write(cr, uid, [task_id], {
648 'date_start': start_date.strftime('%Y-%m-%d'),
649 'date_end': end_date.strftime('%Y-%m-%d')
655 class resource_resource(osv.osv):
656 _inherit = "resource.resource"
657 def search(self, cr, uid, args, offset=0, limit=None, order=None, context=None, count=False):
660 if context.get('project_id',False):
661 project_pool = self.pool.get('project.project')
662 project_rec = project_pool.browse(cr, uid, context['project_id'], context=context)
663 user_ids = [user_id.id for user_id in project_rec.members]
664 args.append(('user_id','in',user_ids))
665 return super(resource_resource, self).search(cr, uid, args, offset, limit, order, context, count)
669 class project_task(osv.osv):
670 _inherit = "project.task"
672 'phase_id': fields.many2one('project.phase', 'Project Phase'),
678 def generate_task(self, cr, uid, task_id, parent=False, flag=False, context=None):
681 resource_pool = self.pool.get('resource.resource')
682 resource_allocation_pool = self.pool.get('project.resource.allocation')
683 task = self.browse(cr, uid, task_id, context=context)
684 duration = str(task.planned_hours )+ 'H'
687 resource_ids = self.search(cr, uid, [('user_id', '=', task.user_id.id),('resource_type','=','user')], context=context)
688 if len(resource_ids):
689 resource = 'Resource_%s'%resource_ids[0]
690 # Phases Defination for the Project
697 '''%(task.id, task.name, duration, resource)
699 start = 'up.Task_%s.end' % (parent.id)
703 #start = datetime.strftime((datetime.strptime(start, "%Y-%m-%d")), "%Y-%m-%d")
710 '''%(task.id, task.name, duration, resource)
712 start = 'up.Task_%s.end' % (parent.id)
719 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: