smtplib.SMTP API calls such as .sendmail() or .login() make sure on
their first line that this command is sent, by calling
.ehlo_or_helo_if_needed().
However, test_smtp_connection() does not use SMTP.sendmail() to simulate
sending email, or the email would really be sent.
Instead it uses the low-level API SMTP.mail() which does not make sure
that HELO was sent.
The connection test could be fixed by ensuring that this command was
sent to the server in the test method. However, this could lead to
inconsistent cases where the connection test passes whereas another
usage in the code fails because the command was not sent.
For example, someone could use the low-level API for some reason.
EHLO could have already been sent because if authentication is enabled
smtplib.SMTP.login() calls ehlo_or_helo_if_needed(). Therefore it is
correct to call it ourselves at the end of our connect() method.
STARTTLS sends a first EHLO, negociates the encryption, and leaves the
state without the second EHLO, which should still be sent to the server,
as stated by RFC 3207, in section "4.2 Result of the STARTTLS Command".
https://www.ietf.org/rfc/rfc3207.txtclosesodoo/odoo#34550
Signed-off-by: Julien Legros (jle) <jle@odoo.com>
It's currently possible for binary downloads to be missing an
extension entirely. Generate an extension from the mimetype and use
that. Also ensure the existing extension (if any) matches the
mimetype.
Warning: this may require adding new mimetype/extensions pairs to the
local mimetype database similar to
f413d155df.
Also fix missing or incorrect filenames on records without a filename
field: in some Odoo versions the client would send a filename of
"null", resulting in a download of e.g. "null.pdf" instead of the
attachment or inferred name.
Task 2025716
closesodoo/odoo#34299
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
- Make a SO with a product that have a carriage return in its
description
- Export FEC report
The CSV contains new lines and is not correctly formatted.
opw-2026861
closesodoo/odoo#34385
Signed-off-by: Nicolas Martinelli (nim) <nim@odoo.com>
When registering a payment against multiple vendor bills and change the memo,
the memo must be populated to all the payments. This behavior has been introduced
with the following commit in stable 11.0: c04065abd8
opw:2024652
closesodoo/odoo#34322
Signed-off-by: Simon Goffin (sig) <sig@openerp.com>
Backport from 12.0 to 11.0 (commit: 3cbdfe8807)
- Have two crm teams with the same team leader, and without team members
(team1, team2 as instance).
- Create a new lead, add as Salesperson the team leader, and as Sales
team the second previously created team (team2).
- Save the new lead.
Before this commit, when we save the lead, the sales team will change,
to set the default sales team for the chosen Salesperson, in this case
team1.
opw-2005924
closesodoo/odoo#33898closesodoo/odoo#34327
Signed-off-by: Simon Goffin (sig) <sig@openerp.com>
A special folder named `0.0.0` can contain scripts that are run on
upgrade of any version.
They are useful to make some sanity checks or other verifications to
ensure database consistency.
The first version of this patch used the more eye-catching `any` for
the migration folder, but it was problematic for upgrading from an older
version that doesn't contain this patch.
Using a version "number" containing two dots is required to avoid it
being prefixed with the server version (see `convert_version` method) and
resulting in a version like `10.0.any`.
Such version would have been executed, even without this patch, when
upgrading from an older major server version (9.0.1.0 < 10.0.any).
closesodoo/odoo#34268
Signed-off-by: Christophe Simonis <chs@odoo.com>
- Create 2 included taxes: 21 % and 6 %
- Create a product A with 21 % as default tax
- Create a fiscal position to map the tax 21 % to tax 6 %
- Allow the fiscal position in the POS
- Add product in a POS order
- Apply the fiscal position
The subtotal is not recomputed correctly. On the other hand, if the
fiscal is first set then the product added, there is no problem.
This is because the `fix_tax_included_price` is only called by
`add_product` and not when changing the fiscal position.
opw-2020755
closesodoo/odoo#34260
Signed-off-by: Nicolas Martinelli (nim) <nim@odoo.com>
DROP CONSTRAINT (even with IF EXISTS is specified) acquires an ACCESS
EXCLUSIVE lock on the table, preventing e.g. inserts in an other
transaction, so ir_logging would systematically deadlock if configured
to the same database and a warning would be triggered during install
or update (if that ran ir.logging's init).
1. hand-roll the "IF EXISTS" bit, to avoid taking an ACCESS EXCLUSIVE
lock on the table if the problematic constraint does not exist and
thus doesn't need to be dropped (which by now should be the vast
majority of cases).
Replacing DROP CONSTRAINT with DISABLE TRIGGER does not fix the
issue as *that* acquires SHARE ROW EXCLUSIVE. While that's less
constraitning than ACCESS EXCLUSIVE, it still conflicts with an
insert's ROW_EXCLUSIVE.
2. add a timeout to the logging INSERT anyway, the deadlock is still
an issue if we're updating a database which does have the
problematic constraint, and we want to preclude the possible
eventual introduction of new deadlocks in the future.
closesodoo/odoo#34243
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
Such move lines can be created by POS, when closing a session. Because of commit https://github.com/odoo/odoo/commit/d3453f7d152d486cb5df01b4e40dbde57f59b49e , the cash basis entries are now created *after* reconciling everything (and not during reconciliation anymore). This causes multiple lines of the move created for the sessions to be reconciled together in case a refund was made (partial or not).
Solves ticket 2008085
closesodoo/odoo#34237
Signed-off-by: Cedric Snauwaert (csn) <csn@openerp.com>
The count sales_to_invoice_count was wrong due to the domain
wrote in function _compute_sales_to_invoice. Using 'order_line.qty_to_invoice'
in the domain included duplicate orders in the read_group on 'sale.order'
because there is auto_join=True on the field order_line.
opw:2009808
closesodoo/odoo#34391
Signed-off-by: Simon Goffin (sig) <sig@openerp.com>
- Make a SO with a product that have a carriage return in its
description
- Export FEC report
The CSV contains new lines and is not correctly formatted. This is due
to c712231745.
opw-2026861
closesodoo/odoo#34386
Signed-off-by: Nicolas Martinelli (nim) <nim@odoo.com>
Steps to reproduce:
- Go to CRM > Reporting > Sales Channels
- Click on link Open Opportunities,
Bug:
It displayed all the opportunities instead of just the open opertunities.
opw:2009808
closesodoo/odoo#34365
Signed-off-by: Simon Goffin (sig) <sig@openerp.com>
Steps to reproduce:
- Enable serial numbers
- Create two products P1 and P2 tracked by lots
- Create an inventory adjustment and specify inventory of one product only
- Select P1 and create a serial number for it
- Save the adjustment and change P1 to P2, adapt the quantity to 10 and
validate the inventory adjustment
Bug:
Go to Lots and serial numbers and the created lot was linked to P1 intead of P2
opw:2010934
closesodoo/odoo#34373
Signed-off-by: Simon Goffin (sig) <sig@openerp.com>
Suppose product P has UoM U with rounding R, and the stock move has quantity Q.
Edit the quantity done to be Q + e, with e << R.
By the semantic of the UoM rounding, this should mean that no change has been
done.
However no such check was done, so a message was posted in chatter, of the form:
The done move line has been corrected.
P:
Quantity : 1000.0 -> 1000.0000000000001
opw 2006831
closesodoo/odoo#34124
Signed-off-by: Arnold Moyaux <amoyaux@users.noreply.github.com>
Have a product P values in FIFO, create an incoming stock move.
Suppose P has UoM U with rounding R, and the stock move has quantity Q.
Edit the quantity done to be Q + e, with e << R.
By the semantic of the UoM rounding, this should mean that no change has been
done. However no such check was done, so the move was updated.
As a result, this would mess up the valuation of P.
opw 2006831
Stock.locations should be in no-update:
Limit the impact of recompute fields during the upgrade of stock module. (especially method _compute_product_availability)
Limit the impact on migration
Method _compute_product_availability is triggered during an upgrade of module and during migrations.
This may take a lot of time of big databases
closesodoo/odoo#34074
Signed-off-by: Nicolas Martinelli (nim) <nim@odoo.com>
In the Discuss app, using Chrome or IE11, try to send the same
attachment to different channels. The first attachment is correctly
detected but not the next ones.
The problem is due to a browser inconsistency, on firefox selecting the
same file in an `<input type=file>` triggers the `change` event. This is
not the case on Chrome/IE, selecting the same file doesn't triggers an
`onchange`.
opw-2006647
closesodoo/odoo#34076
Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
On `WebRequest` `__exit__`, when an exception occured,
(in `self.registry.signal_changes` or `self.registry.reset_changes`)
cursor were left unclosed as `self._cr.close` was not called
in such cases.
Having exceptions in the above mentioned method do not happen
often, but when it does it left unclosed and unusable cursors
in the connection pool, and in the extreme case explained below,
it left the connection pool with only unclosed and unusable cursors.
The entire server was then unusable as it no longer had working cursors.
Case:
- Start a multi-thread server with db_maxconn set to 5
- Ensure you do not send any request to the server,
not even with a left open tab on `http://localhost:8069` in your browser
- Send 6 parallel HTTP requests to `/web/login`
thanks to an external thread python script
(See below, at the end of this long commit message)
According to your registry state (if you have a lot of modules installed or not),
and the native Python Garbage Collecting state,
you might end with
- either warnings telling some unclosed cursor were garbage collected,
and therefore closed (by a kind of luck thanks to the Python garbage collecting),
- either, a server completely blocked not accepting any other request
(you can try for instance `curl http://localhost:8069`
and you end up with a `500 Internal Server Error`
This observed issue looks to appear only in 11.0. Not 10.0 or 12.0.
This is because only 11.0 clear the cache during registry loading:
`https://github.com/odoo/odoo/blob/f1706c848d41c47646dabca771996e9b9f788241/odoo/modules/loading.py#L236`
This cache clearing doesn't happen in 10.0 nor 12.0
(in 12.0, thanks to e181f592f3)
When sending the 6 parallel requests,
it uses instantly all the 5 available cursors of the connection pool to handle these requests,
and when each request exits, in `__exit__`, it calls `self.registry.signal_changes()`
which tries to open a new cursor because of
- `self.cache_invalidated` which is True, for all the 6 requests, thanks to the call to `clear_caches`
explained above during the registry loading and the fact all requests have been treated in parallel,
- `with closing(self.cursor()) as cr:`, `self.cursor()` attempting to use a new cursor
(the `closing(...)` does not have any incidence on this issue, despite it could look like guilty)
The attempt to use a new cursor fails, as there is no more available (`db_maxconn` is reached),
raising a `PoolError('The Connection Pool Is Full')` exception.
In the request `__exit__` method, because of this exception raised when calling `signal_changes`,
`self._cr.close` is never reached, and the parallel request therefore left only unclosed
cursors in the connection pool,
therefore leaving the server in a state where it only has unusable cursors
and therefore can't do anything more.
This might look like really bad luck to land in such a state,
but we observed multiple actual case on Odoo.sh,
the one referenced in this commit (opw-2008340) was because of an Outlook client
which launched 18 parallel requests to fetch the email images,
and the server wasn't spawned, therefore neither was the registry.
The server registry was therefore just loaded when it received the 18 parallel requests,
and it therefore triggered this extreme use case.
The server was left unusable for several minutes, until a forced restart.
For reference, here is the script that has been used to trigger the 6 parallel requests:
```
import requests
import threading
threads = []
for i in range(6):
threads.append(threading.Thread(target=lambda: requests.get('http://localhost:8069/web/login')))
for thread in threads:
thread.start()
```
opw-2008340
closesodoo/odoo#34071
Signed-off-by: Denis Ledoux <beledouxdenis@users.noreply.github.com>