Daily updates from Odoo
Wednesday, November 19, 2025
60 changes · master
Enhancements to existing features
Jordan payroll now uses overtime amounts already calculated from work entries instead of relying on manual payslip inputs. This reduces manual payroll setup, improves consistency, and keeps overtime rules aligned with attendance records.
Original PR description
Before: - Overtime salary rules calculated amounts manually from payslip inputs After: - Link Jordan overtime rules to their respective work entry types in the hr_work_entry_attendance bridge module - Update overtime salary rules to read values directly from worked_days entries - Simplify salary rule logic: use pre-calculated amounts from work entries - Remove obsolete manual payslip input types Task-5103913
VoIP activity cards have been refined to show clearer, more useful information across calls, CRM leads, recruitment applicants, and SMS actions. This helps users understand and act on communication activities faster from the softphone interface.
Original PR description
Task-5207647
Bank reconciliation users can now choose to show transaction details as an optional column in the transaction list. The details are displayed in an easier-to-read format with a hover preview, helping users review bank entries more quickly without opening extra records.
Original PR description
This commit enhances the bank reconciliation widget by adding the transaction_details field as an optional column in the transaction list view. Changes: - Added transaction_details field to the optional hide/show configuration in bank statement list view - Implemented custom formatted_transaction_details widget to display JSON data in human-readable format with hover preview task-5121929
This update adds automated checks for the IoT connection messaging code, helping ensure messages are sent and received as expected. It reduces the risk of future changes breaking connected device communication without changing day-to-day user workflows.
Original PR description
This commit adds a suite of tests for the `IotWebsocket` class. The tests comprehensively cover the functionality of `sendMessage` and `onMessage`. Type hints are also added to these methods.
Appointment pages no longer allow users to edit placeholder images for staff or resources on the website. This avoids confusion because those placeholder edits were never saved and real profile images are not editable from the front end.
Original PR description
Remove the possibility to edit the user/resource image placeholders on the front-end. Editing the placeholders is useless as they won't be saved on page reload anyway. Also, the user/resource record images (displayed when Display Pictures option is set) aren't editable from the front-end. Meaning being able to edit the placeholders could be confusing for the users. Task-5079021
Payroll validation has been optimized to use far fewer database queries, reducing processing overhead when confirming payslips. This should make payroll runs faster and more efficient, especially for larger batches.
Original PR description
Before this changes the number of query needed to do the payslip validation was 274 and with this changes it's only 76 :sunglasses:
Saudi payroll now calculates end-of-service benefits more closely in line with legal wording, including an option to use actual calendar days or an annual approximation. Retirement is treated like contract completion, and payslip provisions better reflect each employee’s employment duration, improving accuracy for HR and payroll teams.
Original PR description
- added field `l10n_sa_use_actual_number_of_days` to mark if we use actual number of days in the year or an approximation. - adjusted the calculation of end of service benefit to be check if we want to use actual number of days or not and changed the calculations to use total years instead of total days to be compatible with how it's stated by the law - changed the case of retirement to be handled the same as the case of contract ending and not resignation - changed the way eos provision is calculated on the payslip to account for the duration of employment of the employee - added test for eos benefit calculation which checks using actual number of days and approximation for the cases of resignation and end of contract - changed the string and tooltip of `l10n_sa_number_of_days` to be more descriptive of what it does task-id: 4766060
Barcode-related automated tests now use dedicated test company and warehouse data instead of relying on default demo records. This makes test results more stable, fixes a known build failure, and slightly speeds up some barcode test runs without changing day-to-day user workflows.
Original PR description
*: stock_barcode_mrp, stock_barcode_mrp_subcontracting, stock_barcode_picking_batch Until now, the default warehouse (WH) was the warehouse used in the `stock_barcode` tests which means all the tests depends of it and are influenced by the changes done in this warehouse (like changes done by the demo data.) A better way to run the tests would be to use a warehouse created for this occasion, and what a chance, that's why this commit does! Incidentally, this commit also fixes [runbot built error 233274](https://runbot.odoo.com/odoo/runbot.build.error/233274) **Community PR:** odoo/odoo#234483 Forward-Port-Of: odoo/enterprise#96657
Employees can now view available VoIP providers and select the one they need without administrator help. Access remains limited to the necessary provider information, keeping sensitive configuration details protected.
Original PR description
We now allow base.group_user to have read access to voip.provider so that user can change provider by themselves. Note that the visible fields to base.group_user are still limited. Task-5262635 Forward-Port-Of: odoo/enterprise#99530
Belgian SODA payroll imports can now handle multiple files for the same accounting month, such as 13th-month payroll cases, by keeping entries uniquely identifiable. Entries are also dated at the end of the accounting period, or just after a locked period when needed, improving accounting accuracy and compliance with period controls.
Original PR description
in some cases it is needed to upload more than one soda files for the same month (i.e. 13th months), in this case we add _xx after the sequence number in the ref of the entry also we changed the date to the last day of the accounting period instead of the gendate and in the case the accounting period is locked it will be the first day after the locked period task-5270270
The Odoo Compliance Assistant now follows updated guidance and is restricted to using only its approved information sources. A sample question was also changed to use New Jersey instead of Japan so demo results are more relevant and useful.
Original PR description
Updated the system prompt for the `Odoo Compliance Assistant` as per the new proposition. Also previously, we were using the prompt `Do I have any customer in Japan?` which returned `I did not find any`. It has been changed to `Do I have any customer in New Jersey?` to get valid results. Task-5153818
UAE payroll benefits are now handled through salary rules instead of separate benefit setup. This makes payroll calculations more consistent and easier to maintain, with updated demo data and tests to reflect the new approach.
Original PR description
In this commit, we converted the payroll benefits into salary rules and adjusted the demo data. task-5122366
When reconnecting or retrying a bank account synchronization, Odoo now reuses the existing journal instead of creating a duplicate. This keeps accounting records cleaner and avoids confusion caused by expired or failed connection links.
Original PR description
[IMP] account_online_synchronization: avoid duplicate journal This commit prevents user to create duplicate journals when synchronizing a bank account. When a user tries to add a new bank account, a journal is created. But if the connection link expires or is in error, we don't want to create a new journal, we just want to replace the online_account (and so the online_link) in the existing journal. task-5042462
Odoo spreadsheets in the trash now behave like CSV and Excel files: users must restore them before opening. This creates a more consistent document experience and helps avoid accidental use of trashed files.
Original PR description
Current behavior before PR: - Trashed Odoo spreadsheets could be opened directly, unlike CSV/Excel files that required restoring first. Desired behavior after PR is merged: - Odoo spreadsheets now follow the same behavior as CSV/Excel files. Trashed files must be restored before they can be opened. Task: 5030282
Point of Sale settings can now be changed even when a session is already open. This reduces operational interruptions by letting businesses adjust enterprise and UrbanPiper-related configuration without waiting for sessions to close.
Original PR description
### in this commit: - Removed restriction preventing config changes during an open session. task-5187838
IoT devices can now be recognized by a stable backup identifier, such as a printer's MAC address, when their main identifier changes. This prevents duplicate device records and keeps existing POS configurations working without manual updates.
Original PR description
Community PR: https://github.com/odoo/odoo/pull/235455 Before this commit, if a device such as a printer were to have its identifier change (usually because its IP changes) then a new device entry would be created, leaving the old device entry non-functional but still linked to e.g. a POS config. After this commit, a new `alternate_identifier` field is added, which a driver can provide for a device as a fallback. In the printer case, it sends the MAC address of the printer here. If we receive a device with an `alternate_identifier` that matches an existing device, we can update that existing device instead of creating a new entry. This way, the configuration of the POS using the device does not need to change. We also adapt the existing blackbox logic to handle this process to use this new `alternate_identifier` field. task-5059488
SendCloud delivery integration can now determine the warehouse name through a customizable process instead of relying only on a fixed name match. This helps businesses with more complex sender-address rules choose the right shipping origin more reliably.
Original PR description
As choosing the proper sender address in SendCloud can be more complex than matching a name to a fixed name in Odoo we open up the freedom to inherit the retrieval of the warehouse name. Info: @wt-io-it Forward-Port-Of: odoo/enterprise#97595
Improves the warnings and errors shown when generating Saudi WPS reports for validated payslips, making issues easier for payroll users to understand and resolve. It also renames the bank account field from Establishment ID to Establishment Code to better match its business meaning.
Original PR description
This commit improves the warning and error messages shown to the user when generating WPS reports for validated payslips in Saudi Arabia. task-5220230
New menus make it easier for accounting users to review sales and purchase order accruals, including viewing balances as of a chosen past date. The reports now open the related order directly from each line, helping teams investigate prepaid expenses, bills to receive, deferred revenue, and invoices to be issued more efficiently.
Original PR description
*: purchase_accountant,sale_account_accountant This commit adds new menu for SO and PO accruals. A custom list view (`js_class`) was created for those reports: `accrual_list_view`. AccrualListView…
*: purchase_accountant,sale_account_accountant This commit adds new menu for SO and PO accruals. A custom list view (`js_class`) was created for those reports: `accrual_list_view`. AccrualListView =============== This view is used both by `sale.order.line` and `purchase.order.line`. Its functionnalities are: - The user can choose a date to see records' values in the past; - If a line is clicked, instead of opening the line's form view, it will open its order form view instead. Technical notes about this view: - The chosen date is passed to the context but there is issue when the view is grouped (and it is by default): while the grouped lines uses the right context with the selected date, the contained lines sometime use an old version of this context with a previously selected date which means the grouped data are not the same than the single lines data. To fix that, we force the context on each group. - The "at_date" fields are non-stored computed fields. By default, there is no sum value for those fields. Server side, we override the `_read_group` method to "manually" compute those fields sum. To be able to do that, we tweak the aggregate config in this view. Boolean fields ============== Four boolean fields are created: - `prepaid_expense` and `bill_to_receive` for `purchase.order.line`; - `deferred_revenue` and `invoice_to_be_issued` for `sale.order.line`. Those fields are usefull to fetch right order lines for the right accrual and are always a balance between delivered/received quantity and invoiced quantity. [task-5075455](https://www.odoo.com/odoo/966/tasks/5075455) Community PR: odoo/odoo#231510 Forward-Port-Of: odoo/enterprise#97151
The Philippine reporting module’s automated tests were updated to match a recent change in report descriptions. This helps ensure reporting checks stay aligned with the latest expected wording and reduces the risk of false test failures.
Original PR description
Related PR: https://github.com/odoo/odoo/pull/235448 TaskID-5248240 Forward-Port-Of: odoo/enterprise#99354
Financial report lines now use consistent spacing between hierarchy levels. This makes nested report sections easier to scan and improves readability without changing the report data.
Original PR description
This commit ensures that indentation difference between reports lines on different levels is identical. Before this commit, a line at level 2 would have indentation of 4px, and for further levels, this number would increase by 8px. This commit makes indentation start at 8px for level 2 to make indentation differences consistent. task-5232821
The IoT Box technical information now links its displayed software commit hash directly to the related GitHub commit page. This makes it faster for support or administrators to confirm exactly which software version is running when diagnosing issues.
Original PR description
To ease checking the HEAD commit on the IoT Box, we now compute the github url to the commit, and redirect to it clicking on the hash in the technical information tab. Forward-Port-Of: odoo/enterprise#99673 Forward-Port-Of: odoo/enterprise#99422
This update makes it easier for Odoo features to remember user preferences in the browser and keep them consistent across tabs. It also adds a safer way to preserve those preferences when storage formats change during upgrades, reducing the risk that users lose settings after updates.
Original PR description
*: frontdesk Before this commit, having a record field saved in local storage and synced among browser tabs was cumbersome. Roughly this was defined as follow: ```js class Settings extends Record {…
*: frontdesk
Before this commit, having a record field saved in local storage and synced among browser tabs was cumbersome. Roughly this was defined as follow:
```js
class Settings extends Record {
static new(...args) {
const settings = super.new(...args);
settings.onStorage = settings.onStorage.bind(settings);
browser.addEventListener("storage", onStorage);
return settings;
}
delete() {
super.delete();
browser.removeEventListener("storage", onStorage);
}
onStorage(ev) {
if (ev.key === USE_BLUR_KEY) {
this.useBlur = ev.newValue === "true";
}
}
useBlur = fields.Attr(false, {
compute: () => browser.localStorage.getItem(USE_BLUR_KEY) === "true",
onUpdate: () =>
this.useBlur
? browser.localStorage.seItem(USE_BLUR_KEY, "true")
: browser.localStorage.removeItem(USE_BLUR_KEY),
});
}
```
This commit simplifies drastically how to define fields that are saved and synced to local storage:
```js
class Settings extends Record {
useBlur = fields.Attr(false, { localStorage: true });
}
```
The write in local storage is made only when the field value differs from default:
- if value is same as default value, then remove from local storage
- if value is different than default value, write current value in local storage
This commit also introduces local storage upgrade scripts. Since local storage keys and values are expected to change but we want to keep user preferences, these scripts help upgrade old local storage values to newer ones.
To define an upgrade script:
```js
import { addUpgrade } from "./upgrade_helpers";
addUpgrade({
version: NEW_VERSION,
key: OLD_KEY,
upgrade: ({ value: oldValue }) => ({
key: NEW_KEY,
value: NEW_VALUE,
}),
});
```
This upgrades `OLD_KEY` local storage entry to `NEW_KEY` local storage entry with `NEW_VALUE`.
Upgrades are executed from oldest to newest version. Range is based on version in local storage at bottom and curent odoo version at the top.
Part of Task-5003012Resolved issues and error corrections
Rental product availability now stays accurate when only part of a rental order has been returned. This prevents staff from seeing too many units as available and helps avoid overbooking rental inventory.
Original PR description
### Issue: Due to this bug, virtual available is not calculated correctly when there are rental orders with some returned lines. #### To reproduce: 1- Create a storable rental product with 10 units in stock. 2- Enable the 'Rental Transfer' setting. 3- Create a rental order with two lines: - line 1: 4 units - line 2: 1 unit 4- Confirm and pick up order lines 5- Return the line with 1 unit 6- Create another order: it must show 6 available but 7 is shown #### Cause: This is caused due to filter on lines in `_get_virtual_unavailable_qty_in_rent` which filters lines with `order_id.rental_status`. However this filter misses the lines which have different status than the `order_id`. In #88689, `rental_status` field is added to `sale_order_line`. Using the `sale_order_line.rental_status`, we can ensure only line with status in `return` and `pickup` are considered. opw-5185084 Forward-Port-Of: odoo/enterprise#98689
When the Belgian POS cannot reach the Blackbox due to a timeout, it now shows a more accurate error instead of saying the fiscal module is missing. This helps cashiers and support teams understand the real issue faster and avoid unnecessary troubleshooting.
Original PR description
Before this commit, in the case when there is a timeout communicating with the Blackbox in the POS, an incorrect error message was shown stating that "The IoT Box is connected but the Fiscal Data Module isn't". This message should only be shown when we receive a reply from the IoT box, but it tells us it cannot find the Blackbox. <img width="695" height="240" alt="image" src="https://github.com/user-attachments/assets/ec011f4a-42dd-4ffd-8741-350032897471" /> Forward-Port-Of: odoo/enterprise#99652
German companies with a dot in their name can now export DATEV reports without encountering an error. This prevents export failures in the General Ledger and keeps accounting reporting workflows running smoothly.
Original PR description
Currently companies with a dot ('.') in the name cannot export the DATEV report due to a traceback.
Steps to reproduce:
- Select a German (DE) Company having a dot in the name.
- Open Accounting / Reporting / Ledgers / General Ledger
- Click cog > Datev DATA (zip)
Issue:
A Traceback will occur
`Error "ValueError: too many values to unpack (expected 2)"`
This occurs because the system separate the filename from the extension without halting to the first `.`, leading to the error.
opw-5232073
Forward-Port-Of: odoo/enterprise#99578Recruitment administrators without employee access could hit an access error when sending referral campaigns. This fix lets the intended recruiting users send referral campaigns successfully, reducing disruption in hiring workflows.
Original PR description
STEP TO REPRODUCE:
------------------
1- Give to Marc Demo the right : Recruitment / Administrator (be sure he doesn't have any right on Employees)
2- Log as Marc Demo
3- Go to Recruitment
4- Click on the three dots in kanban card
5- Click on Referral Campaign
6- Click on Send
You will have an access error
This user (with these groups) should be able to send a referral campaign
task-5082344
Forward-Port-Of: odoo/enterprise#99184
Forward-Port-Of: odoo/enterprise#96746Spreadsheet sharing now avoids showing a warning that cannot lead to any action when edit access is blocked for external users. This makes the sharing dialog less confusing by presenting only the relevant message.
Original PR description
Bug === 1. Create a spreadsheet 2. Add a partner as viewer 3. Set access vial link to edit => 2 warning are displayed (that the right will be extended, and that we can not share spreadsheet in edit mode to non-internal users). The first warning make no sens, because we can not save the modal. Task-5169034 Forward-Port-Of: odoo/enterprise#97857
FEC imports now avoid keeping temporary matching numbers that could prevent some journal items from being automatically reconciled after posting. This helps ensure imported French accounting files reconcile consistently across accounts, reducing manual cleanup for accounting teams.
Original PR description
When a FEC file imports journal items, it will create them to draft with reconciliations stated by a matching number starting with "I" (also the case for other some types of imports). Once the entries are posted, the system will create odoo reconciliation records for those journal items. The issue lies in this part of the code removing the matching when performing reconciliations for the same matching number https://github.com/odoo/odoo/blob/9d34c7ee85d105a56c3393a3dbb3e5d62d4d634a/addons/account/models/account_partial_reconcile.py#L206 Most of the time it's not a problem for the auto reconcile mechanism of FEC. However since this mechanism reconciles grouped on matching + account, we can end up in a case where a first reconciliation on account A will remove all matching number similar but on account B leading to no automatic reconciliation for them. This commit provides a test to reproduce this issue. opw-5086823 Forward-Port-Of: odoo/enterprise#98855
This update prevents an intermittent failure in an automated manufacturing work order test by avoiding a timing issue in the component selection dialog. It also ensures the intended product appears first, making the test more stable without changing business workflows.
Original PR description
The search in the "Add Component" dialog caused a re-render race, making the tour ``test_add_component_from_shop_foor_in_multi_step_manufacturing`` fail intermittently. This fix removes the search steps and marks the “Courage” product as favorite so it appears first in the catalog. runbot-227694 Forward-Port-Of: odoo/enterprise#92403
VoIP now avoids starting a new connection registration when a user naturally leaves or closes the page. This prevents conflicting requests that could trigger errors during page unload, improving call service stability without changing user workflows.
Original PR description
On page unload, two conflicting things happen: - A REGISTER request with expires=0 is sent to invalidate the registration - The WebSocket disconnects, triggering the reconnection mechanism that attempts to reissue a registration These two concurrent and conflicting REGISTER requests result in the following error: > RequestPendingError: REGISTER request already in progress, waiting for final response This commit prevents the reconnection mechanism from occurring in the event of a "natural" disconnection, such as one triggered by a page unload. This way, the two conflicting REGISTER requests aren't sent on page unload. [Task-5261940](https://www.odoo.com/odoo/project/5778/tasks/5261940) Forward-Port-Of: odoo/enterprise#99560 Forward-Port-Of: odoo/enterprise#99376
The report editor now keeps the user's cursor and selection in the right place after inserting an X2Many table in a new report. This prevents editing disruptions and lets users continue typing immediately after adding the table.
Original PR description
On a new report, add a X2Many table in a new Report. In many cases there will be some issues with the selection as, when inserting the Element via the command of the report Editor we explicitly focus the editable of the html_editor. We need the document inside the iframe to get the focus, because our flow implied to click on some popover bound to the main window. But focusing the editable element changed the selection. So, instead, we focus the iframe's inner window, and the selection stays at the right place, and the user can immediately interact with it (by continuing typing after the insertion) task-5159482 Forward-Port-Of: odoo/enterprise#99430 Forward-Port-Of: odoo/enterprise#97642
Attendance Officers without payroll permissions can now edit attendance records even when related work entries already exist. The system safely handles the required work entry regeneration in the background, preventing unnecessary access errors and keeping attendance management smooth.
Original PR description
Steps to reproduce: 1. Log in as an Attendance Officer without payroll rights. 2. Attempt to edit any attendance record. Cause: If work entries already exist for the attendance, Odoo tries to regenerate them an action requiring payroll permissions. Solution: Execute the work entry regeneration wizard with sudo to bypass the payroll access restriction. Task: 5265141 Forward-Port-Of: odoo/enterprise#99507
This change fixes a payroll configuration issue that caused automated build tests to fail for some country-specific payroll setups. The overtime attendance setting is now handled only by the module that provides it, improving reliability without changing day-to-day payroll workflows.
Original PR description
The issue occurs because the _get_whitelist_fields_from_template() method includes the overtime_from_attendance field, introduced in this https://github.com/odoo/enterprise/pull/92093. This field comes from the hr_work_entry_attendance module, which is not listed as a dependency in all payroll localisations. As a result, the field cannot be found during test execution. Solution: Remove the overtime_from_attendance field from all _get_whitelist_fields_from_template overrides in the localisation modules, and instead include this field by overriding the function in the hr_work_entry_attendance module. build error-243483 task-5169211 Forward-Port-Of: odoo/enterprise#97201
The French reporting EDI export form now shows formatted status and error messages instead of raw HTML text. This makes report results easier to read and helps users quickly identify errors highlighted in the interface.
Original PR description
Currently, the message field in the EDI export form displays raw HTML tags instead of properly formatted content, making it difficult for users to read the report status and error details. We now ensure that HTML is rendered. This allows the structured list of statuses and error details (with proper formatting and red color for errors) to display correctly in the UI Note: Wrap the computed message with Markup() during concatenation in _compute_message() to prevent the HTML from being escaped when combined with translated strings. Task-5113752
This update fixes an internal link from payslips so it opens the related employee record in the proper form view. Payroll users can navigate more reliably without being sent to the wrong screen or view.
Original PR description
The contract template form view is now written on the formview_action directly. This is a backport of https://github.com/odoo/enterprise/pull/97463 task-5082709 Forward-Port-Of: odoo/enterprise#99486
Vendor batch payments now use the correct outgoing payment numbering sequence instead of accidentally using the incoming payment sequence. This prevents confusing or incorrect batch names when validating supplier payment batches.
Original PR description
Currently when creating a vendor batch payment, the system may incorrectly use the inbound batch payment sequence to generate the batch name Steps to reproduce: - Create a Vendor payment. - Create a Vendor batch payment, add the payment, validate it. Issue: Name has been set using the incoming batch payment sequence This occurs because `batch_type` is set to readonly when a payment is added to the list. As result, the current batch type is never sent to the backend that will use the default 'inbound'. opw-5128426 Forward-Port-Of: odoo/enterprise#99570
Restaurant floor plans now receive website table booking notifications only when the booking uses the appointment type configured for that POS. If table booking is disabled or no appointment type is selected, irrelevant notifications are avoided, reducing confusion for staff.
Original PR description
Task: [#5005216](https://www.odoo.com/odoo/my-tasks/5005216) Enterprise v17.0: [#93714](https://github.com/odoo/enterprise/pull/93714) --- **Before:** If no appointment type is specified in the POS config and a table is booked via the website, the floor plan is notified of a new booking because the resource used is one of the POS config resources. However, if the page is refreshed, the booking disappears since no appointment type is defined in the POS config **After:** The floor plan is notified of a new booking only if the appointment type of the booking matches the one specified in the POS config. If no appointment type is set in the POS config, no booking notifications are sent. Additionally, when the "Table Booking" field is unchecked in the POS config, the appointment type is automatically unset. Forward-Port-Of: odoo/enterprise#98887 Forward-Port-Of: odoo/enterprise#93636
Purchase orders no longer incorrectly link to budget lines from other companies when using shared analytic accounts. This prevents users working in one company from seeing access errors caused by another company's budget data, making multi-company purchasing smoother.
Original PR description
Steps to reproduce: - Create an analytic account [ACCOUNT] not restricted to any company - Create an analytical distribution model applying [ACCOUNT] to [PRODUCT] not restricted to any company - Create a budget in company [COMP A] using analytic account [ACCOUNT] - Create a budget in company [COMP B] using analytic account [ACCOUNT] - In company [COMP B], create a purchase order, add [PRODUCT] to a line Issue: Access Error is raised Analysis: Because we search with sudo company rules are bypassed and the system assign both budget lines to the order line (budget_line_ids). When we access the field, the system try to access the budget line of the other company, causing the error. As solution we revert https://github.com/odoo-dev/enterprise/commit/4941c1928c9a2bcb38af3cadf023f904c9fd9be0 removing the `sudo` on the search and we explicitly check if the user has read access on the budget analytic model opw-5056712 Forward-Port-Of: odoo/enterprise#98573
OSS sales returns will no longer be created when their eligibility conditions are not met. OSS import returns now use similar eligibility checks, reducing unnecessary reports and helping users avoid incorrect compliance paperwork.
Original PR description
The OSS Sales returns was generated even when its condition wasn't met since auto_generate was still at True. The OSS Imports didn't have any condition and has one which is similar to the OSS Sales. Forward-Port-Of: odoo/enterprise#99700
Draft payslips can now have their period date removed without causing an exception. This prevents interruptions for payroll users while editing payslips and adds test coverage to help keep the flow reliable.
Original PR description
When removing the date in a draft payslip an exception was raised. This was fixed and a test was added to check the flow. Related to odoo/odoo#231247 task-5159666 Forward-Port-Of: odoo/enterprise#99723 Forward-Port-Of: odoo/enterprise#97013
Fixed an issue that could prevent users from opening the payroll payrun view. This restores access to payrun information in the Payroll app after an underlying interface template changed.
Original PR description
Reproduce: 1. open payroll app 2. try to access the payrun view Issue: The `web.KanbanHeader` template is update and replace a `t-esc` with `t-out` when we have an xpath on the old value Solution: update the xpath expr Task: 5323275
Users with billing access can now revoke SEPA Direct Debit mandates even when those mandates have saved payment methods linked to customer portal payments. This prevents unnecessary access errors and lets finance teams manage mandate revocation without administrator intervention.
Original PR description
**Issue:** As a user without "Administration / Settings" access, it is not possible to revoke SEPA Mandates that have been used to pay invoices through the customer portal. **Steps to Reproduce:** -…
**Issue:** As a user without "Administration / Settings" access, it is not possible to revoke SEPA Mandates that have been used to pay invoices through the customer portal. **Steps to Reproduce:** - Enable SEPA Direct Debit payment provider in Test Mode - Create a mandate for a customer w/ valid IBAN - Create an invoice for that customer and post it - Action > Generate a Payment Link, open this in an incognito window - Pay using SEPA Direct Debit - Call `_set_done()` on the payment.transaction - Try to revoke the mandate as a non-admin with "Accounting / Billing" -> Access Error, can't modify payment.token **Cause:** - When SEPA Mandate is revoked, we check for all associated payment tokens (saved payment methods from SEPA Direct Debit payment provider) and deactivate them. - The check in code isn't called with sudo, so it uses the current user access rights, but only admins can modify the payment tokens in any way. **Solution:** - Write to the `linked_tokens` with sudo so we can archive the tokens regardless of user access opw-5136221 Forward-Port-Of: odoo/enterprise#99592 Forward-Port-Of: odoo/enterprise#99232
Fixes an issue where switching from one accounting report to a composite report could crash the interface when period comparison settings differed. Users can now change report variants more reliably without being interrupted by an error.
Original PR description
This fix a traceback: - Create a report "A" with Period Comparison set to True - Create a report "B" with Period Comparison set to False - Create a composite report with report "B" inside. - Use the…
This fix a traceback: - Create a report "A" with Period Comparison set to True - Create a report "B" with Period Comparison set to False - Create a composite report with report "B" inside. - Use the variant filter to switch from report "A" to the composite report This happens because of a UI refresh in `loadReportOptions` trigged by: - delete this.reportOptionsMap[cacheKey]; - delete this.loadingCallNumberByCacheKey[cacheKey]; When refreshing the UI, it will start with the cachedOption set to the value of the displayed report (report "A"), and is able to pass the condition inside `filters.xml`: `<t t-if="controller.filters.show_period_comparison">`. While this is happening, the loading of the new report "composite" reaches `this.cachedFilterOptions = options;`. However, the UI refresh is still ongoing, and when it reaches `<t t-if="controller.cachedFilterOptions.comparison.string">` in `filter_comparaison.xml`. If the new report doesn't have the comparaison filter enabled, cachedFilterOptions.comparison will be undefined triggering the traceback. This is fixed by marking the objects, that would trigger this useless refresh, as raw preventing them from triggering a refresh. This only happened on composite reports since the cacheKey used to load them is different from the one received by the call to get_options due to the sections. task-5085985 Forward-Port-Of: odoo/enterprise#99780
This update corrects how IoT websocket messages are sent so the message type is included as expected. It helps ensure websocket communication can be tested reliably and reduces the risk of issues in connected IoT workflows.
Original PR description
In order to allow testing the websocket protocol, we need to provide the message type to the `sendMessage` method. This was forgotten in odoo/enterprise#97525. Forward-Port-Of: odoo/enterprise#98568
The Belgian POS fiscal device integration now waits up to the documented limit and retries when the device returns an invalid or negative response. This reduces failed point-of-sale fiscal operations caused by temporary communication issues with the blackbox device.
Original PR description
Following documentation, max timeout should be 1.5s and we should retry 3 times on every bb NACK/invalid data. Forward-Port-Of: odoo/enterprise#99911 Forward-Port-Of: odoo/enterprise#99705
The Philippines .dat tax export now uses the same date period selected in the report, preventing files from showing a different period than the data they contain. Users also see a non-blocking warning when the chosen export frequency does not match the report period, helping reduce accidental filing errors while still allowing intentional exports.
Original PR description
Before this commit: - The `.dat` export adjusted its date based on the selected export type’s periodicity (quarterly or annually) using the report filter's date_to. - This caused mismatches where the…
Before this commit: - The `.dat` export adjusted its date based on the selected export type’s periodicity (quarterly or annually) using the report filter's date_to. - This caused mismatches where the `.dat` file showed a different period than the report data. - The adjustment only changed the date in header of `.dat` file but did not restrict data accordingly, leading to inconsistencies when exporting reports with different filter and periodicity types. - Example: If the report filter is set to 'October 2025' month and the export type's periodicity is 'Annual', the `.dat` file would show 12/31/2025 even though the data in `.dat` file only covers 'October 2025'. Similar mismatch occurs for 'month & quarter' and 'annual & quarter' combinations. After this commit: - The `.dat` export date now fully depends on the report’s date filter, keeping report data and export date consistent. - A non blocking warning is added in the `.dat` export wizard when the report period type is different from the export type's periodicity, helping users select the correct period type while still allowing export if intended. task-5172259 Forward-Port-Of: odoo/enterprise#99241
The due button on a contact now remains visible whenever that contact has at least one customer or vendor invoice, even if nothing is currently owed. This keeps quick access to financial details and customer statements available when teams need to review past activity.
Original PR description
The `Due Button` on `res.partner` is a convenient shortcut to access the partner’s current financial situation, especially the Customer Statement report. Even if the partner has no outstanding balance, the shortcut remains useful. So in this commit, we update the visibility logic of the `Due Button` so it appears as long as the partner has at least one `invoice (in/out)` linked to them. This means the button will remain visible even when the total `due amount is `zero`, ensuring the shortcut is always accessible. Task-5264512 Forward-Port-Of: odoo/enterprise#99514
The employee profile's Reviews button now correctly displays related contract review records after an offer is signed. This prevents users from seeing an empty list even when the button indicates records exist, improving confidence in employee contract workflows.
Original PR description
Issue:
When an offer is created and signed by the employee, the `Reviews` smart button appears on the employee profile. Although it indicates that there are records, clicking the button redirects to an empty list.
Reason:
After converting contracts to the versioning system, the action for the Reviews button does not properly display contract versions, regardless of whether they are active or inactive, as it did in the previous version.
Fix:
Added a context `{"active_test": False}` to show active or inactive records.
task-5155455
Forward-Port-Of: odoo/enterprise#96808The spreadsheet pivot side panel now respects debug mode when adding a column, so advanced users can search and see technical field names as expected. This restores the intended behavior for configuring pivot data in spreadsheets and reduces friction for support, implementation, and power users.
Original PR description
Steps to reproduce: - Activate debug mode - Insert a pivot in a spreadsheet - In the side panel, click on "Add column" => the component is not in debug mode, so the technical name cannot be searched and is not displayed Task: 5264589 Forward-Port-Of: odoo/enterprise#99484
This fix removes an overly strict rule that blocked users from choosing or copying certain tax groups when account types did not match expected categories. Businesses can again manage WinBooks tax group settings more flexibly without being prevented by a flawed validation.
Original PR description
**Issue:** A constraint has been added to "account.tax.group" model some month ago, forcing a type for "Tax Payable Account" and "Tax Receivable Account" fields. However, some users had changed the type of these accounts or selected another one and they cannot do it anymore. They can't copy these tax groups neither. The constraint is too restrictive as we want to be more permissive. It's still possible to change the type of the account after selecting it for the tax group. Therefore, the constraint has some flaws. **Solution:** Remove the constraint. **Community PR:** https://github.com/odoo/odoo/pull/235548 opw-5231379 Forward-Port-Of: odoo/enterprise#99733 Forward-Port-Of: odoo/enterprise#99421
Payroll now respects the setting that disables change tracking when employees are edited through the salary configurator. This avoids unnecessary log entries and keeps employee records cleaner for HR teams.
Original PR description
We use a hack to force the tracking of some fields on the employee. It causes some problem when you work with the salary configurator as we don't want the changes logged in this case. The solution is to not track prepare the fields if there is a tracking disable in the context, like mail does. Forward-Port-Of: odoo/enterprise#99800
Sendcloud delivery methods now correctly recognize locker and combined locker/service point options as pickup locations. Customers using these services will be shown the location map so they can choose where their package should be dropped off.
Original PR description
Steps to reproduce ----- - Create a Sendcloud delivery method - Select a delivery service with "Locker or service point" as "Last mile" (eg "bpost @ bpack") > "Use Sendcloud locations" is set to…
Steps to reproduce ----- - Create a Sendcloud delivery method - Select a delivery service with "Locker or service point" as "Last mile" (eg "bpost @ bpack") > "Use Sendcloud locations" is set to false Cause ----- There is a problem with the values retrieved from the Sendcloud API call, more specifically the `available_functionalities` > `last_mile` value. The Sendcloud API (of both previous and current beta version) specifies the possible values to only be the following - `home_delivery` - `mailbox` - `pobox` - `service_point` - null https://api.sendcloud.dev/docs/sendcloud-public-api/shipping-options/operations/create-a-shipping-option https://api.sendcloud.dev/docs/sendcloud-public-api/branches/v2/shipping-products/operations/list-shipping-products However, it seems like they have added some new undocumented values `locker` and `locker_or_service_point`. To detect whether to use drop-off locations, we do https://github.com/odoo/enterprise/blob/5b64c63301bc814c7c9d99146af6a86d37563762/website_delivery_sendcloud/models/delivery_sendcloud.py#L51-L53 Where we compare the retrieved value with the string 'Service point' https://github.com/odoo/enterprise/blob/5b64c63301bc814c7c9d99146af6a86d37563762/website_delivery_sendcloud/models/delivery_sendcloud.py#L13 In our "Locker or service point" case, this does not work because the `in` operator makes a case sensitive comparison. Solution ----- Functionally, both lockers and service points work the same. The user should be prompted a map on which they choose where the delivery should be dropped off. So we can add `Locker` and `Locker or service point` as accepted values and enable the use of sendcloud locations for both. ----- Ticket: opw-5217796 Forward-Port-Of: odoo/enterprise#98875
The Uruguay electronic invoicing module now calculates currency rates consistently against the Uruguayan Peso, regardless of the company's base currency. This helps prevent incorrect exchange rates on electronic invoices for companies using non-UYU base currencies.
Original PR description
This PR fixes the currency rate calculation in the Uruguay EDI module to always compute the rate relative to UYU (Uruguayan Peso) regardless of the company's base currency. * Replaces the previous logic that calculated rates based on company currency with a direct UYU conversioni * Simplifies the rate calculation by removing the amount-based fallback logic * Ensures consistent UYU rate computation for all non-UYU currencies LATAM Task 1358 / Adhoc task 51716 Forward-Port-Of: odoo/enterprise#99587 Forward-Port-Of: odoo/enterprise#93144
This update improves the appointment booking experience by placing the guest option after all registration questions, so customer forms appear in a more logical order. It also corrects when the “Add Closing Day(s)” button appears, ensuring it is available for resource bookings and hidden for staff bookings as intended.
Original PR description
Purpose ======= Fix various interface issues related to the appointment app following the Testing Days for v19. Specification =========== - Placing add guests button after registration questions on…
Purpose ======= Fix various interface issues related to the appointment app following the Testing Days for v19. Specification =========== - Placing add guests button after registration questions on front-end. Following the addition of a phone question type (odoo/enterprise#82973), the user phone input at registration is in the list of questions and not at the top of the form in the base user information section anymore. The Add Guests feature can thus be displayed before the phone number which seems a bit odd. Fixing the issue by moving the Add Guests feature at the end of the form, after the list of questions. - Fix the "Add Closing Day(s)" button visibility. The button should be visible on every resource views (gantt, calendar, list), and should be invisible on every staff booking views (gantt, calendar, list). Currently, the button is visible on the list view for staff bookings, it should not. The button is also not present on the calendar view for resource bookings, it should be. Task-5079021 Forward-Port-Of: odoo/enterprise#96027
Salary offers created from the Offers list now receive a valid access link, matching the behavior of offers generated from an applicant record. This prevents broken offer links and adds safeguards so public visitors cannot open offers tied to employees who should sign in.
Original PR description
#### Steps to Reproduce - Go to Recruitment > Applications > All Applications. - Open an applicant form and click "Generate Offer". - Repeat a few times so that the "Offers" smart button shows a list…
#### Steps to Reproduce - Go to Recruitment > Applications > All Applications. - Open an applicant form and click "Generate Offer". - Repeat a few times so that the "Offers" smart button shows a list view. - From the list view, click "New" to create an offer. - Compare both flows: * With "Generate Offer" button: the generated offer link has a valid token and works even in an incognito window. * With "New" button: the generated offer link has `token=False`, which leads to an invalid link. #### Issue In the first scenario, `action_generate_offer()` generates an `access_token` for the offer's link in `hr.applicant`. In the second scenario, no token was generated in `hr.contract.salary.offer`, so offers created via the "New" button end up with `access_token=False` in their links. #### Fix - Add a compute to `access_token` in `hr.contract.salary.offer` to generate a token if there is no employee or if the employee on the offer has no linked user. - Update controller logic to prevent public users from accessing an offer link if the offer's employee has a linked user. task-5051394 Forward-Port-Of: odoo/enterprise#98856
Employees and contract templates no longer require a Pay Category, so freelancers or people without an occupation can be managed without unnecessary setup. Payroll runs will automatically skip employees without a Pay Category, and form guidance now explains this behavior.
Original PR description
The field is always required in the employee and contract template form views, but a Freelancer, or people without occupation should not bother with it. There was a check on the pay category during the payslip creation which is now removed since the payslip is computed based on the pay structure on the payslip form not the one on the employee profile. Employees without a pay category will be excluded from pay runs, therefore the "Pay Category" placeholder in form views has been updated to indicate so. Task-5237800 Forward-Port-Of: odoo/enterprise#98921
The Philippines Summary Lists of Sales and Purchases report now correctly shows the Registered Name for company contacts. This prevents blank company names in the report and keeps exported files accurate for both companies and individuals.
Original PR description
**Steps to reproduce:** 1. Install the `Accounting` and `l10n_ph_reports` modules. 2. Create a contact with the company flag enabled. 3. Create an invoice using that contact. 4. Go to `Reporting →…
**Steps to reproduce:**
1. Install the `Accounting` and `l10n_ph_reports` modules.
2. Create a contact with the company flag enabled.
3. Create an invoice using that contact.
4. Go to `Reporting → Summary Lists of Sales and Purchases → Sales`.
**Observed behavior:**
* The `Registered Name` column in the report is blank for companies.
**Cause:**
* The query logic was incorrectly showing the registered name only when a last name was present. This issue arose due to the change in how company/individual differentiation is handled.
**Fix:**
* Update the query logic for the Odoo report:
- **Always display the registered name in the Odoo report**:
- If individual: show `First Name`, `Middle Name`, `Last Name`.
- If company: show `commercial_partner_id.name`.
- **For the export file**:
- If company: only show the registered name.
- If individual: show `First Name`, `Middle Name`, `Last Name`.
The fix ensures that **Registered Name** is always displayed in the report, and the export behaves as expected for both individuals and companies.
Note: spec provided by po ->
<img width="1662" height="431" alt="image" src="https://github.com/user-attachments/assets/a7a58a9e-b769-4815-ad0a-cef9c8e2eff7" />
opw-5143677
Forward-Port-Of: odoo/enterprise#99075Check messages in the EU OSS reports now display in a cleaner, more consistent format. This improves readability for users reviewing report checks and removes an awkward multi-line presentation issue.
Original PR description
Multi-line messages for checks are displayed on multiples lines starting in 19.0. This is ugly and we fix this so every checks have a similar look. Before: <img width="368" height="103" alt="image" src="https://github.com/user-attachments/assets/67bb84f9-ac61-4c0d-84ba-b8a886763546" /> After: <img width="337" height="74" alt="image" src="https://github.com/user-attachments/assets/4f45b368-cf60-4b46-b10a-dd1b75ceb9f9" /> Forward-Port-Of: odoo/enterprise#99772
This update ensures bills include the required bill date in accounting and localization workflows. It helps prevent validation errors and keeps Colombian DIAN, Spanish reports, prediction, and Intrastat purchase processes consistent.
Original PR description
task-5214234 Forward-Port-Of: odoo/enterprise#99650