summaryrefslogtreecommitdiff
path: root/addons/project_issue/project_issue.py
diff options
context:
space:
mode:
Diffstat (limited to 'addons/project_issue/project_issue.py')
-rw-r--r--addons/project_issue/project_issue.py146
1 files changed, 62 insertions, 84 deletions
diff --git a/addons/project_issue/project_issue.py b/addons/project_issue/project_issue.py
index 8bcac4581c3..f23f6b6a286 100644
--- a/addons/project_issue/project_issue.py
+++ b/addons/project_issue/project_issue.py
@@ -19,19 +19,16 @@
#
##############################################################################
+from datetime import datetime
+
from openerp import SUPERUSER_ID
-from openerp.addons.base_status.base_stage import base_stage
-from openerp.addons.project.project import _TASK_STATE
+from openerp import tools
from openerp.addons.crm import crm
-from datetime import datetime
from openerp.osv import fields, osv, orm
-from openerp.tools.translate import _
-import binascii
-import time
-from openerp import tools
from openerp.tools import html2plaintext
+from openerp.tools.translate import _
-class project_issue_version(osv.osv):
+class project_issue_version(osv.Model):
_name = "project.issue.version"
_order = "name desc"
_columns = {
@@ -42,37 +39,33 @@ class project_issue_version(osv.osv):
'active': 1,
}
-class project_issue(base_stage, osv.osv):
+class project_issue(osv.Model):
_name = "project.issue"
_description = "Project Issue"
_order = "priority, create_date desc"
_inherit = ['mail.thread', 'ir.needaction_mixin']
+ _mail_post_access = 'read'
_track = {
- 'state': {
- 'project_issue.mt_issue_new': lambda self, cr, uid, obj, ctx=None: obj['state'] in ['new', 'draft'],
- 'project_issue.mt_issue_closed': lambda self, cr, uid, obj, ctx=None: obj['state'] == 'done',
- 'project_issue.mt_issue_started': lambda self, cr, uid, obj, ctx=None: obj['state'] == 'open',
- },
'stage_id': {
- 'project_issue.mt_issue_stage': lambda self, cr, uid, obj, ctx=None: obj['state'] not in ['new', 'draft', 'done', 'open'],
+ 'project_issue.mt_issue_new': lambda self, cr, uid, obj, ctx=None: obj.stage_id and obj.stage_id.sequence == 1,
+ 'project_issue.mt_issue_stage': lambda self, cr, uid, obj, ctx=None: obj.stage_id and obj.stage_id.sequence != 1,
+ },
+ 'user_id': {
+ 'project_issue.mt_issue_assigned': lambda self, cr, uid, obj, ctx=None: obj.user_id and obj.user_id.id,
},
'kanban_state': {
- 'project_issue.mt_issue_blocked': lambda self, cr, uid, obj, ctx=None: obj['kanban_state'] == 'blocked',
+ 'project_issue.mt_issue_blocked': lambda self, cr, uid, obj, ctx=None: obj.kanban_state == 'blocked',
},
}
- def create(self, cr, uid, vals, context=None):
- if context is None:
- context = {}
- if not vals.get('stage_id'):
- ctx = context.copy()
- if vals.get('project_id'):
- ctx['default_project_id'] = vals['project_id']
- vals['stage_id'] = self._get_default_stage_id(cr, uid, context=ctx)
- # context: no_log, because subtype already handle this
- create_context = dict(context, mail_create_nolog=True)
- return super(project_issue, self).create(cr, uid, vals, context=create_context)
+ def _get_default_partner(self, cr, uid, context=None):
+ project_id = self._get_default_project_id(cr, uid, context)
+ if project_id:
+ project = self.pool.get('project.project').browse(cr, uid, project_id, context=context)
+ if project and project.partner_id:
+ return project.partner_id.id
+ return False
def _get_default_project_id(self, cr, uid, context=None):
""" Gives default project by checking if present in the context """
@@ -81,7 +74,7 @@ class project_issue(base_stage, osv.osv):
def _get_default_stage_id(self, cr, uid, context=None):
""" Gives default stage_id """
project_id = self._get_default_project_id(cr, uid, context=context)
- return self.stage_find(cr, uid, [], project_id, [('state', '=', 'draft')], context=context)
+ return self.stage_find(cr, uid, [], project_id, [('sequence', '=', 1)], context=context)
def _resolve_project_id_from_context(self, cr, uid, context=None):
""" Returns ID of project based on the value of 'default_project_id'
@@ -215,6 +208,10 @@ class project_issue(base_stage, osv.osv):
return res
def on_change_project(self, cr, uid, ids, project_id, context=None):
+ if project_id:
+ project = self.pool.get('project.project').browse(cr, uid, project_id, context=context)
+ if project and project.partner_id:
+ return {'value': {'partner_id': project.partner_id.id}}
return {}
def _get_issue_task(self, cr, uid, ids, context=None):
@@ -247,13 +244,6 @@ class project_issue(base_stage, osv.osv):
'partner_id': fields.many2one('res.partner', 'Contact', select=1),
'company_id': fields.many2one('res.company', 'Company'),
'description': fields.text('Private Note'),
- 'state': fields.related('stage_id', 'state', type="selection", store=True,
- selection=_TASK_STATE, string="Status", readonly=True,
- help='The status is set to \'Draft\', when a case is created.\
- If the case is in progress the status is set to \'Open\'.\
- When the case is over, the status is set to \'Done\'.\
- If the case needs to be reviewed then the status is \
- set to \'Pending\'.'),
'kanban_state': fields.selection([('normal', 'Normal'),('blocked', 'Blocked'),('done', 'Ready for next stage')], 'Kanban State',
track_visibility='onchange',
help="A Issue's kanban state indicates special situations affecting it:\n"
@@ -267,6 +257,7 @@ class project_issue(base_stage, osv.osv):
# Project Issue fields
'date_closed': fields.datetime('Closed', readonly=True,select=True),
'date': fields.datetime('Date'),
+ 'date_last_stage_update': fields.datetime('Last Stage Update', select=True),
'channel_id': fields.many2one('crm.case.channel', 'Channel', help="Communication channel."),
'categ_ids': fields.many2many('project.category', string='Tags'),
'priority': fields.selection(crm.AVAILABLE_PRIORITIES, 'Priority', select=True),
@@ -302,13 +293,12 @@ class project_issue(base_stage, osv.osv):
_defaults = {
'active': 1,
- 'partner_id': lambda s, cr, uid, c: s._get_default_partner(cr, uid, c),
- 'email_from': lambda s, cr, uid, c: s._get_default_email(cr, uid, c),
'stage_id': lambda s, cr, uid, c: s._get_default_stage_id(cr, uid, c),
- 'section_id': lambda s, cr, uid, c: s._get_default_section_id(cr, uid, c),
'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'crm.helpdesk', context=c),
'priority': crm.AVAILABLE_PRIORITIES[2][0],
'kanban_state': 'normal',
+ 'date_last_stage_update': fields.datetime.now(),
+ 'user_id': lambda obj, cr, uid, context: uid,
}
_group_by_full = {
@@ -361,7 +351,7 @@ class project_issue(base_stage, osv.osv):
})
vals = {
'task_id': new_task_id,
- 'stage_id': self.stage_find(cr, uid, [bug], bug.project_id.id, [('state', '=', 'pending')], context=context),
+ 'stage_id': self.stage_find(cr, uid, [bug], bug.project_id.id, [('sequence', '=', 1)], context=context),
}
message = _("Project issue <b>converted</b> to task.")
self.message_post(cr, uid, [bug.id], body=message, context=context)
@@ -389,19 +379,25 @@ class project_issue(base_stage, osv.osv):
return super(project_issue, self).copy(cr, uid, id, default=default,
context=context)
+ def create(self, cr, uid, vals, context=None):
+ if context is None:
+ context = {}
+ if vals.get('project_id') and not context.get('default_project_id'):
+ context['default_project_id'] = vals.get('project_id')
+
+ # context: no_log, because subtype already handle this
+ create_context = dict(context, mail_create_nolog=True)
+ return super(project_issue, self).create(cr, uid, vals, context=create_context)
+
def write(self, cr, uid, ids, vals, context=None):
-
- #Update last action date every time the user changes the stage
+ # stage change: update date_last_stage_update
if 'stage_id' in vals:
- vals['date_action_last'] = time.strftime(tools.DEFAULT_SERVER_DATETIME_FORMAT)
- state = self.pool.get('project.task.type').browse(cr, uid, vals['stage_id'], context=context).state
- for issue in self.browse(cr, uid, ids, context=context):
- # Change from draft to not draft EXCEPT cancelled: The issue has been opened -> set the opening date
- if issue.state == 'draft' and state not in ('draft', 'cancelled'):
- vals['date_open'] = time.strftime(tools.DEFAULT_SERVER_DATETIME_FORMAT)
- # Change from not done to done: The issue has been closed -> set the closing date
- if issue.state != 'done' and state == 'done':
- vals['date_closed'] = time.strftime(tools.DEFAULT_SERVER_DATETIME_FORMAT)
+ vals['date_last_stage_update'] = fields.datetime.now()
+ if 'kanban_state' not in vals:
+ vals['kanban_state'] = 'normal'
+ # user_id change: update date_start
+ if vals.get('user_id'):
+ vals['date_start'] = fields.datetime.now()
return super(project_issue, self).write(cr, uid, ids, vals, context)
@@ -411,13 +407,6 @@ class project_issue(base_stage, 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_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 get_empty_list_help(self, cr, uid, help, context=None):
context['empty_list_help_model'] = 'project.project'
context['empty_list_help_id'] = context.get('default_project_id')
@@ -466,11 +455,6 @@ class project_issue(base_stage, osv.osv):
return stage_ids[0]
return False
- def case_cancel(self, cr, uid, ids, context=None):
- """ Cancels case """
- self.case_set(cr, uid, ids, 'cancelled', {'active': True}, context=context)
- return True
-
def case_escalate(self, cr, uid, ids, context=None):
cases = self.browse(cr, uid, ids)
for case in cases:
@@ -483,7 +467,6 @@ class project_issue(base_stage, osv.osv):
self.pool.get('project.task').write(cr, uid, [case.task_id.id], {'project_id': data['project_id'], 'user_id': False})
else:
raise osv.except_osv(_('Warning!'), _('You cannot escalate this issue.\nThe relevant Project has not configured the Escalation Project!'))
- self.case_set(cr, uid, ids, 'draft', data, context=context)
return True
# -------------------------------------------------------
@@ -495,17 +478,6 @@ class project_issue(base_stage, osv.osv):
return [issue.project_id.message_get_reply_to()[0] if issue.project_id else False
for issue in self.browse(cr, uid, ids, context=context)]
- def check_mail_message_access(self, cr, uid, mids, operation, model_obj=None, context=None):
- """ mail.message document permission rule: can post a new message if can read
- because of portal document. """
- if not model_obj:
- model_obj = self
- if operation == 'create':
- model_obj.check_access_rights(cr, uid, 'read')
- model_obj.check_access_rule(cr, uid, mids, 'read', context=context)
- else:
- return super(project_issue, self).check_mail_message_access(cr, uid, mids, operation, model_obj=model_obj, context=context)
-
def message_get_suggested_recipients(self, cr, uid, ids, context=None):
recipients = super(project_issue, self).message_get_suggested_recipients(cr, uid, ids, context=context)
try:
@@ -523,21 +495,19 @@ class project_issue(base_stage, osv.osv):
through message_process.
This override updates the document according to the email.
"""
- if custom_values is None: custom_values = {}
- if context is None: context = {}
+ if custom_values is None:
+ custom_values = {}
+ if context is None:
+ context = {}
context['state_to'] = 'draft'
-
- desc = html2plaintext(msg.get('body')) if msg.get('body') else ''
-
defaults = {
'name': msg.get('subject') or _("No Subject"),
- 'description': desc,
'email_from': msg.get('from'),
'email_cc': msg.get('cc'),
'partner_id': msg.get('author_id', False),
'user_id': False,
}
- if msg.get('priority'):
+ if msg.get('priority'):
defaults['priority'] = msg.get('priority')
defaults.update(custom_values)
@@ -578,8 +548,8 @@ class project_issue(base_stage, osv.osv):
if context is None:
context = {}
res = super(project_issue, self).message_post(cr, uid, thread_id, body=body, subject=subject, type=type, subtype=subtype, parent_id=parent_id, attachments=attachments, context=context, content_subtype=content_subtype, **kwargs)
- if thread_id:
- self.write(cr, SUPERUSER_ID, thread_id, {'date_action_last': time.strftime(tools.DEFAULT_SERVER_DATETIME_FORMAT)}, context=context)
+ if thread_id and subtype:
+ self.write(cr, SUPERUSER_ID, thread_id, {'date_action_last': fields.datetime.now()}, context=context)
return res
@@ -593,7 +563,7 @@ class project(osv.Model):
res = dict.fromkeys(ids, 0)
issue_ids = self.pool.get('project.issue').search(cr, uid, [('project_id', 'in', ids)])
for issue in self.pool.get('project.issue').browse(cr, uid, issue_ids, context):
- if issue.state not in ('done', 'cancelled'):
+ if issue.stage_id and not issue.stage_id.fold:
res[issue.project_id.id] += 1
return res
@@ -653,6 +623,14 @@ class project_project(osv.Model):
elif vals.get('use_issues') and not vals.get('use_tasks'):
vals['alias_model'] = 'project.issue'
+ def on_change_use_tasks_or_issues(self, cr, uid, ids, use_tasks, use_issues, context=None):
+ values = {}
+ if use_tasks and not use_issues:
+ values['alias_model'] = 'project.task'
+ elif not use_tasks and use_issues:
+ values['alias_model'] = 'project.issues'
+ return {'value': values}
+
def create(self, cr, uid, vals, context=None):
self._check_create_write_values(cr, uid, vals, context=context)
return super(project_project, self).create(cr, uid, vals, context=context)