Daily updates from Odoo
Monday, October 6, 2025
23 changes · saas-18.3
Resolved issues and error corrections
Payroll document generation now skips payslips when the related employee contact is missing. This prevents scheduled PDF creation from failing and helps keep payroll document processing running smoothly.
Original PR description
Currently an error occurs when the **'Payroll: Generate pdfs'** scheduled action runs and tries to create a document for a payslip belonging to an employee who does not have a related partner.…
Currently an error occurs when the **'Payroll: Generate pdfs'** scheduled action runs and tries to create a document for a payslip belonging to an employee who does not have a related partner. **Prerequisites:** - Ensure HR is enabled in `settings>Documents` **Steps to Reproduce:** 1) Install `documents_hr_payroll` module.(with Demo) 2) Navigate to the Employees App. 3) Select any Employee(e.g Abigail Peterson) and open form view. >- click on **contacts** smart button. >- Delete that Record 4) Create a confirmed Payslip for the selected Employee(e.g Abigail Peterson). 5) Activate Developer mode and navigate to schedule Actions. >- Search for 'Payroll: Generate pdfs'. >- Run Manually. Error: `NotNullViolation: null value in column 'partner_id' of relation 'documents_access' violates not-null constraint` Root Cause: When the partner is deleted, the value received from `_get_document_partner` at [1] is `False`, which later on tries to create the `documents.access` record for the new document, it fails because no partner is available to assign access rights, resulting in the error. Solution: This commit prevent Error by ensuring `_check_create_documents` method doesn't allow document creation without valid partner. [1]: https://github.com/odoo/enterprise/blob/99a8d83edb42f172d0dd35c91743fa0c9653dcbb/documents_hr_payroll/models/hr_payslip.py#L20C1-L21 sentry-6814524392 Forward-Port-Of: odoo/enterprise#92865
This fix ensures background scheduled tasks refresh their internal app data after a module is uninstalled. It prevents worker processes from crashing when they try to use outdated fields from an app that has just been removed.
Original PR description
**step to reproduce:** - start a database with worker, use `--max-cron-thread=1 --workers=2` - Add a sample cron, which runs every minute(just so that we can see the status) - install helpdesk -…
**step to reproduce:**
- start a database with worker, use `--max-cron-thread=1 --workers=2`
- Add a sample cron, which runs every minute(just so that we can see the status)
- install helpdesk
- uninstall helpdesk
**Observation**
- traceback in console
```
2025-09-25 06:07:26,389 18450 ERROR ? odoo.service.server: Worker WorkerCron (18450) Exception occurred, exiting...
Traceback (most recent call last):
File "/home/odoo/odoo/codebase/odoo/17.0/odoo/service/server.py", line 1171, in _runloop
self.process_work()
File "/home/odoo/odoo/codebase/odoo/17.0/odoo/service/server.py", line 1270, in process_work
base.models.ir_cron.ir_cron._process_jobs(db_name)
File "/home/odoo/odoo/codebase/odoo/17.0/odoo/addons/base/models/ir_cron.py", line 139, in _process_jobs
registry[cls._name]._process_job(db, cron_cr, job)
File "/home/odoo/odoo/codebase/odoo/17.0/odoo/addons/base/models/ir_cron.py", line 331, in _process_job
now = fields.Datetime.context_timestamp(ir_cron, datetime.utcnow())
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
....
....
File "/home/odoo/odoo/codebase/odoo/17.0/odoo/models.py", line 3873, in fetch
fetched = self._fetch_query(query, fields_to_fetch)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/odoo/codebase/odoo/17.0/odoo/addons/base/models/res_users.py", line 546, in _fetch_query
records = super()._fetch_query(query, fields)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/odoo/codebase/odoo/17.0/odoo/models.py", line 3965, in _fetch_query
self.env.cr.execute(query.select(*sql_terms))
File "/home/odoo/odoo/codebase/odoo/17.0/odoo/sql_db.py", line 335, in execute
res = self._obj.execute(query, params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
psycopg2.errors.UndefinedColumn: column res_users.helpdesk_target_closed does not exist
LINE 1: ...s"."odoobot_state", "res_users"."odoobot_failed", "res_users...
```
Issue:
- traceback occurred, as the system is try to fetch fields related to helpdesk module
which do not exists now after uninstalling it.
- cron in case of workers, use daemon threads [1]
- the uninstalled happened with main thread and registry is updated.
- the daemon thread is unaware of this change.
- the `_process_jobs` uses the registry, without checking if it needs reload
[1]: https://github.com/odoo/odoo/blob/e82fdfaf621f45515b92c891334595250accbfbd/odoo/service/server.py#L582-L587
FIx:
- when assigning the registry, we check if needs a reload or not.
opw-5062313
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#229556
Forward-Port-Of: odoo/odoo#228515This fixes a crash that could happen when users removed certain calendar settings, such as the color field, in Odoo Studio. Empty values are now handled correctly, allowing users to edit views without interruption.
Original PR description
On a calendar with studio, try to remove the "color" attribute, or any other that should contain the name of a field. Before this commit there was a crash because the value sent to the server in this case is `undefined` (`null` in JSON or `None` in python), which was stringified and yielding an actual string that was not a field name After this commit, NULL values are not stringified, instead they should represent the emptiness of the attribute. opw-4938351 Forward-Port-Of: odoo/enterprise#95439
The Automation Rules trigger dropdown now uses the correct background color when dark mode is enabled. This improves visual consistency and readability for users configuring automation rules in dark mode.
Original PR description
Steps: - Install `base_automation` - Enable dark mode - Open Automation rules - Create a new rule - open trigger dropdown - the dropdown background is still in light mode This commit apply $dropdown-bg on `o_field_base_automation_trigger_selection` opw-5064357 Forward-Port-Of: odoo/odoo#226666 Forward-Port-Of: odoo/odoo#226116
This fix changes how receipt or report data is passed so existing customizations keep working after the recent IoT update. Businesses benefit from fewer errors in IoT-connected flows, especially point-of-sale printing or document sending, without changing user behavior.
Original PR description
Following commit https://github.com/odoo/enterprise/commit/ecea27f45ab58ae6f348753d94fdf89f902a43b9, the argument `data_base64` was added to the `render_and_send` function. However, adding new arguments in stable versions is not allowed, as it may break custom modules that override this function and do not expect the additional argument. This commit ensures that `data_base64` is passed through the context instead, preventing errors while keeping compatibility with existing overrides. opw-data_base64 Forward-Port-Of: odoo/enterprise#96244
Publishing planning shifts now keeps the filters users selected in the schedule view, such as a specific role, while still applying the chosen date range. This prevents unintended shifts outside the selected criteria from being published or sent, improving accuracy for planners.
Original PR description
To reproduce: ============= -Reset all planning.slot to draft -Search "Dev" role -In weekly Gantt view, click on publish & send -Change date to match the current month (or any other period) -Publish Problem: ========= We filter only by datetime and ignore domain from context : https://github.com/odoo/enterprise/blob/20b45f6c65c78a572a3f26b78f6ed458accf7c9f/planning/wizard/planning_send.py#L31-L33 Solution: ========= - Get active domain from context and override only it's date_time since it changed. opw-5017014 Forward-Port-Of: odoo/enterprise#93295
This fix prevents an error when shoppers use the browser back button immediately after starting payment and then try to pay again from the cart. It helps keep checkout stable in this edge case, avoiding a disruptive crash during payment retry.
Original PR description
This error occurs when trying to make a payment again from the cart. Steps to reproduce: --- - Install the **website_sale** module (with demo) - Activate **Demo** payment provider - Go to Website > Shop > Add a **Warranty** product to Cart > View cart - Pay with Demo > Pay - Click the back button(chrome navbar)(Instantly) - Now again Pay with Demo > Pay Traceback: --- `ValueError: Expected singleton: sale.order()` At [1], this error occurs because **order_sudo** is empty. This happens when there is no product in the cart — typically because, upon clicking **Pay**, a sale order is created for the product, and when the user navigates back, the cart is empty. [1]- https://github.com/odoo/odoo/blob/125fc3028debb311e9f6ad25d8c46699b77525f0/addons/website_sale/controllers/main.py#L1307-L1312 sentry-5682671428 Forward-Port-Of: odoo/odoo#229858
Creating a down payment invoice for an Indian sales quotation with a reseller no longer fails. This prevents invoice creation from being blocked and helps sales teams continue billing normally when reseller information is present.
Original PR description
**Issue** When creating a down payment invoice for a quotation that includes a reseller, an error is raised and the operation is aborted. **Steps to Reproduce** 1. Install Accounting, Studio, and…
**Issue** When creating a down payment invoice for a quotation that includes a reseller, an error is raised and the operation is aborted. **Steps to Reproduce** 1. Install Accounting, Studio, and l10n_in_sale 2. Open the Quotation view in Studio 3. Set the "Referrer" field (i.e., l10n_in_reseller_partner_id) to be always visible and remove group restrictions 4. Create a new quotation and set a reseller in the Referrer field 5. Confirm the quotation 6. Click "Create Invoice" 7. Choose "Down Payment (percentage)" with 10% 8. Click "Create Draft" **Root Cause** The `_prepare_invoice_values()` method was assigning the full `res.partner` record to the `l10n_in_reseller_partner_id` field instead of its ID. Since the `account.move` model expects an integer ID for many2one fields, this caused a `psycopg2.ProgrammingError` due to the database adapter not being able to serialize a recordset. **Fix** Ensure the value passed to l10n_in_reseller_partner_id is the .id of the partner record, not the recordset itself. Opw-4899919 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#222324 Forward-Port-Of: odoo/odoo#220354
Cancelled manufacturing work orders will no longer be assigned an expected duration when backorders are created. This avoids overstating production time and helps keep manufacturing cost calculations consistent.
Original PR description
### Issue: In this bug, the workorder duration being set to duration_expected is causing issues in backorder. To reproduce: 1- Create a Bill of Materials with at least two operations at two work…
### Issue: In this bug, the workorder duration being set to duration_expected is causing issues in backorder. To reproduce: 1- Create a Bill of Materials with at least two operations at two work centers 2- Create a manufacturing order and confirm it. 3- Complete the first operation and edit the quantity on the second operation so there is a backorder for the remaining quantity. 4- In the second work order, the first operation is cancelled, Finish the 2nd operation 5- As you can see, the cancelled operation duration is set to expected duration which is wrong. ### Cause: This issue is caused because of: https://github.com/odoo/odoo/blob/8f0e40286da7b144bfa17880a257406dd8585e57/addons/mrp/models/mrp_production.py#L1774-L1779 Which if work.order.state is `cancel`, the duration will set to `duration_expected`. This will eventually cause issue here: https://github.com/odoo/odoo/pull/222075/commits/8f0e40286da7b144bfa17880a257406dd8585e57#diff-fac872ffb03b811c4976eb2e52991ec544265332df814d92cfda658a5b917423L348 which is fixed by not making the state into `progres` if the state is `cancel`. But that doesn't fix the fact that the cancelled workorder has duration set and it might cause inconsistencies in manufacturing costs. related: #222075 opw-4931653 Forward-Port-Of: odoo/odoo#229742
The ChatGPT plugin chat window now appears above modal windows instead of being hidden behind them. This restores usability when users open the chat from within dialogs, avoiding confusion and interrupted workflows.
Original PR description
This PR fixes an issue with the chatgpt plugin where the chat window was rendered beneath the modal, making it unusable. The fix modifies the z-index of modal windows when the `openDialog` function of the chatgpt plugin is called.
This fix updates the live chat test environment so it includes the same user availability status information as the real server. It helps ensure automated tests better reflect actual behavior, reducing the risk of missed issues in live chat features.
Original PR description
**Description of the issue this PR addresses:** Add missing im_status field in mock server **Current behavior before PR:** Previously, the `im_status` field was available on the server side, but it was missing in the mock server implementation used in tests. **Desired behavior after PR is merged:** This PR updates the mock `DiscussChannelMember` model to include `im_status` in the list of stored partner fields, ensuring that test scenarios accurately reflect server behavior. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#229865
This fix lets Spanish TicketBAI credit notes reference original invoices that were issued before the company started using TicketBAI in Odoo. It prevents unnecessary blocking when businesses migrate from a previous invoicing system while still keeping validation for newer invoices.
Original PR description
…re starting to use Tbai 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#225938
Field Service project settings now show the correct label for the timesheet product when a customer is selected. This prevents confusion by hiding the unrelated sales order line label in that context.
Original PR description
Steps to reproduce: - Install the `industry_fsm_sale` module. - Open the FSM app. - Go to Projects. - Open a project’s settings. - Select a customer. Issue: The label for the timesheet product is not displayed. Instead, the label for the sale order line appears on FSM projects. Cause: In the PR, https://github.com/odoo/odoo/pull/128967 changed the project settings form structure by wrapping `sale_line_id` in a `div` and separating its label, breaking the xpath for `timesheet_product_id`. Fix: - Update the XPath for `timesheet_product_id` to target the correct container. - Hide the `sale_line_id` label on FSM projects. task-4581748 Forward-Port-Of: odoo/enterprise#96022
This fixes an automated Mail test so it clicks the enabled button instead of relying on the Enter key being focused at the right moment. The change reduces intermittent test failures and helps keep release validation more stable without changing end-user behavior.
Original PR description
Pressing Enter is prone to race conditions as it requires the proper element to have the focus at the right time. Clicking on the button directly when it is enabled should be preferred. https://runbot.odoo.com/odoo/runbot.build.error/233169 Forward-Port-Of: odoo/odoo#229872
Fixed an issue where replenishment orders could be created with slightly inflated quantities when products used packaging-based multiples, such as ordering 1.02 instead of 1. This helps businesses avoid unnecessary purchasing errors and keeps stock replenishment aligned with the intended packaging quantities.
Original PR description
**Steps to reproduce:** - enable "units of measure & packagings" settings - navigate to "units and packagings" and create a new one called "pack of 2" - set a quantity of 2 and the reference unit as…
**Steps to reproduce:** - enable "units of measure & packagings" settings - navigate to "units and packagings" and create a new one called "pack of 2" - set a quantity of 2 and the reference unit as "units" - create a new storable product - next to "sale price" change the unit to "pack of 6" - in the sales tab add "pack of 2" in the packagings - in the purchase tab add a vendor - click on the reordering rule smart button and create a new one - set the min and max to 0 and set the replenishment multiple to "pack of 2" (you might have to make this column visible using the filters) - create and confirm a quotation for 1 pack of 6 **Current behavior:** a new Purchase Order is created for a quantity of 1.02 **Expected behavior:** it should be a quantity of 1 **Cause of the issue:** qty_multiple is rounded (in _compute_quantity) before the computation of remainder. https://github.com/odoo/odoo/blob/7a0a246016d50ae80e49f3502a97e82d414ab0b0/addons/stock/models/stock_orderpoint.py#L373-L376 In cases of repeating decimal numbers (like 0.3333333 in our example), this leads to the remainder not being 0 even though it should be 0. opw-5040144 Forward-Port-Of: odoo/odoo#228014
Exporting a Belgian 325 form to PDF no longer results in a server crash when there are no 281.50 forms to include. Users now receive a clear message explaining that they need to record a transaction with a 281.50 tag before generating the PDF.
Original PR description
### Problem When clicking **"Export PDF"** on a 325 form that has **no generated 281.50 forms**, Odoo raised a **server error**: This happened because the method assumed that at least one attachment…
### Problem When clicking **"Export PDF"** on a 325 form that has **no generated 281.50 forms**, Odoo raised a **server error**: This happened because the method assumed that at least one attachment would always be generated, even if no eligible transactions were present. --- ### Steps to Reproduce 1. Go to **Accounting → Reporting → 325 Form**. 2. Create a 325 form for a year without any transactions on accounts tagged with **281.50**. 3. Do not generate any 281.50 forms (`form_281_50_ids` is empty). 4. Click **Export PDF**. **Result before fix:** - Crash with `IndexError: list index out of range`. --- ### Solution - Added a safeguard check before accessing attachments. - If no attachments exist, raise a **UserError** instead of crashing. **New behavior:** > *“No 281.50 lines found to generate a PDF. Please record a transaction with a 281.50 tag first.”* This gives users a instruction on how to resolve the issue. --- ### Result After Fix - **User error message** replaces traceback. - **Normal behavior preserved** when attachments exist: - One file → direct download. - Multiple files → zipped download. --- task-5090120 Forward-Port-Of: odoo/enterprise#94877
The Gantt view now correctly treats the Quarter scale as its own grouping instead of handling it like a month view. This makes project timelines easier to read by showing quarter groups with the expected month-level precision.
Original PR description
**Steps to reproduce:** - Install Project app - Go to Tasks - Go to gantt view - Select Quarter scale in the top left menu - Filtering shows 3 full quarters (9 months) as expected - Precision is set to days, with no grouping by quarter **Issue:** Quarter filtering is treated in the same way as the month filtering after some refactoring. Its scale was removed as well. **Fix:** Added 'quarter' to the possible timedelta and modified the range to use quarter specific scale. opw-4916133 related : https://github.com/odoo/enterprise/commit/067c2b43ec3329d1ef59e0e8f6030f0ec5e43829
This fix restores proper quarter-based grouping in Gantt timeline views, such as project task planning. Users viewing work by quarter will now see the correct time range instead of month-style grouping.
Original PR description
**Issue:** In the gantt views, quarter filtering is treated in the same way as the month filtering after some refactoring. Its scale was removed as well. When using `gantt_scale` to view project tasks, the time range was not displayed properly in the interface (no quarter grouping). **Fix:** Added 'quarter' to the possible timedelta to keep `delta = get_timedelta(1, scale)`. We could also add a simpler check for 'quarter' scale and cast it in month quantity, but it seems worse. opw-4916133 related : https://github.com/odoo/enterprise/commit/1abfc20baae80a3e7e250019b09a7070e831eeac related : https://github.com/odoo/enterprise/commit/067c2b43ec3329d1ef59e0e8f6030f0ec5e43829 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Contacts in the Dominican Republic can now use valid 11-digit Cédula tax identification numbers, in addition to existing 9-digit RNC numbers. This prevents valid customers or vendors from being incorrectly blocked during VAT validation.
Original PR description
**Issue** When inputting a VAT number with a length different from 9 digits, the check fails, even if the number is a valid Dominican RNC. **Steps to Reproduce** 1. Install Dominican localization and the VAT check module (base_vat), along with Contacts. 2. Go to Contacts, create a new contact for the Dominican Republic. 3. Insert "152-0000706-8" as the VAT. **Root Cause** The `check_vat_do` method only validated 9-digit RNC numbers via `stdnum.do.rnc.validate()`. 11-digit Cédula numbers are not supported. **Fix** - Updated `check_vat_do` to: * Validate 9-digit RNC numbers using `stdnum.do.rnc.validate()`. * Validate 11-digit Cédula numbers using `stdnum.luhn.validate()`. Opw-5004221 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#224507
This fix stops users from accidentally pasting text into parts of the website editor that are meant to be locked from editing. It helps preserve page structure and prevents unintended content changes while using the website builder.
Original PR description
When the selection is on text inside an element which is not `contenteditable` and is a inside the editable root, the user could paste text that would get inserted. This commit prevents that by ignoring `paste` events when selection is in a `contenteditable=false`. Steps to reproduce: - On `form/help-1`, open website builder - Select the text of "Help" title - Paste text - Bug: text is inserted task-5109671
The accounting dashboard’s drag-and-drop buttons and upload areas now automatically match the selected theme instead of using fixed colors. This improves readability and visual consistency, especially for users working in dark mode.
Original PR description
Current behavior before PR: - Drag & drop buttons and upload drop zones of dashboard cards had hardcoded backgrounds (#F2EDF0 / grey), which did not adapt to dark mode. Desired behavior after PR is merged: - Removed hardcoded background colors from drag & drop button and upload drop zone cards on dashboard and updated their background to adapt in light & dark modes. Changes implemented: - Removed hardcoded background color (`#F2EDF0`) from `account_drag_drop_btn` & `drag_to_card` CSS classes. - Removed overriding background-color property from `o_drop_area` CSS class. - Updated background-color of `o_drop_area` in `o_account_dashboard_kanban_view` CSS class to `o-view-background-color`. task-5092460 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#227707
Cancelled Gelato orders can now be processed without causing an error in Odoo. Instead of using a removed email template, the cancellation update is recorded directly in the sales order history so teams can still see what happened.
Original PR description
After an order is canceled on Gelato, we receveive a webhook with an `fulfillmentStatus` of `cancel` and while processing it, it crash with: ``` ValueError: External ID not found in the system: sale.mail_template_sale_cancellation ``` The mail template used to notify the status change has been removed in odoo/odoo@2c858ed15e50, so instead we simplify log the information on the sale order chatter. opw-5110226 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Deleting an invoice that had been queued for postal delivery now also removes the related postal mail record. This prevents the scheduled mail processing job from failing on missing invoice data and keeps the queue running reliably.
Original PR description
When an account move linked to a snailmail letter is deleted, the cron ``Snailmail: process letters queue`` crashes with a traceback. Steps to reproduce the error: - Create a new invoice > Confirm > Send > Select ``By post`` > Send - Reset to Draft > Delete the invoice - Run the cron ``Snailmail: process letters queue`` Traceback: ``` MissingError Record does not exist or has been deleted. (Record: account.move(1,), User: 1) ``` Solution: Ensure that when a move is deleted, its related Snailmail letters are also deleted. sentry-6883768061 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#227823