[MERGE] remove stage type ksa, and MASSIVE crm_lead cleanup

bzr revid: al@openerp.com-20110825041037-0jerocl9x8psve2c
This commit is contained in:
Antony Lesuisse 2011-08-25 06:10:37 +02:00
commit 42b36f710e
32 changed files with 963 additions and 1617 deletions

View File

@ -24,17 +24,11 @@ import crm_action_rule
import crm_segmentation
import crm_meeting
import crm_lead
import crm_opportunity
import crm_phonecall
import crm_installer
import report
import wizard
import res_partner
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -69,7 +69,6 @@ Creates a dashboard for CRM that includes:
'crm_meeting_data.xml',
'crm_lead_data.xml',
'crm_meeting_data.xml',
'crm_opportunity_data.xml',
'crm_phonecall_data.xml',
],
'update_xml': [
@ -103,9 +102,6 @@ Creates a dashboard for CRM that includes:
'crm_phonecall_view.xml',
'crm_phonecall_menu.xml',
'crm_opportunity_view.xml',
'crm_opportunity_menu.xml',
'report/crm_lead_report_view.xml',
'report/crm_phonecall_report_view.xml',
@ -121,7 +117,6 @@ Creates a dashboard for CRM that includes:
'crm_demo.xml',
'crm_lead_demo.xml',
'crm_meeting_demo.xml',
'crm_opportunity_demo.xml',
'crm_phonecall_demo.xml',
],
'test': [

View File

@ -44,17 +44,157 @@ AVAILABLE_PRIORITIES = [
('5', 'Lowest'),
]
class crm_case_stage(osv.osv):
""" Stage of case """
_name = "crm.case.stage"
_description = "Stage of case"
_rec_name = 'name'
_order = "sequence"
_columns = {
'name': fields.char('Stage Name', size=64, required=True, translate=True),
'sequence': fields.integer('Sequence', help="Used to order stages."),
'probability': fields.float('Probability (%)', required=True, help="This percentage depicts the default/average probability of the Case for this stage to be a success"),
'on_change': fields.boolean('Change Probability Automatically', help="Setting this stage will change the probability automatically on the opportunity."),
'requirements': fields.text('Requirements'),
'section_ids':fields.many2many('crm.case.section', 'section_stage_rel', 'stage_id', 'section_id', 'Sections'),
}
_defaults = {
'sequence': lambda *args: 1,
'probability': lambda *args: 0.0,
}
class crm_case_section(osv.osv):
"""Sales Team"""
_name = "crm.case.section"
_description = "Sales Teams"
_order = "complete_name"
def get_full_name(self, cr, uid, ids, field_name, arg, context=None):
return dict(self.name_get(cr, uid, ids, context=context))
_columns = {
'name': fields.char('Sales Team', size=64, required=True, translate=True),
'complete_name': fields.function(get_full_name, type='char', size=256, readonly=True, store=True),
'code': fields.char('Code', size=8),
'active': fields.boolean('Active', help="If the active field is set to "\
"true, it will allow you to hide the sales team without removing it."),
'allow_unlink': fields.boolean('Allow Delete', help="Allows to delete non draft cases"),
'change_responsible': fields.boolean('Reassign Escalated', help="When escalating to this team override the saleman with the team leader."),
'user_id': fields.many2one('res.users', 'Team Leader'),
'member_ids':fields.many2many('res.users', 'sale_member_rel', 'section_id', 'member_id', 'Team Members'),
'reply_to': fields.char('Reply-To', size=64, help="The email address put in the 'Reply-To' of all emails sent by OpenERP about cases in this sales team"),
'parent_id': fields.many2one('crm.case.section', 'Parent Team'),
'child_ids': fields.one2many('crm.case.section', 'parent_id', 'Child Teams'),
'resource_calendar_id': fields.many2one('resource.calendar', "Working Time", help="Used to compute open days"),
'note': fields.text('Description'),
'working_hours': fields.float('Working Hours', digits=(16,2 )),
'stage_ids': fields.many2many('crm.case.stage', 'section_stage_rel', 'section_id', 'stage_id', 'Stages'),
}
_defaults = {
'active': lambda *a: 1,
'allow_unlink': lambda *a: 1,
}
_sql_constraints = [
('code_uniq', 'unique (code)', 'The code of the sales team must be unique !')
]
def _check_recursion(self, cr, uid, ids, context=None):
"""
Checks for recursion level for sales team
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of Sales team ids
"""
level = 100
while len(ids):
cr.execute('select distinct parent_id from crm_case_section where id IN %s', (tuple(ids),))
ids = filter(None, map(lambda x: x[0], cr.fetchall()))
if not level:
return False
level -= 1
return True
_constraints = [
(_check_recursion, 'Error ! You cannot create recursive Sales team.', ['parent_id'])
]
def name_get(self, cr, uid, ids, context=None):
"""Overrides orm name_get method
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of sales team ids
"""
if context is None:
context = {}
if not isinstance(ids, list) :
ids = [ids]
res = []
if not ids:
return res
reads = self.read(cr, uid, ids, ['name', 'parent_id'], context)
for record in reads:
name = record['name']
if record['parent_id']:
name = record['parent_id'][1] + ' / ' + name
res.append((record['id'], name))
return res
class crm_case_categ(osv.osv):
""" Category of Case """
_name = "crm.case.categ"
_description = "Category of Case"
_columns = {
'name': fields.char('Name', size=64, required=True, translate=True),
'section_id': fields.many2one('crm.case.section', 'Sales Team'),
'object_id': fields.many2one('ir.model', 'Object Name'),
}
def _find_object_id(self, cr, uid, context=None):
"""Finds id for case object
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param context: A standard dictionary for contextual values
"""
object_id = context and context.get('object_id', False) or False
ids = self.pool.get('ir.model').search(cr, uid, [('model', '=', object_id)])
return ids and ids[0]
_defaults = {
'object_id' : _find_object_id
}
class crm_case_resource_type(osv.osv):
""" Resource Type of case """
_name = "crm.case.resource.type"
_description = "Campaign"
_rec_name = "name"
_columns = {
'name': fields.char('Campaign Name', size=64, required=True, translate=True),
'section_id': fields.many2one('crm.case.section', 'Sales Team'),
}
class crm_base(object):
"""
Base classe for crm object,
Object that inherit from this class should have
date_open
date_closed
user_id
partner_id
partner_address_id
as field to be compatible with this class
""" Base utility mixin class for crm objects,
Object subclassing this should define colums:
date_open
date_closed
user_id
partner_id
partner_address_id
"""
def _get_default_partner_address(self, cr, uid, context=None):
"""Gives id of default address for current user
@ -77,7 +217,7 @@ class crm_base(object):
return False
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
return user.company_id.partner_id.id
def _get_default_email(self, cr, uid, context=None):
"""Gives default email address for current user
:param context: if portal in context is false return false anyway
@ -86,7 +226,7 @@ class crm_base(object):
return False
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
return user.user_email
def _get_default_user(self, cr, uid, context=None):
"""Gives current user id
:param context: if portal in context is false return false anyway
@ -100,7 +240,7 @@ class crm_base(object):
"""
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
return user.context_section_id.id or False
def onchange_partner_address_id(self, cr, uid, ids, add, email=False):
"""This function returns value of partner email based on Partner Address
@param ids: List of case IDs
@ -114,7 +254,7 @@ class crm_base(object):
return {'value': {'email_from': address.email, 'phone': address.phone}}
else:
return {'value': {'phone': address.phone}}
def onchange_partner_id(self, cr, uid, ids, part, email=False):
"""This function returns value of partner address based on partner
@param ids: List of case IDs
@ -127,11 +267,9 @@ class crm_base(object):
data = {'partner_address_id': addr['contact']}
data.update(self.onchange_partner_address_id(cr, uid, ids, addr['contact'])['value'])
return {'value': data}
def case_open(self, cr, uid, ids, *args):
"""Opens Case
@param ids: List of case Ids
"""
cases = self.browse(cr, uid, ids)
for case in cases:
@ -140,7 +278,6 @@ class crm_base(object):
data['user_id'] = uid
self.write(cr, uid, case.id, data)
self._action(cr, uid, cases, 'open')
return True
@ -150,12 +287,8 @@ class crm_base(object):
"""
cases = self.browse(cr, uid, ids)
cases[0].state # to fill the browse record cache
self.write(cr, uid, ids, {'state': 'done',
'date_closed': time.strftime('%Y-%m-%d %H:%M:%S'),
})
#
self.write(cr, uid, ids, {'state': 'done', 'date_closed': time.strftime('%Y-%m-%d %H:%M:%S'), })
# We use the cache of cases to keep the old case state
#
self._action(cr, uid, cases, 'done')
return True
@ -165,17 +298,13 @@ class crm_base(object):
"""
cases = self.browse(cr, uid, ids)
cases[0].state # to fill the browse record cache
self.write(cr, uid, ids, {'state': 'cancel',
'active': True})
self.write(cr, uid, ids, {'state': 'cancel', 'active': True})
# We use the cache of cases to keep the old case state
self._action(cr, uid, cases, 'cancel')
for case in cases:
message = _("The case '%s' has been cancelled.") % (case.name,)
self.log(cr, uid, case.id, message)
return True
def case_pending(self, cr, uid, ids, *args):
"""Marks case as pending
@param ids: List of case Ids
"""
cases = self.browse(cr, uid, ids)
cases[0].state # to fill the browse record cache
@ -185,7 +314,6 @@ class crm_base(object):
def case_reset(self, cr, uid, ids, *args):
"""Resets case as draft
@param ids: List of case Ids
"""
cases = self.browse(cr, uid, ids)
cases[0].state # to fill the browse record cache
@ -204,187 +332,69 @@ class crm_base(object):
return rule_obj._action(cr, uid, rule_ids, cases, scrit=scrit, context=context)
class crm_case(crm_base):
"""
A simple python class to be used for common functions
Object that inherit from this class should inherit from mailgate.thread
And need a stage_id field
And object that inherit (orm inheritance) from a class the overwrite copy
""" A simple python class to be used for common functions
Object that inherit from this class should inherit from mailgate.thread
And need a stage_id field
And object that inherit (orm inheritance) from a class the overwrite copy
"""
def _find_lost_stage(self, cr, uid, type, section_id):
return self._find_percent_stage(cr, uid, 0.0, type, section_id)
def stage_find(self, cr, uid, section_id, domain=[], order='sequence'):
domain = list(domain)
if section_id:
domain.append(('section_ids', '=', section_id))
stage_ids = self.pool.get('crm.case.stage').search(cr, uid, domain, order=order)
if stage_ids:
return stage_ids[0]
def _find_won_stage(self, cr, uid, type, section_id):
return self._find_percent_stage(cr, uid, 100.0, type, section_id)
def stage_set(self, cr, uid, ids, stage_id, context=None):
value = {}
if hasattr(self,'onchange_stage_id'):
value = self.onchange_stage_id(cr, uid, ids, stage_id)['value']
value['stage_id'] = stage_id
self.write(cr, uid, ids, value, context=context)
def _find_percent_stage(self, cr, uid, percent, type, section_id):
def stage_change(self, cr, uid, ids, op, order, context=None):
if context is None:
context = {}
for case in self.browse(cr, uid, ids, context=context):
seq = 0
if case.stage_id:
seq = case.stage_id.sequence
section_id = None
if case.section_id:
section_id = case.section_id.id
next_stage_id = self.stage_find(cr, uid, section_id, [('sequence',op,seq)],order)
if next_stage_id:
self.stage_set(cr, uid, [case.id], next_stage_id, context=context)
def stage_next(self, cr, uid, ids, context=None):
"""This function computes next stage for case from its current stage
using available stage for that case type
"""
Return the first stage with a probability == percent
self.stage_change(cr, uid, ids, '>','sequence', context)
def stage_previous(self, cr, uid, ids, context=None):
"""This function computes previous stage for case from its current
stage using available stage for that case type
"""
stage_pool = self.pool.get('crm.case.stage')
if section_id :
ids = stage_pool.search(cr, uid, [("probability", '=', percent), ("type", 'like', type), ("section_ids", 'in', [section_id])])
else :
ids = stage_pool.search(cr, uid, [("probability", '=', percent), ("type", 'like', type)])
if ids:
return ids[0]
return False
def _find_first_stage(self, cr, uid, type, section_id):
"""
return the first stage that has a sequence number equal or higher than sequence
"""
stage_pool = self.pool.get('crm.case.stage')
if section_id :
ids = stage_pool.search(cr, uid, [("sequence", '>', 0), ("type", 'like', type), ("section_ids", 'in', [section_id])])
else :
ids = stage_pool.search(cr, uid, [("sequence", '>', 0), ("type", 'like', type)])
if ids:
stages = stage_pool.browse(cr, uid, ids)
stage_min = stages[0]
for stage in stages:
if stage_min.sequence > stage.sequence:
stage_min = stage
return stage_min.id
else :
return False
def onchange_stage_id(self, cr, uid, ids, stage_id, context={}):
""" @param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of stages IDs
@stage_id: change state id on run time """
if not stage_id:
return {'value':{}}
stage = self.pool.get('crm.case.stage').browse(cr, uid, stage_id, context)
if not stage.on_change:
return {'value':{}}
return {'value':{'probability': stage.probability}}
self.stage_change(cr, uid, ids, '<', 'sequence desc', context)
def copy(self, cr, uid, id, default=None, context=None):
""" Overrides orm copy method.
"""
Overrides orm copy method.
@param self: the object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param id: Id of mailgate thread
@param default: Dictionary of default values for copy.
@param context: A standard dictionary for contextual values
"""
if context is None:
context = {}
if default is None:
default = {}
default.update({
'message_ids': [],
})
default.update({ 'message_ids': [], })
if hasattr(self, '_columns'):
if self._columns.get('date_closed'):
default.update({
'date_closed': False,
})
default.update({ 'date_closed': False, })
if self._columns.get('date_open'):
default.update({
'date_open': False
})
default.update({ 'date_open': False })
return super(osv.osv, self).copy(cr, uid, id, default, context=context)
def _find_next_stage(self, cr, uid, stage_list, index, current_seq, stage_pool, context=None):
if index + 1 == len(stage_list):
return False
next_stage_id = stage_list[index + 1]
next_stage = stage_pool.browse(cr, uid, next_stage_id, context=context)
if not next_stage:
return False
next_seq = next_stage.sequence
if not current_seq :
current_seq = 0
if (abs(next_seq - current_seq)) >= 1:
return next_stage
else :
return self._find_next_stage(cr, uid, stage_list, index + 1, current_seq, stage_pool)
def stage_change(self, cr, uid, ids, context=None, order='sequence'):
if context is None:
context = {}
stage_pool = self.pool.get('crm.case.stage')
stage_type = context and context.get('stage_type','')
current_seq = False
next_stage_id = False
for case in self.browse(cr, uid, ids, context=context):
next_stage = False
value = {}
if case.section_id.id :
domain = [('type', '=', stage_type),('section_ids', '=', case.section_id.id)]
else :
domain = [('type', '=', stage_type)]
stages = stage_pool.search(cr, uid, domain, order=order)
current_seq = case.stage_id.sequence
index = -1
if case.stage_id and case.stage_id.id in stages:
index = stages.index(case.stage_id.id)
next_stage = self._find_next_stage(cr, uid, stages, index, current_seq, stage_pool, context=context)
if next_stage:
next_stage_id = next_stage.id
value.update({'stage_id': next_stage.id})
if next_stage.on_change:
value.update({'probability': next_stage.probability})
self.write(cr, uid, [case.id], value, context=context)
return next_stage_id #FIXME should return a list of all id
def stage_next(self, cr, uid, ids, context=None):
"""This function computes next stage for case from its current stage
using available stage for that case type
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of case IDs
@param context: A standard dictionary for contextual values"""
return self.stage_change(cr, uid, ids, context=context, order='sequence')
def stage_previous(self, cr, uid, ids, context=None):
"""This function computes previous stage for case from its current stage
using available stage for that case type
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of case IDs
@param context: A standard dictionary for contextual values"""
return self.stage_change(cr, uid, ids, context=context, order='sequence desc')
def _history(self, cr, uid, cases, keyword, history=False, subject=None, email=False, details=None, email_from=False, message_id=False, attach=[], context=None):
mailgate_pool = self.pool.get('mailgate.thread')
return mailgate_pool.history(cr, uid, cases, keyword, history=history,\
@ -395,17 +405,11 @@ class crm_case(crm_base):
def case_open(self, cr, uid, ids, *args):
"""Opens Case
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of case Ids
@param *args: Tuple Value for additional Params
"""
cases = self.browse(cr, uid, ids)
self._history(cr, uid, cases, _('Open'))
for case in cases:
data = {'state': 'open', 'active': True}
data = {'state': 'open', 'active': True }
if not case.user_id:
data['user_id'] = uid
self.write(cr, uid, case.id, data)
@ -414,11 +418,6 @@ class crm_case(crm_base):
def case_close(self, cr, uid, ids, *args):
"""Closes Case
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of case Ids
@param *args: Tuple Value for additional Params
"""
cases = self.browse(cr, uid, ids)
cases[0].state # to fill the browse record cache
@ -434,11 +433,6 @@ class crm_case(crm_base):
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 users ID for security checks,
@param ids: List of case Ids
@param *args: Tuple Value for additional Params
"""
cases = self.browse(cr, uid, ids)
for case in cases:
@ -459,11 +453,6 @@ class crm_case(crm_base):
def case_cancel(self, cr, uid, ids, *args):
"""Cancels Case
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of case Ids
@param *args: Tuple Value for additional Params
"""
cases = self.browse(cr, uid, ids)
cases[0].state # to fill the browse record cache
@ -478,11 +467,6 @@ class crm_case(crm_base):
def case_pending(self, cr, uid, ids, *args):
"""Marks case as pending
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of case Ids
@param *args: Tuple Value for additional Params
"""
cases = self.browse(cr, uid, ids)
cases[0].state # to fill the browse record cache
@ -493,11 +477,6 @@ class crm_case(crm_base):
def case_reset(self, cr, uid, ids, *args):
"""Resets case as draft
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of case Ids
@param *args: Tuple Value for additional Params
"""
state = 'draft'
if 'crm.phonecall' in args:
@ -600,8 +579,6 @@ class crm_case(crm_base):
cases = self.browse(cr, uid, ids2, context=context)
return self._action(cr, uid, cases, False, context=context)
def format_body(self, body):
return self.pool.get('base.action.rule').format_body(body)
@ -621,189 +598,6 @@ class crm_case(crm_base):
res[case.id] = l
return res
class crm_case_stage(osv.osv):
""" Stage of case """
_name = "crm.case.stage"
_description = "Stage of case"
_rec_name = 'name'
_order = "sequence"
def _get_type_value(self, cr, user, context):
return [('lead','Lead'),('opportunity','Opportunity')]
_columns = {
'name': fields.char('Stage Name', size=64, required=True, translate=True),
'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of case stages."),
'probability': fields.float('Probability (%)', required=True, help="This percentage depicts the default/average probability of the Case for this stage to be a success"),
'on_change': fields.boolean('Change Probability Automatically', \
help="Change Probability on next and previous stages."),
'requirements': fields.text('Requirements'),
'type': fields.selection(_get_type_value, 'Type', required=True),
}
def _find_stage_type(self, cr, uid, context=None):
"""Finds type of stage according to object.
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param context: A standard dictionary for contextual values
"""
type = context and context.get('type', '') or ''
return type
_defaults = {
'sequence': lambda *args: 1,
'probability': lambda *args: 0.0,
'type': _find_stage_type,
}
crm_case_stage()
class crm_case_section(osv.osv):
"""Sales Team"""
_name = "crm.case.section"
_description = "Sales Teams"
_order = "complete_name"
def get_full_name(self, cr, uid, ids, field_name, arg, context=None):
return dict(self.name_get(cr, uid, ids, context=context))
_columns = {
'name': fields.char('Sales Team', size=64, required=True, translate=True),
'complete_name': fields.function(get_full_name, type='char', size=256, readonly=True, store=True),
'code': fields.char('Code', size=8),
'active': fields.boolean('Active', help="If the active field is set to "\
"true, it will allow you to hide the sales team without removing it."),
'allow_unlink': fields.boolean('Allow Delete', help="Allows to delete non draft cases"),
'change_responsible': fields.boolean('Reassign Escalated', help="When escalating to this team override the saleman with the team leader."),
'user_id': fields.many2one('res.users', 'Team Leader'),
'member_ids':fields.many2many('res.users', 'sale_member_rel', 'section_id', 'member_id', 'Team Members'),
'reply_to': fields.char('Reply-To', size=64, help="The email address put in the 'Reply-To' of all emails sent by OpenERP about cases in this sales team"),
'parent_id': fields.many2one('crm.case.section', 'Parent Team'),
'child_ids': fields.one2many('crm.case.section', 'parent_id', 'Child Teams'),
'resource_calendar_id': fields.many2one('resource.calendar', "Working Time", help="Used to compute open days"),
'note': fields.text('Description'),
'working_hours': fields.float('Working Hours', digits=(16,2 )),
'stage_ids': fields.many2many('crm.case.stage', 'section_stage_rel', 'section_id', 'stage_id', 'Stages'),
}
_defaults = {
'active': lambda *a: 1,
'allow_unlink': lambda *a: 1,
}
_sql_constraints = [
('code_uniq', 'unique (code)', 'The code of the sales team must be unique !')
]
def _check_recursion(self, cr, uid, ids, context=None):
"""
Checks for recursion level for sales team
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of Sales team ids
"""
level = 100
while len(ids):
cr.execute('select distinct parent_id from crm_case_section where id IN %s', (tuple(ids),))
ids = filter(None, map(lambda x: x[0], cr.fetchall()))
if not level:
return False
level -= 1
return True
_constraints = [
(_check_recursion, 'Error ! You cannot create recursive Sales team.', ['parent_id'])
]
def name_get(self, cr, uid, ids, context=None):
"""Overrides orm name_get method
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of sales team ids
"""
if context is None:
context = {}
if not isinstance(ids, list) :
ids = [ids]
res = []
if not ids:
return res
reads = self.read(cr, uid, ids, ['name', 'parent_id'], context)
for record in reads:
name = record['name']
if record['parent_id']:
name = record['parent_id'][1] + ' / ' + name
res.append((record['id'], name))
return res
crm_case_section()
class crm_case_categ(osv.osv):
""" Category of Case """
_name = "crm.case.categ"
_description = "Category of Case"
_columns = {
'name': fields.char('Name', size=64, required=True, translate=True),
'section_id': fields.many2one('crm.case.section', 'Sales Team'),
'object_id': fields.many2one('ir.model', 'Object Name'),
}
def _find_object_id(self, cr, uid, context=None):
"""Finds id for case object
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param context: A standard dictionary for contextual values
"""
object_id = context and context.get('object_id', False) or False
ids = self.pool.get('ir.model').search(cr, uid, [('model', '=', object_id)])
return ids and ids[0]
_defaults = {
'object_id' : _find_object_id
}
crm_case_categ()
class crm_case_stage(osv.osv):
_inherit = "crm.case.stage"
_columns = {
'section_ids':fields.many2many('crm.case.section', 'section_stage_rel', 'stage_id', 'section_id', 'Sections'),
}
crm_case_stage()
class crm_case_resource_type(osv.osv):
""" Resource Type of case """
_name = "crm.case.resource.type"
_description = "Campaign"
_rec_name = "name"
_columns = {
'name': fields.char('Campaign Name', size=64, required=True, translate=True),
'section_id': fields.many2one('crm.case.section', 'Sales Team'),
}
crm_case_resource_type()
def _links_get(self, cr, uid, context=None):
"""Gets links value for reference field
@param self: The object pointer
@ -830,13 +624,6 @@ class users(osv.osv):
if vals.get('context_section_id', False):
section_obj.write(cr, uid, [vals['context_section_id']], {'member_ids':[(4, res)]}, context)
return res
users()
class res_partner(osv.osv):
_inherit = 'res.partner'
_columns = {
'section_id': fields.many2one('crm.case.section', 'Sales Team'),
}
res_partner()

View File

@ -39,8 +39,9 @@ class crm_lead(crm_case, osv.osv):
""" CRM Lead Case """
_name = "crm.lead"
_description = "Lead/Opportunity"
_order = "date_action, priority, id desc"
_order = "priority,date_action,id desc"
_inherit = ['mailgate.thread','res.partner.address']
def _compute_day(self, cr, uid, ids, fields, args, context=None):
"""
@param cr: the current row, from the database cursor,
@ -124,7 +125,6 @@ class crm_lead(crm_case, osv.osv):
'partner_id': fields.many2one('res.partner', 'Partner', ondelete='set null',
select=True, help="Optional linked partner, usually after conversion of the lead"),
# From crm.case
'id': fields.integer('ID'),
'name': fields.char('Name', size=64, select=1),
'active': fields.boolean('Active', required=False),
@ -138,7 +138,6 @@ class crm_lead(crm_case, osv.osv):
'description': fields.text('Notes'),
'write_date': fields.datetime('Update Date' , readonly=True),
# Lead fields
'categ_id': fields.many2one('crm.case.categ', 'Category', \
domain="['|',('section_id','=',section_id),('section_id','=',False), ('object_id.model', '=', 'crm.lead')]"),
'type_id': fields.many2one('crm.case.resource.type', 'Campaign', \
@ -148,15 +147,11 @@ class crm_lead(crm_case, osv.osv):
'partner_name': fields.char("Customer Name", size=64,help='The name of the future partner that will be created while converting the into opportunity', select=1),
'optin': fields.boolean('Opt-In', help="If opt-in is checked, this contact has accepted to receive emails."),
'optout': fields.boolean('Opt-Out', help="If opt-out is checked, this contact has refused to receive emails or unsubscribed to a campaign."),
'type':fields.selection([
('lead','Lead'),
('opportunity','Opportunity'),
],'Type', help="Type is used to separate Leads and Opportunities"),
'type':fields.selection([ ('lead','Lead'), ('opportunity','Opportunity'), ],'Type', help="Type is used to separate Leads and Opportunities"),
'priority': fields.selection(crm.AVAILABLE_PRIORITIES, 'Priority'),
'date_closed': fields.datetime('Closed', readonly=True),
'stage_id': fields.many2one('crm.case.stage', 'Stage', domain="[('type','=','lead')]"),
'user_id': fields.many2one('res.users', 'Salesman', select=1),
'stage_id': fields.many2one('crm.case.stage', 'Stage', domain="[(section_ids', '=', section_id)]"),
'user_id': fields.many2one('res.users', 'Salesman'),
'referred': fields.char('Referred By', size=64),
'date_open': fields.datetime('Opened', readonly=True),
'day_open': fields.function(_compute_day, string='Days to Open', \
@ -170,9 +165,21 @@ class crm_lead(crm_case, osv.osv):
\nIf the case needs to be reviewed then the state is set to \'Pending\'.'),
'message_ids': fields.one2many('mailgate.message', 'res_id', 'Messages', domain=[('model','=',_name)]),
'subjects': fields.function(_get_email_subject, fnct_search=_history_search, string='Subject of Email', type='char', size=64),
}
# Only used for type opportunity
'partner_address_id': fields.many2one('res.partner.address', 'Partner Contact', domain="[('partner_id','=',partner_id)]"),
'probability': fields.float('Probability (%)',group_operator="avg"),
'planned_revenue': fields.float('Expected Revenue'),
'ref': fields.reference('Reference', selection=crm._links_get, size=128),
'ref2': fields.reference('Reference 2', selection=crm._links_get, size=128),
'phone': fields.char("Phone", size=64),
'date_deadline': fields.date('Expected Closing'),
'date_action': fields.date('Next Action Date'),
'title_action': fields.char('Next Action', size=64),
'stage_id': fields.many2one('crm.case.stage', 'Stage', domain="[(section_ids', '=', section_id)]"),
}
_defaults = {
'active': lambda *a: 1,
'user_id': crm_case._get_default_user,
@ -185,82 +192,120 @@ class crm_lead(crm_case, osv.osv):
#'stage_id': _get_stage_id,
}
def onchange_partner_address_id(self, cr, uid, ids, add, email=False):
"""This function returns value of partner email based on Partner Address
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of case IDs
@param add: Id of Partner's address
@email: Partner's email ID
"""
if not add:
return {'value': {'email_from': False, 'country_id': False}}
address = self.pool.get('res.partner.address').browse(cr, uid, add)
return {'value': {'email_from': address.email, 'phone': address.phone, 'country_id': address.country_id.id}}
def case_open(self, cr, uid, ids, *args):
"""Overrides cancel for crm_case for setting Open Date
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of case's Ids
@param *args: Give Tuple Value
def on_change_optin(self, cr, uid, ids, optin):
return {'value':{'optin':optin,'optout':False}}
def on_change_optout(self, cr, uid, ids, optout):
return {'value':{'optout':optout,'optin':False}}
def onchange_stage_id(self, cr, uid, ids, stage_id, context={}):
if not stage_id:
return {'value':{}}
stage = self.pool.get('crm.case.stage').browse(cr, uid, stage_id, context)
if not stage.on_change:
return {'value':{}}
return {'value':{'probability': stage.probability}}
def stage_find_percent(self, cr, uid, percent, section_id):
""" Return the first stage with a probability == percent
"""
leads = self.browse(cr, uid, ids)
stage_pool = self.pool.get('crm.case.stage')
if section_id :
ids = stage_pool.search(cr, uid, [("probability", '=', percent), ("section_ids", 'in', [section_id])])
else :
ids = stage_pool.search(cr, uid, [("probability", '=', percent)])
if ids:
return ids[0]
return False
def stage_find_lost(self, cr, uid, section_id):
return self.stage_find_percent(cr, uid, 0.0, section_id)
for i in xrange(0, len(ids)):
if leads[i].state == 'draft':
value = {}
if not leads[i].stage_id :
stage_id = self._find_first_stage(cr, uid, leads[i].type, leads[i].section_id.id or False)
value.update({'stage_id' : stage_id})
value.update({'date_open': time.strftime('%Y-%m-%d %H:%M:%S')})
self.write(cr, uid, [ids[i]], value)
self.log_open( cr, uid, leads[i])
def stage_find_won(self, cr, uid, section_id):
return self.stage_find_percent(cr, uid, 100.0, section_id)
def case_open(self, cr, uid, ids, *args):
for l in self.browse(cr, uid, ids):
# When coming from draft override date and stage otherwise just set state
if l.state == 'draft':
if l.type == 'lead':
message = _("The lead '%s' has been opened.") % l.name
elif l.type == 'opportunity':
message = _("The opportunity '%s' has been opened.") % l.name
else:
message = _("The case '%s' has been opened.") % l.name
self.log(cr, uid, l.id, message)
value = {'date_open': time.strftime('%Y-%m-%d %H:%M:%S')}
self.write(cr, uid, [l.id], value)
if l.type == 'opportunity' and not l.stage_id:
stage_id = self.stage_find(cr, uid, l.section_id.id or False, [('sequence','>',0)])
if stage_id:
self.stage_set(cr, uid, [l.id], stage_id)
res = super(crm_lead, self).case_open(cr, uid, ids, *args)
return res
def log_open(self, cr, uid, case):
if case.type == 'lead':
message = _("The lead '%s' has been opened.") % case.name
elif case.type == 'opportunity':
message = _("The opportunity '%s' has been opened.") % case.name
else:
message = _("The case '%s' has been opened.") % case.name
self.log(cr, uid, case.id, message)
def case_close(self, cr, uid, ids, *args):
"""Overrides close for crm_case for setting close date
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of case Ids
@param *args: Tuple Value for additional Params
"""
res = super(crm_lead, self).case_close(cr, uid, ids, *args)
self.write(cr, uid, ids, {'date_closed': time.strftime('%Y-%m-%d %H:%M:%S')})
for case in self.browse(cr, uid, ids):
if case.type == 'lead':
message = _("The lead '%s' has been closed.") % case.name
elif case.type == 'opportunity':
message = _("The opportunity '%s' has been closed.") % case.name
else:
message = _("The case '%s' has been closed.") % case.name
self.log(cr, uid, case.id, message)
return res
def case_cancel(self, cr, uid, ids, *args):
"""Overrides cancel for crm_case for setting probability
"""
res = super(crm_lead, self).case_cancel(cr, uid, ids, args)
self.write(cr, uid, ids, {'probability' : 0.0})
return res
def case_reset(self, cr, uid, ids, *args):
"""Overrides reset as draft in order to set the stage field as empty
"""
res = super(crm_lead, self).case_reset(cr, uid, ids, *args)
self.write(cr, uid, ids, {'stage_id': False, 'probability': 0.0})
return res
def case_mark_lost(self, cr, uid, ids, *args):
"""Mark the case as lost: state = done and probability = 0%
"""
res = super(crm_lead, self).case_close(cr, uid, ids, *args)
self.write(cr, uid, ids, {'probability' : 0.0})
for l in self.browse(cr, uid, ids):
stage_id = self.stage_find_lost(cr, uid, l.section_id.id or False)
if stage_id:
self.stage_set(cr, uid, [l.id], stage_id)
message = _("The opportunity '%s' has been marked as lost.") % l.name
self.log(cr, uid, l.id, message)
return res
def case_mark_won(self, cr, uid, ids, *args):
"""Mark the case as lost: state = done and probability = 0%
"""
res = super(crm_lead, self).case_close(cr, uid, ids, *args)
self.write(cr, uid, ids, {'probability' : 100.0})
for l in self.browse(cr, uid, ids):
stage_id = self.stage_find_won(cr, uid, l.section_id.id or False)
if stage_id:
self.stage_set(cr, uid, [l.id], stage_id)
message = _("The opportunity '%s' has been been won.") % l.name
self.log(cr, uid, l.id, message)
return res
def convert_opportunity(self, cr, uid, ids, context=None):
""" Precomputation for converting lead to opportunity
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of closedays IDs
@param context: A standard dictionary for contextual values
@return: Value of action in dict
"""
if context is None:
context = {}
@ -290,57 +335,8 @@ class crm_lead(crm_case, osv.osv):
}
return value
def write(self, cr, uid, ids, vals, context=None):
if not context:
context = {}
if 'date_closed' in vals:
return super(crm_lead,self).write(cr, uid, ids, vals, context=context)
if 'stage_id' in vals and vals['stage_id']:
stage_obj = self.pool.get('crm.case.stage').browse(cr, uid, vals['stage_id'], context=context)
self.history(cr, uid, ids, _("Changed Stage to: %s") % stage_obj.name, details=_("Changed Stage to: %s") % stage_obj.name)
message=''
for case in self.browse(cr, uid, ids, context=context):
if case.type == 'lead' or context.get('stage_type',False)=='lead':
message = _("The stage of lead '%s' has been changed to '%s'.") % (case.name, stage_obj.name)
elif case.type == 'opportunity':
message = _("The stage of opportunity '%s' has been changed to '%s'.") % (case.name, stage_obj.name)
self.log(cr, uid, case.id, message)
return super(crm_lead,self).write(cr, uid, ids, vals, context)
def stage_next(self, cr, uid, ids, context=None):
stage = super(crm_lead, self).stage_next(cr, uid, ids, context=context)
if stage:
stage_obj = self.pool.get('crm.case.stage').browse(cr, uid, stage, context=context)
if stage_obj.on_change:
data = {'probability': stage_obj.probability}
self.write(cr, uid, ids, data)
return stage
def stage_previous(self, cr, uid, ids, context=None):
stage = super(crm_lead, self).stage_previous(cr, uid, ids, context=context)
if stage:
stage_obj = self.pool.get('crm.case.stage').browse(cr, uid, stage, context=context)
if stage_obj.on_change:
data = {'probability': stage_obj.probability}
self.write(cr, uid, ids, data)
return stage
def unlink(self, cr, uid, ids, context=None):
for lead in self.browse(cr, uid, ids, context):
if (not lead.section_id.allow_unlink) and (lead.state <> 'draft'):
raise osv.except_osv(_('Warning !'),
_('You can not delete this lead. You should better cancel it.'))
return super(crm_lead, self).unlink(cr, uid, ids, context)
def message_new(self, cr, uid, msg, context=None):
"""
Automatically calls when new email message arrives
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks
""" Automatically calls when new email message arrives
"""
mailgate_pool = self.pool.get('email.server.tools')
@ -380,9 +376,6 @@ class crm_lead(crm_case, osv.osv):
def message_update(self, cr, uid, ids, vals={}, msg="", default_act='pending', context=None):
"""
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of update mails IDs
"""
if isinstance(ids, (str, int, long)):
@ -416,22 +409,82 @@ class crm_lead(crm_case, osv.osv):
return res
def msg_send(self, cr, uid, id, *args, **argv):
""" Send The Message
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of emails IDs
@param *args: Return Tuple Value
@param **args: Return Dictionary of Keyword Value
@param ids: List of emails IDs
"""
return True
def on_change_optin(self, cr, uid, ids, optin):
return {'value':{'optin':optin,'optout':False}}
def action_makeMeeting(self, cr, uid, ids, context=None):
"""
This opens Meeting's calendar view to schedule meeting on current Opportunity
@return : Dictionary value for created Meeting view
"""
value = {}
for opp in self.browse(cr, uid, ids, context=context):
data_obj = self.pool.get('ir.model.data')
# Get meeting views
result = data_obj._get_id(cr, uid, 'crm', 'view_crm_case_meetings_filter')
res = 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
context = {
'default_opportunity_id': opp.id,
'default_partner_id': opp.partner_id and opp.partner_id.id or False,
'default_user_id': uid,
'default_section_id': opp.section_id and opp.section_id.id or False,
'default_email_from': opp.email_from,
'default_state': 'open',
'default_name': opp.name
}
value = {
'name': _('Meetings'),
'context': context,
'view_type': 'form',
'view_mode': 'calendar,form,tree',
'res_model': 'crm.meeting',
'view_id': False,
'views': [(id1, 'calendar'), (id2, 'form'), (id3, 'tree')],
'type': 'ir.actions.act_window',
'search_view_id': res['res_id'],
'nodestroy': True
}
return value
def write(self, cr, uid, ids, vals, context=None):
if not context:
context = {}
if 'date_closed' in vals:
return super(crm_lead,self).write(cr, uid, ids, vals, context=context)
if 'stage_id' in vals and vals['stage_id']:
stage_obj = self.pool.get('crm.case.stage').browse(cr, uid, vals['stage_id'], context=context)
self.history(cr, uid, ids, _("Changed Stage to: %s") % stage_obj.name, details=_("Changed Stage to: %s") % stage_obj.name)
message=''
for case in self.browse(cr, uid, ids, context=context):
if case.type == 'lead' or context.get('stage_type',False)=='lead':
message = _("The stage of lead '%s' has been changed to '%s'.") % (case.name, stage_obj.name)
elif case.type == 'opportunity':
message = _("The stage of opportunity '%s' has been changed to '%s'.") % (case.name, stage_obj.name)
self.log(cr, uid, case.id, message)
return super(crm_lead,self).write(cr, uid, ids, vals, context)
def unlink(self, cr, uid, ids, context=None):
for lead in self.browse(cr, uid, ids, context):
if (not lead.section_id.allow_unlink) and (lead.state <> 'draft'):
raise osv.except_osv(_('Warning !'),
_('You can not delete this lead. You should better cancel it.'))
return super(crm_lead, self).unlink(cr, uid, ids, context)
def on_change_optout(self, cr, uid, ids, optout):
return {'value':{'optout':optout,'optin':False}}
crm_lead()

View File

@ -2,97 +2,119 @@
<openerp>
<data noupdate="1">
<record model="crm.case.stage" id="stage_lead6">
<!-- Crm stages -->
<record model="crm.case.stage" id="stage_lead6">
<field name="name">Lost</field>
<field eval="'0'" name="probability"/>
<field eval="'0'" name="sequence"/>
<field name="type">lead</field>
</record>
<!-- CASE STATUS(stage_id) -->
<record model="crm.case.stage" id="stage_lead1">
<field name="name">New</field>
<field eval="'10'" name="probability"/>
<field eval="'1'" name="sequence"/>
<field name="type">lead</field>
<field eval="'11'" name="sequence"/>
</record>
<record model="crm.case.stage" id="stage_lead2">
<field name="name">Qualification</field>
<field eval="'20'" name="probability"/>
<field eval="'2'" name="sequence"/>
<field name="type">lead</field>
<field eval="'12'" name="sequence"/>
</record>
<record model="crm.case.stage" id="stage_lead3">
<field name="name">Proposition</field>
<field eval="'40'" name="probability"/>
<field eval="'3'" name="sequence"/>
<field name="type">lead</field>
<field eval="'13'" name="sequence"/>
</record>
<record model="crm.case.stage" id="stage_lead4">
<field name="name">Negotiation</field>
<field eval="'60'" name="probability"/>
<field eval="'4'" name="sequence"/>
<field name="type">lead</field>
<field eval="'14'" name="sequence"/>
</record>
<record model="crm.case.stage" id="stage_lead5">
<field name="name">Won</field>
<field eval="'100'" name="probability"/>
<field eval="'5'" name="sequence"/>
<field eval="'15'" name="sequence"/>
<field eval="1" name="on_change"/>
<field name="type">lead</field>
</record>
<record model="crm.case.section" id="section_sales_department">
<field name="name">Sales Department</field>
<field name="code">Sales</field>
<field name="stage_ids" eval="[(4, ref('stage_lead1')), (4, ref('stage_lead2')), (4, ref('stage_lead3')), (4, ref('stage_lead4')), (4, ref('stage_lead5')), (4, ref('stage_lead6'))]"/>
</record>
<!-- CASE CATEGORY2(category2_id) -->
<!-- Crm campain -->
<record model="crm.case.resource.type" id="type_lead1">
<field name="name">Telesales</field>
<field name="section_id" ref="section_sales_department"/>
</record>
<record model="crm.case.resource.type" id="type_lead2">
<field name="name">Mail Campaign 1</field>
<field name="section_id" ref="section_sales_department"/>
</record>
<record model="crm.case.resource.type" id="type_lead3">
<field name="name">Mail Campaign 2</field>
<field name="section_id" ref="section_sales_department"/>
</record>
<record model="crm.case.resource.type" id="type_lead4">
<field name="name">Twitter Ads</field>
<field name="section_id" ref="section_sales_department"/>
</record>
<record model="crm.case.resource.type" id="type_lead5">
<field name="name">Google Adwords</field>
<field name="section_id" ref="section_sales_department"/>
</record>
<record model="crm.case.resource.type" id="type_lead6">
<field name="name">Google Adwords 2</field>
<field name="section_id" ref="section_sales_department"/>
</record>
<record model="crm.case.resource.type" id="type_lead7">
<field name="name">Television</field>
<field name="section_id" ref="section_sales_department"/>
</record>
<record model="crm.case.resource.type" id="type_lead8">
<field name="name">Newsletter</field>
<field name="section_id" ref="section_sales_department"/>
</record>
<!-- crm categories -->
<record model="crm.case.categ" id="categ_oppor1">
<field name="name">Interest in Computer</field>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<record model="crm.case.categ" id="categ_oppor2">
<field name="name">Interest in Accessories</field>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<record model="crm.case.categ" id="categ_oppor3">
<field name="name">Need Services</field>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<record model="crm.case.categ" id="categ_oppor4">
<field name="name">Need Information</field>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<record model="crm.case.categ" id="categ_oppor5">
<field name="name">Need a Website Design</field>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<record model="crm.case.categ" id="categ_oppor6">
<field name="name">Potential Reseller</field>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<record model="crm.case.categ" id="categ_oppor7">
<field name="name">Need Consulting</field>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<record model="crm.case.categ" id="categ_oppor8">
<field name="name">Other</field>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
</data>
</openerp>

View File

@ -1,11 +1,7 @@
<?xml version="1.0"?>
<openerp>
<data noupdate="1">
<!--
((((((((((( Demo Cases )))))))))))
-->
<!--For Leads-->
<!-- Demo Leads -->
<record id="crm_case_itisatelesalescampaign0" model="crm.lead">
<field name="type_id" ref="crm.type_lead1"/>
<field eval="'3'" name="priority"/>
@ -37,7 +33,7 @@
<field eval="'Le Club SARL'" name="name"/>
<field eval="'(956) 293-2595'" name="phone"/>
</record>
<record id="crm_case_developingwebapplications0" model="crm.lead">
<field name="type_id" ref="crm.type_lead5"/>
<field eval="'2'" name="priority"/>
@ -186,26 +182,105 @@
<field eval="&quot;Partnership Offer&quot;" name="partner_name"/>
</record>
<!-- Call Function to Open the leads-->
<!-- Call Function to Open the leads-->
<function model="crm.lead" name="case_open">
<value eval="[ref('crm_case_itisatelesalescampaign0'), ref('crm_case_electonicgoodsdealer0'), ref('crm_case_company_partnership0'), ref('crm_case_webvisitor0'), ref('crm_case_business_card0')]"/>
</function>
<!-- Call Function to mark the lead as Pending-->
<function model="crm.lead" name="case_pending">
<value eval="[ref('crm_case_itdeveloper0')]"/>
</function>
<!-- Call Function to Close the leads-->
<function model="crm.lead" name="case_close">
<value eval="[ref('crm_case_vpoperations0'), ref('crm_case_developingwebapplications0'), ref('crm_case_webvisitor0')]"/>
</function>
<!-- Call Function to Cancel the leads-->
<function model="crm.lead" name="case_cancel">
<value eval="[ref('crm_case_mgroperations0'), ref('crm_case_imported_contact0')]"/>
</function>
<!-- Demo Opportunities -->
<record id="crm_case_construstazunits0" model="crm.lead">
<field eval="60" name="probability"/>
<field name="partner_address_id" ref="base.res_partner_address_zen"/>
<field eval="1" name="active"/>
<field name="type">opportunity</field>
<field name="type_id" ref="crm.type_lead1"/>
<field name="partner_id" ref="base.res_partner_3"/>
<field eval="&quot;3&quot;" name="priority"/>
<field name="user_id" ref="base.user_root"/>
<field eval="&quot;open&quot;" name="state"/>
<field eval="85000.0" name="planned_revenue"/>
<field name="section_id" ref="crm.section_sales_department"/>
<field name="categ_id" ref="crm.categ_oppor1"/>
<field name="stage_id" ref="crm.stage_lead3"/>
<field eval="&quot;CONS TRUST (AZ) 529701 - 1000 units&quot;" name="name"/>
</record>
<record id="crm_case_rdroundfundingunits0" model="crm.lead">
<field name="partner_address_id" ref="base.res_partner_address_15"/>
<field eval="1" name="active"/>
<field name="type">opportunity</field>
<field name="type_id" ref="crm.type_lead2"/>
<field name="partner_id" ref="base.res_partner_11"/>
<field eval="&quot;3&quot;" name="priority"/>
<field name="user_id" ref="base.user_root"/>
<field eval="&quot;draft&quot;" name="state"/>
<field eval="45000.0" name="planned_revenue"/>
<field eval="50" name="probability"/>
<field name="section_id" ref="crm.section_sales_department"/>
<field name="categ_id" ref="crm.categ_oppor5"/>
<field name="stage_id" ref="crm.stage_lead1"/>
<field eval="&quot;3rd Round Funding - 1000 units &quot;" name="name"/>
</record>
<record id="crm_case_mediapoleunits0" model="crm.lead">
<field eval="10" name="probability"/>
<field name="partner_address_id" ref="base.res_partner_address_3"/>
<field eval="1" name="active"/>
<field name="type">opportunity</field>
<field name="type_id" ref="crm.type_lead1"/>
<field name="partner_id" ref="base.res_partner_8"/>
<field eval="&quot;3&quot;" name="priority"/>
<field name="user_id" ref="base.user_root"/>
<field eval="&quot;pending&quot;" name="state"/>
<field eval="55000.0" name="planned_revenue"/>
<field eval="70" name="probability"/>
<field name="section_id" ref="crm.section_sales_department"/>
<field name="categ_id" ref="crm.categ_oppor7"/>
<field name="stage_id" ref="crm.stage_lead5"/>
<field eval="&quot;Mediapole - 5000 units&quot;" name="name"/>
<field eval="&quot;info@mycompany.net&quot;" name="email_from"/>
</record>
<record id="crm_case_abcfuelcounits0" model="crm.lead">
<field eval="40" name="probability"/>
<field name="partner_address_id" ref="base.res_partner_address_1"/>
<field eval="1" name="active"/>
<field name="type">opportunity</field>
<field name="type_id" ref="crm.type_lead1"/>
<field name="partner_id" ref="base.res_partner_9"/>
<field eval="&quot;3&quot;" name="priority"/>
<field name="user_id" ref="base.user_demo"/>
<field eval="&quot;open&quot;" name="state"/>
<field eval="45000.0" name="planned_revenue"/>
<field name="section_id" ref="crm.section_sales_department"/>
<field name="categ_id" ref="crm.categ_oppor5"/>
<field name="stage_id" ref="crm.stage_lead4"/>
<field eval="&quot;ABC FUEL CO 829264 - 1000 units &quot;" name="name"/>
<field eval="&quot;info@opensides.be&quot;" name="email_from"/>
</record>
<record id="crm_case_dirtminingltdunits0" model="crm.lead">
<field eval="80" name="probability"/>
<field name="partner_address_id" ref="base.res_partner_address_wong"/>
<field eval="1" name="active"/>
<field name="type">opportunity</field>
<field name="partner_id" ref="base.res_partner_maxtor"/>
<field eval="&quot;3&quot;" name="priority"/>
<field name="user_id" ref="base.user_root"/>
<field eval="&quot;done&quot;" name="state"/>
<field eval="42000.0" name="planned_revenue"/>
<field name="section_id" ref="crm.section_sales_department"/>
<field name="categ_id" ref="crm.categ_oppor2"/>
<field name="stage_id" ref="crm.stage_lead6"/>
<field eval="&quot;Dirt Mining Ltd 271742 - 1000 units&quot;" name="name"/>
</record>
</data>
</openerp>

View File

@ -35,5 +35,68 @@
id="menu_crm_case_categ0_act_leads"
action="crm_case_category_act_leads_all" sequence="1" />
<act_window
id="act_crm_opportunity_crm_phonecall_new"
name="Phone calls"
groups="base.group_extended"
res_model="crm.phonecall"
src_model="crm.lead"
view_mode="tree,calendar,form"
context="{'default_duration': 1.0 ,'default_opportunity_id': active_id,'default_partner_phone':phone}"
domain="[('opportunity_id', '=', active_id)]"
view_type="form"/>
<act_window
id="act_crm_opportunity_crm_meeting_new"
name="Meetings"
res_model="crm.meeting"
src_model="crm.lead"
view_mode="tree,form,calendar,"
context="{'default_duration': 4.0, 'default_opportunity_id': active_id}"
domain="[('opportunity_id', '=', active_id)]"
view_type="form"/>
<record model="ir.actions.act_window" id="crm_case_category_act_oppor11">
<field name="name">Opportunities</field>
<field name="res_model">crm.lead</field>
<field name="view_mode">tree,form,graph,calendar</field>
<field name="domain">[('type','=','opportunity')]</field>
<field name="context">{'search_default_user_id':uid,'search_default_current':1, 'search_default_section_id':section_id, 'stage_type': 'opportunity'}</field>
<field name="view_id" ref="crm_case_tree_view_oppor"/>
<field name="search_view_id" ref="crm.view_crm_case_opportunities_filter"/>
<field name="help">With opportunities you can manage and keep track of your sales pipeline by creating specific customer- or prospect-related sales documents to follow up potential sales. Information such as expected revenue, opportunity stage, expected closing date, communication history and much more can be stored. Opportunities can be connected to the email gateway: new emails may create opportunities, each of them automatically gets the history of the conversation with the customer.
You and your team(s) will be able to plan meetings and phone calls from opportunities, convert them into quotations, manage related documents, track all customer related activities, and much more.</field>
</record>
<record model="ir.actions.act_window.view" id="action_crm_tag_tree_view_oppor11">
<field name="sequence" eval="1"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="crm_case_tree_view_oppor"/>
<field name="act_window_id" ref="crm_case_category_act_oppor11"/>
</record>
<record model="ir.actions.act_window.view" id="action_crm_tag_form_view_oppor11">
<field name="sequence" eval="2"/>
<field name="view_mode">form</field>
<field name="view_id" ref="crm_case_form_view_oppor"/>
<field name="act_window_id" ref="crm_case_category_act_oppor11"/>
</record>
<record model="ir.actions.act_window.view" id="action_crm_tag_graph_view_oppor11">
<field name="sequence" eval="4"/>
<field name="view_mode">graph</field>
<field name="view_id" ref="crm_case_graph_view_opportunity"/>
<field name="act_window_id" ref="crm_case_category_act_oppor11"/>
</record>
<menuitem id="base.menu_sales" name="Sales"
parent="base.menu_base_partner" sequence="1" />
<menuitem name="Opportunities" id="menu_crm_case_opp"
parent="base.menu_sales" action="crm_case_category_act_oppor11"
sequence="2" />
</data>
</openerp>

View File

@ -3,31 +3,23 @@
<data>
<!-- Stage Search view -->
<record id="crm_lead_stage_search" model="ir.ui.view">
<record id="crm_lead_stage_search" model="ir.ui.view">
<field name="name">Stage - Search</field>
<field name="model">crm.case.stage</field>
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Stage Search">
<filter icon="terp-personal" name="lead"
string="Lead" domain="[('type', '=', 'lead')]" context="{'type' : 'lead'}"/>
<filter icon="terp-personal+" name="opportunity"
string="Opportunity" domain="[('type', '=', 'opportunity')]" context="{'type' : 'opportunity'}"/>
<field name="name"/>
</search>
</field>
</record>
<!--Lead Stage Form view -->
<record id="crm_lead_stage_act" model="ir.actions.act_window">
<field name="name">Stages</field>
<field name="res_model">crm.case.stage</field>
<field name="view_type">form</field>
<field name="view_id" ref="crm.crm_case_stage_tree"/>
<field name="context">{'search_default_opportunity':1}</field>
<field name="search_view_id" ref="crm_lead_stage_search"/>
<field name="help">Add specific stages to leads and opportunities allowing your sales to better organise their sales pipeline. Stages will allow them to easily track how a specific lead or opportunity is positioned in the sales cycle.</field>
</record>
@ -74,7 +66,7 @@
<newline />
<field name="user_id" />
<field name="section_id" widget="selection" />
<field name="stage_id" domain="[('type','=','lead'),('section_ids', '=', section_id)]" />
<field name="stage_id" domain="[('section_ids', '=', section_id)]" />
<group col="2" colspan="1">
<button name="stage_previous" string=""
states="open,pending,draft" type="object"
@ -371,5 +363,311 @@
</search>
</field>
</record>
<!-- Opportunities Form View -->
<record model="ir.ui.view" id="crm_case_form_view_oppor">
<field name="name">Opportunities</field>
<field name="model">crm.lead</field>
<field name="type">form</field>
<field name="priority">10</field>
<field name="arch" type="xml">
<form string="Opportunities">
<group colspan="4" col="7">
<field name="name" required="1" string="Opportunity"/>
<label string="Stage:" align="1.0"/>
<group colspan="1" col="4">
<field name="stage_id" nolabel="1"
on_change="onchange_stage_id(stage_id)"
domain="[('section_ids', '=', section_id)]"/>
<button name="stage_previous"
states="draft,open,pending" type="object"
icon="gtk-go-back" string="" context="{'stage_type': 'opportunity'}"/>
<button name="stage_next" states="draft,open,pending"
type="object" icon="gtk-go-forward" string="" context="{'stage_type': 'opportunity'}"/>
</group>
<field name="user_id"/>
<button string="Schedule/Log Call"
name="%(opportunity2phonecall_act)d" icon="terp-call-start" type="action" groups="base.group_extended"/>
<field name="planned_revenue"/>
<field name="probability"/>
<field name="date_deadline"/>
<button name="action_makeMeeting" type="object"
string="Schedule Meeting" icon="gtk-redo" />
<newline/>
<field name="date_action"/>
<field name="title_action"/>
<field name="priority" string="Priority"/>
<newline/>
<field name="type" invisible="1"/>
</group>
<notebook colspan="4">
<page string="Opportunity">
<group col="4" colspan="2">
<separator colspan="4" string="Contacts"/>
<group colspan="2">
<field name="partner_id" select="1"
on_change="onchange_partner_id(partner_id, email_from)" string="Customer"
colspan="2" />
<button name="%(action_crm_lead2partner)d"
icon="terp-partner" type="action"
string="Create"
attrs="{'invisible':[('partner_id','!=',False)]}"/>
</group>
<field name="partner_address_id"
string="Contact"
on_change="onchange_partner_address_id(partner_address_id, email_from)"
colspan="1" />
<group col="3" colspan="2">
<field name="email_from" string="Email" />
<button string="Mail"
name="%(crm.action_crm_send_mail)d"
context="{'mail':'new', 'model': 'crm.lead'}"
icon="terp-mail-message-new" type="action" />
</group>
<field name="phone"/>
</group>
<group col="2" colspan="2">
<separator colspan="2" string="Categorization"/>
<field name="section_id" colspan="1" widget="selection"/>
<field name="categ_id" select="1"
string="Category" widget="selection"
domain="[('object_id.model', '=', 'crm.lead')]" />
</group>
<separator colspan="4" string="Details"/>
<field name="description" nolabel="1" colspan="4"/>
<separator colspan="4"/>
<group col="10" colspan="4">
<field name="state"/>
<button name="case_cancel" string="Cancel" states="draft" type="object" icon="gtk-cancel" />
<button name="case_mark_lost" string="Mark Lost" states="open,pending" type="object" icon="gtk-cancel" />
<button name="case_reset" string="Reset to Draft" states="done,cancel" type="object" icon="gtk-convert" />
<button name="case_open" string="Open" states="draft,pending" type="object" icon="gtk-go-forward" />
<button name="case_pending" string="Pending" states="draft,open" type="object" icon="gtk-media-pause" />
<button name="case_escalate" string="Escalate" states="open,pending" type="object" groups="base.group_extended" icon="gtk-go-up" />
<button name="case_mark_won" string="Mark Won" states="open,pending" type="object" icon="gtk-apply" />
</group>
</page>
<page string="Lead">
<group colspan="2" col="4">
<separator string="Contact" colspan="4" col="4"/>
<field name="partner_name" string="Customer Name" colspan="4"/>
<newline/>
<field domain="[('domain', '=', 'contact')]" name="title" widget="selection"/>
<field name="function" />
<field name="street" colspan="4"/>
<field name="street2" colspan="4"/>
<field name="zip"/>
<field name="city"/>
<field name="country_id"/>
<field name="state_id"/>
</group>
<group colspan="2" col="2">
<separator string="Communication" colspan="2"/>
<field name="fax"/>
<field name="mobile"/>
</group>
<group colspan="2" col="2">
<separator string="Categorization" colspan="2"/>
<field name="type_id" widget="selection" groups="base.group_extended"/>
<field name="channel_id" widget="selection"/>
</group>
<group colspan="2" col="2">
<separator string="Mailings" colspan="2"/>
<field name="optin" on_change="on_change_optin(optin)"/>
<field name="optout" on_change="on_change_optout(optout)"/>
</group>
</page>
<page string="Communication &amp; History" groups="base.group_extended">
<group colspan="4">
<field colspan="4" name="email_cc" string="Global CC" widget="char" size="512"/>
</group>
<field name="message_ids" colspan="4" nolabel="1" mode="tree,form">
<tree string="History">
<field name="display_text" string="History Information"/>
<field name="history" invisible="1"/>
<button
string="Reply" attrs="{'invisible': [('history', '!=', True)]}"
name="%(crm.action_crm_send_mail)d"
context="{'mail':'reply', 'model': 'crm.lead', 'include_original' : True}"
icon="terp-mail-replied" type="action" />
</tree>
<form string="History">
<group col="4" colspan="4">
<field name="email_from"/>
<field name="date"/>
<field name="email_to" size="512"/>
<field name="email_cc" size="512"/>
<field name="name" colspan="4" widget="char" attrs="{'invisible': [('history', '=', False)]}" size="512"/>
<field name="display_text" colspan="4" attrs="{'invisible': [('history', '=', True)]}"/>
<field name="history" invisible="1"/>
</group>
<notebook colspan="4">
<page string="Details">
<field name="description" colspan="4" nolabel="1"/>
<group attrs="{'invisible': [('history', '!=', True)]}">
<button colspan="4"
string="Reply"
name="%(crm.action_crm_send_mail)d"
context="{'mail':'reply', 'model': 'crm.lead', 'include_original' : True}"
icon="terp-mail-replied" type="action" />
</group>
</page>
<page string="Attachments">
<field name="attachment_ids" colspan="4" readonly="1" nolabel="1"/>
</page>
</notebook>
</form>
</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="%(crm.action_crm_send_mail)d"
context="{'mail':'new', 'model': 'crm.lead'}"
icon="terp-mail-message-new" type="action" />
</page>
<page string="Extra Info" groups="base.group_extended">
<group col="2" colspan="2">
<separator string="Dates" colspan="2"/>
<field name="create_date"/>
<field name="write_date"/>
<field name="date_closed"/>
<field name="date_open"/>
</group>
<group col="2" colspan="2">
<separator string="Misc" colspan="2"/>
<field name="active"/>
<field name="day_open"/>
<field name="day_close"/>
<field name="referred"/>
</group>
<separator colspan="4" string="References"/>
<field name="ref"/>
<field name="ref2"/>
</page>
</notebook>
</form>
</field>
</record>
<!-- Opportunities Tree View -->
<record model="ir.ui.view" id="crm_case_tree_view_oppor">
<field name="name">Opportunities Tree</field>
<field name="model">crm.lead</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Opportunities" colors="blue:state=='pending' and not(date_deadline and (date_deadline &lt; current_date));gray:state in ('cancel', 'done');red:date_deadline and (date_deadline &lt; current_date)">
<field name="date_deadline" invisible="1"/>
<field name="create_date"/>
<field name="name" string="Opportunity"/>
<field name="partner_id" string="Customer"/>
<field name="country_id" invisible="context.get('invisible_country', True)" />
<field name="date_action"/>
<field name="title_action" />
<field name="channel_id" invisible="1"/>
<field name="type_id" invisible="1"/>
<field name="subjects" invisible="1"/>
<field name="stage_id"/>
<button name="stage_previous" string="Previous Stage" states="open,pending" type="object" icon="gtk-go-back" />
<button name="stage_next" string="Next Stage" states="open,pending" type="object" icon="gtk-go-forward" />
<field name="planned_revenue" sum="Expected Revenues"/>
<field name="probability" widget="progressbar" avg="Avg. of Probability"/>
<field name="section_id" invisible="context.get('invisible_section', True)" />
<field name="user_id"/>
<field name="priority" invisible="1"/>
<field name="categ_id" invisible="1"/>
<field name="state"/>
<button name="case_open" string="Open" states="draft,pending" type="object" icon="gtk-go-forward" />
<button name="case_pending" string="Pending" states="open,draft" type="object" icon="gtk-media-pause" />
<button name="case_mark_lost" string="Lost" states="open,pending" type="object" icon="gtk-cancel" />
<button name="case_mark_won" string="Won" states="open,pending" type="object" icon="gtk-apply" />
</tree>
</field>
</record>
<!-- Opportunities Search View -->
<record id="view_crm_case_opportunities_filter" model="ir.ui.view">
<field name="name">CRM - Opportunities Search</field>
<field name="model">crm.lead</field>
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Search Opportunities">
<filter icon="terp-check"
string="Current" help="Draft, Open and Pending Opportunities"
name="current"
domain="[('state','in',('draft','open','pending'))]"/>
<filter icon="terp-camera_test"
string="Open" help="Open Opportunities"
domain="[('state','=','open')]"/>
<filter icon="terp-gtk-media-pause"
string="Pending" help="Pending Opportunities"
domain="[('state','=','pending')]"/>
<separator orientation="vertical"/>
<field name="name" string="Opportunity"/>
<field name="partner_id" string="Customer / Email" filter_domain="['|','|',('partner_id','ilike',self),('partner_name','ilike',self),('email_from','ilike',self)]"/>
<field name="user_id">
<filter icon="terp-personal-"
domain="[('user_id','=', False)]"
help="Unassigned Opportunities" />
</field>
<field name="section_id"
context="{'invisible_section': False}"
widget="selection">
<filter icon="terp-personal+" groups="base.group_extended"
domain="['|', ('section_id', '=', context.get('section_id')), '|', ('section_id.user_id','=',uid), ('section_id.member_ids', 'in', [uid])]"
context="{'invisible_section': False}"
help="My Sales Team(s)" />
<filter icon="terp-personal+" groups="base.group_extended"
context="{'invisible_section': False}"
domain="[]"
help="Show Sales Team"/>
</field>
<newline/>
<group expand="0" string="Group By..." colspan="16">
<filter string="Salesman" icon="terp-personal" domain="[]" context="{'group_by':'user_id'}" />
<filter string="Team" help="Sales Team" icon="terp-personal+" domain="[]" context="{'group_by':'section_id'}"/>
<filter string="Customer" help="Partner" icon="terp-personal+" domain="[]" context="{'group_by':'partner_id'}"/>
<separator orientation="vertical" />
<filter string="Stage" icon="terp-stage" domain="[]" context="{'group_by':'stage_id'}" />
<filter string="Priority" icon="terp-rating-rated" domain="[]" context="{'group_by':'priority'}" />
<filter string="Category" icon="terp-stock_symbol-selection" domain="[]" context="{'group_by':'categ_id'}" />
<filter string="Campaign" icon="terp-gtk-jump-to-rtl" domain="[]" context="{'group_by':'type_id'}" groups="base.group_extended"/>
<filter string="Channel" icon="terp-call-start" domain="[]" context="{'group_by':'channel_id'}" />
<filter string="State" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}"/>
<separator orientation="vertical" />
<filter string="Creation" icon="terp-go-month" domain="[]" context="{'group_by':'create_date'}" />
<filter string="Exp.Closing" icon="terp-go-month" help="Expected Closing" domain="[]" context="{'group_by':'date_deadline'}" />
</group>
</search>
</field>
</record>
<!-- crm.lead Opportunities Graph View -->
<record model="ir.ui.view" id="crm_case_graph_view_opportunity">
<field name="name">CRM - Opportunity Graph</field>
<field name="model">crm.lead</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph string="Opportunity by Categories" type="bar" orientation="horizontal">
<field name="categ_id"/>
<field name="planned_revenue" operator="+"/>
<field name="state" group="True"/>
</graph>
</field>
</record>
</data>
</openerp>

View File

@ -1,223 +0,0 @@
#-*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# 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 fields, osv
from tools.translate import _
import crm
AVAILABLE_STATES = [
('draft','Draft'),
('open','Open'),
('cancel', 'Lost'),
('done', 'Converted'),
('pending','Pending')
]
class crm_opportunity(osv.osv):
""" Opportunity Cases """
_order = "priority,date_action,id desc"
_inherit = 'crm.lead'
_columns = {
# From crm.case
'partner_address_id': fields.many2one('res.partner.address', 'Partner Contact', \
domain="[('partner_id','=',partner_id)]"),
# Opportunity fields
'probability': fields.float('Probability (%)',group_operator="avg"),
'planned_revenue': fields.float('Expected Revenue'),
'ref': fields.reference('Reference', selection=crm._links_get, size=128),
'ref2': fields.reference('Reference 2', selection=crm._links_get, size=128),
'phone': fields.char("Phone", size=64),
'date_deadline': fields.date('Expected Closing'),
'date_action': fields.date('Next Action Date'),
'title_action': fields.char('Next Action', size=64),
'stage_id': fields.many2one('crm.case.stage', 'Stage', domain="[('type','=','opportunity')]"),
}
def _case_close_generic(self, cr, uid, ids, find_stage, *args):
res = super(crm_opportunity, self).case_close(cr, uid, ids, *args)
for case in self.browse(cr, uid, ids):
#if the case is not an opportunity close won't change the stage
if not case.type == 'opportunity':
return res
value = {}
stage_id = find_stage(cr, uid, 'opportunity', case.section_id.id or False)
if stage_id:
stage_obj = self.pool.get('crm.case.stage').browse(cr, uid, stage_id)
value.update({'stage_id': stage_id})
if stage_obj.on_change:
value.update({'probability': stage_obj.probability})
#Done un crm.case
#value.update({'date_closed': time.strftime('%Y-%m-%d %H:%M:%S')})
self.write(cr, uid, ids, value)
return res
def case_close(self, cr, uid, ids, *args):
"""Overrides close for crm_case for setting probability and close date
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of case Ids
@param *args: Tuple Value for additional Params
"""
res = self._case_close_generic(cr, uid, ids, self._find_won_stage, *args)
for (id, name) in self.name_get(cr, uid, ids):
opp = self.browse(cr, uid, id)
if opp.type == 'opportunity':
message = _("The opportunity '%s' has been won.") % name
self.log(cr, uid, id, message)
return res
def case_mark_lost(self, cr, uid, ids, *args):
"""Mark the case as lost: state = done and probability = 0%
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of case Ids
@param *args: Tuple Value for additional Params
"""
res = self._case_close_generic(cr, uid, ids, self._find_lost_stage, *args)
for (id, name) in self.name_get(cr, uid, ids):
opp = self.browse(cr, uid, id)
if opp.type == 'opportunity':
message = _("The opportunity '%s' has been marked as lost.") % name
self.log(cr, uid, id, message)
return res
def case_cancel(self, cr, uid, ids, *args):
"""Overrides cancel for crm_case for setting probability
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of case Ids
@param *args: Tuple Value for additional Params
"""
res = super(crm_opportunity, self).case_cancel(cr, uid, ids, args)
self.write(cr, uid, ids, {'probability' : 0.0})
return res
def case_reset(self, cr, uid, ids, *args):
"""Overrides reset as draft in order to set the stage field as empty
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of case Ids
@param *args: Tuple Value for additional Params
"""
res = super(crm_opportunity, self).case_reset(cr, uid, ids, *args)
self.write(cr, uid, ids, {'stage_id': False, 'probability': 0.0})
return res
def case_open(self, cr, uid, ids, *args):
"""Overrides open for crm_case for setting Open Date
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of case's Ids
@param *args: Give Tuple Value
"""
res = super(crm_opportunity, self).case_open(cr, uid, ids, *args)
return res
def onchange_stage_id(self, cr, uid, ids, stage_id, context=None):
""" @param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of stages IDs
@stage_id: change state id on run time """
if not stage_id:
return {'value':{}}
stage = self.pool.get('crm.case.stage').browse(cr, uid, stage_id, context=context)
if not stage.on_change:
return {'value':{}}
return {'value':{'probability': stage.probability}}
_defaults = {
'company_id': lambda s,cr,uid,c: s.pool.get('res.company')._company_default_get(cr, uid, 'crm.lead', context=c),
'priority': crm.AVAILABLE_PRIORITIES[2][0],
}
def action_makeMeeting(self, cr, uid, ids, context=None):
"""
This opens Meeting's calendar view to schedule meeting on current Opportunity
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of Opportunity to Meeting IDs
@param context: A standard dictionary for contextual values
@return : Dictionary value for created Meeting view
"""
value = {}
for opp in self.browse(cr, uid, ids, context=context):
data_obj = self.pool.get('ir.model.data')
# Get meeting views
result = data_obj._get_id(cr, uid, 'crm', 'view_crm_case_meetings_filter')
res = 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
context = {
'default_opportunity_id': opp.id,
'default_partner_id': opp.partner_id and opp.partner_id.id or False,
'default_user_id': uid,
'default_section_id': opp.section_id and opp.section_id.id or False,
'default_email_from': opp.email_from,
'default_state': 'open',
'default_name': opp.name
}
value = {
'name': _('Meetings'),
'context': context,
'view_type': 'form',
'view_mode': 'calendar,form,tree',
'res_model': 'crm.meeting',
'view_id': False,
'views': [(id1, 'calendar'), (id2, 'form'), (id3, 'tree')],
'type': 'ir.actions.act_window',
'search_view_id': res['res_id'],
'nodestroy': True
}
return value
crm_opportunity()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -1,109 +0,0 @@
<?xml version="1.0"?>
<openerp>
<data noupdate="1">
<!-- CASE STATUS(stage_id) -->
<record model="crm.case.stage" id="stage_opportunity6">
<field name="name">Lost</field>
<field eval="'0'" name="probability"/>
<field eval="'0'" name="sequence"/>
<field name="type">opportunity</field>
</record>
<record model="crm.case.stage" id="stage_opportunity1">
<field name="name">New</field>
<field eval="'10'" name="probability"/>
<field eval="'1'" name="sequence"/>
<field name="type">opportunity</field>
</record>
<record model="crm.case.stage" id="stage_opportunity2">
<field name="name">Qualification</field>
<field eval="'20'" name="probability"/>
<field eval="'2'" name="sequence"/>
<field name="type">opportunity</field>
</record>
<record model="crm.case.stage" id="stage_opportunity3">
<field name="name">Proposition</field>
<field eval="'40'" name="probability"/>
<field eval="'3'" name="sequence"/>
<field name="type">opportunity</field>
</record>
<record model="crm.case.stage" id="stage_opportunity4">
<field name="name">Negotiation</field>
<field eval="'60'" name="probability"/>
<field eval="'4'" name="sequence"/>
<field name="type">opportunity</field>
</record>
<record model="crm.case.stage" id="stage_opportunity5">
<field name="name">Won</field>
<field eval="'100'" name="probability"/>
<field eval="'5'" name="sequence"/>
<field eval="1" name="on_change"/>
<field name="type">opportunity</field>
</record>
<record model="crm.case.section" id="section_sales_department">
<field name="name">Sales Department</field>
<field name="code">Sales</field>
<field name="stage_ids" eval="[(4, ref('stage_opportunity1')), (4, ref('stage_opportunity2')), (4, ref('stage_opportunity3')), (4, ref('stage_opportunity4')), (4, ref('stage_opportunity5')), (4, ref('stage_opportunity6'))]"/>
</record>
<!-- CASE CATEGORY(categ_id) -->
<record model="crm.case.categ" id="categ_oppor1">
<field name="name">Interest in Computer</field>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<record model="crm.case.categ" id="categ_oppor2">
<field name="name">Interest in Accessories</field>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<record model="crm.case.categ" id="categ_oppor3">
<field name="name">Need Services</field>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<record model="crm.case.categ" id="categ_oppor4">
<field name="name">Need Information</field>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<record model="crm.case.categ" id="categ_oppor5">
<field name="name">Need a Website Design</field>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<record model="crm.case.categ" id="categ_oppor6">
<field name="name">Potential Reseller</field>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<record model="crm.case.categ" id="categ_oppor7">
<field name="name">Need Consulting</field>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<record model="crm.case.categ" id="categ_oppor8">
<field name="name">Other</field>
<field name="section_id" ref="section_sales_department"/>
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<!-- Case Resource(type_id) -->
<record model="crm.case.resource.type" id="type_oppor1">
<field name="name">Campaign 2</field>
<field name="section_id" ref="section_sales_department"/>
</record>
<record model="crm.case.resource.type" id="type_oppor2">
<field name="name">Campaign 1</field>
<field name="section_id" ref="section_sales_department"/>
</record>
</data>
</openerp>

View File

@ -1,93 +0,0 @@
<?xml version="1.0"?>
<openerp>
<data noupdate="1">
<!--
((((((((((( Demo Cases )))))))))))
-->
<!--For Opportunity-->
<record id="crm_case_construstazunits0" model="crm.lead">
<field eval="60" name="probability"/>
<field name="partner_address_id" ref="base.res_partner_address_zen"/>
<field eval="1" name="active"/>
<field name="type">opportunity</field>
<field name="type_id" ref="crm.type_oppor1"/>
<field name="partner_id" ref="base.res_partner_3"/>
<field eval="&quot;3&quot;" name="priority"/>
<field name="user_id" ref="base.user_root"/>
<field eval="&quot;open&quot;" name="state"/>
<field eval="85000.0" name="planned_revenue"/>
<field name="section_id" ref="crm.section_sales_department"/>
<field name="categ_id" ref="crm.categ_oppor1"/>
<field name="stage_id" ref="crm.stage_opportunity3"/>
<field eval="&quot;CONS TRUST (AZ) 529701 - 1000 units&quot;" name="name"/>
</record>
<record id="crm_case_rdroundfundingunits0" model="crm.lead">
<field name="partner_address_id" ref="base.res_partner_address_15"/>
<field eval="1" name="active"/>
<field name="type">opportunity</field>
<field name="type_id" ref="crm.type_oppor2"/>
<field name="partner_id" ref="base.res_partner_11"/>
<field eval="&quot;3&quot;" name="priority"/>
<field name="user_id" ref="base.user_root"/>
<field eval="&quot;draft&quot;" name="state"/>
<field eval="45000.0" name="planned_revenue"/>
<field eval="50" name="probability"/>
<field name="section_id" ref="crm.section_sales_department"/>
<field name="categ_id" ref="crm.categ_oppor5"/>
<field name="stage_id" ref="crm.stage_opportunity1"/>
<field eval="&quot;3rd Round Funding - 1000 units &quot;" name="name"/>
</record>
<record id="crm_case_mediapoleunits0" model="crm.lead">
<field eval="10" name="probability"/>
<field name="partner_address_id" ref="base.res_partner_address_3"/>
<field eval="1" name="active"/>
<field name="type">opportunity</field>
<field name="type_id" ref="crm.type_oppor1"/>
<field name="partner_id" ref="base.res_partner_8"/>
<field eval="&quot;3&quot;" name="priority"/>
<field name="user_id" ref="base.user_root"/>
<field eval="&quot;pending&quot;" name="state"/>
<field eval="55000.0" name="planned_revenue"/>
<field eval="70" name="probability"/>
<field name="section_id" ref="crm.section_sales_department"/>
<field name="categ_id" ref="crm.categ_oppor7"/>
<field name="stage_id" ref="crm.stage_opportunity5"/>
<field eval="&quot;Mediapole - 5000 units&quot;" name="name"/>
<field eval="&quot;info@mycompany.net&quot;" name="email_from"/>
</record>
<record id="crm_case_abcfuelcounits0" model="crm.lead">
<field eval="40" name="probability"/>
<field name="partner_address_id" ref="base.res_partner_address_1"/>
<field eval="1" name="active"/>
<field name="type">opportunity</field>
<field name="type_id" ref="crm.type_oppor1"/>
<field name="partner_id" ref="base.res_partner_9"/>
<field eval="&quot;3&quot;" name="priority"/>
<field name="user_id" ref="base.user_demo"/>
<field eval="&quot;open&quot;" name="state"/>
<field eval="45000.0" name="planned_revenue"/>
<field name="section_id" ref="crm.section_sales_department"/>
<field name="categ_id" ref="crm.categ_oppor5"/>
<field name="stage_id" ref="crm.stage_opportunity4"/>
<field eval="&quot;ABC FUEL CO 829264 - 1000 units &quot;" name="name"/>
<field eval="&quot;info@opensides.be&quot;" name="email_from"/>
</record>
<record id="crm_case_dirtminingltdunits0" model="crm.lead">
<field eval="80" name="probability"/>
<field name="partner_address_id" ref="base.res_partner_address_wong"/>
<field eval="1" name="active"/>
<field name="type">opportunity</field>
<field name="partner_id" ref="base.res_partner_maxtor"/>
<field eval="&quot;3&quot;" name="priority"/>
<field name="user_id" ref="base.user_root"/>
<field eval="&quot;done&quot;" name="state"/>
<field eval="42000.0" name="planned_revenue"/>
<field name="section_id" ref="crm.section_sales_department"/>
<field name="categ_id" ref="crm.categ_oppor2"/>
<field name="stage_id" ref="crm.stage_opportunity6"/>
<field eval="&quot;Dirt Mining Ltd 271742 - 1000 units&quot;" name="name"/>
</record>
</data>
</openerp>

View File

@ -1,68 +0,0 @@
<?xml version="1.0"?>
<openerp>
<data>
<act_window
id="act_crm_opportunity_crm_phonecall_new"
name="Phone calls"
groups="base.group_extended"
res_model="crm.phonecall"
src_model="crm.lead"
view_mode="tree,calendar,form"
context="{'default_duration': 1.0 ,'default_opportunity_id': active_id,'default_partner_phone':phone}"
domain="[('opportunity_id', '=', active_id)]"
view_type="form"/>
<act_window
id="act_crm_opportunity_crm_meeting_new"
name="Meetings"
res_model="crm.meeting"
src_model="crm.lead"
view_mode="tree,form,calendar,"
context="{'default_duration': 4.0, 'default_opportunity_id': active_id}"
domain="[('opportunity_id', '=', active_id)]"
view_type="form"/>
<record model="ir.actions.act_window" id="crm_case_category_act_oppor11">
<field name="name">Opportunities</field>
<field name="res_model">crm.lead</field>
<field name="view_mode">tree,form,graph,calendar</field>
<field name="domain">[('type','=','opportunity')]</field>
<field name="context">{'search_default_user_id':uid,'search_default_current':1, 'search_default_section_id':section_id, 'stage_type': 'opportunity'}</field>
<field name="view_id" ref="crm_case_tree_view_oppor"/>
<field name="search_view_id" ref="crm.view_crm_case_opportunities_filter"/>
<field name="help">With opportunities you can manage and keep track of your sales pipeline by creating specific customer- or prospect-related sales documents to follow up potential sales. Information such as expected revenue, opportunity stage, expected closing date, communication history and much more can be stored. Opportunities can be connected to the email gateway: new emails may create opportunities, each of them automatically gets the history of the conversation with the customer.
You and your team(s) will be able to plan meetings and phone calls from opportunities, convert them into quotations, manage related documents, track all customer related activities, and much more.</field>
</record>
<record model="ir.actions.act_window.view" id="action_crm_tag_tree_view_oppor11">
<field name="sequence" eval="1"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="crm_case_tree_view_oppor"/>
<field name="act_window_id" ref="crm_case_category_act_oppor11"/>
</record>
<record model="ir.actions.act_window.view" id="action_crm_tag_form_view_oppor11">
<field name="sequence" eval="2"/>
<field name="view_mode">form</field>
<field name="view_id" ref="crm_case_form_view_oppor"/>
<field name="act_window_id" ref="crm_case_category_act_oppor11"/>
</record>
<record model="ir.actions.act_window.view" id="action_crm_tag_graph_view_oppor11">
<field name="sequence" eval="4"/>
<field name="view_mode">graph</field>
<field name="view_id" ref="crm_case_graph_view_opportunity"/>
<field name="act_window_id" ref="crm_case_category_act_oppor11"/>
</record>
<menuitem id="base.menu_sales" name="Sales"
parent="base.menu_base_partner" sequence="1" />
<menuitem name="Opportunities" id="menu_crm_case_opp"
parent="base.menu_sales" action="crm_case_category_act_oppor11"
sequence="2" />
</data>
</openerp>

View File

@ -1,363 +0,0 @@
<?xml version="1.0"?>
<openerp>
<data>
<!-- Opportunities Form View -->
<record model="ir.ui.view" id="crm_case_form_view_oppor">
<field name="name">Opportunities</field>
<field name="model">crm.lead</field>
<field name="type">form</field>
<field name="priority">10</field>
<field name="arch" type="xml">
<form string="Opportunities">
<group colspan="4" col="7">
<field name="name" required="1" string="Opportunity"/>
<label string="Stage:" align="1.0"/>
<group colspan="1" col="4">
<field name="stage_id" nolabel="1"
on_change="onchange_stage_id(stage_id)"
domain="[('type','=','opportunity'),('section_ids', '=', section_id)]"/>
<button name="stage_previous"
states="draft,open,pending" type="object"
icon="gtk-go-back" string="" context="{'stage_type': 'opportunity'}"/>
<button name="stage_next" states="draft,open,pending"
type="object" icon="gtk-go-forward" string="" context="{'stage_type': 'opportunity'}"/>
</group>
<field name="user_id"/>
<button string="Schedule/Log Call"
name="%(opportunity2phonecall_act)d" icon="terp-call-start" type="action" groups="base.group_extended"/>
<field name="planned_revenue"/>
<field name="probability"/>
<field name="date_deadline"/>
<button name="action_makeMeeting" type="object"
string="Schedule Meeting" icon="gtk-redo" />
<newline/>
<field name="date_action"/>
<field name="title_action"/>
<field name="priority" string="Priority"/>
<newline/>
<field name="type" invisible="1"/>
</group>
<notebook colspan="4">
<page string="Opportunity">
<group col="4" colspan="2">
<separator colspan="4" string="Contacts"/>
<group colspan="2">
<field name="partner_id" select="1"
on_change="onchange_partner_id(partner_id, email_from)" string="Customer"
colspan="2" />
<button name="%(action_crm_lead2partner)d"
icon="terp-partner" type="action"
string="Create"
attrs="{'invisible':[('partner_id','!=',False)]}"/>
</group>
<field name="partner_address_id"
string="Contact"
on_change="onchange_partner_address_id(partner_address_id, email_from)"
colspan="1" />
<group col="3" colspan="2">
<field name="email_from" string="Email" />
<button string="Mail"
name="%(crm.action_crm_send_mail)d"
context="{'mail':'new', 'model': 'crm.lead'}"
icon="terp-mail-message-new" type="action" />
</group>
<field name="phone"/>
</group>
<group col="2" colspan="2">
<separator colspan="2" string="Categorization"/>
<field name="section_id" colspan="1" widget="selection"/>
<field name="categ_id" select="1"
string="Category" widget="selection"
domain="[('object_id.model', '=', 'crm.lead')]" />
</group>
<separator colspan="4" string="Details"/>
<field name="description" nolabel="1" colspan="4"/>
<separator colspan="4"/>
<group col="10" colspan="4">
<field name="state"/>
<button name="case_cancel" string="Cancel"
states="draft" type="object"
icon="gtk-cancel" />
<button name="case_mark_lost" string="Mark Lost"
states="open,pending" type="object"
icon="gtk-cancel" />
<button name="case_reset" string="Reset to Draft"
states="done,cancel" type="object"
icon="gtk-convert" />
<button name="case_open" string="Open"
states="draft,pending" type="object"
icon="gtk-go-forward" />
<button name="case_pending" string="Pending"
states="draft,open" type="object"
icon="gtk-media-pause" />
<button name="case_escalate" string="Escalate"
states="open,pending" type="object"
groups="base.group_extended"
icon="gtk-go-up" />
<button name="case_close" string="Mark Won"
states="open,pending" type="object"
icon="gtk-apply" />
</group>
</page>
<page string="Lead">
<group colspan="2" col="4">
<separator string="Contact" colspan="4" col="4"/>
<field name="partner_name" string="Customer Name" colspan="4"/>
<newline/>
<field domain="[('domain', '=', 'contact')]" name="title" widget="selection"/>
<field name="function" />
<field name="street" colspan="4"/>
<field name="street2" colspan="4"/>
<field name="zip"/>
<field name="city"/>
<field name="country_id"/>
<field name="state_id"/>
</group>
<group colspan="2" col="2">
<separator string="Communication" colspan="2"/>
<field name="fax"/>
<field name="mobile"/>
</group>
<group colspan="2" col="2">
<separator string="Categorization" colspan="2"/>
<field name="type_id" widget="selection" groups="base.group_extended"/>
<field name="channel_id" widget="selection"/>
</group>
<group colspan="2" col="2">
<separator string="Mailings" colspan="2"/>
<field name="optin" on_change="on_change_optin(optin)"/>
<field name="optout" on_change="on_change_optout(optout)"/>
</group>
</page>
<page string="Communication &amp; History" groups="base.group_extended">
<group colspan="4">
<field colspan="4" name="email_cc" string="Global CC" widget="char" size="512"/>
</group>
<field name="message_ids" colspan="4" nolabel="1" mode="tree,form">
<tree string="History">
<field name="display_text" string="History Information"/>
<field name="history" invisible="1"/>
<button
string="Reply" attrs="{'invisible': [('history', '!=', True)]}"
name="%(crm.action_crm_send_mail)d"
context="{'mail':'reply', 'model': 'crm.lead', 'include_original' : True}"
icon="terp-mail-replied" type="action" />
</tree>
<form string="History">
<group col="4" colspan="4">
<field name="email_from"/>
<field name="date"/>
<field name="email_to" size="512"/>
<field name="email_cc" size="512"/>
<field name="name" colspan="4" widget="char" attrs="{'invisible': [('history', '=', False)]}" size="512"/>
<field name="display_text" colspan="4" attrs="{'invisible': [('history', '=', True)]}"/>
<field name="history" invisible="1"/>
</group>
<notebook colspan="4">
<page string="Details">
<field name="description" colspan="4" nolabel="1"/>
<group attrs="{'invisible': [('history', '!=', True)]}">
<button colspan="4"
string="Reply"
name="%(crm.action_crm_send_mail)d"
context="{'mail':'reply', 'model': 'crm.lead', 'include_original' : True}"
icon="terp-mail-replied" type="action" />
</group>
</page>
<page string="Attachments">
<field name="attachment_ids" colspan="4" readonly="1" nolabel="1"/>
</page>
</notebook>
</form>
</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="%(crm.action_crm_send_mail)d"
context="{'mail':'new', 'model': 'crm.lead'}"
icon="terp-mail-message-new" type="action" />
</page>
<page string="Extra Info" groups="base.group_extended">
<group col="2" colspan="2">
<separator string="Dates" colspan="2"/>
<field name="create_date"/>
<field name="write_date"/>
<field name="date_closed"/>
<field name="date_open"/>
</group>
<group col="2" colspan="2">
<separator string="Misc" colspan="2"/>
<field name="active"/>
<field name="day_open"/>
<field name="day_close"/>
<field name="referred"/>
</group>
<separator colspan="4" string="References"/>
<field name="ref"/>
<field name="ref2"/>
</page>
</notebook>
</form>
</field>
</record>
<!-- Opportunities Tree View -->
<record model="ir.ui.view" id="crm_case_tree_view_oppor">
<field name="name">Opportunities Tree</field>
<field name="model">crm.lead</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Opportunities" colors="blue:state=='pending' and not(date_deadline and (date_deadline &lt; current_date));gray:state in ('cancel', 'done');red:date_deadline and (date_deadline &lt; current_date)">
<field name="date_deadline" invisible="1"/>
<field name="create_date"/>
<field name="name" string="Opportunity"/>
<field name="partner_id" string="Customer"/>
<field name="country_id" invisible="context.get('invisible_country', True)" />
<field name="date_action"/>
<field name="title_action" />
<field name="stage_id"/>
<field name="channel_id" invisible="1"/>
<field name="type_id" invisible="1"/>
<field name="subjects" invisible="1"/>
<button name="stage_previous" string="Previous Stage"
states="open,pending" type="object" icon="gtk-go-back" />
<button name="stage_next" string="Next Stage"
states="open,pending" type="object"
icon="gtk-go-forward" />
<field name="planned_revenue" sum="Expected Revenues"/>
<field name="probability" widget="progressbar" avg="Avg. of Probability"/>
<field name="section_id"
invisible="context.get('invisible_section', True)" />
<field name="user_id"/>
<field name="priority" invisible="1"/>
<field name="categ_id" invisible="1"/>
<field name="state"/>
<button name="case_open" string="Open"
states="draft,pending" type="object"
icon="gtk-go-forward" />
<button name="case_pending" string="Pending"
states="open,draft" type="object"
icon="gtk-media-pause" />
<button name="case_close" string="Won"
states="open,draft,pending" type="object"
icon="gtk-apply" />
</tree>
</field>
</record>
<!-- Opportunities Graph View -->
<record model="ir.ui.view" id="crm_case_graph_view_opportunity">
<field name="name">CRM - Opportunity Graph</field>
<field name="model">crm.lead</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph string="Opportunity by Categories" type="bar" orientation="horizontal">
<field name="categ_id"/>
<field name="planned_revenue" operator="+"/>
<field name="state" group="True"/>
</graph>
</field>
</record>
<!-- Opportunities Search View -->
<record id="view_crm_case_opportunities_filter" model="ir.ui.view">
<field name="name">CRM - Opportunities Search</field>
<field name="model">crm.lead</field>
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Search Opportunities">
<filter icon="terp-check"
string="Current" help="Draft, Open and Pending Opportunities"
name="current"
domain="[('state','in',('draft','open','pending'))]"/>
<filter icon="terp-camera_test"
string="Open" help="Open Opportunities"
domain="[('state','=','open')]"/>
<filter icon="terp-gtk-media-pause"
string="Pending" help="Pending Opportunities"
domain="[('state','=','pending')]"/>
<separator orientation="vertical"/>
<field name="name" string="Opportunity"/>
<field name="partner_id" string="Customer / Email" filter_domain="['|','|',('partner_id','ilike',self),('partner_name','ilike',self),('email_from','ilike',self)]"/>
<field name="user_id">
<filter icon="terp-personal-"
domain="[('user_id','=', False)]"
help="Unassigned Opportunities" />
</field>
<field name="section_id"
context="{'invisible_section': False}"
widget="selection">
<filter icon="terp-personal+" groups="base.group_extended"
domain="['|', ('section_id', '=', context.get('section_id')), '|', ('section_id.user_id','=',uid), ('section_id.member_ids', 'in', [uid])]"
context="{'invisible_section': False}"
help="My Sales Team(s)" />
<filter icon="terp-personal+" groups="base.group_extended"
context="{'invisible_section': False}"
domain="[]"
help="Show Sales Team"/>
</field>
<newline/>
<group expand="0" string="Group By..." colspan="16">
<filter string="Salesman" icon="terp-personal"
domain="[]" context="{'group_by':'user_id'}" />
<filter string="Team" help="Sales Team" icon="terp-personal+" domain="[]" context="{'group_by':'section_id'}"/>
<filter string="Customer" help="Partner" icon="terp-personal+" domain="[]" context="{'group_by':'partner_id'}"/>
<separator orientation="vertical" />
<filter string="Stage" icon="terp-stage" domain="[]"
context="{'group_by':'stage_id'}" />
<filter string="Priority" icon="terp-rating-rated" domain="[]"
context="{'group_by':'priority'}" />
<filter string="Category" icon="terp-stock_symbol-selection"
domain="[]" context="{'group_by':'categ_id'}" />
<filter string="Campaign" icon="terp-gtk-jump-to-rtl"
domain="[]" context="{'group_by':'type_id'}" groups="base.group_extended"/>
<filter string="Channel" icon="terp-call-start"
domain="[]" context="{'group_by':'channel_id'}" />
<filter string="State" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}"/>
<separator orientation="vertical" />
<filter string="Creation" icon="terp-go-month"
domain="[]" context="{'group_by':'create_date'}" />
<filter string="Exp.Closing"
icon="terp-go-month"
help="Expected Closing" domain="[]"
context="{'group_by':'date_deadline'}" />
</group>
</search>
</field>
</record>
<!-- Opportunities Graph View -->
<record model="ir.ui.view" id="crm_case_graph_view_opportunity">
<field name="name">CRM - Opportunity Graph</field>
<field name="model">crm.lead</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph string="Opportunity by Categories" type="bar" orientation="horizontal">
<field name="categ_id"/>
<field name="planned_revenue" operator="+"/>
<field name="state" group="True"/>
</graph>
</field>
</record>
</data>
</openerp>

View File

@ -108,7 +108,6 @@
<field name="sequence"/>
<field name="name"/>
<field name="probability"/>
<field name="type" />
</tree>
</field>
</record>
@ -124,8 +123,6 @@
<form string="Stage">
<separator string="Stage Definition" colspan="4"/>
<field name="name" select="1"/>
<field name="type" groups="base.group_extended" />
<field name="sequence"/>
<field name="probability"/>
<group colspan="4" col="2" >
@ -133,7 +130,7 @@
</group>
<separator string="Requirements" colspan="4"/>
<field name="requirements" nolabel="1" colspan="4"/>
<field name="section_ids" invisible="1" />
<field name="section_ids" invisible="1" colspan="4"/>
</form>
</field>
</record>
@ -146,9 +143,9 @@
<field name="view_type">form</field>
<field name="view_id" ref="crm_case_stage_tree"/>
</record>
<!-- Case Categories Form View -->
<!-- Case Categories Form View -->
<record id="crm_case_categ-view" model="ir.ui.view">
<field name="name">crm.case.categ.form</field>
@ -372,49 +369,6 @@
</field>
</record>
<!-- Inherit View From Partner -->
<record id="view_partners_form_crm1" model="ir.ui.view">
<field name="name">view.res.partner.form.crm.inherited1</field>
<field name="model">res.partner</field>
<field name="type">form</field>
<field name="inherit_id" ref="base.view_partner_form"/>
<field eval="18" name="priority"/>
<field name="arch" type="xml">
<field name="user_id" position="after">
<field name="section_id" completion="1" widget="selection"
groups="base.group_extended"/>
</field>
</field>
</record>
<record id="view_partners_tree_crm2" model="ir.ui.view">
<field name="name">view.res.partner.tree.crm.inherited2</field>
<field name="model">res.partner</field>
<field name="type">tree</field>
<field name="inherit_id" ref="base.view_partner_tree"/>
<field eval="18" name="priority"/>
<field name="arch" type="xml">
<field name="country" position="after">
<field name="section_id" completion="1" widget="selection"
groups="base.group_extended"/>
</field>
</field>
</record>
<record id="view_partners_form_crm3" model="ir.ui.view">
<field name="name">view.res.partner.search.crm.inherited3</field>
<field name="model">res.partner</field>
<field name="type">search</field>
<field name="inherit_id" ref="base.view_res_partner_filter"/>
<field eval="18" name="priority"/>
<field name="arch" type="xml">
<field name="category_id" position="after">
<field name="section_id" completion="1" widget="selection"
groups="base.group_extended"/>
</field>
</field>
</record>
<!-- menu for the working time -->
<menuitem action="resource.action_resource_calendar_form" id="menu_action_resource_calendar_form" parent="resource.menu_resource_config" sequence="1"/>

View File

@ -74,7 +74,7 @@ class crm_lead_report(osv.osv):
'probable_revenue': fields.float('Probable Revenue', digits=(16,2),readonly=True),
'categ_id': fields.many2one('crm.case.categ', 'Category',\
domain="['|',('section_id','=',False),('section_id','=',section_id)]" , readonly=True),
'stage_id': fields.many2one ('crm.case.stage', 'Stage', readonly=True, domain="[('type', '=', 'lead')]"),
'stage_id': fields.many2one ('crm.case.stage', 'Stage', readonly=True, domain="[(section_ids', '=', section_id)]"),
'partner_id': fields.many2one('res.partner', 'Partner' , readonly=True),
'opening_date': fields.date('Opening Date', readonly=True, select=True),
'creation_date': fields.date('Creation Date', readonly=True, select=True),

View File

@ -121,7 +121,7 @@
<group expand="0" string="Extended Filters..." groups="base.group_extended">
<field name="partner_id"/>
<separator orientation="vertical"/>
<field name="stage_id" widget="selection" domain="[('type', '=', 'lead')]" />
<field name="stage_id" widget="selection" domain="[('section_ids', '=', 'section_id')]" />
<field name="categ_id" widget="selection"/>
<field name="type_id" widget="selection"/>
<field name="channel_id" widget="selection"/>
@ -233,7 +233,6 @@
<field name="view_type">form</field>
<field name="context">{"search_default_filter_opportunity":1, "search_default_opportunity": 1, "search_default_user":1,"search_default_this_month":1,'group_by_no_leaf':1,'group_by':[]}</field>
<field name="view_mode">tree,graph</field>
<field name="domain">[('type', '=', 'opportunity')]</field>
<field name="help">Opportunities Analysis gives you an instant access to your opportunities with information such as the expected revenue, planned cost, missed deadlines or the number of interactions per opportunity. This report is mainly used by the sales manager in order to do the periodic review with the teams of the sales pipeline.</field>
</record>

View File

@ -25,6 +25,7 @@ class res_partner(osv.osv):
""" Inherits partner and adds CRM information in the partner form """
_inherit = 'res.partner'
_columns = {
'section_id': fields.many2one('crm.case.section', 'Sales Team'),
'opportunity_ids': fields.one2many('crm.lead', 'partner_id',\
'Leads and Opportunities'),
'meeting_ids': fields.one2many('crm.meeting', 'partner_id',\

View File

@ -2,8 +2,50 @@
<openerp>
<data>
<!-- Partners inherited form -->
<!-- Add section_id (Sales Team) to res.partner -->
<record id="view_partners_form_crm1" model="ir.ui.view">
<field name="name">view.res.partner.form.crm.inherited1</field>
<field name="model">res.partner</field>
<field name="type">form</field>
<field name="inherit_id" ref="base.view_partner_form"/>
<field eval="18" name="priority"/>
<field name="arch" type="xml">
<field name="user_id" position="after">
<field name="section_id" completion="1" widget="selection"
groups="base.group_extended"/>
</field>
</field>
</record>
<record id="view_partners_tree_crm2" model="ir.ui.view">
<field name="name">view.res.partner.tree.crm.inherited2</field>
<field name="model">res.partner</field>
<field name="type">tree</field>
<field name="inherit_id" ref="base.view_partner_tree"/>
<field eval="18" name="priority"/>
<field name="arch" type="xml">
<field name="country" position="after">
<field name="section_id" completion="1" widget="selection"
groups="base.group_extended"/>
</field>
</field>
</record>
<record id="view_partners_form_crm3" model="ir.ui.view">
<field name="name">view.res.partner.search.crm.inherited3</field>
<field name="model">res.partner</field>
<field name="type">search</field>
<field name="inherit_id" ref="base.view_res_partner_filter"/>
<field eval="18" name="priority"/>
<field name="arch" type="xml">
<field name="category_id" position="after">
<field name="section_id" completion="1" widget="selection"
groups="base.group_extended"/>
</field>
</field>
</record>
<!-- Add History tabs to res.partner form -->
<record id="view_crm_partner_info_form1" model="ir.ui.view">
<field name="name">res.partner.crm.info.inherit1</field>
<field name="model">res.partner</field>
@ -66,6 +108,9 @@
</page>
</field>
</record>
</data>
</openerp>

View File

@ -8,7 +8,7 @@
partner_address_id: base.res_partner_address_1
partner_id: base.res_partner_9
probability: 1.0
stage_id: crm.stage_opportunity1
stage_id: crm.stage_lead1
categ_id: crm.categ_oppor2
section_id: crm.section_sales_department

View File

@ -5,14 +5,13 @@
I want to change the probability to 0.0 when the opportunity is marked as lost.
So I set its Change probability automatically true.
-
!record {model: crm.case.stage, id: crm.stage_opportunity6}:
!record {model: crm.case.stage, id: crm.stage_lead6}:
name: Lost
on_change: true
probability: 0.0
section_ids:
- crm.section_sales_department
sequence: 0.0
type: opportunity
-
I create a lead 'OpenERP Presentation'.
-
@ -56,7 +55,7 @@
-
!python {model: crm.lead}: |
opportunity = self.browse(cr, uid, ref('crm_lead_openerppresentation0'))
assert opportunity.stage_id.id == ref('crm.stage_opportunity6'), 'Stage is not changed!'
assert opportunity.stage_id.id == ref('crm.stage_lead6'), 'Stage is not changed!'
assert opportunity.probability == 0.0, 'Probability is wrong!'
-
I create one more opportunity.
@ -67,9 +66,8 @@
day_open: 0.0
name: Partner Demo
planned_revenue: 50000.0
probability: 70.0
probability: 100.0
section_id: crm.section_sales_department
type: opportunity
-
I open this opportunity.
-
@ -85,5 +83,5 @@
-
!python {model: crm.lead}: |
opportunity = self.browse(cr, uid, ref('crm_lead_partnerdemo0'))
assert opportunity.stage_id.id == ref('crm.stage_opportunity5'), 'Stage is not changed!'
assert opportunity.stage_id.id == ref('crm.stage_lead1'), 'Stage is not changed!'
assert opportunity.probability == 100.0, 'Probability is wrong!'

View File

@ -188,9 +188,9 @@ class crm_lead2opportunity_partner(osv.osv_memory):
for lead in leads.browse(cr, uid, record_id, context=context):
if lead.section_id:
stage_ids = self.pool.get('crm.case.stage').search(cr, uid, [('type','=','opportunity'),('sequence','>=',1), ('section_ids','=', lead.section_id.id)])
stage_ids = self.pool.get('crm.case.stage').search(cr, uid, [('sequence','>=',1), ('section_ids','=', lead.section_id.id)])
else:
stage_ids = self.pool.get('crm.case.stage').search(cr, uid, [('type','=','opportunity'),('sequence','>=',1)])
stage_ids = self.pool.get('crm.case.stage').search(cr, uid, [('sequence','>=',1)])
data = self.browse(cr, uid, ids[0], context=context)

View File

@ -73,7 +73,7 @@ class crm_claim(crm.crm_case, osv.osv):
'email_cc': fields.text('Watchers Emails', size=252, help="These email addresses will be added to the CC field of all inbound and outbound emails for this record before being sent. Separate multiple email addresses with a comma"),
'email_from': fields.char('Email', size=128, help="These people will receive email."),
'partner_phone': fields.char('Phone', size=32),
'stage_id': fields.many2one ('crm.case.stage', 'Stage', domain="[('type','=','claim')]"),
'stage_id': fields.many2one ('crm.case.stage', 'Stage', domain="[('section_ids','=',section_id)]"),
'cause': fields.text('Root Cause'),
'state': fields.selection(crm.AVAILABLE_STATES, 'State', size=16, readonly=True,
help='The state is set to \'Draft\', when a case is created.\
@ -274,20 +274,4 @@ class res_partner(osv.osv):
}
res_partner()
class crm_stage_claim(osv.osv):
def _get_type_value(self, cr, user, context):
list = super(crm_stage_claim, self)._get_type_value(cr, user, context)
list.append(('claim','Claim'))
return list
_inherit = "crm.case.stage"
_columns = {
'type': fields.selection(_get_type_value, 'Type'),
}
crm_stage_claim()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -44,25 +44,20 @@
<record model="crm.case.stage" id="stage_claim1">
<field name="name">Accepted as Claim</field>
<field name="sequence">1</field>
<field name="type">claim</field>
<field name="sequence">26</field>
</record>
<record model="crm.case.stage" id="stage_claim5">
<field name="name">Actions Defined</field>
<field name="sequence">2</field>
<field name="type">claim</field>
<field name="sequence">27</field>
</record>
<record model="crm.case.stage" id="stage_claim2">
<field name="name">Actions Done</field>
<field name="sequence">10</field>
<field name="type">claim</field>
<field name="sequence">28</field>
</record>
<record model="crm.case.stage" id="stage_claim3">
<field name="name">Won't fix</field>
<field name="sequence">0</field>
<field name="type">claim</field>
<field name="sequence">29</field>
</record>
<record model="crm.case.section" id="crm.section_sales_department">
<field name="name">Sales Department</field>

View File

@ -21,23 +21,6 @@
<menuitem action="crm_claim_categ_action" name="Categories"
id="menu_crm_case_claim-act" parent="menu_config_claim" />
<!-- Claim Stage Search view -->
<record id="claim_stage_search" model="ir.ui.view">
<field name="name">Claim Stage - Search</field>
<field name="model">crm.case.stage</field>
<field name="type">search</field>
<field name="inherit_id" ref="crm.crm_lead_stage_search"/>
<field name="arch" type="xml">
<data>
<xpath expr="//field[@name='name']" position="before">
<filter icon="terp-personal-" name="claim"
string="Claim" domain="[('type', '=', 'claim')]" context="{'type' : 'claim'}"/>
</xpath>
</data>
</field>
</record>
<!-- Claim Stages -->
<record id="crm_claim_stage_act" model="ir.actions.act_window">
@ -45,14 +28,10 @@
<field name="res_model">crm.case.stage</field>
<field name="view_type">form</field>
<field name="view_id" ref="crm.crm_case_stage_tree"/>
<field name="search_view_id" ref="claim_stage_search"/>
<field name="context">{'search_default_claim':1}</field>
<field name="help">You can create claim stages to categorize the status of every claim entered in the system. The stages define all the steps required for the resolution of a claim.</field>
</record>
<menuitem action="crm_claim_stage_act" name="Stages"
id="menu_crm_claim_stage_act" parent="menu_config_claim" />
<!-- Claims -->
<record model="ir.ui.view" id="crm_case_claims_tree_view">
@ -101,7 +80,7 @@
<field name="section_id" widget="selection" />
<group colspan="2" col="4">
<field name="stage_id" domain="[('type','=','claim')]"/>
<field name="stage_id" domain="[('section_ids','=',section_id)]"/>
<button name="stage_previous" string="" type="object" icon="gtk-go-back" />
<button icon="gtk-go-forward" string="" name="stage_next" type="object"/>
</group>

View File

@ -62,7 +62,7 @@ class crm_claim_report(osv.osv):
'create_date': fields.datetime('Create Date', readonly=True, select=True),
'day': fields.char('Day', size=128, readonly=True),
'delay_close': fields.float('Delay to close', digits=(16,2),readonly=True, group_operator="avg",help="Number of Days to close the case"),
'stage_id': fields.many2one ('crm.case.stage', 'Stage', readonly=True, domain="[('type','=','claim')]"),
'stage_id': fields.many2one ('crm.case.stage', 'Stage', readonly=True,domain="[('section_ids','=',section_id)]"),
'categ_id': fields.many2one('crm.case.categ', 'Category',\
domain="[('section_id','=',section_id),\
('object_id.model', '=', 'crm.claim')]", readonly=True),
@ -107,7 +107,7 @@ class crm_claim_report(osv.osv):
date_trunc('day',c.create_date) as create_date,
avg(extract('epoch' from (c.date_closed-c.create_date)))/(3600*24) as delay_close,
(SELECT count(id) FROM mailgate_message WHERE model='crm.claim' AND res_id=c.id AND history=True) AS email,
(SELECT avg(probability) FROM crm_case_stage WHERE type='claim' AND id=c.stage_id) AS probability,
(SELECT avg(probability) FROM crm_case_stage WHERE id=c.stage_id) AS probability,
extract('epoch' from (c.date_deadline - c.date_closed))/(3600*24) as delay_expected
from
crm_claim c

View File

@ -110,7 +110,7 @@
<separator orientation="vertical"/>
<field name="partner_id"/>
<separator orientation="vertical"/>
<field name="stage_id" widget="selection" domain="[('type', '=', 'claim')]"/>
<field name="stage_id" widget="selection" domain="[('section_ids', '=', 'section_id')]"/>
<field name="categ_id" widget="selection" domain="[('object_id.model', '=', 'crm.claim')]"/>
<separator orientation="vertical"/>
<field name="priority" />

View File

@ -61,7 +61,7 @@ class crm_fundraising(crm.crm_case, osv.osv):
'partner_name2': fields.char('Employee Email', size=64),
'partner_phone': fields.char('Phone', size=32),
'partner_mobile': fields.char('Mobile', size=32),
'stage_id': fields.many2one ('crm.case.stage', 'Stage', domain="[('type', '=', 'fundraising')]"),
'stage_id': fields.many2one ('crm.case.stage', 'Stage', domain="[('section_ids', '=', section_id)]"),
'type_id': fields.many2one('crm.case.resource.type', 'Campaign', \
domain="[('section_id','=',section_id)]"),
'duration': fields.float('Duration'),
@ -95,18 +95,3 @@ class crm_fundraising(crm.crm_case, osv.osv):
crm_fundraising()
class crm_stage_fundraising(osv.osv):
def _get_type_value(self, cr, user, context):
list = super(crm_stage_fundraising, self)._get_type_value(cr, user, context)
list.append(('fundraising','Fundraising'))
return list
_inherit = "crm.case.stage"
_columns = {
'type': fields.selection(_get_type_value, 'Type'),
}
crm_stage_fundraising()

View File

@ -6,24 +6,6 @@
groups="base.group_extended"
parent="base.menu_base_config" sequence="8" />
<!-- Fund Stage Search view -->
<record id="fund_stage_search" model="ir.ui.view">
<field name="name">Fund Stage - Search</field>
<field name="model">crm.case.stage</field>
<field name="type">search</field>
<field name="inherit_id" ref="crm.crm_lead_stage_search"/>
<field name="arch" type="xml">
<data>
<xpath expr="//field[@name='name']" position="before">
<filter icon="terp-dolar" name="fundraising"
string="Fundraising" domain="[('type', '=', 'fundraising')]" context="{'type' : 'fundraising'}"/>
</xpath>
</data>
</field>
</record>
<!-- Fund Raising Categories Form View -->
<record id="crm_fund_categ_action" model="ir.actions.act_window">
@ -33,7 +15,6 @@
<field name="view_id" ref="crm.crm_case_categ_tree-view"/>
<field name="domain">[('object_id.model', '=', 'crm.fundraising')]</field>
<field name="context">{'object_id':'crm.fundraising'}</field>
<field name="search_view_id" ref="fund_stage_search"/>
<field name="help">Manage and define the fund raising categories you want to be maintained in the system.</field>
</record>
@ -52,13 +33,6 @@
<field name="help">Create and manage fund raising activity categories you want to be maintained in the system.</field>
</record>
<menuitem action="crm_fundraising_stage_act"
groups="base.group_extended" name="Stages"
id="menu_crm_fundraising_stage_act"
parent="menu_config_fundrising" />
<!-- Fund Raising Tree View -->
<record model="ir.ui.view" id="crm_case_tree_view_fund">

View File

@ -61,7 +61,7 @@
<filter string="Referred Partner" icon="terp-personal" domain="[]" context="{'group_by':'partner_assigned_id'}"/>
</filter>
<field name="categ_id" position="after">
<field name="section_id" position="after">
<separator orientation="vertical"/>
<field name="partner_assigned_id"/>
</field>

View File

@ -63,7 +63,7 @@ class crm_lead_report_assign(osv.osv):
'probable_revenue': fields.float('Probable Revenue', digits=(16,2),readonly=True),
'categ_id': fields.many2one('crm.case.categ', 'Category',\
domain="[('section_id','=',section_id)]" , readonly=True),
'stage_id': fields.many2one ('crm.case.stage', 'Stage', domain="[('type', '=', 'lead')]"),
'stage_id': fields.many2one ('crm.case.stage', 'Stage', domain="[('section_ids', '=', section_id)]"),
'partner_id': fields.many2one('res.partner', 'Customer' , readonly=True),
'opening_date': fields.date('Opening Date', readonly=True),
'creation_date': fields.date('Creation Date', readonly=True),

View File

@ -33,7 +33,7 @@
<group expand="0" string="Extended Filters..." groups="base.group_extended">
<field name="partner_id"/>
<separator orientation="vertical"/>
<field name="stage_id" widget="selection" domain="[('type', '=', 'opportunity')]" />
<field name="stage_id" widget="selection" domain="[('section_ids', '=', 'section_id')]"/>
<field name="categ_id" widget="selection" domain="[('object_id.model', '=', 'crm.lead')]"/>
<separator orientation="vertical"/>
<field name="company_id" widget="selection" groups="base.group_multi_company"/>

View File

@ -60,7 +60,7 @@
Now I click on Forward button.
-
!python {model: crm.lead.forward.to.partner}: |
import tools
from tools import config
vals = {
'name': 'email',
'email_to': 'info@axelor.com',
@ -68,6 +68,7 @@
'reply_to': 'sales_openerp@openerp.com'
}
ids = self.create(cr, uid, vals, context={'active_id': ref('crm_lead_questionnaireonopenerp0'), 'active_model': 'crm.lead'})
assert tools.config.get('smtp_user', False), 'SMTP not configured !'
host = config.get('smtp_user', '127.0.0.1')
assert config.get(host, True), 'SMTP not configured !'
self.action_forward(cr, uid, [ids], context={'active_id': ref('crm_lead_questionnaireonopenerp0'), 'active_model': 'crm.lead'})