Friday, August 28, 2026
38 changes · master
Resolved issues and error corrections
Timesheet suggestions created from calendar events now better match the correct project or task and display adjusted event durations correctly after overlaps are resolved. This helps users log time with fewer manual corrections and reduces confusion from inaccurate suggested entries.
Original PR description
task: 6435164 Forward-Port-Of: odoo/enterprise#126680
This fixes a spacing issue where date picker popups could lose their normal padding because of a calendar side panel adjustment. The padding change is now limited to the calendar side panel, keeping popups visually consistent elsewhere.
Original PR description
- requires https://github.com/odoo/odoo/pull/284964 The template override forced `pb-2` on every picker so it would sit flush in the calendar side panel, stripping the padding from popovers too. Set `--DateTimePicker-padding` on the panel instead. task-6512183
This fix restores the expected horizontal spacing around date pickers shown in popovers, making them easier to read and use. Calendar side panels can still keep their tighter layout without affecting date pickers elsewhere.
Original PR description
- requires https://github.com/odoo/enterprise/pull/129503 | //////// | Calendar C.E (identical) | Calendar E.E (preserve top alignment) | Datepicker (restore padding) | Frontend datepicker |…
- requires https://github.com/odoo/enterprise/pull/129503 | //////// | Calendar C.E (identical) | Calendar E.E (preserve top alignment) | Datepicker (restore padding) | Frontend datepicker | |--------|--------|--------|--------|--------| | Master | <img width="466" height="497" alt="image" src="https://github.com/user-attachments/assets/148943b7-c89d-4aec-8b9a-fdf8e58016e2" /> | <img width="487" height="536" alt="image" src="https://github.com/user-attachments/assets/5d09bcd4-a3d4-475b-b97f-02a2254398da" /> | <img width="453" height="418" alt="image" src="https://github.com/user-attachments/assets/fa815751-50de-4257-8b25-81801042c4ce" /> | <img width="616" height="451" alt="image" src="https://github.com/user-attachments/assets/9c4a646c-d1be-4431-afd6-552ab3e84e62" /> | | This PR | <img width="455" height="488" alt="image" src="https://github.com/user-attachments/assets/2957ae2e-32c2-40b1-906a-bf643f1c6028" /> | <img width="488" height="498" alt="image" src="https://github.com/user-attachments/assets/09f66532-45e0-4a73-9133-94ba9561f3d9" /> | <img width="574" height="407" alt="image" src="https://github.com/user-attachments/assets/1bd5cb86-0adc-46ed-8f52-421e103261f1" /> | <img width="602" height="437" alt="image" src="https://github.com/user-attachments/assets/2c06d43c-81db-4b78-bc77-20e3d39cc2f6" />| The calendar refresh narrowed the picker's padding globally (`p-2` -> `py-2`) so it would sit flush in the calendar side panel. A later commit moved that side panel restyling to Enterprise but left the narrowed padding behind, leaving every popover picker without its horizontal spacing. Expose the padding as `--DateTimePicker-padding`, defaulting to the original spacing, and let the side panel opt out. A variable rather than a utility class also removes the `!important` the bottom sheet needed to beat `p-2`. task-6512183 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fixes a small internal cleanup issue in the bus messaging system by removing empty database tracking entries when they are no longer needed. It does not change user-facing behavior, but keeps background bookkeeping tidier and avoids stale internal records.
Original PR description
`_drop_topic_if_empty` discards a topic from its dbname's set but never removes the dbname key once the set becomes empty, leaving a stale empty set if no notify is ever received for this DB. No impact on the dispatch code, just a bookkeeping cleaning.
This fix updates an internal social CRM test so it no longer depends on a generic customer name that can appear in other sample data. It helps keep automated checks stable and reduces false failures during development and release validation.
Original PR description
The social CRM conversion test creates a partner named "John Doe" and expects the post-to-lead wizard to automatically match it. This relies on "John Doe" being unique in the database. Since `pos_restaurant.customer_1` is also named "John Doe", the wizard's `name_search()` can return multiple partners depending on the modules already installed when the test is run. In that case, the wizard correctly considers the match ambiguous and leaves `partner_id` empty, causing the test to fail. This commit uses a test-specific author name instead, ensuring that the test actually provides the single matching partner described by its docstring and does not depend on unrelated demo data or module installation order. [error-243065](https://runbot.odoo.com/odoo/error/243065) Forward-Port-Of: odoo/enterprise#128119
Customers can no longer set optional products on sales orders to negative quantities through the portal. This keeps customer-facing order changes consistent and prevents invalid quantities that should only be handled by sales staff when needed.
Original PR description
Since the fusion of `sale.order.option` model into `sale.order.line` model, the optional products (editable from portal) lines are not deleted when reaching a quantity of 0 or below. This could allow some customers to set negative quantities, which makes no sense as it's only something that should be set by the salesman if necessary. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#284493
Planning notification emails now show action buttons with a visible colored background, so employees can clearly read and click options like viewing their planning. This prevents confusion when shifts or schedules are published and helps employees respond from email more reliably.
Original PR description
Before this change: When publishing a shift or schedule, the buttons "Assign me this shift", "I am unavailable", and "View your planning" inside the notification email sent to the employee appears invisible. The button text is rendered in white on a white background, making the link unreadable and difficult to click. To reproduce: 1. Open the Planning app and create a shift with today's date in the time range. 2. Click "Publish". 3. Go to Settings > Technical > Email > Emails. 4. Open the email that was just sent. 5. Inspect the email body and observe that the "View your planning" button text is not visible. After this change: A default purple background is applied to the button, ensuring the white text is properly visible and legible across email clients. opw-6483147 Forward-Port-Of: odoo/enterprise#128662
Website links that open in a new tab are now handled in a way that better supports screen reader users. This helps visitors understand when navigation will leave the current page context, reducing confusion and improving accessibility.
Original PR description
Screen readers generally do not automatically announce that a link opens in a new tab when a user navigates to it, creating a potential barrier for non-visual users who may become disoriented if the current page is replaced without warning. Commit 2135b3c1a89c3ba0887191f36b5d73d08682f4b6 already fixed it, but this new approach follows more closely the Interaction framework.
Certification content in eLearning courses now displays correctly outside fullscreen mode. This ensures learners can access certification lessons consistently in the standard course view.
Original PR description
**Steps to reproduce:**
- Install website_slides_survey module
- Create a course in eLearning
- Add content with type Certification
- Go to the website and open the content
- It renders properly in fullscreen
- It displays nothing in the normal view
**Issue:**
`<xpath expr="//div[hasclass('o_wslides_lesson_content_type')]` targets the wrong `<div>` since [1] (it adds the certification content inside the `t-if="slide.slide_category == 'infographic'"`)
**Fix:**
Match the `t-else` condition as well for the xpath.
Fix in master as view update is needed.
[1] https://github.com/odoo/odoo/commit/e3389e392e3ccf0061e3838923ad9a9b4ea41cdd
opw-6070973This change makes automated checks for the HTML editor behave consistently across different Odoo editions. It reduces false test failures, helping development and release validation proceed more reliably without changing end-user features.
Original PR description
This PR aims to fix the failing contrast tests in the community version. The failures occur because `this.defaultBg` in contrast_plugin.js has different values in community and enterprise versions, resulting in different color contrast values. This PR fixes the tests by patching `--o-control-panel-background-color` css variable with a hardcoded value. runbot: 946513 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Scrolling or zooming within the image cropper now keeps the user’s selected crop area instead of resetting it. This prevents accidental loss of cropping adjustments and makes image editing more predictable in the HTML editor.
Original PR description
Problem: When scrolling on an image inside the image cropper (which triggers a zoom event), the selected cropping area is reset back to default instead of preserving the existing crop selection. Cause: The `t-on-zoom` event listener called `onCropZoom()`, which executed `resetCropBox()`. This called `cropper.clear()` and `cropper.crop()`, clearing and resetting the crop box whenever a zoom/scroll event occurred. Solution: Remove `onCropZoom` and `resetCropBox` so zooming or scrolling on the image does not reset the active crop box selection. Steps to reproduce: - Insert a large image in the editor. - Crop it. - Reopen the image cropper on the image. - Scroll on the image. - Observe that the selected cropping area is reset instead of preserved. task-6488910 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Invalid VAT warnings now preserve and display the exact VAT number entered by the user, such as Swiss values like CHE-115.391.649. This avoids confusing truncated messages and helps users identify and correct the original input more easily.
Original PR description
Before this change: When entering or importing a VAT number (e.g., CHE-115.391.649), an invalid VAT warning displays a string missing its country_id (e.g., E-115.391.649). This confuses users and masks the actual input string that triggered the validation failure. To reproduce: 1. Open any contact record and set the Country to Switzerland. 2. Enter an invalid or manually formatted Swiss VAT number like `CHE-115.391.649`. 3. Save or trigger the VAT validation check. 4. Observe the warning banner showing `E-115.391.649` instead of `CHE-115.391.649`. After this change: The validation warning logic preserves the original user input when constructing the alert message, ensuring error notifications accurately display VAT number. Issue introduced by: * https://github.com/odoo/odoo/commit/ac95d2d6d80a368dfb190d0ac21da2af479a8488 * https://github.com/odoo/odoo/commit/a2afe3292e1cd0a4f339dc47707e469653d13ea0 opw-6474217 Forward-Port-Of: odoo/odoo#284305
This fix prevents duplicate emails from being sent when expenses are submitted across multiple companies. It helps keep expense notifications accurate and avoids confusing employees or approvers with repeated messages.
Original PR description
Fix a small issue resulting in mail duplication when submitting expenses from multiple companies that appeared in the infamous 704a5a19 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#284861 Forward-Port-Of: odoo/odoo#283013
This fix stops users from marking the main website menu as a mega menu when it already contains child menus. It prevents migration failures and keeps website navigation settings consistent for sites using apps such as recruitment.
Original PR description
Issue: ------- After the fix: https://github.com/odoo/odoo/commit/f1557211d9e7f83761bb36e4800e4c2f62b234c5 we can't create a child menu for a mega menu or a menu can't be a mega menu when there's an…
Issue:
-------
After the fix:
https://github.com/odoo/odoo/commit/f1557211d9e7f83761bb36e4800e4c2f62b234c5 we can't create a child menu for a mega menu or a menu can't be a mega menu when there's an existing child menu except the case of top level menu i.e; (url: /default-main-menu) and that menu will have no parent_id obviously...
Now, as per the above pr conditions the top level can be set as mega menu since it has no parent id. And in version 17.3 in the pr https://github.com/odoo/odoo/commit/47af533e9f5f721b63570d3b301951f3855384a1 a 'Jobs' menu is being created and its parent_id refers to that top level menu which we have set as mega menu. And when the records gets validated during migration the database will get blocked.
Solution:
-----------
Restrict the user by throwing the same user error, when checking/selecting the top level menu as mega menu since it has existing child menus.
Step to reproduce:
-----------------------
1. Create a database in version 17.0 with 'website_hr_recruitment' installed.
2. Go to website menus, set a top level menu(/default-main-menu) as mega menu.
3. Migrate the database to version 18.0 or more.
Traceback:
```
File "/home/odoo/src/odoo/18.0/odoo/models.py", line 5297, in _create
records._validate_fields(name for data in data_list for name in data['stored'])
File "/home/odoo/src/odoo/18.0/odoo/models.py", line 1636, in _validate_fields
check(self)
File "/home/odoo/src/odoo/18.0/addons/website/models/website_menu.py", line 95, in _validate_parent_menu
raise UserError(_("A mega menu cannot have a parent or child menu."))
odoo.exceptions.UserError: A mega menu cannot have a parent or child menu.
File "/home/odoo/src/odoo/18.0/odoo/tools/convert.py", line 603, in _tag_root
raise ParseError('while parsing %s:%s, somewhere inside\n%s' % (
odoo.tools.convert.ParseError: while parsing /home/odoo/src/odoo/18.0/addons/website_hr_recruitment/data/config_data.xml:13, somewhere inside
<record id="website_menu_jobs" model="website.menu">
<field name="name">Jobs</field>
<field name="url">/jobs</field>
<field name="parent_id" ref="website.main_menu"/>
<field name="sequence">59</field>
</record>
```
Ref Images:
Before Fix:
<img width="1598" height="599" alt="image" src="https://github.com/user-attachments/assets/ef719945-a11b-4134-97f8-4b583c4ea6bc" />
After Fix:
<img width="1582" height="633" alt="image" src="https://github.com/user-attachments/assets/da326e45-0de8-4d42-ad47-845bfaedc84e" />
OPW - 6094298
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#280458
Forward-Port-Of: odoo/odoo#263025This fixes an error that appeared when users tried to generate a new serial or lot number for components during a manufacturing barcode operation. Manufacturing teams can now continue barcode workflows without being blocked by this issue.
Original PR description
When generating a serial/lot number in a manufacturing opperation in barcode you get an error. Steps to reproduce: 1. Create a new manufacturing picking for a product with component 2. For the components try to generate a new serial number by clicking the + button 3. An error message shows up
This fix restores the ability to set holiday table values through payroll rule parameters instead of always calculating them automatically. It matters because companies can keep different values for different employees when Mexican payroll requires that flexibility.
Original PR description
In this PR: odoo/enterprise#120199 We replaced the rule parameter for the holiday table by a method to get it automatically. The problem is that the user might want to have different values for different employees. Task: 6512040
Belgian payroll now correctly validates temporary economic unemployment leave that lasts one day. This prevents affected HR users from being blocked when recording short unemployment periods around public holiday handling.
Original PR description
Steps: - Create a 'temporary economic employment for employee' timeoff type for an employee for 1 day only - Attempt validating the leave type Cause: Due to the splitting of economic unemployment period by public holidays, economic unemployment durations for 1 day durations are not returned from the splitting method correctly Solution: Returned economic unemployments with durations <= 1 correctly Task: 6511201
This fixes an issue where planning slots with multiple assigned resources could show incorrect allocated hours after resources were added or removed. Working time is now calculated per resource, helping schedules and capacity figures remain accurate for field service planning.
Original PR description
## Steps to reproduce: - Install planning_field_service - Create a planning slot with one resource - Add another resource for the slot we created - Notice the allocated_hours now equals 16h - Remove one of the resources - Notice now the allocated hours are 5h instead of 8h ## Cause: When adding a second resource in a slot and while computing the break_time we use the working hours of all of the resources combined instead of dividing by the number of resources and this messes up the break_time calculation which affects the allocated_percentage and at the end when trying to compute the allocated hours it will be wrongly calculated ## Fix: We divide the working hours by the number of resources to be able to compute the break_time correctly. opw-6307906 Forward-Port-Of: odoo/enterprise#129439 Forward-Port-Of: odoo/enterprise#125641
This fixes an internal HR Appraisal test that could fail when it ran across midnight. The change helps keep automated checks stable so future updates can be validated reliably without false failures.
Original PR description
### Explanation When `test_hr_appraisal` is run at, for example, 23:59:59, the line `self.hr_employee2.next_appraisal_date = date.today()` is executed after midnight, on the following day. As a result, a validation error is raised: `odoo.exceptions.ValidationError: You cannot set 'Next Appraisal Date' in the past.` Forward-Port-Of: odoo/enterprise#127699
Submitting a tax report opened from a return now reliably updates the same return shown on screen. This prevents Dutch VAT corrections from being accidentally submitted or marked against the original VAT return for the same period.
Original PR description
Opening a tax report from a return and submitting it could act on a different return than the one on screen. _get_return_from_report_options searches by company, period and report with limit=1, but…
Opening a tax report from a return and submitting it could act on a different return than the one on screen. _get_return_from_report_options searches by company, period and report with limit=1, but that combination is not unique: l10n_nl declares two return types on l10n_nl.tax_report, nl_tax_return_type and nl_tax_correction_return_type, so a VAT return and its correction both match. Which one is returned is then decided by _order (is_completed, date_deadline, name, id). For a Dutch VAT correction it resolves to the original VAT return of the same quarter, so send_xbrl submits and flags that record instead of the correction. The options already carry the return type they were built for, in the return_periodicity filter, so restrict the search to it when it is set. l10n_nl_reports kept a return_id option for the same reason when computing the already declared amount of a suppletie; it can use _get_return_from_report_options now. opw-6421300 Forward-Port-Of: odoo/enterprise#129278 Forward-Port-Of: odoo/enterprise#127073
This fix ensures Sendcloud shipping labels are returned in the format requested, such as ZPL or PDF. It prevents partner information sent with the request from accidentally replacing the label format setting, avoiding incorrect PDF-only label downloads.
Original PR description
We send the label type we want to get (zpl, pdf, ...) in the request headers. However, since odoo/enterprise#115999, we also send the partner ID in the headers. This was overriding the headers passed to the method, making Sendcloud always return a PDF label. Forward-Port-Of: odoo/enterprise#129542
Delivery charge lines are no longer shown in the Invoiced not Delivered report because they are not physical items that need delivery. This prevents accounting teams from seeing misleading outstanding delivery entries and improves the accuracy of revenue review reports.
Original PR description
Issue: --- Delivery lines are included in `invoiced not delivered` report, which is wrong as delivery lines are not deliverable. Steps: 1- Create a SO with a good product and add a delivery line. Set the product line as delivered and create an invoice. 2- Open accounting, and from review tab, open `Invoiced not Delivered`. As you see, delivery lines are included in the report. Fix: --- On stable we could fix it inside `_get_accrual_domain` by checking if `delivery` is installed. On master we need to implement a solution to be able to differentiate the lines that won't be delivered. opw-6360894 Forward-Port-Of: odoo/enterprise#123517
The signing process now creates completed documents at the right moment and avoids showing duplicate attachments on related records. Users get clearer completion messages and can find signed files reliably in the attachment tray.
Original PR description
This commit refactors the document completion flow to enforce the SRP and resolve duplicate attachments on reference records. Changes include: - Moved PDF generation (`_generate_completed_documents`) from the send method directly into `_sign` to guarantee documents are built exactly when the state changes to 'signed'. - Extracted reference record updates into a dedicated `_update_reference_document` method for cleaner code structure. - Resolved duplicate attachment displays on the source record by explicitly creating the attachment once and removing the redundant `attachment_ids` from the chatter message. - Updated the completion chatter message to notify users that the files are in the attachment tray, and set the message author to the original request creator. - Overrode `_generate_done_message` to cleanly bypass generic activity messages. Task: 6127862
Copying an image that is already attached to another record now reuses the existing file instead of leaving an unnecessary duplicate. This helps keep stored media cleaner and avoids redundant attachment clutter for users editing website or HTML content.
Original PR description
Copying an image attachment already linked to another record could leave a redundant duplicate behind instead of reusing the existing one. opw-6463012 Forward-Port-Of: odoo/odoo#284610 Forward-Port-Of: odoo/odoo#282287
Invoice and journal entry numbering now checks for missing numbers within each suffix-based sequence separately. This prevents valid entries from being incorrectly highlighted as gaps, improving confidence in accounting sequence checks.
Original PR description
### Issue: When moves share the same `sequence_number` in a journal but have different suffixes (e.g. `INV/2026/00010` and `INV/2026/00010A`), the `made_sequence_gap` flag was incorrectly set ###…
### Issue: When moves share the same `sequence_number` in a journal but have different suffixes (e.g. `INV/2026/00010` and `INV/2026/00010A`), the `made_sequence_gap` flag was incorrectly set ### Cause: `_update_sequence_made_gap`, introduced in commit https://github.com/odoo/odoo/commit/17893089e8b21c0ecab5e61ed8e2c33f3731b3ac selects the previous and next moves ordered by `sequence_number` without filtering by suffix This causes two issues: - Moves from different suffix sequences are used as neighbors, leading to incorrect gap detection - Duplicate `sequence_number` values across suffixes are not accounted for, so only one move is considered per number ### Steps to reproduce: - Install `account` - Post 12 invoices to get a sequence up to `INV/2026/00012` - Reset `INV/2026/00012` to draft, rename it to `INV/2026/00010A` - Reset `INV/2026/00010A` to draft, rename it to `INV/2026/00009A` and confirm Before the fix: `INV/2026/00011` is red Expected: `INV/2026/00011` should not be red because `INV/2026/00010` exists - Delete `INV/2026/00009` Before the fix: `INV/2026/00010` is red Expected: `INV/2026/00010` should be red (gap in no-suffix sequence) - Reset `INV/2026/00009A` to draft and confirm it again Before the fix: `INV/2026/00010` is not red Expected: `INV/2026/00010` should still be red (different suffix) ### Notes: Suffix changes are treated as distinct sequences following the same gap rules as any other sequence This was agreed with R&D — the gap flag is meant to signal inconsistencies within a sequence, not across suffixes opw-6454823 Forward-Port-Of: odoo/odoo#282503
This update fixes incorrect and unclear naming for Japanese fiscal positions. It corrects a wrong Japanese translation for domestic partners, fixes an English spelling issue, and removes unnecessary wording so users see clearer accounting labels.
Original PR description
Japanese translation "海外取引先" for domestic was clearly wrong.
Also fixed the misspelling ("Oversea" -> "Overseas") and removed the unnecessary "Customer" context from the name.
@qrtl
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#284608Odoo now saves the updated Microsoft refresh token whenever calendar access is renewed. This prevents users from being unexpectedly asked to reconnect their Microsoft Calendar after the old token expires, reducing disruption for calendar synchronization.
Original PR description
Microsoft issues a new refresh token on every access token refresh (rolling 90-day sliding window). The previous code discarded it, causing users to be forced to re-authenticate every 90 days once the original token expired. Closes #253543 Forward-Port-Of: odoo/odoo#280535 Forward-Port-Of: odoo/odoo#268284
This fix ensures costs are correctly linked to the right sales order when projects share the same analytic account or when a cost line uses multiple analytic accounts. Businesses get more reliable reinvoicing, reducing missed billable costs and manual corrections.
Original PR description
### Before this fix --- The `_get_so_mapping_from_project()` method returns a mapping where the key is the move line ID and the value is a `sale.order` record (or `None`). Because of the issues…
### Before this fix
---
The `_get_so_mapping_from_project()` method returns a mapping where the key is
the move line ID and the value is a `sale.order` record (or `None`).
Because of the issues described below, a valid `sale.order` could be available
for reinvoicing, but the corresponding move line might still not be mapped to
that sale order. As a result, the move line is not added to the reinvoiceable
sale order.
However, the implementation has two issues:
#### 1. Projects are overwritten when they share the same analytic account
`project_per_accounts` is built as a dictionary mapping an analytic account ID
to a single project. If multiple projects reference the same analytic account,
each new assignment replaces the previous one. As a result, only the last
project associated with a given analytic account is retained.
**Example:**
* Analytic Account **AA1** is linked to **Project A** and **Project B**.
* The dictionary becomes `{AA1: Project B}`.
* **Project A** is lost, even though it also references **AA1**.
**Steps to reproduce:**
1. Create an analytic account **AA1**.
2. Create **Project A** and **Project B**, both linked to **AA1**.
3. Create **Sale Order SO1** linked only to **Project A**.
4. Create a vendor bill (or expense) that generates an AML using **AA1** for a
product configured with **Reinvoice Costs = At Sales Price**.
5. Validate the document.
**Expected behavior:**
The product should be added to **SO1** for reinvoicing.
**Actual behavior:**
The move line is not mapped to **SO1**, so no sale order line is created.
#### 2. Previously found projects are overwritten during iteration
The `project` variable is reassigned on every iteration of the loop. After the
loop completes, it only contains the project (or lack of one) corresponding to
the last processed analytic account. This can cause valid projects found earlier
in the loop to be discarded.
**Example:**
* Move line has analytic accounts **AA1** and **AA2**.
* **AA1** maps to **Project A**.
* **AA2** has no linked project.
* After the loop, `project` is `None`, even though **Project A** was found.
**Steps to reproduce:**
1. Create analytic accounts **AA1** and **AA2**.
2. Create **Project A** linked to **AA1** only.
3. Create **Sale Order SO1** linked to **Project A**.
4. Create a vendor bill (or expense) whose AML is distributed between **AA1**
and **AA2**, where **AA2** is processed after **AA1**.
5. Validate the document.
**Expected behavior:**
The move line should still be mapped to **SO1** because **AA1** references
**Project A**.
**Actual behavior:**
The last processed analytic account (**AA2**) overwrites the previously found
project, causing the move line not to be linked to **SO1**.
### After this fix
---
* `project_per_accounts` stores **all** projects associated with each analytic
account instead of keeping only the last one.
* The project lookup preserves all valid project candidates instead of
overwriting previously found results during iteration.
* As a result, the method can resolve the related `sale.order` in more cases,
improving the overall accuracy of the mapping.
> **Note:** This change prevents valid project associations from being lost
> when multiple projects share an analytic account or when multiple analytic
> accounts are processed for the same move line.
**OPW:** 6294615
Forward-Port-Of: odoo/odoo#277110The PDP registration wizard no longer shows a redundant “Production” mention when the system is already in production mode. This avoids confusing users during registration and makes the displayed information clearer.
Original PR description
It makes no sense to mention (Production) on pdp registration wizard when you are in prod mode Forward-Port-Of: odoo/odoo#280501 Forward-Port-Of: odoo/odoo#280360
This fix prevents the barcode manufacturing scrap process from losing the quantity entered during automated checks. It helps ensure scrap operations are validated with the intended positive quantity instead of being incorrectly rejected as zero.
Original PR description
Selecting the product in the scrap form triggers a `stock.move` onchange. The quantity step only waited for the input to exist, not for that onchange to be applied, so the value could be written while it was still in flight and be reset to 0 by its response. It was also assigned directly on the input, without any event, so the field was never flagged as dirty. The scrap was then recorded with a quantity of 0 and `action_scrap` rejected it with "You can only enter positive quantities.". Wait for the quantity input to hold its post-onchange value before typing, and dispatch an input event, like the other scrap tours already do. error-238911 Forward-Port-Of: odoo/enterprise#129410 Forward-Port-Of: odoo/enterprise#128931
Appointment invitation emails now generate public calendar links without permission errors. This ensures invitees receive usable links and reduces failed email rendering during appointment scheduling.
Original PR description
Since calendar attendee access tokens are restricted to system users, appointment mail templates must sudo token reads when generating public calendar links. This follows the same pattern as the calendar mail templates and avoids an AccessError when rendering attendee invitation emails. ref: https://github.com/odoo/enterprise/commit/88a3cca752a5f726cd0260b485fc93f65a268cf8 Task-4711415 Forward-Port-Of: odoo/enterprise#129511
Fixed an issue where invoices created from Point of Sale orders in Chile were not automatically sent to the SII tax authority. This ensures business customers receive compliant invoice processing after checkout without manual follow-up.
Original PR description
Issue: Invoices from PoS orders are not automatically send to SII. Steps to reproduce: - Open PoS - create an order - add a company as customer - pay - close register - go to invoice Current behavior: Invoice is created but not sent Expected behavior: Invoice is created and send to SII. Cause: Before 19.2 invoices were sent using a cron. Starting from 19.2, invoices are sent using the Send button of the invoice form. In order to get a perf improvement, PDF generation was deactivated for l10n_cl PoS invoices at creation. However, the same method used to generate the PDF is used to send the invoice to SII. Therefore, invoices from PoS were not sent to SII. opw-6423528 Forward-Port-Of: odoo/enterprise#126623
Unreconciling one bank statement line from an invoice or bill now only removes that specific match instead of clearing all related reconciliations. This prevents accidental loss of payment matching when multiple bank statements are tied to the same document.
Original PR description
**STEP TO REPRODUCE** 1. Create a bill or an invoice. 2. Create multiples bank statement. 3. Reconciles those bank statements to the invoice/bill. 4. Unreconciles one of those bank statement on the invoice/bill. 5. Notice the invoice/bill is completely unreconciled. Expected behavior: only the unreconciled line should be unreconciled. **CAUSE** When unreconciling a partial linked to a bank statement, we call `delete_reconciled_line()` on both `partial.credit_move_id` and `partial.debit_move_id`. One on those is the the payment_term line of the invoice/bill the bank statement line is reconciled with. This payment_term line is also linked to all partial reconcilliation line on the invoice/bill, so calling `delete_renconciled_line()` delete all the reconciled line of the invoice/bill. **FIX** We should call `delete_renconciled_line()` only on the bank statement move line, not on the payment term line. opw-6465096 Forward-Port-Of: odoo/enterprise#128126
The Studio search view has been updated to match the newer interface used elsewhere. This provides a more consistent experience for users configuring and customizing views in Odoo Studio.
Original PR description
Before this commit, the search view in studio was still the old one After this commit, the search view in studio is like the new one
This fixes an issue where turning a block of content into a list could create an invalid structure and make the list behave incorrectly. Users editing website content can now convert block elements into lists more reliably.
Original PR description
Before this commit, create a list from a div put the div inside of the list element and then doesn't work the proper way After this commit, when creating a list from a div (block element) the a inline element is put inside the list instead. 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
Opening an action that cannot be edited in Studio from the command palette no longer causes a crash. Instead, users see a clear error notification, reducing disruption and making the limitation easier to understand.
Original PR description
Before this commit: 1. Open studio on Home Page 2. Open an action that cannot be editable with studio through command palette 3. Traceback occurs After this commit, the NotEditableActionError is catch and show an error notification.
The Sign app's guided tour was updated so its drag-and-drop step works correctly with the newer tour system. This helps keep automated checks reliable and reduces the risk of unnoticed issues in the signing experience.
Original PR description
Fix the drag_and_drop run of sign_tour to fit in the new tour system.
Swedish ISO20022 batch payments now generate files that correctly match the selected pain.001.001.09 format. This prevents banks from rejecting payment files that were labeled as the newer format but still contained older-format content.
Original PR description
**Steps to reproduce:** - Install Accounting and l10n_se - Switch to a Swedish company (e.g. SE Company) - In Accounting settings, set "Identification" with anything - In Bank journal: * Set an…
**Steps to reproduce:** - Install Accounting and l10n_se - Switch to a Swedish company (e.g. SE Company) - In Accounting settings, set "Identification" with anything - In Bank journal: * Set an account number * Make sure "Swedish ISO20022" is available in "Outgoing Payments" * Set "pain.001.001.09" as "XML Format" in "Outgoing Payments" - Create a vendor payment: * Vendor: [a vendor with a trusted bank account] * Payment Method: Swedish ISO20022 * Amount: [any] - Confirm the payment - From the payments list, select the payment and create a batch - Validate the batch payment **Issue:** When the batch is validated, a `pain.001.001.09` file should be generated. However, its content is that of a `pain.001.001.03` file, even if the version reported in the file is `pain.001.001.09`. For example, `<ReqdExctnDt>` should contains a subnode `<Dt>` in `001.001.09`, which is not the case. It leads to the file being rejected as non-compliant to `pain.001.001.09`. opw-6472050 Forward-Port-Of: odoo/enterprise#129506 Forward-Port-Of: odoo/enterprise#128598