openerp-community-reviewer team mailing list archive
-
openerp-community-reviewer team
-
Mailing list archive
-
Message #01377
[Merge] lp:~dreis-pt/project-service/7.0-service_desk-dr into lp:project-service
Daniel Reis has proposed merging lp:~dreis-pt/project-service/7.0-service_desk-dr into lp:project-service.
Requested reviews:
Project Core Editors (project-core-editors)
For more details, see:
https://code.launchpad.net/~dreis-pt/project-service/7.0-service_desk-dr/+merge/195270
New modules for managing Service Desks:
Organize teams in Projects, but allow to link tasks and issues to contracts
--
https://code.launchpad.net/~dreis-pt/project-service/7.0-service_desk-dr/+merge/195270
Your team Project Core Editors is requested to review the proposed merge of lp:~dreis-pt/project-service/7.0-service_desk-dr into lp:project-service.
=== modified file 'service_desk/__init__.py' (properties changed: +x to -x)
--- service_desk/__init__.py 2012-12-21 18:34:07 +0000
+++ service_desk/__init__.py 2013-11-14 17:39:36 +0000
@@ -1,4 +1,4 @@
# -*- coding: utf-8 -*-
-import crm_categ
-import project_issue
+import analytic_contact
+import project
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
=== modified file 'service_desk/__openerp__.py' (properties changed: +x to -x)
--- service_desk/__openerp__.py 2013-03-04 16:16:31 +0000
+++ service_desk/__openerp__.py 2013-11-14 17:39:36 +0000
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
##############################################################################
#
-# Copyright (C) 2012 Daniel Reis
+# Copyright (C) 2012-2013 Daniel Reis
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
@@ -18,50 +18,40 @@
#
##############################################################################
{
- 'name': 'Service Desk Central',
- 'version': '0.1',
+ 'name': 'Service Desk',
+ 'summary': 'Use Projects for Service Desks and service teams',
+ 'version': '1.1',
"category": "Project Management",
'description': """\
-Concentrates all request forms in a single place.
-These can be broad Categories for Project Issues or forms from other modules,
-such as CRM Claims or HR Leave requests.
-
-The items/categories available are defined in:
-Project -> Configuration -> Issue -> Categories.
-
-Each one is representend by an icon and a description.
-When clicking on a Service Desk item, the module will find what Action should
-be executed. It this defition is found on it's form or on a parent, it will be
-used. If not, it an Action opening the Project Issue's default form will be
-used.
-
-When opening the Action, two variables are set in the "context":
- * A default master Category (`default_master_categ_id`), the id for the
- selected Category.
- * A default Service Team (`default_section_id`), from the selected Category
- or it's parent tree.
-
-For a quick start the module installs two Actions to be used here:
- * "Issues": opens the standard Project Issue form.
- * "New Incident": opens a showcase simple Issue form.
-
-The showcase form demonstrates the usage of these two default values:
-the Issue's Category selection list is limited to the Service Desk category
-children, and the Service Team is automatically selected.
+Available service desks/teams are defined as Projects.
+
+Incoming requests and tasks can then be related to customer Contracts and
+service locations through additional two additional fields provided by the
+module. This is optional, and is defined on a per project basis.
+
+
+Features:
+
+ * Project has new field "Use Analytic Account?",
+ with options "Yes" and "Required"
+ * Task has new fields "Analytic Account/Contract" and "Location",
+ visible or required depending on the Project's setting
+ * Analytic Account has a new field "Contact", where you can set it's
+ location/address (a Partner). It will be picked as the default locations
+ when the Analytic Account is selected in a Task or Issue.
+
+(Icon image credits to Everaldo Coelho, Crystal icon set)
""",
'author': 'Daniel Reis',
'website': '',
'depends': [
- 'project_issue',
- 'project_issue_department',
- 'project_issue_sequences',
- 'crm_categ_hierarchy',
+ 'project',
],
'data': [
- 'project_issue_view.xml',
- 'crm_categ_view.xml',
+ 'analytic_contact_view.xml',
+ 'service_desk_view.xml',
],
- 'installable': False,
+ 'installable': True,
'application': True,
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
=== added file 'service_desk/analytic_contact.py'
--- service_desk/analytic_contact.py 1970-01-01 00:00:00 +0000
+++ service_desk/analytic_contact.py 2013-11-14 17:39:36 +0000
@@ -0,0 +1,32 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# Copyright (C) 2013 Daniel Reis
+#
+# 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 openerp.osv import fields, orm
+
+
+class AnalyticAccount(orm.Model):
+ """Add Contact to Analytic Accounts"""
+ _inherit = 'account.analytic.account'
+ _columns = {
+ 'contact_id': fields.many2one(
+ 'res.partner', 'Contact',
+ domain="[('parent_id','child_of',partner_id)"
+ ",('parent_id','!=',False)]"),
+ }
=== added file 'service_desk/analytic_contact_view.xml'
--- service_desk/analytic_contact_view.xml 1970-01-01 00:00:00 +0000
+++ service_desk/analytic_contact_view.xml 2013-11-14 17:39:36 +0000
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+ <data>
+
+ <record id="view_account_analytic_account_form_contact" model="ir.ui.view">
+ <field name="name">view_account_analytic_account_form_contact</field>
+ <field name="model">account.analytic.account</field>
+ <field name="inherit_id" ref="analytic.view_account_analytic_account_form"/>
+ <field name="arch" type="xml">
+
+ <field name="manager_id" position="after">
+ <field name="contact_id"/>
+ </field>
+
+ </field>
+ </record>
+
+ </data>
+</openerp>
=== removed file 'service_desk/crm_categ.py'
--- service_desk/crm_categ.py 2013-01-31 13:27:23 +0000
+++ service_desk/crm_categ.py 1970-01-01 00:00:00 +0000
@@ -1,74 +0,0 @@
-# -*- coding: utf-8 -*-
-##############################################################################
-#
-# Copyright (C) 2012 Daniel Reis
-#
-# 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 openerp.osv import fields, orm
-
-
-class crm_case_categ(orm.Model):
- _inherit = 'crm.case.categ'
- _columns = {
- 'section_id': fields.many2one('crm.case.section', 'Service Team'),
- 'icon': fields.binary('Icon'),
- 'act_window_id': fields.many2one('ir.actions.act_window', 'Action'),
- 'show_service_desk': fields.boolean('Show in Service Desk'),
- }
-
- def open_issue_form(self, cr, uid, ids, context=None):
-
- def get_categ_section_id(categ_res):
- """Get Category Team, searching parents upward if necessary"""
- return categ_res.section_id.id or (
- hasattr(categ_res, 'parent_id') and
- categ_res.parent_id and
- get_categ_section_id(categ_res.parent_id))
-
- def get_custom_action_dict(categ_res):
- """Get dict with the custom Action details for a Category
- If none, use the standard Project Issue form."""
- action_id = categ_res.act_window_id.id \
- or self.pool.get('ir.model.data').get_object_reference(
- cr, uid, 'project_issue', 'project_issue_categ_act0')[1]
- return self.pool.get('ir.actions.act_window')\
- .read(cr, uid, action_id, context=context)
-
- def merge_dict_into_text(text, add_dict):
- """Return the text string with the dict contents added to it.
- Ex: `"{'a':1}"` merged with `{'b': 2}` returns `"{'a':1, 'b':2}"`.
- """
- if ':' not in text:
- return str(add_dict)
- else:
- return '{%s, %s}' % (text.strip()[1:-1], str(add_dict)[1:-1])
-
- obj = self.browse(cr, uid, ids, context=context)[0]
- action = get_custom_action_dict(obj)
- action.update({
- 'domain': [('categ_id', 'child_of', obj.id)],
- 'context': merge_dict_into_text(
- action.get('context', ''),
- {'default_master_categ_id': obj.id,
- 'default_section_id': get_categ_section_id(obj) or False,
- 'group_by': False, # remove inherited section_id grouping
- },
- ),
- })
- return action
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
=== removed file 'service_desk/crm_categ_view.xml'
--- service_desk/crm_categ_view.xml 2012-12-21 18:34:07 +0000
+++ service_desk/crm_categ_view.xml 1970-01-01 00:00:00 +0000
@@ -1,75 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<openerp>
- <data>
-
- <!-- FORM crm.case.category -->
- <record id="crm_case_categ_view_icon" model="ir.ui.view">
- <field name="name">crm.case.categ.form.icon</field>
- <field name="model">crm.case.categ</field>
- <field name="inherit_id" ref="crm_categ_hierarchy.crm_case_categ-view_dreis"/>
- <field name="arch" type="xml">
- <field name="note" position="replace">
- <separator colspan="4" string="Service Desk"/>
- <group colspan="2" col="2">
- <field name="act_window_id"/>
- <field name="show_service_desk"/>
- <field name="note"/>
- </group>
- <group colspan="2" col="1">
- <field name="icon" widget='image' nolabel="1"/>
- </group>
- </field>
- </field>
- </record>
-
- <!-- KANBAN crm.case.categories -->
- <record model="ir.ui.view" id="categ_view_kanban">
- <field name="name">categ_view_kanban</field>
- <field name="model">crm.case.categ</field>
- <field name="type">kanban</field>
- <field name="arch" type="xml">
-
- <kanban>
- <field name="name"/>
- <field name="note"/>
- <field name="section_id"/>
- <templates>
- <t t-name="kanban-box">
- <div class="oe_module_vignette">
- <a type="object" name="open_issue_form">
- <img t-att-src="kanban_image('crm.case.categ', 'icon', record.id.value)" class="oe_module_icon"/>
- </a>
- <div class="oe_module_desc">
- <h4><a type="edit"><field name="name"/></a></h4>
- <p><field name="note"/></p>
- <button type="object" name="open_issue_form" class="oe_button">Create</button>
- </div>
- </div>
- </t>
- </templates>
-
- </kanban>
-
- </field>
- </record>
-
-
- <record id="open_categ_view" model="ir.actions.act_window">
- <field name="name">Service Desk</field>
- <field name="res_model">crm.case.categ</field>
- <field name="view_type">form</field>
- <field name="view_mode">kanban</field>
- <field name="domain">[('object_id.model','=','project.issue'),('show_service_desk','=',True)]</field>
- <field name="context">{'group_by':'section_id'}</field>
- </record>
- <menuitem action="open_categ_view" id="menu_categ_view" parent="project.menu_project_management"/>
-
-
- </data>
-</openerp>
-
-
-
-
-
-
=== added directory 'service_desk/i18n'
=== added file 'service_desk/i18n/service_desk.pot'
--- service_desk/i18n/service_desk.pot 1970-01-01 00:00:00 +0000
+++ service_desk/i18n/service_desk.pot 2013-11-14 17:39:36 +0000
@@ -0,0 +1,78 @@
+# Translation of OpenERP Server.
+# This file contains the translation of the following modules:
+# * service_desk
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: OpenERP Server 7.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-11-14 09:22+0000\n"
+"PO-Revision-Date: 2013-11-14 09:22+0000\n"
+"Last-Translator: <>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: service_desk
+#: model:ir.model,name:service_desk.model_project_project
+msgid "Project"
+msgstr ""
+
+#. module: service_desk
+#: model:ir.model,name:service_desk.model_account_analytic_location
+msgid "account.analytic.location"
+msgstr ""
+
+#. module: service_desk
+#: model:ir.model,name:service_desk.model_project_task
+msgid "Task"
+msgstr ""
+
+#. module: service_desk
+#: selection:project.project,use_analytic_account:0
+msgid "No"
+msgstr ""
+
+#. module: service_desk
+#: selection:project.project,use_analytic_account:0
+msgid "Required"
+msgstr ""
+
+#. module: service_desk
+#: model:ir.model,name:service_desk.model_account_analytic_account
+msgid "Analytic Account"
+msgstr ""
+
+#. module: service_desk
+#: view:project.task:0
+msgid "onchange_project(project_id)"
+msgstr ""
+
+#. module: service_desk
+#: field:account.analytic.account,contact_id:0
+msgid "Contact"
+msgstr ""
+
+#. module: service_desk
+#: field:project.task,location_id:0
+msgid "Location"
+msgstr ""
+
+#. module: service_desk
+#: field:project.project,use_analytic_account:0
+#: field:project.task,use_analytic_account:0
+msgid "Use Analytic Account"
+msgstr ""
+
+#. module: service_desk
+#: selection:project.project,use_analytic_account:0
+msgid "Optional"
+msgstr ""
+
+#. module: service_desk
+#: field:project.task,analytic_account_id:0
+msgid "Contract/Analytic"
+msgstr ""
+
=== added file 'service_desk/project.py'
--- service_desk/project.py 1970-01-01 00:00:00 +0000
+++ service_desk/project.py 2013-11-14 17:39:36 +0000
@@ -0,0 +1,87 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# Copyright (C) 2013 Daniel Reis
+#
+# 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 openerp.osv import fields, orm
+
+
+class ProjectProject(orm.Model):
+ _inherit = 'project.project'
+ _columns = {
+ 'use_analytic_account': fields.selection(
+ [('no', 'No'), ('yes', 'Optional'), ('req', 'Required')],
+ 'Use Analytic Account'),
+ }
+ _defaults = {
+ 'use_analytic_account': 'no',
+ }
+
+
+class ProjectTask(orm.Model):
+ """
+ Add related `Analytic Account` and service `Location`.
+ A Location can be any Contact Partner of the AA's Partner.
+ Other logic is possible, such as maintaining a specific list of service
+ addresses for each Contract, but that's out of scpoce here.
+ Modules implementing these other possibilities are very welcome..
+ """
+ _inherit = 'project.task'
+ _columns = {
+ 'analytic_account_id': fields.many2one(
+ 'account.analytic.account', 'Contract/Analytic',
+ domain="[('type','in',['normal','contract'])]"),
+ 'location_id': fields.many2one(
+ 'res.partner', 'Location',
+ domain="[('parent_id','child_of',partner_id)]"),
+ 'use_analytic_account': fields.related(
+ 'project_id', 'use_analytic_account',
+ type='char', string="Use Analytic Account"),
+ }
+
+ def onchange_project(self, cr, uid, id, project_id, context=None):
+ # on_change is necessary to populate fields on Create, before saving
+ try:
+ # try applying a parent's onchange, may it exist
+ res = super(ProjectTask, self).onchange_project(
+ cr, uid, id, project_id, context) or {}
+ except AttributeError:
+ res = {}
+
+ if project_id:
+ obj = self.pool.get('project.project').browse(
+ cr, uid, project_id, context=context)
+ res.setdefault('value', {})
+ res['value']['use_analytic_account'] = (
+ obj.use_analytic_account or 'no')
+ return res
+
+ def onchange_analytic(self, cr, uid, id, analytic_id, context=None):
+ res = {}
+ model = self.pool.get('account.analytic.account')
+ obj = model.browse(cr, uid, analytic_id, context=context)
+ if obj:
+ # "contact_id" and "department_id" may be provided by other modules
+ fldmap = [ # analytic_account field -> task field
+ ('partner_id', 'partner_id'),
+ ('contact_id', 'location_id'),
+ ('department_id', 'department_id')]
+ res['value'] = {dest: getattr(obj, orig).id
+ for orig, dest in fldmap
+ if hasattr(obj, orig) and getattr(obj, orig)}
+ return res
=== removed file 'service_desk/project_issue.py'
--- service_desk/project_issue.py 2013-01-31 14:42:51 +0000
+++ service_desk/project_issue.py 1970-01-01 00:00:00 +0000
@@ -1,139 +0,0 @@
-# -*- coding: utf-8 -*-
-##############################################################################
-#
-# Copyright (C) 2012 Daniel Reis
-#
-# 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 openerp.osv import fields, orm
-from datetime import datetime
-
-
-class project_issue(orm.Model):
- _inherit = 'project.issue'
-
- # `_compute_day` backported from v7.0 (just copied actually)
- # Allows the Issue's `project_id` to be optional.
- #---- START ----
- def _compute_day(self, cr, uid, ids, fields, args, context=None):
- """
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param ids: List of Openday’s IDs
- @return: difference between current date and log date
- @param context: A standard dictionary for contextual values
- """
- cal_obj = self.pool.get('resource.calendar')
- res_obj = self.pool.get('resource.resource')
-
- res = {}
- for issue in self.browse(cr, uid, ids, context=context):
- res[issue.id] = {}
- for field in fields:
- duration = 0
- ans = False
- hours = 0
-
- date_create = datetime.strptime(issue.create_date, "%Y-%m-%d %H:%M:%S")
- if field in ['working_hours_open','day_open']:
- if issue.date_open:
- date_open = datetime.strptime(issue.date_open, "%Y-%m-%d %H:%M:%S")
- ans = date_open - date_create
- date_until = issue.date_open
- #Calculating no. of working hours to open the issue
- 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']:
- if issue.date_closed:
- date_close = datetime.strptime(issue.date_closed, "%Y-%m-%d %H:%M:%S")
- date_until = issue.date_closed
- ans = date_close - date_create
- #Calculating no. of working hours to close the issue
- 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']:
- if issue.create_date:
- days_since_creation = datetime.today() - datetime.strptime(issue.create_date, "%Y-%m-%d %H:%M:%S")
- res[issue.id][field] = days_since_creation.days
- continue
-
- elif field in ['inactivity_days']:
- res[issue.id][field] = 0
- if issue.date_action_last:
- inactive_days = datetime.today() - datetime.strptime(issue.date_action_last, '%Y-%m-%d %H:%M:%S')
- res[issue.id][field] = inactive_days.days
- continue
- if ans:
- resource_id = False
- if issue.user_id:
- resource_ids = res_obj.search(cr, uid, [('user_id','=',issue.user_id.id)])
- if resource_ids and len(resource_ids):
- resource_id = resource_ids[0]
- duration = float(ans.days)
- if issue.project_id and issue.project_id.resource_calendar_id:
- duration = float(ans.days) * 24
-
- new_dates = cal_obj.interval_min_get(cr, uid,
- issue.project_id.resource_calendar_id.id,
- date_create,
- duration, resource=resource_id)
- no_days = []
- date_until = datetime.strptime(date_until, '%Y-%m-%d %H:%M:%S')
- for in_time, out_time in new_dates:
- if in_time.date not in no_days:
- no_days.append(in_time.date)
- if out_time > date_until:
- break
- duration = len(no_days)
-
- if field in ['working_hours_open', 'working_hours_close']:
- res[issue.id][field] = hours
- else:
- res[issue.id][field] = abs(float(duration))
-
- return res
- #---- END ----
-
- _columns = {
- 'regarding_uid': fields.many2one('res.users', 'Regarding User',
- help="User affected by the Issue"),
-
- # `_compute_day` backport: redeclaring columns in order to
- # rebuild references for the replaced method
- #---- START ----
- 'days_since_creation': fields.function(_compute_day, string='Days since creation date', \
- multi='compute_day', type="integer", help="Difference in days between creation date and current date"),
- 'day_open': fields.function(_compute_day, string='Days to Open', \
- multi='compute_day', type="float", store=True),
- 'day_close': fields.function(_compute_day, string='Days to Close', \
- multi='compute_day', type="float", store=True),
- 'working_hours_open': fields.function(_compute_day, string='Working Hours to Open the Issue', \
- multi='compute_day', type="float", store=True),
- 'working_hours_close': fields.function(_compute_day, string='Working Hours to Close the Issue', \
- multi='compute_day', type="float", store=True),
- 'inactivity_days': fields.function(_compute_day, string='Days since last action', \
- multi='compute_day', type="integer", help="Difference in days between last action and current date"),
- #---- END ----
- }
- _defaults = {
- 'regarding_uid': lambda s, cr, uid, c: uid,
- }
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
=== removed file 'service_desk/project_issue_view.xml'
--- service_desk/project_issue_view.xml 2013-01-31 13:20:15 +0000
+++ service_desk/project_issue_view.xml 1970-01-01 00:00:00 +0000
@@ -1,134 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<openerp>
- <data>
-
- <!--PROJECT ISSUE FORM -->
- <record id="project_issue_form_view_simple" model="ir.ui.view">
- <field name="name">project_issue_form_view_simple</field>
- <field name="model">project.issue</field>
- <field name="type">form</field>
- <field name="priority" eval="20"/>
- <field name="arch" type="xml">
-
- <field name="name"/>
- <field name="ref"/>
- <field name="categ_id" required="1"
- domain="[('parent_id','=', default_master_categ_id)]"/>
- <field name="section_id" readonly="1" string="Service Team"/>
- <field name="regarding_uid"/>
- <field name="user_id"/>
- <!-- field name="department_id"/ -->
- <field name="priority"/>
-
- <notebook colspan="4">
- <page string="General">
- <separator string="Description" colspan="4"/>
- <field name="description" nolabel="1" colspan="4"/>
- <separator colspan="4"/>
- <group col="8" colspan="4">
- <field name="state" widget="statusbar" statusbar_visible="draft,open,done" statusbar_colors="{"pending":"blue"}"/>
- <button name="case_cancel" string="Cancel" states="draft,open,pending" type="object" icon="gtk-cancel"/>
- <button name="case_open" string="Open" states="draft,pending" type="object" icon="gtk-go-forward"/>
- <button name="case_close" string="Done" states="open,draft,pending" type="object" icon="terp-dialog-close"/>
- <button name="case_pending" string="Pending" states="draft,open" type="object" icon="gtk-media-pause"/>
- <button name="case_escalate" string="Escalate" states="open,draft,pending" type="object" icon="gtk-go-up"/>
- <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" widget="char" size="512"/>
- </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>
- <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>
- </page>
- </notebook>
- </field>
- </record>
-
- <!-- ACTION to open New Issue form -->
- <record id="action_newissue_wizard" model="ir.actions.act_window">
- <field name="name">Incidents</field>
- <field name="res_model">project.issue</field>
- <field name="view_type">form</field>
- <field name="view_mode">tree,calendar</field>
- <field name="view_id" eval="False"/>
- <field name="domain" eval=""/>
- <field name="context">{}</field>
- <field name="search_view_id" ref="project_issue.view_project_issue_filter"/>
- </record>
-
- <record model="ir.actions.act_window.view" id="action_newissue_wizard_viewtree">
- <field name="sequence" eval="1"/>
- <field name="view_mode">tree</field>
- <field name="view_id" ref="project_issue.project_issue_tree_view"/>
- <field name="act_window_id" ref="action_newissue_wizard"/>
- </record>
-
- <record model="ir.actions.act_window.view" id="action_newissue_wizard_viewform">
- <field name="sequence" eval="2"/>
- <field name="view_mode">form</field>
- <field name="view_id" ref="project_issue_form_view_simple"/>
- <field name="act_window_id" ref="action_newissue_wizard"/>
- </record>
-
- <record model="ir.actions.act_window.view" id="action_newissue_wizard_viewcal">
- <field name="sequence" eval="3"/>
- <field name="view_mode">calendar</field>
- <field name="view_id" ref="project_issue.project_issue_calendar_view"/>
- <field name="act_window_id" ref="action_newissue_wizard"/>
- </record>
-
- </data>
-</openerp>
-
-
-
-
-
-
-
-
-
-
-
=== added file 'service_desk/service_desk_view.xml'
--- service_desk/service_desk_view.xml 1970-01-01 00:00:00 +0000
+++ service_desk/service_desk_view.xml 2013-11-14 17:39:36 +0000
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+ <data>
+
+ <!-- Project form -->
+ <record id="view_project_form_sdesk" model="ir.ui.view">
+ <field name="name">view_project_form_sdesk</field>
+ <field name="model">project.project</field>
+ <field name="inherit_id" ref="project.edit_project"/>
+ <field name="arch" type="xml">
+
+ <field name="parent_id" position="after">
+ <field name="use_analytic_account"/>
+ </field>
+
+ </field>
+ </record>
+
+
+ <!-- Project Task form -->
+ <record id="view_project_task_form_sdesk" model="ir.ui.view">
+ <field name="name">view_project_task_form_sdesk</field>
+ <field name="model">project.task</field>
+ <field name="inherit_id" ref="project.view_task_form2"/>
+ <field name="arch" type="xml">
+
+ <field name="project_id" position="before">
+ <field name="use_analytic_account" invisible="1"/>
+ <field name="analytic_account_id" on_change="onchange_analytic(analytic_account_id)"
+ attrs="{'invisible':[('use_analytic_account','not in',['yes','req'])],'required':[('use_analytic_account','=','req')]}"/>
+ <field name="location_id"
+ attrs="{'invisible':[('use_analytic_account','not in',['yes','req'])],'required':[('use_analytic_account','=','req')]}"/>
+ </field>
+
+ <field name="project_id" position="attributes">
+ <attribute name="on_change">onchange_project(project_id)</attribute>
+ </field>
+
+ </field>
+ </record>
+
+
+ <!-- Project Task filter -->
+ <record id="view_task_search_form" model="ir.ui.view">
+ <field name="name">view_task_search_form_sdesk</field>
+ <field name="model">project.task</field>
+ <field name="inherit_id" ref="project.view_task_search_form"/>
+ <field name="arch" type="xml">
+
+ <field name="name" position="after">
+ <filter name="analytic_account_id"/>
+ <filter name="location_id"/>
+ </field>
+
+ </field>
+ </record>
+
+
+ </data>
+</openerp>
=== modified file 'service_desk/static/src/img/icon.png' (properties changed: +x to -x)
=== added directory 'service_desk_issue'
=== added file 'service_desk_issue/__init__.py'
--- service_desk_issue/__init__.py 1970-01-01 00:00:00 +0000
+++ service_desk_issue/__init__.py 2013-11-14 17:39:36 +0000
@@ -0,0 +1,2 @@
+# -*- coding: utf-8 -*-
+import project
=== added file 'service_desk_issue/__openerp__.py'
--- service_desk_issue/__openerp__.py 1970-01-01 00:00:00 +0000
+++ service_desk_issue/__openerp__.py 2013-11-14 17:39:36 +0000
@@ -0,0 +1,41 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# Copyright (C) 2012-2013 Daniel Reis
+#
+# 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/>.
+#
+##############################################################################
+{
+ 'name': 'Service Desk for Issues',
+ 'summary': 'Use Project Issues for Service Desks and service teams',
+ 'version': '1.1',
+ "category": "Project Management",
+ 'description': """\
+This module extends the ``service_desk`` module to also work with Issues.
+Please refer to that module's description.
+""",
+ 'author': 'Daniel Reis',
+ 'website': '',
+ 'depends': [
+ 'project_issue',
+ 'service_desk',
+ ],
+ 'data': [
+ 'service_desk_view.xml',
+ ],
+ 'installable': True,
+ 'auto_install': True,
+}
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
=== added directory 'service_desk_issue/i18n'
=== added file 'service_desk_issue/i18n/service_desk_issue.pot'
--- service_desk_issue/i18n/service_desk_issue.pot 1970-01-01 00:00:00 +0000
+++ service_desk_issue/i18n/service_desk_issue.pot 2013-11-14 17:39:36 +0000
@@ -0,0 +1,88 @@
+# Translation of OpenERP Server.
+# This file contains the translation of the following modules:
+# * service_desk_issue
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: OpenERP Server 7.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-11-14 16:43+0000\n"
+"PO-Revision-Date: 2013-11-14 16:43+0000\n"
+"Last-Translator: <>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: service_desk_issue
+#: help:project.issue.reassign,project_id:0
+msgid "Project this issue should belong to"
+msgstr ""
+
+#. module: service_desk_issue
+#: field:project.issue,project_code:0
+msgid "Project Code"
+msgstr ""
+
+#. module: service_desk_issue
+#: field:project.issue,analytic_partner_id:0
+msgid "Analytic Account Partner"
+msgstr ""
+
+#. module: service_desk_issue
+#: model:ir.model,name:service_desk_issue.model_project_issue
+msgid "Project Issue"
+msgstr ""
+
+#. module: service_desk_issue
+#: view:project.issue:0
+msgid "{'default_project_id': project_id, 'default_name': name, 'default_analytic_account_id': analytic_account_id, 'default_location_id': location_id}"
+msgstr ""
+
+#. module: service_desk_issue
+#: model:ir.model,name:service_desk_issue.model_project_issue_delegate
+#: model:ir.model,name:service_desk_issue.model_project_issue_reassign
+msgid "Issue Reassign"
+msgstr ""
+
+#. module: service_desk_issue
+#: view:project.issue:0
+msgid "onchange_project(project_id)"
+msgstr ""
+
+#. module: service_desk_issue
+#: view:project.issue:0
+msgid "Contract"
+msgstr ""
+
+#. module: service_desk_issue
+#: help:project.issue.reassign,user_id:0
+msgid "User you want to assign this issue to"
+msgstr ""
+
+#. module: service_desk_issue
+#: field:project.issue.reassign,project_id:0
+msgid "Project"
+msgstr ""
+
+#. module: service_desk_issue
+#: field:project.issue.reassign,user_id:0
+msgid "Assign To"
+msgstr ""
+
+#. module: service_desk_issue
+#: field:project.issue,location_id:0
+msgid "Location"
+msgstr ""
+
+#. module: service_desk_issue
+#: field:project.issue,use_analytic_account:0
+msgid "Use Analytic Account"
+msgstr ""
+
+#. module: service_desk_issue
+#: field:project.issue,analytic_account_id:0
+msgid "Contract/Analytic"
+msgstr ""
+
=== added file 'service_desk_issue/project.py'
--- service_desk_issue/project.py 1970-01-01 00:00:00 +0000
+++ service_desk_issue/project.py 2013-11-14 17:39:36 +0000
@@ -0,0 +1,73 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# Copyright (C) 2013 Daniel Reis
+#
+# 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 openerp.osv import fields, orm
+from openerp.tools.translate import _
+
+
+class ProjectIssue(orm.Model):
+ _inherit = 'project.issue'
+
+ _columns = {
+ 'analytic_account_id': fields.many2one(
+ 'account.analytic.account', 'Contract/Analytic',
+ domain="[('type','in',['normal','contract'])]"),
+ 'analytic_partner_id': fields.related(
+ 'analytic_account_id', 'partner_id', relation='res.partner',
+ type='many2one', string="Analytic Account Partner"),
+ 'location_id': fields.many2one(
+ 'res.partner', 'Location',
+ domain="[('parent_id','child_of',analytic_partner_id)]"),
+ 'use_analytic_account': fields.related(
+ 'project_id', 'use_analytic_account',
+ type='char', string="Use Analytic Account"),
+ 'project_code': fields.related(
+ 'project_id', 'code', type='char', string="Project Code"),
+ }
+
+ def onchange_project(self, cr, uid, id, project_id, context=None):
+ # on_change is necessary to populate fields on Create, before saving
+ try:
+ res = super(ProjectIssue, self).onchange_project(
+ cr, uid, id, project_id, context) or {}
+ except AttributeError:
+ res = {}
+
+ if project_id:
+ obj = self.pool.get('project.project').browse(
+ cr, uid, project_id, context=context)
+ res.setdefault('value', {})
+ res['value']['use_analytic_account'] = (
+ obj.use_analytic_account or 'no')
+ return res
+
+ def onchange_analytic(self, cr, uid, id, analytic_id, context=None):
+ res = {}
+ model = self.pool.get('account.analytic.account')
+ obj = model.browse(cr, uid, analytic_id, context=context)
+ if obj:
+ # "contact_id" and "department_id" may be provided by other modules
+ fldmap = [ # analytic_account field -> issue field
+ ('partner_id', 'analytic_partner_id'),
+ ('contact_id', 'location_id'),
+ ('department_id', 'department_id')]
+ res['value'] = {dest: getattr(obj, orig).id
+ for orig, dest in fldmap if hasattr(obj, orig)}
+ return res
=== added file 'service_desk_issue/service_desk_view.xml'
--- service_desk_issue/service_desk_view.xml 1970-01-01 00:00:00 +0000
+++ service_desk_issue/service_desk_view.xml 2013-11-14 17:39:36 +0000
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+ <data>
+
+
+ <!-- Project Issue form -->
+ <record id="project_issue_form_view_sdesk" model="ir.ui.view">
+ <field name="name">project_issue_form_view_sdesk</field>
+ <field name="model">project.issue</field>
+ <field name="inherit_id" ref="project_issue.project_issue_form_view"/>
+ <field name="arch" type="xml">
+
+ <!-- See Analytic Account and Location, if Project is configured so -->
+ <field name="categ_ids" position="after">
+ <group>
+ <field name="use_analytic_account" invisible="1"/>
+ <field name="analytic_partner_id" invisible="1"/>
+ <field name="analytic_account_id" on_change="onchange_analytic(analytic_account_id)"
+ attrs="{'invisible':[('use_analytic_account','not in',['yes','req'])],'required':[('use_analytic_account','=','req')]}"/>
+ <field name="location_id"
+ attrs="{'invisible':[('use_analytic_account','not in',['yes','req'])],'required':[('use_analytic_account','=','req')]}"/>
+ </group>
+ </field>
+
+ <!-- Use on_change on Project to force updating of "related" fields, used in attrs rules -->
+ <!-- Make Project mandatory, to avoid "lost" Issues not assigned to any Service Team -->
+ <field name="project_id" position="attributes">
+ <attribute name="on_change">onchange_project(project_id)</attribute>
+ <attribute name="required">1</attribute>
+ </field>
+
+ <!-- Make Deadline field available -->
+ <field name="priority" position="after">
+ <field name="date_deadline"/>
+ </field>
+
+ <!-- Friendly default values when creating a ralated Task -->
+ <field name="task_id" position="attributes">
+ <attribute name="context">{'default_project_id': project_id, 'default_name': name, 'default_analytic_account_id': analytic_account_id, 'default_location_id': location_id}</attribute>
+ </field>
+
+ </field>
+ </record>
+
+
+ <!-- Project Issue tree list -->
+ <record model="ir.ui.view" id="project_issue_tree_view_sdesk">
+ <field name="name">project_issue_tree_view_sdesk</field>
+ <field name="model">project.issue</field>
+ <field name="inherit_id" ref="project_issue.project_issue_tree_view"/>
+ <field name="arch" type="xml">
+
+ <!-- See Analytic Account, if Project is configured so -->
+ <field name="name" position="after">
+ <field name="use_analytic_account" invisible="1"/>
+ <field name="analytic_partner_id" invisible="1"/>
+ <field name="analytic_account_id"
+ attrs="{'invisible':[('use_analytic_account','not in',['yes','req'])],'required':[('use_analytic_account','=','req')]}"/>
+ </field>
+
+ </field>
+ </record>
+
+
+ <!-- Project Issue filter -->
+ <record id="view_project_issue_filter_sdesk" model="ir.ui.view">
+ <field name="name">view_project_issue_filter_sdesk</field>
+ <field name="model">project.issue</field>
+ <field name="inherit_id" ref="project_issue.view_project_issue_filter"/>
+ <field name="arch" type="xml">
+
+ <!-- Filter by Analytic Account -->
+ <field name="id" position="after">
+ <field name="analytic_account_id" string="Contract"/>
+ </field>
+
+ </field>
+ </record>
+
+
+ <!-- Fixed: search view was not actually being used -->
+ <record id="project_issue.act_project_project_2_project_issue_all" model="ir.actions.act_window">
+ <field name="search_view_id" ref="project_issue.view_project_issue_filter"/>
+ </record>
+
+
+ </data>
+</openerp>
+