[IMP] crm: removed state field. Refactored code according to the new guidelines.

bzr revid: tde@openerp.com-20130716151003-c2df3nzgo1by0hyi
This commit is contained in:
Thibault Delavallée 2013-07-16 17:10:03 +02:00
parent 7c4f374aca
commit 0e9fd3d5d5
21 changed files with 364 additions and 360 deletions

View File

@ -116,6 +116,7 @@ Dashboard for CRM will include:
'test/crm_lead_onchange.yml',
'test/crm_lead_copy.yml',
'test/crm_lead_unlink.yml',
'test/crm_lead_find_stage.yml',
],
'css': [
'static/src/css/crm.css'

View File

@ -19,7 +19,11 @@
<field name="view_type">form</field>
<field name="view_mode">graph,tree,form</field>
<field name="view_id" ref="view_crm_opportunity_stage_graph"/>
<field name="domain">[('state', 'not in', ('done', 'cancel')), ('type', '=', 'opportunity')]</field>
<!-- avoid done / cancelled -->
<field name="domain">['|',
'!', '&amp;', ('probability', '=', 100), ('stage_id.on_change', '=', 1),
'!', '&amp;', ('probability', '=', 0), ('stage_id.sequence', '!=', 1),
('type', '=', 'opportunity')]</field>
<field name="context">{'search_default_Stage':1}</field>
</record>
@ -43,8 +47,9 @@
<field name="view_type">form</field>
<field name="view_mode">graph,tree,form</field>
<field name="view_id" ref="view_crm_opportunity_user_stage_graph"/>
<field name="domain">[('state','!=','cancel'),('opening_date','&gt;',context_today().strftime("%Y-%m-%d"))]</field>
<field name="context">{'search_default_Stage':1}</field>
<!-- avoid cancelled -->
<field name="domain">['!', '&amp;', ('probability', '=', 0), ('stage_id.sequence', '!=', 1)]</field>
<field name="context">{'search_default_user': 1, 'search_default_Stage': 1}</field>
</record>
<record model="ir.ui.view" id="board_crm_statistical_form">

View File

@ -26,15 +26,6 @@ from openerp import tools
from openerp.osv import fields
from openerp.osv import osv
MAX_LEVEL = 15
AVAILABLE_STATES = [
('draft', 'New'),
('cancel', 'Cancelled'),
('open', 'In Progress'),
('pending', 'Pending'),
('done', 'Closed')
]
AVAILABLE_PRIORITIES = [
('1', 'Highest'),
('2', 'High'),
@ -72,16 +63,13 @@ class crm_case_stage(osv.osv):
'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', string='Sections',
'section_ids': fields.many2many('crm.case.section', 'section_stage_rel', 'stage_id', 'section_id', string='Sections',
help="Link between stages and sales teams. When set, this limitate the current stage to the selected sales teams."),
'state': fields.selection(AVAILABLE_STATES, 'Related Status', required=True,
help="The status of your document will automatically change regarding the selected stage. " \
"For example, if a stage is related to the status 'Close', when your document reaches this stage, it is automatically closed."),
'case_default': fields.boolean('Default to New Sales Team',
help="If you check this field, this stage will be proposed by default on each sales team. It will not assign this stage to existing teams."),
'fold': fields.boolean('Fold by Default',
help="This stage is not visible, for example in status bar or kanban view, when there are no records in that stage to display."),
'type': fields.selection([ ('lead','Lead'),
'type': fields.selection([('lead', 'Lead'),
('opportunity', 'Opportunity'),
('both', 'Both')],
string='Type', size=16, required=True,
@ -91,7 +79,7 @@ class crm_case_stage(osv.osv):
_defaults = {
'sequence': lambda *args: 1,
'probability': lambda *args: 0.0,
'state': 'open',
'on_change': True,
'fold': False,
'type': 'both',
'case_default': True,

View File

@ -5,7 +5,7 @@
<record id="filter_draft_lead" model="ir.filters">
<field name="name">Draft Leads</field>
<field name="model_id">crm.lead</field>
<field name="domain">[('state','=','draft')]</field>
<field name="domain">[('stage_id.sequence', '=', 1)]</field>
<field name="user_id" eval="False"/>
</record>
<record id="action_email_reminder_lead" model="ir.actions.server">

View File

@ -22,14 +22,13 @@
import crm
from datetime import datetime
from operator import itemgetter
from openerp.osv import fields, osv, orm
import time
from openerp import SUPERUSER_ID
from openerp import tools
from openerp.tools.translate import _
from openerp.tools import html2plaintext
from openerp.addons.base.res.res_partner import format_address
from openerp.osv import fields, osv, orm
from openerp.tools import html2plaintext
from openerp.tools.translate import _
CRM_LEAD_FIELDS_TO_MERGE = ['name',
'partner_id',
@ -61,11 +60,7 @@ CRM_LEAD_FIELDS_TO_MERGE = ['name',
'email_from',
'email_cc',
'partner_name']
CRM_LEAD_PENDING_STATES = (
crm.AVAILABLE_STATES[2][0], # Cancelled
crm.AVAILABLE_STATES[3][0], # Done
crm.AVAILABLE_STATES[4][0], # Pending
)
class crm_lead(format_address, osv.osv):
""" CRM Lead Case """
@ -75,13 +70,11 @@ class crm_lead(format_address, osv.osv):
_inherit = ['mail.thread', 'ir.needaction_mixin']
_track = {
'state': {
'crm.mt_lead_create': lambda self, cr, uid, obj, ctx=None: obj.state in ['new', 'draft'],
'crm.mt_lead_won': lambda self, cr, uid, obj, ctx=None: obj.state == 'done',
'crm.mt_lead_lost': lambda self, cr, uid, obj, ctx=None: obj.state == 'cancel',
},
'stage_id': {
'crm.mt_lead_stage': lambda self, cr, uid, obj, ctx=None: obj.state not in ['new', 'draft', 'cancel', 'done'],
'crm.mt_lead_create': lambda self, cr, uid, obj, ctx=None: obj.probability == 0 and obj.stage_id and obj.stage_id.sequence == 1,
'crm.mt_lead_stage': lambda self, cr, uid, obj, ctx=None: (obj.stage_id and obj.stage_id.sequence != 1) and obj.probability < 100,
'crm.mt_lead_won': lambda self, cr, uid, obj, ctx=None: obj.probability == 100 and obj.stage_id and obj.stage_id.on_change,
'crm.mt_lead_lost': lambda self, cr, uid, obj, ctx=None: obj.probability == 0 and obj.stage_id and obj.stage_id.sequence != 1,
},
}
@ -99,7 +92,7 @@ class crm_lead(format_address, osv.osv):
def _get_default_stage_id(self, cr, uid, context=None):
""" Gives default stage_id """
section_id = self._get_default_section_id(cr, uid, context=context)
return self.stage_find(cr, uid, [], section_id, [('state', '=', 'draft')], context=context)
return self.stage_find(cr, uid, [], section_id, [('sequence', '=', '1')], context=context)
def _resolve_section_id_from_context(self, cr, uid, context=None):
""" Returns ID of section based on the value of 'section_id'
@ -150,7 +143,7 @@ class crm_lead(format_address, osv.osv):
stage_ids = stage_obj._search(cr, uid, search_domain, order=order, access_rights_uid=access_rights_uid, context=context)
result = stage_obj.name_get(cr, access_rights_uid, stage_ids, context=context)
# restore order of the search
result.sort(lambda x,y: cmp(stage_ids.index(x[0]), stage_ids.index(y[0])))
result.sort(lambda x, y: cmp(stage_ids.index(x[0]), stage_ids.index(y[0])))
fold = {}
for stage in stage_obj.browse(cr, access_rights_uid, stage_ids, context=context):
@ -158,7 +151,7 @@ class crm_lead(format_address, osv.osv):
return result, fold
def fields_view_get(self, cr, user, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
res = super(crm_lead,self).fields_view_get(cr, user, view_id, view_type, context, toolbar=toolbar, submenu=submenu)
res = super(crm_lead, self).fields_view_get(cr, user, view_id, view_type, context, toolbar=toolbar, submenu=submenu)
if view_type == 'form':
res['arch'] = self.fields_view_get_address(cr, user, res['arch'], context=context)
return res
@ -220,17 +213,6 @@ class crm_lead(format_address, osv.osv):
res[lead.id][field] = abs(int(duration))
return res
def _history_search(self, cr, uid, obj, name, args, context=None):
res = []
msg_obj = self.pool.get('mail.message')
message_ids = msg_obj.search(cr, uid, [('email_from','!=',False), ('subject', args[0][1], args[0][2])], context=context)
lead_ids = self.search(cr, uid, [('message_ids', 'in', message_ids)], context=context)
if lead_ids:
return [('id', 'in', lead_ids)]
else:
return [('id', '=', '0')]
_columns = {
'partner_id': fields.many2one('res.partner', 'Partner', ondelete='set null', track_visibility='onchange',
select=True, help="Linked partner (optional). Usually created when converting the lead."),
@ -243,10 +225,10 @@ class crm_lead(format_address, osv.osv):
'email_from': fields.char('Email', size=128, help="Email address of the contact", select=1),
'section_id': fields.many2one('crm.case.section', 'Sales Team',
select=True, track_visibility='onchange', help='When sending mails, the default email address is taken from the sales team.'),
'create_date': fields.datetime('Creation Date' , readonly=True),
'email_cc': fields.text('Global CC', 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"),
'create_date': fields.datetime('Creation Date', readonly=True),
'email_cc': fields.text('Global CC', 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"),
'description': fields.text('Notes'),
'write_date': fields.datetime('Update Date' , readonly=True),
'write_date': fields.datetime('Update Date', readonly=True),
'categ_ids': fields.many2many('crm.case.categ', 'crm_lead_category_rel', 'lead_id', 'category_id', 'Categories', \
domain="['|',('section_id','=',section_id),('section_id','=',False), ('object_id.model', '=', 'crm.lead')]"),
'type_id': fields.many2one('crm.case.resource.type', 'Campaign', \
@ -269,12 +251,9 @@ class crm_lead(format_address, osv.osv):
multi='day_open', type="float", store=True),
'day_close': fields.function(_compute_day, string='Days to Close', \
multi='day_close', type="float", store=True),
'state': fields.related('stage_id', 'state', type="selection", store=True,
selection=crm.AVAILABLE_STATES, string="Status", readonly=True,
help='The Status is set to \'Draft\', when a case is created. If the case is in progress the Status is set to \'Open\'. When the case is over, the Status is set to \'Done\'. If the case needs to be reviewed then the Status is set to \'Pending\'.'),
# Only used for type opportunity
'probability': fields.float('Success Rate (%)',group_operator="avg"),
'probability': fields.float('Success Rate (%)', group_operator="avg"),
'planned_revenue': fields.float('Expected Revenue', track_visibility='always'),
'ref': fields.reference('Reference', selection=crm._links_get, size=128),
'ref2': fields.reference('Reference 2', selection=crm._links_get, size=128),
@ -325,7 +304,7 @@ class crm_lead(format_address, osv.osv):
def onchange_stage_id(self, cr, uid, ids, stage_id, context=None):
if not stage_id:
return {'value': {}}
stage = self.pool.get('crm.case.stage').browse(cr, uid, stage_id, context)
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}}
@ -358,21 +337,22 @@ class crm_lead(format_address, osv.osv):
section_id = section_ids[0]
return {'value': {'section_id': section_id}}
def _check(self, cr, uid, ids=False, context=None):
""" Override of the base.stage method.
Function called by the scheduler to process cases for date actions
Only works on not done and cancelled cases
"""
cr.execute('select * from crm_case \
where (date_action_last<%s or date_action_last is null) \
and (date_action_next<=%s or date_action_next is null) \
and state not in (\'cancel\',\'done\')',
(time.strftime("%Y-%m-%d %H:%M:%S"),
time.strftime('%Y-%m-%d %H:%M:%S')))
# TDE NOTE: replaced byu base action rule fully working ?
# def _check(self, cr, uid, ids=False, context=None):
# """ Override of the base.stage method.
# Function called by the scheduler to process cases for date actions
# Only works on not done and cancelled cases
# """
# cr.execute('select * from crm_case \
# where (date_action_last<%s or date_action_last is null) \
# and (date_action_next<=%s or date_action_next is null) \
# and state not in (\'cancel\',\'done\')',
# (time.strftime("%Y-%m-%d %H:%M:%S"),
# time.strftime('%Y-%m-%d %H:%M:%S')))
ids2 = map(lambda x: x[0], cr.fetchall() or [])
cases = self.browse(cr, uid, ids2, context=context)
return self._action(cr, uid, cases, False, context=context)
# ids2 = map(lambda x: x[0], cr.fetchall() or [])
# cases = self.browse(cr, uid, ids2, context=context)
# return self._action(cr, uid, cases, False, context=context)
def stage_find(self, cr, uid, cases, section_id, domain=None, order='sequence', context=None):
""" Override of the base.stage method
@ -385,16 +365,16 @@ class crm_lead(format_address, osv.osv):
if isinstance(cases, (int, long)):
cases = self.browse(cr, uid, cases, context=context)
# collect all section_ids
section_ids = []
section_ids = set()
types = ['both']
if not cases:
type = context.get('default_type')
types += [type]
ctx_type = context.get('default_type')
types += [ctx_type]
if section_id:
section_ids.append(section_id)
section_ids.add(section_id)
for lead in cases:
if lead.section_id:
section_ids.append(lead.section_id.id)
section_ids.add(lead.section_id.id)
if lead.type not in types:
types.append(lead.type)
# OR all section_ids and OR with case_default
@ -403,8 +383,7 @@ class crm_lead(format_address, osv.osv):
search_domain += [('|')] * len(section_ids)
for section_id in section_ids:
search_domain.append(('section_ids', '=', section_id))
else:
search_domain.append(('case_default', '=', True))
search_domain.append(('case_default', '=', True))
# AND with cases types
search_domain.append(('type', 'in', types))
# AND with the domain in parameter
@ -415,27 +394,29 @@ class crm_lead(format_address, osv.osv):
return stage_ids[0]
return False
def stage_set(self, cr, uid, ids, stage_id, context=None):
""" Set the new stage. Now just writes the stage.
TDE TODO: remove me when removing state
"""
return self.write(cr, uid, ids, {'stage_id': stage_id}, context=context)
def case_mark_lost(self, cr, uid, ids, context=None):
""" Mark the case as lost: state=cancel and probability=0 """
for lead in self.browse(cr, uid, ids):
stage_id = self.stage_find(cr, uid, [lead], lead.section_id.id or False, [('probability', '=', 0.0),('on_change','=',True)], context=context)
stage_id = self.stage_find(cr, uid, [lead], lead.section_id.id or False, [('probability', '=', 0.0), ('on_change', '=', True), ('sequence', '>', 1)], context=context)
if stage_id:
self.stage_set(cr, uid, [lead.id], stage_id, context=context)
return True
return self.write(cr, uid, [lead.id], {'stage_id': stage_id}, context=context)
else:
raise osv.except_osv(_('Warning!'),
_('To relieve your sales pipe and group all Lost opportunities, configure one of your sales stage as follow:\n'
'probability = 0 %, select "Change Probability Automatically".\n'
'Create a specific stage or edit an existing one by editing columns of your opportunity pipe.'))
def case_mark_won(self, cr, uid, ids, context=None):
""" Mark the case as won: state=done and probability=100 """
for lead in self.browse(cr, uid, ids):
stage_id = self.stage_find(cr, uid, [lead], lead.section_id.id or False, [('probability', '=', 100.0),('on_change','=',True)], context=context)
stage_id = self.stage_find(cr, uid, [lead], lead.section_id.id or False, [('probability', '=', 100.0), ('on_change', '=', True), ('sequence', '>', 1)], context=context)
if stage_id:
self.stage_set(cr, uid, [lead.id], stage_id, context=context)
return True
return self.write(cr, uid, [lead.id], {'stage_id': stage_id}, context=context)
else:
raise osv.except_osv(_('Warning!'),
_('To relieve your sales pipe and group all Won opportunities, configure one of your sales stage as follow:\n'
'probability = 100 % and select "Change Probability Automatically".\n'
'Create a specific stage or edit an existing one by editing columns of your opportunity pipe.'))
def case_escalate(self, cr, uid, ids, context=None):
""" Escalates case to parent level """
@ -451,20 +432,20 @@ class crm_lead(format_address, osv.osv):
self.write(cr, uid, [case.id], data, context=context)
return True
def set_priority(self, cr, uid, ids, priority):
def set_priority(self, cr, uid, ids, priority, context=None):
""" Set lead priority
"""
return self.write(cr, uid, ids, {'priority' : priority})
return self.write(cr, uid, ids, {'priority': priority}, context=context)
def set_high_priority(self, cr, uid, ids, context=None):
""" Set lead priority to high
"""
return self.set_priority(cr, uid, ids, '1')
return self.set_priority(cr, uid, ids, '1', context=context)
def set_normal_priority(self, cr, uid, ids, context=None):
""" Set lead priority to normal
"""
return self.set_priority(cr, uid, ids, '3')
return self.set_priority(cr, uid, ids, '3', context=context)
def _merge_get_result_type(self, cr, uid, opps, context=None):
"""
@ -640,7 +621,8 @@ class crm_lead(format_address, osv.osv):
sequenced_opps = []
for opportunity in opportunities:
sequence = -1
if opportunity.stage_id and opportunity.stage_id.state != 'cancel':
# TDE: was "if opportunity.stage_id and opportunity.stage_id.state != 'cancel':"
if opportunity.probability == 0 and opportunity.stage_id and opportunity.stage_id.sequence != 1 and opportunity.stage_id.fold:
sequence = opportunity.stage_id.sequence
sequenced_opps.append(((int(sequence != -1 and opportunity.type == 'opportunity'), sequence, -opportunity.id), opportunity))

View File

@ -5,71 +5,57 @@
<!-- Crm stages -->
<record model="crm.case.stage" id="stage_lead1">
<field name="name">New</field>
<field eval="1" name="case_default"/>
<field name="state">draft</field>
<field eval="0" name="probability"/>
<field eval="10" name="sequence"/>
<field name="case_default">1</field>
<field name="probability">0</field>
<field name="on_change">1</field>
<field name="sequence">1</field>
<field name="type">both</field>
</record>
<record model="crm.case.stage" id="stage_lead2">
<field name="name">Opportunity</field>
<field eval="1" name="case_default"/>
<field name="state">open</field>
<field eval="20" name="probability"/>
<field eval="20" name="sequence"/>
<field name="type">lead</field>
</record>
<record model="crm.case.stage" id="stage_lead7">
<field name="name">Dead</field>
<field eval="1" name="case_default"/>
<field eval="False" name="fold"/>
<field name="state">cancel</field>
<field eval="0" name="probability"/>
<field eval="30" name="sequence"/>
<field name="case_default">1</field>
<field name="probability">0</field>
<field name="on_change">1</field>
<field name="sequence">30</field>
<field name="type">lead</field>
</record>
<record model="crm.case.stage" id="stage_lead3">
<field name="name">Qualification</field>
<field eval="1" name="case_default"/>
<field name="state">open</field>
<field eval="20" name="probability"/>
<field eval="100" name="sequence"/>
<field name="case_default">1</field>
<field name="probability">20</field>
<field name="on_change">1</field>
<field name="sequence">40</field>
<field name="type">opportunity</field>
</record>
<record model="crm.case.stage" id="stage_lead4">
<field name="name">Proposition</field>
<field eval="1" name="case_default"/>
<field name="state">open</field>
<field eval="40" name="probability"/>
<field eval="110" name="sequence"/>
<field name="case_default">1</field>
<field name="probability">40</field>
<field name="sequence">50</field>
<field name="type">opportunity</field>
</record>
<record model="crm.case.stage" id="stage_lead5">
<field name="name">Negotiation</field>
<field eval="1" name="case_default"/>
<field name="state">open</field>
<field eval="60" name="probability"/>
<field eval="120" name="sequence"/>
<field name="case_default">1</field>
<field name="probability">60</field>
<field name="sequence">60</field>
<field name="type">opportunity</field>
</record>
<record model="crm.case.stage" id="stage_lead6">
<field name="name">Won</field>
<field eval="True" name="fold"/>
<field eval="1" name="case_default"/>
<field name="state">done</field>
<field eval="100" name="probability"/>
<field eval="130" name="sequence"/>
<field eval="1" name="on_change"/>
<field name="case_default">1</field>
<field name="probability">100</field>
<field name="on_change">1</field>
<field name="sequence">70</field>
<field name="type">opportunity</field>
</record>
<record model="crm.case.stage" id="stage_lead8">
<record model="crm.case.stage" id="stage_lead7">
<field name="name">Lost</field>
<field eval="1" name="case_default"/>
<field eval="True" name="fold"/>
<field eval="1" name="on_change"/>
<field name="state">cancel</field>
<field eval="0" name="probability"/>
<field eval="140" name="sequence"/>
<field name="case_default">1</field>
<field name="fold">1</field>
<field name="probability">0</field>
<field name="on_change">1</field>
<field name="sequence">80</field>
<field name="type">opportunity</field>
</record>
@ -77,7 +63,7 @@
<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')),
(4, ref('stage_lead7')), (4, ref('stage_lead8'))]"/>
(4, ref('stage_lead7'))]"/>
</record>
<!-- Crm campain -->
@ -161,7 +147,7 @@
<field name="name">Lead Created</field>
<field name="res_model">crm.lead</field>
<field name="default" eval="False"/>
<field name="description">Opportunity created</field>
<field name="description">Lead created</field>
</record>
<record id="mt_lead_stage" model="mail.message.subtype">
<field name="name">Stage Changed</field>

View File

@ -1,14 +1,15 @@
<?xml version="1.0"?>
<openerp>
<data noupdate="1">
<!-- <data noupdate="1"> -->
<data>
<!-- Demo Leads -->
<record id="crm_case_1" model="crm.lead">
<field name="type">lead</field>
<field name="name">Plan to Attend a Training</field>
<field name="contact_name">Jason Dunagan</field>
<field name="contact_name">Jacques Dunagan</field>
<field name="partner_name">Le Club SARL</field>
<field name="email_from">jason@leclub.fr</field>
<field name="email_from">jdunagan@leclub.fr</field>
<field name="partner_id" ref=""/>
<field name="function">Training Manager</field>
<field name="street">73, rue Léon Dierx</field>
@ -20,14 +21,25 @@
<field name="categ_ids" eval="[(6, 0, [categ_oppor6])]"/>
<field name="channel_id" ref="crm_case_channel_email"/>
<field name="priority">1</field>
<field name="section_id" ref="crm_case_section_2"/>
<field name="section_id" ref="section_sales_department"/>
<field name="user_id" ref="base.user_root"/>
<field name="stage_id" ref="stage_lead1"/>
<field name="description">Hello,
I am Jason from Le Club SARL.
I am intertested to attend a training organized in your company.
Can you send me the details ?</field>
<field eval="1" name="active"/>
I am Jacques from Le Club SARL.
I am interested to attend a training organized in your company.
Could you please send me the details ?</field>
</record>
<record id="crm_case_1" model="crm.lead">
<field name="create_date" eval="(DateTime.today() - relativedelta(months=2)).strftime('%Y-%m-%d %H:%M')"/>
</record>
<record id="msg_case1_1" model="mail.message">
<field name="subject">Inquiry</field>
<field name="model">crm.lead</field>
<field name="res_id" ref="crm_case_1"/>
<field name="body"><![CDATA[<p>Hello,<br />
I am Jacques from Le Club SARL. I am interested to attend a training organized in your company.<br />
Can you send me the details ?</p>]]></field>
<field name="type">email</field>
</record>
<record id="crm_case_2" model="crm.lead">
@ -44,10 +56,20 @@ Can you send me the details ?</field>
<field name="categ_ids" eval="[(6, 0, [categ_oppor2])]"/>
<field name="channel_id" ref="crm_case_channel_website"/>
<field name="priority">4</field>
<field name="section_id" ref="crm_case_section_2"/>
<field name="section_id" ref="section_sales_department"/>
<field name="user_id" ref="base.user_root"/>
<field name="stage_id" ref="stage_lead1"/>
<field eval="1" name="active"/>
</record>
<record id="crm_case_2" model="crm.lead">
<field name="create_date" eval="(DateTime.today() - relativedelta(months=1)).strftime('%Y-%m-%d %H:%M')"/>
</record>
<record id="msg_case2_1" model="mail.message">
<field name="subject">Need Details</field>
<field name="model">crm.lead</field>
<field name="author_id" ref="base.partner_demo"/>
<field name="res_id" ref="crm_case_2"/>
<field name="body">Want to know features and benefits to use the new software.</field>
<field name="type">comment</field>
</record>
<record id="crm_case_3" model="crm.lead">
@ -65,8 +87,10 @@ Can you send me the details ?</field>
<field name="priority">2</field>
<field name="section_id" ref="crm_case_section_1"/>
<field name="user_id" ref="base.user_demo"/>
<field name="stage_id" ref="stage_lead2"/>
<field eval="1" name="active"/>
<field name="stage_id" ref="stage_lead1"/>
</record>
<record id="crm_case_2" model="crm.lead">
<field name="create_date" eval="(DateTime.today() - relativedelta(months=1)).strftime('%Y-%m-%d %H:%M')"/>
</record>
<record id="crm_case_4" model="crm.lead">
@ -82,10 +106,12 @@ Can you send me the details ?</field>
<field name="categ_ids" eval="[(6, 0, [categ_oppor5])]"/>
<field name="channel_id" ref=""/>
<field name="priority">3</field>
<field name="section_id" ref="crm_case_section_1"/>
<field name="user_id" ref=""/>
<field name="stage_id" ref="stage_lead7"/>
<field eval="1" name="active"/>
<field name="section_id" ref="crm_case_section_2"/>
<field name="user_id" ref="base.user_demo"/>
<field name="stage_id" ref="stage_lead6"/>
</record>
<record id="crm_case_2" model="crm.lead">
<field name="create_date" eval="(DateTime.today() - relativedelta(months=1)).strftime('%Y-%m-%d %H:%M')"/>
</record>
<record id="crm_case_5" model="crm.lead">
@ -105,8 +131,8 @@ Can you send me the details ?</field>
<field name="categ_ids" eval="[(6, 0, [categ_oppor1])]"/>
<field name="channel_id" ref="crm_case_channel_website"/>
<field name="priority">3</field>
<field name="section_id" ref="section_sales_department"/>
<field name="user_id" ref="base.user_root"/>
<field name="section_id" ref="crm_case_section_1"/>
<field name="user_id" ref=""/>
<field name="stage_id" ref="stage_lead1"/>
<field name="description">Hi,
Can you send me a quotation for 20 computers with speakers?
@ -116,7 +142,6 @@ Purchase Manager
Stonage IT,
Franklinville
Contact: +1 813 494 5005</field>
<field eval="1" name="active"/>
</record>
<record id="crm_case_6" model="crm.lead">
@ -134,9 +159,8 @@ Contact: +1 813 494 5005</field>
<field name="channel_id" ref=""/>
<field name="priority">3</field>
<field name="section_id" ref="crm_case_section_2"/>
<field name="user_id" ref="base.user_root"/>
<field name="user_id" ref=""/>
<field name="stage_id" ref="stage_lead1"/>
<field eval="1" name="active"/>
</record>
<record id="crm_case_7" model="crm.lead">
@ -153,9 +177,8 @@ Contact: +1 813 494 5005</field>
<field name="channel_id" ref=""/>
<field name="priority">5</field>
<field name="section_id" ref="crm_case_section_2"/>
<field name="user_id" ref="base.user_demo"/>
<field name="stage_id" ref="stage_lead7"/>
<field eval="1" name="active"/>
<field name="user_id" ref="base.user_root"/>
<field name="stage_id" ref="stage_lead1"/>
</record>
<record id="crm_case_8" model="crm.lead">
@ -173,9 +196,8 @@ Contact: +1 813 494 5005</field>
<field name="channel_id" ref=""/>
<field name="priority">4</field>
<field name="section_id" ref="section_sales_department"/>
<field name="user_id" ref="base.user_demo"/>
<field name="stage_id" ref="stage_lead7"/>
<field eval="1" name="active"/>
<field name="user_id" ref="base.user_root"/>
<field name="stage_id" ref="stage_lead1"/>
</record>
<record id="crm_case_9" model="crm.lead">
@ -193,12 +215,8 @@ Contact: +1 813 494 5005</field>
<field name="channel_id" ref="crm_case_channel_phone"/>
<field name="priority">2</field>
<field name="section_id" ref="section_sales_department"/>
<field name="user_id" ref="base.user_root"/>
<field name="user_id" ref="base.user_demo"/>
<field name="stage_id" ref="stage_lead1"/>
<field eval="1" name="active"/>
</record>
<record id="crm_case_9" model="crm.lead">
<field name="create_date" eval="(DateTime.today() - relativedelta(months=1)).strftime('%Y-%m-%d %H:%M')"/>
</record>
<record id="crm_case_10" model="crm.lead">
@ -215,14 +233,13 @@ Contact: +1 813 494 5005</field>
<field name="channel_id" ref="crm_case_channel_email"/>
<field name="priority">2</field>
<field name="section_id" ref="crm_case_section_2"/>
<field name="user_id" ref=""/>
<field name="user_id" ref="base.user_demo"/>
<field name="stage_id" ref="stage_lead1"/>
<field name="description">Hi,
I would like to know more about specification and cost of laptops of your company.
Thanks,
Andrew</field>
<field eval="1" name="active"/>
</record>
<record id="crm_case_11" model="crm.lead">
@ -239,9 +256,8 @@ Andrew</field>
<field name="channel_id" ref="crm_case_channel_direct"/>
<field name="priority">3</field>
<field name="section_id" ref="crm_case_section_1"/>
<field name="user_id" ref="base.user_demo"/>
<field name="user_id" ref=""/>
<field name="stage_id" ref="stage_lead1"/>
<field eval="1" name="active"/>
</record>
<record id="crm_case_12" model="crm.lead">
@ -258,15 +274,23 @@ Andrew</field>
<field name="channel_id" ref="crm_case_channel_website"/>
<field name="priority">2</field>
<field name="section_id" ref="section_sales_department"/>
<field name="user_id" ref="base.user_demo"/>
<field name="stage_id" ref="stage_lead2"/>
<field eval="1" name="active"/>
<field name="user_id" ref=""/>
<field name="stage_id" ref="stage_lead1"/>
</record>
<!-- Call Function to Cancel the leads (set as Dead) -->
<function model="crm.lead" name="write"
eval="[ ref('crm_case_7'), ref('crm_case_8'),
ref('crm_case_9'), ref('crm_case_10'),
ref('crm_case_11'), ref('crm_case_12')],
{'stage_id': ref('stage_lead2')},
{'install_mode': True}"
/>
<!-- Call Function to set the leads as Unread -->
<function model="crm.lead" name="message_mark_as_unread"
eval="[ ref('crm_case_1'), ref('crm_case_2'),
ref('crm_case_5'), ref('crm_case_11')], {}"
ref('crm_case_5'), ref('crm_case_6')], {}"
/>
<!-- Demo Opportunities -->
@ -289,8 +313,7 @@ Andrew</field>
<field name="title_action">Meeting for pricing information.</field>
<field name="section_id" ref="section_sales_department"/>
<field name="user_id" ref="base.user_root"/>
<field name="stage_id" ref="crm.stage_lead3"/>
<field eval="1" name="active"/>
<field name="stage_id" ref="crm.stage_lead1"/>
</record>
<record id="crm_case_14" model="crm.lead">
@ -316,7 +339,6 @@ Andrew</field>
<field name="section_id" ref="section_sales_department"/>
<field name="user_id" ref="base.user_demo"/>
<field name="stage_id" ref="crm.stage_lead3"/>
<field eval="1" name="active"/>
</record>
<record id="crm_case_15" model="crm.lead">
@ -337,9 +359,8 @@ Andrew</field>
<field name="title_action">Call to ask system requirement</field>
<field name="section_id" ref="section_sales_department"/>
<field name="user_id" ref="base.user_demo"/>
<field name="stage_id" ref="crm.stage_lead6"/>
<field eval="1" name="active"/>
<field name="date_closed" eval="(DateTime.today() - relativedelta(months=2)).strftime('%Y-%m-%d %H:%M')"/>
<field name="stage_id" ref="crm.stage_lead3"/>
<!-- <field name="date_closed" eval="(DateTime.today() - relativedelta(months=2)).strftime('%Y-%m-%d %H:%M')"/> -->
</record>
<record id="crm_case_16" model="crm.lead">
@ -362,9 +383,8 @@ Andrew</field>
<field name="title_action">Convert to quote</field>
<field name="section_id" ref="crm_case_section_1"/>
<field name="user_id" ref="base.user_demo"/>
<field name="stage_id" ref="crm.stage_lead6"/>
<field eval="1" name="active"/>
<field name="date_closed" eval="(DateTime.today() - relativedelta(hours=1)).strftime('%Y-%m-%d %H:%M')"/>
<field name="stage_id" ref="crm.stage_lead3"/>
<!-- <field name="date_closed" eval="(DateTime.today() - relativedelta(hours=1)).strftime('%Y-%m-%d %H:%M')"/> -->
</record>
<record id="crm_case_17" model="crm.lead">
@ -388,9 +408,8 @@ Andrew</field>
<field name="title_action">Send price list regarding our interventions</field>
<field name="section_id" ref="crm_case_section_1"/>
<field name="user_id" ref="base.user_demo"/>
<field name="stage_id" ref="crm.stage_lead6"/>
<field eval="1" name="active"/>
<field name="date_closed" eval="(DateTime.today() - relativedelta(hours=1)).strftime('%Y-%m-%d %H:%M')"/>
<field name="stage_id" ref="crm.stage_lead4"/>
<!-- <field name="date_closed" eval="(DateTime.today() - relativedelta(hours=1)).strftime('%Y-%m-%d %H:%M')"/> -->
</record>
<record id="crm_case_18" model="crm.lead">
@ -413,7 +432,7 @@ Andrew</field>
<field name="title_action">Call to define real needs about training</field>
<field name="section_id" ref="crm_case_section_1"/>
<field name="user_id" ref="base.user_demo"/>
<field name="stage_id" ref="crm.stage_lead3"/>
<field name="stage_id" ref="crm.stage_lead4"/>
<field eval="1" name="active"/>
</record>
@ -437,9 +456,8 @@ Andrew</field>
<field name="title_action">Ask for the good receprion of the proposition</field>
<field name="section_id" ref="crm_case_section_1"/>
<field name="user_id" ref="base.user_root"/>
<field name="stage_id" ref="crm.stage_lead6"/>
<field eval="1" name="active"/>
<field name="date_closed" eval="(DateTime.today() - relativedelta(months=3)).strftime('%Y-%m-%d %H:%M')"/>
<field name="stage_id" ref="crm.stage_lead4"/>
<!-- <field name="date_closed" eval="(DateTime.today() - relativedelta(months=3)).strftime('%Y-%m-%d %H:%M')"/> -->
</record>
<record id="crm_case_20" model="crm.lead">
@ -455,8 +473,7 @@ Andrew</field>
<field name="priority">2</field>
<field name="section_id" ref="crm_case_section_1"/>
<field name="user_id" ref="base.user_demo"/>
<field name="stage_id" ref="crm.stage_lead1"/>
<field eval="1" name="active"/>
<field name="stage_id" ref="crm.stage_lead4"/>
</record>
<record id="crm_case_21" model="crm.lead">
@ -470,9 +487,8 @@ Andrew</field>
<field name="priority">3</field>
<field name="section_id" ref="crm_case_section_2"/>
<field name="user_id" ref="base.user_root"/>
<field name="stage_id" ref="crm.stage_lead6"/>
<field eval="1" name="active"/>
<field name="date_closed" eval="(DateTime.today() - relativedelta(months=1)).strftime('%Y-%m-%d %H:%M')"/>
<field name="stage_id" ref="crm.stage_lead4"/>
<!-- <field name="date_closed" eval="(DateTime.today() - relativedelta(months=1)).strftime('%Y-%m-%d %H:%M')"/> -->
</record>
<record id="crm_case_22" model="crm.lead">
@ -489,8 +505,7 @@ Andrew</field>
<field name="priority">3</field>
<field name="section_id" ref="crm_case_section_2"/>
<field name="user_id" ref="base.user_root"/>
<field name="stage_id" ref="crm.stage_lead8"/>
<field eval="1" name="active"/>
<field name="stage_id" ref="crm.stage_lead5"/>
</record>
<record id="crm_case_23" model="crm.lead">
@ -505,9 +520,8 @@ Andrew</field>
<field name="priority">5</field>
<field name="section_id" ref="section_sales_department"/>
<field name="user_id" ref="base.user_demo"/>
<field name="stage_id" ref="crm.stage_lead6"/>
<field eval="1" name="active"/>
<field name="date_closed" eval="(DateTime.today() - relativedelta(hours=1)).strftime('%Y-%m-%d %H:%M')"/>
<field name="stage_id" ref="crm.stage_lead5"/>
<!-- <field name="date_closed" eval="(DateTime.today() - relativedelta(hours=1)).strftime('%Y-%m-%d %H:%M')"/> -->
</record>
<record id="crm_case_24" model="crm.lead">
@ -525,9 +539,8 @@ Andrew</field>
<field eval="time.strftime('%Y-%m-6')" name="date_deadline"/>
<field name="section_id" ref="section_sales_department"/>
<field name="user_id" ref="base.user_root"/>
<field name="stage_id" ref="crm.stage_lead6"/>
<field eval="1" name="active"/>
<field name="date_closed" eval="(DateTime.today() - relativedelta(month=1)).strftime('%Y-%m-%d %H:%M')"/>
<field name="stage_id" ref="crm.stage_lead5"/>
<!-- <field name="date_closed" eval="(DateTime.today() - relativedelta(month=1)).strftime('%Y-%m-%d %H:%M')"/> -->
</record>
<record id="crm_case_25" model="crm.lead">
@ -549,8 +562,7 @@ Andrew</field>
<field name="title_action">Conf call with technical service</field>
<field name="section_id" ref="crm_case_section_1"/>
<field name="user_id" ref="base.user_root"/>
<field name="stage_id" ref="crm.stage_lead4"/>
<field eval="1" name="active"/>
<field name="stage_id" ref="crm.stage_lead5"/>
</record>
<record id="crm_case_26" model="crm.lead">
@ -574,9 +586,8 @@ Andrew</field>
<field name="title_action">Send Catalogue by Email</field>
<field name="section_id" ref="crm_case_section_2"/>
<field name="user_id" ref="base.user_demo"/>
<field name="stage_id" ref="crm.stage_lead6"/>
<field eval="1" name="active"/>
<field name="date_closed" eval="(DateTime.today() - relativedelta(hours=1)).strftime('%Y-%m-%d %H:%M')"/>
<field name="stage_id" ref="crm.stage_lead5"/>
<!-- <field name="date_closed" eval="(DateTime.today() - relativedelta(hours=1)).strftime('%Y-%m-%d %H:%M')"/> -->
</record>
<!-- Unsubscribe Admin from case15, subscribe Demo -->
@ -682,26 +693,9 @@ Andrew</field>
<field name="parent_id" ref="msg_case18_1"/>
<field name="author_id" ref="base.partner_demo"/>
</record>
<record id="msg_case1_1" model="mail.message">
<field name="subject">Inquiry</field>
<field name="model">crm.lead</field>
<field name="res_id" ref="crm_case_1"/>
<field name="body"><![CDATA[<p>Hello,<br />
I am Jason from Le Club SARL. I am interested to attend a training organized in your company.<br />
Can you send me the details ?</p>]]></field>
<field name="type">email</field>
</record>
<record id="msg_case2_1" model="mail.message">
<field name="subject">Need Details</field>
<field name="model">crm.lead</field>
<field name="res_id" ref="crm_case_2"/>
<field name="body">Want to know features and benefits to use the new software.</field>
<field name="type">comment</field>
</record>
<function model="mail.message" name="set_message_starred"
eval="[ ref('msg_case18_1'), ref('msg_case18_2')], True, {}"
/>
</data>
</openerp>

View File

@ -12,9 +12,10 @@
<field name="model">crm.case.stage</field>
<field name="arch" type="xml">
<search string="Stage Search">
<field name="name" string="Stage Name"/>
<field name="state"/>
<field name="name"/>
<field name="type"/>
<field name="sequence"/>
<field name="probability"/>
</search>
</field>
</record>
@ -94,7 +95,8 @@
<form string="Leads Form" version="7.0">
<header>
<button name="%(crm.action_crm_lead2opportunity_partner)d" string="Convert to Opportunity" type="action"
states="draft,open,pending" help="Convert to Opportunity" class="oe_highlight"/>
attrs="{'invisible': [('probability', '=', 100)]}"
help="Convert to Opportunity" class="oe_highlight"/>
<field name="stage_id" widget="statusbar" clickable="True"
domain="['&amp;', '|', ('case_default', '=', True), ('section_ids', '=', section_id), '|', ('type', '=', type), ('type', '=', 'both')]"
on_change="onchange_stage_id(stage_id)"/>
@ -140,12 +142,6 @@
<field name="phone"/>
<field name="mobile"/>
<field name="fax"/>
<!--
This should be integrated in Open Chatter
<button string="Mail"
name="%(mail.action_email_compose_message_wizard)d"
icon="terp-mail-message-new" type="action" colspan="1"/>
-->
</group>
<group>
<field name="user_id" on_change="on_change_user(user_id, context)"
@ -155,7 +151,7 @@
<field name="section_id"/>
<button name="case_escalate" string="Escalate"
type="object" class="oe_link"
attrs="{'invisible': ['|', ('section_id','=',False), ('state', 'not in', ['draft','open','pending'])]}"/>
attrs="{'invisible': ['|', ('section_id','=',False), ('probability', '=', 100)]}"/>
</div>
<field name="type" invisible="1"/>
</group>
@ -173,20 +169,24 @@
<field name="description"/>
</page>
<page string="Extra Info">
<group>
<group string="Categorization" groups="base.group_multi_company,base.group_no_one" name="categorization">
<field name="company_id"
groups="base.group_multi_company"
widget="selection" colspan="2"/>
<field name="state" groups="base.group_no_one"/>
</group>
<group string="Mailings">
<field name="opt_out"/>
</group>
<group string="Misc">
<group string="Categorization" groups="base.group_multi_company,base.group_no_one" name="categorization">
<field name="company_id"
groups="base.group_multi_company"
widget="selection" colspan="2"/>
</group>
<group string="Mailings">
<field name="opt_out"/>
</group>
<group string="Misc">
<group>
<field name="probability" groups="base.group_no_one"/>
<field name="active"/>
<field name="referred"/>
</group>
<group>
<field name="date_open" groups="base.group_no_one"/>
<field name="date_closed" groups="base.group_no_one"/>
</group>
</group>
</page>
</notebook>
@ -216,7 +216,7 @@
<field name="name">Leads</field>
<field name="model">crm.lead</field>
<field name="arch" type="xml">
<tree string="Leads" fonts="bold:message_unread==True" colors="grey:state in ('cancel', 'done')">
<tree string="Leads" fonts="bold:message_unread==True" colors="grey:probability == 100">
<field name="date_deadline" invisible="1"/>
<field name="create_date"/>
<field name="name"/>
@ -228,7 +228,7 @@
<field name="user_id" invisible="1"/>
<field name="partner_id" invisible="1"/>
<field name="section_id" invisible="context.get('invisible_section', True)" groups="base.group_multi_salesteams"/>
<field name="state" invisible="1"/>
<field name="probability" invisible="1"/>
<field name="type_id" invisible="1"/>
<field name="referred" invisible="1"/>
<field name="channel_id" invisible="1"/>
@ -331,16 +331,17 @@
<field name="create_date"/>
<field name="country_id" context="{'invisible_country': False}"/>
<separator/>
<filter string="Open" name="open" domain="[('state','!=','cancel')]" help="Open Leads"/>
<filter string="Dead" name="dead" domain="[('state','=','cancel')]"/>
<filter string="Unassigned" name="unassigned" domain="[('user_id','=', False)]" help="No salesperson"/>
<filter string="Unread Messages" name="message_unread" domain="[('message_unread','=',True)]" help="Unread messages"/>
<filter string="Unassigned" name="unassigned"
domain="[('user_id','=', False)]"
help="No salesperson"/>
<filter string="Assigned to Me"
domain="[('user_id','=',uid)]" context="{'invisible_section': False}"
help="Leads that are assigned to me"/>
<filter string="Assigned to My Team(s)"
<filter string="Assigned to My Team(s)" groups="base.group_multi_salesteams"
domain="[('section_id.member_ids', 'in', [uid])]" context="{'invisible_section': False}"
help="Leads that are assigned to any sales teams I am member of" groups="base.group_multi_salesteams"/>
help="Leads that are assigned to any sales teams I am member of"/>
<filter string="Dead" name="dead"
domain="[('probability', '=', '0'), ('stage_id.sequence', '!=', 1)]"/>
<separator />
<filter string="Available for mass mailing"
name='not_opt_out' domain="[('opt_out', '=', False)]"
@ -378,20 +379,18 @@
<field name="arch" type="xml">
<form string="Opportunities" version="7.0">
<header>
<button name="case_mark_won" string="Mark Won" type="object"
states="draft,open,pending" class="oe_highlight"/>
<button name="case_mark_lost" string="Mark Lost" type="object"
states="draft,open" class="oe_highlight"/>
<field name="stage_id" widget="statusbar" clickable="True"/>
<button name="case_mark_won" string="Mark Won" type="object" class="oe_highlight"
attrs="{'invisible': [('probability', '=', 100)]}"/>
<button name="case_mark_lost" string="Mark Lost" type="object" class="oe_highlight"/>
<field name="stage_id" widget="statusbar" clickable="True"
domain="['&amp;', ('section_ids', '=', section_id), '|', ('type', '=', type), ('type', '=', 'both')]"/>
</header>
<sheet>
<div class="oe_right oe_button_box">
<button string="Schedule/Log Call"
name="%(opportunity2phonecall_act)d"
type="action"/>
<button string="Meeting"
<button string="Schedule/Log Call" type="action"
name="%(opportunity2phonecall_act)d"/>
<button string="Meeting" type="object"
name="action_makeMeeting"
type="object"
context="{'search_default_attendee_id': active_id, 'default_attendee_id' : active_id}"/>
</div>
<div class="oe_title">
@ -430,7 +429,8 @@
<label for="section_id" groups="base.group_multi_salesteams"/>
<div groups="base.group_multi_salesteams">
<field name="section_id" widget="selection"/>
<button name="case_escalate" string="Escalate" type="object" class="oe_link" attrs="{'invisible': ['|', ('section_id','=',False), ('state', 'not in', ['draft','open','pending'])]}"/>
<button name="case_escalate" string="Escalate" type="object" class="oe_link"
attrs="{'invisible': ['|', ('section_id','=',False), ('probability', '=', 100)]}"/>
</div>
</group>
<group>
@ -511,7 +511,7 @@
<field name="name">Opportunities Tree</field>
<field name="model">crm.lead</field>
<field name="arch" type="xml">
<tree string="Opportunities" fonts="bold:message_unread==True" colors="gray:state in ('cancel', 'done');red:date_deadline and (date_deadline &lt; current_date)">
<tree string="Opportunities" fonts="bold:message_unread==True" colors="gray:probability == 100;red:date_deadline and (date_deadline &lt; current_date)">
<field name="date_deadline" invisible="1"/>
<field name="create_date"/>
<field name="name" string="Opportunity"/>
@ -529,7 +529,8 @@
<field name="referred" invisible="1"/>
<field name="priority" invisible="1"/>
<field name="message_unread" invisible="1"/>
<field name="state" invisible="1"/>
<field name="probability" invisible="1"/>
<field name="write_date" invisible="1"/>
</tree>
</field>
</record>
@ -546,15 +547,19 @@
<field name="section_id" context="{'invisible_section': False}" groups="base.group_multi_salesteams"/>
<field name="user_id"/>
<field name="partner_id" filter_domain="[('partner_id','child_of',self)]"/>
<field name="stage_id"/>
<field name="probability"/>
<separator/>
<filter string="New" name="new" domain="[('state','=','draft')]" help="New Opportunities"/>
<filter string="In Progress" name="open" domain="[('state','=','open')]" help="Open Opportunities"/>
<filter string="Won" name="won" domain="[('state','=','done')]"/>
<filter string="Lost" name="lost" domain="[('state','=','cancel')]"/>
<filter string="Unassigned" name="unassigned" domain="[('user_id','=', False)]" help="No salesperson"/>
<filter string="Unread Messages" name="message_unread" domain="[('message_unread','=',True)]" help="Unread messages"/>
<filter string="New" name="new"
domain="[('probability', '=', 0), ('stage_id.sequence', '=', 1)]"/>
<filter string="Won" name="won"
domain="[('probability', '=', 100), ('stage_id.on_change', '=', 1)]"/>
<filter string="Lost" name="lost"
domain="[('probability', '=', 0), ('stage_id.sequence', '!=', 1)]"/>
<filter string="Unassigned" name="unassigned"
domain="[('user_id','=', False)]" help="No salesperson"/>
<filter string="My Opportunities" name="assigned_to_me"
domain="[('user_id','=',uid)]" context="{'invisible_section': False}"
domain="[('user_id', '=', uid)]" context="{'invisible_section': False}"
help="Opportunities that are assigned to me"/>
<filter string="Assigned to My Team(s)"
domain="[('section_id.member_ids', 'in', [uid])]" context="{'invisible_section': False}"
@ -572,6 +577,7 @@
<filter string="Campaign" domain="[]" context="{'group_by':'type_id'}"/>
<filter string="Channel" domain="[]" context="{'group_by':'channel_id'}"/>
<filter string="Creation" domain="[]" context="{'group_by':'create_date'}"/>
<filter string="Last Update Month" domain="[]" context="{'group_by':'write_date'}"/>
</group>
<group string="Display">
<filter string="Show Sales Team" context="{'invisible_section': False}" domain="[]" help="Show Sales Team" groups="base.group_multi_salesteams"/>

View File

@ -80,7 +80,6 @@
<field name="sequence" widget="handle"/>
<field name="name"/>
<field name="probability"/>
<field name="state"/>
<field name="type"/>
</tree>
</field>
@ -96,7 +95,6 @@
<form string="Stage" version="7.0">
<group col="4">
<field name="name"/>
<field name="state"/>
<field name="probability"/>
<field name="type"/>
<field name="on_change"/>

View File

@ -19,17 +19,9 @@
#
##############################################################################
from openerp.osv import fields,osv
from openerp.osv import fields, osv
from openerp import tools
from .. import crm
AVAILABLE_STATES = [
('draft','Draft'),
('open','Open'),
('cancel', 'Cancelled'),
('done', 'Closed'),
('pending','Pending')
]
from openerp.addons.crm import crm
MONTHS = [
('01', 'January'),
@ -70,7 +62,7 @@ class crm_lead_report(osv.osv):
'date_closed': fields.date('Close Date', readonly=True),
# durations
'delay_open': fields.float('Delay to Open',digits=(16,2),readonly=True, group_operator="avg",help="Number of Days to open the case"),
'delay_open': fields.float('Delay to Assign',digits=(16,2),readonly=True, group_operator="avg",help="Number of Days to open the case"),
'delay_close': fields.float('Delay to Close',digits=(16,2),readonly=True, group_operator="avg",help="Number of Days to close the case"),
'delay_expected': fields.float('Overpassed Deadline',digits=(16,2),readonly=True, group_operator="avg"),
@ -79,7 +71,6 @@ class crm_lead_report(osv.osv):
'section_id':fields.many2one('crm.case.section', 'Sales Team', readonly=True),
'channel_id':fields.many2one('crm.case.channel', 'Channel', readonly=True),
'type_id':fields.many2one('crm.case.resource.type', 'Campaign', readonly=True),
'state': fields.selection(AVAILABLE_STATES, 'Status', size=16, readonly=True),
'company_id': fields.many2one('res.company', 'Company', readonly=True),
'probability': fields.float('Probability',digits=(16,2),readonly=True, group_operator="avg"),
'planned_revenue': fields.float('Planned Revenue',digits=(16,2),readonly=True),
@ -94,10 +85,7 @@ class crm_lead_report(osv.osv):
('opportunity','Opportunity'),
],'Type', help="Type is used to separate Leads and Opportunities"),
}
def init(self, cr):
"""
@ -121,7 +109,6 @@ class crm_lead_report(osv.osv):
to_char(c.date_open, 'YYYY-MM-DD') as opening_date,
to_char(c.date_closed, 'YYYY-mm-dd') as date_closed,
c.state,
c.user_id,
c.probability,
c.stage_id,

View File

@ -69,10 +69,12 @@
<filter icon="terp-personal" name="lead" string="Lead" domain="[('type','=', 'lead')]" help="Show only lead"/>
<filter icon="terp-personal+" string="Opportunity" name="opportunity" domain="[('type','=','opportunity')]" help="Show only opportunity"/>
<separator/>
<filter icon="terp-check" string="New" domain="[('state','=','draft')]" help="Leads/Opportunities which are in New state"/>
<filter icon="terp-camera_test" string="Open" domain="[('state','=','open')]" help="Leads/Opportunities which are in open state"/>
<filter icon="gtk-media-pause" string="Pending" domain="[('state','=','pending')]" help="Leads/Opportunities which are in pending state"/>
<filter icon="terp-dialog-close" string="Closed" domain="[('state','=','done')]" help="Leads/Opportunities which are in done state"/>
<filter string="New" name="new"
domain="[('probability', '=', 0), ('stage_id.sequence', '=', 1)]"/>
<filter string="Won" name="won"
domain="[('probability', '=', 100), ('stage_id.on_change', '=', 1)]"/>
<filter string="Lost" name="lost"
domain="[('probability', '=', 0), ('stage_id.sequence', '!=', 1)]"/>
<separator/>
<filter string="My Sales Team(s)" icon="terp-personal+" context="{'invisible_section': False}" domain="[('section_id.user_id','=',uid)]"
help="Leads/Opportunities that are assigned to one of the sale teams I manage" groups="base.group_multi_salesteams"/>
@ -131,7 +133,7 @@
<field name="name">crm.lead.report.tree</field>
<field name="model">crm.lead.report</field>
<field name="arch" type="xml">
<tree colors="blue:state == 'draft';black:state in ('open','pending','done');gray:state == 'cancel' " create="false" string="Opportunities Analysis">
<tree create="false" string="Opportunities Analysis">
<field name="creation_year" invisible="1"/>
<field name="creation_month" invisible="1"/>
<field name="creation_day" invisible="1"/>
@ -141,7 +143,6 @@
<field name="user_id" invisible="1"/>
<field name="partner_id" invisible="1"/>
<field name="country_id" invisible="1"/>
<field name="state" invisible="1"/>
<field name="stage_id" invisible="1"/>
<field name="priority" invisible="1"/>
<field name="type_id" invisible="1"/>
@ -150,7 +151,7 @@
<field name="company_id" invisible="1" groups="base.group_multi_company"/>
<field name="nbr" string="#Opportunities" sum="#Opportunities"/>
<field name="planned_revenue" sum="Planned Revenues"/>
<field name="delay_open" sum='Delay to open'/>
<field name="delay_open" sum='Delay to Assign'/>
<field name="delay_close" sum='Delay to close'/>
<field name="delay_expected"/>
<field name="probability" widget="progressbar"/>

View File

@ -19,16 +19,16 @@
#
##############################################################################
from openerp.osv import fields,osv
from openerp import tools
from .. import crm
from openerp.addons.crm import crm
from openerp.osv import fields, osv
AVAILABLE_STATES = [
('draft','Draft'),
('open','Todo'),
('draft', 'Draft'),
('open', 'Todo'),
('cancel', 'Cancelled'),
('done', 'Held'),
('pending','Pending')
('pending', 'Pending')
]

View File

@ -23,7 +23,7 @@
<field name="nbr" string="#Phone calls" sum="#Phone calls"/>
<field name="duration" avg="Duration"/>
<field name="delay_close" avg="Avg Closing Delay"/>
<field name="delay_open" sum='Delay to open'/>
<field name="delay_open" sum='Delay to Assign'/>
</tree>
</field>
</record>

View File

@ -41,7 +41,7 @@ class res_partner(osv.osv):
_columns = {
'section_id': fields.many2one('crm.case.section', 'Sales Team'),
'opportunity_ids': fields.one2many('crm.lead', 'partner_id',\
'Leads and Opportunities', domain=[('state','in', ('draft','open','pending'))]),
'Leads and Opportunities', domain=[('probability' 'not in', ['0', '100'])]),
'meeting_ids': fields.many2many('crm.meeting', 'crm_meeting_partner_rel','partner_id', 'meeting_id',
'Meetings'),
'phonecall_ids': fields.one2many('crm.phonecall', 'partner_id',\
@ -87,7 +87,6 @@ class res_partner(osv.osv):
'probability' : probability,
'partner_id' : partner_id,
'categ_ids' : categ_ids and categ_ids[0:1] or [],
'state' :'draft',
'type': 'opportunity'
}, context=context)
opportunity_ids[partner_id] = opportunity_id

View File

@ -1,9 +1,14 @@
-
I set a new sale team (with Marketing at parent) and I cancel unqualified lead .
I set a new sale team (with Marketing at parent) .
-
!python {model: crm.lead}: |
section_id = self.pool.get('crm.case.section').create(cr, uid, {'name': "Phone Marketing", 'parent_id': ref("crm.crm_case_section_2")})
self.write(cr, uid, [ref("crm_case_1")], {'section_id': section_id})
-
I check unqualified lead .
-
!assert {model: crm.lead, id: crm.crm_case_1, string: Lead is in new stage}:
- stage_id.sequence == 1
-
I escalate the lead to parent team.
-

View File

@ -0,0 +1,43 @@
-
I create a new lead.
-
!record {model: crm.lead, id: test_crm_lead_new}:
type: 'lead'
name: 'Test lead new'
partner_id: base.res_partner_1
description: This is the description of the test new lead.
section_id: crm.section_sales_department
-
I check default stage of lead.
-
!python {model: crm.lead}: |
stage = self.pool.get('crm.case.stage').search_read(cr,uid,[('sequence','=',1)],['id'],context)[0]
lead = self.browse(cr, uid, ref('test_crm_lead_new'))
stage_id = self.stage_find(cr, uid , [lead], lead.section_id.id or False,[], context)
assert stage_id == stage['id'], "Default stage of lead is incorrect!"
-
I change type from lead to opportunity.
-
!python {model: crm.lead}: |
self.convert_opportunity(cr, uid ,[ref("test_crm_lead_new")], ref("base.res_partner_2"))
-
Now I check default stage after change type.
-
!python {model: crm.lead}: |
stage = self.pool.get('crm.case.stage').search_read(cr,uid,[('sequence','=',1)],['id'],context)[0]
opp = self.browse(cr, uid, ref('test_crm_lead_new'))
stage_id = self.stage_find(cr, uid , [opp], opp.section_id.id or False,[], context)
assert stage_id == stage['id'], "Default stage of opportunity is incorrect!"
-
Now I change the stage of opportunity to won.
-
!python {model: crm.lead}: |
self.case_mark_won(cr, uid, [ref("test_crm_lead_new")])
-
I check statge of opp should won, after change stage.
-
!python {model: crm.lead}: |
opp = self.browse(cr, uid, ref('test_crm_lead_new'))
stage_id = self.stage_find(cr, uid , [opp], opp.section_id.id or False,[('probability','=',100.0)], context)
assert stage_id == opp.stage_id.id, "Stage of opportunity is incorrect!"

View File

@ -2,29 +2,29 @@
-
During a mixed merge (involving leads and opps), data should be handled a certain way following their type (m2o, m2m, text, ...) Start by creating two leads and an opp.
-
!record {model: crm.lead, id: test_crm_lead_01}:
type: 'lead'
name: 'Test lead 1'
partner_id: base.res_partner_1
stage_id: stage_lead1
description: This is the description of the test lead 1.
-
!record {model: crm.lead, id: test_crm_lead_02}:
type: 'lead'
name: 'Test lead 2'
partner_id: base.res_partner_3
stage_id: stage_lead1
description: This is the description of the test lead 2.
-
!record {model: crm.lead, id: test_crm_opp_01}:
!record {model: crm.lead, id: test_crm_opp_1}:
type: 'opportunity'
name: 'Test opportunity 1'
partner_id: base.res_partner_5
stage_id: stage_lead1
description: This is the description of the test opp 1.
-
!record {model: crm.lead, id: test_crm_lead_first}:
type: 'lead'
name: 'Test lead first'
partner_id: base.res_partner_1
stage_id: stage_lead1
description: This is the description of the test lead first.
-
!record {model: crm.lead, id: test_crm_lead_second}:
type: 'lead'
name: 'Test lead second'
partner_id: base.res_partner_1
stage_id: stage_lead1
description: This is the description of the test lead second.
-
!python {model: crm.lead}: |
lead_ids = [ref('test_crm_lead_01'), ref('test_crm_lead_02'), ref('test_crm_opp_01')]
lead_ids = [ref('test_crm_opp_1'), ref('test_crm_lead_first'), ref('test_crm_lead_second')]
context.update({'active_model': 'crm.lead', 'active_ids': lead_ids, 'active_id': lead_ids[0]})
-
I create a merge wizard and merge the leads and opp together in the first item of the list.
@ -38,18 +38,19 @@
-
!python {model: crm.lead}: |
merge_id = self.search(cr, uid, [('name', '=', 'Test opportunity 1'), ('partner_id','=', ref("base.res_partner_5"))])
assert merge_id, 'Fail to create merge opportunity wizard'
merge_result = self.browse(cr, uid, merge_id)[0]
assert merge_result.description == 'This is the description of the test opp 1.\n\nThis is the description of the test lead 1.\n\nThis is the description of the test lead 2.', 'Description mismatch: when merging leads/opps with different text values, these values should get concatenated and separated with line returns'
assert merge_result.description == 'This is the description of the test opp 1.\n\nThis is the description of the test lead first.\n\nThis is the description of the test lead second.', 'Description mismatch: when merging leads/opps with different text values, these values should get concatenated and separated with line returns'
assert merge_result.type == 'opportunity', 'Type mismatch: when at least one opp in involved in the merge, the result should be a new opp (instead of %s)' % merge_result.type
-
The other (tailing) leads/opps shouldn't exist anymore.
-
!python {model: crm.lead}: |
tailing_lead = self.search(cr, uid, [('id', '=', ref('test_crm_lead_01'))])
assert not tailing_lead, 'This tailing lead (id %s) should not exist anymore' % ref('test_crm_lead_02')
tailing_lead = self.search(cr, uid, [('id', '=', ref('test_crm_lead_first'))])
assert not tailing_lead, 'This tailing lead (id %s) should not exist anymore' % ref('test_crm_lead_second')
tailing_opp = self.search(cr, uid, [('id', '=', ref('test_crm_lead_02'))])
tailing_opp = self.search(cr, uid, [('id', '=', ref('test_crm_lead_second'))])
assert not tailing_opp, 'This tailing opp (id %s) should not exist anymore' % ref('test_crm_opp_01')
-
I want to test leads merge. Start by creating two leads (with the same partner).
@ -122,4 +123,4 @@
assert merge_result.partner_id.id == ref("base.res_partner_5"), 'Partner mismatch'
assert merge_result.type == 'opportunity', 'Type mismatch: when opps get merged together, the result should be a new opp (instead of %s)' % merge_result.type
tailing_opp = self.search(cr, uid, [('id', '=', ref('test_crm_opp_03'))])
assert not tailing_opp, 'This tailing opp (id %s) should not exist anymore' % ref('test_crm_opp_03')
assert not tailing_opp, 'This tailing opp (id %s) should not exist anymore' % ref('test_crm_opp_03')

View File

@ -6,14 +6,13 @@
partner_id: base.res_partner_2
type: opportunity
stage_id: crm.stage_lead1
state: draft
-
I create a lead record to call a mailing opt-out onchange method.
-
!record {model: crm.lead, id: crm_case_18}:
name: 'Need 20 Days of Consultancy'
type: opportunity
state: draft
stage_id: crm.stage_lead1
opt_out: True
-
I create a phonecall record to call a partner onchange method.

View File

@ -1,15 +1,25 @@
-
In order to test the conversion of a lead into a opportunity,
-
I set lead to open stage.
-
!python {model: crm.lead}: |
self.write(cr, uid, [ref("crm_case_3")],{'stage_id':ref("stage_lead1")})
-
I check if the lead stage is "Open".
-
!assert {model: crm.lead, id: crm.crm_case_3, string: Lead stage is Open}:
- stage_id.sequence == 1
-
I convert lead into opportunity for exiting customer.
-
!python {model: crm.lead}: |
self.convert_opportunity(cr, uid ,[ref("crm_case_1")], ref("base.res_partner_2"))
self.convert_opportunity(cr, uid ,[ref("crm_case_3")], ref("base.res_partner_2"))
-
I check details of converted opportunity.
-
!python {model: crm.lead}: |
lead = self.browse(cr, uid, ref('crm_case_1'))
lead = self.browse(cr, uid, ref('crm_case_3'))
assert lead.type == 'opportunity', 'Lead is not converted to opportunity!'
assert lead.partner_id.id == ref("base.res_partner_2"), 'Partner mismatch!'
assert lead.stage_id.id == ref("stage_lead1"), 'Stage of opportunity is incorrect!'
@ -18,7 +28,7 @@
-
!python {model: crm.opportunity2phonecall}: |
import time
context.update({'active_model': 'crm.lead', 'active_ids': [ref('crm_case_1')]})
context.update({'active_model': 'crm.lead', 'active_ids': [ref('crm_case_3')]})
call_id = self.create(cr, uid, {'date': time.strftime('%Y-%m-%d %H:%M:%S'),
'name': "Bonjour M. Jean, Comment allez-vous? J'ai bien reçu votre demande, pourrions-nous en parler quelques minutes?"}, context=context)
self.action_schedule(cr, uid, [call_id], context=context)
@ -26,46 +36,46 @@
I check that phonecall is scheduled for that opportunity.
-
!python {model: crm.phonecall}: |
ids = self.search(cr, uid, [('opportunity_id', '=', ref('crm_case_1'))])
ids = self.search(cr, uid, [('opportunity_id', '=', ref('crm_case_3'))])
assert len(ids), 'Phonecall is not scheduled'
-
Now I schedule meeting with customer.
-
!python {model: crm.lead}: |
self.action_makeMeeting(cr, uid, [ref('crm_case_1')])
self.action_makeMeeting(cr, uid, [ref('crm_case_3')])
-
After communicated with customer, I put some notes with contract details.
-
!python {model: crm.lead}: |
self.message_post(cr, uid, [ref('crm_case_1')], subject='Test note', body='Détails envoyés par le client sur le FAX pour la qualité')
self.message_post(cr, uid, [ref('crm_case_3')], subject='Test note', body='Détails envoyés par le client sur le FAX pour la qualité')
-
I win this opportunity
-
!python {model: crm.lead}: |
self.case_mark_won(cr, uid, [ref("crm_case_1")])
self.case_mark_won(cr, uid, [ref("crm_case_3")])
-
I check details of the opportunity after having won the opportunity.
-
!python {model: crm.lead}: |
lead = self.browse(cr, uid, ref('crm_case_1'))
lead = self.browse(cr, uid, ref('crm_case_3'))
assert lead.stage_id.id == ref('crm.stage_lead6'), "Opportunity stage should be 'Won'."
assert lead.state == 'done', "Opportunity is not in 'done' state!"
assert lead.stage_id.probability == 100.0, "Opportunity is not 'done'"
assert lead.probability == 100.0, "Revenue probability should be 100.0!"
-
I convert mass lead into opportunity customer.
-
!python {model: crm.lead2opportunity.partner.mass}: |
context.update({'active_model': 'crm.lead', 'active_ids': [ref("crm_case_11"), ref("crm_case_2")], 'active_id': ref("crm_case_11")})
context.update({'active_model': 'crm.lead', 'active_ids': [ref("crm_case_13"), ref("crm_case_2")], 'active_id': ref("crm_case_13")})
id = self.create(cr, uid, {'user_ids': [(6, 0, [ref('base.user_root')])], 'section_id': ref('crm.section_sales_department')}, context=context)
self.mass_convert(cr, uid, [id], context=context)
-
Now I check first lead converted on opportunity.
-
!python {model: crm.lead}: |
opp = self.browse(cr, uid, ref('crm_case_11'))
assert opp.name == "Need estimated cost for new project", "Opportunity name not correct"
opp = self.browse(cr, uid, ref('crm_case_13'))
assert opp.name == "Plan to buy 60 keyboards and mouses", "Opportunity name not correct"
assert opp.type == 'opportunity', 'Lead is not converted to opportunity!'
expected_partner = "Thomas Passot"
expected_partner = "Will McEncroe"
assert opp.partner_id.name == expected_partner, 'Partner mismatch! %s vs %s' % (opp.partner_id.name, expected_partner)
assert opp.stage_id.id == ref("stage_lead1"), 'Stage of probability is incorrect!'
-
@ -86,14 +96,15 @@
-
!python {model: crm.lead}: |
lead = self.browse(cr, uid, ref('crm_case_2'))
assert lead.stage_id.id == ref('crm.stage_lead8'), "Opportunity stage should be 'Lost'."
assert lead.state == 'cancel', "Lost opportunity is not in 'cancel' state!"
assert lead.stage_id.id == ref('crm.stage_lead7'), "Opportunity stage should be 'Lost'."
assert lead.stage_id.sequence != 1 and lead.stage_id.probability == 0.0, "Lost opportunity is not in 'cancel' state!"
assert lead.probability == 0.0, "Revenue probability should be 0.0!"
-
I confirm review needs meeting.
-
!python {model: crm.meeting}: |
context.update({'active_model': 'crm.meeting'})
self.case_open(cr, uid, [ref('base_calendar.crm_meeting_4')])
-
I invite a user for meeting.
-

View File

@ -21,7 +21,6 @@
from openerp.osv import fields, osv
from openerp.tools.translate import _
from openerp import tools
import re
class crm_lead2opportunity_partner(osv.osv_memory):
@ -58,11 +57,11 @@ class crm_lead2opportunity_partner(osv.osv_memory):
if partner_id:
# Search for opportunities that have the same partner and that arent done or cancelled
ids = lead_obj.search(cr, uid, [('partner_id', '=', partner_id), ('state', '!=', 'done')])
ids = lead_obj.search(cr, uid, [('partner_id', '=', partner_id), ('probability', '<', '100')])
for id in ids:
tomerge.add(id)
if email:
ids = lead_obj.search(cr, uid, [('email_from', 'ilike', email[0]), ('state', '!=', 'done')])
ids = lead_obj.search(cr, uid, [('email_from', 'ilike', email[0]), ('probability', '<', '100')])
for id in ids:
tomerge.add(id)
@ -85,8 +84,8 @@ class crm_lead2opportunity_partner(osv.osv_memory):
context = {}
lead_obj = self.pool.get('crm.lead')
for lead in lead_obj.browse(cr, uid, context.get('active_ids', []), context=context):
if lead.state in ['done', 'cancel']:
raise osv.except_osv(_("Warning!"), _("Closed/Cancelled leads cannot be converted into opportunities."))
if lead.probability == 100:
raise osv.except_osv(_("Warning!"), _("Closed/Dead leads cannot be converted into opportunities."))
return False
def _convert_opportunity(self, cr, uid, ids, vals, context=None):

View File

@ -60,8 +60,7 @@ class crm_merge_opportunity(osv.osv_memory):
def default_get(self, cr, uid, fields, context=None):
"""
Use active_ids from the context to fetch the leads/opps to merge.
In order to get merged, these leads/opps can't be in 'Done' or
'Cancel' state.
In order to get merged, these leads/opps can't be in 'Dead' or 'Closed'
"""
if context is None:
context = {}
@ -72,7 +71,7 @@ class crm_merge_opportunity(osv.osv_memory):
opp_ids = []
opps = self.pool.get('crm.lead').browse(cr, uid, record_ids, context=context)
for opp in opps:
if opp.state not in ('done', 'cancel'):
if opp.probability < 100:
opp_ids.append(opp.id)
if 'opportunity_ids' in fields:
res.update({'opportunity_ids': opp_ids})