Daily updates from Odoo
Wednesday, July 15, 2026
58 changes · master
New functionality added to Odoo
Adds the official Latvian VAT report attachments for domestic, EU purchase, domestic sales/export, and EU sales transactions. Businesses can now review more detailed VAT breakdowns and export the report package in XML for filing or compliance workflows.
Original PR description
This commit adds 4 attachments to the Latvian tax report and an XML export for the tax report (including the attachments). The attachments are the following - PVN 1-I: domestic purchase / import -…
This commit adds 4 attachments to the Latvian tax report
and an XML export for the tax report (including the attachments).
The attachments are the following
- PVN 1-I: domestic purchase / import
- PVN 1-II: EU purchase
- PVN 1-III: domestic sales / export
- PVN 2: EU sale
The attachments give more details for the tax report.
The lines of the attachments are "transactions"
A "transaction" is identified by the move and the transaction type or document type.
The transaction type is given via a tax tag (see community PR).
- PVN 1-I: transaction type, move
- Small transactions (< 150€) are aggregated separately under transaction types 'V' or 'T'
independently of the move
- 'V': All small transactions of a partner in case the total of all their small transactions reaches 150€
- There is max 1 line per partner
- 'T': All small transactions that are not grouped under some 'V' line
- There is max 1 line like this; it has no partner information
- PVN 1-II: transaction type, move
- Small transactions (< 150€) are aggregated separately under transaction types 'V' or 'T'
(like PVN 1-I)
- PVN 1-III: document type, move and line in the main tax report
- All transactions with (document) type 'X' are aggregated on a single line
- Small transactions (< 150€) are aggregated separately under document types 'V' or 'T'
(like PVN 1-I)
- The line in the main tax report is ignored for 'X' and small transactions
- PVN 2: transaction type, move
- No aggregation is performed here
Only account move lines that are tagged with a transaction type (1-I, 1-II, 2)
or a relevant tag for the main report (1-III) are shown in the reports.
The tags `Rep` and `C (car)` only take 40% and 50% respectively of the
base amounts. The tax amount is assumed to be split correctly.
task-4251184
Forward-Port-Of: odoo/enterprise#84135Mexican payroll users can now see key salary values used in payslip calculations, making it easier to validate results. The integration factor can also be adjusted manually when there is not enough historical data, helping ensure correct IMSS contribution setup for new customers.
Original PR description
The daily salary and the integration factor (`l10n_mx_daily_salary` and `l10n_mx_integration_factor`) are two fields used during the payslip computation. Displaying these fields helps users to validate the calculations. Furthermore, when a new customer configures payslips for the first time, there is no historical data in the database to compute the integration factor automatically. Therefore, it is necessary to make this field editable to allow manual adjustments and ensure correct IMSS contributions. target: master task-6267003
This update improves Odoo's AI assistant by moving response generation and chat naming into background jobs, making conversations feel more responsive and reliable. It also adds background subagents that can work independently and surface approval requests clearly, while fixing chat titles, company context, and topic-loading behavior.
Enhancements to existing features
The payroll pay run card now adapts to the actual space available inside the card, not just the browser window size. This makes the header, progress steps, KPI information, and action buttons behave more predictably on different screen sizes and reduces awkward wrapping or overflow.
Original PR description
The pay run header card was assembled by kanban XML inheritance and its responsive behaviour keyed off `ui.size` (the browser-window breakpoint). Regions shifted from one step to the next, and the…
The pay run header card was assembled by kanban XML inheritance and its responsive behaviour keyed off `ui.size` (the browser-window breakpoint). Regions shifted from one step to the next, and the free space and the buttons collapsed based on the window rather than the card's own width - folding while there was still room and overflowing when there wasn't. Rework it into a single OWL shell (PayrunCard) that owns four regions - name | KPIs | steps | buttons. Per-step views only fill the `payrun_kpis` slot and declare their `current_step`; the name block and step bubbles are declared once and reused. The kanban record owns one ResizeObserver that measures the card's actual width and each region's content width, then resolves the layout in priority order: the name truncates to its floor, the buttons collapse into the overflow menu, and finally the steps stack onto their own full-width row. The decision is recomputed only when the width changes, so toggling the layout - which only changes the height - cannot feed back and flicker at the boundary. task-6259171
Payroll administrators can now view and update the first payroll month directly in Payroll Settings. This makes it easier to correct or adjust the initial payroll setup after it has already been entered from the dashboard warning.
Original PR description
Currently, after set the first month of payroll on the dashboard warning. We can't modify it after nor the the information back. In this PR expected to add the first month of payroll in the Payroll Setting, Therefore, Users can modify after set it. task-6377702
Belgian payroll now handles youth and senior time off as separate categories, making payroll and leave tracking clearer. The update also adds checks to warn when youth time off seniority conditions may not be met and to prevent these allocations while regular paid time off remains available.
Original PR description
This PR: - Splits the youth and senior time off types into two different work entry types. - Adds a warning on the allocation of Youth Time Off if the employee does not have at least 1 month of seniority in the company at the beginning of the validity period for the allocation. - Prevents the allocation of youth or senior time offs if there is still paid time off available. task-6360468
Timesheet entry units are now controlled by timesheet settings instead of company-level settings. This makes time tracking behavior more consistent across related areas such as helpdesk, projects, sales timesheets, dashboards, and timesheet grids.
Original PR description
Adjust the `timesheet_encode_uom_id` to depend on timesheet settings, not from company --- # task cancelled task-5932762
The AI app form views and related controls were reorganized to make AI agents and their sources easier to manage. The update also adds native skills and lets agents update themselves, improving flexibility for businesses using AI workflows.
Spreadsheet screen position and viewport behavior are now managed through a shared store instead of an internal plugin, making the experience more consistent across spreadsheet features. Comment popovers now follow the same scroll behavior as other persistent popovers, reducing inconsistent interface behavior.
Original PR description
The `SheetViewPlugin` and the viewport handling was moved into a store rather than a plugin. This commit make the necessary changes to odoo. The test `Scrolling the viewport should hide the comments popover` was deleted. Other persistent popover would automatically be hidden when scrolling, and re-open if scrolling back. There's no reason to have a different behaviour for comments. Task: 6314784
Restricted website editors will no longer see the AI Assistant as an available editing option when they cannot save page changes. A tooltip now explains why the assistant is unavailable, reducing confusion and setting clearer expectations.
Original PR description
Restricted Editors do not have permission to edit website pages. However, the AI Assistant button remains available, giving the impression that the feature can be used even though any changes cannot be saved. This commit disables the AI Assistant button for users without 'Editor and Designer' access and adds a tooltip explaining why the feature is unavailable Forward-Port-Of: odoo/enterprise#123047
Recurring project tasks are now scheduled around assigned users’ workable days, working hours, leave, and contract dates. This helps teams plan recurring work more realistically while still allowing weekend-based recurrences when the original task was intentionally set on a weekend.
Original PR description
## Previous behavior: Recurrent tasks could still be scheduled on weekends, vacation days, or other non-working days. ## New expected behavior: Recurrent tasks are always scheduled based on the…
## Previous behavior: Recurrent tasks could still be scheduled on weekends, vacation days, or other non-working days. ## New expected behavior: Recurrent tasks are always scheduled based on the workable days and working hours of the users assigned to them. Workable days and hours are determined using the assigned users’ shared calendars. If the assigned users do not share the same calendar, the company calendar is used to resolve scheduling conflicts. If a user is on leave, the recurrent tasks they are assigned to are still scheduled, but the user is temporarily removed from the list of assigned users for the duration of their leave.This allows other individuals to take over the task when the user is on leave. Users are also removed from recurrent tasks when their contract start or end dates fall outside the task schedule since users shouldn't work with outdated contracts. ## Exception: This behavior can be overridden if the original recurrent task was initially scheduled on a weekend day (Saturday or Sunday). In this case, recurrent tasks behave exactly as before and may be scheduled on non-working days. This was made to ensure the end-users could have the final say on this behavior in the case it is unwanted. ## Reference: [task-4796700](https://www.odoo.com/odoo/project/4105/tasks/4796700)
Payroll warning settings can now show the same warning on both dashboards and employee or payroll record pages at the same time. This reduces duplicate setup work and makes important payroll alerts more consistently visible across supported country payroll modules.
Original PR description
Replace the `display_on` selection field with two distinct boolean fields: `display_on_dashboard` and `display_on_model`. This allows a single warning configuration to be displayed on both the dashboard and record views simultaneously, eliminating the need for data duplication. Update the view to show these choices as side-by-side checkboxes. Task: 6267499
Signature requests created from other apps now include the template name alongside the related record name. This makes request names, filenames, and email subjects easier to recognize and less likely to be confused with the signer's name.
Original PR description
When requesting a signature from another app, the request name, filename and email subject only showed the linked record name, which often read as the signer's name. The template name is now added so all three follow the same "<prefix> - <template> - <record>" format. task-6317174 Forward-Port-Of: odoo/enterprise#122963
The AI website assistant now includes added design guidance in its prompts. This should help generate website content with better visual direction and more consistent design recommendations.
Creating a shift from the Attendance Gantt view now uses the employee's expected daily working hours instead of defaulting to a full 24-hour shift. This prevents incorrect overnight shifts and avoids accidentally moving the end date to the next day.
Original PR description
Currently, when creating a new shift from the Gantt view in "Attendance", if the scale is "week" or higher, the shift will have a duration of 24 hours and span from 12:00 AM to 12:00 AM the next day. This will always be wrong, and also shifts the end date by a day. To resolve this issue, now if a new shift is created by clicking on a day (instead of dragging the click to select hours), editing the starting hour will automatically change the end hour to be start + expected hours per day. Task ID:6326685
Belgian payroll now supports restructuring social security reductions for up to three quarters instead of two. A new start date field helps track cases where an employee already received the reduction with a previous employer, improving payroll accuracy and compliance.
Original PR description
**What**: - Restructuring reduction can be received for 3 quarters previously it was only for 2 quarters - There is a chance that the person can get restructuring reduction from previous employer so added a new field 'restructuring_date_start' to know the start date of restructuring reduction task-6344925
The salary calculator now waits to show missing-field errors until users try to configure benefits or copy a link, instead of interrupting them while they are still editing. This makes the offer setup process smoother while still clearly listing required information before key actions can continue.
Original PR description
The salary calculator was showing validation errors while users were still filling in the form. This made the calculator harder to use. With this change: - Do not show validation errors while editing a simulation offer. - When the user clicks "Configure Benefits" or "Copy Link", validate all required fields and show an error listing any missing fields. - Remove the "Optional" placeholder from the employee field since it is required to use these actions. Task-6340556
Mexican payroll CFDI checks have been updated to match version 1.2e requirements. This helps ensure payslip XML data is validated correctly for taxable and exempt earnings, other salary income, and employment subsidy limits before reporting.
Original PR description
**. Perceptions – ImporteGravado / ImporteExento (XML Nodes)** For each Perception node, validate that: If ImporteExento = 0, then ImporteGravado > 0. If ImporteGravado = 0, then ImporteExento > 0. Both values cannot be 0 at the same time. These validations must be applied per Perception node, not at an aggregated level. **. TipoPercepcion = "038" (Other Salary Income) (XML Nodes)** When TipoPercepcion = "038": ImporteExento must always be 0. The amount must be recorded only in ImporteGravado. **. SubsidioCausado (XML Nodes)** Update the validation logic for the SubsidioCausado attribute based on NumDiasPagados: If NumDiasPagados ≤ 31, SubsidioCausado ≤ 628.00 If NumDiasPagados > 31, SubsidioCausado ≤ NumDiasPagados × 0.206 task-5412728 Forward-Port-Of: odoo/enterprise#121304
Hong Kong payroll salary rules have been consolidated so regular and casual employee structures can share common rules instead of maintaining duplicate versions. This reduces configuration complexity and should make payroll support and future updates easier while preserving the differences needed for MPF rules.
Original PR description
Recently, salary rules were updated to support more than one salary structure on a same rule. This change allows us to clean our structures and remove a lot of duplication between regular and casual employees. Both structures are 90% the same, besides MPF rules, so we now can really simplify it to facilitate support and reduce complexity task-6267295
Belgian payroll rules now reflect the legal change effective August 1, 2026: employees with less than six months of service have a one-week notice period whether they resign or are dismissed. This helps employers calculate end-of-collaboration notice durations correctly and consistently, including contracts that span the change date.
Original PR description
Starting from August 01 2026, the legal notice period will change if the employee has been working for their company less than six months: it will only be one week, no matter if the employee quit or was fired. Task: 6365099
Payment check reports now better explain cases where a check is written for less than the invoice total because an early payment discount was applied. This helps users and recipients understand the payment amount and keeps localized payment report layouts aligned.
Original PR description
Previously, the check amount didn't match the applied payment. This makes it clear why the a check for less than the total was written out. Because we change the layout of the payment report in community, we have to update some xpaths here. For MX, a `is_cfdi_signed` block was not migrated because it's dead code. That variable isn't defined anywhere. task-5172527
This update makes deferred account settings appear based on the account type, reducing confusion when configuring accounts. It also adds clearer guidance in the interface so users better understand the deferred option.
Original PR description
*accountant, reports Purpose: Some improvements missed in the initial commit: https://github.com/odoo/enterprise/commit/65ea8b266d8024736bec388425c90d9efd9a8cce will be addressed here. - Changed the deferred_account_id invisibility to be based on the account type since it should not be based on is_deferred as they are not related to each other - Added a tooltip to is_deferred for further clarity task-6293902
Resolved issues and error corrections
This change restores payroll fields that were removed too early, including the refund indicator and beneficiary details for salary attachments. It helps ensure payroll payments and related reports can continue handling beneficiary information while the longer-term design is reconsidered.
Original PR description
In this previous PR (https://github.com/odoo/enterprise/pull/114188) we removed the is_refund flag and, together with it, also the fields related to the beneficiary. This is because there is an onchange method on is_refund that sets the beneficiary bank account for any attachment that is not a refund to False. However, while the removal of is_refund is still in the plans, we want to take back the beneficiary fields and use them even in the case of non-refund attachments. We need to think better about how to remove the is_refund field and structure negative attachments around it, so for now we revert the previous PR. Task: 6376383 Forward-Port-Of: odoo/enterprise#123728
Instagram image posts that hit network delays will now be marked as failed instead of causing a server crash. Users receive clearer failure messages, including guidance to use a smaller image when timeouts occur.
Original PR description
Making an Instagram containing an image can crash the server with an unhandled `ReadTimeout` instead of marking the post as failed. ### Cause When creating a media container, Odoo passes a URL pointing to its own server and Instagram fetches the image from it server-side before responding. The timeout therefore covers network latency, Instagram's download speed from the Odoo server, and image processing time, making it prone to being exceeded. When it is, `requests` raises a `ReadTimeout` which is unhandled, leading to a raw RPC error instead of a clean `state='failed'`. ### Fix Catch the network errors and mark the post as failed instead of letting them crash the request. Timeouts get a message suggesting a smaller image, since they are usually caused by Instagram fetching and processing a large image server-side. Any other request error falls back to a generic message. opw-6015997 Forward-Port-Of: odoo/enterprise#122406 Forward-Port-Of: odoo/enterprise#112573
Payslips sent by email now show a neutral message saying they were sent, instead of incorrectly saying they were re-sent on the first send. When sending payslips for multiple employees, each payslip now receives only one chatter note, reducing confusion in payroll records.
Original PR description
**Issue:** Clicking Send By Email on a payslip opens the hr.payslip.send.mail wizard. Its action_send() always logs "The payslip has been re-send to the employee." in the payslip chatter, even when…
**Issue:** Clicking Send By Email on a payslip opens the hr.payslip.send.mail wizard. Its action_send() always logs "The payslip has been re-send to the employee." in the payslip chatter, even when the payslip is being sent for the first time. The log call also runs inside the loop over the employees and goes through all the payslips of the wizard on each pass, so when the wizard sends payslips of several employees every payslip gets the same note once per employee. This started with the rework of the wizard in https://github.com/odoo/enterprise/commit/39e0488a7e076ee648b47cc3d1cad41cadfd692e **Fix:** The wizard cannot tell a first send from a resend. There is no field on the payslip that keeps track of a previous send, and the chatter cannot be used for that either because the mail sent automatically on validation can be deleted after sending. The fix changes the log in action_send() to say the payslip has been sent by email, which is true in both cases, and moves it out of the employee loop so each payslip gets exactly one note. **Steps to reproduce:** 1. In Payroll > Configuration > Settings, set "Send payslips to employees" to When Paid and save 2. In Payroll > Payslips, create an off-cycle payslip for an employee, click Compute, then Validate 3. Go back to the settings and set "Send payslips to employees" to When Confirmed 4. On the payslip, click Pay, then Mark as Paid 5. Click Print so the payslip document is generated 6. Click Send By Email and send the mail 7. Check the payslip chatter => The chatter shows "The payslip has been re-send to the employee." while the payslip was never sent before Ticket [link](https://www.odoo.com/odoo/project.task/6324204) opw-6324204 Forward-Port-Of: odoo/enterprise#123298
Chilean export invoice PDFs now keep customs information in the correct columns even when origin or destination port details are missing. This prevents package quantities and other export details from appearing under the wrong headings, improving document accuracy for customers and customs processes.
Original PR description
### Issue: On Chilean export invoices, the customs information table may display data in the wrong columns When `Origin Port` or `Destination Port` is not set, the corresponding `td` is omitted by…
### Issue: On Chilean export invoices, the customs information table may display data in the wrong columns When `Origin Port` or `Destination Port` is not set, the corresponding `td` is omitted by QWeb, causing the remaining columns to shift left This results in `Qty of Packages` appearing under `Origin Port` or `Destination Port` in the printed document ### Cause: `l10n_cl_port_origin_id` and `l10n_cl_port_destination_id` have no default value and are optional fields `t-out` on a falsy value omits the `td` entirely in QWeb, breaking the column alignment Adding `or ''` ensures an empty `td` is always rendered, preserving the table structure regardless of whether the fields are set ### Steps to reproduce: - Install `l10n_cl_edi_exports` and switch to CL Company - Create an Invoice (any customer, any line) - In the gear menu, select Print > Invoice PDF copy (Chile) Before the fix, `Qty of Packages` appears under `Origin Port` when neither port field is set opw-6304670 Forward-Port-Of: odoo/enterprise#123150 Forward-Port-Of: odoo/enterprise#121923
Belgian termination holiday attest payslips now use the employee's private address directly, so the address is shown correctly in the required places. This helps ensure departing employees receive complete and accurate payroll documents.
Original PR description
[FIX] l10n_be: missing employee address on holiday attest Bug reproduction: Belgium -> create employee -> fire the employee -> look to the holiday attest payslips (N and N-1) -> private address of the employee is missing in 2 places in payslip Bug cause: o.employee_id.work_contact_id work contact id was used in report but we can just use private_street, private_city etc. instead. Bug solution: Use private_street, private_city etc. fields directly from the employee model. task - 6361457 Forward-Port-Of: odoo/enterprise#123528
This fixes an installation blocker for the Peruvian electronic invoicing localization caused by a typo in an internal database query. Businesses using or enabling Peru localization can install the module successfully again.
Original PR description
A refactor/cleanup [1] introduced a buggy SQL query preventing the Peruvian localization install. [1]: https://github.com/odoo/enterprise/commit/e182608f13c6eefae11339bba24e80497c2b3903#diff-deaab3f5010fea8defc8af11dc186415ecc9079d86d307537b09222dda7ab751R119 task-none
This update fixes issues in the social CRM and social feed experience where post menus could appear empty, feed refreshes could fail due to timeouts, and LinkedIn image uploads could error. The changes make day-to-day social media management more reliable and reduce interruptions for users working with social posts and leads.
Original PR description
Bug 1 === Since b75755ea8ac65ce5ce973412e3c4194fa1bd6fd3 , the menu on the stream post could be visible but empty. The reason is that we checked for `this.isConvertibleToLead` instead of `this.isConvertibleToLead()`. We take advantage of this bug fix to correctly overwrite the condition without replacing the entire button (which can break other module overwriting the same element). Bug 2 === Sometimes, when refreshing the feed view, an error occurs because the request timeout. To fix it, we increase the timeout when doing requests in batch. Bug 3 === When uploading an image in LinkedIn, an error happens. The reason is that `LocalBinaryFile` is now returned when reading Binary field, and in the requests API, the `data` arguments expect the bytes. (for other media, we upload the image with `file` argument). Task-6254983 Forward-Port-Of: odoo/enterprise#123949 Forward-Port-Of: odoo/enterprise#118329
Subscription product pages now load correctly when a discount is configured directly on a recurring plan without a pricelist. This prevents website errors during price calculation and ensures customers see the intended discounted recurring price.
Original PR description
**Problem:** On the website, a subscription product page returns a 500 error when a discount is set directly on the recurring plan (a time-based pricing rule with a plan but no pricelist). **Steps to…
**Problem:** On the website, a subscription product page returns a 500 error when a discount is set directly on the recurring plan (a time-based pricing rule with a plan but no pricelist). **Steps to reproduce:** 1. Create a subscription product with a recurring plan. 2. Add a recurring price rule for that plan with no pricelist, set as a percentage discount (base = sales price). 3. Open the product page on the website. **Current behavior:** The page fails with a 500: Internal Server Error during price computation. **Expected behavior:** The page loads and shows the discounted recurring price. **Cause of the issue:** For a recurring price rule based on the sales price, `_compute_base_price` looks up "the no-pricelist rule for the plan" to use as its base, via `_get_applicable_rules_domain(plan_id=...)`. When the discount is set directly on the plan, the rule being computed has no pricelist itself, so that search returns the very same rule and calls `_compute_price` on it again, leading to infinite recursion. **Fix:** Excluding the rule itself from the base-rule lookup lets a no-pricelist plan rule resolve its base from the product's sales price (the super() fallback) instead of re-entering its own computation. A rule applied through a pricelist is unaffected, since its no-pricelist base rule is a different record. opw-6306105 Forward-Port-Of: odoo/enterprise#121466
Fixed an issue where outbound FedEx shipment labels could lose their reference field when return labels were enabled. This helps businesses keep the expected shipment reference visible on original delivery labels while still supporting return labels.
Original PR description
Issue ----- When setting the delivery method to create return labels aswell, the reference (`REF`) field is not present on the original outbound shipment. <img width="438" height="148" alt="image" src="https://github.com/user-attachments/assets/42acce7b-6177-4f8f-81d3-ad6dfd3e4bb2" /> Steps to reproduce ----- - Setup Fedex - Enable returns - Create a product (set weight) - Create a delivery for the product - Set carrier as Fedex - Validate delivery - Open the label > REF field is empty Cause ----- Fedex doesn't include references on the label of returns. When the option for returns is enabled, the outbound shipment is marked as a "Courtesy return". It doesn't make sense to specify a return reason on the original shipment. Expected outcome (after fix) ---- <img width="428" height="146" alt="image" src="https://github.com/user-attachments/assets/0d22e147-da90-4aa4-b3ca-2d996c7cc147" /> ----- Ticket: opw-6101620 Forward-Port-Of: odoo/enterprise#118659
Fixed a conflict that caused Obox quality-control cameras to stop working after the IoT module was installed. Users can continue taking required quality-check photos without seeing a false camera-not-found error, and irrelevant IoT controls are hidden when no IoT device is configured.
Original PR description
Steps to reproduce: - Install `obox_quality_control` but do not install `iot`. - Configure a quality check to take a picture with an Obox camera. - Validate a receipt an confirm the camera works as expected. - Now install the `iot` module, and try to take a picture again. **Expected behaviour:** The camera still works as expected. **Actual behaviour:** There is a 'Camera not found' error. This issue is caused by both the Obox and IoT quality modules adding an `identifier` field to the quality control wizard. The fix is simply to use a different name for the Obox field. In addition, we now hide the IoT button in the wizard if the IoT device is not set. task-6329066 Forward-Port-Of: odoo/enterprise#122490
Fixes an installation and upgrade failure in the Peru electronic invoicing module that could affect databases with existing journal entries. This helps ensure updates complete successfully and required invoice data is filled in correctly.
Original PR description
### Description Installing or upgrading `l10n_pe_edi` aborts with a `psycopg2.errors.SyntaxError` whenever `account_move` already contains rows: ``` psycopg2.errors.SyntaxError: syntax error at or…
### Description
Installing or upgrading `l10n_pe_edi` aborts with a `psycopg2.errors.SyntaxError` whenever `account_move` already contains rows:
```
psycopg2.errors.SyntaxError: syntax error at or near "AND"
LINE 9: AND l10n_pe_edi_operation_type IS NULL
```
### Root cause
The `init_storage` SQL that backfills `l10n_pe_edi_operation_type` (added in e182608f13c6 `[REF] *: use init_storage`) closes the `WHERE` clause with a stray semicolon right after the country condition:
```sql
WHERE res_company.id = account_move.company_id
AND move_type IN ('out_invoice', 'out_refund')
AND res_country.code = 'PE'; -- stray ';' ends the UPDATE
AND l10n_pe_edi_operation_type IS NULL -- parsed as a new statement -> syntax error
```
The semicolon terminates the `UPDATE` early, so `AND l10n_pe_edi_operation_type IS NULL` is parsed as a separate statement starting with `AND`.
`init_storage` only runs when the table already has rows (`_init_column_data` in `odoo/orm/fields.py` skips empty tables), which is why the crash surfaces on databases that already contain journal entries — e.g. runbot `*-all` builds, or `button_immediate_install` over a populated database.
### Fix
Remove the stray semicolon so the NULL guard stays part of the `WHERE` clause.
### Validation
Reproduced and verified on `master` (community + enterprise), with a row present in `account_move`:
- **Before:** `-u l10n_pe_edi` fails with `syntax error at or near "AND"` at `LINE 9`.
- **After:** the module installs/updates cleanly and the column is backfilled without error.Payroll runs now correctly identify when expected payslips are missing. This ensures payroll teams receive the right warning and can address gaps before processing payroll.
Original PR description
The missing payslip in a payrun warning wasn't triggered correctly because we were filtering on the schedule pay of the payrun and this field was removed in a previous PR. task-6329134 Forward-Port-Of: odoo/enterprise#121641
Sales commission plans now reject salesperson start dates that fall outside the plan's effective period. This prevents invalid commission setup and helps ensure salespeople are assigned only within eligible plan dates.
Original PR description
Version: 18.0 Steps to reproduce: - open sale commission plans and create a new plan with an effective period - go to the salesperson tab and add a salesperson - set the salesperson from date after the plan end date issue: salesperson period start date was accepted even if it was set after the plan end date fix: added validation to raise an error when the salesperson start date falls outside the plan effective period task id: 6241188 Forward-Port-Of: odoo/enterprise#122870 Forward-Port-Of: odoo/enterprise#118289
Twitter replies are now blocked in Odoo when the account is not allowed to respond, such as when the tweet does not mention the account or quote one of its tweets. This prevents failed or inappropriate automated replies and helps avoid unwanted outreach to Twitter users.
Original PR description
Purpose ======= To prevent LLM from spamming Twitter users, Twitter does not allow to reply to a tweet if we are not mentioned in it, or if the tweet does not quote one of our tweet. For that reason, we disable the reply button when needed. Task-5964524
Canadian EFT batch payment exports now use each payment's ID as the Item Trace Number instead of filling it with zeros. This helps ensure files comply with CPA-005 banking rules and avoids payment rejections by Canadian financial institutions.
Original PR description
Issue: The Item Trace Number according to CPA-005 standard should be a nonzero sequence that serves as unique reference ID for payments. Currently, Odoo sets the Item Trace Number of all payments as…
Issue: The Item Trace Number according to CPA-005 standard should be a nonzero sequence that serves as unique reference ID for payments. Currently, Odoo sets the Item Trace Number of all payments as a zero-filled sequence According to CPA-005 standards on the Item Trace Number: "The data elements (b), (c) and (d) each must be greater than zero or the TRANSACTION WILL BE REJECTED" (page 36). https://www.payments.ca/sites/default/files/standard005eng.pdf Steps to reproduce: 1. Install the module l10n_ca_payment_cpa005 2. Go into "CA Company" 3. In the configuration for "CA Company", add something to the fields "Short Name used in Canadian EFT" and "Company ID" i.e. "CCC" 4. Set all the fields in the "Canadian EFT/CPA Configuration" section of the bank journal 5. Set the bank record on the bank journal. Set the field "Financial Institution ID Number" field of the "Account Number" record of the bank journal to any numerical sequence 6. Create a bank account on "Azure Interior" and make sure to check the field to trust the bank account that you created (otherwise there will be an error) 7. Create two payments with the vendor of "Azure Interior" using the payment method of "Canadian EFT" 8. Create a batch payment for both payments created 9. Validate the batch payment and the export file should show up in the chatter 10. Note that in the export file, the Item Trace Number for each payment is set to be all zeros, whereas it should be a nonzero identification sequence Solution: Set the Item Trace Number to be the payment's id opw-6323432 Forward-Port-Of: odoo/enterprise#124016 Forward-Port-Of: odoo/enterprise#123633
The timesheet assistant now captures time spent in Odoo applications even when the activity cannot be linked to a specific project, task, or ticket. This helps users get more complete time suggestions, with these activities shown as separate key entries for easier review.
Original PR description
This PR adds support for tracking time spent in the Odoo apps in the assistant, for when we can't trace URLs to a project/task/ticket. The activities detected this way are marked as key events, such that each appears as an individual line in the assistant suggestions. With this, most of the time users spend working in their Odoo database should be reflected in the assistant suggestions. Task-6250449 Forward-Port-Of: odoo/enterprise#123147 Forward-Port-Of: odoo/enterprise#119096
The database authentication module was added to the translation workflow so translators can provide localized text. The update also corrects wording mistakes and tidies an internal error check, improving clarity with minimal user impact.
Original PR description
The aim of this commit is to allow the translator to work on this module translation and fix a typo that was made. Task-id: None Forward-Port-Of: odoo/enterprise#124038
Printing an appraisal form from the action menu now waits briefly so the menu can close first. This prevents the dropdown from appearing on the printed document, giving users a cleaner and more professional printout.
Original PR description
When printing the appraisal form from the action (cog) menu, the drop down menu itself was incorrectly showing up in the printed document. This happened because the browser started printing immediately before the menu had time to close. By adding a small delay before triggering the print action, the menu now has time to completely close, so it no longer appears in the final print. task-6369240 Forward-Port-Of: odoo/enterprise#123242
This update corrects a database query issue in the Peru electronic invoicing module. It helps prevent errors when processing accounting documents, improving reliability for affected users.
This update improves manufacturing work order planning by showing planned work orders by default and aligning shop floor card options with company settings. It also corrects engineering change cost calculations so bill of materials cost differences better reflect real operation cost changes.
Original PR description
Forward-Port-Of: odoo/enterprise#122639
Fixes an issue where the cursor could jump backwards while users typed in Studio's XML editor. The editor now keeps cursor position reliably per editing session, making report and view editing smoother and less disruptive.
Original PR description
Steps to reproduce the issue: -> Open studio -> Edit any view -> Edit xml => Cursor moves backwards when typing Some components inside of the report editor were managing the cursor position based on the document manually. Rendering timings could cause the cursor to move while typing. This commit internalizes the cursor position in the CodeEditor and keep track of them based on the sessionsId, making sure that the cursor position is always correct and only changing when switching between sessions while also making the component API simpler. Community: https://github.com/odoo/odoo/pull/274681 Forward-Port-Of: odoo/enterprise#123244
This change updates an accounting reports screen so it continues to work with the latest underlying interface framework. It prevents a compatibility issue that could affect the display or behavior of the account return check kanban view.
Original PR description
The previous code worked because owl was too permissive.
Mexican payroll payslip forms no longer crash when users add Daily Salary or Integration Factor fields with Odoo Studio. This helps payroll teams review salary-related calculations safely, including while creating off-cycle payslips before an employee is selected.
Original PR description
Users frequently use Odoo Studio to display the Daily Salary (`l10n_mx_daily_salary`) and Integration Factor (`l10n_mx_integration_factor`) fields on the payslip form to verify salary rule…
Users frequently use Odoo Studio to display the Daily Salary (`l10n_mx_daily_salary`) and Integration Factor (`l10n_mx_integration_factor`) fields on the payslip form to verify salary rule computations. However, doing so raises a traceback immediately upon closing the Studio editor, as well as when attempting to create a new Off-Cycle payslip.
### Steps to reproduce:
* Install `l10n_mx_hr_payroll` and `web_studio`.
* Switch to "INNOVACION VALOR Y DESARROLLO SA SA" company.
* Go to Payroll > Payslips > Payslips and create a "New Off-Cycle"
* Use the Studio editor to add `l10n_mx_daily_salary` or `l10n_mx_integration_factor` fields.
* Close the Studio editor.
### Current behavior:
A traceback is raised depending on the field added
#### For the Daily Salary field:
```py
File "/Users/ivgm/odev/worktrees/19.0/enterprise/l10n_mx_hr_payroll/models/hr_payslip.py", line 21, in _compute_daily_salary
payslip.l10n_mx_daily_salary = payslip.version_id.wage / payslip._rule_parameter('l10n_mx_schedule_table')[payslip.version_id.schedule_pay]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
KeyError: False
```
#### For the Integration Factor field:
```py
File "/Users/ivgm/odev/worktrees/19.0/enterprise/l10n_mx_hr_payroll/models/hr_payslip.py", line 33, in _compute_integration_factor
payslip.employee_id.with_context(before_date=payslip.date_from)._get_first_contract_date()
File "/Users/ivgm/odev/worktrees/19.0/odoo/addons/hr/models/hr_employee.py", line 493, in _get_first_contract_date
versions = self._get_first_versions_filtered(no_gap=no_gap).filtered(lambda x: x.contract_date_start)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/ivgm/odev/worktrees/19.0/odoo/addons/hr/models/hr_employee.py", line 461, in _get_first_versions_filtered
self.ensure_one()
File "/Users/ivgm/odev/worktrees/19.0/odoo/odoo/orm/models.py", line 5942, in ensure_one
raise ValueError("Expected singleton: %s" % self)
ValueError: Expected singleton: hr.employee()
```
### Expected behavior:
No error is raised, and the fields are correctly displayed on the form view.
### Solution:
* Add Guard Clause: When creating a "New Off-Cycle" payslip, `payslip.version_id` is not initially set because no employee has been selected yet. Added a condition to check if `version_id` exists before computing the values to prevent the traceback.
* View Update: Since displaying these fields is a highly requested feature for traceability, they have now been added to the form view.
target: 19.0
task-6267003
Forward-Port-Of: odoo/enterprise#121718The attendance Gantt view now hides empty parentheses in progress bar labels when there is no extra information to show. This removes confusing visual clutter and makes attendance planning information easier to read.
Original PR description
The label should not display empty parenthesis if there is no extra info to display task-6391439
Point of Sale receipts will no longer include the separate terminal receipt generated by Worldline payments. This keeps customer receipts cleaner and avoids redundant payment information being printed or shown.
Original PR description
This PR removes the terminal receipt from Worldline we are currently inserting in the Point Of Sale receipt We don't adapt the driver code to get the receipt as we cannot change C method prototypes task-6373975 Forward-Port-Of: odoo/enterprise#123770
The payroll payrun chatter panel and button are now limited to the correct payrun screens. This prevents confusing extra options from appearing in unrelated payroll views, giving users a cleaner and more predictable experience.
Original PR description
The global `PayRunChatterService` was leaking state across shared views, causing the chatter panel and button to appear on views accessed outside the PayRun layout (e.g., via the main Payroll > Time Offs menu). Fix this by introducing a `useEffect` hook in `PayRunLayout` that checks for a valid `payrun_id` or `payRunReactive` state on view render. If absent, the chatter service state is explicitly reset and closed. The control panel button is also wrapped in a contextual `t-if` check, fully isolating the feature to its intended screens. Task : 6347871 Forward-Port-Of: odoo/enterprise#123570
Employees and managers can now request and save appraisals even when the scheduled appraisal date has already passed. This removes an unnecessary error that blocked late appraisal requests and avoids requiring users to manually adjust dates they may not have permission to change.
Original PR description
# How to reproduce You need to simulate the fact that you are creating an appraisal late so either : A) Directly edit the `next_appraisal_date` in SQL B) Go to Employee App > any Employee > Settings,…
# How to reproduce You need to simulate the fact that you are creating an appraisal late so either : A) Directly edit the `next_appraisal_date` in SQL B) Go to Employee App > any Employee > Settings, set Next Appraisal Date to tomorrow and wait for 2 days Then : - Click on Request Appraisal - Save # The problem An error is shown saying "You cannot set 'Next Appraisal Date' in the past.". You can workaround this by changing the Next Appraisal Date to a date in the future, but the problem is not every user has the right to do this. # Cause `next_appraisal_date` is also defined in hr.appraisal as a relate field of hr.employee : https://github.com/odoo/enterprise/blob/0226ad15abc8db70f8e379fddec3d83d15749c85/hr_appraisal/models/hr_appraisal.py#L56-L57 When creating an hr.appraisal, `next_appraisal_date` is present in `vals_list` because it is defined in the view since : https://github.com/odoo/enterprise/commit/58fba3098f33db82dfbccca2db229550402ed3ab https://github.com/odoo/enterprise/blob/0226ad15abc8db70f8e379fddec3d83d15749c85/hr_appraisal/views/hr_appraisal_views.xml#L92 This triggers a write on `next_appraisal_date` of hr.employee which triggers a constraint : https://github.com/odoo/enterprise/blob/0226ad15abc8db70f8e379fddec3d83d15749c85/hr_appraisal/models/hr_employee.py#L81-L85 opw-6147865 Forward-Port-Of: odoo/enterprise#123817 Forward-Port-Of: odoo/enterprise#114876
Payroll start warnings now include the evaluation logic needed to determine when they should appear. This helps payroll teams receive the right warning before starting a pay run, reducing confusion and the risk of missed checks.
Original PR description
In this commit, we finxed the definition of start payrun warning to include the evaluation code in the warning definition. task-6179707
Rental planning now only blocks resources for company-wide leave when that leave applies to their working calendar, preventing unnecessary allocation conflicts. The update also strengthens related rental planning website and backend tests to help keep booking behavior reliable.
Original PR description
## [FIX] sale_renting_planning: check global leaves working schedule Before this commit: any `resource.calendar.leaves` with no `resource_id` created would prevent all resources from being allocated…
## [FIX] sale_renting_planning: check global leaves working schedule
Before this commit: any `resource.calendar.leaves` with no `resource_id` created would prevent all resources from being allocated during the leave date.
After this commit: any `resource.calendar.leaves` with `no resource_id` would be applied only to resources with the same `calendar_id` as the leave.
if the leave has no `calendar_id` then the leave applies to all `resource.calendars`
if a resource has no `calendar_id` then leaves with no `calendar_id` apply to it as well
## [IMP] {website_}sale_renting_planning: move tests from industry and fix existing ones
This commit moves the tests from [odoo/industry#1980](vscode-file://vscode-app/snap/code/237/usr/share/code/resources/app/out/vs/code/electron-browser/workbench/workbench.html) to their respective standard modules.
It also fixes the logic behind some tests as they weren't testing a `planning.role` with `sync_shift_rental` enabled.
task-6179505
Forward-Port-Of: odoo/enterprise#120983
Forward-Port-Of: odoo/enterprise#116430Belgian payroll pay runs no longer fail when an employee has multiple contract or work schedule versions within the same month. This ensures payslips can be generated reliably for employees with mid-month changes, reducing payroll processing interruptions.
Original PR description
Currently, there is an error while running payrun step with employee who has multiple version in 1 month. ``` number_of_hours = (work100_wds - worked_day).number_of_hours ValueError: Expected singleton: hr.payslip.worked_days(233, 234) ``` Step to reproduce: 1. Create Employee with multiple version in 1 month 2. Create New PayRun during that month 3. Run the PayRun until Payslip step 4. Expected error on payslip steps reason: substraction of work100_wds and worked_day generate more than 1 value, if we have multiple version in 1 month task-6296276 Forward-Port-Of: odoo/enterprise#122723 Forward-Port-Of: odoo/enterprise#122483
This update fixes several issues around how taxes are calculated and stored when documents switch tax modes. It improves consistency for invoices, purchases, sales, and Italian electronic invoice imports, reducing the risk of incorrect totals or validation issues.
Original PR description
- changing python constraint on document tax mode on account.move to SQL - style enhancements to the overlap_badge_tab and new component - removing inconsistent rounding in purchase.order - adding document tax mode logic to account.tax compute_all method - adding missing document tax mode ‘tax_excluded’ setting to l10n_it_edi during account.move creation of imported invoices odoo/odoo/pull/272730 Following up: https://github.com/odoo/odoo/pull/251800 Forward-Port-Of: odoo/enterprise#122246
Sendcloud shipping labels now correctly handle delivery addresses where the house number contains a dot, such as “12.345”. This prevents incorrect address data from being sent to the carrier and helps avoid malformed labels or delivery issues.
Original PR description
Issue ----- Labels have unexpected format when the delivery address has a dot (`.`) in the number. Steps to reproduce ----- - Set up Sendcloud (carrier shouldn't matter) - Enable logs - Create a customer (with valid address, phone and email) - Address must contain a dot, eg Grand Place 12.345 - Deliver a product to the customer - Add sendcloud as delivery method - Go to the logs - Open the "sendcloud request parcels" log > house_number is 12 Cause ----- The `house_number` field is populated using `_get_house_number`, where the regex used to extract the number from the address line does not accept the `.` character. https://github.com/odoo/enterprise/blob/f93882555864a1f0a2a3e3863780096c78923bfa/delivery_sendcloud/models/sendcloud_service.py#L323 ----- Ticket: opw-6295904 Forward-Port-Of: odoo/enterprise#123820 Forward-Port-Of: odoo/enterprise#123266
Features or functions removed from Odoo
Odoo is removing an obsolete report setting that is no longer used to generate QWeb reports. Reports now rely on the existing report name setting, reducing redundant configuration with no expected change to normal reporting behavior.
Original PR description
The `report_file` field on `ir.actions.report` is no longer used by the QWeb reporting engine. QWeb reports rely on `report_name` to locate and render the template. This commit removes this redundant field from report actions. Community PR:- https://github.com/odoo/odoo/pull/275521 Upgrade PR:- https://github.com/odoo/upgrade/pull/10750
Belgian payroll calculations are updated so employees in Brussels no longer receive the elderly worker reduction starting in Q3 2026. This keeps payroll results aligned with the regional rule change and updates validation tests accordingly.
Original PR description
removed the reduction for everyone in BXL starting Q3 2026 and adapted the tests task - 6331080 Forward-Port-Of: odoo/enterprise#123921
Code cleanup and technical improvements
The payroll module received an internal technical update to stay compatible with the latest Odoo web interface framework. This helps keep payroll screens reliable and maintainable without changing day-to-day user workflows.
Original PR description
As part of the Owl 3 migration, replace onWillUpdateProps hook with the appropriate Owl 3 alternatives.
This update modernizes internal Studio code by replacing a deprecated technical component with newer supported alternatives. It helps keep Studio easier to maintain and reduces future upgrade risk, without changing visible business functionality.
Original PR description
This commit removes the use of the deprecated 'useComponent' hook to use other more appropriate Owl features instead.