diff --git a/addons/crm/__openerp__.py b/addons/crm/__openerp__.py index 04c57637dbe..8e195bb5d01 100644 --- a/addons/crm/__openerp__.py +++ b/addons/crm/__openerp__.py @@ -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, diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py index a281ea66c07..788903ce083 100644 --- a/addons/crm/crm_lead.py +++ b/addons/crm/crm_lead.py @@ -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') diff --git a/addons/crm/crm_phonecall.py b/addons/crm/crm_phonecall.py index 748f85ad063..1adf63b9a34 100644 --- a/addons/crm/crm_phonecall.py +++ b/addons/crm/crm_phonecall.py @@ -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 user’s 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 user’s 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 user’s 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 user’s 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 = {} diff --git a/addons/crm/crm_phonecall_demo.xml b/addons/crm/crm_phonecall_demo.xml index 8f0661ab8be..e80930284f4 100644 --- a/addons/crm/crm_phonecall_demo.xml +++ b/addons/crm/crm_phonecall_demo.xml @@ -83,9 +83,6 @@ - - - diff --git a/addons/crm/res_partner.py b/addons/crm/res_partner.py index 0fc6f5dff89..a00a25f47a4 100644 --- a/addons/crm/res_partner.py +++ b/addons/crm/res_partner.py @@ -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() diff --git a/addons/crm/test/customer_request.eml b/addons/crm/test/customer_request.eml new file mode 100644 index 00000000000..2c6c5e8110d --- /dev/null +++ b/addons/crm/test/customer_request.eml @@ -0,0 +1,30 @@ +Return-Path: +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 ; 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 +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 diff --git a/addons/crm/test/process/cancel_lead.yml b/addons/crm/test/process/cancel_lead.yml index 75afa71c1d9..0cc13208d03 100644 --- a/addons/crm/test/process/cancel_lead.yml +++ b/addons/crm/test/process/cancel_lead.yml @@ -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" diff --git a/addons/crm/test/process/communication_with_customer.yml b/addons/crm/test/process/communication_with_customer.yml index e5f805a36b2..444c7a704d2 100644 --- a/addons/crm/test/process/communication_with_customer.yml +++ b/addons/crm/test/process/communication_with_customer.yml @@ -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 ')]) + 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 ')]) + 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 ')]) + 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 ') + 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) + + diff --git a/addons/crm/test/process/draft2open_lead.yml b/addons/crm/test/process/draft2open_lead.yml deleted file mode 100644 index 97947b5846b..00000000000 --- a/addons/crm/test/process/draft2open_lead.yml +++ /dev/null @@ -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" diff --git a/addons/crm/test/process/lead2opportunity2win.yml b/addons/crm/test/process/lead2opportunity2win.yml index 9662cd6998f..ed33a251b80 100644 --- a/addons/crm/test/process/lead2opportunity2win.yml +++ b/addons/crm/test/process/lead2opportunity2win.yml @@ -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')) diff --git a/addons/crm/test/process/mass_leads2opportunity.yml b/addons/crm/test/process/mass_leads2opportunity.yml deleted file mode 100644 index 9258814b68b..00000000000 --- a/addons/crm/test/process/mass_leads2opportunity.yml +++ /dev/null @@ -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!' diff --git a/addons/crm/test/process/merge_opportunity.yml b/addons/crm/test/process/merge_opportunity.yml index 2a5b269153f..6d16ca17694 100644 --- a/addons/crm/test/process/merge_opportunity.yml +++ b/addons/crm/test/process/merge_opportunity.yml @@ -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) + diff --git a/addons/crm/test/process/partner2opportunity.yml b/addons/crm/test/process/partner2opportunity.yml deleted file mode 100644 index b9668a1a0f9..00000000000 --- a/addons/crm/test/process/partner2opportunity.yml +++ /dev/null @@ -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' diff --git a/addons/crm/test/process/phone-call2opportunity.yml b/addons/crm/test/process/phone-call2opportunity.yml deleted file mode 100644 index 03671d6df3b..00000000000 --- a/addons/crm/test/process/phone-call2opportunity.yml +++ /dev/null @@ -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" diff --git a/addons/crm/test/process/schedule_other_phone-call.yml b/addons/crm/test/process/schedule_other_phone-call.yml deleted file mode 100644 index a92496dc265..00000000000 --- a/addons/crm/test/process/schedule_other_phone-call.yml +++ /dev/null @@ -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" \ No newline at end of file diff --git a/addons/crm/test/ui/lead_form.yml b/addons/crm/test/ui/lead_form.yml index 8cfc96283b0..7ec86106947 100644 --- a/addons/crm/test/ui/lead_form.yml +++ b/addons/crm/test/ui/lead_form.yml @@ -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 + diff --git a/addons/crm/wizard/__init__.py b/addons/crm/wizard/__init__.py index 3ebdceda437..2fc39c51505 100644 --- a/addons/crm/wizard/__init__.py +++ b/addons/crm/wizard/__init__.py @@ -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 diff --git a/addons/crm/wizard/crm_lead_to_opportunity.py b/addons/crm/wizard/crm_lead_to_opportunity.py index 98d061f8520..9b03f7813a1 100644 --- a/addons/crm/wizard/crm_lead_to_opportunity.py +++ b/addons/crm/wizard/crm_lead_to_opportunity.py @@ -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: diff --git a/addons/crm/wizard/crm_lead_to_partner.py b/addons/crm/wizard/crm_lead_to_partner.py index 8cc6d3e58cf..5363264ca37 100644 --- a/addons/crm/wizard/crm_lead_to_partner.py +++ b/addons/crm/wizard/crm_lead_to_partner.py @@ -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() diff --git a/addons/crm/wizard/crm_opportunity_to_phonecall.py b/addons/crm/wizard/crm_opportunity_to_phonecall.py index 714376766f6..a6383438350 100644 --- a/addons/crm/wizard/crm_opportunity_to_phonecall.py +++ b/addons/crm/wizard/crm_opportunity_to_phonecall.py @@ -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 user’s 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 user’s 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() diff --git a/addons/crm/wizard/crm_opportunity_to_phonecall_view.xml b/addons/crm/wizard/crm_opportunity_to_phonecall_view.xml index 764648a877b..93b3c5cab85 100644 --- a/addons/crm/wizard/crm_opportunity_to_phonecall_view.xml +++ b/addons/crm/wizard/crm_opportunity_to_phonecall_view.xml @@ -23,8 +23,8 @@