Tuesday, August 12, 2025
14 changes · saas-18.4
Enhancements to existing features
Bank statement processing now identifies partners for multiple statement lines at once instead of repeating the same work line by line. This reduces database lookups and improves performance when importing or reconciling large bank statements.
Original PR description
The retrieve_partner function is actually executed on each statement line, with multiple search, which is killing performance. This commit change that, so retrieve_partner is executed on a statement line recordset, minimizing the amount of queries on each call. task-4749377 Forward-Port-Of: odoo/enterprise#87444
Resolved issues and error corrections
Project profitability figures now use the accounting line balance instead of recalculating amounts with current currency rates. This prevents incorrect project cost and profitability totals when vendor bills or other entries use historical or manually adjusted exchange rates.
Original PR description
Issue description: The profitability items for projects were not matching the numbers from analytic accounting reports due to discrepancies in currency rate calculations. This issue was traced to two…
Issue description: The profitability items for projects were not matching the numbers from analytic accounting reports due to discrepancies in currency rate calculations. This issue was traced to two main causes: 1. Profitability items were using the currency rate of today, even for old move lines. ```rates = self.env['res.currency'].browse(list(currency_ids))._get_rates(self.company_id, date.today())``` While this was deemed acceptable for performance reasons in #113146, it caused mismatches with analytic accounting reports. 2. Some move lines use a changed currency rate that differs from the rate stored in the currency table for the same date (due to manual change in the currency rate), leading to further mismatches. To resolve this: - The `balance` is now used instead of `price_subtotal` for calculations. This ensures accurate amounts without relying on conversion rates when the project currency matches the company currency. Steps to Reproduce: 1. Create a project with an associated analytic account. 2. Enable any foreign currency and add different rates for it for today and yesterday. 3. Create a new vendor bill with: - Date = yesterday - Currency = the new foreign currency - Analytic distribution set to the created project's analytic account. 4. Check the project dashboard profitability. You will see the numbers are incorrect because it uses the currency rate of today. opw - 4881380 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#222462 Forward-Port-Of: odoo/odoo#217337
Marketing card previews and test mailings now use the right preview card, avoid recording preview interactions as real clicks, and show translated default content. Campaigns linked to removed business models are also cleaned up automatically, while field selection controls are easier to clear and display more consistently.
Original PR description
- Avoid counting "clicks" on archived (implicitly preview) cards - Pick the preview card when building the default mailing body - Translate the default mailing body - If a card targets a model that has been uninstalled, remove the campaign as is done for mailings task-4247003 Forward-Port-Of: odoo/odoo#222383 Forward-Port-Of: odoo/odoo#214315
Point of Sale now correctly opens the product configuration popup when a combo item includes products with special variant settings. It also avoids asking cashiers to choose variant options that were already selected in the combo flow, reducing confusion and checkout errors.
Original PR description
When a combo contained a product that had variant with type 'no_variant' and 'always', if you added the product to the cart the product configuration popup would not open. Also, in the combo you can…
When a combo contained a product that had variant with type 'no_variant' and 'always', if you added the product to the cart the product configuration popup would not open. Also, in the combo you can only select product_product and not product_template, so the product configuration popup should not propose the variant linked to the 'always' type, as you already selected a product template in the combo configuration popup. Steps to reproduce: ------------------- * Create a product attribute PA1 with type 'no_variant' and 2 values V1 and V2 * Create a product attribute PA2 with type 'always' and 2 values V3 and V4 * Create a product template PT1 with PA1 and PA2 * Create a combo choice PC1 with the 2 variants of PT1 * Create a combo product CP1 with PC1 * Open PoS and add CP1 to the cart * The combo configurator popup opens, click on the version with V2 > Observation: The product configurator popup does not open > Second fix: The product configurator allows you to select the variant linked to the 'always' type, which is not correct as you already selected it through the combo configurator popup Why the fix: ------------ The first fix just make sure that the product configuration popup opens when it is necessary. The second fix filters the variants proposed in the product configuration popup to only show the variants that are not linked to the 'always' type. But this only happens when we do it from the combo configuration popup. opw-4719258 Forward-Port-Of: odoo/odoo#222252 Forward-Port-Of: odoo/odoo#215603
Paid time off in the French localization now uses the employee’s actual working schedule when calculating hours, instead of defaulting to the company schedule. This keeps timesheets accurate when employees work different daily hours while preserving the legally required day count rules.
Original PR description
With the French fiscal localization: When an employee has a different working schedule than the company’s default one. If the employee’s daily working hours are greater than the company’s default…
With the French fiscal localization: When an employee has a different working schedule than the company’s default one. If the employee’s daily working hours are greater than the company’s default hours. The timesheet for paid time off only displays the company’s default hours instead of the employee’s actual hours. Steps to reproduce: ------------------- * Install l10n_fr_hr_holidays * Set the French fiscal localization * Working schedule of the company -> 7:30 per day * Working schedule of the employee -> 8 per day * Create a paid time-off with this employee * Check the Timesheet of this employee > Observation: Timesheet shows 7:30 instead of 8 Why the fix: ------------ We needed to ensure the hours are always calculated correctly (using the employee’s or company’s calendar when appropriate) while still forcing the correct day count (1 or 0.5) and extending it according to French law. ✅ Day count is forced (0.5 or 1) depending on the leave type. ✅ Hours are fetched from `super()._get_durations()` so the timesheet keeps accurate hours. This prevents timesheets from showing incorrect hours when the employee's work schedule differs from the company's work schedule. opw-4744516 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#220511
This update corrects outdated field references in the employee work entry module after HR contract data was renamed during the saas-18.4 migration. It prevents upgrades from being blocked, helping customers move to the new version without this migration error.
Original PR description
- When migrating from `saas~18.3` to `saas~18.4` upgrade is blocked. Issue - - The model `hr.contract` was…
- When migrating from `saas~18.3` to `saas~18.4` upgrade is blocked.
Issue
-
- The model `hr.contract` was [renamed](https://github.com/odoo/upgrade/blob/815644044a3cf9ec41b2cf7580da47abdf6d3553/migrations/hr/saas~18.4.1.1/pre-migrate.py#L25) to `hr.version`. The fields `date_start` and `date_end` were also [renamed](https://github.com/odoo/upgrade/blob/815644044a3cf9ec41b2cf7580da47abdf6d3553/migrations/hr/saas~18.4.1.1/pre-migrate.py#L30-L31) to `contract_date_start` and `contract_date_end` in the hr.version model.
- These fields were still referenced in this module, causing issues.
Solution:
-
- Updated the references from `date_start` and `date_end` to `contract_date_start` and `contract_date_end` to resolve the issue.
- Reference [PR](https://github.com/odoo/odoo/pull/202869/files)
Traceback:
-
```python3
Traceback (most recent call last):
File "/home/odoo/src/odoo/saas-18.4/odoo/service/server.py", line 1410, in preload_registries
registry = Registry.new(dbname, update_module=update_module, install_modules=config['init'], upgrade_modules=config['update'])
File "<decorator-gen-6>", line 2, in new
File "/home/odoo/src/odoo/saas-18.4/odoo/tools/func.py", line 89, in locked
return func(inst, *args, **kwargs)
File "/home/odoo/src/odoo/saas-18.4/odoo/orm/registry.py", line 175, in new
load_modules(
File "/home/odoo/src/odoo/saas-18.4/odoo/modules/loading.py", line 450, in load_modules
load_module_graph(
File "/home/odoo/src/odoo/saas-18.4/odoo/modules/loading.py", line 201, in load_module_graph
registry.init_models(env.cr, model_names, {'module': package.name}, new_install)
File "/home/odoo/src/odoo/saas-18.4/odoo/orm/registry.py", line 719, in init_models
model._auto_init()
File "/home/odoo/src/odoo/saas-18.4/odoo/orm/models.py", line 2908, in _auto_init
new = field.update_db(self, columns)
File "/home/odoo/src/odoo/saas-18.4/odoo/orm/fields_relational.py", line 284, in update_db
return super().update_db(model, columns)
File "/home/odoo/src/odoo/saas-18.4/odoo/orm/fields.py", line 1120, in update_db
self.update_db_notnull(model, column)
File "/home/odoo/src/odoo/saas-18.4/odoo/orm/fields.py", line 1173, in update_db_notnull
model._init_column(self.name)
File "/home/odoo/src/odoo/saas-18.4/addons/hr_work_entry/models/hr_work_entry.py", line 82, in _init_column
self.env.cr.execute("""
File "/home/odoo/src/odoo/saas-18.4/odoo/sql_db.py", line 426, in execute
self._obj.execute(query, params)
psycopg2.errors.UndefinedColumn: column hc.date_start does not exist
LINE 14: hwe.date_start >= hc.date_start AND
^
HINT: Perhaps you meant to reference the column "hwe.date_start".
```
- OPW - 4996246
- UPG - 3056379
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-prA scheduled accounting task now stops retrying journal entries that fail during automatic posting. This prevents repeated error messages and excessive record creation, helping keep accounting operations and system performance stable.
Original PR description
**Steps to reproduce:** - For simplicity, create a new account. - Create a new journal entry, with one line on the newly created account. - Set the date to today or older. - Set auto-post to "At…
**Steps to reproduce:** - For simplicity, create a new account. - Create a new journal entry, with one line on the newly created account. - Set the date to today or older. - Set auto-post to "At date". - Make sure the journal has autocheck_on_post set to True. - Keep the journal entry in draft, and duplicate it until you have 100 copies. (Make sure auto-post is set to "At date" on all of the copies aswell) - Set the newly created account to 'Deprecated'. - Manually execute the scheduled action "Account: Post draft entries with auto_post enabled and accounting date up to today" **Issue:** The scheduled action fails and then falls into an infinte loop, and logs an error on the chatter every minute, which could lead to thousands of mail_message records beign created. **Cause:** If the autopost scheduled action fails on a certain move, it marks it as 'move.checked = False'. So that when it is calls itself again (if the number of moves to post is greater than or equal to 100), it won't fetch the same move and fail again. But having 'journal_id.autocheck_on_post = True' in the search domain allows autopost to fetch the same move it marked before (if the journal allows it), which leads to an infinite loop. **Solution:** If autopost fails on a move, set 'auto_post' to 'no' so it won't be fetched again. opw-4815790 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#214946 Forward-Port-Of: odoo/odoo#213642
This fix prevents French FEC file imports from incorrectly replacing account names when multiple accounts share similar codes. Businesses can import accounting files with greater confidence that existing account labels will remain accurate.
Original PR description
Steps to reproduce: - import a fec with different account 164*** with different names Issue: All the account's name will be overriden Cause: Before 18.0, apparently, code and name were joined and was not an issue solution: update the code to the new logic by filtering out the name from the override (`_apply_template`) opw-4690284 Forward-Port-Of: odoo/enterprise#89194 Forward-Port-Of: odoo/enterprise#86809
New salary offers now appear correctly when users return to applicant or employee offer lists. When creating an offer from an employee record, the employee field is filled in automatically, reducing manual entry and confusion.
Original PR description
…ee field - = hr_contract_salary Steps: - Navigate to Recruitment > Job Positions > Applications> Offers - Now, create a New offer using the New button, and go back to offer list view - Navigate to Employee > Select an employee > Contract > Offers - Now, create a New offer using the New button, and go back to offer list view - Navigate to Employee > Select an employee > Contract > Offers - Now, click on New button to open offer form. Issues: - New offer is not included in list for applicants when returning via breadcrumb - New offer is not included in list for employees when returning via breadcrumb - Employee field is not pre-populated when creating a new offer for employee Fix: - Modified smart button action for applicants - Modified smart button action for employees - Computed the employee field to be autofilled Task - 4787302 Forward-Port-Of: odoo/enterprise#86160
This fix prevents one employee from being automatically clocked out when another employee clocks in from a different point-of-sale device. Businesses using Belgian POS certification can now keep accurate simultaneous staff attendance records across synchronized devices.
Original PR description
- Fixes an issue where clocking in a second employee on a different device would automatically clock out the first one. This was due to `self` being unset during POS session leading to incorrect loading of `users_clocked_ids` and `employees_clocked_ids`. - The issue was appearing when `pos_session._post_read_pos_data` is triggered from `pos_config.notify_synchronisation`. task-id: 4902090 Forward-Port-Of: odoo/enterprise#89273
Subscriptions that were paused and then manually invoiced now clear the pause state when that invoice is posted. This prevents resumed subscriptions from using an already-invoiced date and helps keep billing periods accurate.
Original PR description
Version: - saas-18.4 Before: - If a subscription was paused and a manual invoice was created, resuming the subscription would set the next invoice date incorrectly. - It would often pick a date that had already been invoiced manually, skipping over the pause period. - This happened because the user_pause_start is not reset after posting the manual invoice. After: - Now, when a manual invoice is posted during a pause, the pause state is cleared right away. - This makes sure the next_invoice_date is calculated properly when the subscription is resumed, without missing the pause period. Impact: - Fixes issues where subscriptions skipped billing periods after a manual invoice during a pause. - Keeps the billing period accurate when pausing and resuming subscriptions. Steps to reproduce: - Create and confirm a subscription. - Pause the subscription. - Post a manual invoice. - Resume the subscription. task-4946268
Rental orders now show the correct remaining availability when rental transfers are disabled. This prevents products from appearing unavailable after another rental is picked up, helping sales teams confidently confirm valid rental orders.
Original PR description
Steps to reproduce: - Do not enable “Rental Transfer” in settings - Create a storable product “P1”: - Enable “Can be rented” - update available quantity to 10 units - Create a first rental order for…
Steps to reproduce:
- Do not enable “Rental Transfer” in settings
- Create a storable product “P1”:
- Enable “Can be rented”
- update available quantity to 10 units
- Create a first rental order for 24h:
- 9 units of P1
- Confirm the order
- Create a second rental order for the same 24h period:
- 1 unit of P1
-> Expected: The availability widget is green and indicates 1 unit available (correct).
Problem:
After picking up the first order, the widget on the second order turns red and incorrectly shows no availability.
The current logic checks virtual_available (1 unit) and subtracts rented_qty_during_period (9 units), resulting in -8. It then takes max(0, -8) → 0. However, the actual picked quantity should be taken into account, regardless of whether “Rental Transfer” is enabled, since disabling it merely omits the creation of a picking—not the move itself.
opw-4901017
opw-4906162
Forward-Port-Of: odoo/enterprise#92056
Forward-Port-Of: odoo/enterprise#91155The Spanish VAT books export now avoids a technical error when the company’s IAE Group or Heading is missing. Instead, users are guided to update the company settings, making the issue easier to resolve and reducing disruption during tax reporting.
Original PR description
**Steps to reproduce:** 1. Install the `l10n_es_reports` module. 2. Remove the value from the `IAE Group or Heading` field in company settings. 3. Navigate to `Accounting -> Reporting -> Tax Report -> Generic Tax Report`. 4. Click the down arrow and select `VAT Record Books (XLSX)`. **Observed behavior:** * A traceback error occurs when attempting to export the VAT books. **Root cause:** * The system attempts to traverse the `IAE Group or Heading` field, which is empty, causing the traceback. **ref**: https://github.com/odoo/enterprise/blob/d8539dff5f3dcecfeb99fd7fc22a6915aaa02c4b/l10n_es_reports/models/libros_export.py#L126-L138 **Solution:** * If field `IAE Group or Heading` not configured, a RedirectWarning is raised to guide the user to the company form view for proper setup. opw-4981531 Forward-Port-Of: odoo/enterprise#92049 Forward-Port-Of: odoo/enterprise#91607
UPS commercial invoices generated from deliveries now show the same currency as the related customer order instead of defaulting to the company's currency. This helps avoid incorrect customs paperwork and reduces confusion for international shipments.
Original PR description
The automatically generated UPS Commercial Invoice is using the company's currency instead of the currency of the invoiced order. ### How to reproduce: * Setup UPS Delivery Method. * Create a sale order with a currency different from the company's. * Assign a customer in a different country. * Validate the delivery. * Check the UPS Commercial Invoice — it shows the company's currency. opw-4973217 Forward-Port-Of: odoo/enterprise#92065 Forward-Port-Of: odoo/enterprise#91883