Monday, October 6, 2025
10 changes · saas-18.3
Enhancements to existing features
Bank reconciliation now creates the accounting move immediately when an XML file is uploaded. This makes the imported move lines available directly on the bank statement line, streamlining reconciliation work for accounting users.
Original PR description
When uploading a xml from the bank rec widget, the move will be created directly so we can put the move lines in the bank statement line. task-5107112
Resolved issues and error corrections
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#228515Publishing 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
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
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
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
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