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>
Since #32404, the fallback case where we have no recipients and no parent_id
on message notify has a typo on mail_message. A user will receive a traceback
when using compose message wizard on a record not inheriting from mail_thread if
he forgot to add recipients.
If the typo should be fixed, notifying the user that no recipients were found and thus,
message_notify won't do anything could be interresting. We can raise a UserError
to give a more explicit failure reason.
We would like to avoid to raise this error on a low level like in message_notify
to avoid to break mail_gateway mechanism, but raising it from mail.compose.message
send_mail shouldn't have any side effect.
We can simply check the output of message_notify to know if something was done
to avoid to duplicate logic used to define recipients.
task-2046180
closesodoo/odoo#35378
Signed-off-by: Xavier Dollé (xdo) <xdo@odoo.com>
PURPOSE
Add some improvements in mail gateway: remove private discussion, improve
bounce management, allow resetting bounce counters, improve automatic set or
reset of blacklists and ease mass mailing inheritance.
SPECIFICATIONS
Private discussion support in mail gateway means having incoming messages
not linked to a document. It means having a void model and res_id on related
messages.
Old private conversations in Odoo were implemented using messages not linked
to any document [1]. It was possible to send an email to some people through
the UX and they were able to answer it. Messages were not attached to any
document and model. There were some limitations to this feature, notably it was
limited to replies (no beginning of private discussion through mail gateway).
One way of doing it was through the use of res.users aliases [2]. There was
also a vaguely twitter-lite use of chatter on HR employee profiles linked
to users aliases, then removed with an explicit support of private
discussions [3].
It is not supported anymore since discussion between users is now done using
chat. Aliases on users have since been removed [4]. Contacting partners or
customers can be done on business documents or on channels. Simple email
discussion is not supported in Odoo as it is not the purpose of mailgateway.
This commit removes code related to private discussion in mail gateway and
some specific support in message_post method.
LINKS
Related to task 1893155
Linked to PR #33340
[1] History is a bit messy, see notably fd90140d7b and commits around
[2] User alias addition 052f2ace57
[3] End of employee twitter-like and posting on users = private discussion 89896f32bb
[4] User alias removal 029d1baf35
This attribute is misleading as it is insufficient to correctly upgrade
the database. It only renames the column in the database, but other
operations are needed, like updating the corresponding `ir.model.fields`
record (and its xmlid). The default values and the translations are also
lost during the upgrade.
Moreover, this feature was misused. It was:
- left on fields during multiple versions.
- used on reports (SQL views). This would be ok if the feature was
complete, but, as is, it was useless.
- kept unchanged after a second renaming of the field (which can happen
versions later the first rename).
- used, even when the meaning of the field changed. i.e. the field
`archived` has been renamed to the classic `active`, but the value
in the database should be switched.
Create an invoice for a customer, send him an email from the chatter, in
the mail template set a specific "Reply to" and send the email. The
"Reply-To" template mail header is ignore and the one generated by
`mail_thread._notify_get_reply_to` is used.
See also 1c57d5e and 7b0806b
opw-2041640
closesodoo/odoo#35127
Signed-off-by: Julien Castiaux <Julien00859@users.noreply.github.com>
This reverts commit 7273719b88.
Reply to header of templates should be used only for mass mailing purpose.
It is a known limitation and should not be changed in table without more
in-depth testing.
closesodoo/odoo#35354
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.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>
Purpose of this commit is to improve performance of post and notify through
various code improvements.
Containing
* making of _notify_customize_recipients a mail.thread method;
* _message_auto_subscribe_followers optimized;
* renaming and optimisation of _notify_partners;
* message_post_attachements optization;
* remove unused mail_post_autofollow_partner_ids context key;
* minimize message create queries;
* only check record related access right for thread messages not in pending
moderation;
* get attachements from values instead of db;
* storing lang in ctx from the beginning;
* don't track on write on attachments;
Related to task 1943901
Linked to PR #32404
Purpose is to make field use more obvious by correctly stating in the
name it should contain an xml id to a qweb layout used for email
notifications. This renaming is propagated through various calls and
addons.
Related to task 1943901
Linked to PR #32404
Purpose of this commit is to clean notification process: calls, methods
API, method name, variable propagation.
Contains notably
* simplify API of methods used to group recipients when sending notification
emails;
* improve and rename methods used in email notification process;
* move some methods on model itself as non mail thread records could be
mass-mailed and _notify_email_headers could be called on other records;
Related to task 1943901
Linked to PR #32404
Message post should always be called on a record (ensure_one). That way we
ensure posting a message is always done in a record's context with right
values computed (reply_to, followers, ...)
Message_notify can be called on record or on mail_thread and must have
partner_ids. It is based on the recently modified user_notification mechanism
and allow to notify a partner on a record or just to push him a message
(aka, not linked to a record).
Small performance improvement
* browse recipients instead of search in _notify_email_recipients;
* todo in future optimizations: mayybe be improve by searching on ids
and is_blacklist immediately;
Related to task 1943901
Linked to PR #32404
Purpose of this commit is to clean some bits of code, notably calls to
message_post/log as well as notification methods. It will ease performance
improvement work.
Small optimization: account: read content after extension check
Parameter cleaning
* use message log with kwargs instead of args;
* remove message post after hook useless parameters;
* remove _notify_email_recipients useless message parameter;
* remove message_notify useless send_after_commit parameters;
* remove message post params matching default values;
Other improvements
* remove message_post commands support for partners and channels;
* only calls message_post with ids list for channels and partners. We
don't support mix of ids and command anymore to simplify code;
* remove support of private discussion in mail.thread adding partners
as recipients, as there is no use anymore;
Related to task 1943901
Linked to PR #32404
The stable behaviour of the mail composer is the following:
- if a template adds new attachments, the composer only has this list
- if a template doesn't add attachments, the list is unchanged
- if no template is set, the list is cleared up
In the case of templates, we also check that both static and dynamic attachments
are added to the list.
We clean up after c6d718f211 and subsequently 516f22c398 which failed to take
into account the fact that the attachement list could be a blend of commands
and ids.
Transforming that is taken care of by _convert_to_write, which semantics was
changed by c6d718f211.
To keep the second behaviour, we thus need to add a (5,) command.
opw 2003197
closesodoo/odoo#33707
Signed-off-by: Nans Lefebvre (len) <len@odoo.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'`
Some functional flows use sudo() to create records as current user is the
public user. This user has no email. Since 1e6c3bec2c using sudo does
not take superuser identity completely as it only bypasses access rights.
It means some messages are created with public user as author, meaning no
email_from.
In this commit we fix some functional flows by setting a default email_from
in the message composer only if a real email is found. Otherwise it will have
to be set either by the template, either later in the process when creating
messages or emails.
closesodoo/odoo#34742
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
This reverts commit 6230f72d2b.
Crashing when user have no valid email is the expected behavior. Flows sending
emails must ensure either current user has valid login / email, either it
uses an user OR author_id / email_from that has a meaning in the functional
flow. Notably when public user is involved. Hiding functional issues is not
what we want.
The old tree views don't really exist anymore, this odd pseudo-flag to
dispatch between "list" and "tree" tree views has no reason to remain.
Task 1937686
closesodoo/odoo#31243
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
Fine-tuning of 516f22c398.
This commit missed attachments that are linked to a mail.template,
which should be added to every mail sent using the template.
To make sure that we both fix the duplicates and the generation issue,
we add a test.
opw 2000515
opw 1998782
closesodoo/odoo#33653
Signed-off-by: Nans Lefebvre (len) <len@odoo.com>
Open a mail.compose.message wizard.
Select a template that generates an attachment.
Reselect it. A second attachment has been generated.
Can be repeated ad infinitum.
At template onchange, the template is rendered to overwrite the composers values
This includes the attachments.
Let L1 be the list of attachments generated by the template.
When _convert_to_write(values) is called with {'attachment_ids': L1},
it gets self.attachments_ids = L2, and generates a [(6, 0, L1 + L2)] command.
As a result attachments are only added,
the previous ones need to be removed manually.
Since c6d718f, the semantics of _convert_to_write changed.
Before, it always returned an empty list for new records (without an id).
In other words, wa always had L2 == [].
As a result we need to adapt the wizard to keep its old behaviour.
To solve it we bypass the _convert_to_write for 'attachment_ids' and directly
generate the 6 command with the list of ids L1 generated by the template.
We only do this for templates that add attachments to keep the templates
composable (a template only overwrites the values it defines).
Unfortunately, we don't have any way to know which attachments have been added
manually, so we can't preserve these (which was the old behaviour anyway).
opw 1997430
opw 1987169
opw 1998115
opw 1998782
closesodoo/odoo#33387
Signed-off-by: Nans Lefebvre (len) <len@odoo.com>
* mail.blacklist.mixin now clearly make inheritance on mail.thread. Indeed
we consider models using the blacklist mechanism as being used in mailing
features, meaning they will anyway inherit form mail.thread. In standard
Odoo it is the case for the 3 models using it (Lead/Opportunity, Contact
and Mailing Contact);
* define message_bounce directly in mail.blacklist.mixin. Bounce counter
is indeed linked to the blacklist and mailing mechanism;
* rename mail.blacklist.mixin to mail.thread.blacklist to ensure coherency
with mail.thread and mail.thread.cc (another mixin build on mailL.thread);
Inherit declarations in various addons are updated accordingly.
Related to task ID 1911679
Linked to PR #29483
Purpose: make some methods from mail.thread mixin private and update their
naming if necessary. Some methods prepare data for business flows and deal
with internal information. Public methods should either use of give some
access to those methods. Computation itself should be keps internal.
In this commit we put message_get_default_recipients as private. Its API
is improved to clearly separate model-inherited method (overriden in some
addons) and general tool method given by the mixin. Finally all sudo hidden
in the computation are removed. Caller now give a sudo-ed record set in order
to be more explicit. Low level method just computes the result and does not
care about sudo-ing or ACLs.
Note a model approach for this method is necessary as mass mailing using
mail.template records does not ensure records to check inherit from mail
thread.
Some addons are updated accordingly to the method change.
Related to task ID 1911679
Linked to PR #29483
Allow to specify the `model_description` when sending an email to take
into account for cases where the same model is used for different
business concepts.
opw-1915230
This commit replaces calls to pycompat helpers that were intended for
python 2 <-> python 3 interoperability for python 3 builtins, as python
2 is no longer officially supported by Odoo.
This includes:
* calls to imap/izip/ifilter replaced by map/zip/filter
* uses of text_type replaced by str
* uses of unichr replaced by chr
* calls to implements_to_string, implements_iterator removed
* string_types and integer_types replaced by str, int respectively
* calls to to_native replaced by calls to to_text
This is done in preparation to the removal of these deprecated helpers
in the following commit.
Apply the mail.address.mixin on blacklist mixin. So that every model
inheriting the blacklist.mixin will also inherit the address.mixin.
That simplify also the comparaison to - and the searches on - the
blacklist.
Task ID 1896677
Base issue: unnecessary inherit of composer on mail.message. Indeed there are
a lot of unused fields coming from mail.message as well as message specific
behavior (notify, check access, various business methods) not relevant for
composer.
Specifications
* remove inherit from mail.message;
* re-define used fields;
* ensure everything still works;
Commit linked to task ID 1907153 and PR #28464
Signed-off-by: Xavier Dollé (xdo) <xdo@odoo.com>
Until now, a recipient with a formatted email like 'John Doe
<john_doe@example.com>' could be reached by email even if its email address
was blacklisted. Now when sending a mass mail using the composer, the email
is sanitized before comparing it to blacklist entries.
This commit is related to task ID 33224 (original blacklist implementation
done for v12) and its PR #25966 as well as task ID 1889703 (tests and fixes)
and its PR #27330. Done with collaboration of @dbeguin.
Purpose
=======
Remove the method 'render_template' in mail.compose.message as the indirection
is not useful. Call the method on the correct model (mail.template) directly.
Several quick fixes:
- repair malformed SQL queries and injection problems
- proper token comparisons (consteq)
- better translatable terms (less context-lessplaceholders)
- basic testing of case-(in)sensitivity of blacklist
- safety check for non-implemented cases in search methods for computed
field
More testing and review is needed for case-sensitivity and email
extraction from generic "addressing fields".
Purpose
=======
- Apply the blacklist implementation to Improve mailing subscription to be more
compliant with the European GDPR law. Keep a list of people who does not want
to receive promotional emails (or mass mailing in general) anymore.
- Allows the recipient to update himself his mailing preferences
Specifications
===========
This commit is regrouping some main changes on mass mailing.
Apply Blacklist for following models through blacklist.mixin :
- crm.lead
- res.partner
- mail.mass_mailing.contact
- mail.channel.partner
- Opt_out per mailing list instead of per mailing contact.
- Replace opt_out by blacklist in crm.lead + res.partner models
- Added 'ignored' state for mass_mailing. Ignored = blacklisted, opted-out
Ignored email are not included into final statistics to avoid confusion.
- Unsubscribe(d) pages migrated from website_mass_mailing to mass_mailing module
as thoses pages should work without having the website module installed
Detailed implementation
===================
Mass-mailing :
- A blacklisted email is notified by the ban icon next to the email field.
(at the left of the email field for display purpose)
- Renaming the '_get_blacklist' method that was actually
searching opt_out list into 'get_opt_out_list'
- Opt out per mailing list : Add opt_out + related fields (for display and
ergonomy reasons) on the relational model
- Display relational model tree view instead of mass_mailing.contact tree
view when clicking on mass_mailing_list in kanban view
-> In order to be align between contact_nbr displayed in kanban tile and
the content of the tree view
-> mass_mailing contact is accesible via the user icon in this tree view
- Remove custom filters 'filter_contact_subscription' and
'filter_contact_unsubscription' as opt_out is not on mass_mailing.contact
model anymore
- Add 'is_public' to mailing list
The name of this mailing list can be seen (or not) by recipient in
the unsubscription page
If the mailing lists used in the mass mailing are not public,
the user in only informed that he has been unsubscribed.
If the mailing lists are public, the user is informed that he has been
unsubscribed from the mailing lists
and he has the choice to modify his subscription to all the public
mailing list he is or was subscribed to.
- Unsubscription Page :
- mass_mailing_contact :
Opt_out per mailing list, done by email and not by id, as multiple
contact can have the same email
The recipient can add/remove himself to/from the blacklist
The recipient can send a feedback about why he unsubscribed
- crm.lead + res.partner :
Once the recipient unsubscribe, he is automatically blacklisted
The recipient can 'Come back' and remove himself from the blacklist
if he changes his mind
- Show blacklist button parameter added in config :
The idea is to enable/disable the fact that the recipient can add
himself to the blacklist by showing or not the 'blacklist me' button
Only applies for mass_mailing.contact. The recipient, once
blacklisted, can always, no matter the value of this parameter,
'come back' and unblacklist himself
crm.lead + res.partner :
- Replace opt_out by blacklist in crm.lead + res.partner models.
As when a res.partner or crm.lead unsubcribe, we assume that the recipient
does not want to receive mass mailing anymore, at all, even if we adds him
to a mailing list afterwards. He is then blacklisted to avoid this.
With this behaviour, if a new lead is created with the same email address,
he won't be able to receive mail in mass_mode.
But he will still be able to receive '1 to 1' direct email.
Task ID 33224
Closes#25966
Purpose
=======
Improve mailing subscription to be more compliant with the European GDPR law.
Keep a list of people who does not want to receive promotional emails
(or mass mailing in general) anymore.
Specifications
===========
This commit is regrouping some main changes on mass mailing.
- Added blacklist : Avoid sending mass mailing to blacklisted recipient
(blacklisted = email address that doens't want to receive mass mailing anymore)
Detailed implementation
===================
Mail :
- Add Blacklist mechanism in mail module (NOT in mass-mailing) :
as we can send mass-mail without the mass-mailing module
- Unicity in email -> To avoid error in import, override the create and return
the existing record if any, else, create the record normally.
- Blacklisting is done by email address and is cross model.
Will apply to model that inherit the blacklist.mixin.
- field 'is_blacklisted' -> computed : check if email is in blacklist
+ search method to be able to filter on is_blacklisted
- When a email address is blacklisted, it will never get mass mailings anymore.
Even if the email address is added to another mailing lists
- Avoid sending notification to blacklisted recipients when sending email
in mass mail mode. If the recipient is blacklisted, we should not even send a
notification in the recipient's chatter for an email that he won't even
receive.
- When a email address is blacklisted, it can still get 'normal' mailings.
- The blacklist shoud be accessible in
Mass Mailing / Configuration / Blacklist
and Settings / Technical / Email / Blacklist
-> Renaming Settings / Technical / White / Black List config menu item
into Channel Moderation to avoid confusion with Mass Mail Blacklist
- Add indexes to the blacklist table (on email) to make it fast for access for
the different use cases
- _primary_email : attribute that must be overriden to specify which field must
be used as email in the blacklist mechanism.
- Filtering the blacklisted recipient in mail composer :
done in mail._get mail value()
In case of real mass mailing, we need the statistics to be computed in order
to know how many recipients were ignored in the mail.
So we cannot avoid sending mail but instead flag the mail as canceled.
Task ID 33224
This commit allows the user to link some mail template to activity type
with res_model.
When a activity has template, buttons appears in activity, allowing the user
to send mail based on templates.
Task: #1844563
PR: #25620
Only the add_sign from notif_values is usefull for a resend. We can consider
that a mail on resend can be delete in every case, and we can find the
model_description from model since a resend can only be performed on
message linked to a model.
The other notif_values are now parameter in order to ease the understanding
of what can transit through this flow.
Task: #1860054
PR: #25622