diff options
| author | Divyesh Makwana (Open ERP) <mdi@tinyerp.com> | 2012-04-12 12:06:52 +0530 |
|---|---|---|
| committer | Divyesh Makwana (Open ERP) <mdi@tinyerp.com> | 2012-04-12 12:06:52 +0530 |
| commit | 492c856bbcec5a855bcf38dd2dbd26c0892e8b24 (patch) | |
| tree | 6e2398a1a5bacc60a26c702c231783fa204d0140 /addons/project_issue | |
| parent | 2df24b6d9212e2a52d75e616db668dce7afa75ef (diff) | |
| parent | e44315701dd1bdb6996f24c40be7ac0640aaffe5 (diff) | |
[Merge] Merge with main branch
bzr revid: mdi@tinyerp.com-20120412063652-e4vgtl5cbr117c4g
Diffstat (limited to 'addons/project_issue')
| -rw-r--r-- | addons/project_issue/__init__.py | 1 | ||||
| -rw-r--r-- | addons/project_issue/__openerp__.py | 1 | ||||
| -rw-r--r-- | addons/project_issue/project_issue.py | 194 | ||||
| -rw-r--r-- | addons/project_issue/project_issue_menu.xml | 3 | ||||
| -rw-r--r-- | addons/project_issue/project_issue_view.xml | 54 | ||||
| -rw-r--r-- | addons/project_issue/res_config.py | 46 | ||||
| -rw-r--r-- | addons/project_issue/res_config_view.xml | 26 |
7 files changed, 198 insertions, 127 deletions
diff --git a/addons/project_issue/__init__.py b/addons/project_issue/__init__.py index f519698a60c..b04f25914c7 100644 --- a/addons/project_issue/__init__.py +++ b/addons/project_issue/__init__.py @@ -22,5 +22,6 @@ import project_issue import report +import res_config # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/project_issue/__openerp__.py b/addons/project_issue/__openerp__.py index 0d9db1a3bba..6ddbfb07ea4 100644 --- a/addons/project_issue/__openerp__.py +++ b/addons/project_issue/__openerp__.py @@ -52,6 +52,7 @@ and decide on their status as they evolve. 'security/project_issue_security.xml', 'security/ir.model.access.csv', "board_project_issue_view.xml", + "res_config_view.xml", ], 'demo_xml': ['project_issue_demo.xml'], 'test': [ diff --git a/addons/project_issue/project_issue.py b/addons/project_issue/project_issue.py index 4cb98fab0e5..e7c2194d304 100644 --- a/addons/project_issue/project_issue.py +++ b/addons/project_issue/project_issue.py @@ -48,45 +48,7 @@ class project_issue(crm.crm_case, osv.osv): _name = "project.issue" _description = "Project Issue" _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 + _inherit = ['ir.needaction_mixin', 'mail.thread'] def _compute_day(self, cr, uid, ids, fields, args, context=None): """ @@ -114,7 +76,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']: @@ -123,7 +86,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']: @@ -168,6 +132,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') @@ -183,16 +166,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), @@ -247,15 +220,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, @@ -285,14 +249,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') @@ -314,12 +277,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'), @@ -351,28 +315,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: @@ -380,14 +354,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'} @@ -400,7 +384,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): @@ -432,7 +416,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 = {} @@ -477,6 +460,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() @@ -488,11 +510,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_menu.xml b/addons/project_issue/project_issue_menu.xml index 086a0c43de3..dd61992a555 100644 --- a/addons/project_issue/project_issue_menu.xml +++ b/addons/project_issue/project_issue_menu.xml @@ -1,6 +1,7 @@ <?xml version="1.0"?> <openerp> <data> + <!-- ALL BUGS --> @@ -53,7 +54,7 @@ view_mode="tree,form,calendar,graph" view_type="form"/> - <menuitem name="Issues" id="menu_project_issue_track" parent="base.menu_aftersale" + <menuitem name="Issues" id="menu_project_issue_track" parent="project.menu_project_management" action="project_issue_categ_act0" sequence="15"/> </data> </openerp> diff --git a/addons/project_issue/project_issue_view.xml b/addons/project_issue/project_issue_view.xml index 8a93b6c90a4..d209bfe8958 100644 --- a/addons/project_issue/project_issue_view.xml +++ b/addons/project_issue/project_issue_view.xml @@ -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" groups="base.group_no_one"/> </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> diff --git a/addons/project_issue/res_config.py b/addons/project_issue/res_config.py new file mode 100644 index 00000000000..1944444923a --- /dev/null +++ b/addons/project_issue/res_config.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Business Applications +# Copyright (C) 2004-2012 OpenERP S.A. (<http://openerp.com>). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +############################################################################## + +from osv import osv, fields + +class project_issue_settings(osv.osv_memory): + _name = 'project.config.settings' + _inherit = ['project.config.settings', 'fetchmail.config.settings'] + + _columns = { + 'fetchmail_issue': fields.boolean("Create issues from an email account", + fetchmail_model='project.issue', fetchmail_name='Incoming issues', + help="""Allows you to configure your incoming mail server, and create issues from incoming emails."""), + 'issue_server' : fields.char('Server', size=256), + 'issue_port' : fields.integer('Port'), + 'issue_type': fields.selection([ + ('pop', 'POP Server'), + ('imap', 'IMAP Server'), + ('local', 'Local Server'), + ], 'Type'), + 'issue_is_ssl': fields.boolean('SSL/TLS', help="Connections are encrypted with SSL/TLS through a dedicated port (default: IMAPS=993, POP=995)"), + 'issue_user' : fields.char('Username', size=256), + 'issue_password' : fields.char('Password', size=1024), + } + + _defaults = { + 'issue_type': 'pop', + } diff --git a/addons/project_issue/res_config_view.xml b/addons/project_issue/res_config_view.xml new file mode 100644 index 00000000000..d2cc501bc96 --- /dev/null +++ b/addons/project_issue/res_config_view.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<openerp> + <data> + + <record id="view_config_settings" model="ir.ui.view"> + <field name="name">Project Application</field> + <field name="model">project.config.settings</field> + <field name="type">form</field> + <field name="inherit_id" ref="project.view_config_settings"/> + <field name="arch" type="xml"> + <group name="support" position="after"> + <field name="fetchmail_issue"/> + <group colspan="2" attrs="{'invisible': [('fetchmail_issue','=',False)]}"> + <field name="issue_server" attrs="{'required': [('fetchmail_issue','=',True)]}"/> + <field name="issue_type" on_change="onchange_fetchmail('issue', issue_type, issue_is_ssl)" attrs="{'required': [('fetchmail_issue','=',True)]}"/> + <field name="issue_port" attrs="{'required': [('fetchmail_issue','=',True)]}"/> + <field name="issue_is_ssl" on_change="onchange_fetchmail('issue', issue_type, issue_is_ssl)"/> + <field name="issue_user" attrs="{'required': [('fetchmail_issue','=',True)]}"/> + <field name="issue_password" password="True" attrs="{'required': [('fetchmail_issue','=',True)]}"/> + </group> + </group> + </field> + </record> + + </data> +</openerp> |
