1 # -*- coding: utf-8 -*-
2 ##############################################################################
4 # OpenERP, Open Source Management Solution
5 # Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>). All Rights Reserved
8 # This program is free software: you can redistribute it and/or modify
9 # it under the terms of the GNU Affero General Public License as published by
10 # the Free Software Foundation, either version 3 of the License, or
11 # (at your option) any later version.
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU Affero General Public License for more details.
18 # You should have received a copy of the GNU Affero General Public License
19 # along with this program. If not, see <http://www.gnu.org/licenses/>.
21 ##############################################################################
26 from osv import osv, fields
28 from tools.translate import _
30 class crm_lead_forward_to_partner(osv.osv_memory):
31 """Forwards lead history"""
32 _name = 'crm.lead.forward.to.partner'
33 _inherit = "crm.send.mail"
36 'name': fields.selection([('user', 'User'), ('partner', 'Partner'), \
37 ('email', 'Email Address')], 'Send to', required=True),
38 'user_id': fields.many2one('res.users', "User"),
39 'partner_id' : fields.many2one('res.partner', 'Partner'),
40 'address_id' : fields.many2one('res.partner.address', 'Address'),
41 'history': fields.selection([('info', 'Case Information'), ('latest', 'Latest email'), ('whole', 'Whole Story')], 'Send history', required=True),
47 'email_from': lambda self, cr, uid, *a: self.pool.get('res.users')._get_email_from(cr, uid, uid)[uid],
51 def get_whole_history(self, cr, uid, ids, context=None):
52 """This function gets whole communication history and returns as top posting style
53 @param self: The object pointer
54 @param cr: the current row, from the database cursor,
55 @param uid: the current user’s ID for security checks,
56 @param ids: List of history IDs
57 @param context: A standard dictionary for contextual values
61 whole.append(self.get_latest_history(cr, uid, hist_id, context=context))
62 whole = '\n\n'.join(whole)
65 def get_latest_history(self, cr, uid, hist_id, context=None):
66 """This function gets latest communication and returns as top posting style
67 @param self: The object pointer
68 @param cr: the current row, from the database cursor,
69 @param uid: the current user’s ID for security checks,
70 @param hist_id: Id of latest history
71 @param context: A standard dictionary for contextual values
73 log_pool = self.pool.get('mailgate.message')
74 hist = log_pool.browse(cr, uid, hist_id, context=context)
75 header = '-------- Original Message --------'
76 sender = 'From: %s' %(hist.email_from or '')
77 to = 'To: %s' % (hist.email_to or '')
78 sentdate = 'Date: %s' % (hist.date or '')
79 desc = '\n%s'%(hist.description)
80 original = [header, sender, to, sentdate, desc]
81 original = '\n'.join(original)
84 def on_change_email(self, cr, uid, ids, user):
85 """This function fills email information based on user selected
86 @param self: The object pointer
87 @param cr: the current row, from the database cursor,
88 @param uid: the current user’s ID for security checks,
89 @param ids: List of Mail’s IDs
90 @param user: Changed User id
91 @param partner: Changed Partner id
94 return {'value': {'email_to': False}}
95 email = self.pool.get('res.users')._get_email_from(cr, uid, [user])[user]
96 return {'value': {'email_to': email}}
98 def on_change_history(self, cr, uid, ids, history_type, context=None):
99 """Gives message body according to type of history selected
100 * info: Forward the case information
101 * whole: Send the whole history
102 * latest: Send the latest histoy
103 @param self: The object pointer
104 @param cr: the current row, from the database cursor,
105 @param uid: the current user’s ID for security checks,
106 @param ids: List of history IDs
107 @param context: A standard dictionary for contextual values
109 #TODO: ids and context are not comming
111 res_id = context.get('active_id')
112 msg_val = self._get_case_history(cr, uid, history_type, res_id, context=context)
114 res = {'value': {'body' : '\n\n' + msg_val}}
117 def _get_case_history(self, cr, uid, history_type, res_id, context=None):
122 case_info = self.get_lead_details(cr, uid, res_id, context=context)
123 model_pool = self.pool.get('crm.lead')
125 if history_type == 'info':
128 elif history_type == 'whole':
129 log_ids = model_pool.browse(cr, uid, res_id, context=context).message_ids
130 log_ids = map(lambda x: x.id, filter(lambda x: x.history, log_ids))
131 msg_val = case_info + '\n\n' + self.get_whole_history(cr, uid, log_ids, context=context)
133 elif history_type == 'latest':
134 log_ids = model_pool.browse(cr, uid, res_id, context=context).message_ids
135 log_ids = filter(lambda x: x.history and x.id, log_ids)
139 msg_val = case_info + '\n\n' + self.get_latest_history(cr, uid, log_ids[0].id, context=context)
143 def on_change_partner(self, cr, uid, ids, partner_id):
144 """This function fills address information based on partner/user selected
145 @param self: The object pointer
146 @param cr: the current row, from the database cursor,
147 @param uid: the current user’s ID for security checks,
148 @param ids: List of Mail’s IDs
149 @param user: Changed User id
150 @param partner: Changed Partner id
153 return {'value' : {'email_to' : False, 'address_id': False}}
155 partner_obj = self.pool.get('res.partner')
156 addr = partner_obj.address_get(cr, uid, [partner_id], ['contact'])
157 data = {'address_id': addr['contact']}
158 data.update(self.on_change_address(cr, uid, ids, addr['contact'])['value'])
160 partner = partner_obj.browse(cr, uid, [partner_id])
161 user_id = partner and partner[0].user_id or False
162 email = user_id and user_id.user_email or ''
163 data.update({'email_cc' : email})
166 'domain' : {'address_id' : partner_id and "[('partner_id', '=', partner_id)]" or "[]"}
169 def on_change_address(self, cr, uid, ids, address_id):
172 email = self.pool.get('res.partner.address').browse(cr, uid, address_id).email
173 return {'value': {'email_to' : email}}
175 def action_forward(self, cr, uid, ids, context=None):
177 Forward the lead to a partner
181 this = self.browse(cr, uid, ids[0], context=context)
182 case_pool = self.pool.get(context.get('active_model'))
183 res_id = context and context.get('active_id', False) or False
184 case = case_pool.browse(cr, uid, res_id, context=context)
186 context.update({'mail': 'forward'})
187 super(crm_lead_forward_to_partner, self).action_send(cr, uid, ids, context=context)
189 to_write = {'date_assign': time.strftime('%Y-%m-%d')}
190 if (this.name == 'partner' and this.partner_id):
191 to_write['partner_assigned_id'] = this.partner_id.id
193 if this.name == 'user':
194 to_write.update({'user_id' : this.user_id.id})
195 email_re = r'([^ ,<@]+@[^> ,]+)'
196 email_cc = re.findall(email_re, case.email_cc or '')
199 new_cc.append(case.email_cc)
200 for to in this.email_to.split(','):
201 email_to = re.findall(email_re, to)
202 email_to = email_to and email_to[0] or ''
203 if email_to not in email_cc:
205 to_write.update({'email_cc' : ', '.join(new_cc) })
206 case_pool.write(cr, uid, case.id, to_write, context=context)
208 return {'type': 'ir.actions.act_window_close'}
210 def get_lead_details(self, cr, uid, lead_id, context=None):
213 Below is possibly an interesting lead for you.
215 OpenERP Leads are now forwarded to our trusted partners, through our OpenERP CRM.
216 We hope that this one will provide you an interesting project, as they've recently contacted us showing interest in our software.
218 Please keep your account manager informed about the advancements of this lead or if you are not able to answer to its requests by replying to this email. This way, we can keep track of closed leads or forward them to other partners.
220 Please don't forget to propose our OpenERP Publisher's Warranty at the beginning of your implementation projects, together with your services quotation. The Warranty will provide unlimited bugfixing that will avoid you waste time on bugs detected during the implementation. It also provides free migration services for the current stable version at the time of signature; otherwise if we released a new version during your implementation, the customer would not always be able to easily migrate to newer versions. Please find all related information via http://www.openerp.com/services/pricing
222 Kind regards, OpenERP Team
225 lead_proxy = self.pool.get('crm.lead')
226 lead = lead_proxy.browse(cr, uid, lead_id, context=context)
227 if not lead.type or lead.type == 'lead' or not lead.partner_address_id:
229 'partner_name', 'title', 'function', 'street', 'street2',
230 'zip', 'city', 'country_id', 'state_id', 'email_from',
231 'phone', 'fax', 'mobile', 'categ_id', 'description',
234 for field_name in field_names:
235 field_definition = lead_proxy._columns[field_name]
238 if field_definition._type == 'selection':
239 if hasattr(field_definition.selection, '__call__'):
240 key = field_definition.selection(lead_proxy, cr, uid, context=context)
242 key = field_definition.selection
243 value = dict(key).get(lead[field_name], lead[field_name])
244 elif field_definition._type == 'many2one':
246 value = lead[field_name].name_get()[0][1]
248 value = lead[field_name]
250 body.append("%s: %s" % (field_definition.string, value or ''))
251 elif lead.type == 'opportunity':
252 pa = lead.partner_address_id
254 "Partner: %s" % (lead.partner_id and lead.partner_id.name_get()[0][1]),
255 "Contact: %s" % (pa.name or ''),
256 "Title: %s" % (pa.title or ''),
257 "Function: %s" % (pa.function or ''),
258 "Street: %s" % (pa.street or ''),
259 "Street2: %s" % (pa.street2 or ''),
260 "Zip: %s" % (pa.zip or ''),
261 "City: %s" % (pa.city or ''),
262 "Country: %s" % (pa.country_id and pa.country_id.name_get()[0][1] or ''),
263 "State: %s" % (pa.state_id and pa.state_id.name_get()[0][1] or ''),
264 "Email: %s" % (pa.email or ''),
265 "Phone: %s" % (pa.phone or ''),
266 "Fax: %s" % (pa.fax or ''),
267 "Mobile: %s" % (pa.mobile or ''),
268 "Lead Category: %s" % (lead.categ_id and lead.categ_id.name or ''),
269 "Details: %s" % (lead.description or ''),
271 return "\n".join(template + body + ['---'])
273 def default_get(self, cr, uid, fields, context=None):
275 This function gets default values
281 defaults = super(crm_lead_forward_to_partner, self).default_get(cr, uid, fields, context=context)
282 active_id = context.get('active_id')
286 lead_proxy = self.pool.get('crm.lead')
287 partner_obj = self.pool.get('res.partner')
288 lead = lead_proxy.browse(cr, uid, active_id, context=context)
292 if lead.partner_assigned_id:
293 partner = partner_obj.browse(cr, uid, [lead.partner_assigned_id.id])
294 user_id = partner and partner[0].user_id or False
295 email_cc = user_id and user_id.user_email or ''
297 addr = partner_obj.address_get(cr, uid, [partner[0].id], ['contact'])
298 email = self.pool.get('res.partner.address').browse(cr, uid, addr['contact']).email
302 body = self._get_case_history(cr, uid, defaults.get('history', 'latest'), lead.id, context=context)
304 'subject' : '%s: %s - %s' % (_('Fwd'), 'Openerp lead forward', lead.name),
306 'email_cc' : email_cc,
311 crm_lead_forward_to_partner()
313 class crm_lead_mass_forward_to_partner(osv.osv_memory):
314 _name = 'crm.lead.mass.forward.to.partner'
315 _inherit = 'crm.lead.forward.to.partner'
317 def action_mass_forward(self, cr, uid, ids, context=None):
321 active_ids = context.get('active_ids')
322 case_obj = self.pool.get('crm.lead')
323 for case in case_obj.browse(cr, uid, active_ids, context=context):
324 if case.type != "opportunity":
327 if not case.partner_assigned_id:
328 case_obj.assign_partner(cr,uid, [case.id], context=context)
329 case = case_obj.browse(cr, uid, case.id, context=context)
331 if not case.partner_assigned_id:
334 context.update({'active_id' : case.id})
335 value = self.default_get(cr, uid, ['body', 'email_to', 'email_cc', 'subject', 'history'], context=context)
336 self.write(cr, uid, ids, value, context=context)
337 self.action_forward(cr,uid, ids, context=context)
339 return {'type': 'ir.actions.act_window_close'}
342 crm_lead_mass_forward_to_partner()
344 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: