[ADD]:fields:responsible_id,sequence on phase

bzr revid: rvo@tinyerp.co.in-20100225060127-163r7s9v40jo08xf
This commit is contained in:
Rvo (Open ERP)
2010-02-25 11:31:27 +05:30
parent eabe16de50
commit 04a579d34d
2 changed files with 71 additions and 105 deletions
+34 -93
View File
@@ -31,7 +31,6 @@ class project_phase(osv.osv):
_description = "Project Phase"
def _check_recursion(self,cr,uid,ids):
obj_self = self.browse(cr, uid, ids[0])
prev_ids = obj_self.previous_phase_ids
@@ -51,7 +50,7 @@ class project_phase(osv.osv):
#iter prev_ids
while prev_ids:
cr.execute('select distinct prv_phase_id from project_phase_previous_rel where phase_id in ('+','.join(map(str, prev_ids))+')')
cr.execute('select distinct next_phase_id from project_phase_rel where prv_phase_id in ('+','.join(map(str, prev_ids))+')')
prv_phase_ids = filter(None, map(lambda x: x[0], cr.fetchall()))
if obj_self.id in prv_phase_ids:
return False
@@ -62,7 +61,7 @@ class project_phase(osv.osv):
#iter next_ids
while next_ids:
cr.execute('select distinct next_phase_id from project_phase_next_rel where phase_id in ('+','.join(map(str, next_ids))+')')
cr.execute('select distinct prv_phase_id from project_phase_rel where next_phase_id in ('+','.join(map(str, next_ids))+')')
next_phase_ids = filter(None, map(lambda x: x[0], cr.fetchall()))
if obj_self.id in next_phase_ids:
return False
@@ -80,109 +79,51 @@ class project_phase(osv.osv):
'constraint_date_start': fields.datetime('Constraint Starting Date'),
'constraint_date_end': fields.datetime('Constraint End Date'),
'project_id': fields.many2one('project.project', 'Project', required=True),
'next_phase_ids': fields.many2many('project.phase', 'project_phase_next_rel', 'phase_id', 'next_phase_id', 'Next Phases'),
'previous_phase_ids': fields.many2many('project.phase', 'project_phase_previous_rel', 'phase_id', 'prv_phase_id', 'Previous Phases'),
'duration': fields.float('Duration'),
'product_uom': fields.many2one('product.uom', 'Duration UoM', help="UoM (Unit of Measure) is the unit of measurement for Duration"),
'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'),
'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of phases."),
'duration': fields.float('Duration',required=True),
'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'),
'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\'.')
}
_defaults = {
'responsible_id': lambda obj,cr,uid,context: uid,
'date_start': lambda *a: time.strftime('%Y-%m-%d'),
'state': lambda *a: 'draft',
'sequence': lambda *a: 10,
}
_order = "name"
_constraints = [
(_check_recursion,'Error ! Loops In Phases Not Allowed',['next_phase_ids','previous_phase_ids'])
]
# _constraints = [
# (_check_recursion,'Error ! Loops In Phases Not Allowed',['next_phase_ids','previous_phase_ids'])
# ]
def timeformat_convert(self,cr, uid, time_string, context={}):
# To Convert input time string:: 8.5 to output time string 8:30
split_list = str(time_string).split('.')
hour_part = split_list[0]
mins_part = split_list[1]
round_mins = int(round(float(mins_part) * 60,-2))
converted_string = hour_part + ':' + str(round_mins)[0:2]
return converted_string
def phase_draft(self, cr, uid, ids,*args):
self.write(cr, uid, ids, {'state': 'draft'})
return True
def compute_hours(self,cr,uid,calendar_id,context = None):
# To compute average hours of the working calendar
def phase_start(self, cr, uid, ids,*args):
self.write(cr, uid, ids, {'state': 'open'})
return True
resource_week_pool = self.pool.get('resource.calendar.week')
week_ids = resource_week_pool.search(cr,uid,[('calendar_id','=',calendar_id)])
week_obj = resource_week_pool.read(cr,uid,week_ids,['dayofweek','hour_from','hour_to'])
hours = []
hr = 0
wk_days = []
for week in week_obj:
if week['dayofweek'] not in wk_days:
wk_days.append(week['dayofweek'])
hour_from_str = self.timeformat_convert(cr,uid,week['hour_from'])
hour_to_str = self.timeformat_convert(cr,uid,week['hour_to'])
hours.append(week['hour_from'])
hours.append(week['hour_to'])
def phase_pending(self, cr, uid, ids,*args):
self.write(cr, uid, ids, {'state': 'pending'})
return True
for hour in range(len(hours)):
if hour%2 ==0:
hr += float(hours[hour+1]) - float(hours[hour])
return hr/len(wk_days)
def phase_cancel(self, cr, uid, ids,*args):
self.write(cr, uid, ids, {'state': 'cancelled'})
return True
def constraint_date_start(self,cr,uid,phase,date_end,context=None):
# Recursive call for all previous phases if change in date_start < older time
resource_cal_pool = self.pool.get('resource.calendar')
calendar_id = phase.project_id.resource_calendar_id.id
avg_hours = self.compute_hours(cr,uid,calendar_id)
hours = phase.duration * avg_hours
work_time = resource_cal_pool.interval_min_get(cr, uid, calendar_id or False, date_end, hours or 0.0)
dt_start = work_time[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')})
def constraint_date_end(self,cr,uid,phase,date_start,context=None):
# Recursive call for all next phases if change in date_end > older time
resource_cal_pool = self.pool.get('resource.calendar')
calendar_id = phase.project_id.resource_calendar_id.id
avg_hours = self.compute_hours(cr,uid,calendar_id)
hours = phase.duration * avg_hours
work_time = resource_cal_pool.interval_get(cr, uid, calendar_id or False, date_start, hours or 0.0)
dt_end = work_time[-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})
def write(self, cr, uid, ids, vals,context=None):
phase = self.browse(cr,uid,ids[0])
resource_cal_pool = self.pool.get('resource.calendar')
calendar_id = phase.project_id.resource_calendar_id.id
avg_hours = self.compute_hours(cr,uid,calendar_id)
if not context:
context = {}
# write method changes the date_start and date_end
#for previous and next phases respectively based on valid condition
if vals.get('date_start'):
if vals['date_start'] < phase.date_start:
dt_start = mx.DateTime.strptime(vals['date_start'],'%Y-%m-%d %H:%M:%S')
hrs = phase.duration * avg_hours
work_times = resource_cal_pool.interval_get(cr, uid, calendar_id or False, dt_start, hrs or 0.0)
vals['date_end'] = work_times[-1][1].strftime('%Y-%m-%d %H:%M:%S')
super(project_phase, self).write(cr, uid, ids, vals, context=context)
for prv_phase in phase.previous_phase_ids:
self.constraint_date_start(cr,uid,prv_phase,dt_start)
if vals.get('date_end'):
if vals['date_end'] > phase.date_end:
dt_end = mx.DateTime.strptime(vals['date_end'],'%Y-%m-%d %H:%M:%S')
hrs = phase.duration * avg_hours
work_times = resource_cal_pool.interval_min_get(cr, uid, calendar_id or False, dt_end, hrs or 0.0)
vals['date_start'] = work_times[0][0].strftime('%Y-%m-%d %H:%M:%S')
super(project_phase, self).write(cr, uid, ids, vals, context=context)
for next_phase in phase.next_phase_ids:
self.constraint_date_end(cr,uid,next_phase,dt_end)
return super(project_phase, self).write(cr, uid, ids, vals, context=context)
def phase_done(self, cr, uid, ids,*args):
self.write(cr, uid, ids, {'state': 'done'})
return True
project_phase()
@@ -192,7 +133,7 @@ class project_resource_allocation(osv.osv):
_rec_name = 'resource_id'
_columns = {
'resource_id': fields.many2one('resource.resource', 'Resource', required=True),
'phase_id': fields.many2one('project.phase', 'Project Phase', required=True),
'phase_id': fields.many2one('project.phase', 'Project Phase',required=True),
'useability': fields.float('Useability', help="Useability of this ressource for this project phase in percentage (=50%)"),
}
_defaults = {
+37 -12
View File
@@ -19,9 +19,8 @@
<field name="type">tree</field>
<field name="priority" eval="5"/>
<field name="arch" type="xml">
<tree string="Project Resource Allocation">
<tree editable="bottom" string="Project Resource Allocation">
<field name="resource_id"/>
<field name="phase_id"/>
<field name="useability"/>
</tree>
</field>
@@ -34,29 +33,55 @@
<form string="Project Phase">
<group colspan="6" col="6">
<field name="name" select="1"/>
<field name="project_id"/>
<field name="project_id" on_change="onchange_project(project_id)"/>
<field name="responsible_id"/>
<field name="date_start"/>
<field name="date_end"/>
<field name="constraint_date_start"/>
<field name="constraint_date_end"/>
<field name="duration"/>
<field name="product_uom"/>
</group>
<notebook colspan="4">
<page string="Task Detail">
<separator colspan="4" string="Project's Tasks"/>
<field colspan="4" name="task_ids" nolabel="1"/>
</page>
<page string="Resource Allocation Detail">
<page string="Resource Allocation Detail">
<separator colspan="4" string="Resource Allocation"/>
<field colspan="4" name="resource_ids" nolabel="1"/>
<field colspan="4" name="resource_ids" nolabel="1">
<tree editable="bottom" string="Project Resource Allocation">
<field name="resource_id" context="{'project_id':parent.project_id}"/>
<field name="useability"/>
</tree>
<form string="Project Resource Allocation">
<field name="resource_id" context="{'project_id':parent.project_id}"/>
<field name="useability"/>
</form>
</field>
<group col="12" colspan="4">
<field name="state" select="1"/>
<button string="Draft" name="phase_draft" states="open"/>
<button string="Start Phase" name="phase_start" states="pending,draft"/>
<button string="Cancel" name="phase_cancel" states="draft,open,pending"/>
<button string="Done" name="phase_done" states="draft,pending,open"/>
<button string="Pending" name="phase_pending" states="open"/>
</group>
</page>
<page string="Other Info">
<group colspan="2" col="2">
<separator string="Constraints" colspan="2"/>
<field name="constraint_date_start"/>
<field name="constraint_date_end"/>
</group>
<group colspan="2" col="2">
<separator string="Scheduling" colspan="2"/>
<field name="sequence"/>
</group>
<separator colspan="4" string="Next Phases"/>
<field colspan="4" name="next_phase_ids" nolabel="1"/>
<separator colspan="4" string="Previous Phases"/>
<field colspan="4" name="previous_phase_ids" nolabel="1"/>
</page>
<page string="Task Detail">
<separator colspan="4" string="Project's Tasks"/>
<field colspan="4" name="task_ids" nolabel="1"/>
<button name="%(wizard_schedule_task)d" string="Schedule Tasks" type="action" icon="gtk-jump-to"/>
</page>
</notebook>
<newline/>
</form>
@@ -92,7 +117,7 @@
res_model="project.task"
src_model="project.phase"
view_mode="tree,form"
domain="[('phase_id','=',active_id)]"/>
domain="[('phase_id','=',active_id)]"/>
<menuitem action="act_project_phase" id="menu_project_phase" parent="project.menu_project_management" sequence="4"/>