The purpose is to have more common code for failure and notifications, with less
override in `sms` and `snailmail`.
task-2176017
closesodoo/odoo#44170
Related: odoo/enterprise#9140
Related: odoo/upgrade#918
Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
TL;DR: remember `osv` and `except_orm` ? You can forget about them.
* Deprecated `except_orm` dropped.
* `UserError` elevated as super type of all user-related
errors.
* Unused `DeferredException` dropped.
* Unused `QWebException` dropped (real one is in `qweb.py`).
* `MailDeliveryException` made a python exception.
* `name` legacy exception attribute made an alias of the python standard
`args[0]` attribute and deprecated.
* `value` legacy exception attribute dropped.
* `exception_type` RPC error response key dropped.
* Deprecated `osv` module dropped.
* `--osv-memory-age-limit` cli option made an alias of
`--transient-age-limit` and deprecated.
The `odoo.exceptions.Warning` have long been a deprecated alias to
`UserError`. It is going to be removed in a future version but first we
explicitly deprecate it with a warning.
The `odoo.exceptions.DeferredException` was a very old internal
exception, it has been removed without deprecation notice as it is never
raised.
The `odoo.exceptions.except_orm` has been a deprecated exception type
with deprecation warning for 5 years, it has been removed in favor of
UserError which becomes the super class of all user-related errors.
The `odoo.base.models.ir_mail_server.MailDeliveryException` was
inheriting `except_orm`. As it is not related to a user error but is
more of a problem an admin much take care of, the exception has been
made a Python error.
The `exception_type` JSON key in RPC error responses was holding an
hardcoded value derived from the exception type. Its usage has been
dropped in favor of the `name` JSON key that holds the precise exception
name. Again as it was hardly used in the source code (beside the crash
manager) it has been dropped without deprecation warning.
Since we are here trying to clean odoo custom exceptions, we are also
deprecating the `name` exception attribute in favor of the more standard
`args[0]` attribute.
The `name` (along with `value`) were two attributes used to raise
`except_orm` exceptions before the introduction of `UserError`,
`AccessError` and related exceptions. The `name` attribute, at the time,
was holding the exception type/title. Nowadays it contains the error
message. The `value` attribute, at the time, was holding the error
message. Nowadays it is no more used.
The `osv` module contains very old deprecated aliases. There is no
simple way to log a deprecation warning for osv, osv_memory and
osv_abstract but as they have not been in use for ages, they have been
removed too. To be consistent, the `--osv-memory-age-limit` cli option
has been made a deprecated alias to the `--transient-age-limit`.
closesodoo/odoo#45723
Task: 2187728
Related: odoo/enterprise#9162
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
Currently the message for help tooltip of auto_delete field is not sufficiently
clear for user to understand.
In this commit, improving message for help tooltip by adding some extra details
in it so user can easily understand about it for models mail.mail, mail.template
and wizard mail_compose_message.
Task-2055702
Closes https://github.com/odoo/odoo/pull/45063closesodoo/odoo#45063
Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
When simply need to parse a domain, it is easier
Add .strip() on ir.ui.view as ast.literal_eval produces an syntax
error if the node starts with spaces (as done in the xpath of
hr_attendance.view_employee_form_inherit_hr_attendance)
closesodoo/odoo#43831
Related: odoo/enterprise#7894
Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
Purpose is to prepare future cleanups and speed improvements. In this commit
we use create multi on mail.mail, allowing to batch their creation when
necessary.
Task ID 1853147
PR #39272
In some cases you may have a void attachment (datas being False) that you
try to send through the mail.mail send flow and this make crash the send
process. This commit fixes that behavior by filtering void attachments.
closesodoo/odoo#38098
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
[PEP 594] is going to depreciate the legacy `email.message.Message` API
and its related modules. Among them the `email.utils.formataddr`
function, this function takes a `(name, email)` pair and returns a
string value suitable for From, To and Cc headers.
The stdlib function is capable of handling several character encoding
and two binary-to-ascii encoding. Odoo only uses `utf-8` which is
compatible with the base64 b2a encoding. The re-implementation of that
function has been simplified to only support base64-ed utf-8 and ascii.
[PEP 594]: https://www.python.org/dev/peps/pep-0594/\#email-lagacy-api
This branch is the combination of several optimizations in the ORM:
* store field values once in the cache: the cache reflects more
faithfully the database, only fields that explicitly depend on the
context have an extra indirection in the cache;
* delay recomputations by default: use method `recompute` to explicitly
flush out pending recomputations;
* delay updates in method `write`: updates are stored in a data
structure that can be flushed efficiently to the database with method
`flush` (which also flush out recomputations);
* make method `modified` take advantage of inverse fields to inverse
dependencies;
* filter records by evaluating a domain on records in Python;
* a computed field with `readonly=False` behaves like a normal field
with an onchange method;
* computed fields are computed in superuser mode by default.
Work done by Toufik Ben Jaa, Raphael Collet, Denis Ledoux and Fabien
Pinckaers.
closesodoo/odoo#35659
Signed-off-by: Denis Ledoux <beledouxdenis@users.noreply.github.com>
Multi is the default api for methods, it is not necessary to explicitly
decorate methods with it, adds clutter and most people use it because
they see that the rest of the code uses it.
Done with `find . -type f -name '*.py' | xargs sed -i '/@api.multi/d'`
This commit prepares SMS refactoring by updating some mail models. Purpose
is to be able to store SMS notification information inside existing mail
flow and models.
Main changes
* mail.notification: define a notification_type field to store the medium
used to notify people. In mail two ways exist: inbox and email. It will
ease introduction of SMS notification mechanism. This field replaces the
is_email boolean field;
* mail.notification: make res_partner_id field not required. This means
notifications could be linked to something else than a partner. An SMS
for example. For Inbox and email notifications partner is still required
and a constraint is added accordingly;
* mail.thread: let notification methods handle the creation and update of
their notification instead of creating them in _notify_thread and tweaking
them in sub notification methods;
* mail.thread: clearly move inbox-style notification in its own method like
notify by email;
Some lighter code changes
* propagate message_type to notification recipient computation. It will
allow for example to be more precise when computing a notification type
depending on the message_type. For example, send a notification by SMS
when the message_type is SMS;
* ease inheritance of ``_notify_thread`` by returning computed recipients
data. It will allow to work on it without having to re-compute it;
* propagate kwargs from message_post and message_notify to notify methods.
This allow to avoid depending on context and set explicit parameters.
Drawback is that message_post and notify must separate kwargs used to
create a message and those that are propagated to notification methods;
* update various notification check to ensure they work on email
notifications, notably the resend and cancel wizards;
One side effect of this commit is that notifications are created by the
relevant notification method. Previously all notifications were created
by writing on needaction_partner_ids fields then updated according to the
notification process. Notably there could be too much notification created
when sending emails due to _notify_customize_recipients not being correctly
synchronized with notification. This issue is now solved as only really
sent emails create notifications.
Migration tips
* notification_type: notification.is_email and 'email' else 'inbox';
* remove is_email;
Related to task 1922163
Linked to PR #33510
When sending a message (e.g. in a CRM lead or SO),
a failure_type and failure_reason are displayed, even when the message
is successfully sent.
This is because these fields are not updated when the email_status
is changed to "sent". We reset these fields to '' when the message is sent.
OPW-2003290
closesodoo/odoo#34082
Signed-off-by: Nans Lefebvre (len) <len@odoo.com>
This commit removes the field `datas_fname` from `ir.attachment` as
it was unnecessary and most of the time the duplicate of `name` or
`url`.
Task #1909865closesodoo/odoo#32976
Signed-off-by: Martin Geubelle (mge) <mge@openerp.com>
Currently if a message has a res_id and a res_model it appears in the
matching record's chatter. Its access rights are computed based on this
record. This is the standard behavior of mail.message model.
User notifications are currently built on messages not having model and
res_id in order to avoid appearing on chatter. This has several drawbacks
notably access rights, redirection to the record, systray, finding back
records, ...
This commit solves those issues by adding new message_type 'user_notification'
that should be as a classic mail.message with model and res_id but without
the whole notification mechanism and without being displayed in the chatter.
An user notification is now a classic message pushed to a given partner only
and not displayed in the chatter.
Related to task 1943901
Linked to PR #32404
If the smtp session was dead, it would lead the whole mail batch to fail.
opw 1949270
closesodoo/odoo#32424
Signed-off-by: Olivier Dony (odo) <odo@openerp.com>
When we go on a failed mail.mail and do "Retry" -> "Send Now", if there
is an existing notification that is not to the current user, we may get
an error or get the email in error.
This is because on a notification only:
- the superuser
- the targetted user of the notification
have write permission by default in Odoo.
So with existing notifications resending (by the mail.mail views, the
alternative mail.resend.message wizard works as expected) only worked
if they were current user's notifications or if user is superuser.
opw-1957730
closes#32346
Signed-off-by: Nicolas Lempereur (nle) <nle@odoo.com>
This is related to revision
71f188082f
This is nice to have a meaningful explanation
for the user to understand why his mail is not sent,
this is better to not interrupt the mail queue when doing so.
Because of the above revision,
when the mail queue iterated on a mail failing because
of an ASCII encoding issue,
the mail queue was interrupted,
and on the next cron call it failed again and again
on the same mail, therefore leading to the mail queue
to never be processed.
Fixes#27804
The CRON job that sends email sends them in a LIFO order instead
of a FIFO order which can lead to confusion when the order is
important.
Exemple, when updating multiple time an appointement, the last
update should be the newest mail clients receive in their mail box
which was not the case before this PR.
opw-1888601
closesodoo/odoo#27888
When sending notifications by batch one notification email can be send
up to 50 people. For one mail_mail entry to handle 50 emails can be sent
as those are sent independently for each recipient.
In some cases a bounce may occur while the whole batch of recipients is
not completely mailed. In that case the mailgateway will update the
notification status to bounced. When the cron finishes to send the whole
batch of emails it tries to update the notifications of all recipients.
However as a notification has already been updated due to the bounce we
face a concurrent update, meaning the transaction is rollbacked.
Emails have been sent but notifications are not considered as sent as they
have not been updated accordingly. Next time the cron runs it will send the
same batch again, with probably the same bounce and rollback. We could
therefore face an email loop.
This commit fixes that by setting notifications to a transient exception
state. Notifications are locked, meaning bounced will have to wait for the
transaction to finish before updating them. That way the cron can run
safely on the whole batch and we avoid having emails loop. It has an impact
on query count as a search and write is performed in the send process.
This commit is linked to task ID 1893054. Done in collaboration with
@Xavier-Do .
Sending email to addresses containing unicode characters
cannot be parsed by python and result in a UnicodeEncodeError.
This PR catch that specific exception and output a meaningful
error message.
Decision has been taken to not trigger any error message
client-side has it would have needed modifications on some
sensitive low-level backend code.
To reproduce:
- Configure odoo so it uses an email server
- Send an invoice to a partner whoose email address contains
some unicode characters (exemple: æøåÇÀ@example.com)
opw-1892409
closesodoo/odoo#27804
The default value for failure_type was the 'NONE', instead of being
simply False/NULL. This represents a significant waste of tablespace
with no added value.
Switching to true NULL value for representing the absence of error
also save some precious time during database upgrades on databases with
large numbers of emails.
While fixing the values for failure_type, also fixed a few typos and
untranslated strings.
See original feature at 133eeb1bbf
If the user send an email with a '/web/content' or /web/image' link in
the body, the attachment are not send by email to not to increase the
size of the email unnecessarily.
If the parameter ids is given to the process_mail_queue method, it is supposed
to only process the ids it was given, not all mails.
Commit https://github.com/odoo/odoo/commit/4b122ad41d873febe288ab1f8c6cdc078ca2a479
replaced ids by self.ids, and thus default filter was always applied.
fix suggested by @suganthikarunanithi, Sodexis team
opw 1860484
When a mail is in failure state, a red envelope appears next to the message
in a thread but it was difficult to send the mail again.
This tasks will allow users to send mail again easily, or mark notification
as cancelled if the user want to ignore this failure.
A notification will appear in sender systray while mail are in failure.
Task: #46158
PR: #24628
Purpose is to lessen query count by avoiding to browse and/or fetch data when
not necessary. This commit does two main things
* first one is to avoid checking for existing statistics in mass_mailing
where only checking existing of a mass_mailing on a mail to send is
sufficient. It allows to avoid fetching data from statistics table;
* second one is to rewrite part of the post_process code called after sending
emails. Using list comprehension and mailing_id existence on mail_mail
allows to save several queries on standard post flows;
Most tests benefit from this code update. On overall community runbot about
3K queries are saved with those small optimizations.
Send methods of mail.mail model are set private and simplified. Those
methods have been written when a lot of overrides were necessary to
generate notification emails. Since then the flow has changed but
methods have not been updated completely. This commit therefore simplified
a bit the call chain and parameters.
This commit is purely technical and does not hold any functional change.
Purpose is to clean code in order to prepare future changes in mail
application.
Commit 0d3d0e9563 added a key in context when sending emails to know
the target model name. It was used at that time to forge for footer of
notification emails.
Since that time notification emails have evolved a lot. The code based on
that context key has been removed. Context key has been transformed into a
context switch. However it is not used anymore and can be removed. It allows
to clean a bit the code and save a context switch.
This commit is purely technical and does not hold any functional change.
Purpose is to clean code in order to prepare future changes in mail
application.
This commit allows to gain some queries in mail sending process, meaning
removing context switch is interesting. One query is gained when using
the send process. Complex performance test involving several message post
gain 3 queries each.
Purpose
* move notify in message_post instead of always doing it at message
creation
Specifications
* message create should only create a message
* message post should be in charge of calling the notification process
Now that we're closer to switching to P3 for good, these helpers have
outlived their usefulness, and mostly add noise.
All remaining dict.iter*() or dict.view*() must be converted to the
normal keys(), values() or items() calls.
Whenever the result is likely to be used for more than the scope of a
loop, or when the dict needs to be modified during iteration, the calls
must be wrapped in a ``list()``, to protect the new P3 semantics.
Those cases are very exceptional.
Also removed some dead code or improved the API to remove unnecessary
conversions.
No formal decision there, and the stdlib API seems like a PITA as it's
based around native strings, not bytes and not text.
* try to use cross-model API instead of random encode/decode
* unicode all the mail_template things
* formataddr *requires* a text tuple now
In P2, formataddr((False, False)) "worked" (generated "False
<False>"), in P3 it will fail and blow up.
* attachments are quite definitely bytes
* remove try_coerce_ascii because it's garbage
* cross-version metaclass spec
* more formally deprecate browse_record and browse_null since they
were using metaclasses anyway
* update docstrings referencing the latter
In Python 3:
* various builtins and dict methods were changed to return
view/iterable objects rather than lists
* and the separate Python 2 view/iterable builtins and methods were
removed altogether
This is problematic when using these items as list (which the happens
repeatedly in Odoo), but more viciously when iterating *multiple times*
over them (which also happens, which I've messed up multiple times while
writing this, and which is a pain to debug even when you've just created
the issue).
Convert all code using these to semantics-matching cross-version
helper functions to get the LCD behaviour between P2 and P3, and
forbid the builtins via lint.
issue #8530
With this commit, the mimetype will be sent with the attachment.
That will allow some Mail Client (e.g. thunderbird) to 'understand' the
purpose of the attachemnt.
E.g. when you sent a text/calendar mimetype, thunderbird propose you to add
automatically the event into your calendar.
The mass-mailing App suffered from severe issues due to its inability
to detect and handle duplicates "at the email level", and the absence
of any global blacklist system, leading to lack of user trust.
Mailing-lists typically include multiple records with the same email,
and it is critical to avoid sending them the same email several times.
A related problem is the unsubscription of an email that is present
in other records (duplicates). Opting out the first email should
automatically blacklist it for other records as well.
Ideally we should have a global blacklist table in order to
share the unsubscription requests globally across models (Leads,
Partners, Mailing-list contacts). It would also allow importing
it from other blacklist systems. (TODO for master)
This commit introduces a partial solution, made of several
small changes:
- In mail.mail: double-check that an outgoing email has the
correct status (`outgoing`) before sending it. This allows
adding emails in the queue and cancelling them before they
actually get sent.
- In crm.lead: force predictable recipients for mass-mailing,
by always using the email of the lead rather than the email
of the linked partner when there is one. This simplifies the
computation of the blacklist and seen list. Other areas in
the codebase already assume as much.
- In mass.mailing:
+ Before sending out a mailing-list batch, compute the
blacklist (all opted-out emails) and the seen_list
(emails who previously received this mail) to make
sure we only ever target valid recipients.
+ While delivering the mass-mailing, any email targeting
an address that is in the blacklist or "seen list" is
canceled before being sent. The corresponding statistics
entry is considered "not delivered".
Also updates the "seen list" continuously.
+ When a mass-mail belongs to a campaign with the
"unique AB/B testing" flag, the "seen list" is
common to the whole campaign, as an extra safety.
+ Auto-delete mass-mailing test messages sent with the
test wizard, to avoid polluting the mail_mail table
Note: this fix uses a simple regex for efficiently extracting
the blacklist in pure SQL from different models, and doing so,
assumes that each record only holds a single email
(no comma-separated adresses). This should be sufficient for
most cases. The regex:
([^ ,;<@]+@[^> ,;]+)
Commit 00bd7274c4 introduced speed improvements when
sending emails through batching and reusing an SMTP connection for a
given batch.
However exception management was slightly changed during that patch.
Previously to this patch all errors in the sending process were considered
as MailDeliveryException, except for MemoryError and psycopg errors.
However now mail_mail.send() may raise another kind of exception in the
SMTP connect process. Moreover a raise_exception parameter allows to
choose to either raise an exception, or just set emails in exception
state without raising an error. However since the patch it is not taken
into account correctly.
This leads to several issues, notably
* auth_signup waits for a MailDeliveryException when sending a password
request email. A badly configured SMTP server leads to a connection
error that is not caught. This prevents creating users, which could
be annoying.
* chatter does not handle exceptions as notification emails are sent
using raise_exception being False. Having an issue in the connect
process crashes the chatter.
This commit fixes the exception management so that it behaves like
before the patch.