Thursday, September 3, 2026
31 changes · 19.0
Resolved issues and error corrections
Uploading BIS3 vendor bill XML files no longer fails when the supplier country is not included in the file. The system now falls back to the country saved on the related partner record, helping Belgian companies process supplier bills more reliably.
Original PR description
Steps to reproduce: - Install accounting and create BE company - Create BIS3 xml where there's no country for AccountingSupplierParty - From BE company, upload the xml vendor bill Current behavior: Error when trying to upload xml Expected behavior: No error Cause of issue: Currently there's no check to see if a country exists in the BIS3 xml. This PR adds a check and adds a fallback to get the country attached to the partner record if there's none present in the xml opw-6498830 Forward-Port-Of: odoo/odoo#284862 Forward-Port-Of: odoo/odoo#284554
Fixed an issue where selling and invoicing a shared product in Point of Sale could fail when another company’s vendor data was cached. The change ensures only vendor information relevant to the active company is considered, reducing interruptions for multi-company users.
Original PR description
**Steps to reproduce:** - Install PoS and Purchase - Make 2 companies, A and B - On product "Office Lamp" that is accessed by both companies, put Partner A in the vendor tab for company B - Company A…
**Steps to reproduce:**
- Install PoS and Purchase
- Make 2 companies, A and B
- On product "Office Lamp" that is accessed by both companies, put Partner A in the vendor tab for company B
- Company A should have a Partner A and Partner B in this tab
- In the stock, set a replenishment for company A, with Partner A on Office Lamp
- Go to company B and open the PoS
- Try to buy Office Lamp while requesting an invoice
- An access error appears
**Why the fix:**
When requesting an invoice in the PoS, we try to create the stock picking. Doing so will trigger the replenishment rules linked to the product to be recomputed.
Those are executed when we **flush_all()**, processing Company A's replenishments as sudo(), meaning all of Company A's **seller_id** are fetched and cached. This means the product's **seller_ids** now contains Company A's **seller_id**, even though we are currently in Company B.
While trying to get the product's code, we iterate over **product.seller_ids**, but we do not have access to every record in that product.
https://github.com/odoo/odoo/blob/b8e5291d103d9f43bd8db6d2dfe708076a57ea37/addons/product/models/product_product.py#L337-L343
As we don't have access to those, we get an access error when we stumble upon it.
To avoid those errors, we now filter the sellers to only have the ones compatible with our current Company in the given product we are currently buying.
Another solution would be to do **product.invalidate_recordset(['seller_ids'])** before looping over it, but feels more like a band-aid than the current fix IMO.
We could also write **self.lines.product_id.mapped('code')** in **_create_order_picking(self)** to have the solution be in PoS directly, but the error might arise from somewhere else at some point, and this just hides the issue by adding the code to the cache so that we don't have to fetch it again later.
opw-6308182Portal users could sometimes see a “not found” page when opening a task from a project they follow, even though the task appeared in their task list. This fix checks their normal read permission for the task, making access more consistent and reducing confusion.
Original PR description
Before this commit, the portal user could have a request not found when he wants to access to a task from a project he follows even if he can access to the task in /my/tasks route. This commit makes sure the read access are checked instead of checking if the user can access to the task thanks to the token since the token if the one of the project.
Invoices that are already paid or have no remaining balance will no longer automatically include a payment QR code. This avoids wasting invoice space and reduces the chance that customers mistakenly try to pay an invoice that is already settled.
Original PR description
**Description of the issue/feature this PR addresses:** It does not make sense to provide a QR Code for payment when the invoice is already settled because this would just waste space on the invoice and might be wrongly interpreted **Current behavior before PR:** QR Code always assigned without consent (most likely by the user) **Desired behavior after PR is merged:** QR Code should only applied automatically when the invoice is unpaid Info: @wt-io-it --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix prevents Saudi e-invoices from being submitted more than once to ZATCA when a user only has read-only access to journals. It ensures the successful submission record is saved correctly, avoiding duplicate reporting and related compliance issues.
Original PR description
**Steps to reproduce:** This issue is hard to reproduce because it requires a live ZATCA connection: - As a user with read-only permission on journals, send an invoice to ZATCA. - You get an access error on the journal, and the invoice is unchanged (You can try sending it again to ZATCA). **Issue:** What happens is: - A user with read-only permission on journals sends an invoice to ZATCA. - If ZATCA responds with a 200 (successfully submitted), we try to write on the field `journal.l10n_sa_latest_submission_hash` - With no write permissions, the write fails and all changes are rolled back (on odoo, not on ZATCA) - We can send the invoice again to ZATCA, resulting in duplicates. **Solution:** - Added a sudo when writing on the field: `journal.l10n_sa_latest_submission_hash` opw-6320179 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#281468 Forward-Port-Of: odoo/odoo#278728
Automated checks for financial reports were updated to wait for report lines to finish loading before continuing. This reduces random test failures and helps keep report functionality validation stable after performance-related rendering changes.
Original PR description
After https://github.com/odoo/enterprise/pull/127516 report lines that are folded or filtered are no longer kept in the DOM with d-none. They are now removed entirely to reduce the number of rendered components on large reports. This made several tours non-deterministic. The tours unfolded multiple lines in succession using positional nth-child selectors. Since unfolding now creates new rows, the next positional selector could match an existing row before the previous DOM update was completed, causing the tour to click the wrong line. The tour would then wait indefinitely for a child of the intended line to appear. We should wait for the expected child line after each unfold before continuing with the next action. Also make some positional triggers more specific by checking the expected line name. This ensures that each DOM update is completed before the following nth-child selector is evaluated. [error-946088](https://runbot.odoo.com/odoo/error/946088)
The Helpdesk SLA Status Analysis report now calculates "Hours Open" from ticket creation to ticket closing, matching the Ticket Analysis report. This gives managers consistent and accurate reporting on how long tickets stayed open, instead of confusing it with time to assignment.
Original PR description
1. Open Helpdesk > Tickets and create a ticket on the team "Customer Care", assigned to yourself 2. More than an hour later, move it to the "Solved" stage to close it 3. Open Helpdesk > Reporting > Ticket Analysis, switch to the pivot view and pick the "Hours Open" measure -> the ticket holds the hour it stayed open 4. Open Helpdesk > Reporting > SLA Status Analysis and pick the "Hours Open" measure as well -> the ticket holds nothing, as it was assigned as soon as it was created odoo/enterprise#47454 added the "Hours Open" measure of the ticket analysis to the SLA status analysis, but computes it up to the assignment date instead of the closing date. The measure therefore holds the hours until the ticket was assigned, which the report already offers as "Working Hours to Assign". With this commit, both reports count the hours from the creation of the ticket to its closing. Forward-Port-Of: odoo/enterprise#130170
The French reports module now checks for duplicate VAT declaration XML files before sending them to Aspone. This helps avoid rejected submissions and prevents unnecessary paid contacts with the service provider.
Original PR description
When sending an xml to aspone, they will check if a duplicate declaration exist, and if it's the case, then they will refuse it. Since contacting aspone cost us money we will block the sending before that. task-6420220
The return creation wizard now checks for duplicate returns only within the relevant company. This prevents users working with multiple active companies from being incorrectly blocked by returns that belong to another company.
Original PR description
To reproduce the issue: 1) Create two companies in Belgium: A and B 2) Manually create a return for A before its opening date 3) Switch to company B, and keep A active as well 4) Try creating a return of the same type and at the same date as in 2) ===> The wizard blocks you and displays a warning saying there's already a return at this date. There is, but for another company. We fix that by properly filtering the company when searching for existing returns. Moving the _read_group inside the loop on self is okay here: we'll never compute that field for multiple wizards at once.
This fixes an internal automated test for Canadian CPA005 payment processing by ensuring expected results are checked in a consistent order. It helps keep validation reliable and prevents false test failures, with no direct change to customer-facing features.
Original PR description
Sorts the expected items in `test_cpa005` to ensure consistent ordering. runbot error: https://runbot.odoo.com/odoo/error/941567 Forward-Port-Of: odoo/enterprise#127703
This pull request improves several Odoo Enterprise apps by fixing visibility, reporting, scheduling, testing, and timesheet issues, while also updating internal web components for the newer interface framework. Business users should see clearer email buttons, more useful overtime reporting, more reliable tax return checks, and fewer inconsistencies in planning and timesheets.
Original PR description
See commit messages for details. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fixes an issue where company-specific invoice rules could incorrectly make analytic fields mandatory on unrelated screens like Work Centers or Employees. The default analytic plan setting is now respected when a screen does not provide a business context, preventing unnecessary or confusing mandatory requirements for users.
Original PR description
### Issue: When an analytic plan has applicability lines with a company filter, the applicability is incorrectly applied on views that do not define a `business_domain`, such as Work Centers or…
### Issue: When an analytic plan has applicability lines with a company filter, the applicability is incorrectly applied on views that do not define a `business_domain`, such as Work Centers or Employee views For example, if a plan has: - Default Applicability: Unavailable - A line with Domain: Invoice, Company: My Company, Applicability: Mandatory Opening the analytic distribution on a Work Center shows `Mandatory` instead of the default `Unavailable` ### Cause: In commit https://github.com/odoo/odoo/commit/ffcf2ee1a3185ef73db93bfd95625844506692c5 `_get_score` was updated to return `0.5` when the applicability line's company matches the caller's company, even when no `business_domain` is provided In `_get_applicability`, the loop selects the first rule whose score exceeds the current minimum, which starts at `0`: https://github.com/odoo/odoo/blob/710e056e5171af2ab72d7d7793da3518f12faf5e/addons/analytic/models/analytic_plan.py#L255-L264 A score of `0.5` is enough to win over the default applicability, so a company-only match on a domain-specific rule incorrectly overrides the default when no `business_domain` is passed ### Steps to reproduce: - Install `mrp` and `accountant` with demo data - Enable Analytic Accounting in Settings - Open the Internal analytic plan and edit its applicability line: -- Remove the account prefix -- Default Applicability: Unavailable -- Domain: Invoice, Company: My Company (SF), Applicability: Mandatory - Go to Manufacturing > Configuration > Work Centers - Open any work center and click on Analytic Distribution Before the fix, Internal is shown as Mandatory instead of Unavailable Removing the company from the applicability line confirms the issue opw-6404884 Forward-Port-Of: odoo/odoo#280312
This fixes internal test failures that could occur around midnight in Belgium due to a mismatch between UTC and the configured local timezone. It helps keep automated validation stable without changing business functionality for users.
Original PR description
## Issue By default in Odoo, `datetime.now()` returns the UTC time, which is two hours behind the local time in Belgium. This leads to two tests failing when executed between 00:00 and 02:00 Belgian…
## Issue By default in Odoo, `datetime.now()` returns the UTC time, which is two hours behind the local time in Belgium. This leads to two tests failing when executed between 00:00 and 02:00 Belgian time: `test_ir_sequence_interpolation_dict` and `test_ir_sequence_iso_directives`. The `_interpolate_dict` method (responsible for interpolating the prefix/suffix from the sequences) specifies the tzinfo when calling `datetime.now()`: https://github.com/odoo/odoo/blob/9c67949be529eb86886b3d5bde08e81e048ecfe7/odoo/addons/base/models/ir_sequence.py#L211-L212 Since this is not the case in the tests, the tests evaluate the date using UTC. This creates a two hours difference between the time expected and the time actually used by `next_by_code`. The tests thus fail between 00:00 and 02:00 because the evaluate dates from both `datetime.now` calls differ, leading to a mismatch in the expected prefixes. ## Fix We force the `env.tz` on the `datetime.now()` call, to mimic the behavior from the `_interpolate_dict`. runbot-242662
The demo payment provider now handles refunds correctly after a manually captured payment. This prevents transactions from getting stuck with an incorrect negative authorized amount, making demo checkout and refund testing more reliable.
Original PR description
Issue: --- When using manual capture, you can refund the transaction but it will be only authorized, and you'll then be blocked with a negative authorized amount and the impossibility to refund it. This seems to be specific to demo payment provider. Steps: 1- Enable manual capture on demo provider. 2- Buy a product from shop and checkout and pay. 3- Capture the payment in backend. Then click on post process. 4- Try refund. opw-6413515 Forward-Port-Of: odoo/odoo#282315
Journal entries that are reset to draft and later leave a numbering gap are now identified correctly. This helps accounting teams maintain accurate sequence controls without changing already assigned document numbers.
Original PR description
To reproduce: * create and post 2 journal entries in the same journal * reset to draft the entry with the highest number * create and post a third entry in the same journal The draft entry is not flagged as having made a gap, because at the time of resetting it to draft, it was the last entry and therefore didn't really make a gap. 3 options to solve were considered: * flag all moves when reseting to draft even if they were the last of the chain * if we reset the last move of the sequence to draft, also remove its sequence and put it back to `/` * when posting, check if the previous number was draft. If it was the case, flag it. The last options was taken in this fix to avoid changing the previous behavior while fixing the current issue.
FedEx shipments can now be validated when the main customer contact has no phone number but the delivery address does. This prevents delivery blocking errors by using the available phone number from the related parent or child contact.
Original PR description
Issue ----- Users cannot deliver to a contact's delivery address if the contact address itself doesn't have a phone number. Steps to reproduce ----- - Setup Fedex - Create a contact with no phone number - Create a delivery address for the contact (with phone number) - Create a SO with the contact using Fedex & confirm - Change the partner on the picking to use the delivery address - Validate the picking > Error: missing phone number Cause ----- To populate the `soldTo` part of thepayload, we call `_get_contact_from_partner` with the contact specified on the SO https://github.com/odoo/enterprise/blob/8e60f910a52e3b836e997e54a0b704e5786a28f2/delivery_fedex_rest/models/delivery_fedex.py#L171 https://github.com/odoo/enterprise/blob/8e60f910a52e3b836e997e54a0b704e5786a28f2/delivery_fedex_rest/models/fedex_request.py#L447-L452 The phone number is then taken directly from the contact. ----- Ticket: opw-6427962
Fixed an issue where newly created contextual actions could remain missing from a model's Actions menu, even after refreshing the page. The system now refreshes the relevant view information when action bindings change, so users see the actions they create without stale cached data getting in the way.
Original PR description
### Steps to reproduce 1. **Settings ‣ Technical ‣ Server Actions**, create a server action on any model, type *Execute Code*. 2. Click **Create Contextual Action**. 3. Open the list view of that…
### Steps to reproduce
1. **Settings ‣ Technical ‣ Server Actions**, create a server action on any model,
type *Execute Code*.
2. Click **Create Contextual Action**.
3. Open the list view of that model, select a record, open the **Actions** menu.
Expected: the new action is listed. Actual: it is not — and it is still missing
after reloading the page.
[](https://www.youtube.com/watch?v=ZfZhjLNkI8E)
### Cause
The view `toolbar` is built server side from the action bindings and travels
inside the `get_views` response. The view service serves that response from a
**disk** cache:
[`view_service.js#L98-L102`](https://github.com/odoo/odoo/blob/c3376d7854da41bcf4adae712dbc0c4bb36d8a8d/addons/web/static/src/views/view_service.js#L98-L102)
```js
const result = await orm.cache({ type: "disk" }).call(resModel, "get_views", [], {...});
```
and invalidates it for two models only:
[`view_service.js#L47-L54`](https://github.com/odoo/odoo/blob/c3376d7854da41bcf4adae712dbc0c4bb36d8a8d/addons/web/static/src/views/view_service.js#L47-L54)
```js
if (["ir.ui.view", "ir.filters"].includes(model)) {
if (UPDATE_METHODS.includes(method)) rpcBus.trigger("CLEAR-CACHES", "get_views");
}
```
`ir.actions.server` is not in that list, and `create_action` / `unlink_action`
(the *Create / Remove Contextual Action* buttons) go through `call_button`, so
they are not in [`UPDATE_METHODS`](https://github.com/odoo/odoo/blob/c3376d7854da41bcf4adae712dbc0c4bb36d8a8d/addons/web/static/src/core/orm_service.js#L88-L96)
either. Binding an action to a model therefore never invalidates `get_views`.
### Why it only shows up in 19.0
In 18.0 the same cache was a plain in-memory object rebuilt on every page load
([`view_service.js#L47`](https://github.com/odoo/odoo/blob/9486aa7413896624e01f35ad831783916c40d068/addons/web/static/src/views/view_service.js#L47),
[`#L107-L108`](https://github.com/odoo/odoo/blob/9486aa7413896624e01f35ad831783916c40d068/addons/web/static/src/views/view_service.js#L107-L108)), so a refresh hid the missing
invalidation. The cache is now persisted, so the stale entry survives the reload
and the action stays invisible for good.
### The server side is correct
Creating the action through the ORM and calling `create_action()` the way the
button does, `get_bindings` and `get_views(toolbar=True)` both return the new
action immediately. The ORM cache invalidation works and nothing filters the
binding out, so the stale data is on the client.
### Fix
Invalidate the `get_views` cache for the action models as well, including the
`create_action` and `unlink_action` buttons.
Tested using the 19.0 sha c3376d7854da41bcf4adae712dbc0c4bb36d8a8dThis fixes an issue where employees with the same name could appear in an unpredictable order, causing incorrect or inconsistent leave return dates in partner data and failing automated checks. Employee records are now ordered consistently, making HR-related information more reliable.
Original PR description
Before this commit, TestPartner.test_res_partner_to_store fails on the all-modules and per-country builds: AssertionError: '2024-06-06' != '2024-06-07' : Return date is the return date of the main…
Before this commit, TestPartner.test_res_partner_to_store fails on the all-modules and per-country builds: AssertionError: '2024-06-06' != '2024-06-07' : Return date is the return date of the main user of the partner This happens because the test reads the first entry of the hr.employee list, which holds one employee per user of the partner: back on the 7th for the main user, on the 6th for the other. This comes from "[FIX] hr*: load out-of-office dates from all user employees", which added the employees of the partner to the payload, where it held those of the main user only. The problem is that the list keeps the order of employee_ids, which is 'name' with no tiebreaker, and both employees are named test1, as an employee takes the name of its user and creating the second user renames the partner. Postgres is then free to return either one first, and the failing builds get the second one. This commit fixes the issue by ordering the employees on 'name, id', so that employees sharing a name keep a stable order instead of the one the database picks. The test asserts the whole hr.employee list, one entry per user of the partner, rather than its first entry alone, and that assertion pins the order. https://runbot.odoo.com/odoo/error/945994
Stripe SEPA payments will again show the company name as the bank statement descriptor instead of relying on the order reference. This prevents payment failures when an order reference contains only numbers and avoids checkout disruption for affected customers.
Original PR description
**Steps to reproduce:** 1. Install Sales, l10n_be, payment_stripe and switch to belgian company 2. Switch the admin user's company to the belgian one, and update their contact address to be in Belgium 3. Enable stripe payment provider 4. Add SEPA payment method in stripe configuration 5. Create a sale order with a name that doesn't include any characters (numbers only), confirm, click preview and attempt to make a payment using SEPA **Issue:** `The statement descriptor must contain at least one Latin character.` **Cause:** The previous fix (4fde0232b821c9a1d46d589ff14495f4e19029f4) passed the order reference directly, assuming it will contain characters. The intended behavior is to actually have the company name used in the statement descriptor field: https://support.stripe.com/questions/what-is-a-statement-descriptor-and-how-do-i-update-it This was the existing behavior before the fix, so will revert back to it. opw-6497127
Users can now correct line descriptions on confirmed sales orders while the order remains open, even after delivery or invoicing. This removes confusing behavior where editability depended on the column layout, while still preventing product changes on processed lines.
Original PR description
Descriptions on order lines become impossible to change after the line is delivered or invoiced, even though the order is still open. Interestingly, hiding the product column makes the description editable again. This shows that editing descriptions is already technically allowed, but currently depends on the column layout, which is confusing for users. Keep descriptions editable until the order is locked or cancelled. This lets users correct text without allowing changes to products on processed lines. Desired behavior after PR is merged: After a sale order is confirmed, users can modify descriptions while the order remains unlocked, regardless of the column layout. Products on processed lines remain protected. @moduon MT-15454 opw-6432243 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This change corrects how Adyen payment information is read from incoming payment messages. It helps ensure payments are processed with the right details, reducing the risk of failed or incorrect payment handling for customers and businesses.
Original PR description
opw-6512723 Forward-Port-Of: odoo/odoo#284773
This update restores the correct table layout in the inventory report after a previous change caused extra columns to appear in the report body. Users should see cleaner, properly aligned inventory reports again.
Original PR description
This reverts commit 43add3f72f29c35280869010b897c3c5656f5120. It was adding too many columns in table body after columns were removed from the header in 19.0. opw-6307728
This fix stops the Bulgarian SAF-T setup process from recreating standard accounts or taxes that a customer has intentionally deleted. It helps avoid incorrect accounting records and prevents related setup or upgrade errors.
Original PR description
If a client deletes a standard account or tax, its XMLID can no longer be resolved during the post-init hook. In that case, _load_data() may create a new record using only the provided data, e.g.:…
If a client deletes a standard account or tax, its XMLID can no longer be resolved during the post-init hook. In that case, _load_data() may create a new record using only the provided data, e.g.:
```
('l10n_bg_691001', {'l10n_bg_saft_account_code': '624'})
```
This can lead to incorrect records.
Only update records whose XMLIDs still exist, avoiding the creation of new records when the corresponding standard record has been deleted.
```
File "/home/odoo/src/enterprise/19.0/l10n_bg_saft/__init__.py", line 10, in _add_account_saft_code
Template._load_data({'account.account': Template._get_bg_saft_account_code()})
File "/tmp/tmpbu1ntr1j/migrations/account/0.0.0/pre-ensure-deferred-accounts.py", line 37, in _load_data
return super()._load_data(data, *args, **kwargs)
File "/home/odoo/src/odoo/19.0/addons/account/models/chart_template.py", line 697, in _load_data
created_records[model] = self.with_context(lang='en_US').env[model]._load_records(all_records_vals)
File "/home/odoo/src/odoo/19.0/odoo/orm/models.py", line 5196, in _load_records
records = self._load_records_create([data['values'] for data in to_create])
File "/home/odoo/src/odoo/19.0/odoo/orm/models.py", line 5103, in _load_records_create
records = self.create(vals_list)
File "/home/odoo/src/odoo/19.0/odoo/orm/decorators.py", line 369, in create
return method(self, vals_list)
File "/home/odoo/src/odoo/19.0/addons/account/models/account_account.py", line 1055, in create
)).create(vals_list_for_company)
File "/home/odoo/src/odoo/19.0/odoo/orm/decorators.py", line 369, in create
return method(self, vals_list)
File "/home/odoo/src/odoo/19.0/addons/mail/models/mail_thread.py", line 329, in create
threads = super(MailThread, self).create(vals_list)
File "/home/odoo/src/odoo/19.0/odoo/orm/decorators.py", line 369, in create
return method(self, vals_list)
File "/tmp/tmpbu1ntr1j/migrations/util/orm.py", line 267, in wrapper
return f(*args, **kwargs)
File "/tmp/tmpbu1ntr1j/migrations/base/0.0.0/pre-models-match_uniq.py", line 25, in create
return super().create(vals_list)
File "/home/odoo/src/odoo/19.0/odoo/orm/decorators.py", line 369, in create
return method(self, vals_list)
File "/home/odoo/src/odoo/19.0/odoo/orm/models.py", line 4711, in create
records = self._create(data_list)
File "/home/odoo/src/odoo/19.0/odoo/orm/models.py", line 4887, in _create
cr.execute(SQL(
File "/home/odoo/src/odoo/19.0/odoo/sql_db.py", line 440, in execute
self._obj.execute(query, params)
psycopg2.errors.NotNullViolation: null value in column "account_type" of relation "account_account" violates not-null constraint
DETAIL: Failing row contains (734, null, 1, 1, null, null, null, t, f, f, 2026-08-25 08:18:15.751937, 2026-08-25 08:18:15.751937, no, f, null, null, null, null, 411).
```
upg-4611390
tbg-2902Image upload fields now apply the Android camera workaround only on Android Chromium-based browsers that need it. This keeps camera access available on affected devices while avoiding incorrect file picker options in the native app and unaffected browsers.
Original PR description
Since Android 14, Chromium sends a file input accepting only images straight to the photo picker, which has no "Camera" entry. The image fields work around it by appending `dummy/allowAndroidCamera`…
Since Android 14, Chromium sends a file input accepting only images straight to the photo picker, which has no "Camera" entry. The image fields work around it by appending `dummy/allowAndroidCamera` to their accept attribute: a mimetype which is not an image is enough to get the generic chooser, and its camera, back. https://issues.chromium.org/issues/40937303 That invalid mimetype was appended for everyone, while only the browsers based on Chromium on Android need it: - the issue is an Android one, the desktop file dialogs are not concerned - the native app builds its own file chooser out of the accept attribute, and the invalid mimetype makes it offer the document picker on a field which only accepts images - Firefox and Safari are not based on Chromium and are not affected The workaround is now limited to the browsers needing it, and the expression moved from the template to a getter, since it is no longer a simple concatenation. Code made by Claude Supervised by RFR --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#286074 Forward-Port-Of: odoo/odoo#285643
A rental website test was made independent of the time of day so it no longer fails late in the UTC day. This improves reliability of automated checks without changing customer-facing behavior.
Original PR description
Scenario:
- be (or switch your computer) at time between 21:01 and 23:59 UTC
- run test test_product_attribute_value_config_get_combination_info
Result:
This error is happening:
Traceback (most recent call last):
File "…/tests/test_website_sale_product_attribute_value_config.py",
line 106, in test_product_attribute_value_config_get_combination_info
self.assertEqual(combination_info['price'], price_3_hours)
AssertionError: 6.42 != 15.0
Cause: since the time range is on multiple day, we favor a weekly price
that is more interesting and the result is not the 3 hours price.
Fix: set the date for the test.
runbot-227695
Forward-Port-Of: odoo/enterprise#130062The website editor no longer shows theme-based background options for tab sections where those choices were not working reliably. This avoids confusing website editors with settings that appear available but do not apply correctly.
Original PR description
The theme background options (`o_cc` classes) on the `s_tabs` snippet's tabs doesn't work since 18.4 (html_builder refactor). It was not supported either in previous versions. We decided to fix it so it would be useable in master (20.0) but leave stable versions as is, by restraining the available tabs and removing the theme one. task-5951656 Forward-Port-Of: odoo/odoo#277528
This fix ensures UPS shipment requests can still use a valid customer name when the invoicing address is missing one. It prevents deliveries from being rejected by UPS in cases where invoice addresses were created without a name.
Original PR description
Issue ----- By default, invoicing addresses of existing partners are created without a name. This leads to the deliveries being rejected by UPS. Steps to reproduce ----- - Set Up UPS - Create a Customer - Create an invoicing address with no name - Create a SO for the partner & confirm - UPS delivery - Open the picking and confirm it > UPS rejects the shipment /!\ I could not reproduce in testing environment, so this is based off user steps in their production DB. /!\ Cause ----- The partner being used in `_set_invoice` was changed in #119747 but this use case was missed due to the error not occuring in test mode. ----- Ticket: opw-6485164 Forward-Port-Of: odoo/enterprise#128933
Fixes an issue where creating an additional website could fail when themes and eCommerce features were involved. The system now keeps track of the correct website during theme installation, preventing crashes and allowing website setup to complete reliably.
Original PR description
During theme installation (`button_choose_theme`), Odoo triggers a registry rebuild. This rebuild spawns a fresh environment that strips out the HTTP request and context. As a result,…
During theme installation (`button_choose_theme`), Odoo triggers a registry rebuild. This rebuild spawns a fresh environment that strips out the HTTP request and context. As a result, `get_current_website()` loses track of the active website and incorrectly falls back to Website 1 when generating snippet templates via `_generate_primary_snippet_templates`. This causes a crash when creating a second website if the first website has no theme and the `website_sale` module is installed. Because the system evaluates Website 1, its `theme_id` is empty, and theme-provided configurator snippets are silently skipped. This results in a traceback (`Template not found: 'website_sale.configurator_hompage_s_dynamic_snippet_category_list'`) and prevents the new website from being created. This commit fixes the issue by temporarily injecting the active website ID into the current thread before triggering the theme installation. `get_current_website` is updated to check for `configurator_website_id` on the thread, ensuring the correct website is referenced even across an environment reset. opw-6483323
This fix stops users from creating incomplete order or invoice email templates directly from settings. It ensures new templates are created with the right setup, preventing payment post-processing errors after online orders.
Original PR description
Currently, an error occurs when the scheduled action `Payment: Post-process transactions` attempts to post-process a payment after performing the following steps: - Install `website_sale` with demo…
Currently, an error occurs when the scheduled action `Payment: Post-process transactions` attempts to post-process a payment after performing the following steps: - Install `website_sale` with demo data - Enable payment provider `Demo` for testing - Go to Settings and search for `Order Confirmation` - Under Email, enter a template name that does not exist (e.g., `Test`) - Click `Create "Test"` and save the settings - Go to the website shop, place an order, and complete the payment `KeyError: False` The issue occurs because clicks`Create "Test"` creates a `mail.template` record without setting the required `model_id` field. As a result, `render_model` remains empty, causing an error when `self.env[self.render_model]` is accessed (see code [1] and [2]). This commit fixes the issue by disabling quick creation for the `Order Confirmation` email template using the `no_quick_create` option. Also provides `default_model` in the context to ensure that `sale.order` is pre selected when creating a new email template through the form view. By forcing template creation through the form view, all required fields are properly initialized, preventing the creation of incomplete or incorrectly configured email templates. The same change has also been applied to `invoice_mail_template_id` to ensure invoice email templates are created with the correct default model and cannot be quick-created. [1]: https://github.com/odoo/odoo/blob/bb94f13b38f0bf1ce8886f4630ad42caf6c56325/addons/mail/models/mail_render_mixin.py#L739 [2]: https://github.com/odoo/odoo/blob/bb94f13b38f0bf1ce8886f4630ad42caf6c56325/addons/mail/models/mail_template.py#L125-L128 Sentry-7634490774
This fix prevents the Polish bank verification module from recalculating all existing payments during installation. It helps avoid installation crashes for companies with large payment histories, making deployment safer and more reliable.
Original PR description
account.payment model computes every record l10n_pl_verification_id at module installation (l10n_pl_bank_verification), causing crash in case of db with a large number of records wrong method name correction: _auto_init instead of init and call super after creating the db column see odoo/odoo#282504 Forward-Port-Of: odoo/odoo#285968
Manual quantity-based quality checks can now record a partial failed quantity without blocking the warehouse transfer. This prevents validation errors when checks are created directly from a picking and helps teams keep inventory operations moving.
Original PR description
Version: -------- - 19.0+ Steps to reproduce: ------------------- - Install `quality_control` module - Create a picking order with a product - From the gear menu, create an on-demand Quality Check -…
Version:
--------
- 19.0+
Steps to reproduce:
-------------------
- Install `quality_control` module
- Create a picking order with a product
- From the gear menu, create an on-demand Quality Check
- Set the check to *Control per Quantity* and back to the picking
- Set the done quantity to 10
- Open the Quality Check wizard
- Try to fail 3 units
Issue:
------
Validating the partial failure raises a `ValidationError`:
- Missing required value for the field 'Team' (team_id)
The quality check split is not performed and the picking cannot be processed.
Cause:
--------
Quality checks created on-demand from the picking (via the gear menu) have
no associated `quality.point` or `stock.move.line` — only
`picking_id` is set at creation time.
https://github.com/odoo/enterprise/blob/7d40d6b787511bf2fcbf581859ed2cd38ba3f658/quality_control/models/quality.py#L457
In `_move_to_failure_location()`, the `move_line` branch assumes
`check.move_line_id` is populated. Since it is empty for on-demand
checks, the split logic operates on an empty recordset.
The new quality check for the split is then created via:
https://github.com/odoo/enterprise/blob/7d40d6b787511bf2fcbf581859ed2cd38ba3f658/quality_control/models/quality.py#L493
At this point both `failed_move_line` (a copy of the empty move line) and
`check.point_id` are empty. `_get_check_values(False)` cannot derive
fields normally sourced from the quality point (`team_id`, `company_id`,
`measure_on`, `test_type_id`, etc.), causing the `ValidationError` on record creation.
Fix:
----
- If the quality check is not linked to a move line, find the matching move line
from the picking before splitting the failed quantity.
https://github.com/odoo/enterprise/blob/7d40d6b787511bf2fcbf581859ed2cd38ba3f658/quality_control/models/stock_move_line.py#L94-L97
- `_get_check_values()` normally takes values from a Quality Point.
Since on-demand quality checks do not have one, fill the missing
values (`team_id`, `measure_on`) from the original quality check instead.
This allows manually created quantity-based quality checks to be
split correctly after a partial failure.
---
opw-6428749