+
+
+
+
+ report.crm.case.section.categ.stage
+ form
+ tree
+ [('name','=',time.strftime('%Y-%m-01'))]
+
+
+
+ report.crm.case.section.categ.stage
+ form
+ tree
+
+
+
+ #
+ # Cases by section, category and category2
+ #
+
+
+ CRM Report - Section, Category and Type(Tree)
+ report.crm.case.section.categ.categ2
+ tree
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ CRM Report - Section, Category and Type(Form)
+ report.crm.case.section.categ.categ2
+ form
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ report.crm.case.section.categ.categ2
+ form
+ tree
+ [('name','=',time.strftime('%Y-%m-01'))]
+
+
+
+ report.crm.case.section.categ.categ2
+ form
+ tree
+
+
+
+
diff --git a/addons/crm/process/crm_configuration_process.xml b/addons/crm/process/crm_configuration_process.xml
new file mode 100755
index 00000000000..8d69fff1001
--- /dev/null
+++ b/addons/crm/process/crm_configuration_process.xml
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/addons/crm/report/__init__.py b/addons/crm/report/__init__.py
index 59925053f66..ac2113a5deb 100644
--- a/addons/crm/report/__init__.py
+++ b/addons/crm/report/__init__.py
@@ -20,6 +20,7 @@
##############################################################################
import report_businessopp
+import crm_report
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/crm/report/crm_report.py b/addons/crm/report/crm_report.py
new file mode 100644
index 00000000000..991403ca090
--- /dev/null
+++ b/addons/crm/report/crm_report.py
@@ -0,0 +1,187 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2009 Tiny SPRL ().
+#
+# 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 .
+#
+##############################################################################
+
+from osv import fields,osv
+
+import tools.sql
+
+AVAILABLE_STATES = [
+ ('draft','Draft'),
+ ('open','Open'),
+ ('cancel', 'Cancelled'),
+ ('done', 'Closed'),
+ ('pending','Pending')
+]
+
+class report_crm_case_section_categ2(osv.osv):
+ _name = "report.crm.case.section.categ2"
+ _description = "Cases by section and category2"
+ _auto = False
+ _columns = {
+ 'name': fields.date('Month', readonly=True),
+ 'user_id':fields.many2one('res.users', 'User', readonly=True),
+ 'section_id':fields.many2one('crm.case.section', 'Section', readonly=True),
+ 'category2_id':fields.many2one('crm.case.category2', 'Type', readonly=True),
+ 'stage_id':fields.many2one('crm.case.stage', 'Stage', readonly=True),
+ 'amount_revenue': fields.float('Est.Revenue', readonly=True),
+ 'nbr': fields.integer('# of Cases', readonly=True),
+ 'state': fields.selection(AVAILABLE_STATES, 'State', size=16, readonly=True),
+ 'delay_close': fields.char('Delay Close', size=20, readonly=True),
+ }
+ _order = 'category2_id, section_id'
+
+ def init(self, cr):
+ tools.sql.drop_view_if_exists(cr, "report_crm_case_section_categ2")
+ cr.execute("""
+ create view report_crm_case_section_categ2 as (
+ select
+ min(c.id) as id,
+ to_char(c.create_date,'YYYY-MM')||'-01' as name,
+ c.user_id,
+ c.state,
+ c.category2_id,
+ c.stage_id,
+ c.section_id,
+ count(*) as nbr,
+ sum(planned_revenue) as amount_revenue,
+ to_char(avg(date_closed-c.create_date), 'DD"d" HH24:MI:SS') as delay_close
+ from
+ crm_case c
+ where c.category2_id is not null
+ group by to_char(c.create_date,'YYYY-MM'), c.user_id, c.state, c.stage_id, c.category2_id, c.section_id)""")
+
+report_crm_case_section_categ2()
+
+class report_crm_case_section_stage(osv.osv):
+ _name = "report.crm.case.section.stage"
+ _description = "Cases by section and stage"
+ _auto = False
+ _columns = {
+ 'name': fields.date('Month', readonly=True),
+ 'user_id':fields.many2one('res.users', 'User', readonly=True),
+ 'section_id':fields.many2one('crm.case.section', 'Section', readonly=True),
+ 'categ_id':fields.many2one('crm.case.categ', 'Category', readonly=True),
+ 'stage_id':fields.many2one('crm.case.stage', 'Stage', readonly=True),
+ 'amount_revenue': fields.float('Est.Revenue', readonly=True),
+ 'nbr': fields.integer('# of Cases', readonly=True),
+ 'state': fields.selection(AVAILABLE_STATES, 'State', size=16, readonly=True),
+ 'delay_close': fields.char('Delay Close', size=20, readonly=True),
+ }
+ _order = 'stage_id, section_id'
+
+ def init(self, cr):
+ tools.sql.drop_view_if_exists(cr, "report_crm_case_section_stage")
+ cr.execute("""
+ create view report_crm_case_section_stage as (
+ select
+ min(c.id) as id,
+ to_char(c.create_date,'YYYY-MM')||'-01' as name,
+ c.user_id,
+ c.state,
+ c.stage_id,
+ c.section_id,
+ count(*) as nbr,
+ sum(planned_revenue) as amount_revenue,
+ to_char(avg(date_closed-c.create_date), 'DD"d" HH24:MI:SS') as delay_close
+ from
+ crm_case c
+ where c.stage_id is not null
+ group by to_char(c.create_date,'YYYY-MM'), c.user_id, c.state, c.stage_id, c.section_id)""")
+
+report_crm_case_section_stage()
+
+class report_crm_case_section_categ_stage(osv.osv):
+ _name = "report.crm.case.section.categ.stage"
+ _description = "Cases by section, Category and stage"
+ _auto = False
+ _columns = {
+ 'name': fields.date('Month', readonly=True),
+ 'user_id':fields.many2one('res.users', 'User', readonly=True),
+ 'categ_id':fields.many2one('crm.case.categ', 'Category', readonly=True),
+ 'section_id':fields.many2one('crm.case.section', 'Section', readonly=True),
+ 'stage_id':fields.many2one('crm.case.stage', 'Stage', readonly=True),
+ 'nbr': fields.integer('# of Cases', readonly=True),
+ 'state': fields.selection(AVAILABLE_STATES, 'State', size=16, readonly=True),
+ 'delay_close': fields.char('Delay Close', size=20, readonly=True),
+ }
+ _order = 'stage_id, section_id, categ_id'
+
+ def init(self, cr):
+ tools.sql.drop_view_if_exists(cr, "report_crm_case_section_categ_stage")
+ cr.execute("""
+ create view report_crm_case_section_categ_stage as (
+ select
+ min(c.id) as id,
+ to_char(c.create_date,'YYYY-MM')||'-01' as name,
+ c.user_id,
+ c.categ_id,
+ c.state,
+ c.stage_id,
+ c.section_id,
+ count(*) as nbr,
+ to_char(avg(date_closed-c.create_date), 'DD"d" HH24:MI:SS') as delay_close
+ from
+ crm_case c
+ where c.categ_id is not null AND c.stage_id is not null
+ group by to_char(c.create_date,'YYYY-MM'), c.user_id, c.categ_id, c.state, c.stage_id, c.section_id)""")
+
+report_crm_case_section_categ_stage()
+
+class report_crm_case_section_categ_categ2(osv.osv):
+ _name = "report.crm.case.section.categ.categ2"
+ _description = "Cases by section, Category and Category2"
+ _auto = False
+ _columns = {
+ 'name': fields.date('Month', readonly=True),
+ 'user_id':fields.many2one('res.users', 'User', readonly=True),
+ 'categ_id':fields.many2one('crm.case.categ', 'Category', readonly=True),
+ 'category2_id':fields.many2one('crm.case.category2', 'Type', readonly=True),
+ 'section_id':fields.many2one('crm.case.section', 'Section', readonly=True),
+ 'stage_id':fields.many2one('crm.case.stage', 'Stage', readonly=True),
+ 'nbr': fields.integer('# of Cases', readonly=True),
+ 'state': fields.selection(AVAILABLE_STATES, 'State', size=16, readonly=True),
+ 'delay_close': fields.char('Delay Close', size=20, readonly=True),
+ }
+ _order = 'section_id, categ_id, category2_id'
+
+ def init(self, cr):
+ tools.sql.drop_view_if_exists(cr, "report_crm_case_section_categ_categ2")
+ cr.execute("""
+ create view report_crm_case_section_categ_categ2 as (
+ select
+ min(c.id) as id,
+ to_char(c.create_date, 'YYYY-MM')||'-01' as name,
+ c.user_id,
+ c.categ_id,
+ c.category2_id,
+ c.state,
+ c.stage_id,
+ c.section_id,
+ count(*) as nbr,
+ to_char(avg(date_closed-c.create_date), 'DD"d" HH24:MI:SS') as delay_close
+ from
+ crm_case c
+ where c.categ_id is not null AND c.category2_id is not null
+ group by to_char(c.create_date,'YYYY-MM'), c.user_id, c.categ_id, c.category2_id, c.state, c.stage_id, c.section_id)""")
+
+report_crm_case_section_categ_categ2()
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+
diff --git a/addons/crm/security/ir.model.access.csv b/addons/crm/security/ir.model.access.csv
index 5be7146b9f1..7a08f037a32 100644
--- a/addons/crm/security/ir.model.access.csv
+++ b/addons/crm/security/ir.model.access.csv
@@ -21,3 +21,17 @@
"access_crm_email_history_user","crm.email.history","model_crm_email_history","crm.group_crm_user",1,0,0,0
"access_crm_email_add_cc_manager","crm.email.add.cc","model_crm_email_add_cc","crm.group_crm_manager",1,1,1,1
"access_crm_email_add_cc_user","crm.email.add.cc","model_crm_email_add_cc","crm.group_crm_user",1,0,0,0
+"access_crm_case_stage","crm.case.stage","model_crm_case_stage","crm.group_crm_user",1,0,0,0
+"access_report_crm_case_section_stage","report.crm.case.section.stage","model_report_crm_case_section_stage","crm.group_crm_manager",1,0,0,0
+"access_report_crm_case_section_categ_stage","report.crm.case.section.categ.stage","model_report_crm_case_section_categ_stage","crm.group_crm_manager",1,0,0,0
+"access_report_crm_case_section_categ_categ2","report.crm.case.section.categ.categ2","model_report_crm_case_section_categ_categ2","crm.group_crm_manager",1,0,0,
+"access_report_crm_case_section_categ2","report.crm.case.section.categ2","model_report_crm_case_section_categ2","crm.group_crm_manager",1,0,0,
+"access_crm_case_stage_manager","crm.case.stage","model_crm_case_stage","crm.group_crm_manager",1,1,1,1
+"access_crm_menu_config_wizard","crm config wizard manager","model_crm_menu_config_wizard","crm.group_crm_manager",1,1,1,1
+"access_crm_menu_config_wizard system","crm config wizard manager system","model_crm_menu_config_wizard","base.group_system",1,1,1,1
+"access_crm_case_category2_user","crm_case_category2 user","model_crm_case_category2","crm.group_crm_user",1,0,0,0
+"access_crm_case_category2_manager","crm_case_category2 manager","model_crm_case_category2","crm.group_crm_manager",1,1,1,1
+"access_crm_generic_wizard_manager","crm.generic_wizard","model_crm_generic_wizard","crm.group_crm_manager",1,1,1,1
+"access_crm_generic_wizard_manager","crm.generic_wizard","model_crm_generic_wizard","crm.group_crm_user",1,0,0,0
+"access_crm_calendar_config_wizard","crm.calendar.config_wizard","model_crm_calendar_config_wizard",,1,1,1,1
+"access_crm_caldav_attendee","crm.caldav.attendee","model_crm_caldav_attendee",,1,1,1,1
diff --git a/addons/crm/wizard/__init__.py b/addons/crm/wizard/__init__.py
index 764eb33dbcf..bcaad7e61ae 100644
--- a/addons/crm/wizard/__init__.py
+++ b/addons/crm/wizard/__init__.py
@@ -26,5 +26,12 @@ import wizard_fetch_mail
import wizard_cal_export
import wizard_cal_import
+import meeting_planify
+import wizard_partner_create
+import wizard_opportunity_set
+import schedule_phone_call
+import wizard_history_event
+import wizard_partner_opportunity
+
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/crm/wizard/meeting_planify.py b/addons/crm/wizard/meeting_planify.py
new file mode 100644
index 00000000000..bf654f2d7b7
--- /dev/null
+++ b/addons/crm/wizard/meeting_planify.py
@@ -0,0 +1,109 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2009 Tiny SPRL ().
+#
+# 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 .
+#
+##############################################################################
+
+from mx.DateTime import now
+
+import wizard
+import netsvc
+import ir
+import pooler
+
+from tools.translate import _
+
+case_form = """
+
+
+
+
+
"""
+
+case_fields = {
+ 'date': {'string': 'Meeting date', 'type': 'datetime', 'required': 1},
+ 'duration': {'string': 'Duration (Hours)', 'type': 'float', 'required': 1}
+}
+
+
+class make_meeting(wizard.interface):
+ def _selectPartner(self, cr, uid, data, context):
+ case_obj = pooler.get_pool(cr.dbname).get('crm.case')
+ case = case_obj.browse(cr, uid, data['id'])
+ return {'date': case.date, 'duration': case.duration or 2.0}
+
+ def _makeMeeting(self, cr, uid, data, context):
+ pool = pooler.get_pool(cr.dbname)
+ case_obj = pool.get('crm.case')
+ sec_obj = pool.get('crm.case.section')
+ meeting_id = sec_obj.search(cr, uid, [('code','=','Mtngs')])
+ if not meeting_id:
+ raise wizard.except_wizard(_('Error !'),
+ _('You did not installed the Meetings when you configured the crm module.' \
+ '\nyou must create a section with the code \'Mtngs\'.'
+ ))
+ for case in case_obj.browse(cr, uid, data['ids']):
+ new_id=case_obj.copy(cr, uid, case.id)
+ modif = {
+ 'date': data['form']['date'],
+ 'duration': data['form']['duration'],
+ 'case_id': case.id,
+ }
+ if meeting_id:
+ modif['section_id']=meeting_id[0]
+ new_id = case_obj.write(cr, uid, [new_id], modif, context=context)
+# case_obj._history(cr, uid, case_obj.browse(cr, uid, data['ids']), _('meeting'))
+ data_obj = pool.get('ir.model.data')
+ result = data_obj._get_id(cr, uid, 'crm', 'view_crm_case_meetings_filter')
+ id = data_obj.read(cr, uid, result, ['res_id'])
+ id1 = data_obj._get_id(cr, uid, 'crm', 'crm_case_calendar_view_meet')
+ id2 = data_obj._get_id(cr, uid, 'crm', 'crm_case_form_view_meet')
+ id3 = data_obj._get_id(cr, uid, 'crm', 'crm_case_tree_view_meet')
+ if id1:
+ id1 = data_obj.browse(cr, uid, id1, context=context).res_id
+ if id2:
+ id2 = data_obj.browse(cr, uid, id2, context=context).res_id
+ if id3:
+ id3 = data_obj.browse(cr, uid, id3, context=context).res_id
+ return {
+ 'domain':"[('section_id','=','Meetings')]",
+ 'name': _('Meetings'),
+ 'view_type': 'form',
+ 'view_mode': 'calendar,form,tree',
+ 'res_model': 'crm.case',
+ 'view_id': False,
+ 'views': [(id1,'calendar'),(id2,'form'),(id3,'tree'),(False,'graph')],
+ 'type': 'ir.actions.act_window',
+ 'search_view_id': id['res_id']
+ }
+
+ states = {
+ 'init': {
+ 'actions': [_selectPartner],
+ 'result': {'type': 'form', 'arch': case_form, 'fields': case_fields,
+ 'state' : [('end', 'Cancel','gtk-cancel'),('order', 'Set Meeting','gtk-go-forward')]}
+ },
+ 'order': {
+ 'actions': [],
+ 'result': {'type': 'action', 'action': _makeMeeting, 'state': 'end'}
+ }
+ }
+
+make_meeting('crm.case.meeting')
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/crm/wizard/schedule_phone_call.py b/addons/crm/wizard/schedule_phone_call.py
new file mode 100644
index 00000000000..e19b4a02ac2
--- /dev/null
+++ b/addons/crm/wizard/schedule_phone_call.py
@@ -0,0 +1,127 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2009 Tiny SPRL (). All Rights Reserved
+# $Id$
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+#
+##############################################################################
+
+from mx.DateTime import now
+
+import wizard
+import netsvc
+import ir
+import pooler
+import time
+
+from tools.translate import _
+
+case_form = """
+
+
+
+
+
+
+
+
+
+
+
"""
+
+case_fields = {
+ 'user_id' : {'string' : 'Assign To', 'type' : 'many2one', 'relation' : 'res.users'},
+ 'deadline' : {'string' : 'Planned Date', 'type' : 'datetime'},
+ 'note' : {'string' : 'Goals', 'type' : 'text'},
+ 'category_id' : {'string' : 'Category', 'type' : 'many2one', 'relation' : 'crm.case.categ', 'required' : True},
+ 'section_id' : {'string' : 'Section', 'type' : 'many2one', 'relation' : 'crm.case.section', 'required' : True},
+
+}
+
+class reschedule_phone_call(wizard.interface):
+ def _default_values(self, cr, uid, data, context):
+ case_obj = pooler.get_pool(cr.dbname).get('crm.case')
+ sec_obj = pooler.get_pool(cr.dbname).get('crm.case.section')
+ sec_id = sec_obj.search(cr, uid, [('code', '=', 'Phone')])
+
+ if not sec_id:
+ raise wizard.except_wizard(_('Error !'),
+ _('You did not installed the Phone Calls when you configured the crm module.' \
+ '\nyou must create a section with the code \'Phone\'.'
+ ))
+ categ_id=pooler.get_pool(cr.dbname).get('crm.case.categ').search(cr, uid, [('name','=','Outbound')])
+ case = case_obj.browse(cr, uid, data['ids'][0])
+ return {
+ 'user_id' : case.user_id and case.user_id.id,
+ 'category_id' : categ_id and categ_id[0] or case.categ_id and case.categ_id.id,
+ 'section_id' : sec_id and sec_id[0],
+ 'note' : case.description
+ }
+
+ def _doIt(self, cr, uid, data, context):
+ form = data['form']
+ pool = pooler.get_pool(cr.dbname)
+ mod_obj = pool.get('ir.model.data')
+ result = mod_obj._get_id(cr, uid, 'crm', 'view_crm_case_phonecalls_filter')
+ res = mod_obj.read(cr, uid, result, ['res_id'])
+ case_obj = pool.get('crm.case')
+
+ # Select the view
+
+ data_obj = pool.get('ir.model.data')
+ id2 = data_obj._get_id(cr, uid, 'crm', 'crm_case_phone_tree_view')
+ id3 = data_obj._get_id(cr, uid, 'crm', 'crm_case_phone_form_view')
+ if id2:
+ id2 = data_obj.browse(cr, uid, id2, context=context).res_id
+ if id3:
+ id3 = data_obj.browse(cr, uid, id3, context=context).res_id
+
+ # We duplicate the current object
+ for id in data['ids']:
+ new_case = case_obj.copy(cr, uid, id, {'case_id':id,'user_id':form['user_id'],'categ_id':form['category_id'],'description':form['note'],'date' : form['deadline'], 'section_id' : form['section_id']}, context=context)
+ # Don't forget to cancel the current object,
+ for case in case_obj.browse(cr, uid, data['ids']):
+ if case.section_id.code == 'Phone':
+ case_obj.write(cr, uid, [case.id], {'state' : 'cancel'})
+ value = {
+ 'domain': "[('section_id','=',%d)]"%form['section_id'],
+ 'name': _('Phone Call'),
+ 'view_type': 'form',
+ 'view_mode': 'tree,form',
+ 'res_model': 'crm.case',
+ 'res_id' : new_case,
+ 'views': [(id3,'form'),(id2,'tree'),(False,'calendar'),(False,'graph')],
+ 'type': 'ir.actions.act_window',
+ 'search_view_id': res['res_id']
+ }
+ return value
+
+ states = {
+ 'init': {
+ 'actions': [_default_values],
+ 'result': {'type': 'form', 'arch': case_form, 'fields': case_fields,
+ 'state' : [('end', 'Cancel','gtk-cancel'),('order', 'Schedule Phone Call','gtk-go-forward')]}
+ },
+ 'order': {
+ 'actions': [],
+ 'result': {'type': 'action', 'action': _doIt, 'state': 'end'}
+ }
+ }
+
+reschedule_phone_call('crm.case.reschedule_phone_call')
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/crm/wizard/wizard_history_event.py b/addons/crm/wizard/wizard_history_event.py
new file mode 100644
index 00000000000..5b1b1b3b7d2
--- /dev/null
+++ b/addons/crm/wizard/wizard_history_event.py
@@ -0,0 +1,61 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2009 Tiny SPRL (). All Rights Reserved
+# $Id$
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+#
+##############################################################################
+
+import wizard
+import pooler
+import time
+
+def _open_history_event(self, cr, uid, data, context):
+ pool = pooler.get_pool(cr.dbname)
+ data_obj = pool.get('ir.model.data')
+ result = data_obj._get_id(cr, uid, 'crm', 'view_crm_case_filter')
+ id = data_obj.read(cr, uid, result, ['res_id'])
+ id2 = data_obj._get_id(cr, uid, 'crm', 'crm_case_calendar_section-view')
+ if id2:
+ id2 = data_obj.browse(cr, uid, id2, context=context).res_id
+ res = ''
+ if data.get('model',False) and data.get('ids',False):
+ model_obj = pooler.get_pool(cr.dbname).get(data['model'])
+ res = model_obj.browse(cr,uid,data['ids'])
+ if len(res):
+ res = res[0].name
+ return {
+ 'name': 'History : ' + res,
+ 'view_type': 'form',
+ "view_mode": 'calendar, tree, form',
+ 'view_id' : False,
+ 'views': [(id2,'calendar'),(False,'form'),(False,'tree'),(False,'graph')],
+ 'res_model': 'crm.case',
+ 'type': 'ir.actions.act_window',
+ 'domain': data.get('id',False) and "[('case_id','=',%d)]" % (data['id']) or "[]",
+ 'search_view_id': id['res_id']
+ }
+
+class case_history_event(wizard.interface):
+ states = {
+ 'init': {
+ 'actions': [],
+ 'result': {'type': 'action', 'action': _open_history_event, 'state':'end'}
+ }
+ }
+
+case_history_event('crm.case.history.events')
diff --git a/addons/crm/wizard/wizard_opportunity_set.py b/addons/crm/wizard/wizard_opportunity_set.py
new file mode 100644
index 00000000000..f1b0a57f389
--- /dev/null
+++ b/addons/crm/wizard/wizard_opportunity_set.py
@@ -0,0 +1,201 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2009 Tiny SPRL ().
+#
+# 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 .
+#
+##############################################################################
+
+from mx.DateTime import now
+
+import wizard
+import netsvc
+import ir
+import pooler
+from tools.translate import _
+
+partner_form = """
+
+
+
+
+
+
+
+
+
"""
+
+partner_fields = {
+ 'action': {'type':'selection',
+ 'selection':[('exist','Link to an existing partner'),('create','Create a new partner')],
+ 'string':'Action', 'required':True, 'default': lambda *a:'create'},
+ 'partner_id' : {'type':'many2one', 'relation':'res.partner', 'string':'Partner'},
+}
+
+case_form = """
+
+
+
+
+
+
+
"""
+
+case_fields = {
+ 'name': {'type':'char', 'size':64, 'string':'Opportunity Summary', 'required':True},
+ 'planned_revenue': {'type':'float', 'digits':(16,2), 'string': 'Expected Revenue'},
+ 'probability': {'type':'float', 'digits':(16,2), 'string': 'Success Probability'},
+ 'partner_id' : {'type':'many2one', 'relation':'res.partner', 'string':'Partner'},
+}
+
+
+class make_opportunity(wizard.interface):
+
+ def _selectopportunity(self, cr, uid, data, context):
+ pool = pooler.get_pool(cr.dbname)
+ case_obj = pool.get('crm.case')
+ for case in case_obj.browse(cr, uid, data['ids']):
+ if not case.partner_id:
+ return 'create_partner'
+ return {'name': case.name, 'probability': case.probability or 20.0,
+ 'planned_revenue':case.planned_revenue, 'partner_id':case.partner_id.id}
+
+ def _selectChoice(self, cr, uid, data, context):
+ pool = pooler.get_pool(cr.dbname)
+ case_obj = pool.get('crm.case')
+ for case in case_obj.browse(cr, uid, data['ids']):
+ if not case.partner_id:
+ return 'create_partner'
+ return 'opportunity'
+
+ def _makeOrder(self, cr, uid, data, context):
+ pool = pooler.get_pool(cr.dbname)
+ data_obj = pool.get('ir.model.data')
+ result = data_obj._get_id(cr, uid, 'crm', 'view_crm_case_opportunities_filter')
+ res = data_obj.read(cr, uid, result, ['res_id'])
+ section_obj = pool.get('crm.case.section')
+ id = section_obj.search(cr, uid, [('code','=','oppor')], context=context)
+ if not id:
+ raise wizard.except_wizard(_('Error !'),
+ _('You did not installed the opportunities tracking when you configured the crm module.' \
+ '\nYou can not convert the prospect to an opportunity, you must create a section with the code \'oppor\'.'
+ ))
+ id = id[0]
+
+ id2 = data_obj._get_id(cr, uid, 'crm', 'crm_case_form_view_oppor')
+ id3 = data_obj._get_id(cr, uid, 'crm', 'crm_case_tree_view_oppor')
+ if id2:
+ id2 = data_obj.browse(cr, uid, id2, context=context).res_id
+ if id3:
+ id3 = data_obj.browse(cr, uid, id3, context=context).res_id
+
+ case_obj = pool.get('crm.case')
+ new_pros=case_obj.copy(cr, uid, data['id'])
+# case_obj._history(cr, uid, case_obj.browse(cr, uid, [new_pros]), 'convert')
+ case_obj.write(cr, uid, [new_pros], {
+ 'section_id': id,
+ 'name': data['form']['name'],
+ 'planned_revenue': data['form']['planned_revenue'],
+ 'probability': data['form']['probability'],
+ 'partner_id': data['form']['partner_id'],
+ 'case_id':data['id'],
+ 'state':'open',
+ })
+
+ vals = {
+ 'partner_id': data['form']['partner_id'],
+ 'state':'done',
+ }
+ case_id = case_obj.read(cr, uid, data['id'], ['case_id'])['case_id']
+ if not case_id:
+ vals.update({'case_id' : new_pros})
+ case_obj.write(cr, uid, [data['id']], vals)
+ value = {
+ 'domain': "[('section_id','=',%d)]"%(id),
+ 'name': _('Opportunity'),
+ 'view_type': 'form',
+ 'view_mode': 'form,tree',
+ 'res_model': 'crm.case',
+ 'res_id': int(new_pros),
+ 'view_id': False,
+ 'views': [(id2,'form'),(id3,'tree'),(False,'calendar'),(False,'graph')],
+ 'type': 'ir.actions.act_window',
+ 'search_view_id': res['res_id']
+ }
+ return value
+
+ def _makePartner(self, cr, uid, data, context):
+ pool = pooler.get_pool(cr.dbname)
+ case_obj = pool.get('crm.case')
+ partner_obj = pool.get('res.partner')
+ contact_obj = pool.get('res.partner.address')
+ if data['form']['action']=='create':
+ for case in case_obj.browse(cr, uid, data['ids']):
+ partner_id = partner_obj.search(cr, uid, [('name', '=', case.partner_name or case.name)])
+ if partner_id:
+ raise wizard.except_wizard(_('Warning !'),_('A partner is already existing with the same name.'))
+ else:
+ partner_id = partner_obj.create(cr, uid, {
+ 'name': case.partner_name or case.name,
+ 'user_id': case.user_id.id,
+ 'comment': case.description,
+ })
+ contact_id = contact_obj.create(cr, uid, {
+ 'partner_id': partner_id,
+ 'name': case.partner_name2,
+ 'phone': case.partner_phone,
+ 'mobile': case.partner_mobile,
+ 'email': case.email_from
+ })
+ else:
+ partner = partner_obj.browse(cr,uid,data['form']['partner_id'])
+ partner_id=partner.id
+ contact_id=partner.address and partner.address[0].id
+
+ case_obj.write(cr, uid, data['ids'], {
+ 'partner_id': partner_id,
+ 'partner_address_id': contact_id
+ })
+ return {}
+
+ states = {
+ 'init': {
+ 'actions': [],
+ 'result': {'type':'choice','next_state':_selectChoice}
+ },
+ 'create_partner': {
+ 'actions': [],
+ 'result': {'type': 'form', 'arch': partner_form, 'fields': partner_fields,
+ 'state' : [('end', 'Cancel', 'gtk-cancel'),('create', 'Continue', 'gtk-go-forward')]}
+ },
+ 'create': {
+ 'actions': [],
+ 'result': {'type': 'action', 'action': _makePartner, 'state':'opportunity' }
+ },
+ 'opportunity': {
+ 'actions': [_selectopportunity],
+ 'result': {'type': 'form', 'arch': case_form, 'fields': case_fields,
+ 'state' : [('end', 'Cancel', 'gtk-cancel'),('confirm', 'Create Opportunity', 'gtk-go-forward')]}
+ },
+ 'confirm': {
+ 'actions': [],
+ 'result': {'type': 'action', 'action': _makeOrder, 'state': 'end'}
+ }
+ }
+
+make_opportunity('crm.case.opportunity_set')
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/crm/wizard/wizard_partner_create.py b/addons/crm/wizard/wizard_partner_create.py
new file mode 100644
index 00000000000..64f15ce97f8
--- /dev/null
+++ b/addons/crm/wizard/wizard_partner_create.py
@@ -0,0 +1,113 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2009 Tiny SPRL ().
+#
+# 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 .
+#
+##############################################################################
+
+from mx.DateTime import now
+
+import wizard
+import netsvc
+import ir
+import pooler
+from tools.translate import _
+
+case_form = """
+
+
+
+
+
"""
+
+case_fields = {
+ 'close': {'type':'boolean', 'string':'Close Prospect'}
+}
+
+
+class make_partner(wizard.interface):
+
+ def _selectPartner(self, cr, uid, data, context):
+ pool = pooler.get_pool(cr.dbname)
+ case_obj = pool.get('crm.case')
+ for case in case_obj.browse(cr, uid, data['ids']):
+ if case.partner_id:
+ raise wizard.except_wizard(_('Warning !'),
+ _('A partner is already defined on this prospect.'))
+ return {}
+
+ def _makeOrder(self, cr, uid, data, context):
+ pool = pooler.get_pool(cr.dbname)
+ mod_obj = pool.get('ir.model.data')
+ result = mod_obj._get_id(cr, uid, 'base', 'view_res_partner_filter')
+ res = mod_obj.read(cr, uid, result, ['res_id'])
+ case_obj = pool.get('crm.case')
+ partner_obj = pool.get('res.partner')
+ contact_obj = pool.get('res.partner.address')
+ for case in case_obj.browse(cr, uid, data['ids']):
+ partner_id = partner_obj.search(cr, uid, [('name', '=', case.partner_name or case.name)])
+ if partner_id:
+ raise wizard.except_wizard(_('Warning !'),_('A partner is already existing with the same name.'))
+ else:
+ partner_id = partner_obj.create(cr, uid, {
+ 'name': case.partner_name or case.name,
+ 'user_id': case.user_id.id,
+ 'comment': case.description,
+ })
+ contact_id = contact_obj.create(cr, uid, {
+ 'partner_id': partner_id,
+ 'name': case.partner_name2,
+ 'phone': case.partner_phone,
+ 'mobile': case.partner_mobile,
+ 'email': case.email_from
+ })
+
+
+ case_obj.write(cr, uid, data['ids'], {
+ 'partner_id': partner_id,
+ 'partner_address_id': contact_id
+ })
+ if data['form']['close']:
+ case_obj.case_close(cr, uid, data['ids'])
+
+ value = {
+ 'domain': "[]",
+ 'view_type': 'form',
+ 'view_mode': 'form,tree',
+ 'res_model': 'res.partner',
+ 'res_id': int(partner_id),
+ 'view_id': False,
+ 'type': 'ir.actions.act_window',
+ 'search_view_id': res['res_id']
+ }
+ return value
+
+ states = {
+ 'init': {
+ 'actions': [_selectPartner],
+ 'result': {'type': 'form', 'arch': case_form, 'fields': case_fields,
+ 'state' : [('end', 'Cancel', 'gtk-cancel'),('confirm', 'Create Partner', 'gtk-go-forward')]}
+ },
+ 'confirm': {
+ 'actions': [],
+ 'result': {'type': 'action', 'action': _makeOrder, 'state': 'end'}
+ }
+ }
+
+make_partner('crm.case.partner_create')
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+
diff --git a/addons/crm/wizard/wizard_partner_opportunity.py b/addons/crm/wizard/wizard_partner_opportunity.py
new file mode 100644
index 00000000000..e1de000c718
--- /dev/null
+++ b/addons/crm/wizard/wizard_partner_opportunity.py
@@ -0,0 +1,124 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2009 Tiny SPRL ().
+#
+# 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 .
+#
+##############################################################################
+
+from mx.DateTime import now
+
+import wizard
+import netsvc
+import ir
+import pooler
+from tools.translate import _
+
+
+case_form = """
+