From 3529cca4f1fa8aca8131d5d7486c827b9d41a54d Mon Sep 17 00:00:00 2001 From: "Jiten (OpenERP)" Date: Mon, 5 Mar 2012 17:33:41 +0530 Subject: [PATCH 01/13] [IMP] Create social chatter for 'Project Issues'. bzr revid: jra@tinyerp.com-20120305120341-57h2iiytumjtpa9v --- addons/hr_recruitment/hr_recruitment.py | 17 +- addons/project/project.py | 2 + addons/project/project_view.xml | 2 + addons/project_issue/project_issue.py | 242 +++++++++++++------- addons/project_issue/project_issue_view.xml | 66 ++---- 5 files changed, 191 insertions(+), 138 deletions(-) diff --git a/addons/hr_recruitment/hr_recruitment.py b/addons/hr_recruitment/hr_recruitment.py index 2a6bc0db64c..18d3f8545ce 100644 --- a/addons/hr_recruitment/hr_recruitment.py +++ b/addons/hr_recruitment/hr_recruitment.py @@ -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 In Progress.") + message = _("Changed Status to in Progress.") 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 Hired and employee created.") + message = _("Applicant is hired and employee created.") case[0].message_append_note('' ,message, type='notification') else: - message = _("Applicant is Hired.") + message = _("Applicant is hired.") 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 Cancelled.") + message = _("Applicant is cancelled.") case[0].message_append_note('' ,message, type="notification") return True def _case_pending_notification(self, case, context=None): - message = _("Changed Status to Pending.") + message = _("Changed Status to pending.") 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 New."), type='notification', need_action_user_id=obj.user_id.id, context=context) + _("Changed Status to new."), 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 Created."), type='notification', need_action_user_id=obj.user_id.id, context=context) + _("Applicant is created."), 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 %s.") % stage.name, type='notification') + _("Changed stage to %s.") % stage.name, type='notification') return super(hr_applicant,self).write(cr, uid, ids, vals, context=context) hr_applicant() diff --git a/addons/project/project.py b/addons/project/project.py index 9966ad02ee8..b9a3ccd0578 100644 --- a/addons/project/project.py +++ b/addons/project/project.py @@ -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): diff --git a/addons/project/project_view.xml b/addons/project/project_view.xml index 26abe86fe99..fa5d1539e60 100644 --- a/addons/project/project_view.xml +++ b/addons/project/project_view.xml @@ -97,6 +97,7 @@ + @@ -309,6 +310,7 @@ + diff --git a/addons/project_issue/project_issue.py b/addons/project_issue/project_issue.py index b950bfd0b34..646be577211 100644 --- a/addons/project_issue/project_issue.py +++ b/addons/project_issue/project_issue.py @@ -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), @@ -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 %s.") % 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 opened.") + 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 %s is closed.") + 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 converted 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 created."), type='notification', need_action_user_id=False, context=context) + return True + + def _case_pending_notification(self, case, context=None): + message = _("Issue is on pending.") + 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 escalated from project '%s'.") % (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 escalated.") + 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 new."), 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 cancelled.") + 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 user’s 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 user’s 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 user’s 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']) diff --git a/addons/project_issue/project_issue_view.xml b/addons/project_issue/project_issue_view.xml index d50501279fd..1d6a560158d 100644 --- a/addons/project_issue/project_issue_view.xml +++ b/addons/project_issue/project_issue_view.xml @@ -54,7 +54,12 @@ - + + +