[MERGE] project related modules improvements

bzr revid: mra@mra-laptop-20100729092715-vog7b7epwp8uc2c3
This commit is contained in:
PAP(OpenERP)
2010-07-29 14:57:15 +05:30
committed by Mustufa Rangwala
14 changed files with 136 additions and 105 deletions
+8 -7
View File
@@ -152,17 +152,17 @@ where prp.id in %s''',(tuple(ids),))
'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of Projects."),
'analytic_account_id': fields.many2one('account.analytic.account', 'Analytic Account', help="Link this project to an analytic account if you need financial management on projects. It enables you to connect projects with budgets, planning, cost and revenue analysis, timesheets on projects, etc."),
'priority': fields.integer('Sequence', help="Gives the sequence order when displaying a list of task"),
'warn_manager': fields.boolean('Warn Manager', help="If you check this field, the project manager will receive a request each time a task is completed by his team."),
'members': fields.many2many('res.users', 'project_user_rel', 'project_id', 'uid', 'Project Members', help="Project's member. Not used in any computation, just for information purpose."),
'warn_manager': fields.boolean('Warn Manager', help="If you check this field, the project manager will receive a request each time a task is completed by his team.", states={'close':[('readonly',True)], 'cancelled':[('readonly',True)]}),
'members': fields.many2many('res.users', 'project_user_rel', 'project_id', 'uid', 'Project Members', help="Project's member. Not used in any computation, just for information purpose.", states={'close':[('readonly',True)], 'cancelled':[('readonly',True)]}),
'tasks': fields.one2many('project.task', 'project_id', "Project tasks"),
'planned_hours': fields.function(_progress_rate, multi="progress", method=True, string='Planned Time', help="Sum of planned hours of all tasks related to this project and its child projects."),
'effective_hours': fields.function(_progress_rate, multi="progress", method=True, string='Time Spent', help="Sum of spent hours of all tasks related to this project and its child projects."),
'total_hours': fields.function(_progress_rate, multi="progress", method=True, string='Total Time', help="Sum of total hours of all tasks related to this project and its child projects."),
'progress_rate': fields.function(_progress_rate, multi="progress", method=True, string='Progress', type='float', help="Percent of tasks closed according to the total of tasks todo."),
'warn_customer': fields.boolean('Warn Partner', help="If you check this, the user will have a popup when closing a task that propose a message to send by email to the customer."),
'warn_header': fields.text('Mail Header', help="Header added at the beginning of the email for the warning message sent to the customer when a task is closed."),
'warn_footer': fields.text('Mail Footer', help="Footer added at the beginning of the email for the warning message sent to the customer when a task is closed."),
'type_ids': fields.many2many('project.task.type', 'project_task_type_rel', 'project_id', 'type_id', 'Tasks Stages'),
'warn_customer': fields.boolean('Warn Partner', help="If you check this, the user will have a popup when closing a task that propose a message to send by email to the customer.", states={'close':[('readonly',True)], 'cancelled':[('readonly',True)]}),
'warn_header': fields.text('Mail Header', help="Header added at the beginning of the email for the warning message sent to the customer when a task is closed.", states={'close':[('readonly',True)], 'cancelled':[('readonly',True)]}),
'warn_footer': fields.text('Mail Footer', help="Footer added at the beginning of the email for the warning message sent to the customer when a task is closed.", states={'close':[('readonly',True)], 'cancelled':[('readonly',True)]}),
'type_ids': fields.many2many('project.task.type', 'project_task_type_rel', 'project_id', 'type_id', 'Tasks Stages', states={'close':[('readonly',True)], 'cancelled':[('readonly',True)]}),
}
_order = "sequence"
@@ -480,7 +480,8 @@ class task(osv.osv):
'ref_doc1': 'project.task,%d'% (task.id,),
'ref_doc2': 'project.project,%d'% (project.id,),
})
elif project.warn_manager and cntx.get('mail_send',True):
elif (project.warn_manager or project.warn_customer) and cntx.get('mail_send',True):
cntx.update({'send_manager': project.warn_manager, 'send_partner': project.warn_customer})
mail_send = True
message = _('Task ') + " '" + task.name + "' "+ _("is Done.")
self.log(cr, uid, task.id, message)
+6 -6
View File
@@ -20,9 +20,9 @@
<group colspan="6" col="6">
<field name="name" string="Project Name" select="1"/>
<field name="parent_id" string="Parent Project"/>
<field name="user_id" string="Project Manager" select="1"/>
<field name="date_start"/>
<field name="date"/>
<field name="user_id" string="Project Manager" select="1" attrs="{'readonly':[('state','in',['close', 'cancelled'])]}"/>
<field name="date_start" attrs="{'readonly':[('state','in',['close', 'cancelled'])]}"/>
<field name="date" attrs="{'readonly':[('state','in',['close', 'cancelled'])]}"/>
<field name="progress_rate" widget="progressbar"/>
</group>
<notebook colspan="4">
@@ -48,8 +48,8 @@
<button name="set_template" string="Set as Template" type="object" states="open" icon="gtk-convert"/>
<button name="set_open" string="Reactivate Project" type="object" states="pending,cancelled,close" icon="gtk-ok"/>
<button name="set_pending" string="Pending" type="object" states="open" icon="gtk-media-pause"/>
<button name="set_cancel" string="Cancel" type="object" states="open,pending" icon="gtk-cancel"/>
<button name="set_done" string="Done" type="object" states="open,pending" icon="gtk-jump-to"/>
<button name="set_cancel" string="Cancel" type="object" states="open,pending" icon="gtk-cancel"/>
<button name="reset_project" string="Reset as Project" type="object" states="template" icon="gtk-convert"/>
<button
string="New Project Based on Template"
@@ -247,8 +247,8 @@
<field name="name" select="1"/>
<field name="project_id" required="1" select="1" domain="[('user_id','=',uid)]"/>
<field name="total_hours" widget="float_time"/>
<field name="date_deadline"/>
<field name="user_id" select="1"/>
<field name="date_deadline" attrs="{'readonly':[('state','in',['done', 'cancelled'])]}"/>
<field name="user_id" select="1" attrs="{'readonly':[('state','in',['done', 'cancelled'])]}"/>
<field name="progress" widget="progressbar"/>
</group>
<notebook colspan="4">
+6 -3
View File
@@ -48,7 +48,10 @@
if not new_prj:
raise Exception( "New project based on template not created")
new_id = new_prj['res_id']
state = self.read(cr, uid, [new_id], ['state'])[0]['state']
new_prj = self.read(cr, uid, [new_id], ['name', 'state'])[0]
state = new_prj['state']
name = new_prj['name']
print "Project '%s' created"%name
assert state == 'open', "Project in %s state. Project created from template project must be in open state"%state
-
Reset project template to normal project
@@ -275,7 +278,7 @@
name: Training on yml
user_id: base.user_root
-
Check for effective hours and remaining hours
Check for effective hours and remaining hours, remaining_hours must be 5, effective_hours must be 45
-
!assert {model: project.task, id: project_task_technicaltraining0, severity: error, string: After work task of 5 hours effective_hours must be equal to 45 and remaining_hours is 5}:
- planned_hours == 30
@@ -312,6 +315,6 @@
-
Check if project in close state
-
!assert {model: project.project, id: project_project_openerptrainingprogramme0, severity: error}:
!assert {model: project.project, id: project_project_openerptrainingprogramme0, severity: error, string: "Project must be in closed state"}:
- state == "close"
@@ -43,8 +43,10 @@
{"lang": "en_US", "active_model": "ir.ui.menu", "active_ids": [ref("project.menu_action_view_task")],
"tz": False, "active_id": ref("project.menu_action_view_task"), })
-
Test the delegate wizard
-
Creating a project.task.delegate record
Creating a delegate task 'Publish the References' of 15 hours, renaming parent task to 'CHECK Publish the References' of 1 hour
-
!record {model: project.task.delegate, id: project_task_publish_book_delegate}:
name: Publish the References
@@ -56,14 +58,19 @@
user_id: base.user_demo
-
Performing an osv_memory action validate on module project.task.delegate
Validating the delegate task
-
!python {model: project.task.delegate}: |
self.validate(cr, uid, [ref("project_task_publish_book_delegate")],
{"lang": "en_US", "active_model": "project.task", "tz": False, "record_id":
4, "active_ids": [ref("project_task_publish_book")], "active_id": ref("project_task_publish_book"),
})
-
Check if parent task 'CHECK Publish the References' is in pending state
-
!assert {model: project.task, id: project_task_publish_book, severity: error, string: "Task must be in pending state after delegation"}:
- state == "pending"
-
Creating a delegate task 'Prepare a book that gives functional overview of OpenERP'
-
@@ -160,7 +167,7 @@
-
Check if 'Prepare a technical reference for creating your modules' in pending state
-
!assert {model: project.task, id: project_task_delegate_developer_book, severity: error, string: Task is in pending state}:
!assert {model: project.task, id: project_task_delegate_developer_book, severity: error, string: Task must be in pending state}:
- state == "pending"
-
+40 -18
View File
@@ -32,15 +32,28 @@ class project_close_task(osv.osv_memory):
_name = "close.task"
_description = "Project Close Task"
_columns = {
'email': fields.char('E-Mail', size=64, help="Email Address"),
'manager_email': fields.char('Manager E-Mail ID', size=64, help="Email Address of Project's Manager"),
'partner_email': fields.char('Partner E-Mail ID', size=64, help="Email Address of Partner"),
'description': fields.text('Description'),
}
def _get_email(self, cr, uid, context=None):
def _get_manager_email(self, cr, uid, context=None):
if context is None:
context = {}
email = ''
if 'task_id' in context:
if context.get('send_manager', False) and ('task_id' in context):
project_id = self.pool.get('project.task').read(cr, uid, context['task_id'], ['project_id'])['project_id'][0]
project = self.pool.get('project.project').browse(cr, uid, project_id)
manager_id = project.user_id or False
if manager_id and manager_id.user_email:
email = manager_id.user_email
return email
def _get_partner_email(self, cr, uid, context=None):
if context is None:
context = {}
email = ''
if context.get('send_partner', False) and ('task_id' in context):
task = self.pool.get('project.task').browse(cr, uid, context['task_id'])
partner_id = task.partner_id or task.project_id.partner_id
if partner_id and len(partner_id.address) and partner_id.address[0].email:
@@ -56,7 +69,8 @@ class project_close_task(osv.osv_memory):
return ''
_defaults = {
'email': _get_email,
'manager_email': _get_manager_email,
'partner_email': _get_partner_email,
'description': _get_desc,
}
@@ -71,12 +85,19 @@ class project_close_task(osv.osv_memory):
if not 'task_id' in context:
return {}
close_task = self.read(cr, uid, ids[0], [])
to_adr = close_task['email']
to_adr = []
description = close_task['description']
if 'task_id' in context:
task_obj = self.pool.get('project.task')
for task in task_obj.browse(cr, uid, [context['task_id']], context=context):
if context.get('send_manager', False) and not close_task.get('manager_email', False):
raise osv.except_osv(_('Error'), _("Please specify the email address of Manager."))
elif context.get('send_partner', False) and not close_task.get('partner_email', False):
raise osv.except_osv(_('Error'), _("Please specify the email address of partner."))
else:
task_obj = self.pool.get('project.task')
task = task_obj.browse(cr, uid, context['task_id'], context=context)
project = task.project_id
subject = "Task '%s' closed" % task.name
if task.user_id and task.user_id.address_id and task.user_id.address_id.email:
@@ -84,8 +105,7 @@ class project_close_task(osv.osv_memory):
signature = task.user_id.signature
else:
raise osv.except_osv(_('Error'), _("Couldn't send mail because your email address is not configured!"))
if to_adr:
val = {
val = {
'name': task.name,
'user_id': task.user_id.name,
'task_id': "%d/%d" % (project.id, task.id),
@@ -93,15 +113,17 @@ class project_close_task(osv.osv_memory):
'date_end': task.date_end,
'state': task.state
}
header = (project.warn_header or '') % val
footer = (project.warn_footer or '') % val
body = u'%s\n%s\n%s\n\n-- \n%s' % (header, description, footer, signature)
email(from_adr, [to_adr], subject, body.encode('utf-8'), email_bcc=[from_adr])
task_obj.write(cr, uid, [task.id], {'state': 'done', 'date_end':time.strftime('%Y-%m-%d %H:%M:%S'), 'remaining_hours': 0.0})
message = _('Task ') + " '" + task.name + "' "+ _("is Done.")
self.log(cr, uid, task.id, message)
else:
raise osv.except_osv(_('Error'), _("Please specify the email address of partner."))
header = (project.warn_header or '') % val
footer = (project.warn_footer or '') % val
body = u'%s\n%s\n%s\n\n-- \n%s' % (header, description, footer, signature)
to_adr.append(context.get('send_manager', '') and close_task.get('manager_email', '') or '')
to_adr.append(context.get('send_partner', '') and close_task.get('partner_email', '') or '')
email(from_adr, to_adr, subject, body.encode('utf-8'), email_bcc=[from_adr])
task_obj.write(cr, uid, [task.id], {'state': 'done', 'date_end':time.strftime('%Y-%m-%d %H:%M:%S'), 'remaining_hours': 0.0})
message = _('Task ') + " '" + task.name + "' "+ _("is Done.")
self.log(cr, uid, task.id, message)
return {}
project_close_task()
@@ -12,7 +12,9 @@
<separator string="" colspan="4"/>
<group colspan="4" col="6">
<newline/>
<field name="email"/>
<field name="manager_email" invisible="not context.get('send_manager',False)"/>
<newline/>
<field name="partner_email" invisible="not context.get('send_partner',False)"/>
<newline/>
<field name="description" />
</group>
+2 -2
View File
@@ -406,8 +406,8 @@ project_issue()
class project(osv.osv):
_inherit = "project.project"
_columns = {
'resource_calendar_id' : fields.many2one('resource.calendar', 'Working Time', help="Timetable working hours to adjust the gantt diagram report"),
'project_escalation_id' : fields.many2one('project.project','Project Escalation', help='If any issue is escalated from the current Project, it will be listed under the project selected here.'),
'resource_calendar_id' : fields.many2one('resource.calendar', 'Working Time', help="Timetable working hours to adjust the gantt diagram report", states={'close':[('readonly',True)], 'cancelled':[('readonly',True)]}),
'project_escalation_id' : fields.many2one('project.project','Project Escalation', help='If any issue is escalated from the current Project, it will be listed under the project selected here.', states={'close':[('readonly',True)], 'cancelled':[('readonly',True)]}),
'reply_to' : fields.char('Reply-To Email Address', size=256)
}
+23 -23
View File
@@ -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()
@@ -269,14 +269,14 @@
<field name="name">Information Gathering and Understanding</field>
<field name="product_uom" ref="product.uom_day"/>
<field eval="10" name="sequence"/>
<field name="constraint_date_end" eval="(DateTime.now()+timedelta(18-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="date_start" eval="(DateTime.now()-timedelta(70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="constraint_date_end" eval="(DateTime.now()+timedelta(18-70)).strftime('%Y-%m-%d')"/>
<field name="date_start" eval="(DateTime.now()-timedelta(70)).strftime('%Y-%m-%d')"/>
<field name="state">draft</field>
<field name="responsible_id" ref="res_users_demouser1"/>
<field eval="15.0" name="duration"/>
<field name="project_id" ref="project_project_openerpwebsitedevelopment0"/>
<field name="constraint_date_start" eval="(DateTime.now()+timedelta(2-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="date_end" eval="(DateTime.now()+timedelta(15-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="constraint_date_start" eval="(DateTime.now()+timedelta(2-70)).strftime('%Y-%m-%d')"/>
<field name="date_end" eval="(DateTime.now()+timedelta(15-70)).strftime('%Y-%m-%d')"/>
</record>
<record id="project_phase_planning0" model="project.phase">
@@ -284,59 +284,59 @@
<field name="name">Planning</field>
<field name="product_uom" ref="product.uom_day"/>
<field eval="10" name="sequence"/>
<field name="constraint_date_end" eval="(DateTime.now()+timedelta(28-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="date_start" eval="(DateTime.now()+timedelta(10-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="constraint_date_end" eval="(DateTime.now()+timedelta(28-70)).strftime('%Y-%m-%d')"/>
<field name="date_start" eval="(DateTime.now()+timedelta(10-70)).strftime('%Y-%m-%d')"/>
<field name="state">draft</field>
<field name="responsible_id" ref="res_users_manager0"/>
<field eval="15.0" name="duration"/>
<field name="project_id" ref="project_project_openerpwebsitedevelopment0"/>
<field name="constraint_date_start" eval="(DateTime.now()+timedelta(13-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="date_end" eval="(DateTime.now()+timedelta(25-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="constraint_date_start" eval="(DateTime.now()+timedelta(13-70)).strftime('%Y-%m-%d')"/>
<field name="date_end" eval="(DateTime.now()+timedelta(25-70)).strftime('%Y-%m-%d')"/>
</record>
<record id="project_phase_webdesign0" model="project.phase">
<field eval="[(6, 0, [ref('project_phase_informationgatheringandunderstanding0'), ref('project_phase_planning0')])]" name="previous_phase_ids"/>
<field eval="[(6, 0, [ref('project_phase_planning0')])]" name="previous_phase_ids"/>
<field name="name">Web Design </field>
<field name="product_uom" ref="product.uom_day"/>
<field eval="10" name="sequence"/>
<field name="constraint_date_end" eval="(DateTime.now()+timedelta(45-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="date_start" eval="(DateTime.now()+timedelta(20-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="constraint_date_end" eval="(DateTime.now()+timedelta(45-70)).strftime('%Y-%m-%d')"/>
<field name="date_start" eval="(DateTime.now()+timedelta(20-70)).strftime('%Y-%m-%d')"/>
<field name="state">draft</field>
<field name="responsible_id" ref="res_users_userdesign0"/>
<field eval="20.0" name="duration"/>
<field name="project_id" ref="project_project_openerpwebsitedevelopment0"/>
<field name="constraint_date_start" eval="(DateTime.now()+timedelta(25-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="date_end" eval="(DateTime.now()+timedelta(40-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="constraint_date_start" eval="(DateTime.now()+timedelta(25-70)).strftime('%Y-%m-%d')"/>
<field name="date_end" eval="(DateTime.now()+timedelta(40-70)).strftime('%Y-%m-%d')"/>
</record>
<record id="project_phase_developmentintegrationandtesting0" model="project.phase">
<field eval="[(6, 0, [ref('project_phase_informationgatheringandunderstanding0'), ref('project_phase_planning0'), ref('project_phase_webdesign0')])]" name="previous_phase_ids"/>
<field eval="[(6, 0, [ref('project_phase_webdesign0')])]" name="previous_phase_ids"/>
<field name="name">Development, Integration and Testing</field>
<field name="product_uom" ref="product.uom_day"/>
<field eval="10" name="sequence"/>
<field name="constraint_date_end" eval="(DateTime.now()+timedelta(57-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="date_start" eval="(DateTime.now()+timedelta(30-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="constraint_date_end" eval="(DateTime.now()+timedelta(57-70)).strftime('%Y-%m-%d')"/>
<field name="date_start" eval="(DateTime.now()+timedelta(30-70)).strftime('%Y-%m-%d')"/>
<field name="state">draft</field>
<field name="responsible_id" ref="res_users_manager0"/>
<field eval="22.0" name="duration"/>
<field name="project_id" ref="project_project_openerpwebsitedevelopment0"/>
<field name="constraint_date_start" eval="(DateTime.now()+timedelta(35-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="date_end" eval="(DateTime.now()+timedelta(52-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="constraint_date_start" eval="(DateTime.now()+timedelta(35-70)).strftime('%Y-%m-%d')"/>
<field name="date_end" eval="(DateTime.now()+timedelta(52-70)).strftime('%Y-%m-%d')"/>
</record>
<record id="project_phase_websitedeployment0" model="project.phase">
<field eval="[(6, 0, [ref('project_phase_informationgatheringandunderstanding0'), ref('project_phase_planning0'), ref('project_phase_webdesign0'), ref('project_phase_developmentintegrationandtesting0')])]" name="previous_phase_ids"/>
<field eval="[(6, 0, [ref('project_phase_developmentintegrationandtesting0')])]" name="previous_phase_ids"/>
<field name="name">Website Deployment</field>
<field name="product_uom" ref="product.uom_day"/>
<field eval="10" name="sequence"/>
<field name="constraint_date_end" eval="(DateTime.now()+timedelta(63-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="date_start" eval="(DateTime.now()+timedelta(55-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="constraint_date_end" eval="(DateTime.now()+timedelta(63-70)).strftime('%Y-%m-%d')"/>
<field name="date_start" eval="(DateTime.now()+timedelta(55-70)).strftime('%Y-%m-%d')"/>
<field name="state">draft</field>
<field name="responsible_id" ref="res_users_manager0"/>
<field eval="5.0" name="duration"/>
<field name="project_id" ref="project_project_openerpwebsitedevelopment0"/>
<field name="constraint_date_start" eval="(DateTime.now()+timedelta(58-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="date_end" eval="(DateTime.now()+timedelta(60-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="constraint_date_start" eval="(DateTime.now()+timedelta(58-70)).strftime('%Y-%m-%d')"/>
<field name="date_end" eval="(DateTime.now()+timedelta(60-70)).strftime('%Y-%m-%d')"/>
</record>
<!-- Project Resource Allocation -->
@@ -16,7 +16,7 @@
Create phase 'Develop GUI' in Outlook
-
!record {model: project.phase, id: project_phase_phase0}:
date_start: '2010-06-02 00:00:00'
date_start: '2010-06-02'
duration: 200.0
name: phase123
product_uom: product.uom_day
@@ -36,7 +36,6 @@
-
!record {model: project.task, id: project_task_t0}:
name: t1
occupation_rate: 1.0
planned_hours: 20.0
remaining_hours: 20.0
state: draft
@@ -49,7 +48,6 @@
-
!record {model: project.task, id: project_task_t1}:
name: t2
occupation_rate: 1.0
planned_hours: 25.0
remaining_hours: 25.0
state: draft
@@ -61,7 +59,6 @@
-
!record {model: project.task, id: project_task_t2}:
name: t3
occupation_rate: 1.0
planned_hours: 30.0
remaining_hours: 30.0
state: draft
@@ -74,7 +71,6 @@
-
!record {model: project.task, id: project_task_3}:
name: t4
occupation_rate: 1.0
planned_hours: 25.0
remaining_hours: 25.0
state: draft
@@ -10,7 +10,7 @@
Create a project phase 'Defining Client's Basic Idea of Project'
-
!record {model: project.phase, id: project_phase_definingclientsbasicideaofproject0}:
date_start: '2010-06-02 00:00:00'
date_start: '2010-06-02'
duration: 15.0
name: "Defining Client's Basic Idea of Project"
product_uom: product.uom_day
@@ -22,7 +22,7 @@
Create project phase 'Establishing Project Feasibility'
-
!record {model: project.phase, id: project_phase_establishingprojectfeasibility0}:
date_start: '2010-06-02 00:00:00'
date_start: '2010-06-02'
duration: 30.0
name: Establishing Project Feasibility
product_uom: product.uom_day
@@ -33,7 +33,7 @@
Create project phase 'Preparation of Engineering Designs'
-
!record {model: project.phase, id: project_phase_preparationofengineeringdesigns0}:
date_start: '2010-06-02 00:00:00'
date_start: '2010-06-02'
duration: 100.0
name: Preparation of Engineering Designs
product_uom: product.uom_hour
@@ -45,7 +45,7 @@
Create project phase 'Procurement of Works and Goods'
-
!record {model: project.phase, id: project_phase_procurementofworksandgoods0}:
date_start: '2010-06-02 00:00:00'
date_start: '2010-06-02'
duration: 24.0
name: Procurement of Works and Goods
product_uom: product.uom_hour
@@ -57,7 +57,7 @@
Create project phase 'Project Construction'
-
!record {model: project.phase, id: project_phase_projectconstruction0}:
date_start: '2010-06-02 00:00:00'
date_start: '2010-06-02'
duration: 4320.0
name: Project Construction
product_uom: product.uom_hour
@@ -69,7 +69,7 @@
Create project phase 'Project Completion'
-
!record {model: project.phase, id: project_phase_projectcompletion0}:
date_start: '2010-06-02 00:00:00'
date_start: '2010-06-02'
duration: 240.0
name: Project Completion
product_uom: product.uom_hour
@@ -17,7 +17,7 @@
Create phase 'Develop GUI' in Thunderbird
-
!record {model: project.phase, id: project_phase_phase1}:
date_start: '2010-06-02 00:00:00'
date_start: '2010-06-02'
duration: 100.0
name: phase22
product_uom: product.uom_day
@@ -103,20 +103,20 @@ class project_compute_phases(osv.osv_memory):
# Recalculate date_start and date_end
# according to constraints on date start and date end on phase
if phase.constraint_date_start and str(s_date) < phase.constraint_date_start:
start_date = datetime.datetime.strptime(phase.constraint_date_start, '%Y-%m-%d %H:%M:%S')
start_date = datetime.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.datetime.strptime(phase.constraint_date_end, '%Y-%m-%d %H:%M:%S')
date_start = phase.constraint_date_end[:-3]
end_date= datetime.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})
phase_obj.write(cr, uid, [phase.id], {'date_start': start_date.strftime('%Y-%m-%d %H:%M:%S'),
'date_end': end_date.strftime('%Y-%m-%d %H:%M:%S')},
phase_obj.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:
@@ -92,7 +92,7 @@ class project_schedule_task(osv.osv_memory):
if task_ids:
task_ids.sort()
tasks = task_obj.browse(cr, uid, task_ids, context=context)
start_date = str(phase.date_start)[:-9]
start_date = str(phase.date_start)
if not phase.date_start:
if not phase.project_id.date_start:
start_date = datetime.datetime.now().strftime("%Y-%m-%d")