Daily updates from Odoo
Navigate
Branch
Tuesday, August 26, 2025
41 changes
Security fixes and vulnerability patches
This fix ensures sensitive payroll details, such as salary and contract information, are only visible to authorized payroll or HR manager users. It also improves payroll-related employee record handling so routine HR updates avoid access errors and unnecessary processing.
Original PR description
Forward-Port-Of: odoo/enterprise#89553
This update tightens who can access IAP account tokens used by several document extraction, tax, and signing services. It helps protect sensitive service credentials while keeping the affected business workflows working as expected.
Enhancements to existing features
The salary contract page was updated to use a newer internal web approach instead of older browser code. This helps keep the HR salary contract experience maintainable and aligned with current platform standards without changing core business workflows.
Original PR description
wip
Payroll teams can now manage salary adjustments directly from an employee record in a dedicated tab. The new view shows key details such as type, dates, amount, payment progress, remaining periods, and status, making salary attachment follow-up clearer and more centralized.
Original PR description
- Add a tab Salary Adjustments in the employee - Add a list view with Type, Start, Note, Amount, Until and Status (optional hide, Amount Paid (computed from payslips lines), Periods Left, End Date) -Add a line opens a form view popup. One column for the inputs, the other is for the description Task: 4930543
Brazilian localization users can now set a CFOP code directly on operation types, giving businesses more control over how fiscal operations are classified. This value is used consistently in tax calculation and electronic invoicing, reducing manual corrections and helping align invoices with local tax requirements.
Original PR description
In this PR: - Added `l10n_br_cfop_code` field to operation types in form view for providing users with greater flexibility in selecting the appropriate CFOP. - Modified Avatax tax calculation service to send the custom CFOP value when configured, overriding automatic determination. - Updated invoice line CFOP computation logic to prioritize operation type override over standard Avatax response. - Modified EDI submission to preserve CFOP overrides by re-applying them when reusing stored Avatax tax calculation data. Task-4947957
The OCR document processing flow no longer creates extra database checkpoints while fetching results. This reduces overhead when many documents are processed at once, improving performance with minimal user-facing change.
Original PR description
Very similar to commit 7f7ff8d, see full explanation in that commit message. This savepoint was also initiated in a loop which could cause performances issues when too many of them are active at the same time. This one is much less critical and can be removed without much trouble. It was only allowing to recover from a serialization failure, in the case where a user was concurrently editing a document while it was being updated by the OCR. Forward-Port-Of: odoo/enterprise#93000
French VAT report exports now combine tax declarations and related reimbursement requests into one submission. This reduces duplicate export steps and improves tracking of each included document through the external filing process.
Original PR description
This commit merges the tax export and tax reimbursements into a single export. New model `account_report_async_document` was created for handling document specific fields, like `deposit_uid`, `declaration_uid`, `state`, and the logs, as these fields are set from the response of the ASPone API. Before this commit, we couldn't merge multiple documents into a single export due to these fields. These fields were removed from the `account_report_async_export` models and moved to the `account_report_async_document`. Also, most methods in `account_report_async_document` are taken from `account_report_async_export` with minimal changes. The export creation was modified to account for handling multiple documents. task-4546529
Hong Kong payroll will no longer automatically include a 200 HKD internet allowance. This avoids applying an arbitrary allowance that is not considered common practice, helping payroll defaults better match typical business needs.
Original PR description
Removes the default 200 HKD of internet allowance, as it is not a common practice in any way to give it, and the 200 is arbitrary and is also not common practice of any kind. task-5010960
Manufacturing planners can now open a suggestion pop-up in the Master Production Schedule to estimate and fill forecasted demand for a selected product. Suggestions use historical or actual demand across periods, helping teams plan faster and with less manual entry.
Original PR description
This PR enables the user to use a pop-up suggestion for the MPS. The tool suggests for the user the forecasted demand and fills it out in all periods for the chosen product in the MPS based on historical demand (last year, before last year or actual demand). If the user chooses to apply the suggestion for a certain period and not all the periods in MPS, the suggestion will be based only on last year. Task-4827486
The departure process now gives HR teams the option to remove a departing employee’s linked user account when archiving the employee. This helps streamline offboarding and reduces the chance of inactive staff retaining system access.
Original PR description
When you archive an employee and he has a user we need to have the ability to remove this user from the departure wizard Task: 4680081
Mexican accounting now uses dedicated accounts for credit notes, discounts, bonuses, returns, and certain POS re-invoicing entries instead of mixing them with regular sales. This helps businesses comply with local accounting rules and better see how much revenue was reduced by these operations, while allowing users to customize the default accounts.
Original PR description
[IMP] l10n_mx_*: provide different account for credit notes modules: l10n_mx_reports, l10n_mx_edi, l10n_mx_edi_pos When handling credit notes for accounting purposes it's not correct (or even legal…
[IMP] l10n_mx_*: provide different account for credit notes modules: l10n_mx_reports, l10n_mx_edi, l10n_mx_edi_pos When handling credit notes for accounting purposes it's not correct (or even legal in mexico) to use the same account for anything related to credit notes (discounts, bonuses or returns). Instead, all of these are accounted for in a different account that reduces the sales but also tell us how much of the sales were reduced by this account. This commit provide an account for these cases, and make it customizable for the user to set the account he wants (with a setting in the 'Default Accounting' section). Also, POS returns are now associated with this account. A second account is created to handle the "re-invoicing" concept: when a pos order is done and the session is closed, if the customer wants to self-invoice the system perform a reversal of the session and create 2 new invoices, 1 for the customer and 1 for all other orders from the original session. The new account is associated to the debit lines of the reversal (not vat), the credit lines of the customer invoice (not vat) Task-4576187
Users can again mark individual invoices or journal items so they do not trigger customer payment follow-ups. Follow-up reports, exports, and reminder emails now exclude those marked items, while entries without due dates are shown as due rather than overdue.
Original PR description
During the [rework of the follow-up report][1], we removed the "No Follow-Up" field from journal items, making it impossible to exclude individual journal items from triggering a follow-up. In the…
During the [rework of the follow-up report][1], we removed the "No Follow-Up" field from journal items, making it impossible to exclude individual journal items from triggering a follow-up. In the related community commit, we re-introduce a field for that, since it is a common requirement to be able to exclude individual items from the follow-up reports. In this commit we do the following: 1. Adapt the Follow-Up Report and Customer Statement variants of the Partner Ledger to add a toggle for the "No Follow-Up" field on each report line, that toggles the field on the corresponding journal item(s). 2. Prevent the follow-up status on the partner to change when all of the overdue journal items are marked as "No Follow-Up". 3. Make sure users can toggle the "No Follow-Up" setting on the invoice level when opening the "Overdue Invoices" view from the partner's "Accounting" tab. 4. Make sure all receivable/payable lines without a due date (either from a manual miscellaneous entry or a PoS entry) are put under the "Due" section is the Follow-Up Report instead of the "Overdue" section. Since there is no due date, they can't be overdue. [1]: https://github.com/odoo/odoo/commit/67dc71588751c9f115e09959d774686c2207a1f9 [task-4632300](https://www.odoo.com/odoo/project.task/4632300) Related to https://github.com/odoo/odoo/pull/203329
Enterprise payroll and localization reporting tests were updated to follow the new default tax rounding behavior. This helps ensure Odoo's business calculations stay consistent across community and enterprise versions without requiring extra configuration.
Original PR description
**Purpose**: --- - Align enterprise tests with the community change setting 'Round per Tax Group' (round_globally) as the default tax rounding method. **Changes**: --- - Removed explicit round_globally configuration in tests (now default). - Updated “Round per Line” test cases to run under the global rounding setting. - Adjusted expected results to match the new computation behavior. community pr- https://github.com/odoo/odoo/pull/221027 task-4971648
Audit report PDFs now include the styling needed to display edited content more consistently and professionally. Layouts, checklists, icons, tables, and common formatting options render more clearly, making reports easier to read and present.
Original PR description
This commit embeds the required Bootstrap assets into the HTML pages used for generating audit report PDFs. By leveraging Bootstrap's styles, the reports now have a cleaner, more professional appearance, and many of the blocks from the HTML editor are rendered with consistent, high-quality formatting. The column layout (`/column`), the checklists (`/checklist`), the icons (`/image`), etc will be displayed properly on the PDF. In addition to that, the tables will span over the entire page width making them more readable and some of the Bootstrap utility class will now also be supported (such as `bg-100`). Note: `wkhtmltopdf` does not support CSS variables, which prevents some Bootstrap rules from applying as intended. To address this, `bootstrap_review_report.scss` includes targeted workarounds to replace certain variable-based properties, ensuring the styles remain consistent in the PDF output. Task-4989809
Resolved issues and error corrections
Planning calendar invites can now be exported even when a shift has no employee assigned. The system uses a safe fallback timezone, preventing an error and ensuring managers can still send or download calendar invites.
Original PR description
Currently, an error occurs when a user tries to export a calendar invite (ICS) for a planning shift that has no assigned resource. **Steps to reproduce:** - Install the `planning` module. - Go to `Planning > New`, and click `Publish & Send`. - Enable developer mode and go to `Settings > Technical > Email > Emails`. - Open the latest email record and click `iCal/Outlook`. **Error:** `AttributeError: 'bool' object has no attribute 'upper'` **Root Cause:** At [1], when no employee is assigned to the shift, `slot.employee_id` is `empty`, so `slot.employee_id.tz` is `False`, which leads to an error. This commit ensures a valid timezone is always used by selecting the current user's timezone or 'UTC' when the shift has no assigned employee. [1] https://github.com/odoo/enterprise/blob/13ce65b8ca61f9a825f2876e2727cddfae83f894/planning/controllers/main.py#L355 sentry-6781639319 Forward-Port-Of: odoo/enterprise#92984 Forward-Port-Of: odoo/enterprise#91889
Cancelling selection or numeric filter setup no longer leaves an extra side panel open. This keeps spreadsheet filter configuration cleaner and avoids confusing stacked panels for users.
Original PR description
…numeric filter Steps to reproduce: - Open the global filter side panel - Click on selection filter or numeric filter - Click on cancel => Two side panels are stacked. Commit 51f2d18f5952a63ced1ed8e1b252650cffc50c2a already fix this issue, but selection and numeric filter were forgotten. Task: 5042490
A misplaced internal method has been moved to the right area so AI-powered livechat channels can start and run properly. This fixes a regression that could prevent businesses from using AI assistance in livechat conversations.
Original PR description
[FIX] ai_livechat: move method to the correct model In 5fc0a49, `_get_or_create_ai_chat` and all the methods that it uses internally were moved from `discuss.channel` model into `ai.agent` model. However, one method `_get_ai_channel_type_domain` was not moved by mistake which prevented livechat channels with AI from working properly. This commit moves the method to the correct model (ai.agent). The commit also fixes references to the moved methods so that they are called from `ai.agent` model instead of `discuss.channel` model.
This fixes an issue in Indian GST reports where matching purchase bills by IRN could fail unexpectedly. The required matching information is now always set, helping bill matching complete reliably and avoiding runtime errors.
Original PR description
Before this IR: - When a purchase document was matched using the IRN number, the variable `matching_keys` was not defined. - This led to an `UnboundLocalError` during bill matching. After this PR: - `matching_keys` is now set together with the IRN number. - This ensures `matching_keys` is always available and prevents runtime errors when IRN matches bills. opw-5037128 Forward-Port-Of: odoo/enterprise#93051
This fix lets Odoo Quality IoT distinguish between multiple connected cameras, so businesses can use more than one camera at the same time without device conflicts. It also improves camera communication reliability by preventing a websocket error when sending camera data.
Original PR description
Due to an issue with the `CameraInterface`, the same identifier would be chosen for any connected camera (`camera-2`), meaning only one camera could be used at once. To fix this, the `camera.id`…
Due to an issue with the `CameraInterface`, the same identifier would be chosen for any connected camera (`camera-2`), meaning only one camera could be used at once. To fix this, the `camera.id` property is used as the identifier instead. The `libcamera` documentation says the following: > The camera ID is a free-form string that identifies a camera in the > system. IDs are guaranteed to be unique and stable: the same camera, > when connected to the system in the same way > (e.g. in the same USB port), will have the same ID across both > unplug/replug and system reboots. However, we will also still return the last camera with the `camera-2` identifier, so that existing device configurations in the backend don't get lost. In master we will remove this legacy identifier. You can see the legacy camera with the others in the list below: <img width="801" height="385" alt="image" src="https://github.com/user-attachments/assets/6f3a6408-bcb4-46b0-980e-b5a8881f6df0" /> In addition, another small fix was made to the `CameraDriver` to ensure a string is sent rather than raw bytes, this prevents a traceback when communicating over the websocket. task-4792552 Forward-Port-Of: odoo/enterprise#93076
Work entries are now calculated correctly for employees on flexible schedules when they record attendance during a public holiday. This prevents short gaps between attendances from being incorrectly counted as a full 8-hour work entry, improving payroll and time tracking accuracy.
Original PR description
### Steps to reproduce: - Set Marc Demo's contract work entry source to attendances and working schedule to flexible hours. - Create a public holiday with generic time off work entry type. - Create…
### Steps to reproduce: - Set Marc Demo's contract work entry source to attendances and working schedule to flexible hours. - Create a public holiday with generic time off work entry type. - Create one or multiple attendances for marc demo on the public holiday. - Regenerate work entries for marc demo for that day, the gaps in between the attendances created and the working hours will be filled with work entries with the right start/end time but duration will always be 8h. ### Cause: This is happening because when getting the duration batch for the work entry we get the attendance intervals the employee should work in that period and if the employee is flexible we will get a fake attendance with the number of hours required per day ignoring if the period is just a small period of the day ### Fix: We are checking now since the start date not monday so we don't set a fixed week start. We check if the period is less than the remaining hours we get it as it mostly means that it is less than one day opw-4887933 Forward-Port-Of: odoo/enterprise#92519 Forward-Port-Of: odoo/enterprise#90163
The payroll setup now prevents saving group insurance rates that are zero, negative, or 100% and above. This helps avoid incorrect contract payroll data and reduces the chance of downstream payroll calculation issues.
Original PR description
Prevent users from entering invalid percentages in the `l10n_be_group_insurance_rate` field by adding a `constraint` that warns the user if the input is less than or equal to 0 or greater than or equal to 100. task-4982158
When invoice OCR finds several contacts with the same VAT number, it now chooses the contact with the strongest customer or supplier relationship instead of an arbitrary match. This helps invoices link to the correct partner when companies have multiple addresses or related contact records.
Original PR description
It's possible that multiple partners are sharing the same VAT number, for example, when multiple addresses are set on it (each address will be a child `res.partner` with the same VAT number). Previously, when the OCR matched such partners from their VAT number, it would select one "at random" (based on the default sort of `res.partner`). Now, it will match the one with the highest supplier/customer rank. opw-[4954057](https://www.odoo.com/odoo/49/tasks/4954057) Forward-Port-Of: odoo/enterprise#92398
Swiss payroll declarations now include contact person details only when all required contact fields are filled in. This helps prevent incomplete information from being sent during ELM transmissions, reducing submission errors and follow-up work.
Original PR description
Contact person information should only be transmitted if all 3 fields are filled Forward-Port-Of: odoo/enterprise#93084
This fixes an access error that prevented regular users from opening the Dashboard app. Users can now view dashboards without being blocked by an internal permissions issue, improving reliability for day-to-day reporting.
Original PR description
Steps to reproduce: - login as a regular user - open the Dashboard app -> "You are not allowed to access 'Model Data' (ir.model.data) records." runbot-error-230950
This update makes the AI live chat handling more reliable by separating how the system finds different types of AI chat channels. It also cleans up internal access to AI chat actions, reducing the chance of incorrect chat matching while keeping the user experience unchanged.
Original PR description
- In bc4929a0, controller methods were added to call 'post_error_message' , 'close_ai_chat' and 'generate_response' and all orm.call usages that referenced these methods were turned into rpc calls.…
- In bc4929a0, controller methods were added to call 'post_error_message' , 'close_ai_chat' and 'generate_response' and all orm.call usages that referenced these methods were turned into rpc calls. Hence, the visiblity of these methods can be changed to private. Note: 'generate_response' was also renamed because there is already a private '_generate_response' method. - The `_get_or_create_ai_chat` method was changed to receive channel_id parameter to be used for retrieving the ai chat channel if exists. However, this caused a bug because the more than one chat channel could be retrieved by the channel while all the flows that depend on`_get_or_create_ai_chat` expect only one. To fix this, retrieving an ai chat channel was separated into two methods. - `_get_ai_chat_channel` which retrieves channels of type `ai_chat`. All the flows ensure that there will only be one `ai_chat` channel. - `_get_ai_channel_from_id` which receives channel_id parameter and retrieves the ai channels of any type, namely `ai_chat` or `livechat`.
Belgian payroll users now see a clear error when trying to change an employee's working schedule without a contract start date. This prevents an unexpected system crash and guides users to correct the missing employee contract information first.
Original PR description
Prevent the apparition of a traceback when changing the schedule through the wizard Forward-Port-Of: odoo/enterprise#91880
The contract offer screen now hides the signature request button for users who cannot access the related request. This prevents users from clicking a button that would lead to an error, while keeping it visible for authorized users such as signature administrators.
Original PR description
Before this PR, when logged in as a different user from the one responsible for counter-signing the contract, the smart button still showed, and clicking on it caused an error. This PR fixes that, by hiding the smart button when there are no accessible signature requests. Note that sign admins will still be able to see the smart button; users with access to the signature request. Task-4966129 Forward-Port-Of: odoo/enterprise#90819
A missing setting was added to Point of Sale Enterprise tests so they run correctly during automated builds. This helps prevent false build failures and keeps quality checks reliable without changing customer-facing behavior.
Original PR description
steps to reproduce: 1. install pos_enterprise 2. run the test `test_should_not_affect_other_pos_config` or `test_is_header_or_footer_to_false` this commit adds the missing_field `account_tax_return_journal_id` to the test build_error-230301 Forward-Port-Of: odoo/enterprise#90995
The Swiss payroll accounting test setup now gives the test user the needed payroll permissions. This prevents a known automated test failure caused by missing access rights, helping keep payroll-related releases stable.
Original PR description
steps to reproduce: 1. install l10n_ch_hr_payroll_account 2. run test_ema_declaration_2021_11 test added payroll user and manager groups to the test user to avoid missing access rights error build_error-230682
Employee referral progress now reflects the applicant's actual recruitment stage, including when an applicant is moved back to an earlier stage. This prevents employees from seeing incorrect completed stages and helps ensure referral points and notifications stay accurate.
Original PR description
**Steps:** - Install the hr_referral and hr_recruitment modules. - Open a referred applicant from the Recruitment module. - Create a new stage and place it before the applicant’s current stage. -…
**Steps:** - Install the hr_referral and hr_recruitment modules. - Open a referred applicant from the Recruitment module. - Create a new stage and place it before the applicant’s current stage. - Move the applicant back to the newly created stage. - Open the Referral view for the referring employee. **Description of the issue/feature this PR addresses:** Even though the applicant is moved back to a newly created stage, the referral view still shows the previous (later) stage as completed. The new stage is not reflected, leading to incorrect stage tracking in the referral module. **Cause:** The `use_in_referral` field in the `hr.recruitment.stage` model controls whether points are updated for a stage. Stage checkbox in the referral view depend on these points. **Fix:** This PR updates the logic to: - Allow stage point updates even when the applicant moves back to a previous stage. - Ensuring that points are awarded for all use_in_referral stages skipped when jumping from one to any non-referral stage. - Ensure that points are added or removed properly and even sending notification based on the `use_in_referral` field. task-4968602
Employees can no longer create time off requests through a shortcut when the time off type requires an approved allocation. This keeps all request entry points consistent and helps prevent leave balances from being bypassed.
Original PR description
Steps: - Navigate to Time Off > Configuration > Time Off Types. - Open a time off type that requires allocation. - Click on the 'Time Off' smart button and try to create a request. Issues: - Employees could create time off requests via the smart button even without an approved allocation. - This bypassed the existing restriction enforced in the standard time off request creation flow. Fix: - Added a constraint on the time off model to validate allocations even when requests are created via the smart button. - Ensured validation covers both allocation presence and allowed negative leaves - Raised a ValidationError when no valid allocation is found. - Added a test case to ensure constraint behaves correctly. - Adjusted some of tests to comply with the new validation. Task - 4671236 Forward-Port-Of: odoo/enterprise#92377 Forward-Port-Of: odoo/enterprise#89975
Fixed an issue where opening return links from the dashboard showed the audit-style view instead of the tax return view. This ensures users land on the expected screen and can continue their tax return work without confusion.
Original PR description
When users click on the return links on the dashboard, the audit-style view is opened instead of the tax returns one. task-id: 5016400
The automated accounting walkthrough was adjusted so it opens the correct menu during nightly testing. This helps keep quality checks stable and reduces false build failures for the accounting area.
Original PR description
The nightly build were failing due to the wrong menu being opened, the solution is to use a more generic filter for the Add button, this is not a perfect solution as it will also select add button on other views that we dont want. task-4822215
A small issue in the Documents app was corrected to ensure document-related database queries run as intended. This helps prevent errors in affected document operations and improves reliability without changing the user experience.
Original PR description
odoo/odoo#219105
Features or functions removed from Odoo
Payroll “other input types” are being removed and replaced with input-type salary rules, making payroll configuration more consistent. This streamlines how payroll teams set up and reuse inputs across structures and local payroll variants.
Original PR description
In this PR we remove model `hr_payslip_input_type` and replace the relation with a salary rule of type INPUT Task: 4930632
The old Cost Analysis Report has been removed because its role is now covered by newer manufacturing reporting tools. Users should use MO Overview for individual manufacturing order costs and the Production Analysis report for analysis across multiple orders.
Original PR description
The 'Cost Analysis Report' is obsolete as it has been replaced by: - MO Overview for single MO cost analysis (pre/during/post MO). - Production analysis report for multi MO analysis. Therefore, it has been removed. Task: 4890524
Code cleanup and technical improvements
The Documents app now checks how long deleted files stay in the trash only when a user actually moves a document there. This avoids an unnecessary background request when opening Documents and reuses the result for repeated deletions, improving responsiveness and reducing resource use.
Original PR description
`get_deletion_delay` is called every time the Documents app is open, even though it's only needed when sending a document to the trash. This adds network latency and uses resources for nothing. With this commit, it's fetched only when needed: when the user sends a document to the trash. It's also cached in memory to avoid repeating the same RPC multiple times if the users deletes multiple documents. The value is very unlikely to change.
This update cleans up parts of the online sales checkout customization code, especially for Chilean and Mexican electronic invoicing flows. It helps prepare the website sales experience for future modernization while keeping current customer-facing behavior essentially unchanged.
Original PR description
task-4919046 Community PR: https://github.com/odoo/odoo/pull/216836
This update simplifies how manufacturing planning schedules are handled behind the scenes. It reduces unnecessary internal processing, helping keep planning data interactions cleaner without changing day-to-day user workflows.
Original PR description
Description ----------- Follow-up on odoo/enterprise@00fd82c15d2fd38634361b7c68b24f724684fb92: - Convert the usage of a context key into a param - Extract the internal implementation of `get_impacted_schedule` to return records instead of ids for internal backend usage and avoiding re-browsing.
This update modernizes an internal part of the employee referral app by using Odoo's standard deprecation approach for an overridden method. It helps keep the module easier to maintain and safer to evolve, with no expected change for everyday users.
Original PR description
https://github.com/odoo/odoo/pull/221244
This update simplifies how cohort and recruitment pivot reports process their filtering data now that only one domain is supported. It reduces legacy complexity in the reporting code, making future maintenance safer while keeping the user-facing reporting experience unchanged.
Original PR description
Since https://github.com/odoo/odoo/pull/186454 and https://github.com/odoo/enterprise/pull/73467, the cohort and pivot views no longer have to handle several domains. Here we finish the job and remove the references to domains, originIndex,...