Steps to reproduce:
- define a home action for the user
- delete the action in configuration > Window Action
- refresh to the home page
-> id not found
Solution:
- prevent the deletion of a window action if used as a home action
OPW-2728824
closesodoo/odoo#89420
X-original-commit: b868583690d8560d3cc300b9448f0af32f41d81a
Signed-off-by: yosa-odoo <yosa@odoo.com>
Avoid calling with_user() inside method has_group() when possible, as it
represents a major overhead inside this method which is commonly called. This
sole optimization speeds up the accounting general ledger by about 6%.
closesodoo/odoo#89206
X-original-commit: e858507aaf01c3701bf5642978490d7947acf35d
Signed-off-by: Raphael Collet <rco@odoo.com>
SVG images are considered an xml like format, as a consequence restrictions
apply for manipulating svg type attachments. This poses a problem when a
website designer tries to save a page containing images with svg shapes. This
commit allows writing attachments with an xml like mimetype to anyone with
write access rights on views.
opw-2806930
closesodoo/odoo#89185
X-original-commit: d5aa54ca108eb99c7eb855a7d456bfe2f208a8eb
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com>
Revert commit 54cd73a4f4 as it prevents customers from closing
their pos sessions without timeouting.
closesodoo/odoo#88941
X-original-commit: 43165dc3f7a8cc199219b8a32b65eb0ee7b5c2dd
Signed-off-by: Julien Castiaux <juc@odoo.com>
Signed-off-by: Olivier Dony <odo@odoo.com>
Fixesodoo/odoo#86216
When printing qweb report use the current company.
For example, the company logo printed was always from user company
default instead of the current company.
closesodoo/odoo#86356
X-original-commit: becdd7d54a5dd7dc50ca1458951f98f95b011d56
Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
This is a followup of #86567, where we change the computation of
display_name to match the values of name_get(). Forcing its value to
False instead of the empty string causes many regressions in frontend
applications like website_blog.
closesodoo/odoo#88438
X-original-commit: d467881f66b11021005005584854f30059971b6c
Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com>
Purpose
=======
Migrate subscription to sales order to simplify the code, the UX & make it more flexible for the future and easier to maintain.
Subscription still appears as a separate module.
This PR aims to move the sale.subscription models to sale.order. The implementation is quite similar to the sale_renting module.
Before this PR, sale.subscription records are similar to sale.order ones. A lot of logic is duplicated to handle the subscription line computations, tax handling, etc.
The current implementation of subscription has several drawbacks:
* the sale.subscription records depends on required sale order template.
* it is not possible to mix different periodicity in a subscription. Each partner has as many contract as periodicity needed (monthly, yearly etc)
* when the flow starts in sale_management, the first invoice must be created from the sale application.
* upsell prorata calculation to apply a discount is flawed when the salesman want to apply another discount.
This PR fixes these issues and make subscription more flexible. One record can have subscription lines with different periodicity. Each line have a next_invoice_date and invoices are generated when they are due with the matching lines.
Before this commit, the sale module could not be used to manage subscriptions in an override.
This commit adapts the sale module to odoo/enterprise#21825closesodoo/odoo#82632
Taskid: 2568007
Signed-off-by: Yannick Tivisse (yti) <yti@odoo.com>
Before this commit, the sale module could not be used to manage subscriptions in an override.
This commit adapts the sale module to https://github.com/odoo/enterprise/pull/21825
taskid: 2568007
This fix prevents the `/Annot` key from a PDF PageObject
to cause errors during its handling by PyPDF2.
opw-2811793
closesodoo/odoo#88182
X-original-commit: 1c0fc5b20efb9e5829447f97480d0813c6c9e367
Signed-off-by: William André (wan) <wan@odoo.com>
Most of the extensions of `_name_get` are very similar and only want to
search for the given string in multiple fields.
A lot of extensions also don't take into account the negative operators.
Some implementations were also really outdated and needlessly
complicated.
closesodoo/odoo#86588
Related: odoo/enterprise#25608
Signed-off-by: Raphael Collet <rco@odoo.com>
* Previously, when reconciling journal items in multi-currencies, the exchange difference entry was created only on the full reconciliation. It will now be created directly at each partial to ensure the ratio between amount_residual_currency and amount_residual is always kept identical.
* Also when reconciling two lines, one with a foreign currency and one expressed in company currency, the reconciliation is now made based on the foreign currency.
==== RATIONALE ====
This patch allows to fix the following use cases (among others)
1) When everything is expressed in foreign currency, the reconciliation is made in that currency:
Suppose EUR is the foreign currency and USD is the company currency. Reconciling:
L1: 120 EUR 60 USD (rate 2:1)
L2: 240 EUR 80 USD (rate 3:1)
..leads to a partial of 120 EUR and min(80, 60) = 60 USD
After the reconciliation, L1 is fully matched but L2 is still open with 120 EUR but only 20 USD.
This is the first problem is the current reconciliation because L2 is supposed to have a rate 3:1 so the residual amount should be 120 / 3 = 40 USD.
Since the rate is no longer consistent on L2, the user will probably close the reconciliation by using another line in EUR or will close manually the reconciliation with 20 USD but without any additional exchange difference journal items explaining where this unconsistency comes from.
2) When the current lines are mixing multiple currencies, the reconciliation is made using the company's currency.
In some countries like Mexico, Ethiopia or Costa Rica, the customer is free to pay an invoice using the company's currency instead of the foreign one.
So, suppose USD is the foreign currency and MXN is the company currency.
The invoice is expressed by:
L1: 120 USD 60 MXN (rate 2:1)
If the customer is paying at a date in which the rate is 3:1, he is free to pay
either L2: 120 USD 40 MXN (rate 3:1), either L2: 40 MXN.
In the second case, he is expecting the invoice to be fully paid because its paiement is equivalent to 120 USD at the payment date.
In Odoo, the second case led to an open balance of 20 MXN and the invoice was not completely paid.
Even this situation could be easily fixed by a manual write-off, this makes the Mexican payment EDI very complicated to fullfil correctly because the government is expecting a complete matching between the invoice and the payment.
When the customer is paying multiple invoices or the invoices are paid using multiple payments, the currently generated mexican EDI file in Odoo was wrong.
==== REFERENCES ====
Original idea suggested by hbto@vauxoo.com. Thanks for the contribution and patience of the many persons having, at some point, helped on that.
github issue: https://github.com/odoo/odoo/issues/37469closesodoo/odoo#84201
Task: 2669371
Related: odoo/enterprise#24268
Signed-off-by: Quentin De Paoli <qdp@odoo.com>
This follows up e045e76e35.
Change the heuristics for ordering columns, as padding is not determined
by column size, but by column alignment inside a row. Because in Odoo a
row always starts with a column of size 4, the following columns should
be the ones aligned on 4 bytes, then the ones aligned on 1 byte, then
the ones aligned on 8 bytes.
The analysis in the commit message of e045e76e was not correct, as it
did not take into account the fact that rows themselves are aligned on 8
bytes. So we have: before each row used 40 bytes (+24b header)
attname | typname | typlen
-------------+-----------+--------
id | int4 | 4
create_uid | int4 | 4
create_date | timestamp | 8
write_uid | int4 | 4 -> 4 bytes padding
write_date | timestamp | 8
active | bool | 1 -> 7 bytes padding
After each row uses 32 bytes (8 bytes saved per row):
attname | typname | typlen
-------------+-----------+--------
id | int4 | 4
create_uid | int4 | 4
write_uid | int4 | 4
active | bool | 1 -> 3 bytes padding
create_date | timestamp | 8
write_date | timestamp | 8
Of course, when more columns are present, the space savings depend on
the alignment of the other columns.
closesodoo/odoo#88084
Signed-off-by: Vincent Schippefilt (vsc) <vsc@odoo.com>
Postgres is aligning columns to 4 or 8 bytes, depending on their type.
So, consecutive fixed-length columns of differing size will be padded
with empty bytes due to the alignment requirements.
Before this patch, columns where created in their definition order. Now,
they are ordered based on their size, in order to minimize the padding.
As an example, before each row uses 36 bytes (+24b header):
attname | typname | typlen
-------------+-----------+--------
id | int4 | 4
create_uid | int4 | 4
create_date | timestamp | 8
write_uid | int4 | 4 -> 4 bytes padding
write_date | timestamp | 8
active | bool | 1 -> 3 bytes padding
After each row uses 32 bytes (4 bytes saved per row):
attname | typname | typlen
-------------+-----------+--------
id | int4 | 4
create_uid | int4 | 4
write_uid | int4 | 4
active | bool | 1 -> 3 bytes padding
create_date | timestamp | 8
write_date | timestamp | 8
This saving scheme applies to all rows in all tables. We save between 4
and 8 bytes per row just on the usual create_uid, create_date,
write_uid, write_date.
closesodoo/odoo#87896
Signed-off-by: Raphael Collet <rco@odoo.com>
Before this commit, since https://github.com/odoo/odoo/pull/83574,
attempting to join a call through the channel guest page while being
logged as a portal user would give an acess error.
This commit fixes this issue
closesodoo/odoo#87995
X-original-commit: e6a637dc1d4e024c67b946fbe26a1b1e0dd144f3
Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
Every request comes with a session, a dictionary that is persisted on
the filesystem and that saves various information such as the user
cart on the ecommerce.
When a user simply visits the website, a default session is created and
saved on disk, this bloats the filestore with many sessions. Creating
the session on-the-fly is cheaper than loading it from the filesystem.
With this work the default session is not saved on disk anymore unless
explicitly asked via `session.touch()`.
An exception to the statement "creating the session on-the-fly is
cheaper" is geoip, the ip geolocalization is not cheap. In this work,
geoip have been moved from http_routing/request.session.geoip to a
lazy property core/request.geoip. When requested the info is persisted
on the session. Like other keys from the default session, geoip will not
be persisted unless there is non-default stuff in the session.
Because the CSRF-TOKEN is based on the session-id, it is important the
session-id stays the same across multiples requests even when the
session is not persisted on disk. Even when a session is not persisted
on disk, the session-id cookie is still set so that the next session
created on-the-fly uses the same session-id.
Technical note regarding the session, it has been decided to drop the
session-snapshot protocol and to reintroduce a "modified" flag. It has
been decided not to use werkzeug's session (which natively comes with a
"modified" flag) and to keep our own session object. We decided to
extend MutableMapping instead of dict; using MutableMapping we only
have to override __setitem__ and __detitem__; using dict we would had to
override update()/pop()/... too.
Task: 2789035
Part-of: odoo/odoo#86015
The profiler can be useful to debug random behaviour, but the frame
duration becomes irrelevant in this case.
A new option allows to make all sample last exactly one second,
making the duration correspond to the number of frame,
especially useful for sql and query count debugging.
task-2796579
Part-of: odoo/odoo#85525
When a filename is given to the function binary_content it was shadowed
by _binary_ir_attachment_redirect_content if it is an ir.attachment.
To reproduce:
1. Start a brand new database in V14, install any app on which you can add an attachment (like Project or CRM)
2. Add a file as an attachment
3. Try to call the route "/web/content/<string:model>/<int:id>/<string:field>/<string:filename>"
closesodoo/odoo#87879
Solution: Use another variable to store the return value of _binary_ir_attachment_redirect_content and use it if the filename is not provided.
X-original-commit: 55e6097502da6169b85056b4769f4bf7fd230968
Signed-off-by: Wanderscheid Mathieu (mawa) <wama@odoo.com>
Signed-off-by: Julien Castiaux <juc@odoo.com>
Currently, when creating a partner, there could be a situation
in which a commerical field has some access restriction
due to `groups` being set on a the field declaration.
The `sudo()` makes sure it does not happen.
closesodoo/odoo#83205
Related: odoo/enterprise#25828
Signed-off-by: William André (wan) <wan@odoo.com>
The basic idea of this functionality is for users
to be able to put limits on Partners that would
trigger non-blocking warnings when trying to confirm new:
- Sales Orders
- Invoices
when that partner has too many open invoices.
task-2722165
Part-of: odoo/odoo#83205
Steps to reproduce:
1) start from a clean database (http_routing should not be installed).
2) go to the app menu and install project (don't install via `-i`!!).
3) traceback: `request` has not attribute `is_frontend` while rendering
a template.
The `is_frontend` attribute on request is set by the http_routing
module. At the moment the "install now" button is clicked, http_routing
was not installed so the `is_frontend` attribute was not set.
FF to the end of the installation: the registry is reloaded to include
the modules that have been installed, http_routing among them.
We are in a tricky situation: (1) there is a request, (2) http_routing
is installed and (3) the `is_frontend` attribute is missing from the
request.
This situation is illegal, when http_routing is installed, the
`is_frontend` attribut should always be set. In this work we reset the
missing attributes using sensitive default values via post-init hooks.
closesodoo/odoo#87684
Signed-off-by: Julien Castiaux <juc@odoo.com>
Because the `savepoint` and `clear` calls are nested inside the
`assertRaises` context, if one of them happens to throw *the exception
we're looking for* the interpreter will jump back to the `with`, the
`assertRaises` will swallow the exception (and count it as a success)
and the function will end having not gone through a `yield`.
This is rather frustrating to debug as it's easy to forget that a
`with` is a control flow structure, leading to a seemingly impossible
error.
We can fix this by initializing and `__enter__`-ing the savepoint
first, but doing this by hand is a bit iffy and not really
future-proof as the addition of more fallible steps during the
initialization phase of `_assertRaises` could lead to the savepoint
not being properly disposed of. Furthermore once in the scope of the
"actual" assertRaises we want the savepoint to unwind first (otherwise
the savepoint won't be rolled back when the exception *we are
expecting* gets raised).
As it turns out `ExitStack` offers the solution to our woes though
it's a bit tricky at first glance: while modifying the cleanup queue
in-place is haram, `pop_all` allows moving cleanup callbacks from one
queue to the next.
This means we can first add the savepoint to one stack and get its
errors (if any) correctly reported, cover the rest of the
initialization, then move the savepoint from one stack to an other, in
order to correctly order the coverage of the `yield` (and the userland
code).
closesodoo/odoo#87733
X-original-commit: b1cd4e4e3c918b4b08d27b30b1017fc898d4b08a
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
Steps to reproduce
- Install procurement_jit
- Go to settings
- Search for 'serv'
-> Re**serv**ation is highlighted but also ba**se**d
closesodoo/odoo#87611
X-original-commit: 8bbfbfbf0eb6c2238542166984b558b5734c7a2a
Signed-off-by: Hubert Van De Walle <huvw@odoo.com>
Steps to follow
- Go to Settings
- Type 'Import' in the search bar
-> 'Import & Export' is displayed
Cause of the issue
`_wordHighlighter` works on the HTML as a string
Solution
- Use textContent to get the correct text value
- Replace the content of the highlighted element by
* a textnode with the text before the matched substring
* a `span.highlighter` with the search word
* a textnode with the text after the matcher substring
Other issues
A string concatanated css rule was used to filter the matching elements
This could cause an invalid selector
-> Filter nodes by their textContent instead.
opw-2778304
X-original-commit: fba1b833eab46ff7a20f7151978394da3aaaa566
Part-of: odoo/odoo#87611
When setting up the PG replication, the slave is considered in recovery
mode. However, `LISTEN / NOTIFY` is not supported in this mode, leading
to an endless loop of crashes.
In recovery mode, we simply deactivate the feature.
closesodoo/odoo#87619
X-original-commit: 6389a64953081130d62f2a1703a27ddfa751098b
Signed-off-by: Nicolas Martinelli (nim) <nim@odoo.com>
The odoo.addons.web.controllers.main python module have been splitted
over multiple files on the basis 1 controller = 1 file. In this work we
adapt all modules to use the new imports.
A non-exhaustive list of where stuff have been moved:
* main.Home --> home.Home
* main.Session --> session.Session
* main.WebClient --> webclient.WebClient
* main.clean_action --> action.clean_action
* main.ensure_db --> home.ensure_db
The complete list is accessible in odoo.addons.web.controllers.main.
closesodoo/odoo#87571
Related: odoo/enterprise#25746
Signed-off-by: Raphael Collet <rco@odoo.com>
Install auth_signup, go to /web/login, 500 Internal Server Error.
auth_signup extends the /web/login template and in this extension calls
`keep_query()` which has been wrongly moved from base to http_routing in
commit 880954ebfc. Here, we restored `keep_query()` in the base module
but moved in ir_qweb.
closesodoo/odoo#87491
Related: odoo/enterprise#25754
Signed-off-by: Julien Castiaux <juc@odoo.com>
Since v15 and the owl improvment, the signatures of other users
could not be modified in HTML (as v14 and previous) as the
codeview button was missing.
In order to modify the signature with this commit in v15:
1/ Access a user
2/ Edit
3/ Click on the codeview button (Odoo Green button with </> inside)
4/ Copy/paste your html code
5/ (/!\) Click again on the codeview button
> You should see your HTML signature
6/ Save
opw-2728194
follow-up of https://github.com/odoo/odoo/pull/80788closesodoo/odoo#87506
X-original-commit: 573a33d10d0cc830ab6e23b4ec512f9394530c90
Signed-off-by: Simon Goffin <sig@odoo.com>
Signed-off-by: Vergote Baptiste (bve) <bve@odoo.com>
There has been a change in the code for the state_id for Mexico City. Since the beginning of 2022, the new code is CMX instead of DIF.
opw-2801208
closesodoo/odoo#87419
X-original-commit: fd72db46667e4e612a0f1d70a9e3e3ccf163de43
Signed-off-by: Josse Colpaert <jco@odoo.com>
Signed-off-by: Desausoi Laurent (lade) <lade@odoo.com>
Since
https://github.com/odoo/odoo/commit/d2e0b48271dbd8cd7bbdbc5c2c1649c55c51417b,
qweb view from imported module are counted. the issue is that qweb view
created with the wysiwig editor of studio got an external ID from
studio_customization module which is declared as imported
So those views were wrongly counted for the maintenance fee.
Solution
--------
Exclude qweb view from studio_customization module
closesodoo/odoo#87424
X-original-commit: 77db024140e4f7c9ae8e6b5eb95de857afbab0da
Signed-off-by: Christophe Simonis <chs@odoo.com>
This flat structure makes caching easier if odoo adds shared caches for
example. In addition, the use of idempotent names makes it possible to
compare methods during development.
closesodoo/odoo#85110
Related: odoo/design-themes#554
Related: odoo/enterprise#24622
Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
There were inconsistencies in the calls to `_render`.
* the view context could contain information that misled developers.
Indeed, the context and value of the view are not supposed to be found
in the rendering. Thus by calling `ir.qweb` with the name of the
template, we ensure that there is no unwanted information and in
addition the cache key is that of the name of the template which saves
a query.
* the context used for rendering was modified by a method on
`ir.ui.view`, except this is not information used by this model. There
is now a `_prepare_environment` method residing on `ir.qweb`. This
method allows to modify the value dictionary as well as the context in
which the rendering will be done. This preparation of the data as well
as my security check is done only once per rendering. This also saves
some queries
* Freeze options for rendering were inconsistent. It could be that
options on which rendering depends were not part of the cache key. Thus,
depending on the user who generated the generation of the rendering
function, there was or was not information in the template. For example
for automatic branding. This is no longer possible, because it is the
context that is used. The options serving as a cache key are only
recorded for information (for the profiling system for example). A
simplification of the `ir.qweb.field` models could be made.
The report rendering and call `ir.qweb` instead of `ir.ui.view`.
Part-of: odoo/odoo#85110
This fixes a problem that occurs with conditions on one2many fields,
where most conditions are translated with a subquery like
"model".id IN (
SELECT "comodel"."model_id" FROM "comodel" WHERE ...
)
The issue occurs when the subquery return NULL values, i.e., when the
field "model_id" in the subquery above can be NULL. The fix simply
consists in adding the condition "model_id IS NOT NULL" in the WHERE
clause of the subquery.
The problem with NULL values returned by subqueries is the fact that
they make the SQL condition undetermined instead of false, and this
discards some of the results returned by a query. Simply consider:
id NOT IN (1, 2, 3)
The value id=3 makes the condition false, while i=4 makes it true. Now
consider that the set also includes a NULL value, like:
id NOT IN (1, 2, 3, NULL)
The value id=3 makes the condition false, but the value id=4 makes it
undetermined. Therefore this condition is actually undetermined for all
possible values of id, and a query containing that condition simply
returns nothing!
closesodoo/odoo#87285
X-original-commit: 6d680bac0333c6c7ce9f056cba0e1f7e9fa22f9c
Signed-off-by: Vincent Schippefilt (vsc) <vsc@odoo.com>
Signed-off-by: Raphael Collet <rco@odoo.com>
This fixes two problems that occur with conditions on many2many fields:
the subtle bug caused by NULL values that are returned by subqueries,
and the performance of those subqueries.
The problem with NULL values returned by subqueries is the fact that
they make the SQL condition undetermined instead of false, and this
discards some of the results returned by a query. Simply consider:
id NOT IN (1, 2, 3)
The value id=3 makes the condition false, while i=4 makes it true. Now
consider that the set also includes a NULL value, like:
id NOT IN (1, 2, 3, NULL)
The value id=3 makes the condition false, but the value id=4 makes it
undetermined. Therefore this condition is actually undetermined for all
possible values of id, and a query containing that condition simply
returns nothing!
Regarding performance, consider a domain like [('tag_ids', '=', False)].
It is currently translated in SQL as
"model".id NOT IN (
SELECT "model_id"
FROM "model_tag_rel"
WHERE "model_id" IS NOT NULL
)
PostgreSQL does not handle well this "NOT IN" expression when the
relation table is large, and uses some very inefficient query plan in
that case. The inefficient query plan is possibly related to the
special handling of NULL values, by the way. This commit changes the
above expression to a "NOT EXISTS" expression (as below), which is
executed with a much more efficient query plan, even with large tables.
NOT EXISTS (
SELECT 1
FROM "model_tag_rel"
WHERE "model_tag_rel"."model_id" = "model".id
)
This change was motivated by a use-case with 2.7M account moves, 11M
account move lines and a many2many relation table with 2.3M lines
(`account_move_line_account_tax_rel`). The query was timing out (15
minutes), and it now takes 15 seconds.
We have replaced all the conditions on many2many fields to use the
relational operators EXISTS and NOT EXISTS.
A test has been added to reflect a case where the many2many table
contains NULL values, like the one for channel_partner in regards to
partner_id and guest_id.
task-2753782
X-original-commit: 334b2aa2aa437d2ed86130f2ed426025f8fe4b86
Part-of: odoo/odoo#87285
Co-authored-by: Didier Debondt <did@odoo.com>
Until now using a groupby on a view containing a reified field added
with studio was not possible.
Because `read_group` uses these pseudofields as simple fields when they
are not actually columns in the table.
With `read`, `write`, `create` and `fields_get` it was already
supported.
This commit solves this problem by ignoring reified fields in an
override of `read_group`
opw-2793148
closesodoo/odoo#87186
X-original-commit: a25e25aeab3ed6aa1af57fac13312346b723dbf8
Signed-off-by: Raphael Collet <rco@odoo.com>
mail_* = mail, test_mail, test_mail_full, test_mass_mailing
PURPOSE
Improve tooling of mail tests. Use SMTP mockup class available in base tests
in mail tests to have a better and simplified mock tool when dealing with
mail tests. Remove old fashioned code.
SPECIFICATIONS
Include ``MockSmtplibCase`` directly into ``MockEmail`` so that we re-use
existing components for mocking outgoing emails. Also make parameters for
gateway coherent between those two classes (use same test values).
Remove 'sim_error' weird parameter of Mail ``mock_mail_gateway`` and use
standard mock 'side_effect' instead in some specific tests, notably on
SMTP.connect() mock.
Add some assert / tools method and improve existing tools, used for creating
or improving test data. This will be used in future commits when adding new
tests.
Add outgoing mail servers data in mail tests, allowing to make tests closer
to real life use cases.
Remove unnecessary calls to ``_init_mail_gateway`` as it is automatically
done in ``MailCommon.setUpClass()``.
Try to consolidate starting test data, notably with countries, phone numbers
or email in mind to be sure test mail are deterministic.
Task-2673913 (TestMail: Cleanup and improve test coverage)
Part-of: odoo/odoo#86393
We should also use the tzinfo to display only the time of a
datetime.
task-2458013
closesodoo/odoo#86967
X-original-commit: 49604185d04a3f9d7772d2a60771f0e777720eef
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
Add the possibility for portal users to manage API keys
in the frontend portal interface.
- Allow for portal users to manage their API keys if the system parameter
`portal.allow_api_keys` is set.
A settting in `res.config.settings` is added in order
to enable or disable the feature (to add/remove the system parameter)
through a compute field,
to avoid adding a new database column in standard
(as this revision targets stable 15.0).
The setting appear only in debug mode.
- Display the API keys in the portal in debug mode only
(as in the back-end for regular users, in their profile)
- The flow in the frontend is a mimic of the flow from the backend,
the wording and the look and feel is from the back-end.
closesodoo/odoo#86915
Signed-off-by: Denis Ledoux (dle) <dle@odoo.com>