[MERGE] Merged with JRA Project issue branch
bzr revid: tde@openerp.com-20120403102408-q0ctxqz10mpw5phb
This commit is contained in:
@@ -48,44 +48,6 @@ class project_issue(crm.crm_case, osv.osv):
|
||||
_order = "priority, create_date desc"
|
||||
_inherit = ['mail.thread']
|
||||
|
||||
def write(self, cr, uid, ids, vals, context=None):
|
||||
#Update last action date everytime the user change the stage, the state or send a new email
|
||||
logged_fields = ['type_id', 'state', 'message_ids']
|
||||
if any([field in vals for field in logged_fields]):
|
||||
vals['date_action_last'] = time.strftime('%Y-%m-%d %H:%M:%S')
|
||||
return super(project_issue, self).write(cr, uid, ids, vals, context)
|
||||
|
||||
def case_open(self, cr, uid, ids, *args):
|
||||
"""
|
||||
@param self: The object pointer
|
||||
@param cr: the current row, from the database cursor,
|
||||
@param uid: the current user’s ID for security checks,
|
||||
@param ids: List of case's Ids
|
||||
@param *args: Give Tuple Value
|
||||
"""
|
||||
|
||||
res = super(project_issue, self).case_open(cr, uid, ids, *args)
|
||||
self.write(cr, uid, ids, {'date_open': time.strftime('%Y-%m-%d %H:%M:%S'), 'user_id' : uid})
|
||||
for (id, name) in self.name_get(cr, uid, ids):
|
||||
message = _("Issue '%s' has been opened.") % name
|
||||
self.log(cr, uid, id, message)
|
||||
return res
|
||||
|
||||
def case_close(self, cr, uid, ids, *args):
|
||||
"""
|
||||
@param self: The object pointer
|
||||
@param cr: the current row, from the database cursor,
|
||||
@param uid: the current user’s ID for security checks,
|
||||
@param ids: List of case's Ids
|
||||
@param *args: Give Tuple Value
|
||||
"""
|
||||
|
||||
res = super(project_issue, self).case_close(cr, uid, ids, *args)
|
||||
for (id, name) in self.name_get(cr, uid, ids):
|
||||
message = _("Issue '%s' has been closed.") % name
|
||||
self.log(cr, uid, id, message)
|
||||
return res
|
||||
|
||||
def _compute_day(self, cr, uid, ids, fields, args, context=None):
|
||||
"""
|
||||
@param cr: the current row, from the database cursor,
|
||||
@@ -112,7 +74,8 @@ class project_issue(crm.crm_case, osv.osv):
|
||||
ans = date_open - date_create
|
||||
date_until = issue.date_open
|
||||
#Calculating no. of working hours to open the issue
|
||||
hours = cal_obj.interval_hours_get(cr, uid, issue.project_id.resource_calendar_id.id,
|
||||
if issue.project_id.resource_calendar_id:
|
||||
hours = cal_obj.interval_hours_get(cr, uid, issue.project_id.resource_calendar_id.id,
|
||||
date_create,
|
||||
date_open)
|
||||
elif field in ['working_hours_close','day_close']:
|
||||
@@ -121,7 +84,8 @@ class project_issue(crm.crm_case, osv.osv):
|
||||
date_until = issue.date_closed
|
||||
ans = date_close - date_create
|
||||
#Calculating no. of working hours to close the issue
|
||||
hours = cal_obj.interval_hours_get(cr, uid, issue.project_id.resource_calendar_id.id,
|
||||
if issue.project_id.resource_calendar_id:
|
||||
hours = cal_obj.interval_hours_get(cr, uid, issue.project_id.resource_calendar_id.id,
|
||||
date_create,
|
||||
date_close)
|
||||
elif field in ['days_since_creation']:
|
||||
@@ -166,6 +130,25 @@ class project_issue(crm.crm_case, osv.osv):
|
||||
|
||||
return res
|
||||
|
||||
def _hours_get(self, cr, uid, ids, field_names, args, context=None):
|
||||
task_pool = self.pool.get('project.task')
|
||||
res = {}
|
||||
for issue in self.browse(cr, uid, ids, context=context):
|
||||
progress = 0.0
|
||||
if issue.task_id:
|
||||
progress = task_pool._hours_get(cr, uid, [issue.task_id.id], field_names, args, context=context)[issue.task_id.id]['progress']
|
||||
res[issue.id] = {'progress' : progress}
|
||||
return res
|
||||
|
||||
def _get_project(self, cr, uid, context=None):
|
||||
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
|
||||
if user.context_project_id:
|
||||
return user.context_project_id.id
|
||||
return False
|
||||
|
||||
def on_change_project(self, cr, uid, ids, project_id, context=None):
|
||||
return {}
|
||||
|
||||
def _get_issue_task(self, cr, uid, ids, context=None):
|
||||
issues = []
|
||||
issue_pool = self.pool.get('project.issue')
|
||||
@@ -181,16 +164,6 @@ class project_issue(crm.crm_case, osv.osv):
|
||||
issues += issue_pool.search(cr, uid, [('task_id','=',work.task_id.id)])
|
||||
return issues
|
||||
|
||||
def _hours_get(self, cr, uid, ids, field_names, args, context=None):
|
||||
task_pool = self.pool.get('project.task')
|
||||
res = {}
|
||||
for issue in self.browse(cr, uid, ids, context=context):
|
||||
progress = 0.0
|
||||
if issue.task_id:
|
||||
progress = task_pool._hours_get(cr, uid, [issue.task_id.id], field_names, args, context=context)[issue.task_id.id]['progress']
|
||||
res[issue.id] = {'progress' : progress}
|
||||
return res
|
||||
|
||||
_columns = {
|
||||
'id': fields.integer('ID', readonly=True),
|
||||
'name': fields.char('Issue', size=128, required=True),
|
||||
@@ -249,15 +222,6 @@ class project_issue(crm.crm_case, osv.osv):
|
||||
}),
|
||||
}
|
||||
|
||||
def _get_project(self, cr, uid, context=None):
|
||||
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
|
||||
if user.context_project_id:
|
||||
return user.context_project_id.id
|
||||
return False
|
||||
|
||||
def on_change_project(self, cr, uid, ids, project_id, context=None):
|
||||
return {}
|
||||
|
||||
|
||||
_defaults = {
|
||||
'active': 1,
|
||||
@@ -287,14 +251,13 @@ class project_issue(crm.crm_case, osv.osv):
|
||||
return self.set_priority(cr, uid, ids, '3')
|
||||
|
||||
def convert_issue_task(self, cr, uid, ids, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
|
||||
case_obj = self.pool.get('project.issue')
|
||||
data_obj = self.pool.get('ir.model.data')
|
||||
task_obj = self.pool.get('project.task')
|
||||
|
||||
|
||||
if context is None:
|
||||
context = {}
|
||||
|
||||
|
||||
result = data_obj._get_id(cr, uid, 'project', 'view_task_search_form')
|
||||
res = data_obj.read(cr, uid, result, ['res_id'])
|
||||
id2 = data_obj._get_id(cr, uid, 'project', 'view_task_form2')
|
||||
@@ -316,12 +279,13 @@ class project_issue(crm.crm_case, osv.osv):
|
||||
'user_id': bug.user_id.id,
|
||||
'planned_hours': 0.0,
|
||||
})
|
||||
|
||||
vals = {
|
||||
'task_id': new_task_id,
|
||||
'state':'pending'
|
||||
}
|
||||
case_obj.write(cr, uid, [bug.id], vals)
|
||||
self.convert_to_task_send_note(cr, uid, [bug.id], context=context)
|
||||
case_obj.write(cr, uid, [bug.id], vals, context=context)
|
||||
self.case_pending_send_note(cr, uid, [bug.id], context=context)
|
||||
|
||||
return {
|
||||
'name': _('Tasks'),
|
||||
@@ -353,28 +317,38 @@ class project_issue(crm.crm_case, osv.osv):
|
||||
def convert_to_bug(self, cr, uid, ids, context=None):
|
||||
return self._convert(cr, uid, ids, 'bug_categ', context=context)
|
||||
|
||||
def next_type(self, cr, uid, ids, *args):
|
||||
def next_type(self, cr, uid, ids, context=None):
|
||||
for task in self.browse(cr, uid, ids):
|
||||
typeid = task.type_id.id
|
||||
types = map(lambda x:x.id, task.project_id.type_ids or [])
|
||||
if types:
|
||||
if not typeid:
|
||||
self.write(cr, uid, task.id, {'type_id': types[0]})
|
||||
self.write(cr, uid, [task.id], {'type_id': types[0]})
|
||||
elif typeid and typeid in types and types.index(typeid) != len(types)-1 :
|
||||
index = types.index(typeid)
|
||||
self.write(cr, uid, task.id, {'type_id': types[index+1]})
|
||||
self.write(cr, uid, [task.id], {'type_id': types[index+1]})
|
||||
return True
|
||||
|
||||
def prev_type(self, cr, uid, ids, *args):
|
||||
def prev_type(self, cr, uid, ids, context=None):
|
||||
for task in self.browse(cr, uid, ids):
|
||||
typeid = task.type_id.id
|
||||
types = map(lambda x:x.id, task.project_id and task.project_id.type_ids or [])
|
||||
if types:
|
||||
if typeid and typeid in types:
|
||||
index = types.index(typeid)
|
||||
self.write(cr, uid, task.id, {'type_id': index and types[index-1] or False})
|
||||
self.write(cr, uid, [task.id], {'type_id': index and types[index-1] or False})
|
||||
return True
|
||||
|
||||
def write(self, cr, uid, ids, vals, context=None):
|
||||
#Update last action date every time the user change the stage, the state or send a new email
|
||||
logged_fields = ['type_id', 'state', 'message_ids']
|
||||
if any([field in vals for field in logged_fields]):
|
||||
vals['date_action_last'] = time.strftime('%Y-%m-%d %H:%M:%S')
|
||||
if vals.get('type_id', False):
|
||||
stage = self.pool.get('project.task.type').browse(cr, uid, vals['type_id'], context=context)
|
||||
self.message_append_note(cr, uid, ids, body=_("Stage changed to <b>%s</b>.") % stage.name, context=context)
|
||||
return super(project_issue, self).write(cr, uid, ids, vals, context)
|
||||
|
||||
def onchange_task_id(self, cr, uid, ids, task_id, context=None):
|
||||
result = {}
|
||||
if not task_id:
|
||||
@@ -382,14 +356,24 @@ class project_issue(crm.crm_case, osv.osv):
|
||||
task = self.pool.get('project.task').browse(cr, uid, task_id, context=context)
|
||||
return {'value':{'user_id': task.user_id.id,}}
|
||||
|
||||
def case_escalate(self, cr, uid, ids, *args):
|
||||
"""Escalates case to top level
|
||||
@param self: The object pointer
|
||||
@param cr: the current row, from the database cursor,
|
||||
@param uid: the current user’s ID for security checks,
|
||||
@param ids: List of case Ids
|
||||
@param *args: Tuple Value for additional Params
|
||||
def case_reset(self, cr, uid, ids, context=None):
|
||||
"""Resets case as draft
|
||||
"""
|
||||
res = super(project_issue, self).case_reset(cr, uid, ids, context)
|
||||
self.write(cr, uid, ids, {'date_open': False, 'date_closed': False})
|
||||
return res
|
||||
|
||||
def create(self, cr, uid, vals, context=None):
|
||||
obj_id = super(project_issue, self).create(cr, uid, vals, context=context)
|
||||
self.create_send_note(cr, uid, [obj_id], context=context)
|
||||
return obj_id
|
||||
|
||||
def case_open(self, cr, uid, ids, context=None):
|
||||
res = super(project_issue, self).case_open(cr, uid, ids, context)
|
||||
self.write(cr, uid, ids, {'date_open': time.strftime('%Y-%m-%d %H:%M:%S'), 'user_id' : uid})
|
||||
return res
|
||||
|
||||
def case_escalate(self, cr, uid, ids, context=None):
|
||||
cases = self.browse(cr, uid, ids)
|
||||
for case in cases:
|
||||
data = {'state' : 'draft'}
|
||||
@@ -402,7 +386,7 @@ class project_issue(crm.crm_case, osv.osv):
|
||||
else:
|
||||
raise osv.except_osv(_('Warning !'), _('You cannot escalate this issue.\nThe relevant Project has not configured the Escalation Project!'))
|
||||
self.write(cr, uid, [case.id], data)
|
||||
self.message_append(cr, uid, cases, _('Escalate'))
|
||||
self.case_escalate_send_note(cr, uid, [case.id], context)
|
||||
return True
|
||||
|
||||
def message_new(self, cr, uid, msg, custom_values=None, context=None):
|
||||
@@ -434,7 +418,6 @@ class project_issue(crm.crm_case, osv.osv):
|
||||
return res_id
|
||||
|
||||
def message_update(self, cr, uid, ids, msg, vals=None, default_act='pending', context=None):
|
||||
|
||||
if vals is None:
|
||||
vals = {}
|
||||
|
||||
@@ -479,6 +462,45 @@ class project_issue(crm.crm_case, osv.osv):
|
||||
default['name'] = issue['name'] + _(' (copy)')
|
||||
return super(project_issue, self).copy(cr, uid, id, default=default,
|
||||
context=context)
|
||||
|
||||
# -------------------------------------------------------
|
||||
# OpenChatter methods and notifications
|
||||
# -------------------------------------------------------
|
||||
|
||||
def get_needaction_user_ids(self, cr, uid, ids, context=None):
|
||||
result = dict.fromkeys(ids, [])
|
||||
for obj in self.browse(cr, uid, ids, context=context):
|
||||
if obj.state == 'draft' and obj.user_id:
|
||||
result[obj.id] = [obj.user_id.id]
|
||||
return result
|
||||
|
||||
def message_get_subscribers(self, cr, uid, ids, context=None):
|
||||
sub_ids = self.message_get_subscribers_ids(cr, uid, ids, context=context);
|
||||
for obj in self.browse(cr, uid, ids, context=context):
|
||||
if obj.user_id:
|
||||
sub_ids.append(obj.user_id.id)
|
||||
return self.pool.get('res.users').read(cr, uid, sub_ids, context=context)
|
||||
|
||||
def case_get_note_msg_prefix(self, cr, uid, id, context=None):
|
||||
return 'Project issue '
|
||||
|
||||
def convert_to_task_send_note(self, cr, uid, ids, context=None):
|
||||
message = _("Project issue has been <b>converted</b> in to task.")
|
||||
return self.message_append_note(cr, uid, ids, body=message, context=context)
|
||||
|
||||
def create_send_note(self, cr, uid, ids, context=None):
|
||||
message = _("Project issue has been <b>created</b>.")
|
||||
return self.message_append_note(cr, uid, ids, body=message, context=context)
|
||||
|
||||
def case_escalate_send_note(self, cr, uid, ids, context=None):
|
||||
for obj in self.browse(cr, uid, ids, context=context):
|
||||
if obj.project_id:
|
||||
message = _("has been <b>escalated</b> to <em>'%s'</em>.") % (obj.project_id.name)
|
||||
obj.message_append_note(body=message, context=context)
|
||||
else:
|
||||
message = _("has been <b>escalated</b>.")
|
||||
obj.message_append_note(body=message, context=context)
|
||||
return True
|
||||
|
||||
project_issue()
|
||||
|
||||
@@ -490,11 +512,11 @@ class project(osv.osv):
|
||||
}
|
||||
|
||||
def _check_escalation(self, cr, uid, ids, context=None):
|
||||
project_obj = self.browse(cr, uid, ids[0], context=context)
|
||||
if project_obj.project_escalation_id:
|
||||
if project_obj.project_escalation_id.id == project_obj.id:
|
||||
return False
|
||||
return True
|
||||
project_obj = self.browse(cr, uid, ids[0], context=context)
|
||||
if project_obj.project_escalation_id:
|
||||
if project_obj.project_escalation_id.id == project_obj.id:
|
||||
return False
|
||||
return True
|
||||
|
||||
_constraints = [
|
||||
(_check_escalation, 'Error! You cannot assign escalation to the same project!', ['project_escalation_id'])
|
||||
|
||||
@@ -54,7 +54,12 @@
|
||||
<group colspan="4" col="6">
|
||||
<field name="name"/>
|
||||
<field name="project_id" required="True" on_change="on_change_project(project_id)"/>
|
||||
<field name="categ_id" widget="selection" domain="[('object_id.model', '=', 'project.issue')]"/>
|
||||
<group colspan="2" col="3">
|
||||
<field name="categ_id" widget="selection" domain="[('object_id.model', '=', 'project.issue')]"/>
|
||||
<button string="Send New Email"
|
||||
name="%(mail.action_email_compose_message_wizard)d"
|
||||
icon="terp-mail-message-new" type="action"/>
|
||||
</group>
|
||||
<field name="user_id"/>
|
||||
<field name="version_id" colspan="2" widget="selection"/>
|
||||
<group colspan="2" col="4">
|
||||
@@ -91,41 +96,9 @@
|
||||
<button name="case_reset" string="Reset to New" states="done,cancel" type="object" icon="gtk-convert"/>
|
||||
</group>
|
||||
</page>
|
||||
<page string="Communication & History" groups="base.group_extended">
|
||||
<group colspan="4">
|
||||
<field colspan="4" name="email_cc" string="Global CC" widget="email"/>
|
||||
</group>
|
||||
<field name="message_ids" colspan="4" nolabel="1" mode="tree" readonly="1">
|
||||
<tree string="History">
|
||||
<field name="display_text" string="History Information"/>
|
||||
<field name="email_from" invisible="1"/>
|
||||
<button
|
||||
string="Reply" attrs="{'invisible': [('email_from', '=', False)]}"
|
||||
name="%(mail.action_email_compose_message_wizard)d"
|
||||
context="{'mail.compose.message.mode':'reply', 'message_id':active_id}"
|
||||
icon="terp-mail-replied" type="action" />
|
||||
</tree>
|
||||
</field>
|
||||
<separator colspan="4"/>
|
||||
<button string="Add Internal Note"
|
||||
name="%(crm.action_crm_add_note)d"
|
||||
context="{'model': 'crm.lead' }"
|
||||
icon="terp-document-new" type="action" />
|
||||
<button string="Send New Email"
|
||||
name="%(mail.action_email_compose_message_wizard)d"
|
||||
icon="terp-mail-message-new" type="action"/>
|
||||
</page>
|
||||
<page string="Extra Info" groups="base.group_no_one">
|
||||
<group col="2" colspan="2">
|
||||
<separator colspan="2" string="Date"/>
|
||||
<field name="create_date"/>
|
||||
<field name="write_date" />
|
||||
<field name="date_closed"/>
|
||||
<field name="date_open"/>
|
||||
<field name="date_action_last"/>
|
||||
</group>
|
||||
<group colspan="2" col="2">
|
||||
<separator string="Statistics" colspan="2" col="2"/>
|
||||
<page string="Extra Info" groups="base.group_extended">
|
||||
<group col="4" colspan="4">
|
||||
<separator string="Statistics" colspan="4" col="4"/>
|
||||
<field name="day_open"/>
|
||||
<field name="day_close"/>
|
||||
<field name="working_hours_open" widget="float_time"/>
|
||||
@@ -133,13 +106,14 @@
|
||||
<field name="inactivity_days"/>
|
||||
<field name="days_since_creation"/>
|
||||
</group>
|
||||
<group colspan="2" col="2">
|
||||
<separator string="References" colspan="2"/>
|
||||
<field name="id"/>
|
||||
<field name="active"/>
|
||||
<group colspan="4" col="4">
|
||||
<separator string="References" colspan="4"/>
|
||||
<field name="id"/>
|
||||
<field name="active"/>
|
||||
</group>
|
||||
</page>
|
||||
</notebook>
|
||||
<field name="message_ids_social" colspan="4" widget="ThreadView" nolabel="1"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
Reference in New Issue
Block a user