1 # -*- coding: utf-8 -*-
2 ##############################################################################
4 # OpenERP, Open Source Management Solution
5 # Copyright (C) 2010-Today OpenERP SA (<http://www.openerp.com>)
7 # This program is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation, either version 3 of the License, or
10 # (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>
20 ##############################################################################
22 from openerp.osv import osv
23 from openerp.osv import fields
24 from openerp.tools.translate import _
25 from datetime import datetime
31 emails_split = re.compile(r"[;,\n\r]+")
34 class survey_mail_compose_message(osv.TransientModel):
35 _name = 'survey.mail.compose.message'
36 _inherit = 'mail.compose.message'
37 _description = 'Email composition wizard for Survey'
40 def _get_public_url(self, cr, uid, ids, name, arg, context=None):
41 res = dict((id, 0) for id in ids)
42 survey_obj = self.pool.get('survey.survey')
43 for wizard in self.browse(cr, uid, ids, context=context):
44 res[wizard.id] = survey_obj.browse(cr, uid, wizard.survey_id, context=context).public_url
47 def _get_public_url_html(self, cr, uid, ids, name, arg, context=None):
48 """ Compute if the message is unread by the current user """
49 urls = self._get_public_url(cr, uid, ids, name, arg, context=context)
50 for key, url in urls.items():
51 urls[key] = '<a href="%s">%s</a>' % (url, _("Click here to start survey"))
55 'survey_id': fields.many2one('survey.survey', 'Survey', required=True),
56 'public': fields.selection([('public_link', 'Share the public web link to your audience.'),
57 ('email_public_link', 'Send by email the public web link to your audience.'),
58 ('email_private', 'Send private invitation to your audience (only one response per recipient and per invitation).')],
59 string='Share options', required=True),
60 'public_url': fields.function(_get_public_url, string="Public url", type="char"),
61 'public_url_html': fields.function(_get_public_url_html, string="Public HTML web link", type="char"),
62 'partner_ids': fields.many2many('res.partner',
63 'survey_mail_compose_message_res_partner_rel',
64 'wizard_id', 'partner_id', 'Existing contacts'),
65 'attachment_ids': fields.many2many('ir.attachment',
66 'survey_mail_compose_message_ir_attachments_rel',
67 'wizard_id', 'attachment_id', 'Attachments'),
68 'multi_email': fields.text(string='List of emails', help="This list of emails of recipients will not converted in contacts. Emails separated by commas, semicolons or newline."),
69 'date_deadline': fields.date(string="Deadline to which the invitation to respond is valid", help="Deadline to which the invitation to respond for this survey is valid. If the field is empty, the invitation is still valid."),
73 'public': 'public_link',
74 'survey_id': lambda self, cr, uid, ctx={}: ctx.get('model') == 'survey.survey' and ctx.get('res_id') or None
77 def default_get(self, cr, uid, fields, context=None):
78 res = super(survey_mail_compose_message, self).default_get(cr, uid, fields, context=context)
79 if context.get('active_model') == 'res.partner' and context.get('active_ids'):
80 res.update({'partner_ids': context.get('active_ids')})
83 def onchange_multi_email(self, cr, uid, ids, multi_email, context=None):
84 emails = list(set(emails_split.split(multi_email or "")))
90 if not re.search(r"^[^@]+@[^@]+$", email):
91 error_message += "\n'%s'" % email
93 emails_checked.append(email)
95 raise osv.except_osv(_('Warning!'), _("One email at least is incorrect: %s" % error_message))
98 values = {'multi_email': '\n'.join(emails_checked)}
99 return {'value': values}
101 def onchange_survey_id(self, cr, uid, ids, survey_id, context=None):
102 """ Compute if the message is unread by the current user. """
104 survey = self.pool.get('survey.survey').browse(cr, uid, survey_id, context=context)
107 'subject': survey.title,
108 'public_url': survey.public_url,
109 'public_url_html': '<a href="%s">%s</a>' % (survey.public_url, _("Click here to take survey")),
112 txt = _("Please select a survey")
116 'public_url_html': txt,
119 #------------------------------------------------------
120 # Wizard validation and send
121 #------------------------------------------------------
123 def send_mail(self, cr, uid, ids, context=None):
124 """ Process the wizard content and proceed with sending the related
125 email(s), rendering any template patterns on the fly if needed """
129 survey_response_obj = self.pool.get('survey.user_input')
130 partner_obj = self.pool.get('res.partner')
131 mail_mail_obj = self.pool.get('mail.mail')
133 model, anonymous_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'portal', 'group_anonymous')
137 def create_response_and_send_mail(wizard, token, partner_id, email):
138 """ Create one mail by recipients and replace __URL__ by link with identification token """
140 url = wizard.survey_id.public_url
142 url = urlparse.urlparse(url).path[1:] # dirty hack to avoid incorrect urls
145 url = url + '/' + token
151 'subject': wizard.subject,
152 'body': wizard.body.replace("__URL__", url),
153 'body_html': wizard.body.replace("__URL__", url),
155 'partner_ids': partner_id and [(4, partner_id)] or None,
156 'notified_partner_ids': partner_id and [(4, partner_id)] or None,
157 'attachment_ids': wizard.attachment_ids or None,
158 'email_from': wizard.email_from or None,
161 mail_id = mail_mail_obj.create(cr, uid, values, context=context)
162 mail_mail_obj.send(cr, uid, [mail_id], context=context)
164 def create_token(wizard, partner_id, email):
165 if context.get("survey_resent_token"):
166 response_ids = survey_response_obj.search(cr, uid, [('survey_id', '=', wizard.survey_id.id), ('state', 'in', ['new', 'skip']), '|', ('partner_id', '=', partner_id), ('email', '=', email)], context=context)
168 return survey_response_obj.read(cr, uid, response_ids, ['token'], context=context)[0]['token']
169 if wizard.public != 'email_private':
172 token = uuid.uuid4().__str__()
173 # create response with token
174 survey_response_obj.create(cr, uid, {
175 'survey_id': wizard.survey_id.id,
176 'deadline': wizard.date_deadline,
177 'date_create': datetime.now(),
181 'partner_id': partner_id,
185 for wizard in self.browse(cr, uid, ids, context=context):
186 # check if __URL__ is in the text
187 if wizard.body.find("__URL__") < 0:
188 raise osv.except_osv(_('Warning!'), _("The content of the text don't contain '__URL__'. \
189 __URL__ is automaticaly converted into the special url of the survey."))
191 if not wizard.multi_email and not wizard.partner_ids and (context.get('default_partner_ids') or context.get('default_multi_email')):
192 wizard.multi_email = context.get('default_multi_email')
193 wizard.partner_ids = context.get('default_partner_ids')
195 # quick check of email list
197 if wizard.multi_email:
198 emails = list(set(emails_split.split(wizard.multi_email)) - set([partner.email for partner in wizard.partner_ids]))
200 email = email.strip()
201 if re.search(r"^[^@]+@[^@]+$", email):
202 emails_list.append(email)
204 # remove public anonymous access
206 for partner in wizard.partner_ids:
207 if not anonymous_id or not partner.user_ids or anonymous_id not in [x.id for x in partner.user_ids[0].groups_id]:
208 partner_list.append({'id': partner.id, 'email': partner.email})
210 if not len(emails_list) and not len(partner_list):
211 if wizard.model == 'res.partner' and wizard.res_id:
213 raise osv.except_osv(_('Warning!'), _("Please enter at least one valid recipient."))
215 for email in emails_list:
216 partner_id = partner_obj.search(cr, uid, [('email', '=', email)], context=context)
217 partner_id = partner_id and partner_id[0] or None
218 token = create_token(wizard, partner_id, email)
219 create_response_and_send_mail(wizard, token, partner_id, email)
221 for partner in partner_list:
222 token = create_token(wizard, partner['id'], partner['email'])
223 create_response_and_send_mail(wizard, token, partner['id'], partner['email'])
225 return {'type': 'ir.actions.act_window_close'}