[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_onchange.yml',
'test/crm_lead_copy.yml', 'test/crm_lead_copy.yml',
'test/crm_lead_unlink.yml', 'test/crm_lead_unlink.yml',
'test/crm_lead_find_stage.yml',
], ],
'css': [ 'css': [
'static/src/css/crm.css' 'static/src/css/crm.css'

View File

@ -19,7 +19,11 @@
<field name="view_type">form</field> <field name="view_type">form</field>
<field name="view_mode">graph,tree,form</field> <field name="view_mode">graph,tree,form</field>
<field name="view_id" ref="view_crm_opportunity_stage_graph"/> <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> <field name="context">{'search_default_Stage':1}</field>
</record> </record>
@ -43,8 +47,9 @@
<field name="view_type">form</field> <field name="view_type">form</field>
<field name="view_mode">graph,tree,form</field> <field name="view_mode">graph,tree,form</field>
<field name="view_id" ref="view_crm_opportunity_user_stage_graph"/> <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> <!-- avoid cancelled -->
<field name="context">{'search_default_Stage':1}</field> <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>
<record model="ir.ui.view" id="board_crm_statistical_form"> <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 fields
from openerp.osv import osv from openerp.osv import osv
MAX_LEVEL = 15
AVAILABLE_STATES = [
('draft', 'New'),
('cancel', 'Cancelled'),
('open', 'In Progress'),
('pending', 'Pending'),
('done', 'Closed')
]
AVAILABLE_PRIORITIES = [ AVAILABLE_PRIORITIES = [
('1', 'Highest'), ('1', 'Highest'),
('2', 'High'), ('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"), '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."), 'on_change': fields.boolean('Change Probability Automatically', help="Setting this stage will change the probability automatically on the opportunity."),
'requirements': fields.text('Requirements'), '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."), 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', '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."), 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', '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."), 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'), ('opportunity', 'Opportunity'),
('both', 'Both')], ('both', 'Both')],
string='Type', size=16, required=True, string='Type', size=16, required=True,
@ -91,7 +79,7 @@ class crm_case_stage(osv.osv):
_defaults = { _defaults = {
'sequence': lambda *args: 1, 'sequence': lambda *args: 1,
'probability': lambda *args: 0.0, 'probability': lambda *args: 0.0,
'state': 'open', 'on_change': True,
'fold': False, 'fold': False,
'type': 'both', 'type': 'both',
'case_default': True, 'case_default': True,

View File

@ -5,7 +5,7 @@
<record id="filter_draft_lead" model="ir.filters"> <record id="filter_draft_lead" model="ir.filters">
<field name="name">Draft Leads</field> <field name="name">Draft Leads</field>
<field name="model_id">crm.lead</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"/> <field name="user_id" eval="False"/>
</record> </record>
<record id="action_email_reminder_lead" model="ir.actions.server"> <record id="action_email_reminder_lead" model="ir.actions.server">

View File

@ -22,14 +22,13 @@
import crm import crm
from datetime import datetime from datetime import datetime
from operator import itemgetter from operator import itemgetter
from openerp.osv import fields, osv, orm
import time
from openerp import SUPERUSER_ID from openerp import SUPERUSER_ID
from openerp import tools 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.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', CRM_LEAD_FIELDS_TO_MERGE = ['name',
'partner_id', 'partner_id',
@ -61,11 +60,7 @@ CRM_LEAD_FIELDS_TO_MERGE = ['name',
'email_from', 'email_from',
'email_cc', 'email_cc',
'partner_name'] '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): class crm_lead(format_address, osv.osv):
""" CRM Lead Case """ """ CRM Lead Case """
@ -75,13 +70,11 @@ class crm_lead(format_address, osv.osv):
_inherit = ['mail.thread', 'ir.needaction_mixin'] _inherit = ['mail.thread', 'ir.needaction_mixin']
_track = { _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': { '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): def _get_default_stage_id(self, cr, uid, context=None):
""" Gives default stage_id """ """ Gives default stage_id """
section_id = self._get_default_section_id(cr, uid, context=context) 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): def _resolve_section_id_from_context(self, cr, uid, context=None):
""" Returns ID of section based on the value of 'section_id' """ 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) 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) result = stage_obj.name_get(cr, access_rights_uid, stage_ids, context=context)
# restore order of the search # 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 = {} fold = {}
for stage in stage_obj.browse(cr, access_rights_uid, stage_ids, context=context): 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 return result, fold
def fields_view_get(self, cr, user, view_id=None, view_type='form', context=None, toolbar=False, submenu=False): 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': if view_type == 'form':
res['arch'] = self.fields_view_get_address(cr, user, res['arch'], context=context) res['arch'] = self.fields_view_get_address(cr, user, res['arch'], context=context)
return res return res
@ -220,17 +213,6 @@ class crm_lead(format_address, osv.osv):
res[lead.id][field] = abs(int(duration)) res[lead.id][field] = abs(int(duration))
return res 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 = { _columns = {
'partner_id': fields.many2one('res.partner', 'Partner', ondelete='set null', track_visibility='onchange', '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."), 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), 'email_from': fields.char('Email', size=128, help="Email address of the contact", select=1),
'section_id': fields.many2one('crm.case.section', 'Sales Team', '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.'), 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), '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"), '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'), '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', \ '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')]"), domain="['|',('section_id','=',section_id),('section_id','=',False), ('object_id.model', '=', 'crm.lead')]"),
'type_id': fields.many2one('crm.case.resource.type', 'Campaign', \ '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), multi='day_open', type="float", store=True),
'day_close': fields.function(_compute_day, string='Days to Close', \ 'day_close': fields.function(_compute_day, string='Days to Close', \
multi='day_close', type="float", store=True), 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 # 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'), 'planned_revenue': fields.float('Expected Revenue', track_visibility='always'),
'ref': fields.reference('Reference', selection=crm._links_get, size=128), 'ref': fields.reference('Reference', selection=crm._links_get, size=128),
'ref2': fields.reference('Reference 2', 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): def onchange_stage_id(self, cr, uid, ids, stage_id, context=None):
if not stage_id: if not stage_id:
return {'value': {}} 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: if not stage.on_change:
return {'value': {}} return {'value': {}}
return {'value': {'probability': stage.probability}} return {'value': {'probability': stage.probability}}
@ -358,21 +337,22 @@ class crm_lead(format_address, osv.osv):
section_id = section_ids[0] section_id = section_ids[0]
return {'value': {'section_id': section_id}} return {'value': {'section_id': section_id}}
def _check(self, cr, uid, ids=False, context=None): # TDE NOTE: replaced byu base action rule fully working ?
""" Override of the base.stage method. # def _check(self, cr, uid, ids=False, context=None):
Function called by the scheduler to process cases for date actions # """ Override of the base.stage method.
Only works on not done and cancelled cases # 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) \ # cr.execute('select * from crm_case \
and (date_action_next<=%s or date_action_next is null) \ # where (date_action_last<%s or date_action_last is null) \
and state not in (\'cancel\',\'done\')', # and (date_action_next<=%s or date_action_next is null) \
(time.strftime("%Y-%m-%d %H:%M:%S"), # and state not in (\'cancel\',\'done\')',
time.strftime('%Y-%m-%d %H:%M:%S'))) # (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 []) # ids2 = map(lambda x: x[0], cr.fetchall() or [])
cases = self.browse(cr, uid, ids2, context=context) # cases = self.browse(cr, uid, ids2, context=context)
return self._action(cr, uid, cases, False, 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): def stage_find(self, cr, uid, cases, section_id, domain=None, order='sequence', context=None):
""" Override of the base.stage method """ Override of the base.stage method
@ -385,16 +365,16 @@ class crm_lead(format_address, osv.osv):
if isinstance(cases, (int, long)): if isinstance(cases, (int, long)):
cases = self.browse(cr, uid, cases, context=context) cases = self.browse(cr, uid, cases, context=context)
# collect all section_ids # collect all section_ids
section_ids = [] section_ids = set()
types = ['both'] types = ['both']
if not cases: if not cases:
type = context.get('default_type') ctx_type = context.get('default_type')
types += [type] types += [ctx_type]
if section_id: if section_id:
section_ids.append(section_id) section_ids.add(section_id)
for lead in cases: for lead in cases:
if lead.section_id: if lead.section_id:
section_ids.append(lead.section_id.id) section_ids.add(lead.section_id.id)
if lead.type not in types: if lead.type not in types:
types.append(lead.type) types.append(lead.type)
# OR all section_ids and OR with case_default # 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) search_domain += [('|')] * len(section_ids)
for section_id in section_ids: for section_id in section_ids:
search_domain.append(('section_ids', '=', section_id)) search_domain.append(('section_ids', '=', section_id))
else: search_domain.append(('case_default', '=', True))
search_domain.append(('case_default', '=', True))
# AND with cases types # AND with cases types
search_domain.append(('type', 'in', types)) search_domain.append(('type', 'in', types))
# AND with the domain in parameter # AND with the domain in parameter
@ -415,27 +394,29 @@ class crm_lead(format_address, osv.osv):
return stage_ids[0] return stage_ids[0]
return False 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): def case_mark_lost(self, cr, uid, ids, context=None):
""" Mark the case as lost: state=cancel and probability=0 """ """ Mark the case as lost: state=cancel and probability=0 """
for lead in self.browse(cr, uid, ids): 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: if stage_id:
self.stage_set(cr, uid, [lead.id], stage_id, context=context) return self.write(cr, uid, [lead.id], {'stage_id': stage_id}, context=context)
return True 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): def case_mark_won(self, cr, uid, ids, context=None):
""" Mark the case as won: state=done and probability=100 """ """ Mark the case as won: state=done and probability=100 """
for lead in self.browse(cr, uid, ids): 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: if stage_id:
self.stage_set(cr, uid, [lead.id], stage_id, context=context) return self.write(cr, uid, [lead.id], {'stage_id': stage_id}, context=context)
return True 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): def case_escalate(self, cr, uid, ids, context=None):
""" Escalates case to parent level """ """ 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) self.write(cr, uid, [case.id], data, context=context)
return True return True
def set_priority(self, cr, uid, ids, priority): def set_priority(self, cr, uid, ids, priority, context=None):
""" Set lead priority """ 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): def set_high_priority(self, cr, uid, ids, context=None):
""" Set lead priority to high """ 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): def set_normal_priority(self, cr, uid, ids, context=None):
""" Set lead priority to normal """ 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): def _merge_get_result_type(self, cr, uid, opps, context=None):
""" """
@ -640,7 +621,8 @@ class crm_lead(format_address, osv.osv):
sequenced_opps = [] sequenced_opps = []
for opportunity in opportunities: for opportunity in opportunities:
sequence = -1 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 sequence = opportunity.stage_id.sequence
sequenced_opps.append(((int(sequence != -1 and opportunity.type == 'opportunity'), sequence, -opportunity.id), opportunity)) sequenced_opps.append(((int(sequence != -1 and opportunity.type == 'opportunity'), sequence, -opportunity.id), opportunity))

View File

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

View File

@ -1,14 +1,15 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<openerp> <openerp>
<data noupdate="1"> <!-- <data noupdate="1"> -->
<data>
<!-- Demo Leads --> <!-- Demo Leads -->
<record id="crm_case_1" model="crm.lead"> <record id="crm_case_1" model="crm.lead">
<field name="type">lead</field> <field name="type">lead</field>
<field name="name">Plan to Attend a Training</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="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="partner_id" ref=""/>
<field name="function">Training Manager</field> <field name="function">Training Manager</field>
<field name="street">73, rue Léon Dierx</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="categ_ids" eval="[(6, 0, [categ_oppor6])]"/>
<field name="channel_id" ref="crm_case_channel_email"/> <field name="channel_id" ref="crm_case_channel_email"/>
<field name="priority">1</field> <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="user_id" ref="base.user_root"/>
<field name="stage_id" ref="stage_lead1"/> <field name="stage_id" ref="stage_lead1"/>
<field name="description">Hello, <field name="description">Hello,
I am Jason from Le Club SARL. I am Jacques from Le Club SARL.
I am intertested to attend a training organized in your company. I am interested to attend a training organized in your company.
Can you send me the details ?</field> Could you please send me the details ?</field>
<field eval="1" name="active"/> </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>
<record id="crm_case_2" model="crm.lead"> <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="categ_ids" eval="[(6, 0, [categ_oppor2])]"/>
<field name="channel_id" ref="crm_case_channel_website"/> <field name="channel_id" ref="crm_case_channel_website"/>
<field name="priority">4</field> <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="user_id" ref="base.user_root"/>
<field name="stage_id" ref="stage_lead1"/> <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>
<record id="crm_case_3" model="crm.lead"> <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="priority">2</field>
<field name="section_id" ref="crm_case_section_1"/> <field name="section_id" ref="crm_case_section_1"/>
<field name="user_id" ref="base.user_demo"/> <field name="user_id" ref="base.user_demo"/>
<field name="stage_id" ref="stage_lead2"/> <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>
<record id="crm_case_4" model="crm.lead"> <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="categ_ids" eval="[(6, 0, [categ_oppor5])]"/>
<field name="channel_id" ref=""/> <field name="channel_id" ref=""/>
<field name="priority">3</field> <field name="priority">3</field>
<field name="section_id" ref="crm_case_section_1"/> <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_lead7"/> <field name="stage_id" ref="stage_lead6"/>
<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>
<record id="crm_case_5" model="crm.lead"> <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="categ_ids" eval="[(6, 0, [categ_oppor1])]"/>
<field name="channel_id" ref="crm_case_channel_website"/> <field name="channel_id" ref="crm_case_channel_website"/>
<field name="priority">3</field> <field name="priority">3</field>
<field name="section_id" ref="section_sales_department"/> <field name="section_id" ref="crm_case_section_1"/>
<field name="user_id" ref="base.user_root"/> <field name="user_id" ref=""/>
<field name="stage_id" ref="stage_lead1"/> <field name="stage_id" ref="stage_lead1"/>
<field name="description">Hi, <field name="description">Hi,
Can you send me a quotation for 20 computers with speakers? Can you send me a quotation for 20 computers with speakers?
@ -116,7 +142,6 @@ Purchase Manager
Stonage IT, Stonage IT,
Franklinville Franklinville
Contact: +1 813 494 5005</field> Contact: +1 813 494 5005</field>
<field eval="1" name="active"/>
</record> </record>
<record id="crm_case_6" model="crm.lead"> <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="channel_id" ref=""/>
<field name="priority">3</field> <field name="priority">3</field>
<field name="section_id" ref="crm_case_section_2"/> <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 name="stage_id" ref="stage_lead1"/>
<field eval="1" name="active"/>
</record> </record>
<record id="crm_case_7" model="crm.lead"> <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="channel_id" ref=""/>
<field name="priority">5</field> <field name="priority">5</field>
<field name="section_id" ref="crm_case_section_2"/> <field name="section_id" ref="crm_case_section_2"/>
<field name="user_id" ref="base.user_demo"/> <field name="user_id" ref="base.user_root"/>
<field name="stage_id" ref="stage_lead7"/> <field name="stage_id" ref="stage_lead1"/>
<field eval="1" name="active"/>
</record> </record>
<record id="crm_case_8" model="crm.lead"> <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="channel_id" ref=""/>
<field name="priority">4</field> <field name="priority">4</field>
<field name="section_id" ref="section_sales_department"/> <field name="section_id" ref="section_sales_department"/>
<field name="user_id" ref="base.user_demo"/> <field name="user_id" ref="base.user_root"/>
<field name="stage_id" ref="stage_lead7"/> <field name="stage_id" ref="stage_lead1"/>
<field eval="1" name="active"/>
</record> </record>
<record id="crm_case_9" model="crm.lead"> <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="channel_id" ref="crm_case_channel_phone"/>
<field name="priority">2</field> <field name="priority">2</field>
<field name="section_id" ref="section_sales_department"/> <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 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>
<record id="crm_case_10" model="crm.lead"> <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="channel_id" ref="crm_case_channel_email"/>
<field name="priority">2</field> <field name="priority">2</field>
<field name="section_id" ref="crm_case_section_2"/> <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="stage_id" ref="stage_lead1"/>
<field name="description">Hi, <field name="description">Hi,
I would like to know more about specification and cost of laptops of your company. I would like to know more about specification and cost of laptops of your company.
Thanks, Thanks,
Andrew</field> Andrew</field>
<field eval="1" name="active"/>
</record> </record>
<record id="crm_case_11" model="crm.lead"> <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="channel_id" ref="crm_case_channel_direct"/>
<field name="priority">3</field> <field name="priority">3</field>
<field name="section_id" ref="crm_case_section_1"/> <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 name="stage_id" ref="stage_lead1"/>
<field eval="1" name="active"/>
</record> </record>
<record id="crm_case_12" model="crm.lead"> <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="channel_id" ref="crm_case_channel_website"/>
<field name="priority">2</field> <field name="priority">2</field>
<field name="section_id" ref="section_sales_department"/> <field name="section_id" ref="section_sales_department"/>
<field name="user_id" ref="base.user_demo"/> <field name="user_id" ref=""/>
<field name="stage_id" ref="stage_lead2"/> <field name="stage_id" ref="stage_lead1"/>
<field eval="1" name="active"/>
</record> </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 --> <!-- Call Function to set the leads as Unread -->
<function model="crm.lead" name="message_mark_as_unread" <function model="crm.lead" name="message_mark_as_unread"
eval="[ ref('crm_case_1'), ref('crm_case_2'), 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 --> <!-- Demo Opportunities -->
@ -289,8 +313,7 @@ Andrew</field>
<field name="title_action">Meeting for pricing information.</field> <field name="title_action">Meeting for pricing information.</field>
<field name="section_id" ref="section_sales_department"/> <field name="section_id" ref="section_sales_department"/>
<field name="user_id" ref="base.user_root"/> <field name="user_id" ref="base.user_root"/>
<field name="stage_id" ref="crm.stage_lead3"/> <field name="stage_id" ref="crm.stage_lead1"/>
<field eval="1" name="active"/>
</record> </record>
<record id="crm_case_14" model="crm.lead"> <record id="crm_case_14" model="crm.lead">
@ -316,7 +339,6 @@ Andrew</field>
<field name="section_id" ref="section_sales_department"/> <field name="section_id" ref="section_sales_department"/>
<field name="user_id" ref="base.user_demo"/> <field name="user_id" ref="base.user_demo"/>
<field name="stage_id" ref="crm.stage_lead3"/> <field name="stage_id" ref="crm.stage_lead3"/>
<field eval="1" name="active"/>
</record> </record>
<record id="crm_case_15" model="crm.lead"> <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="title_action">Call to ask system requirement</field>
<field name="section_id" ref="section_sales_department"/> <field name="section_id" ref="section_sales_department"/>
<field name="user_id" ref="base.user_demo"/> <field name="user_id" ref="base.user_demo"/>
<field name="stage_id" ref="crm.stage_lead6"/> <field name="stage_id" ref="crm.stage_lead3"/>
<field eval="1" name="active"/> <!-- <field name="date_closed" eval="(DateTime.today() - relativedelta(months=2)).strftime('%Y-%m-%d %H:%M')"/> -->
<field name="date_closed" eval="(DateTime.today() - relativedelta(months=2)).strftime('%Y-%m-%d %H:%M')"/>
</record> </record>
<record id="crm_case_16" model="crm.lead"> <record id="crm_case_16" model="crm.lead">
@ -362,9 +383,8 @@ Andrew</field>
<field name="title_action">Convert to quote</field> <field name="title_action">Convert to quote</field>
<field name="section_id" ref="crm_case_section_1"/> <field name="section_id" ref="crm_case_section_1"/>
<field name="user_id" ref="base.user_demo"/> <field name="user_id" ref="base.user_demo"/>
<field name="stage_id" ref="crm.stage_lead6"/> <field name="stage_id" ref="crm.stage_lead3"/>
<field eval="1" name="active"/> <!-- <field name="date_closed" eval="(DateTime.today() - relativedelta(hours=1)).strftime('%Y-%m-%d %H:%M')"/> -->
<field name="date_closed" eval="(DateTime.today() - relativedelta(hours=1)).strftime('%Y-%m-%d %H:%M')"/>
</record> </record>
<record id="crm_case_17" model="crm.lead"> <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="title_action">Send price list regarding our interventions</field>
<field name="section_id" ref="crm_case_section_1"/> <field name="section_id" ref="crm_case_section_1"/>
<field name="user_id" ref="base.user_demo"/> <field name="user_id" ref="base.user_demo"/>
<field name="stage_id" ref="crm.stage_lead6"/> <field name="stage_id" ref="crm.stage_lead4"/>
<field eval="1" name="active"/> <!-- <field name="date_closed" eval="(DateTime.today() - relativedelta(hours=1)).strftime('%Y-%m-%d %H:%M')"/> -->
<field name="date_closed" eval="(DateTime.today() - relativedelta(hours=1)).strftime('%Y-%m-%d %H:%M')"/>
</record> </record>
<record id="crm_case_18" model="crm.lead"> <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="title_action">Call to define real needs about training</field>
<field name="section_id" ref="crm_case_section_1"/> <field name="section_id" ref="crm_case_section_1"/>
<field name="user_id" ref="base.user_demo"/> <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"/> <field eval="1" name="active"/>
</record> </record>
@ -437,9 +456,8 @@ Andrew</field>
<field name="title_action">Ask for the good receprion of the proposition</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="section_id" ref="crm_case_section_1"/>
<field name="user_id" ref="base.user_root"/> <field name="user_id" ref="base.user_root"/>
<field name="stage_id" ref="crm.stage_lead6"/> <field name="stage_id" ref="crm.stage_lead4"/>
<field eval="1" name="active"/> <!-- <field name="date_closed" eval="(DateTime.today() - relativedelta(months=3)).strftime('%Y-%m-%d %H:%M')"/> -->
<field name="date_closed" eval="(DateTime.today() - relativedelta(months=3)).strftime('%Y-%m-%d %H:%M')"/>
</record> </record>
<record id="crm_case_20" model="crm.lead"> <record id="crm_case_20" model="crm.lead">
@ -455,8 +473,7 @@ Andrew</field>
<field name="priority">2</field> <field name="priority">2</field>
<field name="section_id" ref="crm_case_section_1"/> <field name="section_id" ref="crm_case_section_1"/>
<field name="user_id" ref="base.user_demo"/> <field name="user_id" ref="base.user_demo"/>
<field name="stage_id" ref="crm.stage_lead1"/> <field name="stage_id" ref="crm.stage_lead4"/>
<field eval="1" name="active"/>
</record> </record>
<record id="crm_case_21" model="crm.lead"> <record id="crm_case_21" model="crm.lead">
@ -470,9 +487,8 @@ Andrew</field>
<field name="priority">3</field> <field name="priority">3</field>
<field name="section_id" ref="crm_case_section_2"/> <field name="section_id" ref="crm_case_section_2"/>
<field name="user_id" ref="base.user_root"/> <field name="user_id" ref="base.user_root"/>
<field name="stage_id" ref="crm.stage_lead6"/> <field name="stage_id" ref="crm.stage_lead4"/>
<field eval="1" name="active"/> <!-- <field name="date_closed" eval="(DateTime.today() - relativedelta(months=1)).strftime('%Y-%m-%d %H:%M')"/> -->
<field name="date_closed" eval="(DateTime.today() - relativedelta(months=1)).strftime('%Y-%m-%d %H:%M')"/>
</record> </record>
<record id="crm_case_22" model="crm.lead"> <record id="crm_case_22" model="crm.lead">
@ -489,8 +505,7 @@ Andrew</field>
<field name="priority">3</field> <field name="priority">3</field>
<field name="section_id" ref="crm_case_section_2"/> <field name="section_id" ref="crm_case_section_2"/>
<field name="user_id" ref="base.user_root"/> <field name="user_id" ref="base.user_root"/>
<field name="stage_id" ref="crm.stage_lead8"/> <field name="stage_id" ref="crm.stage_lead5"/>
<field eval="1" name="active"/>
</record> </record>
<record id="crm_case_23" model="crm.lead"> <record id="crm_case_23" model="crm.lead">
@ -505,9 +520,8 @@ Andrew</field>
<field name="priority">5</field> <field name="priority">5</field>
<field name="section_id" ref="section_sales_department"/> <field name="section_id" ref="section_sales_department"/>
<field name="user_id" ref="base.user_demo"/> <field name="user_id" ref="base.user_demo"/>
<field name="stage_id" ref="crm.stage_lead6"/> <field name="stage_id" ref="crm.stage_lead5"/>
<field eval="1" name="active"/> <!-- <field name="date_closed" eval="(DateTime.today() - relativedelta(hours=1)).strftime('%Y-%m-%d %H:%M')"/> -->
<field name="date_closed" eval="(DateTime.today() - relativedelta(hours=1)).strftime('%Y-%m-%d %H:%M')"/>
</record> </record>
<record id="crm_case_24" model="crm.lead"> <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 eval="time.strftime('%Y-%m-6')" name="date_deadline"/>
<field name="section_id" ref="section_sales_department"/> <field name="section_id" ref="section_sales_department"/>
<field name="user_id" ref="base.user_root"/> <field name="user_id" ref="base.user_root"/>
<field name="stage_id" ref="crm.stage_lead6"/> <field name="stage_id" ref="crm.stage_lead5"/>
<field eval="1" name="active"/> <!-- <field name="date_closed" eval="(DateTime.today() - relativedelta(month=1)).strftime('%Y-%m-%d %H:%M')"/> -->
<field name="date_closed" eval="(DateTime.today() - relativedelta(month=1)).strftime('%Y-%m-%d %H:%M')"/>
</record> </record>
<record id="crm_case_25" model="crm.lead"> <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="title_action">Conf call with technical service</field>
<field name="section_id" ref="crm_case_section_1"/> <field name="section_id" ref="crm_case_section_1"/>
<field name="user_id" ref="base.user_root"/> <field name="user_id" ref="base.user_root"/>
<field name="stage_id" ref="crm.stage_lead4"/> <field name="stage_id" ref="crm.stage_lead5"/>
<field eval="1" name="active"/>
</record> </record>
<record id="crm_case_26" model="crm.lead"> <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="title_action">Send Catalogue by Email</field>
<field name="section_id" ref="crm_case_section_2"/> <field name="section_id" ref="crm_case_section_2"/>
<field name="user_id" ref="base.user_demo"/> <field name="user_id" ref="base.user_demo"/>
<field name="stage_id" ref="crm.stage_lead6"/> <field name="stage_id" ref="crm.stage_lead5"/>
<field eval="1" name="active"/> <!-- <field name="date_closed" eval="(DateTime.today() - relativedelta(hours=1)).strftime('%Y-%m-%d %H:%M')"/> -->
<field name="date_closed" eval="(DateTime.today() - relativedelta(hours=1)).strftime('%Y-%m-%d %H:%M')"/>
</record> </record>
<!-- Unsubscribe Admin from case15, subscribe Demo --> <!-- Unsubscribe Admin from case15, subscribe Demo -->
@ -682,26 +693,9 @@ Andrew</field>
<field name="parent_id" ref="msg_case18_1"/> <field name="parent_id" ref="msg_case18_1"/>
<field name="author_id" ref="base.partner_demo"/> <field name="author_id" ref="base.partner_demo"/>
</record> </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" <function model="mail.message" name="set_message_starred"
eval="[ ref('msg_case18_1'), ref('msg_case18_2')], True, {}" eval="[ ref('msg_case18_1'), ref('msg_case18_2')], True, {}"
/> />
</data> </data>
</openerp> </openerp>

View File

@ -12,9 +12,10 @@
<field name="model">crm.case.stage</field> <field name="model">crm.case.stage</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<search string="Stage Search"> <search string="Stage Search">
<field name="name" string="Stage Name"/> <field name="name"/>
<field name="state"/>
<field name="type"/> <field name="type"/>
<field name="sequence"/>
<field name="probability"/>
</search> </search>
</field> </field>
</record> </record>
@ -94,7 +95,8 @@
<form string="Leads Form" version="7.0"> <form string="Leads Form" version="7.0">
<header> <header>
<button name="%(crm.action_crm_lead2opportunity_partner)d" string="Convert to Opportunity" type="action" <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" <field name="stage_id" widget="statusbar" clickable="True"
domain="['&amp;', '|', ('case_default', '=', True), ('section_ids', '=', section_id), '|', ('type', '=', type), ('type', '=', 'both')]" domain="['&amp;', '|', ('case_default', '=', True), ('section_ids', '=', section_id), '|', ('type', '=', type), ('type', '=', 'both')]"
on_change="onchange_stage_id(stage_id)"/> on_change="onchange_stage_id(stage_id)"/>
@ -140,12 +142,6 @@
<field name="phone"/> <field name="phone"/>
<field name="mobile"/> <field name="mobile"/>
<field name="fax"/> <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>
<group> <group>
<field name="user_id" on_change="on_change_user(user_id, context)" <field name="user_id" on_change="on_change_user(user_id, context)"
@ -155,7 +151,7 @@
<field name="section_id"/> <field name="section_id"/>
<button name="case_escalate" string="Escalate" <button name="case_escalate" string="Escalate"
type="object" class="oe_link" type="object" class="oe_link"
attrs="{'invisible': ['|', ('section_id','=',False), ('state', 'not in', ['draft','open','pending'])]}"/> attrs="{'invisible': ['|', ('section_id','=',False), ('probability', '=', 100)]}"/>
</div> </div>
<field name="type" invisible="1"/> <field name="type" invisible="1"/>
</group> </group>
@ -173,20 +169,24 @@
<field name="description"/> <field name="description"/>
</page> </page>
<page string="Extra Info"> <page string="Extra Info">
<group> <group string="Categorization" groups="base.group_multi_company,base.group_no_one" name="categorization">
<group string="Categorization" groups="base.group_multi_company,base.group_no_one" name="categorization"> <field name="company_id"
<field name="company_id" groups="base.group_multi_company"
groups="base.group_multi_company" widget="selection" colspan="2"/>
widget="selection" colspan="2"/> </group>
<field name="state" groups="base.group_no_one"/> <group string="Mailings">
</group> <field name="opt_out"/>
<group string="Mailings"> </group>
<field name="opt_out"/> <group string="Misc">
</group> <group>
<group string="Misc"> <field name="probability" groups="base.group_no_one"/>
<field name="active"/> <field name="active"/>
<field name="referred"/> <field name="referred"/>
</group> </group>
<group>
<field name="date_open" groups="base.group_no_one"/>
<field name="date_closed" groups="base.group_no_one"/>
</group>
</group> </group>
</page> </page>
</notebook> </notebook>
@ -216,7 +216,7 @@
<field name="name">Leads</field> <field name="name">Leads</field>
<field name="model">crm.lead</field> <field name="model">crm.lead</field>
<field name="arch" type="xml"> <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="date_deadline" invisible="1"/>
<field name="create_date"/> <field name="create_date"/>
<field name="name"/> <field name="name"/>
@ -228,7 +228,7 @@
<field name="user_id" invisible="1"/> <field name="user_id" invisible="1"/>
<field name="partner_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="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="type_id" invisible="1"/>
<field name="referred" invisible="1"/> <field name="referred" invisible="1"/>
<field name="channel_id" invisible="1"/> <field name="channel_id" invisible="1"/>
@ -331,16 +331,17 @@
<field name="create_date"/> <field name="create_date"/>
<field name="country_id" context="{'invisible_country': False}"/> <field name="country_id" context="{'invisible_country': False}"/>
<separator/> <separator/>
<filter string="Open" name="open" domain="[('state','!=','cancel')]" help="Open Leads"/> <filter string="Unassigned" name="unassigned"
<filter string="Dead" name="dead" domain="[('state','=','cancel')]"/> domain="[('user_id','=', False)]"
<filter string="Unassigned" name="unassigned" domain="[('user_id','=', False)]" help="No salesperson"/> help="No salesperson"/>
<filter string="Unread Messages" name="message_unread" domain="[('message_unread','=',True)]" help="Unread messages"/>
<filter string="Assigned to Me" <filter string="Assigned to Me"
domain="[('user_id','=',uid)]" context="{'invisible_section': False}" domain="[('user_id','=',uid)]" context="{'invisible_section': False}"
help="Leads that are assigned to me"/> 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}" 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 /> <separator />
<filter string="Available for mass mailing" <filter string="Available for mass mailing"
name='not_opt_out' domain="[('opt_out', '=', False)]" name='not_opt_out' domain="[('opt_out', '=', False)]"
@ -378,20 +379,18 @@
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="Opportunities" version="7.0"> <form string="Opportunities" version="7.0">
<header> <header>
<button name="case_mark_won" string="Mark Won" type="object" <button name="case_mark_won" string="Mark Won" type="object" class="oe_highlight"
states="draft,open,pending" class="oe_highlight"/> attrs="{'invisible': [('probability', '=', 100)]}"/>
<button name="case_mark_lost" string="Mark Lost" type="object" <button name="case_mark_lost" string="Mark Lost" type="object" class="oe_highlight"/>
states="draft,open" class="oe_highlight"/> <field name="stage_id" widget="statusbar" clickable="True"
<field name="stage_id" widget="statusbar" clickable="True"/> domain="['&amp;', ('section_ids', '=', section_id), '|', ('type', '=', type), ('type', '=', 'both')]"/>
</header> </header>
<sheet> <sheet>
<div class="oe_right oe_button_box"> <div class="oe_right oe_button_box">
<button string="Schedule/Log Call" <button string="Schedule/Log Call" type="action"
name="%(opportunity2phonecall_act)d" name="%(opportunity2phonecall_act)d"/>
type="action"/> <button string="Meeting" type="object"
<button string="Meeting"
name="action_makeMeeting" name="action_makeMeeting"
type="object"
context="{'search_default_attendee_id': active_id, 'default_attendee_id' : active_id}"/> context="{'search_default_attendee_id': active_id, 'default_attendee_id' : active_id}"/>
</div> </div>
<div class="oe_title"> <div class="oe_title">
@ -430,7 +429,8 @@
<label for="section_id" groups="base.group_multi_salesteams"/> <label for="section_id" groups="base.group_multi_salesteams"/>
<div groups="base.group_multi_salesteams"> <div groups="base.group_multi_salesteams">
<field name="section_id" widget="selection"/> <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> </div>
</group> </group>
<group> <group>
@ -511,7 +511,7 @@
<field name="name">Opportunities Tree</field> <field name="name">Opportunities Tree</field>
<field name="model">crm.lead</field> <field name="model">crm.lead</field>
<field name="arch" type="xml"> <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="date_deadline" invisible="1"/>
<field name="create_date"/> <field name="create_date"/>
<field name="name" string="Opportunity"/> <field name="name" string="Opportunity"/>
@ -529,7 +529,8 @@
<field name="referred" invisible="1"/> <field name="referred" invisible="1"/>
<field name="priority" invisible="1"/> <field name="priority" invisible="1"/>
<field name="message_unread" 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> </tree>
</field> </field>
</record> </record>
@ -546,15 +547,19 @@
<field name="section_id" context="{'invisible_section': False}" groups="base.group_multi_salesteams"/> <field name="section_id" context="{'invisible_section': False}" groups="base.group_multi_salesteams"/>
<field name="user_id"/> <field name="user_id"/>
<field name="partner_id" filter_domain="[('partner_id','child_of',self)]"/> <field name="partner_id" filter_domain="[('partner_id','child_of',self)]"/>
<field name="stage_id"/>
<field name="probability"/>
<separator/> <separator/>
<filter string="New" name="new" domain="[('state','=','draft')]" help="New Opportunities"/> <filter string="New" name="new"
<filter string="In Progress" name="open" domain="[('state','=','open')]" help="Open Opportunities"/> domain="[('probability', '=', 0), ('stage_id.sequence', '=', 1)]"/>
<filter string="Won" name="won" domain="[('state','=','done')]"/> <filter string="Won" name="won"
<filter string="Lost" name="lost" domain="[('state','=','cancel')]"/> domain="[('probability', '=', 100), ('stage_id.on_change', '=', 1)]"/>
<filter string="Unassigned" name="unassigned" domain="[('user_id','=', False)]" help="No salesperson"/> <filter string="Lost" name="lost"
<filter string="Unread Messages" name="message_unread" domain="[('message_unread','=',True)]" help="Unread messages"/> 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" <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"/> help="Opportunities that are assigned to me"/>
<filter string="Assigned to My Team(s)" <filter string="Assigned to My Team(s)"
domain="[('section_id.member_ids', 'in', [uid])]" context="{'invisible_section': False}" 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="Campaign" domain="[]" context="{'group_by':'type_id'}"/>
<filter string="Channel" domain="[]" context="{'group_by':'channel_id'}"/> <filter string="Channel" domain="[]" context="{'group_by':'channel_id'}"/>
<filter string="Creation" domain="[]" context="{'group_by':'create_date'}"/> <filter string="Creation" domain="[]" context="{'group_by':'create_date'}"/>
<filter string="Last Update Month" domain="[]" context="{'group_by':'write_date'}"/>
</group> </group>
<group string="Display"> <group string="Display">
<filter string="Show Sales Team" context="{'invisible_section': False}" domain="[]" help="Show Sales Team" groups="base.group_multi_salesteams"/> <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="sequence" widget="handle"/>
<field name="name"/> <field name="name"/>
<field name="probability"/> <field name="probability"/>
<field name="state"/>
<field name="type"/> <field name="type"/>
</tree> </tree>
</field> </field>
@ -96,7 +95,6 @@
<form string="Stage" version="7.0"> <form string="Stage" version="7.0">
<group col="4"> <group col="4">
<field name="name"/> <field name="name"/>
<field name="state"/>
<field name="probability"/> <field name="probability"/>
<field name="type"/> <field name="type"/>
<field name="on_change"/> <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 openerp import tools
from .. import crm from openerp.addons.crm import crm
AVAILABLE_STATES = [
('draft','Draft'),
('open','Open'),
('cancel', 'Cancelled'),
('done', 'Closed'),
('pending','Pending')
]
MONTHS = [ MONTHS = [
('01', 'January'), ('01', 'January'),
@ -70,7 +62,7 @@ class crm_lead_report(osv.osv):
'date_closed': fields.date('Close Date', readonly=True), 'date_closed': fields.date('Close Date', readonly=True),
# durations # 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_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"), '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), 'section_id':fields.many2one('crm.case.section', 'Sales Team', readonly=True),
'channel_id':fields.many2one('crm.case.channel', 'Channel', readonly=True), 'channel_id':fields.many2one('crm.case.channel', 'Channel', readonly=True),
'type_id':fields.many2one('crm.case.resource.type', 'Campaign', 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), 'company_id': fields.many2one('res.company', 'Company', readonly=True),
'probability': fields.float('Probability',digits=(16,2),readonly=True, group_operator="avg"), 'probability': fields.float('Probability',digits=(16,2),readonly=True, group_operator="avg"),
'planned_revenue': fields.float('Planned Revenue',digits=(16,2),readonly=True), 'planned_revenue': fields.float('Planned Revenue',digits=(16,2),readonly=True),
@ -94,10 +85,7 @@ class crm_lead_report(osv.osv):
('opportunity','Opportunity'), ('opportunity','Opportunity'),
],'Type', help="Type is used to separate Leads and Opportunities"), ],'Type', help="Type is used to separate Leads and Opportunities"),
} }
def init(self, cr): 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_open, 'YYYY-MM-DD') as opening_date,
to_char(c.date_closed, 'YYYY-mm-dd') as date_closed, to_char(c.date_closed, 'YYYY-mm-dd') as date_closed,
c.state,
c.user_id, c.user_id,
c.probability, c.probability,
c.stage_id, 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" 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"/> <filter icon="terp-personal+" string="Opportunity" name="opportunity" domain="[('type','=','opportunity')]" help="Show only opportunity"/>
<separator/> <separator/>
<filter icon="terp-check" string="New" domain="[('state','=','draft')]" help="Leads/Opportunities which are in New state"/> <filter string="New" name="new"
<filter icon="terp-camera_test" string="Open" domain="[('state','=','open')]" help="Leads/Opportunities which are in open state"/> domain="[('probability', '=', 0), ('stage_id.sequence', '=', 1)]"/>
<filter icon="gtk-media-pause" string="Pending" domain="[('state','=','pending')]" help="Leads/Opportunities which are in pending state"/> <filter string="Won" name="won"
<filter icon="terp-dialog-close" string="Closed" domain="[('state','=','done')]" help="Leads/Opportunities which are in done state"/> domain="[('probability', '=', 100), ('stage_id.on_change', '=', 1)]"/>
<filter string="Lost" name="lost"
domain="[('probability', '=', 0), ('stage_id.sequence', '!=', 1)]"/>
<separator/> <separator/>
<filter string="My Sales Team(s)" icon="terp-personal+" context="{'invisible_section': False}" domain="[('section_id.user_id','=',uid)]" <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"/> 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="name">crm.lead.report.tree</field>
<field name="model">crm.lead.report</field> <field name="model">crm.lead.report</field>
<field name="arch" type="xml"> <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_year" invisible="1"/>
<field name="creation_month" invisible="1"/> <field name="creation_month" invisible="1"/>
<field name="creation_day" invisible="1"/> <field name="creation_day" invisible="1"/>
@ -141,7 +143,6 @@
<field name="user_id" invisible="1"/> <field name="user_id" invisible="1"/>
<field name="partner_id" invisible="1"/> <field name="partner_id" invisible="1"/>
<field name="country_id" invisible="1"/> <field name="country_id" invisible="1"/>
<field name="state" invisible="1"/>
<field name="stage_id" invisible="1"/> <field name="stage_id" invisible="1"/>
<field name="priority" invisible="1"/> <field name="priority" invisible="1"/>
<field name="type_id" 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="company_id" invisible="1" groups="base.group_multi_company"/>
<field name="nbr" string="#Opportunities" sum="#Opportunities"/> <field name="nbr" string="#Opportunities" sum="#Opportunities"/>
<field name="planned_revenue" sum="Planned Revenues"/> <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_close" sum='Delay to close'/>
<field name="delay_expected"/> <field name="delay_expected"/>
<field name="probability" widget="progressbar"/> <field name="probability" widget="progressbar"/>

View File

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

View File

@ -23,7 +23,7 @@
<field name="nbr" string="#Phone calls" sum="#Phone calls"/> <field name="nbr" string="#Phone calls" sum="#Phone calls"/>
<field name="duration" avg="Duration"/> <field name="duration" avg="Duration"/>
<field name="delay_close" avg="Avg Closing Delay"/> <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> </tree>
</field> </field>
</record> </record>

View File

@ -41,7 +41,7 @@ class res_partner(osv.osv):
_columns = { _columns = {
'section_id': fields.many2one('crm.case.section', 'Sales Team'), 'section_id': fields.many2one('crm.case.section', 'Sales Team'),
'opportunity_ids': fields.one2many('crm.lead', 'partner_id',\ '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', 'meeting_ids': fields.many2many('crm.meeting', 'crm_meeting_partner_rel','partner_id', 'meeting_id',
'Meetings'), 'Meetings'),
'phonecall_ids': fields.one2many('crm.phonecall', 'partner_id',\ 'phonecall_ids': fields.one2many('crm.phonecall', 'partner_id',\
@ -87,7 +87,6 @@ class res_partner(osv.osv):
'probability' : probability, 'probability' : probability,
'partner_id' : partner_id, 'partner_id' : partner_id,
'categ_ids' : categ_ids and categ_ids[0:1] or [], 'categ_ids' : categ_ids and categ_ids[0:1] or [],
'state' :'draft',
'type': 'opportunity' 'type': 'opportunity'
}, context=context) }, context=context)
opportunity_ids[partner_id] = opportunity_id 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}: | !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")}) 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}) 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. 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. 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}: !record {model: crm.lead, id: test_crm_opp_1}:
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}:
type: 'opportunity' type: 'opportunity'
name: 'Test opportunity 1' name: 'Test opportunity 1'
partner_id: base.res_partner_5 partner_id: base.res_partner_5
stage_id: stage_lead1 stage_id: stage_lead1
description: This is the description of the test opp 1. 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}: | !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]}) 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. 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}: | !python {model: crm.lead}: |
merge_id = self.search(cr, uid, [('name', '=', 'Test opportunity 1'), ('partner_id','=', ref("base.res_partner_5"))]) 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' assert merge_id, 'Fail to create merge opportunity wizard'
merge_result = self.browse(cr, uid, merge_id)[0] 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 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. The other (tailing) leads/opps shouldn't exist anymore.
- -
!python {model: crm.lead}: | !python {model: crm.lead}: |
tailing_lead = self.search(cr, uid, [('id', '=', ref('test_crm_lead_01'))]) 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_02') 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') 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). 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.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 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'))]) 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 partner_id: base.res_partner_2
type: opportunity type: opportunity
stage_id: crm.stage_lead1 stage_id: crm.stage_lead1
state: draft
- -
I create a lead record to call a mailing opt-out onchange method. I create a lead record to call a mailing opt-out onchange method.
- -
!record {model: crm.lead, id: crm_case_18}: !record {model: crm.lead, id: crm_case_18}:
name: 'Need 20 Days of Consultancy' name: 'Need 20 Days of Consultancy'
type: opportunity type: opportunity
state: draft stage_id: crm.stage_lead1
opt_out: True opt_out: True
- -
I create a phonecall record to call a partner onchange method. 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, 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. I convert lead into opportunity for exiting customer.
- -
!python {model: crm.lead}: | !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. I check details of converted opportunity.
- -
!python {model: crm.lead}: | !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.type == 'opportunity', 'Lead is not converted to opportunity!'
assert lead.partner_id.id == ref("base.res_partner_2"), 'Partner mismatch!' 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!' assert lead.stage_id.id == ref("stage_lead1"), 'Stage of opportunity is incorrect!'
@ -18,7 +28,7 @@
- -
!python {model: crm.opportunity2phonecall}: | !python {model: crm.opportunity2phonecall}: |
import time 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'), 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) '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) self.action_schedule(cr, uid, [call_id], context=context)
@ -26,46 +36,46 @@
I check that phonecall is scheduled for that opportunity. I check that phonecall is scheduled for that opportunity.
- -
!python {model: crm.phonecall}: | !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' assert len(ids), 'Phonecall is not scheduled'
- -
Now I schedule meeting with customer. Now I schedule meeting with customer.
- -
!python {model: crm.lead}: | !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. After communicated with customer, I put some notes with contract details.
- -
!python {model: crm.lead}: | !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 I win this opportunity
- -
!python {model: crm.lead}: | !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. I check details of the opportunity after having won the opportunity.
- -
!python {model: crm.lead}: | !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.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!" assert lead.probability == 100.0, "Revenue probability should be 100.0!"
- -
I convert mass lead into opportunity customer. I convert mass lead into opportunity customer.
- -
!python {model: crm.lead2opportunity.partner.mass}: | !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) 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) self.mass_convert(cr, uid, [id], context=context)
- -
Now I check first lead converted on opportunity. Now I check first lead converted on opportunity.
- -
!python {model: crm.lead}: | !python {model: crm.lead}: |
opp = self.browse(cr, uid, ref('crm_case_11')) opp = self.browse(cr, uid, ref('crm_case_13'))
assert opp.name == "Need estimated cost for new project", "Opportunity name not correct" assert opp.name == "Plan to buy 60 keyboards and mouses", "Opportunity name not correct"
assert opp.type == 'opportunity', 'Lead is not converted to opportunity!' 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.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!' assert opp.stage_id.id == ref("stage_lead1"), 'Stage of probability is incorrect!'
- -
@ -86,14 +96,15 @@
- -
!python {model: crm.lead}: | !python {model: crm.lead}: |
lead = self.browse(cr, uid, ref('crm_case_2')) 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.stage_id.id == ref('crm.stage_lead7'), "Opportunity stage should be 'Lost'."
assert lead.state == 'cancel', "Lost opportunity is not in 'cancel' state!" 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!" assert lead.probability == 0.0, "Revenue probability should be 0.0!"
- -
I confirm review needs meeting. I confirm review needs meeting.
- -
!python {model: crm.meeting}: | !python {model: crm.meeting}: |
context.update({'active_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. I invite a user for meeting.
- -

View File

@ -21,7 +21,6 @@
from openerp.osv import fields, osv from openerp.osv import fields, osv
from openerp.tools.translate import _ from openerp.tools.translate import _
from openerp import tools
import re import re
class crm_lead2opportunity_partner(osv.osv_memory): class crm_lead2opportunity_partner(osv.osv_memory):
@ -58,11 +57,11 @@ class crm_lead2opportunity_partner(osv.osv_memory):
if partner_id: if partner_id:
# Search for opportunities that have the same partner and that arent done or cancelled # 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: for id in ids:
tomerge.add(id) tomerge.add(id)
if email: 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: for id in ids:
tomerge.add(id) tomerge.add(id)
@ -85,8 +84,8 @@ class crm_lead2opportunity_partner(osv.osv_memory):
context = {} context = {}
lead_obj = self.pool.get('crm.lead') lead_obj = self.pool.get('crm.lead')
for lead in lead_obj.browse(cr, uid, context.get('active_ids', []), context=context): for lead in lead_obj.browse(cr, uid, context.get('active_ids', []), context=context):
if lead.state in ['done', 'cancel']: if lead.probability == 100:
raise osv.except_osv(_("Warning!"), _("Closed/Cancelled leads cannot be converted into opportunities.")) raise osv.except_osv(_("Warning!"), _("Closed/Dead leads cannot be converted into opportunities."))
return False return False
def _convert_opportunity(self, cr, uid, ids, vals, context=None): 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): def default_get(self, cr, uid, fields, context=None):
""" """
Use active_ids from the context to fetch the leads/opps to merge. 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 In order to get merged, these leads/opps can't be in 'Dead' or 'Closed'
'Cancel' state.
""" """
if context is None: if context is None:
context = {} context = {}
@ -72,7 +71,7 @@ class crm_merge_opportunity(osv.osv_memory):
opp_ids = [] opp_ids = []
opps = self.pool.get('crm.lead').browse(cr, uid, record_ids, context=context) opps = self.pool.get('crm.lead').browse(cr, uid, record_ids, context=context)
for opp in opps: for opp in opps:
if opp.state not in ('done', 'cancel'): if opp.probability < 100:
opp_ids.append(opp.id) opp_ids.append(opp.id)
if 'opportunity_ids' in fields: if 'opportunity_ids' in fields:
res.update({'opportunity_ids': opp_ids}) res.update({'opportunity_ids': opp_ids})