Daily updates from Odoo
Friday, October 31, 2025
100 changes
10 changes
Enhancements to existing features
VoIP sessions now try to sign out automatically when a browser tab is closed and expire sooner if that does not happen. This helps prevent users from hitting provider limits caused by multiple open or recently closed Odoo tabs.
Original PR description
Some providers like OnSIP allow for a limited number of registrations per user. This is a problem in Odoo because each tab opened creates a new registration for one hour. This commit mitigates the problems in two ways: - Sends an "unregister" request onbeforeunload to try to invalidate the registration upon closing the tab. - Reduces the TTL of registrations so that they get invalidated quicker in case the unregistration failed. Forward-Port-Of: odoo/enterprise#98413 Forward-Port-Of: odoo/enterprise#97963
Recruitment screens now load much faster by simplifying how eligible users are determined for job records. This reduces page processing time and response size, making the Recruitment app feel more responsive, especially for companies with many users.
Original PR description
Description ----------- The commit odoo/odoo@0f981b14ea22cc154bcd93f53dc19f46c37ecb13 tried to fix an issue where, if the `company_id` was not set in the Form view, no `user_id` would match if they…
Description
-----------
The commit odoo/odoo@0f981b14ea22cc154bcd93f53dc19f46c37ecb13 tried to fix an issue where, if the `company_id` was not set in the Form view, no `user_id` would match if they had a `company_id` set, while the wanted behavior was the inverse, all internal users should match regardless of companies.
This was fixed by introducing a computed field `allowed_user_ids` which was doing the company computation manually and replaced the `company_ids` domain leaf on the field.
Sadly, this approach introduces a performance regression on the front-end side, as the webclient creates internal data structures *per* individual result of the RHS in the domain. So if `allowed_user_ids` returns a lot of matching `ids`, it becomes a significant overhead.
Following the refactoring of `domains.py`, a slight semantic change happened and the initial issue of the bugfix can be resolved by just changing the domain operator to `'=?'` instead. When `company_id=False`, the domain leaf `('company_ids, '=?', False)` is optimized out by `_operator_equal_if_value` as `_TRUE_DOMAIN` (aka `(1, '=', 1)`). This is as expected behavior post-bugfix. This was not the case before the refactoring.
This allows us to completely deprecate the usage of the field `allowed_user_ids` and the front-end has no significant post-processing to do.
⚠️ This commits deprecates `hr.job.allowed_user_ids`, but doesn't remove it yet, as it might be referenced by views or custom JS.
Benchmark
---------
On a 19.0 database where `allowed_user_ids` returns 1.4k ids, opening the default kanban view of the Recruitment app took:
| | Before | After | Improvement |
|-----------------------|---------|--------|-------------|
| Backend process time | 400ms | 160ms | 2.5x |
| Frontend process time | 3.3s | 220ms | **15x** |
| Total (LCP) time | 3.7s | 380ms | 9.7x |
| Response Payload size | ~800KiB | ~33KiB | **24x** |
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#232354Resolved issues and error corrections
This fixes an issue where live chat operators with standard live chat permissions could not pin a customer's message after a chatbot handed the conversation over to them. The change prevents an unnecessary permission check during message pinning, helping operators manage live chat conversations without errors.
Original PR description
To reproduce (on runbot): - S1: Connect as "admin", leave the "YourWebsite.com" then logout - S1: Connect as "demo" user - S2: As public user, go to /contactus and start a chat session - S2: On the chatbot interaction, choose "I have a pricing question" (this will forward to the operator) - S2: enter a message - S1: On the livechat session, try to pin the last user message Since 1ecddc3d79dd an `AccessError` is raised, as the "demo" user (which is only `LiveChat / User`) don't have access to the chatbot step anymore. As we're not in the interacting with the chatbot when pinning a message, simplify skip that part if there is no "chatbotx answner" context to prevent the `AccessError`. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#233617
Corrects discount rounding for Mexican electronic global invoices so valid invoices are not rejected by CFDI validation. This prevents errors when confirming invoices with percentage discounts and helps ensure compliant invoice generation.
Original PR description
Steps to reproduce: ------------------- * Create an invoice with the following line: * Unit price: 47.25, Qty: 1, Taxes: 16%, Discount 50% * Confirm, create a global invoice > Observation: Error ```…
Steps to reproduce: ------------------- * Create an invoice with the following line: * Unit price: 47.25, Qty: 1, Taxes: 16%, Discount 50% * Confirm, create a global invoice > Observation: Error ``` Code : CFDI40108 Message : El TipoDeComprobante es I,E o N, el importe registrado en el campo no es igual al redondeo de la suma de los importes de los conceptos registrados. ``` Why the fix: ------------ The issue occurs because the `descuento` value, originally 23.625, is now being corrected to 23.615 which leads to `importe` having a value of 23.635 which round up to 23.64 and not 23.63. https://github.com/odoo/enterprise/blob/08564f3312c255f2f3ab95cef5a9bfc57727bd1f/l10n_mx_edi/models/l10n_mx_edi_document.py#L1111 https://github.com/odoo/enterprise/blob/08564f3312c255f2f3ab95cef5a9bfc57727bd1f/l10n_mx_edi/models/l10n_mx_edi_document.py#L1336 Before this commit https://github.com/odoo/enterprise/commit/39759babddc732a312ec5cd6a60a2f1819abc62c the discount value was being rounded when corrected. It would end up being evaluated to 23.62. To not bring back the issue the fixed by the mentioned commit we round the discount when generating the global invoice cfdi values. Now `importe` will have a value of 23.63 as `descuento` is rounded to 23.62. opw-5023597 Forward-Port-Of: odoo/enterprise#95982 Forward-Port-Of: odoo/enterprise#94438
Odoo now blocks deletion of a unit of measure if it is still referenced by a purchase order line. This prevents purchase order confirmations from failing after a unit was removed, improving reliability for purchasing workflows.
Original PR description
When a user deletes the UoM used in a purchase order line and then tries to confirm the purchase order. Steps to reproduce: --- - Install `purchase_stock` module(without demo) - Create a New PO > Add a product in Line (with UoM=Units) - Remove UoM in order line and select `Dozen` in it > Save - Settings > Units of Measure Categories > Open `Units` > Remove `Dozen` - Orders > Requests for Quotation > Open PO > `Confirm Order` Traceback: --- `ValueError: Expected singleton: uom.uom()` `AssertionError: precision_rounding must be positive, got 0.0` This error occurs because, after the UoM is deleted, the `product_uom` field becomes empty, which leads to an error. Solution: --- This commit resolves the error by restricting the deletion of a UoM when it is still in use. sentry-6746792383 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#233783 Forward-Port-Of: odoo/odoo#231478
This fixes an error that could prevent HR users from archiving an employee when they entered a detailed departure reason. The change keeps the departure reason recorded through the existing employee activity log without triggering an unsupported system action.
Original PR description
When archiving an employee with a Detailed Reason, a traceback occurs. Steps to reproduce the error: - Open any employee record > Archive - Set ``Detailed Reason`` > Apply Traceback: ```py…
When archiving an employee with a Detailed Reason, a traceback occurs. Steps to reproduce the error: - Open any employee record > Archive - Set ``Detailed Reason`` > Apply Traceback: ```py NotImplementedError: Unsupported tracking on field departure_description (type html ``` https://github.com/odoo/odoo/blob/8002b82d5783744b88b75c1199c4c1f222a0f7d0/addons/hr/models/hr_version.py#L130 here, ``tracking=True`` was added for the ``departure_description`` html field by the commit [1]. but tracking is not supported for the html field. So, it will lead to the above traceback. Tracking for ``departure_description`` field is already handled via a chatter message in the write method by the commit [2]. https://github.com/odoo/odoo/blob/8002b82d5783744b88b75c1199c4c1f222a0f7d0/addons/hr/models/hr_employee.py#L1187-L1191 [1]: https://github.com/odoo/odoo/commit/aa4d13b89b4497d2e5b33faa49ad86e0788782a2 [2]: https://github.com/odoo/odoo/commit/9b723e2591224f2b563924d3b3dfe27ab909b7d0 sentry-6973440621 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix prevents negative or incorrect leave durations when Indian sandwich leave rules involve weekends or public holidays. Employees and HR teams now see more accurate leave balances when leave spans non-working days, public holidays, or linked leave requests are changed.
Original PR description
Before this PR, if you created a leave of a type that had sandwich leave enabled on a non-working day, it would show a negative duration. This PR fixes some issues related to sandwich leave cases…
Before this PR, if you created a leave of a type that had sandwich leave enabled on a non-working day, it would show a negative duration. This PR fixes some issues related to sandwich leave cases (where Saturday and Sunday are considered non-working days): - Friday - Monday across weekend - counted (4 days). - Hour-based leave types: weekend bridging increases hours accordingly - Public holiday in the middle (Tue-Thu with Wed PH) - counted (3 days). - Stop/Start exactly on a public holiday(Tue-Wed(Public holiday), or Wed(Public holiday)-Thu) - trimmed to 1 day. - Public holiday only - 0 days. - Two single-day leaves around a Public holiday - When the second leave is created, it bridges via a public holiday (2 days), - The first one remains 1 day if it stands alone - Mixed leave types: - If the linked leave type doesn’t have sandwich enabled, no sandwich rules. - If both leave enable sandwich (with different types) - sandwich rule applies - Refusing/canceling a linked leave must immediately adjust the other side’s duration (e.g., Monday refused - Friday drops from 3 - 1 day) Task-4430044 Co-authored-by: @mepe-odoo Forward-Port-Of: odoo/odoo#233717 Forward-Port-Of: odoo/odoo#193186
Point of Sale users can now search for products whose templates use dynamic attributes, even before a variant has been created. This prevents products from being missed during checkout or sales setup, improving reliability for businesses with configurable items.
Original PR description
Before this commit, it was not possible to search a product that had a dynamic attribute configured on its template, since no product variant was created yet. opw-5188725 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#232838
The Quality Control app now uses much less memory when warehouses open large lists of incoming transfers with many quality checks. This prevents worker crashes and keeps the receiving workflow available for high-volume operations.
Original PR description
The fields `quality_check_todo` and `quality_check_fail` are calculated for stock.picking records by iterating all checks of a stock.picking. This causes a problem when clicking the "To Receive"…
The fields `quality_check_todo` and `quality_check_fail` are calculated for stock.picking records by iterating all checks of a stock.picking. This causes a problem when clicking the "To Receive" button for a warehouse in the inventory app, in case there are many transfers each with many quality checks. The function will default to loading all data associated with quality checks in memory through field prefetching. However, since quality checks have too much data (particularly because of the HTML fields) associated with them, the cache can quickly bloat causing an OOM error and crashing the worker. This PR disables the prefetcher for quality checks before iterating them, preventing this issue from happening since we only need very light fields in the loop. For a specific customer (opw-5025162), this was the case. Benchmarks: | No. stock.picking | avg no. quality checks | peak memory before | peak memory after | | ----------------- | ---------------------- | ------------------ | ----------------- | | 25 | 20 | 2771 mb | 235 mb | opw-5025162 Forward-Port-Of: odoo/enterprise#95568
Italian electronic invoicing no longer blocks valid invoices that include ENASARCO together with a separate withholding tax. The change restores expected behavior for affected Italian invoices while keeping safeguards against invalid tax setups.
Original PR description
In the Italian localization, we validate that each invoice line has at most one tax per kind (VAT, withholding, pension fund). In Italy, a product cannot have more than one VAT tax. Also, the…
In the Italian localization, we validate that each invoice line has at most one tax per kind (VAT, withholding, pension fund). In Italy, a product cannot have more than one VAT tax. Also, the FatturaPA XML structure only allows global declarations for withholding and pension fund taxes — on the line level, it can only specify if those taxes apply, not which ones. To reflect this, we enforce one tax per kind per line. This validation was broken and recently fixed. However, ENASARCO is a special case: it acts both as a withholding and a pension fund tax. We added the Withholding flag recently (odoo/odoo#226968). In realistic cases (e.g., a line with VAT + withholding 23% RIT AG + ENASARCO), the validation fails and the user gets a blocking error in account.move.send. Since ENASARCO already has dedicated support through the AltriDatiGestionali tag on the line, we allow it to pass the check as if it were only a pension fund, restoring the previous behavior before we added the withholding flag. Some validation added and fields clear up in the tax editing phase, preventing invalid cases. Ticket [link](https://www.odoo.com/odoo/project.task/5154223) opw-5154223 Forward-Port-Of: odoo/odoo#233698 Forward-Port-Of: odoo/odoo#232140
12 changes
Enhancements to existing features
Recruitment pages now avoid loading large hidden user lists, making key views open much faster. This improves responsiveness for recruiters, especially in databases with many users, while keeping the same company-based user selection behavior.
Original PR description
Description ----------- The commit odoo/odoo@0f981b14ea22cc154bcd93f53dc19f46c37ecb13 tried to fix an issue where, if the `company_id` was not set in the Form view, no `user_id` would match if they…
Description
-----------
The commit odoo/odoo@0f981b14ea22cc154bcd93f53dc19f46c37ecb13 tried to fix an issue where, if the `company_id` was not set in the Form view, no `user_id` would match if they had a `company_id` set, while the wanted behavior was the inverse, all internal users should match regardless of companies.
This was fixed by introducing a computed field `allowed_user_ids` which was doing the company computation manually and replaced the `company_ids` domain leaf on the field.
Sadly, this approach introduces a performance regression on the front-end side, as the webclient creates internal data structures *per* individual result of the RHS in the domain. So if `allowed_user_ids` returns a lot of matching `ids`, it becomes a significant overhead.
Following the refactoring of `domains.py`, a slight semantic change happened and the initial issue of the bugfix can be resolved by just changing the domain operator to `'=?'` instead. When `company_id=False`, the domain leaf `('company_ids, '=?', False)` is optimized out by `_operator_equal_if_value` as `_TRUE_DOMAIN` (aka `(1, '=', 1)`). This is as expected behavior post-bugfix. This was not the case before the refactoring.
This allows us to completely deprecate the usage of the field `allowed_user_ids` and the front-end has no significant post-processing to do.
⚠️ This commits deprecates `hr.job.allowed_user_ids`, but doesn't remove it yet, as it might be referenced by views or custom JS.
Benchmark
---------
On a 19.0 database where `allowed_user_ids` returns 1.4k ids, opening the default kanban view of the Recruitment app took:
| | Before | After | Improvement |
|-----------------------|---------|--------|-------------|
| Backend process time | 400ms | 160ms | 2.5x |
| Frontend process time | 3.3s | 220ms | **15x** |
| Total (LCP) time | 3.7s | 380ms | 9.7x |
| Response Payload size | ~800KiB | ~33KiB | **24x** |
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#232354Portal comments that include a rating are now treated as meaningful even when no written text is added. This helps customer reviews, course feedback, and rated chatter entries remain visible and editable instead of being ignored as empty messages.
Original PR description
*: portal, portal_rating, rating, website_slides task-5016995 Forward-Port-Of: odoo/odoo#230426 Forward-Port-Of: odoo/odoo#223515
Resolved issues and error corrections
Point of Sale invoices linked to orders can no longer be reset to draft, avoiding a situation where an unposted invoice prevents the cash register session from closing. Users are guided to use a refund or credit note instead, keeping end-of-day operations smoother and more reliable.
Original PR description
Before this commit, it was possible to set the invoice of a PoS order to draft, which could prevent closing the session since unposted invoices block the session closing. This commit prevents that by raising a user error suggesting to refund the order or create a credit note instead. opw-5079889 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#232566 Forward-Port-Of: odoo/odoo#232464
Purchase orders now prevent deletion of a unit of measure that is still referenced by a purchase order line. This avoids confirmation failures and keeps purchasing workflows stable when units are being managed.
Original PR description
When a user deletes the UoM used in a purchase order line and then tries to confirm the purchase order. Steps to reproduce: --- - Install `purchase_stock` module(without demo) - Create a New PO > Add a product in Line (with UoM=Units) - Remove UoM in order line and select `Dozen` in it > Save - Settings > Units of Measure Categories > Open `Units` > Remove `Dozen` - Orders > Requests for Quotation > Open PO > `Confirm Order` Traceback: --- `ValueError: Expected singleton: uom.uom()` `AssertionError: precision_rounding must be positive, got 0.0` This error occurs because, after the UoM is deleted, the `product_uom` field becomes empty, which leads to an error. Solution: --- This commit resolves the error by restricting the deletion of a UoM when it is still in use. sentry-6746792383 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#233783 Forward-Port-Of: odoo/odoo#231478
Users importing Indian IRN invoice JSON files no longer need extra company record permissions for the import to complete. This prevents a permissions error during invoice import and helps affected users continue their billing workflow without administrative access changes.
Original PR description
When importing an IRN JSON as an invoice, users without sufficient access rights to `res.company` fields encountered an access error on `l10n_in_edi_production_env`. This commit uses `sudo()` to safely read the company’s EDI environment configuration without requiring extra permissions. Before this PR: Import failed with error: `You do not have enough rights to access the field 'l10n_in_edi_production_env' on Companies (res.company)` After this PR: Import proceeds successfully for users without `res.company` read rights.
The Point of Sale now checks that its local browser database has all required data tables when it starts. If any are missing, it automatically updates the database setup, preventing sessions from failing after modules such as restaurant add new data needs.
Original PR description
Currently, new IndexedDB object stores are only created during the 'onupgradeneeded' event. This event only fires if the database version is manually incremented in the code. If a new module (e.g.,…
Currently, new IndexedDB object stores are only created during the 'onupgradeneeded' event. This event only fires if the database version is manually incremented in the code. If a new module (e.g., restaurant) adds a new object store to the PoS database schema but the `dbVersion` is not bumped, the store is never created. This causes the PoS session to fail when it tries to access the missing store. This commit modifies the `databaseEventListener` to add a check inside the `onsuccess` handler. After the database opens, it compares the list of required stores (`this.dbStores`) with the list of existing stores (`this.db.objectStoreNames`). If a mismatch is detected: 1. The current database connection is closed. 2. The `dbVersion` is incremented. 3. The database connection process is re-run. This forces the `onupgradeneeded` event to trigger, which then correctly creates the missing object stores, ensuring the database schema is always up-to-date. opw-5166049 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Warehouse users can now open receiving lists more reliably when transfers include many quality checks. The change reduces memory use during quality check status calculations, avoiding worker crashes in large-volume inventory operations.
Original PR description
The fields `quality_check_todo` and `quality_check_fail` are calculated for stock.picking records by iterating all checks of a stock.picking. This causes a problem when clicking the "To Receive"…
The fields `quality_check_todo` and `quality_check_fail` are calculated for stock.picking records by iterating all checks of a stock.picking. This causes a problem when clicking the "To Receive" button for a warehouse in the inventory app, in case there are many transfers each with many quality checks. The function will default to loading all data associated with quality checks in memory through field prefetching. However, since quality checks have too much data (particularly because of the HTML fields) associated with them, the cache can quickly bloat causing an OOM error and crashing the worker. This PR disables the prefetcher for quality checks before iterating them, preventing this issue from happening since we only need very light fields in the loop. For a specific customer (opw-5025162), this was the case. Benchmarks: | No. stock.picking | avg no. quality checks | peak memory before | peak memory after | | ----------------- | ---------------------- | ------------------ | ----------------- | | 25 | 20 | 2771 mb | 235 mb | opw-5025162 Forward-Port-Of: odoo/enterprise#95568
This update fixes website builder scrolling behavior so footer animations appear correctly and newly added FAQ horizontal entries are brought into view. It improves the editing experience by making these visual elements behave as expected when pages require scrolling.
Original PR description
[FIX] website: get scroll from document element for footer animation __Current behavior before commit:__ Since [this PR], the scrolling is not done on `#wrapwrap` anymore. Now when an animation is…
[FIX] website: get scroll from document element for footer animation __Current behavior before commit:__ Since [this PR], the scrolling is not done on `#wrapwrap` anymore. Now when an animation is set on an element inside the footer it will not appear if a slideout effect is set on it. __Description of the fix:__ Get `scrollTop` and `scrollHeight` from the document element instead of `#wrapwrap` and add a test tour. __Steps to reproduce:__ 1. Open the Website builder. 2. Click on a column in the footer. 3. Set an "On Appearance" Animation on it. 4. Set the footer Slideout Effect to "Slide Hover". 5. Add some content on the page so that it's needed to scroll for the footer to be visible. 6. Save. 7. Scroll to the footer. => The column doesn't appear. [this PR]: https://github.com/odoo/odoo/pull/98429 --- [FIX] website: scroll on new entry in faq horizontal __Current behavior before commit:__ Since [this PR][1], the scrolling is not done on `#wrapwrap` anymore. Now when adding a new entry to the snippet faq horizontal, the page doesn't scroll automatically to the new entry. This behavior has actually never worked because [the PR that introduced faq horizontal][2] was merged just after [the PR that moved the scrolling to the document element][1]. __Description of the fix:__ Get `scrollTop` and `scrollHeight` from the document element instead of `#wrapwrap` and add a test tour. __Steps to reproduce:__ 1. Open the Website builder. 2. Drag a Text block 3. Choose the FAQ horizontal snippet 4. Click on "Add New" => The page doesn't scroll to the new entry. [1]: https://github.com/odoo/odoo/pull/98429 [2]: https://github.com/odoo/odoo/pull/176438 Forward-Port-Of: odoo/odoo#233850 Forward-Port-Of: odoo/odoo#228396
Odoo updates Peppol participant lookup handling to stay compatible with upcoming network rule changes that retire the old DNS method. Lookups are now routed through Odoo's IAP service, helping keep electronic invoicing connectivity reliable as Peppol requirements evolve.
Original PR description
From November 1st, CNAME DNS will be deprecated for Peppol lookups. From February 1st CNAME lookups will no longer be supported. The replacement are NAPTR DNS records. Multiple solutions were available, such as using DoH (e.g. with cloudflare DNS), but we ended up choosing to proxy DNS requests through IAP to centralize the lookups and make such specs upgrades easier to handle in the future. IAP is now responsible of doing the DNS lookup and fetching the service groups of the found SMP. IAP-side: https://github.com/odoo/iap-apps/pull/1227 task-5179969 Forward-Port-Of: odoo/odoo#233272 Forward-Port-Of: odoo/odoo#232483
VAT return check refreshes are faster after removing a slow duplicate check and replacing it with a clearer warning on reports with negative amounts. Access rules for company branches were corrected so users can view and refresh returns appropriately, while submissions require access to the full company structure.
Original PR description
The "No negative amount in VAT report" return check was too slow, we removed it and clean the database. On the other hand, refreshing checks had issues with the access rights when there was company branches. task-id: 5145537
Invoices created from Point of Sale orders can now be reset to draft when changes are needed, instead of being blocked. Users will see a warning notification, which supports local requirements where invoices must be adjusted before submission to government systems.
Original PR description
After this commit, it becomes possible to make an invoice linked to a PoS order draft, showing only a warning notification instead of blocking the action. This is required in some localizations where invoices must be modified before being sent to the government. opw-5218715 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#233649
The Helpdesk website "Browse Articles" button now sends portal users directly to the linked Knowledge article instead of an empty Knowledge home page. This ensures customers can reach the intended support content without confusion or extra navigation.
Original PR description
To reproduce: ============= 1. Create a Helpdesk Team linked to a Knowledge Article 2. Access the Help page on website as a portal user 3. Click on "Browse Articles" button -> redirected to empty knowledge home portal view Problem: ======== before this commit, redirection was made through the method `redirect_to_article` which will later call `_redirect_to_portal_view` that doesn't use the `article` parameter anymore as there is a patch on the front side to handle the redirection to the articale through the router, but as the calls are server-side, the patch is not applied and the redirection fails. Solution: ========= instead of calling `redirect_to_article`, directly redirect to the article's `website_url`. opw-5114885 Forward-Port-Of: odoo/enterprise#98363
3 changes
Resolved issues and error corrections
This update reduces memory use when viewing incoming warehouse transfers that have many quality checks. It prevents worker crashes for large quality control workloads, making the Inventory app more reliable for affected customers.
Original PR description
The fields `quality_check_todo` and `quality_check_fail` are calculated for stock.picking records by iterating all checks of a stock.picking. This causes a problem when clicking the "To Receive"…
The fields `quality_check_todo` and `quality_check_fail` are calculated for stock.picking records by iterating all checks of a stock.picking. This causes a problem when clicking the "To Receive" button for a warehouse in the inventory app, in case there are many transfers each with many quality checks. The function will default to loading all data associated with quality checks in memory through field prefetching. However, since quality checks have too much data (particularly because of the HTML fields) associated with them, the cache can quickly bloat causing an OOM error and crashing the worker. This PR disables the prefetcher for quality checks before iterating them, preventing this issue from happening since we only need very light fields in the loop. For a specific customer (opw-5025162), this was the case. Benchmarks: | No. stock.picking | avg no. quality checks | peak memory before | peak memory after | | ----------------- | ---------------------- | ------------------ | ----------------- | | 25 | 20 | 2771 mb | 235 mb | opw-5025162 Forward-Port-Of: odoo/enterprise#95568
Barcode scans are now ignored when a warehouse batch transfer is still being created or is not active, preventing confusing errors in the barcode app. This helps inventory users avoid crashes or misleading messages when they accidentally scan items before a batch is ready to process.
Original PR description
### Issue: Scans processed during picking batch creation in the barcode app are interpreted as scans related to the BarcodePickingBatchModel edition (that is product, lot, package,... scans) which…
### Issue: Scans processed during picking batch creation in the barcode app are interpreted as scans related to the BarcodePickingBatchModel edition (that is product, lot, package,... scans) which does not make sense and raises multiple errors. ### Steps to reproduce: - In the settings enable "Batch Transfers" - Inventory/Operations/Transfers/Batch Transfers - Create a new batch and do not confirm it - Go to the barcode app > Batch Transfers > Clear filters - Select your draft batch - Scan anything #### > Traceback #### Other issues: The same flow with a cancelled batch triggers the same tracebacks and, with a done batch triggers the message: "This picking is already done". ### Cause of the issue: Since `this.state.view === "barcodeLines"`, scans are processed as if we were processing an existing `BarcodePickingBatchModel` with lines: https://github.com/odoo/enterprise/blob/ce7460b27028d4133c4689afd2e8f303268494a0/stock_barcode/static/src/components/main.js#L204-L209 In particular, if the scan corresponds to a product, and error will be raised because the scan can not process a `createNewLine` for the scanned product in the current view and if the scan does not correspond to anything valid, it will raise an error because `this.picking` is undefined and `this.picking.use_existing_lots` raises an error: https://github.com/odoo/enterprise/blob/ce7460b27028d4133c4689afd2e8f303268494a0/stock_barcode/static/src/models/barcode_model.js#L1115 https://github.com/odoo/enterprise/blob/ce7460b27028d4133c4689afd2e8f303268494a0/stock_barcode_picking_batch/static/src/models/barcode_picking_batch_model.js#L177-L179 opw-5162164 Forward-Port-Of: odoo/enterprise#97816 Forward-Port-Of: odoo/enterprise#97526
Portal users clicking “Browse Articles” from a Helpdesk help page are now taken directly to the linked Knowledge article instead of an empty knowledge home page. This restores the expected self-service support flow and helps customers find the intended help content faster.
Original PR description
To reproduce: ============= 1. Create a Helpdesk Team linked to a Knowledge Article 2. Access the Help page on website as a portal user 3. Click on "Browse Articles" button -> redirected to empty knowledge home portal view Problem: ======== before this commit, redirection was made through the method `redirect_to_article` which will later call `_redirect_to_portal_view` that doesn't use the `article` parameter anymore as there is a patch on the front side to handle the redirection to the articale through the router, but as the calls are server-side, the patch is not applied and the redirection fails. Solution: ========= instead of calling `redirect_to_article`, directly redirect to the article's `website_url`. opw-5114885 Forward-Port-Of: odoo/enterprise#98363
25 changes
New functionality added to Odoo
Adds late attendance management to Saudi payroll so companies can track employee lateness and reflect it in payroll calculations. This helps HR teams apply attendance policies more consistently and reduces manual payroll adjustments.
Original PR description
IN this PR we interduce late attendance management for SA payroll loca Task: 4598879
Enhancements to existing features
The Shop Floor registration flow no longer changes production quantity, component reservations, or manufacturing order status just because a lot or serial number is generated. This helps prevent unintended manufacturing order updates and gives users clearer control when registering production, especially for serial-numbered items.
Original PR description
In the Shop Floor app, opening the 'Register Production' step no longer pre-fills the 'Quantity Producing' field, and the field is now editable for serial numbers. Additionally, generating a lot or serial number for a manufacturing order no longer updates the 'Quantity Producing' field. Component reservations and the MO status also remain unchanged when a lot or serial number is generated. These changes ensure that generating lot or serial numbers does not introduce unintended side effects in the manufacturing order flow. Task ID: [4688059](https://www.odoo.com/odoo/project/966/tasks/4688059)
Malta reporting now includes return deadlines and guided submission wizards for EC Sales List, tax returns, and Intrastat goods reports. This helps businesses track compliance timing and prepare required submissions more consistently within Odoo.
Original PR description
- add ec_sales_list return deadline and wizard - add tax_return wizard - add intrastat return deadline and wizard task - 4781287
Payroll salary rules can now specify whether they appear on payslips always, never, or only when the result is not zero. This improves payslip clarity across multiple country payroll localizations and ensures items like Australia's Medicare Adjustment appear only when relevant.
Original PR description
- Modify the 'Appear on Payslip' field from a boolean to a selection field with the following options:
- Always
- Never
- If result is not zero
- update the data for 'appear on payslip' field in several localization.
- In the Australia localization, update the 'Medicare Adjustment' appear_on_payslip field to "If Result is Not Zero". This adjustment is necessary since the payslip template utilizes this configuration.
task-4979423Mexican payroll payslips now show clear issues when required information is missing for CFDI generation. This helps payroll teams identify and correct missing data earlier, reducing failed electronic payslip processing.
Original PR description
We now have a "issues" system on the payslips. Let's use it to signal what is missing for the correct generation of the CFDI. Task: 5068311 Forward-Port-Of: odoo/enterprise#94748
This update improves the bank reconciliation widget with more consistent styling and clearer transaction details. It also prevents users from choosing certain bank-related accounts that would create ineffective reconciliation rules, and keeps payable and receivable actions more consistently available.
Original PR description
[IMP] account_accountant: css backport To have a consistent css across all version of the new bank rec widget, we decided to backport few changes. backport of:…
[IMP] account_accountant: css backport To have a consistent css across all version of the new bank rec widget, we decided to backport few changes. backport of: https://github.com/odoo/enterprise/commit/524a7a46a0c2888b591de7ad1a0a6d744e345f5a https://github.com/odoo/enterprise/commit/2a83c85cb2c9a7a5da3d4a8483120eeda6b2e6cb https://github.com/odoo/enterprise/commit/e3cb3ab3ec8c64297d8e97d941e0d2eea3e64667 https://github.com/odoo/enterprise/commit/fdbb93abbf831cfa2fdc75e79aa76c094d6e522a https://github.com/odoo/enterprise/commit/f9725d7b01cbd1235f022821a6861adb2955e49e [FIX] account_accountant: restrict some account in the set_account Before this commit, we could select the liquidity account or bank suspense account which could create a reco model for it that would do nothing. [FIX] account_accountant: partner_name Before this commit, when a transaction had no partner_name and some lines with the same partner. When unfolded, we had the info of the partner on the statement line and on the line itself which was a duplicate of information. This commit will change when the line is unfolded so that the partner is visible on the statement line only when there is a partner_name [FIX] account_accountant: payable and receivable button Before this commit, the payable and receivable buttons where on the top line only when the reconcile button was not there anymore. Now We decided to always have them present in secondary next to the reconcile button. no task-id Forward-Port-Of: odoo/enterprise#98458 Forward-Port-Of: odoo/enterprise#96852
The IoT restart button now uses the shared IoT communication service to restart IoT Boxes remotely. This makes remote restart handling more consistent and easier to maintain, with minimal visible change for users.
Original PR description
In order to simplify restarting IoT Boxes remotely, we adapted the restart button to use the `iot_http` service. odoo/odoo#232133 Task: 5169648 Forward-Port-Of: odoo/enterprise#97525
VoIP browser tabs now try to close their phone service registration when the tab is closed, and unused registrations expire sooner if that cleanup fails. This helps businesses avoid hitting provider limits that can prevent users from making or receiving calls.
Original PR description
Some providers like OnSIP allow for a limited number of registrations per user. This is a problem in Odoo because each tab opened creates a new registration for one hour. This commit mitigates the problems in two ways: - Sends an "unregister" request onbeforeunload to try to invalidate the registration upon closing the tab. - Reduces the TTL of registrations so that they get invalidated quicker in case the unregistration failed. Forward-Port-Of: odoo/enterprise#98413 Forward-Port-Of: odoo/enterprise#97963
Companies can now choose how negative amounts appear in financial reports, either with a minus sign or in parentheses. US companies will use the parentheses format by default, matching common local accounting practice, while other companies can set their preferred format in settings.
Original PR description
This PR allows the user to choose how to display the negative amounts in the reports, either " (negative_amount) " - common US formatting - or " - negative_amount ". If the country is US the (negative_amount) format will be selected by default. The choice is available in the settings and is company specific. task-5118741
WhatsApp users can now mark channels as favorites, making key conversations easier to find in the Discuss sidebar. This improves day-to-day navigation for teams that rely on WhatsApp channels to manage customer or operational conversations.
Original PR description
Enterprise counter-part. task-4113458 https://github.com/odoo/odoo/pull/232398
Resolved issues and error corrections
This fix prevents overlapping work order time tracking entries from being wrongly removed or changed when manufacturing orders are saved. It keeps displayed work order duration and saved time records consistent, improving reliability for production tracking.
Original PR description
#### Issue: In this bug, workorder duration inverse is causing some time_ids to be deleted. To reproduce: 1- Create a db with mrp installed, and enable work orders in Setting 2- Create a MO, and…
#### Issue:
In this bug, workorder duration inverse is causing some time_ids to be deleted.
To reproduce:
1- Create a db with mrp installed, and enable work orders in Setting
2- Create a MO, and confirm it
3- Add a new work order to the MO
4- Add two time tracking lines:
- First one 10:00 -> 12:00
- Second one 10:00 -> 11:00
5- As you see, duration reflects duration of first line as it is the interval duration
6- Save and close work center form. Then save MO form.
7- Open work orders again: As you see second line is unlinked
#### Cause:
The reason to this bug, is because in Enterprise, the `_compute_duration` override changes the logic of how duration is computed but the inverse function doesn't reflect the same logic.
To be specific this is the compute function override: https://github.com/odoo/enterprise/blob/3cbe2bbbfd989a3daaa32769a843aeaa09c7ed3e/mrp_workorder/models/mrp_workorder.py#L757-L766
In which duration is calculated using get_duration: https://github.com/odoo/enterprise/blob/3cbe2bbbfd989a3daaa32769a843aeaa09c7ed3e/mrp_workorder/models/mrp_workorder.py#L828-L837
Which doesn't sum the durations, but calculates the intervals duration counting overlaps only once.
However, there is no override of inverse method in Enterprise, meaning that the logic behind inverse will not match with this logic. In the inverse it is assumed duration is sum of all time_ids intervals: https://github.com/odoo/odoo/blob/9b286285a6c66bc2d629eacf651c3439cffb55cc/addons/mrp/models/mrp_workorder.py#L355-L400
As a result, if time_ids overlap:
new_order_duration < old_order_duration
As a result some time_ids will be unlinked and some will have duration changed.
#### Fix:
Inside the inverse function in Community we can do:
```diff
+ old_order_duration = order.get_duration()
- sum(order.time_ids.mapped('duration'))
```
As get_duration in Odoo Community is:
https://github.com/odoo/odoo/blob/9b286285a6c66bc2d629eacf651c3439cffb55cc/addons/mrp/models/mrp_workorder.py#L889-L899
The order.get_duration will be sum of duration of all time_ids in community, hence the logic will be unchanged.
In Enterprise, this is going to reflect the logic implemented in override of get_duration, as a result the duration logic will be consistent in compute and inverse function.
However, this might cause another issue:
If `order.duration` is not computed yet, and inverse method `_set_duration` is called, then `get_duration` inside `_set_duration` will be called before the `get_duration` in compute method. As a result there might be a small unexpected time difference between `old_order_duration` and `new_order_diuration`. To avoid that inside `get_working_duration` we can use cursor now instead:
```diff
+ now = self.env.cr.now()
- now = datetime.now()
```
opw-5082477
Forward-Port-Of: odoo/enterprise#96632Fixed an issue where closing a live chat window did not end the conversation when the final human agent left. This ensures customers and support teams see accurate chat status and prevents conversations from remaining open incorrectly.
Original PR description
*: ai_website_livechat, test_discuss_full_enterprise Before this commit, when the last agent from a live chat conversation leave, the live chat conversation did not end. Steps to reproduce: - install…
*: ai_website_livechat, test_discuss_full_enterprise Before this commit, when the last agent from a live chat conversation leave, the live chat conversation did not end. Steps to reproduce: - install "ai" and "im_livechat" modules - have a visitor initiate a live chat conversation with 1 available human agent - have have human agent open conversation in chat window and close chat window + confirm button => the live chat conversation does not end When live chat agent is about to close the chat window of live chat, there's a warning to tell that this will make him/her leave the conversation and thus end the conversation. When proceeding, it doesn't actually do this. This is a bug caused by overrides of `ChatWindow._onClose()`, which is a function invoked during the closing of chat window, that has an option `notifyState` that determines whether the user leaves the conversation or not. The overridden code had to ensure the param is preserved and passed to `super` calls, but they fail to do this, and thus the closing of chat window is not making the user leave the conversation. This commit fixes the issue by passing `...arguments` to super calls to make sure the params are preserved as expected by original code of the `_onClose` function. Note that we had a test for the good working of the feature, but this test run with `im_livechat` assets and not overrides on top of it such as `ai` module. The main culpit of the problem was caused by the override in `ai` module. To have test coverage for this problem, the test is not executed in both `im_livechat` test suite and the `test_discuss_full_enterprise`, which is a module whose HOOT suite runs code of discuss with all overrides such as `ai` module. Forward-Port-Of: odoo/enterprise#98481
Ecuadorian vendor bill imports now select purchase taxes instead of accidentally applying sales taxes with the same rate. This helps keep imported supplier bills accurate and reduces manual correction work for accounting teams.
Original PR description
### Issue:
When importing a bill, some sale taxes are added to the lines.
### Steps to reproduce:
- Install 'l10n_ec_edi' and switch to an Ecuadorian company
- Accounting > Vendor > Bill
- Import an XML fill with a tax of 15%
- The created lines use the tax "VAT 15% G" which is a sale tax
### Cause:
The search to get the tax takes the first one from the right tax group.
### Solution:
Added `('type_tax_use', '=', 'purchase')` in the search domain to only retrieve purchase taxes.
opw-5174139
Forward-Port-Of: odoo/enterprise#98188Vendor bill imports for Chilean electronic documents now recognize numeric currency codes as well as standard currency abbreviations. This prevents import failures when suppliers send valid XML files using numeric currency values, with a safe fallback to Chilean pesos if the currency cannot be matched.
Original PR description
### Steps to reproduce: - Install "l10n_cl_edi" and switch to a Chilean company - Go in Accounting > Vendor > Bills - Import an XML with the line `<Moneda>013</Moneda>` - Traceback ### Cause: `Moneda` can be the currency name code like `USD` but also a numeric code corresponding to the currency. ### Solution: Add a dictionary linking codes to the currency names and check the dictionary if `Moneda` is numeric. Also add a fallback on `CLP` in case the value of `Moneda` fails to be translated to a currency. This avoids a traceback later when reading `vals['currency_id']`. opw-5184950 Forward-Port-Of: odoo/enterprise#98067
Users who work across multiple companies can now assign themselves to planning slots for the company where their employee record exists, even when another company is set as current. This prevents silent failures and makes planning assignment behave as expected in multi-company setups.
Original PR description
_______________________________________ ## Short functional explanation of the error Let's say we have the scenario where a user has access to company_1 and company_2, but only has a corresponding…
_______________________________________ ## Short functional explanation of the error Let's say we have the scenario where a user has access to company_1 and company_2, but only has a corresponding employee in company_2. If the user selects company_1 and company_2 but keeps company_1 as his current company, and tries to assign himself a task that has been created for company_2, nothing happens. ## Reproduction Steps 1. As an admin, create a user with which you'll be able to log. Make sure that you have at least 2 companies created, and that the user has access to both. Create an employee for that user in company_2. 2. Select both companies. In planning, create a slot for company_2 and publish it. 3. Log in as the user you created. Make sure that the current company is company_1. Select company_2. 4. Go to planning and try to assign yourself to the slot you've just created as an admin ### Expected behavior Either an error message shows, or the employee is assigned to the slot for company_2 (as company_2 is selected). ### Unexpected behavior Nothing happens ## Origin of the issue When the current company isn't the one corresponding to the one the employee is in, even if another company is selected and contains the employee, self.env.user.employee_id is set at False _________________________________________ opw-4963674 --- Forward-Port-Of: odoo/enterprise#95933 Forward-Port-Of: odoo/enterprise#91616
Scanned purchase receipts are now correctly recognized as purchase documents instead of sales documents. This prevents the system from applying sales taxes where purchase taxes should be used, improving accounting accuracy for OCR-processed receipts.
Original PR description
Since task [4776275](https://www.odoo.com/odoo/project/2068/tasks/4776275) (commit [a7e9575](https://github.com/odoo/enterprise/commit/a7e9575d4c7fccff06db8a3ec2b9315d8ac33805)), the OCR is able to automatically detect and change a vendor bill into a receipt. The calls to `is_purchase_document` should have been updated to reflect that, but they weren't. Because of this, purchase receipts were considered as sale receipts, causing multiple issues such as sale taxes being selected instead of purchase taxes. task-none Forward-Port-Of: odoo/enterprise#98472
This fixes an error that could prevent users from generating analytic budgets when using the split option. Budget creation now completes reliably in this workflow, reducing interruptions for accounting teams.
Original PR description
Currently, on creating a budget using split budget causing an error. **Steps to Reporduce:** 1) Install **account_budget module(with Demo)** 2) Navigate to **Accounting>Accounting>Analytic Budget**…
Currently, on creating a budget using split budget causing an error. **Steps to Reporduce:** 1) Install **account_budget module(with Demo)** 2) Navigate to **Accounting>Accounting>Analytic Budget** 3) Click on `Generate` set `Analytic Plan` and click on `Split` Error: `ValueError: Cannot convert budget.line.achieved_amount to SQL because it is not stored` Root Cause: since [this commit](https://github.com/odoo/odoo/pull/224667/commits/53b4670b1ad375ffc3800fc3beb97e960f229dc6), a new aggregate spec `sum_currency` was added. As a result, the code at [1] is executed for currency-aware aggregates. From the line, `self._field_to_sql(self._table, fname, query)` the ORM tries to create an SQL expression for `achieved_amount`. Because `achieved_amount` is computed `_field_to_sql` fails and error is raised. Fix: Provide a default SQL expression for computed fields on Budget Line [1]: https://github.com/odoo/odoo/blob/af668f545676f72385c52629f8498edfe22219cd/odoo/orm/models.py#L1972-L2004 Used Reference: https://github.com/odoo/odoo/blob/d42102cac8fff3967cb605a897bbb0e8690464ed/addons/crm/models/crm_lead.py#L286-L298 sentry-6917352415 Forward-Port-Of: odoo/enterprise#98215
Users can now send SMS authentication messages for signing as long as they still have purchased SMS credits available. This prevents valid signing requests from being blocked when the remaining balance is below one full credit but still enough to pay for one or more SMS messages.
Original PR description
Before this PR, when the authentication method is SMS in a sign document, the check to decide whether the authentication SMS is sent out checks that the amount of owned credits is >=1. The correct approach would be to check that they are >= sms_price but this price depends on the phone number of the recipient (or its international prefix) which we still don't know at the time of this computation. Because of this, when the function was originally written, the check was set to >=1 since 1>sms_price for every country. This, however, blocks the user from sending messages when sms_price<num_credits<1 which could even be multiple sms. By switching the 1 to a 0 we allow to send every sms the user purchased credits for and the last sms (which would bring the credits to <0) will be blocked directly by the iap server. Task: 4876220
The barcode app now respects the delivery setting that blocks extra products when workers scan whole packages. This prevents unintended items from being added to deliveries, reducing picking errors and improving inventory control.
Original PR description
## Issue 1: "Allow Extra Products" option ignored for packages ### Steps to reproduce: - In the settings enable "Packages" - Go to Inventory > Configuration > Warehouse Management > Operation Types -…
## Issue 1: "Allow Extra Products" option ignored for packages
### Steps to reproduce:
- In the settings enable "Packages"
- Go to Inventory > Configuration > Warehouse Management > Operation Types
- Disable "Allow Extra Products" on the "Delivery" operation type
- Create two storable product P1, P2 and add on hand quantities
- 10 x P1 in a package PACK01
- 10 x P2 in a package PACK02
- Create and confirm a delivery for 10 unit of P1
- Open your delivery from the barcode app
- Scan PACK02
#### > The content of PACK02 is added to the delivery even thought it contains extra products.
### Cause of the issue:
The check for extra products is only applied when scanning individual products but is bypassed by package scan. To be more precise, the `barcode_allow_extra_product` option is checked in the public method `createNewLine`:
https://github.com/odoo/enterprise/blob/331442fd9cbd59d542432b2237299df9497ce241/stock_barcode/static/src/models/barcode_picking_model.js#L59-L80
While this method is called at new line creation when a product is scanned, scanning a package will add new lines during the `_processPackage` adn bypasses the rest of the `_processBarcode`:
https://github.com/odoo/enterprise/blob/331442fd9cbd59d542432b2237299df9497ce241/stock_barcode/static/src/models/barcode_model.js#L1261-L1267
The issue being that the `__processPackage` does not check the `barcode_allow_extra_product` option and creates its new lines via the private `_createNewLine` call:
https://github.com/odoo/enterprise/blob/331442fd9cbd59d542432b2237299df9497ce241/stock_barcode/static/src/models/barcode_picking_model.js#L1564-L1565
https://github.com/odoo/enterprise/blob/331442fd9cbd59d542432b2237299df9497ce241/stock_barcode/static/src/models/barcode_picking_model.js#L1655-L1667
https://github.com/odoo/enterprise/blob/331442fd9cbd59d542432b2237299df9497ce241/stock_barcode/static/src/models/barcode_picking_model.js#L1671
### Fix:
Since scanning a package is expected to add all its content to the picking, and since a package can not be split among two locations, it is necessary to check in advance if any product of its content is extra and avoid any update in this case.
## Issue 2: impossibility of package line removal
### State of the art:
There is currently no option to remove a package line from the barcode. In particular, once the option `show_entire_packs`(Move Entire Packages) is enabled on a picking type, you can not remove the package line once generated by a scan.
#### Steps to reproduce:
- In the settings enable "Packages"
- Go to Inventory > Configuration > Warehoue Management > Operation Types
- Enable "Move Entire Packages" on the "Delivery" operation type
- Create a storable product and add on hand quanties:
- 10 units in package PACK01
- 10 units in package PACK02
- Create and confirm a delivery for PACK01 (in the package lines)
- Open your delivery from the barcode app
- Scan PACK02
#### > The new line associated to PACK02 can not be removed by any mean
opw-4863621
opw-5080637
Forward-Port-Of: odoo/enterprise#97700
Forward-Port-Of: odoo/enterprise#96299The Australian payroll integration now uses updated IAP proxy connection URLs and a revised connection process. This helps keep payroll reporting and superannuation data exchanges working reliably while preserving existing connections.
Original PR description
Adds the new urls configured for the iap proxy. Adapts for the updated connection flow. This does not break any existing connections. Related PR: https://github.com/odoo/iap-apps/pull/1124 Forward-Port-Of: odoo/enterprise#95071
Users who are not administrators can now use the AI document sorting action when their documents are eligible for auto-sorting. This fixes missing access to the button and ensures AI can correctly identify destination folders, reducing manual re-upload work.
Original PR description
Purpose: -------- Non-admin users should be able to trigger the auto-sort of their documents (since anyways they could delete and reupload their documents, which will trigger the auto-sort). - The "Sort with AI" button was missing in the topbar for non-admin users. To fix this, a boolean `ai_has_sort_prompt` is added in the search panel values (the button was shown if `ai_sort_prompt` was set, which is only accessible by users with group_system) - The display name of folders is now the folder name if the env is sudo-ed even if the user has not access this folder (these folders are valid targets if they are in the `ai_sort_prompt`, but they were inserted as "Restricted Folder" so the LLM could not decide in which folder to move the document) - Add a few sudo's so that the auto-sort action can be triggered by a non admin user Task-5144695 Forward-Port-Of: odoo/enterprise#96874
Corrects Mexican payroll CFDI generation so the employment subsidy section is only included for the specific subsidy payment types allowed by the government. This prevents payroll submissions with other payment inputs from being rejected.
Original PR description
Bug: If we add other inputs to a payslip, in the CFDI, then sending to the government will fail. Cause: In the CFDI, the node 'SubsidioAlEmpleo' is present when it shouldn't. Fix: The node should be present only for other payments of code 002, 007 or 008, all related to subsidies. Task: 5224176 Forward-Port-Of: odoo/enterprise#98529
Requests for quotation created from approvals now use the currency configured for the selected vendor instead of defaulting to the company currency. This keeps purchasing amounts consistent with other RFQ creation flows and avoids currency mismatches when updating existing purchase orders.
Original PR description
Issue: When creating an RFQ from an approval, the created purchase order does not use the currency set on the vendor of the product. Rather, it uses the currency of the company, with the value converted based on the vendor's currency to get the price. This is not consistent with other ways we create RFQs, which all respect the vendor currency. Solution: Pass the vendor's currency into the values sent when creating the purchase order. In the case of modifying an existing purchase order, only modify purchase orders matching vendor's currency. opw-4549937 Forward-Port-Of: odoo/enterprise#98205 Forward-Port-Of: odoo/enterprise#97069
The Helpdesk website's "Browse Articles" button now sends portal users directly to the linked Knowledge article instead of an empty Knowledge home page. This prevents confusion and helps customers reach the intended self-service content faster.
Original PR description
To reproduce: ============= 1. Create a Helpdesk Team linked to a Knowledge Article 2. Access the Help page on website as a portal user 3. Click on "Browse Articles" button -> redirected to empty knowledge home portal view Problem: ======== before this commit, redirection was made through the method `redirect_to_article` which will later call `_redirect_to_portal_view` that doesn't use the `article` parameter anymore as there is a patch on the front side to handle the redirection to the articale through the router, but as the calls are server-side, the patch is not applied and the redirection fails. Solution: ========= instead of calling `redirect_to_article`, directly redirect to the article's `website_url`. opw-5114885 Forward-Port-Of: odoo/enterprise#98363
Features or functions removed from Odoo
The employee overtime setting based on attendance has been removed because payroll and work entry rules now determine when extra hours apply. This simplifies configuration and reduces the chance of conflicting overtime settings across HR processes.
Original PR description
The overtime_from_attendance field is no longer needed, since the ruleset already provides the necessary information to determine whether extra hours should be applied. This change removes the redundant field. task-5082639
27 changes
Enhancements to existing features
VoIP browser tabs now try to unregister when closed and registrations expire sooner if cleanup does not happen. This helps customers avoid hitting provider limits on active phone registrations, especially when users open multiple Odoo tabs.
Original PR description
Some providers like OnSIP allow for a limited number of registrations per user. This is a problem in Odoo because each tab opened creates a new registration for one hour. This commit mitigates the problems in two ways: - Sends an "unregister" request onbeforeunload to try to invalidate the registration upon closing the tab. - Reduces the TTL of registrations so that they get invalidated quicker in case the unregistration failed. Forward-Port-Of: odoo/enterprise#98413 Forward-Port-Of: odoo/enterprise#97963
Purchase catalog suggestions now show all recommended products on the first page when suggestions are enabled, instead of hiding some behind pagination. The change also improves performance and makes bulk adding suggestions respect the selected purchase order section.
Original PR description
Description of the issue/feature this PR addresses: Improves purchase catalog suggestions, adding a filter on products with `suggested_qty > 0` on suggestion toggle. This ensure all suggested products will be shown on the first catalog page Perf improvements on both front end (reducing number of RPCs) and backend (filtering domain as much as possible on search method). Current behavior before PR: Before, if there were more products than the paging limit, not all suggested product would be pulled to the front (couldn't order a view by a computed field.) Desired behavior after PR is merged: All suggested products are shown on first page. task#5114649 previous PR: odoo/odoo#218343 And separated all the refacto on a beanch on master: https://github.com/odoo/odoo/pull/232456 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Mass mailing now better supports older email templates during the move to Odoo 19. Users can still view legacy email content, receive clearer warnings when parts are outdated, and avoid several editing crashes.
Original PR description
This work's purpose is to prepare `mass_mailing` for the upcoming migration to Odoo 19.0. Existing mail content produced with the old editor is not upgraded, and users who end up editing such content must be informed if a snippet is not up to date. contents: - ensure that existing mail content with an obsolete mail HTML structure is properly displayed, even if the editor will not work at all, instead of showing the Theme Selector if no authorized theme is detected. - ensure that a user editing an obsolete snippet is informed and can change it to the new version - various crash fixes See commits messages for further detail. task-5134263
Resolved issues and error corrections
Fixes an error that could occur when users opened a Field Service task from the map view. The task time is now displayed using the user’s local time format without seconds, improving reliability for Field Service teams.
Original PR description
Steps: -------- - Install industry_fsm - Go to FSM app > Map Issue: -------- When opening the FSM task from the map menu, a traceback occurs. Cause: ---------- The removal of `shortTimeFormat`, as shown in the this commit. https://github.com/odoo/odoo/commit/062b14097033afc19252cf3b8bb1fc541f8c868d#diff-39c1e6808cb2412961c390a24d5e6737f2fca1ef85ba2c40e501114311f596c2L67 Fix: ---- In this commit, the time object is built to be able to format the time without any seconds and take into account the time format defined in localization. task-5220054
Corrects a rounding issue in Mexican electronic invoicing that could block global invoices with discounted lines from being validated. This helps businesses avoid rejected invoices caused by small discount calculation differences.
Original PR description
Steps to reproduce: ------------------- * Create an invoice with the following line: * Unit price: 47.25, Qty: 1, Taxes: 16%, Discount 50% * Confirm, create a global invoice > Observation: Error ```…
Steps to reproduce: ------------------- * Create an invoice with the following line: * Unit price: 47.25, Qty: 1, Taxes: 16%, Discount 50% * Confirm, create a global invoice > Observation: Error ``` Code : CFDI40108 Message : El TipoDeComprobante es I,E o N, el importe registrado en el campo no es igual al redondeo de la suma de los importes de los conceptos registrados. ``` Why the fix: ------------ The issue occurs because the `descuento` value, originally 23.625, is now being corrected to 23.615 which leads to `importe` having a value of 23.635 which round up to 23.64 and not 23.63. https://github.com/odoo/enterprise/blob/08564f3312c255f2f3ab95cef5a9bfc57727bd1f/l10n_mx_edi/models/l10n_mx_edi_document.py#L1111 https://github.com/odoo/enterprise/blob/08564f3312c255f2f3ab95cef5a9bfc57727bd1f/l10n_mx_edi/models/l10n_mx_edi_document.py#L1336 Before this commit https://github.com/odoo/enterprise/commit/39759babddc732a312ec5cd6a60a2f1819abc62c the discount value was being rounded when corrected. It would end up being evaluated to 23.62. To not bring back the issue the fixed by the mentioned commit we round the discount when generating the global invoice cfdi values. Now `importe` will have a value of 23.63 as `descuento` is rounded to 23.62. opw-5023597 Forward-Port-Of: odoo/enterprise#95982 Forward-Port-Of: odoo/enterprise#94438
Chilean electronic invoice imports no longer fail when a supplier uses a numeric currency code instead of a currency abbreviation. The system now recognizes those codes and falls back to Chilean pesos when needed, helping users import vendor bills without interruptions.
Original PR description
### Steps to reproduce: - Install "l10n_cl_edi" and switch to a Chilean company - Go in Accounting > Vendor > Bills - Import an XML with the line `<Moneda>013</Moneda>` - Traceback ### Cause: `Moneda` can be the currency name code like `USD` but also a numeric code corresponding to the currency. ### Solution: Add a dictionary linking codes to the currency names and check the dictionary if `Moneda` is numeric. Also add a fallback on `CLP` in case the value of `Moneda` fails to be translated to a currency. This avoids a traceback later when reading `vals['currency_id']`. opw-5184950 Forward-Port-Of: odoo/enterprise#98067
This update makes the bank reconciliation screen more consistent across versions and reduces confusing duplicate partner information. It also prevents users from selecting certain bank-related accounts in reconciliation models when that selection would not produce a useful result, and keeps key payment action buttons easier to access.
Original PR description
[IMP] account_accountant: css backport To have a consistent css across all version of the new bank rec widget, we decided to backport few changes. backport of:…
[IMP] account_accountant: css backport To have a consistent css across all version of the new bank rec widget, we decided to backport few changes. backport of: https://github.com/odoo/enterprise/commit/524a7a46a0c2888b591de7ad1a0a6d744e345f5a https://github.com/odoo/enterprise/commit/2a83c85cb2c9a7a5da3d4a8483120eeda6b2e6cb https://github.com/odoo/enterprise/commit/e3cb3ab3ec8c64297d8e97d941e0d2eea3e64667 https://github.com/odoo/enterprise/commit/fdbb93abbf831cfa2fdc75e79aa76c094d6e522a https://github.com/odoo/enterprise/commit/f9725d7b01cbd1235f022821a6861adb2955e49e [FIX] account_accountant: restrict some account in the set_account Before this commit, we could select the liquidity account or bank suspense account which could create a reco model for it that would do nothing. [FIX] account_accountant: partner_name Before this commit, when a transaction had no partner_name and some lines with the same partner. When unfolded, we had the info of the partner on the statement line and on the line itself which was a duplicate of information. This commit will change when the line is unfolded so that the partner is visible on the statement line only when there is a partner_name [FIX] account_accountant: payable and receivable button Before this commit, the payable and receivable buttons where on the top line only when the reconcile button was not there anymore. Now We decided to always have them present in secondary next to the reconcile button. no task-id Forward-Port-Of: odoo/enterprise#98325 Forward-Port-Of: odoo/enterprise#96852
OCR-processed purchase receipts are now correctly treated as purchase documents instead of sales receipts. This prevents the system from selecting sales taxes on supplier receipts, improving accounting accuracy and reducing manual corrections.
Original PR description
Since task [4776275](https://www.odoo.com/odoo/project/2068/tasks/4776275) (commit [a7e9575](https://github.com/odoo/enterprise/commit/a7e9575d4c7fccff06db8a3ec2b9315d8ac33805)), the OCR is able to automatically detect and change a vendor bill into a receipt. The calls to `is_purchase_document` should have been updated to reflect that, but they weren't. Because of this, purchase receipts were considered as sale receipts, causing multiple issues such as sale taxes being selected instead of purchase taxes. task-none
Scanning a package in the barcode app now follows the same “Allow Extra Products” setting as scanning individual items. This prevents warehouse staff from accidentally adding the wrong packaged products to deliveries when extra products are not permitted.
Original PR description
## Issue 1: "Allow Extra Products" option ignored for packages ### Steps to reproduce: - In the settings enable "Packages" - Go to Inventory > Configuration > Warehouse Management > Operation Types -…
## Issue 1: "Allow Extra Products" option ignored for packages
### Steps to reproduce:
- In the settings enable "Packages"
- Go to Inventory > Configuration > Warehouse Management > Operation Types
- Disable "Allow Extra Products" on the "Delivery" operation type
- Create two storable product P1, P2 and add on hand quantities
- 10 x P1 in a package PACK01
- 10 x P2 in a package PACK02
- Create and confirm a delivery for 10 unit of P1
- Open your delivery from the barcode app
- Scan PACK02
#### > The content of PACK02 is added to the delivery even thought it contains extra products.
### Cause of the issue:
The check for extra products is only applied when scanning individual products but is bypassed by package scan. To be more precise, the `barcode_allow_extra_product` option is checked in the public method `createNewLine`:
https://github.com/odoo/enterprise/blob/331442fd9cbd59d542432b2237299df9497ce241/stock_barcode/static/src/models/barcode_picking_model.js#L59-L80
While this method is called at new line creation when a product is scanned, scanning a package will add new lines during the `_processPackage` adn bypasses the rest of the `_processBarcode`:
https://github.com/odoo/enterprise/blob/331442fd9cbd59d542432b2237299df9497ce241/stock_barcode/static/src/models/barcode_model.js#L1261-L1267
The issue being that the `__processPackage` does not check the `barcode_allow_extra_product` option and creates its new lines via the private `_createNewLine` call:
https://github.com/odoo/enterprise/blob/331442fd9cbd59d542432b2237299df9497ce241/stock_barcode/static/src/models/barcode_picking_model.js#L1564-L1565
https://github.com/odoo/enterprise/blob/331442fd9cbd59d542432b2237299df9497ce241/stock_barcode/static/src/models/barcode_picking_model.js#L1655-L1667
https://github.com/odoo/enterprise/blob/331442fd9cbd59d542432b2237299df9497ce241/stock_barcode/static/src/models/barcode_picking_model.js#L1671
### Fix:
Since scanning a package is expected to add all its content to the picking, and since a package can not be split among two locations, it is necessary to check in advance if any product of its content is extra and avoid any update in this case.
## Issue 2: impossibility of package line removal
-> Resolved in 19.0 see https://github.com/odoo/enterprise/commit/060f4c3e24e7add05273cfad5853884546937d0e#diff-3c84b414a086808e446ae3f90b3b803edf964c28237c153af19edda3ed05cc6bL21
### State of the art:
There is currently no option to remove a package line from the barcode. In particular, once the option `show_entire_packs`(Move Entire Packages) is enabled on a picking type, you can not remove the package line once generated by a scan.
#### Steps to reproduce:
- In the settings enable "Packages"
- Go to Inventory > Configuration > Warehoue Management > Operation Types
- Enable "Move Entire Packages" on the "Delivery" operation type
- Create a storable product and add on hand quanties:
- 10 units in package PACK01
- 10 units in package PACK02
- Create and confirm a delivery for PACK01 (in the package lines)
- Open your delivery from the barcode app
- Scan PACK02
#### > The new line associated to PACK02 can not be removed by any mean
opw-4863621
opw-5080637
Forward-Port-Of: odoo/enterprise#97497
Forward-Port-Of: odoo/enterprise#96299Users without administrator rights can now use the AI document sorting option when it is configured for their workspace. This removes an unnecessary permission barrier and helps documents be routed to the right folders more reliably.
Original PR description
Purpose: -------- Non-admin users should be able to trigger the auto-sort of their documents (since anyways they could delete and reupload their documents, which will trigger the auto-sort). - The "Sort with AI" button was missing in the topbar for non-admin users. To fix this, a boolean `ai_has_sort_prompt` is added in the search panel values (the button was shown if `ai_sort_prompt` was set, which is only accessible by users with group_system) - The display name of folders is now the folder name if the env is sudo-ed even if the user has not access this folder (these folders are valid targets if they are in the `ai_sort_prompt`, but they were inserted as "Restricted Folder" so the LLM could not decide in which folder to move the document) - Add a few sudo's so that the auto-sort action can be triggered by a non admin user Task-5144695
Budget generation no longer fails when users split a budget by analytic plan. This helps accounting teams create split budgets reliably without encountering an error during the process.
Original PR description
Currently, on creating a budget using split budget causing an error. **Steps to Reporduce:** 1) Install **account_budget module(with Demo)** 2) Navigate to **Accounting>Accounting>Analytic Budget**…
Currently, on creating a budget using split budget causing an error. **Steps to Reporduce:** 1) Install **account_budget module(with Demo)** 2) Navigate to **Accounting>Accounting>Analytic Budget** 3) Click on `Generate` set `Analytic Plan` and click on `Split` Error: `ValueError: Cannot convert budget.line.achieved_amount to SQL because it is not stored` Root Cause: since [this commit](https://github.com/odoo/odoo/pull/224667/commits/53b4670b1ad375ffc3800fc3beb97e960f229dc6), a new aggregate spec `sum_currency` was added. As a result, the code at [1] is executed for currency-aware aggregates. From the line, `self._field_to_sql(self._table, fname, query)` the ORM tries to create an SQL expression for `achieved_amount`. Because `achieved_amount` is computed `_field_to_sql` fails and error is raised. Fix: Provide a default SQL expression for computed fields on Budget Line [1]: https://github.com/odoo/odoo/blob/af668f545676f72385c52629f8498edfe22219cd/odoo/orm/models.py#L1972-L2004 Used Reference: https://github.com/odoo/odoo/blob/d42102cac8fff3967cb605a897bbb0e8690464ed/addons/crm/models/crm_lead.py#L286-L298 sentry-6917352415
This fixes issues in Email Marketing where the wrong email editor could appear when moving between mailing records, and where editor toolbars could disrupt the editing area. Users should see the correct editor consistently and have a smoother editing experience.
Original PR description
### use overlay offset for basic editor In this prior [fix], overlays spawned by the HtmlBuilder and its children have a modified offset in order to prevent the `MassMailingIframe` from unloading its…
### use overlay offset for basic editor In this prior [fix], overlays spawned by the HtmlBuilder and its children have a modified offset in order to prevent the `MassMailingIframe` from unloading its content. However the `MassMailingHtmlField` also handles a Simple Editor feature, which does not use the Builder. This feature still uses an iframe and also uses overlays (popover toolbars). This work moves the [fix] in `MassMailingIframe` so that it applies also for the Simple Editor. [fix]: https://github.com/odoo/odoo/commit/dd31e31f3cecd4d23dc90f9c88780bf3b969a294 ### ensure correct editor instance on record switch Issue: When switching from one record to another using the Form view pager, the `activeTheme` was set to the theme value of the previous record, resulting in the wrong Editor instance in some cases. How to reproduce: - Open the list view in Email Marketing - Ensure there are 2 records in the list view: - one editable with the builder (default theme) - one editable with the simple editor (basic theme) - click on the record with the simple editor - use the pager to switch to the next record Issue: - switching from simple -> builder, the builder is not instanced but it should have been - switching from builder -> simple, the builder is instanced but it should not have been Resolution: Update the active theme based on the value of the nextRecord instead of the record currently in `props`, because `this.props.record` is updated after `updateActiveTheme` is called. task-5217595
Employee working hours now display correctly when their contract or occupation starts before the employee record version date. This prevents schedules such as 24 hours per week from incorrectly showing as zero and improves workforce planning accuracy.
Original PR description
**Issue / current behavior:** When you create an employee with version date = today and set him an occupation starting in the past and then when we try to assign him a working schedule 24h/week it shows 0 working hours. **Required behavior:** It should display 24 working hours or whatever selected. **Solution:** Changed the field of available time of the week to contract_start_date from the version_start_date. task-4985887 I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#221912
This fix stops users from deleting a unit of measure that is still referenced by a purchase order line. It prevents purchase order confirmation errors and helps keep purchasing data consistent.
Original PR description
When a user deletes the UoM used in a purchase order line and then tries to confirm the purchase order. Steps to reproduce: --- - Install `purchase_stock` module(without demo) - Create a New PO > Add a product in Line (with UoM=Units) - Remove UoM in order line and select `Dozen` in it > Save - Settings > Units of Measure Categories > Open `Units` > Remove `Dozen` - Orders > Requests for Quotation > Open PO > `Confirm Order` Traceback: --- `ValueError: Expected singleton: uom.uom()` `AssertionError: precision_rounding must be positive, got 0.0` This error occurs because, after the UoM is deleted, the `product_uom` field becomes empty, which leads to an error. Solution: --- This commit resolves the error by restricting the deletion of a UoM when it is still in use. sentry-6746792383 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#233783 Forward-Port-Of: odoo/odoo#231478
This update ensures the Appraisals app includes the required hierarchy component during upgrades. It prevents upgrade failures for databases where related hierarchy features were previously not installed or were removed.
Original PR description
In version `19.0` new hierarchy views was added to module `hr_appraisal` by this commit[^1]. But the module `web_hierarchy` is not dependency of `hr_appraisal`. When we install `hr_appraisal` it…
In version `19.0` new hierarchy views was added to module `hr_appraisal` by this commit[^1]. But the module `web_hierarchy` is not dependency of `hr_appraisal`.
When we install `hr_appraisal` it triggers the installation of `hr` because of dependency. On the other side `hr_org_chart`[^2] gets installed because of auto_install=true. So it makes `web_hierarchy` installed because of the `hr_org_chart` dependency.
If we upgrade db from `18.0` to `19.0` which `hr_appraisal` installed and `web_hierarchy` uninstalled we will get issue as `hr_appraisal` requires dependency to `web_hierarchy` because of new views.
Steps to reproduce (case 1):
1. Install `hr_appraisal` in `18.0`
2. Uninstall `web_hierarchy`
3. Upgrade to `19.0`
Steps to reproduce (case 2):
1. Install `hr_appraisal` in `16.0`
2. Uninstall `hr_org_chart`
3. Upgrade to `19.0`
In this 2nd case, the `web_hierarchy` is not existing yet and `hr_org_chart` is auto installed module, so during upgrade it will not be re-installed again.
We will get traceback like this:
```
Traceback (most recent call last):
File "/home/odoo/src/odoo/19.0/odoo/service/server.py", line 1509, in preload_registries
registry = Registry.new(dbname, update_module=update_module, install_modules=config['init'], upgrade_modules=config['update'], reinit_modules=config['reinit'])
File "/home/odoo/src/odoo/19.0/odoo/tools/func.py", line 88, in locked
return func(inst, *args, **kwargs)
File "/home/odoo/src/odoo/19.0/odoo/orm/registry.py", line 185, in new
load_modules(
File "/home/odoo/src/odoo/19.0/odoo/modules/loading.py", line 449, in load_modules
load_module_graph(
File "/home/odoo/src/odoo/19.0/odoo/modules/loading.py", line 211, in load_module_graph
load_data(env, idref, mode, kind='data', package=package)
File "/home/odoo/src/odoo/19.0/odoo/modules/loading.py", line 58, in load_data
convert_file(env, package.name, filename, idref, mode, noupdate=kind == 'demo')
File "/home/odoo/src/odoo/19.0/odoo/tools/convert.py", line 646, in convert_file
convert_xml_import(env, module, fp, idref, mode, noupdate)
File "/home/odoo/src/odoo/19.0/odoo/tools/convert.py", line 745, in convert_xml_import
obj.parse(doc.getroot())
File "/home/odoo/src/odoo/19.0/odoo/tools/convert.py", line 616, in parse
self._tag_root(de)
File "/home/odoo/src/odoo/19.0/odoo/tools/convert.py", line 570, in _tag_root
raise ParseError(msg) from None # Restart with "--log-handler odoo.tools.convert:DEBUG" for complete traceback
odoo.tools.convert.ParseError: while parsing /home/odoo/src/enterprise/19.0/hr_appraisal/views/hr_appraisal_goal_template_views.xml:71
Invalid view type: 'hierarchy'.
You might have used an invalid starting tag in the architecture.
Allowed types are: list, form, graph, pivot, calendar, kanban, search, qweb, cohort, gantt, grid, map, activity
View error context:
'-no context-'
```
[^1]: https://github.com/odoo/enterprise/commit/dbe4946218b3523bea4fb8a79be8f3fc29d8d33e
[^2]: https://github.com/odoo/odoo/blob/dec621e60794ede263222e3b5be0ebfc33ed6f40/addons/hr_org_chart/__manifest__.py#L16-L17Mexican payroll documents now include the employment subsidy section only when the payment type is actually subsidy-related. This prevents government submission failures when payslips include other non-subsidy inputs.
Original PR description
Bug: If we add other inputs to a payslip, in the CFDI, then sending to the government will fail. Cause: In the CFDI, the node 'SubsidioAlEmpleo' is present when it shouldn't. Fix: The node should be present only for other payments of code 002, 007 or 008, all related to subsidies. Task: 5224176
Nilvera e-invoice document resubmissions now resend the full XML file instead of accidentally sending an empty file after a retry. This helps prevent failed submissions and 400 errors when Turkish e-invoicing documents need to be resubmitted.
Original PR description
Resubmitting a Nilvera document reused the same XML stream, leading to an empty file on retries. The issue occurs because `requests.Session. request()` reads the BytesIO buffer, moving its cursor to the end of the file. As a result, subsequent reads return empty content. This fix wraps the XML content in a new BytesIO buffer before each submission to ensure safe recursive resubmissions and prevent 400 errors caused by empty payloads. task-5163253 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fixes an issue in Point of Sale where choosing a customer after adding an online payment could leave the completed payment without the correct customer information. Businesses get more reliable order records and smoother reconciliation for online payments.
Original PR description
Before this commit, if a partner was selected after adding an online payment line, the partner was not synced after completing the online payment. opw-5098127 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#233405 Forward-Port-Of: odoo/odoo#232455
Fixes an issue where running a test import with batching could cause the final import to start from the wrong point, importing only the last batch. After a successful test import, the import process now resets to the beginning so all intended records are imported.
Original PR description
Steps to reproduce ================== - Go to contacts - Click on the cog menu > Import records - Upload a csv file - Limit the batch limit to a value lower than the total number of records in the csv file - Click on the test button - Click on the Import button => Only the last batch is imported Cause of the issue ================== The start line is not reset after the test import, which can be confusing Solution ======== When the test import fully succeeds, we reset the start line opw-4916102 Forward-Port-Of: odoo/odoo#233498 Forward-Port-Of: odoo/odoo#230805
Creating a sales order from a project no longer fails when the order has no products or only non-service products. This helps users save project-related sales orders reliably without encountering an unexpected error.
Original PR description
Currently, an error occurs when creating a sale order for a project. **Steps to Reproduce:** - Install the `sale_project` module. - Go to `Project` and, in the `list view`, create a `project` and…
Currently, an error occurs when creating a sale order for a project. **Steps to Reproduce:** - Install the `sale_project` module. - Go to `Project` and, in the `list view`, create a `project` and `set a customer`. - Click the `Sales Order` button in the header. - Save the `sale order` without adding `any product` or by adding a `non-service product`. **Error:** `AttributeError: 'bool' object has no attribute 'order_id'` This error occurs, when user creating a sale order for a project without adding a service product, then service sol becomes empty [1], which raises an error here [2] when trying to access the sale order. This commit ensures that if there is no service sol, empty sol is taken in the service sol. [1]- https://github.com/odoo/odoo/blob/3121577430cdfa485af4d69792745a6f9c2ffe2f/addons/sale_project/models/sale_order.py#L272 [2]- https://github.com/odoo/odoo/blob/3121577430cdfa485af4d69792745a6f9c2ffe2f/addons/sale_project/models/sale_order.py#L276 sentry-6948584510 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix prevents errors when users edit images that are already stored in Odoo, such as applying filters or converting formats in the website or HTML editor. The editor now reuses the existing image data when needed, so users can continue editing without unexpected server errors.
Original PR description
Description of the issue/feature this PR addresses: Issue reported[ here ](https://github.com/odoo/odoo/issues/233130) Impacted versions: 19.0 (and likely earlier stable versions: 17.0, 18.0) Steps…
Description of the issue/feature this PR addresses: Issue reported[ here ](https://github.com/odoo/odoo/issues/233130) Impacted versions: 19.0 (and likely earlier stable versions: 17.0, 18.0) Steps to reproduce: Open the Website Editor or HTML Editor (e.g., editing a website page). Insert or select an image that has been saved as an attachment (source is a /web/image/... URL, not a Base64 string). Perform an action that triggers the attachment modification logic (e.g., applying a filter, or a WebP conversion step). **Current behavior before PR:** - The client-side JavaScript correctly omits the data parameter in the RPC request to /html_editor/modify_image/<attachment_id>. - The Python modify_image controller receives data=None, and subsequent image processing fails because it expects the image content, leading to a server-side traceback (e.g., a KeyError or a failure in image manipulation libraries). **Desired behavior after PR is merged:** The modify_image controller should successfully retrieve the existing image content from the database and process the modification without error. - This controller endpoint handles modifications for existing attachments. When the client is modifying a server-stored image (sourced via /web/image/...), the client efficiently omits the image data payload. - The controller should be resilient to this behavior by retrieving the image content directly from the existing attachment record. - The fix introduces a conditional check to load the image's base64 content (attachment.datas) into the data variable if the client does not provide a new payload (data is None). - This is the most robust and performant solution, as it ensures the controller has the necessary image data without forcing the client to re-upload potentially large files --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
French VAT report submission no longer fails when users start the EDI VAT process from the tax report menu. This prevents an error during filing and lets accounting teams submit the VAT return through the expected workflow.
Original PR description
Steps to reproduce: - With a FR Company Setup - Create a bill with tax in past month - Create Tax return for past month, validate - Click "Submit", fill the required vals in wizard and 'Send VAT report' - Everything works as expected - From Accounting / Accounting / Closing / Tax Returns click Cog > EDI VAT - Fill the required vals in wizard and again 'Send VAT report' Issue: Traceback will raise `ValueError: Expected singleton: account.return()` Analysis: When opening the VAT Return wizard from Accounting / Accounting / Closing / Tax Returns the value of return record is not passed on opw-5107549
Point of Sale users can now search for products that use dynamic attributes, even before a specific variant has been created. This prevents missing products during checkout and helps staff find configurable items more reliably.
Original PR description
Before this commit, it was not possible to search a product that had a dynamic attribute configured on its template, since no product variant was created yet. opw-5188725 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#233779 Forward-Port-Of: odoo/odoo#232838
This fixes Stripe payments in Point of Sale so tips added after payment are handled correctly. Businesses using POS Restaurant with Stripe can again capture payments properly and support post-payment tipping without failed or uncaptured transactions.
Original PR description
Since [^1], tip after payment has been broken for stripe as `_update_payment_line_for_tip` is no longer called anywhere. This means that all payments were put in as uncaptured and no future tipping would work. This PR fixes it by using the "new" send_payment_adjust method like ayden to guarantee the payments are properly handled. Note that this is solved by wrapping `capturePayment` into a new method `capturePaymentStripe` to keep the stable policy. A followup PR will move the data back to `capturePayment` in master with the new parameters. opw-5121568 [^1]: 9c37f42ef4e23372f5e2bdbb956b625b3a47d8e1 Forward-Port-Of: odoo/odoo#232574
Importing Indian IRN invoice JSON files now works for users who do not have access to certain company settings. This prevents an unnecessary permission error and helps invoice processing continue smoothly without granting extra company-level access.
Original PR description
When importing an IRN JSON as an invoice, users without sufficient access rights to `res.company` fields encountered an access error on `l10n_in_edi_production_env`. This commit uses `sudo()` to safely read the company’s EDI environment configuration without requiring extra permissions. Before this PR: Import failed with error: `You do not have enough rights to access the field 'l10n_in_edi_production_env' on Companies (res.company)` After this PR: Import proceeds successfully for users without `res.company` read rights. Forward-Port-Of: odoo/enterprise#98528
Portal users clicking Browse Articles from a Helpdesk help page are now sent directly to the linked Knowledge article instead of an empty Knowledge home page. This makes self-service support content easier to access and avoids a confusing dead end for customers.
Original PR description
To reproduce: ============= 1. Create a Helpdesk Team linked to a Knowledge Article 2. Access the Help page on website as a portal user 3. Click on "Browse Articles" button -> redirected to empty knowledge home portal view Problem: ======== before this commit, redirection was made through the method `redirect_to_article` which will later call `_redirect_to_portal_view` that doesn't use the `article` parameter anymore as there is a patch on the front side to handle the redirection to the articale through the router, but as the calls are server-side, the patch is not applied and the redirection fails. Solution: ========= instead of calling `redirect_to_article`, directly redirect to the article's `website_url`. opw-5114885 Forward-Port-Of: odoo/enterprise#98363
This fix helps Point of Sale sessions start correctly when extra features, such as restaurant functionality, add new local data storage needs. The system now detects missing local storage tables and updates them automatically, reducing session failures for cashiers and restaurants.
Original PR description
Currently, new IndexedDB object stores are only created during the 'onupgradeneeded' event. This event only fires if the database version is manually incremented in the code. If a new module (e.g.,…
Currently, new IndexedDB object stores are only created during the 'onupgradeneeded' event. This event only fires if the database version is manually incremented in the code. If a new module (e.g., restaurant) adds a new object store to the PoS database schema but the `dbVersion` is not bumped, the store is never created. This causes the PoS session to fail when it tries to access the missing store. This commit modifies the `databaseEventListener` to add a check inside the `onsuccess` handler. After the database opens, it compares the list of required stores (`this.dbStores`) with the list of existing stores (`this.db.objectStoreNames`). If a mismatch is detected: 1. The current database connection is closed. 2. The `dbVersion` is incremented. 3. The database connection process is re-run. This forces the `onupgradeneeded` event to trigger, which then correctly creates the missing object stores, ensuring the database schema is always up-to-date. opw-5166049 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#233268
16 changes
Enhancements to existing features
The Pakistan payroll localization has been updated with the latest 2026 income tax bracket values. This helps businesses calculate employee payroll taxes in line with the new requirements.
Original PR description
Tax brackets for pakistan localization has been updated to include the new values for 2026.
Resolved issues and error corrections
The update prevents company chart setup from failing when newly introduced Indian tax records are not yet present for an existing company. This helps businesses continue using or configuring Indian localization without unexpected errors after stable legal tax updates.
Original PR description
If new taxes are introduced in stable (for legal reasons), and for Indian localisation we create new fiscals position for branch In such that case the new taxes will be not updated for the current company in such that case it will be lead to traceback with External ID not found for taxes. In this commit we add a new context `raise_if_not_found_ref`, through which if the tax doesn't exists the error is not raised --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Portal users clicking "Browse Articles" from a Helpdesk help page are now taken directly to the linked Knowledge article instead of an empty knowledge home page. This fixes a navigation issue and helps customers find the intended self-service content faster.
Original PR description
To reproduce: ============= 1. Create a Helpdesk Team linked to a Knowledge Article 2. Access the Help page on website as a portal user 3. Click on "Browse Articles" button -> redirected to empty knowledge home portal view Problem: ======== before this commit, redirection was made through the method `redirect_to_article` which will later call `_redirect_to_portal_view` that doesn't use the `article` parameter anymore as there is a patch on the front side to handle the redirection to the articale through the router, but as the calls are server-side, the patch is not applied and the redirection fails. Solution: ========= instead of calling `redirect_to_article`, directly redirect to the article's `website_url`. opw-5114885
Fixes an issue where updating multiple combo products in an unsaved sales order could cause their related items to appear under the wrong combo. This keeps sales order lines clear and accurate while users adjust quantities before saving.
Original PR description
Steps to Reproduce: - Create a Sale Order containing two combo products placed consecutively. - Change the quantity of the first combo → corresponding combo items update correctly. - Without saving,…
Steps to Reproduce: - Create a Sale Order containing two combo products placed consecutively. - Change the quantity of the first combo → corresponding combo items update correctly. - Without saving, change the quantity of the second combo. - Observe that the combo items now appear misplaced — items from the second combo are inserted before those of the first combo. Issue: - The order of combo items becomes incorrect when multiple combo products are updated consecutively in the same unsaved Sale Order. Cause: - During `onchange`, the `self.order_line` recordset reflects the *in-memory order of applied commands* rather than the database `sequence` field because they are not saved in the DB during the edition. - Each `onchange` rebuilds `order_line` using concatenated command lists (`delete + create + update`), So when multiple combos are modified without save, newly created combo items are appended according to command evaluation order — not by logical grouping. - This causes combo items to shift relative to their parent combo lines. Solution: - Restrict the recomputation of order lines to non-combo lines by filtering out combo item lines during the rebuild. As combo items will always be in their desired sequence. - This ensures that combo items always stay under their respective parent combos and their sequence is preserved, regardless of the order in which combos are updated. opw-5148770 Affected Version:18.0 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fixes Stripe payments in Point of Sale so tips added after payment are handled correctly. Payments are now properly captured and adjusted, preventing failed or blocked future tipping for restaurant and POS customers.
Original PR description
Since [^1], tip after payment has been broken for stripe as `_update_payment_line_for_tip` is no longer called anywhere. This means that all payments were put in as uncaptured and no future tipping would work. This PR fixes it by using the "new" send_payment_adjust method like ayden to guarantee the payments are properly handled. Note that this is solved by wrapping `capturePayment` into a new method `capturePaymentStripe` to keep the stable policy. A followup PR will move the data back to `capturePayment` in master with the new parameters. opw-5121568 [^1]: 9c37f42ef4e23372f5e2bdbb956b625b3a47d8e1
Fixes an error that occurred when users tried to split more than one Manufacturing Order at the same time. This helps manufacturing teams complete bulk actions from the order list without hitting a system traceback.
Original PR description
Steps to reproduce: - Create two Manufacturing Orders - From the list, select them and click on cog -> Split Issue: A traceback appears, as we try to insert `res.users` records in the database rather than their id. Since #154607, the wizard's `counter` has its default set to 2. However, when opening the wizard with multiple MOs at once, even if the `counter` isn't displayed, the details will be computed for each MO. This didn't cause issue in previous versions as we always went through a `web_save` that sent their ID, but now its possible to have this whole process server-side at the creation of the wizard, exposing the error. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Fixed an issue where purchase order tax totals could fail when multiple currencies were involved. The calculation now uses the currency from the current purchase order, preventing errors and helping users view accurate tax totals reliably.
Original PR description
On the tax computation, when trying to compute the total tax, customer was having an error " Expected singleton: res.currency(1, 69) " As Odoo is trying to get the currency of all the records instead of the one in the current order opw-5177551
Customers will now receive email notifications when Gelato sends an order status update. This fixes a communication gap so buyers are kept informed about progress on their orders.
Original PR description
Fix not sending the email to customer, when order status update was received from Gelato. opw-4962878
The self-ordering menu mode has been fixed so customers can browse the menu as intended. This helps restaurants avoid confusion or interruptions when customers use mobile self-ordering without placing an immediate order.
Original PR description
Menu mode was broken in self ordering. This commit fix it.
The Journal Report now keeps its Global Tax Summary in sync when users change the rounding unit. This prevents mismatched figures between the main report and tax summary, improving confidence in financial report presentation.
Original PR description
Currently when users change the rounding unit filter in the Journal Report, the Global Tax Summary values remain in the old format instead of updating to reflect the new rounding setting. This…
Currently when users change the rounding unit filter in the Journal Report, the Global Tax Summary values remain in the old format instead of updating to reflect the new rounding setting. This creates inconsistency where main report values update correctly but tax summary values stay unchanged. Cause: - The issue occurs because `_format_column_values` method in `account_report.py` wasn't handling the special tax summary data structures (`tax_report_lines` and `tax_grid_summary_lines`) that store pre-formatted values. These structures need to be reformatted when rounding unit changes, but the formatting logic only covered standard report columns. Fix Applied: - Updated frontend (`filters.js`) to call `format_column_values_from_client` via `dispatch_report_action` instead of calling `format_column_values` directly. (this enables proper routing through the custom handler system) - Added `format_column_values_from_client` override in `JournalReportCustomHandler` that intercepts the formatting call and applies special handling for tax summary lines by adding logic to reformat `tax_report_lines` and `tax_grid_summary_lines` monetary fields using their `_no_format` counterparts. - The custom handler then delegates to the base method via `report.format_column_values_from_client()` to format standard columns. - Also added missing `_no_format` fields in `account_journal_report.py` for `base_amount` and `tax_amount` to enable proper reformatting. Forward-Port-Of: odoo/enterprise#94660
Portal users can no longer change the customer field on project tasks, preventing them from accidentally removing the customer and being unable to restore it. The fix also avoids an access error when portal users create new tasks with a default customer.
Original PR description
Since the user can only set himself as customer for task in the portal view, we removed this option in order to avoid issues on the customer side. E.A. setting the customer to False, then save, and being unable to put back the original customer. 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#200366
New field service tasks created from the portal now automatically use the current user as the customer when no customer is provided. This prevents task creation issues caused by a missing required customer and makes the process more reliable across related field service workflows.
Original PR description
When creating a new FSM task in the portal view, the current user will now be set as default user instead of False. The fix is done to be more generic. The customer field is mandatory on fsm tasks, but there is no restriction on it in the backend side. So we might encounter a similar issue again. With assigning a default user for fsm tasks at the creation, we ensure that the field is always set. Forward-Port-Of: odoo/enterprise#80770
Company logo fetching for partner autocomplete now uses the updated logo.dev service through Odoo's IAP service instead of loading logos directly in the browser. Logos are no longer shown during search selection and are fetched only during enrichment, making the process more centralized and reliable.
Original PR description
Before this commit- We used to rely on clearbit to fetch the logo of the company on the client side After this commit- We replace it with logo.dev and remove the fetching of logo from client side and move it to the IAP task-5126337 IAP PR- https://github.com/odoo/iap-apps/pull/1234 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#231397
Subscription invoices now keep recurring delivery charges at their full fixed amount when billing periods are prorated. This prevents customers from being undercharged for shipping when subscriptions are aligned to calendar billing.
Original PR description
Version - 18.0 Steps to reproduce: 1. Create a subscription with delivery product. 2. Select align to calendar in the recurring plan 2. Add shipping method by assigning a delivery product with recurring_invoice. 3. Create an invoice with prorated Issue: - Delivery products are considered service-type products and their price was prorated in invoice. Cause: - The proration logic treated delivery lines like normal recurring service products, instead of keeping their fixed charge. Solution: - Exclude delivery products from proration by setting their period ratio to 1. Co-authored-by: Darshan Patel dvpa@odoo.com Co-authored-by: Federico Braidi brfe@odoo.com task-4662188
Turkish withholding e-invoices sent through Nilvera now include the VAT percentage in the tax details. This ensures the VAT amount is displayed correctly on the generated PDF, reducing confusion for customers and accounting teams.
Original PR description
Before this commit: For withholding invoices, the VAT percentage was not included inside the <cac:TaxTotals> node, due to this, the VAT amount was not displayed in the PDF in Nilvera. After this commit: The VAT amount is shown correctly in the <cbc:Percent> node inside the <cac:TaxTotals> node and percent amount appears correctly in the PDF. task-5225600 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Features or functions removed from Odoo
The media dialog no longer offers Dailymotion or Youku embed options where they can create broken video content due to platform changes. Users will see a more accurate list of supported video platforms, reducing the chance of adding videos that do not work properly on websites.
Original PR description
Specification: Improve `VideoSelector` Component. After this PR: - Dailymotion has deprecated its legacy embed endpoint starting September 23, 2024. Removed support for embedding Dailymotion videos in the media dialog. - Embedding Youku videos via iframe has become unreliable and no longer functions properly in the media dialog. Removed support for Youku embeds to prevent broken video content. - The supported platforms string now correctly lists YouTube, Vimeo, and Dailymotion, Instagram as supported platforms. task-4855038 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#214296
7 changes
Enhancements to existing features
Stock availability calculations now avoid unnecessary repeated checks when many incoming and outgoing stock moves are linked. This can make large picking reports much faster, reducing wait times for users reviewing product availability.
Original PR description
Before this commit, computing `product_availability` and `product_availability_state` required calling the `get_report_lines` method from the `stock.forecasted_product_product` model. In pickings…
Before this commit, computing `product_availability` and `product_availability_state` required calling the `get_report_lines` method from the `stock.forecasted_product_product` model. In pickings containing moves linked to many incoming and outgoing moves, the `reconcile_out_with_ins` function caused performance issues. The reconciliation logic worked as follows: 1. For each `out_move`, attempt to match it with an `in_move` if the `in_move` references the `out_move` in its `move_dests`. 2. If the demand of the `out_move` is not fully satisfied, add it to `unreconciled_outs`. 3. Loop over `unreconciled_outs` (after attempting to reconcile them using the initial prodcedure) to reconcile against the remaining `in_moves`. The performance bottleneck was that even when an `in_move` directly referenced an `out_move`, the code would unnecessarily loop over **all** `in_moves` to filter out the `in_moves` that has the `out_move` in its `move_dest`. --- To improve performance, an **inverse mapping** from `out_move` IDs to their corresponding `in_moves` is introduced. - Reconciliation now starts by iterating only over the relevant `in_moves`. - If the demand is still unmet, the algorithm attempts reconciliation against the remaining `in_moves`. - This reduces the time complexity to **O(N + M)**, since `in_moves` with zero quantities are removed and never revisited. **Implementation details:** - An `OrderedSet` is used for the inverse mapping to preserve the original query order. - Benefits of `OrderedSet`: - **O(1)** removal (assuming no collisions) - Maintains insertion order, ensuring the same order as the query result. --- | Metric | Before PR | After PR | |---------------|-----------|----------| | Execution Time| ~90 sec | ~10 sec | The benchmark above is done on a `stock.picking` record that queried in the `_get_report_lines` method **5331** `out_moves` and **8922** `in_moves`. opw-4951469
Resolved issues and error corrections
This fixes cases where a renamed document still showed its old file name in the preview window. Users will now see the correct document name immediately and consistently when previewing files, reducing confusion when managing documents.
Original PR description
# Issues There are a total of 3 different flows by which we observe the common issue (name not updating in the fileviewer) ----------------------------- ### 1st flow 1. click on any image to preview…
# Issues There are a total of 3 different flows by which we observe the common issue (name not updating in the fileviewer) ----------------------------- ### 1st flow 1. click on any image to preview it. 2. close the preview. 3. now just select the same document. 4. change it's name from the inspector and hit ENTER. 5. now keeping it selected, preview it again. 6. you will notice the file name has not been updated in the file viewer. issue: - the existing IF condition which is present only checks for the datapoint ID (which changes only when we replace the existing document with a new document). reason: - but in our case, since the document is same the ID remains the same. - as a result, the code inside the IF block does not get executed and the document store is not updated. but we still need to update the document store with the newly updated document. fix: - we remove the IF condition so that we ensure that the document store is updated everytime we PREVIEW any document. ---------------------------------------------------- ### 2nd flow 1. click on any image to preview it. (do not select it) 2. change it's name from the inspector and hit ENTER. 3. close the PREVIEW. 4. PREVIEW the same document again. 4. you will notice the file name has not been updated in the file viewer. issue: - for some reason the existing `record.save()` fails to save/update the root records. fix: - we find that record from the root and save it from the root. ---------------------------------------------------------- ### 3rd flow 1. click on any image to preview it. 2. change it's name from the inspector and hit ENTER. 3. you will notice the file name has not been updated in the file viewer. issue: - the `previewStore` object is formed/updated only when we preview any document. it is this `previewStore` object which contains the list of documents to preview. - but when we update the file name from the inspector, the code to update the `previewStore` is absent. fix: - on updating the values from the inspector, we now update the `previewStore` as well. which then goes on to update the name in the FILEVIEWER. Task-4605750
Planning analysis reports no longer count hours from a shift that falls outside an employee's working schedule just because it crosses into a new month. This prevents planned hours from being overstated in the wrong reporting period, improving accuracy for capacity and timesheet planning.
Original PR description
### Steps to reproduce: - Create an employee with fixed working schedule from 8 to 5 - Create a Planning shift for this employee that starts in a month and ends in the first day of the next month outside of working hours (e.g. Sept30th 8AM -> Oct1st 2AM) - Navigate to Timesheets / Planning analysis reports - Notice October has been taken into consideration in the report's planned hours ### Cause: The query we are using for the timesheets/planning report doesn't take working hours into consideration it only cares about the date. So if the shift ends in October 1st we are taking it into account whether it is inside working hours or not. ### Fix: Add a condition to the where clause to check the working hours and if the record lays in this period or not. opw-5089052
Company logo lookup now uses Odoo's enrichment service instead of fetching logos directly in the user's browser. This should make partner enrichment more reliable while removing logo display from the initial search results.
Original PR description
Before this commit- We used to rely on clearbit to fetch the logo of the company on the client side After this commit- We replace it with logo.dev and remove the fetching of logo from client side and move it to the IAP task-5126337 IAP PR- https://github.com/odoo/iap-apps/pull/1234 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Copying an email template now also creates separate copies of its attachments, instead of sharing the same files across templates. This prevents attachment changes from unintentionally affecting other copied templates and helps avoid access issues where attachment permissions depend on the specific template.
Original PR description
Copying tmeplates should copy their attachments. Otherwise they are
shared, which means
* wrong res_id: ACL check on attachments relies on a specific
template, as res_model / res_id is used in access check;
* propagated changes: changing one attachment changes it on all
duplicated templates;
If custom rules on templates are implemented, this means notably
ACL issues when accessing attachments. It is not the case in standard
Odoo 17 as everyone can read templates but this notably changes in
future versions of Odoo.
While being there, also fix 'default' usage in copy override. User
given values should not be erased by default computation of name.
Task-5128863This fix keeps the bill of materials selection in sync when a user changes the product on a scrap order. It prevents scrap orders from showing a zero quantity while still moving the original quantity, reducing inventory inconsistencies.
Original PR description
Problem: When a user changes the product on a scrap order, the bom_id field does not get updated. If they update the product from a product that has BoM to a product that doesn’t have one, then the bom_id field is hidden and remains set. This will cause the scrap quantity to be set to 0 when they validate the scrap. However, the product move actually happens for the correct quantity causing an inconsistency. Purpose: This will either set the bom_id field to False if the new product doesn’t have a valid BoM, or it will update it to the first available BoM. Steps to Reproduce on Runbot: 1. Create a scrap order for a product that has a kit type BoM and set the kit field. 2. Change the product to a product without a kit type BoM. 3. Validate the scrap order. 4. Observe the quantity field is set to 0, but there are product moves for the correct quantity. opw-5122880 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Swiss payroll now avoids applying AHV/IV/EO deductions when a retired employee’s AVS salary becomes negative due to variable pay and exemption thresholds. This prevents an incorrect increase to net salary and keeps payslip calculations aligned with expected payroll rules.
Original PR description
**Issue:** For retired employees with AHV Insurance and variable pay, if their pay previously exceeded the exempt amount but is below the exempt amount on the current payslip, the AVS Salary will be…
**Issue:** For retired employees with AHV Insurance and variable pay, if their pay previously exceeded the exempt amount but is below the exempt amount on the current payslip, the AVS Salary will be negative, which is expected. However, the AVS deduction is still calculated based on this negative amount and adds to the Net Salary, which is incorrect. Instead, no deduction should be applied. **Steps to Reproduce:** 1) Install l10n_ch_hr_payroll_elm_transmission 2) Change to My Swiss Company and enable the Switzerland Fiscal Package 3) Go to Payroll > Configuration > AVS/AC Insurances 4) Create a new record, fill in the empty required fields with any data 5) Create a new employee 6) Create a contract for the employee starting January 1, with: - Contract Type = Permanent contract with monthly salary - Has Monthly Wage = True, 500.00 7) On the contract under Insurances tab, set: - AVS/AC Insurance = The Insurance created in (4) - AVS Special Status = Retired 8) Create a payslip for January, compute sheet, and post draft entries. -> AVSSALARY = 0 (Correct) 9) Change the Monthly Wage and repeat payslip creation and posting for the following months: - February: 800 - March: 1,200 - April & May: 3,000 - June: 800 -> On the June payslip, notice that the AVS Salary is negative (correct) but the AVS Deduction is positive and adds to net salary (wrong) **Solution:** Modify the AHV/IV/EO contribution and AHV/IV/EO Employer contribution rules so that if the AVS Salary is less than 0, no deduction is made. opw-5042175