Thursday, July 2, 2026
16 changes · saas-18.3
Resolved issues and error corrections
Restaurant PoS users can now merge or unmerge tables without running into permission errors. The update also hides the “Edit Plan” option for these users when they do not have the required access, preventing confusing failures during service.
Original PR description
This commit fixes access errors encountered by PoS users when merging or unmerging tables. The changes include: - Granting PoS users write access to restaurant tables required for the merge/unmerge flow. - Hiding the "Edit Plan" button for PoS users, as it requires write/create access to the floor plan. Task-6352316
WebP images are now checked against the same maximum size limit as other image formats when users upload them. This prevents very large images from being accepted and helps keep the system consistent and more reliable.
Original PR description
Since 17.0, `webp` images can be uploaded at any resolution, whereas every other format is refused above IMAGE_MAX_RESOLUTION (50 Mpx) when the attachment is created on the server. Root cause…
Since 17.0, `webp` images can be uploaded at any resolution, whereas every other format is refused above IMAGE_MAX_RESOLUTION (50 Mpx) when the attachment is created on the server. Root cause =========== `ImageProcess` grouped webp together with empty sources and SVG and set `self.image = False`, returning before the `verify_resolution` check. As a result the resolution limit enforced for `png/jpeg/...` was never applied to `webp`. Fix === Split `webp` out of the skip branch: it is still not processed as before, but its resolution is now read from the RIFF header with `get_webp_size()` and checked against `IMAGE_MAX_RESOLUTION`, so oversized webp images are refused on upload like any other format. Steps to reproduce =================== 1. Edit any page with the website editor 2. Upload a `webp` image larger than 50 Mpx (e.g. 8000x8000) => The image is accepted, while a `png/jpeg` of the same size is refused task-4134430 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#273140 Forward-Port-Of: odoo/odoo#273010
This fix ensures the SAF-T export uses the correct official grouping codes for Norwegian accounts. It prevents certain account numbers from being sliced incorrectly, which could otherwise produce the wrong code in exported accounting reports.
Original PR description
Steps to reproduce: - change 1920 Banck account to 19204321 - go in general ledger and export to "SAF-T" Issue: The grouping code is 4321 Grouping code should match official grouping code. As a matter of fact the chart of account seems to match thos grouping account if we slice them correctly. opw-6285078 Forward-Port-Of: odoo/enterprise#121932
This change prevents a memory or timeout problem that could occur when installing the Spanish VeriFactu module on databases that already contain accounting entries. It makes the installation process more reliable and avoids failures during setup.
Original PR description
### Description: When trying to install the module `l10n_es_edi_verifactu` on a database that already has moves, it is possible to encounter a timeout or a memory error. This is caused by the compute `l10n_es_edi_verifactu_state` and `l10n_es_edi_verifactu_clave_regimen`, both compute linked to the new model `l10n_es_edi_verifactu.document`. ### Reference: opw-6293590 Forward-Port-Of: odoo/odoo#271550
This update fixes a problem where uploaded fonts with spaces in their filenames were not working correctly on websites. It also ensures font weight information is kept properly, so the right font style is displayed.
Original PR description
When uploading a font file "FontName 123 Light.otf" the baseFontName needs to be quoted in the font-face CSS to be valid. Single font files parsing for the shortestNamedFont now also correctly keeps…
When uploading a font file "FontName 123 Light.otf" the baseFontName needs to be quoted in the font-face CSS to be valid.
Single font files parsing for the shortestNamedFont now also correctly keeps the weight for the targetFonts.
Description of the issue/feature this PR addresses:
Uploaded fonts with spaces in the name are not working.
Current behavior before PR:
When uploading a font with a space in the filename like "FontName 123 Light.otf" the css declaration in the attachement is wrong and not working:
```css
@font-face {
font-family: FontName 123 Light;
font-style: normal;
font-weight: 400;
src: url("/web/content/1057/FontName 123 Light.otf");
}@font-face {
font-family: FontName 123 Light;
font-style: normal;
font-weight: 400;
src: url("/web/content/1057/FontName 123 Light.otf");
}
```
Desired behavior after PR is merged:
The font name is now correctly quoted and the font attributes are no longer overwritten for the shortestNameFont:
```css
@font-face {
font-family: "FontName 123 Light";
font-style: normal;
font-weight: 400;
src: url("/web/content/1057/FontName 123 Light.otf");
}@font-face {
font-family: "FontName 123 Light";
font-style: normal;
font-weight: 300;
src: url("/web/content/1057/FontName 123 Light.otf");
}
```
Info @wt-io-it
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#268842This update ensures that product barcodes are recognized correctly even when they also look like a GS1 barcode pattern. It prevents the system from mistaking a normal product scan for a quantity or lot scan, avoiding incorrect quantities being added to delivery lines.
Original PR description
In certain cases the barcode of a product could be a valid standalone GS1 sequence. In that case it needs to be be correctly interpreted as a product scan. ### Steps to reproduce: - In the settings…
In certain cases the barcode of a product could be a valid standalone GS1 sequence. In that case it needs to be be correctly interpreted as a product scan. ### Steps to reproduce: - In the settings enable "Default GS1 Nomenclature" - Create a storable product P with the barcode 3701762412212 - Create and confirm a delivery for 2 units of P and set the qty to 2 - Go to the barcode app and open your delivery - Scan 3701762412212 > The line of P is now selected with a quantity of 1/2 - Scan 3701762412212 #### > A new line is created for 1762411 units ### Cause of the issue: According to the GS1 nomenclature, the barcode 3701762412212 matches the scan of a quantity of "1762412" units of the lot name "2". As the scan of the of the product match a pattern for the GS1 nomenclature before matching a product, its barcode data is expected to be reset by these lines: https://github.com/odoo/enterprise/blob/7cceddaf086d849b8e2121e1023ef3479397534f/stock_barcode/static/src/models/barcode_model.js#L1320-L1324 In order to bypass the GS1 parser and to add 1 unit of the product. This is what happen on the first scan. However, performing the first scan also selects the associated line and, hence on the second scan the lines just above this check do set the product to match the product of the current line: https://github.com/odoo/enterprise/blob/7cceddaf086d849b8e2121e1023ef3479397534f/stock_barcode/static/src/models/barcode_model.js#L1294-L1320 In particular, we do not bypass the result provided by the GS1 parser and add `1762412` units of the product. opw-6175621 Forward-Port-Of: odoo/enterprise#122256 Forward-Port-Of: odoo/enterprise#120035
This update adjusts the order of fields in the Mexican trial balance XML export so it matches the structure recommended by the SAT. The report content stays the same, but the generated file now aligns better with government specifications and expected formatting.
Original PR description
**Steps to reproduce:** - Install the `l10n_mx_reports` module and switch to a Mexican company. - Navigate to Accounting > Reporting > Trial Balance. - From the dropdown menu, click `SAT (XML)`. -…
**Steps to reproduce:** - Install the `l10n_mx_reports` module and switch to a Mexican company. - Navigate to Accounting > Reporting > Trial Balance. - From the dropdown menu, click `SAT (XML)`. - Open the generated XML file and inspect the `<BCE:Ctas>` nodes. **Observation:** - The generated XML uses the following attribute order: `Debe > NumCta > Haber > SaldoFin > SaldoIni` - However, the SAT-recommended structure is: `NumCta > SaldoIni > Debe > Haber > SaldoFin` **Root Cause:** At [1], the attributes of the `<BCE:Ctas>` node are defined in an order that differs from the SAT-recommended structure. While the XML remains valid, the generated report does not match the layout recommended by the Mexican government specification. **Fix:** This commit reorders the `<BCE:Ctas>` attributes to follow the SAT-recommended structure, aligning the generated XML with the behavior introduced at [2] for `saas-19.3`. backport-of: https://github.com/odoo/enterprise/pull/115374 [1]: https://github.com/odoo/enterprise/blob/cb9c19272309d793379fa4d23145162f72fa5552/l10n_mx_reports/data/templates/cfdibalance.xml#L15-L20 [2]: https://github.com/odoo/enterprise/blob/acf0929a88ec788aecd44f6b4c647e468dc0a319/l10n_mx_reports/data/templates/cfdibalance.xml#L17-L22 opw-6297711 Forward-Port-Of: odoo/enterprise#122469 Forward-Port-Of: odoo/enterprise#121440
When a customer books an appointment through Reserve with Google, Odoo now uses the name provided in Google’s booking details instead of falling back to the email address. This ensures contacts, calendar entries, and attendee details display the customer’s real name, improving clarity for staff and customers.
Original PR description
When a customer books through Reserve with Google, the createBooking payload carries the booker given_name and family_name next to the email, but the handler passed only the normalized email to…
When a customer books through Reserve with Google, the createBooking payload carries the booker given_name and family_name next to the email, but the handler passed only the normalized email to _mail_find_partner_from_emails. The new res.partner was therefore created with its name falling back to the email, see https://github.com/odoo/odoo/blob/aa7b5921191a0ff53ef1cc32af99fe458c45c0da/addons/mail/models/res_partner.py#L177 That name then flows into the calendar.event name, the attendee common_name and the contact details, all showing the email instead of the customer name. The module has read neither field since it was added in https://github.com/odoo/enterprise/commit/2e855b910173b56e8501d0ebe9ee6f83ac5845bc. Build the booker name from given_name and family_name and pass it with the email through formataddr in google_reserve_booking_create, so a newly created partner is named after the customer. A partner matched on an existing email keeps its current name. Steps to reproduce: 1. Enable Reserve with Google on an appointment type. 2. Book a slot from Google Maps with given name John and family name Doe. 3. Open the created booking and its contact in Odoo. => the contact name is the email instead of John Doe Ticket [link](https://www.odoo.com/odoo/project/49/tasks/6232318) opw-6232318 Forward-Port-Of: odoo/enterprise#120604
The payment flow now confirms that the self-order point of sale is actually set up as a kiosk before continuing. It also checks that an IoT payment method is configured, helping prevent payment errors and reducing failed transactions.
Original PR description
This commit makes the payment endpoint more robust by verifying the POS config is indeed a kiosk, and that it has an IoT payment method configured. Forward-Port-Of: odoo/enterprise#121894
This update fixes a test failure that appeared when two Swedish payment-related modules were installed together. It keeps the payment export behavior stable by replacing the outdated test with one that matches the new file format, reducing the risk of false alarms in automated checks.
Original PR description
Here https://github.com/odoo/enterprise/pull/114662 we changed the way the CdtrAgt node is used in the SEPA XML file for Sweden. But this change broke a test when both account_iso20022 & l10n_se_bban are installed, leading to a Non-expected child error. This commit skip the failling test if l10n_se_bban is installed, and add a new one to replace it. runbot-938366 runbot-938367 Forward-Port-Of: odoo/enterprise#122359 Forward-Port-Of: odoo/enterprise#121485
Tracked URLs generated without an active website context now fall back to the system base URL instead of picking a company website at random. This ensures links created by background processes, such as mass mailing, point to the intended public domain and stay consistent across companies.
Original PR description
The [`_compute_short_url_host`](https://github.com/odoo/odoo/blob/a81fa8699c89385d2cccb260ada07255c6ea1275/addons/website_links/models/link_tracker.py#L20-L24) override builds link.tracker short URLs…
The [`_compute_short_url_host`](https://github.com/odoo/odoo/blob/a81fa8699c89385d2cccb260ada07255c6ea1275/addons/website_links/models/link_tracker.py#L20-L24) override builds link.tracker short URLs from `website.get_current_website()` and the current company's website domain. It was introduced by https://github.com/odoo/odoo/commit/f13ecb15af7f0bdc67e37dfb41e8bac77f5a541a for a multi-company backend flow (users switching companies to post social marketing links), but it runs for every compute, including CRON contexts with no HTTP request such as the mass-mailing queue. Without a request, `get_current_website()` picks an arbitrary website (the first in the database) and `self.env.company` resolves to the user's main company, so the short URL uses that company's website domain instead of `web.base.url`. Fall back to `super()._compute_short_url_host()` (which uses `web.base.url`) when no website is resolvable from the request, session, or context. Backend flows with a real request still hit the company-aware branch. Steps to reproduce: 1. Install Email Marketing and Website. 2. Settings > Companies: create a second company B. Settings > Websites: ensure website A points to company A with domain A, and create website B for company B with domain B. 3. Settings > Technical > Parameters > System Parameters: set `web.base.url` to a third domain C, and add `web.base.url.freeze` = `True`. 4. On company A, Email Marketing: create a mailing with body `<a href="http://example.com">test</a>` and a recipient list, then click Send. 5. Settings > Technical > Automation > Scheduled Actions > "Mass Mailing: Process queue" > Run Manually. 6. Email Marketing > Configuration > Link Tracker: open the tracker generated for the mailing. => The Tracked URL uses domain A. => The Tracked URL uses domain C. Ticket [link](https://www.odoo.com/odoo/project.task/6038590) opw-6038590 Forward-Port-Of: odoo/odoo#259200
The Timesheet app now correctly shows an employee’s own non-working days as unavailable in the My Timesheet view. This prevents users from seeing a day as available when it should be grayed out, helping avoid incorrect time entry.
Original PR description
To reproduce: ============= - modify Mitchel Admin's working schedule and remove a day of work - open timesheet app as Mitchel Admin - the removed day is not grayed out as unavailable Porblem: ======== the method `get_unavailabily` was handling only the case when calling it with `groupby=employee_id` otherwise it returns the company's unvailability Solution: ========= when the "My Timesheet" action is opened, the method `get_unavailabily` is now called with a specific context key, allowing to return the current user's unavailability instead of the company's one. opw-5949236 Forward-Port-Of: odoo/enterprise#122191 Forward-Port-Of: odoo/enterprise#113984
This fix prevents users from setting default values for fields they do not have permission to change. It helps keep default settings aligned with access rights and reduces the risk of unintended or unauthorized behavior.
Original PR description
Users should be able to set default values only for fields they have access to. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#273230 Forward-Port-Of: odoo/odoo#273089
This update restores essential tests related to the flow of transactions for the l10n_fr_pdp_pos module. These tests were temporarily removed during a recent integration of e-reporting and e-invoicing features. Restoring these tests ensures continued functionality and stability of the POS system.
Original PR description
During the merge of l10n_fr_pdp e-reporting and e-invoicing, some tests had to be removed. Task-6296356 Forward-Port-Of: odoo/odoo#272649 Forward-Port-Of: odoo/odoo#271294
This update resolves issues where scanning employee badges didn't always work correctly within the Point of Sale system. Specifically, it ensures badges scan reliably, prevents accidental PIN confirmations, and correctly switches between cashiers when scanning another's badge. These improvements enhance the user experience and streamline the login process for employees.
Original PR description
See commit messages. [[FIX] pos_hr: scanning badge should work with PIN input focused](https://github.com/odoo/odoo/commit/95d9329674e81b2659445e2021a35b21bbbc81a3) [[FIX] point_of_sale: scanning a badge should not auto confirm the PIN](https://github.com/odoo/odoo/commit/d59fb1f6fe27d117579b3945c5bba400d17d0014) (Note: this is only needed up to saas-18.4 included -- 19.0 already has this diff) [[FIX] pos_hr: scanning another cashier's badge switches to that cashier](https://github.com/odoo/odoo/commit/c812fe596694b16a494e3dcf908d17f621f7ce92) opw-6125029 Forward-Port-Of: odoo/odoo#273154 Forward-Port-Of: odoo/odoo#262474
A recent change in Cloudflare impacted how turnstile callbacks functioned, causing a disruption. This pull request reverts a previous update that relied on specific implementation details, restoring the original callback structure. This ensures turnstile functionality continues to operate correctly.
Original PR description
Callbacks were changed to use a single shared callback instead of a bunch of callbacks that captured a specific container. Cloudlfare since introduced a change that breaks this change by not making "this" available inside callbacks. We thus go back to the previous implementation that did not rely on implementation details of the external widget. related: 5aa5cf62a9d3f2b0c862b0aab337b22367843fa6 Forward-Port-Of: odoo/odoo#273538 Forward-Port-Of: odoo/odoo#273336