diff --git a/addons/crm/test/test_crm_recurrent_meeting_case2.yml b/addons/base_calendar/test/test_crm_recurrent_meeting_case2.yml
similarity index 100%
rename from addons/crm/test/test_crm_recurrent_meeting_case2.yml
rename to addons/base_calendar/test/test_crm_recurrent_meeting_case2.yml
diff --git a/addons/crm/__openerp__.py b/addons/crm/__openerp__.py
index 54dfc335a2b..a98a0cbc6a4 100644
--- a/addons/crm/__openerp__.py
+++ b/addons/crm/__openerp__.py
@@ -118,18 +118,14 @@ Creates a dashboard for CRM that includes:
'crm_phonecall_demo.xml',
],
'test': [
- 'test/test_crm_lead.yml',
- 'test/test_crm_meeting.yml',
- 'test/test_crm_opportunity.yml',
- 'test/test_crm_phonecall.yml',
- 'test/test_crm_recurrent_meeting.yml',
- 'test/test_crm_stage_changes.yml',
- 'test/test_crm_recurrent_meeting_case2.yml',
- 'test/test_crm_lead_case2.yml',
- 'test/test_crm_opportunity_case2.yml',
- 'test/test_crm_phonecall_case2.yml',
- 'test/test_crm_partner2opportunity.yml',
- 'test/test_crm_segmentation.yml',
+ 'test/process/communication_with_customer.yml',
+ 'test/process/lead2opportunity2win.yml',
+ 'test/process/merge_opportunity.yml',
+ 'test/process/cancel_lead.yml',
+ 'test/process/segmentation.yml',
+ 'test/ui/crm_demo.yml',
+ 'test/ui/duplicate_lead.yml',
+ 'test/ui/delete_lead.yml'
],
'installable': True,
'active': False,
diff --git a/addons/crm/crm.py b/addons/crm/crm.py
index 03cdb31832d..bee1e48ada2 100644
--- a/addons/crm/crm.py
+++ b/addons/crm/crm.py
@@ -468,10 +468,12 @@ class crm_case(crm_base):
self._action(cr, uid, cases, state)
return True
+ #DEAD Code
def remind_partner(self, cr, uid, ids, context=None, attach=False):
return self.remind_user(cr, uid, ids, context, attach,
destination=False)
+ #DEAD Code
def remind_user(self, cr, uid, ids, context=None, attach=False, destination=True):
mail_message = self.pool.get('mail.message')
for case in self.browse(cr, uid, ids, context=context):
diff --git a/addons/crm/crm_demo.xml b/addons/crm/crm_demo.xml
index 16ae0e73129..f345d86d030 100644
--- a/addons/crm/crm_demo.xml
+++ b/addons/crm/crm_demo.xml
@@ -1,6 +1,6 @@
-
+
@@ -12,5 +12,17 @@
+
+ Sales Marketing Department
+ Sales Marketing
+
+
+
+
+ OpenERP partners
+ True
+
+
+
diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py
index 3a5c411993d..49272c97576 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
@@ -352,36 +352,380 @@ class crm_lead(crm_case, osv.osv):
"""
return self.set_priority(cr, uid, ids, '3')
- def convert_opportunity(self, cr, uid, ids, context=None):
- """ Precomputation for converting lead to opportunity
+
+ def _merge_data(self, cr, uid, ids, oldest, fields, context=None):
+ # prepare opportunity data into dictionary for merging
+ opportunities = self.browse(cr, uid, ids, context=context)
+ def _get_first_not_null(attr):
+ if hasattr(oldest, attr):
+ return getattr(oldest, attr)
+ for opportunity in opportunities:
+ if hasattr(opportunity, attr):
+ return getattr(opportunity, attr)
+ return False
+
+ def _get_first_not_null_id(attr):
+ res = _get_first_not_null(attr)
+ return res and res.id or False
+
+ def _concat_all(attr):
+ return ', '.join(filter(lambda x: x, [getattr(opportunity, attr) or '' for opportunity in opportunities if hasattr(opportunity, attr)]))
+
+ data = {}
+ for field_name in fields:
+ field_info = self._all_columns.get(field_name)
+ if field_info is None:
+ continue
+ field = field_info.column
+ if field._type in ('many2many', 'one2many'):
+ continue
+ elif field._type == 'many2one':
+ data[field_name] = _get_first_not_null_id(field_name) # !!
+ elif field._type == 'text':
+ data[field_name] = _concat_all(field_name) #not lost
+ else:
+ data[field_name] = _get_first_not_null(field_name) #not lost
+ return data
+
+ 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 = 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)
+
+ def _mail_body_text(self, cr, uid, lead, fields, title=False, context=None):
+ body = []
+ if title:
+ body.append("%s\n" % (title))
+ for field_name in fields:
+ field_info = self._all_columns.get(field_name)
+ if field_info is None:
+ continue
+ field = field_info.column
+ value = None
+
+ if field._type == 'selection':
+ if hasattr(field.selection, '__call__'):
+ key = field.selection(self, cr, uid, context=context)
+ else:
+ key = field.selection
+ value = dict(key).get(lead[field_name], lead[field_name])
+ elif field._type == 'many2one':
+ if lead[field_name]:
+ value = lead[field_name].name_get()[0][1]
+ else:
+ value = lead[field_name]
+
+ body.append("%s: %s" % (field.string, value or ''))
+ return "\n".join(body + ['---'])
+
+ def _merge_notification(self, cr, uid, opportunity_id, opportunities, context=None):
+ #TOFIX: mail template should be used instead of fix body, subject text
+ details = []
+ merge_message = _('Merged opportunities')
+ subject = [merge_message]
+ fields = ['name', 'partner_id', 'stage_id', 'section_id', 'user_id', 'categ_id', 'channel_id', 'company_id', 'contact_name',
+ 'email_from', 'phone', 'fax', 'mobile', 'state_id', 'description', 'probability', 'planned_revenue',
+ 'country_id', 'city', 'street', 'street2', 'zip']
+ for opportunity in opportunities:
+ subject.append(opportunity.name)
+ title = "%s : %s" % (merge_message, opportunity.name)
+ details.append(self._mail_body_text(cr, uid, opportunity, fields, title=title, context=context))
+
+ subject = subject[0] + ", ".join(subject[1:])
+ details = "\n\n".join(details)
+ return self.message_append(cr, uid, [opportunity_id], subject, body_text=details, context=context)
+
+ def _merge_opportunity_history(self, cr, uid, opportunity_id, opportunities, context=None):
+ message = self.pool.get('mail.message')
+ for opportunity in opportunities:
+ for history in opportunity.message_ids:
+ message.write(cr, uid, history.id, {
+ 'res_id': opportunity_id,
+ 'subject' : _("From %s : %s") % (opportunity.name, history.subject)
+ }, context=context)
+
+ return True
+
+ def _merge_opportunity_attachments(self, cr, uid, opportunity_id, opportunities, context=None):
+ attachment = self.pool.get('ir.attachment')
+
+ # return attachments of opportunity
+ def _get_attachments(opportunity_id):
+ attachment_ids = attachment.search(cr, uid, [('res_model', '=', self._name), ('res_id', '=', opportunity_id)], context=context)
+ return attachment.browse(cr, uid, attachment_ids, context=context)
+
+ count = 1
+ first_attachments = _get_attachments(opportunity_id)
+ for opportunity in opportunities:
+ attachments = _get_attachments(opportunity.id)
+ for first in first_attachments:
+ for attachment in attachments:
+ if attachment.name == first.name:
+ values = dict(
+ name = "%s (%s)" % (attachment.name, count,),
+ res_id = opportunity_id,
+ )
+ attachment.write(values)
+ count+=1
+
+ return True
+
+ def merge_opportunity(self, cr, uid, ids, context=None):
+ """
+ To merge opportunities
+ :param ids: list of opportunities ids to merge
+ """
+ if context is None: context = {}
+
+ #TOCHECK: where pass lead_ids in context?
+ lead_ids = context and context.get('lead_ids', []) or []
+
+ if len(ids) <= 1:
+ raise osv.except_osv(_('Warning !'),_('Please select more than one opportunities.'))
+
+ 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]
+ tail_opportunities = opportunities_list[1:]
+
+ fields = ['partner_id', 'title', 'name', 'categ_id', 'channel_id', 'city', 'company_id', 'contact_name', 'country_id',
+ 'partner_address_id', 'type_id', 'user_id', 'section_id', 'state_id', 'description', 'email', 'fax', 'mobile',
+ 'partner_name', 'phone', 'probability', 'planned_revenue', 'street', 'street2', 'zip', 'create_date', 'date_action_last',
+ 'date_action_next', 'email_from', 'email_cc', 'partner_name']
+
+ data = self._merge_data(cr, uid, ids, oldest, fields, context=context)
+
+ # merge data into first opportunity
+ self.write(cr, uid, [first_opportunity.id], data, context=context)
+
+ #copy message and attachements into the first opportunity
+ self._merge_opportunity_history(cr, uid, first_opportunity.id, tail_opportunities, context=context)
+ self._merge_opportunity_attachments(cr, uid, first_opportunity.id, tail_opportunities, context=context)
+
+ #Notification about loss of information
+ self._merge_notification(cr, uid, first_opportunity, opportunities, context=context)
+ #delete tail opportunities
+ self.unlink(cr, uid, [x.id for x in tail_opportunities], context=context)
+
+ #open first opportunity
+ self.case_open(cr, uid, [first_opportunity.id])
+ return first_opportunity.id
+
+ def _convert_opportunity_data(self, cr, uid, lead, customer, section_id=False, context=None):
+ crm_stage = self.pool.get('crm.case.stage')
+ contact_id = False
+ if customer:
+ 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_id = stage_ids and stage_ids[0] or False
+ return {
+ 'planned_revenue': lead.planned_revenue,
+ 'probability': lead.probability,
+ 'name': lead.name,
+ 'partner_id': customer and customer.id or False,
+ 'user_id': (lead.user_id and lead.user_id.id),
+ 'type': 'opportunity',
+ 'stage_id': stage_id or False,
+ 'date_action': time.strftime('%Y-%m-%d %H:%M:%S'),
+ 'partner_address_id': contact_id
+ }
+ 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._send_mail_to_salesman(cr, uid, lead, context=context)
+ return True
+
+ 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 = False
+ if partner_id:
+ customer = partner.browse(cr, uid, partner_id, context=context)
+ for lead in self.browse(cr, uid, ids, context=context):
+ 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:
+ msg_ids = [ x.id for x in lead.message_ids]
+ mail_message.write(cr, uid, msg_ids, {
+ 'partner_id': lead.partner_id.id
+ }, context=context)
+ return True
+
+ def _lead_create_partner(self, cr, uid, lead, context=None):
+ partner = self.pool.get('res.partner')
+ partner_id = partner.create(cr, uid, {
+ 'name': lead.partner_name or lead.contact_name or lead.name,
+ 'user_id': lead.user_id.id,
+ 'comment': lead.description,
+ 'section_id': lead.section_id.id or False,
+ 'address': []
+ })
+ return partner_id
+
+ def _lead_set_partner(self, cr, uid, lead, partner_id, context=None):
+ res = False
+ res_partner = self.pool.get('res.partner')
+ if partner_id:
+ res_partner.write(cr, uid, partner_id, {'section_id': lead.section_id.id or False})
+ contact_id = res_partner.address_get(cr, uid, [partner_id])['default']
+ res = lead.write({'partner_id' : partner_id, 'partner_address_id': contact_id}, context=context)
+
+ return res
+
+ def _lead_create_partner_address(self, cr, uid, lead, partner_id, context=None):
+ address = self.pool.get('res.partner.address')
+ return address.create(cr, uid, {
+ 'partner_id': partner_id,
+ 'name': lead.contact_name,
+ 'phone': lead.phone,
+ 'mobile': lead.mobile,
+ 'email': lead.email_from and to_email(lead.email_from)[0],
+ 'fax': lead.fax,
+ 'title': lead.title and lead.title.id or False,
+ 'function': lead.function,
+ 'street': lead.street,
+ 'street2': lead.street2,
+ 'zip': lead.zip,
+ 'city': lead.city,
+ 'country_id': lead.country_id and lead.country_id.id or False,
+ 'state_id': lead.state_id and lead.state_id.id or False,
+ })
+
+ def convert_partner(self, cr, uid, ids, action='create', 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 = {}
- context.update({'active_ids': ids})
+ partner_ids = {}
+ for lead in self.browse(cr, uid, ids, context=context):
+ 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_set_partner(cr, uid, lead, partner_id, context=context)
+ partner_ids[lead.id] = partner_id
+ return partner_ids
- data_obj = self.pool.get('ir.model.data')
- value = {}
+ def _send_mail_to_salesman(self, cr, uid, lead, context=None):
+ """
+ Send mail to salesman with updated Lead details.
+ @ lead: browse record of 'crm.lead' object.
+ """
+ #TOFIX: mail template should be used here instead of fix subject, body text.
+ message = self.pool.get('mail.message')
+ email_to = lead.user_id and lead.user_id.user_email
+ if not email_to:
+ return False
+
+ email_from = lead.section_id and lead.section_id.user_id and lead.section_id.user_id.user_email or email_to
+ partner = lead.partner_id and lead.partner_id.name or lead.partner_name
+ subject = "lead %s converted into opportunity" % lead.name
+ body = "Info \n Id : %s \n Subject: %s \n Partner: %s \n Description : %s " % (lead.id, lead.name, lead.partner_id.name, lead.description)
+ return message.schedule_with_attach(cr, uid, email_from, [email_to], subject, body)
- for case in self.browse(cr, uid, ids, context=context):
- context.update({'active_id': case.id})
- data_id = data_obj._get_id(cr, uid, 'crm', 'view_crm_lead2opportunity_partner')
- view_id1 = False
- if data_id:
- view_id1 = data_obj.browse(cr, uid, data_id, context=context).res_id
- value = {
- 'name': _('Create Partner'),
- 'view_type': 'form',
- 'view_mode': 'form,tree',
- 'res_model': 'crm.lead2opportunity.partner',
- 'view_id': False,
- 'context': context,
- 'views': [(view_id1, 'form')],
- 'type': 'ir.actions.act_window',
- 'target': 'new',
- 'nodestroy': True
+ def allocate_salesman(self, cr, uid, ids, user_ids, team_id=False, context=None):
+ index = 0
+ for lead_id in ids:
+ value = {}
+ if team_id:
+ value['section_id'] = team_id
+ if index < len(user_ids):
+ value['user_id'] = user_ids[index]
+ index += 1
+ if value:
+ self.write(cr, uid, [lead_id], value, context=context)
+ return True
+
+ def schedule_phonecall(self, cr, uid, ids, schedule_time, call_summary, desc, phone, contact_name, 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' : desc or '',
+ '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' : phone or 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,
}
- return value
+
+ 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')
+
+ # Get Opportunity views
+ form_view = models_data.get_object_reference(cr, uid, 'crm', 'crm_case_form_view_oppor')
+ tree_view = models_data.get_object_reference(cr, uid, 'crm', 'crm_case_tree_view_oppor')
+ return {
+ 'name': _('Opportunity'),
+ 'view_type': 'form',
+ 'view_mode': 'tree, form',
+ 'res_model': 'crm.lead',
+ 'domain': [('type', '=', 'opportunity')],
+ 'res_id': int(opportunity_id),
+ 'view_id': False,
+ 'views': [(form_view and form_view[1] or False, 'form'),
+ (tree_view and tree_view[1] or False, 'tree'),
+ (False, 'calendar'), (False, 'graph')],
+ 'type': 'ir.actions.act_window',
+ }
+
def message_new(self, cr, uid, msg, custom_values=None, context=None):
"""Automatically calls when new email message arrives"""
@@ -447,17 +791,10 @@ class crm_lead(crm_case, osv.osv):
data_obj = self.pool.get('ir.model.data')
for opp in self.browse(cr, uid, ids, context=context):
# Get meeting views
- result = data_obj._get_id(cr, uid, 'crm', 'view_crm_case_meetings_filter')
- res = data_obj.read(cr, uid, result, ['res_id'])
- id1 = data_obj._get_id(cr, uid, 'crm', 'crm_case_calendar_view_meet')
- id2 = data_obj._get_id(cr, uid, 'crm', 'crm_case_form_view_meet')
- id3 = data_obj._get_id(cr, uid, 'crm', 'crm_case_tree_view_meet')
- if id1:
- id1 = data_obj.browse(cr, uid, id1, context=context).res_id
- if id2:
- id2 = data_obj.browse(cr, uid, id2, context=context).res_id
- if id3:
- id3 = data_obj.browse(cr, uid, id3, context=context).res_id
+ tree_view = data_obj.get_object_reference(cr, uid, 'crm', 'crm_case_tree_view_meet')
+ form_view = data_obj.get_object_reference(cr, uid, 'crm', 'crm_case_form_view_meet')
+ calander_view = data_obj.get_object_reference(cr, uid, 'crm', 'crm_case_calendar_view_meet')
+ search_view = data_obj.get_object_reference(cr, uid, 'crm', 'view_crm_case_meetings_filter')
context.update({
'default_opportunity_id': opp.id,
'default_partner_id': opp.partner_id and opp.partner_id.id or False,
@@ -474,9 +811,9 @@ class crm_lead(crm_case, osv.osv):
'view_mode': 'calendar,form,tree',
'res_model': 'crm.meeting',
'view_id': False,
- 'views': [(id1, 'calendar'), (id2, 'form'), (id3, 'tree')],
+ 'views': [(calander_view and calander_view[1] or False, 'calendar'), (form_view and form_view[1] or False, 'form'), (tree_view and tree_view[1] or False, 'tree')],
'type': 'ir.actions.act_window',
- 'search_view_id': res['res_id'],
+ 'search_view_id': search_view and search_view[1] or False,
'nodestroy': True
}
return value
diff --git a/addons/crm/crm_lead_demo.xml b/addons/crm/crm_lead_demo.xml
index 576f258facc..830b572676d 100644
--- a/addons/crm/crm_lead_demo.xml
+++ b/addons/crm/crm_lead_demo.xml
@@ -1,6 +1,6 @@
-
+
@@ -9,8 +9,8 @@
-
-
+
+
@@ -92,7 +92,7 @@
-
+
diff --git a/addons/crm/crm_lead_view.xml b/addons/crm/crm_lead_view.xml
index 784a57fa398..6527fa4cf25 100644
--- a/addons/crm/crm_lead_view.xml
+++ b/addons/crm/crm_lead_view.xml
@@ -59,10 +59,11 @@
widget="selection"
domain="[('object_id.model','=','crm.lead')]"/>
+ type="action"
+ />
@@ -142,34 +143,6 @@
type="object" icon="gtk-convert" />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -222,6 +195,34 @@
name="%(mail.action_email_compose_message_wizard)d"
icon="terp-mail-message-new" type="action"/>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -459,7 +460,7 @@
Opportunities
crm.lead
form
- 10
+ 20
-
-
-
diff --git a/addons/crm/res_partner.py b/addons/crm/res_partner.py
index cbb05ee3e74..e2016f6d8aa 100644
--- a/addons/crm/res_partner.py
+++ b/addons/crm/res_partner.py
@@ -33,6 +33,44 @@ class res_partner(osv.osv):
'phonecall_ids': fields.one2many('crm.phonecall', 'partner_id',\
'Phonecalls'),
}
+
+ def redirect_partner_form(self, cr, uid, partner_id, context=None):
+ search_view = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'base', 'view_res_partner_filter')
+ 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': search_view and search_view[1] or False
+ }
+ 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 = {}
+ for partner in self.browse(cr, uid, ids, context=context):
+ 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_summary,
+ 'planned_revenue' : planned_revenue,
+ 'probability' : probability,
+ 'partner_id' : partner_id,
+ 'partner_address_id' : address,
+ 'categ_id' : categ_ids and categ_ids[0] or '',
+ 'state' :'draft',
+ 'type': 'opportunity'
+ })
+ 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
new file mode 100644
index 00000000000..a5f85a14058
--- /dev/null
+++ b/addons/crm/test/process/cancel_lead.yml
@@ -0,0 +1,53 @@
+-
+ I cancel unqualified lead.
+-
+ !python {model: crm.lead}: |
+ self.case_cancel(cr, uid, [ref("crm_case_itisatelesalescampaign0")])
+-
+ I check cancelled lead.
+-
+ !assert {model: crm.lead, id: crm.crm_case_itisatelesalescampaign0, string: Lead is in cancel state}:
+ - state == "cancel"
+-
+ I reset cancelled lead into unqualified lead.
+-
+ !python {model: crm.lead}: |
+ self.case_reset(cr, uid, [ref("crm_case_itisatelesalescampaign0")])
+-
+ I check unqualified lead after reset.
+-
+ !assert {model: crm.lead, id: crm.crm_case_itisatelesalescampaign0, string: Lead is in draft state}:
+ - state == "draft"
+-
+ I put unqualified lead into pending.
+-
+ !python {model: crm.lead}: |
+ self.case_pending(cr, uid, [ref("crm_case_itisatelesalescampaign0")])
+-
+ I check status of pending lead.
+-
+ !assert {model: crm.lead, id: crm.crm_case_itisatelesalescampaign0, string: Lead is in pending state}:
+ - state == "pending"
+-
+ I Escalate the Lead to Parent Team.
+-
+ !python {model: crm.lead}: |
+ self.case_escalate(cr, uid, [ref("crm_case_itisatelesalescampaign0")])
+-
+ I check lead escalate to Parent Team.
+-
+ !assert {model: crm.lead, id: crm.crm_case_itisatelesalescampaign0, string: Escalate lead to parent team}:
+ - section_id.name == "Sales Department"
+-
+ I mark as lost the opportunity.
+-
+ !python {model: crm.lead}: |
+ self.case_mark_lost(cr, uid, [ref("crm_case_itisatelesalescampaign0")])
+-
+ I check opportunity after lost.
+-
+ !python {model: crm.lead}: |
+ lead = self.browse(cr, uid, ref('crm_case_itisatelesalescampaign0'))
+ assert lead.state == 'done', "lead is not done state"
+ assert lead.stage_id.id == ref('crm.stage_lead6'), 'Stage is not changed!'
+ assert lead.probability == 0.0, 'Probability is wrong!'
diff --git a/addons/crm/test/process/communication_with_customer.yml b/addons/crm/test/process/communication_with_customer.yml
new file mode 100644
index 00000000000..92e711ce016
--- /dev/null
+++ b/addons/crm/test/process/communication_with_customer.yml
@@ -0,0 +1,56 @@
+-
+ Customer interested in our product. so He send request by email to get more details.
+-
+ 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}: |
+ 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"
+-
+ 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", 'email_from': 'sales@mycompany.com'}, 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}: |
+ lead_ids = self.search(cr, uid, [('email_from','=', 'Mr. John Right ')])
+ self.convert_partner(cr, uid, lead_ids, context=context)
+-
+ Now, I search customer in regular customer list.
+-
+ !python {model: crm.lead}: |
+ 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."
+-
+ I convert one phonecall request as a customer and put into regular customer list.
+-
+ !python {model: crm.phonecall}: |
+ self.convert_partner(cr, uid, [ref('crm.crm_case_phone06')], context=context)
+-
+ I check converted phonecall to partner.
+-
+ !python {model: res.partner}: |
+ partner_id = self.search(cr, uid, [('phonecall_ids', '=', ref('crm.crm_case_phone06'))])
+ assert partner_id, "Customer is not found in regular customer list."
+ data = self.browse(cr, uid, partner_id, context=context)[0]
+ assert data.user_id.id == ref("base.user_root"), "User not assign properly"
+ assert data.name == "Bad time", "User not assign properly"
diff --git a/addons/crm/test/process/lead2opportunity2win.yml b/addons/crm/test/process/lead2opportunity2win.yml
new file mode 100644
index 00000000000..dbc04abae19
--- /dev/null
+++ b/addons/crm/test/process/lead2opportunity2win.yml
@@ -0,0 +1,90 @@
+-
+ In order to test convert customer lead into opportunity,
+-
+ I open customer lead.
+-
+ !python {model: crm.lead}: |
+ self.case_open(cr, uid, [ref("crm_case_qrecorp0")])
+-
+ I check lead state is "Open".
+-
+ !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"))
+-
+ I check details of converted opportunity.
+-
+ !python {model: crm.lead}: |
+ lead = self.browse(cr, uid, ref('crm_case_qrecorp0'))
+ assert lead.type == 'opportunity', 'Lead is not converted to opportunity!'
+ 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!'
+-
+ Now I begin communication and schedule a phone call with the 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)
+-
+ I check that phonecall is scheduled for that opportunity.
+-
+ !python {model: crm.phonecall}: |
+ ids = self.search(cr, uid, [('opportunity_id', '=', ref('crm_case_qrecorp0'))])
+ assert len(ids), 'phonecall is not scheduled'
+-
+ Now I schedule Meeting with Customer.
+-
+ !python {model: crm.lead}: |
+ self.action_makeMeeting(cr, uid, [ref('crm_case_qrecorp0')])
+
+-
+ 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")])
+-
+ I check details of the opportunity After won the opportunity.
+-
+ !python {model: crm.lead}: |
+ lead = self.browse(cr, uid, ref('crm_case_qrecorp0'))
+ assert lead.state == 'done', 'Opportunity is not in done state!'
+ assert lead.stage_id.name == 'Won', ' Stage of Opportunity is not win!'
+ assert lead.probability == 100.0, 'probability revenue should not be 100.0!'
+-
+ I convert mass lead into opportunity customer.
+-
+ !python {model: crm.lead2opportunity.partner.mass}: |
+ context.update({'active_model': 'crm.lead', 'active_ids': [ref("crm_case_employee0"), ref("crm_case_electonicgoodsdealer0")], 'active_id': ref("crm_case_qrecorp0")})
+ id = self.create(cr, uid, {'user_ids': [ref('base.user_root')], 'section_id': ref('crm.section_sales_department')}, context=context)
+ self.mass_convert(cr, uid, [id], context=context)
+-
+ Now I check First lead converted on opportunity.
+-
+ !python {model: crm.lead}: |
+ opp = self.browse(cr, uid, ref('crm_case_employee0'))
+ assert opp.name == "Need Info about Onsite Intervention", "Opportunity name not correct"
+ assert opp.type == 'opportunity', 'Lead is not converted to opportunity!'
+ assert opp.partner_id.name == "Agrolait", 'Partner missmatch!'
+ assert opp.stage_id.id == ref("stage_lead1"), 'Stage of probability is incorrect!'
+-
+ Then check for Second lead converted on opportunity.
+-
+ !python {model: crm.lead}: |
+ opp = self.browse(cr, uid, ref('crm_case_electonicgoodsdealer0'))
+ assert opp.name == "Interest in Your New Product", "Opportunity name not correct"
+ assert opp.type == 'opportunity', 'Lead is not converted to opportunity!'
+ assert opp.stage_id.id == ref("stage_lead1"), 'Stage of probability is incorrect!'
\ No newline at end of file
diff --git a/addons/crm/test/process/merge_opportunity.yml b/addons/crm/test/process/merge_opportunity.yml
new file mode 100644
index 00000000000..463e330fc10
--- /dev/null
+++ b/addons/crm/test/process/merge_opportunity.yml
@@ -0,0 +1,51 @@
+-
+ 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}: |
+ opportunity_ids = self.search(cr, uid, [('partner_id','=', ref("base.res_partner_9"))])
+ self.merge_opportunity(cr, uid, opportunity_ids, context=context)
+-
+ I check for merged opportunities for customer.
+-
+ !python {model: crm.lead}: |
+ merge_id = self.search(cr, uid, [('partner_id','=', ref("base.res_partner_9"))])
+ assert merge_id, 'Fail to create Merge opportunity'
+ merge_data = self.browse(cr, uid, merge_id)[0]
+ assert merge_data.type == 'opportunity', 'Merged opportunity type not change!'
+ assert merge_data.partner_id.id == ref("base.res_partner_9"), 'Partner missmatch!'
+-
+ 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)
+-
+ I schedule Meeting on this phonecall.
+-
+ !python {model: crm.phonecall}: |
+ self.action_make_meeting(cr, uid, [ref("crm.crm_case_phone06")])
+-
+ I setting Phone call to Held (Done).
+-
+ !python {model: crm.phonecall}: |
+ self.case_close(cr, uid, [ref("crm.crm_case_phone06")])
+-
+ I check that the phone call is in 'Held' state.
+-
+ !assert {model: crm.phonecall, id: crm.crm_case_phone06, string: Phone call Helded}:
+ - state == "done"
diff --git a/addons/crm/test/process/segmentation.yml b/addons/crm/test/process/segmentation.yml
new file mode 100644
index 00000000000..74500049290
--- /dev/null
+++ b/addons/crm/test/process/segmentation.yml
@@ -0,0 +1,16 @@
+-
+ In order to test segmentation process which create specific partner categories criteria,
+-
+ I start the process.
+-
+ !python {model: crm.segmentation}: |
+ self.process_start(cr, uid, [ref("crm_segmentation0")],context)
+ #Todo: Need to check after segmentation started
+
+-
+ I create rule Segmentation line record for partner .
+-
+ !python {model: crm.segmentation.line}: |
+ id = self.create(cr, uid, {'name': "OpenERP partners",'expr_value': 25})
+ self.test(cr, uid, [id],partner_id=0)
+ #Todo: Need to test segmantation line record
\ No newline at end of file
diff --git a/addons/crm/test/test_crm_lead.yml b/addons/crm/test/test_crm_lead.yml
deleted file mode 100644
index d5d3c6b933b..00000000000
--- a/addons/crm/test/test_crm_lead.yml
+++ /dev/null
@@ -1,154 +0,0 @@
--
- In order to test the CRM in OpenERP, I will do a customer qualification
- process that starts with a fist contact with a customer (a lead), which will
- be converted to a business opportunity and a partner.
--
- I create a two new users "user_crm" and I assign the group "salesman".
--
- !record {model: res.users, id: res_users_usercrm0}:
- company_id: base.main_company
- context_lang: en_US
- context_section_id: crm.section_sales_department
- groups_id:
- - base.group_sale_salesman
- login: user_crm
- name: user_crm
- password: user_crm
-
-- |
- I start by creating a new lead "New Customer" and I provide an address to this
- new customer, as well as an email "info@mycustomer.com".
--
- !record {model: crm.lead, id: crm_lead_newcustomer0}:
- email_from: info@mycustomer.com
- name: New Customer
- partner_name: Capegemini
- partner_id: base.res_partner_9
- phone: (855) 924-4364
- mobile: (333) 715-1450
- section_id: crm.section_sales_department
- referred: False
-- |
- I check that the lead is in 'draft' state.
--
- !assert {model: crm.lead, id: crm_lead_newcustomer0, string: Lead in Draft}:
- - state == "draft"
--
- I open lead by click on "Open" button.
--
- !python {model: crm.lead}: |
- self.case_open(cr, uid, [ref("crm_lead_newcustomer0")])
- fields={
- 'day_open': 0.0,
- 'day_close': 0.0
- }
- self._compute_day(cr, uid, [ref("crm_lead_newcustomer0")], fields, context)
-- |
- I check that lead is now in 'open' state.
--
- !assert {model: crm.lead, id: crm_lead_newcustomer0, string: Lead in open state}:
- - state == "open"
--
- I search id for case object.
--
- !python {model: crm.case.categ}: |
- self._find_object_id(cr, uid, context)
-- |
- As the lead seems to be a real business opportunity, I will convert it to a
- partner
- and a business opportunity by clicking on the "Convert" button.
--
- !python {model: crm.lead}: |
- lead = self.browse(cr, uid, ref('crm_lead_newcustomer0'))
- action = self.convert_opportunity(cr, uid, [ref("crm_lead_newcustomer0")], {'active_ids': [ref("crm_lead_newcustomer0")]})
- assert action['res_model'] == 'crm.lead2opportunity.partner'
--
- |
- I select "create a new partner" option.
--
- !record {model: crm.lead2opportunity.partner, id: crm_lead2opportunity_partner_create_0}:
- action: 'create'
- name: 'convert'
--
- Then, Click on "Create Opportunity" button.
--
- !python {model: crm.lead2opportunity.partner}: |
- self.action_apply(cr, uid, [ref("crm_lead2opportunity_partner_create_0")], {'active_ids': [ref("crm_lead_newcustomer0")], 'active_id': ref("crm_lead_newcustomer0")})
--
- |
- I select "Link to an existing partner" option.
--
- !record {model: crm.lead2opportunity.partner, id: crm_lead2opportunity_partner_create_1}:
- action: 'exist'
--
- Then, Click on "Create Opportunity" button.
--
- !python {model: crm.lead2opportunity.partner}: |
- self.action_apply(cr, uid, [ref("crm_lead2opportunity_partner_create_1")], {'active_ids': [ref("crm_lead_newcustomer0")], 'active_id': ref("crm_lead_newcustomer0")})
--
- |
- I select "Do not link to a partner" option.
--
- !record {model: crm.lead2opportunity.partner, id: crm_lead2opportunity_partner_create_2}:
- action: 'nothing'
--
- Then, Click on "Create Opportunity" button.
--
- !python {model: crm.lead2opportunity.partner}: |
- self.action_apply(cr, uid, [ref("crm_lead2opportunity_partner_create_2")], {'active_ids': [ref("crm_lead_newcustomer0")], 'active_id': ref("crm_lead_newcustomer0")})
-- |
- In order to check the opportunity is created or not, I check type.
--
- !python {model: crm.lead}: |
- lead = self.browse(cr, uid, ref("crm_lead_newcustomer0"))
- assert lead.type == 'opportunity'
-
--
- I create mass report of lead to opprtunity partner.
--
- !record {model: crm.lead2opportunity.partner.mass, id: crm_lead2opportunity_partner_mass0}:
- user_ids:
- - base.user_root
- section_id: crm.section_sales_department
--
- Then, execute that mass wizard.
--
- !python {model: crm.lead2opportunity.partner.mass}: |
- self.mass_convert(cr, uid, [ref("crm_lead2opportunity_partner_mass0")],{'active_ids': [ref("crm_lead_newcustomer0")], 'active_id': ref("crm_lead_newcustomer0")})
--
- I close lead by click on "close" button.
--
- !python {model: crm.lead}: |
- self.case_close(cr, uid, [ref("crm_lead_newcustomer0")])
-- |
- I check that lead is now in 'done' state.
--
- !assert {model: crm.lead, id: crm_lead_newcustomer0, string: Lead in done state}:
- - state == "done"
--
- I cancel lead by click on "cancel" button.
--
- !python {model: crm.lead}: |
- self.case_cancel(cr, uid, [ref("crm_lead_newcustomer0")])
-- |
- I check that lead is now in 'cancel' state.
--
- !assert {model: crm.lead, id: crm_lead_newcustomer0, string: Lead in cancel state}:
- - state == "cancel"
-
-#-
-# |
-# yaml is also not working with smtp server and send new email.
-
-- |
- I configure with smtp server.
-- |
- And I communicate with lead through send New mail to Lead using its email address from the user who is logged in.
-- |
- I check that communication history generated when send email to lead.
-- |
- Then, I add a cc which receive copy of future communication between partner and users by mail.
-
-- |
- I Reply to last Email to lead with some document attached.and check that communication history generated or not.
-
diff --git a/addons/crm/test/test_crm_lead_case2.yml b/addons/crm/test/test_crm_lead_case2.yml
deleted file mode 100644
index 23a654d31a8..00000000000
--- a/addons/crm/test/test_crm_lead_case2.yml
+++ /dev/null
@@ -1,151 +0,0 @@
--
- In order to do complete test the CRM in OpenERP,
- I will create new full configured record and carry test on it.
-- |
- I Start by creating "Test Sales Team" with No Unlink.
- I create a crm.case.section record.
--
- !record {model: crm.case.section, id: crm_case_section_demosalesteam}:
- code: DEMO
- complete_name: Test Sales Team
- name: Test Sales Team
- allow_unlink: False
- member_ids:
- - base.user_admin
- stage_ids:
- - crm.stage_lead1
- - crm.stage_lead2
- - crm.stage_lead3
- - crm.stage_lead4
- - crm.stage_lead5
- - crm.stage_lead6
- working_hours: 0.0
- resource_calendar_id: resource.timesheet_group1
- parent_id: crm.section_sales_department
--
- I assign segmentation.
--
- !record {model: res.users, id: res_users_usercrm0}:
- context_section_id: crm_case_section_demosalesteam
-- |
- I create a new lead "Test Customer" and I provide an address to this
- demo customer and email "info@democustomer.com" and Also "Test Sales Team".
--
- !record {model: crm.lead, id: crm_lead_democustomer}:
- email_from: info@democustomer.com
- name: Test Customer
- partner_name: NotSoTinySARL
- phone: (+32).81.81.37.00
- mobile: (+32).81.81.37.00
- section_id: crm_case_section_demosalesteam
- referred: False
- type: lead
--
- I check that the lead is in 'draft' state.
--
- !assert {model: crm.lead, id: crm_lead_democustomer, string: Lead in Draft}:
- - state == "draft"
--
- I create categories.
--
- !record {model: crm.case.categ, id: crm_case_categ0}:
- name: crm_case_section_demosalesteam
- section_id: crm_case_section_demosalesteam
--
- I assigning contact detail to the Lead "Test Customer" without address.
--
- !python {model: crm.lead}: |
- self.onchange_partner_address_id(cr, uid, ref("crm_lead_democustomer"), None, email=False)
-
--
- I assigning contact detail to the Lead "Test Customer" with address.
--
- !python {model: crm.lead}: |
- self.onchange_partner_address_id(cr, uid, ref("crm_lead_democustomer"), ref("base.res_partner_address_notsotinysarl0"), email=False)
-
--
- I selecting email "Opt-out" option for the "Test Customer" Lead.
--
- !python {model: crm.lead}: |
- self.on_change_optout(cr, uid, ref("crm_lead_democustomer"), True)
-
--
- I change the Opt-out to Opt-in to show email receive preference.
--
- !python {model: crm.lead}: |
- self.on_change_optin(cr, uid, ref("crm_lead_democustomer"), True)
--
- I open lead by click on "Open" button.
--
- !python {model: crm.lead}: |
- self.case_open(cr, uid, [ref("crm_lead_democustomer")])
--
- I check that lead "Test Customer" is now in 'open' state.
--
- !assert {model: crm.lead, id: crm_lead_democustomer, string: Lead in open state}:
- - state == "open"
--
- I reset the lead "Test Customer".
--
- !python {model: crm.lead}: |
- self.case_reset(cr, uid, [ref("crm_lead_democustomer")])
--
- I again opening lead by click on "Open" button.
--
- !python {model: crm.lead}: |
- self.case_open(cr, uid, [ref("crm_lead_democustomer")])
--
- I setting stage "New" for the lead "Test Customer".
--
- !python {model: crm.lead}: |
- self.stage_next(cr, uid, [ref("crm_lead_democustomer")], context={'stage_type': 'lead'})
--
- I try to Unlink the Lead "Test Customer" demo Lead.
--
- !python {model: crm.lead}: |
- try:
- self.unlink(cr, uid, [ref("crm_lead_democustomer")])
- except:
- pass
--
- I setting Lead "Test Customer" to Pending State.
--
- !python {model: crm.lead}: |
- self.case_pending(cr, uid, [ref("crm_lead_democustomer")])
--
- I check that lead "Test Customer" is now in 'Pending' state.
--
- !assert {model: crm.lead, id: crm_lead_democustomer, string: Lead in Pending state}:
- - state == "pending"
--
- I Escalate the Lead "Test Customer" Parent "Sales Team".
--
- !python {model: crm.lead}: |
- self.case_escalate(cr, uid, [ref("crm_lead_democustomer")])
--
- I add Internal Note Saying Escalated Reason.
--
- !record {model: crm.add.note, id: crm_add_note_0}:
- body: Sales Lead Has Been Escalated Due to Some Technical reason to the parent 'Sales
- Team'
- state: unchanged
--
- I click a note button to attach the record.
--
- !python {model: crm.add.note}: |
- context['active_model'] = "crm.lead"
- context['active_ids'] = [ref("crm_lead_democustomer")]
- self.action_add(cr, uid, [ref("crm_add_note_0")], context=context)
-
--
- I Copying this lead "Test Customer" to New Lead.
--
- !python {model: crm.lead}: |
- self.copy(cr, uid, ref("crm_lead_democustomer"))
--
- I checking the Lead Copied or Not.
--
- !python {model: crm.lead}: |
- sid = self.search(cr, uid, [('name', '=', 'Test Customer'),('state', '=', 'draft')])
- if not sid:
- raise AssertionError("Lead is not copied Successfully")
diff --git a/addons/crm/test/test_crm_meeting.yml b/addons/crm/test/test_crm_meeting.yml
deleted file mode 100644
index 1aee11463dd..00000000000
--- a/addons/crm/test/test_crm_meeting.yml
+++ /dev/null
@@ -1,97 +0,0 @@
-- |
- I will test Meetings which may be customer meeting or phonecall meeting or
- internal Meeting.
-- |
- I start by creating a new Meeting.
--
- !record {model: crm.meeting, id: crm_meeting_regardingpresentation0}:
- categ_id: crm.categ_meet2
- date: !eval time.strftime('%Y-%m-%d 16:04:00')
- date_deadline: !eval "(datetime.now() + timedelta(1)).strftime('%Y-%m-%d 00:04:00')"
- duration: 8.0
- email_from: info@balmerinc.be
- location: Ahmedabad
- name: Regarding Presentation
- partner_address_id: base.res_partner_address_1
- partner_id: base.res_partner_9
- rrule_type: weekly
- section_id: crm.section_sales_department
-- |
- I check that the Meetings is in 'UnConfirmed' state.
--
- !assert {model: crm.meeting, id: crm_meeting_regardingpresentation0}:
- - state == "draft"
-- |
- I can set reminder on meeting if I put reminder "40 minutes before" .
-- |
- For that, I first create alarm.
--
- !record {model: res.alarm, id: res_alarm_minituesbefore0}:
- name: 40 minutes before
- trigger_duration: 40
- trigger_interval: minutes
- trigger_occurs: before
- trigger_related: start
-- |
- I will assign this reminder.
-
-- !python {model: crm.meeting}: |
- self.write(cr, uid, [ref('crm_meeting_regardingpresentation0')], {'alarm_id': ref("res_alarm_minituesbefore0")})
-- |
- In order to check recurrence on meetings I will set Recurrency to Custom
- and I set the fields so that the meeting will occur weekly on Monday and Friday 10 times.
--
- !python {model: crm.meeting}: |
- self.write(cr, uid, [ref("crm_meeting_regardingpresentation0")], {'fr': 1, 'mo': 1, 'th': 1, 'tu': 1, 'we':1, 'count':10, 'interval': 1, 'rrule_type': 'weekly', 'recurrency' : True})
-
-- |
- I can see from the calendar view that the meeting is scheduled on Monday and Friday
- for 10 times.
-
--
- !python {model: crm.meeting}: |
- self.fields_view_get(cr, uid, False, 'calendar', context)
-- |
- I will search for one of the recurrent event and count the number of meeting.
--
- !python {model: crm.meeting}: |
- import time
- from datetime import datetime, date, timedelta
- ids = self.search(cr, uid, [('date', '>=', time.strftime('%Y-%m-%d 00:00:00')), ('date', '<=', (datetime.now()+timedelta(31)).strftime('%Y-%m-%d 00:00:00')), ('name', '=', 'Regarding Presentation')], context={'virtual_id': True})
- assert len(ids) == 10
-
-- |
- If I want to edit meetings information for all occurrence I click on "Edit All" button.
--
- !python {model: crm.meeting}: |
- self.write(cr, uid, [ref('crm_meeting_regardingpresentation0')], {'edit_all':'True'},context)
-- |
- I can see that new meeting form is opened with same value.
- I change some data for meeting and save it.
- I can see from meeting's calendar view that all meeting occurrences are changed accordingly.
--
- !record {model: crm.meeting, id: crm.crm_meeting_regardingpresentation0}:
- alarm_id: base_calendar.alarm9
- rrule_type: weekly
-
-- |
- In order to invite people for this meetings, I click on "Invite People" button
- I can invite internal user.
--
- !record {model: base_calendar.invite.attendee, id: base_calendar_invite_attendee_0}:
- type: internal
- send_mail: False
- partner_id: base.res_partner_9
- user_ids:
- - base.user_demo
--
- I click on "Invite" button of "Invite attendee" wizard.
--
- !python {model: base_calendar.invite.attendee}: |
- self.do_invite(cr, uid, [ref('base_calendar_invite_attendee_0')], {'active_id': ref('crm_meeting_regardingpresentation0'), 'model' : 'crm.meeting', 'attendee_field':'attendee_ids'})
-
-- |
- After direct/indirect confirmation for meetings I can confirm meeting.
--
- !python {model: crm.meeting}: |
- self.case_open(cr, uid, [ref('crm_meeting_regardingpresentation0')])
diff --git a/addons/crm/test/test_crm_opportunity.yml b/addons/crm/test/test_crm_opportunity.yml
deleted file mode 100644
index 734a1cae46c..00000000000
--- a/addons/crm/test/test_crm_opportunity.yml
+++ /dev/null
@@ -1,113 +0,0 @@
-- |
- I start by creating a new Opportunity. And I select partner for opportunity.
- I can see that after selecting partner his contact and email is automatically filled.
--
- !record {model: crm.lead, id: crm_opportunity_abcfuelcounits0}:
- email_from: info@balmerinc.be
- name: 'ABC FUEL CO 829264 - 10002 units'
- partner_address_id: base.res_partner_address_1
- partner_id: base.res_partner_9
- probability: 1.0
- stage_id: crm.stage_lead1
- categ_id: crm.categ_oppor2
- section_id: crm.section_sales_department
-- |
- I check that the opportunity is in 'New' state.
--
- !assert {model: crm.lead, id: crm_opportunity_abcfuelcounits0}:
- - state == "draft"
-
-- |
- I check that phonecall record is created for that opportunity.
--
- !python {model: crm.phonecall}: |
- phone_obj = self.pool.get('crm.phonecall')
-- |
- I schedule Meeting on this current opportunity by clicking on "schedule
- Meeting".
--
- !python {model: crm.lead}: |
- self.action_makeMeeting(cr, uid, [ref("crm_opportunity_abcfuelcounits0")])
-
-- |
- I can see that Meeting's calendar view is shown.
- then I click on the date on which I want to schedule meeting.
- I fill proper data for that meeting and save it.
--
- !record {model: crm.meeting, id: crm_meeting_abcfuelcounits0}:
- date: !eval time.strftime('%Y-%m-%d 00:00:00')
- date_deadline: !eval time.strftime('%Y-%m-%d 08:00:00')
- duration: 8.0
- email_from: info@balmerinc.be
- name: 'ABC FUEL CO 829264 - 10002 units'
- opportunity_id: 'crm_opportunity_abcfuelcounits0'
- partner_address_id: base.res_partner_address_1
- partner_id: base.res_partner_9
- section_id: crm.section_sales_department
- state: open
-- |
- In order to schedule a phonecall to the partner
- I click on "schedule call" button and select planned date for the call.
--
- !record {model: crm.opportunity2phonecall, id: crm_opportunity2phonecall_abcfuelcounits0}:
- date: !eval "(datetime.now() + timedelta(1)).strftime('%Y-%m-%d 11:15:00')"
- name: 'ABC FUEL CO 829264 - 10002 units'
- section_id: crm.section_sales_department
- user_id: base.user_demo
- categ_id: crm.categ_phone1
-- |
- schedule phonecall by opportunity2phoncall wizard.
--
- !python {model: crm.opportunity2phonecall}: |
- self.action_apply(cr, uid, [ref('crm_opportunity2phonecall_abcfuelcounits0')], {'active_ids': [ref("crm_opportunity_abcfuelcounits0")]})
-- |
- I check that phonecall record is created for that opportunity.
--
- !python {model: crm.phonecall}: |
- phone_obj = self.pool.get('crm.phonecall')
- ids = phone_obj.search(cr, uid, [('name', '=', 'ABC FUEL CO 829264 - 10002 units')])
- assert len(ids)
-- |
- I can see phonecall record after click on "Schedule call" wizard.
--
- !record {model: crm.phonecall, id: crm_phonecall_abcfuelcounits0}:
- date: !eval "(datetime.now() + timedelta(1)).strftime('%Y-%m-%d 11:15:00')"
- duration: 3.0
- name: 'ABC FUEL CO 829264 - 10002 units'
- partner_address_id: base.res_partner_address_1
- partner_id: base.res_partner_9
- section_id: crm.section_sales_department
-- |
- I Merge the opportunities.
--
- for that create two opportunities first opportunity 'Test FUEL CO'.
--
- !record {model: crm.lead, id: crm_opportunity_1}:
- email_from: info@balmerinc.be
- name: 'Test FUEL CO 829264 - 10002 units'
- partner_address_id: base.res_partner_address_1
- partner_id: base.res_partner_9
- probability: 1.0
- stage_id: crm.stage_lead1
- categ_id: crm.categ_oppor2
- section_id: crm.section_sales_department
--
- I create the opportunity 'FUEL CO'.
--
- !record {model: crm.lead, id: crm_opportunity_2}:
- email_from: info@balmerinc.be
- name: 'FUEL CO 829264 - 10002 units'
- partner_address_id: base.res_partner_address_1
- partner_id: base.res_partner_9
- probability: 1.0
- stage_id: crm.stage_lead1
- categ_id: crm.categ_oppor2
- section_id: crm.section_sales_department
-- |
- I Merge two Opportunities.
--
- !python {model: crm.merge.opportunity}: |
- op_list = [ref('crm_opportunity_1'),ref('crm_opportunity_2')]
- op_ids=self.pool.get('crm.lead').browse(cr,uid,op_list)
- lead_ids = [ref('crm_lead_newcustomer0')]
- self.merge(cr, uid, op_ids, {'lead_ids': lead_ids})
diff --git a/addons/crm/test/test_crm_opportunity_case2.yml b/addons/crm/test/test_crm_opportunity_case2.yml
deleted file mode 100644
index dc0dbe517f1..00000000000
--- a/addons/crm/test/test_crm_opportunity_case2.yml
+++ /dev/null
@@ -1,45 +0,0 @@
-- |
- I start by creating a new Opportunity. And I select partner for opportunity.
- I can see that after selecting partner his contact and email is automatically filled.
--
- !record {model: crm.lead, id: crm_opportunity_demotestopportunity}:
- email_from: info@balmerinc.be
- name: 'Demo Test Opportunity'
- partner_address_id: base.res_partner_address_1
- partner_id: base.res_partner_9
- probability: 1.0
- categ_id: crm.categ_oppor2
- section_id: crm.section_sales_department
- type: opportunity
--
- I check that the opportunity is in 'New' state.
--
- !assert {model: crm.lead, id: crm_opportunity_demotestopportunity, string: Opportunity in Draft}:
- - state == "draft"
--
- I open opportunity by click on "Open" button.
--
- !python {model: crm.lead}: |
- self.case_open(cr, uid, [ref("crm_opportunity_demotestopportunity")])
--
- I change partner of the opportunity.
--
- !python {model: crm.lead}: |
- self.onchange_partner_id(cr, uid, [ref("crm_opportunity_demotestopportunity")], ref("base.res_partner_agrolait"))
-
--
- I change Contact Detail of the opportunity.
--
- !python {model: crm.lead}: |
- self.onchange_partner_address_id(cr, uid,[ref("crm_opportunity_demotestopportunity")], ref("base.res_partner_address_8invoice"))
-
--
- I change Opportunity to Won State.
--
- !python {model: crm.lead}: |
- self.case_mark_won(cr, uid, [ref("crm_opportunity_demotestopportunity")])
--
- I check that the opportunity is in 'Done' state.
--
- !assert {model: crm.lead, id: crm_opportunity_demotestopportunity, string: Opportunity is Won}:
- - state == "done"
diff --git a/addons/crm/test/test_crm_partner2opportunity.yml b/addons/crm/test/test_crm_partner2opportunity.yml
deleted file mode 100644
index fe026074f4f..00000000000
--- a/addons/crm/test/test_crm_partner2opportunity.yml
+++ /dev/null
@@ -1,25 +0,0 @@
-- |
- I start by creating a new opportunity from partner.
--
- !record {model: crm.partner2opportunity, id: crm_partner2opportunity_id_0}:
- name: test
- planned_revenue: 0.0
- partner_id: base.res_partner_9
- probability: 0.0
--
- I click on "Create Opportunity" button of this wizard.
--
- !python {model: crm.partner2opportunity}: |
- fields = {
- 'name': 'test',
- 'planned_revenue': '0.0',
- 'partner_id': ref('base.res_partner_9'),
- 'probability': '0.0'
- }
- self.default_get(cr, uid, fields, {"active_ids": [ref("crm_partner2opportunity_id_0")]})
-- |
- In order to check the opportunity is created or not, I check type.
--
- !python {model: crm.partner2opportunity}: |
- opportunity = self.make_opportunity(cr, uid, [ref("crm_partner2opportunity_id_0")], {"active_ids": [ref("crm_partner2opportunity_id_0")]})
- assert True
diff --git a/addons/crm/test/test_crm_phonecall.yml b/addons/crm/test/test_crm_phonecall.yml
deleted file mode 100644
index 0754a5b9544..00000000000
--- a/addons/crm/test/test_crm_phonecall.yml
+++ /dev/null
@@ -1,116 +0,0 @@
-- |
- I start by creating a new phonecall.
--
- !record {model: crm.phonecall, id: crm_phonecall_interviewcall0}:
- date: !eval time.strftime('%Y-%m-%d 08:00:00')
- name: Interview call
- duration: 2.0
- section_id: crm.section_sales_department
--
- I select partner by click on "Create a Partner" button.
--
- !record {model: crm.phonecall2partner, id: crm_phonecall2partner_1}:
- action: exist
- partner_id: base.res_partner_9
-
--
- I click on "Continue" button of this wizard and make partner.
--
- !python {model: crm.phonecall2partner}: |
-
- self._select_partner(cr, uid,{"active_ids": [ref("crm_phonecall_interviewcall0")]})
- self.open_create_partner(cr, uid, [ref("crm_phonecall2partner_1")], {"active_ids": [ref("crm_phonecall_interviewcall0")]})
- self.make_partner(cr, uid, [ref("crm_phonecall2partner_1")], {"active_ids": [ref("crm_phonecall_interviewcall0")]})
-
-- |
- As the success of phonecall seems to be a real business opportunity, I will convert
- it to opportunity by clicking on the "Convert to Opportunity" button.
--
- !record {model: crm.phonecall2opportunity, id: crm_phonecall2opportunity_interviewcall0}:
- name: Interview call
- partner_id: base.res_partner_9
- planned_revenue: 0.0
- probability: 0.0
-- |
- I can see that a business opportunity is now assigned to this phonecall
--
- !assert {model: crm.phonecall, id: crm_phonecall_interviewcall0}:
- - opportunity_id != False
--
- I click on "Convert" button of this wizard.
--
- !python {model: crm.phonecall2opportunity}: |
- self.action_apply(cr, uid, [ref("crm_phonecall2opportunity_interviewcall0")], {"active_id": ref("crm_phonecall_interviewcall0")})
-- |
- And I check that the phonecall and the newly created business opportunity is linked
- to same partner.
--
- !python {model: crm.phonecall}: |
- obj_phonecall = self.browse(cr, uid, ref('crm_phonecall_interviewcall0'))
- ids = self.pool.get('crm.lead').search(cr, uid, [('name', '=', obj_phonecall.opportunity_id.name)])
- obj_opp = self.pool.get('crm.lead').browse(cr, uid, ids)[0]
- assert obj_phonecall.partner_id == obj_opp.partner_id
-- |
- I schedule Meeting on this current phonecall by clicking on "schedule
- Meeting".
--
- !python {model: crm.phonecall}: |
- self.action_make_meeting(cr, uid, [ref('crm_phonecall_interviewcall0')])
-
-- |
- I can see that Meeting's calendar view is shown.
- then I click on the date on which I want schedule meeting.
- I fill proper data for that meeting and save it.
--
- !record {model: crm.meeting, id: crm_meeting_interviewcall0}:
- alarm_id: base_calendar.alarm3
- date: !eval "'%s-%s-%s 09:00:00' %(datetime.now().year,datetime.now().month,datetime.now().day)"
- date_deadline: !eval "'%s-%s-%s 17:00:00' %(datetime.now().year,datetime.now().month,datetime.now().day)"
- duration: 8.0
- email_from: info@balmerinc.be
- name: Interview call
- partner_address_id: base.res_partner_address_1
- partner_id: base.res_partner_9
- phonecall_id: 'crm_phonecall_interviewcall0'
- state: open
-
-- |
- In order to schedule other phonecall to the partner
- I click on "schedule other call" button. and plan for other call
- I can see that it will open other phonecall view with some data same as current
- phonecall.
--
- !record {model: crm.phonecall2phonecall, id: crm_phonecall2phonecall_interviewcall0}:
- date: !eval "'%s-%s-%s 19:49:00' %(datetime.now().year,datetime.now().month,datetime.now().day)"
- name: Interview call
- section_id: crm.section_sales_department
- user_id: base.user_root
- action: schedule
- categ_id: crm.categ_phone1
--
- I click on "schedule other call" button. and plan for other call.
--
- !record {model: crm.phonecall2phonecall, id: crm_phonecall2phonecall_interviewcall1}:
- date: !eval "'%s-%s-%s 19:49:00' %(datetime.now().year,datetime.now().month,datetime.now().day)"
- name: Interview call
- section_id: crm.section_sales_department
- user_id: base.user_root
- action: log
- categ_id: crm.categ_phone1
-- |
- I click on "Schedule" button of this wizard.
--
- !python {model: crm.phonecall2phonecall}: |
- fields = {
- 'name': 'Interview call',
- 'section_id': ref('crm.section_sales_department'),
- 'user_id': ref('base.user_root'),
- 'categ_id': ref('crm.categ_phone1')
- }
- self.default_get(cr, uid, fields,{'active_id': ref('crm_phonecall_interviewcall0')})
- self.action_apply(cr, uid, [ref('crm_phonecall2phonecall_interviewcall0')], {'active_id': ref('crm_phonecall_interviewcall0')})
-- |
- I click on "Schedule" button of this wizard with log option.
--
- !python {model: crm.phonecall2phonecall}: |
- self.action_apply(cr, uid, [ref('crm_phonecall2phonecall_interviewcall1')], {'active_id': ref('crm_phonecall_interviewcall0')})
diff --git a/addons/crm/test/test_crm_phonecall_case2.yml b/addons/crm/test/test_crm_phonecall_case2.yml
deleted file mode 100644
index 1b07121183c..00000000000
--- a/addons/crm/test/test_crm_phonecall_case2.yml
+++ /dev/null
@@ -1,26 +0,0 @@
-- |
- I start by creating a new phonecall.
--
- !record {model: crm.phonecall, id: crm_phonecall_dummycall}:
- date: !eval time.strftime('%Y-%m-%d 08:00:00')
- name: Dummy call
- duration: 0.0
- section_id: crm.section_sales_department
- partner_id: base.res_partner_agrolait
- state: open
--
- I change Contact Detail of the Partner.
--
- !python {model: crm.phonecall}: |
- self.onchange_partner_address_id(cr, uid,[ref("crm_phonecall_dummycall")], ref("base.res_partner_address_8invoice"))
-
--
- I setting Phone call to Held (Done).
--
- !python {model: crm.phonecall}: |
- self.case_close(cr, uid, [ref("crm_phonecall_dummycall")])
--
- I check that the hone call is in 'Held' state.
--
- !assert {model: crm.phonecall, id: crm_phonecall_dummycall, string: Phone call Helded}:
- - state == "done"
diff --git a/addons/crm/test/test_crm_recurrent_meeting.yml b/addons/crm/test/test_crm_recurrent_meeting.yml
deleted file mode 100644
index 297ca8d5e4e..00000000000
--- a/addons/crm/test/test_crm_recurrent_meeting.yml
+++ /dev/null
@@ -1,106 +0,0 @@
--
- In order to test recurrent meetings in OpenERP, I create meetings with different recurrency.
--
- I create a customer meeting record with daily recurrency.
--
- !record {model: crm.meeting, id: crm_meeting_pricelistdiscussion0}:
- categ_id: crm.categ_meet1
- count: 0.0
- date: '2011-01-05 00:00:00'
- date_deadline: '2011-01-05 01:00:00'
- day: 0.0
- duration: 1.0
- end_date: '2011-01-12'
- end_type: end_date
- name: Pricelist Discussion
- recurrency: true
- recurrent_uid: 0.0
- rrule: FREQ=DAILY;INTERVAL=1;UNTIL=20110112T235959Z
- rrule_type: daily
- sequence: 0.0
--
- I create another meeting record with weekly recurrency.
--
- !record {model: crm.meeting, id: crm_meeting_changesindesigning0}:
- categ_id: crm.categ_meet2
- count: 15
- date: '2011-01-22 11:05:05'
- date_deadline: '2011-01-22 16:05:05'
- day: 0.0
- duration: 5.0
- email_from: info@opensides.be
- end_type: count
- fr: true
- mo: true
- name: Changes in Designing
- partner_address_id: base.res_partner_address_1
- partner_id: base.res_partner_9
- recurrency: true
- recurrent_uid: 0.0
- rrule: FREQ=WEEKLY;BYDAY=FR,TU,TH,WE,MO;INTERVAL=1;COUNT=15
- rrule_type: weekly
- section_id: crm.section_sales_department
- sequence: 0.0
- th: true
- tu: true
- user_id: base.user_demo
- we: true
--
- I create a meeting record with monthly recurrency.
--
- !record {model: crm.meeting, id: crm_meeting_reviewneeds0}:
- categ_id: crm.categ_meet3
- count: 0.0
- date: '2011-01-20 10:02:02'
- date_deadline: '2011-01-20 16:02:02'
- day: 15
- duration: 6.0
- end_date: '2011-05-31'
- end_type: end_date
- name: Review needs
- partner_address_id: base.res_partner_address_15
- partner_id: base.res_partner_11
- recurrency: true
- recurrent_uid: 0.0
- rrule: FREQ=MONTHLY;INTERVAL=1;UNTIL=20110531T235959Z;BYMONTHDAY=15
- rrule_type: monthly
- section_id: crm.section_sales_department
- sequence: 0.0
- user_id: base.user_demo
--
- I create a record for daily scrum meeting.
--
- !record {model: crm.meeting, id: crm_meeting_scrummeeting0}:
- categ_id: crm.categ_meet2
- count: 0.0
- date: '2011-01-06 00:00:00'
- date_deadline: '2011-01-06 01:00:00'
- day: 0.0
- duration: 1.0
- name: Scrum meeting
- recurrency: true
- recurrent_uid: 0.0
- rrule: FREQ=DAILY;INTERVAL=1
- rrule_type: daily
- sequence: 0.0
--
- I create a meeting record for yearly recurrency.
--
- !record {model: crm.meeting, id: crm_meeting_updatethedata0}:
- categ_id: crm.categ_meet2
- count: 0.0
- date: '2011-01-18 13:12:49'
- date_deadline: '2011-01-19 02:30:49'
- day: 0.0
- duration: 13.300000000000001
- end_date: '2015-01-06'
- end_type: end_date
- name: Update the data
- partner_address_id: base.res_partner_address_7
- partner_id: base.res_partner_4
- recurrency: true
- recurrent_uid: 0.0
- rrule: FREQ=YEARLY;INTERVAL=1;UNTIL=20150106T235959Z
- rrule_type: yearly
- section_id: crm.section_sales_department
- sequence: 0.0
diff --git a/addons/crm/test/test_crm_segmentation.yml b/addons/crm/test/test_crm_segmentation.yml
deleted file mode 100644
index 5563f1ce52f..00000000000
--- a/addons/crm/test/test_crm_segmentation.yml
+++ /dev/null
@@ -1,38 +0,0 @@
-- |
- I will test segmentation which create specific partner categories criteria.
--
- I create a new segmentation record.
--
- !record {model: crm.segmentation, id: crm_segmentation_id_0}:
- categ_id: base.res_partner_category_5
- exclusif: true
- name: segment
- som_interval: 0.0
- sales_purchase_active : True
--
- I start the process.
--
- !python {model: crm.segmentation}: |
- self.process_start(cr, uid, [ref("crm_segmentation_id_0")],context)
--
- I continue the segmentation process.
--
- !python {model: crm.segmentation}: |
- context.update({'start': True})
- self.process_continue(cr, uid, [ref("crm_segmentation_id_0")], context)
--
- I create the segmentation line.
--
- !record {model: crm.segmentation.line, id: crm_segmentation_line_id_0}:
- expr_name: sale
- expr_operator: '>'
- expr_value: 1000.0
- name: Rule1
- operator: or
- segmentation_id: crm_segmentation_id_0
-
--
- I check the Segmentation line record.
--
- !python {model: crm.segmentation.line}: |
- self.test(cr, uid, [ref("crm_segmentation_line_id_0")],partner_id=0)
diff --git a/addons/crm/test/test_crm_stage_changes.yml b/addons/crm/test/test_crm_stage_changes.yml
deleted file mode 100644
index 391a328bffe..00000000000
--- a/addons/crm/test/test_crm_stage_changes.yml
+++ /dev/null
@@ -1,96 +0,0 @@
--
- In order to test the changes on stage of a lead or an opportunity with OpenERP,
- I create some leads and test the stage changes.
--
- I want to change the probability to 0.0 when the opportunity is marked as lost.
- So I set its Change probability automatically true.
--
- !record {model: crm.case.stage, id: crm.stage_lead6}:
- name: Lost
- on_change: true
- probability: 0.0
- section_ids:
- - crm.section_sales_department
- sequence: 0
--
- I create a lead 'Test Lead1'.
--
- !record {model: crm.lead, id: crm_lead_openerppresentation0}:
- categ_id: crm.categ_oppor4
- day_close: 0.0
- day_open: 0.0
- name: Test Lead1
- planned_revenue: 0.0
- probability: 10.0
- section_id: crm.section_sales_department
--
- I open the lead.
--
- !python {model: crm.lead}: |
- self.case_open(cr, uid, [ref('crm_lead_openerppresentation0')])
--
- I assigning stage.
--
- !python {model: crm.lead}: |
- self.onchange_stage_id(cr, uid, [ref('crm_lead_openerppresentation0')], [], context)
--
- I assigning percent.
--
- !python {model: crm.lead}: |
- self.stage_find_percent(cr, uid, 10.0, [])
--
- I find that this lead can be converted to opportunity.
--
- !record {model: crm.lead2opportunity.partner, id: crm_lead2opportunity_partner0}:
- action: 'create'
- name: 'convert'
--
- So I convert the lead to opportunity.
--
- !python {model: crm.lead2opportunity.partner}: |
- self.action_apply(cr, uid, [ref('crm_lead2opportunity_partner0')], context={'active_ids': [ref('crm_lead_openerppresentation0')]})
--
- I check that lead is now converted to opportunity.
--
- !python {model: crm.lead}: |
- lead = self.browse(cr, uid, ref('crm_lead_openerppresentation0'))
- assert lead.type == 'opportunity', 'Lead is not converted to opportunity!'
--
- I mark this opportunity as lost.
--
- !python {model: crm.lead}: |
- self.case_mark_lost(cr, uid, [ref('crm_lead_openerppresentation0')])
--
- I check whether the probability is set according to stage change or not.
--
- !python {model: crm.lead}: |
- opportunity = self.browse(cr, uid, ref('crm_lead_openerppresentation0'))
- assert opportunity.stage_id.id == ref('crm.stage_lead6'), 'Stage is not changed!'
- assert opportunity.probability == 0.0, 'Probability is wrong!'
--
- I create one more opportunity.
--
- !record {model: crm.lead, id: crm_lead_test2}:
- name: Partner Demo
- type: opportunity
- categ_id: crm.categ_oppor3
- planned_revenue: 50000.0
- probability: 100.0
- section_id: crm.section_sales_department
--
- I open this opportunity.
--
- !python {model: crm.lead}: |
- self.case_open(cr, uid, [ref('crm_lead_test2')])
--
- I mark this opportunity as won.
--
- !python {model: crm.lead}: |
- self.case_mark_won(cr, uid, [ref('crm_lead_test2')])
--
- I check whether the stage is changed to 'Won' and probability is 100.0 or not.
--
- !python {model: crm.lead}: |
- opportunity = self.browse(cr, uid, ref('crm_lead_test2'))
- assert opportunity.stage_id.id == ref('crm.stage_lead5'), 'Stage is not changed!'
- assert opportunity.probability == 100.0, 'Probability is wrong!'
diff --git a/addons/crm/test/ui/crm_demo.yml b/addons/crm/test/ui/crm_demo.yml
new file mode 100644
index 00000000000..5ef40838466
--- /dev/null
+++ b/addons/crm/test/ui/crm_demo.yml
@@ -0,0 +1,29 @@
+-
+ I create lead record to call of partner onchange, stage onchange and Mailing opt-in onchange method.
+-
+ !record {model: crm.lead, id: crm_case_shelvehouse}:
+ name: 'Need more info about your pc2'
+ partner_id: base.res_partner_theshelvehouse0
+ type: opportunity
+ stage_id: crm.stage_lead1
+ state: draft
+ optin: True
+-
+ I create lead record to call Mailing opt-out onchange method.
+-
+ !record {model: crm.lead, id: crm_case_mediapoleunits0}:
+ name: 'Need 20 Days of Consultancy'
+ type: opportunity
+ state: draft
+ optout: True
+-
+ I create phonecall record to call partner onchange method.
+-
+ !record {model: crm.phonecall, id: crm_case_phone05}:
+ name: 'Bad time'
+ partner_id: base.res_partner_5
+-
+ I setting next stage "New" for the lead.
+-
+ !python {model: crm.lead}: |
+ self.stage_next(cr, uid, [ref("crm_case_qrecorp0")], context={'stage_type': 'lead'})
diff --git a/addons/crm/test/ui/delete_lead.yml b/addons/crm/test/ui/delete_lead.yml
new file mode 100644
index 00000000000..472b22d0d2d
--- /dev/null
+++ b/addons/crm/test/ui/delete_lead.yml
@@ -0,0 +1,5 @@
+-
+ I Unlink the Lead.
+-
+ !python {model: crm.lead}: |
+ self.unlink(cr, uid, [ref("crm_case_qrecorp0")])
diff --git a/addons/crm/test/ui/duplicate_lead.yml b/addons/crm/test/ui/duplicate_lead.yml
new file mode 100644
index 00000000000..6b349ca350c
--- /dev/null
+++ b/addons/crm/test/ui/duplicate_lead.yml
@@ -0,0 +1,5 @@
+-
+ I make duplicate the Lead.
+-
+ !python {model: crm.lead}: |
+ self.copy(cr, uid, ref("crm_case_qrecorp0"))
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 87ab9229d26..52a79e4514c 100644
--- a/addons/crm/wizard/crm_lead_to_opportunity.py
+++ b/addons/crm/wizard/crm_lead_to_opportunity.py
@@ -54,6 +54,8 @@ class crm_lead2opportunity_partner(osv.osv_memory):
email = False
for lead in lead_obj.browse(cr, uid, opportunities, context=context):
partner_id = lead.partner_id and lead.partner_id.id or False
+
+ #TOFIX: use mail.mail_message.to_mail
email = re.findall(r'([^ ,<@]+@[^> ,]+)', lead.email_from or '')
email = map(lambda x: "'" + x + "'", email)
@@ -93,139 +95,51 @@ class crm_lead2opportunity_partner(osv.osv_memory):
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 user’s ID for security checks,
- @param fields: List of fields for default value
- @param context: A standard dictionary for contextual values
"""
if context is None:
context = {}
lead_obj = self.pool.get('crm.lead')
-
for lead in lead_obj.browse(cr, uid, context.get('active_ids', []), context=context):
if lead.state in ['done', 'cancel']:
raise osv.except_osv(_("Warning !"), _("Closed/Cancelled Leads can not be converted into Opportunity"))
return False
- def _convert(self, cr, uid, ids, lead, partner_id, stage_ids, context=None):
- leads = self.pool.get('crm.lead')
- address_id = False
- if partner_id:
- address_id = self.pool.get('res.partner.address').search(cr, uid,
- [('partner_id', '=', partner_id)],
- order='create_date desc',
- limit=1)
- vals = {
- 'planned_revenue': lead.planned_revenue,
- 'probability': lead.probability,
- 'name': lead.name,
- 'partner_id': partner_id,
- 'user_id': (lead.user_id and lead.user_id.id),
- 'type': 'opportunity',
- 'stage_id': stage_ids and stage_ids[0] or False,
- 'date_action': time.strftime('%Y-%m-%d %H:%M:%S'),
- }
- if partner_id and address_id:
- vals['partner_address_id'] = address_id[0]
- else:
- vals['partner_address_id'] = False
+ def _convert_opportunity(self, cr, uid, ids, vals, context=None):
+ if context is None:
+ context = {}
+ lead = self.pool.get('crm.lead')
+ partner_id = self._create_partner(cr, uid, ids, context=context)
+ lead_ids = vals.get('lead_ids', [])
+ user_ids = vals.get('user_ids', False)
+ team_id = vals.get('section_id', False)
+ return lead.convert_opportunity(cr, uid, lead_ids, partner_id, user_ids, team_id, context=context)
- lead.write(vals, context=context)
- text = _('Converted to opportunity')
- leads.message_append(cr, uid, [lead], text, body_text=text, context=context)
- if lead.partner_id:
- msg_ids = [ x.id for x in lead.message_ids]
- self.pool.get('mail.message').write(cr, uid, msg_ids, {
- 'partner_id': lead.partner_id.id
- }, context=context)
- leads.log(cr, uid, lead.id, _("Lead '%s' has been converted to an opportunity.") % lead.name)
-
- def send_mail_to_salesman(self, cr, uid, lead):
- email_to = lead.user_id and lead.user_id.user_email
- if not email_to:
- return False
- message_pool = self.pool.get('mail.message')
- email_from = lead.section_id and lead.section_id.user_id and lead.section_id.user_id.user_email or email_to
- partner = lead.partner_id and lead.partner_id.name or lead.partner_name
- subject = "lead %s converted into opportunity" % lead.name
- body = "Info \n Id : %s \n Subject: %s \n Partner: %s \n Description : %s " % (lead.id, lead.name, lead.partner_id.name, lead.description)
- return message_pool.schedule_with_attach(cr, uid, email_from, [email_to], subject, body)
+ 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
- @param ids: ids of the leads to convert to opportunities
-
- @return : View dictionary opening the Opportunity form view
"""
if not context:
context = {}
-
- record_id = context and context.get('active_ids') or False
- if not record_id:
- return {'type': 'ir.actions.act_window_close'}
-
- leads = self.pool.get('crm.lead')
- models_data = self.pool.get('ir.model.data')
-
- # Get Opportunity views
- result = models_data._get_id(
- cr, uid, 'crm', 'view_crm_case_opportunities_filter')
- opportunity_view_search = models_data.browse(
- cr, uid, result, context=context).res_id
- opportunity_view_form = models_data._get_id(
- cr, uid, 'crm', 'crm_case_form_view_oppor')
- opportunity_view_tree = models_data._get_id(
- cr, uid, 'crm', 'crm_case_tree_view_oppor')
- if opportunity_view_form:
- opportunity_view_form = models_data.browse(
- cr, uid, opportunity_view_form, context=context).res_id
- if opportunity_view_tree:
- opportunity_view_tree = models_data.browse(
- cr, uid, opportunity_view_tree, context=context).res_id
-
- for lead in leads.browse(cr, uid, record_id, context=context):
- if lead.section_id:
- stage_ids = self.pool.get('crm.case.stage').search(cr, uid, [('sequence','>=',1), ('section_ids','=', lead.section_id.id)])
- else:
- stage_ids = self.pool.get('crm.case.stage').search(cr, uid, [('sequence','>=',1)])
-
- data = self.browse(cr, uid, ids[0], context=context)
-
-
- if data.action == 'create':
- partner_ids = []
- partner_ids = self._create_partner(cr, uid, ids, context=context)
- partner_id = partner_ids and partner_ids[0]
- elif data.action == 'exist':
- partner_id = data.partner_id and data.partner_id.id
- else:
- partner_id = False
-
- self._convert(cr, uid, ids, lead, partner_id, stage_ids, context=context)
- self.send_mail_to_salesman(cr, uid, lead)
- #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 {
- 'name': _('Opportunity'),
- 'view_type': 'form',
- 'view_mode': 'form,tree',
- 'res_model': 'crm.lead',
- 'domain': [('type', '=', 'opportunity')],
- 'res_id': int(lead.id),
- 'view_id': False,
- 'views': [(opportunity_view_form, 'form'),
- (opportunity_view_tree, 'tree'),
- (False, 'calendar'), (False, 'graph')],
- 'type': 'ir.actions.act_window',
- 'search_view_id': opportunity_view_search
- }
+
+ lead = self.pool.get('crm.lead')
+ lead_ids = context.get('active_ids', [])
+ data = self.browse(cr, uid, ids, context=context)[0]
+ self._convert_opportunity(cr, uid, ids, {'lead_ids': lead_ids}, context=context)
+ self._merge_opportunity(cr, uid, ids, data.opportunity_ids, data.action, context=context)
+ return lead.redirect_opportunity_view(cr, uid, lead_ids[0], context=context)
crm_lead2opportunity_partner()
@@ -240,55 +154,19 @@ class crm_lead2opportunity_mass_convert(osv.osv_memory):
'section_id': fields.many2one('crm.case.section', 'Sales Team'),
}
+ def _convert_opportunity(self, cr, uid, ids, vals, context=None):
+ data = self.browse(cr, uid, ids, context=context)[0]
+ salesteam_id = data.section_id and data.section_id.id or False
+ salesman = []
+ if data.user_ids:
+ salesman = [x.id for x in data.user_ids]
+ vals.update({'user_ids': salesman, 'section_id': salesteam_id})
+ return super(crm_lead2opportunity_mass_convert, self)._convert_opportunity(cr, uid, ids, vals, context=context)
def mass_convert(self, cr, uid, ids, context=None):
- lead_obj = self.pool.get('crm.lead')
- if not context:
- context = {}
-
- active_ids = context.get('active_ids')
- data = self.browse(cr, uid, ids, context=context)[0]
-
- salesteam = data.section_id and data.section_id.id
- if data.user_ids:
- salesmans = map(lambda x : x.id, data.user_ids)
- index = 0
- else:
- salesmans = False
-
- for lead_id in active_ids:
- value = {}
- if salesteam:
- value['section_id'] = salesteam
- if salesmans:
- value['user_id'] = salesmans[index]
- index += 1
- index = index < len(salesmans) and index or 0
- if value:
- lead_obj.write(cr, uid, [lead_id], value, context=context)
-
- context['active_ids'] = [lead_id]
- 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)
-
- self.action_apply(cr, uid, ids, context=context)
-
-
-
- models_data = self.pool.get('ir.model.data')
- result = models_data._get_id(cr, uid, 'crm', 'view_crm_case_opportunities_filter')
- opportunity_view_search = models_data.browse(cr, uid, result, context=context).res_id
-
- return {
- 'name': _('Opportunity'),
- 'view_type': 'form',
- 'view_mode': 'tree,form',
- 'res_model': 'crm.lead',
- 'domain': [('type', '=', 'opportunity'), ('id', 'in', active_ids)],
- 'type': 'ir.actions.act_window',
- 'search_view_id': opportunity_view_search,
- }
-
+ 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)
+ 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_opportunity_view.xml b/addons/crm/wizard/crm_lead_to_opportunity_view.xml
index 833c04c3575..5f8453768c0 100644
--- a/addons/crm/wizard/crm_lead_to_opportunity_view.xml
+++ b/addons/crm/wizard/crm_lead_to_opportunity_view.xml
@@ -65,6 +65,15 @@
+
+
+ Create a Partner
+ ir.actions.act_window
+ crm.lead2opportunity.partner
+ form
+
+ new
+
,]+)', lead.email_from or '')
- email = map(lambda x: "'" + x + "'", email)
- if email:
- cr.execute("""select partner_id from res_partner_address
- where
- substring(email from '([^ ,<@]+@[^> ,]+)') in (%s)""" % (','.join(email)))
- partner_ids = map(lambda x: x[0], cr.fetchall())
-
- # 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', '=ilike', 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})
-
+ 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):
"""
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 user’s ID for security checks,
- @param ids: List of Lead to Partner's IDs
- @param context: A standard dictionary for contextual values
-
- @return : Dictionary value for next form.
"""
- if context is None:
- context = {}
-
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):
"""
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 user’s ID for security checks,
- @param ids: List of Lead to Partner's IDs
- @param context: A standard dictionary for contextual values
-
- @return : Dictionary {}.
"""
if context is None:
context = {}
-
- lead_obj = self.pool.get('crm.lead')
- partner_obj = self.pool.get('res.partner')
- contact_obj = self.pool.get('res.partner.address')
- partner_ids = []
- partner_id = False
- rec_ids = context and context.get('active_ids', [])
-
- for data in self.browse(cr, uid, ids, context=context):
- for lead in lead_obj.browse(cr, uid, rec_ids, context=context):
- if data.action == 'create':
- partner_id = partner_obj.create(cr, uid, {
- 'name': lead.partner_name or lead.contact_name or lead.name,
- 'user_id': lead.user_id.id,
- 'comment': lead.description,
- 'address': []
- })
- contact_obj.create(cr, uid, {
- 'partner_id': partner_id,
- 'name': lead.contact_name,
- 'phone': lead.phone,
- 'mobile': lead.mobile,
- 'email': lead.email_from,
- 'fax': lead.fax,
- 'title': lead.title and lead.title.id or False,
- 'function': lead.function,
- 'street': lead.street,
- 'street2': lead.street2,
- 'zip': lead.zip,
- 'city': lead.city,
- 'country_id': lead.country_id and lead.country_id.id or False,
- 'state_id': lead.state_id and lead.state_id.id or False,
- })
-
- else:
- if data.partner_id:
- partner_id = data.partner_id.id
- self.assign_partner(cr, uid, lead.id, partner_id)
- partner_ids.append(partner_id)
- return partner_ids
-
-
- def assign_partner(self, cr, uid, lead_id, partner_id):
- self.pool.get("crm.lead").write(cr, uid, [lead_id], {'partner_id' : partner_id})
-
+ lead = self.pool.get('crm.lead')
+ lead_ids = context and context.get('active_ids') or []
+ data = self.browse(cr, uid, ids, context=context)[0]
+ partner_id = data.partner_id and data.partner_id.id or False
+ partner_ids = lead.convert_partner(cr, uid, lead_ids, data.action, partner_id, context=context)
+ return partner_ids[lead_ids[0]]
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 user’s ID for security checks,
- @param ids: List of Lead to Partner's IDs
- @param context: A standard dictionary for contextual values
-
- @return : Dictionary value for created Partner form.
"""
- if context is None:
- context = {}
-
- partner_ids = self._create_partner(cr, uid, ids, context=context)
- return {'type': 'ir.actions.act_window_close'}
+ partner_id = self._create_partner(cr, uid, ids, context=context)
+ return self.pool.get('res.partner').redirect_partner_form(cr, uid, partner_id, context=context)
crm_lead2partner()
diff --git a/addons/crm/wizard/crm_merge_opportunities.py b/addons/crm/wizard/crm_merge_opportunities.py
index f092d6ad0b6..381bb9871ea 100644
--- a/addons/crm/wizard/crm_merge_opportunities.py
+++ b/addons/crm/wizard/crm_merge_opportunities.py
@@ -26,195 +26,16 @@ class crm_merge_opportunity(osv.osv_memory):
_name = 'crm.merge.opportunity'
_description = 'Merge two Opportunities'
- def _get_first_not_null_id(self, attr, ops, oldest):
- if hasattr(oldest, attr) and getattr(oldest, attr):
- return getattr(oldest, attr).id
-
- for op in ops:
- if hasattr(op, attr) and getattr(op, attr):
- return getattr(op, attr).id
- return False
-
- def _get_first_not_null(self, attr, ops, oldest):
- if hasattr(oldest, attr) and getattr(oldest, attr):
- return getattr(oldest, attr)
-
- for op in ops:
- if hasattr(op, attr) and getattr(op, attr):
- return getattr(op, attr)
- return False
-
- def _concat_all(self, attr, ops):
- return ', '.join([getattr(op, attr) for op in ops if hasattr(op, attr) and getattr(op, attr)])
-
-
- def get_attachments(self, cr, uid, id, context=None):
- proxy = self.pool.get('ir.attachment')
- ids = proxy.search(cr, uid, [('res_model', '=', 'crm.lead'), ('res_id', '=', id)], context=context)
- return proxy.browse(cr, uid, ids, context=context)
-
- def find_oldest(self, cr, uid, op_ids, context=None):
- if not context:
- context = {}
- ids = [op_id.id for op_id in op_ids]
- if context.get('convert'):
- ids = list(set(ids) - set(context.get('lead_ids', False)) )
- lead_obj = self.pool.get('crm.lead')
- op_id = lead_obj.search(cr, uid, [('id', 'in', ids)], order='create_date' , context=context)
- if not op_id:
- return False
- opps = lead_obj.browse(cr, uid, [op_id[0]], context=context)
- return opps[0]
-
- def _update_data(self, op_ids, oldest_opp):
- data = {
- 'partner_id': self._get_first_not_null_id('partner_id', op_ids, oldest_opp), # !!
- 'title': self._get_first_not_null_id('title', op_ids, oldest_opp),
- 'name' : self._get_first_not_null('name', op_ids, oldest_opp), #not lost
- 'categ_id' : self._get_first_not_null_id('categ_id', op_ids, oldest_opp), # !!
- 'channel_id' : self._get_first_not_null_id('channel_id', op_ids, oldest_opp), # !!
- 'city' : self._get_first_not_null('city', op_ids, oldest_opp), # !!
- 'company_id' : self._get_first_not_null_id('company_id', op_ids, oldest_opp), #!!
- 'contact_name' : self._get_first_not_null('contact_name', op_ids, oldest_opp), #not lost
- 'country_id' : self._get_first_not_null_id('country_id', op_ids, oldest_opp), #!!
- 'partner_address_id' : self._get_first_not_null_id('partner_address_id', op_ids, oldest_opp), #!!
- 'type_id' : self._get_first_not_null_id('type_id', op_ids, oldest_opp), #!!
- 'user_id' : self._get_first_not_null_id('user_id', op_ids, oldest_opp), #!!
- 'section_id' : self._get_first_not_null_id('section_id', op_ids, oldest_opp), #!!
- 'state_id' : self._get_first_not_null_id('state_id', op_ids, oldest_opp),
- 'description' : self._concat_all('description', op_ids), #not lost
- 'email' : self._get_first_not_null('email', op_ids, oldest_opp), # !!
- 'fax' : self._get_first_not_null('fax', op_ids, oldest_opp),
- 'mobile' : self._get_first_not_null('mobile', op_ids, oldest_opp),
- 'partner_name' : self._get_first_not_null('partner_name', op_ids, oldest_opp),
- 'phone' : self._get_first_not_null('phone', op_ids, oldest_opp),
- 'probability' : self._get_first_not_null('probability', op_ids, oldest_opp),
- 'planned_revenue' : self._get_first_not_null('planned_revenue', op_ids, oldest_opp),
- 'street' : self._get_first_not_null('street', op_ids, oldest_opp),
- 'street2' : self._get_first_not_null('street2', op_ids, oldest_opp),
- 'zip' : self._get_first_not_null('zip', op_ids, oldest_opp),
- 'state' : 'open',
- 'create_date' : self._get_first_not_null('create_date', op_ids, oldest_opp),
- 'date_action_last': self._get_first_not_null('date_action_last', op_ids, oldest_opp),
- 'date_action_next': self._get_first_not_null('date_action_next', op_ids, oldest_opp),
- 'email_from' : self._get_first_not_null('email_from', op_ids, oldest_opp),
- 'email_cc' : self._get_first_not_null('email_cc', op_ids, oldest_opp),
- 'partner_name' : self._get_first_not_null('partner_name', op_ids, oldest_opp),
- }
- return data
-
- def merge(self, cr, uid, op_ids, context=None):
- """
- :param opp_ids: list of opportunities ids to merge
- """
- opp_obj = self.pool.get('crm.lead')
- message_obj = self.pool.get('mail.message')
-
- lead_ids = context and context.get('lead_ids', []) or []
-
- if len(op_ids) <= 1:
- raise osv.except_osv(_('Warning !'),_('Please select more than one opportunities.'))
-
- opportunities = opp_obj.browse(cr, uid, lead_ids, context=context)
- opportunities_list = list(set(op_ids) - set(opportunities))
- oldest_opp = self.find_oldest(cr, uid, op_ids, context=context)
- if opportunities :
- first_opportunity = opportunities[0]
- tail_opportunities = opportunities_list
- else:
- first_opportunity = opportunities_list[0]
- tail_opportunities = opportunities_list[1:]
- data = self._update_data(op_ids, oldest_opp)
-
- #copy message into the first opportunity + merge attachement
- count = 1
- first_attachments = self.get_attachments(cr, uid, first_opportunity, context=context)
- for opp in tail_opportunities:
- attachments = self.get_attachments(cr, uid, opp, context=context)
- for first in first_attachments:
- for attachment in attachments:
- if attachment.name == first.name:
- values = dict(
- name = "%s (%s)" % (attachment.name, count,),
- res_id = first_opportunity.id,
- )
- attachment.write(values)
- count+=1
-
- for history in opp.message_ids:
- message_obj.write(cr, uid, history.id, {'res_id': first_opportunity.id, 'subject' : _("From %s : %s") % (opp.name, history.subject) }, context=context)
-
- #Notification about loss of information
- details = []
- subject = ['Merged opportunities :']
- for opp in op_ids:
- subject.append(opp.name)
- details.append(_('Merged Opportunity: %s\n Partner: %s\n Stage: %s\n Section: %s\n Salesman: %s\n Category: %s\n Channel: %s\n Company: %s\n Contact name: %s\n Email: %s\n Phone number: %s\n Fax: %s\n Mobile: %s\n State: %s\n Description: %s\n Probability: %s\n Planned revennue: %s\n Country: %s\n City: %s\n Street: %s\n Street 2: %s\n Zip 2: %s') % ( opp.name, opp.partner_id.name or '',
- opp.stage_id.name or '',
- opp.section_id.name or '',
- opp.user_id.name or '',
- opp.categ_id.name or '',
- opp.channel_id.name or '',
- opp.company_id.name or '',
- opp.contact_name or '',
- opp.email_from or '',
- opp.phone or '',
- opp.fax or '',
- opp.mobile or '',
- opp.state_id.name or '',
- opp.description or '',
- opp.probability or '',
- opp.planned_revenue or '',
- opp.country_id.name or '',
- opp.city or '',
- opp.street or '',
- opp.street2 or '',
- opp.zip or '',
- ))
- subject = subject[0] + ", ".join(subject[1:])
- details = "\n\n".join(details)
-
- opp_obj.message_append(cr, uid, [first_opportunity], subject, body_text=details)
- #data.update({'message_ids' : [(6, 0 ,self._concat_o2m('message_ids', op_ids))]})
- opp_obj.write(cr, uid, [first_opportunity.id], data, context=context)
- unlink_ids = map(lambda x: x.id, tail_opportunities)
- opp_obj.unlink(cr, uid, unlink_ids, context=context)
-
- models_data = self.pool.get('ir.model.data')
-
- # Get Opportunity views
- opportunity_view_form = models_data._get_id(
- cr, uid, 'crm', 'crm_case_form_view_oppor')
- opportunity_view_tree = models_data._get_id(
- cr, uid, 'crm', 'crm_case_tree_view_oppor')
- if opportunity_view_form:
- opportunity_view_form = models_data.browse(
- cr, uid, opportunity_view_form, context=context).res_id
- if opportunity_view_tree:
- opportunity_view_tree = models_data.browse(
- cr, uid, opportunity_view_tree, context=context).res_id
-
- return {
- 'name': _('Opportunity'),
- 'view_type': 'form',
- 'view_mode': 'tree, form',
- 'res_model': 'crm.lead',
- 'domain': [('type', '=', 'opportunity')],
- 'res_id': int(first_opportunity.id),
- 'view_id': False,
- 'views': [(opportunity_view_form, 'form'),
- (opportunity_view_tree, 'tree'),
- (False, 'calendar'), (False, 'graph')],
- 'type': 'ir.actions.act_window',
- }
-
-
def action_merge(self, cr, uid, ids, context=None):
- obj_opportunity = self.browse(cr, uid, ids[0], context=context)
- op_ids = obj_opportunity.opportunity_ids
- self.write(cr, uid, ids, {'opportunity_ids' : [(6,0, [op_ids[0].id])]}, context=context)
- context['lead_ids'] = [op_ids[0].id]
- return self.merge(cr, uid, op_ids, context)
+ lead = self.pool.get('crm.lead')
+ record = self.browse(cr, uid, ids[0], context=context)
+ opportunities = record.opportunity_ids
+ #TOFIX: why need to check lead_ids here
+ lead_ids = [opportunities[0].id]
+ self.write(cr, uid, ids, {'opportunity_ids' : [(6,0, lead_ids)]}, context=context)
+ context['lead_ids'] = lead_ids
+ merge_id = lead.merge_opportunity(cr, uid, [x.id for x in opportunities], context=context)
+ return lead.redirect_opportunity_view(cr, uid, merge_id, context=context)
_columns = {
'opportunity_ids' : fields.many2many('crm.lead', 'merge_opportunity_rel', 'merge_id', 'opportunity_id', 'Opportunities', domain=[('type', '=', 'opportunity')]),
@@ -223,13 +44,6 @@ class crm_merge_opportunity(osv.osv_memory):
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_ids = context and context.get('active_ids', False) or False
res = super(crm_merge_opportunity, self).default_get(cr, uid, fields, context=context)
diff --git a/addons/crm/wizard/crm_opportunity_to_phonecall.py b/addons/crm/wizard/crm_opportunity_to_phonecall.py
index b0bfbf3b817..a45c87b1a6f 100644
--- a/addons/crm/wizard/crm_opportunity_to_phonecall.py
+++ b/addons/crm/wizard/crm_opportunity_to_phonecall.py
@@ -28,36 +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"),
- 'contact_name':fields.char('Contact', size=64),
- 'phone':fields.char('Phone', size=64),
- '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),
- 'note':fields.text('Note'),
- }
-
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')
@@ -66,8 +41,8 @@ class crm_opportunity2phonecall(osv.osv_memory):
categ_id = data_obj.browse(cr, uid, res_id, context=context).res_id
record_ids = context and context.get('active_ids', []) or []
- res = super(crm_opportunity2phonecall, self).default_get(cr, uid, fields, context=context)
- res.update({'action': 'log', 'date': time.strftime('%Y-%m-%d %H:%M:%S')})
+ res = {}
+ res.update({'action': 'schedule', 'date': time.strftime('%Y-%m-%d %H:%M:%S')})
for opp in opp_obj.browse(cr, uid, record_ids, context=context):
if 'name' in fields:
res.update({'name': opp.name})
@@ -87,84 +62,20 @@ class crm_opportunity2phonecall(osv.osv_memory):
res.update({'phone': opp.phone or (opp.partner_address_id and opp.partner_address_id.phone 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])
- return {'type': 'ir.actions.act_window_close'}
-
- 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.note, data.phone, data.contact_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 980b93500d2..a12bd92115c 100644
--- a/addons/crm/wizard/crm_opportunity_to_phonecall_view.xml
+++ b/addons/crm/wizard/crm_opportunity_to_phonecall_view.xml
@@ -16,24 +16,19 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
+
+
diff --git a/addons/crm/wizard/crm_partner_to_opportunity.py b/addons/crm/wizard/crm_partner_to_opportunity.py
index 4d24bd5b78f..6322d0341c1 100644
--- a/addons/crm/wizard/crm_partner_to_opportunity.py
+++ b/addons/crm/wizard/crm_partner_to_opportunity.py
@@ -35,16 +35,15 @@ class crm_partner2opportunity(osv.osv_memory):
'partner_id': fields.many2one('res.partner', 'Partner'),
}
+ def action_cancel(self, cr, uid, ids, context=None):
+ """
+ Closes Partner 2 Opportunity
+ """
+ return {'type':'ir.actions.act_window_close'}
+
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.
"""
partner_obj = self.pool.get('res.partner')
data = context and context.get('active_ids', []) or []
@@ -58,56 +57,17 @@ class crm_partner2opportunity(osv.osv_memory):
return res
def make_opportunity(self, cr, uid, ids, context=None):
- """
- @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 context: A standard dictionary for contextual values
- """
-
- data = context and context.get('active_ids', []) or []
- make_opportunity = self.pool.get('crm.partner2opportunity')
- data_obj = self.pool.get('ir.model.data')
- part_obj = self.pool.get('res.partner')
- categ_obj = self.pool.get('crm.case.categ')
- case_obj = self.pool.get('crm.lead')
-
- for make_opportunity_obj in make_opportunity.browse(cr, uid, ids, context=context):
- 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
-
- address = part_obj.address_get(cr, uid, data)
- categ_ids = categ_obj.search(cr, uid, [('object_id.model','=','crm.lead')])
-
- opp_id = case_obj.create(cr, uid, {
- 'name' : make_opportunity_obj.name,
- 'planned_revenue' : make_opportunity_obj.planned_revenue,
- 'probability' : make_opportunity_obj.probability,
- 'partner_id' : make_opportunity_obj.partner_id.id,
- 'partner_address_id' : address['default'],
- 'categ_id' : categ_ids and categ_ids[0] or '',
- 'state' :'draft',
- 'type': 'opportunity'
- })
- value = {
- 'name' : _('Opportunity'),
- 'view_type' : 'form',
- 'view_mode' : 'form,tree',
- 'res_model' : 'crm.lead',
- 'res_id' : opp_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
+ partner_ids = context and context.get('active_ids', []) or []
+ partner = self.pool.get('res.partner')
+ lead = self.pool.get('crm.lead')
+ 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()
diff --git a/addons/crm/wizard/crm_partner_to_opportunity_view.xml b/addons/crm/wizard/crm_partner_to_opportunity_view.xml
index 1111bbbbc50..f75f3d5b90e 100644
--- a/addons/crm/wizard/crm_partner_to_opportunity_view.xml
+++ b/addons/crm/wizard/crm_partner_to_opportunity_view.xml
@@ -16,7 +16,7 @@
-
+
diff --git a/addons/crm/wizard/crm_phonecall_to_opportunity.py b/addons/crm/wizard/crm_phonecall_to_opportunity.py
index ffab1867ebb..7305cbd8b5f 100644
--- a/addons/crm/wizard/crm_phonecall_to_opportunity.py
+++ b/addons/crm/wizard/crm_phonecall_to_opportunity.py
@@ -26,97 +26,31 @@ 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 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.
"""
record_id = context and context.get('active_id', False) or False
- res = super(crm_phonecall2opportunity, self).default_get(cr, uid, fields, context=context)
+ res = {}
if record_id:
phonecall = self.pool.get('crm.phonecall').browse(cr, uid, record_id, context=context)
diff --git a/addons/crm/wizard/crm_phonecall_to_opportunity_view.xml b/addons/crm/wizard/crm_phonecall_to_opportunity_view.xml
index ea024831b54..d3c59f89433 100644
--- a/addons/crm/wizard/crm_phonecall_to_opportunity_view.xml
+++ b/addons/crm/wizard/crm_phonecall_to_opportunity_view.xml
@@ -19,7 +19,7 @@
-
+
diff --git a/addons/crm/wizard/crm_phonecall_to_partner.py b/addons/crm/wizard/crm_phonecall_to_partner.py
index 38e673108e4..0fa077bbf42 100644
--- a/addons/crm/wizard/crm_phonecall_to_partner.py
+++ b/addons/crm/wizard/crm_phonecall_to_partner.py
@@ -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 user’s 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 user’s 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,117 +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 user’s 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 user’s 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 = self.pool.get('crm.phonecall')
- 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', [])
-
- 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)
- 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 user’s 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
+ data = self.browse(cr, uid, ids, context=context)[0]
+ call_ids = context and context.get('active_ids') or []
+ 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[call_ids[0]]
crm_phonecall2partner()
diff --git a/addons/crm/wizard/crm_phonecall_to_phonecall.py b/addons/crm/wizard/crm_phonecall_to_phonecall.py
index 2872acad4eb..d68591ab0b7 100644
--- a/addons/crm/wizard/crm_phonecall_to_phonecall.py
+++ b/addons/crm/wizard/crm_phonecall_to_phonecall.py
@@ -25,108 +25,50 @@ 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"),
+ 'contact_name':fields.char('Contact', size=64),
+ 'phone':fields.char('Phone', size=64),
+ '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"),
+ 'note':fields.text('Note')
+ }
+
+
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 user’s 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 user’s 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.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 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.
+
"""
res = super(crm_phonecall2phonecall, self).default_get(cr, uid, fields, context=context)
record_id = context and context.get('active_id', False) or False
diff --git a/addons/crm/wizard/crm_phonecall_to_phonecall_view.xml b/addons/crm/wizard/crm_phonecall_to_phonecall_view.xml
index 794634da4f1..572fbb8b9a1 100644
--- a/addons/crm/wizard/crm_phonecall_to_phonecall_view.xml
+++ b/addons/crm/wizard/crm_phonecall_to_phonecall_view.xml
@@ -22,8 +22,8 @@
-
-
+
+
diff --git a/addons/crm_claim/__openerp__.py b/addons/crm_claim/__openerp__.py
index ae493c5dac2..8c3854ffd2e 100644
--- a/addons/crm_claim/__openerp__.py
+++ b/addons/crm_claim/__openerp__.py
@@ -48,7 +48,9 @@ automatically new claims based on incoming emails.
'demo_xml': [
'crm_claim_demo.xml',
],
- 'test': ['test/test_crm_claim.yml'],
+ 'test': ['test/process/claim.yml',
+ 'test/ui/claim_demo.yml'
+ ],
'installable': True,
'active': False,
'certificate' : '00612027414703404749',
diff --git a/addons/crm_claim/crm_claim.py b/addons/crm_claim/crm_claim.py
index b5cd2009698..7875d6a2f1a 100644
--- a/addons/crm_claim/crm_claim.py
+++ b/addons/crm_claim/crm_claim.py
@@ -46,6 +46,7 @@ class crm_claim(crm.crm_case, osv.osv):
_columns = {
'id': fields.integer('ID', readonly=True),
'name': fields.char('Claim Subject', size=128, required=True),
+ 'active': fields.boolean('Active'),
'action_next': fields.char('Next Action', size=200),
'date_action_next': fields.datetime('Next Action Date'),
'description': fields.text('Description'),
@@ -95,6 +96,7 @@ class crm_claim(crm.crm_case, osv.osv):
'date': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'crm.case', context=c),
'priority': lambda *a: crm.AVAILABLE_PRIORITIES[2][0],
+ 'active': lambda *a: 1
}
def onchange_partner_id(self, cr, uid, ids, part, email=False):
@@ -129,8 +131,6 @@ class crm_claim(crm.crm_case, osv.osv):
if l.state == 'draft':
message = _("The claim '%s' has been opened.") % l.name
self.log(cr, uid, l.id, message)
- value = {'date_open': time.strftime('%Y-%m-%d %H:%M:%S')}
- self.write(cr, uid, [l.id], value)
stage_id = self.stage_find(cr, uid, l.section_id.id or False, [('sequence','>',0)])
if stage_id:
self.stage_set(cr, uid, [l.id], stage_id)
diff --git a/addons/crm_claim/crm_claim_demo.xml b/addons/crm_claim/crm_claim_demo.xml
index 0f8488628b5..8279e04eb6f 100644
--- a/addons/crm_claim/crm_claim_demo.xml
+++ b/addons/crm_claim/crm_claim_demo.xml
@@ -15,8 +15,6 @@
-
-
@@ -31,8 +29,6 @@
-
-
@@ -47,8 +43,6 @@
-
-
@@ -63,8 +57,6 @@
-
-
@@ -79,8 +71,6 @@
-
-
@@ -88,14 +78,12 @@
-
-
@@ -104,14 +92,12 @@
-
-
diff --git a/addons/crm_claim/test/customer_claim.eml b/addons/crm_claim/test/customer_claim.eml
new file mode 100644
index 00000000000..ff3c45b9142
--- /dev/null
+++ b/addons/crm_claim/test/customer_claim.eml
@@ -0,0 +1,17 @@
+Message-ID: <4EA66F25.7080001@customer.com>
+Date: Tue, 25 Oct 2011 13:41:17 +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: claims@my.com
+Subject: demande de =?ISO-8859-1?Q?r=E8glement_de_votre_produit=2E?=
+Content-Type: text/plain; charset=ISO-8859-1; format=flowed
+Content-Transfer-Encoding: 8bit
+
+J'ai acheté votre produit il ya quelques jours. maintenant certains
+problèmes sont survenus sur votre produit.
+je demande donc à convertir cette demande que la réclamation et de
+résoudre les problèmes le plus tôt possible.
+
+Merci
+
diff --git a/addons/crm_claim/test/process/claim.yml b/addons/crm_claim/test/process/claim.yml
new file mode 100644
index 00000000000..e20436cd3c6
--- /dev/null
+++ b/addons/crm_claim/test/process/claim.yml
@@ -0,0 +1,46 @@
+-
+ Customer requests a claim after the sale of our product. He sends claim request by email.
+-
+ 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_claim','test', 'customer_claim.eml'),'rb')
+ request_message = request_file.read()
+ self.message_process(cr, uid, 'crm.claim', request_message)
+-
+ After getting the mail, I check details of new claim of that customer.
+-
+ !python {model: crm.claim}: |
+ from openerp import tools
+ claim_ids = self.search(cr, uid, [('email_from','=', 'Mr. John Right ')])
+ assert claim_ids and len(claim_ids), "Claim is not created after getting request"
+ claim = self.browse(cr, uid, claim_ids[0], context=context)
+ assert claim.name == tools.ustr("demande derèglement de votre produit."), "Subject does not match"
+-
+ I open customer claim.
+-
+ !python {model: crm.claim}: |
+ claim_ids = self.search(cr, uid, [('email_from','=', 'Mr. John Right ')])
+ self.case_open(cr, uid, claim_ids)
+-
+ I check Claim Details after open.
+-
+ !python {model: crm.claim}: |
+ claim_ids = self.search(cr, uid, [('email_from','=', 'Mr. John Right ')])
+ claim = self.browse(cr, uid, claim_ids[0])
+ assert claim.state == "open", "Claim is not in Open state"
+ assert claim.stage_id.id == ref("crm.stage_lead1"), "Claim is not in New stage"
+-
+ After complete all service from our side, I close this claim.
+-
+ !python {model: crm.claim}: |
+ claim_ids = self.search(cr, uid, [('email_from','=', 'Mr. John Right ')])
+ self.case_close(cr, uid, claim_ids)
+-
+ I check Claim details after closed.
+-
+ !python {model: crm.claim}: |
+ claim_ids = self.search(cr, uid, [('email_from','=', 'Mr. John Right ')])
+ claim = self.browse(cr, uid, claim_ids[0])
+ assert claim.state == "done", "Claim is not in close state"
diff --git a/addons/crm_claim/test/test_crm_claim.yml b/addons/crm_claim/test/test_crm_claim.yml
deleted file mode 100644
index 9ee130329a7..00000000000
--- a/addons/crm_claim/test/test_crm_claim.yml
+++ /dev/null
@@ -1,44 +0,0 @@
-- |
- I check claims which contain customer claim information about document
- related problem, product related problem.
-- |
- I start by creating new claims for Damaged product as Value Claims with priority High and specify
- date of claim at which claim is created.
--
- !record {model: crm.claim, id: crm_claim_damagedproduct0}:
- categ_id: crm_claim.categ_claim2
- date: !eval time.strftime('%Y-%m-%d %H:%M:%S')
- email_from: info@balmerinc.be
- name: 'Damaged product '
- partner_address_id: base.res_partner_address_1
- partner_id: base.res_partner_9
- priority: '2'
- section_id: crm.section_sales_department
-
-- |
- I check that the claims is in 'draft' state.
--
- !assert {model: crm.claim, id: crm_claim_damagedproduct0}:
- - state == 'draft'
-- |
- I can change that stage by next button right on it.
--
- !python {model: crm.claim}: |
- self.stage_next(cr, uid, [ref('crm_claim_damagedproduct0')])
-- |
- I make this claim as Open.
--
- !python {model: crm.claim}: |
- self.case_open(cr, uid, [ref('crm_claim_damagedproduct0')])
-- |
- I am changing partner Assigned to the Claim.
--
- !python {model: crm.claim}: |
- self.onchange_partner_id(cr, uid, [ref('crm_claim_damagedproduct0')], [])
- self.onchange_partner_id(cr, uid, [ref('crm_claim_damagedproduct0')], ref('base.res_partner_10'))
-- |
- I am changing partner Address to the Claim.
--
- !python {model: crm.claim}: |
- self.onchange_partner_address_id(cr, uid, [ref('crm_claim_damagedproduct0')], [], email = False)
-
diff --git a/addons/crm_claim/test/ui/claim_demo.yml b/addons/crm_claim/test/ui/claim_demo.yml
new file mode 100644
index 00000000000..520434fcd90
--- /dev/null
+++ b/addons/crm_claim/test/ui/claim_demo.yml
@@ -0,0 +1,15 @@
+-
+ I create claim record to call of partner onchange method.
+-
+ !record {model: crm.claim, id: crm_case_claim04}:
+ name: 'Damaged Product'
+ partner_id: base.res_partner_6
+-
+ I Update the message for claim.
+-
+ !python {model: crm.claim}: |
+ try:
+ self.message_update(cr, uid,[ref('crm_case_claim04')], {'subject': 'Claim Update record','body_text': 'first training session completed',})
+ except:
+ pass
+
\ No newline at end of file
diff --git a/addons/crm_fundraising/__openerp__.py b/addons/crm_fundraising/__openerp__.py
index 2d75f9e69b7..993b3dc6434 100644
--- a/addons/crm_fundraising/__openerp__.py
+++ b/addons/crm_fundraising/__openerp__.py
@@ -51,7 +51,7 @@ fund status.
'demo_xml': [
'crm_fundraising_demo.xml',
],
- 'test': ['test/test_crm_fund.yml'],
+ 'test': ['test/process/fund-rising.yml'],
'installable': True,
'active': False,
'certificate' : '00871545204231528989',
diff --git a/addons/crm_fundraising/test/customer_fundraising.eml b/addons/crm_fundraising/test/customer_fundraising.eml
new file mode 100644
index 00000000000..e7cd3f9482e
--- /dev/null
+++ b/addons/crm_fundraising/test/customer_fundraising.eml
@@ -0,0 +1,14 @@
+Message-ID: <4EA66F25.7080010@customer.com>
+Date: Tue, 25 Oct 2011 13:41:17 +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: contribute@my.com
+Subject: Demande de controbute dans votre fonds.
+Content-Type: text/plain; charset=ISO-8859-1; format=flowed
+Content-Transfer-Encoding: 8bit
+
+Client est très heureux d'utiliser notre produit et il l'intérêt de donner une partie des fonds dans notre produit. Il a donc envoyé la demande par courriel pour les collectes de fonds.
+
+Merci
+
diff --git a/addons/crm_fundraising/test/process/fund-rising.yml b/addons/crm_fundraising/test/process/fund-rising.yml
new file mode 100644
index 00000000000..b49f1f5c1bd
--- /dev/null
+++ b/addons/crm_fundraising/test/process/fund-rising.yml
@@ -0,0 +1,19 @@
+-
+ Customer is very happy with our service and he interest to contribute into our fund. so He sent request by email for Fundraising.
+-
+ 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_fundraising','test', 'customer_fundraising.eml'),'rb')
+ request_message = request_file.read()
+ self.message_process(cr, uid, 'crm.fundraising', request_message)
+-
+ After getting the mail, I check details of new fundraising of that customer.
+-
+ !python {model: crm.fundraising}: |
+ from openerp import tools
+ fund_ids = self.search(cr, uid, [('email_from','=', 'Mr. John Right ')])
+ assert fund_ids and len(fund_ids), "Fund is not created after getting request"
+ fund = self.browse(cr, uid, fund_ids[0], context=context)
+ assert fund.name == tools.ustr("Demande de controbute dans votre fonds."), "Subject does not match"
diff --git a/addons/crm_fundraising/test/test_crm_fund.yml b/addons/crm_fundraising/test/test_crm_fund.yml
deleted file mode 100644
index ef81afeb563..00000000000
--- a/addons/crm_fundraising/test/test_crm_fund.yml
+++ /dev/null
@@ -1,45 +0,0 @@
-- |
- I start test Fund Raising which contain information about Donation or charity
- given by user.
-- |
- I start by creating new Funds entry for donation for books to poor school children
- with cost 500000.00 and category as "Learning And Education"
- I make payment by Cheque so I make sure that the mode on fund is selected as cheque.
--
- !record {model: crm.fundraising, id: crm_fundraising_donationforbookstopoorschoolchildren0}:
- categ_id: crm_fundraising.categ_fund2
- email_from: info@balmerinc.be
- name: Donation for books to poor school children
- partner_address_id: base.res_partner_address_1
- partner_id: base.res_partner_9
- planned_cost: 500000.0
- section_id: crm.section_sales_department
- type_id: crm_fundraising.type_fund2
-- |
- I check that the Funds is in 'draft' state.
--
- !assert {model: crm.fundraising, id: crm_fundraising_donationforbookstopoorschoolchildren0}:
- - state == 'draft'
-- |
- I open Funds by click on "Open" button.
--
- !python {model: crm.fundraising}: |
- self.case_open(cr, uid, [ref('crm_fundraising_donationforbookstopoorschoolchildren0')])
--
- I create the message regarding the all details of fundraising.
--
- !python {model: crm.fundraising}: |
- msg = {
- 'subject': 'fundraising_email',
- 'body_text': 'fundraising details',
- 'from': 'Administrator ',
- 'priority':'3',
- }
- context = None
- self.message_new(cr, uid,msg,context)
-
-- |
- After a request via email now I close this fundraising Request by clicking on "Done" button.
--
- !python {model: crm.fundraising}: |
- self.case_close(cr, uid, [ref('crm_fundraising_donationforbookstopoorschoolchildren0')])
diff --git a/addons/crm_helpdesk/__openerp__.py b/addons/crm_helpdesk/__openerp__.py
index 5124c3c5817..2adf7d26dcc 100644
--- a/addons/crm_helpdesk/__openerp__.py
+++ b/addons/crm_helpdesk/__openerp__.py
@@ -49,7 +49,7 @@ and categorize your interventions with a channel and a priority level.
'demo_xml': [
'crm_helpdesk_demo.xml',
],
- 'test': ['test/test_crm_helpdesk.yml'],
+ 'test': ['test/process/help-desk.yml'],
'installable': True,
'active': False,
'certificate' : '00830691522781519309',
diff --git a/addons/crm_helpdesk/test/customer_question.eml b/addons/crm_helpdesk/test/customer_question.eml
new file mode 100644
index 00000000000..38a4c95fb0c
--- /dev/null
+++ b/addons/crm_helpdesk/test/customer_question.eml
@@ -0,0 +1,15 @@
+Message-ID: <4EA66F25.7080013@customer.com>
+Date: Tue, 25 Oct 2011 13:41:17 +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: info@my.com
+Subject: Where is download link of user manual of your product ?
+Content-Type: text/plain; charset=ISO-8859-1; format=flowed
+Content-Transfer-Encoding: 8bit
+
+I want to download user manual of your product.
+can you provide download link?
+
+Thanks
+
diff --git a/addons/crm_helpdesk/test/process/help-desk.yml b/addons/crm_helpdesk/test/process/help-desk.yml
new file mode 100644
index 00000000000..320bd61c2af
--- /dev/null
+++ b/addons/crm_helpdesk/test/process/help-desk.yml
@@ -0,0 +1,30 @@
+-
+ Customer has Questions regarding our service. so He sent questions list by email.
+-
+ 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_helpdesk','test', 'customer_question.eml'),'rb')
+ request_message = request_file.read()
+ self.message_process(cr, uid, 'crm.helpdesk', request_message)
+-
+ After getting the mail, I check details of new question of that customer.
+-
+ !python {model: crm.helpdesk}: |
+ from openerp import tools
+ question_ids = self.search(cr, uid, [('email_from','=', 'Mr. John Right ')])
+ assert question_ids and len(question_ids), "Question is not created after getting request"
+ question = self.browse(cr, uid, question_ids[0], context=context)
+ assert question.name == tools.ustr("Where is download link of user manual of your product ? "), "Subject does not match"
+-
+ Now I Update message according to provide services.
+-
+ !python {model: crm.helpdesk}: |
+ question_ids = self.search(cr, uid, [('email_from','=', 'Mr. John Right ')])
+ try:
+ self.message_update(cr, uid, question_ids, {'subject': 'Link of product', 'body_text': 'www.openerp.com'})
+ except:
+ pass
+
+
diff --git a/addons/crm_helpdesk/test/test_crm_helpdesk.yml b/addons/crm_helpdesk/test/test_crm_helpdesk.yml
deleted file mode 100644
index eb0a25d2110..00000000000
--- a/addons/crm_helpdesk/test/test_crm_helpdesk.yml
+++ /dev/null
@@ -1,57 +0,0 @@
--
- |
- I start by creating New helpdesk request regarding some functional questions.
- I select Date at which helpdesk request is created.
--
- !record {model: crm.helpdesk, id: crm_helpdesk_somefunctionalquestion0}:
- date: !eval time.strftime('%Y-%m-%d %H:%M:%S')
- email_from: info@balmerinc.be
- name: Some functional question.
- partner_address_id: base.res_partner_address_1
- partner_id: base.res_partner_9
- section_id: crm.section_sales_department
--
- I create the message.
--
- !python {model: crm.helpdesk}: |
- msg = {
- 'subject': 'test_email',
- 'body_text': 'Testing',
- 'from': 'Administrator ',
- }
- context = None
- self.message_new(cr, uid,msg,context)
-
-- |
- I check that the Helpdesk request is in 'Draft' state.
--
- !assert {model: crm.helpdesk, id: crm_helpdesk_somefunctionalquestion0}:
- - state == 'draft'
-- |
- I make it "Open".
--
- !python {model: crm.helpdesk}: |
- self.case_open(cr, uid, [ref('crm_helpdesk_somefunctionalquestion0')])
--
- Update the created message.
--
- !python {model: crm.helpdesk}: |
- vals = {}
- msg = {
- 'subject': 'test_email',
- 'body_text': 'Testing',
- 'from': 'Administrator ',
- 'priority': 'done'
- }
- context = None
- default_act = 'pending'
- try:
- self.message_update(cr, uid,[ref('crm_helpdesk_somefunctionalquestion0')], msg,context)
- except:
- pass
-- |
- After a proper communication for the request via email I make sure that the request is fulfilled and
- I close this HelpDesk Request by clicking on "Close" button.
--
- !python {model: crm.helpdesk}: |
- self.case_close(cr, uid, [ref('crm_helpdesk_somefunctionalquestion0')])
diff --git a/addons/crm_partner_assign/__openerp__.py b/addons/crm_partner_assign/__openerp__.py
index a38da8a665a..555717899b1 100644
--- a/addons/crm_partner_assign/__openerp__.py
+++ b/addons/crm_partner_assign/__openerp__.py
@@ -38,6 +38,9 @@ You can also use the geolocalization without using the GPS coordinates.
""",
'author': 'OpenERP SA',
'depends': ['crm'],
+ 'demo_xml': [
+ 'res_partner_demo.xml',
+ ],
'update_xml': [
'security/ir.model.access.csv',
'res_partner_view.xml',
@@ -46,7 +49,9 @@ You can also use the geolocalization without using the GPS coordinates.
'report/crm_lead_report_view.xml',
'report/crm_partner_report_view.xml',
],
- 'test': ['test/test_crm_partner_assign.yml'],
+ 'test': [
+ 'test/process/partner_assign.yml',
+ ],
'installable': True,
'active': False,
'certificate': '00503409558942442061',
diff --git a/addons/crm_partner_assign/crm_lead_view.xml b/addons/crm_partner_assign/crm_lead_view.xml
index 2ec3c85353b..14e160fb397 100644
--- a/addons/crm_partner_assign/crm_lead_view.xml
+++ b/addons/crm_partner_assign/crm_lead_view.xml
@@ -8,7 +8,7 @@
-
+
@@ -27,7 +27,7 @@
-
diff --git a/addons/crm_partner_assign/partner_geo_assign.py b/addons/crm_partner_assign/partner_geo_assign.py
index 401d09146ae..08c4f7d23b6 100644
--- a/addons/crm_partner_assign/partner_geo_assign.py
+++ b/addons/crm_partner_assign/partner_geo_assign.py
@@ -24,22 +24,25 @@ from osv import fields
import urllib,re
import random, time
from tools.translate import _
+import tools
def geo_find(addr):
+ addr = addr.encode('utf8')
+ regex = '([+-]?[0-9\.]+),([+-]?[0-9\.]+),([+-]?[0-9\.]+)'
+ url = 'http://maps.google.com/maps/geo?q=' + urllib.quote(addr) + '&output=xml&oe=utf8&sensor=false'
try:
- regex = '([+-]?[0-9\.]+),([+-]?[0-9\.]+),([+-]?[0-9\.]+)'
- url = 'http://maps.google.com/maps/geo?q=' + urllib.quote(addr) + '&output=xml&oe=utf8&sensor=false'
xml = urllib.urlopen(url).read()
- if '' in xml:
- return None
- result = re.search(regex, xml, re.M|re.I)
- if not result:
- return None
- return float(result.group(2)),float(result.group(1))
except Exception, e:
raise osv.except_osv(_('Network error'),
_('Could not contact geolocation servers, please make sure you have a working internet connection (%s)') % e)
+ if '' in xml:
+ return None
+ result = re.search(regex, xml, re.M|re.I)
+ if not result:
+ return None
+ return float(result.group(2)),float(result.group(1))
+
class res_partner_grade(osv.osv):
_order = 'sequence'
@@ -74,9 +77,13 @@ class res_partner(osv.osv):
for partner in self.browse(cr, uid, ids, context=context):
if not partner.address:
continue
- part = partner.address[0]
- addr = ', '.join(filter(None, [part.street, (part.zip or '')+' '+(part.city or ''), part.state_id and part.state_id.name, part.country_id and part.country_id.name]))
- result = geo_find(addr.encode('utf8'))
+ contact = partner.address[0] #TOFIX: should be get latitude and longitude for default contact?
+ addr = ', '.join(filter(None, [
+ contact.street,
+ "%s %s" % (contact.zip , contact.city),
+ contact.state_id and contact.state_id.name,
+ contact.country_id and contact.country_id.name]))
+ result = geo_find(tools.ustr(addr))
if result:
self.write(cr, uid, [partner.id], {
'partner_latitude': result[0],
@@ -94,14 +101,13 @@ class crm_lead(osv.osv):
'partner_assigned_id': fields.many2one('res.partner', 'Assigned Partner', help="Partner this case has been forwarded/assigned to.", select=True),
'date_assign': fields.date('Assignation Date', help="Last date this case was forwarded/assigned to a partner"),
}
+ def _merge_data(self, cr, uid, ids, oldest, fields, context=None):
+ fields += ['partner_latitude', 'partner_longitude', 'partner_assigned_id', 'date_assign']
+ return super(crm_lead, self)._merge_data(cr, uid, ids, oldest, fields, context=context)
+
def onchange_assign_id(self, cr, uid, ids, partner_assigned_id, context=None):
"""This function updates the "assignation date" automatically, when manually assign a partner in the geo assign tab
- @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 stage’s IDs
- @stage_id: change state id on run time """
-
+ """
if not partner_assigned_id:
return {'value':{'date_assign': False}}
else:
@@ -112,73 +118,113 @@ class crm_lead(osv.osv):
'user_id' : user_id}
}
- def assign_partner(self, cr, uid, ids, context=None):
- ok = False
- for part in self.browse(cr, uid, ids, context=context):
- if not part.country_id:
- continue
- addr = ', '.join(filter(None, [part.street, (part.zip or '')+' '+(part.city or ''), part.state_id and part.state_id.name, part.country_id and part.country_id.name]))
- result = geo_find(addr.encode('utf8'))
- if result:
- self.write(cr, uid, [part.id], {
- 'partner_latitude': result[0],
- 'partner_longitude': result[1]
- }, context=context)
+ def action_assign_partner(self, cr, uid, ids, context=None):
+ return self.assign_partner(cr, uid, ids, partner_id=False, context=context)
+ def assign_partner(self, cr, uid, ids, partner_id=False, context=None):
+ partner_ids = {}
+ res = False
+ res_partner = self.pool.get('res.partner')
+ if not partner_id:
+ partner_ids = self.search_geo_partner(cr, uid, ids, context=context)
+ for lead in self.browse(cr, uid, ids, context=context):
+ if not partner_id:
+ partner_id = partner_ids.get(lead.id, False)
+ if not partner_id:
+ continue
+ self.assign_geo_localize(cr, uid, [lead.id], lead.partner_latitude, lead.partner_longitude, context=context)
+ partner = res_partner.browse(cr, uid, partner_id, context=context)
+ if partner.user_id:
+ for lead_id in ids:
+ self.allocate_salesman(cr, uid, [lead_id], [partner.user_id.id], context=context)
+ self.write(cr, uid, [lead.id], {'date_assign': time.strftime('%Y-%m-%d'), 'partner_assigned_id': partner_id}, context=context)
+ return res
+
+
+ def assign_geo_localize(self, cr, uid, ids, latitude=False, longitude=False, context=None):
+ for lead in self.browse(cr, uid, ids, context=context):
+ if not lead.country_id:
+ continue
+ addr = ', '.join(filter(None, [
+ lead.street,
+ "%s %s" % (lead.zip, lead.city),
+ lead.state_id and lead.state_id.name or '',
+ lead.country_id and lead.country_id.name or ''
+ ]))
+ result = geo_find(tools.ustr(addr))
+ if not latitude and result:
+ latitude = result[0]
+ if not longitude and result:
+ longitude = result[1]
+ self.write(cr, uid, [lead.id], {
+ 'partner_latitude': latitude,
+ 'partner_longitude': longitude
+ }, context=context)
+ return True
+
+ def search_geo_partner(self, cr, uid, ids, context=None):
+ res_partner = self.pool.get('res.partner')
+ res_partner_ids = {}
+ self.assign_geo_localize(cr, uid, ids, context=context)
+ for lead in self.browse(cr, uid, ids, context=context):
+ partner_ids = []
+ if not lead.country_id:
+ continue
+ latitude = lead.partner_latitude
+ longitude = lead.partner_longitude
+ if latitude and longitude:
# 1. first way: in the same country, small area
- part_ids = self.pool.get('res.partner').search(cr, uid, [
- ('partner_weight','>',0),
- ('partner_latitude','>',result[0]-2), ('partner_latitude','<',result[0]+2),
- ('partner_longitude','>',result[1]-1.5), ('partner_longitude','<',result[1]+1.5),
- ('country', '=', part.country_id.id),
+ partner_ids = res_partner.search(cr, uid, [
+ ('partner_weight', '>', 0),
+ ('partner_latitude', '>', latitude - 2), ('partner_latitude', '<', latitude + 2),
+ ('partner_longitude', '>', longitude - 1.5), ('partner_longitude', '<', longitude + 1.5),
+ ('country', '=', lead.country_id.id),
], context=context)
# 2. second way: in the same country, big area
- if not part_ids:
- part_ids = self.pool.get('res.partner').search(cr, uid, [
- ('partner_weight','>',0),
- ('partner_latitude','>',result[0]-4), ('partner_latitude','<',result[0]+4),
- ('partner_longitude','>',result[1]-3), ('partner_longitude','<',result[1]+3),
- ('country', '=', part.country_id.id),
+ if not partner_ids:
+ partner_ids = res_partner.search(cr, uid, [
+ ('partner_weight', '>', 0),
+ ('partner_latitude', '>', latitude - 4), ('partner_latitude', '<', latitude + 4),
+ ('partner_longitude', '>', longitude - 3), ('partner_longitude', '<' , longitude + 3),
+ ('country', '=', lead.country_id.id),
], context=context)
# 5. fifth way: anywhere in same country
- if not part_ids:
+ if not partner_ids:
# still haven't found any, let's take all partners in the country!
- part_ids = self.pool.get('res.partner').search(cr, uid, [
- ('partner_weight','>',0),
- ('country', '=', part.country_id.id),
+ partner_ids = res_partner.search(cr, uid, [
+ ('partner_weight', '>', 0),
+ ('country', '=', lead.country_id.id),
], context=context)
# 6. sixth way: closest partner whatsoever, just to have at least one result
- if not part_ids:
+ if not partner_ids:
# warning: point() type takes (longitude, latitude) as parameters in this order!
cr.execute("""SELECT id, distance
FROM (select id, (point(partner_longitude, partner_latitude) <-> point(%s,%s)) AS distance FROM res_partner
WHERE partner_longitude is not null
AND partner_latitude is not null
AND partner_weight > 0) AS d
- ORDER BY distance LIMIT 1""", (result[1],result[0]))
+ ORDER BY distance LIMIT 1""", (longitude, latitude))
res = cr.dictfetchone()
if res:
- part_ids.append(res['id'])
+ partner_ids.append(res['id'])
- total = 0
+ total_weight = 0
toassign = []
- for part2 in self.pool.get('res.partner').browse(cr, uid, part_ids, context=context):
- total += part2.partner_weight
- toassign.append( (part2.id, total) )
+ for partner in res_partner.browse(cr, uid, partner_ids, context=context):
+ total_weight += partner.partner_weight
+ toassign.append( (partner.id, total_weight) )
+
random.shuffle(toassign) # avoid always giving the leads to the first ones in db natural order!
- mypartner = random.randint(0,total)
- for t in toassign:
- if mypartner<=t[1]:
- vals = self.onchange_assign_id(cr,uid, ids, t[0], context=context)['value']
- vals.update({'partner_assigned_id': t[0], 'date_assign': time.strftime('%Y-%m-%d')})
- self.write(cr, uid, [part.id], vals, context=context)
+ nearest_weight = random.randint(0, total_weight)
+ for partner_id, weight in toassign:
+ if nearest_weight <= weight:
+ res_partner_ids[lead.id] = partner_id
break
- ok = True
- return ok
+ return res_partner_ids
crm_lead()
diff --git a/addons/crm_partner_assign/res_partner_demo.xml b/addons/crm_partner_assign/res_partner_demo.xml
new file mode 100644
index 00000000000..66ee1fbd5e7
--- /dev/null
+++ b/addons/crm_partner_assign/res_partner_demo.xml
@@ -0,0 +1,13 @@
+
+
+
+
+ First
+ 1
+
+
+
+ 10
+
+
+
diff --git a/addons/crm_partner_assign/test/process/partner_assign.yml b/addons/crm_partner_assign/test/process/partner_assign.yml
new file mode 100644
index 00000000000..1035f7e8862
--- /dev/null
+++ b/addons/crm_partner_assign/test/process/partner_assign.yml
@@ -0,0 +1,37 @@
+-
+ In order to test find nearest Partner functionality and assign to opportunity ,
+-
+ I Set Geo Lattitude and Longitude according to partner address.
+-
+ !python {model: res.partner}: |
+ self.geo_localize(cr, uid, [ref('base.res_partner_ericdubois0')], context)
+-
+ I check Geo Latitude and Longitude of partner after set
+-
+ !python {model: res.partner}: |
+ partner = self.browse(cr, uid, ref('base.res_partner_ericdubois0'))
+ assert partner.partner_latitude == 50.4530495 , "Latitude is wrong"
+ assert partner.partner_longitude == 3.9693885 , "Longitude is wrong"
+-
+ I assign nearest partner to opportunity.
+-
+ !python {model: crm.lead}: |
+ self.assign_partner(cr, uid, [ref('crm.crm_case_abcfuelcounits0')], context=context)
+-
+ I check assigned partner of opportunity who is nearest Geo Latitude and Longitude of opportunity.
+-
+ !python {model: crm.lead}: |
+ lead = self.browse(cr, uid, ref('crm.crm_case_abcfuelcounits0'))
+ assert lead.partner_assigned_id.id == ref('base.res_partner_ericdubois0') , "Opportuniy is not assigned nearest partner"
+ assert lead.partner_latitude == 50.8495239 , "Latitude is wrong"
+ assert lead.partner_longitude == 4.3667002 , "Longitude is wrong"
+-
+ I forward this opportunity to its nearest partner.
+-
+ !python {model: crm.lead.forward.to.partner}: |
+ context.update({'active_model': 'crm.lead', 'active_id': ref('crm.crm_case_abcfuelcounits0'), 'active_ids': [ref('crm.crm_case_abcfuelcounits0')]})
+ forward_id = self.create(cr, uid, {'send_to': 'partner'}, context=context)
+ try:
+ self.action_forward(cr, uid, [forward_id], context=context)
+ except:
+ pass
diff --git a/addons/crm_partner_assign/test/test_crm_partner_assign.yml b/addons/crm_partner_assign/test/test_crm_partner_assign.yml
deleted file mode 100644
index 359fa8454f6..00000000000
--- a/addons/crm_partner_assign/test/test_crm_partner_assign.yml
+++ /dev/null
@@ -1,137 +0,0 @@
--
- In order to test Forward Partner functionality, I create an opportunity and forward it to partner.
--
- I assign an email address to Administrator.
--
- !record {model: res.users, id: base.user_root}:
- user_email: admin@openerp.com
--
- I create some partner grades.
--
- I create a grade 'First'.
--
- !record {model: res.partner.grade, id: res_partner_grade_first0}:
- name: First
- sequence: 1
--
- I create another grade 'Second'.
--
- !record {model: res.partner.grade, id: res_partner_grade_second0}:
- name: Second
- sequence: 2
--
- I create one more grade 'Third'.
--
- !record {model: res.partner.grade, id: res_partner_grade_third0}:
- name: Third
- sequence: 3
--
- I assign grade 'First' to the partner 'Axelor'.
--
- !record {model: res.partner, id: base.res_partner_desertic_hispafuentes}:
- grade_id: res_partner_grade_first0
--
- I change the User email id or partner if needed.
--
- !python {model: res.partner}: |
- self.geo_localize(cr, uid, [ref('base.res_partner_desertic_hispafuentes')], context)
--
- I assgin a reply-to email address to Sales Team.
--
- !record {model: crm.case.section, id: crm.section_sales_department}:
- reply_to: sales_openerp@openerp.com
--
- I create an opportunity 'Questionnaire on OpenERP'.
--
- !record {model: crm.lead, id: crm_lead_questionnaireonopenerp0}:
- categ_id: crm.categ_oppor7
- section_id: crm.section_sales_department
- country_id: base.fr
- date_assign: '2011-02-07'
- day_close: 0.0
- day_open: 0.0
- email_from: info@axelor.com
- name: Questionnaire on OpenERP
- partner_address_id: base.res_partner_address_3000
- partner_assigned_id: base.res_partner_desertic_hispafuentes
- partner_id: base.res_partner_desertic_hispafuentes
- partner_latitude: 0.0
- partner_longitude: 0.0
- phone: +33 1 64 61 04 01
- planned_revenue: 0.0
- probability: 0.0
- type: opportunity
--
- I change the assigned partner.
--
- !python {model: crm.lead}: |
- self.onchange_assign_id(cr, uid, [ref('crm_lead_questionnaireonopenerp0')], ref('base.res_partner_desertic_hispafuentes'), context)
- self.assign_partner(cr, uid, [ref('crm_lead_questionnaireonopenerp0')], context)
--
- I change the User email id or partner if needed.
--
- !python {model: crm.lead.forward.to.partner}: |
- context.update({'history': 'latest', })
- user = ref('base.user_root')
- self.on_change_email(cr, uid, [ref('crm_lead_questionnaireonopenerp0')], user)
- self.on_change_partner(cr, uid, [ref('crm_lead_questionnaireonopenerp0')], ref('base.res_partner_desertic_hispafuentes'))
--
- I change in history define.
--
- !python {model: crm.lead.forward.to.partner}: |
- context.update({'history': 'info', })
- self.on_change_history(cr, uid, [ref('crm_lead_questionnaireonopenerp0')], context.get('history'), context)
--
- I check the case history.
--
- !python {model: crm.lead.forward.to.partner}: |
- context.update({'history': 'latest', })
- self._get_case_history(cr, uid, context.get('history'), ref('crm_lead_questionnaireonopenerp0'), context=context)
-
- context.update({'history': 'info', })
- self._get_case_history(cr, uid, context.get('history'), ref('crm_lead_questionnaireonopenerp0'), context=context)
-
- context.update({'history': 'whole', })
- self._get_case_history(cr, uid, context.get('history'), ref('crm_lead_questionnaireonopenerp0'), context=context)
--
- I get lead details.
--
- !python {model: crm.lead.forward.to.partner}: |
- self.get_lead_details(cr, uid, ref('crm_lead_questionnaireonopenerp0'), context)
--
- I click on Forward button.
--
- !python {model: crm.lead.forward.to.partner}: |
- from tools import config
- vals = {
- 'subject': 'email',
- 'email_to': 'info@axelor.com',
- 'email_from': 'Administrator ',
- 'reply_to': 'sales_openerp@openerp.com',
- 'state': 'draft',
- 'history': 'latest',
- }
- ids = self.create(cr, uid, vals, context={'active_id': ref('crm_lead_questionnaireonopenerp0'), 'active_model': 'crm.lead'})
- host = config.get('smtp_user', '127.0.0.1')
- assert config.get(host, True), 'SMTP not configured !'
- try:
- self.action_forward(cr, uid, [ids], context={'active_id': ref('crm_lead_questionnaireonopenerp0'), 'active_model': 'crm.lead'})
- except:
- pass
--
- I create the opportunity.
--
- !record {model: crm.lead, id: crm_opportunity2}:
- email_from: info@balmerinc.be
- name: 'FUEL CO 829264 - 10002 units'
- partner_address_id: base.res_partner_address_1
- partner_id: base.res_partner_9
- probability: 1.0
- stage_id: crm.stage_lead1
- categ_id: crm.categ_oppor2
- section_id: crm.section_sales_department
-- |
- I Update the data.
--
- !python {model: crm.merge.opportunity}: |
- self._update_data([ref('crm_opportunity2')], ref('crm_lead_questionnaireonopenerp0'))
diff --git a/addons/crm_partner_assign/wizard/__init__.py b/addons/crm_partner_assign/wizard/__init__.py
index b6bda71deaf..9224173145b 100644
--- a/addons/crm_partner_assign/wizard/__init__.py
+++ b/addons/crm_partner_assign/wizard/__init__.py
@@ -20,6 +20,3 @@
##############################################################################
import crm_forward_to_partner
-import crm_merge_opportunity
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/crm_partner_assign/wizard/crm_forward_to_partner.py b/addons/crm_partner_assign/wizard/crm_forward_to_partner.py
index cdaf8f19b12..565f99b9db1 100644
--- a/addons/crm_partner_assign/wizard/crm_forward_to_partner.py
+++ b/addons/crm_partner_assign/wizard/crm_forward_to_partner.py
@@ -24,6 +24,7 @@ import time
import re
from osv import osv, fields
from tools.translate import _
+from mail.mail_message import to_email
class crm_lead_forward_to_partner(osv.osv_memory):
"""Forwards lead history"""
@@ -34,6 +35,7 @@ class crm_lead_forward_to_partner(osv.osv_memory):
'send_to': fields.selection([('user', 'User'), ('partner', 'Partner'), \
('email', 'Email Address')], 'Send to', required=True),
'user_id': fields.many2one('res.users', "User"),
+ 'attachment_ids': fields.many2many('ir.attachment','lead_forward_to_partner_attachment_rel', 'wizard_id', 'attachment_id', 'Attachments'),
'partner_id' : fields.many2one('res.partner', 'Partner'),
'address_id' : fields.many2one('res.partner.address', 'Address'),
'history': fields.selection([('info', 'Case Information'), ('latest', 'Latest email'), ('whole', 'Whole Story')], 'Send history', required=True),
@@ -46,48 +48,8 @@ class crm_lead_forward_to_partner(osv.osv_memory):
}
- def get_whole_history(self, cr, uid, ids, context=None):
- """This function gets whole communication history and returns as top posting style
- @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 history IDs
- @param context: A standard dictionary for contextual values
- """
- whole = []
- for hist_id in ids:
- whole.append(self.get_latest_history(cr, uid, hist_id, context=context))
- whole = '\n\n'.join(whole)
- return whole or ''
-
- def get_latest_history(self, cr, uid, hist_id, context=None):
- """This function gets latest communication and returns as top posting style
- @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 hist_id: Id of latest history
- @param context: A standard dictionary for contextual values
- """
- log_pool = self.pool.get('mail.message')
- hist = log_pool.browse(cr, uid, hist_id, context=context)
- header = '-------- Original Message --------'
- sender = 'From: %s' %(hist.email_from or '')
- to = 'To: %s' % (hist.email_to or '')
- sentdate = 'Date: %s' % (hist.date or '')
- desc = '\n%s'%(hist.body_text)
- original = [header, sender, to, sentdate, desc]
- original = '\n'.join(original)
- return original
-
+
def on_change_email(self, cr, uid, ids, user):
- """This function fills email information based on user selected
- @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 Mail’s IDs
- @param user: Changed User id
- @param partner: Changed Partner id
- """
if not user:
return {'value': {'email_to': False}}
email = self.pool.get('res.users')._get_email_from(cr, uid, [user])[user]
@@ -98,54 +60,19 @@ class crm_lead_forward_to_partner(osv.osv_memory):
* info: Forward the case information
* whole: Send the whole history
* latest: Send the latest histoy
- @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 history IDs
- @param context: A standard dictionary for contextual values
"""
#TODO: ids and context are not comming
- res = False
+ res = {}
res_id = context.get('active_id')
- msg_val = self._get_case_history(cr, uid, history_type, res_id, context=context)
- if msg_val:
- res = {'value': {'body_text' : '\n\n' + msg_val}}
+ model = context.get('active_model')
+ lead = self.pool.get(model).browse(cr, uid, res_id, context)
+ body_text = self._get_message_body_text(cr, uid, lead, history_type, context=context)
+ if body_text:
+ res = {'value': {'body_text' : body_text}}
return res
-
- def _get_case_history(self, cr, uid, history_type, res_id, context=None):
- if not res_id:
- return
-
- msg_val = ''
- case_info = self.get_lead_details(cr, uid, res_id, context=context)
- model_pool = self.pool.get('crm.lead')
-
- if history_type == 'info':
- msg_val = case_info
-
- elif history_type == 'whole':
- log_ids = model_pool.browse(cr, uid, res_id, context=context).message_ids
- log_ids = map(lambda x: x.id, filter(lambda x: x.email_from, log_ids))
- msg_val = case_info + '\n\n' + self.get_whole_history(cr, uid, log_ids, context=context)
-
- elif history_type == 'latest':
- log_ids = model_pool.browse(cr, uid, res_id, context=context).message_ids
- log_ids = filter(lambda x: x.email_from and x.id, log_ids)
- if not log_ids:
- msg_val = case_info
- else:
- msg_val = case_info + '\n\n' + self.get_latest_history(cr, uid, log_ids[0].id, context=context)
-
- return msg_val
-
+
def on_change_partner(self, cr, uid, ids, partner_id):
"""This function fills address information based on partner/user selected
- @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 Mail’s IDs
- @param user: Changed User id
- @param partner: Changed Partner id
"""
if not partner_id:
return {'value' : {'email_to' : False, 'address_id': False}}
@@ -158,11 +85,11 @@ class crm_lead_forward_to_partner(osv.osv_memory):
partner = partner_obj.browse(cr, uid, [partner_id])
user_id = partner and partner[0].user_id or False
email = user_id and user_id.user_email or ''
- data.update({'email_cc' : email})
+ data.update({'email_cc' : email, 'user_id': user_id and user_id.id or False})
return {
'value' : data,
'domain' : {'address_id' : partner_id and "[('partner_id', '=', partner_id)]" or "[]"}
- }
+ }
def on_change_address(self, cr, uid, ids, address_id):
email = ''
@@ -170,155 +97,125 @@ class crm_lead_forward_to_partner(osv.osv_memory):
email = self.pool.get('res.partner.address').browse(cr, uid, address_id).email
return {'value': {'email_to' : email}}
- def send_mail(self, cr, uid, ids, context=None):
- if context is None:
- context = {}
- super(crm_lead_forward_to_partner, self).send_mail(cr, uid, ids, context=context)
- self.action_forward(cr, uid, ids, context)
- return {'type': 'ir.actions.act_window_close'}
-
def action_forward(self, cr, uid, ids, context=None):
"""
Forward the lead to a partner
"""
if context is None:
context = {}
+ res = {'type': 'ir.actions.act_window_close'}
+ model = context.get('active_model')
+ if model not in ('crm.lead'):
+ return res
+
this = self.browse(cr, uid, ids[0], context=context)
- case_pool = self.pool.get(context.get('active_model'))
- res_id = context and context.get('active_id', False) or False
- case = case_pool.browse(cr, uid, res_id, context=context)
- context.update({'mail': 'forward'})
-
- to_write = {'date_assign': time.strftime('%Y-%m-%d')}
- if (this.send_to == 'partner' and this.partner_id):
- to_write['partner_assigned_id'] = this.partner_id.id
-
- if this.send_to == 'user':
- to_write.update({'user_id' : this.user_id.id})
- email_re = r'([^ ,<@]+@[^> ,]+)'
- email_cc = re.findall(email_re, case.email_cc or '')
- new_cc = []
- if case.email_cc:
- new_cc.append(case.email_cc)
- for to in this.email_to.split(','):
- email_to = re.findall(email_re, to)
- email_to = email_to and email_to[0] or ''
- if email_to not in email_cc:
- new_cc.append(to)
- to_write.update({'email_cc' : ', '.join(new_cc) })
- case_pool.write(cr, uid, case.id, to_write, context=context)
- return {'type': 'ir.actions.act_window_close'}
-
- def get_lead_details(self, cr, uid, lead_id, context=None):
- body = []
- lead_proxy = self.pool.get('crm.lead')
- lead = lead_proxy.browse(cr, uid, lead_id, context=context)
- if not lead.type or lead.type == 'lead' or not lead.partner_address_id:
- field_names = [
- 'partner_name', 'title', 'function', 'street', 'street2',
- 'zip', 'city', 'country_id', 'state_id', 'email_from',
- 'phone', 'fax', 'mobile', 'categ_id', 'description',
- ]
-
- for field_name in field_names:
- field_definition = lead_proxy._columns[field_name]
- value = None
-
- if field_definition._type == 'selection':
- if hasattr(field_definition.selection, '__call__'):
- key = field_definition.selection(lead_proxy, cr, uid, context=context)
- else:
- key = field_definition.selection
- value = dict(key).get(lead[field_name], lead[field_name])
- elif field_definition._type == 'many2one':
- if lead[field_name]:
- value = lead[field_name].name_get()[0][1]
- else:
- value = lead[field_name]
-
- body.append("%s: %s" % (field_definition.string, value or ''))
- elif lead.type == 'opportunity':
- pa = lead.partner_address_id
- body += [
- "Partner: %s" % (lead.partner_id and lead.partner_id.name_get()[0][1]),
- "Contact: %s" % (pa.name or ''),
- "Title: %s" % (pa.title or ''),
- "Function: %s" % (pa.function or ''),
- "Street: %s" % (pa.street or ''),
- "Street2: %s" % (pa.street2 or ''),
- "Zip: %s" % (pa.zip or ''),
- "City: %s" % (pa.city or ''),
- "Country: %s" % (pa.country_id and pa.country_id.name_get()[0][1] or ''),
- "State: %s" % (pa.state_id and pa.state_id.name_get()[0][1] or ''),
- "Email: %s" % (pa.email or ''),
- "Phone: %s" % (pa.phone or ''),
- "Fax: %s" % (pa.fax or ''),
- "Mobile: %s" % (pa.mobile or ''),
- "Lead Category: %s" % (lead.categ_id and lead.categ_id.name or ''),
- "Details: %s" % (lead.description or ''),
- ]
- return "\n".join(body + ['---'])
-
- def default_get(self, cr, uid, fields, context=None):
- """
- This function gets default values
- """
-
- if context is None:
- context = {}
-
- defaults = super(crm_lead_forward_to_partner, self).default_get(cr, uid, fields, context=context)
- active_id = context.get('active_id')
- if not active_id:
- return defaults
-
- lead_proxy = self.pool.get('crm.lead')
- partner_obj = self.pool.get('res.partner')
- lead = lead_proxy.browse(cr, uid, active_id, context=context)
-
- email_cc = ''
- email = ''
- if lead.partner_assigned_id:
- partner = partner_obj.browse(cr, uid, [lead.partner_assigned_id.id])
- user_id = partner and partner[0].user_id or False
- email_cc = user_id and user_id.user_email or ''
-
- addr = partner_obj.address_get(cr, uid, [partner[0].id], ['contact'])
- email = self.pool.get('res.partner.address').browse(cr, uid, addr['contact']).email
-
- body = self._get_case_history(cr, uid, defaults.get('history', 'latest'), lead.id, context=context)
- defaults.update({
- 'subject' : '%s: %s - %s' % (_('Fwd'), 'Openerp lead forward', lead.name),
- 'body_text' : body,
- 'email_cc' : email_cc,
- 'email_to' : email or 'dummy@dummy.ly'
- })
- return defaults
-
-class crm_lead_mass_forward_to_partner(osv.osv_memory):
- _name = 'crm.lead.mass.forward.to.partner'
- _inherit = 'crm.lead.forward.to.partner'
-
- def action_mass_forward(self, cr, uid, ids, context=None):
- if not context:
- context = {}
-
- active_ids = context.get('active_ids')
- case_obj = self.pool.get('crm.lead')
- for case in case_obj.browse(cr, uid, active_ids, context=context):
- if not case.partner_assigned_id:
- case_obj.assign_partner(cr,uid, [case.id], context=context)
- case = case_obj.browse(cr, uid, case.id, context=context)
-
- if not case.partner_assigned_id:
- continue
-
- context.update({'active_id' : case.id})
+ lead = self.pool.get(model)
+ lead_id = context and context.get('active_id', False) or False
+ lead_ids = lead_id and [lead_id] or []
+ mode = context.get('mail.compose.message.mode')
+ if mode == 'mass_mail':
+ lead_ids = context and context.get('active_ids', []) or []
value = self.default_get(cr, uid, ['body_text', 'email_to', 'email_cc', 'subject', 'history'], context=context)
self.write(cr, uid, ids, value, context=context)
- self.action_forward(cr,uid, ids, context=context)
+ context['mail.compose.message.mode'] = mode
- return {'type': 'ir.actions.act_window_close'}
+ self.send_mail(cr, uid, ids, context=context)
+ for case in lead.browse(cr, uid, lead_ids, context=context):
+ if (this.send_to == 'partner' and this.partner_id):
+ lead.assign_partner(cr, uid, [case.id], this.partner_id.id, context=context)
+ if this.send_to == 'user':
+ lead.allocate_salesman(cr, uid, [case.id], [this.user_id.id], context=context)
+ email_cc = to_email(case.email_cc)
+ email_cc = email_cc and email_cc[0] or ''
+ new_cc = []
+ if email_cc:
+ new_cc.append(email_cc)
+ for to in this.email_to.split(','):
+ email_to = to_email(to)
+ email_to = email_to and email_to[0] or ''
+ if email_to not in new_cc:
+ new_cc.append(to)
+ update_vals = {'email_cc' : ', '.join(new_cc) }
+ lead.write(cr, uid, case.id, update_vals, context=context)
+ return res
+
+ def _get_info_body_text(self, cr, uid, lead, context=None):
+ field_names = []
+ proxy = self.pool.get(lead._name)
+ if lead.type == 'opportunity':
+ field_names += ['partner_id']
+ field_names += [
+ 'partner_name' , 'title', 'function', 'street', 'street2',
+ 'zip', 'city', 'country_id', 'state_id', 'email_from',
+ 'phone', 'fax', 'mobile', 'categ_id', 'description',
+ ]
+ return proxy._mail_body_text(cr, uid, lead, field_names, context=context)
+
+ def _get_message_body_text(self, cr, uid, lead, mode='whole', context=None):
+ """This function gets whole communication history and returns as top posting style
+ """
+ mail_message = self.pool.get('mail.message')
+ message_ids = []
+ body = self._get_info_body_text(cr, uid, lead, context=context)
+ if mode in ('whole', 'latest'):
+ message_ids = lead.message_ids
+ message_ids = map(lambda x: x.id, filter(lambda x: x.email_from, message_ids))
+ if mode == 'latest' and len(message_ids):
+ message_ids = [message_ids[0]]
+ for message in mail_message.browse(cr, uid, message_ids, context=context):
+ header = '-------- Original Message --------'
+ sender = 'From: %s' %(message.email_from or '')
+ to = 'To: %s' % (message.email_to or '')
+ sentdate = 'Date: %s' % (message.date or '')
+ desc = '\n%s'%(message.body_text)
+ original = [header, sender, to, sentdate, desc, '\n']
+ original = '\n'.join(original)
+ body += original
+ return body or ''
+
+ def get_value(self, cr, uid, model, res_id, context=None):
+ if context is None:
+ context = {}
+ res = super(crm_lead_forward_to_partner, self).get_value(cr, uid, model, res_id, context=context)
+ if model not in ("crm.lead"):
+ return res
+ proxy = self.pool.get(model)
+ partner = self.pool.get('res.partner')
+ lead = proxy.browse(cr, uid, res_id, context=context)
+ mode = context.get('mail.compose.message.mode')
+ if mode == "forward":
+ body_type = context.get('mail.compose.message.body')
+ email_cc = res.get('email_cc', "")
+ email = res.get('email_to', "")
+ subject = '%s: %s - %s' % (_('Fwd'), 'Lead forward', lead.name)
+ body = self._get_message_body_text(cr, uid, lead, body_type, context=context)
+ partner_assigned_id = lead.partner_assigned_id and lead.partner_assigned_id.id or False
+ user_id = False
+ if not partner_assigned_id:
+ partner_assigned_id = proxy.search_geo_partner(cr, uid, [lead.id], context=None).get(lead.id, False)
+ if partner_assigned_id:
+ assigned_partner = partner.browse(cr, uid, partner_assigned_id, context=context)
+ user_id = assigned_partner.user_id and assigned_partner.user_id.id or False
+ email_cc = assigned_partner.user_id and assigned_partner.user_id.user_email or ''
+ email = assigned_partner.email
+
+ res.update({
+ 'subject' : subject,
+ 'body_text' : body,
+ 'email_cc' : email_cc,
+ 'email_to' : email,
+ 'partner_assigned_id': partner_assigned_id,
+ 'user_id': user_id,
+ })
+ return res
+
+
+ def default_get(self, cr, uid, fields, context=None):
+ if context is None:
+ context = {}
+ context['mail.compose.message.mode'] = 'forward'
+ context['mail.compose.message.body'] = 'info'
+ return super(crm_lead_forward_to_partner, self).default_get(cr, uid, fields, context=context)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/crm_partner_assign/wizard/crm_forward_to_partner_view.xml b/addons/crm_partner_assign/wizard/crm_forward_to_partner_view.xml
index 8bdb03cf962..645c729b164 100644
--- a/addons/crm_partner_assign/wizard/crm_forward_to_partner_view.xml
+++ b/addons/crm_partner_assign/wizard/crm_forward_to_partner_view.xml
@@ -35,7 +35,7 @@
-
+
@@ -45,7 +45,7 @@
-
+
@@ -61,56 +61,14 @@
-
- crm.new.mass.forward.mail.form
- crm.lead.mass.forward.to.partner
- form
-
-
-
-
-
+
diff --git a/addons/crm_partner_assign/wizard/crm_merge_opportunity.py b/addons/crm_partner_assign/wizard/crm_merge_opportunity.py
deleted file mode 100644
index 3c56fada5a1..00000000000
--- a/addons/crm_partner_assign/wizard/crm_merge_opportunity.py
+++ /dev/null
@@ -1,44 +0,0 @@
-# -*- coding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# Copyright (C) 2004-2010 Tiny SPRL ().
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as
-# published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see .
-#
-##############################################################################
-from osv import osv, fields
-from tools.translate import _
-
-
-class crm_merge_opportunity_assign_partner(osv.osv_memory):
- """Merge two Opportunities"""
-
- _inherit = 'crm.merge.opportunity'
-
- def _update_data(self, op_ids, oldest_opp):
- data = super(crm_merge_opportunity_assign_partner, self)._update_data(op_ids, oldest_opp)
-
- new_data = {
- 'partner_latitude': self._get_first_not_null('partner_latitude', op_ids, oldest_opp),
- 'partner_longitude': self._get_first_not_null('partner_longitude', op_ids, oldest_opp),
- 'partner_assigned_id': self._get_first_not_null_id('partner_assigned_id', op_ids, oldest_opp),
- 'date_assign' : self._get_first_not_null('date_assign', op_ids, oldest_opp),
- }
- data.update(new_data)
- return data
-
-crm_merge_opportunity_assign_partner()
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/crm_profiling/__openerp__.py b/addons/crm_profiling/__openerp__.py
index 656f8360f0b..1d8f9f7ee79 100644
--- a/addons/crm_profiling/__openerp__.py
+++ b/addons/crm_profiling/__openerp__.py
@@ -41,7 +41,9 @@ It also has been merged with the earlier CRM & SRM segmentation tool because the
'init_xml': [],
'update_xml': ['security/ir.model.access.csv', 'crm_profiling_view.xml'],
'demo_xml': ['crm_profiling_demo.xml'],
- 'test': ['test/test_crm_profiling.yml'],
+ 'test': [
+ #'test/process/profiling.yml', #TODO:It's not debuging because problem to write data for open.questionnaire from partner section.
+ ],
'installable': True,
'active': False,
'certificate': '0033984979005',
diff --git a/addons/crm_profiling/crm_profiling_demo.xml b/addons/crm_profiling/crm_profiling_demo.xml
index 1789e8bace8..6a0ca130ec3 100644
--- a/addons/crm_profiling/crm_profiling_demo.xml
+++ b/addons/crm_profiling/crm_profiling_demo.xml
@@ -102,7 +102,7 @@
Profiles / crm.segmentation
-->
-
+
OpenERP partners
@@ -111,22 +111,23 @@
Bronze partners
-
+
True
Silver partners
-
+
True
Gold partners
-
+
+ True
True
diff --git a/addons/crm_profiling/test/process/profiling.yml b/addons/crm_profiling/test/process/profiling.yml
new file mode 100644
index 00000000000..91c48410f8d
--- /dev/null
+++ b/addons/crm_profiling/test/process/profiling.yml
@@ -0,0 +1,10 @@
+-
+ I check segmentation which allows users to perform segmentation within partners
+ and set the category according to question, so first compute questions(answers)
+ scenario with parther and check that category set according to questions.
+-
+ !python {model: res.partner}: |
+ data ={'form': {'quest_form3': ref("partner_quality3"), 'quest_form2': ref("nb_employees2"),'quest_form1': ref("sector1"),'questionnaire_name': ref('questionnaire1')}, 'ids': [ref('base.res_partner_ericdubois0')], 'report_type': 'pdf', 'model': 'res.partner', 'id': ref('base.res_partner_ericdubois0')}
+ data = self._questionnaire_compute(cr, uid, data, context)
+ partner = self.browse(cr, uid, ref('base.res_partner_ericdubois0'))
+ assert partner.category_id[0].id == ref("base.res_partner_category_17"), "Category not assign properly"
diff --git a/addons/crm_profiling/test/test_crm_profiling.yml b/addons/crm_profiling/test/test_crm_profiling.yml
deleted file mode 100644
index 2b70cac592b..00000000000
--- a/addons/crm_profiling/test/test_crm_profiling.yml
+++ /dev/null
@@ -1,77 +0,0 @@
-- |
- I check segmentation which allows users to perform segmentation within partners.
--
- I create a crm profiling question record.
--
- !record {model: crm_profiling.question, id: crm_profiling_question_openerppartner0}:
- answers_ids:
- - name: 'no'
- name: OpenERP partner?
--
- I create a crm profiling answer record.
--
- !record {model: crm_profiling.answer, id: crm_profiling_answer_openerppartner0}:
- name: 'yes'
- question_id: crm_profiling_question_openerppartner0
--
- I create Partner category Customers.
--
- !record {model: res.partner.category, id: res_partner_category_customers0}:
- name: Customers
-- |
- I'm creating new partner "John" with his email "info@mycustomer.com".
--
- !record {model: res.partner, id: res_partner_john0}:
- address:
- - city: Bruxelles
- country_id: base.be
- street: Rue des Palais 51, bte 33
- type: default
- zip: '1000'
- email: 'info@mycustomer.com'
- name: John
- category_id:
- - res_partner_category_customers0
- answers_ids:
- - crm_profiling_answer_openerppartner0
-
--
- Define the answers and category to partner.
--
- !python {model: res.partner}: |
- data ={'form': {'questionnaire_name': ref('res_partner_john0')}, 'ids': [ref('res_partner_john0')], 'report_type': 'pdf', 'model': 'res.partner', 'id': ref('res_partner_john0')}
- self._questionnaire_compute(cr, uid, data, context)
-- |
- I start by creating new Questionnaire.
--
- !record {model: crm_profiling.questionnaire, id: crm_profiling_questionnaire_basequestionnaire0}:
- description: First questionnaire.
- name: Base questionnaire
- questions_ids:
- - crm_profiling.activity_sector
- - crm_profiling.nb_employees
- - crm_profiling.partner_level
-- |
- I create the form for the "Base questionnaire".
--
- !python {model: crm_profiling.questionnaire}: |
- context.update({'active_id':ref('res_partner_john0')})
- data ={'form': {'questionnaire_name': ref('res_partner_john0')}, 'ids': [ref('res_partner_john0')], 'report_type': 'pdf', 'model': 'res.partner', 'id': ref('res_partner_john0')}
- self.build_form(cr, uid, data, context)
--
- I create a segmentation record.
--
- !record {model: crm.segmentation, id: crm_segmentation_test1}:
- answer_yes:
- - crm_profiling_answer_openerppartner0
- categ_id: res_partner_category_customers0
- name: test
- parent_id: crm_profiling.crm_segmentation0
- profiling_active: true
- som_interval: 0.0
-- |
- I continue the process of segmentation.
--
- !python {model: crm.segmentation}: |
- self.process_continue(cr, uid, [ref('crm_segmentation_test1')], start=False)
-