Daily updates from Odoo
Thursday, June 18, 2026
37 changes · saas-19.3
Resolved issues and error corrections
This update optimizes a key process within Odoo's accounting module, specifically when validating journal entries. By caching a frequently used calculation, the system now responds more quickly, particularly when handling multiple journal entries or lines. This results in a smoother and faster user experience.
Original PR description
The method `get_relevant_plans` is called in `_validate_distribution`, which is often called in loops, for instance when validating the analytic distribution of multiple journal entries or of journal entries with multiple lines. That method is doing a lot of work by filtering all the plans and all the applicabilities every time, which can be avoided since the `kwargs` are likely to often be the same ones. Forward-Port-Of: odoo/odoo#269155
This fix resolves a problem where emails sent in bulk to accounting aliases could intermittently fail to process, resulting in bounced emails. The issue stemmed from concurrent database updates triggered by email attachments and OCR processing, leading to serialization errors. This update prevents these errors by improving how the system handles these concurrent operations.
Original PR description
Since https://github.com/odoo/odoo/commit/17893089e8b21c0ecab5e61ed8e2c33f3731b3ac, in certain cases, customers sending large batches of emails to an accounting email alias would report a small…
Since https://github.com/odoo/odoo/commit/17893089e8b21c0ecab5e61ed8e2c33f3731b3ac, in certain cases, customers sending large batches of emails to an accounting email alias would report a small number of emails being bounced (ca. 5%). Context: 1. While processing an email (after matching mail.alias, with the thread going through `message_process`), if an error is uncaught and raised, the mailgate generates a bounce email, as we presume that the email could not be processed correctly. 2. When sending an email with an attachment to an accounting journal alias, depending on the DB configuration, IAP calls for automatic OCR are triggered asynchronously. These calls trigger callbacks from the IAP server, which might hit the DB in parallel while another thread is processing another email. Given their nature, they trigger updates on the relevant account.move, thus triggering downstream computes in the model. 3. When processing an attachment, the account module triggers `_extend_with_attachments`, which tries decoding the attachment in a rollback context (see: https://github.com/odoo/odoo/blob/31df5033e31c193b4576ef37dfbc5fc683817bc5/addons/account/models/account_document_import_mixin.py#L343-L344). If a SerializationError happens during that process (concurrent update), it will NOT use the retry mechanism of the ORM because the error is caught in the `except Exception` block. Instead, it will try to post a message to the record to inform the user that the attachment could not be processed. 4. The commit mentioned above changes the way `_update_sequence_made_gap` works. One side effect seems to be that every time `made_sequence_gap` is re-assigned (even if the value does not change per se), the ORM tries to update the `write_date` on the flagged invoice that generated a sequence gap. Bug: Given the above context, emails might bounce unnecessarily for a valid email alias and a valid email with an attachment if: 1. The journal is not using a slash-based sequence pattern (e.g., using "1234" for the naming instead of "INV/2026/1234"). In that case, `sequence_prefix` == "". 2. The first invoice does not start at "1". 3. When sending a burst of simultaneous emails in a multi-worker setup, each thread will trigger `message_process` and downstream accounting computes while processing the invoice. It will also trigger IAP calls and callbacks asynchronously when automatic digitization is activated. 4. Each draft invoice that is created is named "/", meaning `sequence_prefix` == "", which in turn re-triggers the checks in `_update_sequence_made_gap`. 5. This increases the chances dramatically of a serialization error while all the parallel processes indirectly trigger an update on the `made_sequence_gap` field of invoice "1234". 6. Most of the time, the serialization error is not triggered in the thread processing the email, which correctly retries it. But in the few unlucky cases where it is raised in the thread processing the email, it will be triggered in the transaction rollback in `_extend_with_attachments`. While handling the exception, it triggers a second error because it tries to post a message to the record that was just rolled back: -> `ERROR: current transaction is aborted, commands ignored until end of transaction block` is raised in the thread running `message_process`, which in turn triggers a bounce email. Example logs (simplified): ``` 2026-06-12 14:12:15 [Worker-Thread-101] INFO mail_thread: Routing email (1) 2026-06-12 14:12:15 [Worker-Thread-102] INFO mail_thread: Routing email (2) 2026-06-12 14:12:16 [Worker-Thread-101] INFO iap_tools: dispatching /parse 2026-06-12 14:12:16 [Worker-Thread-102] INFO iap_tools: dispatching /parse 2026-06-12 14:12:18 [Worker-Thread-101] INFO iap_tools: Webhook received, triggering /get_result 2026-06-12 14:12:18 [Worker-Thread-102] INFO iap_tools: Webhook received, triggering /get_result 2026-06-12 14:12:19 [Worker-Thread-101] INFO odoo.sql_db: UPDATE "account_move" SET "made_sequence_gap" = true WHERE "id" = 1234 -> STATUS: OK (Acquired Row Lock) 2026-06-12 14:12:19 [Worker-Thread-102] ERROR odoo.sql_db: bad query: UPDATE "account_move" SET "made_sequence_gap" = true WHERE "id" = 1234 ERROR: could not serialize access due to concurrent update psycopg2.errors.SerializationFailure: could not serialize access 2026-06-12 14:12:19 [Worker-Thread-102] ERROR odoo.sql_db: bad query: SELECT "mail_message"."id" FROM "mail_message" WHERE ... ERROR: current transaction is aborted, commands ignored until end of transaction block psycopg2.errors.InFailedSqlTransaction: transaction is aborted 2026-06-12 14:12:19 [Worker-Thread-102] INFO "POST /saas_worker/smtp" 200 -> triggers Bounce email ``` Proposed Fix: A) We update the conditions in `check_around` to ignore draft invoices when they are the "previous" entity being checked. Only posted invoices should be considered when doing the gap checks. B) We add some guard clauses to prevent unnecessary writes to invoices that created sequence gaps. Instead of assigning values directly, we store the result of the check and only assign `made_sequence_gap` explicitly if the value is different from the currently stored value. This prevents unnecessary writes to the record if the value did not change. Note: - We chose this approach instead of touching `_extend_with_attachments` and the rollback context directly. Mostly to prevent any unforseen side-effects, given that this methods are used in accounting for all attachments. But it might be worth analysing if those methods might be improved to handle scenarios as described above in multi-worker setups + email handling. - fixing the rollbackable context might tricky because the serialization error happens at the first `cr.commit()` inside the context manager - raising explicitly with `except psycopg2.extensions.TransactionRollbackError:` in `_extend_with_attachments` retries the whole request to the `message_process`, which might not be a good idea OPW-6272396 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#270251
This update resolves an issue where navigating between tasks in Odoo caused errors due to outdated information being restored from the browser's session storage. The fix ensures that only dynamic actions are reused, preventing problems with context values and improving the overall stability of task navigation. This enhances the user experience by reducing unexpected errors.
Original PR description
Steps to reproduce: - Open any project task - Click a project notification that opens another task (requires the corresponding notification preference to be enabled) - Use the browser's Back and Forward buttons => Traceback: active_id is undefined When navigating to a form view via a URL (e.g. `/odoo/m-<model>/<id>`), the action service looks up the last action from session storage and reuses it if the model matches. This behavior, introduced in a4b179a7118916aac032ad252c0e421d452e553c, does not discriminate between dynamic and non-dynamic actions. Non-dynamic actions (those with an id) may rely on context values such as active_id that are only valid in their original execution context. Restoring such an action during browser history navigation causes a traceback because active_id is undefined. Fix by only reusing the session-stored action when it is a dynamic action (no id). Forward-Port-Of: odoo/odoo#270521 Forward-Port-Of: odoo/odoo#270076
A previous error message in the Odoo loyalty program was confusing for users, leading to frustration. This update corrects the error message to provide clearer guidance when discount codes aren't applied due to minimum purchase requirements. This ensures a smoother experience for customers using the loyalty program.
Original PR description
Issue: Error message was ambiguous and left users wondering what was wrong. Steps to reproduce: Set a discount code where the conditional rule is set to "minimum purchase" among specified products. Then, spend an amount larger than this on unrelated products and try to apply the discount code. "A minimum of x(currency) should be purchased to get reward" Cause: Poor error message caused ambiguity Solution: Corrected the error message so that the user can better understand where the issue is. opw-6290514 Forward-Port-Of: odoo/odoo#269319
This update resolves an issue where the EC List XML export incorrectly treated invoices with the same VAT number as separate partners, leading to rejection by tax agencies. The fix ensures that invoices with identical VATs are correctly grouped, resolving the rejection and improving compliance. This impacts the Belgian VAT reporting process.
Original PR description
With l10n_be: - Create two contacts with the same VAT - Create an invoice for each that is EC List compatible - Generate the return and export the EC List XML In the generated xml the two partners with the same vat are treated as different partners, which causes a rejection by the tax agency. opw-6109585 Forward-Port-Of: odoo/enterprise#120305 Forward-Port-Of: odoo/enterprise#117702
This update fixes a potential issue where Odoo would incorrectly try to install auto-install modules if a required dependency was missing. Now, if an auto-install module has a missing dependency, it won't be marked for installation, preventing installation errors and ensuring a smoother database setup process.
Original PR description
Let's consider an auto-install module `A` having 2 dependencies, one to `base` and the second to custom module `B`. If module `B` is not present in the addons path (i.e is unknown), during a new database initialization module `A` would still be marked as `to install`. This commit ensures that if an auto-install module has a missing dependency, it will not be marked as `to install`. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#270346
This update resolves an issue where product images in the self-order point-of-sale system were appearing distorted. The team applied a technical fix to ensure all product images are fully visible and displayed correctly, improving the customer experience. This change impacts the cart, combo, product list, and product detail pages within the self-order module.
Original PR description
In this commit: ------------------- - Applied `object-fit: scale` to ensure product images are fully visible and properly displayed without distortion. task: [6260046](https://www.odoo.com/odoo/project.task/6260046) Forward-Port-Of: odoo/odoo#270387 Forward-Port-Of: odoo/odoo#268521
This update corrects a minor issue within the Odoo Sale Project module's testing environment. A test was referencing a field that wasn't present in the community version of the module. Removing this reference ensures the tests run correctly and prevents potential errors.
Original PR description
The domain in the `test_group_expand_sales_order` test was using a field (`planned_date_begin`) that was not available in community. Since the domain is not relevant to the test, simply removing it fixes the issue. Runbot error: https://runbot.odoo.com/odoo/runbot.build.error/241204 task-6311159
This update fixes an issue where Point of Sale reports were incorrectly showing the session start date instead of the user-selected date range. The change ensures that reports accurately reflect the date range specified by the user, improving the accuracy of sales reporting. This was caused by a recent update to how the report determines session data.
Original PR description
Steps to reproduce ------------------ 1. Open a PoS session, e.g. at 1h45 2. Wait a bit and make an order, e.g. at 1h55 3. Keep the session open and go to PoS > Reporting > Sale Details. 4. Select a…
Steps to reproduce ------------------ 1. Open a PoS session, e.g. at 1h45 2. Wait a bit and make an order, e.g. at 1h55 3. Keep the session open and go to PoS > Reporting > Sale Details. 4. Select a starting date before the ordre and after the session open, e.g. at 1h50 5. Generate the report. The header shows the starting date of the session, i.e. at 1h45, instead of that of the selected date, i.e. 1h50 Why it's happening ------------------ Commit 5003774bf2a7 changed the way the report decides if the data comes from a single session: now if all the orders in the user selected start and end date belong to one particular session, the start and end date on the report are overriden to be those of that particular session, ignoring the user selected ranges. The fix ------- Only overwrite the start and end dates when `session_ids` was passed (i.e. the report is about a specific session). When called via date range + `config_ids` (from the backend wizard like in our reproduction steps), keep the user-selected range. opw-6185106 Forward-Port-Of: odoo/odoo#270310 Forward-Port-Of: odoo/odoo#267200
This update resolves an issue where related fields weren't correctly updating after changes were made in Odoo Studio. Specifically, when using Studio, the system didn't properly reflect new choices added to related fields. This fix ensures that related fields are consistently updated, regardless of how they were initially created.
Original PR description
This is because webclient knows the current value (c), but not the new available choices, still with the previous one (a, b). Actually this works correctly if the field is created within a model…
This is because webclient knows the current value (c), but not the new
available choices, still with the previous one (a, b).
Actually this works correctly if the field is created within a model
class.
```py
if model_cls._setup_done__ and field._base_fields__:
# the field has been created by model_classes._setup() as
# Field(_base_fields__=...); restore it to force its setup
name = field.name
base_fields = field._base_fields__
field.__dict__.clear()
field.__init__(_base_fields__=base_fields)
field._toplevel = True
field.__set_name__(model_cls, name)
field._setup_done = False
models_field_depends_done.discard(model_cls)
```
It does not works with studio because there are no parent class
(`_base_fields__`), so the if is not reached.
A solution would be to check if the field is a manually created related
and mark the whole model for setup unlike when `_base_fields__` is
present where we only setup this specific field.
opw-6293768
Forward-Port-Of: odoo/odoo#270349This update resolves an error that prevented users from opening the Gantt view for work orders. The fix ensures the system correctly handles resources without calendars, preventing a system crash when calculating availability. This improves the reliability of the work order scheduling process.
Original PR description
Currently, an error occurs when opening the gantt view of work orders. **Steps to Reproduce:** - Install `mrp_workorder` with demo data. - Go to `Settings` > `Technical` > `Resource` > `Resources`. -…
Currently, an error occurs when opening the gantt view of work orders. **Steps to Reproduce:** - Install `mrp_workorder` with demo data. - Go to `Settings` > `Technical` > `Resource` > `Resources`. - Open the `Assembly 1` resource and remove its `working time`. - Go to `Manufacturing` > `Operations` > `Work Orders`. - Switch to the `Gantt view`. `KeyError: 22` when the user opens the Gantt view, the system checks the unavailability of work centers and employees based on their resource calendars. While computing unavailable intervals for resources [1], resources without a calendar are flexible resources. If no leave interval exists within the specified start and end range that matches the domain, the resource is not included in the result [2]. when updating the unavailable intervals dictionary [3], the resource is missing. As a result, when it later tries to access the unavailable intervals for that resource, it raises an error [4]. This commit prevents the error by safely handling resources that are not present in the unavailable intervals dictionary by using an empty list instead. [1]: https://github.com/odoo/odoo/blob/1f666de440479dd3d30b7b6cf7c42862c5fcb37a/addons/resource/models/resource_resource.py#L186 [2]: https://github.com/odoo/odoo/blob/1f666de440479dd3d30b7b6cf7c42862c5fcb37a/addons/resource/models/resource_calendar.py#L532-L536 [3]:https://github.com/odoo/odoo/blob/1f666de440479dd3d30b7b6cf7c42862c5fcb37a/addons/resource/models/resource_resource.py#L187 [4] https://github.com/odoo/enterprise/blob/47f2e9e88fa0bbb8852fe7734c6bece4dca8b9d0/mrp_workorder/models/mrp_workorder.py#L692-L694 sentry-7525704808 Forward-Port-Of: odoo/enterprise#119385
This update resolves a bug that caused the Odoo application to crash when opening articles with embedded account reports. The fix prevents a change to the report's name during setup, ensuring stability and proper component functionality. This improves the user experience for reporting features.
Original PR description
When opening an article containing an embedded account report component, the application crashes because the `name` prop is mutated during the component `setup`, which is not allowed.
Steps to reproduce:
1. Create a new audit report
2. Open the "Journal Audit" article containing an embedded account report
=> The following exception is raised:
```
Uncaught (in promise) TypeError: setting getter-only property "name"
setup account_report.js:15
```
To fix the issue, the translation of the `name` prop is moved to `getProps`, which prepares component props before mounting. This ensures the value is already translated at instantiation time, avoids any mutation during setup, and preserves prop immutability throughout the component lifecycle.
Ref: odoo/enterprise#109962
Task-6292898
Forward-Port-Of: odoo/enterprise#120077This update resolves an issue where moving Odoo databases via the command line would inadvertently deregister the associated subscription. The new `--move` flag ensures the database's original UUID is retained during a move, maintaining the subscription link. This improves the reliability of server-to-server database transfers.
Original PR description
### What & why `odoo db load` always calls `restore_db(..., copy=True)`, which forces the generation of a new `dbuuid` via `ir.config_parameter.init(force=True)`. That is the right default when…
### What & why `odoo db load` always calls `restore_db(..., copy=True)`, which forces the generation of a new `dbuuid` via `ir.config_parameter.init(force=True)`. That is the right default when *duplicating* a database, but it breaks the intended behaviour when *moving* a database between servers: Enterprise subscription codes are registered against the database UUID, so regenerating it deregisters the moved database. The web database manager already lets the user choose between copying and moving (the `copy` flag of the `/web/database/restore` route), but the CLI exposed no equivalent and forced a copy unconditionally. The CLI is the better tool for server-to-server moves: it isn't subject to reverse-proxy upload/timeout limits and can run unattended or interactively. ### Steps to reproduce the current limitation 1. On server A: `odoo db dump mydb mydb.zip` (Enterprise DB registered to its UUID) 2. On server B: `odoo db load mydb mydb.zip` 3. `database.uuid` has changed → the subscription is deregistered ### Fix Add a `--move` flag to `odoo db load` that maps to `restore_db(copy=False)`, keeping the original UUID. The default remains `copy=True`, so existing behaviour is unchanged. ```sh odoo db load mydb mydb.zip # unchanged: restore as a copy (new UUID) odoo db load --move mydb mydb.zip # new: restore as a move (keep the UUID) ``` ### Backport request This would be greatly appreciated as a backport to 18.0, 17.0, and 16.0 as well. Those are precisely the versions that ship the `odoo db` CLI subcommand, so the fix is applicable to all of them — which is why the backport range is 16.0 → 19.0 and stops at 16.0. Forward-Port-Of: odoo/odoo#268700 Forward-Port-Of: odoo/odoo#268501
This update eliminates a frustrating popup that appeared during refund order creation in Point of Sale. Now, refund processes for both direct sales and refunds proceed without interruption, improving the user experience and efficiency for our sales teams.
Original PR description
Before this commit: =================== - Preset selection popup was shown when creating refund orders. - Refund process was interrupted by unnecessary preset selection. After this commit: ================== - Preset selection popup no longer appears for refund orders. - Direct sale refund orders proceed smoothly. Task - 6170816
This update fixes an issue where employee attendance records were incorrectly recorded due to timezone discrepancies. The system now accurately stores attendance check-in/out times in UTC, ensuring accurate reporting and scheduling. This improves the reliability of attendance data.
Original PR description
This commit includes the following: - BioTime returns punch_time as naive local time in the employee's timezone, but it was stored verbatim and treated as UTC, so attendance check-in/out times were off by the timezone offset. - Convert punch_time through the employee's timezone to UTC before storing, via the new _punch_time_to_utc helper. Task-6181807
This update fixes an issue where order-level customer notes weren't appearing on preparation tickets. The fix ensures that all customer notes, including internal notes, are now printed on these tickets, improving communication with the kitchen staff. It also prevents unnecessary tickets from being generated when notes are updated.
Original PR description
Steps to Reproduce: - Open Restaurant POS configured with a preparation printer. - Create a new order and add a customer note at the order level. - Send the order for preparation. Issue: - The order-level customer note is not printed on the preparation ticket. Fix: - Ensure the customer note is included in the preparation ticket. - Prevent additional preparation tickets from being printed when the customer note (or internal note) is modified alongside order lines. Task-5960046 Forward-Port-Of: odoo/odoo#250063
This update resolves an error that occurred on the `/partners` website page after upgrading to version 19.2. The issue stemmed from a change in how website templates are managed during upgrades, specifically related to a technical element called 't-call'. This fix ensures a smoother upgrade process and prevents website access problems.
Original PR description
**Issue:** Currently, an error occurs when users access the `/partners` website page after upgrading a database with the `website_crm_partner_assign` module (including demo data) to saas-19.2. **Root…
**Issue:**
Currently, an error occurs when users access the `/partners` website page
after upgrading a database with the `website_crm_partner_assign`
module (including demo data) to saas-19.2.
**Root cause:**
This issue occurs because recent changes introduced in PR [1] added a
new template as id `index_layout`. Inside this template, a `t-call` element
was using a nested `t-set` element to define `additional_title`. We were
referencing this `t-set` element in the XPath of the `index` template to
override the value of `additional_title`.
However, recent changes removed the `t-set` from the `t-call` and replaced
it with a direct variable assignment inside the `t-call`. During the upgrade,
the migration script automatically moves the `additional_title` attribute
into `t-call` and removes the `t-set` from the `t-call` (see the script and
related changes in [2]).
As a result, the XPath expression that targets the `t-set` element fails
because the referenced element no longer exists, which causes the error.
**Solution:**
This commit fixes the issue by moving the `t-set` element outside the `t-call`
and passing its value as an attribute of the `t-call` during the upgrade.
The `t-set` element is preserved to maintain compatibility with custom `XPath`
expressions that may target it, prenet XPath target errors after the upgrade.
The upgrade-specific behavior is enabled only when `config.get('upgrade_path')`
is set, allowing the code to detect that it is running in an upgrade context.
[1]: https://github.com/odoo/odoo/commit/711c3baad58f3e0f1dc39cb90eb8176aba91e9dd
[2]: https://github.com/odoo/odoo/pull/235469/changes#diff-29ae6f0bcf846a2fcaffc38fdd0d3b19ea328c133ff4dfe18cc9725715f34dd9
Sentry-7400315548
Forward-Port-Of: odoo/odoo#268864This update corrects a visual issue where employee profile images were stretched in the employee form. The change ensures images display correctly and consistently with other employee views, improving the overall user experience. This fix was implemented as part of a broader redesign effort.
Original PR description
Vertical images were stretched due to changes made during the form view's redesign (a58ed7d) and after adding a fixed size (6d40ab9). We've added an `.object-fit-contain` class to fix this issue and a rounded border to make the image's aligned with other similar views. task-5418517 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#270126 Forward-Port-Of: odoo/odoo#262033
This update ensures that Odoo can properly create functional indexes using the 'unaccent' PostgreSQL function. Previously, the system wasn't correctly recognizing when 'unaccent' was available for indexing, leading to potential performance issues. This fix ensures indexes are created only when the function is properly configured for use.
Original PR description
PostgreSQL's `unaccent` function must be marked as `IMMUTABLE` before it can be used in a functional index. The ORM usually handles this when the `unaccent` extension is missing and `odoo-bin` is…
PostgreSQL's `unaccent` function must be marked as `IMMUTABLE` before it can be used in a functional index.
The ORM usually handles this when the `unaccent` extension is missing and `odoo-bin` is started with the `--unaccent` flag during database creation.
However, it is also possible to start `odoo-bin` with an existing database where the `unaccent` extension is already installed, but the function was never marked as `IMMUTABLE`.
In that case, `unaccent` can still be used in conditions such as `WHERE` clauses, but it cannot be used in functional indexes.
`has_unaccent()` actually has three possible states:
```py
class FunctionStatus(IntEnum):
MISSING = 0 # function is not present (falsy)
PRESENT = 1 # function is present but not indexable (not immutable)
INDEXABLE = 2 # function is present and indexable (immutable)
```
Therefore, checking only `if has_unaccent()` before creating an index using `unaccent` is not enough. The index should only be created when `has_unaccent()` returns `FunctionStatus.INDEXABLE`.
task-6307060
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#270420
Forward-Port-Of: odoo/odoo#270278This update corrects a duplication of functionality within the Web Studio module. The abstract field, previously a separate addition, has been removed as it's now correctly implemented in the base Odoo module. This ensures consistency and simplifies the Web Studio experience.
Original PR description
The abstract field was added in odoo/odoo#186121 in the base module. Removing the overwrite here. runbot-940119 Backport of https://github.com/odoo/enterprise/pull/120708
This update fixes an issue where the field selector expanded beyond the display edges. The change removes a previously added style rule, allowing the selector to properly utilize its intended maximum height and display correctly. This ensures a consistent and functional user experience.
Original PR description
Prior to this commit, the field selector would expand vertically to the edges or beyond the edges of the display. That was caused by the addition of the `o_popover` class in the scss selector in the file of the component. It was originally done to avoid having this style applied on touch devices but most of the changes of the original PR got reverted. This commit removes the extra popover class in the css selection and thus allows the `max-height` rule that was defined there to properly apply to the component. Task-6277505 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update resolves an issue where the rental and subscription status badges were overlapping in sales orders. The fix replaces a positioning method with a simpler float-end approach, ensuring both badges are correctly displayed without interference. This improves the visual clarity of sales order information.
Original PR description
Steps to produce: --- - Install the `Rental` and `Subscription` modules. - Create a rental product and a subscription product. - Create a sales order containing both products and set a rental period.…
Steps to produce: --- - Install the `Rental` and `Subscription` modules. - Create a rental product and a subscription product. - Create a sales order containing both products and set a rental period. - Confirm the sales order. Issue: --- - The rental status badge overlaps the subscription status badge. Root cause: --- - The rental status badge uses the position-absolute CSS class to place it at the end of the header. When the subscription status badge is also displayed in the same area, both badges are positioned at the same location, causing them to overlap. - After [commit], this issue is introduced. Solution: --- - Replace position-absolute with float-end so the badges remain right-aligned without overlapping. [commit]: https://github.com/odoo/enterprise/commit/32ab15dc1f26af0e3d510ec859b1ec428068e9b5 Before: --- <img width="122" height="64" alt="image" src="https://github.com/user-attachments/assets/e6b47c9e-ed59-4a4b-a95c-0318cc43660e" /> After: --- <img width="175" height="57" alt="image" src="https://github.com/user-attachments/assets/ea98f7a1-67f6-4b2b-b699-1f2cd3376d8f" /> opw-6295212 ---
This pull request addresses a bug in the testing of POS orders that have been partially refunded. The fix ensures accurate calculations when handling refunds on POS orders, preventing potential discrepancies in reported amounts. This improves the reliability of our point-of-sale reporting.
Original PR description
runbot-939926 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update fixes a bug where rental order PDFs didn't show the pickup and return dates. The fix adds the necessary fields to the PDF report, ensuring consistent presentation with the customer portal. This improves clarity and accuracy for rental order documentation.
Original PR description
**Problem:** On a rental order, the sales order / quotation PDF no longer shows the pickup and return dates. The line description only displays the rental duration (e.g. "2 Days"), so the actual…
**Problem:** On a rental order, the sales order / quotation PDF no longer shows the pickup and return dates. The line description only displays the rental duration (e.g. "2 Days"), so the actual dates are missing from the printout. **Steps to reproduce:** 1. Create a rental order with a rentable product and pickup/return dates 2. Print the order (Print > Quotation / Order) 3. Observe the PDF shows only the duration, with no pickup/return dates **Current behavior:** Neither the rental dates (removed from the description) nor any pickup/return field appear on the PDF. **Expected behavior:** The pickup and return dates are shown on the rental order PDF. **Cause of the issue:** The rental line description was intentionally reduced to only the duration (`_get_rental_duration_description`), the actual dates being meant to appear as dedicated Pickup/Return fields. This was added to the customer portal (`sale_rental_portal_details` inherits `sale.sale_order_portal_content`) but the equivalent was never added to the `sale.report_saleorder_document` PDF report, so the dates disappeared from the printout. **Fix:** Inherit the sale order report to render the order-level pickup and return dates for rental orders, mirroring the existing portal presentation so the PDF and the portal stay consistent. opw-6268640
This update resolves a technical error preventing the 'XML Polizas (SAT)' export from functioning correctly for Innovacion Company users. The fix ensures the export process correctly handles file data types, allowing users to successfully generate and download their required financial reports. This improves the reliability of a key accounting reporting feature.
Original PR description
How to reproduce it: - Install l10n_mx_reports and select Innovacion Company - Go to accounting app > reporting and Open the General Ledger report - Trigger the "XML Polizas (SAT)" export, fill in the wizard (export type and order/process number) and click Export - A traceback is raised instead of downloading the file: TypeError: ... report_data: use BinaryValue instead of bytes This error happens because export_xml writes the generated file to the report_data field as raw bytes. After the introduction of BinaryValue, no longer accepts bytes values (unless raw field) for Binary fields and now expects a BinaryValue, causing the traceback. The write was modified on refactoring PR, but not correctly and there wasn't a test targeting the url action part so it was not flagged. This commit fixes the issue by wrapping the content in BinaryBytes (since is a BinaryValue) before assigning it to report_data and added tests covering the single and multiple period cases. task-6297731
This update fixes a visual issue where downloaded PDF invoices and debit notes incorrectly displayed 'INVOICE DINV...' instead of 'DEBIT NOTE DINV...'. This change ensures that debit notes are clearly distinguishable from invoices in printed and sent documents, improving clarity for our customers.
Original PR description
### Steps to reproduce the issue: 1. Download Invoice and Debit Notes 2. Go to an invoice (or create a new one) 3. Create a debit note for that invoice and print it or send it 4. In the PDF the title is 'INVOICE DINV....' instead of 'DEBIT NOTE DINV...' ### Reason to introduce the fix: Differentiate debit notes from invoices. opw-6252239 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#268207
This update prevents users who aren't designated approvers from directly accepting or rejecting approval requests through the system's activity interface. Previously, this allowed unintended actions, causing errors. This change improves security and ensures that approval workflows are handled correctly by authorized personnel.
Original PR description
Currently when a user submits an approval request, an activity is created for the approver who can validate or refuse the request directly from the activity, however these options are also visible to other users who will trigger an error if interacting with the options. This commit removes these options for users who are not the approver. **Steps to reproduce:** - Log in as admin - Go to approvals - Select dropdown menu of General Approval and Edit - Change documents to optionnal - Make sure admin is in the approvers list - Log in as demo - Go to approvals -> General Approval -> New Request - Submit the request - You'll see an activity be created for admin, with Accept and Refuse options - If you select any of these options you will get an access error opw-5423528 Forward-Port-Of: odoo/enterprise#120643 Forward-Port-Of: odoo/enterprise#109047
This update ensures that binary files uploaded through forms now correctly store their filenames. Previously, this functionality was limited to manual fields, causing issues with mimetype detection and hindering the use of these fields in SaaS modules. This change improves data accuracy and simplifies future migrations.
Original PR description
Description of the issue/feature this PR addresses: Since [1], studio binary fields uploaded through a form store their filename. Due to the condition of [1], this behaviour is restricted to manual…
Description of the issue/feature this PR addresses: Since [1], studio binary fields uploaded through a form store their filename. Due to the condition of [1], this behaviour is restricted to manual fields, which limits the usage of those fields in standard and is particularly problematic when Saas modules that use this feature are migrated to Python. Not storing the filename can lead to incorrect mimetype guesses. Given that a more appropriate condition has already been added in [2], it should no longer be necessary to restrict this feature to manual fields. This commit removes that restriction to allow standard binary fields to store their filename when uploaded through a form. Current behavior before PR: When uploading a file to a non-manual binary field that has a related '_filename' field, the filename will not be stored, which can later lead to incorrectly guessing the mimetype of the file. Desired behavior after PR is merged: Uploading a file to a non-manual binary field that has a related '_filename' field stores the filename of the file. Task related to this issue: https://www.odoo.com/odoo/project.task/5917543 [1] https://github.com/odoo/odoo/commit/0e2f3b144581c47d25a99cecdd7e058a3d55bcc3 [2] https://github.com/odoo/odoo/commit/1bcab2f42eebf98127416e54f31cd6e351938b7f --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#268014
This update resolves an issue where SEPA QR codes were occasionally displaying incorrect decimal places due to floating-point precision problems in the underlying calculations. The fix ensures the QR code accurately reflects the vendor bill payment amount with the correct currency precision, improving data accuracy for payments.
Original PR description
**Description of the issue/feature this PR addresses:** When generating a SEPA QR code for a vendor bill payment, the embedded amount could occasionally contain excess decimal places instead of…
**Description of the issue/feature this PR addresses:** When generating a SEPA QR code for a vendor bill payment, the embedded amount could occasionally contain excess decimal places instead of respecting the currency's expected precision. This occurs because the `amount` variable in `_get_qr_vals` was being converted directly using `str(amount)`. Due to Python's floating-point arithmetic, the float value in memory can contain decimal drift. Directly casting it to a string exposes this drift in the payload. This commit resolves the issue by replacing `str(amount)` with `float_repr(amount, currency.decimal_places)`. This safely bypasses the float representation issue, ensuring the string strictly respects the currency's configured decimal precision before being injected into the QR code. opw-5504258 **Steps to reproduce:** - Select company “My Belgian Company” - Create a 23% purchase tax - Create vendor bill - Select Vendor “BE Company CoA” - Choose any single product, change price to 37.18 and choose the 23% tax. The Untaxed Amount should be 37.18, VAT tax should be 8.55, and Total should be 45.73 - Confirm > Register Payment > scan QR code. EUR45.730000000000004 should show **Current behavior before PR:** - When generating a SEPA QR code for a payment, the embedded amount can contain excess decimal places due to floating-point drift. **Desired behavior after PR is merged:** - The SEPA QR code is generated with the correct number of decimal places. Forward-Port-Of: odoo/odoo#269190 Forward-Port-Of: odoo/odoo#267293
This update fixes an issue where canceling a CFDI incorrectly triggered a cancellation of the associated down payment. The system now correctly uses the '04' origin code for CFDI cancellations, aligning with Mexican regulations and preventing unintended down payment cancellations. This ensures accurate CFDI processing and compliance.
Original PR description
**Steps to reproduce:** - Install Sales, Accounting and l10n_mx_edi - Switch to a Mexican company (e.g. ZAPATERIA URTADO ÑERI) - Create a SO: * Customer: [a Mexican customer] (e.g. INMOBILIARIA CVA) * Payment Way: Efectivo * Payment Policy: PUE * Product: [any product with a UNSPSC Category] * Taxes: [any] (e.g. 16%) - Confirm the SO - Create a down payment (e.g. 60%) - Confirm the down payment - Send it to CFDI - Copy the fiscal folio - Go back to SO - Create the final invoice - Set the copied fiscal folio prepend with "07|" as CFDI Origin - Confirm the invoice - Send to CFDI **Issue:** A cancellation request is sent to CFDI for the down payment. "07" origin code is used to link the invoice to a down payment. It should not cancel the down payment. It should only be done with "04" origin code used for substitution of a previous invoice. opw-6266678 Forward-Port-Of: odoo/enterprise#120757
This update resolves a requirement from Luxembourg auditors regarding the classification of partners in our SAFT reports. Specifically, it ensures that less than 30% of transactions with payable or receivable accounts have missing supplier or customer IDs, respectively. The changes update the XML data to align with audit guidelines and maintain compliance.
Original PR description
This PR is one of many triggered by responses from Luxembourg auditors. See PR #113316 for a full list of these PRs. As described in PR #117799, the \CustomerID and \SupplierID elements on…
This PR is one of many triggered by responses from Luxembourg auditors. See PR #113316 for a full list of these PRs. As described in PR #117799, the \CustomerID and \SupplierID elements on \Transaction\Line elements is determined by a partner's `customer_rank` and `supplier_rank`. This is a binary designation, one or the other. The Luxembourg FAIA report requires that less than 30% of \Transaction\Line elements with payable accounts (class 6) can not have \SupplierID. The same applies for \Transaction\Line elements with receivable accounts (class 7) and the \CustomerID element. TSB clarified that any partner on an receivable or payable line should be added to the Customer list or Supplier list respectively https://github.com/odoo/enterprise/pull/100749#issuecomment-3655127511. In addition, I verified that Luxembourg's analysis of four separate FAIA files (from ticket 5427296) aligns with this expectation. <img width="1322" height="690" alt="image" src="https://github.com/user-attachments/assets/1a82f99e-5b32-4dbb-96e1-1b25bab2629b" /> This commit adds partners to the \Supplier and \Customer lists if they have any payable or receivable lines, respectively. It also picks between the \CustomerID and \SupplierID based on a line's `account_type`. This logic is applied to `account_saft` and updates the other, country-specific SAFT reports where appropriate. It also retains the previous `customer_rank` and `supplier_rank` logic as a fallback for older XML reports and for accounts other than `asset_receivable` or `liability_payable`. opw-6118024 Forward-Port-Of: odoo/enterprise#120790 Forward-Port-Of: odoo/enterprise#118714
This update corrects a bug where the timesheet timer was incorrectly adding extra seconds, leading to inaccurate overtime calculations and marking workdays as exceeding their allotted hours. The fix ensures that the user-entered time is accurately saved, preventing this overtime display issue. This change was introduced in the saas-19.2 release.
Original PR description
Steps to reproduce --- 1. Set an employee to work 8 hours per day. 2. Open the timesheet timer in the systray, type a duration like 8:00 and save. 3. Open the My Timesheets grid for that day. The day…
Steps to reproduce --- 1. Set an employee to work 8 hours per day. 2. Open the timesheet timer in the systray, type a duration like 8:00 and save. 3. Open the My Timesheets grid for that day. The day is marked as overtime (yellow) even though only 8 hours were logged. Issue --- While the entry is open the timer keeps running and, every second, writes the elapsed time into unit_amount down to the second. https://github.com/odoo/enterprise/blob/a3c9295cf28b47f43233ac6a9f4106810842e37a/timesheet_grid/static/src/components/timesheet_timer_inline_form/timesheet_timer_inline_form.js#L89-L102 When the duration is set by hand, the save skips the usual rounding and keeps the value as it is. https://github.com/odoo/enterprise/blob/a3c9295cf28b47f43233ac6a9f4106810842e37a/timesheet_grid/static/src/components/timesheet_timer_inline_form/timesheet_timer_inline_form.js#L120-L132 So the clean 8:00 the user typed gets a few extra seconds from the next timer tick (8h 1s, stored as 8.000277) and is saved with them. The seconds are hidden in the HH:MM display but are enough to push the day above its working hours, so the grid paints it as overtime. This timer form is new in saas-19.2 (c3dac6ccdb5), which is why earlier versions are not affected. The fix ignores timer ticks once the duration has been set by hand, so the typed value is kept. opw-6180676 --- Forward-Port-Of: odoo/enterprise#120601
This update resolves an issue where the appointment calendar displayed 'no slots available' in future months due to incorrect calculation of availability. The fix accounts for appointment lead times, ensuring the calendar accurately reflects available slots when navigating forward. This improves the user experience for scheduling appointments.
Original PR description
The website appointment calendar fills availabilities one month at a time and the update_available_slots route maps the calendar month index to an absolute month from datetime.now(). This only…
The website appointment calendar fills availabilities one month at a time and the update_available_slots route maps the calendar month index to an absolute month from datetime.now(). This only matches the displayed months when the first one is the current month. When the first bookable slot is later, a punctual appointment starting in a future month or any appointment whose "at least X hours before start time" lead time pushes the first slot past the current month, navigating forward requests the wrong month and the reached month renders empty. In update_available_slots, take the lead time into account when computing the reference month so it lands on the first displayed month: the start datetime for a punctual appointment starting in the future, otherwise now plus the minimum schedule hours. The navigated month index is then added to that reference. This extends https://github.com/odoo/enterprise/commit/f0e5b14a823cf97218f4094d287a328e2744fd73 which only handled the future start datetime. Steps to reproduce: 1. Open the Appointments app 2. Open an appointment type, set Schedule to Weekly and Allow Bookings to On specific dates with a range ending a few months out 3. Set the "at least N hours before start time" field to 360 4. Save and click the Preview button in the header 5. Pick a resource or staff member to reach the calendar 6. Click the right arrow to navigate to the next month => the next month shows "Sorry, we have no more slots available for this month" opw-6206293 Forward-Port-Of: odoo/enterprise#120715
This update fixes an issue where the system wasn't accurately tracking component usage when creating backorders on manufacturing orders. Specifically, the component quantity wasn't being fully consumed, leading to incorrect inventory levels. This change ensures that the correct amount of components is deducted from stock when a backorder is created, improving inventory accuracy.
Original PR description
### Steps to reproduce: - In the settings enable: Multi-Steps Routes - Set your warehouse to manufacture in 2 steps (pick then manufacture). - Create a final product (FP) with a BOM in flexible…
### Steps to reproduce: - In the settings enable: Multi-Steps Routes - Set your warehouse to manufacture in 2 steps (pick then manufacture). - Create a final product (FP) with a BOM in flexible consumption: - 2 x COMP (lot tracked) - Put a lot for 6 units in of COMP in stock - Create and confirm an MO for 5 units of FP - Set the quantity producing on the MO to 1, requiring 2 of the 6 available units of COMP - Validate the MO and create a backorder for the remaining quantity. #### > The consumed qty on the main MO is of 0 units rather than 2. ### Cause of the issue: Since the component is tracked, and since the pbm move was backordered, the move quantity will not be automatically set when setting the `qty_producing`: https://github.com/odoo/odoo/blob/a1bcd917846493d08dd02b63e6110078ff5156a3/addons/mrp/models/mrp_production.py#L1405-L1411 And in particular, the move is not picked as it would if the product was untracked or if the pbm move was not backordered: https://github.com/odoo/odoo/blob/a1bcd917846493d08dd02b63e6110078ff5156a3/addons/mrp/models/mrp_production.py#L1421-L1427 And, since the move will not be picked at any other point in this flow, the move will be unreserved during the `button_mark_done`: https://github.com/odoo/odoo/blob/7c35e183d6cc33a6e5d20e5e97ffef79e03b49d4/addons/mrp/models/mrp_production.py#L2216 https://github.com/odoo/odoo/blob/7c35e183d6cc33a6e5d20e5e97ffef79e03b49d4/addons/mrp/models/mrp_production.py#L1895-L1896 https://github.com/odoo/odoo/blob/7c35e183d6cc33a6e5d20e5e97ffef79e03b49d4/addons/mrp/models/mrp_production.py#L1901 opw-6128575 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#269535 Forward-Port-Of: odoo/odoo#269235
This update fixes an issue where the /checklist command was not functioning in the CRM's activity note editor. The change reverts a recent update that inlined activity note content, causing the checklist to be disabled. Now, the checklist command is correctly available within activity notes, allowing users to easily add checklist items.
Original PR description
In 19.0 the /checklist command does not appear in the activity note editor. The note fields of activities, the schedule activity wizard and activity plan templates were moved to widget="html_mail" by…
In 19.0 the /checklist command does not appear in the activity note editor. The note fields of activities, the schedule activity wizard and activity plan templates were moved to widget="html_mail" by https://github.com/odoo/odoo/commit/2f61560ab45576191394510016c38a7442b95ec8, https://github.com/odoo/odoo/commit/35d673dccdc0f0c2a06cb0732e3148370f035af9 and https://github.com/odoo/odoo/commit/4d3a6156d07dc47bb2399d1907e2a47869827933 to render attachment overviews statically instead of with embedded components. html_mail is made for email bodies, it inlines the content on save and it disables the checklist since https://github.com/odoo/odoo/commit/f94f695ca9fc9a894a837640df2e4160e561f1ab because checklists do not survive the inlining of outgoing emails. The activity note is not an email body, so it gets both side effects for nothing. Keep the default html widget on these note fields and pass the embedded_components option as false, which is the only part of html_mail the attachment commits needed. The checklist works again, the note is not inlined on save anymore, and the attachment overview still renders statically. The widgets used for real email bodies keep the checklist disabled. Steps to reproduce: 0. Install the CRM module. 1. Open a lead from the CRM pipeline. 2. Click Activity to open the Schedule Activity dialog. 3. Click inside the Log a note field and type /checklist. => Checklist doesn't appear. Ticket [link](https://www.odoo.com/odoo/project.task/6139971) opw-6139971 Forward-Port-Of: odoo/odoo#261071
This update resolves an issue where required fields on the customer form within the Point of Sale (POS) system were disappearing due to a change in how the form was displayed. The fix maintains the simplified view while allowing localization teams to easily re-enable these fields, ensuring accurate invoicing and customer data. This change was implemented to streamline the POS form without impacting core functionality.
Original PR description
*: l10n_{ar,co,in,pe,uy}_pos **Problem:** The POS "Edit/Create customer" Form was switched to a standalone, hardcoded form view (view_partner_form_pos_ui) that inherits nothing during [1], in the…
*: l10n_{ar,co,in,pe,uy}_pos
**Problem:**
The POS "Edit/Create customer" Form was switched to a standalone, hardcoded form view (view_partner_form_pos_ui) that inherits nothing during [1], in the attempt to simplify the view when accessed from the PoS.
Every field that localizations and other modules add to the partner form by inheriting base.view_partner_form therefore disappeared when accessed from PoS. Some of the fields are required, for example, to invoice.
**Solution:**
Keep the simplified view as the default, but route the view selection through an overridable hook that localization can tweak case by case. The override is applied to the affected POS bridges (see module list).
Add a test to prevent future regression.
**Note:**
Another possibility is to re-inherit for each localization the new
standalone view, but this fix would need to update the module to work,
while this one works with just a restart.
There are still ongoing discussion with PoS team to see if we really
want to go back to each localization needing to inherit backend views.
[1]: https://github.com/odoo/odoo/pull/230721/changes#diff-66cd201e7e8cfff5218a9fa93efd72f0bd77659b87359f2ca8763702462aaf92R26
opw-6244777 (many more)
Forward-Port-Of: odoo/odoo#268158This update resolves an issue where required fields on customer forms within the Point of Sale (PoS) system were disappearing for certain localization modules (Brazil, Chile, etc.). The fix temporarily keeps the simplified view while introducing a mechanism for localization teams to easily re-enable these fields. This ensures accurate invoicing and customer data.
Original PR description
*: br,cl,ec,gt,it,ke,mx **Problem:** The POS "Edit/Create customer" Form was switched to a standalone, hardcoded form view (view_partner_form_pos_ui) that inherits nothing during [1], in the attempt…
*: br,cl,ec,gt,it,ke,mx **Problem:** The POS "Edit/Create customer" Form was switched to a standalone, hardcoded form view (view_partner_form_pos_ui) that inherits nothing during [1], in the attempt to simplify the view when accessed from the PoS. Every field that localizations and other modules add to the partner form by inheriting base.view_partner_form therefore disappeared when accessed from PoS. Some of the fields are required, for example, to invoice. **Solution:** Keep the simplified view as the default, but route the view selection through an overridable hook that localization can tweak case by case. The override is applied to the affected POS bridges (see module list). Add a test to prevent future regression. **Note:** Another possibility is to re-inherit for each localization the new standalone view, but this fix would need to update the module to work, while this one works with just a restart. There are still ongoing discussion with PoS team to see if we really want to go back to each localization needing to inherit backend views. [1]: https://github.com/odoo/odoo/pull/230721/changes#diff-66cd201e7e8cfff5218a9fa93efd72f0> opw-6244777 (many more) Forward-Port-Of: odoo/enterprise#119316