Commit Graph
678 Commits
Author SHA1 Message Date
Julien Van Roy e553f0b372 [FIX] mail,account_edi: fix creation of invoice upon email reception
When receiving an email on a mailbox with an alias that triggers the
creation of invoices, 4 bugs could occur.

1. If the xml received contains replacement characters (U+FFFD �), and
the charset of the part of the email is "US-ASCII" the encoding of the
string will fail, preventing the rest of the flow to be completed. Be
more resilient, encode the string and ignores these characters if this
case occurs.

NB: sometimes, the charset is omitted for a Content-type: text/xml. This
is valid but not recommended (see:
https://www.ietf.org/rfc/rfc2376.txt). In this case, the default used is
"US-ASCII". This means that any non-ascii char will be lost (they are
replaced by the replacement character: �, see:
https://github.com/python/cpython/blob/3.10/Lib/email/contentmanager.py#L67)
when decoding the attachment.

2. When the xml attachment is created in Odoo, the mimetype is
'text/plain' (rather than 'application/xml'). Thus, the
`_decode_attachment` needs to be more flexible when guessing the type of
the attachment (to know which function to use to read the content of the
attachment and create the invoice).

3. When creating an invoice from an email with an xml attachment, the
xml is attached as the `message_main_attachment_id`. It's only later on
that the content of the xml is read and we possibly find the PDF in
base64 inside. When creating the PDF attachment, it was not set as the
`message_main_attachment_id`, so the PDF was not rendered on the right
part of the invoice form view. Add a clause to replace the
`message_main_attachment_id` in such a case.

4. When the xml attachment represents a credit note, the move_type of
the invoice created by the email alias needs to be changed. Indeed, the
invoice is created before decoding the attachment, so we can only change
the `move_type` later.

opw-3144519
opw-3149649

closes odoo/odoo#121076

X-original-commit: 1e193a92b9c84e75b958985f8067873b90f686e0
Signed-off-by: Laurent Smet <las@odoo.com>
Signed-off-by: Julien Van Roy <juvr@odoo.com>
2023-05-11 08:28:42 +02:00
Pierre-Yves Dufays b3d9fbd3d5 [IMP] mail: allows unfollowing record from inbox
Allow users to unfollow easily document from the inbox for which he/she doesn't
want to be notified anymore.

When hovering on a follow up message with a related document followed by the
user, the interface displays an action to unfollow it that allows the user to
remove himself/herself as follower of the document. As a result of performing
that action a toast is displayed as a feedback.

Technical note:
The unfollow link is displayed on a message.canUnfollow is true which check
that the thread related to the message is followed by the user.

In order to know if the user follows the record related to the message, we now
transmit with each message the id of the follower table that link the user to
the related record if it follows it. This allows to insert the follower on
client side so that the unfollow action can use the standard mechaism already
developed to unfollow a record.

Unfortunately, that information coudn't be added in the already public method
message_format of mail message because that method is not always called on the
user retreiving the message but also by the one posting message. We didn't want
also to include all followers in the formated message so we rely on additional
method that add that information per partner.

To support unfollowing a document in the inbox no matter the current company,
we have modified message_unsubscribe in mail_thread to allow internal user to
unsubscribe themself without checking any rights. Indeed, some document have
record rule that prevents reading it if the user is not in the right company
(ex. crm.lead) and then was preventing the user to unfollow the document using
that method.

Task-3061864

Part-of: odoo/odoo#107978
2023-05-10 13:21:06 +02:00
Renaud Thiry 39f14ca2c9 [IMP] mail: add auto_comment message type
Currently some auto_reply templates are internal as a means to prevent
notifying users everytime we send a reply to somebody.

This raises the issue that since responses to internal notifications
are themselves internal notifications, often nobody will be notified of
responses to these automated messages.

We fix this by marking these messages as auto_comments, which will
ensure responses to these messages are
considered non-internal (and thus 'discussions', by default).

task-2834304

closes odoo/odoo#94018

Related: odoo/enterprise#35466
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
2023-05-05 09:25:42 +02:00
Renaud Thiry c9f55bb227 [IMP] mail: Show reorder template response
If a tracked value sent a mail template on creation of a record,
the template was displayed before the original message in the chatter.

We fix this by using precommit hooks similar to those already used for
tracking.

We also update the query count for a couple of tests. This is required
because in those tests the test user is not in the cache when we execute
the precommit hook, which we use to fetch a fallback language early in
the precommit.

Task-2834304

Part-of: odoo/odoo#94018
2023-05-05 09:25:42 +02:00
Maryam Kia ec93077b8d [IMP] mail: Edited label on edited message
By this commit, If a user edits the message body or changes
the message attachments, the edited label in the blob,
shows the last edit Info.

Task-2664848

closes odoo/odoo#117896

Related: odoo/enterprise#40208
Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
2023-05-04 14:03:42 +02:00
Sébastien Theys 09ac15e2dd [REF] mail: clean code for message update
As a bonus, add cross-tab update for current user in chatter.

Part of task-3265211

closes odoo/odoo#120018

Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
2023-04-28 12:26:43 +02:00
Sébastien Theys 3d1a21dc18 [REF] mail: move channel of message post controller to discuss
Part of task-3265211

closes odoo/odoo#120002

Signed-off-by: Louis Wicket (wil) <wil@odoo.com>
2023-04-27 18:25:33 +02:00
Sébastien Theys c1a3ad8e01 [REF] mail: move channel specific code of reaction to discuss
The opportunity is taken to clean the methods to make the override
actually possible.

Part of task-3265211

closes odoo/odoo#119942

Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
2023-04-27 17:21:53 +02:00
Rémy Voet (ryv) 234db70d86 [IMP] *: Use the new API of _read_group for backend use
Part-of: odoo/odoo#110737
2023-04-19 21:58:27 +02:00
Louis Baudoux 1a965a8045 [IMP] mail: add the ability to set the author of the tracking message
A new `_track_set_author` method is now available to explicitly set the
author of the tracking messages.

Related Enterprise PR: odoo/enterprise#38986

closes odoo/odoo#117073

Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
2023-04-18 15:38:49 +02:00
Nasreddin Boulif (bon) c78edec4d5 [FIX] mail_thread: save attachment from mail in same encoding
Steps to reproduce:

  - Configure incoming mail server and set it to create X record
    on incoming mails (X can be any model with a chatter)
  - Create a CSV file and set the encoding to UTF-16
  - Send the CSV file through Gmail to the Odoo instance
  - Go to model X and open the created record
  - In the chatter, click/download the CSV file
  - Open the downloaded file with Geany (or any file editor that can
    show the file encoding)

Issue:

  The file encoding is not the same as the original file (utf-8 instead
  of utf-16).
  Working with Outlook.

Cause:

  The difference between Outlook and Gmail is that Gmail provides the
  charset of the file.

  The content of the mail is retrieved using `email` python lib.
  The lib will try to retrieve the charset of the file and fallback
  on `ASCII` if not available, then return the decode content.

```python
  def get_text_content(msg, errors='replace'):
    content = msg.get_payload(decode=True)
    charset = msg.get_param('charset', 'ASCII')
    return content.decode(charset, errors=errors)
```

  Example:
  content = b'd\x00a\x00,\x00,\x00,\......'
  Outlook:
  charset = 'ASCII'
  return => 'd\x00a\x00,\x00,\x00...'
  Gmail:
  charset = 'UTF-16LE'
  return => 'da,,,,,\n,,,,,\....'

  In the post process of the attachment, the content is encoded in
  'utf-8' (to then encoded in base64) before creating the attachment
  record.

  Content encoded to 'utf-8':
  Outlook: b'd\x00a\x00,\x00,\x00...'
  Gmail:  b'da,,,,,\n,,,,,\n....'

  Therefore, when writing the file on the disk, the encoding is based
  on the binary content.

Solution:

  When parsing the mail, add the encoding charset to the `info` variable.
  Then, when creating the attachment, use the charset in `info` (or
  fallback on 'utf'8' if no charset set) to encode the content.

opw-3089009

closes odoo/odoo#118694

X-original-commit: 2d1b13e68d8bb204ecfe12a9d3db519c4264592c
Signed-off-by: Nicolas Lempereur (nle) <nle@odoo.com>
Signed-off-by: Nasreddin Boulif (bon) <bon@odoo.com>
2023-04-17 15:18:54 +02:00
Martin Trigaux 69f911d994 [IMP] *: enforce usage of Markup in mail
When using message_post, the body format must be explicitly specified.
If html is expected, a Markup object should be used.
If text is given, the content will be escaped.

Before this PR:
message_post was unaware if the content of a message was HTML or
text. This lead to multiple situation where the content was
incorrectly considered as HTML and led to display errors.
In
  self.message_post(body="Hello %s!" % self.name)
if the name contained HTML, it would be evaluated.

In
  self.message_post(body="Contact Raoul <raoul@caramail.be>")
the email would not be displayed as considered as unknown HTML and
discarded by the sanitizer

Now each call must explict the type of content.
Use the escape() helper to properly combine Markup and translations.
It would also be acceptable to use Markup() to wrap a static
translation but escape is better as one can not guarantee the content
of a translation.

closes odoo/odoo#111850

Related: odoo/documentation#3612
Related: odoo/enterprise#36728
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
2023-04-13 16:39:48 +02:00
tsm-odoo 1c1604466f [IMP] mail, im_livechat: add pin messages feature to channels
With this commit, messages can be pinned on a channel and
chat conversation. There's a new menu listing all pinned
messages on a conversation, and we can jump to these messages
in the current conversation.

As this feature incentives to see older messages, this commit
also adds a "Jump to Present" button when looking at old messages.

closes odoo/odoo#116666

Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
2023-04-13 04:08:11 +02:00
mky-odoo 2cc2690c8f [FIX] mail: prevent to call _message_compute_subject outside of a thread model
While we run cron `Data Merge: Find Duplicate Records` an issue raises because
`data_merge.model` has no method `_message_compute_subject`. Indeed it is
possible to notify on non-thread models but that method is a thread-only
method.

In this commit, we only call `_message_compute_subject` when it's available
in model.

sentry-3947126655
Task-3254379

Part-of: odoo/odoo#117763
2023-04-05 15:11:32 +02:00
Thibault DelavalléeandJulien Banken b4d210b245 [REF] mail: split notification email generation by recipient language
RATIONALE

Naming conventions
  * content = core message / subject (+ other fields);
  * email layout = layouting applied to messages when sent to recipients who
    receive notifications by email e.g. access button, ...;
  * comment mode / mailing mode: composer main composition mode: posting on
    record(s) / sending a mailing on records;

Content situation when using a template to post on a composer

  * comment, monorecord mode: choose a template, content is rendered directly
    from template side according to 'lang' field definition -> ok;
  * comment, multirecord mode / mailing mode: choose a template, content is
    the raw content. At post / send, content is rendered and translated if
    matching template content -> ok;

Email layout situation when posting / mailing

  * comment: layout translated based on template 'lang' field definition
    or fallback on current user's lang;
  * mailing: no layout supported;

PURPOSE

Translate layout into recipient's lang when available, instead of either
current user or template defined lang. As it is contextual better translate
it to the end user lang.

SPECIFICATIONS

Move recipients and email layout rendering into a method returning an iterator.
That way a list of recipient groups (as given by '_notify_get_recipients') can
be split into sub-groups, with each having its own rendering values for
email notifications.

Do a split / recipient lang. It is already fetched when notifying messages
as part of '_get_recipient_data' returned values. We now return recipients
groups per lang and per usage type (user, portal, customer, ...). Rendering
values are computed for each group as several values depend on the lang (
actions, notification buttons, global layout, ...).

Layouts when posting are dependent on recipient lang, and not on current user
anymore. Template lang that forced the content lang is now used only as a
fallback when recipient have no lang.

SUMMARY

When a user in Spanish, posts using a template specifying the lang of the
customer on a record whose customer is in French, with a follower being
in English

  * content will be translated following template choice, aka french;
  * layouting for the french customer will be in french, layouting for the
    english customer is in english, while the core content is always the
    same and in french;

When a user in Spanish, posts some custome content on a record whose customer
is in French, with a follower being in English

  * content is whatever the user wrote;
  * layouting for the french customer will be in french, layouting for the
    english customer is in english, while the core content is always the
    same and in french;

Task-3046371 (Mail: Better Language Support in Composer)
Task-2555155 (Mail: Translate notification action/access buttons)
Task-3186426 (Mail: Support notification layout in template / email composer)

Part-of: odoo/odoo#106177
Co-authored-by: Julien Banken <jbn@odoo.com>
2023-03-09 15:54:15 +01:00
Thibault Delavallée 9887bd0c7b [IMP] mail: correctly propagate language when posting from composer
RATIONALE

Naming conventions
  * content = core message / subject (+ other fields);
  * email layout = layouting applied to messages when sent to recipients who
    receive notifications by email e.g. access button, ...;
  * comment mode / mailing mode: composer main composition mode: posting on
    record(s) / sending a mailing on records;

Content situation when using a template to post on a composer

  * comment, monorecord mode: choose a template, content is rendered directly
    from template side according to 'lang' field definition -> ok;
  * comment, multirecord mode / mailing mode: choose a template, content is
    the raw content. At post / send, content is rendered and translated if
    matching template content -> ok;

Email layout situation when posting / mailing

  * comment, monorecord model, using a template from UX: layout is partly
    translated based on template 'lang' field to match the content translation.
    Part of the layout still uses the current user lang;
  * other comment use cases: layout is translated based on current user lang;
  * mailing mode: layout not supported;

PURPOSE

Correctly propagate lang from template in all situations whenever a template
is used, and translate all layout parts.

SPECIFICATIONS

When using the composer to post messages (either as comment or in batch) the
language coming from the template is not propagated until the notification
process.

A hack has been done to try to guess the language inside the notification
process, based on context keys at odoo/odoo@9e71d228ed. This was done to partly fix
the bug in stable.

Since odoo/odoo@3eb9680602 it is possible to propagate a lang from 'message_post' or
'message_notify' calls until the notification process. We can therefore call
the posting methods using the rendered lang (in both mono and multi record
modes) and remove that hack.

When a lang is propagated using the 'force_email_lang' it is used to choose
the language of the layout (content, buttons). Currently all recipients
receives the same language for layouting. We plan to soon use the recipient
language when possible, then fallback on that forced lang. This will offer
more granularity and a better user experience.

When using scheduled messages (creating message but delaying the sending of
notifications) it is also working as notification parameters are saved when
creating the scheduling record, see odoo/odoo@9b11a9d82b.

EXAMPLE

A user in english uses a template on a lead whose customer is in spanish
with a follower being in german. Template lang is customer's lang:

  * content is translated into spanish (customer's lang);
  * layout is translated into spanish (customer's lang);

Both recipients (customer and follower) receive the content in spanish.

LINKS

Task-3046371 (Mail: Better Language Support in Composer)
Task-2555155 (Mail: Translate notification action/access buttons)

Part-of: odoo/odoo#106177
2023-03-09 15:54:14 +01:00
Thibault Delavallée c088d5423e [IMP] mail: cleanup _notify_get_recipients code bits
This commit contains mainly code cleaning, docstrings and a small split
for notification tool methods. In this commit we

  * make some notification groups variable explicit;
  * move the filler of groups into its own submethod to ease being called
    from other code (to be used soon);
  * fix some strange overrides or code manipulation;
  * propagate some additional parameters to ease future commits that will
    improve rendering of groups-based notification emails;
  * cleanup, fixup and improve docstrings;

This does not change anything from functional point of view, just preparing
further work.

Task-3046371 (Mail: Better Language Support in Composer)

Part-of: odoo/odoo#106177
2023-03-09 15:54:12 +01:00
Thibault Delavallée acfb07e79c [FIX] mail: effectively allow to post when notified on unreachable documents
When being notified on a document they cannot read users should be able to
post, as indicated in message ACLs. However some data preparation prevents
from doing it as ACLs are raised on document level.

In this commit we sudo the call to display_name to populate record_name when
not given. Indeed access is checked at message level so no need to crash in
this specific use case.

Task-3213982 (Mail: fix 'multi-company' post support)

X-original-commit: odoo/odoo@2d73c61136
Part-of: odoo/odoo#114511
2023-03-07 18:03:04 +01:00
Thibault Delavallée 452ca009e3 [FIX] mail: allow to update main attachment
When replying on a document they cannot read (notably when being notified)
ACLs raise when trying to check if 'main_attachment_id' is already set before
updating it. This is fixed in this commit. This fixes the recently introduced
'test_post_wo_access' test that does not pass without this fix.

Note that the update of 'main_attachment_id' was already done in sudo. As all
read or update access is now done in sudo, better call the whole method as
sudo in 'message_post' and let '_message_set_main_attachment_id' works on
the given record set environment.

Task-3213982 (Mail: fix 'multi-company' post support)

X-original-commit: odoo/odoo@0375bb227a
Part-of: odoo/odoo#114511
2023-03-07 18:03:03 +01:00
Pierre-Yves Dufays 5c5282ba15 [FIX] {test_}mail: fix send message button activation (_mail_post_access)
The attribute _mail_post_access='read' on a model allows user with read only
access on the model to post a message. It was not taken into account on the
client side, making the send message button disabled for user with readonly
access on such model. This commit fixes this issue and now correctly takes
into account that class parameter.

Task-3178885 (Mail: fix 'readonly' post support)

X-original-commit: odoo/odoo@d2b8612cf7
Part-of: odoo/odoo#114511
2023-03-07 18:03:03 +01:00
Pierre-Yves Dufays e725ba761f [FIX] mail: allow post on model with readonly access when authorized
The attribute _mail_post_access='read' on a model class allows to post on that
model with readonly access. But when providing an attachment such action was
throwing a security error due to the check done on the attachment. Indeed
adding an attachment to a model is modifying that model so the write access
is needed. To solve this problem, we add the attachment in sudo in the
'_message_post_process_attachments' method.

Justification

This is an internal method and we have stated in its documentation that it is
the caller responsibility to check the rights. Actually, the checks are done at
mail.message creation (to which the attachment are linked) by the override
of 'check_access_rule' which calls '_get_mail_message_access' which takes into
account that attribute (_mail_post_access). Moreover sudo is already used
in '_message_post_process_attachments' to link existing attachments. Here we
add a sudo for the new attachments as well.

Note

This fix allows the test 'test_post_with_read_access' to pass (located in
test_mail/tests/test_mail_multi_company.py). But it is currently hard to
reproduce functionally as

  - answering an email works as it is executed by the cron;
  - replying in discuss trigger a multi company error no matter there is an
    attachment or not (so it is another problem);
  - sending a message (with readonly access) on a thread from the interface
    works without this fix because the attachment are created beforehand and
    the part that handle already existing attachment is already in sudo;

Multicompany issues will be solved in the next commits.

Task-3178885 (Mail: fix 'readonly' post support)

X-original-commit: odoo/odoo@f9a6f7f7ce
Part-of: odoo/odoo#114511
2023-03-07 18:03:03 +01:00
Thibault Delavallée ae791c7a7a [FIX] mail: correctly check 'is_thread_notification' when notifying
Due to misplaced / missing parenthesis some corner cases were not correctly
computed, notably when having Falsy values and using the fallback. Also
it was returning the thread ID instead of a boolean. This was not harmful
but better return a boolean "is a thread notification".

Task-3046371 (Mail: Better Language Support in Composer)

Part-of: odoo/odoo#114511
2023-03-07 18:03:02 +01:00
std-odoo 97ca45e4f3 [IMP] mail, mass_mailing: store the bounce email and allow the user to read it
Purpose
=======
The bounce emails aren't stored in Odoo, which can complicate the
debugging of the email sending.

Now, we store this bounce email, and we allow the user to read it from
the interface, so he can easily find the issue when an email sending
fail.

Specifications
==============
The bounce email is stored on the mail notification for standard emails
sending, and on the mailing traces when using mass mailing.

For some email providers (e.g. Yahoo), the "Final-Recipient" header is
not present. Normally, it allows us to retrieve the original recipient
of the email which bounced and then the partner. So if this header is
not there in a bounce email, we take the first recipient of the parent
<mail.message>.

Change the way that we parse the email body, for the bounce email.
For most email providers, the first mail body is the one that contains
the error and the next one contains the parent email body. So, the
current logic might ignore this body for Outlook and Yahoo.

Task-2116296

closes odoo/odoo#105923

Related: odoo/enterprise#34051
Signed-off-by: Warnon Aurélien (awa) <awa@odoo.com>
2023-03-06 17:47:29 +01:00
Raphael Collet 6ef3772847 [IMP] *: optimize code with search_fetch() and fetch()
closes odoo/odoo#112126

Related: odoo/enterprise#36782
Signed-off-by: Raphael Collet <rco@odoo.com>
2023-03-05 15:12:57 +01:00
Pierre-Yves Dufays f8c7f2e5bb [MOV] mail: move main attachment feature to mixin
Main attachment is quite costly and as it is implemented in mail.thread, is
present in most model. In order to improve performance, we remove it here from
mail.thread and add it, through a new mixin, only on models that actually use
that feature.

Technical note: with the current implementation, even if the font-end view
expect the model to implement the main attachment feature and the model
doesn't, it doesn't crash. Indeed, the main attachment on the front-end is only
used to know the first image to display in the image 'carousel' on the right
(widget rendered through the presence of the class o_attachment_preview). And
as 'register_as_main_attachment' of ir.attachment doesn't crash even if the
model doesn't support main attachment feature, the only consequence is that the
first image to display is not persisted (if you refresh after changing the main
attachment, it will get back to the previous one).

Task-2648976

Part-of: odoo/odoo#110734
2023-03-02 12:32:10 +01:00
Thibault Delavallée 1a2a8d82fe [FIX] mail: do not subscribe inactive users creating records
Inactive users should not be added in followers of records, especially using
automated subscription. Indeed they mainly generate noise in notification
process and are generally skipped.

Few use case exists of inactive users creating records. One use case is the
mailgateway running as root but a context key 'mail_create_nosubscribe' is
used to avoid it. Other use cases include automated action for example who
are also generally protected.

Anyway better be sure and consider this is a standard use case. To extend
this rationale, inactive people are currently not added when posting. It
therefore makes sense to keep this behavior coherent through the mail stack.

Task-3046371 (Mail: Better Language Support in Composer)

Part-of: odoo/odoo#113522
2023-02-23 18:28:59 +01:00
Pierre-Yves Dufays 31811ba89f [IMP] base, crm, mail: prefill partner creation form with current record data
Selecting a recipient for which there exists no partner trigger a partner form
dialog creation. For some model (ex.: crm.lead), some default values can be
prefilled from the current record. This is what we do here by calling a generic
mechanism that allows each model to define default value for related partner.

Note that we don't provide a more detailed form to the user because some will
otherwise feel obligated to fill it out entirely.

Technical note: As there is no need for a custom form per model from which the
data are extracted to populate the related partner, the simplified partner form
(view_partner_simple_form) is just augmented with additional invisible field by
modules that add fields to partner and need to populate them automatically from
values of another model.

Technical note: In TestCRMLead.test_message_recipient_partner_auto_creation, we
test that the _message_get_suggested_recipients returns the correct default
values to copy some fields from the lead to the partner to avoid the user to
reenter them. But we don't test specifically that it also work when using mail
composer and template (which generate the partner) because it has already been
tested when introducing the mechanism. Although, we verify that it should
behave the same because we verify that the default values returned by
_get_customer_information, that is used in mail template when using the
composer, are the same as the ones returned by _message_get_suggested_recipients
which is tested here.

Task-3024050

Part-of: odoo/odoo#105111
2023-02-23 14:53:56 +01:00
Pierre-Yves Dufays 1018c72571 [IMP] mail, test_mail: allow model to provide partner default values
Allow model to provide default values for auto creation of related res_partner
such as name, title, company_id, ...

It is used when claling 'Partner._find_or_create_from_emails()' that now
accepts custom data when creating partners based on a given email_normalized.
This allows notably to flatten a loop due to multi-company when creating
partners from emails in template management. It is now done using this email
based dict allowing to create all partners at once.

Task-3024050

Part-of: odoo/odoo#105111
2023-02-23 14:53:56 +01:00
Thibault Delavallée 2075dd0848 [FIX] mail: fix language fetch when sending notification
When using the composer in batch and comment mode, the first record of the
batch was used to find the language for notifications instead of the one
linked to the message.

Previously to odoo/odoo#99482 batch comment mode was not supported and there
were always only a singleton as record ids. Now that it is supported we have
to be more careful when dealing with IDs.

To solve this issue we check the message res_id which effectively contains
the correct record ID.

Oversight of odoo/odoo#99482

Task-3035101 (Mail: Support batch-posting from composer)

closes odoo/odoo#113015

Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
2023-02-17 22:02:35 +01:00
Thibault Delavallée 8a66cc7db0 [IMP] mail: display scheduled_datetime of delayed notify in chatter
Followup of odoo/odoo#95623 (introduce scheduled message notification) as well
as odoo/odoo#99482 (support scheduled datetime from template to composer in
both comment and mailing modes).

Task-3093257 (Mail: The Composer Update)

Part-of: odoo/odoo#107356
2023-01-27 19:56:09 +01:00
Thibault Delavallée 300ae603d1 [REF] mail: remove composer onchange, now unnecessary
PURPOSE

Purpose of this task is to remove the _onchange_template_id method on composer
model. Split it into editable computed stored fields. It gives a better control
of value generation and avoid having to call the onchange when composer is
invoked in code.

SPECIFICATIONS

Remove onchange as it is not used anymore. All fields have been converted.

Task-2088884 (Mail: Use editable computed stored fields in composer)

Part-of: odoo/odoo#107356
2023-01-27 19:56:08 +01:00
Thibault Delavallée 8fb59b55d9 [IMP] mail: improve 'real author' detection when posting a message
When posting a message, author is added in followers in order to receive
answers. They also do not receive its own messages, to avoid being notified
of something they just posted.

However the real author is not always the message author. In this commit
we better define this author
  * when current user is active, real author is the current user. It means
    posting on behalf of someone will send answers to you, not to the
    spoofed partner;
  * when current user is inactive, real author is the message author. An
    inactive current user means the post was probably done as sudo, aka
    in the mailgateway or frontend. In that case we don't want to add
    odoobot in followers, but the actual message author;

Task-3093257 (Mail: The Composer Update)

Part-of: odoo/odoo#107356
2023-01-27 19:56:03 +01:00
Thibault Delavallée 17e6cd1e14 [IMP] mail: add a notification parameter to allow notifying the author
Currently notification process called notably by message_{post,notify} does
not notify message's author by default. Rationale is that as he typed the
message he is already aware of it.

However in some cases we want to skip this step, notably when messages are
generated in the name of the author and when we want him to be notified if
he should.

This is currently controllable through a context key 'mail_notify_author'.
In this commit we add an explicit parameter propagated through the notify
process, allowing to remove some context key usage and instead use real
parameters.

Note that all context keys usage cannot be removed as it is not always
possible to propagate this parameter.

Followup of odoo#99482

Task-2710804 (Mail: Clean MailThread API)

Part-of: odoo/odoo#107356
2023-01-27 19:56:03 +01:00
Thibault Delavallée e2c659eb0c [IMP] mail: make message_notify process attachments
Method 'message_notify' is a simplified version of 'message_post' to use
to notify people of something, without posting on a document. It creates
a "user notification", a specific kind of message.

In this commit we make 'message_notify' process attachments like posting
does. That way the API is more similar between those two methods. Moreover
it allows to give 'attachments' to notify. Those are then transformed into
real 'attachment_ids' and converted if they come from the composer.

That way the mail composer can be used in notification mode with attachments.
This happens notably when using a template on a record that does not inherit
from MailThread. It is a classic usage of 'message_notify' which allows
notifying on documents that have no chatter, notably technical or admin
oriented models.

Followup of odoo/odoo#99482

Task-2710804 (Mail: Clean MailThread API)

Part-of: odoo/odoo#107356
2023-01-27 19:56:03 +01:00
Julien CastiauxandBaptiste Vergote 37ca7770a6 [FIX] mail: bad CTE/QP decoding of rfc822-headers
Based on RFC3462, a Content-Type text/rfc822-headers
exists and provide a mechanism to label and return
only the RFC 822 headers of a failed message (bounce)

These are only the headers and not the full message.

The Content-Type-Encoding should be either 7-bit(US-ASCII)
or Quoted-Printable (QP) as in the section 2 of the RFC.

Spawn the error:
After getting reported by a customer, I had to reproduce
by spamming wrong outlook addresses and add logging
in a sh database on the message_process of mail_thread.py
and logged the `message` variable.

After few retry, I got one of the part that was defined
as followed:
Content-Description: Undelivered Message Headers
Content-Type: text/rfc822-headers
Content-Transfer-Encoding: quoted-printable

The `get_payload()`function used was only assuming
that there is a full email on that part and that
it could only be encoded as an email, which was not
the case in this situation (quoted-printable:
76 characters per line, character `=` used
as the end of line character).

opw-3064589
task-3131561

closes odoo/odoo#110901

X-original-commit: f86f4b671696178f8fa42b81d8753d2591578431
Signed-off-by: Julien Castiaux <juc@odoo.com>
Co-authored-by: Baptiste Vergote <bve@odoo.com>
2023-01-24 23:21:57 +01:00
Thibault Delavallée 1a1acabd7b [REF] mail: cleanup mono/multi record composer behavior
RATIONALE

Improve usage of composer in comment or email mode: support batch-posting in
comment, support more configuration from templates, improve global model.

SPECIFICATIONS

Support a real res_ids field on mail.compose.message model. Instead of relying
on active_ids from context, store it once for all at composer level and use
it in code. Active_ids usage is still done at default_get level, using it to
populate the field.

Improve usage of domain, renamed to res_domain to match other document related
fields naming. Add support of a res_domain_user_id field allowing to set the
user from which the domain should be evaluated.

Composer now runs on a list of IDs. Mass mail mode and comment mode are now
distinct from running on a singleton or on more records. Rendered or raw
mode is not triggered by

  * mass mailing mode: always display raw mode, whatever the number of records;
  * comment mode: display rendered mode when having a single record (like the
    previous comment mode). Display raw mode when having either no records
    either at least two records.

Task-3035101 (Mail: Support batch-posting from composer)

Part-of: odoo/odoo#99482
2023-01-17 20:58:39 +01:00
Thibault Delavallée 041e9924c7 [REF] mail: improve default record-based data in composer
Purpose is to ease understanding of those default values and prepare move
towards editable stored computed fields by rewriting a bit the code to better
understand its purpose.

While being at it, some tests introduced recently are moved at their right
place now that everything is ready to rewrite the posting API and the
composer. Some tests are added to ensure notification-specific methods are
called along with the newly-introduced '_message_compute_subject', aka methods
to add custom header and custom mail values.

Task-2710804 (Mail: Clean MailThread Posting API)
Prepares Task-2088884 (Mail: Use editable computed stored fields in compo

Part-of: odoo/odoo#99482
2023-01-17 20:58:38 +01:00
Thibault Delavallée 9180843bb9 [MOV] mail: move "main attachment" update as an after-post hook
A method ``_message_set_main_attachment_id`` exists to handle main attachment
reference, used notably in discuss and accounting. It is now called inside
``_message_post_after_hook``, so that it is part of the post processing after
having posted the message. Its API has been updated so that attachment_ids is
now a real list of ids, which is clearer.

A wrong override of '_message_post_after_hook' dealing with parameters is
cleaned while passing by.

Task-2710804 (Mail: Clean MailThread Posting API)

Part-of: odoo/odoo#99482
2023-01-17 20:58:35 +01:00
Thibault Delavallée 9bbb276c42 [REF] mail: cleanup message_{notify, log} wrappers
RATIONALE

Purpose of this commit is to cleanup main post helpers and have a more easy
and understandable way of calling them.

SPECIFICATIONS

Update methods parameters to look more like 'message_post' definition. Add
docstrings to explain parameter usage. Cleanup some parameter we do not
want. Add a api.returns on message_notify to wrap the value in case of external
call, as this method is public, like message_post.

Task-2710804 (Mail: Clean MailThread Posting API)

Part-of: odoo/odoo#99482
2023-01-17 20:58:35 +01:00
Thibault Delavallée 4775bd93a2 [REF] mail: cleanup post with {view, template} wrappers
RATIONALE

Purpose of this commit is to cleanup main post helpers and have a more easy
and understandable way of calling them.

SUMMARY

We now have two main API methods, based on business flow: either posting
on documents, either sending a mass mailing. Indeed those two flows are
different

  * post: create message, then launch notification process by taking into
    account subtype, followers, ...
  * mail: create mails in batch with recipients being based on template or
    given partners. No notifications is involved, only maybe traces if a
    mass mailing is linked

Delegate QWeb rendering to the render mixin (i.e. _render_template_qweb_view)
in order to have a single point to forge evaluation context and re-use
existing rendering code.

SPECIFICATIONS

Main API helpers are now

  * ``message_post_with_source``: (batch) post on records, using an ir.ui.view
    (given a record or its xml id) or a mail.template record (given a record or
    its xml id). When using a template, a composer is called to post on each
    record (as batch post is not yet supported). When using a view, a direct
    call to message_post using the rendered bodies is done, one record at a
    time.
  * ``message_mail_with_source``: send a mass mailing on records, acting like
    invoking the mail composer in mass mode. Same arguments are valid, either
    a reference to a view, either a reference to a mail template.

Other helpers are

  * ``_message_log_with_view``: (batch) log on records, using an ir.ui.view
    to render the body using QWeb (no notification process);
  * ``_message_log(_batch)``: (batch) log on records (no notification process);
  * ``message_notify``: notify partners on records (creating notifications
    specifically for some people while message itself is not displayed in
    chatter);

Code migration

  * ``message_post_with_template`` in "mass mode": use ``message_mail_with_source``
    and set the template record as source;
  * ``message_post_with_template`` in "comment" mode: use ``message_post_with_source``
    and set the template record as source;
  * ``message_post_with_view``: its main usage was to post on a document, in which
    case it generally can be replaced by ``message_mail_with_source`` using
    the view reference as source;

Task-2710804 (Mail: Clean MailThread Posting API)

Part-of: odoo/odoo#99482
2023-01-17 20:58:34 +01:00
Thibault Delavallée 2175bde607 [IMP] mail: add sanity checks for message_post and its helpers
Purpose of this commit is to clearly check input of ``message_post`` method
and its main helpers in order to prevent wrong usage of message post API.

Some values used to populate message fields should not be set directly when
posting or logging messages. Indeed they may be part of other process (like
notification process managed by ``_notify_thread``, or could be setup by
custom routes like 'reaction_ids', or custom usage of 'model' and 'res_id'
that could conflicts with record on which methods are called).

We therefore add checks and cleanup in those methods to be sure the API
is used as intended and avoid unwanted side effects.

Task-2710804 (Mail: Clean MailThread Posting API)

Part-of: odoo/odoo#99482
2023-01-17 20:58:34 +01:00
Thibault Delavallée 418761e344 [LINT] mail, various: use explicit subtype in message_post_{with_...}
RATIONALE

Purpose of this commit is to be explicit in subtype chosen when invoking the
message composer / calling message_post. As default value may not always be
clear, better be explicit in case the composer default value changes.

SPECIFICATIONS

Add explicit references to subtype when it is not obvious what will be the
final subtype, notably when using helpers (post_with_view or template which
uses the composer that is not crystal clear in its subtype management).

In this commit we also add support of XMLID-based subtype when invoking the
composer. A ``default_subtype_xmlid`` context key is transformed into a
``default_subtype_id``, to be used notably in JS where we cannot easily
use a ``ref``-like statement. Post API now also supports 'subytpe_xmlid'
argument allowing to give the xml id and ease calling the methods.

Use ``_xmlid_to_res_id`` to get directly the ID of subtypes in order to
avoid useless queries from ``ref`` that does an exists.

Also remove useless values given to post API, notably author_id that is by
default the current users' partner.

Task-2710804 (Mail: Clean MailThread Posting API)

Part-of: odoo/odoo#99482
2023-01-17 20:58:33 +01:00
Renaud Thiry f039f57eb8 [IMP] Add more detailed default email subjects from chatter
All emails sent from the chatter start with "Re:" followed
by the name of the record. The name of the record alone is sometimes not enough for
the followers to understand what the mail is about.
Additionally, "Re:" does not make sense when starting a conversation.

This commit gives better default subject
for event registrations and allows thread models
to override the default subject of messages.

This also removes "Re:" from default mail subjects.

Task-2833215

closes odoo/odoo#95817

Signed-off-by: Stéphane Debauche (std) <std@odoo.com>
2023-01-05 15:36:53 +01:00
Pierre-Yves Dufays d4c865199e [IMP] mail, test_mail_full: add portal flow test
The tests consist in sending a mail related to a record to a customer and
checking that the record can be viewed through the embedded link:
- either in the backend if the user is connected and has the right to
- or in the portal otherwise

It also test that if the embedded link is tampered, the access is forbidden.

Task-2797311

closes odoo/odoo#105405

Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
2022-12-19 13:38:00 +01:00
bve-odooandJulien Castiaux 48109c15d3 [FIX] mail: parse Content-Type binary/octet-stream
Some mail clients set a wrong content-type for PDF attachments, they
set `binary/octet-stream` which doesn't exist[^1]. Odoo would crash
with a traceback in case it tried to extract the content of such
malformed attachment because Python doesn't know how to decode such
content-types.

Looking at the actual content of the emails we received, we would had
expected the content-type to be `application/octet-stream` instead. It
is fair to assume that the mail client software is buggy or poorly
configured and that it assumes that `application/octet-stream` and
`binary/octet-stream` represent the same thing.

Following Postel's Law[^2], it is better to still handle those malformed
emails, assuming the content-type is `application/octet-stream`.

opw-3030113
opw-2716507

[^1]: https://www.rfc-editor.org/rfc/rfc2046#section-3
[^2]: https://en.wikipedia.org/wiki/Robustness_principle

closes odoo/odoo#107317

X-original-commit: e6169325b968711a0a28444818b34aa1932a6bae
Signed-off-by: Julien Castiaux <juc@odoo.com>
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
Co-authored-by: Julien Castiaux <juc@odoo.com>
2022-12-06 14:34:47 +01:00
Pierre-Yves Dufays c069cf75c7 [IMP] hr,{test_}mail{_group}: warn user when alias model creation fails
Warn user and alias responsible when model creation fails on incoming
message due to alias mis-configuration.

Alias custom default values that references archived or deleted records can
prevent the record to be created when receiving an email.
Unfortunately, correcting values on the fly has too many downsides:
- as the value cannot come from nowhere, we would probably end up with
corrupted record like a task without a project
- as errors are silent, lots of suboptimal record could be created before it
is corrected
- as the code would have to deal with different kind of updates, it would be
heavily depend on the framework meaning additional maintenance cost
- the attempt made had also a performance cost by using savepoint which we
want to avoid

For all those reasons, we have decided to warm the user rather than trying to
solve the problem automatically.
The users are warned:
- through a bounce email sent to the sender and alias responsible
- in the alias interface through an alias status present in the list and the
form view

Technical notes:
- They are multiple kind of errors: error in the message (ex.: user not
authorized to send to a specific alias), error in the alias (ex.: dangling
reference in alias_defaults), other error (ex: technical error like a
service unavailable when receiving the message). Here, we want only to detect
alias error and skip other errors. So rather than doing a big try except around
_message_route_process, we have selected the spot where we should detect alias
error:
-- in _alias_get_error_message where we distinct a message error from an alias
error
-- in inside _message_route_process where record are created using
alias_defaults (custom values with reference to record that might have been
deleted since the alias creation)
- In test, we call mail.thread message_process with sudo as it is the case in
real use case (processed when fetching mail). It is needed as in some test
alias status are modified.

Task-2675209

closes odoo/odoo#101019

Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
2022-12-06 09:25:50 +01:00
Thibault Delavallée 04c1959456 [MOV] account, mail: move model-specific template code to model
PURPOSE

Purpose of this task is to cleanup attachment management done in generic mail
models overrides and move it in account as model overrides.

SPECIFICATIONS

Account_edi and various l10n submodules hold some custom code to generate and
handle EDI attachments. It is used to add attachments linked using AccountMove
specific 'edi_document_ids' field when sending emails based on templates.

Currently MailTemplate is overridden in accounting modules to hold code related
to AccountMove and AccountEdiDocument attachments manipulation. This is linked
to EDI and report naming, not mail specific. This should therefore not be
implemented at template level, but in those specific models.

For that purpose we introduce a method in MailThread that allow to handle
attachments when being in a template context. An override in account_edi
allows to implement its specific behavior.

By the way an old docstring in l10n_it_edi that was quite unrelated to the
override is also removed, as it was more confusing than helping.

Task-2792146 (Mail: Move model-dependent code from composer / template)
Task-2710804 (Mail: Clean MailThread API)

Part-of: odoo/odoo#106658
2022-11-28 15:52:59 +01:00
Thibault Delavallée 0be5b37008 [MOV] mail, loyalty, purchase, (website_)sale: move model-specific composer code to model
PURPOSE

Purpose of this task is to cleanup attachment management done in generic mail
models overrides and move it in account as model overrides.

SPECIFICATIONS

Update addons

  * in purchase and sale: context key update should be done at message_post
    level, especially this is not used in mass mailing mode;
  * in website_sale: code to update sale order to avoid sending recovery
    emails several times belongs to a "post hook" method on sale order model;
  * in loyalty: remove a deprecated / unsupported 'mark_coupon_as_sent' key;

Task-2792146 (Mail: Move model-dependent code from composer / template)

Part-of: odoo/odoo#106658
2022-11-28 15:52:59 +01:00
Thibault Delavallée 1c240f11df [IMP] mail: cleanup code bits in attachments processing
Purpose of this commit is to try to make code a bit easier to follow using
dicts, sets and tuples, as well as updating some variable names.

Also rename the method to be clearer. Tools methods may omit the namespacing
to avoid too much confusion in naming.

Task-2710804 (Mail: Clean MailThread API)

Part-of: odoo/odoo#106658
2022-11-28 15:52:59 +01:00
Thibault Delavallée f1bb452ce4 [MOV] mail: move method to process attachments
Purpose is to make a section that will cover pre- and post- process methods
for posting or mailing records.

Task-2710804 (Mail: Clean MailThread API)

Part-of: odoo/odoo#106658
2022-11-28 15:52:58 +01:00