diff --git a/addons/account/edi/invoice_action_data.xml b/addons/account/edi/invoice_action_data.xml index 9aa1a4b720f..53fa03a6902 100644 --- a/addons/account/edi/invoice_action_data.xml +++ b/addons/account/edi/invoice_action_data.xml @@ -123,64 +123,6 @@ ]]> - '%(object.user_id.email) or ''} - -You can view the invoice document, download it and pay online using the following link: - ${ctx.get('edi_web_url_view') or 'n/a'} - -% if object.company_id.paypal_account and object.type in ('out_invoice', 'in_refund'): -<% -comp_name = quote(object.company_id.name) -inv_number = quote(object.number) -paypal_account = quote(object.company_id.paypal_account) -inv_amount = quote(str(object.amount_total)) -cur_name = quote(object.currency_id.name) -paypal_url = "https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=%s&item_name=%s%%20Invoice%%20%s"\ - "&invoice=%s&amount=%s¤cy_code=%s&button_subtype=services&no_note=1&bn=OpenERP_Invoice_PayNow_%s" % \ - (paypal_account,comp_name,inv_number,inv_number,inv_amount,cur_name,cur_name) -%> -It is also possible to directly pay with Paypal: - ${paypal_url} -% endif - -If you have any question, do not hesitate to contact us. - - -Thank you for choosing ${object.company_id.name}! - - --- -${object.user_id.name} ${object.user_id.email and '<%s>'%(object.user_id.email) or ''} -${object.company_id.name} -% if object.company_id.street: -${object.company_id.street or ''} -% endif -% if object.company_id.street2: -${object.company_id.street2} -% endif -% if object.company_id.city or object.company_id.zip: -${object.company_id.zip or ''} ${object.company_id.city or ''} -% endif -% if object.company_id.country_id: -${object.company_id.state_id and ('%s, ' % object.company_id.state_id.name) or ''} ${object.company_id.country_id.name or ''} -% endif -% if object.company_id.phone: -Phone: ${object.company_id.phone} -% endif -% if object.company_id.website: -${object.company_id.website or ''} -% endif - ]]> diff --git a/addons/account_followup/wizard/account_followup_print.py b/addons/account_followup/wizard/account_followup_print.py index d151d2171a4..2b573fe0275 100644 --- a/addons/account_followup/wizard/account_followup_print.py +++ b/addons/account_followup/wizard/account_followup_print.py @@ -213,8 +213,6 @@ class account_followup_print_all(osv.osv_memory): mod_obj = self.pool.get('ir.model.data') move_obj = self.pool.get('account.move.line') user_obj = self.pool.get('res.users') - line_obj = self.pool.get('account_followup.stat') - mail_message = self.pool.get('mail.message') if context is None: context = {} @@ -241,7 +239,6 @@ class account_followup_print_all(osv.osv_memory): if (not dest) and partner.type=='default': if partner.email: dest = [partner.email] - src = tools.config.options['email_from'] if not data.partner_lang: body = data.email_body else: @@ -281,7 +278,12 @@ class account_followup_print_all(osv.osv_memory): msg = '' if dest: try: - mail_message.schedule_with_attach(cr, uid, src, dest, sub, body, context=context) + vals = {'state': 'outgoing', + 'subject': sub, + 'body_html': '
%s
' % body, + 'email_to': dest, + 'email_from': data_user.email or tools.config.options['email_from']} + self.pool.get('mail.mail').create(cr, uid, vals, context=context) msg_sent += partner.name + '\n' except Exception, e: raise osv.except_osv('Error !', e ) diff --git a/addons/auth_reset_password/auth_reset_password.xml b/addons/auth_reset_password/auth_reset_password.xml index d2256a8911a..b7d7e0baef6 100644 --- a/addons/auth_reset_password/auth_reset_password.xml +++ b/addons/auth_reset_password/auth_reset_password.xml @@ -9,16 +9,13 @@ ]]> Password reset - A password reset was requested the OpenERP account linked to this email on ${object._auth_reset_password_host()}

-You may change your password following this link: +

You may change your password following this link, +or by copy-pasting the following URL in your browser: ${object._auth_reset_password_link()}

-${object._auth_reset_password_link()} - -If you don't have asked for password reset, you can safely ignore this email. - -]]>
+

Note: If you did not ask for a password reset, you can safely ignore this email.

]]> diff --git a/addons/base_action_rule/base_action_rule.py b/addons/base_action_rule/base_action_rule.py index 8c115baed23..7e9bbacab13 100644 --- a/addons/base_action_rule/base_action_rule.py +++ b/addons/base_action_rule/base_action_rule.py @@ -302,33 +302,27 @@ the rule to mark CC(mail to any other person defined in actions)."), return self.format_body(body % data) def email_send(self, cr, uid, obj, emails, body, emailfrom=None, context=None): - """ send email - @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 email: pass the emails - @param emailfrom: Pass name the email From else False - @param context: A standard dictionary for contextual values """ - if not emailfrom: - emailfrom = tools.config.get('email_from', False) - - if context is None: - context = {} - - mail_message = self.pool.get('mail.message') + emailfrom = tools.config.get('email_from') body = self.format_mail(obj, body) - if not emailfrom: - if hasattr(obj, 'user_id') and obj.user_id and obj.user_id.email: - emailfrom = obj.user_id.email - - name = '[%d] %s' % (obj.id, tools.ustr(obj.name)) + if not emailfrom and hasattr(obj, 'user_id') and obj.user_id and obj.user_id.email: + emailfrom = obj.user_id.email emailfrom = tools.ustr(emailfrom) reply_to = emailfrom if not emailfrom: raise osv.except_osv(_('Error!'), - _("No email ID found for your company address.")) - return mail_message.schedule_with_attach(cr, uid, emailfrom, emails, name, body, model='base.action.rule', reply_to=reply_to, res_id=obj.id) + _("Missing default email address or missing email on responsible user")) + return self.pool.get('mail.mail').create(cr, uid, + { 'email_from': emailfrom, + 'email_to': emails.join(','), + 'reply_to': reply_to, + 'state': 'outgoing', + 'subject': '[%d] %s' % (obj.id, tools.ustr(obj.name)), + 'body_html': '
%s
' % body, + 'res_id': obj.id, + 'model': obj._table_name, + 'auto_delete': True + }, context=context) def do_check(self, cr, uid, action, obj, context=None): diff --git a/addons/base_calendar/base_calendar.py b/addons/base_calendar/base_calendar.py index d560eaacd66..a6d5f6859af 100644 --- a/addons/base_calendar/base_calendar.py +++ b/addons/base_calendar/base_calendar.py @@ -471,18 +471,10 @@ property or property parameter."), def _send_mail(self, cr, uid, ids, mail_to, email_from=tools.config.get('email_from', False), context=None): """ Send mail for event invitation to event attendees. - @param cr: the current row, from the database cursor, - @param uid: the current user’s ID for security checks, - @param ids: List of attendee’s IDs. @param email_from: Email address for user sending the mail - @param context: A standard dictionary for contextual values @return: True """ - if context is None: - context = {} - company = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.name - mail_message = self.pool.get('mail.message') for att in self.browse(cr, uid, ids, context=context): sign = att.sent_by_uid and att.sent_by_uid.signature or '' sign = '
'.join(sign and sign.split('\n') or []) @@ -508,17 +500,18 @@ property or property parameter."), } body = html_invitation % body_vals if mail_to and email_from: - attach = self.get_ics_file(cr, uid, res_obj, context=context) - mail_message.schedule_with_attach(cr, uid, - email_from, - mail_to, - sub, - body, - attachments=attach and {'invitation.ics': attach} or None, - content_subtype='html', - reply_to=email_from, - context=context - ) + ics_file = self.get_ics_file(cr, uid, res_obj, context=context) + vals = {'email_from': email_from, + 'email_to': mail_to, + 'state': 'outgoing', + 'subject': sub, + 'body_html': body, + 'auto_delete': True} + if ics_file: + vals['attachment_ids'] = [(0,0,{'name': 'invitation.ics', + 'datas_fname': 'invitation.ics', + 'datas': str(ics_file).encode('base64')})] + self.pool.get('mail.mail').create(cr, uid, vals, context=context) return True def onchange_user_id(self, cr, uid, ids, user_id, *args, **argv): @@ -812,7 +805,6 @@ class calendar_alarm(osv.osv): """ if context is None: context = {} - mail_message = self.pool.get('mail.message') current_datetime = datetime.now() alarm_ids = self.search(cr, uid, [('state', '!=', 'done')], context=context) @@ -849,36 +841,10 @@ class calendar_alarm(osv.osv): else: re_dates = [alarm.trigger_date] - for r_date in re_dates: - ref = alarm.model_id.model + ',' + str(alarm.res_id) - - # search for alreay sent requests - #if request_obj.search(cr, uid, [('trigger_date', '=', r_date), ('ref_doc1', '=', ref)], context=context): - #continue - - # Deactivated because of the removing of res.request - # TODO: when cleaning calendar module, re-add this in a new mechanism - #if alarm.action == 'display': - #value = { - #'name': alarm.name, - #'act_from': alarm.user_id.id, - #'act_to': alarm.user_id.id, - #'body': alarm.description, - #'trigger_date': r_date, - #'ref_doc1': ref - #} - #request_id = request_obj.create(cr, uid, value) - #request_ids = [request_id] - #for attendee in res_obj.attendee_ids: - #if attendee.user_id: - #value['act_to'] = attendee.user_id.id - #request_id = request_obj.create(cr, uid, value) - #request_ids.append(request_id) - #request_obj.request_send(cr, uid, request_ids) - + if re_dates: if alarm.action == 'email': - sub = '[Openobject Reminder] %s' % (alarm.name) - body = """ + sub = '[OpenERP Reminder] %s' % (alarm.name) + body = """
 Event: %s
 Event Date: %s
 Description: %s
@@ -888,20 +854,21 @@ From:
 
 ----
 %s
-
+
""" % (alarm.name, alarm.trigger_date, alarm.description, \ alarm.user_id.name, alarm.user_id.signature) mail_to = [alarm.user_id.email] for att in alarm.attendee_ids: mail_to.append(att.user_id.email) if mail_to: - mail_message.schedule_with_attach(cr, uid, - tools.config.get('email_from', False), - mail_to, - sub, - body, - context=context - ) + vals = { + 'state': 'outgoing', + 'subject': sub, + 'body_html': body, + 'email_to': mail_to, + 'email_from': tools.config.get('email_from', mail_to), + } + self.pool.get('mail.mail').create(cr, uid, vals, context=context) if next_trigger_date: update_vals.update({'trigger_date': next_trigger_date}) else: diff --git a/addons/base_status/base_stage.py b/addons/base_status/base_stage.py index 26afe548217..529e70fdb49 100644 --- a/addons/base_status/base_stage.py +++ b/addons/base_status/base_stage.py @@ -297,55 +297,31 @@ class base_stage(object): destination=False) def remind_user(self, cr, uid, ids, context=None, attach=False, destination=True): - mail_message = self.pool.get('mail.message') - for case in self.browse(cr, uid, ids, context=context): - if not destination and not case.email_from: - return False - if not case.user_id.email: - return False - if destination and case.section_id.user_id: - case_email = case.section_id.user_id.email - else: - case_email = case.user_id.email - - src = case_email - dest = case.user_id.email or "" - body = case.description or "" - for message in case.message_ids: - if message.email_from and message.body: - body = message.body - break - - if not destination: - src, dest = dest, case.email_from - if body and case.user_id.signature: - if body: - body += '\n\n%s' % (case.user_id.signature) - else: - body = '\n\n%s' % (case.user_id.signature) - - body = self.format_body(body) - - attach_to_send = {} - - if attach: - attach_ids = self.pool.get('ir.attachment').search(cr, uid, [('res_model', '=', self._name), ('res_id', '=', case.id)]) - attach_to_send = self.pool.get('ir.attachment').read(cr, uid, attach_ids, ['datas_fname', 'datas']) - attach_to_send = dict(map(lambda x: (x['datas_fname'], base64.decodestring(x['datas'])), attach_to_send)) - - # Send an email - subject = "Reminder: [%s] %s" % (str(case.id), case.name, ) - mail_message.schedule_with_attach(cr, uid, - src, - [dest], - subject, - body, - model=self._name, - reply_to=case.section_id.reply_to, - res_id=case.id, - attachments=attach_to_send, - context=context - ) + if 'message_post' in self: + for case in self.browse(cr, uid, ids, context=context): + if destination: + recipient_id = case.user_id.partner_id.id + else: + if not case.email_from: + return False + recipient_id = self.pool.get('res.partner').find_or_create(cr, uid, case.email_from, context=context) + + body = case.description or "" + for message in case.message_ids: + if message.type == 'email' and message.body: + body = message.body + break + body = self.format_body(body) + attach_to_send = {} + if attach: + attach_ids = self.pool.get('ir.attachment').search(cr, uid, [('res_model', '=', self._name), ('res_id', '=', case.id)]) + attach_to_send = self.pool.get('ir.attachment').read(cr, uid, attach_ids, ['datas_fname', 'datas']) + attach_to_send = dict(map(lambda x: (x['datas_fname'], x['datas'].decode('base64')), attach_to_send)) + + subject = "Reminder: [%s] %s" % (case.id, case.name) + self.message_post(cr, uid, case.id, body=body, + subject=subject, attachments=attach_to_send, + partner_ids=[recipient_id], context=context) return True def _check(self, cr, uid, ids=False, context=None): @@ -360,17 +336,6 @@ class base_stage(object): def format_mail(self, obj, body): return self.pool.get('base.action.rule').format_mail(obj, body) - def message_thread_followers(self, cr, uid, ids, context=None): - res = {} - for case in self.browse(cr, uid, ids, context=context): - l=[] - if case.email_cc: - l.append(case.email_cc) - if case.user_id and case.user_id.email: - l.append(case.user_id.email) - res[case.id] = l - return res - # ****************************** # Notifications # ****************************** diff --git a/addons/crm/crm_action_rule.py b/addons/crm/crm_action_rule.py index 36700b5b6c2..8b1ba655afc 100644 --- a/addons/crm/crm_action_rule.py +++ b/addons/crm/crm_action_rule.py @@ -46,21 +46,11 @@ class base_action_rule(osv.osv): } def email_send(self, cr, uid, obj, emails, body, emailfrom=tools.config.get('email_from', False), context=None): - mail_message = self.pool.get('mail.message') - body = self.format_mail(obj, body) - if not emailfrom: - if hasattr(obj, 'user_id') and obj.user_id and obj.user_id.email: - emailfrom = obj.user_id.email - - name = '[%d] %s' % (obj.id, tools.ustr(obj.name)) - emailfrom = tools.ustr(emailfrom) - if hasattr(obj, 'section_id') and obj.section_id and obj.section_id.alias_id: + mail_id = super(base_action_rule, self).email_send(cr, uid, obj, emails, body, emailfrom=emailfrom, context=context) + if mail_id and hasattr(obj, 'section_id') and obj.section_id and obj.section_id.alias_id: reply_to = obj.section_id.alias_id.name_get()[0][1] - else: - reply_to = emailfrom - if not emailfrom: - raise osv.except_osv(_('Error!'), _("There is no email for your company address.")) - return mail_message.schedule_with_attach(cr, uid, emailfrom, emails, name, body, model=obj._name, reply_to=reply_to, res_id=obj.id) + self.pool.get('mail.mail').write(cr, uid, [mail_id], {'reply_to': reply_to}, context=context) + return mail_id def do_check(self, cr, uid, action, obj, context=None): ok = super(base_action_rule, self).do_check(cr, uid, action, obj, context=context) diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py index 801895885b2..36af90fcf07 100644 --- a/addons/crm/crm_lead.py +++ b/addons/crm/crm_lead.py @@ -671,24 +671,6 @@ class crm_lead(base_stage, osv.osv): partner_ids[lead.id] = partner_id return partner_ids - def _send_mail_to_salesman(self, cr, uid, lead, context=None): - """ - Send mail to salesman with updated Lead details. - @ lead: browse record of 'crm.lead' object. - """ - #TOFIX: mail template should be used here instead of fix subject, body text. - message = self.pool.get('mail.message') - email_to = lead.user_id and lead.user_id.email - if not email_to: - return False - - email_from = lead.section_id and lead.section_id.user_id and lead.section_id.user_id.email or email_to - partner = lead.partner_id and lead.partner_id.name or lead.partner_name - subject = "lead %s converted into opportunity" % lead.name - body = "Info \n Id : %s \n Subject: %s \n Partner: %s \n Description : %s " % (lead.id, lead.name, lead.partner_id.name, lead.description) - return message.schedule_with_attach(cr, uid, email_from, [email_to], subject, body) - - def allocate_salesman(self, cr, uid, ids, user_ids, team_id=False, context=None): index = 0 for lead_id in ids: diff --git a/addons/crm_partner_assign/wizard/crm_forward_to_partner.py b/addons/crm_partner_assign/wizard/crm_forward_to_partner.py index 6ed8da7b231..0cac38e0163 100644 --- a/addons/crm_partner_assign/wizard/crm_forward_to_partner.py +++ b/addons/crm_partner_assign/wizard/crm_forward_to_partner.py @@ -89,11 +89,6 @@ class crm_lead_forward_to_partner(osv.osv_memory): lead = self.pool.get(model).browse(cr, uid, res_id, context=context) body = self._get_message_body(cr, uid, lead, history_mode, context=context) return {'value': {'body': body}} - - def on_change_partner_ids(self, cr, uid, ids, partner_ids, context=None): - """ TDE-TODO: Keep void; maybe we could check that partner_ids have - email defined. """ - return {} def create(self, cr, uid, values, context=None): """ TDE-HACK: remove 'type' from context, because when viewing an @@ -106,9 +101,7 @@ class crm_lead_forward_to_partner(osv.osv_memory): return new_id def action_forward(self, cr, uid, ids, context=None): - """ - Forward the lead to a partner - """ + """ Forward the lead to a partner """ if context is None: context = {} res = {'type': 'ir.actions.act_window_close'} @@ -126,7 +119,7 @@ class crm_lead_forward_to_partner(osv.osv_memory): self.send_mail(cr, uid, ids, context=context) # for case in lead.browse(cr, uid, lead_ids, context=context): - # TDE: WHAT TO DO WITH THAT ? + # TODO: WHAT TO DO WITH THAT ? # if (this.send_to == 'partner' and this.partner_id): # lead.assign_partner(cr, uid, [case.id], this.partner_id.id, context=context) diff --git a/addons/crm_partner_assign/wizard/crm_forward_to_partner_view.xml b/addons/crm_partner_assign/wizard/crm_forward_to_partner_view.xml index fe9e1476817..0d8f27eec74 100644 --- a/addons/crm_partner_assign/wizard/crm_forward_to_partner_view.xml +++ b/addons/crm_partner_assign/wizard/crm_forward_to_partner_view.xml @@ -16,7 +16,7 @@ on_change="on_change_history_mode(history_mode, model, res_id)"/> + on_change="onchange_partner_ids(partner_ids)"/> diff --git a/addons/event/email_template.xml b/addons/event/email_template.xml index 49738185547..95ffbf46d8d 100644 --- a/addons/event/email_template.xml +++ b/addons/event/email_template.xml @@ -7,15 +7,12 @@ ${object.user_id.email or object.company_id.email or 'noreply@' + object.company_id.name + '.com'} ${object.email} Your registration at ${object.event_id.name} - - hello ${object.name}, - - The event ${object.event_id.name} that you registered for is confirmed and will be held from ${object.event_id.date_begin} to ${object.event_id.date_end}. For any further information please contact our event department. - - we thank you for your participation - - best regards - + Hello ${object.name},

+

The event ${object.event_id.name} that you registered for is confirmed and will be held from ${object.event_id.date_begin} to ${object.event_id.date_end}. + For any further information please contact our event department.

+

Thank you for your participation!

+

Best regards

]]>
@@ -27,15 +24,12 @@ ${object.user_id.email or object.company_id.email or 'noreply@' + object.company_id.name + '.com'} ${object.email} Your registration at ${object.event_id.name} - - hello ${object.name}, - - We confirm you that your registration to the event ${object.event_id.name} has been recorded. You will automatically receive an email providing you more practical information (such as the schedule, the plan...) as soon as the event will be confirmed to be held. - - we thank you for your participation - - best regards - + Hello ${object.name},

+

We confirm that your registration to the event ${object.event_id.name} has been recorded. + You will automatically receive an email providing you more practical information (such as the schedule, the agenda...) as soon as the event is confirmed.

+

Thank you for your participation!

+

Best regards

]]>
diff --git a/addons/hr_evaluation/hr_evaluation.py b/addons/hr_evaluation/hr_evaluation.py index def21f2b169..3508dc36d49 100644 --- a/addons/hr_evaluation/hr_evaluation.py +++ b/addons/hr_evaluation/hr_evaluation.py @@ -228,9 +228,13 @@ class hr_evaluation(osv.osv): body = phase.mail_body % {'employee_name': child.name, 'user_signature': child.user_id.signature, 'eval_name': phase.survey_id.title, 'date': time.strftime('%Y-%m-%d'), 'time': time } sub = phase.email_subject - dest = [child.work_email] - if dest: - mail_message.schedule_with_attach(cr, uid, evaluation.employee_id.work_email, dest, sub, body, context=context) + if child.work_email: + vals = {'state': 'outgoing', + 'subject': sub, + 'body_html': '
%s
' % body, + 'email_to': child.work_email, + 'email_from': evaluation.employee_id.work_email} + self.pool.get('mail.mail').create(cr, uid, vals, context=context) self.write(cr, uid, ids, {'state':'wait'}, context=context) return True diff --git a/addons/hr_evaluation/hr_evaluation_view.xml b/addons/hr_evaluation/hr_evaluation_view.xml index 9f64df8808d..4f49b7ba516 100644 --- a/addons/hr_evaluation/hr_evaluation_view.xml +++ b/addons/hr_evaluation/hr_evaluation_view.xml @@ -267,16 +267,27 @@
-
-
@@ -388,7 +399,6 @@ action="action_hr_evaluation_interview_tree"/> - + context="{'default_composition_mode': 'mass_mail', + 'default_body_text': 'Hello,\n\nKindly post your response for the survey interview.\n\nThanks', + 'default_subject': 'Reminder to fill up Survey'}"/> @@ -81,7 +81,6 @@
- diff --git a/addons/mail/mail_message.py b/addons/mail/mail_message.py index 4a25a8aa0c9..1559a412e44 100644 --- a/addons/mail/mail_message.py +++ b/addons/mail/mail_message.py @@ -136,7 +136,8 @@ class mail_message(osv.Model): _defaults = { 'type': 'email', 'date': lambda *a: fields.datetime.now(), - 'author_id': _get_default_author + 'author_id': lambda self,cr,uid,ctx: self._get_default_author(cr, uid, ctx), + 'body': '', } #------------------------------------------------------ diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index c7b4f333ebf..2422f556446 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -29,7 +29,6 @@ import time import tools import xmlrpclib -from email.utils import parsedate from email.message import Message from mail_message import decode from osv import osv, fields @@ -42,24 +41,20 @@ def decode_header(message, header, separator=' '): return separator.join(map(decode,message.get_all(header, []))) class many2many_reference(fields.many2many): - """ many2many_reference is an override of fields.many2many. It manages - many2many-like table where one id is given by two fields, res_model - and res_id. - """ + """ many2many_reference manages many2many fields where one id is found + by a reference-like key (a char column in addition to the foreign id). + The reference_column attribute on the many2many fields is used; + if not defined, ``res_model`` is used. """ def _get_query_and_where_params(self, cr, model, ids, values, where_params): - """ Add in where: - - ``mail_followers``.res_model = 'crm.lead' - """ - # reference column name: given by attribute or res_model - ref_col_name = self.ref_col_name if self.ref_col_name else 'res_model' - values.update({'ref_col_name': ref_col_name, 'ref_col_value': model._name}) - + """ Add in where condition like mail_followers.res_model = 'crm.lead' """ + reference_column = self.reference_column if self.reference_column else 'res_model' + values.update(reference_column=reference_column, reference_value=model._name) query = 'SELECT %(rel)s.%(id2)s, %(rel)s.%(id1)s \ FROM %(rel)s, %(from_c)s \ WHERE %(rel)s.%(id1)s IN %%s \ AND %(rel)s.%(id2)s = %(tbl)s.id \ - AND %(rel)s.%(ref_col_name)s = \'%(ref_col_value)s\' \ + AND %(rel)s.%(reference_column)s = \'%(reference_value)s\' \ %(where_c)s \ %(order_by)s \ %(limit)s \ @@ -68,41 +63,41 @@ class many2many_reference(fields.many2many): return query, where_params def set(self, cr, model, id, name, values, user=None, context=None): - """ Override to add the res_model field in queries. """ + """ Override to add the reference field in queries. """ if not values: return rel, id1, id2 = self._sql_names(model) obj = model.pool.get(self._obj) # reference column name: given by attribute or res_model - ref_col_name = self.ref_col_name if self.ref_col_name else 'res_model' + reference_column = self.reference_column if self.reference_column else 'res_model' for act in values: if not (isinstance(act, list) or isinstance(act, tuple)) or not act: continue if act[0] == 0: idnew = obj.create(cr, user, act[2], context=context) - cr.execute('INSERT INTO '+rel+' ('+id1+','+id2+','+ref_col_name+') VALUES (%s,%s,%s)', (id, idnew, model._name)) + cr.execute('INSERT INTO '+rel+' ('+id1+','+id2+','+reference_column+') VALUES (%s,%s,%s)', (id, idnew, model._name)) elif act[0] == 3: - cr.execute('DELETE FROM '+rel+' WHERE '+id1+'=%s AND '+id2+'=%s AND '+ref_col_name+'=%s', (id, act[1], model._name)) + cr.execute('DELETE FROM '+rel+' WHERE '+id1+'=%s AND '+id2+'=%s AND '+reference_column+'=%s', (id, act[1], model._name)) elif act[0] == 4: # following queries are in the same transaction - so should be relatively safe - cr.execute('SELECT 1 FROM '+rel+' WHERE '+id1+'=%s AND '+id2+'=%s AND '+ref_col_name+'=%s', (id, act[1], model._name)) + cr.execute('SELECT 1 FROM '+rel+' WHERE '+id1+'=%s AND '+id2+'=%s AND '+reference_column+'=%s', (id, act[1], model._name)) if not cr.fetchone(): - cr.execute('INSERT INTO '+rel+' ('+id1+','+id2+','+ref_col_name+') VALUES (%s,%s,%s)', (id, act[1], model._name)) + cr.execute('INSERT INTO '+rel+' ('+id1+','+id2+','+reference_column+') VALUES (%s,%s,%s)', (id, act[1], model._name)) elif act[0] == 5: - cr.execute('delete from '+rel+' where '+id1+' = %s AND '+ref_col_name+'=%s', (id, model._name)) + cr.execute('delete from '+rel+' where '+id1+' = %s AND '+reference_column+'=%s', (id, model._name)) elif act[0] == 6: d1, d2,tables = obj.pool.get('ir.rule').domain_get(cr, user, obj._name, context=context) if d1: d1 = ' and ' + ' and '.join(d1) else: d1 = '' - cr.execute('DELETE FROM '+rel+' WHERE '+id1+'=%s AND '+ref_col_name+'=%s AND '+id2+' IN (SELECT '+rel+'.'+id2+' FROM '+rel+', '+','.join(tables)+' WHERE '+rel+'.'+id1+'=%s AND '+rel+'.'+id2+' = '+obj._table+'.id '+ d1 +')', [id, model._name, id]+d2) + cr.execute('DELETE FROM '+rel+' WHERE '+id1+'=%s AND '+reference_column+'=%s AND '+id2+' IN (SELECT '+rel+'.'+id2+' FROM '+rel+', '+','.join(tables)+' WHERE '+rel+'.'+id1+'=%s AND '+rel+'.'+id2+' = '+obj._table+'.id '+ d1 +')', [id, model._name, id]+d2) for act_nbr in act[2]: - cr.execute('INSERT INTO '+rel+' ('+id1+','+id2+','+ref_col_name+') VALUES (%s,%s,%s)', (id, act_nbr, model._name)) + cr.execute('INSERT INTO '+rel+' ('+id1+','+id2+','+reference_column+') VALUES (%s,%s,%s)', (id, act_nbr, model._name)) # cases 1, 2: performs write and unlink -> default implementation is ok else: return super(many2many_reference, self).set(cr, model, id, name, values, user, context) -class mail_thread(osv.Model): +class mail_thread(osv.AbstractModel): ''' mail_thread model is meant to be inherited by any model that needs to act as a discussion topic on which messages can be attached. Public methods are prefixed with ``message_`` in order to avoid name @@ -161,19 +156,18 @@ class mail_thread(osv.Model): type='boolean', string='Is a Follower', multi='_get_message_data'), 'message_follower_ids': many2many_reference('res.partner', 'mail_followers', 'res_id', 'partner_id', - ref_col_name='res_model', string='Followers'), + reference_column='res_model', string='Followers'), 'message_comment_ids': fields.one2many('mail.message', 'res_id', - domain=lambda self: [('model','=',self._name),('type','in',('comment','email'))], - string='Related Messages', - help="All messages related to the current document."), + domain=lambda self: [('model', '=', self._name), ('type', 'in', ('comment', 'email'))], + string='Comments and emails', + help="Comments and emails"), 'message_ids': fields.one2many('mail.message', 'res_id', domain=lambda self: [('model','=',self._name)], - string='Related Messages', - help="All messages related to the current document."), + string='Messages', + help="Messages and communication history"), 'message_unread': fields.function(_get_message_data, fnct_search=_search_unread, - string='Has Unread Messages', type='boolean', - help="When checked, new messages require your attention.", - multi="_get_message_data"), + type='boolean', string='Unread Messages', multi="_get_message_data", + help="If checked new messages require your attention."), 'message_summary': fields.function(_get_message_data, method=True, type='text', string='Summary', multi="_get_message_data", help="Holds the Chatter summary (number of messages, ...). "\ @@ -186,7 +180,7 @@ class mail_thread(osv.Model): #------------------------------------------------------ def create(self, cr, uid, vals, context=None): - """ Override of create to subscribe the current user. """ + """ Override to subscribe the current user. """ thread_id = super(mail_thread, self).create(cr, uid, vals, context=context) self.message_subscribe_users(cr, uid, [thread_id], [uid], context=context) return thread_id @@ -217,14 +211,20 @@ class mail_thread(osv.Model): # Mail gateway #------------------------------------------------------ + def message_capable_models(self, cr, uid, context=None): + """ Used by the plugin addon, based for plugin_outlook and others. """ + ret_dict = {} + for model_name in self.pool.obj_list(): + model = self.pool.get(model_name) + if 'mail.thread' in getattr(model, '_inherit', []): + ret_dict[model_name] = model._description + return ret_dict + def _message_find_partners(self, cr, uid, message, header_fields=['From'], context=None): """ Find partners related to some header fields of the message. """ s = ', '.join([decode(message.get(h)) for h in header_fields if message.get(h)]) - mails = tools.email_split(s) - result = [] - for email in mails: - result += self.pool.get('res.partner').search(cr, uid, [('email', 'ilike', email)], context=context) - return result + return [partner_id for email in tools.email_split(s) + for partner_id in self.pool.get('res.partner').search(cr, uid, [('email', 'ilike', email)], context=context)] def _message_find_user_id(self, cr, uid, message, context=None): from_local_part = tools.email_split(decode(message.get('From')))[0] @@ -387,9 +387,7 @@ class mail_thread(osv.Model): for a given thread model, if the message did not belong to an existing thread. The default behavior is to create a new record of the corresponding - model (based on some very basic info extracted from the message), - then attach the message to the newly created record - (by calling ``message_append_dict``). + model (based on some very basic info extracted from the message). Additional behavior may be implemented by overriding this method. :param dict msg_dict: a map containing the email details and @@ -422,9 +420,8 @@ class mail_thread(osv.Model): def message_update(self, cr, uid, ids, msg_dict, update_vals=None, context=None): """Called by ``message_process`` when a new message is received - for an existing thread. The default behavior is to create a - new mail.message in the given thread (by calling - ``message_append_dict``) + for an existing thread. The default behavior is to update the record + with update_vals taken from the incoming email. Additional behavior may be implemented by overriding this method. :param dict msg_dict: a map containing the email details and @@ -556,23 +553,23 @@ class mail_thread(osv.Model): #------------------------------------------------------ def log(self, cr, uid, id, message, secondary=False, context=None): - _logger.warning("log() is deprecated. As this module inherit from \ - mail.thread, the message will be managed by this \ - module instead of by the res.log mechanism. Please \ - use the mail.thread OpenChatter API instead of the \ - now deprecated res.log.") + _logger.warning("log() is deprecated. As this module inherit from "\ + "mail.thread, the message will be managed by this "\ + "module instead of by the res.log mechanism. Please "\ + "use mail_thread.message_post() instead of the "\ + "now deprecated res.log.") self.message_post(cr, uid, [id], message, context=context) def message_post(self, cr, uid, thread_id, body='', subject=False, - msg_type='notification', parent_id=False, attachments=None, subtype='other', context=None, **kwargs): - """ Post a new message in an existing message thread, returning the new + type='notification', parent_id=False, attachments=None, subtype='other', context=None, **kwargs): + """ Post a new message in an existing thread, returning the new mail.message ID. Extra keyword arguments will be used as default column values for the new mail.message record. :param int thread_id: thread ID to post into, or list with one ID :param str body: body of the message, usually raw HTML that will be sanitized :param str subject: optional subject - :param str msg_type: mail_message.type + :param str type: mail_message.type :param int parent_id: optional ID of parent message in this thread :param tuple(str,str) attachments: list of attachment tuples in the form ``(name,content)``, where content is NOT base64 encoded @@ -608,11 +605,11 @@ class mail_thread(osv.Model): if self._name in [model.model for model in subtype_browse.model_ids]: values['subtype_id']=subtype_browse.id values.update( { - 'model': thread_id and context.get('thread_model', self._name) or False, + 'model': context.get('thread_model', self._name) if thread_id else False, 'res_id': thread_id or False, 'body': body, 'subject': subject, - 'type': msg_type, + 'type': type, 'parent_id': parent_id, 'attachment_ids': attachment_ids, }) @@ -626,16 +623,14 @@ class mail_thread(osv.Model): def message_subscribe_users(self, cr, uid, ids, user_ids=None, context=None): """ Wrapper on message_subscribe, using users. If user_ids is not provided, subscribe uid instead. """ - # isinstance: because using message_subscribe_users called in a view set the context as user_ids - if not user_ids or isinstance(user_ids, dict): user_ids = [uid] + if not user_ids: user_ids = [uid] partner_ids = [user.partner_id.id for user in self.pool.get('res.users').browse(cr, uid, user_ids, context=context)] return self.message_subscribe(cr, uid, ids, partner_ids, context=context) def message_subscribe(self, cr, uid, ids, partner_ids,subtype_ids = None, context=None): """ Add partners to the records followers. - :param partner_ids: a list of partner_ids to subscribe - :param return: new value of followers, for Chatter + :param return: new value of followers if read_back key in context """ self.write(cr, uid, ids, {'message_follower_ids': [(4, pid) for pid in partner_ids]}, context=context) if not subtype_ids: @@ -643,28 +638,27 @@ class mail_thread(osv.Model): subtype_ids = subtype_obj.search(cr, uid, [('default', '=', 'true'),('model_ids.model', '=', self._name)]) if subtype_ids: self.message_subscribe_udpate_subtypes(cr, uid, ids, partner_ids, subtype_ids, context=context) - # TDE: temp, must check followers widget + if context and context.get('read_back'): + return [follower.id for thread in self.browse(cr, uid, ids, context=context) for follower in thread.message_follower_ids] return [] - # return [follower.id for thread in self.browse(cr, uid, ids, context=context) for follower in thread.message_follower_ids] + def message_unsubscribe_users(self, cr, uid, ids, user_ids=None, context=None): """ Wrapper on message_subscribe, using users. If user_ids is not provided, unsubscribe uid instead. """ - # isinstance: because using message_subscribe_users called in a view set the context as user_ids - if not user_ids or isinstance(user_ids, dict): user_ids = [uid] + if not user_ids: user_ids = [uid] partner_ids = [user.partner_id.id for user in self.pool.get('res.users').browse(cr, uid, user_ids, context=context)] return self.message_unsubscribe(cr, uid, ids, partner_ids, context=context) def message_unsubscribe(self, cr, uid, ids, partner_ids, context=None): """ Remove partners from the records followers. - :param partner_ids: a list of partner_ids to unsubscribe - :param return: new value of followers, for Chatter + :param return: new value of followers if read_back key in context """ self.write(cr, uid, ids, {'message_follower_ids': [(3, pid) for pid in partner_ids]}, context=context) - # TDE: temp, must check followers widget + if context and context.get('read_back'): + return [follower.id for thread in self.browse(cr, uid, ids, context=context) for follower in thread.message_follower_ids] return [] - # return [follower.id for thread in self.browse(cr, uid, ids, context=context) for follower in thread.message_follower_ids] #------------------------------------------------------ # Thread state diff --git a/addons/mail/static/src/js/mail_followers.js b/addons/mail/static/src/js/mail_followers.js index fc9223b3657..5d7b2ec5116 100644 --- a/addons/mail/static/src/js/mail_followers.js +++ b/addons/mail/static/src/js/mail_followers.js @@ -9,7 +9,7 @@ openerp_mail_followers = function(session, mail) { * mail_followers Widget * ------------------------------------------------------------ * - * This widget handles the display of a list of records as a vetical + * This widget handles the display of a list of records as a vertical * list, with an image on the left. The widget itself is a floatting * right-sided box. * This widget is mainly used to display the followers of records @@ -71,25 +71,17 @@ openerp_mail_followers = function(session, mail) { this.$el.find('div.oe_mail_recthread_aside').hide(); return; } - if (this.getParent().fields.message_is_follower === undefined) { - // TDE: TMP, need to change all form views - this.message_is_follower = false; - } - else { - this.message_is_follower = this.getParent().fields.message_is_follower.get_value(); - } return this.fetch_followers(value_); }, fetch_followers: function (value_) { - return this.ds_follow.call('read', [value_ || this.get_value(), ['name']]).then(this.proxy('display_followers')); + return this.ds_follow.call('read', [value_ || this.get_value(), ['name', 'user_ids']]).then(this.proxy('display_followers')); }, - /** - * Display the followers. - * TODO: replace the is_follower check by fields read */ + /** Display the followers, evaluate is_follower directly */ display_followers: function (records) { var self = this; + this.message_is_follower = _.indexOf(_.flatten(_.pluck(records, 'user_ids')), this.session.uid) != -1; var node_user_list = this.$el.find('ul.oe_mail_followers_display').empty(); this.$el.find('div.oe_mail_recthread_followers h4').html(this.options.title + ' (' + records.length + ')'); _(records).each(function (record) { @@ -137,7 +129,8 @@ openerp_mail_followers = function(session, mail) { }, do_follow: function () { - return this.ds_model.call('message_subscribe_users', [[this.view.datarecord.id]]).pipe(this.proxy('set_value')); + var context = new session.web.CompoundContext(this.build_context(), {'read_back': true}); + return this.ds_model.call('message_subscribe_users', [[this.view.datarecord.id], undefined, context]).pipe(this.proxy('set_value')); }, //fetch subtype from subtype model @@ -150,7 +143,8 @@ openerp_mail_followers = function(session, mail) { }, do_unfollow: function () { - return this.ds_model.call('message_unsubscribe_users', [[this.view.datarecord.id]]).pipe(this.proxy('set_value')); + var context = new session.web.CompoundContext(this.build_context(), {'read_back': true}); + return this.ds_model.call('message_unsubscribe_users', [[this.view.datarecord.id], undefined, context]).pipe(this.proxy('set_value')); }, }); }; diff --git a/addons/mail/tests/test_mail.py b/addons/mail/tests/test_mail.py index cfb885eb74b..bc8a0e5c085 100644 --- a/addons/mail/tests/test_mail.py +++ b/addons/mail/tests/test_mail.py @@ -251,7 +251,7 @@ class test_mail(common.TransactionCase): _attachments = [('First', 'My first attachment'), ('Second', 'My second attachment')] # CASE1: post comment, body and subject specified - msg_id = self.mail_group.message_post(cr, uid, self.group_pigs_id, body=_body1, subject=_subject, msg_type='comment') + msg_id = self.mail_group.message_post(cr, uid, self.group_pigs_id, body=_body1, subject=_subject, type='comment') message = self.mail_message.browse(cr, uid, msg_id) mail_ids = self.mail_mail.search(cr, uid, [], limit=1) mail = self.mail_mail.browse(cr, uid, mail_ids[0]) @@ -281,7 +281,7 @@ class test_mail(common.TransactionCase): # CASE2: post an email with attachments, parent_id, partner_ids # TESTS: automatic subject, signature in body_html, attachments propagation - msg_id2 = self.mail_group.message_post(cr, uid, self.group_pigs_id, body=_body2, msg_type='email', + msg_id2 = self.mail_group.message_post(cr, uid, self.group_pigs_id, body=_body2, type='email', partner_ids=[(6, 0, [p_d_id])], parent_id=msg_id, attachments=_attachments) message = self.mail_message.browse(cr, uid, msg_id2) mail_ids = self.mail_mail.search(cr, uid, [], limit=1) diff --git a/addons/mail/wizard/mail_compose_message.py b/addons/mail/wizard/mail_compose_message.py index 15f428264ff..3c93440642d 100644 --- a/addons/mail/wizard/mail_compose_message.py +++ b/addons/mail/wizard/mail_compose_message.py @@ -81,7 +81,7 @@ class mail_compose_message(osv.TransientModel): elif composition_mode == 'comment' and model and res_id: vals = self.get_record_data(cr, uid, model, res_id, context=context) elif composition_mode == 'mass_mail' and model and active_ids: - vals = {'model': model, 'res_id': res_id, 'content_subtype': 'html'} + vals = {'model': model, 'res_id': res_id} else: vals = {'model': model, 'res_id': res_id} if composition_mode: @@ -106,7 +106,7 @@ class mail_compose_message(osv.TransientModel): 'mail_compose_message_ir_attachments_rel', 'wizard_id', 'attachment_id', 'Attachments'), 'filter_id': fields.many2one('ir.filters', 'Filters'), - 'body_text': fields.text('Plain-text editor body'), + 'body_text': fields.text('Plain-text Contents'), 'content_subtype': fields.char('Message content subtype', size=32, readonly=1, help="Type of message, usually 'html' or 'plain', used to select "\ "plain-text or rich-text contents accordingly"), @@ -269,7 +269,7 @@ class mail_compose_message(osv.TransientModel): post_values['attachments'] += new_attachments post_values.update(email_dict) # post the message - active_model_pool.message_post(cr, uid, [res_id], msg_type='comment', context=context, **post_values) + active_model_pool.message_post(cr, uid, [res_id], type='comment', context=context, **post_values) return {'type': 'ir.actions.act_window_close'} diff --git a/addons/mail/wizard/mail_compose_message_view.xml b/addons/mail/wizard/mail_compose_message_view.xml index 4ce5db3f4e3..70b50c154ac 100644 --- a/addons/mail/wizard/mail_compose_message_view.xml +++ b/addons/mail/wizard/mail_compose_message_view.xml @@ -6,34 +6,43 @@ mail.compose.message + + + + + - - - - - - - + + - + - + +
-
- mail.compose.message.form + mail.compose.message.form.chatter mail.compose.message 18 diff --git a/addons/marketing_campaign/marketing_campaign_demo.xml b/addons/marketing_campaign/marketing_campaign_demo.xml index 0c2d7f32715..92443fe987d 100644 --- a/addons/marketing_campaign/marketing_campaign_demo.xml +++ b/addons/marketing_campaign/marketing_campaign_demo.xml @@ -3,29 +3,29 @@ - Template for New Partner + welcome new partner info@openerp.com - Welcome in OpenERP Partner Channel! + Welcome to the OpenERP Partner Channel! ${object.email or ''} - Hello, We are very happy to send Welcome message. + Hello, you will receive your welcome pack via email shortly. - Template for Silver Partner + congrats silver partner info@openerp.com - Congratulation! You become now our Silver Partner. + Congratulations! You are now a Silver Partner! ${object.email or ''} - Hello, We are happy to announce that you now become our Silver Partner. + Hi, we are delighted to welcome you among our Silver Partners as of today! - Template for Gold Partner + congrats gold partner info@openerp.com - Congratulation! You become our Gold Partner. + Congratulations! You are now one of our Gold Partners! ${object.email or ''} - Hello, We are happy to announce that you become our Gold Partner. + Hi, we are delighted to let you know that you have entered the select circle of our Gold Partners diff --git a/addons/marketing_campaign_crm_demo/marketing_campaign_demo.xml b/addons/marketing_campaign_crm_demo/marketing_campaign_demo.xml index 6545dd93cb2..141981a21d6 100644 --- a/addons/marketing_campaign_crm_demo/marketing_campaign_demo.xml +++ b/addons/marketing_campaign_crm_demo/marketing_campaign_demo.xml @@ -40,7 +40,10 @@ - Hello,Thanks for generous interest you have shown in the openERP.Regards,OpenERP Team, + Hello,

+

Thanks for the genuine interest you have shown in OpenERP.

+

If any further information is required, do not hesitate to reply to this message.

+

Regards,OpenERP Team,

]]>
For OpenERP OnDemand Free Trial 2010
@@ -50,11 +53,11 @@ - Hello,We have very good offer that might suit you. - We propose you to subscribe to the OpenERP Discovery Day on May 2010. - If any further information required kindly revert back. - We really appreciate your co-operation on this. - Regards,OpenERP Team, + Hello,

+

We have very good offer that might suit you. + We suggest you subscribe to the OpenERP Discovery Day on May 2010.

+

If any further information is required, do not hesitate to reply to this message.

+

Regards,OpenERP Team,

]]>
For OpenERP Discovery Day on May 2010
@@ -65,10 +68,10 @@ - Hello,Thanks for showing intrest and for subscribing to the OpenERP Discovery Day. - If any further information required kindly revert back. - I really appreciate your co-operation on this. - Regards,OpenERP Team, + Hello,

+

Thanks for showing interest and for subscribing to the OpenERP Discovery Day.

+

If any further information is required, do not hesitate to reply to this message.

+

Regards,OpenERP Team,

]]>
For OpenERP Discovery Day @@ -79,10 +82,10 @@ - Hello,Thanks for showing intrest and buying the OpenERP book. + Hello,

+

Thanks for showing interest and buying the OpenERP book.

If any further information required kindly revert back. - I really appreciate your co-operation on this. - Regards,OpenERP Team,
+

Regards,OpenERP Team,

]]>
For OpenERP book @@ -92,12 +95,12 @@ - Hello, We have very good offer that might suit you. - For our gold partners,We are arranging free technical training on june,2010. - If any further information required kindly revert back. - I really appreciate your co-operation on this. - Regards,OpenERP Team, - For technical training to Gold partners + Hello,

+

We have very good offer that might suit you. + For our gold partners,We are arranging free technical training on june,2010.

+

If any further information is required, do not hesitate to reply to this message.

+

Regards,OpenERP Team,

]]>
+ technical training to gold partners @@ -107,12 +110,12 @@ - Hello, We have very good offer that might suit you. - For our silver partners,We are paid technical training on june,2010. - If any further information required kindly revert back. - I really appreciate your co-operation on this. - Regards,OpenERP Team, - For training to Silver partners + Hello,

+

We have very good offer that might suit you. + For our silver partners,We are paid technical training on june,2010.

+

If any further information is required, do not hesitate to reply to this message.

+

Regards,OpenERP Team,

]]>
+ training to silver partners
@@ -122,12 +125,12 @@ - Hello, We have very good offer that might suit you. - For our silver partners,We are offering Gold partnership. - If any further information required kindly revert back. - I really appreciate your co-operation on this. - Regards,OpenERP Team, - For gold partnership to silver partners + Hello,

+

We have very good offer that might suit you. + For our silver partners, we are offering Gold partnership.

+

If any further information is required, do not hesitate to reply to this message.

+

Regards,OpenERP Team,

]]>
+ gold partnership to silver partners
@@ -137,9 +140,12 @@ - Hello, Thanks for showing intrest and for subscribing to technical training.If any further information required kindly revert back.I really appreciate your co-operation on this. - Regards,OpenERP Team, - For subscribing to technical training + Hello,

+

Thanks for showing interest and for subscribing to technical training.

+ If any further information required kindly revert back.I really appreciate your co-operation on this.

+

If any further information is required, do not hesitate to reply to this message.

+

Regards,OpenERP Team,

]]>
+ subscribing to technical training
diff --git a/addons/portal/wizard/portal_wizard.py b/addons/portal/wizard/portal_wizard.py index 0260ce338fc..85f6566eba6 100644 --- a/addons/portal/wizard/portal_wizard.py +++ b/addons/portal/wizard/portal_wizard.py @@ -171,7 +171,7 @@ class wizard(osv.osv_memory): 'url': wiz.portal_id.url or _("(missing url)"), 'db': cr.dbname, } - mail_message_obj = self.pool.get('mail.message') + mail_mail_obj = self.pool.get('mail.mail') dest_uids = user_obj.search(cr, ROOT_UID, login_cond) dest_users = user_obj.browse(cr, ROOT_UID, dest_uids) for dest_user in dest_users: @@ -184,10 +184,12 @@ class wizard(osv.osv_memory): email_to = dest_user.email subject = _(WELCOME_EMAIL_SUBJECT) % data body = _(WELCOME_EMAIL_BODY) % data - res = mail_message_obj.schedule_with_attach(cr, uid, email_from , [email_to], subject, body, context=context) - if not res: - _logger.warning( - 'Failed to send email from %s to %s', email_from, email_to) + mail_id = mail_mail_obj.create(cr, uid, { + 'email_from': email_from , + 'email_to': email_to, + 'subject': subject, + 'state': 'outgoing', + 'body_html': '
%s
' % body}, context=context) return {'type': 'ir.actions.act_window_close'} diff --git a/addons/project_issue/project_issue.py b/addons/project_issue/project_issue.py index 9cc97ec470b..22384a12a10 100644 --- a/addons/project_issue/project_issue.py +++ b/addons/project_issue/project_issue.py @@ -363,7 +363,6 @@ class project_issue(base_stage, osv.osv): return super(project_issue, self).write(cr, uid, ids, vals, context) def onchange_task_id(self, cr, uid, ids, task_id, context=None): - result = {} if not task_id: return {'value':{}} task = self.pool.get('project.task').browse(cr, uid, task_id, context=context) diff --git a/addons/purchase/edi/purchase_order_action_data.xml b/addons/purchase/edi/purchase_order_action_data.xml index 95e6adda3d9..daad4467929 100644 --- a/addons/purchase/edi/purchase_order_action_data.xml +++ b/addons/purchase/edi/purchase_order_action_data.xml @@ -108,51 +108,6 @@ ]]>
- - % endif - | Your contact: ${object.validator.name} ${object.validator.email and '<%s>'%(object.validator.email) or ''} - -You can view the ${object.state in ('draft', 'sent') and 'request for quotation' or 'order confirmation'} and download it using the following link: - ${ctx.get('edi_web_url_view') or 'n/a'} - -If you have any question, do not hesitate to contact us. - -Thank you! - - --- -${object.validator.name} ${object.validator.email and '<%s>'%(object.validator.email) or ''} -${object.company_id.name} -% if object.company_id.street: -${object.company_id.street or ''} -% endif -% if object.company_id.street2: -${object.company_id.street2} -% endif -% if object.company_id.city or object.company_id.zip: -${object.company_id.zip or ''} ${object.company_id.city or ''} -% endif -% if object.company_id.country_id: -${object.company_id.state_id and ('%s, ' % object.company_id.state_id.name) or ''} ${object.company_id.country_id.name or ''} -% endif -% if object.company_id.phone: -Phone: ${object.company_id.phone} -% endif -% if object.company_id.website: -${object.company_id.website or ''} -% endif - ]]> diff --git a/addons/sale/edi/sale_order_action_data.xml b/addons/sale/edi/sale_order_action_data.xml index 478f0b17a8c..49ebe6053e6 100644 --- a/addons/sale/edi/sale_order_action_data.xml +++ b/addons/sale/edi/sale_order_action_data.xml @@ -126,67 +126,6 @@ ]]>
- - % endif - | Your contact: ${object.user_id.name} ${object.user_id.email and '<%s>'%(object.user_id.email) or ''} - -You can view the ${object.state in ('draft', 'sent') and 'quotation' or 'order confirmation'}, download it and even pay online using the following link: - ${ctx.get('edi_web_url_view') or 'n/a'} - -% if object.order_policy in ('prepaid','manual') and object.company_id.paypal_account and object.state not in ('draft', 'sent'): -<% -comp_name = quote(object.company_id.name) -order_name = quote(object.name) -paypal_account = quote(object.company_id.paypal_account) -order_amount = quote(str(object.amount_total)) -cur_name = quote(object.pricelist_id.currency_id.name) -paypal_url = "https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=%s&item_name=%s%%20Order%%20%s&invoice=%s&amount=%s" \ - "¤cy_code=%s&button_subtype=services&no_note=1&bn=OpenERP_Order_PayNow_%s" % \ - (paypal_account,comp_name,order_name,order_name,order_amount,cur_name,cur_name) -%> -It is also possible to directly pay with Paypal: - ${paypal_url} -% endif - -If you have any question, do not hesitate to contact us. - - -Thank you for choosing ${object.company_id.name}! - - --- -${object.user_id.name} ${object.user_id.email and '<%s>'%(object.user_id.email) or ''} -${object.company_id.name} -% if object.company_id.street: -${object.company_id.street or ''} -% endif -% if object.company_id.street2: -${object.company_id.street2} -% endif -% if object.company_id.city or object.company_id.zip: -${object.company_id.zip or ''} ${object.company_id.city or ''} -% endif -% if object.company_id.country_id: -${object.company_id.state_id and ('%s, ' % object.company_id.state_id.name) or ''} ${object.company_id.country_id.name or ''} -% endif -% if object.company_id.phone: -Phone: ${object.company_id.phone} -% endif -% if object.company_id.website: -${object.company_id.website or ''} -% endif - ]]> diff --git a/addons/share/wizard/share_wizard.py b/addons/share/wizard/share_wizard.py index a0489c9c017..375c33b1e8c 100644 --- a/addons/share/wizard/share_wizard.py +++ b/addons/share/wizard/share_wizard.py @@ -775,8 +775,8 @@ class share_wizard(osv.TransientModel): if res_id <= 0: raise osv.except_osv(_('Record id not found'), _('The share engine has not been able to fetch a record_id for your invitation.')) self.pool.get(model.model).message_subscribe(cr, uid, [res_id], new_ids + existing_ids, context=context) - self.send_invite_email(cr, uid, wizard_data, context=context) - self.send_invite_note(cr, uid, model.model, res_id, wizard_data, context=context) + # self.send_invite_email(cr, uid, wizard_data, context=context) + # self.send_invite_note(cr, uid, model.model, res_id, wizard_data, context=context) # CLOSE # A. Not invite: as before @@ -820,9 +820,10 @@ class share_wizard(osv.TransientModel): elif tmp_idx == len(wizard_data.result_line_ids)-2: body += ' and' body += '.' - return self.pool.get(model_name).message_post(cr, uid, [res_id], _('System Notification'), body, context=context) + return self.pool.get(model_name).message_post(cr, uid, [res_id], body=body, context=context) def send_invite_email(self, cr, uid, wizard_data, context=None): + # TDE Note: not updated because will disappear message_obj = self.pool.get('mail.message') notification_obj = self.pool.get('mail.notification') user = self.pool.get('res.users').browse(cr, UID_ROOT, uid) @@ -855,13 +856,13 @@ class share_wizard(osv.TransientModel): def send_emails(self, cr, uid, wizard_data, context=None): _logger.info('Sending share notifications by email...') - mail_message = self.pool.get('mail.message') + mail_mail = self.pool.get('mail.mail') user = self.pool.get('res.users').browse(cr, UID_ROOT, uid) if not user.email: raise osv.except_osv(_('Email required'), _('The current user must have an email address configured in User Preferences to be able to send outgoing emails.')) # TODO: also send an HTML version of this mail - msg_ids = [] + mail_ids = [] for result_line in wizard_data.result_line_ids: email_to = result_line.user_id.email if not email_to: @@ -884,10 +885,14 @@ class share_wizard(osv.TransientModel): body += "--\n" body += _("OpenERP is a powerful and user-friendly suite of Business Applications (CRM, Sales, HR, etc.)\n" "It is open source and can be found on http://www.openerp.com.") - msg_ids.append(mail_message.schedule_with_attach(cr, uid, user.email, [email_to], subject, body, model='share.wizard', context=context)) + mail_ids.append(mail_mail.create(cr, uid, { + 'email_from': user.email, + 'email_to': email_to, + 'subject': subject, + 'body_html': '
%s
' % body}, context=context)) # force direct delivery, as users expect instant notification - mail_message.send(cr, uid, msg_ids, context=context) - _logger.info('%d share notification(s) sent.', len(msg_ids)) + mail_mail.send(cr, uid, mail_ids, context=context) + _logger.info('%d share notification(s) sent.', len(mail_ids)) def onchange_embed_options(self, cr, uid, ids, opt_title, opt_search, context=None): wizard = self.browse(cr, uid, ids[0], context) diff --git a/addons/survey/wizard/survey_answer.py b/addons/survey/wizard/survey_answer.py index 66098b45fa8..e2216ea8389 100644 --- a/addons/survey/wizard/survey_answer.py +++ b/addons/survey/wizard/survey_answer.py @@ -420,7 +420,17 @@ class survey_question_wiz(osv.osv_memory): if user_email and resp_email: user_name = user_obj.browse(cr, uid, uid, context=context).name mail = "Hello " + survey_data.responsible_id.name + ",\n\n " + str(user_name) + " has given the Response Of " + survey_data.title + " Survey.\nThe Response has been attached herewith.\n\n Thanks." - mail_message.schedule_with_attach(cr, uid, user_email, [resp_email], "Survey Answer Of " + str(user_name) , mail, attachments=attachments, context=context) + vals = {'state': 'outgoing', + 'subject': "Survey Answer Of " + user_name, + 'body_html': '
%s
' % mail, + 'email_to': [resp_email], + 'email_from': user_email} + if attachments: + vals['attachment_ids'] = [(0,0,{'name': a_name, + 'datas_fname': a_name, + 'datas': str(a_content).encode('base64')}) + for a_name, a_content in attachments] + self.pool.get('mail.mail').create(cr, uid, vals, context=context) xml_form = etree.Element('form', {'string': _('Complete Survey Answer')}) etree.SubElement(xml_form, 'separator', {'string': 'Complete Survey', 'colspan': "4"}) diff --git a/addons/survey/wizard/survey_send_invitation.py b/addons/survey/wizard/survey_send_invitation.py index da439959ec5..5677a985e09 100644 --- a/addons/survey/wizard/survey_send_invitation.py +++ b/addons/survey/wizard/survey_send_invitation.py @@ -116,7 +116,6 @@ class survey_send_invitation(osv.osv_memory): existing = "" created = "" error = "" - user_exists = False new_user = [] attachments = {} current_sur = survey_ref.browse(cr, uid, context.get('active_id'), context=context) @@ -150,8 +149,14 @@ class survey_send_invitation(osv.osv_memory): mail = record['mail']%{'login':partner.email, 'passwd':user.password, \ 'name' : partner.name} if record['send_mail_existing']: - mail_message.schedule_with_attach(cr, uid, record['mail_from'], [partner.email] , \ - record['mail_subject_existing'] , mail, context=context) + vals = { + 'state': 'outgoing', + 'subject': record['mail_subject_existing'], + 'body_html': '
%s
' % mail, + 'email_to': partner.email, + 'email_from': record['mail_from'], + } + self.pool.get('mail.mail').create(cr, uid, vals, context=context) existing+= "- %s (Login: %s, Password: %s)\n" % (user.name, partner.email, \ user.password) continue @@ -160,8 +165,19 @@ class survey_send_invitation(osv.osv_memory): out+= partner.email + ',' + passwd + '\n' mail= record['mail'] % {'login' : partner.email, 'passwd' : passwd, 'name' : partner.name} if record['send_mail']: - ans = mail_message.schedule_with_attach(cr, uid, record['mail_from'], [partner.email], \ - record['mail_subject'], mail, attachments=attachments, context=context) + vals = { + 'state': 'outgoing', + 'subject': record['mail_subject'], + 'body_html': '
%s
' % mail, + 'email_to': partner.email, + 'email_from': record['mail_from'], + } + if attachments: + vals['attachment_ids'] = [(0,0,{'name': a_name, + 'datas_fname': a_name, + 'datas': str(a_content).encode('base64')}) + for a_name, a_content in attachments] + ans = self.pool.get('mail.mail').create(cr, uid, vals, context=context) if ans: res_data = {'name': partner.name or _('Unknown'), 'login': partner.email,