[IMP] crm: clean test cases, APIs of crm.lead, crm.phonecall

bzr revid: hmo@tinyerp.com-20111024133010-ve55lvg2cie206l9
This commit is contained in:
Harry (OpenERP) 2011-10-24 19:00:10 +05:30
parent d5239a04f2
commit 340c9c5576
26 changed files with 535 additions and 748 deletions

View File

@ -119,17 +119,11 @@ Creates a dashboard for CRM that includes:
'crm_phonecall_demo.xml',
],
'test': [
'test/process/draft2open_lead.yml',
'test/process/communication_with_customer.yml',
'test/process/lead2opportunity2win.yml',
'test/process/merge_opportunity.yml',
'test/process/partner2opportunity.yml',
'test/process/cancel_lead.yml',
'test/process/meeting.yml',
'test/process/mass_leads2opportunity.yml',
'test/ui/lead_form.yml',
'test/process/phone-call2opportunity.yml',
'test/process/phone-call2meeting.yml',
'test/process/schedule_other_phone-call.yml'
],
'installable': True,
'active': False,

View File

@ -27,7 +27,7 @@ from tools.translate import _
from crm import crm_case
import binascii
import tools
from mail.mail_message import to_email
CRM_LEAD_PENDING_STATES = (
crm.AVAILABLE_STATES[2][0], # Cancelled
@ -351,7 +351,7 @@ class crm_lead(crm_case, osv.osv):
return res and res.id or False
def _concat_all(attr):
return ', '.join([getattr(opportunity, attr) for opportunity in opportunities if hasattr(opportunity, attr)])
return ', '.join([getattr(opportunity, attr) or '' for opportunity in opportunities if hasattr(opportunity, attr)])
data = {
'partner_id': _get_first_not_null_id('partner_id'), # !!
@ -392,11 +392,12 @@ class crm_lead(crm_case, osv.osv):
def _merge_find_oldest(self, cr, uid, ids, context=None):
if context is None:
context = {}
#TOCHECK: where pass 'convert' in context ?
if context.get('convert'):
ids = list(set(ids) - set(context.get('lead_ids', False)) )
#search opportunities order by create date
opportunity_ids = lead_obj.search(cr, uid, [('id', 'in', ids)], order='create_date' , context=context)
opportunity_ids = self.search(cr, uid, [('id', 'in', ids)], order='create_date' , context=context)
oldest_id = opportunity_ids[0]
return self.browse(cr, uid, oldest_id, context=context)
@ -481,11 +482,12 @@ class crm_lead(crm_case, osv.osv):
if len(ids) <= 1:
raise osv.except_osv(_('Warning !'),_('Please select more than one opportunities.'))
opportunities = self.browse(cr, uid, lead_ids, context=context)
opportunities_list = list(set(ids) - set(opportunities))
oldest = self._find_oldest_opportunity(cr, uid, ids, context=context)
if opportunities :
first_opportunity = opportunities[0]
ctx_opportunities = self.browse(cr, uid, lead_ids, context=context)
opportunities = self.browse(cr, uid, ids, context=context)
opportunities_list = list(set(opportunities) - set(ctx_opportunities))
oldest = self._merge_find_oldest(cr, uid, ids, context=context)
if ctx_opportunities :
first_opportunity = ctx_opportunities[0]
tail_opportunities = opportunities_list
else:
first_opportunity = opportunities_list[0]
@ -507,13 +509,16 @@ class crm_lead(crm_case, osv.osv):
return first_opportunity.id
def _convert_opportunity_data(self, lead):
def _convert_opportunity_data(self, cr, uid, lead, customer, section_id=False, context=None):
crm_stage = self.pool.get('crm.case.stage')
if lead.section_id:
stage_ids = crm_stage.search(cr, uid, [('sequence','>=',1), ('section_ids','=', lead.section_id.id)])
contact_id = self.pool.get('res.partner').address_get(cr, uid, [customer.id])['default']
if not section_id:
section_id = lead.section_id and lead.section_id.id or False
if section_id:
stage_ids = crm_stage.search(cr, uid, [('sequence','>=',1), ('section_ids','=', section_id)])
else:
stage_ids = crm_stage.search(cr, uid, [('sequence','>=',1)])
stage_ids = crm_stage.search(cr, uid, [('sequence','>=',1)])
stage_id = stage_ids and stage_ids[0] or False
return {
'planned_revenue': lead.planned_revenue,
'probability': lead.probability,
@ -521,25 +526,32 @@ class crm_lead(crm_case, osv.osv):
'partner_id': customer.id,
'user_id': (lead.user_id and lead.user_id.id),
'type': 'opportunity',
'stage_id': stage_ids and stage_ids[0] or False,
'stage_id': stage_id or False,
'date_action': time.strftime('%Y-%m-%d %H:%M:%S'),
'partner_address_id': len(customer.address_id) and customer.address_id[0] or False
'partner_address_id': contact_id
}
def _convert_opportunity_notification(self, cr, uid, lead, context=context):
def _convert_opportunity_notification(self, cr, uid, lead, context=None):
success_message = _("Lead '%s' has been converted to an opportunity.") % lead.name
self.message_append(cr, uid, [lead.id], success_message, body_text=success_message, context=context)
self.log(cr, uid, [lead.id], success_message)
self.log(cr, uid, lead.id, success_message)
self._send_mail_to_salesman(cr, uid, lead, context=context)
return True
def convert_opportunity(self, cr, uid, ids, partner_id, mass_convert=False, merge=False, context=None):
def convert_opportunity(self, cr, uid, ids, partner_id, user_ids=False, section_id=False, context=None):
partner = self.pool.get('res.partner')
mail_message = self.pool.get('mail.message')
customer = partner.browse(cr, uid, partner_id, context=context)
for lead in self.browse(cr, uid, ids, context=context):
vals = self._convert_opportunity_data(lead)
if lead.state in ('done', 'cancel'):
continue
if user_ids or section_id:
self.allocate_salesman(cr, uid, [lead.id], user_ids, section_id, context=context)
vals = self._convert_opportunity_data(cr, uid, lead, customer, section_id, context=context)
self.write(cr, uid, [lead.id], vals, context=context)
self._convert_opportunity_notification(cr, uid, lead, context=context)
#TOCHECK: why need to change partner details in all messages of lead ?
if lead.partner_id:
@ -547,7 +559,7 @@ class crm_lead(crm_case, osv.osv):
mail_message.write(cr, uid, msg_ids, {
'partner_id': lead.partner_id.id
}, context=context)
return True
return True
def _lead_create_partner(self, cr, uid, lead, context=None):
partner = self.pool.get('res.partner')
@ -560,7 +572,8 @@ class crm_lead(crm_case, osv.osv):
return partner_id
def _lead_assign_partner(self, cr, uid, ids, partner_id, context=None):
return self.write(cr, uid, ids, {'partner_id' : partner_id}, context=context)
contact_id = self.pool.get('res.partner').address_get(cr, uid, [partner_id])['default']
return self.write(cr, uid, ids, {'partner_id' : partner_id, 'partner_address_id': contact_id}, context=context)
def _lead_create_partner_address(self, cr, uid, lead, partner_id, context=None):
address = self.pool.get('res.partner.address')
@ -569,7 +582,7 @@ class crm_lead(crm_case, osv.osv):
'name': lead.contact_name,
'phone': lead.phone,
'mobile': lead.mobile,
'email': lead.email_from,
'email': to_email(lead.email_from)[0],
'fax': lead.fax,
'title': lead.title and lead.title.id or False,
'function': lead.function,
@ -581,7 +594,7 @@ class crm_lead(crm_case, osv.osv):
'state_id': lead.state_id and lead.state_id.id or False,
})
def convert_partner(self, cr, uid, ids, action='new', partner_id=False, context=None):
def convert_partner(self, cr, uid, ids, action='create', partner_id=False, context=None):
"""
This function convert partner based on action.
if action is 'new', create new partner with contact and assign lead to new partner_id.
@ -589,12 +602,15 @@ class crm_lead(crm_case, osv.osv):
"""
if context is None:
context = {}
partner_ids = []
partner_ids = {}
for lead in self.browse(cr, uid, ids, context=context):
if action == 'create':
partner_id = self._lead_create_partner(cr, uid, lead, context=context)
partner_id = lead.partner_id and lead.partner_id.id or False
if action == 'create':
if not partner_id:
partner_id = self._lead_create_partner(cr, uid, lead, context=context)
self._lead_create_partner_address(cr, uid, lead, partner_id, context=context)
self._lead_assign_partner(cr, uid, [lead.id], partner_id, context=context)
partner_ids.append(partner_id)
partner_ids[lead.id] = partner_id
return partner_ids
def _send_mail_to_salesman(self, cr, uid, lead, context=None):
@ -628,6 +644,45 @@ class crm_lead(crm_case, osv.osv):
self.write(cr, uid, [lead_id], value, context=context)
return True
def schedule_phonecall(self, cr, uid, ids, schedule_time, call_summary, user_id=False, section_id=False, categ_id=False, action='schedule', context=None):
"""
action :('schedule','Schedule a call'), ('log','Log a call')
"""
phonecall = self.pool.get('crm.phonecall')
model_data = self.pool.get('ir.model.data')
phonecall_dict = {}
if not categ_id:
res_id = model_data._get_id(cr, uid, 'crm', 'categ_phone2')
if res_id:
categ_id = model_data.browse(cr, uid, res_id, context=context).res_id
for lead in self.browse(cr, uid, ids, context=context):
if not section_id:
section_id = lead.section_id and lead.section_id.id or False
if not user_id:
user_id = lead.user_id and lead.user_id.id or False
vals = {
'name' : call_summary,
'opportunity_id' : lead.id,
'user_id' : user_id or False,
'categ_id' : categ_id or False,
'description' : lead.description or False,
'date' : schedule_time,
'section_id' : section_id or False,
'partner_id': lead.partner_id and lead.partner_id.id or False,
'partner_address_id': lead.partner_address_id and lead.partner_address_id.id or False,
'partner_phone' : lead.phone or (lead.partner_address_id and lead.partner_address_id.phone or False),
'partner_mobile' : lead.partner_address_id and lead.partner_address_id.mobile or False,
'priority': lead.priority,
}
new_id = phonecall.create(cr, uid, vals, context=context)
phonecall.case_open(cr, uid, [new_id])
if action == 'log':
phonecall.case_close(cr, uid, [new_id])
phonecall_dict[lead.id] = new_id
return phonecall_dict
def redirect_opportunity_view(self, cr, uid, opportunity_id, context=None):
models_data = self.pool.get('ir.model.data')

View File

@ -102,11 +102,6 @@ class crm_phonecall(crm_base, osv.osv):
def case_close(self, cr, uid, ids, *args):
"""Overrides close for crm_case for setting close date
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of case Ids
@param *args: Tuple Value for additional Params
"""
res = True
for phone in self.browse(cr, uid, ids):
@ -121,11 +116,6 @@ class crm_phonecall(crm_base, osv.osv):
def case_reset(self, cr, uid, ids, *args):
"""Resets case as Todo
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of case Ids
@param *args: Tuple Value for additional Params
"""
res = super(crm_phonecall, self).case_reset(cr, uid, ids, args, 'crm.phonecall')
self.write(cr, uid, ids, {'duration': 0.0})
@ -134,25 +124,155 @@ class crm_phonecall(crm_base, osv.osv):
def case_open(self, cr, uid, ids, *args):
"""Overrides cancel for crm_case for setting Open Date
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of case's Ids
@param *args: Give Tuple Value
"""
res = super(crm_phonecall, self).case_open(cr, uid, ids, *args)
self.write(cr, uid, ids, {'date_open': time.strftime('%Y-%m-%d %H:%M:%S')})
return res
def schedule_another_phonecall(self, cr, uid, ids, schedule_time, call_summary, \
user_id=False, section_id=False, categ_id=False, action='schedule', context=None):
"""
action :('schedule','Schedule a call'), ('log','Log a call')
"""
model_data = self.pool.get('ir.model.data')
phonecall_dict = {}
if not categ_id:
res_id = model_data._get_id(cr, uid, 'crm', 'categ_phone2')
if res_id:
categ_id = model_data.browse(cr, uid, res_id, context=context).res_id
for call in self.browse(cr, uid, ids, context=context):
if not section_id:
section_id = call.section_id and call.section_id.id or False
if not user_id:
user_id = call.user_id and call.user_id.id or False
vals = {
'name' : call_summary,
'user_id' : user_id or False,
'categ_id' : categ_id or False,
'description' : call.description or False,
'date' : schedule_time,
'section_id' : section_id or False,
'partner_id': call.partner_id and call.partner_id.id or False,
'partner_address_id': call.partner_address_id and call.partner_address_id.id or False,
'partner_phone' : call.partner_phone,
'partner_mobile' : call.partner_mobile,
'priority': call.priority,
}
new_id = self.create(cr, uid, vals, context=context)
self.case_open(cr, uid, [new_id])
if action == 'log':
self.case_close(cr, uid, [new_id])
phonecall_dict[call.id] = new_id
return phonecall_dict
def _call_create_partner(self, cr, uid, phonecall, context=None):
partner = self.pool.get('res.partner')
partner_id = partner.create(cr, uid, {
'name': phonecall.name,
'user_id': phonecall.user_id.id,
'comment': phonecall.description,
'address': []
})
return partner_id
def _call_assign_partner(self, cr, uid, ids, partner_id, context=None):
return self.write(cr, uid, ids, {'partner_id' : partner_id}, context=context)
def _call_create_partner_address(self, cr, uid, phonecall, partner_id, context=None):
address = self.pool.get('res.partner.address')
return address.create(cr, uid, {
'partner_id': partner_id,
'name': phonecall.name,
'phone': phonecall.partner_phone,
})
def convert_partner(self, cr, uid, ids, action='new', partner_id=False, context=None):
"""
This function convert partner based on action.
if action is 'create', create new partner with contact and assign lead to new partner_id.
otherwise assign lead to specified partner_id
"""
if context is None:
context = {}
partner_ids = {}
for call in self.browse(cr, uid, ids, context=context):
partner_id = call.partner_id and call.partner_id.id or False
if action == 'create':
if not partner_id:
partner_id = self._call_create_partner(cr, uid, call, context=context)
self._call_create_partner_address(cr, uid, call, partner_id, context=context)
self._call_assign_partner(cr, uid, [call.id], partner_id, context=context)
partner_ids[call.id] = partner_id
return partner_ids
def redirect_phonecall_view(self, cr, uid, phonecall_id, context=None):
model_data = self.pool.get('ir.model.data')
# Select the view
id2 = model_data._get_id(cr, uid, 'crm', 'crm_case_phone_tree_view')
id3 = model_data._get_id(cr, uid, 'crm', 'crm_case_phone_form_view')
if id2:
id2 = model_data.browse(cr, uid, id2, context=context).res_id
if id3:
id3 = model_data.browse(cr, uid, id3, context=context).res_id
result = model_data._get_id(cr, uid, 'crm', 'view_crm_case_phonecalls_filter')
res = model_data.read(cr, uid, result, ['res_id'])
value = {
'name': _('Phone Call'),
'view_type': 'form',
'view_mode': 'tree,form',
'res_model': 'crm.phonecall',
'res_id' : int(phonecall_id),
'views': [(id3, 'form'), (id2, 'tree'), (False, 'calendar')],
'type': 'ir.actions.act_window',
'search_view_id': res['res_id'],
}
return value
def convert_opportunity(self, cr, uid, ids, opportunity_summary=False, partner_id=False, planned_revenue=0.0, probability=0.0, context=None):
partner = self.pool.get('res.partner')
address = self.pool.get('res.partner.address')
opportunity = self.pool.get('crm.lead')
opportunity_dict = {}
for call in self.browse(cr, uid, ids, context=context):
if not partner_id:
partner_id = call.partner_id and call.partner_id.id or False
if partner_id:
address_id = partner.address_get(cr, uid, [partner_id])['default']
if address_id:
default_contact = address.browse(cr, uid, address_id, context=context)
opportunity_id = opportunity.create(cr, uid, {
'name': opportunity_summary or call.name,
'planned_revenue': planned_revenue,
'probability': probability,
'partner_id': partner_id or False,
'partner_address_id': default_contact and default_contact.id,
'phone': default_contact and default_contact.phone,
'mobile': default_contact and default_contact.mobile,
'section_id': call.section_id and call.section_id.id or False,
'description': call.description or False,
'phonecall_id': call.id,
'priority': call.priority,
'type': 'opportunity',
'phone': call.partner_phone or False,
})
vals = {
'partner_id': partner_id,
'opportunity_id' : opportunity_id,
}
self.write(cr, uid, [call.id], vals)
self.case_close(cr, uid, [call.id])
opportunity.case_open(cr, uid, [opportunity_id])
opportunity_dict[call.id] = opportunity_id
return opportunity_dict
def action_make_meeting(self, cr, uid, ids, context=None):
"""
This opens Meeting's calendar view to schedule meeting on current Phonecall
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of Phonecall to Meeting IDs
@param context: A standard dictionary for contextual values
@return : Dictionary value for created Meeting view
"""
value = {}

View File

@ -83,9 +83,6 @@
<field eval="2.08" name="duration"/>
</record>
<record id="crm_case_phone06" model="crm.phonecall">
<field name="partner_address_id" ref="base.res_partner_address_1"/>
<field eval="1" name="active"/>
<field name="partner_id" ref="base.res_partner_9"/>
<field eval="&quot;3&quot;" name="priority"/>
<field name="user_id" ref="base.user_root"/>
<field eval="&quot;Bad time&quot;" name="name"/>

View File

@ -34,27 +34,45 @@ class res_partner(osv.osv):
'Phonecalls'),
}
def make_opportunity(self, cr, uid, ids, opportunity, planned_revenue=0.0, probability=0.0, partner_id=None, context=None):
def redirect_partner_form(self, cr, uid, partner_id, context=None):
model_data = self.pool.get('ir.model.data')
result = model_data._get_id(cr, uid, 'base', 'view_res_partner_filter')
res = model_data.read(cr, uid, result, ['res_id'])
value = {
'domain': "[]",
'view_type': 'form',
'view_mode': 'form,tree',
'res_model': 'res.partner',
'res_id': int(partner_id),
'view_id': False,
'context': context,
'type': 'ir.actions.act_window',
'search_view_id': res['res_id']
}
return value
def make_opportunity(self, cr, uid, ids, opportunity_summary, planned_revenue=0.0, probability=0.0, partner_id=None, context=None):
categ = self.pool.get('crm.case.categ')
address = self.address_get(cr, uid, ids)
categ_ids = categ.search(cr, uid, [('object_id.model','=','crm.lead')])
lead = self.pool.get('crm.lead')
opportunity_ids = []
opportunity_ids = {}
for partner in self.browse(cr, uid, ids, context=context):
address = self.address_get(cr, uid, partner.id)
address = self.address_get(cr, uid, [partner.id])['default']
if not partner_id:
partner_id = partner.id
opportunity_id = lead.create(cr, uid, {
'name' : opportunity,
'name' : opportunity_summary,
'planned_revenue' : planned_revenue,
'probability' : probability,
'partner_id' : partner_id,
'partner_address_id' : address['default'],
'partner_address_id' : address,
'categ_id' : categ_ids and categ_ids[0] or '',
'state' :'draft',
'type': 'opportunity'
})
opportunity_id.add(opportunity_id)
opportunity_ids[partner_id] = opportunity_id
return opportunity_ids
res_partner()

View File

@ -0,0 +1,30 @@
Return-Path: <info@customer.com>
X-Original-To: info@customer.com
Delivered-To: sales@my.com
Received: by mail.my.com (Postfix, from userid xxx)
id 822ECBFB67; Mon, 24 Oct 2011 07:36:51 +0200 (CEST)
X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.my.com
X-Spam-Level:
X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED autolearn=ham
version=3.3.1
Received: from [192.168.1.146]
(Authenticated sender: info@mail.customer.com)
by mail.customer.com (Postfix) with ESMTPSA id 07A30BFAB4
for <sales@my.com>; Mon, 24 Oct 2011 07:36:50 +0200 (CEST)
Message-ID: <4EA4F95D.904@customer.com>
Date: Mon, 24 Oct 2011 11:06:29 +0530
From: Mr. John Right <info@customer.com>
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.14) Gecko/20110223 Lightning/1.0b2 Thunderbird/3.1.8
MIME-Version: 1.0
To: sales@my.com
Subject: Fournir votre devis avec le meilleur prix.
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 8bit
Bonjour l'équipe de vente,
Je veux acheter vos produits et services.
S'il vous plaît fournir votre cotation avec le meilleur prix.
Merci

View File

@ -1,76 +1,31 @@
-
Cheking for lead from draft to cancel, I cancel this lead.
I cancel unqualified lead.
-
!python {model: crm.lead}: |
self.case_cancel(cr, uid, [ref("crm_case_itisatelesalescampaign0")])
-
I test lead is on cancel state.
I check cancelled lead.
-
!assert {model: crm.lead, id: crm.crm_case_itisatelesalescampaign0, string: Lead is in cancel state}:
- state == "cancel"
-
Checking for lead from cancel to reset, I reset this lead.
I reset cancelled lead into unqualified lead.
-
!python {model: crm.lead}: |
self.case_reset(cr, uid, [ref("crm_case_itisatelesalescampaign0")])
-
I test lead is on draft state.
I check unqualified lead after reset.
-
!assert {model: crm.lead, id: crm.crm_case_itisatelesalescampaign0, string: Lead is in draft state}:
- state == "draft"
-
Cheking for lead from reset to pending, I pending this lead.
I put unqualified lead into pending.
-
!python {model: crm.lead}: |
self.case_pending(cr, uid, [ref("crm_case_itisatelesalescampaign0")])
-
I test lead is on pending state.
I check status of pending lead.
-
!assert {model: crm.lead, id: crm.crm_case_itisatelesalescampaign0, string: Lead is in pending state}:
- state == "pending"
-
Cheking for lead from pending to cancel, I cancel this lead.
-
!python {model: crm.lead}: |
self.case_cancel(cr, uid, [ref("crm_case_itisatelesalescampaign0")])
-
I test lead is on cancel state.
-
!assert {model: crm.lead, id: crm.crm_case_itisatelesalescampaign0, string: Lead is in cancel state}:
- state == "cancel"
-
I create sales executive department that will be work under Sales Department.
-
!record {model: crm.case.section, id: section_sales_exe_department}:
name: "Sales Executive"
parent_id: crm.section_sales_department
-
Escalate lead from sales executive department to sales department,
for that purpose i assign sales executive department on lead,
after i will be process to escalate lead to sales department
-
!record {model: crm.lead, id: crm.crm_case_itisatelesalescampaign0}:
section_id: section_sales_exe_department
-
Processing on Lead escalate to sales departemnt, i check for lead escalate to sales Department from Executive
department or not.
-
!python {model: crm.lead}: |
self.case_reset(cr, uid, [ref("crm_case_itisatelesalescampaign0")])
self.case_escalate(cr, uid, [ref("crm_case_itisatelesalescampaign0")])
-
I test lead escalate from sales department from Executive department.
-
!assert {model: crm.lead, id: crm.crm_case_itisatelesalescampaign0, string: Escalate lead to on sales team from Executive teame}:
- section_id.name == "Sales Department"
-
Cheking for lead from escalate to cancel, I cancel this lead.
-
!python {model: crm.lead}: |
self.case_cancel(cr, uid, [ref("crm_case_itisatelesalescampaign0")])
-
I test lead is on cancel state.
-
!assert {model: crm.lead, id: crm.crm_case_itisatelesalescampaign0, string: Lead is in cancel state}:
- state == "cancel"

View File

@ -1,51 +1,54 @@
-
Communication by mail, Customer Interest with our product and to take functional
training with us.
Customer would like to purchase our product. so He send request by email to our mail server.
-
Mail script will be fetched him request from mail server. so I process that mail after read EML file
-
!python {model: mail.thread}: |
import addons
request_file = open(addons.get_module_resource('crm','test', 'customer_request.eml'),'rb')
request_message = request_file.read()
self.message_process(cr, uid, 'crm.lead', request_message)
-
After getting the mail, I check details of new lead of that customer.
-
!python {model: crm.lead}: |
#create message manually to create lead by(Mail) self.message_new(cr, uid, msg, context=None)
lead_ids = self.search(cr, uid, [('email_from','=', 'Mr. John Right <info@customer.com>')])
assert lead_ids and len(lead_ids), "Lead is not created after getting request"
lead = self.browse(cr, uid, lead_ids[0], context=context)
assert not lead.partner_id, "Customer should be a new"
assert lead.name == "Fournir votre devis avec le meilleur prix.", "Subject does not match"
-
After getting the mail, I call to customer for more communication.
I reply him request with welcome message.
-
!python {model: mail.compose.message}: |
lead_ids = self.pool.get('crm.lead').search(cr, uid, [('email_from','=', 'Mr. John Right <info@customer.com>')])
context.update({'active_model': 'crm.lead','active_id': lead_ids[0]})
id = self.create(cr, uid, {'body_text': "Merci à l'intérêt pour notre produit.nous vous contacterons bientôt. Merci"}, context=context)
try:
self.send_mail(cr, uid, [id], context=context)
except:
pass
-
Now, I convert him into customer and put into regular customer list.
-
!python {model: crm.lead}: |
#schedule phonecall to customer
#search lead which came by customer and create function in crm.lead-schedule_phonecall to customer
lead_ids = self.search(cr, uid, [('email_from','=', 'Mr. John Right <info@customer.com>')])
self.convert_partner(cr, uid, lead_ids, context=context)
-
Communication by phonecall with customer, customer want to meet us so I arrage
meeting for customer.
Now, I search customer in regular customer list.
-
!python {model: crm.lead}: |
#schedule to arrange meeting with customer.
#search lead which came by customer and call to action_makeMeeting.
partner_ids = self.message_partner_by_email(cr, uid, 'Mr. John Right <info@customer.com>')
assert partner_ids.get('partner_id'), "Customer is not found in regular customer list."
-
Customer do initial discussion with us on meeting, so I check confirm
meeting and after completed, meeting will be close.
I convert one phonecall request as a customer and put into regular customer list.
-
!python {model: crm.meeting}: |
#open and close the meeting.
#search id from lead and open and close this meeting.
-
After communicated by meeting with customer, I send mail to more discussion
with Customer.
-
!python {model: crm.lead}: |
#send mail to customer.
-
Also another communication send Fax to customer and maintain communication history.
-
!record {model: crm.add.note, id: crm_add_note_time_schedule}:
#create fax history
#body: 'Timining Scenario to come office'
-
I give Fax to customer for our detail scenario of functional training timing
schedule.
-
!python {model: crm.add.note}: |
#add this fax history to lead
#self.action_add(cr, uid, [ref("crm_add_note_time_schedule")], {"active_model": "crm.lead","active_ids": [ref("crm_case_qrecorp0")]})
-
After Adding Fax scenario, I test it.
-
!python {model: crm.lead}: |
#checked Fax history added.
#search lead history and compare with record
!python {model: crm.phonecall}: |
self.convert_partner(cr, uid, [ref('crm.crm_case_phone06')], context=context)

View File

@ -1,10 +0,0 @@
-
I got lead from Customer, I open this lead.
-
!python {model: crm.lead}: |
self.case_open(cr, uid, [ref("crm_case_qrecorp0")])
- |
In order to test lead, i test lead is in open stage.
-
!assert {model: crm.lead, id: crm.crm_case_qrecorp0, string: Lead in open state}:
- state == "open"

View File

@ -1,10 +1,21 @@
-
Convert opportunity based on exiting partner.
I open customer lead.
-
!python {model: crm.lead}: |
self.case_open(cr, uid, [ref("crm_case_qrecorp0")])
-
I check lead is in open stage.
-
!assert {model: crm.lead, id: crm.crm_case_qrecorp0, string: Lead in open state}:
- state == "open"
-
I convert lead into opportunity for exiting customer.
-
!python {model: crm.lead}: |
self.convert_opportunity(cr, uid ,[ref("crm_case_qrecorp0")], ref("base.res_partner_agrolait"))
-
After converted in opportunity, I test that lead is converted to opportunity.
I check details of converted opportunity.
-
!python {model: crm.lead}: |
lead = self.browse(cr, uid, ref('crm_case_qrecorp0'))
@ -12,12 +23,28 @@
assert lead.partner_id.id == ref("base.res_partner_agrolait"), 'Partner missmatch!'
assert lead.stage_id.id == ref("stage_lead1"), 'Stage of opportunity is incorrect!'
-
Finally, i won this opportunity, so I close this opportunity.
Now I start Communication by phonecall with customer.
-
!python {model: crm.opportunity2phonecall}: |
import time
context.update({'active_model': 'crm.lead', 'active_ids': [ref('crm_case_qrecorp0')]})
call_id = self.create(cr, uid, {'date': time.strftime('%Y-%m-%d %H:%M:%S'),
'name': "Bonjour M. Jean, Comment êtes-vous? J'ai obtenu votre demande. peut-on parler au sujet de ce pour quelques minutes?"}, context=context)
self.action_schedule(cr, uid, [call_id], context=context)
-
After communicated with customer, I put some notes with Contract details.
-
!python {model: crm.add.note}: |
context.update({'active_model': 'crm.lead', 'active_id': ref('crm_case_qrecorp0')})
note_id = self.create(cr, uid, {'body': "ces détails envoyés par le client sur le FAX pour la qualité"})
self.action_add(cr, uid, [note_id], context=context)
-
Finally, I won this opportunity, so I close this opportunity.
-
!python {model: crm.lead}: |
self.case_mark_won(cr, uid, [ref("crm_case_qrecorp0")])
-
After wininng the opportunity , I test the opportunity.
I check details of the opportunity After won the opportunity.
-
!python {model: crm.lead}: |
lead = self.browse(cr, uid, ref('crm_case_qrecorp0'))

View File

@ -1,25 +0,0 @@
-
Convert two Leads to two opportunity(Mass conversion).
-
!python {model: crm.lead}: |
self.convert_opportunity(cr, uid, [ref("crm_case_employee0"), ref("crm_case_electonicgoodsdealer0")], mass_convert=True)
-
First lead converted on opportunity, I test it.
-
!python {model: crm.lead}: |
lead = self.browse(cr, uid, ref('crm_case_employee0'))
assert lead.type == 'opportunity', 'Lead is not converted to opportunity!'
assert lead.planned_revenue == 0.0, 'Planned revenue should be 0!'
assert lead.probability == 0.0, 'probability revenue should be 0!'
assert lead.partner_id.name == "Agrolait", 'Partner missmatch!'
assert lead.stage_id.id == ref("stage_lead1"), 'Stage of probability is incorrect!'
-
Second lead converted on opportunity, I test it.
-
!python {model: crm.lead}: |
lead = self.browse(cr, uid, ref('crm_case_electonicgoodsdealer0'))
assert lead.type == 'opportunity', 'Lead is not converted to opportunity!'
assert lead.planned_revenue == 0.0, 'Planned revenue should be 0!'
assert lead.probability == 0.0, 'probability revenue should be 0!'
assert lead.partner_id.name == "Le Club SARL", 'Partner missmatch!'
assert lead.stage_id.id == ref("stage_lead1"), 'Stage of probability is incorrect!'

View File

@ -1,8 +1,30 @@
-
I have two opportunity ,so i merge this two Opportunities, I test which two opportunity has been merged .
I make direct opportunity for Customer.
-
!python {model: crm.partner2opportunity}: |
context.update({'active_model': 'res.partner', 'active_ids': [ref("base.res_partner_9")]})
res_id = self.create(cr, uid, {'name': "enquête pour l'achat de services"}, context=context)
self.make_opportunity(cr, uid, [res_id], context=context)
-
I make another opportunity from phonecall for same customer.
-
!python {model: crm.phonecall2opportunity}: |
context.update({'active_model': 'crm.phonecall', 'active_ids': [ref("crm.crm_case_phone06")]})
res_id = self.create(cr, uid, {'name': "Quoi de prix de votre autre service?", 'partner_id': ref("base.res_partner_9")}, context=context)
self.make_opportunity(cr, uid, [res_id], context=context)
-
Now I merge all opportunities of customer.
-
!python {model: crm.lead}: |
op_list = [ref('crm_case_bankwealthy2'),ref('crm_case_unifliege')]
op_ids=self.pool.get('crm.lead').browse(cr,uid,op_list)
lead_ids = [ref('crm_case_bankwealthy2')]
self.merge_opportunity(cr, uid, op_ids, {'lead_ids': lead_ids})
opportunity_ids = self.search(cr, uid, [('partner_id','=', ref("base.res_partner_9"))])
self.merge_opportunity(cr, uid, opportunity_ids, context=context)
-
Now I schedule another phonecall to customer after merged.
-
!python {model: crm.phonecall2phonecall}: |
context.update({'active_model': 'crm.phonecall', 'active_ids': [ref("crm.crm_case_phone06")]})
res_id = self.create(cr, uid, {'name': "vos chances sont fusionnés en un seul"}, context=context)
self.action_schedule(cr, uid, [res_id], context=context)

View File

@ -1,11 +0,0 @@
-
Convert partner to opportunity, i test to convert opportunity is from partner.
-
!python {model: res.partner}: |
opportunity = self.make_opportunity(cr, uid, [ref("base.res_partner_9")], 'BalmerInc S.A.', 200.0, 150.0)
opportunity_rec = self.pool.get('crm.lead').browse(cr, uid, opportunity['res_id'])
assert opportunity_rec.type == 'opportunity', 'Lead is not converted to opportunity!'
assert opportunity_rec.planned_revenue == 200.0, 'Planned revenue should be 200!'
assert opportunity_rec.probability == 150.0, 'probability revenue should be 150!'
assert opportunity_rec.partner_id.id == ref("base.res_partner_9"), 'Partner missmatch!'
assert opportunity_rec.state == 'draft', 'Opportunity stage not in draft state'

View File

@ -1,23 +0,0 @@
-
For customer purpose, I called to him/her for discussion about openerp.
As the success of phonecall seems to be a real business opportunity, so first i
create record of phonecall.
-
!record {model: crm.phonecall2opportunity, id: crm_phonecall2opportunity_disc_openerp}:
name: Discuss Review Process
partner_id: base.res_partner_tinyatwork
-
Succeed phonecall, it's convert into on opportunity.
-
!python {model: crm.phonecall2opportunity}: |
self.action_apply(cr, uid, [ref("crm_phonecall2opportunity_disc_openerp")], {"active_id": ref("crm_case_phone04")})
-
I check that the phonecall and the newly created business opportunity is
linked to same partner and also check with phonecall closed and opportunity
is on intial stage or not.
-
!python {model: crm.phonecall}: |
phonecall = self.browse(cr, uid, ref('crm_case_phone04'))
assert phonecall.partner_id.id == phonecall.opportunity_id.partner_id.id, "created business opportunity is not linked to same partner"
assert phonecall.opportunity_id.stage_id.id == ref("stage_lead1"), "Converted opportunity is not in Initial stage"
assert phonecall.state == "done", "phonecall is held"

View File

@ -1,23 +0,0 @@
-
I schedule phonecall to another phonecall, so first i create record of schedule call.
-
!record {model: crm.phonecall2phonecall, id: crm_schedule_phonecall}:
name: 'Test Discuss Review Process'
categ_id: crm.categ_phone1
date: !eval time.strftime('%Y-%m-%d')
-
I Convert schedule phonecall.
-
!python {model: crm.phonecall2phonecall}: |
self.action_apply(cr, uid, [ref('crm_schedule_phonecall')], {'active_id': ref('crm_case_phone04')})
-
I check for another schedule call.
-
!python {model: crm.phonecall}: |
phonecall = self.search(cr, uid, [('name', '=', 'Test Discuss Review Process')])
assert phonecall, "Do not create another schedule call"
schedule_phonecall = self.browse(cr, uid, phonecall)[0]
assert schedule_phonecall.user_id.id == ref("base.user_root"), "Responsible person not assign"
assert schedule_phonecall.section_id.id == ref("crm.section_sales_department"), "Do not assign proper section"
assert schedule_phonecall.categ_id.id == ref("crm.categ_phone1"), "Category of phonecall is not apply"
assert schedule_phonecall.partner_id.id == ref("base.res_partner_tinyatwork"), "Partner missmatch"

View File

@ -1,24 +1,8 @@
-
In order to check for changes on partner, country and phone number change automatically according to partner,
I check onchange event of partner address on lead form.
-
!python {model: crm.lead}: |
action = self.onchange_partner_address_id(cr, uid, ref("crm_case_qrecorp0"), ref("base.res_partner_address_notsotinysarl0"), email=False)
assert action['value']['country_id'] == 20, "Country name not True"
assert action['value']['phone'] == '(+32).81.81.37.00', "phone number is wrong"
-
I try to Unlink the lead, so I create new record of lead on cancel stage.
-
!record {model: crm.lead, id: crm_case_new_lead}:
name: Openerp Trainning
state: cancel
-
I test copy and unlink this lead.
-
!python {model: crm.lead}: |
self.copy(cr, uid, ref("crm_case_new_lead"))
sid = self.search(cr, uid, [('name', '=', 'Openerp Trainning')])
assert len(sid) == 2, 'Lead is not copied Successfully'
try:
self.unlink(cr, uid, [ref("crm_case_new_lead")])
except:
pass

View File

@ -24,11 +24,11 @@ import crm_add_note
import crm_lead_to_partner
import crm_lead_to_opportunity
import crm_opportunity_to_phonecall
import crm_phonecall_to_phonecall
import crm_opportunity_to_phonecall
import crm_phonecall_to_partner
import crm_phonecall_to_opportunity
import crm_partner_to_opportunity
import crm_phonecall_to_opportunity
import crm_merge_opportunities

View File

@ -102,7 +102,30 @@ class crm_lead2opportunity_partner(osv.osv_memory):
raise osv.except_osv(_("Warning !"), _("Closed/Cancelled Leads can not be converted into Opportunity"))
return False
def _convert_opportunity(self, cr, uid, ids, context=None):
if context is None:
context = {}
lead = self.pool.get('crm.lead')
partner_ids = self._create_partner(cr, uid, ids, context=context)
partner_id = partner_ids and partner_ids[0] or False
lead_ids = context.get('active_ids', [])
user_ids = context.get('user_ids', False)
team_id = context.get('section_id', False)
return lead.convert_opportunity(cr, uid, lead_ids, partner_id, user_ids, team_id, context=context)
def _merge_opportunity(self, cr, uid, ids, opportunity_ids, action='merge', context=None):
#TOFIX: is it usefully ?
if context is None:
context = {}
merge_opportunity = self.pool.get('crm.merge.opportunity')
res = False
#If we convert in mass, don't merge if there is no other opportunity but no warning
if action == 'merge' and (len(opportunity_ids) > 1 or not context.get('mass_convert') ):
self.write(cr, uid, ids, {'opportunity_ids' : [(6,0, [opportunity_ids[0].id])]}, context=context)
context.update({'lead_ids' : record_id, "convert" : True})
res = merge_opportunity.merge(cr, uid, data.opportunity_ids, context=context)
return res
def action_apply(self, cr, uid, ids, context=None):
"""
This converts lead to opportunity and opens Opportunity view
@ -112,20 +135,13 @@ class crm_lead2opportunity_partner(osv.osv_memory):
"""
if not context:
context = {}
if not record_id:
return {'type': 'ir.actions.act_window_close'}
lead = self.pool.get('crm.lead')
data = self.browse(cr, uid, ids, context=context)[0]
self._convert_opportunity(cr, uid, ids, context=context)
self._merge_opportunity(cr, uid, ids, data.opportunity_ids, data.action, context=context)
partner_ids = self._create_partner(cr, uid, ids, context=context)
partner_id = partner_ids and partner_ids[0] or False
leads.convert_opportunity(cr, uid, lead_ids, partner_id, context=context)
#If we convert in mass, don't merge if there is no other opportunity but no warning
if data.name == 'merge' and (len(data.opportunity_ids) > 1 or not context.get('mass_convert') ):
merge_obj = self.pool.get('crm.merge.opportunity')
self.write(cr, uid, ids, {'opportunity_ids' : [(6,0, [data.opportunity_ids[0].id])]}, context=context)
context.update({'lead_ids' : record_id, "convert" : True})
return merge_obj.merge(cr, uid, data.opportunity_ids, context=context)
return leads.redirect_opportunity_view(cr, uid, lead_ids[0], context=context)
return lead.redirect_opportunity_view(cr, uid, lead_ids[0], context=context)
crm_lead2opportunity_partner()
@ -150,13 +166,14 @@ class crm_lead2opportunity_mass_convert(osv.osv_memory):
data = self.browse(cr, uid, ids, context=context)[0]
salesteam_id = data.section_id and data.section_id.id or False
salesmans = []
salesman = []
if data.user_ids:
salesmans = [x.id for x in data.user_ids]
lead.allocate_salesman(cr, uid, active_ids, salesman, salesteam_id, context=context)
salesman = [x.id for x in data.user_ids]
value = self.default_get(cr, uid, ['partner_id', 'opportunity_ids'], context=context)
value['opportunity_ids'] = [(6, 0, value['opportunity_ids'])]
self.write(cr, uid, ids, value, context=context)
context.update({'user_ids': salesman, 'section_id': salesteam_id})
return self.action_apply(cr, uid, ids, context=context)
crm_lead2opportunity_mass_convert()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -21,7 +21,6 @@
from osv import osv, fields
from tools.translate import _
import re
class crm_lead2partner(osv.osv_memory):
""" Converts lead to partner """
@ -38,49 +37,47 @@ class crm_lead2partner(osv.osv_memory):
"""
This function checks for precondition before wizard executes
"""
lead_obj = self.pool.get('crm.lead')
if context is None:
context = {}
model = context.get('active_model')
model = self.pool.get(model)
rec_ids = context and context.get('active_ids', [])
for lead in lead_obj.browse(cr, uid, rec_ids, context=context):
if lead.partner_id:
for this in model.browse(cr, uid, rec_ids, context=context):
if this.partner_id:
raise osv.except_osv(_('Warning !'),
_('A partner is already defined on this lead.'))
_('A partner is already defined.'))
def _select_partner(self, cr, uid, context=None):
if context is None:
context = {}
lead = self.pool.get('crm.lead')
partner = self.pool.get('res.partner')
lead_ids = list(context and context.get('active_ids', []) or [])
if not len(lead_ids):
return False
this = lead.browse(cr, uid, lead_ids[0], context=context)
# Find partner address matches the email_from of the lead
res = lead.message_partner_by_email(cr, uid, this.email_from, context=context)
partner_id = res.get('partner_id', False)
# Find partner name that matches the name of the lead
if not partner_id and this.partner_name:
partner_ids = partner.search(cr, uid, [('name', '=', this.partner_name)], context=context)
if partner_ids and len(partner_ids):
partner_id = partner_ids[0]
return partner_id
def default_get(self, cr, uid, fields, context=None):
"""
This function gets default values
"""
lead_obj = self.pool.get('crm.lead')
partner_obj = self.pool.get('res.partner')
partner_id = False
data = list(context and context.get('active_ids', []) or [])
res = super(crm_lead2partner, self).default_get(cr, uid, fields, context=context)
for lead in lead_obj.browse(cr, uid, data, context=context):
partner_ids = []
# Find partner address matches the email_from of the lead
email = re.findall(r'([^ ,<@]+@[^> ,]+)', lead.email_from or '')
email = map(lambda x: "'" + x + "'", email)
if email:
cr.execute("""select id from res_partner_address
where
substring(email from '([^ ,<@]+@[^> ,]+)') in (%s)""" % (','.join(email)))
address_ids = map(lambda x: x[0], cr.fetchall())
if address_ids:
partner_ids = partner_obj.search(cr, uid, [('address', 'in', address_ids)], context=context)
# Find partner name that matches the name of the lead
if not partner_ids and lead.partner_name:
partner_ids = partner_obj.search(cr, uid, [('name', '=', lead.partner_name)], context=context)
partner_id = partner_ids and partner_ids[0] or False
if 'partner_id' in fields:
res.update({'partner_id': partner_id})
if 'action' in fields:
res.update({'action': partner_id and 'exist' or 'create'})
if 'opportunity_ids' in fields:
res.update({'opportunity_ids': data})
res = super(crm_lead2partner, self).default_get(cr, uid, fields, context=context)
partner_id = self._select_partner(cr, uid, context=context)
if 'partner_id' in fields:
res.update({'partner_id': partner_id})
if 'action' in fields:
res.update({'action': partner_id and 'exist' or 'create'})
return res
def open_create_partner(self, cr, uid, ids, context=None):
@ -88,17 +85,17 @@ class crm_lead2partner(osv.osv_memory):
This function Opens form of create partner.
"""
view_obj = self.pool.get('ir.ui.view')
view_id = view_obj.search(cr, uid, [('model', '=', 'crm.lead2partner'), \
('name', '=', 'crm.lead2partner.view')])
view_id = view_obj.search(cr, uid, [('model', '=', self._name), \
('name', '=', self._name+'.view')])
return {
'view_mode': 'form',
'view_type': 'form',
'view_id': view_id or False,
'res_model': 'crm.lead2partner',
'res_model': self._name,
'context': context,
'type': 'ir.actions.act_window',
'target': 'new',
}
}
def _create_partner(self, cr, uid, ids, context=None):
"""
@ -118,7 +115,7 @@ class crm_lead2partner(osv.osv_memory):
This function Makes partner based on action.
"""
partner_ids = self._create_partner(cr, uid, ids, context=context)
return {'type': 'ir.actions.act_window_close'}
return self.pool.get('res.partner').redirect_partner_form(cr, uid, partner_ids[0], context=context)
crm_lead2partner()

View File

@ -28,33 +28,11 @@ import time
class crm_opportunity2phonecall(osv.osv_memory):
"""Converts Opportunity to Phonecall"""
_inherit = 'crm.phonecall2phonecall'
_name = 'crm.opportunity2phonecall'
_description = 'Opportunity to Phonecall'
_columns = {
'name' : fields.char('Call summary', size=64, required=True, select=1),
'user_id' : fields.many2one('res.users', "Assign To"),
'partner_id' : fields.many2one('res.partner', "Partner"),
'date': fields.datetime('Date'),
'section_id': fields.many2one('crm.case.section', 'Sales Team'),
'categ_id': fields.many2one('crm.case.categ', 'Category', \
domain="['|',('section_id','=',False),('section_id','=',section_id),\
('object_id.model', '=', 'crm.phonecall')]"),
'action': fields.selection([('schedule','Schedule a call'), ('log','Log a call')], 'Action', required=True),
}
def default_get(self, cr, uid, fields, context=None):
"""
This function gets default values
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param fields: List of fields for default value
@param context: A standard dictionary for contextual values
@return : default values of fields.
"""
opp_obj = self.pool.get('crm.lead')
categ_id = False
data_obj = self.pool.get('ir.model.data')
@ -78,83 +56,20 @@ class crm_opportunity2phonecall(osv.osv_memory):
res.update({'partner_id': opp.partner_id and opp.partner_id.id or False})
return res
def action_cancel(self, cr, uid, ids, context=None):
"""
Closes Opportunity to Phonecall form
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of Opportunity to Phonecall's IDs
@param context: A standard dictionary for contextual values
"""
return {'type': 'ir.actions.act_window_close'}
def action_apply(self, cr, uid, ids, context=None):
"""
This converts Opportunity to Phonecall and opens Phonecall view
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current user's ID for security checks,
@param ids: List of Opportunity to Phonecall IDs
@param context: A standard dictionary for contextual values
@return : Dictionary value for created Opportunity form
"""
def action_schedule(self, cr, uid, ids, context=None):
value = {}
record_ids = context and context.get('active_ids', []) or []
phonecall_obj = self.pool.get('crm.phonecall')
opp_obj = self.pool.get('crm.lead')
mod_obj = self.pool.get('ir.model.data')
result = mod_obj._get_id(cr, uid, 'crm', 'view_crm_case_phonecalls_filter')
res = mod_obj.read(cr, uid, result, ['res_id'])
data_obj = self.pool.get('ir.model.data')
# Select the view
id2 = data_obj._get_id(cr, uid, 'crm', 'crm_case_phone_tree_view')
id3 = data_obj._get_id(cr, uid, 'crm', 'crm_case_phone_form_view')
if id2:
id2 = data_obj.browse(cr, uid, id2, context=context).res_id
if id3:
id3 = data_obj.browse(cr, uid, id3, context=context).res_id
for this in self.browse(cr, uid, ids, context=context):
for opp in opp_obj.browse(cr, uid, record_ids, context=context):
vals = {
'name' : opp.name,
'case_id' : opp.id,
'user_id' : this.user_id and this.user_id.id or False,
'categ_id' : this.categ_id.id,
'description' : opp.description or False,
'date' : this.date,
'section_id' : this.section_id.id or False,
'partner_id': opp.partner_id and opp.partner_id.id or False,
'partner_address_id': opp.partner_address_id and opp.partner_address_id.id or False,
'partner_phone' : opp.phone or (opp.partner_address_id and opp.partner_address_id.phone or False),
'partner_mobile' : opp.partner_address_id and opp.partner_address_id.mobile or False,
'priority': opp.priority,
'opportunity_id': opp.id,
'date_open': time.strftime('%Y-%m-%d %H:%M:%S')
}
new_case = phonecall_obj.create(cr, uid, vals, context=context)
if this.action == 'log':
phonecall_obj.case_close(cr, uid, [new_case])
value = {
'name': _('Phone Call'),
'domain': "[('user_id','=',%s),('opportunity_id','=',%s)]" % (uid,opp.id),
'view_type': 'form',
'view_mode': 'tree,form',
'res_model': 'crm.phonecall',
'res_id' : new_case,
'views': [(id3, 'form'), (id2, 'tree'), (False, 'calendar')],
'type': 'ir.actions.act_window',
'search_view_id': res['res_id'],
}
return value
if context is None:
context = {}
phonecall = self.pool.get('crm.phonecall')
opportunity_ids = context and context.get('active_ids') or []
opportunity = self.pool.get('crm.lead')
data = self.browse(cr, uid, ids, context=context)[0]
call_ids = opportunity.schedule_phonecall(cr, uid, opportunity_ids, data.date, data.name, \
data.user_id and data.user_id.id or False, \
data.section_id and data.section_id.id or False, \
data.categ_id and data.categ_id.id or False, \
action=data.action, context=context)
return phonecall.redirect_phonecall_view(cr, uid, call_ids[opportunity_ids[0]], context=context)
crm_opportunity2phonecall()

View File

@ -23,8 +23,8 @@
<separator string="" colspan="4"/>
<group colspan="4" col="3">
<button name="action_cancel" string="_Cancel" icon="gtk-cancel" special="cancel" />
<button name="action_apply" type="object" string="Log call" icon="gtk-ok" attrs="{'invisible' : [('action', '!=', 'log')]}" />
<button name="action_apply" type="object" string="Schedule call" icon="gtk-ok" attrs="{'invisible' : [('action', '!=', 'schedule')]}" />
<button name="action_schedule" type="object" string="Log call" icon="gtk-ok" attrs="{'invisible' : [('action', '!=', 'log')]}" />
<button name="action_schedule" type="object" string="Schedule call" icon="gtk-ok" attrs="{'invisible' : [('action', '!=', 'schedule')]}" />
</group>
</form>
</field>

View File

@ -54,14 +54,14 @@ class crm_partner2opportunity(osv.osv_memory):
partner_ids = context and context.get('active_ids', []) or []
partner = self.pool.get('res.partner')
lead = self.pool.get('crm.lead')
for data in self.browse(cr, uid, ids, context=context):
opportunity_ids = partner.make_opportunity(cr, uid, partner_ids,
data.name,
data.planned_revenue,
data.probability,
})
opportunity_id = len(opportunity_ids) and opportunity_ids[0] or False
return lead.redirect_opportunity_view(cr, uid, opportunity_id, context=context)
data = self.browse(cr, uid, ids, context=context)[0]
opportunity_ids = partner.make_opportunity(cr, uid, partner_ids,
data.name,
data.planned_revenue,
data.probability,
)
opportunity_id = opportunity_ids[partner_ids[0]]
return lead.redirect_opportunity_view(cr, uid, opportunity_id, context=context)
crm_partner2opportunity()

View File

@ -26,94 +26,28 @@ class crm_phonecall2opportunity(osv.osv_memory):
""" Converts Phonecall to Opportunity"""
_name = 'crm.phonecall2opportunity'
_inherit = 'crm.partner2opportunity'
_description = 'Phonecall To Opportunity'
def action_cancel(self, cr, uid, ids, context=None):
"""
Closes Phonecall to Opportunity form
"""
return {'type':'ir.actions.act_window_close'}
def action_apply(self, cr, uid, ids, context=None):
def make_opportunity(self, cr, uid, ids, context=None):
"""
This converts Phonecall to Opportunity and opens Phonecall view
"""
record_id = context and context.get('active_id', False) or False
if record_id:
opp_obj = self.pool.get('crm.lead')
phonecall_obj = self.pool.get('crm.phonecall')
case = phonecall_obj.browse(cr, uid, record_id, context=context)
data_obj = self.pool.get('ir.model.data')
result = data_obj._get_id(cr, uid, 'crm', 'view_crm_case_opportunities_filter')
res = data_obj.read(cr, uid, result, ['res_id'])
id2 = data_obj._get_id(cr, uid, 'crm', 'crm_case_form_view_oppor')
id3 = data_obj._get_id(cr, uid, 'crm', 'crm_case_tree_view_oppor')
if id2:
id2 = data_obj.browse(cr, uid, id2, context=context).res_id
if id3:
id3 = data_obj.browse(cr, uid, id3, context=context).res_id
for this in self.browse(cr, uid, ids, context=context):
address = None
if this.partner_id:
address_id = self.pool.get('res.partner').address_get(cr, uid, [this.partner_id.id])
if address_id['default']:
address = self.pool.get('res.partner.address').browse(cr, uid, address_id['default'], context=context)
new_opportunity_id = opp_obj.create(cr, uid, {
'name': this.name,
'planned_revenue': this.planned_revenue,
'probability': this.probability,
'partner_id': this.partner_id and this.partner_id.id or False,
'partner_address_id': address and address.id,
'phone': address and address.phone,
'mobile': address and address.mobile,
'section_id': case.section_id and case.section_id.id or False,
'description': case.description or False,
'phonecall_id': case.id,
'priority': case.priority,
'type': 'opportunity',
'phone': case.partner_phone or False,
})
vals = {
'partner_id': this.partner_id.id,
'opportunity_id' : new_opportunity_id,
}
phonecall_obj.write(cr, uid, [case.id], vals)
phonecall_obj.case_close(cr, uid, [case.id])
opp_obj.case_open(cr, uid, [new_opportunity_id])
value = {
'name': _('Opportunity'),
'view_type': 'form',
'view_mode': 'form,tree',
'res_model': 'crm.lead',
'res_id': int(new_opportunity_id),
'view_id': False,
'views': [(id2, 'form'), (id3, 'tree'), (False, 'calendar'), (False, 'graph')],
'type': 'ir.actions.act_window',
'search_view_id': res['res_id']
}
return value
_columns = {
'name' : fields.char('Opportunity Summary', size=64, required=True, select=1),
'probability': fields.float('Success Probability'),
'planned_revenue': fields.float('Expected Revenue'),
'partner_id': fields.many2one('res.partner', 'Partner'),
}
if not len(ids):
return False
call_ids = context and context.get('active_ids', False) or False
this = self.browse(cr, uid, ids[0], context=context)
if not call_ids:
return {}
opportunity = self.pool.get('crm.lead')
phonecall = self.pool.get('crm.phonecall')
opportunity_ids = phonecall.convert_opportunity(cr, uid, call_ids, this.name, this.partner_id and this.partner_id.id or False, \
this.planned_revenue, this.probability, context=context)
return opportunity.redirect_opportunity_view(cr, uid, opportunity_ids[call_ids[0]], context=context)
def default_get(self, cr, uid, fields, context=None):
"""
This function gets default values
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param fields: List of fields for default value
@param context: A standard dictionary for contextual values
@return : default values of fields.
"""
record_id = context and context.get('active_id', False) or False
res = super(crm_phonecall2opportunity, self).default_get(cr, uid, fields, context=context)

View File

@ -26,42 +26,12 @@ class crm_phonecall2partner(osv.osv_memory):
""" Converts phonecall to partner """
_name = 'crm.phonecall2partner'
_inherit = 'crm.lead2partner'
_description = 'Phonecall to Partner'
_columns = {
'action': fields.selection([('exist', 'Link to an existing partner'), \
('create', 'Create a new partner')], \
'Action', required=True),
'partner_id': fields.many2one('res.partner', 'Partner')
}
def view_init(self, cr, uid, fields, context=None):
"""
This function checks for precondition before wizard executes
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param fields: List of fields for default value
@param context: A standard dictionary for contextual values
"""
phonecall_obj = self.pool.get('crm.phonecall')
rec_ids = context and context.get('active_ids', [])
for phonecall in phonecall_obj.browse(cr, uid, rec_ids, context=context):
if phonecall.partner_id:
raise osv.except_osv(_('Warning !'),
_('A partner is already defined on this phonecall.'))
def _select_partner(self, cr, uid, context=None):
"""
This function Searches for Partner from selected phonecall.
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param fields: List of fields for default value
@param context: A standard dictionary for contextual values
@return : Partner id if any for selected phonecall.
"""
if context is None:
context = {}
@ -75,7 +45,7 @@ class crm_phonecall2partner(osv.osv_memory):
for phonecall in phonecall_obj.browse(cr, uid, rec_ids, context=context):
partner_ids = partner_obj.search(cr, uid, [('name', '=', phonecall.name or phonecall.name)])
if not partner_ids and phonecall.email_from:
address_ids = contact_obj.search(cr, uid, [('email', '=', phonecall.email_from)])
address_ids = contact_obj.search(cr, uid, ['|', ('phone', '=', phonecall.partner_phone), ('mobile','=',phonecall.partner_mobile)])
if address_ids:
addresses = contact_obj.browse(cr, uid, address_ids)
partner_ids = addresses and [addresses[0].partner_id.id] or False
@ -83,118 +53,20 @@ class crm_phonecall2partner(osv.osv_memory):
partner_id = partner_ids and partner_ids[0] or False
return partner_id
_defaults = {
'action': lambda *a:'exist',
'partner_id': _select_partner
}
def open_create_partner(self, cr, uid, ids, context=None):
"""
This function Opens form of create partner.
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of Phonecall to Partner's IDs
@param context: A standard dictionary for contextual values
@return : Dictionary value for next form.
"""
view_obj = self.pool.get('ir.ui.view')
view_id = view_obj.search(cr, uid, [('model', '=', 'crm.phonecall2partner'), \
('name', '=', 'crm.phonecall2partner.view')])
return {
'view_mode': 'form',
'view_type': 'form',
'view_id': view_id or False,
'res_model': 'crm.phonecall2partner',
'context': context,
'type': 'ir.actions.act_window',
'target': 'new',
}
def _create_partner(self, cr, uid, ids, context=None):
"""
This function Creates partner based on action.
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of Phonecall to Partner's IDs
@param context: A standard dictionary for contextual values
@return : Dictionary {}.
"""
if context is None:
context = {}
phonecall_obj = self.pool.get('crm.phonecall')
partner_obj = self.pool.get('res.partner')
contact_obj = self.pool.get('res.partner.address')
partner_ids = []
contact_id = False
rec_ids = context and context.get('active_ids', [])
phonecall = self.pool.get('crm.phonecall')
call_ids = context and context.get('active_ids') or []
for data in self.browse(cr, uid, ids, context=context):
for phonecall in phonecall_obj.browse(cr, uid, rec_ids, context=context):
if data.action == 'create':
partner_id = partner_obj.create(cr, uid, {
'name': phonecall.name or phonecall.name,
'user_id': phonecall.user_id.id,
'comment': phonecall.description,
})
contact_id = contact_obj.create(cr, uid, {
'partner_id': partner_id,
'name': phonecall.name,
'phone': phonecall.partner_phone,
})
else:
if data.partner_id:
partner_id = data.partner_id.id
contact_id = partner_obj.address_get(cr, uid, [partner_id])['default']
partner_ids.append(partner_id)
vals = {}
if partner_id:
vals.update({'partner_id': partner_id})
if contact_id:
vals.update({'partner_address_id': contact_id})
phonecall_obj.write(cr, uid, [phonecall.id], vals)
partner_id = data.partner_id and data.partner_id.id or False
partner_ids += phonecall.convert_partner(cr, uid, call_ids, data.action, partner_id, context=context)
return partner_ids
def make_partner(self, cr, uid, ids, context=None):
"""
This function Makes partner based on action.
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of Phonecall to Partner's IDs
@param context: A standard dictionary for contextual values
@return : Dictionary value for created Partner form.
"""
partner_ids = self._create_partner(cr, uid, ids, context=context)
mod_obj = self.pool.get('ir.model.data')
result = mod_obj._get_id(cr, uid, 'base', 'view_res_partner_filter')
res = mod_obj.read(cr, uid, result, ['res_id'])
value = {
'domain': "[]",
'view_type': 'form',
'view_mode': 'form,tree',
'res_model': 'res.partner',
'res_id': partner_ids and int(partner_ids[0]) or False,
'view_id': False,
'context': context,
'type': 'ir.actions.act_window',
'search_view_id': res['res_id']
}
return value
crm_phonecall2partner()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -25,108 +25,47 @@ from tools.translate import _
import time
class crm_phonecall2phonecall(osv.osv_memory):
""" Converts Phonecall to Phonecall"""
_name = 'crm.phonecall2phonecall'
_description = 'Phonecall To Phonecall'
_columns = {
'name' : fields.char('Call summary', size=64, required=True, select=1),
'user_id' : fields.many2one('res.users',"Assign To"),
'categ_id': fields.many2one('crm.case.categ', 'Category', \
domain="['|',('section_id','=',False),('section_id','=',section_id),\
('object_id.model', '=', 'crm.phonecall')]"),
'date': fields.datetime('Date'),
'section_id':fields.many2one('crm.case.section','Sales Team'),
'action': fields.selection([('schedule','Schedule a call'), ('log','Log a call')], 'Action', required=True),
'partner_id' : fields.many2one('res.partner', "Partner"),
}
def action_cancel(self, cr, uid, ids, context=None):
"""
Closes Phonecall to Phonecall form
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of Phonecall to Phonecall's IDs
@param context: A standard dictionary for contextual values
"""
return {'type':'ir.actions.act_window_close'}
def action_apply(self, cr, uid, ids, context=None):
"""
This converts Phonecall to Phonecall and opens Phonecall view
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of Phonecall to Phonecall IDs
@param context: A standard dictionary for contextual values
@return : Dictionary value for created Opportunity form
"""
res = {}
record_id = context and context.get('active_id', False) or False
phonecall_obj = self.pool.get('crm.phonecall')
if record_id:
data_obj = self.pool.get('ir.model.data')
# Get Phonecall views
result = data_obj._get_id(cr, uid, 'crm', 'view_crm_case_phonecalls_filter')
res = data_obj.read(cr, uid, result, ['res_id'])
id2 = data_obj._get_id(cr, uid, 'crm', 'crm_case_phone_form_view')
id3 = data_obj._get_id(cr, uid, 'crm', 'crm_case_phone_tree_view')
if id2:
id2 = data_obj.browse(cr, uid, id2, context=context).res_id
if id3:
id3 = data_obj.browse(cr, uid, id3, context=context).res_id
phonecall = phonecall_obj.browse(cr, uid, record_id, context=context)
for this in self.browse(cr, uid, ids, context=context):
values = {
'name': this.name,
'user_id': this.user_id and this.user_id.id,
'categ_id': this.categ_id.id,
'section_id': this.section_id.id or (phonecall.section_id and phonecall.section_id.id),
'description': phonecall.description or '',
'partner_id': phonecall.partner_id.id,
'partner_address_id': phonecall.partner_address_id.id,
'partner_mobile': phonecall.partner_mobile or False,
'priority': phonecall.priority,
'partner_phone': phonecall.partner_phone or False,
'date': this.date
}
phonecall_id = phonecall_obj.create(cr, uid, values, context=context)
if this.action == 'schedule':
phonecall_obj.case_open(cr, uid, [phonecall_id])
elif this.action == 'log':
phonecall_obj.case_close(cr, uid, [phonecall_id])
res = {
'name': _('Phone Call'),
'view_type': 'form',
'view_mode': 'form',
'res_model': 'crm.phonecall',
'view_id': False,
'views': [(id2, 'form'), (id3, 'tree'), (False, 'calendar'), (False, 'graph')],
'type': 'ir.actions.act_window',
'res_id': phonecall_id,
'domain': [('id', '=', phonecall_id)],
'search_view_id': res['res_id']
}
return res
_columns = {
'name' : fields.char('Call summary', size=64, required=True, select=1),
'user_id' : fields.many2one('res.users',"Assign To"),
'categ_id': fields.many2one('crm.case.categ', 'Category', \
domain="['|',('section_id','=',False),('section_id','=',section_id),\
('object_id.model', '=', 'crm.phonecall')]"),
'date': fields.datetime('Date'),
'section_id':fields.many2one('crm.case.section','Sales Team'),
'action': fields.selection([('schedule','Schedule a call'), ('log','Log a call')], 'Action', required=True),
'partner_id' : fields.many2one('res.partner', "Partner"),
}
def action_schedule(self, cr, uid, ids, context=None):
value = {}
if context is None:
context = {}
phonecall = self.pool.get('crm.phonecall')
phonecall_ids = context and context.get('active_ids') or []
for this in self.browse(cr, uid, ids, context=context):
phocall_ids = phonecall.schedule_another_phonecall(cr, uid, phonecall_ids, this.date, this.name, \
this.user_id and this.user_id.id or False, \
this.section_id and this.section_id.id or False, \
this.categ_id and this.categ_id or False, \
action=this.action, context=context)
return phonecall.redirect_phonecall_view(cr, uid, phocall_ids[phonecall_ids[0]], context=context)
def default_get(self, cr, uid, fields, context=None):
"""
This function gets default values
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param fields: List of fields for default value
@param context: A standard dictionary for contextual values
@return : default values of fields.
"""
res = super(crm_phonecall2phonecall, self).default_get(cr, uid, fields, context=context)
record_id = context and context.get('active_id', False) or False

View File

@ -22,8 +22,8 @@
<separator string=" " colspan="4"/>
<group colspan="4" col="3" >
<button name="action_cancel" string="_Cancel" icon="gtk-cancel" special="cancel" />
<button name="action_apply" type="object" string="Log call" icon="gtk-ok" attrs="{'invisible' : [('action', '!=', 'log')]}" />
<button name="action_apply" type="object" string="Schedule call" icon="gtk-ok" attrs="{'invisible' : [('action', '!=', 'schedule')]}" />
<button name="action_schedule" type="object" string="Log call" icon="gtk-ok" attrs="{'invisible' : [('action', '!=', 'log')]}" />
<button name="action_schedule" type="object" string="Schedule call" icon="gtk-ok" attrs="{'invisible' : [('action', '!=', 'schedule')]}" />
</group>
</form>
</field>