Purpose
=======
This commit improves the UI of the mail group module (backend and portal
view), fix some bugs and clean the code.
Bug 1
=====
If a user click 2 times on a confirmation link, an error is raised.
Bug 2
=====
A bug about the website snippets has been fixed;
- Add the snippet to a group in which you are member
- Change the group of the snippet to a group in which you are not member
- The snippet still show "Unsubscribe"
Bug 3
=====
In the portal view, when messages are filtered by month, messages which
are created in the last day of the month appear also in the next month.
Specification
=============
UI
--
Show the Allow / Ban buttons whatever is the state of the message, so
the user can ban / whitelist a message even if there's no pending email.
When we receive an email, remove the "Mailing List" footer. This was a
big issue because when some users reply many times, the footer was
duplicated on each answer.
Improve the form view of the mail group:
- On non-moderated group, show all messages instead of only pending
message
- Show the guidelines stuff on non-moderated groups
Improve the portal view
- show the attachments under every message (not only on opened message)
- improve the template to confirm the subscription of the user
- improve the portal view for mobile device
- do not show rejected messages, even for admin
- do not show the button "X replies" when the mode is not thread
Technical
---------
Split the route "/groups/subscription" into "/group/subscribe" and
"/group/unsubscribe"
Correctly quote the parent email for the emails sent by web version of
Outlook (with the HTML id "divRplyFwdMsg").
ACLs
----
Now only administrators or responsible / moderators can write / unlink
the group.
Fix an ACL issue on the group member where the responsible of a
non-moderated group could not access the members of the group.
Members with same email
-----------------------
Improve the behavior when multiple members have the same email address
(this situation is possible because there's no unique constraint on the
email field of the <res.partner> model.) We now return the most
appropriate member for the given email address and partner.
When unsubscribing by clicking on the confirmation link that we received
by email, remove all members with the same email address.
Links
=====
Task-2599676
See odoo/odoo/pull/73640
closesodoo/odoo#73640
Related: odoo/upgrade#2774
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
This commit removes the pdf and zpl reports for product templates and
variants. Instead, labels are printed via a new wizard allowing to
specify the label quantity, format and optional text.
There are a bunch of usual retail label sizes in pdf or zpl code
Task : 2501730
closesodoo/odoo#69690
Related: odoo/enterprise#20246
Related: odoo/upgrade#2542
Signed-off-by: William Henrotin <Whenrow@users.noreply.github.com>
Previously, having a remove directive in a bundle that didn't match any
file of that bundle's type would raise an error, saying that the path
we're attempting to remove could not be located in the current bundle.
This basically breaks the remove directive inside of xml/js-css hybrid
bundles, because getting the assets path in xml-mode will cause all
remove directives that only target css/js files to fail and vice versa.
This commit fixes that by only raising an error when there were files
that match the extensions currently enabled, and those files were not
found in the bundle.
closesodoo/odoo#75790
Signed-off-by: Simon Genin (ges@odoo) <ges@odoo.com>
Since c53724ebc3, the contact image in contact kanban view for a shipping
or delivery contact type would be the regular placeholder instead of the truck
or money image.
Now, by using the new avatar system, we restore that behavior.
+ we also use that new avatar system to cleanup some code in the kanban in the
form view (`child_ids` field in `Contacts & Addresses` tab). That part was
working fine but wasn't using the new system and needed extra code.
closesodoo/odoo#75709
X-original-commit: a97cbdd033391af75628bed50accfef11c73687c
Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
Signed-off-by: Romain Derie <rdeodoo@users.noreply.github.com>
Purpose
=======
Review the UX of the 2-factor authentication flow in order to make it more clear
and easy to use.
Specifications
==============
This commit applies multiple rewording of instructions, button, etc. Tests have
been adapted accordingly.
It also adds an 'invite to use two-factor authentication' flow that will
send an email to the selected used to redirect them their account security
settings.
- If portal is not installed yet, the user is redirected to his account security
settings in backend.
- If portal is installed, the user is redirected to /my/profile if them are
portal user. Otherwise, the redirection is still done at backend side.
As the backend view of auth_totp wizard is used at frontend side, copyclipboard
widget has to be rebuilt at frontend side (click event, style etc..).
As API key section is now displayed only on debug mode, test urls have been
adapted accordingly.
Task-2487630
Part-of: odoo/odoo#71142
The initial behaviour of ExecutionContext was to
- add the context for the current level of the stack on enter
- remove the context at this same level on exit.
When two ExecutionContext are nested at the same stack level:
- the first one adds it's context;
- the second one overrides the current context;
- the second one removes it at the end;
- the first one fails to remove the context at the same level a second time.
def call():
with ExecutionContext(foo=1):
with ExecutionContext(bar=2):
execute()
In this case we could imagine to combine both Execution managers in one:
def call():
with ExecutionContext(foo=1, bar=2)
execute()
But the semantics is different: ExecutionContext should add one level to
the stack, instead of two. In the first example above, we expect two
additionnal levels:
call
foo=1
bar=2
execute
A simple solution would be to transform the value of the context at some
level to a list of dict, but this would make the copy more difficult.
The decision was taken to change the context storage strategy, going
from a dict where the keys are the level to a tuple of tuples where the
first element is the level.
{3: {foo: 1}, 4: {bar: 2}} => ((3, {foo: 1}), (4, {bar: 2}))
The first benefit is to allow multiple contexts at the same level. The
second one is that we don't need to copy the data structure, since
tuples are immutables and the dicts are coming from kwargs. This means
that saving the context is faster, and the tuple is shared between
multiple samples. This is interesting if we assume that we do more
samples than exec_context mutations.
closesodoo/odoo#75687
Signed-off-by: Xavier Dollé (xdo) <xdo@odoo.com>
- Channels
* "hash tag" avatar with different backgroud colors
* only private channels have lock thread icon
- DM groups
* "users" avatar with different background colors
* no thread icon
task-2584994
closesodoo/odoo#75653
Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
Grouping by many2many has been added with PR odoo/odoo#68958 (commit f4f570c3d6b403512d8523c74acd34d485f46af1)
However the display names are not resolved resulting in the grouping
displaying the actual id of the records.
This also breaks some features such as `read_groups` which expect the
group by data to contain a tuple (id, x) instead of just the id, this
commit adds name resolving on many2many group bys.
Task ID: 2398734
Part-of: odoo/odoo#74985
This code was no more called, as there is the same-ish condition a few lines
above:
```
if (tools.config['test_enable'] or tools.config['test_file']) ...:
```
Moreover, that code was wrong and was crashing if you remove the first if
condition to test that code, as the method is expected to return a tuple.
It would just raise a traceback
```
too many values to unpack (expected 2)
```
Part of #75377
Related: odoo/enterprise#20449
Signed-off-by: Romain Derie <rdeodoo@users.noreply.github.com>
`result` might be a Markup object (eg during tests) or a bytes-like object.
Step to reproduce: click on "Send by Mail" on a SO -> Traceback
Step to reproduce (2):
- Install website_sale
- Add something to the cart
- Go through checkout and click on Pay Now
- Crash, 500 error page, as this step is trying to generate the SO PDF to send
by mail to the customer, which tries to encode a bytes-like object.
```
AttributeError: 'bytes' object has no attribute 'encode'
```
But if you do that flow during a test, eg
```
./odoo-bin -d mydb --test-tags=.test_02_admin_checkout
```
You have a Markup object, thus you had to encode it.
Now, even during test, we return a bytes-like object.
Related to #68299
Community: https://github.com/odoo/odoo/pull/75377
Enterprise: https://github.com/odoo/enterprise/pull/20449
Part-of: odoo/odoo#75377
This commit let you choose a Point Relais® as your shipping address.
It instantiates the Widget only.
It will not handle the print label.
Part-of: odoo/odoo#75281
No real bug was found regarding this issue but it looks
like `nodeAttrs and nodeAttrs.get("media")` was missing from
`ormcache_context` since it is used to generate the output.
closesodoo/odoo#75248
Signed-off-by: Xavier Dollé (xdo) <xdo@odoo.com>
Regarding previous commit, the option parameter can be removed
from _get_asset_content api, followed by a nice snowball effect.
Part-of: odoo/odoo#75248
This commit proposes a mechanism to manually add a frame before a
blocking c-call and triggers it before calling libsaas.compile.
closesodoo/odoo#75519
X-original-commit: f836ff3a67d446cd8b3ab2cf573fab649153e6da
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
Sometimes the profiler provides confusing information. This happens
when calling a C library without releasing the GIL (Python's global
interpreter lock). The time spent in the call will be attributed by the
profiler to the former stack trace, because the collector cannot run
during the call.
This commit adds information on the frame when a given stack frame has
lasted for too long.
X-original-commit: 5e193c5dbcdfbdbab38309ed292131ae1f5d3026
PR #42723 changed the public method context_get on res.users return a
frozendict instead of a classic CPython dict.
Since the default XMLRPC Marshaller does not know how to serialize a
frozendict, this would result in errors when calling the method directly
via the XMLRPC layer.
This commit solves this issue by defining a marshalling procedure for
frozendict objects in our custom OdooMarshaller class, this simply
converts the frozendict into a dict and uses the default dict-to-xml
dump procedure (dump_struct).
Fixes#75412closesodoo/odoo#75478
X-original-commit: e80a299ed910cacac4aa4e64164909af36ce62ad
Signed-off-by: Adrian Torres (adt) <adt@odoo.com>
For some reason _logger.info with exc_info=True inside a recursive
function generates RecursionErrors, presumably because the logger uses
recursion itself to generate the stack trace that is logged.
A simple solution would be to remove exc_info=True, but I've decided to
move the log out of the delete function and simply call it once per
uninstall process with all undeletable IDs, so it's kind of a fix +
optimization.
closesodoo/odoo#75445
X-original-commit: 3a04de569bca10a1d1a01f719635de6842e747b2
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
Signed-off-by: Adrian Torres (adt) <adt@odoo.com>
Co-authored-by: Raphael Collet <rco@odoo.com>
When called with a `srt` as readgroup parameter we get a traceback.
Example:
`read_group([('partner_id', 'in', self.ids)], 'partner_id', 'partner_id')`
TB:
```
Traceback (most recent call last):
File "/home/odoo/src/odoo/14.0/odoo/tools/safe_eval.py", line 330, in safe_eval
return unsafe_eval(c, globals_dict, locals_dict)
File "", line 2, in <module>
File "/home/odoo/src/odoo/14.0/odoo/addons/base/models/ir_attachment.py", line 420, in read_group
if any('(' in field for field in fields + groupby):
TypeError: can only concatenate list (not "str") to list
```
Observed on the upgrade request 22627.
closesodoo/odoo#75416
X-original-commit: 8e7990dd5c069f7b0dba9f3d27f620f0fcad5441
Signed-off-by: Christophe Simonis <chs@odoo.com>
Since now, there was no possibilities to pay a Sale Order in a point of
sale without re-encoding every lines of the sale order in a pos order.
So we've now added the possibility to choose a sale order from the point
of sale, and apply a down payment or settle the selected order. You
still get the possibility to invoice it, and the stock is correctly
managed.
The SO is then updated accordingly to what have been done throught the
POS.
closesodoo/odoo#74096
Task-id: 2500902
Signed-off-by: pimodoo <pimodoo@users.noreply.github.com>
Rename website_calendar module by appointment in order to match
the changes on the enterprise part.
We now no longer use the website module to manage the basics of
online appointments. The portal module is now used in its place.
For additional info, check the enterprise PR.
task-2427015
closesodoo/odoo#72241
Related: odoo/upgrade#2492
Related: odoo/enterprise#18426
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
Purpose is to better understand the use of email_re regex (find emails in a
text) and email_split_tuples (find name and email in a string used in email
headers or as email_from / email_to / email_cc).
Task ID-2377974
Community PR odoo/odoo#61467
This tool function is deprecated. As explained in docstring: "since OpenERP 6.1
please use ir.mail_server.send_email()". Seems we are allowed to finally remove
it.
Task ID-2377974
Community PR odoo/odoo#61467
Before commit[1] there was only one field image_1920 in group with 'colspan=1'.
In commit[1] a new invisible field avatar_128 is added in this group. But due
to this an empty 'tr' element is added in view and it breaks the view.
With this commit we move avatar_128 field outside of the group and placed it
with other invisible fields, so it doesn't break view. And also adding comment
field in new group because it is html field now so it displays nicely.
Followup of odoo/odoo@cb4f597410 and odoo/enterprise@971f3ed9ae
commit[1]: c53724ebc3
LINKS
Task Id-2558824
PR odoo/odoo#74795
PR odoo/enterprise#2011
`update_list` is an expensive operation and could be avoided when no modules are
updated. Particually, it speeds up initial theme installation on website, which
has following code:
```
themes.filtered(lambda m: m.state == 'installed').button_upgrade()
```
Benchmark for Odoo 15: `/website/configurator_apply` spends 1.3 sec for unneeded
`update_list` call.
closesodoo/odoo#75140
X-original-commit: 82ba4994e54fc46cc55a463629727e840349bb6e
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
Signed-off-by: Ivan Yelizariev // IEL <yelizariev@users.noreply.github.com>
The fields dict maps field names to their description. Before this
commit, the field name wasn't specified in the description, meaning
that we could never manipulate the field description without its
key, which would often be convenient.
closesodoo/odoo#75121
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
In the xml file of the list view, it is possible to define a button that
will be placed in a new column. When the user clicks on a button from a
list view, the script will execute the action linked to the corresponding
button. Unfortunately, all the buttons of the list views are not necessary
linked to an action: This is for example the case for the trophy icon of
the survey module. An exception can hence be thrown if the user clicks on
such button.
To solve the issue, we will add the 'disabled' property support for the
buttons and we will add that property to the buttons that do not have
an action. With this property, the script will bind no listener to the
button and it will hence not call the listener causing the error.
task-2612033
closesodoo/odoo#75096
X-original-commit: c698d589e7dfa6fe3df8b4014fe30627693e9043
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
Automatically activate `group_multi_currency` if there is more than one active currency,
deactivate it if there is only one active currency
retain sale/pos feature of activating group_product_pricelist
adapt tests accordingly
Task 2610735
closesodoo/odoo#74396
Related: odoo/enterprise#20106
Signed-off-by: Laurent Smet <smetl@users.noreply.github.com>
PURPOSE
=======
We want to increase the score of the emails sent by Odoo and we want to
avoid them to be marked as spam by the mail clients (gmail, outook...).
SPECIFICATIONS
===============
From filter
-----------
Add a new field on the "ir.mail_server" which is "from_filter". This
field defines the email address for which the outgoing email server can
be used.
The "from_filter" can either define an email address or a domain name.
Use the system parameter "mail.default.from" which allow us to define
a default email address which is used to encapsulate the emails
(default: notifications@<catch.all.domain>).
Mail server priorities
----------------------
When sending an email, we read the FROM header and,
- We first look for a mail server which match the entire mail FROM
in that case, we do not change the email header (not needed)
- If not found, we search a mail server which matches the domain name of
the mail from (do not need to change the headers in that case)
- If not found, find the mail server linked to the "notifications"
email (defined in the system parameter). Then change the FROM header
to the notification email, and put the old one in the name part of
this header.
E.g.
Initial mail from: "Admin" < admin@example.com >
Final mail from: "Admin (admin@odoo.com)" < notifications@odoo.com >
- If no notification email is configured or if no mail server are
found for the notification email, fallback to the old system and
spoof the FROM header. In that case we do not have the choice if we
want to send the email, he will probably be marked as spam.
Sending method priority
-----------------------
In the mail server models, we defined some priorities,
1. Forced SMTP session
2. Forced mail server
3. Try to find the best mail server (see "Mail server priorities")
4. If not found, read the odoo-bin arguments
Bounce
------
As there's no standard for bounce address, we put it in the envelope
(smtp_from). But in some case, it might be considered as spoofing. So,
we use the bounce address ONLY if the mail server is configured for the
entire domain name.
One behavior which might be broken is the following; we send an email as
"std@gmail.com" and the bounce address is on the domain "odoo.com".
Before we received the bounce notifications but we were spoofing the
local part and the domain.
Now
- if a mail server is configured for GMAIL, we do not use the bounce
address (and we might not receive the bounce notification)
- if no mail server is configured for GMAIL, but one is configured for
"odoo.com"
- the FROM header will be "notifications@odoo.com"
- the FROM envelope will be the bounce address
=> In this situation we are spoofing only the local part of the email
but it's allowed as the mail server is configured for the entire
domain name
LINKS
=====
Task-2367946
odoo/odoo#61853odoo/upgrade#1903
Purpose
=======
Split the code of "send_email" in "ir.mail_server" so the changes will
be easier to review.
Task-2367946
odoo/odoo#61853odoo/upgrade#1903
PURPOSE
=======
We want to be able to authenticate our servers with a certificate
for the entire domain name instead of using a username and a password.
SPECIFICATIONS
==============
Add 2 fields on the `ir.mail_server`, which are
- the SSL certificate
- the SSL private key
When we uploaded both files, we use them to authenticate the client of
the SSL connection.
Add 2 options on the Odoo binary, so we can provide the filenames of both
files (like we do for the SMTP username/password).
SETTINGS
========
Note that this type of authentication doesn't work locally for Microsoft
office 365. It seems like Microsoft is blocking non-static IP address
(not able to ping the host locally, but it works on the server).
The host name of the server is defined in the MX DNS record. Then, on
Office 365 you must create an SMTP relay based on a certificate and not
based on a hard coded IP address. The certificate must be valid for your
domain name.
e.g.
Host: openerp-org.mail.protection.outlook.com
Port: 25
Username: <keep it blank>
Password: <keep it blank>
Security: STARTTLS
Email: admin@odoobe.com
New Python dependence
=====================
The standard SSL python library only takes a filename to the certificate
/ private key.
But, we do not want to use attachments and take the full path to the
file (in the filestore) or to create temporary file.
So, we need to use a new library "PyOpenSSL" which allows you to load
a certificate / private key from a byte array.
To make this library work with SMTPLIB we use a wrapper developed
in urllib3 (PyOpenSSLContext).
LINKS
=====
Task-2367946
odoo/odoo#61853odoo/upgrade#1903
Purpose
=======
Revert the commit a757cab857
because the rewriting of the FROM of the emails sent will
be done in a smarter way in master.
Task-2367946
odoo/odoo#61853odoo/upgrade#1903
Currently, empty screen of the settings is not very beautiful
without proper action helper and decoration. It displays only
'no record found' string when no setting is found for the
search string.
With this commit, we make the no content helper for the settings
consistent with other apps. It now displays empty folder and
proper helper message.
TaskID-2588387
closesodoo/odoo#74570
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
This is the same behavior as javascript. Which had been changed during
the refactoring of qweb. t-esc asked for escaping whatever the content.
However, a lot of templates still use t-esc. It is easier to go back to
the previous functionality.
odoo/odoo#74678 fixed the universal traceback which would happen any
time an HTML field would be read, however it's incomplete because:
* it was tested on a field which wasn't HTML in 14.4
* and no markup was put in the field anyway
So the markup being embedded in the XML-RPC document unescaped was
missed, leading to:
* corrupted (partial) responses when the HTML content is XML-valid,
depending on the exact API of the client it might only return the
first or last text segment, or all the text without markup, or
something else
* outright deserialisation error on XML-invalid content (e.g. void
elements like <br>)
The cause being that `Markup` overrides all `str` methods to first
escape their parameters before actually applying on the object. This
means `xmlrpc.client.escape` would basically do nothing, then would
concatenate the `Markup` into the document (stringifying it) and send
the entire thing on its way.
Fixes#74884closesodoo/odoo#74957
X-original-commit: 8a0f7d820cb2296f410be215ffeadd1cefae174c
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
*: tools
The app received many fixes and its code was improved and cleaned. It
was about time to include it directly into the website features.
task-2215118
closesodoo/odoo#74697
Related: odoo/design-themes#478
Related: odoo/upgrade#2709
Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com>
In 01875541b1, HTML fields (and various
methods) were made to return markupsafe.Markup objects.
However at the time I didn't consider that XML-RPC serialization
remains based on type *identity*, and thus the `Markup` object would
not serialize outbound through XML-RPC, and would blow up instead.
This should fix the issue, by serializing Markup objects as str.
closesodoo/odoo#74684
X-original-commit: 165bd3bf88becc42416e49ad2f430e90675219fa
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>