Monday, October 6, 2025
13 changes · master
Enhancements to existing features
AI-powered URL fetching now checks each website's robots.txt rules before accessing pages, using the Odoobot identity. This helps Odoo interact more politely with external websites, avoid disallowed content, and provide clearer feedback when access is blocked.
Original PR description
### Purpose Add `robots.txt` compliance to the `_fetch_url` helper. Before fetching any URL, we now check the site's `robots.txt` and ensure that our user agent (`Odoobot/1.0`) is allowed to access the requested path. ### Changes - Added `robots.txt` validation using `urllib.robotparser` - Respect disallow rules for the `Odoobot/1.0` user agent ### Why This ensures that our crawler behaves politely, avoids fetching disallowed resources, and provides more transparent failure reporting. --- **Task-ID:** 4779962
Lithuanian payroll benefits are now managed as configurable payroll properties instead of fixed rule amounts. This gives payroll teams more flexibility to model employee benefits and helps ensure salary rules apply the right values in more complex payroll scenarios.
VoIP call handling has been improved so that each active call keeps its own state instead of sharing one global state. This reduces the risk of call mix-ups or timing issues when users perform attended transfers involving more than one simultaneous call.
Original PR description
The original VoIP code was written under the assumption that there would only ever be one session at a time. Consequently, much of the session state was stored in a global object called the UserAgent. However, Odoo 19 implemented an attended transfer in VoIP, creating situations in which two sessions occur simultaneously. For this reason, the asynchronous code should no longer update session properties stored on the global UserAgent, as the session may have changed in the meantime, which could lead to race conditions. This commit moves some logic from the UserAgent to the Session, and ensures all callbacks are properly mapped to the relevant session. Forward-Port-Of: odoo/enterprise#95417
Belgian payroll now includes dedicated records for joint committees and their categories, making employee payroll setup more structured and aligned with local labor classifications. This helps businesses manage Belgian HR payroll information more accurately and consistently across employee records.
Website pages can now be served from a high-level cache when it is safe to do so, reducing page rendering time and database load. The change includes safeguards to avoid caching pages that may contain dynamic or sensitive content, such as session-related sales data.
Original PR description
This commit introduces a high-level cache on the `website.page` model, similar to the one that existed before the `t-cache` directive was implemented in `ir.qweb`. This cache is designed to…
This commit introduces a high-level cache on the `website.page` model, similar to the one that existed before the `t-cache` directive was implemented in `ir.qweb`. This cache is designed to significantly improve performance by storing the HTML response of published pages, thereby reducing rendering time and database queries. The management and logic for this cache are placed directly on the `website.page` model, as it is the source of the HTML response for these records. This approach makes it easy to control caching behavior through a few new, overridable methods: - `_allow_to_use_cache`: Determines whether a page is allowed to be served from the cache based on the current request, URL, or session. For example, a page with a `sale.order` in the session would not use the cache. - `_allow_cache_insertion`: Checks if the generated HTML content is eligible for caching. This is useful for preventing sensitive or dynamic content from being stored. For instance, a page with a reference to a `sale.order` would not be inserted into the cache. - `_post_process_response_from_cache`: A hook called after a response is retrieved from the cache. This method allows for post-processing, such as incrementing counters or modifying HTTP headers, without regenerating the entire page. see https://github.com/odoo/odoo/pull/224487 see https://github.com/odoo/odoo/pull/88276 Forward-Port-Of: odoo/enterprise#94487
Changing a folder so it is not discoverable no longer automatically makes all documents inside require a direct link. This keeps folder-level visibility choices from unexpectedly restricting access to individual files, reducing confusion for users managing shared documents.
Original PR description
Changing the discoverability to not propagate to its children. Previously setting a folder to Discoverable to 'No' would result in all the files also requiring a link to access them, which is unwanted behaviour. Task-4996667 Forward-Port-Of: odoo/enterprise#93697
Resolved issues and error corrections
Romanian SAF-T reporting now correctly identifies partners as customers or suppliers even when their balance is zero, avoiding validation errors in required tax submissions. The change also prevents empty-value ledger lines from being reported while keeping related source documents included, improving compliance and report accuracy.
Original PR description
We need to know for each partner if it is a customer or a supplier, even more for Romania[^1] where it is enfored and validated. > 1. If the element SD.P.22 CustomerID is reported with value ”0”…
We need to know for each partner if it is a customer or a supplier, even more for Romania[^1] where it is enfored and validated. > 1. If the element SD.P.22 CustomerID is reported with value ”0” (zero), then the element SD.P.23 SupplierID must be different from ”0” (zero), meaning the identity of the partner from which the purchase was made (conventionally considered ”supplier”) is reported. Else if SD.P.22 CustomerID AND SD.P.23 SupplierID are concomitantly equal to ”0” (zero), then is return a semantic validation error. (CustomerID and SupplierID can not be concomitantly 0 (zero)) In order to fix this, we don't use the Partner Ledger anymore to query the balance per partner because it is removing the partners with 0 balance automatically. To keep it simple, we query manually and locally, allowing to reduce the number of queries from 3 to 1 for that part. For the performance, the `|=` operator done in a loop has also been removed, keeping the time complexity in `O(n)` instead of `O(n²)`. opw-5122910 [^1]: https://www.anaf.ro/anaf/internet/ANAF/despre_anaf/strategii_anaf/proiecte_digitalizare/saf_t Forward-Port-Of: odoo/enterprise#96355 Forward-Port-Of: odoo/enterprise#95804
This fixes a crash that could occur when validating Register Production/Serial from the shop floor if multiple related quality checks existed. Manufacturing users can now complete production validation without being blocked by an unexpected error.
Original PR description
When user tries to validate Register Production/Serial in shop floor, A traceback will appear. Steps to reproduce the error: - Install ``mrp_workorder`` and ``quality_control`` modules with demo data…
When user tries to validate Register Production/Serial in shop floor, A traceback will appear. Steps to reproduce the error: - Install ``mrp_workorder`` and ``quality_control`` modules with demo data - Go to Quality > Create a new Control point > Product: Table Top > Operations: Manufacturing > Save - Create a new MO > Product: Table Top > Confirm > Shop Floor > Click on Assembly 1 > Click on 3 dots > Update Instructions > Improvement Suggestion > Add a step > Propose Change > Validate - Click on 3 dots > Register Production/Serial > Validate - Go back to MO > Quality Checks > Duplicate the newly created quality check > Shop Floor > Click on Assembly 1 > Click on 3 dots > Register Production/Serial > Validate Traceback: ``ValueError: Expected singleton: quality.check(1, 5)`` https://github.com/odoo/enterprise/blob/5103383df3ddf23503e2c7817c5129a742a7800f/mrp_workorder/models/mrp_workorder.py#L846-L848 When User clicks on the validate, ``current_check`` may include several quality checks without a ``previous_check_id``. The code expects only one record, which causes a traceback. sentry-6839419788 Forward-Port-Of: odoo/enterprise#93624
Payroll users can now generate payslips from a pay run without hitting an error. This fixes a broken field reference introduced after work entry dates were simplified, restoring a key payroll processing step for batches with multiple employees.
Original PR description
Steps to reproduce: - In the Payroll app, go to Pay Runs - Select a pay run with several employees in it - Click on "Generate Payslips" - Get a traceback Reason: The function responsible to generate payslips did not get updated when the fields "date_start" and "date_stop" where replaced by "date" in work entries, causing the error. How it was fixed: Changed "date_start" and "date_end" in the condition to "date" Task ID: 5084666 Forward-Port-Of: odoo/enterprise#94919
Swiss payroll users can once again access Individual Account reports and monthly payroll report menu entries. This restores missing navigation so payroll teams can find and use the expected reports without workarounds.
Original PR description
… menuitems Forward-Port-Of: odoo/enterprise#96162 Forward-Port-Of: odoo/enterprise#95929
Uploaded files added to field service worksheets are now shown correctly when customers view or sign worksheet reports in the portal. This prevents missing attachment information and helps ensure signed reports match the completed worksheet.
Original PR description
Steps to reproduce: ------- - Install industry_fsm_report module - Open FSM app - Select worksheets from settings in the configuration - Go to worksheet templates in the configuration - Create a worksheet template - Click the design template button. You arrive in the studio - Add file field and close it - Create a new task and select a newly created template in the worksheet template - Click the worksheet button in the control panel - Upload a file and save it - Click on the sign report button - Here file field is not visible Issue: ------- The file field is not visible in the worksheet portal. Cause: ------ The view of the file field is not created for the worksheet portal. Solution: ------- Created the view of the file field to display in the worksheet portal. task-3691529 Forward-Port-Of: odoo/enterprise#95970 Forward-Port-Of: odoo/enterprise#56035
Chilean electronic delivery guide XML files now show the quantity actually delivered instead of the quantity originally ordered. This prevents mismatches in official DTE documents when a shipment is partially delivered without a backorder.
Original PR description
**Issue** When the delivered quantity of a product is less than the originally demanded quantity, the generated Delivery Guide XML shows the demand (product_uom_qty) instead of the actual delivered…
**Issue** When the delivered quantity of a product is less than the originally demanded quantity, the generated Delivery Guide XML shows the demand (product_uom_qty) instead of the actual delivered quantity (quantity). This results in an incorrect quantity being displayed in the DTE. **Steps to Reproduce** 1. Install the Accounting module, Chilean localization, Sales module, and l10n_cl_edi_stock. 2. Create and confirm a new Sale Order. 3. Click on the Delivery smart button. 4. Adjust the delivered quantity to a value lower than the demand, save, and validate with no backorder. 5. Generate the Delivery Guide. 6. Open the generated DTE XML and observe that the quantity is incorrect. **Root Cause** The quantity displayed in the DTE is taken from product_uom_qty, which represents the planned quantity to be moved, not the actual delivered quantity. The correct field to use is quantity, which reflects the real delivered amount. **Fix** Change the XML output to use quantity instead of product_uom_qty to accurately reflect the actual delivered quantity in the DTE. Opw-4892276 Forward-Port-Of: odoo/enterprise#93260 Forward-Port-Of: odoo/enterprise#89633
German PoS payments are now sent to Fiskaly in the required format, preventing payment validation errors. The update also avoids creating unnecessary zero-value payment lines caused by rounding when multiple decimal payments use the same method.
Original PR description
This ticket fixes two bugs: ### Problem 1 Fiskaly requires `amounts_per_payment_type` values to be strings with 2 to 5 decimal places. After this PR: https://github.com/odoo/enterprise/pull/83300, amounts started being sent as numbers, which caused bad request error when paying a PoS order in version 19.0. ### Solution 1: Restore the use of `.toFixed(2)` to ensure amounts are sent as strings. ### Problem 2 When adding two payment lines with decimal amounts using the same payment method, the system merges both payments into a single line by adding the second amount to the first. This can cause a rounding difference and may trigger sending an additional payment line to Fiskaly with a 0.00 amount. ### Solution 2: Check if rounded change is zero before creating the change line. opw-5115157 Forward-Port-Of: odoo/enterprise#96020