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))[:-1]
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")
254 phase_ids.append(phase.id)
257 todo_task_ids = task_pool.search(cr, uid, [('id', 'in', map(lambda x : x.id, phase.task_ids)),
258 ('state', 'in', ['draft', 'open', 'pending'])
260 for task in task_pool.browse(cr, uid, todo_task_ids, context=context):
261 s += task_pool.generate_task(cr, uid, task.id, parent=parent, flag=False, context=context)
264 task_ids.append(task.id)
267 # Recursive call till all the next phases scheduled
268 for next_phase in phase.next_phase_ids:
269 if next_phase.state in ['draft', 'open', 'pending']:
270 rf, rphase_ids = self.generate_phase(cr, uid, [next_phase.id], f = '', parent=phase, context=context)
272 phase_ids += rphase_ids
277 def schedule_tasks(self, cr, uid, ids, context=None):
279 Schedule tasks base on faces lib
283 if type(ids) in (long, int,):
285 task_pool = self.pool.get('project.task')
286 resource_pool = self.pool.get('resource.resource')
287 data_pool = self.pool.get('ir.model.data')
288 resource_allocation_pool = self.pool.get('project.resource.allocation')
290 for phase in self.browse(cr, uid, ids, context=context):
291 project = phase.project_id
292 calendar_id = project.resource_calendar_id and project.resource_calendar_id.id or False
293 start_date = project.date_start
294 #Creating resources using the member of the Project
295 u_ids = [i.id for i in project.members]
296 resource_objs = resource_pool.generate_resources(cr, uid, u_ids, calendar_id, context=context)
297 start_date = datetime.strftime((datetime.strptime(start_date, "%Y-%m-%d")), "%Y-%m-%d")
300 minimum_time_unit = 1
302 working_hours_per_day = 24
303 working_days_per_week = 7
304 working_days_per_month = 30
305 working_days_per_year = 365
309 working_hours_per_day = 8 #TODO: it should be come from calendars
310 working_days_per_week = 5
311 working_days_per_month = 20
312 working_days_per_year = 200
313 vacation = tuple(resource_pool.compute_vacation(cr, uid, calendar_id, context=context))
315 working_days = resource_pool.compute_working_calendar(cr, uid, calendar_id, context=context)
318 # Creating Resources for the Project
319 for key, vals in resource_objs.items():
321 class Resource_%s(Resource):
325 '''%(key, vals.get('name',False), vals.get('vacation', False), vals.get('efficiency', False))
327 # Create a new project for each phase
330 from resource.faces import Resource
333 minimum_time_unit = %s
334 working_hours_per_day = %s
335 working_days_per_week = %s
336 working_days_per_month = %s
337 working_days_per_year = %s
340 '''%(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 )
344 todo_task_ids = task_pool.search(cr, uid, [('id', 'in', map(lambda x : x.id, phase.task_ids)),
345 ('state', 'in', ['draft', 'open', 'pending'])
347 for task in task_pool.browse(cr, uid, todo_task_ids, context=context):
348 func_str += task_pool.generate_task(cr, uid, task.id, parent=parent, flag=True, context=context)
351 task_ids.append(task.id)
353 #Temp File to test the Code for the Allocation
354 # fn = '/home/hmo/Desktop/plt.py'
356 # fp.writelines(func_str)
359 # Allocating Memory for the required Project and Pahses and Resources
361 Phase = eval('Phase_%d' % phase.id)
362 phase = Task.BalancedProject(Phase)
364 for task_id in task_ids:
365 task = eval("phase.Task_%d" % task_id)
366 start_date = task.start.to_datetime()
367 end_date = task.end.to_datetime()
369 task_pool.write(cr, uid, [task_id], {
370 'date_start': start_date.strftime('%Y-%m-%d'),
371 'date_end': end_date.strftime('%Y-%m-%d')
376 class project_resource_allocation(osv.osv):
377 _name = 'project.resource.allocation'
378 _description = 'Project Resource Allocation'
379 _rec_name = 'resource_id'
381 def get_name(self, cr, uid, ids, field_name, arg, context=None):
383 for allocation in self.browse(cr, uid, ids, context=context):
384 name = allocation.phase_id.name
385 name += ' (%s%%)' %(allocation.useability)
386 res[allocation.id] = name
389 'name': fields.function(get_name, method=True, type='char', size=256),
390 'resource_id': fields.many2one('resource.resource', 'Resource', required=True),
391 'phase_id': fields.many2one('project.phase', 'Project Phase', ondelete='cascade', required=True),
392 'project_id': fields.related('phase_id', 'project_id', type='many2one', relation="project.project", string='Project', store=True),
393 'user_id': fields.related('resource_id', 'user_id', type='many2one', relation="res.users", string='User'),
394 'date_start': fields.date('Start Date', help="Starting Date"),
395 'date_end': fields.date('End Date', help="Ending Date"),
396 'useability': fields.float('Availability', help="Availability of this resource for this project phase in percentage (=50%)"),
402 project_resource_allocation()
404 class project(osv.osv):
405 _inherit = "project.project"
407 'phase_ids': fields.one2many('project.phase', 'project_id', "Project Phases"),
408 'resource_calendar_id': fields.many2one('resource.calendar', 'Working Time', help="Timetable working hours to adjust the gantt diagram report", states={'close':[('readonly',True)]} ),
410 def generate_members(self, cr, uid, ids, context=None):
412 Return a list of Resource Class objects for the resources allocated to the phase.
415 resource_pool = self.pool.get('resource.resource')
416 for project in self.browse(cr, uid, ids, context=context):
417 user_ids = map(lambda x:x.id, project.members)
418 calendar_id = project.resource_calendar_id and project.resource_calendar_id.id or False
419 resource_objs = resource_pool.generate_resources(cr, uid, user_ids, calendar_id, context=context)
420 res[project.id] = resource_objs
423 def schedule_phases(self, cr, uid, ids, context=None):
425 Schedule phase base on faces lib
429 if type(ids) in (long, int,):
431 phase_pool = self.pool.get('project.phase')
432 task_pool = self.pool.get('project.task')
433 resource_pool = self.pool.get('resource.resource')
434 data_pool = self.pool.get('ir.model.data')
435 resource_allocation_pool = self.pool.get('project.resource.allocation')
436 uom_pool = self.pool.get('product.uom')
437 data_model, day_uom_id = data_pool.get_object_reference(cr, uid, 'product', 'uom_day')
439 for project in self.browse(cr, uid, ids, context=context):
440 root_phase_ids = phase_pool.search(cr, uid, [('project_id', '=', project.id),
441 ('state', 'in', ['draft', 'open', 'pending']),
442 ('previous_phase_ids', '=', False)
444 calendar_id = project.resource_calendar_id and project.resource_calendar_id.id or False
445 start_date = project.date_start
447 # start_date = datetime.strftime((datetime.strptime(start_date, "%Y-%m-%d")), "%Y-%m-%d")
448 #Creating resources using the member of the Project
449 u_ids = [i.id for i in project.members]
450 resource_objs = resource_pool.generate_resources(cr, uid, u_ids, calendar_id, context=context)
453 minimum_time_unit = 1
455 working_hours_per_day = 24
456 working_days_per_week = 7
457 working_days_per_month = 30
458 working_days_per_year = 365
462 working_hours_per_day = 8 #TODO: it should be come from calendars
463 working_days_per_week = 5
464 working_days_per_month = 20
465 working_days_per_year = 200
466 vacation = tuple(resource_pool.compute_vacation(cr, uid, calendar_id, context=context))
468 working_days = resource_pool.compute_working_calendar(cr, uid, calendar_id, context=context)
471 # Creating Resources for the Project
472 for key, vals in resource_objs.items():
474 class Resource_%s(Resource):
478 '''%(key, vals.get('name',False), vals.get('vacation', False), vals.get('efficiency', False))
480 # Create a new project for each phase
483 from resource.faces import Resource
486 minimum_time_unit = %s
487 working_hours_per_day = %s
488 working_days_per_week = %s
489 working_days_per_month = %s
490 working_days_per_year = %s
493 '''%(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 )
496 for root_phase in phase_pool.browse(cr, uid, root_phase_ids, context=context):
497 phases, child_phase_ids = phase_pool.generate_phase(cr, uid, [root_phase.id], '', context=context)
499 phase_ids += child_phase_ids
500 #Temp File to test the Code for the Allocation
501 fn = '/home/tiny/Desktop/plt.py'
503 fp.writelines(func_str)
506 # Allocating Memory for the required Project and Pahses and Resources
508 Project = eval('Project_%d' % project.id)
509 project = Task.BalancedProject(Project)
511 for phase_id in phase_ids:
512 act_phase = phase_pool.browse(cr, uid, phase_id, context=context)
513 print "============",act_phase
514 phase = eval("project.Phase_%d" % phase_id)
515 start_date = phase.start.to_datetime()
516 end_date = phase.end.to_datetime()
517 if act_phase.task_ids:
518 for task in act_phase.task_ids:
520 #Getting values of the Tasks
521 temp = eval("phase.Task_%s"%task.id)
522 vals.update({'date_start' : temp.start.strftime('%Y-%m-%d %H:%M:%S')})
523 # vals.update({'date_end' : temp.end.strftime('%Y-%m-%d %H:%M:%S')})
524 vals.update({'planned_hours' : str(temp._Task__calc_duration().strftime('%H.%M'))})
525 vals.update({'date_deadline' : str(temp._Task__calc_end().strftime('%Y-%m-%d %H:%M:%S'))})
526 task_pool.write(cr, uid, task.id, vals, context=context)
527 print ">>>>>",dir(temp)
528 print ">>>><<<<<<<<<<<<<<<<>",temp.booked_resource
530 # Recalculate date_start and date_end
531 # according to constraints on date start and date end on phase
533 #if phase.constraint_date_start and str(s_date) < phase.constraint_date_start:
534 # start_date = datetime.strptime(phase.constraint_date_start, '%Y-%m-%d')
536 # start_date = s_date
537 #if phase.constraint_date_end and str(e_date) > phase.constraint_date_end:
538 # end_date= datetime.strptime(phase.constraint_date_end, '%Y-%m-%d')
539 # date_start = phase.constraint_date_end
542 # date_start = end_date
544 # Write the calculated dates back
545 #ctx = context.copy()
546 #ctx.update({'scheduler': True})
547 phase_pool.write(cr, uid, [phase_id], {
548 'date_start': start_date.strftime('%Y-%m-%d'),
549 'date_end': end_date.strftime('%Y-%m-%d')
553 def schedule_tasks(self, cr, uid, ids, context=None):
555 Schedule task base on faces lib
559 if type(ids) in (long, int,):
561 task_pool = self.pool.get('project.task')
562 resource_pool = self.pool.get('resource.resource')
563 data_pool = self.pool.get('ir.model.data')
564 resource_allocation_pool = self.pool.get('project.resource.allocation')
565 uom_pool = self.pool.get('product.uom')
566 data_model, day_uom_id = data_pool.get_object_reference(cr, uid, 'product', 'uom_day')
568 for project in self.browse(cr, uid, ids, context=context):
569 calendar_id = project.resource_calendar_id and project.resource_calendar_id.id or False
570 start_date = project.date_start
571 #Creating resources using the member of the Project
572 u_ids = [i.id for i in project.members]
573 resource_objs = resource_pool.generate_resources(cr, uid, u_ids, calendar_id, context=context)
574 start_date = datetime.strftime((datetime.strptime(start_date, "%Y-%m-%d")), "%Y-%m-%d")
577 minimum_time_unit = 1
579 working_hours_per_day = 24
580 working_days_per_week = 7
581 working_days_per_month = 30
582 working_days_per_year = 365
586 working_hours_per_day = 8 #TODO: it should be come from calendars
587 working_days_per_week = 5
588 working_days_per_month = 20
589 working_days_per_year = 200
590 vacation = tuple(resource_pool.compute_vacation(cr, uid, calendar_id, context=context))
592 working_days = resource_pool.compute_working_calendar(cr, uid, calendar_id, context=context)
595 # Creating Resources for the Project
596 for key, vals in resource_objs.items():
598 class Resource_%s(Resource):
602 '''%(key, vals.get('name',False), vals.get('vacation', False), vals.get('efficiency', False))
604 # Create a new project for each phase
607 from resource.faces import Resource
610 minimum_time_unit = %s
611 working_hours_per_day = %s
612 working_days_per_week = %s
613 working_days_per_month = %s
614 working_days_per_year = %s
617 '''%(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 )
621 todo_task_ids = task_pool.search(cr, uid, [('project_id', '=', project.id),
622 ('state', 'in', ['draft', 'open', 'pending'])
624 for task in task_pool.browse(cr, uid, todo_task_ids, context=context):
625 func_str += task_pool.generate_task(cr, uid, task.id, parent=parent, flag=True,context=context)
628 task_ids.append(task.id)
630 #Temp File to test the Code for the Allocation
631 fn = '/home/tiny/Desktop/plt_1.py'
633 fp.writelines(func_str)
636 # Allocating Memory for the required Project and Pahses and Resources
638 Project = eval('Project_%d' % project.id)
639 project = Task.BalancedProject(Project)
640 for task_id in task_ids:
641 task = eval("project.Task_%d" % task_id)
642 start_date = task.start.to_datetime()
643 end_date = task.end.to_datetime()
645 task_pool.write(cr, uid, [task_id], {
646 'date_start': start_date.strftime('%Y-%m-%d'),
647 'date_end': end_date.strftime('%Y-%m-%d')
653 class resource_resource(osv.osv):
654 _inherit = "resource.resource"
655 def search(self, cr, uid, args, offset=0, limit=None, order=None, context=None, count=False):
658 if context.get('project_id',False):
659 project_pool = self.pool.get('project.project')
660 project_rec = project_pool.browse(cr, uid, context['project_id'], context=context)
661 user_ids = [user_id.id for user_id in project_rec.members]
662 args.append(('user_id','in',user_ids))
663 return super(resource_resource, self).search(cr, uid, args, offset, limit, order, context, count)
667 class project_task(osv.osv):
668 _inherit = "project.task"
670 'phase_id': fields.many2one('project.phase', 'Project Phase'),
676 def generate_task(self, cr, uid, task_id, parent=False, flag=False, context=None):
679 resource_pool = self.pool.get('resource.resource')
680 resource_allocation_pool = self.pool.get('project.resource.allocation')
681 task = self.browse(cr, uid, task_id, context=context)
682 duration = str(task.planned_hours )+ 'H'
685 resource_ids = self.search(cr, uid, [('user_id', '=', task.user_id.id),('resource_type','=','user')], context=context)
686 print "\n\n==========", task.user_id.name, resource_ids
687 if len(resource_ids):
688 resource = 'Resource_%s'%resource_ids[0]
689 # Phases Defination for the Project
696 '''%(task.id, task.name, duration, resource)
698 start = 'up.Task_%s.end' % (parent.id)
702 #start = datetime.strftime((datetime.strptime(start, "%Y-%m-%d")), "%Y-%m-%d")
709 '''%(task.id, task.name, duration, resource)
711 start = 'up.Task_%s.end' % (parent.id)
718 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: