X-Git-Url: http://git.inspyration.org/?a=blobdiff_plain;f=addons%2Fcrm%2Fcrm_lead.py;h=7680f8c49e5b3c96e123de77319760296958cde6;hb=c5bbcb470528685e05b3d5f02fd57682c3b6fe13;hp=0b58975bca2cbf779742b574a1d0d5b1b4f59c51;hpb=cd19f68eb9f145e9049949074e06196d540cf2c2;p=odoo%2Fodoo.git diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py index 0b58975..7680f8c 100644 --- a/addons/crm/crm_lead.py +++ b/addons/crm/crm_lead.py @@ -40,7 +40,8 @@ class crm_lead(base_stage, osv.osv): _name = "crm.lead" _description = "Lead/Opportunity" _order = "priority,date_action,id desc" - _inherit = ['ir.needaction_mixin', 'mail.thread','res.partner'] + _inherit = ['ir.needaction_mixin', 'mail.thread'] + _mail_compose_message = True def _get_default_section_id(self, cr, uid, context=None): """ Gives default section by checking if present in the context """ @@ -189,11 +190,11 @@ class crm_lead(base_stage, osv.osv): select=True, help="Optional linked partner, usually after conversion of the lead"), 'id': fields.integer('ID', readonly=True), - 'name': fields.char('Name', size=64, select=1), + 'name': fields.char('Subject', size=64, required=True, select=1), '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", select=1), + 'email_from': fields.char('Email', size=128, help="Email address of the contact", select=1), 'section_id': fields.many2one('crm.case.section', 'Sales Team', \ select=True, help='When sending mails, the default email address is taken from the sales team.'), 'create_date': fields.datetime('Creation Date' , readonly=True), @@ -245,6 +246,20 @@ class crm_lead(base_stage, osv.osv): '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), + + # Fields for address, due to separation from crm and res.partner + 'street': fields.char('Street', size=128), + 'street2': fields.char('Street2', size=128), + 'zip': fields.char('Zip', change_default=True, size=24), + 'city': fields.char('City', size=128), + 'state_id': fields.many2one("res.country.state", 'State', domain="[('country_id','=',country_id)]"), + 'country_id': fields.many2one('res.country', 'Country'), + 'phone': fields.char('Phone', size=64), + 'fax': fields.char('Fax', size=64), + 'mobile': fields.char('Mobile', size=64), + 'function': fields.char('Function', size=128), + 'title': fields.many2one('res.partner.title', 'Title'), + 'company_id': fields.many2one('res.company', 'Company', select=1), } _defaults = { @@ -259,14 +274,6 @@ class crm_lead(base_stage, osv.osv): 'color': 0, } - def get_needaction_user_ids(self, cr, uid, ids, context=None): - result = dict.fromkeys(ids, []) - for obj in self.browse(cr, uid, ids, context=context): - # salesman must perform an action when in draft mode - if obj.state == 'draft' and obj.user_id: - result[obj.id] = [obj.user_id.id] - return result - def create(self, cr, uid, vals, context=None): obj_id = super(crm_lead, self).create(cr, uid, vals, context) self.create_send_note(cr, uid, [obj_id], context=context) @@ -282,9 +289,21 @@ class crm_lead(base_stage, osv.osv): if not stage_id: return {'value':{}} stage = self.pool.get('crm.case.stage').browse(cr, uid, stage_id, context) + if stage.state == "draft": + return {'value':{'probability': 0.0}} + if stage.state == "open": + cases = self.browse(cr, uid, ids, context=context) + data = {'active': True} + for case in cases: + if case.stage_id and case.stage_id.state == 'draft': + data['date_open'] = fields.datetime.now() + if not case.user_id: + data['user_id'] = uid + return {'value':data} if not stage.on_change: return {'value':{}} - return {'value':{'probability': stage.probability}} + else: + return {'value':{'probability': stage.probability}} def _check(self, cr, uid, ids=False, context=None): """ Override of the base.stage method. @@ -756,131 +775,98 @@ class crm_lead(base_stage, osv.osv): 'type': 'ir.actions.act_window', } + def action_makeMeeting(self, cr, uid, ids, context=None): + """ This opens Meeting's calendar view to schedule meeting on current Opportunity + @return : Dictionary value for created Meeting view + """ + opportunity = self.browse(cr, uid, ids[0], context) + res = self.pool.get('ir.actions.act_window').for_xml_id(cr, uid, 'base_calendar', 'action_crm_meeting', context) + res['context'] = { + 'default_opportunity_id': opportunity.id, + 'default_partner_id': opportunity.partner_id and opportunity.partner_id.id or False, + 'default_user_id': uid, + 'default_section_id': opportunity.section_id and opportunity.section_id.id or False, + 'default_email_from': opportunity.email_from, + 'default_state': 'open', + 'default_name': opportunity.name, + } + return res + + def unlink(self, cr, uid, ids, context=None): + for lead in self.browse(cr, uid, ids, context): + if (not lead.section_id.allow_unlink) and (lead.state != 'draft'): + raise osv.except_osv(_('Error'), + _("You cannot delete lead '%s'; it must be in state 'Draft' to be deleted. " \ + "You should better cancel it, instead of deleting it.") % lead.name) + return super(crm_lead, self).unlink(cr, uid, ids, context) + + def write(self, cr, uid, ids, vals, context=None): + if vals.get('stage_id') and not vals.get('probability'): + # change probability of lead(s) if required by stage + stage = self.pool.get('crm.case.stage').browse(cr, uid, vals['stage_id'], context=context) + if stage.on_change: + vals['probability'] = stage.probability + return super(crm_lead,self).write(cr, uid, ids, vals, context) + + # ---------------------------------------- + # Mail Gateway + # ---------------------------------------- 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) - subject = msg.get('subject') or _("No Subject") - body = msg.get('body_text') - - msg_from = msg.get('from') - priority = msg.get('priority') - vals = { - 'name': subject, - 'email_from': msg_from, + """ Overrides mail_thread message_new that is called by the mailgateway + through message_process. + This override updates the document according to the email. + """ + if custom_values is None: custom_values = {} + custom_values.update({ + 'name': msg.get('subject') or _("No Subject"), + 'description': msg.get('body_text'), + 'email_from': msg.get('from'), 'email_cc': msg.get('cc'), - 'description': body, 'user_id': False, - } - if priority: - vals['priority'] = priority - vals.update(self.message_partner_by_email(cr, uid, msg.get('from', False))) - self.write(cr, uid, [res_id], vals, context) - return res_id - - def message_update(self, cr, uid, ids, msg, vals=None, default_act='pending', context=None): + }) + if msg.get('priority') in dict(crm.AVAILABLE_PRIORITIES): + custom_values['priority'] = msg.get('priority') + custom_values.update(self.message_partner_by_email(cr, uid, msg.get('from', False), context=context)) + return super(crm_lead, self).message_new(cr, uid, msg, custom_values=custom_values, context=context) + + def message_update(self, cr, uid, ids, msg, update_vals=None, context=None): + """ Overrides mail_thread message_update that is called by the mailgateway + through message_process. + This method updates the document according to the email. + """ 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 update_vals is None: update_vals = {} if msg.get('priority') in dict(crm.AVAILABLE_PRIORITIES): vals['priority'] = msg.get('priority') maps = { 'cost':'planned_cost', 'revenue': 'planned_revenue', - 'probability':'probability' + 'probability':'probability', } - vls = {} - for line in msg['body_text'].split('\n'): + for line in msg.get('body_text', '').split('\n'): line = line.strip() res = tools.misc.command_re.match(line) if res and maps.get(res.group(1).lower()): key = maps.get(res.group(1).lower()) - vls[key] = res.group(2).lower() - vals.update(vls) - - # Unfortunately the API is based on lists - # but we want to update the state based on the - # previous state, so we have to loop: - for case in self.browse(cr, uid, ids, context=context): - values = dict(vals) - if case.state in CRM_LEAD_PENDING_STATES: - #re-open - values.update(state=crm.AVAILABLE_STATES[1][0]) - if not case.date_open: - values['date_open'] = time.strftime(tools.DEFAULT_SERVER_DATETIME_FORMAT) - res = self.write(cr, uid, [case.id], values, context=context) - return res - - def action_makeMeeting(self, cr, uid, ids, context=None): - """ - 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): - # Get meeting views - 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, - 'default_section_id': opp.section_id and opp.section_id.id or False, - 'default_email_from': opp.email_from, - 'default_state': 'open', - 'default_name': opp.name - }) - value = { - 'name': _('Meetings'), - 'context': context, - 'view_type': 'form', - 'view_mode': 'calendar,form,tree', - 'res_model': 'crm.meeting', - 'view_id': False, - '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': search_view and search_view[1] or False, - 'nodestroy': True - } - return value + vals[key] = res.group(2).lower() + return super(crm_lead, self).message_update(cr, uid, ids, msg, update_vals=update_vals, context=context) - def unlink(self, cr, uid, ids, context=None): - for lead in self.browse(cr, uid, ids, context): - if (not lead.section_id.allow_unlink) and (lead.state != 'draft'): - raise osv.except_osv(_('Error'), - _("You cannot delete lead '%s'; it must be in state 'Draft' to be deleted. " \ - "You should better cancel it, instead of deleting it.") % lead.name) - return super(crm_lead, self).unlink(cr, uid, ids, context) - - def write(self, cr, uid, ids, vals, context=None): - if vals.get('stage_id') and not vals.get('probability'): - # change probability of lead(s) if required by stage - stage = self.pool.get('crm.case.stage').browse(cr, uid, vals['stage_id'], context=context) - if stage.on_change: - vals['probability'] = stage.probability - return super(crm_lead,self).write(cr, uid, ids, vals, context) - # ---------------------------------------- # OpenChatter methods and notifications # ---------------------------------------- def message_get_subscribers(self, cr, uid, ids, context=None): - sub_ids = self.message_get_subscribers_ids(cr, uid, ids, context=context) - # add salesman to the subscribers + """ Override to add the salesman. """ + user_ids = super(crm_lead, self).message_get_subscribers(cr, uid, ids, context=context) for obj in self.browse(cr, uid, ids, context=context): - if obj.user_id: - sub_ids.append(obj.user_id.id) - return self.pool.get('res.users').read(cr, uid, sub_ids, context=context) - + if obj.user_id and not obj.user_id.id in user_ids: + user_ids.append(obj.user_id.id) + return user_ids + def stage_set_send_note(self, cr, uid, ids, stage_id, context=None): """ Override of the (void) default notification method. """ stage_name = self.pool.get('crm.case.stage').name_get(cr, uid, [stage_id], context=context)[0][1] @@ -910,7 +896,7 @@ class crm_lead(base_stage, osv.osv): if action == 'log': prefix = 'Logged' else: prefix = 'Scheduled' message = _("%s a call for the %s.") % (prefix, phonecall.date) - return self. message_append_note(cr, uid, ids, body=message, context=context) + return self.message_append_note(cr, uid, ids, body=message, context=context) def _lead_set_partner_send_note(self, cr, uid, ids, context=None): for lead in self.browse(cr, uid, ids, context=context):