Launchpad automatic translations update.
[odoo/odoo.git] / addons / crm / crm_lead.py
index 01c597f..feed5e2 100644 (file)
 #
 ##############################################################################
 
-from osv import fields, osv, orm
-from datetime import datetime, timedelta
+from osv import fields, osv
+from datetime import datetime
 import crm
-import math
 import time
-import mx.DateTime
 from tools.translate import _
 from crm import crm_case
-import collections
 import binascii
 import tools
 
@@ -38,13 +35,13 @@ CRM_LEAD_PENDING_STATES = (
     crm.AVAILABLE_STATES[4][0], # Pending
 )
 
-class crm_lead(osv.osv, crm_case):
+class crm_lead(crm_case, osv.osv):
     """ CRM Lead Case """
     _name = "crm.lead"
-    _description = "Lead"
-    _order = "priority, id desc"
+    _description = "Lead/Opportunity"
+    _order = "date_action, priority, id desc"
     _inherit = ['mailgate.thread','res.partner.address']
-    def _compute_day(self, cr, uid, ids, fields, args, context={}):
+    def _compute_day(self, cr, uid, ids, fields, args, context=None):
         """
         @param cr: the current row, from the database cursor,
         @param uid: the current user’s ID for security checks,
@@ -56,7 +53,7 @@ class crm_lead(osv.osv, crm_case):
         res_obj = self.pool.get('resource.resource')
 
         res = {}
-        for lead in self.browse(cr, uid, ids , context):
+        for lead in self.browse(cr, uid, ids, context=context):
             for field in fields:
                 res[lead.id] = {}
                 duration = 0
@@ -86,12 +83,12 @@ class crm_lead(osv.osv, crm_case):
                         new_dates = cal_obj.interval_get(cr,
                             uid,
                             lead.section_id.resource_calendar_id and lead.section_id.resource_calendar_id.id or False,
-                            mx.DateTime.strptime(lead.create_date, '%Y-%m-%d %H:%M:%S'),
+                            datetime.strptime(lead.create_date, '%Y-%m-%d %H:%M:%S'),
                             duration,
                             resource=resource_id
                         )
                         no_days = []
-                        date_until = mx.DateTime.strptime(date_until, '%Y-%m-%d %H:%M:%S')
+                        date_until = datetime.strptime(date_until, '%Y-%m-%d %H:%M:%S')
                         for in_time, out_time in new_dates:
                             if in_time.date not in no_days:
                                 no_days.append(in_time.date)
@@ -105,33 +102,32 @@ class crm_lead(osv.osv, crm_case):
         # Overridden from res.partner.address:
         'partner_id': fields.many2one('res.partner', 'Partner', ondelete='set null', 
             select=True, help="Optional linked partner, usually after conversion of the lead"),
-        
+
         # From crm.case
+        'id': fields.integer('ID'),
         'name': fields.char('Name', size=64),
         'active': fields.boolean('Active', required=False),
         'date_action_last': fields.datetime('Last Action', readonly=1),
         'date_action_next': fields.datetime('Next Action', readonly=1),
         'email_from': fields.char('Email', size=128, help="E-mail address of the contact"),
         'section_id': fields.many2one('crm.case.section', 'Sales Team', \
-                        select=True, help='Sales team to which this case belongs to.\
-                             Defines responsible user and e-mail address for the mail gateway.'),
+                        select=True, help='Sales team to which this case belongs to. Defines responsible user and e-mail address for the mail gateway.'),
         'create_date': fields.datetime('Creation Date' , readonly=True),
-        'email_cc': fields.text('Watchers Emails', size=252 , help="These \
-addresses will receive a copy of the future e-mail communication between partner \
-and users"),
+        'email_cc': fields.text('Global CC', size=252 , help="These email addresses will be added to the CC field of all inbound and outbound emails for this record before being sent. Separate multiple email addresses with a comma"),
         'description': fields.text('Notes'),
         'write_date': fields.datetime('Update Date' , readonly=True),
 
         # Lead fields
-        'categ_id': fields.many2one('crm.case.categ', 'Lead Source', \
-                        domain="[('section_id','=',section_id),\
-                        ('object_id.model', '=', 'crm.lead')]"),
-        'type_id': fields.many2one('crm.case.resource.type', 'Lead Type', \
-                         domain="[('section_id','=',section_id),\
-                        ('object_id.model', '=', 'crm.lead')]"),
-        'partner_name': fields.char("Partner Name", size=64),
-        'optin': fields.boolean('Opt-In'),
-        'optout': fields.boolean('Opt-Out'),
+        'categ_id': fields.many2one('crm.case.categ', 'Category', \
+            domain="['|',('section_id','=',section_id),('section_id','=',False), ('object_id.model', '=', 'crm.lead')]"),
+        'type_id': fields.many2one('crm.case.resource.type', 'Campaign', \
+            domain="['|',('section_id','=',section_id),('section_id','=',False)]"),
+        'channel_id': fields.many2one('res.partner.canal', 'Channel'),
+
+        'contact_name': fields.char('Contact Name', size=64), 
+        'partner_name': fields.char("Customer Name", size=64,help='The name of the future partner that will be created while converting the into opportunity'),
+        'optin': fields.boolean('Opt-In', help="If opt-in is checked, this contact has accepted to receive emails."),
+        'optout': fields.boolean('Opt-Out', help="If opt-out is checked, this contact has refused to receive emails or unsubscribed to a campaign."),
         'type':fields.selection([
             ('lead','Lead'),
             ('opportunity','Opportunity'),
@@ -139,9 +135,7 @@ and users"),
         ],'Type', help="Type is used to separate Leads and Opportunities"),
         'priority': fields.selection(crm.AVAILABLE_PRIORITIES, 'Priority'),
         'date_closed': fields.datetime('Closed', readonly=True),
-        'stage_id': fields.many2one('crm.case.stage', 'Stage', \
-                            domain="[('section_id','=',section_id),\
-                            ('object_id.model', '=', 'crm.lead')]"),
+        'stage_id': fields.many2one('crm.case.stage', 'Stage', domain="[('type','=','lead')]"),
         'user_id': fields.many2one('res.users', 'Salesman',help='By Default Salesman is Administrator when create New User'),
         'referred': fields.char('Referred By', size=64),
         'date_open': fields.datetime('Opened', readonly=True),
@@ -154,9 +148,9 @@ and users"),
                                   \nIf the case is in progress the state is set to \'Open\'.\
                                   \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=[('history', '=', True),('model','=',_name)]),
-        'log_ids': fields.one2many('mailgate.message', 'res_id', 'Logs', domain=[('history', '=', False),('model','=',_name)]),
+        'message_ids': fields.one2many('mailgate.message', 'res_id', 'Messages', domain=[('model','=',_name)]),
     }
+    
 
     _defaults = {
         'active': lambda *a: 1,
@@ -167,8 +161,25 @@ and users"),
         'section_id': crm_case._get_section,
         '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],
+        #'stage_id': _get_stage_id,
     }
     
+    
+
+    def onchange_partner_address_id(self, cr, uid, ids, add, email=False):
+        """This function returns value of partner email based on Partner Address
+        @param self: The object pointer
+        @param cr: the current row, from the database cursor,
+        @param uid: the current user’s ID for security checks,
+        @param ids: List of case IDs
+        @param add: Id of Partner's address
+        @email: Partner's email ID
+        """
+        if not add:
+            return {'value': {'email_from': False, 'country_id': False}}
+        address = self.pool.get('res.partner.address').browse(cr, uid, add)
+        return {'value': {'email_from': address.email, 'phone': address.phone, 'country_id': address.country_id.id}}
+
     def case_open(self, cr, uid, ids, *args):
         """Overrides cancel for crm_case for setting Open Date
         @param self: The object pointer
@@ -177,12 +188,30 @@ and users"),
         @param ids: List of case's Ids
         @param *args: Give Tuple Value
         """
+        leads = self.browse(cr, uid, ids)
+        
+        
+        
+        for i in xrange(0, len(ids)): 
+            if leads[i].state == 'draft':
+                value = {}
+                if not leads[i].stage_id :
+                    stage_id = self._find_first_stage(cr, uid, leads[i].type, leads[i].section_id.id or False)
+                    value.update({'stage_id' : stage_id})
+                value.update({'date_open': time.strftime('%Y-%m-%d %H:%M:%S')})
+                self.write(cr, uid, [ids[i]], value)
+            self.log_open( cr, uid, leads[i])
         res = super(crm_lead, self).case_open(cr, uid, ids, *args)
-        self.write(cr, uid, ids, {'date_open': time.strftime('%Y-%m-%d %H:%M:%S')})
-        for (id, name) in self.name_get(cr, uid, ids):
-            message = _('Lead ') + " '" + name + "' "+ _("is Open.")
-            self.log(cr, uid, id, message)
         return res
+        
+    def log_open(self, cr, uid, case):
+        if case.type == 'lead':
+            message = _("The lead '%s' has been opened.") % case.name
+        elif case.type == 'opportunity':
+            message = _("The opportunity '%s' has been opened.") % case.name
+        else:
+            message = _("The case '%s' has been opened.") % case.name
+        self.log(cr, uid, case.id, message)
 
     def case_close(self, cr, uid, ids, *args):
         """Overrides close for crm_case for setting close date
@@ -192,11 +221,16 @@ and users"),
         @param ids: List of case Ids
         @param *args: Tuple Value for additional Params
         """
-        res = super(crm_lead, self).case_close(cr, uid, ids, args)
+        res = super(crm_lead, self).case_close(cr, uid, ids, *args)
         self.write(cr, uid, ids, {'date_closed': time.strftime('%Y-%m-%d %H:%M:%S')})
-        for (id, name) in self.name_get(cr, uid, ids):
-            message = _('Lead ') + " '" + name + "' "+ _("is Closed.")
-            self.log(cr, uid, id, message)
+        for case in self.browse(cr, uid, ids):
+            if case.type == 'lead':
+                message = _("The lead '%s' has been closed.") % case.name
+            elif case.type == 'opportunity':
+                message = _("The opportunity '%s' has been closed.") % case.name
+            else:
+                message = _("The case '%s' has been closed.") % case.name
+            self.log(cr, uid, case.id, message)
         return res
 
     def convert_opportunity(self, cr, uid, ids, context=None):
@@ -207,17 +241,18 @@ and users"),
         @param context: A standard dictionary for contextual values
         @return: Value of action in dict
         """
-        if not context:
+        if context is None:
             context = {}
         context.update({'active_ids': ids})
 
         data_obj = self.pool.get('ir.model.data')
-        data_id = data_obj._get_id(cr, uid, 'crm', 'view_crm_lead2opportunity_create')
+        data_id = data_obj._get_id(cr, uid, 'crm', 'view_crm_lead2opportunity_action')
         value = {}
 
         view_id = False
         if data_id:
             view_id = data_obj.browse(cr, uid, data_id, context=context).res_id
+
         for case in self.browse(cr, uid, ids):
             context.update({'active_id': case.id})
             if not case.partner_id:
@@ -243,7 +278,7 @@ and users"),
                         'name': _('Create Opportunity'),
                         'view_type': 'form',
                         'view_mode': 'form,tree',
-                        'res_model': 'crm.lead2opportunity',
+                        'res_model': 'crm.lead2opportunity.action',
                         'view_id': False,
                         'context': context,
                         'views': [(view_id, 'form')],
@@ -253,16 +288,35 @@ and users"),
                         }
         return value
 
+    def write(self, cr, uid, ids, vals, context=None):
+        if not context:
+            context = {}
+            
+        if 'date_closed' in vals:
+            return super(crm_lead,self).write(cr, uid, ids, vals, context=context)
+            
+        if 'stage_id' in vals and vals['stage_id']:
+            stage_obj = self.pool.get('crm.case.stage').browse(cr, uid, vals['stage_id'], context=context)
+            self.history(cr, uid, ids, _('Stage'), details=stage_obj.name)
+            message=''
+            for case in self.browse(cr, uid, ids, context=context):
+                if case.type == 'lead' or  context.get('stage_type',False)=='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 super(crm_lead,self).write(cr, uid, ids, vals, context)
+    
     def stage_next(self, cr, uid, ids, context=None):
-        stage = super(crm_lead, self).stage_next(cr, uid, ids, context)
+        stage = super(crm_lead, self).stage_next(cr, uid, ids, context=context)
         if stage:
             stage_obj = self.pool.get('crm.case.stage').browse(cr, uid, stage, context=context)
             if stage_obj.on_change:
                 data = {'probability': stage_obj.probability}
                 self.write(cr, uid, ids, data)
         return stage
-
-    def message_new(self, cr, uid, msg, context):
+    
+    def message_new(self, cr, uid, msg, context=None):
         """
         Automatically calls when new email message arrives
 
@@ -270,10 +324,9 @@ and users"),
         @param cr: the current row, from the database cursor,
         @param uid: the current user’s ID for security checks
         """
-
         mailgate_pool = self.pool.get('email.server.tools')
 
-        subject = msg.get('subject')
+        subject = msg.get('subject') or _("No Subject")
         body = msg.get('body')
         msg_from = msg.get('from')
         priority = msg.get('priority')
@@ -293,11 +346,8 @@ and users"),
             vals.update(res)
 
         res = self.create(cr, uid, vals, context)
-        
-        message = _('A Lead created') + " '" + subject + "' " + _("from Mailgate.")
-        self.log(cr, uid, res, message)
-        
         attachents = msg.get('attachments', [])
+        att_ids = []
         for attactment in attachents or []:
             data_attach = {
                 'name': attactment,
@@ -307,23 +357,21 @@ and users"),
                 'res_model': self._name,
                 'res_id': res,
             }
-            self.pool.get('ir.attachment').create(cr, uid, data_attach)
+            att_ids.append(self.pool.get('ir.attachment').create(cr, uid, data_attach))
 
-        return res
+        return res,att_ids
 
-    def message_update(self, cr, uid, ids, vals={}, msg="", default_act='pending', context={}):
+    def message_update(self, cr, uid, ids, vals={}, msg="", default_act='pending', 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 ids: List of update mail’s IDs 
         """
-
         if isinstance(ids, (str, int, long)):
             ids = [ids]
 
-        msg_from = msg['from']
-        if msg.get('priority'):
+        if msg.get('priority') in dict(crm.AVAILABLE_PRIORITIES):
             vals['priority'] = msg.get('priority')
 
         maps = {
@@ -348,7 +396,6 @@ and users"),
             if case.state in CRM_LEAD_PENDING_STATES:
                 values.update(state=crm.AVAILABLE_STATES[1][0]) #re-open
             res = self.write(cr, uid, [case.id], values, context=context)
-
         return res
 
     def msg_send(self, cr, uid, id, *args, **argv):