[MERGE] Merge with lp:openobject-addons
authorBhumika (OpenERP) <sbh@tinyerp.com>
Wed, 13 Apr 2011 04:55:50 +0000 (10:25 +0530)
committerBhumika (OpenERP) <sbh@tinyerp.com>
Wed, 13 Apr 2011 04:55:50 +0000 (10:25 +0530)
bzr revid: sbh@tinyerp.com-20110413045550-zlcq9sjo6txa65nz

1  2 
addons/crm/crm_lead.py
addons/crm/wizard/crm_lead_to_partner.py
addons/crm/wizard/crm_merge_opportunities.py
addons/crm_partner_assign/wizard/crm_forward_to_partner.py

diff --combined addons/crm/crm_lead.py
@@@ -98,6 -98,27 +98,27 @@@ class crm_lead(crm_case, osv.osv)
                  res[lead.id][field] = abs(int(duration))
          return res
  
+     def _history_search(self, cr, uid, obj, name, args, context=None):
+         res = []
+         msg_obj = self.pool.get('mailgate.message')
+         message_ids = msg_obj.search(cr, uid, [('history','=',True), ('name', args[0][1], args[0][2])], context=context)
+         lead_ids = self.search(cr, uid, [('message_ids', 'in', message_ids)], context=context)
+         if lead_ids:
+             return [('id', 'in', lead_ids)]
+         else:
+             return [('id', '=', '0')]
+     def _get_email_subject(self, cr, uid, ids, fields, args, context=None):
+         res = {}
+         for obj in self.browse(cr, uid, ids, context=context):
+             res[obj.id] = ''
+             for msg in obj.message_ids:
+                 if msg.history:
+                     res[obj.id] = msg.name
+                     break
+         return res
      _columns = {
          # Overridden from res.partner.address:
          'partner_id': fields.many2one('res.partner', 'Partner', ondelete='set null',
                                    \nWhen the case is over, the state is set to \'Done\'.\
                                    \nIf the case needs to be reviewed then the state is set to \'Pending\'.'),
          'message_ids': fields.one2many('mailgate.message', 'res_id', 'Messages', domain=[('model','=',_name)]),
+         'subjects': fields.function(_get_email_subject, fnct_search=_history_search, string='Subject of Email', method=True, type='char', size=64),
      }
  
  
          data_obj = self.pool.get('ir.model.data')
          value = {}
  
 -        view_id = False
  
          for case in self.browse(cr, uid, ids, context=context):
              context.update({'active_id': case.id})
                  self.log(cr, uid, case.id, message)
          return super(crm_lead,self).write(cr, uid, ids, vals, context)
  
-     def stage_historize(self, cr, uid, ids, stage, context=None):
-         stage_obj = self.pool.get('crm.case.stage').browse(cr, uid, stage, context=context)
-         self.history(cr, uid, ids, _('Stage'), details=stage_obj.name)
-         for case in self.browse(cr, uid, ids, context=context):
-             if case.type == 'lead':
-                 message = _("The stage of lead '%s' has been changed to '%s'.") % (case.name, stage_obj.name)
-             elif case.type == 'opportunity':
-                 message = _("The stage of opportunity '%s' has been changed to '%s'.") % (case.name, stage_obj.name)
-             self.log(cr, uid, case.id, message)
-         return True
      def stage_next(self, cr, uid, ids, context=None):
          stage = super(crm_lead, self).stage_next(cr, uid, ids, context=context)
          if stage:
@@@ -71,9 -71,8 +71,8 @@@ class crm_lead2partner(osv.osv_memory)
          contact_obj = self.pool.get('res.partner.address')
          partner_id = False
  
-         data = context and context.get('active_ids', []) or []
+         data = list(context and context.get('active_ids', []) or [])
          res = super(crm_lead2partner, self).default_get(cr, uid, fields, context=context)
          for lead in lead_obj.browse(cr, uid, data, context=context):
              partner_ids = []
              # Find partner address matches the email_from of the lead
                                  substring(email from '([^ ,<@]+@[^> ,]+)') in (%s)""" % (','.join(email)))
                  address_ids = map(lambda x: x[0], cr.fetchall())
                  if address_ids:
-                     addresses = contact_obj.browse(cr, uid, address_ids)
-                     partner_ids = addresses and [addresses[0].partner_id.id] or False
+                     partner_ids = partner_obj.search(cr, uid, [('address', 'in', address_ids)], context=context)
+                     
              # Find partner name that matches the name of the lead
              if not partner_ids and lead.partner_name:
                  partner_ids = partner_obj.search(cr, uid, [('name', '=', lead.partner_name)], context=context)
-             if not partner_ids:
-                 cr.execute("""SELECT p.id from res_partner p
-                             where regexp_replace(lower(p.name), '[^a-z]*', '', 'g') = regexp_replace(%s, '[^a-z]*', '', 'g')""", (lead.name.lower(), ))
-                 partner_ids = map(lambda x: x[0], cr.fetchall())
+                 
              partner_id = partner_ids and partner_ids[0] or False
+             
+             
  
              if 'partner_id' in fields:
                  res.update({'partner_id': partner_id})
          contact_obj = self.pool.get('res.partner.address')
          partner_ids = []
          partner_id = False
 -        contact_id = False
          rec_ids = context and context.get('active_ids', [])
  
          for data in self.browse(cr, uid, ids, context=context):
                          'user_id': lead.user_id.id,
                          'comment': lead.description,
                      })
 -                    contact_id = contact_obj.create(cr, uid, {
 +                    contact_obj.create(cr, uid, {
                          'partner_id': partner_id,
                          'name': lead.contact_name,
                          'phone': lead.phone,
                  else:
                      if data.partner_id:
                          partner_id = data.partner_id.id
 -                        contact_id = partner_obj.address_get(cr, uid, [partner_id])['default']
                  self.assign_partner(cr, uid, lead.id, partner_id)
                  partner_ids.append(partner_id)
          return partner_ids
          if context is None:
              context = {}
  
 -        partner_ids = self._create_partner(cr, uid, ids, context=context)
 +        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'])
@@@ -1,4 -1,4 +1,3 @@@
--# -*- coding: utf-8 -*-
  ##############################################################################
  #
  #    OpenERP, Open Source Management Solution
@@@ -27,13 -27,19 +26,19 @@@ class crm_merge_opportunity(osv.osv_mem
      _name = 'crm.merge.opportunity'
      _description = 'Merge two Opportunities'
  
-     def _get_first_not_null_id(self, attr, ops):
+     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):
+     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)
@@@ -45,6 -51,7 +50,6 @@@
  
      def get_attachments(self, cr, uid, id, context=None):
          attach_obj = self.pool.get('ir.attachment')
 -        result = []
          attach_ids = attach_obj.search(cr, uid, [('res_model' , '=', 'crm.lead'), ('res_id', '=', id)])
          return attach_ids
  
          attach_obj.write(cr, uid, attach_ids, {'res_id' : op_id})
  
  
+     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)
+         opps = lead_obj.browse(cr, uid, [op_id[0]], context=context)
+         return opps[0]
  
      def merge(self, cr, uid, op_ids, context=None):
          """
          opp_obj = self.pool.get('crm.lead')
          message_obj = self.pool.get('mailgate.message')
  
-         lead_ids = context and context.pop('lead_ids', []) or []
+         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 = {
-                 'partner_id': self._get_first_not_null_id('partner_id', op_ids),  # !!
-                 'title': self._get_first_not_null_id('title', op_ids),
-                 'name' : self._concat_all('name', op_ids),  #not lost
-                 'categ_id' : self._get_first_not_null_id('categ_id', op_ids), # !!
-                 'channel_id' : self._get_first_not_null_id('channel_id', op_ids), # !!
-                 'city' : self._get_first_not_null('city', op_ids),  # !!
-                 'company_id' : self._get_first_not_null_id('company_id', op_ids), #!!
-                 'contact_name' : self._concat_all('contact_name', op_ids), #not lost
-                 'country_id' : self._get_first_not_null_id('country_id', op_ids), #!!
-                 'partner_address_id' : self._get_first_not_null_id('partner_address_id', op_ids), #!!
-                 'partner_assigned_id' : hasattr(opp_obj,'partner_assigned_id') and self._get_first_not_null_id('partner_assigned_id', op_ids), #!!
-                 'type_id' : self._get_first_not_null_id('type_id', op_ids), #!!
-                 'user_id' : self._get_first_not_null_id('user_id', op_ids), #!!
-                 'section_id' : self._get_first_not_null_id('section_id', op_ids), #!!
-                 'state_id' : self._get_first_not_null_id('state_id', op_ids),
+                 '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), #!!
+                 'partner_assigned_id' : hasattr(opp_obj,'partner_assigned_id') and self._get_first_not_null_id('partner_assigned_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), # !!
-                 'fax' : self._get_first_not_null('fax', op_ids),
-                 'mobile' : self._get_first_not_null('mobile', op_ids),
-                 'partner_latitude' : hasattr(opp_obj,'partner_latitude') and self._get_first_not_null('partner_latitude', op_ids),
-                 'partner_longitude' : hasattr(opp_obj,'partner_longitude') and self._get_first_not_null('partner_longitude', op_ids),
-                 'partner_name' : self._get_first_not_null('partner_name', op_ids),
-                 'phone' : self._get_first_not_null('phone', op_ids),
-                 'probability' : self._get_first_not_null('probability', op_ids),
-                 'planned_revenue' : self._get_first_not_null('planned_revenue', op_ids),
-                 'street' : self._get_first_not_null('street', op_ids),
-                 'street2' : self._get_first_not_null('street2', op_ids),
-                 'zip' : self._get_first_not_null('zip', op_ids),
+                 '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_latitude' : hasattr(opp_obj,'partner_latitude') and self._get_first_not_null('partner_latitude', op_ids, oldest_opp),
+                 'partner_longitude' : hasattr(opp_obj,'partner_longitude') and self._get_first_not_null('partner_longitude', 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_nexte', 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),
  
              }
+         
          #copy message into the first opportunity + merge attachement
-         for opp in tail_opportunities:
+         
+         for opp in tail_opportunities + [first_opportunity]:
              attach_ids = self.get_attachments(cr, uid, opp, context=context)
              self.set_attachements_res_id(cr, uid, first_opportunity.id, attach_ids)
              for history in opp.message_ids:
-                 message_obj.copy(cr, uid, history.id, default={'res_id': opp.id})
++
+                 new_history = message_obj.write(cr, uid, history.id, {'res_id': first_opportunity.id, 'name' : _("From %s : %s") % (opp.name, history.name) }, context=context)
  
          #Notification about loss of information
          details = []
  
  
          # Get Opportunity views
 -        result = models_data._get_id(
 -            cr, uid, 'crm', 'view_crm_case_opportunities_filter')
          opportunity_view_form = models_data._get_id(
              cr, uid, 'crm', 'crm_case_form_view_oppor')
          opportunity_view_tree = models_data._get_id(
          res = super(crm_merge_opportunity, self).default_get(cr, uid, fields, context=context)
  
          if record_ids:
+             opp_ids = []
+             opps = self.pool.get('crm.lead').browse(cr, uid, record_ids, context=context)
+             for opp in opps:
+                 if opp.state not in ('done', 'cancel'):
+                     opp_ids.append(opp.id)
              if 'opportunity_ids' in fields:
-                 res.update({'opportunity_ids': record_ids})
+                 res.update({'opportunity_ids': opp_ids})
  
          return res
  
  #
  ##############################################################################
  
  import time
  import re
  from osv import osv, fields
 -import tools
  from tools.translate import _
  
  class crm_lead_forward_to_partner(osv.osv_memory):
      _defaults = {
          'name' : 'email',
          'history': 'latest',
-         'email_from': lambda self, cr, uid, *a: self.pool.get('res.users')._get_email_from(cr, uid, uid)[uid]
+         'email_from': lambda self, cr, uid, *a: self.pool.get('res.users')._get_email_from(cr, uid, uid)[uid],
      }
  
      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
@@@ -85,7 -88,7 +86,7 @@@
          @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  
+         @param partner: Changed Partner id
          """
          if not user:
              return {'value': {'email_to': False}}
          @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  
+         @param partner: Changed Partner id
          """
          if not partner_id:
              return {'value' : {'email_to' : False, 'address_id': False}}
          addr = partner_obj.address_get(cr, uid, [partner_id], ['contact'])
          data = {'address_id': addr['contact']}
          data.update(self.on_change_address(cr, uid, ids, addr['contact'])['value'])
-         
          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})
          return {
-             'value' : data, 
+             'value' : data,
              'domain' : {'address_id' : partner_id and "[('partner_id', '=', partner_id)]" or "[]"}
              }
  
                      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 ''), 
+             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 + ['---'])
  
          """
          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' % (_('Fwd'), lead.name),
+             'subject' : '%s: %s - %s' % (_('Fwd'), 'Openerp lead forward', lead.name),
              'body' : body,
-             'email_cc' : ''
+             'email_cc' : email_cc,
+             'email_to' : email or 'dummy@dummy.ly'
          })
          return defaults
  
  crm_lead_forward_to_partner()
  
+ 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})
+             value = self.default_get(cr, uid, ['body', 'email_to', 'email_cc', 'subject', 'history'], context=context)
+             self.write(cr, uid, ids, value, context=context)
+             self.action_forward(cr,uid, ids, context=context)
+         return {'type': 'ir.actions.act_window_close'}
+ crm_lead_mass_forward_to_partner()
  # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: