Daily updates from Odoo
Tuesday, November 18, 2025
46 changes · master
Security fixes and vulnerability patches
Access permissions for online bank synchronization actions have been adjusted so most related actions are available to users responsible for invoicing and banks. More sensitive actions, such as duplicate handling and account field changes, remain restricted to help prevent accidental or unauthorized changes.
Original PR description
Most access right for Online Sync related actions should be Invoicing & Banks. Only Duplicate Wizard (because you can delete transactions easily) and Online Account Fields (because can change date without explicit showing) will be with other group. task-5149304 Forward-Port-Of: odoo/enterprise#96727
New functionality added to Odoo
Saudi payroll now includes a way to record and manage employee disciplinary actions when company policies are violated. The feature supports actions ranging from warnings to salary deductions, helping HR teams handle policy enforcement more consistently.
Original PR description
Added a new model: Disciplinary Actions. This model is aimed to provide disciplinary actions in case employees violated company's policies. Actions vary from verbal/mail warnings, to salary deductions. Task: 4890404
Adds a dedicated Phone dashboard to help teams monitor call-related activity from the spreadsheet dashboard area. This gives business users a clearer, ready-made view of VoIP performance and sample data for easier onboarding.
Original PR description
Task: 5180630
Indian payroll users can now generate a gratuity calculation report for selected employees in XLSX format. The report can be narrowed down by department, salary structure, job position, or employee tags, making it easier to review and export gratuity-related information.
Original PR description
Added Gratuity Calculation report wizard for Indian payroll localization. Exports report in XLSX format for selected employees. It can be filtered by department, salary structure, job position, or employee tags. task-4203939
Rental products can now be booked for specific parts of a day, including morning, afternoon, night, or a full day, with pricing adjusted to the selected period. This improves booking flexibility for customers and helps businesses price short or overnight rentals more accurately.
Original PR description
3 new periods: morning, afternoon, night. A product with a night unit will be rented from July 30 to July 31 for 1 unit. A product with a day unit will be rented from July 30 to July 31 for 2 units. The day unit is being considered by date now. Possibility to rent products by morning, afternoon, or full day on the same date. Price adapted based on the hours selected. Rental order dates are defined by the first rental period.
Enhancements to existing features
The Jordan payroll module was tidied up by removing unnecessary fields and making labels and tooltips clearer. This makes payroll setup and employee information screens easier to understand and reduces confusion for users.
Original PR description
In this commit, we made some general cleanup in the jordan payroll module, by removing uncessary fields, and improving naming of some existing fields in the UI + tooltips. task: 5176975
Payroll users can now set a priority order for salary adjustments, such as deductions or attachments. This helps ensure the most important adjustments are paid first when the available payroll amount cannot cover them all.
Original PR description
add priority to salary adjustments to but an order of which one should be paid first if the total amount paid does not cover all Task: 5114092
The yearly salary report by employee in Indian payroll has been simplified to make it easier to read and use. This helps HR and payroll teams review annual employee salary information more efficiently.
Original PR description
Simplified yearly salary report by employee format. task-5126551
The Gantt view’s date picker no longer uses an old display adjustment that was only needed for mobile fullscreen popovers. Since the picker now opens in a bottom sheet, this simplifies the experience without changing user workflows.
Original PR description
This was only used on mobile to display the date(time) picker in a fullscreen popover, to ensure that the picker had enough space to be fully displayed. The picker is now opened in a bottom sheet, so we can safely remove this. task-5131135
Point of Sale users in Belgium now see clearer error messages when the fiscal data module is disconnected or when required social security information is missing. The messages explain what action to take, helping staff resolve payment validation issues faster and reduce checkout disruption.
Original PR description
We now display an error when the FDM is disconnected, or when the user needs to fill in the social security number. We also advise what to do in such cases. Forward-Port-Of: odoo/enterprise#99546 Forward-Port-Of: odoo/enterprise#99285
Payroll users in Mexico can now generate a CFDI document for an entire pay run once it is ready, instead of handling payslips one by one. This streamlines payroll processing and helps teams complete required electronic payroll documentation more efficiently.
Original PR description
This adds a button to generate a CFDI for the whole payrun when ready. Task: 5224206 Forward-Port-Of: odoo/enterprise#98797
This update simplifies how the AI feature manages chat windows by removing an outdated internal closing mechanism. It helps keep the messaging experience more consistent and easier to maintain, with minimal visible impact for users.
Original PR description
PR community: https://github.com/odoo/odoo/pull/234289
The payroll screens now hide salary rules that are already assigned when users add inputs for employees or payslips. This reduces duplicate selections and makes payroll setup faster and less error-prone.
Original PR description
Previously the list shown when the "Add Inputs" button was clicked on an employee's payroll tab in their form view, it would show all the available salary rules that is available to the employee's salary structure even if they were already assigned to that structure. This commit hides the already existing rules from the list. The same concept applies to payslips. Task-5138584
UAE employee cost calculations now include housing, transportation, other allowances, and relevant employer contributions. This gives businesses a clearer view of the true total cost of employing staff in the UAE.
Original PR description
Before this commit: - The employer costs section (Yearly and Monthly cost) not considered allowances. - This led to an inaccurate calculation of the actual employer cost. After this commit: - Added l10n_ae_hr_contract_salary benefits so Housing, Transportation, and Other allowances are included in employer costs. - This provides a more accurate reflection of the employer's total cost for an employee. Task-5065776
The UrbanPiper point-of-sale enhancements have been merged into the main UrbanPiper POS module. This simplifies maintenance and keeps related restaurant ordering, store timing, and preparation display capabilities together in one place.
Original PR description
In this commit: === - Merged the `pos_urban_piper_enhancements` module into the `pos_urban_piper` module to consolidate features and ensure streamlined functionality. Related: https://github.com/odoo/upgrade/pull/7042
Payroll users can now open an email composer directly from a payslip to send or resend it by email. This makes the process more consistent with other Odoo actions and reduces manual steps when sharing payslips with employees.
The default VOIP call graph now organizes calls by the week they were created instead of by user. This makes the report faster and easier to read when there are many users, while showing the time-based view users are most likely to need.
Original PR description
By default, the graph view of voip.call should be grouped by week of create_date instead of by user. When it is grouped by user we risk to have something that is too heavy, whereas it is never too heavy when it is by week even with many users. And it is what the user would be the most likely to want to see. We are choosing to use create_date instead of start_date because there is no risk that create_date is empty. task-5266035
Payroll users can now start a group salary adjustment from a wizard, which automatically creates a separate adjustment for each selected employee. This reduces confusion and prevents partially completed shared adjustment records by ensuring every salary adjustment belongs to one employee.
Original PR description
Purpose: Creating Salary Adjustment for multiple employees is weird, can lead to half-finished lines. It would be more simple to adopt same flow as Time Off Multi-Request, a wizard that will create multiple 1-1 Salary Adjustment. Current behavior: - added button `New group Sal. Adjustment` to open the wizard for creating multiple salary adjustments. - trasformed the field `employee_ids` on `hr.salary.attachment` into many2one `employee_id` to have each adjustment linked to only one employee. - added `test_salary_adjustment_multi_wizard` to test the multi adjustment generation - removed test `test_action_split_preserves_all_values` as the split logic is removed because there will be always only one employee for each attachment task-id: 5173000
The VoIP call field previously labeled "Responsible" is now labeled "User". This makes the wording clearer and more consistent for people reviewing or managing VoIP call records.
Original PR description
Task-5266072
The VoIP keypad buttons have been refined to make them easier to use, especially on mobile devices. The “Show more” layout is now more consistent across VoIP views, creating a smoother and more predictable calling experience.
Original PR description
This commit refines the keypad button design to improve usability on mobile devices. It also harmonizes the layout of the "Show more" component across allviews. task-5172842  
The legacy QUnit test assets were reduced to only what is still needed for remaining older tests. This cuts bundle size substantially, making test assets faster to generate and load without changing business features.
Original PR description
As the QUnit test suite is now legacy and trimmed down to basically only test PublicWidget and alike, the asset bundle could be also dramatically reduced. This commit cleans it up to only let the requirements for the last QUnit tests to properly run. Note: in term of bundles sizes, it goes from 26MB to 1.5MB (faster to load but more so, faster to generate).
Turkish payroll now supports advance salary payments for employees going on regular or sick leave. This helps companies follow common local payroll practices and improves payroll accuracy for leave-related payments.
Original PR description
As companies in Turkey, should pay their employees an advanced salary when employees go on leave. Also, it is also a common practice that companies pay the employees an advanced salary when they go on sick leave. Task: 4910992
Website pages now automatically show helpful tooltip messages wherever they are configured. This reduces custom setup work and makes it easier to provide guidance to visitors consistently across online sales and rental pages.
Original PR description
* : website_sale_renting. Purpose: ====== This commit introduces default support for Bootstrap tooltips across all website pages. Before this commit: ======= Tooltips had to be manually initialized or handled case by case in JavaScript for each snippet/page with a specific Interaction. After this commit: ======= Any HTML node with the attribute `data-bs-toggle="tooltip"` automatically displays a Bootstrap tooltip without requiring custom initialization code. Task-5249371
Saudi payroll now calculates end-of-service benefits using actual service duration and legal year-based rules, improving accuracy for resignations, contract endings, and retirement. Payslip provisions also better reflect each employee's employment duration, with clearer labels and added validation tests.
Original PR description
- adjusted the calculation of end of service benefit to use actual number of days 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 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 Forward-Port-Of: odoo/enterprise#96404
Confirmation dialogs now use specific action words instead of generic labels like Ok or Cancel. This makes important decisions easier to understand and helps users avoid mistakes across several business workflows.
Original PR description
Improve the clarity of confirmation dialogs by replacing generic "Ok/Cancel" labels with descriptive, action-oriented verbs. This helps users understand the impact of their decisions and reduces ambiguity in critical actions. Task-5106240
When the Appraisals module is installed, users can now see the Details page where relevant job information is displayed. This makes appraisal-related job setup clearer and easier to access without changing broader HR workflows.
Original PR description
- Display the Details page if the hr_appraisal module is installed. task-5215960
The VoIP softphone now collapses automatically when users open the call history. This makes it easier to review past calls without the softphone panel taking up unnecessary screen space.
Original PR description
Task-5273218
Resolved issues and error corrections
This fixes a crash that could happen when certain accounting report screens used manually generated data models. The affected pages now include the required service, helping users access account return and report views reliably.
Original PR description
With this PR: https://github.com/odoo/odoo/pull/229492, comes a new service which is needed on models. Without this service on our manually generated models, this would crash because it was trying to access an undefined variable.
Approved late hours for Saudi employees are now included when generating payslips. This ensures payroll deductions or calculations tied to lateness are reflected correctly and consistently after module installation.
Original PR description
Reproduce 1. create an attencande for SA employee with latehours 2. approve latehours 3. create a payslip for this employee. you will not find the hours reflected to the payslip Issue the property input rule that take the late hours amount was missed Solution add the rule back and make sure it is added to the defention on the module installation Task: 5253150
The Ask AI action now handles cases where a user has multiple AI chat channels without crashing. It also starts a fresh AI chat from the main entry point and removes a duplicate search-view button, making the experience more reliable and less cluttered.
Original PR description
When multiple AI chat channels existed for the same agent/user, `_get_or_create_ai_chat` could return several records. This caused a singleton error when calling `action_ask_ai` because the code expected a single channel record. This commit filters a single record so that only one channel is returned, preventing the crash. And also 'action_ask_ai' will now always opens a new ai chat. Additionally, the redundant 'Ask AI' button in the search view has been removed, as the same functionality is already available from the systray. task-5107276 Forward-Port-Of: odoo/enterprise#95585
The OCR process will no longer automatically change a customer invoice into a sale receipt when the Sale Receipt option is not enabled. This prevents documents from being categorized into a disabled workflow and helps keep invoice processing aligned with company settings.
Original PR description
If the "Sale Receipt" setting isn't enabled, the OCR should never automatically switch a customer invoice to a sale receipt. task-[5265382](https://www.odoo.com/odoo/project.task/5265382) Forward-Port-Of: odoo/enterprise#99522
Payment reminder emails now send any files and dynamic reports configured on the selected email template. This ensures customers receive the complete follow-up information intended by the business, reducing missing-document issues and manual resend work.
Original PR description
### Issue: We can add attachments and dynamic report to the email templates, but they are not sent with follow-ups. ### Steps to reproduce: - Go to the "Payment reminder" email template - Under the…
### Issue: We can add attachments and dynamic report to the email templates, but they are not sent with follow-ups. ### Steps to reproduce: - Go to the "Payment reminder" email template - Under the page "Content", add an attachment by clicking the "Attachments" button - Under the page "Settings", add a dynamic report - Create an overdue invoice for a partner - Go on the form view of the partner, "Accounting" page - Click "Send", make sure the template used is the one with the attachments - Send - The attachments on the template and the dynamic report are not sent ### Cause: The mail template to send the follow-ups is only used to prefill the wizard. ### Solution: Add the template in `_get_wizard_options()` to add the template in the option and later use it to add/generate its attachments. This commit also refactors how the attachments are computed: The previous code was adding the invoices PDFs then removing them. The whole process was confusing. Now `options['attachment_ids']` is appended in `_get_followup_attachments()` with the desired attachments depending on the options. Also `_get_invoices_to_print()` had unnecessary lines. The options are always initiated before calling the method and the condition on "manual_followup" is useless as the invoices are already in options['attachment_ids'] when coming from the wizard. opw-5147736 Forward-Port-Of: odoo/enterprise#99458 Forward-Port-Of: odoo/enterprise#98454
Payroll PDF generation now handles certain report errors without stopping the scheduled process. If one employee declaration cannot be generated, the error is saved on that record and the system continues processing the remaining payroll documents.
Original PR description
When rendering PDF files, `_get_rendering_data` is expected to return a dict with the key `error` when needed. Some localizations respect this correctly, but others will raise an UserError instead. In particular, the `Payroll: Generate pdfs` cron will keep trying to generate the file and the `UserError` will never be caught, so the scheduled action will eventually be deactivated. With this fix, the exception is caught, the message is recorded on the sheet, and the PDF is skipped. The cron will then keep processing the other records. Source: investigation after the cron got disabled on our server Forward-Port-Of: odoo/enterprise#99490
When a cashier tries to sync orders while the Belgian blackbox connection is unavailable, affected orders are now returned to draft instead of remaining stuck. This lets staff retry the sync once the connection is restored, reducing checkout disruption.
Original PR description
When trying to sync orders while being offline, a `ConnectionLostError` is raised. This error was not handled in the pos_blackbox_be module. Now, if an order was not signed correctly by the blackbox, we put its state back to "draft", allowing the cashier to retry later (when the connection to bbox is re-established). Forward-Port-Of: odoo/enterprise#99202 Forward-Port-Of: odoo/enterprise#98778
This fix ensures automated tests properly finish drag-and-drop actions before ending. It helps prevent false test failures and supports more stable quality checks for scheduling-related features.
Original PR description
Since drag sequences are automatically canceled at the end of tests, 'cancel' or 'drop' calls should be properly awaited before the end of a test. This commit ensures that these actions are properly finished before a test ends. Community: https://github.com/odoo/odoo/pull/235359 Forward-Port-Of: odoo/enterprise#99634 Forward-Port-Of: odoo/enterprise#99369
This fix restores the ability to add reactions to messages when using Discuss on a mobile device. It improves day-to-day collaboration by making quick responses work consistently across desktop and mobile.
Original PR description
Task-4607436 Task-5261880 https://github.com/odoo/odoo/pull/235852 Forward-Port-Of: odoo/enterprise#99588
VoIP contact search now avoids checking mobile phone matches until at least three characters are entered. This prevents error messages from appearing while users type the first few digits or letters, making the search experience smoother.
Original PR description
`phone_mobile_search` doesn't allow you to search for less than 3 characters. This commit excludes `phone_mobile_search` from the search domain when there are less than 3 characters. This avoids triggering an UserError on the first characters typed. Forward-Port-Of: odoo/enterprise#99626 Forward-Port-Of: odoo/enterprise#99548
Fixes an issue where switching variants on subscription products in the online shop could trigger an error when no pricing was available. The system now handles missing pricing safely, helping customers browse subscription product options without interruption.
Original PR description
Step to reproduce: - install website_sale_subscription - create a product, add few variants and tick 'Subscriptions' option. - open that product from /shop - toggle between variants Cause: - In case the pricing is not present, 'False' is passed(not an iterable) - `_onChangeCombinationSubscription` expects a iterable, causing traceback Fix: - we pass empty list instead of False opw-5241612 Forward-Port-Of: odoo/enterprise#99160
Studio no longer crashes when users edit JSON-based fields such as analytic distribution. The update lets these fields handle placeholder settings correctly, improving reliability when customizing forms.
Original PR description
When trying to edit the `analytic_distribution` field using Studio, the following traceback occurred: `Caused by: TypeError: Cannot read properties of undefined (reading 'subOptions')` This happened because the new option `placeholder_field` was [introduced](https://github.com/odoo/odoo/commit/6620ebbd184de6f106fceb4427a081b61d97296a) for dynamic placeholders in widget. However, there was no support declared for `placeholder` inside the `FIELD_TYPE_ATTRIBUTES` definition for the `json` field type. This commit adds `EDITABLE_FIELD_ATTRIBUTES.placeholder` to the `json` field type, allowing widgets on JSON fields to correctly handle `placeholder_field` options without causing a Studio crash. opw - 5180896 upg - 3249816 Forward-Port-Of: odoo/enterprise#98526
This fix prevents Belgian tax return generation from crashing when a company’s fiscal year is configured to end on February 29. The date calculation now handles leap-year settings correctly, helping migrations and return generation complete reliably.
Original PR description
``` File "/tmp/tmpm_3a__2e/migrations/account_reports/saas~18.3.1.0/end-account-returns.py", line 340, in migrate generate_or_refresh_all_returns(company) File…
```
File "/tmp/tmpm_3a__2e/migrations/account_reports/saas~18.3.1.0/end-account-returns.py", line 340, in migrate
generate_or_refresh_all_returns(company)
File "/home/odoo/src/enterprise/19.0/account_reports/models/account_return.py", line 228, in _generate_or_refresh_all_returns
self._generate_all_returns(fiscal_country.code, company, domestic_tax_unit)
File "/home/odoo/src/enterprise/19.0/l10n_be_reports/models/account_return.py", line 24, in _generate_all_returns
super()._generate_all_returns(country_code, main_company, tax_unit=tax_unit)
File "/home/odoo/src/enterprise/19.0/account_reports/models/account_return.py", line 281, in _generate_all_returns
report_type._try_create_returns_for_fiscal_year(main_company, tax_unit=tax_unit)
File "/home/odoo/src/enterprise/19.0/account_reports/models/account_return.py", line 353, in _try_create_returns_for_fiscal_year
period_date_from, period_date_to = self._get_period_boundaries(main_company, date_pointer)
File "/home/odoo/src/enterprise/19.0/account_reports/models/account_return.py", line 530, in _get_period_boundaries
start_day, start_month = self._get_start_date_elements(company_id)
File "/home/odoo/src/enterprise/19.0/l10n_be_reports/models/account_return.py", line 16, in _get_start_date_elements
fiscal_year_date = date(2025, int(main_company.fiscalyear_last_month), main_company.fiscalyear_last_day)
ValueError: day is out of range for month
```
```
(Pdb) main_company
res.company(3,)
(Pdb) main_company.fiscalyear_last_month
'2'
(Pdb) main_company.fiscalyear_last_day
29
(Pdb) date_from
datetime.date(2025, 3, 1)
```
- During the migration process the system calls [_generate_or_refresh_all_returns](https://github.com/odoo/upgrade/blob/e20a9e2edec4441b2c7aa5858db2a53fb2e9b215/migrations/account_reports/saas~18.3.1.0/end-account-returns.py#L340) which internally uses [_get_start_date_elements](https://github.com/odoo/enterprise/blob/ebdc2fe2ade72b1505dac5490b7df2a1d06fcb4b/l10n_be_reports/models/account_return.py#L14) to compute the fiscal year start date.
- The customer has configured fiscalyear_last_month = February and fiscalyear_last_day = 29 Because of this configuration, the method attempts to construct 29th February 2025, which is invalid since 2025 is not a leap year. The issue occurs because the method uses a hardcoded year [(2025)](https://github.com/odoo/enterprise/blob/ebdc2fe2ade72b1505dac5490b7df2a1d06fcb4b/l10n_be_reports/models/account_return.py#L16) instead of determining the year dynamically.
- I reviewed implementations in other localizations and found that this logic has [1](https://github.com/odoo/enterprise/blob/ebdc2fe2ade72b1505dac5490b7df2a1d06fcb4b/l10n_uk_reports/models/account_return.py#L33), [2](https://github.com/odoo/enterprise/blob/ebdc2fe2ade72b1505dac5490b7df2a1d06fcb4b/l10n_nz_reports/models/account_return.py#L8) already been corrected there to compute the appropriate start date dynamically.
- I’ve updated this localization to follow the improved implementation used in other countries, so the start-date calculation now works correctly in all cases, including leap years and any fiscal year settings the customer may configure.
opw-5249243
Forward-Port-Of: odoo/enterprise#99353The VoIP keypad now keeps numbers inserted in the intended place when users tap digits after moving the cursor. This prevents dialing errors on Android when the phone keyboard is hidden and the input loses focus.
Original PR description
Keypad input now reads selection from the persisted model whenever the DOM selection isn't trustworthy, particularly on Android where the input blurs to hide the keyboard, so digits typed at any cursor location stay in place. task-5241464
The appointment booking error message now clearly includes the appointment type name when there are not enough seats available. This makes the issue easier for users to understand and resolve when saving appointments without resources.
Original PR description
Currently, when creating a new appointment with a specified number of people but no resources, saving the record triggers a UserError that does not display the appointment type name. Issue: 2 seats are missing to be able to book the appointment.type(1,): Table (30) <img width="1813" height="776" alt="image" src="https://github.com/user-attachments/assets/f87f45de-3552-47bb-b34c-fcc06cea425f" /> Solution: 2 seats are missing to be able to book the Table: Table (30) <img width="1769" height="905" alt="image" src="https://github.com/user-attachments/assets/04188071-be67-4500-b720-039ee7a27c2e" /> Forward-Port-Of: odoo/enterprise#99646
This fixes an issue where portal users could see an error when sending an attachment in a live chat with an agent. The change ensures the user availability field is properly set, helping chats continue smoothly without interruption.
Original PR description
Bug === As portal, open a live chat with an agent, and try to send an attachment. An error will be raised because of `offline_since` (which is not initialized in the compute). Task-4687269
Code cleanup and technical improvements
The Enterprise-only Share URL menu and related mobile menu button have been removed because this capability now lives in the community web module. This reduces duplicate maintenance while keeping the feature available where progressive web app support is now shared.
Original PR description
This commit removes the code related to the Share URL menu item from the enterprise version of odoo, since the code has been moved to the community version. It was no longer relevant to support only this menu item and BurgerMenu button in enterprise, since PWA are also installable in the community version. Tests have been moved as well in the /web module of community.
The WhatsApp integration has been internally reorganized so chat channel detection now sits with the discussion channel model. This should not change user behavior, but it makes the code easier to maintain and align with the related community update.
Original PR description
This commit moves isChatChannel to discuss.channel model. PR community: https://github.com/odoo/odoo/pull/235983
This update reorganizes how AI features read conversation channel information, making the implementation cleaner and easier to maintain. There is no expected change in day-to-day behavior for users, but it helps keep AI-related messaging features reliable as the platform evolves.
Original PR description
PR community: https://github.com/odoo/odoo/pull/235260