Monday, August 18, 2025
21 changes · saas-18.3
Enhancements to existing features
The Belgian Annual Accounts export from the General Ledger now produces an XML file instead of a fixed-format TXT file. This better matches official formatting expectations and supports richer information such as account balances, multilingual descriptions, and metadata for downstream processing.
Original PR description
The previous Annual Accounts export in the General Ledger generated a TXT file with a fixed column order, which did not meet the structural or formatting requirements for downstream usage. This commit replaces the TXT export with an XML export conforming to the official format, including fields such as account code, debit, credit, multilingual descriptions, and metadata. task-5005345 Forward-Port-Of: odoo/enterprise#92326 Forward-Port-Of: odoo/enterprise#92071
Resolved issues and error corrections
Fixes an issue where clicking repair data in the Inventory dashboard could show an error instead of the expected repair orders. The repair search now uses the correct date information and handles multiple date categories properly, making dashboard navigation reliable again.
Original PR description
The _search_date_category method was using the incorrect field 'scheduled_date' instead of 'schedule_date', which broke the domain logic. This commit also wraps individual domain clauses in an expression.OR(...) to ensure proper filtering across multiple date categories, in line with the updated ORM search behavior (task-4150178). Caused by: https://github.com/odoo/odoo/commit/92301a5b300dec1ddfca44dc35318b83d67c56fa This fix aligns `_search_date_category` logic in repair to match what is done in mrp & stock. https://github.com/user-attachments/assets/e45791c3-feaf-4d52-9f63-6ff43fb84ca8 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This change reverts a recent sales update that could cause rental order creation to crash when pricing information was missing or inconsistent. It restores the affected flow so hotel rental demonstrations and related planning-to-sales processes can continue reliably.
Original PR description
"line.currency_id" might be empty or contain more than 1 value, resulting in a crash of the method. This reverts commit ced1335c38834d5ac31f27705a2f7a0047ca8cc2. Traceback discovered when creating a rental order from a resource (planning flow). <img width="1607" height="907" alt="image" src="https://github.com/user-attachments/assets/0980b89b-fc2a-4bfe-a4c7-a290c92bb0e4" /> Quick revert needed to unblock the flow and allow a demo of hotel industry rentals. Forward-Port-Of: odoo/odoo#222826
The Point of Sale now calculates taxes for negative order lines the same way as the backend. This prevents mismatched totals and helps avoid accounting entries becoming unbalanced when refunds or negative lines are involved.
Original PR description
Before this commit, when an order contained a negative line, the backend treated it as a refund line while the POS UI did not. This mismatch caused inconsistent tax calculations between the UI and the backend, which could result in unbalanced journal entries. With this commit, the tax calculation logic is aligned between the UI and the backend, ensuring consistency and preventing unbalanced moves. opw-4972314 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#222918 Forward-Port-Of: odoo/odoo#222632
This update fixes several issues with the color selector in Odoo's HTML editor. The color picker now hides correctly when the toolbar scrolls out of view, handles unsupported gradient colors safely, and replaces fully selected gradients only when the matching text or background color is changed.
Original PR description
**Current behavior before PR:** **Issue 1:** - Have a long text content in editable, making the container scrollable. - Select first line of the text, in toolbar open color selector. - Scroll down…
**Current behavior before PR:** **Issue 1:** - Have a long text content in editable, making the container scrollable. - Select first line of the text, in toolbar open color selector. - Scroll down until the toolbar overflows and becomes hidden. - Notice that the toolbar disappears when it overflows its container while color picker remains open, floating at the top of container. **Issue 2:** - Select a text having gradient text color. - Open text color selector, switch to custom color picker. - Notice that hex and rgba fields are empty and user is not able to apply color through it. In colorpicker.js, the convertCSSColorToRgba method fails when attempting to convert a gradient color to RGBA. As a result, colorComponents does not receive valid values and colorpicker doesn't work as expected. **Issue 3:** After merging commit [1], text color can be applied without removing or affecting the existing gradient color. In result, if gradient is fully selected then applying text color creates a new font tag inside gradient instead of replacing the gradient. **Desired behavior after PR:** **Issue 1:** Now, when the toolbar overflows and gets hidden, the color selector becomes hidden along with toolbar. **Issue 2:** Now, if `convertCSSColorToRgba` fails to convert selected color to rgba color then default color `#FF0000`is assigned to color components. This ensures that the colorpicker functions correctly. **Issue 3:** Now, if gradient is fully selected then, - Applying text color removes existing text gradient. - Applying background color removes existing background gradient. - Applying text color doen't remove the existing background gradient. - Applying background color doesn't remove the existing text gradient. [1]: https://github.com/odoo/odoo/commit/938995744b15f345958a2d78a6c844dd5bf1ae6c Enterprise PR: https://github.com/odoo/enterprise/pull/84579 task-4581884 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#219508 Forward-Port-Of: odoo/odoo#202889
This update brings the spreadsheet component to the latest maintenance version and fixes issues affecting pivot measures, formula recalculation, and clickable cells. Business users should see more reliable spreadsheet reports and interactions, with fewer incorrect results or missed updates.
Original PR description
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/68ef49703 [REL] 18.3.16 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0)…
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/68ef49703 [REL] 18.3.16 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/9a22c13bd [FIX] Pivot: sanitize measure id [Task: 4876828](https://www.odoo.com/odoo/2328/tasks/4876828) https://github.com/odoo/o-spreadsheet/commit/b518d5b2a [FIX] Functions: OFFSET dependencies are not correctly added [Task: 5001405](https://www.odoo.com/odoo/2328/tasks/5001405) https://github.com/odoo/o-spreadsheet/commit/fcf912e5b [FIX] ClickableCells: cache empty positions as well [Task: 5007745](https://www.odoo.com/odoo/2328/tasks/5007745) Co-authored-by: Anthony Hendrickx (anhe) <anhe@odoo.com> Co-authored-by: Alexis Lacroix (laa) <laa@odoo.com> Co-authored-by: Lucas Lefèvre (lul) <lul@odoo.com> Co-authored-by: Dhrutik Patel (dhrp) <dhrp@odoo.com> Co-authored-by: Adrien Minne (adrm) <adrm@odoo.com> Co-authored-by: Ronak Mukeshbhai Bharadiya <rmbh@odoo.com> Co-authored-by: Florian Damhaut (flda) <flda@odoo.com> Co-authored-by: Rémi Rahir (rar) <rar@odoo.com> Co-authored-by: Pierre Rousseau (pro) <pro@odoo.com> Co-authored-by: Vincent Schippefilt (vsc) <vsc@odoo.com>
This change prevents an access error that could appear when a returning visitor used live chat after switching between guest and logged-in sessions. Live chat conversations are now correctly linked to the visitor record, helping keep chat history consistent and avoiding interruptions on tracked website pages.
Original PR description
When a new website.visitor is created while a guest is set in the context, livechat channels of the related guest need to be updated to link the newly created visitor. Before this PR, the update caused an access error because the public user does not have permission to update channel records. Steps to reproduce: - Go to a tracked page (e.g., /contactus) and start a livechat as a guest, then end it. - Log in as a user, go to a tracked page, start a livechat, then end it. - Log out and go to a tracked page -> an access error occurs. This PR uses sudo to allow updating channels, as guests can access their own channels. task-[4891195](https://www.odoo.com/odoo/project/1519/tasks/4891195)
Purchase catalog prices now convert vendor prices into the purchase order currency. This prevents mismatched product prices when buyers use vendors and orders with different currencies, improving quote accuracy.
Original PR description
Before this commit, the unit price in the catalog for purchase order wasn't converted from other currencies to the order one It was just set to the price regardless of the vendor currency This fix will automatically convert the catalog prices from seller's currency to purchase.order's currency Steps to reproduce: - Create a product to Purchase - Add a vendor in the Purchase Tab - Set quantity to 1, price to 100 and currency to EUR - Create a RFQ - Select the Vendor from the product created - Check to currency to be USD - Add the product and take note of the Unit Price - Remove the product line - Go to Catalog - Compare the Price with the Unit Price (They doesn't match before the fix) opw-4909789 Forward-Port-Of: odoo/odoo#217285
This fix ensures work entries for employees on flexible schedules calculate partial-day attendance gaps correctly, including on public holidays. It prevents those gaps from being incorrectly recorded as a full 8-hour duration, improving payroll and time-off accuracy.
Original PR description
### Steps to reproduce: - Set Marc Demo's contract work entry source to attendances and working schedule to flexible hours. - Create a public holiday with generic time off work entry type. - Create…
### Steps to reproduce: - Set Marc Demo's contract work entry source to attendances and working schedule to flexible hours. - Create a public holiday with generic time off work entry type. - Create one or multiple attendances for marc demo on the public holiday. - Regenerate work entries for marc demo for that day, the gaps in between the attendances created and the working hours will be filled with work entries with the right start/end time but duration will always be 8h. ### Cause: This is happening because when getting the duration batch for the work entry we get the attendance intervals the employee should work in that period and if the employee is flexible we will get a fake attendance with the number of hours required per day ignoring if the period is just a small period of the day ### Fix: We are checking now since the start date not monday so we don't set a fixed week start. We check if the period is less than the remaining hours we get it as it mostly means that it is less than one day opw-4887933 Forward-Port-Of: odoo/odoo#218823
Regular users can now update settings on recurring calendar events without encountering an access error. This prevents disruption when managing repeated meetings with reminders and keeps calendar workflows reliable for non-admin staff.
Original PR description
**Issue:** An access error occurs when a non-admin user attempts to modify the meeting settings of a recurring calendar event. **Steps to reproduce:** - Log in as non admin user - Go to Calendar > Create new meeting. - Set Reminders - Check the Recurrent checkbox and save the event. - Edit the Recurring Event settings and save again (2–3 times) An access error is raised as non admin users aren't allowed to read ir.cron.trigger opw-4899572 Forward-Port-Of: odoo/odoo#222855
Manufacturing users can now generate serial and lot numbers from the shop floor without hitting an error or seeing missing generated lines. The fix ensures the needed quantity is available during generation and that newly generated lots are reflected correctly in the manufacturing details view.
Original PR description
**Steps to Reproduce :** 1. Install MRP. 2. Create a Bill of Materials (BOM) and add a component with lot tracking. 3. Create and confirm a Manufacturing Order (MO) with BOM. 4. Navigate to the shop…
**Steps to Reproduce :** 1. Install MRP. 2. Create a Bill of Materials (BOM) and add a component with lot tracking. 3. Create and confirm a Manufacturing Order (MO) with BOM. 4. Navigate to the shop floor and click on Generate Serials/Lots. 5. The error appears when trying to generate the lot . **Issue :** Error raised when try to Generate Serials/Lots during the manufacturing process. `TypeError: unsupported operand type(s) for //: 'NoneType' and 'int'` **Cause:** This error occurs because the quantity field is undefined when Generate Serials/Lots is triggered, the quantity field is not being passed in the context, and its value is undefined, which is leading to a division by [none](https://github.com/odoo/odoo/blob/18.0/addons/stock/models/stock_move.py#L993). **Solution:** To fix this, we added the stock move’s demand quantity as a fallback.This ensures the quantity field value is present and its value correctly passed during lot generation. opw-4763600 Enterprise: https://github.com/odoo/enterprise/pull/88739 Forward-Port-Of: odoo/odoo#220303 Forward-Port-Of: odoo/odoo#209860
Point of Sale now automatically matches customer account charges with the corresponding settlement payments. This prevents settled POS account amounts from incorrectly appearing as available credit for other invoices, reducing accounting confusion for customers and staff.
Original PR description
### Problem: When paying a PoS order using customer account, an account move line debiting Account Receivable will be created. Settling this amount inside the PoS (by depositing money) will create…
### Problem:
When paying a PoS order using customer account, an account move line debiting Account Receivable will be created. Settling this amount inside the PoS (by depositing money) will create another account move line crediting Account Receivable (represents the payment). The second move line is considered, by Odoo, as an outstanding amount, and this amount can be used to pay another invoice (sale order invoice). The moves affecting Account Receivable are still correct. However, unreconciling the two lines created from PoS will cause a confusion for clients who may use this amount to pay other invoices.
### How to reproduce:
* Open a PoS session.
* Create an order and pay using customer account.
* Settle this customer's account (inside PoS).
* Create a Sale Order and invoice it (or just an invoice).
* The amount settled can be used as outstanding amount and can be used to pay the created invoice.
enterprise PR: https://github.com/odoo/enterprise/pull/86114
opw-4794793
Forward-Port-Of: odoo/odoo#210619Manufacturing users can now stop work order operations even when the task takes longer than expected and creates or updates billable time entries. This prevents an access error for users without accounting permissions, keeping production and project billing flows uninterrupted.
Original PR description
To reproduce:
=============
- create a BOM with an operation having an expected duration
- make sure the product of BOM has MTO and Manufacturing routes
- create a Billable project with visibility=portal
- create an SO with the product of BOM and set the project for analytic distribution
- confirm the SO -> a MO is created
- with a user having:
- hr.group_hr_user
- mrp.group_mrp_manager
- project.group_project_user
- hr_timesheet.group_hr_timesheet_approver
- go to the MO and start the first operation and wait to exceed the expected duration
- stop the operation -> access error on the analytic account line
Problem:
========
when the user tries to stop the operation, at first moment AAL will be created, as we exceed the expected duration, we will try to update the AAL which leads to an access error as the user does not have accounting rights.
Solution:
=========
deal with AAL records as sudo
opw-4897142
Forward-Port-Of: odoo/enterprise#92422Expense digitization now correctly replaces default “Untitled Expense” names with the name detected by OCR. This helps users receive properly labeled expense records after uploading receipts, reducing manual corrections.
Original PR description
The combination of the following recent changes prevented the OCR from filling the name of the expense: - New expenses are named "Untitled Expense {date}" by default instead of the name of the…
The combination of the following recent changes prevented the OCR from filling the name of the expense:
- New expenses are named "Untitled Expense {date}" by default instead of the name of the attachment (see commit odoo/odoo@ca1f644).
- The OCR doesn't override the name if it's not set to the default value (see commit 5c813dc).
The first commit didn't update the default expense name that was used in the OCR code, it was still computed from the attachment name.
After the second commit, the OCR couldn't fill in the name of the expense anymore, since it was expecting the name to be the attachment name, but it was "Untitled Expense {date}" instead.
This is fixed by checking that the expense name contains "Untitled Expense" (and taking translation into consideration).
This commit also improves the tests in multiple ways:
- For the `test_auto_send_for_digitization` test, it now mimicks an upload of the document to force the creation of the expense with the default name, this should prevent this from happening again.
- It now uses an actual PDF document instead of "fake" attachments.
- Minor clean up.
task-[4684825](https://www.odoo.com/odoo/project/967/tasks/4684825)This fixes an issue where grouped accounting report lines did not collapse correctly and could trigger an error when users folded or unfolded partner-level rows. The change helps users navigate custom financial reports reliably without duplicate line errors interrupting their workflow.
Original PR description
Steps to reproduce: - Create an Account Group - Create a new Account Report as follows: * Name: any * Lines: 1. [test line] * Group By: partner_id,account_id * Expressions: 1. [test expression] *…
Steps to reproduce:
- Create an Account Group
- Create a new Account Report as follows:
* Name: any
* Lines:
1. [test line]
* Group By: partner_id,account_id
* Expressions:
1. [test expression]
* Computation Engine: Odoo Domain
* Formula: [('account_id.account_type', '=', 'asset_receivable')]
* Subformula: sum
- Actions > Create Menu Item
- Open the new report
- Try to unfold/fold a partner line
Issue:
Folding will not fold the first child (representing the created account group). Also, error will raise
```
Uncaught Promise > Got duplicate key in t-foreach: ~account.report~37|~account.report.line~255|{'groupby': 'partner_id'}~res.partner~4226|~account.group~90
Occured on odoo.nas.cpolar.cn on 2025-04-26 04:58:53 GMT
OwlError: Got duplicate key in t-foreach: ~account.report~37|~account.report.line~255|{'groupby': 'partner_id'}~res.partner~4226|~account.group~90
Error: Got duplicate key in t-foreach: ~account.report~37|~account.report.line~255|{'groupby': 'partner_id'}~res.partner~4226|~account.group~90
at AccountReport.template (eval at compile (https://odoo.nas.cpolar.cn/web/assets/debug/web.assets_web.js:13743:20), <anonymous>:138:49) (/web/static/lib/owl/owl.js:5752)
at App.callTemplate (https://odoo.nas.cpolar.cn/web/assets/debug/web.assets_web.js:11363:50) (/web/static/lib/owl/owl.js:3372)
at AccountReport.template (eval at compile (https://odoo.nas.cpolar.cn/web/assets/debug/web.assets_web.js:13743:20), <anonymous>:9:12) (/web/static/lib/owl/owl.js:5752)
at RootFiber._render (https://odoo.nas.cpolar.cn/web/assets/debug/web.assets_web.js:9774:38) (/web/static/lib/owl/owl.js:1783)
at RootFiber.render (https://odoo.nas.cpolar.cn/web/assets/debug/web.assets_web.js:9766:18) (/web/static/lib/owl/owl.js:1775)
at ComponentNode.render (https://odoo.nas.cpolar.cn/web/assets/debug/web.assets_web.js:10493:23) (/web/static/lib/owl/owl.js:2502)
```
Analysis:
Folding issues occurs because of a mismatch in the grouping markup quote escape. If we don't have the very same string the controller cannot properly recognize the parent line and then is unable to fold/unfold properly.
This eventually led to the mentioned error at unfold as the backend will try to generate the apparently missing lines to unfold, only to create duplicate lines
opw-4754241
Forward-Port-Of: odoo/enterprise#89726Fixes an issue where flexible-schedule employees could receive incorrect 8-hour work entry durations for short gaps on public holidays. Work entries now calculate attendance periods from the actual start time, improving payroll and attendance accuracy.
Original PR description
### Steps to reproduce: - Set Marc Demo's contract work entry source to attendances and working schedule to flexible hours. - Create a public holiday with generic time off work entry type. - Create…
### Steps to reproduce: - Set Marc Demo's contract work entry source to attendances and working schedule to flexible hours. - Create a public holiday with generic time off work entry type. - Create one or multiple attendances for marc demo on the public holiday. - Regenerate work entries for marc demo for that day, the gaps in between the attendances created and the working hours will be filled with work entries with the right start/end time but duration will always be 8h. ### Cause: This is happening because when getting the duration batch for the work entry we get the attendance intervals the employee should work in that period and if the employee is flexible we will get a fake attendance with the number of hours required per day ignoring if the period is just a small period of the day ### Fix: We are checking now since the start date not monday so we don't set a fixed week start. We check if the period is less than the remaining hours we get it as it mostly means that it is less than one day opw-4887933 Forward-Port-Of: odoo/enterprise#90163
DHL shipping rate checks during online checkout now use a planned date in the future, matching DHL's requirements. This prevents customers from seeing rate errors caused by the default order time being too close to the current time.
Original PR description
Before this commit: During checkout on Ecommerce website the default date of the order is current date and time. There is no option to change the date when getting rate. Which results in an error that the date must be in the future. After this commit: `Planned_date` for getting rate is set in furture to avoid the error. Docs reference: https://developer.dhl.com/api-reference/dhl-express-mydhl-api#reference-docs-section under rating endpoints. opw-4849754 Forward-Port-Of: odoo/enterprise#91705
Restaurant floor plans now show only appointments scheduled for the current day, preventing future bookings from appearing at the wrong time. Late customer appointments are also highlighted correctly, helping staff spot delays more easily.
Original PR description
Steps to reproduce: =================== 1. Install `pos_restaurant_appointment`. 2. From the Appointments menu, schedule an appointment for tomorrow for a table. 3. Open the restaurant floor plan. Issue 1: ======== - Appointments scheduled for tomorrow are incorrectly shown on the floor plan. Issue 2: ======== - When a customer is late, the appointment label is not displayed in red. Common Cause: ============= - The appointment's `start` field is already a `DateTime` object, but it is being deserialized again, which leads to incorrect time-based comparisons. Fix: ==== - Avoid deserializing the `start` field if it is already a `DateTime` object. Task: 4845006 Forward-Port-Of: odoo/enterprise#86997
Rental sales invoice lines are now excluded from automatic cost-of-goods-sold entries. This prevents rental orders from creating incorrect accounting costs, improving the accuracy of financial reports.
Original PR description
…entries Modified the COGS generation logic to skip any invoice lines that come from a rental sales order. task-4919306 Forward-Port-Of: odoo/enterprise#91347 Forward-Port-Of: odoo/enterprise#90901
Manufacturing users can now generate serial or lot numbers from the shop floor without errors or missing lines. The fix uses the expected demand quantity when needed and ensures generated lots appear correctly in detailed operations, reducing interruptions during production processing.
Original PR description
This [PR](https://github.com/odoo/odoo/pull/209860) adds a fallback to product_uom_qty when the quantity field is not present during serial/lot generation from the shop floor. Includes a tour and…
This [PR](https://github.com/odoo/odoo/pull/209860) adds a fallback to product_uom_qty when the quantity field is not present during serial/lot generation from the shop floor. Includes a tour and test case in mrp_workorder to validate the fix. **Steps to Reproduce :** 1. Install MRP. 2. Create a Bill of Materials (BOM) and add a component with lot tracking. 3. Create and confirm a Manufacturing Order (MO) with BOM. 4. Navigate to the shop floor and click on Generate Serials/Lots. 5. The error appears when trying to generate the lot . **Issue :** Error raised when try to Generate Serials/Lots during the manufacturing process. `TypeError: unsupported operand type(s) for //: 'NoneType' and 'int'` **Cause:** This error occurs because the quantity field is undefined when Generate Serials/Lots is triggered, the quantity field is not being passed in the context, and its value is undefined, which is leading to a division by [none](https://github.com/odoo/odoo/blob/18.0/addons/stock/models/stock_move.py#L993). **Solution:** To fix this, we added the stock move’s demand quantity as a fallback.This ensures the quantity field value is present and its value correctly passed during lot generation. opw-4763600 Community: https://github.com/odoo/odoo/pull/209860 Forward-Port-Of: odoo/enterprise#90879 Forward-Port-Of: odoo/enterprise#88739
Settled Point of Sale customer account payments are now automatically matched with the original receivable entry. This prevents the settled amount from incorrectly appearing as available credit for other invoices, reducing customer account confusion.
Original PR description
### Problem: When paying a PoS order using customer account, an account move line debiting Account Receivable will be created. Settling this amount inside the PoS (by depositing money) will create…
### Problem:
When paying a PoS order using customer account, an account move line debiting Account Receivable will be created. Settling this amount inside the PoS (by depositing money) will create another account move line crediting Account Receivable (represents the payment). The second move line is considered, by Odoo, as an outstanding amount, and this amount can be used to pay another invoice (sale order invoice). The moves affecting Account Receivable are still correct. However, unreconciling the two lines created from PoS will cause a confusion for clients who may use this amount to pay other invoices.
### How to reproduce:
* Open a PoS session.
* Create an order and pay using customer account.
* Settle this customer's account (inside PoS).
* Create a Sale Order and invoice it (or just an invoice).
* The amount settled can be used as outstanding amount and can be used to pay the created invoice.
commmunity PR: https://github.com/odoo/odoo/pull/210619#pullrequestreview-2853451890
opw-4794793
Forward-Port-Of: odoo/enterprise#86114