[IMP] Create social chatter for 'Project Issues'.

bzr revid: jra@tinyerp.com-20120305120341-57h2iiytumjtpa9v
This commit is contained in:
Jiten (OpenERP) 2012-03-05 17:33:41 +05:30
parent 324eb16d3c
commit 3529cca4f1
5 changed files with 191 additions and 138 deletions

View File

@ -392,45 +392,44 @@ class hr_applicant(crm.crm_case, osv.osv):
return res
def _case_open_notification(self, case, context=None):
message = _("Changed Status to <b>In Progress<b>.")
message = _("Changed Status to <b>in Progress<b>.")
case.message_append_note('' ,message, type='notification')
return True
def _case_close_notification(self, case, context=None):
case[0].message_mark_done(context)
if case[0].emp_id:
message = _("Applicant is <b>Hired</b> and employee created.")
message = _("Applicant is <b>hired</b> and employee created.")
case[0].message_append_note('' ,message, type='notification')
else:
message = _("Applicant is <b>Hired</b>.")
message = _("Applicant is <b>hired</b>.")
case[0].message_append_note('' ,message, type='notification')
return True
def _case_cancel_notification(self, case, context=None):
case[0].message_mark_done(context=context)
message = _("Applicant is <b>Cancelled<b>.")
message = _("Applicant is <b>cancelled<b>.")
case[0].message_append_note('' ,message, type="notification")
return True
def _case_pending_notification(self, case, context=None):
message = _("Changed Status to <b>Pending<b>.")
message = _("Changed Status to <b>pending<b>.")
case[0].message_append_note('' ,message, type='notification')
return True
def _case_reset_notification(self, cr, uid, ids, context=None):
for obj in self.browse(cr, uid, ids, context=context):
self.message_append_note(cr, uid, ids, _('System notification'),
_("Changed Status to <b>New<b>."), type='notification', need_action_user_id=obj.user_id.id, context=context)
_("Changed Status to <b>new<b>."), type='notification', need_action_user_id=obj.user_id.id, context=context)
return True
def create_notificate(self, cr, uid, ids, context=None):
for obj in self.browse(cr, uid, ids, context=context):
self.message_subscribe(cr, uid, ids, [obj.user_id.id], context=context)
self.message_append_note(cr, uid, ids, _('System notification'),
_("Applicant is <b>Created</b>."), type='notification', need_action_user_id=obj.user_id.id, context=context)
_("Applicant is <b>created</b>."), type='notification', need_action_user_id=obj.user_id.id, context=context)
return True
def create(self, cr, uid, vals, context=None):
obj_id = super(hr_applicant, self).create(cr, uid, vals, context=context)
self.create_notificate(cr, uid, [obj_id], context=context)
@ -518,7 +517,7 @@ class hr_applicant(crm.crm_case, osv.osv):
if 'stage_id' in vals and vals['stage_id']:
stage = self.pool.get('hr.recruitment.stage').browse(cr, uid, vals['stage_id'], context=context)
self.message_append_note(cr, uid, ids, _('System notification'),
_("Changed Stage to <b>%s</b>.") % stage.name, type='notification')
_("Changed stage to <b>%s</b>.") % stage.name, type='notification')
return super(hr_applicant,self).write(cr, uid, ids, vals, context=context)
hr_applicant()

View File

@ -53,6 +53,7 @@ class project(osv.osv):
_name = "project.project"
_description = "Project"
_inherits = {'account.analytic.account': "analytic_account_id"}
_inherit = ['mail.thread']
def search(self, cr, user, args, offset=0, limit=None, order=None, context=None, count=False):
if user == 1:
@ -457,6 +458,7 @@ class task(osv.osv):
_description = "Task"
_log_create = True
_date_name = "date_start"
_inherit = ['mail.thread']
def _resolve_project_id_from_context(self, cr, uid, context=None):

View File

@ -97,6 +97,7 @@
</page>
</notebook>
<newline/>
<field name="message_ids_social" colspan="4" widget="ThreadView" nolabel="1"/>
</form>
</field>
</record>
@ -309,6 +310,7 @@
<field colspan="4" name="notes" nolabel="1"/>
</page>
</notebook>
<field name="message_ids_social" colspan="4" widget="ThreadView" nolabel="1"/>
</form>
</field>
</record>

View File

@ -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 users 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 users 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),
@ -251,15 +224,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,
@ -319,11 +283,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'
}
self._convert_to_task_notification(cr, uid, ids, context)
cases = self.browse(cr, uid, ids)
self._case_pending_notification(cases, context=context)
case_obj.write(cr, uid, [bug.id], vals)
return {
@ -356,28 +322,39 @@ 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):
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]})
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]})
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 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]})
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]})
return True
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')
if 'type_id' in vals and vals['type_id']:
stage = self.pool.get('project.task.type').browse(cr, uid, vals['type_id'], context=context)
self.message_append_note(cr, uid, ids, _('System notification'),
_("Changed stage to <b>%s</b>.") % stage.name, type='notification')
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:
@ -385,13 +362,113 @@ 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):
def _case_open_notification(self, case, context=None):
if case.state:
message = _("Issue is <b>opened</b>.")
case.message_append_note('' ,message, type='notification')
return True
def _case_close_notification(self, case, context=None):
case[0].message_mark_done(context)
message = _("Issue <em>%s</em> is <b>closed</b>.")
case[0].message_append_note('' ,message, type='notification')
return True
def _convert_to_task_notification(self, cr, uid, ids, context=None):
for obj in self.browse(cr, uid, ids, context=context):
self.message_append_note(cr, uid, ids, _('System notification'),
_("Issue is <b>converted</b> in to task."), type='notification', context=context)
return True
def create_notificate(self, cr, uid, ids, context=None):
for obj in self.browse(cr, uid, ids, context=context):
self.message_append_note(cr, uid, ids, _('System notification'),
_("Issue is <b>created</b>."), type='notification', need_action_user_id=False, context=context)
return True
def _case_pending_notification(self, case, context=None):
message = _("Issue is on <b>pending<b>.")
case[0].message_append_note('' ,message, type='notification')
return True
def _case_escalate_notification(self, case, context=None):
if case[0].project_id.project_escalation_id.user_id.id:
message = _("Issue is <b>escalated</b> from project <em>'%s'</em>.") % (case[0].project_id.name)
case[0].message_append_note('' ,message, type='notification', need_action_user_id=case[0].project_id.project_escalation_id.user_id.id, context=context)
else:
message = _("Issue is <b>escalated</b>.")
case[0].message_append_note('' ,message, type='notification', need_action_user_id=False, context=context)
return True
def _case_reset_notification(self, cr, uid, ids, context=None):
for obj in self.browse(cr, uid, ids, context=context):
self.message_append_note(cr, uid, ids, _('System notification'),
_("Issue is reset as <b>new<b>."), type='notification', need_action_user_id=obj.user_id.id, context=context)
return True
def _case_cancel_notification(self, case, context=None):
case[0].message_mark_done(context=context)
message = _("Issue is <b>cancelled<b>.")
case[0].message_append_note('' ,message, type="notification")
return True
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})
self._case_reset_notification(cr, uid, ids, context)
return res
def case_pending(self, cr, uid, ids, context=None):
"""Marks case as pending"""
res = super(project_issue, self).case_pending(cr, uid, ids, context)
self.write(cr, uid, ids, context)
return res
def case_cancel(self, cr, uid, ids, context=None):
"""Overrides cancel for crm_case for setting probability
"""
res = super(project_issue, self).case_cancel(cr, uid, ids, context)
self.write(cr, uid, ids, context)
return res
def create(self, cr, uid, vals, context=None):
obj_id = super(project_issue, self).create(cr, uid, vals, context=context)
self.create_notificate(cr, uid, [obj_id], context=context)
return obj_id
def case_open(self, cr, uid, ids, context=None):
"""
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of case's Ids
"""
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_close(self, cr, uid, ids, context=None):
"""
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of case's Ids
"""
res = super(project_issue, self).case_close(cr, uid, ids, context)
return res
def case_escalate(self, cr, uid, ids, context=None):
"""Escalates case to top level
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of case Ids
@param *args: Tuple Value for additional Params
"""
cases = self.browse(cr, uid, ids)
for case in cases:
@ -405,7 +482,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_notification(cases, context=context)
return True
def message_new(self, cr, uid, msg, custom_values=None, context=None):
@ -437,7 +514,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 = {}
@ -493,11 +569,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'])

View File

@ -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">
@ -92,55 +97,24 @@
<button name="case_reset" string="Reset to New" states="done,cancel" type="object" icon="gtk-convert"/>
</group>
</page>
<page string="Communication &amp; History" groups="base.group_extended">
<group colspan="4">
<field colspan="4" name="email_cc" string="Global CC" widget="url"/>
<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"/>
<field name="working_hours_close" widget="float_time"/>
<field name="inactivity_days"/>
<field name="days_since_creation"/>
</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_extended">
<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"/>
<field name="day_open"/>
<field name="day_close"/>
<field name="working_hours_open" widget="float_time"/>
<field name="working_hours_close" widget="float_time"/>
<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>