Before this commit, updating a boolean field through a server action was
possible but unintuitive: if you wanted to set the field to `False`, you
had to leave the value empty - worse, writing down `False` would be
considered truth-y since it was evaluated as a string!
This commit introduces a simpler UX for these cases, where the user can
select Yes/No in a selection field if the field they're trying to update
is a boolean field.
Task-3450200
Part-of: odoo/odoo#138804
Commit b05e7e4da0 rightfully removed the _compute_name dependency on
context keys (a bad idea for stored computed fields), but this change
could lead to UX frustrations (Server Action names getting reset all the
time despite what the user may have used as a name before) and UX issues
(e.g. triggering a recompute by accident at module removal that could
reset all 'code' action names to 'Execute Code').
This commit simply removes the automated naming feature from the base
module and moves the logic to the base_automation module - and only
computes automated names based on the link with an automation rule or
not (so 'standalone' server actions need a name given by the user at all
times).
Task-3450200
Part-of: odoo/odoo#138804
Before this commit, server actions of the 'Update Record' type could
only write on m2m fields entirely - meaning that there was no support
for commands like adding or removing records from the set without
writing it completely.
This commit introduces this possibility, along with some UI changes to
come from it regarding the display of such actions in automation rules.
Task-3450200
Part-of: odoo/odoo#138804
Webhook server actions allow users to send a POST request to an external
system, e.g. Slack, Github or even another Odoo instance.
This is a rather simple setup, as this feature does not include frequent
features of typical webhooks, such as the possibility to use headers for
authentication, or a retry-policy with exponential decay and all the
bells and whistles of that style.
However, this can be useful for simple actions and automations.
Task-3450200
Part-of: odoo/odoo#138804
Up until now, the 'Update record' server actions could only update the
record on which the action was triggered.
This is a rather serious limitations, especially in modules that
leverage server actions, like base automation - indeed, if you want a
server action run on e.g. Leads that will write changes on the leads'
customer, you *had* to use Python code.
This commit makes it possible to traverse relations when selecting the
field to update, and indeed to write across relations.
Task-3450200
Part-of: odoo/odoo#138804
Now that some field attributes like invisible are given by Python expressions
and that those can involve some set operations, we have to ensure that
the views can be validated if they use such operations. We do that and
add a test.
closesodoo/odoo#139451
Signed-off-by: Géry Debongnie <ged@odoo.com>
Most of the time, rates are computed in a loop by using
`<res.currency>._convert`. This leads to a lot of round trips with the
database.
This PR is caching the value for a whole transaction.
In order to do that, the non stored field `rate` has new (missing)
contextual dependencies: the arguments of `_get_conversion_rate`.
This allows to move the actual computation of the rate to the computed
field, and `_get_conversion_rate` is now only a proxy to avoid playing
with the context manually; also kept for backward compatibility.
Other solutions were considered:
* `ormcache`, but we want to avoid creating multiple caches and reduce
the possibility to have inter dependent caches.
* managing a local cache everywhere, which is cumbersome and error prone
* a helper for the previous option by using a converter factory, but it
is still an issue when the convert function is called from multiple
call functions because the cache isn't shared then.
Part-of: odoo/odoo#137609
PURPOSE
Allow alias domains to be multiple, notably to be used in a multi company
environment where each company has its own alias domain.
SPECIFICATIONS
Now that alias domains are used in Odoo codebase there is no usage anymore
for the old config parameters. So long and thanks for all the fish !
Task-36879 (Mail: Support Multi Domains Aliases)
Part-of: odoo/odoo#76734
PURPOSE
Allow alias domains to be multiple, notably to be used in a multi company
environment where each company has its own alias domain.
SPECIFICATIONS: MAIL.MAIL
Update MailMail to use alias domains. Notably "Return-Path" headers are
now computed based on alias domain when possible, using the recently added
fields on 'mail.message' model for that purpose. Fallback is to use current
company's bounce email when mail_mail creation is done outside of classic
mail flows or without that information.
SPECIFICATIONS: IR.MAIL.SERVER
Update IrMailServer and low-level stack to use alias domains. This has an
impact notably on default values computation for from and bounce emails
* '_get_default_bounce_address' is called when there is no 'Return-Path'
given. Most classic mail flows will set it according to current record
company / alias domain. Fallback when not set is to fallback on current
company's bounce email, computed based on its alias domain;
* '_get_default_from_address' is used in two use cases
* computing a default 'email_from' for outgoing emails when it is not set.
In most classic mail flows it is set based on current user's email. If
not set fallback on current company's notification emails is considered
as a safe bet, replacing the global configuration parameter;
* overriding the 'email_from' of emails that are considered spoofing the
mail server, allowing to wrap the sending into a 'notifications@domain'
generic sender. For those we should try to keep record's information as
it may be called in classic mail flows;
* '_get_default_from_filter' is added in base and overridden in mail to
either use 'mail.default.from_filter' ICP, or use the one defined on
the alias domain. Supporting both is still an option, as its behavior
is implemented for basic email sending, without mail being available.
Those methods are updated to try to support multi domains / multi company
setup. However as those defaults are located ar ir.mail_server level it is
not always easy to have complete environment information, hence fallbacking
on current company's parameters when no better information is provided.
A test about 'mail.default.from' is removed, as it was testing a default_from
outside of catchall domain. It is not possible anymore as default_from is now
part of domain definition. As multi domains is supported, no need to support
exotic configuration like that.
SPECIFICATIONS: FROM MAIL.MAIL TO OUTGOING EMAILS
When sending emails based on MailMail, we now prepares sending groups based
on MailServer, email_from, but also alias domain to which the mail belongs to.
Information about alias domain (e.g. notifications email based on default_from
and bounce email) is propagated to low-level email preparation methods. It
uses the context as it is the easiest way to propagate information to that
level without hacking too much models or calls.
Task-36879 (Mail: Support Multi Domains Aliases)
Part-of: odoo/odoo#76734
PURPOSE
Allow alias domains to be multiple, notably to be used in a multi company
environment where each company has its own alias domain.
SPECIFICATIONS
Make mail gateway support alias domains instead of relying on configuration
parameters. This implies the following changes
* destination alias check is now based on full email by default. Previously
only left-part of aliases were checked. Optionally an allowed list of
domains could be additionally checked. Default from now on is to check
the complete email e.g. 'sales@mydomain.com' != 'sales@mydomain.in';
* detection of direct write to catchall implies checking all domains
catchall emails;
* detection of write to bounce implies checking all domains bounce emails;
* when having to send bounce emails using the bounce alias as mailer-daemon,
find the bounce email from the relevant company;
However we have to ease transition from the old ICP-based model used since
ages to the new domain-based model. Notably a common usage of mail gateways
is to do mail forwarding e.g. forward mail from domainA to domainB without
rewriting destination. It means that e.g. sales@mail.domainA should be
considered as a valid alias equivalent to sales@mail.domainB. This was
working due to left-part only check of destination aliases. In order to
keep this setup working after migration a flag is added on aliases allowing
to keep the detection of those aliases based only on local parts.
In summary: When searching for aliases, mailgateway now either checks for
exact email, either for matching local parts when the flag is active. This
is not the default behavior, as we want a stricter comparison of emails by
default but it will be the default behavior at **migration time**.
The 'mail.catchall.domain.allowed' configuration parameter is kept. It is
used only for left-part check aliases, allowing to limit the scope of the
match.
Task-36879 (Mail: Support Multi Domains Aliases)
Part-of: odoo/odoo#76734
This may have an impact when trying to find an outgoing mail server based
on from and filter, as first match wins when checking matching filter on a
bunch of mail servers.
Prepares Task-36879 (Mail: Support Multi Domains Aliases)
Part-of: odoo/odoo#76734
Due to current implementation of mocks context is lost when accessing methods
'connect' and '_find_mail_server' of IrMailServer. Indeed self is replaced by
an instance of IrMailServer and code relying on context could not be called as
planned.
This commit aims at doing a custom mock so that we can correctly rely on self
and context in those methods. This is necessary for incoming changes in mail
notably to allow testing SMTP feature in multi domains environment.
Logged information when having failed SMTP check is improved: we now also
log found From in order to ease debugging failing tests due to invalid from.
Prepares Task-36879 (Mail: Support Multi Domains Aliases)
Part-of: odoo/odoo#76734
The new method should be used to generate an SQL object that represents
how to order by a field in an SQL query. We introduced the auxiliary
method _order_field_to_sql() so that one can specify some SQL for
ordering by a given field with a simple method override.
Part-of: odoo/odoo#138019
We take advantage of SQL objects to discard the use of domain operators
'inselect and 'not inselect'. Indeed, as we now support SQL objects at
the right-hand side of a condition, one can replace conditions like
(lhs, 'inselect', (query, params)) by (lhs, 'in', SQL(query, *params)).
This commit also adds tests that ensure the correct behavior of the
adaptation of the implementation.
Part-of: odoo/odoo#138019
For very large bits of SQL code with potentially repeated terms, it is
useful to use named parameters instead of positional parameters:
sql = SQL(
"SELECT %(column)s FROM %(table)s WHERE %(column)s IS NOT NULL",
table=SQL.identifier("foo"),
column=SQL.identifier("foo", "bar"),
)
Part-of: odoo/odoo#138019
The current used version of wkhtmltopdf manages is frozen to 0.12.5
because some features used by odoo are only available in this version
using a patched qt.
Anyway, it become difficult to keep this version up to date, especially
with Ubuntu Jammy and updates of the dependencies used by wkhtmltopdf.
More than that because of qt related issues, wkhtmltopdf maintenance
will end soon.
Adding a test to check some caracteristics of pdf reports may be usefull
to check that current version is still working, and eventually to find
an alternative solution.
This test checks that pdf reports contains the expected headers and
footers elements with the correct page number (2 record of 2 pages)
This also check that the pdf is in the expected A4 format.
Future test may check other formats, margins, layout,
page size/pagebreak combination, (table of content?), ...
This test may also check performances and existing limitations.
closesodoo/odoo#136626
Signed-off-by: Christophe Monniez (moc) <moc@odoo.com>
In the context of branches, you need to be able to select taxes of
an ancestor company on an invoice/bill, even when you don't have access
to the ancestor company.
In order to do that, we relax the restriction when searching with a
`parent_of` or `child_of` on a related field, so that it also includes
ids of related field records you don't have access to. This should not
be a problem, since in the end the search will return records of a
model restricted by its own access rules.
task-3503204
closesodoo/odoo#138942
Signed-off-by: William André (wan) <wan@odoo.com>
Signed-off-by: Dylan Kiss (dyki) <dyki@odoo.com>
To avoid developers to update the dict of `_events`
in their overrides, to not alter by mistake
the default behavior.
Using a frozendict will force them to create a copy
of the dict.
closesodoo/odoo#123261
Signed-off-by: Arnaud Joset (arj) <arj@odoo.com>
This commit is a preparation for the new page from template feature.
In order to make it possible for new page templates to be customizable
at several levels from themes, it was decided to create several layers
of primary templates.
Those templates are build from the descriptions found in manifest files
under the new `new_page_templates` key.
The same principle is also applied for configurator pages (described in
manifest files under the `snippet_lists` key) because we noticed that
some of the changes that were made in themes for some blocks were not
supposed to impact the "drag'n'drop" version of the block, but only
the version used inside the pages generated by the configurator. (E.g.
connecting shapes between blocks)
The manifest entries now have the following structure:
```py
'snippet_lists': {
'somepagename': ['s_block_name', ...],
},
'new_template_pages': {
'somecategoryname': {
'sometemplatename': ['s_block_name', ...],
},
},
```
This commit finds those entries in the manifests and creates the
following primary templates:
- `s_block_name`: already exists, this is the block that is drag and
dropped using the website builder
- `configurator_s_block_name`: specialization of `s_block_name` used in
all pages generated by the configurator
- `configurator_somepagename_s_block_name`: specialization of
`configurator_s_block_name` for that specific page
- `new_page_template_s_block_name`: specialization of `s_block_name`
used in all new page templates
- `new_page_template_somecategoryname_s_block_name`: specialization of
`new_page_template_s_block_name` used in new page templates of that
specific category
- `new_page_template_somecategoryname_sometemplatename_s_block_name`:
specialization of `new_page_template_somecategoryname_s_block_name` for
that specific template
For the template pages defined in `website` it also creates primary
templates that assemble `t-snippet-call`s of the most specific block
templates. Those templates are named
`new_page_template_sections_somecategoryname_sometemplatename`.
task-3381714
Part-of: odoo/odoo#126719
The issue with the t-cache (discribeds with a test in previous commit)
is that the key/value can be anything. It can be based on other t-cache
(assets in the example) but could be anything else.
The proposed solution will clear the t-cache when ANY other cache is
cleared. This is similar to the behaviour when the t-cache was
introduced (single ormcache)
Also sligly improve logging to precise what was cleared
closesodoo/odoo#138647
X-original-commit: aa69fa9f8efed0da45c601e5d57ce252446e376f
Signed-off-by: Xavier Dollé (xdo) <xdo@odoo.com>
This reverts commit 4573ca0c83eb63785016f4389a5157efb21fa9a4.
Because now, `display_name` is implicitly on every form (last breadcrumb
item). Then it will be queried by `onchange` calls. When we create a
new record, `_rec_name` can be `False` and the display_name will be a
technical one: '<model_name>,<NewId0x...>' which is uglier than the
previous situation showing 'New'.
Part-of: odoo/odoo#138061
Replace all the calls to get_resource_path to the better file_path or
directly use file_open when not needed
Doing both a get_resource_path and file_open means checking twice that
the file exists.
Doing a simple path concatenation before a file_open is safe.
If given to another method (e.g. etree.parse), calling file_path is
the prefered method.
Note that get_resource_path used to return False when the file does
not exists while file_path/file_open raises a FileNotFoundException
closesodoo/odoo#135607
Related: odoo/upgrade#5187
Related: odoo/enterprise#47475
Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
at checkout use the invoice address as billing address instead of
main address if the invoice one is defined. Add the functionality to
add new billings addresses at checkout.
task-3258835
Part-of: odoo/odoo#118428
Babel's named / implicit formats (short, medium, long, ...) come from
the CLDR, which can get tuned as debates get settled, cultures shift,
etc... as a result using these formats can break tests on any babel or
even CLDR release (technically nothing stops distros from updating
their bundled babel with new CLDR data).
b77eb98bbf6bc937efb7941802c0794ae3622094 previously did some
mitigation of this issue, but even if they're not yet in distros
further Babel updates (e.g. 2.12) already affect some of the patterns
we're using.
Proactively mitigate this issue more by only using explicit datetime
patterns (and time patterns, date is fine because it retrieves the
pattern from the lang rather than default to babel patterns) in the
date/time formatting tests. This means only specific terms still vary,
and those should be a lot more stable / reliable than e.g. futzing
with separators and minor formatting issues.
closesodoo/odoo#137181
X-original-commit: 3547e980428cc1dd11c8e82446e7d7f824b9f6f8
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
Since [1] qweb library is not used anymore, rendering this test useless.
1 : 4b0a951af6closesodoo/odoo#136610
Signed-off-by: Raphael Collet <rco@odoo.com>
The 'like'/'ilike' operators automatically add the wildcard character
(`%`) at the beginning and at the end of the value. This commit fixes
the incorrect usage.
closesodoo/odoo#136007
Related: odoo/enterprise#47886
Signed-off-by: Raphael Collet <rco@odoo.com>
The `=like`/`like` domain operators are accent-insensitive, but still
case-sensitive. This is not really coherent, since `unaccent` is a best
effort to find records from the client, and it is the same idea behind
being case-insensitive. Also, `=like`/`like` cannot be used from the web
client, and we use them in domain to search from the Python side.
Moreover, adding `unaccent` to `=like` can be very inefficient when
searching for a prefix ('prefix%'). In fact, PostgreSQL can use btree
index to find prefix matches, but because we create dy default btree
index without unaccent (when we put
`index=True/'btree'/'btree_not_null'` on the field), PostgreSQL cannot
use this index.
Part-of: odoo/odoo#136007
We introduce a new class of objects to wrap SQL code together with its
parameters. It is designed to be easily composable and to discourage
SQL injections. Its API is similar to the methods of module 'logging':
the code is a format string, and the positional parameters are meant to
be merged into it using the string formatting operator.
# default and increment are parameters of the SQL code in first argument
term = SQL("COALESCE(value, %s) + %s", default, increment)
# term can safely be injected into another SQL, besides regular parameters
query = SQL("SELECT %s FROM mytable WHERE id = %s", term, id_)
The SQL wrapper can return the final SQL code string as query.code, and
the corresponding parameters as query.params (list). The cursor method
execute() can now take an SQL object, and execute it just like
cr.execute(query.code, query.params)
It is quite easy to make SQL objects safe against SQL injections: if the
code is a string literal, then the SQL object is guaranteed safe,
provided the SQL objects within its parameters are themselves safe.
Part-of: odoo/odoo#134677
In this viewtiverse, the heroes remove the context dependencies for
`get_views`, from the views and python fields (such as domain). To reduce
inconsistencies and the number of rpc.
Current issues:
* There may be inconsistencies in views at the JavaScript level. Some
overrides modify the behavior of get_views or domains on fields via
context keys, therefore by changing the action, the rendering may be
different. However, these views are cached. However, the cache key
(Javascript) does not reflect the entire context, and requires additional
post-processing from the server.
* Multiple rpc for the same rendering. get_views being dependent on the
context, as soon as it changes, a new rpc is performed. In most cases,
when JavaScript needs the same view, there is no change depending on the
context, the rpc is useless.
* Inconsistency when rendering subviews, some views could be different
depending on the context, this context can be modified in the view itself
via the context attributes. However, the JavaScript client does not redo
an rpc for each change of these sub-contexts. Therefore the result may be
inconsistent.
Solution:
Limit as much as possible the number of context keys provided when calling
get_views, and use the context provided as a cache key. The authorized
keys are 'lang' and '*_view_ref'. For the cache key, options are added in
the get_views method.
Instead of using the context, it is inserted into python expressions.
This will be evaluated by JavaScript and thus avoids inconsistencies.
task-3414108
task-3414068
closesodoo/odoo#135145
Related: odoo/enterprise#47584
Signed-off-by: Raphael Collet <rco@odoo.com>
Update (some) query counters according to runbot state.
Also make some tests deterministic when involving company name.
Task-36879 (Mail: Support MultiCompany Aliases)
closesodoo/odoo#135288
Related: odoo/enterprise#47345
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
For model_terms translated fields if a translation for a lang(fr_FR) has never
been defined
before this commit
when update translations for both en_US and fr_FR, the new translation for fr_FR
cannot be saved.
after this commit
new translations can be correctly saved when en_US and fr_FR are updated at the
same time.
closesodoo/odoo#135103
X-original-commit: ef4b195eeac178a14eb47f4e6cc61ddc97f78866
Signed-off-by: Raphael Collet <rco@odoo.com>
Signed-off-by: Chong Wang (cwg) <cwg@odoo.com>
With input 'name email@domain.com' (missing chevrons allowing to clearly spot
the email part) 'getaddresses' returns ('', 'name email@domain.com) i.e. the
whole input is considered as being the email.
To improve the heuristic we can add a fallback by recalling 'getadresses'
on the input with spaces replaced by commas when it found only an email and
no name. The new email will be split into sub pairs allowing to find the real
email and various name parts, allowing to make a new name / email pair.
Emails should not contain spaces thus this is coherent with email formation.
This fallback actually comes from a specific code done in '_parse_partner_name'
of Partner model. Supporting it directly at tools level make the behavior
coherent for all models.
Task-2612945 (Mail: Defensive email formatting)
X-original-commit: odoo/odoo@18c71edf59
Part-of: odoo/odoo#134934
PURPOSE
Be defensive when dealing with email fields, notably when having multi-emails
or email field containing an already-formatted email.
SPECIFICATIONS
As of rfc5322 section 3.4.1 local-part is case-sensitive. However most main
providers do consider the local-part as case insensitive. With the introduction
of smtp-utf8 within odoo, this assumption is certain to fall short for
international emails. We now consider that
* if local part is ascii: normalize still 'lower' ;
* else: use as it, SMTP-UF8 is made for non-ascii local parts;
Concerning domain part of the address, as of v14 international domain (IDNA)
are handled fine. The domain is always lowercase, lowering it is fine as it
is probably an error. With the introduction of IDNA, there is an encoding
that allow non-ascii characters to be encoded to ascii ones, using 'idna.encode'.
Also remove usage of 'email_re' in mailing email check. It is too restrictive
compared to real formatting we support (or try to). Valid outgoing emails
were directly canceled, notably when containing unicode.
Task-2612945 (Mail: Defensive email formatting)
X-original-commit: odoo/odoo@3ce5fb3072
Part-of: odoo/odoo#134934
PURPOSE
Be defensive when dealing with email fields, notably when having multi-emails
or email field containing an already-formatted email.
SPECIFICATIONS
When having multi-emails input in an email field, 'email_normalized' field is
currently 'False', as they expect the field to contain a single email. This
has several drawbacks
* searching partners or fetching information based on emails does not work as
most tool methods use 'email_normalized' which is False (see e.g.
'_message_partner_info_from_emails', '_mail_find_partner_from_emails'
or 'find_or_create');
* blacklist is not available as it is based on 'email_normalized';
* mass_mailing wrongly considers those emails as invalid and cancel their
mail and related trace, as it tries to skip sending emails to invalid
emails;
Be more defensive and use first found email in case of multi-emails field.
Other emails are ignored. It is already an improvement that does not break
flows in stable and allow more emails to be sent.
before
-> email: '"Raoul" <raoul1@raoul.fr>, raoul2@raoul.fr'
-> email_normalized: False
after
-> email: '"Raoul" <raoul1@raoul.fr>, raoul2@raoul.fr'
-> email_normalized: raoul1@raoul.fr
A side effect is that it helps finding back some partners, as indicated in
tests where less phantom partners are created. It also helps suggested
partners / emails flow in discuss.
Task-2612945 (Mail: Defensive email formatting)
X-original-commit: odoo/odoo@90218186c5
Part-of: odoo/odoo#134934
PURPOSE
Be defensive when dealing with email fields, notably when having multi-emails
or email field containing an already-formatted email.
SPECIFICATIONS
Main fix in this commit: fix multiple nested formatting in 'email_formatted'
computation for <res.partner>. Other use cases are mainly left untouched as
we let users deal with their input. In summary :
* double format: if email already holds a formatted email, we should not use
it to compute email_formatted, like
name: Name / email: 'Format' <email@domain.com>
-> before '"Name" <"Name" <email@domain.com>>"
-> after '"Name" <email@domain.com>''
* multi emails: sometimes this field is used to hold several addresses
like email1@domain.com, email2@domain.com. We currently let this value
globally untouched by extracting emails and joining them, as we do not
expect email_formatted to be a list of emails. Extractin emails allows
to filter out extra text stored in email field, like
name: Name / email: text, email1@domain.com, email2@domain.com
-> before: "Name" <text, email1@domain.com, email2@domain.com>
-> after: "Name" <email1@domain.com,email2@domain.com>
* invalid email: if something is wrong, better keep it in email_formatted
than harcoding "False". Indeed this eases management and understanding
of failures at mail.mail, mail.notification and mailing.trace level. This
behavior does not change as it was already implemented like that even if
not sure it was intended;
Task-2612945 (Mail: Defensive email formatting)
X-original-commit: odoo/odoo@9175bbd8e2
Part-of: odoo/odoo#134934
Move tests currently in mail about helpers defined in 'tools/mail.py' directly
into base. No need to test it in mail, there is no specific override or
behavior change compared to base.
Regroup partner related tests in base into 'test_res_partner'. This breaks
part of test history but it helps knowing which features are tested.
Task-2612945 (Mail: Defensive email formatting)
Part-of: odoo/odoo#134934
PURPOSE
Be defensive when dealing with email fields, notably when having multi-emails
or email field containing an already-formatted email.
RATIONALE
Add tests related to not standard usage of email field. Two main use cases
are tested here
* formatted emails: `"Full Name" <email@domain.com>` stored into the 'email'
field;
* multi emails: `email1@domain.com, email2@domain.com` stored into a single
'email' field;
Additional tests: tests with unicode / ascii / case / wrong formatting are also
added to check the support in normalize and format methods.
IMPLICATION
Email field is generally managed as "containing a valid email". This means
it is sometimes used as it in 'formataddr' as well as to perform searches or
identification checks. Example of issue: partner 'Raoul' has a formatted email
like "Raoul" <raoul@raoul.fr>. Using 'formataddr' in email_from leads to
from: "Raoul" <"Raoul" <raoul@raoul.fr>>
-> which is incorrect (but often dynamically corrected by email servers);
Email field holding multi-emails are not normalized, as current normalize
is done only if the field holds a single email. It means
* no easy finding based on 'email_normalized', e.g. various tools like
'_mail_find_partner_from_emails' or 'find_or_create' do not find partners
based on this email;
* no exclusion list management;
* issue with formatting, like
to: "Raoul" <raoul@raoul.fr,raoul.other@raoul.fr>
-> which is incorrect (but often dynamically corrected by email servers);
USAGE: OUTGOING EMAILS
Those use cases currently generate faulty outgoing emails. This is valid for
recipients ('email_cc', 'email_to') as well as author ('email_from').
For formatted emails: `email_to` is formatted again based on name and email
which leads to sending emails to `"Full Name" <"Other"<email@domain.com>>`.
Note that multi emails without formatting may work as it leads to email_to
`"Full name" <email1@domain.com,email2@domain.com>`. Some outgoing email
servers correctly send multiple emails. It depends on their fault
tolerance.
USAGE: FIND BASED ON EMAIL (NORMALIZED)
When searching for partners (e.g. using '_mail_find_partner_from_emails' or
'find_or_create') normalized version of input is used.
In case of multi emails sanitize is 'False', as normalization expects a single
email in the field. Therefore no partner is found. In processes that do a
"search or create" (e.g. using a template on a record) this leads to creating
a new partner (or several partners in case of multi emails) each time.
USAGE: OTHER FLOWS
Other flows are build on top of '_mail_find_partner_from_emails' / 'create'
of outgoing emails and are impacted by formatted email / multi email usage.
Those include notably
* mass_mailing: '_message_get_default_recipients' should be defensive to
give correct values when creating mailing emails;
* mass_mailing: faulty emails is based on normalize and multi-emails are
considered as faulty and ignored;
* after post hook: '_message_post_after_hook' tries to link messages without
author (but email_from) with newly-created partners, when partners are
created from chatter. It is therefore impacted by those corner cases;
* marketing_automation: built on top of mass_mailing and suffers from the
same issues;
USAGE: UNICODE
Unicode in emails should be supported. 'formataddr' and IrMailServer notably
received fixes to support unicode. Some check performed on email addresses
fail when unicode is involved, which leads to some emails not being sent
while they could.
SPECIFICATIONS
Add tests related to those corner cases. Also add tests for computation of
`email_formatted` field of Partner model. It currently generates wrong email
values for the same corner cases (multi emails, formatted emails).
Tests are also added for the computation of `email_normalized` field used
notably for blacklists. It is not computed currently when being in multi
email mode which prevents from any blacklist mechanism as well as make
email finding harder. `_mail_find_partner_from_emails` tool method is also
tested with multi email as it uses the same heuristic as normalized email
field.
Tests are also added for mass mailing, when having to mail documents that
have a partner with formatted emails / multi-emails, or that have an email
field with formatted emails / multi-emails.
Also restore a test removed at odoo/odoo@afcb734908 while it should have been
updated to state that email addresses containing non-ascii characters are
supported.
Add some tests for tools methods used in various email processing flows.
Unicode tests are also added.
In future commits we will try to make email usage a bit more defensive to
try to lessen issues with that kind of use cases.
Task-2612945 (Mail: Defensive email formatting)
X-original-commit: odoo/odoo@fc8442f133
Part-of: odoo/odoo#134934
Add 'id' in partner ordering, to be sure searching on duplicated partners is
deterministic.
In mail, use standard ordering when searching on users to be deterministic.
As ordering on users is based on name then login which is unique, this is a
safe ordering and can be used as it.
Task-2612945 (Mail: Defensive email formatting)
X-original-commit: odoo/odoo@1e6d50a141
Part-of: odoo/odoo#134934
Server actions that 'update the record' have a mechanism to allow users
to easily select a selection value if the field they want to update is a
selection field (instead of having to type the technical value
directly).
Before this commit, this mechanism incorrectly stored the selection's
name instead of the value (e.g. 'Done' instead of '01_done'), making the
write crash when the action was run.
closesodoo/odoo#134625
Signed-off-by: Bouvy Damien (dbo) <dbo@odoo.com>
*: base, crm, digest, mail, mass_mailing, sms, test_base_automation,
website_forum, website_sale
This commit makes "Automated Actions" more discoverable and usable by:
- Adding a menu in the kanban header config dropdown to add/edit them.
- Creating a new custom kanban view for a clear understanding of each
automated action record and its associated actions.
- Introducing new "smart" triggers that appear in the form view based on the
chosen model:
- Updated Values category:
- "Stage is set to" when a `stage_id` field exists in the model,
allowing users to select a specific stage value.
- "State is set to" when a `state` field exists in the model,
allowing users to select a specific state value.
- "Priority is set to" (`priority`) where users can select a specific priority.
- "User is set" (`user_id`, `user_ids` fields)
- "Tag is added" (`tag_ids` field) where users can select a specific tag.
- "On Archive"
- "On Unarchive"
- Timing Conditions:
- "After creation"
- "After last update"
- Deprecating previously known triggers "On Creation" (`on_create`) and "On
Update" (`on_write`) to simplify the user experience. "On Creation & Update"
(`on_create_or_write`) is retained and renamed to "On save".
- Changing the `ir.actions.server` Many2one relationship to a One2many
relationship. Automated actions can now directly contain multiple actions,
eliminating the need for an "Execute several actions" action in automation
rules.
- Introducing a widget for the new `ir.actions.server` One2many field for a
clearer understanding of multiple actions.
This commit also enhances the usability of "Server Actions" (`ir.actions`) by:
- Removing the `ir.server.object.lines` model and the associated `fields_lines`
One2Many field. The attributes of the removed model are now merged into
`ir.actions`. An action can now write to only one field, and the create action
is now a name_create action.
- Adapting the form view when creating an "Update the record" action. The value
field shown adapts itself based on the field to update; this field can be a
`reference` field for a `one2many` `update_field_id`, a `one2many` field for a
selection `update_field_id`, or a `text` field otherwise.
- Refactoring the form view to display only relevant details and other
miscellaneous improvements.
Taskid: 3085360
Part-of: odoo/odoo#114352
Co-authored-by: Florent Dardenne <dafl@odoo.com>
Co-authored-by: Julien Carion <juca@odoo.com>
Co-authored-by: Lucas Perais <lpe@odoo.com>
before this commit, from list view users can install
module using the button in list view and from the
action button.
initially the Install button was not available in the
list view and only option to install multiple apps was
from the action button.
but with the introduction of the button in list header
there is no need for an another server action to
perform the same.
after this commit, the activate modules server action
will be removed from the code and its related test
and also newly added Install button will be renamed
to "Activate" to align with the button in kanban and
form.
closesodoo/odoo#133544
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
The inherited field of a custom field cannot be deleted
Steps to reproduce:
1. Install Contacts and Studio
2. Go to Contacts and open any contact
3. Toggle Studio
4. Add a field of any type in the view, remove it and close Studio
5. Go to Settings > Technical > Database Structure > Fields and search
for `x_studio`
Solution:
Mark the inherited field as manual if its parent field is manual and
allow the deletion of inherited custom field if we also delete its
dependency
Problem:
The inherited field was not marked as custom so it was impossible to
delete it
opw-3093581
closesodoo/odoo#133820
X-original-commit: 526f3407c7c5b4cd014a4d091ca01b9617e6e938
Signed-off-by: Raphael Collet <rco@odoo.com>
Signed-off-by: Guillaume Merlin (megu) <megu@odoo.com>
Since 3c62ca1eb9, if the `_rec_name` value
is False, `name_search` and `name_create` will return a tuple of
(<id>, False). This is an invalid response for the web client,
which triggers a JS traceback.
Instead of using the old behavior (returning an empty string, resulting
in a partially invisible row in the Many2one selection),
use the same fallback as when the `_rec_name` doesn't exist.
Since `display_name` should never be Falsy anymore, remove part of the
test_mail_message_values_fromto_long_name that covers the
Falsy `display_name` case.
task-3424154
closesodoo/odoo#133691
X-original-commit: 0cb9e66edd9b7142a6e56bc6ee6491e6d6047e51
Signed-off-by: Raphael Collet <rco@odoo.com>
Signed-off-by: Rémy Voet (ryv) <ryv@odoo.com>
RATIONALE
As multi-company tolerant alias domains will soon replace the usage of
configuration parameters, having them in base then replaced by more advanced
models in mail would be complicated to handle and not useful. Move those
ICP to 'mail' so that all mail configuration is done in that module.
SPECIFICATIONS
Move config parameter used for alias domains configuration in 'mail' module.
Base should be as simple as possible and let mail deal with mail server
complexity.
Move 'mail.{bounce/catchall}.alias' used with 'mail.alias.domain' to make
bounce and catchall emails. Move 'mail.default.from' as it will be integrated
into alias domains in some form.
Note that 'mail.default.from_filter' stays as an ICP in base as it is a
more global default parameter. It is used as default value in 'connect' when
no mail_server is used and no from_filter can be retrieved.
Some tests in 'base' are either fixed, either moved directly into 'mail'.
We now differentiate base behavior (without ICP) from configurable behavior
(with ICP in mail).
Task-3453347 (Mail: Move Mail ICP from Base to Mail)
Prepares Task-36879 (Mail: Support MultiCompany Aliases)
Part-of: odoo/odoo#130750
From filter could be ill-defined, like ' ' or ','. This commit just make
some code more defensive against those values.
Task-3453347 (Mail: Move Mail ICP from Base to Mail)
Prepares Task-36879 (Mail: Support MultiCompany Aliases)
Part-of: odoo/odoo#130750