Daily updates from Odoo
Thursday, April 16, 2026
69 changes
15 changes
Resolved issues and error corrections
This update resolves an issue where the Sales/Purchase Tax Report was incorrectly displaying doubled VAT amounts for invoices using 'Imported VAT' taxes. The fix replaces a problematic calculation method to accurately sum VAT amounts, ensuring financial reports are reliable. This improves the accuracy of VAT reporting for Vietnamese businesses.
Original PR description
The Sales/Purchase Tax Report showed doubled untaxed amounts and VAT amounts for bills using import VAT group taxes (e.g. "Imported VAT 10%"). The root cause: accessing `tag_t.balance_negate` in the SQL queries triggered a LEFT JOIN on `account_report_expression` (via `_compute_sql_balance_negate`). The Form 01/GTGT report references import VAT tags in two expressions (the parent line and the "including imported" sub-line), so this JOIN produced two rows per account move line, causing GROUP BY to double the SUM. Fix: replace `balance_negate` with a `balance_sign` option (-1 for sales, +1 for purchase) set in each handler's initializer to avoid the problematic JOIN. task-6083697
This update fixes an issue where invoice periods were incorrectly calculated when subscriptions started on the 1st of a month and 'Align to Period Start' was enabled. The fix ensures invoices accurately reflect the subscription's billing cycle, displaying the correct month and date range. This improves invoice accuracy and reduces potential billing discrepancies.
Original PR description
Steps to reproduce: ------------------------------------- 1. Install the Subscription module. 2. Go to Subscription > Configuration > Recurring Plans. * Open a Monthly recurring plan and enable Align…
Steps to reproduce: ------------------------------------- 1. Install the Subscription module. 2. Go to Subscription > Configuration > Recurring Plans. * Open a Monthly recurring plan and enable Align to Period Start. 3. Create a new Subscription: * Select the configured monthly plan. * Add any subscription product. * In the Other Info tab, set a Start Date in the past on the 1st day of a month (e.g., 01/11/2025). 4. Confirm the subscription. 5. Create a draft invoice. Observation: ----------------------------------- In the invoice line, you see the message: `61 days 11/01/2025 to 12/31/2025` It should be: `1 Month 11/01/2025 to 11/30/2025` Issue: ----------------------------------- https://github.com/odoo/enterprise/blob/a5a76de5f25483afa5432ed333c48d78832f128c/sale_subscription/models/sale_order_line.py#L376-L378 In `_get_invoice_line_parameters`, the computation attempts to find the next 1st day of the month However, `new_period_stop` already includes the billing period. When `new_period_stop` is in the past, an extra month is added through `new_period_stop + relativedelta(months=1)`, resulting in an incorrect period range Solution: ----------------------------------- Use `new_period_start` as the anchor point for period computation. Ensure the billing period ends on the last day of the starting month when Align to Period Start is enabled For upsell orders, the fix is NOT applied because for upsells, `new_period_stop` is already set to the parent subscription's `next_invoice_date`, which represents the correct billing boundary. opw-5920036 Forward-Port-Of: odoo/enterprise#107407
This update fixes an error in how Odoo calculates the available capacity for appointments booked through Google Reserve. Previously, the system reserved the full party size for each resource, leading to overbooking. The fix ensures accurate capacity allocation, preventing double-booking and improving appointment scheduling efficiency.
Original PR description
The current logic inside the appointment google reserve controller to compute reserved and used capacity per resource was incorrect. It was reserving the full party size for each resource instead of properly computing how much spots we are reserving for each. The code was fixed and a test was adapted for proper coverage. Task-6120016 Forward-Port-Of: odoo/enterprise#113908 Forward-Port-Of: odoo/enterprise#113805
This update ensures that the date range used to fetch transactions from iap is always accurate. Previously, incorrect dates could be used, leading to missing transactions. This change now uses the latest statement or statement line date, guaranteeing complete and reliable transaction retrieval.
Original PR description
To fetch transactions from iap, we have to give a date from. Before this commit, it was possible to have a date from prior the lock date which is not supposed to happen. This commit will do the max between the lock date the last date of either the statement or the statement line. task-6019584 Forward-Port-Of: odoo/enterprise#110010
This update fixes a problem where the REAGYP compensation amount wasn't being correctly included in the deductible quota submitted to the Spanish tax authority (AEAT). The change ensures that all relevant tax deductions are accurately reported, improving compliance with Spanish regulations. A related test was updated to reflect the new calculation.
Original PR description
Currently, the deducible amount for REAGYP is not passing through to the AEAT. This happens because the REAGYP compensation amount (ImporteCompensacionREAGYP) was missing from the total deductible quota calculation in the SII JSON payload. To fix this, we add 'sujeto_agricultura' to the list that cheks if the tax value for l10n_es is in the list task-6072773 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#259232 Forward-Port-Of: odoo/odoo#256586
This update fixes an issue where recruitment officers couldn't view job tracker information. The change ensures officers have direct access to this feature through their designated role, simplifying the recruitment process and eliminating the need for additional employee permissions. This improves efficiency and streamlines workflows for the recruitment team.
Original PR description
Steps to reproduce: ---------------------------------------- 1. Install the `hr_recruitment` module 2. Create a new user and configure the following access rights: * Employees: No * Recruitment:…
Steps to reproduce:
----------------------------------------
1. Install the `hr_recruitment` module
2. Create a new user and configure the following access rights:
* Employees: No
* Recruitment: Officer Manage all applicants
3. Create new job position > Set created user in Recruiter
4. Log in with the created user
5. Go to Recruitment > Click on the Configure button of that job position
Observation:
----------------------------------------
The Trackers page is not visible on the job position form for the recruitment officer user.
If the user is additionally granted the Employees → Officer: Manage all employees group, the Trackers page becomes visible. The access to the recruitment Trackers should not depend on the Employee 'Officer: Manage all employees' access right.
Issue:
----------------------------------------
The visibility of the Trackers page depends on the Employees → Officer: Manage all employees group instead of the recruitment officer access rights
Solution:
----------------------------------------
Grant access to the Trackers page using the Recruitment Officer group so recruitment officers can access it without requiring the employee officer privileges
opw-5969416
Forward-Port-Of: odoo/odoo#252209This update fixes an issue where the event ticket download button wasn't appearing for orders processed with online payments. The fix ensures that necessary data is always set, regardless of the payment method, allowing users to download their tickets seamlessly after completing the purchase. This improves the customer experience for online event ticket sales.
Original PR description
**Steps to reproduce:** - Set up an event, go put it's state to Annonced - Set up any online payment method (Demo also triggers the bug) - Go to a PoS that sells the event tickets - Purchase one and…
**Steps to reproduce:** - Set up an event, go put it's state to Annonced - Set up any online payment method (Demo also triggers the bug) - Go to a PoS that sells the event tickets - Purchase one and pay with the online payment method - Once on the ticket screen, the button to download the event tickets is not displayed **Why the fix:** The normal flow only works for offline payment methods, because we check if the ordered is either paid or invoiced before setting all the values needed by the frontend regarding the ticket registration. The problem is that with an online payment method, once we enter the **read_pos_data** method that sets the values for the frontend, the order is still in draft, so we just return without doing anything. We now set the values regardless of the order's status and send the confirmation mail in the same way as if it was an online payment. In the case of an online payment, the mail will be sent by the **action_pos_order_paid** function that is called once the payment is processed. A test might be a bit weird to make as we don't have a bridge for pos_online_payment and pos_event, and that we would need to mock the server's answer to be able to pay for the online payment and check that we have the needed values. So the setup for pos_event would have to be copied into pos_online_payment to test it and it would only be ran if both modules are installed. opw-5438432 Forward-Port-Of: odoo/odoo#258986 Forward-Port-Of: odoo/odoo#249306
This update corrects a bug in the Helpdesk module where priority filters weren't working correctly. A recent change caused the priority filter to become nested, leading to all tickets being displayed instead of just those with high or urgent priority. This fix ensures priority filters function as intended, improving ticket organization and prioritization.
Original PR description
Steps to reproduce: - Install Helpdesk. - Click on the High/Urgent priority filter. Issue: - All tickets are shown instead of only filtered priority tickets. cause: - Priority filter became nested after changes in pr https://github.com/odoo/enterprise/pull/105481 Fix: - Adjust the filter handling to correctly apply the nested priority filter domain. task-6089715
This update fixes an issue where the Envia delivery integration incorrectly processed zip codes in Colombia. By using Envia's geocoding service, the system now accurately transmits the required municipality codes, ensuring correct delivery addresses and improving the reliability of shipments within Colombia. This resolves a previous data processing error.
Original PR description
For Colombia, Envia expects the municipality/DANE-style code in the address payload, not the raw postal code. When `l10n_co_edi` was not installed, the Envia integration fell back to the partner zip code and padded it locally before sending it as both `postalCode` and `city`. This produced incorrect values such as turning the Ibagué zip code `730001` into `73000100`, while Envia geocodes resolves that zip code to `73001000`. Use Envia geocodes to resolve the Colombia zip fallback and retrieve the `stat_8digit` code expected by Envia instead of deriving it locally. opw-6083181 Forward-Port-Of: odoo/enterprise#112838
This update fixes a problem where combo prices were incorrectly doubling when multiple items were added to a sale. The change ensures that free items and parent unit prices are accurately recalculated during pricelist updates, resulting in correct pricing for combo orders. This improves the reliability of point-of-sale transactions.
Original PR description
Fix combo prices doubling when quantity > 1 during pricelist changes. Correctly scale free items in 'getFreeAndExtraChildLines' and ensure parent unit prices are updated in 'setPricelist'. task-id: 5971935 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#250666
This update resolves an issue where the system was incorrectly calculating payroll neutralization in Switzerland. The fix ensures accurate reporting of neutralized amounts, which is crucial for compliance with Swiss tax regulations. This change improves the reliability of payroll data for our Swiss clients.
Original PR description
Forward-Port-Of: odoo/enterprise#113961
This update resolves an issue where appraisers without full access to the appraisal module couldn't add other appraisers. The fix utilizes record IDs for comparison, ensuring accurate determination of appraisal management rights. This improves usability for all users involved in the appraisal process.
Original PR description
When you are an appraiser but don't have access rights on appraisal module. You should be able to add other appraiser to the apprasial. This depends on the field 'is_manager', which is computed and triggered by the modification of appraisers. In the compute of this field we are comparing the m2m employee records and the employee_ids of the current user. This doesn't work in the context of an onchange because we have 'New' records with the origin_id, so we need to use the records ids for comparison which always works.
This update fixes an issue where the web interface could incorrectly access data due to cached information after a user update. The change ensures that data accessed through the web interface always respects current user permissions, preventing potential access errors and improving data consistency. This enhances the reliability of user-related features.
Original PR description
**Description of the issue/feature this PR addresses**: web_read on x2many fields can reuse cached ids after write/web_save. Some of these cached ids may be inaccessible with the current record…
**Description of the issue/feature this PR addresses**:
web_read on x2many fields can reuse cached ids after write/web_save. Some of these cached ids may be inaccessible with the current record rules/context (cache pollution).
**Example**:
- **Context**:
- Two companies exist: Company A and Company B.
- Two users exist: User A and User B.
- User A can only access Company A (company_ids=[A], company_id=A).
- User B is linked to both companies (company_ids=[A, B], company_id=A).
- The "res.company" record rule is the standard one: [('id', 'in', company_ids)] (company_ids comes from allowed_company_ids).
- User A edits User B and saves the form.
- **Steps**:
- User A performs a web_read to load User B: company_ids contains only Company A.
- User A performs web_save (write + internal web_read in the same request): cached ids [A, B] are reused and the code attempts to read Company B.
**Current behavior before PR (without fix)**:
After saving a form with an x2many field, web_save calls write and then web_read. In this flow, web_read can include inaccessible x2many ids from cache and raise an AccessError.
**Desired behavior after PR is merged**:
x2many records are re-filtered with current read rules before formatting, and inaccessible ids are removed from values_list.
Forward-Port-Of: odoo/odoo#257517
Forward-Port-Of: odoo/odoo#250904This update fixes an issue where Backspace within a blockquote would unexpectedly remove the blockquote content. Now, Backspace correctly removes inner content, allows list creation inside blockquotes, and resolves issues with trailing line breaks after tables. This enhances the usability of the HTML editor for creating and editing rich text content.
Original PR description
Description of the issue this PR addresses: - Pressing Backspace inside a blockquote that has visible content but no text content removes the blockquote instead of the content. The content (image or table) gets moved outside of the blockquote. - Trailing BR was kept after tables because tables are marked as unsplittable blocks. This left unnecessary BR nodes after tables in blockquote. - Lists could not be created inside a `blockquote`. Desired behavior after PR is merged: - Backspace removes the inner content first when blockquote contains nodes. - Trailing BR is removed when placed table inside blockquote. Cursor can still be placed at the edge of the table without requiring a BR anchor. - Lists can be created directly inside a blockquote. task-5864080 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#259132 Forward-Port-Of: odoo/odoo#245011
This update resolves a problem where Odoo invoices sent via Peppol were being rejected due to incorrect tax calculations. The fix ensures that the TaxableAmount is consistently calculated across all tax categories, including those with discounts and fractional prices, aligning with Peppol's requirements.
Original PR description
Steps to reproduce: 1. Create an invoice with a 0% tax (Exempt from VAT, category E) 2. Add two lines with 20% discount and fractional prices: - qty=4, price_unit=39.615 and qty=4 with…
Steps to reproduce: 1. Create an invoice with a 0% tax (Exempt from VAT, category E) 2. Add two lines with 20% discount and fractional prices: - qty=4, price_unit=39.615 and qty=4 with price_unit=0.84 3. Send via Peppol 4. Peppol rejects with: [BR-E-08] VAT category taxable amount shall equal the sum of Invoice line net amounts The TaxableAmount recalculation in _ubl_get_tax_subtotal_node was only applied for tax category 'S' (Standard Rate). However, Peppol schematron has identical rules for all tax categories: BR-E-08 (Exempt), BR-Z-08 (Zero), BR-AE-08 (Reverse Charge), etc. When lines have discounts and fractional prices, the individually rounded LineExtensionAmount values can sum to a different total than the tax base_amount. This affects both rounding modes. For 'S' taxes this was already handled, but for 'E' (and others) it caused Peppol rejection. Remove the 'S'-only filter and match dynamically against the actual tax category code so the recalculation applies universally. opw-6093243 Forward-Port-Of: odoo/odoo#258909
16 changes
Resolved issues and error corrections
This update fixes an issue where invoice periods were incorrectly calculated when subscriptions started on the 1st of a month and 'Align to Period Start' was enabled. The fix ensures invoices accurately reflect the subscription's billing cycle, displaying the correct month and dates. This prevents invoicing discrepancies and improves financial reporting.
Original PR description
Steps to reproduce: ------------------------------------- 1. Install the Subscription module. 2. Go to Subscription > Configuration > Recurring Plans. * Open a Monthly recurring plan and enable Align…
Steps to reproduce: ------------------------------------- 1. Install the Subscription module. 2. Go to Subscription > Configuration > Recurring Plans. * Open a Monthly recurring plan and enable Align to Period Start. 3. Create a new Subscription: * Select the configured monthly plan. * Add any subscription product. * In the Other Info tab, set a Start Date in the past on the 1st day of a month (e.g., 01/11/2025). 4. Confirm the subscription. 5. Create a draft invoice. Observation: ----------------------------------- In the invoice line, you see the message: `61 days 11/01/2025 to 12/31/2025` It should be: `1 Month 11/01/2025 to 11/30/2025` Issue: ----------------------------------- https://github.com/odoo/enterprise/blob/a5a76de5f25483afa5432ed333c48d78832f128c/sale_subscription/models/sale_order_line.py#L376-L378 In `_get_invoice_line_parameters`, the computation attempts to find the next 1st day of the month However, `new_period_stop` already includes the billing period. When `new_period_stop` is in the past, an extra month is added through `new_period_stop + relativedelta(months=1)`, resulting in an incorrect period range Solution: ----------------------------------- Use `new_period_start` as the anchor point for period computation. Ensure the billing period ends on the last day of the starting month when Align to Period Start is enabled For upsell orders, the fix is NOT applied because for upsells, `new_period_stop` is already set to the parent subscription's `next_invoice_date`, which represents the correct billing boundary. opw-5920036 Forward-Port-Of: odoo/enterprise#107407
This update fixes an issue where the Envia integration for Colombia was incorrectly formatting zip codes. By using Envia's geocoding service, the system now accurately transmits the required municipality codes, ensuring correct delivery processing. This resolves a previous error that caused incorrect zip code formatting and potential delivery problems.
Original PR description
For Colombia, Envia expects the municipality/DANE-style code in the address payload, not the raw postal code. When `l10n_co_edi` was not installed, the Envia integration fell back to the partner zip code and padded it locally before sending it as both `postalCode` and `city`. This produced incorrect values such as turning the Ibagué zip code `730001` into `73000100`, while Envia geocodes resolves that zip code to `73001000`. Use Envia geocodes to resolve the Colombia zip fallback and retrieve the `stat_8digit` code expected by Envia instead of deriving it locally. opw-6083181 Forward-Port-Of: odoo/enterprise#112838
This update resolves an issue where the calculation of neutralized payroll amounts was inaccurate in the Swiss HR Payroll module. The fix ensures that payroll deductions are correctly processed, leading to more precise financial reporting and compliance with Swiss tax regulations. This improves the reliability of payroll data.
This update resolves an issue preventing users from generating session reports in the CO company setting. The fix addresses a technical problem with accessing sale details, ensuring the report generation process now functions correctly. This improves the usability of the POS system for CO companies.
Original PR description
Currently when trying to generate the session report a traceback appears. Steps to reproduce: ------------------- * Install l10n_co_edi_pos * Switch to CO company * Open pos session * Make a sale * Close register * Generate session report > Traceback Why the fix: ------------ We get the sale details with: https://github.com/odoo/odoo/blob/0ce5baf2918960591284eb494d82dfef07043af0/addons/point_of_sale/models/report_sale_details.py#L429-L430 Where the config ids given to `get_sale_details` are given here https://github.com/odoo/odoo/blob/0ce5baf2918960591284eb494d82dfef07043af0/addons/point_of_sale/models/report_sale_details.py#L413-L414 From there we can't access any field from a list of number. opw-6049484 Forward-Port-Of: odoo/enterprise#111627
This update fixes a performance issue in the website's gradient picker. Previously, dragging the angle knob triggered excessive updates, causing lag. The fix now delays SCSS generation until the drag is complete, resulting in a smoother and faster editing experience.
Original PR description
Cause: ====== Because the debounce function is called with await, the execution of `debouncedSCSSColorsCusto` pauses for every mousemove event. This prevents subsequent calls from overlapping,…
Cause: ====== Because the debounce function is called with await, the execution of `debouncedSCSSColorsCusto` pauses for every mousemove event. This prevents subsequent calls from overlapping, meaning the debounce logic never triggers to cancel previous timers. This results in the heavy SCSS generation running sequentially for every single mouse movement, causing performance lag. In other words, the await forced the browser to handle one request at a time, completely finishing it before accepting the next one. Solution: ========== In the gradient picker, only update the visual CSS gradient preview during drag and defer the `onGradientChange` callback to mouseup to avoid triggering heavy operations (e.g. SCSS generation) on every mousemove. Steps to reproduce: =================== 1. Go to website & edit mode. 2. Click on Header block. 3. Click on background color preview & select Gradient & Custom. 4. Click and drag the Angle knob. => The website preview triggers excessive updates dragging the knob opw-5411628 Forward-Port-Of: odoo/odoo#241764
This update ensures that table assignments are consistently synchronized across all devices within a POS session. Previously, a waiter marking a table as occupied on one device wouldn't reflect that status on other devices. The fix also improves synchronization by treating table-based orders as 'pending', ensuring immediate updates.
Original PR description
When a waiter selects a table without adding any items and returns to the floor screen, the table appears as occupied (green) on their device but not on other devices in the same POS session. Steps to reproduce: ------------------- * Open POS session on device A * Open same POS session on device B * On device A: click a table, don't add items, go back to floor * On device B: observe the table does not appear as occupied > Observation: Empty table assignments were not being synced to the server, so other devices couldn't detect the table occupancy. Why the fix: ------------ Also treat orders with a table_id as pending so they sync immediately when a table is opened. The backend already supports this: pos.order can be created with just table_id, and pos_restaurant._get_open_order looks orders up by table_id for table-based sync. opw-5236119 Forward-Port-Of: odoo/odoo#241321
This update fixes a limitation where users couldn't edit images on product pages after replacing them. The change ensures that image editing options are displayed correctly only when the image is newly uploaded, preventing confusion and improving the user experience for updating product visuals. This ensures consistent functionality across the eCommerce platform.
Original PR description
## Context On the website page of a product, users can transform a picture in various ways (shape, size, cropping, etc.) when uploading it. ## Issue When uploading a new picture, users can only…
## Context On the website page of a product, users can transform a picture in various ways (shape, size, cropping, etc.) when uploading it. ## Issue When uploading a new picture, users can only replace the image or reorder it, but they cannot reshape it, crop it, or edit its size. ## Steps to reproduce 1. Install the *eCommerce* (`website_sale`) app. 2. Create a product and set a picture for it. 3. Go to that product's page in the Website app and open the website editor. 4. Click on the picture and replace it. 5. **The options to transform the picture are not displayed.** ## Cause The transformation options are disabled due to the following static `exclude` variable in `ImageToolOption`: https://github.com/odoo/odoo/blob/2b6b937c1c6d92e4e8b4657ae62127f0f8a7eb56/addons/html_builder/static/src/plugins/image/image_tool_option.js#L16 ## Solution We should prevent the transformation options from being displayed **only** when the image is external. In such cases, certain options from the `ImageToolOption` (such as the `ImageTransformOption` or the `ImageShapeOption`) cannot be applied. This is confirmed by the message displayed when trying to crop an external image: https://github.com/odoo/odoo/blob/2b6b937c1c6d92e4e8b4657ae62127f0f8a7eb56/addons/web_editor/static/src/js/wysiwyg/widgets/image_crop.js#L164-L173 We can determine whether an image is external by looking at its `data-attachment-id` property. If it is present, the image was recently uploaded to Odoo. On top of updating the `exclude` variable, we need to filter out the options that cannot be used on images from the eCommerce. These options are: - Description - Tooltip - Transform (*"Transform the picture"*) - Size ## Tests The test checks that the behavior matches the one from previous versions: the options to edit an image are not displayed before replacing the image, but are displayed after. Both the test `image field should not be editable, but the image can be replaced` (shown below) and the new test from this PR fail if the modified `exclude` variable allow to edit the image before replacing it. https://github.com/odoo/odoo/blob/dea5a1d28a1935c2b4d87c3c6e8c07cd874c7d6b/addons/html_builder/static/tests/image_field.test.js#L7-L16 ## Options displayed | | Before this commit | After this commit | Previous versions | |---|---|---|---| | **Before replacing the image** | Media, Re-order | Media, Re-order | Media, Re-order | **After replacing the image** | Media, Re-order | Media, Re-order, Shape, Transform (crop), Filter, Format, Quality | Media, Re-order, Shape, Transform (crop), Filter, Format, Quality opw-5251864 Forward-Port-Of: odoo/odoo#247539 Forward-Port-Of: odoo/odoo#241071
This update ensures that payments registered in the future are not processed according to Mexican government regulations (CFDI). The system now filters out future payments, removing the 'Update Payments' button when only future payments are present, ensuring compliance and avoiding potential errors.
Original PR description
To sign a payment registered in the future is not allowed by the government. See http://omawww.sat.gob.mx/tramitesyservicios/Paginas/documentos/Guia_llenado_pagos.pdf Steps: - Create a PDD invoice (the due date should be at least 1 month later than the invoice date) - Send it to CFDI - Register a payment in the future -> We have the 'Update payments' button that appear on the invoice view, if you clik on it the payment will be signed With this commit, we filter out the payments with a future date, that way we don't have the 'Update Payments' button if there are only future payments, or the future payments won't be taken into account when clicking on the button. opw-5934753 Forward-Port-Of: odoo/enterprise#113945 Forward-Port-Of: odoo/enterprise#112320
This update resolves an issue where the chat composer on mobile devices would become unresponsive when the navigation menu was open. The fix prevents the navigation menu from stealing focus from the composer, ensuring users can consistently access and use the chat feature. This improves the mobile user experience.
Original PR description
**Description of the issue this PR addresses:** On mobile devices, the chat composer becomes unresponsive when the navigation menu `navbar-toggler` is open.…
**Description of the issue this PR addresses:** On mobile devices, the chat composer becomes unresponsive when the navigation menu `navbar-toggler` is open. https://github.com/user-attachments/assets/8ef01ec6-4a44-41d3-8b86-74f68caf47ef Steps to reproduce: 1. Open the website in a mobile view. 2. Tap the navbar toggler to open the mobile menu. 3. Without closing the menu, open the chat window. 4. Tap on the message composer text area. → The composer is not accessible. This happens because the bootstrap `Offcanvas` (used by the `navbar-toggler`) traps focus by listening for `focusin` events bubbling up to the document. When the composer is tapped, the Offcanvas intercepts the event and immediately steals focus back to itself, dismissing the virtual keyboard. This commit stops the event propagation at the composer level, ensuring the composer can reliably retain focus in responsive views without interference from active menus. Task-[5954657](https://www.odoo.com/odoo/project/1519/tasks/5954657) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#259257 Forward-Port-Of: odoo/odoo#250294
This update resolves a bug in the AI composer that was causing crashes. The fix ensures that focus events are correctly passed to the base handler, maintaining stability and preventing errors when the AI composer is used. This improves the overall reliability of the AI composer functionality.
Original PR description
**Purpose of this PR:** The AI composer patch overrides `Composer.onFocusin()` but did not forward the focus event to the base handler. This used to be harmless while the base mail composer focus handler did not use the event. Since odoo/odoo#258974, the mail composer now uses the event to stop `focusin` propagation, so dropping it makes the base handler crash when AI composer focus is triggered. This commit fixes the AI composer patch by forwarding the focus event to the base handler, preserving the expected handler contract. Related: odoo/odoo#258974 Task-5954657 Forward-Port-Of: odoo/enterprise#113873 Forward-Port-Of: odoo/enterprise#113763
This update fixes an issue where Backspace within a blockquote would unexpectedly remove the blockquote content. Now, Backspace correctly deletes the inner content, and lists can be created directly inside blockquotes. This enhances the usability of the HTML editor for formatting content.
Original PR description
Description of the issue this PR addresses: - Pressing Backspace inside a blockquote that has visible content but no text content removes the blockquote instead of the content. The content (image or table) gets moved outside of the blockquote. - Trailing BR was kept after tables because tables are marked as unsplittable blocks. This left unnecessary BR nodes after tables in blockquote. - Lists could not be created inside a `blockquote`. Desired behavior after PR is merged: - Backspace removes the inner content first when blockquote contains nodes. - Trailing BR is removed when placed table inside blockquote. Cursor can still be placed at the edge of the table without requiring a BR anchor. - Lists can be created directly inside a blockquote. task-5864080 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#259132 Forward-Port-Of: odoo/odoo#245011
This update resolves an issue where Peppol invoices with zero-rated VAT (Exempt category) were being rejected due to incorrect tax calculations. The fix ensures that the taxable amount is consistently calculated across all tax categories, aligning with Peppol's requirements and preventing invoice rejections.
Original PR description
Steps to reproduce: 1. Create an invoice with a 0% tax (Exempt from VAT, category E) 2. Add two lines with 20% discount and fractional prices: - qty=4, price_unit=39.615 and qty=4 with…
Steps to reproduce: 1. Create an invoice with a 0% tax (Exempt from VAT, category E) 2. Add two lines with 20% discount and fractional prices: - qty=4, price_unit=39.615 and qty=4 with price_unit=0.84 3. Send via Peppol 4. Peppol rejects with: [BR-E-08] VAT category taxable amount shall equal the sum of Invoice line net amounts The TaxableAmount recalculation in _ubl_get_tax_subtotal_node was only applied for tax category 'S' (Standard Rate). However, Peppol schematron has identical rules for all tax categories: BR-E-08 (Exempt), BR-Z-08 (Zero), BR-AE-08 (Reverse Charge), etc. When lines have discounts and fractional prices, the individually rounded LineExtensionAmount values can sum to a different total than the tax base_amount. This affects both rounding modes. For 'S' taxes this was already handled, but for 'E' (and others) it caused Peppol rejection. Remove the 'S'-only filter and match dynamically against the actual tax category code so the recalculation applies universally. opw-6093243 Forward-Port-Of: odoo/odoo#258909
This update ensures that the REAGYP compensation amount is accurately included in the deductible quota submitted to the Spanish tax authority (AEAT). Previously, this amount was missing, leading to potential discrepancies. The fix adds a necessary check to the calculation process, ensuring compliance with Spanish tax regulations.
Original PR description
Currently, the deducible amount for REAGYP is not passing through to the AEAT. This happens because the REAGYP compensation amount (ImporteCompensacionREAGYP) was missing from the total deductible quota calculation in the SII JSON payload. To fix this, we add 'sujeto_agricultura' to the list that cheks if the tax value for l10n_es is in the list task-6072773 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#259232 Forward-Port-Of: odoo/odoo#256586
This update fixes an issue where recruitment officers couldn't view job tracker information. The change ensures officers can access this critical data directly through their recruitment role, simplifying the hiring process and eliminating the need for additional employee permissions. This improves efficiency and streamlines workflows for the recruitment team.
Original PR description
Steps to reproduce: ---------------------------------------- 1. Install the `hr_recruitment` module 2. Create a new user and configure the following access rights: * Employees: No * Recruitment:…
Steps to reproduce:
----------------------------------------
1. Install the `hr_recruitment` module
2. Create a new user and configure the following access rights:
* Employees: No
* Recruitment: Officer Manage all applicants
3. Create new job position > Set created user in Recruiter
4. Log in with the created user
5. Go to Recruitment > Click on the Configure button of that job position
Observation:
----------------------------------------
The Trackers page is not visible on the job position form for the recruitment officer user.
If the user is additionally granted the Employees → Officer: Manage all employees group, the Trackers page becomes visible. The access to the recruitment Trackers should not depend on the Employee 'Officer: Manage all employees' access right.
Issue:
----------------------------------------
The visibility of the Trackers page depends on the Employees → Officer: Manage all employees group instead of the recruitment officer access rights
Solution:
----------------------------------------
Grant access to the Trackers page using the Recruitment Officer group so recruitment officers can access it without requiring the employee officer privileges
opw-5969416
Forward-Port-Of: odoo/odoo#252209This update fixes an issue where the event ticket download button wasn't appearing for online payments. The fix ensures that necessary data is always set, regardless of the payment method, allowing users to correctly download their tickets after completing an online purchase. This improves the user experience for all event ticket sales.
Original PR description
**Steps to reproduce:** - Set up an event, go put it's state to Annonced - Set up any online payment method (Demo also triggers the bug) - Go to a PoS that sells the event tickets - Purchase one and…
**Steps to reproduce:** - Set up an event, go put it's state to Annonced - Set up any online payment method (Demo also triggers the bug) - Go to a PoS that sells the event tickets - Purchase one and pay with the online payment method - Once on the ticket screen, the button to download the event tickets is not displayed **Why the fix:** The normal flow only works for offline payment methods, because we check if the ordered is either paid or invoiced before setting all the values needed by the frontend regarding the ticket registration. The problem is that with an online payment method, once we enter the **read_pos_data** method that sets the values for the frontend, the order is still in draft, so we just return without doing anything. We now set the values regardless of the order's status and send the confirmation mail in the same way as if it was an online payment. In the case of an online payment, the mail will be sent by the **action_pos_order_paid** function that is called once the payment is processed. A test might be a bit weird to make as we don't have a bridge for pos_online_payment and pos_event, and that we would need to mock the server's answer to be able to pay for the online payment and check that we have the needed values. So the setup for pos_event would have to be copied into pos_online_payment to test it and it would only be ran if both modules are installed. opw-5438432 Forward-Port-Of: odoo/odoo#258986 Forward-Port-Of: odoo/odoo#249306
This update ensures that live chat agents can consistently see and use the live chat button while actively engaged in existing conversations. Previously, agents couldn't initiate new chats while already part of an active live chat. This improvement streamlines the agent workflow and enhances user experience.
Original PR description
Previously, users who were part of active livechats as agents could not see the livechat button to start a new conversation. This change ensures the button remains visible so users can start additional livechats as a visitor. task-[5119098](https://www.odoo.com/odoo/project/1519/tasks/5119098) Forward-Port-Of: odoo/odoo#258688 Forward-Port-Of: odoo/odoo#253894
2 changes
Resolved issues and error corrections
This update resolves an issue where the checkout process became unresponsive when using Avatax with Brazilian tax identification. The previous code was unnecessarily calling external tax APIs, leading to errors that blocked the confirmation step. This fix removes the unnecessary API call, improving checkout stability and performance.
Original PR description
Issue: --- The extra external_tax call introduced in odoo/enterprise#101579 is causing multiple issues: 1- It doesn't catch errors while `_get_and_set_external_taxes_on_eligible_records` easily raises errors, causing uncatch errors in `website_sale`. 2- Extra unnecessary external api call in non-express checkout methods which is not desirable. Steps to reproduce: --- 1- Install l10n_br_avatax_sale, website_sale 2- Using a public user, add a product to cart and got to checkout. 3- In the address form, use CPF identification type. Outcome: The confirm button is unresponsive. Cause: --- This is due to uncatch error raised by external tax call, while it was not necessary at this step of this flow to call external tax api. opw-6005767 Forward-Port-Of: odoo/enterprise#113861 Forward-Port-Of: odoo/enterprise#112515
This update ensures that payments registered in the future are not processed according to Mexican tax regulations (CFDI). The system now filters out future payments, removing the 'Update Payments' button when only future payments are present, preventing incorrect tax signing and maintaining compliance.
Original PR description
To sign a payment registered in the future is not allowed by the government. See http://omawww.sat.gob.mx/tramitesyservicios/Paginas/documentos/Guia_llenado_pagos.pdf Steps: - Create a PDD invoice (the due date should be at least 1 month later than the invoice date) - Send it to CFDI - Register a payment in the future -> We have the 'Update payments' button that appear on the invoice view, if you clik on it the payment will be signed With this commit, we filter out the payments with a future date, that way we don't have the 'Update Payments' button if there are only future payments, or the future payments won't be taken into account when clicking on the button. opw-5934753 Forward-Port-Of: odoo/enterprise#113945 Forward-Port-Of: odoo/enterprise#112320
11 changes
Resolved issues and error corrections
This update resolves an issue where Odoo invoices sent via Peppol were being rejected due to incorrect tax calculations. The fix ensures that the TaxableAmount is consistently calculated across all tax categories, including those with discounts and fractional prices, aligning with Peppol's requirements.
Original PR description
Steps to reproduce: 1. Create an invoice with a 0% tax (Exempt from VAT, category E) 2. Add two lines with 20% discount and fractional prices: - qty=4, price_unit=39.615 and qty=4 with…
Steps to reproduce: 1. Create an invoice with a 0% tax (Exempt from VAT, category E) 2. Add two lines with 20% discount and fractional prices: - qty=4, price_unit=39.615 and qty=4 with price_unit=0.84 3. Send via Peppol 4. Peppol rejects with: [BR-E-08] VAT category taxable amount shall equal the sum of Invoice line net amounts The TaxableAmount recalculation in _ubl_get_tax_subtotal_node was only applied for tax category 'S' (Standard Rate). However, Peppol schematron has identical rules for all tax categories: BR-E-08 (Exempt), BR-Z-08 (Zero), BR-AE-08 (Reverse Charge), etc. When lines have discounts and fractional prices, the individually rounded LineExtensionAmount values can sum to a different total than the tax base_amount. This affects both rounding modes. For 'S' taxes this was already handled, but for 'E' (and others) it caused Peppol rejection. Remove the 'S'-only filter and match dynamically against the actual tax category code so the recalculation applies universally. opw-6093243 Forward-Port-Of: odoo/odoo#258909
This update resolves an issue where a Peppol document would repeatedly be created when a user removed their journal configuration. The fix ensures that acknowledgements are correctly sent to IAP, preventing unnecessary document duplication and improving the reliability of Peppol document processing. This ensures accurate data exchange and avoids potential delays.
Original PR description
When a user removes its journal on its Peppol configuration, when receiving one, a new document would be created but the acknowledgement would never be sent to IAP. Everytime the user tries to retrieve new documents, the same document would then be created again. Forward-Port-Of: odoo/odoo#259330
This update resolves an issue where a new Peppol document was incorrectly created and repeatedly generated when a user removed their journal configuration. The fix ensures that acknowledgements are properly sent to IAP, preventing duplicate document creation and improving the reliability of the Peppol integration.
Original PR description
When a user removes its journal on its Peppol configuration, when receiving one, a new document would be created but the acknowledgement would never be sent to IAP. Everytime the user tries to retrieve new documents, the same document would then be created again. Forward-Port-Of: odoo/enterprise#113922
This update fixes an issue where transaction date ranges were sometimes inaccurate when importing data from Codabox. The change ensures that the date range used for importing transactions is always the latest available date – either the Codabox lock date or the last statement date – preventing data discrepancies.
Original PR description
To fetch transactions from iap, we have to give a date from. Before this commit, it was possible to have a date from prior the lock date which is not supposed to happen. This commit will do the max between the lock date the last date of either the statement or the statement line. task-6019584 Forward-Port-Of: odoo/enterprise#110010
This update fixes an issue where tax group changes could cause errors due to account updates not being synchronized. The change ensures that account relationships within tax groups are only updated when necessary, preventing constraint violations and improving system stability. This primarily impacts how tax groups are managed and related to accounts.
Original PR description
Upon chart reload, accounts will not be updated (except for tax_ids), but tax groups are. If a tax group was changed to relate to a different account and this account was re-purposed (e.g.…
Upon chart reload, accounts will not be updated (except for tax_ids), but tax groups are. If a tax group was changed to relate to a different account and this account was re-purposed (e.g. account_type changed from an incompatible to a compatible type, the fact that the account is not updated will trigger constraints in the tax group when it is written. IOW, if the purpose of an account is not changed, its use should not be changed either. E.g.: 1f4710deb206736cd71580d8fd95552d9b7c8014 changed the value of `tax_payable_account_id` on tax group `tax_group_cofins_incl_goods` to `account_template_202011005` and the same commit changed the value of `account_type` on `account_template_202011005` from `liability_non_current` to `liability_payable`, triggering `_constrains_payable_receivable_account` (in 19.2: https://github.com/odoo/odoo/blob/e00dd21880c3c4e5c22d65567c700e02541f7259/addons/account/models/account_tax.py#L68). So here, we skip the update of relations to accounts on tax groups, if the account already exists. Forward-Port-Of: odoo/odoo#259160
This update resolves an issue preventing users from generating session reports in the CO company setting. The fix addresses a technical error related to accessing sale details, ensuring the report generation process now functions correctly. This improves the usability of the POS system for CO companies.
Original PR description
Currently when trying to generate the session report a traceback appears. Steps to reproduce: ------------------- * Install l10n_co_edi_pos * Switch to CO company * Open pos session * Make a sale * Close register * Generate session report > Traceback Why the fix: ------------ We get the sale details with: https://github.com/odoo/odoo/blob/0ce5baf2918960591284eb494d82dfef07043af0/addons/point_of_sale/models/report_sale_details.py#L429-L430 Where the config ids given to `get_sale_details` are given here https://github.com/odoo/odoo/blob/0ce5baf2918960591284eb494d82dfef07043af0/addons/point_of_sale/models/report_sale_details.py#L413-L414 From there we can't access any field from a list of number. opw-6049484 Forward-Port-Of: odoo/enterprise#111627
This update resolves an issue where the Avatax integration in the express checkout process was causing the confirmation button to become unresponsive. The fix removes unnecessary external API calls related to tax calculations, streamlining the checkout flow and improving stability. This change addresses a bug related to error handling during tax calculations.
Original PR description
Issue: --- The extra external_tax call introduced in odoo/enterprise#101579 is causing multiple issues: 1- It doesn't catch errors while `_get_and_set_external_taxes_on_eligible_records` easily raises errors, causing uncatch errors in `website_sale`. 2- Extra unnecessary external api call in non-express checkout methods which is not desirable. Steps to reproduce: --- 1- Install l10n_br_avatax_sale, website_sale 2- Using a public user, add a product to cart and got to checkout. 3- In the address form, use CPF identification type. Outcome: The confirm button is unresponsive. Cause: --- This is due to uncatch error raised by external tax call, while it was not necessary at this step of this flow to call external tax api. opw-6005767 Forward-Port-Of: odoo/odoo#259229 Forward-Port-Of: odoo/odoo#256692
This update resolves an issue where the checkout process became unresponsive when using the Avatax module with the Brazilian localization. The previous code was unnecessarily calling external tax APIs, leading to errors and preventing users from completing their purchases. This fix removes the unnecessary API calls, restoring the checkout functionality.
Original PR description
Issue: --- The extra external_tax call introduced in odoo/enterprise#101579 is causing multiple issues: 1- It doesn't catch errors while `_get_and_set_external_taxes_on_eligible_records` easily raises errors, causing uncatch errors in `website_sale`. 2- Extra unnecessary external api call in non-express checkout methods which is not desirable. Steps to reproduce: --- 1- Install l10n_br_avatax_sale, website_sale 2- Using a public user, add a product to cart and got to checkout. 3- In the address form, use CPF identification type. Outcome: The confirm button is unresponsive. Cause: --- This is due to uncatch error raised by external tax call, while it was not necessary at this step of this flow to call external tax api. opw-6005767 Forward-Port-Of: odoo/enterprise#113861 Forward-Port-Of: odoo/enterprise#112515
This update addresses a regulatory requirement in Mexico (CFDI) that prohibits signing payments registered in the future. The code now filters out future payments, removing the 'Update Payments' button when only future payments are present. This ensures compliance and avoids potential issues with government regulations.
Original PR description
To sign a payment registered in the future is not allowed by the government. See http://omawww.sat.gob.mx/tramitesyservicios/Paginas/documentos/Guia_llenado_pagos.pdf Steps: - Create a PDD invoice (the due date should be at least 1 month later than the invoice date) - Send it to CFDI - Register a payment in the future -> We have the 'Update payments' button that appear on the invoice view, if you clik on it the payment will be signed With this commit, we filter out the payments with a future date, that way we don't have the 'Update Payments' button if there are only future payments, or the future payments won't be taken into account when clicking on the button. opw-5934753 Forward-Port-Of: odoo/enterprise#113945 Forward-Port-Of: odoo/enterprise#112320
This update fixes an issue where web applications could incorrectly access data due to cached records. Specifically, when users edit records with x2many fields, the system now filters these records based on the user's current permissions before displaying them, preventing access errors and ensuring data security. This improves the reliability of web-based features.
Original PR description
**Description of the issue/feature this PR addresses**: web_read on x2many fields can reuse cached ids after write/web_save. Some of these cached ids may be inaccessible with the current record…
**Description of the issue/feature this PR addresses**:
web_read on x2many fields can reuse cached ids after write/web_save. Some of these cached ids may be inaccessible with the current record rules/context (cache pollution).
**Example**:
- **Context**:
- Two companies exist: Company A and Company B.
- Two users exist: User A and User B.
- User A can only access Company A (company_ids=[A], company_id=A).
- User B is linked to both companies (company_ids=[A, B], company_id=A).
- The "res.company" record rule is the standard one: [('id', 'in', company_ids)] (company_ids comes from allowed_company_ids).
- User A edits User B and saves the form.
- **Steps**:
- User A performs a web_read to load User B: company_ids contains only Company A.
- User A performs web_save (write + internal web_read in the same request): cached ids [A, B] are reused and the code attempts to read Company B.
**Current behavior before PR (without fix)**:
After saving a form with an x2many field, web_save calls write and then web_read. In this flow, web_read can include inaccessible x2many ids from cache and raise an AccessError.
**Desired behavior after PR is merged**:
x2many records are re-filtered with current read rules before formatting, and inaccessible ids are removed from values_list.
Forward-Port-Of: odoo/odoo#257517
Forward-Port-Of: odoo/odoo#250904This update fixes an inconsistency in how rental prices are calculated when dealing with time-zoned dates. Previously, using relativedelta on UTC dates resulted in incorrect price calculations. Now, the system accurately determines the rental duration based on the start and end dates in their respective time zones, ensuring consistent pricing across different locations.
Original PR description
Relativedelta on UTC dates or time-zoned dates doesn't return the same result. In order to calculate consistent prices (price for 1 month in December = price for 1 month in January), we need to work…
Relativedelta on UTC dates or time-zoned dates doesn't return the same result. In order to calculate consistent prices (price for 1 month in December = price for 1 month in January), we need to work on time-zoned dates. Example: Consider a website in UTC+1 (Brussels timezone DST off). And a rental from the 01/12/2025 to the 31/12/2025 = by design, from the 01/01/2025 00h00 (start_date) to the 31/12/2025 23h59 (end_date). Converted in UTC for the back-end, we have: from the 30/11/2025 23h00 to the 31/12/2025 22h59. relativedelta(end_date, start_date) = time between the 2 dates is calculated as follow: 30/11/2025 23h00 + 1 month = 30/12/2025 23h00 +23h59 = 31/12/2025 22h59. Time difference = 1 month, 23 hours, 59 minutes. Price = 2 months. Consider a second rental from the 01/01/2026 to the 31/01/2026. 31/12/2025 23h00 + 30 days = 30/01/2026 23h + 23h59 = 31/01/2026 22h59. Time difference = 30 days, 23 hours, 59 minutes. Price = 1 month. opw-5130762 Forward-Port-Of: odoo/enterprise#101714 Forward-Port-Of: odoo/enterprise#98571
3 changes
Resolved issues and error corrections
This update resolves a recurring problem where a new Peppol document was incorrectly created when a user removed their journal configuration. Previously, acknowledgements weren't sent, leading to duplicate document creation. This fix ensures proper acknowledgement transmission, streamlining Peppol document processing.
Original PR description
When a user removes its journal on its Peppol configuration, when receiving one, a new document would be created but the acknowledgement would never be sent to IAP. Everytime the user tries to retrieve new documents, the same document would then be created again. Forward-Port-Of: odoo/enterprise#113922
This update resolves an issue preventing users from generating session reports within the CO company's point-of-sale system. The fix ensures that sale details are correctly retrieved, allowing users to accurately track sales data. This improves the reliability of the CO company's financial reporting.
Original PR description
Currently when trying to generate the session report a traceback appears. Steps to reproduce: ------------------- * Install l10n_co_edi_pos * Switch to CO company * Open pos session * Make a sale * Close register * Generate session report > Traceback Why the fix: ------------ We get the sale details with: https://github.com/odoo/odoo/blob/0ce5baf2918960591284eb494d82dfef07043af0/addons/point_of_sale/models/report_sale_details.py#L429-L430 Where the config ids given to `get_sale_details` are given here https://github.com/odoo/odoo/blob/0ce5baf2918960591284eb494d82dfef07043af0/addons/point_of_sale/models/report_sale_details.py#L413-L414 From there we can't access any field from a list of number. opw-6049484 Forward-Port-Of: odoo/enterprise#111627
This update ensures that the date range used to fetch transactions from iap is always accurate. Previously, incorrect date ranges could occur, but this fix now uses the latest statement or statement line date, guaranteeing correct transaction retrieval. This improves the reliability of IAP data.
Original PR description
To fetch transactions from iap, we have to give a date from. Before this commit, it was possible to have a date from prior the lock date which is not supposed to happen. This commit will do the max between the lock date the last date of either the statement or the statement line. task-6019584 Forward-Port-Of: odoo/enterprise#110010
3 changes
Resolved issues and error corrections
This update ensures that transaction dates used to fetch data from iap are always within the correct 'lock date' range. Previously, dates could be inaccurate, leading to potential data discrepancies. This fix guarantees the most reliable and accurate retrieval of financial information.
Original PR description
To fetch transactions from iap, we have to give a date from. Before this commit, it was possible to have a date from prior the lock date which is not supposed to happen. This commit will do the max between the lock date the last date of either the statement or the statement line. task-6019584 Forward-Port-Of: odoo/enterprise#110010
This update resolves an issue where the system was incorrectly retrieving neutralization data for payroll calculations in Switzerland. The fix ensures accurate payroll processing by correcting the way the system fetches this critical information. This improves the reliability of financial reporting related to employee compensation.
Original PR description
Forward-Port-Of: odoo/enterprise#113961
This update enhances the Sign module's user experience by streamlining request workflows and addressing key usability issues. Specifically, users can now cancel sent signature requests and receive prompts to update contact information, while a critical bug causing issues with the 'Thank You' dialog has been resolved.
Original PR description
This commit introduces several UX improvements, workflow adjustments, and bug fixes to the Sign module to streamline the user experience. Specific changes: - Views & UI: - Add a related model filter to the sign templates search view. - Clean up the sign request pivot view by removing irrelevant measures. - Request Management: - Allow the original request sender to cancel a sent signature request. - Stop automatically saving the certificate of completion into the Documents app. - Integrate the missing-email popover into the Send Sign Request wizard to prompt users to update contacts on the fly. - Bug Fixes: - [FIX] Resolve the dismiss bug in the Thank You dialog by properly hooking the ESC key/background click into the global dialog environment.
7 changes
Resolved issues and error corrections
This update resolves a critical issue in the payroll processing for Mexico that could cause the system to crash when no bank account information was available for an employee. The change ensures the system handles missing data gracefully, preventing errors and maintaining accurate payroll calculations. This improves stability and data integrity.
Original PR description
Accessing the employee bank accounts using index [0] raised an IndexError when no accounts were defined. Additionally, computing the CLABE flag using len() caused a TypeError when the account number was missing. This change uses a safe recordset slice to avoid accessing empty records and guards the length check to only evaluate when a value is present. It prevents crashes while keeping the original behavior unchanged and avoids sending invalid empty values in the CFDI.
This update resolves a bug preventing portal users from uploading files correctly on mobile devices. The issue stemmed from a change in the user interface component, causing file selection to fail. The fix ensures proper file uploads for mobile users.
Original PR description
**Steps to reproduce:** - Install Documents app - As admin, share a folder to a portal user with editor access - Log as portal user on mobile view - Try to upload a new file from the control panel -…
**Steps to reproduce:** - Install Documents app - As admin, share a folder to a portal user with editor access - Log as portal user on mobile view - Try to upload a new file from the control panel - File dialog appears, but selected file is not saved **Issue:** Seems like changing the boostraps dropdown to the owl component created this issue. It is caused by Upload button trying to use the `<input>` of its parent dropdown. When the dialog opens, the current dropdown and its parent are removed (with the surrounding overlay) due to the default closingMode. `onSelected="() => this.uploadFileInputRef.el.click()"` Also the page has multiple time the same `<input>` element due to the duplication of the actions for the bottom drawer. **Fix:** Put the `<input>` element in a place where it won't be duplicated on mobile when creating the overlay with the upload interactions. This ensures we always use the same `<input>` element for the dropdown, so that files are properly added even if the dropdown is removed. We could also change the closingMode to `closest` or `none` and manually close the remaining dropdown(s) on file upload. dropdown component: https://github.com/odoo/enterprise/commit/06802d3d6cc5141842adba74f7c9f1970feeb263 similar issue for non-portal user: https://github.com/odoo/odoo/commit/8a871a120b75f7c09c70dbf07530239244dbb5d6 opw-6042353
This update addresses a regulatory requirement in Mexico regarding electronic payments (CFDI). The system now prevents users from registering payments with future dates, which were previously allowed and not compliant with government regulations. This ensures accurate and legal payment processing.
Original PR description
To sign a payment registered in the future is not allowed by the government. See http://omawww.sat.gob.mx/tramitesyservicios/Paginas/documentos/Guia_llenado_pagos.pdf Steps: - Create a PDD invoice (the due date should be at least 1 month later than the invoice date) - Send it to CFDI - Register a payment in the future -> We have the 'Update payments' button that appear on the invoice view, if you clik on it the payment will be signed With this commit, we filter out the payments with a future date, that way we don't have the 'Update Payments' button if there are only future payments, or the future payments won't be taken into account when clicking on the button. opw-5934753 Forward-Port-Of: odoo/enterprise#113945 Forward-Port-Of: odoo/enterprise#112320
This update enables quick checkout by default for event and appointment bookings, streamlining the purchase process. Previously, a broad change risked disrupting existing flows, but we've determined that customer addresses aren't relevant for event taxes. A new system parameter allows businesses to retain full billing address details if needed.
Original PR description
Forward-Port-Of: odoo/enterprise#113724 Forward-Port-Of: odoo/enterprise#113575
This update fixes a reporting issue on the Swiss Balance Sheet by changing the date range used for calculating 'Current Year Retained Earnings'. Previously, the default date scope caused inaccurate figures. This change ensures the report reflects the correct fiscal year, improving the accuracy of Swiss financial reporting.
Original PR description
The "Current Year Retained Earnings" (CH_299_A) line on the Swiss Balance Sheet was using the default `strict_range` date scope. This commit forces the `date_scope` to `from_fiscalyear`. task-6119493
This update fixes a calculation error in the Luxembourg tax reports. Previously, a line item was displaying a negative value, which was incorrect. The formula has been adjusted to accurately reflect the credited amount, ensuring correct tax reporting for LU companies. This resolves a discrepancy impacting financial reporting accuracy.
Original PR description
Steps to reproduce: - Install `l10n_lu` module - Switch to `LU Company` - Create a invoice and in journal items use tax grid `226` - Open the Tax Report and check the line `226 - Supplies carried out within the scope of the special arrangement of art. 56sexies` - The value appears negative instead of positive. Cause: This issue is caused by the major tax revamp introduced in version 19 [commit]. The credited amount is currently displayed as a negative value, which is incorrect, it should be shown as positive. Solution: To resolve this issue, the formula has been modified from `226` to `-226`. [commit]: https://github.com/odoo/odoo/commit/17a6117ed88c29b5bc4db0c872bcdbc109a7d98b#diff-3441c5d05315ec0562923797f973eae66488452a6772d23e198998c1890aa06c opw-6050665
This update resolves an issue where the checkout process became unresponsive when using the Avatax module for Brazilian sales. The previous code was unnecessarily calling external tax APIs, leading to errors that blocked the confirmation step. This fix removes the unnecessary API call, restoring the checkout functionality.
Original PR description
Issue: --- The extra external_tax call introduced in odoo/enterprise#101579 is causing multiple issues: 1- It doesn't catch errors while `_get_and_set_external_taxes_on_eligible_records` easily raises errors, causing uncatch errors in `website_sale`. 2- Extra unnecessary external api call in non-express checkout methods which is not desirable. Steps to reproduce: --- 1- Install l10n_br_avatax_sale, website_sale 2- Using a public user, add a product to cart and got to checkout. 3- In the address form, use CPF identification type. Outcome: The confirm button is unresponsive. Cause: --- This is due to uncatch error raised by external tax call, while it was not necessary at this step of this flow to call external tax api. opw-6005767 Forward-Port-Of: odoo/enterprise#113861 Forward-Port-Of: odoo/enterprise#112515
11 changes
Resolved issues and error corrections
This update ensures that raw component moves in manufacturing orders consume the correct quantities of materials. Previously, the system incorrectly added all available stock to the production, even when manually adjusting quantities on the move line. This fix now prioritizes the quantities specified on the move line, ensuring accurate material consumption and reducing potential overstocking issues.
Original PR description
Commit https://github.com/odoo-dev/odoo/commit/63e44737fe469ab56b8e8e96c1ad47205ead1094 force `picked` to `True` when editing the stock move line in mrp module. The issue is, having Manufacturing installed, writing on any stock move (even in a picking) will go throughout this code and mark the move as picked. This commit adds a contrains to only update raw component moves. Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update fixes an issue where manually set lot quantities during manufacturing order production were not being applied correctly. The change ensures that the specified lot quantity is used first, resolving discrepancies in consumed lot amounts. This improves accuracy in tracking materials used in production.
Original PR description
**Issue** Lots manually indicated on stock move lines can be overridden when producing a Manufacturing Order. **Steps to reproduce** - Create a storable product P tracked by lot - Create two lots for…
**Issue** Lots manually indicated on stock move lines can be overridden when producing a Manufacturing Order. **Steps to reproduce** - Create a storable product P tracked by lot - Create two lots for product P with 2 units each - Create a MO for a product consuming two units P and confirm it - On the raw move, manually set 1 unit for each lot - Click on "Produce All" - Check the move line associated to the product P -> 2 units associated to the first lot consumed instead of 1 unit each **Cause** While producing: https://github.com/odoo/odoo/blob/0fe2023dc57b6cc02bd399d3c8fc5d6c8ed6e833/addons/mrp/models/mrp_production.py#L2109-L2110 It sets the quantities: https://github.com/odoo/odoo/blob/0fe2023dc57b6cc02bd399d3c8fc5d6c8ed6e833/addons/mrp/models/mrp_production.py#L2246 This calls `_set_quantity_done_prepare_vals` with a qty of 2: https://github.com/odoo/odoo/blob/0fe2023dc57b6cc02bd399d3c8fc5d6c8ed6e833/addons/stock/models/stock_move.py#L2264 which will, for each move line: - Take the quantity indicated by move line: https://github.com/odoo/odoo/blob/0fe2023dc57b6cc02bd399d3c8fc5d6c8ed6e833/addons/stock/models/stock_move.py#L2274 https://github.com/odoo/odoo/blob/0fe2023dc57b6cc02bd399d3c8fc5d6c8ed6e833/addons/stock/models/stock_move.py#L2296-L2297 - Then take all the available quantity left for the lot associated to the move line: https://github.com/odoo/odoo/blob/0fe2023dc57b6cc02bd399d3c8fc5d6c8ed6e833/addons/stock/models/stock_move.py#L2302-L2309 https://github.com/odoo/odoo/blob/0fe2023dc57b6cc02bd399d3c8fc5d6c8ed6e833/addons/stock/models/stock_move.py#L2326-L2327 Instead of first taking all the quantity indicated by the move line, before checking available quantity **Solution** Assume that raw move lines being created in mrp without changing the producing quantity are manually created opw-5946439
This update fixes an issue where the system incorrectly consumed all components from the first lot when producing a product, even when multiple lots were selected. The fix ensures that components are accurately distributed across the specified lots, preventing stock discrepancies and improving traceability. This ensures accurate inventory management during manufacturing.
Original PR description
Currently, when the user takes a component product from different lots for manufacturing, after producing the product, the stock moves are modified in such a way that only the first lot is used for…
Currently, when the user takes a component product from different lots for manufacturing, after producing the product, the stock moves are modified in such a way that only the first lot is used for consumption, ignoring the intended selection across multiple lots. ## Steps to replicate: - Install mrp without demo data - Enable Lots and Serial Numbers - Create two products: Car and Bolt, and set Bolt to be tracked by lots - Update the on-hand quantity of Bolt by creating two lots with 10 units each - Create a BoM for Car with Bolt as a component and quantity set to 4 - Create and confirm a Manufacturing Order for Car, see Components and open More Details - Assign Lot 1 with quantity 2 and Lot 2 with quantity 2, then save the MO - Click on Produce All ## Observed Behavior: Even though the user manually selected 2 units from lot 2 and 2 units from lot 1 , after producing the product, all 4 units are taken from lot 1 instead of being split evenly. This can also be verified in the traceability report. ## Root cause: This issue was introduced after commit [1], which added support for considering physical inventory (stock quants) when updating quantities on stock moves and automatically creating or adjusting stock move lines. When the `Produce All` button is pressed, the `button_mark_done` method is triggered This calls `pre_button_mark_done`, which in turn invokes `_set_quantities` [2]. That method calls `_set_qty_producing`, eventually leading to `_set_quantity_done` [3], which marks the move as done. During this process, `_set_quantity_done_prepare_vals` is executed. Inside `_set_quantity_done_prepare_vals` [4], the system assigns quantities to move lines based on the move and its reservations. In this scenario, the stock move has a total quantity of 4. The first move line has a quantity of 2, which is subtracted as the consumed (taken) quantity. At this point, the reserved (available) quantity is also 2, so the final condition is satisfied. This condition subtracts the available quantity from the remaining required quantity for the move, which is 2 for the next move line. As a result, the remaining required quantity becomes 0. Because of this, the next move line ends up with a required quantity of 0 and is removed at [5], effectively prioritizing the first move line. [1]: https://github.com/odoo/odoo/commit/eed96007f9032d1a9e30211c8bdcf53f8ce96a49 [2]: https://github.com/odoo/odoo/blob/a9a63976372d3b5411fd798a48cc5302c2de8af0/addons/mrp/models/mrp_production.py#L2821-L2830 [3]: https://github.com/odoo/odoo/blob/a9a63976372d3b5411fd798a48cc5302c2de8af0/addons/mrp/models/mrp_production.py#L1342-L1343 [4]: https://github.com/odoo/odoo/blob/a9a63976372d3b5411fd798a48cc5302c2de8af0/addons/stock/models/stock_move.py#L2301-L2322 [5]: https://github.com/odoo/odoo/blob/a9a63976372d3b5411fd798a48cc5302c2de8af0/addons/stock/models/stock_move.py#L2286-L2288 ## Solution: Since manual selection of lots is possible, the total available quantity across all lots should be checked before prioritizing any specific move line for updates. Updates should only occur when lots are not being used and the maximum possible quantity has already been reserved from the total available inventory. This prevents all quantities from being assigned to the first stock move line associated with a lot and ensures manually added lots remain on the move lines. opw-6058908
This update fixes an issue where inter-company delivery returns were incorrectly creating credit entries to stock input accounts instead of reversing the original delivery. By including transit locations as valid locations, the system now correctly debits the stock output account for returns, aligning with standard return behavior. This ensures accurate accounting for inter-company transactions.
Original PR description
### Problem: When returning a delivery or receipt for an inter-company transaction, the journal entry created for the return will account on the opposite stock interim account. That is, a delivery to…
### Problem:
When returning a delivery or receipt for an inter-company transaction, the journal entry created for the return will account on the opposite stock interim account. That is, a delivery to another company will debit the stock output account, but returning the delivery will create an account move that credits the stock input account. Compare this to normal return behavior which will credit the stock output account to reverse the original delivery's entry.
### Solution:
When deciding whether a stock move is a return, we will include transit locations as valid locations.
### Steps to reproduce (Runbot v18)
- Automatic accounting
1. Create a SO for the automatically accounted product, selling to another company in the system
2. Validate the delivery, check the valuation and note there is a debit on the stock output account
3. Create a return for the delivery and validate it, check the valuation and note the credit on the stock input account
To clarify, this differs from when the customer on the SO is anything other than a res.company, where we will see a credit on the stock output account when the return is validated.
Also, this flow is the same for POs, and the same bug is addressed by this fix.
### Before
<table>
<th>Move type</th>
<th>Account</th>
<th>Debit</th>
<th>Credit</th>
<tr>
<td>Delivery</td>
<td>Stock output</td>
<td>100</td>
<td>0</td>
</tr>
<tr>
<td>Delivery Return</td>
<td style="{color: red}">Stock input</td>
<td>0</td>
<td>100</td>
</tr>
</table>
### After
(Or normal behavior without inter-company transfer)
<table>
<th>Move type</th>
<th>Account</th>
<th>Debit</th>
<th>Credit</th>
<tr>
<td>Delivery</td>
<td>Stock output</td>
<td>100</td>
<td>0</td>
</tr>
<tr>
<td>Delivery Return</td>
<td>Stock output</td>
<td>0</td>
<td>100</td>
</tr>
</table>
opw-5993147This update clarifies invoices generated for ECpay transactions. The system now includes a 'Unit of Measure' description in the invoice details, resolving confusion caused by the ECpay API's lack of measurement information. This ensures accurate and understandable invoices for customers.
Original PR description
Issue: -- The documents returned by the ECpay API can be confusing as it does not include the measurement (UOM). The make it clearer a description is provided to ECpay through the json with the Key "ItemRemark" Current behavior: -- displayed data in PDF 品名 數量 單價 金額 備註 test 1 5 5 Expected behavior: -- displayed data in PDF 品名 數量 單價 金額 備註 test 1 5 5 商品單位: Units opw-6070269 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update resolves an issue preventing credit notes with currency exchange differences from being posted correctly. The fix bypasses a validation error that occurred when automatic exchange moves didn't include the required analytic plan distribution. This ensures credit notes with exchange moves can now be successfully processed.
Original PR description
**Issue:** When a user posts a credit note with a currency exchange difference relative to the reversed move, the resulting exchange move lines lack the mandatory analytic distribution. This triggers…
**Issue:** When a user posts a credit note with a currency exchange difference relative to the reversed move, the resulting exchange move lines lack the mandatory analytic distribution. This triggers a validation error, preventing the credit note from being posted. **Steps to reproduce:** - Set "mandatory" applicability on any analytic plan. - Set two different currency rates on two different dates for any foreign currency. - Create and post an invoice on the first date (ensure the mandatory analytic distribution is set). - Create a credit note from that invoice using the second date. - Click on the post button on the credit note. Result: A validation error occurs even though the credit note itself has the mandatory analytic plan set, because the auto-generated exchange move does not. **Fix:** Since the context key validate_analytic is set to True by the post button action, it must be manually set to False during the automatic creation of exchange difference moves to bypass the mandatory plan check. OPW-6081632 Forward-Port-Of: odoo/odoo#259381
This update resolves an issue where Polish KSeF invoices were being rejected due to empty email and phone number fields in the XML format. The fix adds checks to ensure these fields are only included when a value is actually present, ensuring compliance with KSeF requirements.
Original PR description
Before this commit: Steps 1. Create a Polish company 2. Create and send an invoice to KSeF where the buyer has no email or no phone number 3. KSeF rejects the invoice with error code 450 (semantic verification error) This happens because `Email` and `Telefon` elements are always rendered inside `DaneKontaktowe`, even when their values are empty, producing invalid empty tags. After this commit: Add `t-if="buyer.email"` and `t-if="buyer.phone"` guards on each field so that `Email` and `Telefon` are only rendered when a value is present. opw-6124187
This update resolves an issue where managers without Time Off access rights couldn't approve leave requests from the overview. The change removes a restriction on data access, allowing managers to fulfill their approval role while maintaining security controls for Time Off officers. This ensures all employees can utilize the leave approval process effectively.
Original PR description
Steps to reproduce: ------------------- 1. Install Time Off. 2. Create a user and employee without Time Off access rights. 3. Create another employee and set the first employee as the manager. (This…
Steps to reproduce: ------------------- 1. Install Time Off. 2. Create a user and employee without Time Off access rights. 3. Create another employee and set the first employee as the manager. (This automatically sets them as the Time Off approver.) 4. Create a time off request for the second employee from Time Off > Management. 5. Ensure that "Employee's Manager" is set as the approver in the corresponding Time Off type. 6. Log in with the first user, go to Overview and try to approve the leave. Issue: ------ An AccessError occurs when approving the leave from the overview: ```python You do not have enough rights to access the fields 'leave_id' on Time Off Calendar (hr.leave.report.calendar) ``` Cause: ------ In `hr_leave_report_calendar`, the `leave_id` field is restricted to `hr_holidays.group_hr_holidays_user`. When a leave manager without Time Off user rights tries to approve a leave from the overview, the field access restriction triggers an AccessError. related commit: https://github.com/odoo/odoo/commit/b5c9420543bdaae52b191e518c5e0f31ba925e46 Solution: --------- Remove the group restriction on the `leave_id` field and introduce record rules on `hr.leave.report.calendar` to control access. - Leave managers can read records related to their employees. - Time Off officers retain full read access. This prevents the AccessError while still restricting the visibility of leave information for unauthorized users. opw-5921263 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix resolves a problem where users couldn't create WhatsApp event templates. The issue stemmed from a restriction in how templates were created, preventing users from saving changes to the event form. Removing a direct creation method in the template setup process now allows users to successfully create and save WhatsApp event templates.
Original PR description
Issue: User goes to Event.event Form -> communication tab -> add line 2) Select whatsapp -> type something -> create and edit -> create new template with any model except event.registration -> save ( all the way including the event form) 3) reload page -> whatsapp event.mail displays "User does not have access to this record". Fix: Remove direct creation in the "get m2oProps()". opw-6037488
This update fixes an issue where manually set lot quantities during manufacturing order production were not accurately reflected. The change ensures that the specified lot quantity is correctly consumed, preventing discrepancies in finished goods tracking. This improves the reliability of inventory management within the manufacturing process.
Original PR description
**Issue** Lots manually indicated on stock move lines can be overridden when producing a Manufacturing Order. **Steps to reproduce** - Create a storable product P tracked by lot - Create two lots for…
**Issue** Lots manually indicated on stock move lines can be overridden when producing a Manufacturing Order. **Steps to reproduce** - Create a storable product P tracked by lot - Create two lots for product P with 2 units each - Create a MO for a product consuming two units P and confirm it - On the raw move, manually set 1 unit for each lot - Click on "Produce All" - Check the move line associated to the product P -> 2 units associated to the first lot consumed instead of 1 unit each **Cause** While producing: https://github.com/odoo/odoo/blob/0fe2023dc57b6cc02bd399d3c8fc5d6c8ed6e833/addons/mrp/models/mrp_production.py#L2109-L2110 It sets the quantities: https://github.com/odoo/odoo/blob/0fe2023dc57b6cc02bd399d3c8fc5d6c8ed6e833/addons/mrp/models/mrp_production.py#L2246 This calls `_set_quantity_done_prepare_vals` with a qty of 2: https://github.com/odoo/odoo/blob/0fe2023dc57b6cc02bd399d3c8fc5d6c8ed6e833/addons/stock/models/stock_move.py#L2264 which will, for each move line: - Take the quantity indicated by move line: https://github.com/odoo/odoo/blob/0fe2023dc57b6cc02bd399d3c8fc5d6c8ed6e833/addons/stock/models/stock_move.py#L2274 https://github.com/odoo/odoo/blob/0fe2023dc57b6cc02bd399d3c8fc5d6c8ed6e833/addons/stock/models/stock_move.py#L2296-L2297 - Then take all the available quantity left for the lot associated to the move line: https://github.com/odoo/odoo/blob/0fe2023dc57b6cc02bd399d3c8fc5d6c8ed6e833/addons/stock/models/stock_move.py#L2302-L2309 https://github.com/odoo/odoo/blob/0fe2023dc57b6cc02bd399d3c8fc5d6c8ed6e833/addons/stock/models/stock_move.py#L2326-L2327 Instead of first taking all the quantity indicated by the move line, before checking available quantity **Solution** Assume that raw move lines being created in mrp without changing the producing quantity are manually created opw-5946439
This update fixes an issue where web forms could incorrectly access data due to cached records. The change ensures that data accessed through web forms is always filtered based on the user's permissions, preventing errors and improving data security. This enhances the reliability of web-based applications.
Original PR description
**Description of the issue/feature this PR addresses**: web_read on x2many fields can reuse cached ids after write/web_save. Some of these cached ids may be inaccessible with the current record…
**Description of the issue/feature this PR addresses**:
web_read on x2many fields can reuse cached ids after write/web_save. Some of these cached ids may be inaccessible with the current record rules/context (cache pollution).
**Example**:
- **Context**:
- Two companies exist: Company A and Company B.
- Two users exist: User A and User B.
- User A can only access Company A (company_ids=[A], company_id=A).
- User B is linked to both companies (company_ids=[A, B], company_id=A).
- The "res.company" record rule is the standard one: [('id', 'in', company_ids)] (company_ids comes from allowed_company_ids).
- User A edits User B and saves the form.
- **Steps**:
- User A performs a web_read to load User B: company_ids contains only Company A.
- User A performs web_save (write + internal web_read in the same request): cached ids [A, B] are reused and the code attempts to read Company B.
**Current behavior before PR (without fix)**:
After saving a form with an x2many field, web_save calls write and then web_read. In this flow, web_read can include inaccessible x2many ids from cache and raise an AccessError.
**Desired behavior after PR is merged**:
x2many records are re-filtered with current read rules before formatting, and inaccessible ids are removed from values_list.
Forward-Port-Of: odoo/odoo#2509041 change
Resolved issues and error corrections
This update fixes an issue where vendor bills were incorrectly using Swiss taxes instead of the correct Belgian taxes. The change ensures that the fiscal position country is accurately reflected during invoice import, preventing errors in tax calculations and compliance. This improves data accuracy for financial reporting.
Original PR description
**Steps to reproduce:** - Create a company in Belgium and set the fiscal localisation accordingly. - In the same company, create a fiscal position in Switzerland, set the foreign tax ID and then generate the taxes for it. - Install the module account_edi_ubl_cii. - Create and invoice for a belgian customer, with one product line having a 0% tax. - Export the invoice as XML. - Go to taxes, filter by purchase, and make sure that the 0% switzerland tax has a higher sequence than the belgian 0% tax. - Import the previous invoice XML as a vendor bill. **Issue:** After importing the bill, the switzerland tax is used even though the fiscal localisation is belgian, which is wrong as it violates the constraint _validate_taxes_country **Solution:** Added a more selective domain to _import_fill_invoice_line_taxes opw-5467936 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr