Wednesday, August 19, 2026
37 changes · saas-19.4
Enhancements to existing features
Cached website generation requests now schedule a quick follow-up trigger instead of waiting or calling webhooks too early. This helps related notifications run reliably without tying up processing workers.
Original PR description
When a request is cached a webhook won't be called because if we did it immediatly it might arrive before the generator commited. And we don't want to delay the webhook call to not stall a worker just for that. So we simply scheldule a trigger if a request was cached. Forward-Port-Of: odoo/enterprise#128206
The Dutch payroll localization now includes the 2026 resident income tax rate values. This helps payroll calculations stay aligned with the latest tax rules for employees in the Netherlands.
Original PR description
Added 2026 values for the residents' income tax rates rule parameter. task-6462877 Forward-Port-Of: odoo/enterprise#127556
Users can now move through return items in the returns kanban view using the up and down arrow keys without triggering an error. This improves day-to-day navigation and prevents interruptions when reviewing or selecting returns.
Original PR description
In returns kanban view, a traceback occurs when pressing down. Fix this by adding the support for up/down keyboard navigation for returns selection. task-6281033 Forward-Port-Of: odoo/enterprise#128308 Forward-Port-Of: odoo/enterprise#125164
The default waiting time for certain web interface test checks has been increased from a very short window to 10 seconds. This reduces false test failures on busy machines without slowing successful test runs, improving confidence in automated quality checks.
Original PR description
Before this commit, waitFor, waitForNone and waitUntil gave the DOM 200 milliseconds, which the loop turns into 12 animation frames, while contains() and expect.waitForSteps sitting in the same tests…
Before this commit, waitFor, waitForNone and waitUntil gave the DOM 200 milliseconds, which the loop turns into 12 animation frames, while contains() and expect.waitForSteps sitting in the same tests give 10 seconds. 430 call sites in addons reach these three helpers and 29 pass an explicit timeout, so 12 frames is what the other 401 get. The problem is that 12 frames is less than what the client needs on a loaded machine. Measured on "should remove file from html editor if removed from attachment list", on the wait that follows the Full composer button: - 5 to 7 frames on an idle machine; - 11 to 18 frames over 8 runs with the machine at load 10 to 20, 5 of the 8 above the 12 frames the default allows. Those 5 are failing runs, and the same test at load 13 to 29 fails 6 runs out of 6 with the 200 milliseconds, 0 out of 6 with 10 seconds. Note that a longer timeout costs nothing on a green build: the wait ends on the frame the DOM matches, so it only delays the report of a test that was going to fail anyway. Hoot fails the test itself after 5 seconds, 15 in test_js.py, which keeps bounding a wait that never resolves. This commit raises the default to 10 seconds, the delay a tour step already gets in macro.js and the one contains() and expect.waitForSteps already have. https://runbot.odoo.com/odoo/error/946094 Forward-Port-Of: odoo/odoo#282702
Resolved issues and error corrections
The Project task Gantt view now avoids showing misleading progress bars on individual task rows when grouped by assignee in sparse mode. Instead, users see the task's allocated hours, making planning information clearer and less confusing.
Original PR description
## Current behavior: In the task gantt view grouped by assignees and displayed in sparse mode, task leaf rows reuse the row progress bar and display a misleading visual indicator on each task. ## Expected behavior: It would make more sense to not display anything for the progress bar of each task, rather display the allocated_hours per task ## Steps to reproduce: 1. Open Project tasks in Gantt view 2. Group by Assignees 3. Enable sparse display so each task appears on its own row 4. Notice that task rows show a progress bar that is not meaningful for the task itself ## Cause of the issue: Each task rows currently has no meaningful progress-bar semantics, but they still inherit the generic row progress-bar rendering ## Fix: Override the task gantt renderer to hide progress bars, and only show `allocated_hours` for each task opw-6352260
Features or functions removed from Odoo
Current behavior before PR: - In [49f01db](https://github.com/odoo-dev/odoo/commit/49f01dbbe7a607b83865cab308e0dc8193ee9f0b), `getDefaultValueFromGlobalFilter` was introduced just for `GlobalFilterInput`. Desired behavior after PR is merged: - `GlobalFilterInput` no longer relies on this function, so remove the unused getter. Task: [6388147](https://www.odoo.com/odoo/project/2328/tasks/6388147) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submi
Original PR description
Current behavior before PR: - In [49f01db](https://github.com/odoo-dev/odoo/commit/49f01dbbe7a607b83865cab308e0dc8193ee9f0b), `getDefaultValueFromGlobalFilter` was introduced just for `GlobalFilterInput`. Desired behavior after PR is merged: - `GlobalFilterInput` no longer relies on this function, so remove the unused getter. Task: [6388147](https://www.odoo.com/odoo/project/2328/tasks/6388147) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#277761
Miscellaneous changes
Behavior before: When uploading an animated GIF to fields utilizing image responsive sizing or cropping (such as employee avatars or product images), no downscaling or cropping occurs for sub-variants like 'image_128' or 'image_1024'. The responsive fields replicate the exact file size and data footprint of the original large image, leading to heavy storage overhead and unnecessary frontend asset loading. Behavior after: Animated GIF images scale down and crop correctly to match requested r
Original PR description
Behavior before: When uploading an animated GIF to fields utilizing image responsive sizing or cropping (such as employee avatars or product images), no downscaling or cropping occurs for…
Behavior before: When uploading an animated GIF to fields utilizing image responsive sizing or cropping (such as employee avatars or product images), no downscaling or cropping occurs for sub-variants like 'image_128' or 'image_1024'. The responsive fields replicate the exact file size and data footprint of the original large image, leading to heavy storage overhead and unnecessary frontend asset loading. Behavior after: Animated GIF images scale down and crop correctly to match requested responsive dimensions and aspect ratios. Sub-variants take up significantly less space in the filestore, matching proportional dimensions without dropping or stripping the underlying animation loop. Large images that are smaller than requested boxes are safely left un-upscaled to maximize database deduplication. Root Cause: Historically, a legacy safeguard bypassed GIF resizing and cropping because older versions of the Pillow library did not gracefully handle multi-frame sequential image buffers. As a result, standard 'image.crop()', 'image.thumbnail()', or 'image.resize()' implementations would flatten multi-frame animated sequences down into a single, static first frame or throw dimension/mode mismatches during save operations. Fix: Intercept the image processing pipeline when encountering an asset identified as a GIF where 'is_animated' evaluates to True. Implemented a unified, in-place multi-frame helper routine (`_apply_gif_operation`) using PIL's 'ImageSequence.Iterator' to cleanly step through, normalize to a uniform color mode (RGBA), duplicate, and modify each animation frame individually. This single helper handles sequential workflows for both 'crop' and 'thumbnail' operations while preserving individual frame duration arrays and native loop metadata. Both 'resize' and 'crop_resize' leverage this logic to achieve precise dimensions cleanly. Crucially, upscaling (expanding) is intentionally unsupported for animated GIFs. Forcing a low-resolution, 256-color indexed animation to stretch beyond its native dimensions forces heavy color dithering across every single frame. This breaks the sequential LZW pattern compression, causing the resulting file sizes to skyrocket catastrophically. The logic utilizes thumbnail boundaries to completely block this expansion, protecting the filestore from accidental bloat. Benchmark: -------------------------------------------------------------------------------------------- | GIF size | Variant | Size Before (KB) | Size After (KB) | |---------------|--------------------|--------------------------|-----------------------| | (2.5MB) | image_1024 | 2475.87 | 2475.87 | | | image_128 | 2475.87 | 257.93 | |---------------|--------------------|--------------------------|-----------------------| | (3.8MB) | image_1024 | 3724.93 | 3724.93 | | | image_128 | 3724.93 | 463.62 | |----------------|-------------------|--------------------------|-----------------------| | (442KB) | image_1024 | 432.49 | 432.49 | | | image_128 | 432.49 | 36.14 | |----------------|-------------------|--------------------------|-----------------------| | (3.6MB) | image_1024 | 3491.98 | 3491.98 | | | image_128 | 3491.98 | 1728.25 | |----------------|-------------------|--------------------------|-----------------------| opw-6232841 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#282831 Forward-Port-Of: odoo/odoo#273098
This fixes an issue that could cause Colombian point-of-sale order reports to crash when users grouped records by state. The problem came from an outdated internal name left after two localization modules were merged, and the update keeps reporting behavior stable.
Original PR description
l10n_co_edi and l10n_co_dian were two modules merged together, when that happened some of the dian models and systems were renamed to the standard `l10n_co_edi.` system. The sql compute for the state field on pos.order was missed/forward ported up to a version that didn't have that name and as such would crash if you try to group. task-none
Fixed an issue where Dominican Republic electronic consumer invoices could show the company name twice when company address details were not configured. Invoice headers now display the company name only once, making printed and previewed e-CF invoices cleaner and more professional.
Original PR description
Steps to Reproduce: 1. Install l10n_do_edi on a company configured with Dominican Republic localization. 2. Leave the company's address / Document Layout details unconfigured (Settings > Companies >…
Steps to Reproduce:
1. Install l10n_do_edi on a company configured with Dominican Republic localization.
2. Leave the company's address / Document Layout details unconfigured (Settings > Companies > Configure Document Layout).
3. Enable 'Use Documents' on the sales journal and create a Customer Invoice with Document Type = Electronic Consumer Invoice (e-CF).
4. Confirm/post the invoice and print/preview the PDF.
5. Observe the company name is printed twice in the header.
Root Cause:
l10n_do_edi.custom_header explicitly renders the company name via:
[`<span t-field='o.company_id.partner_id.name'/>`](https://github.com/odoo-dev/enterprise/blob/c23d526f53402471dccbbf9460cfd04ce377b5d0/l10n_do_edi/views/report_invoice.xml#L10)
immediately followed by a call to the core template web.company_address_list:
[` <t t-call='web.company_address_list'/>`](https://github.com/odoo-dev/enterprise/blob/c23d526f53402471dccbbf9460cfd04ce377b5d0/l10n_do_edi/views/report_invoice.xml#L11)
When the company's address/Document Layout is empty, `company.is_company_details_empty` evaluates True, causing `web.company_address_list` to fall back to a contact widget with `fields=['address', 'name']` — which renders the company name a second time. custom_header assumed `company_address_list` would never render the name itself, which does not hold in this empty-address state, resulting in the duplicate. This only surfaces on e-CF document types, since custom_header is only set via l10n_do_edi.report_invoice_document's routing (_get_name_invoice_report()), which standard invoices never hit.
Solution:
Made the explicit name span in `l10n_do_edi.custom_header` conditional on whether the company's details are configured. `web.company_address_list` (core, shared across other reports, left untouched) already renders the company name via its contact widget fallback when the address is empty — so the explicit span now only prints the name when `company_details` is populated, avoiding both sources printing it at once.
Result:
Company name now renders exactly once on e-CF invoices, regardless of whether the company's address/Document Layout is configured.
opw-6430918
Forward-Port-Of: odoo/enterprise#127542Fixes an issue where clearing a spreadsheet filter could also remove its default value from the edit panel. This keeps the value currently applied to a spreadsheet separate from the default value shown when editing the filter, making filter setup more reliable for users.
Original PR description
Current behavior before PR: - In [da282d4](https://github.com/odoo-dev/enterprise/commit/da282d4a031fa1c1377a6836acf662100c68bde0), date filter values were cleared when selecting 'All time'. - Based on this, we handled the crash by relying on the active filter value, but forgot that the same component is also used in the edit panel. - As a result, clearing a filter could make its default value disappear from the edit panel. Desired behavior after PR is merged: - Always use the `globalFilterValue` passed to `GlobalFilterInput`. - Keep the current filter value independent from the filter's default value. - This makes the component independent of the active filter state. Task: [6388147](https://www.odoo.com/odoo/project/2328/tasks/6388147) Forward-Port-Of: odoo/enterprise#125153
The document app’s automated tests were updated to reflect improved GIF thumbnail processing. This helps ensure resized GIF thumbnails are validated correctly without failing on outdated byte-by-byte comparisons.
Original PR description
Previously, test_document_thumbnail_status asserted that document thumbnails were byte-for-byte identical to the raw GIF content. Following improvements to GIF handling in image_process(), thumbnails are now correctly resized, causing the raw byte assertion to fail. Update the test to assert the presence and status of the thumbnail rather than matching exact raw unresized payload bytes. [odoo/odoo#281883](https://github.com/odoo/odoo/pull/281883) opw-6232841 Forward-Port-Of: odoo/enterprise#128150 Forward-Port-Of: odoo/enterprise#128032
Enabling Billing in Planning now automatically selects the expected default project after installation. This prevents setup confusion for teams using Planning with Field Service and sales timesheets.
Original PR description
Steps to reproduce: - 1. Create a new database and install Planning and Field Service. 2. Open the Planning settings and enable Billing. Issue: - Billing is enabled but no default project is selected. Cause: - The default of `res.company.planning_project_id` references the module's own `fsm_project` xmlid, but it is evaluated before the module's data files are loaded. The ref resolves to nothing and no value is written. Fix: - Set the project in the post-init hook, once the data files are loaded. task-6460106
Users can now see and select WhatsApp signing templates even before they are approved. This makes it clearer that templates must be submitted for approval, while keeping the related signing flow inactive until approval is complete.
Original PR description
Previously, users couldn’t see or select unapproved WhatsApp templates in Settings, which made it unclear that they needed to submit templates for approval first. Now, users can select unapproved templates, making the process clearer. The flow will still remain disabled until the template is approved. task-6306091 Forward-Port-Of: odoo/enterprise#127910
A leftover employee appraisal action that no longer worked has been removed. Users should use the existing Launch Campaign option to request appraisals for multiple employees, avoiding an error when starting appraisal requests.
Original PR description
#### Description of the issue/feature this PR addresses: The "Request Appraisals" server action on hr.employee calls model._create_multi_appraisals(), a method that no longer exists. Running it…
#### Description of the issue/feature this PR addresses: The "Request Appraisals" server action on hr.employee calls model._create_multi_appraisals(), a method that no longer exists. Running it raises AttributeError: 'hr.employee' object has no attribute '_create_multi_appraisals'. #### Current behavior before PR: Commit 8845eb2ac29 replaced the multi-appraisal flow with hr.appraisal.campaign.wizard: it deleted _create_multi_appraisals and repointed the employee list header button to action_open_appraisal_campaign_wizard, but left the action_create_multi_appraisals record in hr_appraisal/views/hr_employee_views.xml. Its code is now the only reference to the deleted method, so the action crashes whenever it is run. #### Desired behavior after PR is merged: The dangling action is gone. Requesting appraisals for several employees at once is done with the "Launch Campaign" button already present in the Employees list view; action_open_appraisal_campaign_wizard reads active_ids when active_model is hr.employee and pre-fills the selected employees. Nothing references the removed xml id, and the record is not noupdate, so _process_end removes it from existing databases on update; no migration script is required. Verified on a 19.0 database: with the orphan record loaded, updating hr_appraisal with this change deletes it. opw-6408609 Forward-Port-Of: odoo/enterprise#127983 Forward-Port-Of: odoo/enterprise#125630
This update prevents errors when payroll salary attachment names are generated for several employees at once. It helps payroll users view and process multiple salary attachments reliably without interruptions.
Original PR description
Currently, an error occurs when the display name is computed for multiple salary attachments. `ValueError: Expected singleton: hr.employee(58, 56)` After [recent commit], when computing the display name, the employee's display name is accessed through multiple attachment records at once. This results in accessing the display name of multiple employees simultaneously, which raises a singleton error. This commit ensures that the employee is accessed from each individual attachment record when computing the display name. [recent commit]: https://github.com/odoo/enterprise/commit/d9648ef695903113d6ed2f40cd4fcfdd68221fa8 [1]- https://github.com/odoo/enterprise/blob/d913de3097d06e723a08d24907024f83769b1fb8/hr_payroll/models/hr_salary_attachment.py#L150-L153 sentry-7665634830 Forward-Port-Of: odoo/enterprise#127765
The Belgian payroll warning for missing transport benefits will no longer appear for company executives. This prevents irrelevant alerts on executive contracts and keeps the warning focused on regular employees who may need transport benefits reviewed.
Original PR description
The transport benefit warning incorrectly applies to company executives (Joint Committee = 999). This warning is intended solely for regular employees. Steps to reproduce: 1. Go to an employee's contract and set the Joint Committee to 999. 2. Set a monthly wage that results in an annual salary below 34,654€. 3. Ensure no transport benefits are selected. 4. Save the contract; the missing transport benefit warning is incorrectly displayed. This change skips the validation for Joint Committee 999 to ensure the warning only triggers when applicable. task-6442880
The salary configurator now correctly shows included optional benefits as selected when an employee opens a contract offer. This prevents confusion during offer review by ensuring Yes/No benefit choices reflect what is already part of the offer.
Original PR description
Issue: When an employee opens the salary configurator for a contract offer, optional benefits configured with Yes/No radio choices (such as Medical Insurance) fail to pre-select 'Yes' even when the benefit is already included in the offer. Steps to Reproduce: 1. Go to Salary Configurator and open a contract offer that has an active benefit 2. Observe that 'Yes' is not selected for the benefit on initial load. Fix: Ensure that when a contract offer includes a benefit, the salary configurator automatically defaults the radio selection to `Yes`. task-6392064 Forward-Port-Of: odoo/enterprise#127544
Sendcloud return labels now avoid printing the customer's house number twice in the origin address. This improves label accuracy and helps prevent confusion during return shipments.
Original PR description
Issue ----- On return labels, the house number of the origin address (so the customer) is printed twice. Steps to reproduce ----- - Setup sendcloud - Select a return service - Enable "Generate Return Label" - Create a delivery using sendcloud - Validate the delviery > The return label has the house number printed twice Cause ----- For the origin address shown on labels, Sendcloud prints both the address line and the house number. There doesn't seem to be any parsing made on the address line to extract the house number. For the WH -> Customer label, the "from" address is taken directly from the Sendcloud account's configuration. For the Customer -> WH return, we provide it in the `from_` fields of the request. Note that, when including the house number on the address line in Sendcloud, the issue is also present. ----- Ticket: opw-6405054 Forward-Port-Of: odoo/enterprise#127855 Forward-Port-Of: odoo/enterprise#126250
Project Forecast no longer shows the Time Management section in project settings unless the Timesheets app is installed. This avoids displaying irrelevant settings and keeps project configuration clearer for users who do not use timesheets.
Original PR description
**Steps to reproduce:** - Install the project_forecast module. - Go to Projects -> Open the settings of any project (create one if none exist) -> Settings. - You will see the Time Management section. **Issue:** The project_forecast module was forcefully setting the invisible attribute of group_time_managment to 0. This caused the group to remain visible at all times, even when the Timesheets app was not installed. **Fix:** Remove the forced attribute setting from the project_project_view. The visibility is already properly managed by the hr_timesheet module, and project_forecast does not depend on timesheet_grid or hr_timesheet. task-6195716 Forward-Port-Of: odoo/enterprise#128159 Forward-Port-Of: odoo/enterprise#121454
This fix prevents an automated field service planning test from failing because of a conflict with another planning module. It keeps validation focused on the intended behavior, improving build reliability without changing user-facing functionality.
Original PR description
On runbot, the `test_onchange_break_time_after_removing_dates` test was failing during the "all" build due to the `planning_slot_check_datetimes_set_or_plannable_slot` SQL constraint introduced by the sale_planning module. The test previously used `odoo.tests.Form` as a context manager, which implicitly triggered a database save and flushed the dateless test shift to PostgreSQL. Can resolved this by instantiating the Form in memory to validate the frontend `@api.depends` logic without triggering the cross-module database constraint. runbot-6463625 Forward-Port-Of: odoo/enterprise#127859
A test setup for accounting reports now uses the correct PDF generation mock, avoiding crashes during automated validation. This helps keep reporting workflows reliably tested without needing a real PDF engine in the test environment.
Original PR description
Description of the issue this commit addresses: Commit d3b4294a56a5ead3f5ea60714eccdba586f72ef0 changed `_run_wkhtmltopdf` into a subprocess wrapper. A later FW, 64f46c270e062df94d4ce37e3065b3e0a0ba68db, did not account for that change and continued mocking the method with PDF bytes. When the wkhtmltopdf path is reached, reading from those bytes crashes. --- Desired behavior after this commit is merged: This commit mocks `_run_pdf_engine_without_processing`, whose contract is to return PDF bytes, so the tour can validate without invoking a real PDF engine. --- runbot-[944189](https://runbot.odoo.com/odoo/error/944189)
This change restores the expected description for a Point of Sale popup so automated tests can run without errors. It does not change the customer-facing behavior of the popup, but it prevents test failures that were blocking quality checks.
Original PR description
### Issue: In 19.3, the following hoot tests fail with a RunBot error: - "called at right time (when canceling order)" - "called at right time (when canceling order never sent to blackbox)" - "called…
### Issue:
In 19.3, the following hoot tests fail with a RunBot error:
- "called at right time (when canceling order)"
- "called at right time (when canceling order never sent to blackbox)"
- "called at right time (when canceling a combo order)"
### Cause:
Commit 0dfd71b9f4 removed `close` from `ControlButtonsPopup` as the Dialog patch now handles closing via `this.data.close()` With no remaining props to declare, `static props` was removed entirely
Without `static props`, Owl skips all prop validation but emits: "Component 'ControlButtonsPopup' does not have a
static props description"
`mountWithCleanup` forces `warnIfNoStaticProps` to `true` in hoot tests, causing the tests to fail
`close` is declared as optional since `dialog_service.js` always injects it via `subProps: markRaw({ ...props, close })` at runtime, but the component no longer uses it directly
### Steps to reproduce:
- Install `l10n_be_pos_blackbox`
- Enable Developer mode
- Open the JS test UI
- Run one of the failing tests
runbot-941231
Forward-Port-Of: odoo/odoo#277790This fix ensures the payment card shown in the customer portal follows the same rules as the /my/payment_method page. As a result, customers will see a consistent set of payment options in both places, avoiding confusion when cards appear or disappear unexpectedly.
Original PR description
Commit bcfeed4b24f51 introduce `ResPartner._get_payment_tokens` method to determine which tokens are available for a specific partner, in case that method is overridden in some way, the portal card will not be visible/hidden correctly. This commit, use that method to align the portal card visibility with the tokens that will effectively be shown on the `/my/payment_method` page. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The hidden avatar counter in chat-related lists now adjusts correctly when the number reaches double digits, so labels like "+10" are no longer cut off. This makes the count easier to read and avoids confusion in views that use avatar tags, such as Live Chat.
Original PR description
Problem: When using the many2many_avatar_user widget (such as in the Live Chat app), the badge displaying the number of hidden tags overflows if the count reaches double digits (e.g., "+10"). This…
Problem: When using the many2many_avatar_user widget (such as in the Live Chat app), the badge displaying the number of hidden tags overflows if the count reaches double digits (e.g., "+10"). This causes the text to get cut off, making the exact number unreadable. Solution: This commit updates the badge container to properly accommodate larger numbers. The text now fits entirely within the badge without overflowing, ensuring the hidden tag count remains fully readable. Steps to reproduce (runbot v19.3): 1. Open the Live Chat app (or any view using the many2many_avatar_user widget). 2. Add enough agents to a session so the remaining count hits double digits (10 or more). 3. Observe that the badge showing the remaining agent count (e.g., "+10") overflows the badge container, cutting off the text and making it unreadable. opw-6453976 <img width="2655" height="1111" alt="avatar_tag_193_before" src="https://github.com/user-attachments/assets/9c31007d-5300-4bb7-a703-01a13b5bdd10" /> <img width="2655" height="1112" alt="avatar_tag_193_after" src="https://github.com/user-attachments/assets/7b2a4074-3738-4a6c-9649-f6652601f3f3" /> Forward-Port-Of: odoo/odoo#281570
This change makes an automated image upload test more reliable by giving the system a little more time to detect the uploaded image. It helps prevent occasional false failures in testing, especially when the server is under heavy load.
Original PR description
Before this commit, this image field test sometimes failed because it could not find the image that had just been uploaded. Similarly to [1], we increase the waitFor timeout to 1s. Indeed, uploading an image can take time, and with high CPU usage, it could happen that the default 200ms delay wasn't enough. [1] https://github.com/odoo/odoo/pull/168196 runbot error-242406 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#281200
The live chat statistics section now uses the available screen width more effectively on mobile devices. This removes awkward empty space and makes the interface cleaner and easier to read on smaller screens.
Original PR description
Previously, the live chat statistics section did not use the available width on mobile devices, leaving unnecessary empty space and resulting in an awkward layout. This PR makes the statistics cards take the full available width on mobile, providing a cleaner and more consistent interface. <table> <tr> <th>Before</th> <th>After</th> </tr> <tr> <td> <img width="372" height="805" alt="image" src="https://github.com/user-attachments/assets/6934927b-f744-4c93-b63e-1f49ecd33004" /> </td> <td> <img width="382" height="734" alt="image" src="https://github.com/user-attachments/assets/24f8b7e4-9fe7-4fa0-bf64-5d7917623830" /> </td> </tr> </table> --- Task ID - 6372787 Forward-Port-Of: odoo/odoo#274945
Currently an error occurs when user tries to send a pdf of a invoice to a customer. Steps to replicate: (Make sure to have `python 3.14.4` and `pypdf=5.4.0`) - Install `l10n_sa_edi` with demo and switch to `My Saudi Arabia Company`. - Open invoices and create an invoice with customer and an invoice line. - Click `Send` > Again Click `Send`. Error: ``` AttributeError: 'PageObject' object has no attribute 'getObject' AttributeError: No attribute getObject found in IndirectObject or poi
Original PR description
Currently an error occurs when user tries to send a pdf of a invoice to a customer. Steps to replicate: (Make sure to have `python 3.14.4` and `pypdf=5.4.0`) - Install `l10n_sa_edi` with demo and…
Currently an error occurs when user tries to send a pdf of a invoice to a customer. Steps to replicate: (Make sure to have `python 3.14.4` and `pypdf=5.4.0`) - Install `l10n_sa_edi` with demo and switch to `My Saudi Arabia Company`. - Open invoices and create an invoice with customer and an invoice line. - Click `Send` > Again Click `Send`. Error: ``` AttributeError: 'PageObject' object has no attribute 'getObject' AttributeError: No attribute getObject found in IndirectObject or pointed object ``` - A recent [PR] introduced the old `getObject()` API in the PDF/A conversion code, even though it has been renamed to `get_object()` in the modern pypdf API. - As PyPDF2 1.x compatibility has already been removed, `getObject()` is no longer available and causes the error to log on the terminal. - Please refer to [1] and [2]. [PR]: https://github.com/odoo/odoo/pull/281275 [1]: https://github.com/odoo/odoo/pull/248197/files#diff-f3528e61bb9aa2d24d9b57cddafb7429d21216ba29f9dc7e08c92bb617949911L218 [2]: https://pypdf.readthedocs.io/en/stable/meta/changelog-v1.html#details sentry-7663263079 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#282159
`test_prepare_order_vals_rights` builds its PoS user with stock.`group_stock_user`. Until 19.2 `point_of_sale` depended on `stock_account`, so stock was always installed and the xmlid resolved. Since 6a56bd10cec7 split stock out of PoS, the module no longer pulls in stock, and `env.ref `raises "External ID not found in the system" when the module is tested alone. The group was never needed: the test only calls `_prepare_invoice_vals`, which reads the symbol as sudo and touches no stock record
Original PR description
`test_prepare_order_vals_rights` builds its PoS user with stock.`group_stock_user`. Until 19.2 `point_of_sale` depended on `stock_account`, so stock was always installed and the xmlid resolved. Since 6a56bd10cec7 split stock out of PoS, the module no longer pulls in stock, and `env.ref `raises "External ID not found in the system" when the module is tested alone. The group was never needed: the test only calls `_prepare_invoice_vals`, which reads the symbol as sudo and touches no stock record. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#282859
The PoS client draws the QR code itself, but `showQR` was feeding it the result of `build_qr_code_url`, which is not a payment payload but the URL of the report rendering one: /report/barcode/?barcode_type=QR&quiet=0&width=128&height=128&value=... Scanning the code therefore gave the bank app a report path instead of the payment data. All methods going through `res.partner.bank` were affected: `sct_qr`, `emv_qr`, `id_qr` and `ch_qr`. Add `build_qr_code_value`, returning the value th
Original PR description
The PoS client draws the QR code itself, but `showQR` was feeding it the result of `build_qr_code_url`, which is not a payment payload but the URL of the report rendering one:
/report/barcode/?barcode_type=QR&quiet=0&width=128&height=128&value=...
Scanning the code therefore gave the bank app a report path instead of the payment data. All methods going through `res.partner.bank` were affected: `sct_qr`, `emv_qr`, `id_qr` and `ch_qr`.
Add `build_qr_code_value`, returning the value the barcode controller would have encoded, and use it in the PoS. This also fixes `default_qr`, the offline fallback. `get_qr_code_url` is renamed to `get_qr_code_value` as it no longer returns a URL.
task-6465442
Forward-Port-Of: odoo/odoo#282220**Steps to reproduce:** - Configure a Belgian company on a database without demo data - Install Accounting - From Accounting settings, activate Peppol - Use "Odoo Demo ID" as "Peppol EAS" **Issue:** The activation fails while tryings to activate Peppol in production mode. As `Odoo Demo ID` is used, it should activate Peppol in demo mode without issue, but the selected value is not taken into account. **Cause:** In this commit https://github.com/odoo/odoo/commit/6f8c2526a00d, `peppol
Original PR description
**Steps to reproduce:** - Configure a Belgian company on a database without demo data - Install Accounting - From Accounting settings, activate Peppol - Use "Odoo Demo ID" as "Peppol EAS" **Issue:**…
**Steps to reproduce:** - Configure a Belgian company on a database without demo data - Install Accounting - From Accounting settings, activate Peppol - Use "Odoo Demo ID" as "Peppol EAS" **Issue:** The activation fails while tryings to activate Peppol in production mode. As `Odoo Demo ID` is used, it should activate Peppol in demo mode without issue, but the selected value is not taken into account. **Cause:** In this commit https://github.com/odoo/odoo/commit/6f8c2526a00d, `peppol_eas` and `peppol_endpoint` have been renamed to `routing_scheme` and `routing_endpoint`. In the process, some logic has been lost. Previously, the "Peppol Registration" wizard had a related field to the `peppol_eas` field of the company partner. When selecting `Odoo Demo ID` in the wizard, it was also updating the related field to `odemo`. After the refactoring, the related field of the wizard has been replaced by a computed stored field without an inverse method. So changing the value in the wizard doesn't impact the `routing_scheme` field of the company partner that is not set to `odemo`. opw-6421240 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Steps to reproduce: - Install `l10n_fr_pdp` and `Accounting` > Switch to `FR Company` - Activate `French electronic invoicing` - Create New Invoice with `FR Company` as Customer - Send > unchecked French E-Invoicing (Demo) Traceback: `AttributeError: 'res.partner' object has no attribute '_get_pdp_receiver_identification_info'` In this REF [PR], we removed the `_get_pdp_receiver_identification_info` method and replaced it with the `l10n_fr_is_pdp` field, but we missed updating it here
Original PR description
Steps to reproduce: - Install `l10n_fr_pdp` and `Accounting` > Switch to `FR Company` - Activate `French electronic invoicing` - Create New Invoice with `FR Company` as Customer - Send > unchecked French E-Invoicing (Demo) Traceback: `AttributeError: 'res.partner' object has no attribute '_get_pdp_receiver_identification_info'` In this REF [PR], we removed the `_get_pdp_receiver_identification_info` method and replaced it with the `l10n_fr_is_pdp` field, but we missed updating it here. Solution: Replaced the removed `_get_pdp_receiver_identification_info` method with `l10n_fr_is_pdp`. [PR]: https://github.com/odoo/odoo/commit/5c3dde7f36609a74ffed8357c11a648d85942bdd#diff-a9b0aba990a93514e74372976dd8c77cda07db893324a0a2fad8a9027ec0b1da opw-6443303
The fix proposed in #274619 was not properly adapted for saas-19.4 and onwards as we changed the class name of the chart menu (see https://github.com/odoo/o-spreadsheet/pull/7861). Task-6441988 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Original PR description
The fix proposed in #274619 was not properly adapted for saas-19.4 and onwards as we changed the class name of the chart menu (see https://github.com/odoo/o-spreadsheet/pull/7861). Task-6441988 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Steps to reproduce: 1. Install `l10n_pe` 2. Create and set the current company to the Peru company 3. In mobile view, try to create a contact 4. Fill in the identification number type to RUC Issue: - The field of VAT is collapsed and not visible Cause: - The VAT div `vat_div` is displayed as a flex row (`o_row d-flex`) so the 'add identifier' button sits on the same line as the VAT field. https://github.com/odoo/odoo/blob/7d2d41fdef3446ca118290c1b31287887c0794db/addons/account/vie
Original PR description
Steps to reproduce: 1. Install `l10n_pe` 2. Create and set the current company to the Peru company 3. In mobile view, try to create a contact 4. Fill in the identification number type to RUC Issue: -…
Steps to reproduce:
1. Install `l10n_pe`
2. Create and set the current company to the Peru company
3. In mobile view, try to create a contact
4. Fill in the identification number type to RUC
Issue:
- The field of VAT is collapsed and not visible
Cause:
- The VAT div `vat_div` is displayed as a flex row (`o_row d-flex`) so the 'add identifier' button sits on the same line as the VAT field.
https://github.com/odoo/odoo/blob/7d2d41fdef3446ca118290c1b31287887c0794db/addons/account/views/partner_view.xml#L169-L171
Localizations based on `l10n_latam_base` also put an identification type field (e.g. RUC, DNI) in that same row, before the VAT field.
https://github.com/odoo/odoo/blob/7d2d41fdef3446ca118290c1b31287887c0794db/addons/l10n_latam_base/views/res_partner_view.xml#L14-L21
That identification type field carried the `oe_inline` class, which matched an unrelated, pre-existing mobile-only rule forcing any inline many2one to `width: 100% !important`.
https://github.com/odoo/odoo/blob/7d2d41fdef3446ca118290c1b31287887c0794db/addons/web/static/src/views/form/form_controller.scss#L999-L1001
Inside the flex row this left no space for its sibling, collapsing the VAT value input.
<table>
<tr>
<th width="50%">Before</th>
<th width="50%">After</th>
</tr>
<tr>
<td width="50%">
<img src="https://github.com/user-attachments/assets/12b1774f-2c60-4c89-a348-ccf514528552" width="100%">
</td>
<td width="50%">
<img src="https://github.com/user-attachments/assets/3f1571f1-8e88-41d3-89bb-b9e2ce1e85fc" width="100%">
</td>
</tr>
</table>
Solution:
- Drop the `oe_inline` class from the identification type field in `l10n_latam_base`'s partner view.
opw-6375655
Forward-Port-Of: odoo/odoo#275905Before this commit: --- The company logo is displayed above the background on the customer display. After this commit: --- The company logo is displayed only when there is no background or QR code to display. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#281406
Original PR description
Before this commit: --- The company logo is displayed above the background on the customer display. After this commit: --- The company logo is displayed only when there is no background or QR code to display. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#281406
Issue: --- Adding a pickup-in-store delivery method to a sales order from the backend `Add shipping` wizard and clicking on the pickup point selector raises: Invalid props for component `LocationSelectorDialog`: `countryId` is not a number. Steps to reproduce: 1- Create a SO with a partner without country set. 2- Enable debug mode. 3- Use `Add shipping` wizard and choose pick-up delivery method. 4- Open the location selector. Cause: --- `PickupLocationMany2OneField.countryId` re
Original PR description
Issue: --- Adding a pickup-in-store delivery method to a sales order from the backend `Add shipping` wizard and clicking on the pickup point selector raises: Invalid props for component `LocationSelectorDialog`: `countryId` is not a number. Steps to reproduce: 1- Create a SO with a partner without country set. 2- Enable debug mode. 3- Use `Add shipping` wizard and choose pick-up delivery method. 4- Open the location selector. Cause: --- `PickupLocationMany2OneField.countryId` returns the `id` of `this.partnerRecord.country_id` which is `false` when the company is not set. This can be fixed by a safe optional chain access. opw-6321167 Forward-Port-Of: odoo/odoo#281720
Issue: --- On the product page, when the image layout is set to grid and only one image is there, the image doesn't take the full width of its container on mobile devices. A empty space appears next to it. Steps to reproduce: 1- Go to a product page with mlutiple images. 2- Switch the image layout from carousel to grid. 3- Remove extra images and keep only one image. 4- Open the page using mobile view in chrome. This can be fixed by forcing `width: 100%` explicitly on the image wrapp
Original PR description
Issue: --- On the product page, when the image layout is set to grid and only one image is there, the image doesn't take the full width of its container on mobile devices. A empty space appears next to it. Steps to reproduce: 1- Go to a product page with mlutiple images. 2- Switch the image layout from carousel to grid. 3- Remove extra images and keep only one image. 4- Open the page using mobile view in chrome. This can be fixed by forcing `width: 100%` explicitly on the image wrapper for `o_grid_solo`. opw-6265732 Forward-Port-Of: odoo/odoo#281728
In this commit: - Ensure event ticket information is preserved during self-order processing and use the configured ticket price when recomputing order line prices. - This prevents ticket prices from being replaced by the product price after proceeding to payment and keeps the amounts consistent across the payment page. Task:6375899 Forward-Port-Of: odoo/odoo#282530 Forward-Port-Of: odoo/odoo#275645
Original PR description
In this commit: - Ensure event ticket information is preserved during self-order processing and use the configured ticket price when recomputing order line prices. - This prevents ticket prices from being replaced by the product price after proceeding to payment and keeps the amounts consistent across the payment page. Task:6375899 Forward-Port-Of: odoo/odoo#282530 Forward-Port-Of: odoo/odoo#275645