Launchpad automatic translations update.
[odoo/odoo.git] / addons / crm / crm_lead.py
index 6702e86..feed5e2 100644 (file)
@@ -23,7 +23,6 @@ from osv import fields, osv
 from datetime import datetime
 import crm
 import time
-import mx.DateTime
 from tools.translate import _
 from crm import crm_case
 import binascii
@@ -36,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"
+    _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,
@@ -54,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
@@ -84,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)
@@ -103,7 +102,7 @@ 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),
@@ -114,20 +113,21 @@ class crm_lead(osv.osv, crm_case):
         '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.'),
         'create_date': fields.datetime('Creation Date' , readonly=True),
-        'email_cc': fields.text('Watchers Emails', 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"),
+        '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'),
@@ -135,7 +135,7 @@ class crm_lead(osv.osv, crm_case):
         ],'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'),
+        '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),
@@ -148,10 +148,9 @@ class crm_lead(osv.osv, crm_case):
                                   \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=[('model','=',_name)], readonly=True),
-        '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"),
+        'message_ids': fields.one2many('mailgate.message', 'res_id', 'Messages', domain=[('model','=',_name)]),
     }
+    
 
     _defaults = {
         'active': lambda *a: 1,
@@ -162,7 +161,10 @@ class crm_lead(osv.osv, crm_case):
         '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
@@ -186,22 +188,30 @@ class crm_lead(osv.osv, crm_case):
         @param ids: List of case's Ids
         @param *args: Give Tuple Value
         """
-        old_state = self.read(cr, uid, ids, ['state'])[0]['state']
-        res = super(crm_lead, self).case_open(cr, uid, ids, *args)
-        if old_state == 'draft':
-            stage_id = super(crm_lead, self).stage_next(cr, uid, ids, *args)
-            if stage_id:
-                value = self.onchange_stage_id(cr, uid, ids, stage_id, context={})['value']
-            else:
+        leads = self.browse(cr, uid, ids)
+        
+        
+        
+        for i in xrange(0, len(ids)): 
+            if leads[i].state == 'draft':
                 value = {}
-            value.update({'date_open': time.strftime('%Y-%m-%d %H:%M:%S'), 'stage_id': stage_id})
-            self.write(cr, uid, ids, value)
-
-        for (id, name) in self.name_get(cr, uid, ids):
-            type = self.browse(cr, uid, id).type or 'Lead'
-            message = (_('The ') + type.title()) + " '" + name + "' "+ _("has been Opened.")
-            self.log(cr, uid, id, message)
+                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)
         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
@@ -211,13 +221,16 @@ class crm_lead(osv.osv, crm_case):
         @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):
-            lead = self.browse(cr, uid, id)
-            if lead.type == 'lead':
-                message = _('The Lead') + " '" + name + "' "+ _("has been 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):
@@ -228,7 +241,7 @@ class crm_lead(osv.osv, crm_case):
         @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})
 
@@ -275,16 +288,35 @@ class crm_lead(osv.osv, crm_case):
                         }
         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
 
@@ -292,10 +324,9 @@ class crm_lead(osv.osv, crm_case):
         @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')
@@ -315,11 +346,8 @@ class crm_lead(osv.osv, crm_case):
             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,
@@ -329,22 +357,21 @@ class crm_lead(osv.osv, crm_case):
                 '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]
 
-        if msg.get('priority'):
+        if msg.get('priority') in dict(crm.AVAILABLE_PRIORITIES):
             vals['priority'] = msg.get('priority')
 
         maps = {
@@ -369,7 +396,6 @@ class crm_lead(osv.osv, crm_case):
             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):