[ADD]CRM:use proper sentence case
[odoo/odoo.git] / addons / crm / crm_lead.py
index a281ea6..216a898 100644 (file)
@@ -27,7 +27,7 @@ from tools.translate import _
 from crm import crm_case
 import binascii
 import tools
-
+from mail.mail_message import to_email
 
 CRM_LEAD_PENDING_STATES = (
     crm.AVAILABLE_STATES[2][0], # Cancelled
@@ -42,6 +42,24 @@ class crm_lead(crm_case, osv.osv):
     _order = "priority,date_action,id desc"
     _inherit = ['mail.thread','res.partner.address']
 
+    def _read_group_stage_ids(self, cr, uid, ids, domain, read_group_order=None, access_rights_uid=None, context=None):
+        access_rights_uid = access_rights_uid or uid
+        stage_obj = self.pool.get('crm.case.stage')
+        order = stage_obj._order
+        if read_group_order == 'stage_id desc':
+            # lame hack to allow reverting search, should just work in the trivial case
+            order = "%s desc" % order
+        stage_ids = stage_obj._search(cr, uid, ['|', ('id','in',ids),('case_default','=',1)], order=order,
+                                      access_rights_uid=access_rights_uid, context=context)
+        result = stage_obj.name_get(cr, access_rights_uid, stage_ids, context=context)
+        # restore order of the search
+        result.sort(lambda x,y: cmp(stage_ids.index(x[0]), stage_ids.index(y[0])))
+        return result
+
+    _group_by_full = {
+        'stage_id': _read_group_stage_ids
+    }
+
     # overridden because res.partner.address has an inconvenient name_get,
     # especially if base_contact is installed.
     def name_get(self, cr, user, ids, context=None):
@@ -188,6 +206,7 @@ class crm_lead(crm_case, osv.osv):
         'stage_id': fields.many2one('crm.case.stage', 'Stage', domain="[('section_ids', '=', section_id)]"),
         'color': fields.integer('Color Index'),
         'partner_address_name': fields.related('partner_address_id', 'name', type='char', string='Partner Contact Name', readonly=True),
+        'partner_address_email': fields.related('partner_address_id', 'email', type='char', string='Partner Contact Email', readonly=True),
         'company_currency': fields.related('company_id', 'currency_id', 'symbol', type='char', string='Company Currency', readonly=True),
         'user_email': fields.related('user_id', 'user_email', type='char', string='User Email', readonly=True),
         'user_login': fields.related('user_id', 'login', type='char', string='User Login', readonly=True),
@@ -204,7 +223,6 @@ class crm_lead(crm_case, osv.osv):
         'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'crm.lead', context=c),
         'priority': lambda *a: crm.AVAILABLE_PRIORITIES[2][0],
         'color': 0,
-        #'stage_id': _get_stage_id,
     }
 
     def onchange_partner_address_id(self, cr, uid, ids, add, email=False):
@@ -335,7 +353,7 @@ class crm_lead(crm_case, osv.osv):
         return self.set_priority(cr, uid, ids, '3')
 
     
-    def _merge_data(self, cr, uid, ids, oldest, context=None):
+    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):
@@ -351,84 +369,75 @@ class crm_lead(crm_case, osv.osv):
             return res and res.id or False
     
         def _concat_all(attr):
-            return ', '.join([getattr(opportunity, attr) for opportunity in opportunities if hasattr(opportunity, attr)])
-
-        data = {
-            'partner_id': _get_first_not_null_id('partner_id'),  # !!
-            'title': _get_first_not_null_id('title'),
-            'name' : _get_first_not_null('name'),  #not lost
-            'categ_id' : _get_first_not_null_id('categ_id'), # !!
-            'channel_id' : _get_first_not_null_id('channel_id'), # !!
-            'city' : _get_first_not_null('city'),  # !!
-            'company_id' : _get_first_not_null_id('company_id'), #!!
-            'contact_name' : _get_first_not_null('contact_name'), #not lost
-            'country_id' : _get_first_not_null_id('country_id'), #!!
-            'partner_address_id' : _get_first_not_null_id('partner_address_id'), #!!
-            'type_id' : _get_first_not_null_id('type_id'), #!!
-            'user_id' : _get_first_not_null_id('user_id'), #!!
-            'section_id' : _get_first_not_null_id('section_id'), #!!
-            'state_id' : _get_first_not_null_id('state_id'),
-            'description' : _concat_all('description'),  #not lost
-            'email' : _get_first_not_null('email'), # !!
-            'fax' : _get_first_not_null('fax'),
-            'mobile' : _get_first_not_null('mobile'),
-            'partner_name' : _get_first_not_null('partner_name'),
-            'phone' : _get_first_not_null('phone'),
-            'probability' : _get_first_not_null('probability'),
-            'planned_revenue' : _get_first_not_null('planned_revenue'),
-            'street' : _get_first_not_null('street'),
-            'street2' : _get_first_not_null('street2'),
-            'zip' : _get_first_not_null('zip'),
-            'state' : 'open',
-            'create_date' : _get_first_not_null('create_date'),
-            'date_action_last': _get_first_not_null('date_action_last'),
-            'date_action_next': _get_first_not_null('date_action_next'),
-            'email_from' : _get_first_not_null('email_from'),
-            'email_cc' : _get_first_not_null('email_cc'),
-            'partner_name' : _get_first_not_null('partner_name'),
-        }
+            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 = lead_obj.search(cr, uid, [('id', 'in', ids)], order='create_date' , context=context)
+        opportunity_ids = self.search(cr, uid, [('id', 'in', ids)], order='create_date' , context=context)
         oldest_id = opportunity_ids[0]
         return self.browse(cr, uid, oldest_id, context=context)
 
+    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)
-            details.append(_('%s : %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')  % (merge_message, opportunity.name, opportunity.partner_id.name or '',
-                        opportunity.stage_id.name or '',
-                        opportunity.section_id.name or '',
-                        opportunity.user_id.name or '',
-                        opportunity.categ_id.name or '',
-                        opportunity.channel_id.name or '',
-                        opportunity.company_id.name or '',
-                        opportunity.contact_name or '',
-                        opportunity.email_from or '',
-                        opportunity.phone or '',
-                        opportunity.fax or '',
-                        opportunity.mobile or '',
-                        opportunity.state_id.name or '',
-                        opportunity.description or '',
-                        opportunity.probability or '',
-                        opportunity.planned_revenue or '',
-                        opportunity.country_id.name or '',
-                        opportunity.city or '',
-                        opportunity.street or '',
-                        opportunity.street2 or '',
-                        opportunity.zip or '',
-                        ))
+            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)
@@ -481,17 +490,23 @@ class crm_lead(crm_case, osv.osv):
         if len(ids) <= 1:
             raise osv.except_osv(_('Warning !'),_('Please select more than one opportunities.'))
 
-        opportunities = self.browse(cr, uid, lead_ids, context=context)
-        opportunities_list = list(set(ids) - set(opportunities))
-        oldest = self._find_oldest_opportunity(cr, uid, ids, context=context)
-        if opportunities :
-            first_opportunity = opportunities[0]
+        ctx_opportunities = self.browse(cr, uid, lead_ids, context=context)
+        opportunities = self.browse(cr, uid, ids, context=context)
+        opportunities_list = list(set(opportunities) - set(ctx_opportunities))
+        oldest = self._merge_find_oldest(cr, uid, ids, context=context)
+        if ctx_opportunities :
+            first_opportunity = ctx_opportunities[0]
             tail_opportunities = opportunities_list
         else:
             first_opportunity = opportunities_list[0]
             tail_opportunities = opportunities_list[1:]
 
-        data = self._merge_data(cr, uid, ids, oldest, context=context)
+        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)
@@ -505,41 +520,55 @@ class crm_lead(crm_case, osv.osv):
         #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, lead):
+    def _convert_opportunity_data(self, cr, uid, lead, customer, section_id=False, context=None):
         crm_stage = self.pool.get('crm.case.stage')
-        if lead.section_id:
-            stage_ids = crm_stage.search(cr, uid, [('sequence','>=',1), ('section_ids','=', lead.section_id.id)])
+        contact_id = 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_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.id,
+                'partner_id': customer and customer.id or False,
                 'user_id': (lead.user_id and lead.user_id.id),
                 'type': 'opportunity',
-                'stage_id': stage_ids and stage_ids[0] or False,
+                'stage_id': stage_id or False,
                 'date_action': time.strftime('%Y-%m-%d %H:%M:%S'),
-                'partner_address_id': len(customer.address_id) and customer.address_id[0] or False
+                'partner_address_id': contact_id
         }
-    def _convert_opportunity_notification(self, cr, uid, lead, context=context):
+    def _convert_opportunity_notification(self, cr, uid, lead, context=None):
         success_message = _("Lead '%s' has been converted to an opportunity.") % lead.name
         self.message_append(cr, uid, [lead.id], success_message, body_text=success_message, context=context)
-        self.log(cr, uid, [lead.id], success_message)
+        self.log(cr, uid, lead.id, success_message)
         self._send_mail_to_salesman(cr, uid, lead, context=context)
         return True
 
-    def convert_opportunity(self, cr, uid, ids, partner_id, mass_convert=False, merge=False, context=None):
+    def convert_opportunity(self, cr, uid, ids, partner_id, user_ids=False, section_id=False, context=None):
         partner = self.pool.get('res.partner')
         mail_message = self.pool.get('mail.message')
-        customer = partner.browse(cr, uid, partner_id, context=context)
-        
+        customer = False
+        if partner_id:
+            customer = partner.browse(cr, uid, partner_id, context=context)
         for lead in self.browse(cr, uid, ids, context=context):
-            vals = self._convert_opportunity_data(lead)
+            if lead.state in ('done', 'cancel'):
+                continue
+            if user_ids or section_id:
+                self.allocate_salesman(cr, uid, [lead.id], user_ids, section_id, context=context)
+            
+            vals = self._convert_opportunity_data(cr, uid, lead, customer, section_id, context=context)
             self.write(cr, uid, [lead.id], vals, context=context)
+            
             self._convert_opportunity_notification(cr, uid, lead, context=context)
             #TOCHECK: why need to change partner details in all messages of lead ?
             if lead.partner_id:
@@ -547,7 +576,7 @@ class crm_lead(crm_case, osv.osv):
                 mail_message.write(cr, uid, msg_ids, {
                         'partner_id': lead.partner_id.id
                     }, context=context)
-         return True
+        return True
 
     def _lead_create_partner(self, cr, uid, lead, context=None):
         partner = self.pool.get('res.partner')
@@ -555,12 +584,20 @@ class crm_lead(crm_case, osv.osv):
                     '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_assign_partner(self, cr, uid, ids, partner_id, context=None):
-        return self.write(cr, uid, ids, {'partner_id' : partner_id}, context=context)
+    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')
@@ -569,7 +606,7 @@ class crm_lead(crm_case, osv.osv):
                     'name': lead.contact_name,
                     'phone': lead.phone,
                     'mobile': lead.mobile,
-                    'email': lead.email_from,
+                    '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,
@@ -581,20 +618,22 @@ class crm_lead(crm_case, osv.osv):
                     'state_id': lead.state_id and lead.state_id.id or False,
                 })
 
-    def convert_partner(self, cr, uid, ids, action='new', partner_id=False, context=None):
+    def convert_partner(self, cr, uid, ids, action='create', partner_id=False, context=None):
         """
         This function convert partner based on action.
-        if action is 'new', create new partner with contact and assign lead to new partner_id.
+        if action is 'create', create new partner with contact and assign lead to new partner_id.
         otherwise assign lead to specified partner_id
         """
         if context is None:
             context = {}
-        partner_ids = []
+        partner_ids = {}
         for lead in self.browse(cr, uid, ids, context=context):
-            if action == 'create':
-               partner_id = self._lead_create_partner(cr, uid, lead, context=context)
-            self._lead_assign_partner(cr, uid, [lead.id], partner_id, context=context)
-            partner_ids.append(partner_id)
+            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
 
     def _send_mail_to_salesman(self, cr, uid, lead, context=None):
@@ -628,21 +667,51 @@ class crm_lead(crm_case, osv.osv):
                 self.write(cr, uid, [lead_id], value, context=context)
         return True
 
+    def schedule_phonecall(self, cr, uid, ids, schedule_time, call_summary, 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,
+            }
+            
+            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
-        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
-
+        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',
@@ -651,44 +720,13 @@ class crm_lead(crm_case, osv.osv):
                 'domain': [('type', '=', 'opportunity')],
                 'res_id': int(opportunity_id),
                 'view_id': False,
-                'views': [(opportunity_view_form, 'form'),
-                          (opportunity_view_tree, 'tree'),
+                '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 button_convert_opportunity(self, cr, uid, ids, context=None):
-        """ Precomputation for converting lead to opportunity
-        """
-        if context is None:
-            context = {}
-        context.update({'active_ids': ids})
-
-        data_obj = self.pool.get('ir.model.data')
-        value = {}
-
-
-        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
-            }
-        return value
-
     def message_new(self, cr, uid, msg, custom_values=None, context=None):
         """Automatically calls when new email message arrives"""
         res_id = super(crm_lead, self).message_new(cr, uid, msg, custom_values=custom_values, context=context)
@@ -710,10 +748,11 @@ class crm_lead(crm_case, osv.osv):
         self.write(cr, uid, [res_id], vals, context)
         return res_id
 
-    def message_update(self, cr, uid, ids, msg, vals={}, default_act='pending', context=None):
+    def message_update(self, cr, uid, ids, msg, vals=None, default_act='pending', context=None):
         if isinstance(ids, (str, int, long)):
             ids = [ids]
-
+        if vals == None:
+            vals = {}
         super(crm_lead, self).message_update(cr, uid, ids, msg, context=context)
 
         if msg.get('priority') in dict(crm.AVAILABLE_PRIORITIES):
@@ -747,24 +786,17 @@ class crm_lead(crm_case, osv.osv):
         This opens Meeting's calendar view to schedule meeting on current Opportunity
         @return : Dictionary value for created Meeting view
         """
+        if context is None:
+            context = {}
         value = {}
+        data_obj = self.pool.get('ir.model.data')
         for opp in self.browse(cr, uid, ids, context=context):
-            data_obj = self.pool.get('ir.model.data')
-
             # 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
-
-            context = {
+            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,
                 'default_user_id': uid, 
@@ -772,7 +804,7 @@ class crm_lead(crm_case, osv.osv):
                 'default_email_from': opp.email_from,
                 'default_state': 'open',  
                 'default_name': opp.name
-            }
+            })
             value = {
                 'name': _('Meetings'),
                 'context': context,
@@ -780,9 +812,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