Daily updates from Odoo
Wednesday, July 1, 2026
374 changes
32 changes
Enhancements to existing features
This change speeds up how Odoo retrieves task activity information by adding a database index for a frequently used query. It reduces the time spent on this lookup, which helps pages and actions that rely on /mail/data load more quickly.
Original PR description
`/mail/data` is called a lot. It spends roughly 33% of its time on the query fetching task activities in `_get_activity_groups` https://github.com/odoo/odoo/blob/a52b277a4db5f14516717738ca962e3bb3c7180f/addons/project_todo/models/res_users.py#L27 This commit adds an index to speed up the query. - before ~25ms https://explain.dalibo.com/plan/72b26edce8448b51 - after <1ms https://explain.dalibo.com/plan/c4g6851e5b4hh702 task-6327159 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#272712
The French e-invoicing registration experience was updated to guide companies more clearly toward PDP registration when needed. Odoo now shows more relevant warnings and help messages, and the registration wizard is simpler to complete because key fields are visible and locked at the right time.
Original PR description
#### [IMP] account_peppol,l10n_fr_pdp: rework PDP registration If PDP is not installed but Peppol is installed we suggest installing the PDP module for French companies - in the send & print instead…
#### [IMP] account_peppol,l10n_fr_pdp: rework PDP registration
If PDP is not installed but Peppol is installed we suggest
installing the PDP module for French companies
- in the send & print instead of the following warnings
- "You can send this invoice electronically via Peppol." (what is peppol)
- "partner has requested electronic invoices reception on Peppol."
- in the send & print for any French company that is not on PDP
(this warning can be disabled by setting the system parameter
`account_peppol.disable_pdp_warning` to true)
- in the peppol registration wizard by adding a warning
If PDP is installed we make the following changes to the send & print
- change the wording mentioning "Peppol" to mention the French e-invoicing instead
- make a PDP version of the "Peppol Info" (`account_peppol.WhatIsPeppol`)
- it explains what French E-Invoicing is
- it provides a button to open the registration wizard
- in case the company is registered on Peppol it deregisters the
company first (just like the "complete registration" button)
- display the "You can send this electronically via Peppol" warning
also for French companies (with the wording and "Peppol Info" mentioned above)
- It is displayed in case we are opening the Send & Print wizard from a French
company for a partner on peppol but the "Peppol" / "French
E-invoicing" checkbox is not checked
- Change the wording of the French company non-PDP warning to encourage
the user to register
In the PDP registration wizard
- make all the fields visible directly (already at the start of the KYB/KYC)
- make the SIREN part of the identifier readonly
- make the fields readonly after the verification
- automatically "validate" / register to PDP when we receive the KYC success
task-6320246
#### [IMP] l10n_fr_pdp: add system param for kyc siren
After the previous commit it is not really possible anymore
to use a different SIREN for the KYC than the one in the pdp identifier.
This is because:
- We derive the SIREN directly from the
Identifier in the registration wizard.
- The registration will be validated automatically after the KYC
- The values are readonly after the KYC in any case
That is a problem for testing because we have 1 SIREN to test the
KYC and it is independent from the identifiers provided by the French
datasets for the PDP test environment.
task-None
Forward-Port-Of: odoo/odoo#272208
Forward-Port-Of: odoo/odoo#271733This change corrects a display label in the accounting interface so it matches the updated wording used elsewhere. It helps keep the product terminology consistent and avoids confusion for users working with reconciliation settings.
Original PR description
Since this PR https://github.com/odoo/odoo/pull/249536 "Allow Reconcilation" became "Payment Reconciliation" This change in labels didn't take effect in the account.move.line model. This commit fixes this issue by ensuring that the label of is_account_reconcile field matches that of the account.account.reconcile field. task-6306159 Forward-Port-Of: odoo/odoo#273339
Resolved issues and error corrections
Printing the Planning report now works reliably even when it is grouped by fields other than Employee, such as Role or Project. This prevents report generation from crashing and ensures multi-day shifts are handled correctly in those views.
Original PR description
### Issue: When printing the Planning report (PDF) and grouping by a field other than Employee (e.g., Role, Project, or a Char/Selection field), the server crashes with a `TypeError` or…
### Issue: When printing the Planning report (PDF) and grouping by a field other than Employee (e.g., Role, Project, or a Char/Selection field), the server crashes with a `TypeError` or `AttributeError`. ### Cause: The `action_print_plannings` method hardcoded the assumption that the `group_by` key would always be a `resource.resource` recordset. 1. When the user grouped by other fields, it returned strings, booleans, or empty recordsets, causing crashes when the code blindly called `.id` and `.display_name`. 2. During the sorting phase, mixing `False` (for unassigned empty recordsets) with strings caused a `TypeError`. 3. For multi-day shifts, the method failed to extract the actual resource to calculate the shift splits if the grouping was not explicitly set to `resource_ids`. ### Fix: - Implement safe attribute checks (`hasattr`) when extracting group IDs and display names. - Ensure unassigned empty recordsets properly fall back to the "Undefined" string and empty strings during sorting to prevent TypeErrors. - Universally fallback to extracting the resource directly from the slot (`slot.resource_ids[:1]`) for multi-day time splitting when grouped by non-resource fields. - Add a unit test to ensure stability when grouping by `role_id` with multi-day shifts. Task: 6244057 Forward-Port-Of: odoo/enterprise#118530
This update fixes the Peru Kardex PLE report so it produces more accurate inventory and cost figures in the 19.0 system. It improves how opening balances, product filtering, and special stock movements are handled, reducing reporting errors that could affect accounting and tax filings.
Original PR description
*Continuing on the work from https://github.com/odoo/enterprise/pull/111526, new PR because we cannot push to it.* Adapt the Kardex PLE 12.1/13.1 reports from the SVL-based approach in 18.0 to the stock.move-based approach required in 19.0. Key changes: - Use traceable IDs (account_move_id/stock_move_id) for CUO field - Back-calculate opening balance cost at report date instead of using current standard_price, which is wrong when post-period purchases have changed the average cost - Filter storable products only (is_storable) matching v17/v18 behavior - Handle negative opening balance quantities correctly - Add bridge module l10n_pe_reports_stock_landed_costs to show landed costs as separate Kardex lines (operation_type=26) without forcing stock_landed_costs as a hard dependency Forward-Port-Of: odoo/enterprise#121855
This change prevents an error that could happen when the system looked up an IoT device and found more than one match. By ensuring only one device is selected, it makes IoT access more reliable and avoids interruptions for users relying on connected hardware.
Original PR description
Currently, a singleton error occurs while accessing the `type` field on `iot_device`, as the search assigned to `iot_device` returns multiple `iot.device` records. Error: `ValueError: Expected singleton: iot.device(5, 10)` This commit fixes the above issue by adding `limit=1` to the search, ensuring that `iot_device` always contains a single record and preventing the singleton error. Sentry-7579060623 Forward-Port-Of: odoo/enterprise#122219
This fix prevents inventory cost entries from being treated like normal tax base lines when a vendor bill is confirmed. As a result, manually edited taxes stay in place instead of being recalculated and overwritten, avoiding unexpected changes on bills with automated inventory valuation.
Original PR description
## Description of the issue/feature this PR addresses: Setup plus video 1. Go to settings, enable "Automatic Valuation" and "Storeable Locations". 2. Navigate to Product Categories. 3. Create a new…
## Description of the issue/feature this PR addresses: Setup plus video 1. Go to settings, enable "Automatic Valuation" and "Storeable Locations". 2. Navigate to Product Categories. 3. Create a new product category with the costing method Standard Price and the inventory valuation Automatic. 4. Navigate to Products, click into any product. 5. Add the new product category to this product under General Information. 6. Add any tax in the purchase tax field. 7. In the Accounting tab of the product, add any account to the Price Difference Account field. https://drive.google.com/file/d/1i2DHEt0g9G5Edad_QB3QaFkOT49cbMAZ/view?usp=sharing Instructions to reproduce error 1. Navigate to Purchase. 2. Add a customer, then add the configured product. 3. Add a tax to the line. Ensure that the tax and price_unit are nonzero. 4. Confirm the order. 5. Receive the product. 6. Create the bill. 7. Edit the tax on the vendor bill, then save the changes. Notice that the changes are kept. 8. Select Confirm. Notice that the changes to the tax line are not kept, and that the COGS lines appeared (with taxes applied to them). 9. Reset the bill to draft. 10. Click into the configured product and remove the product category. 11. Repeat steps 7-8 . No COGS lines, and the tax line is the manually set value. ## Current behavior before PR: COGS lines with taxes have no net effect on any tax lines as they cancel each other out. However, their creation triggers the recalculation of all tax lines, undoing any manual adjustments to tax lines. ## Desired behavior after PR is merged: This commit ensures that COGS lines are not considered base tax lines, so that their creation does not trigger the recalculation of other base tax lines. opw-5387248 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#271262 Forward-Port-Of: odoo/odoo#262442
This fix ensures quality alerts can be created from incoming emails even when the quality team has no company selected. It prevents email-driven alerts from failing silently, so teams do not miss important quality issues.
Original PR description
Steps to reproduce 1. Install quality 2. Create an incoming email server 3. Go to Quality > Configuration > Quality Teams > Team > add alias email 4. Do not fill the company field 5. Send email to this alias 6. Fetch emails from incoming email server Issue: - Record is not created in the quality alert Root cause: - For the Quality alert model, the field `company_id` is required, but while we fetch emails We haven't set the `company_id` on the quality alert team, resulting in trying to insert a null value on the quality alert model. Solution: - Give a default value to company_id. - Raise a validation error on not having a company_id - Update alias default values on changing company_id opw-5917791 Forward-Port-Of: odoo/enterprise#121778 Forward-Port-Of: odoo/enterprise#109947
## [FIX] base: Fix vat label css With the wrapping div the label lost it's label style. task-6352123 ## [FIX] l10n_*: Fix xpath after multi ID * l10n_br,l10n_my_ubl_pint,l10n_ca,l10n_ph,l10n_in,l10n_rs_edi In the multi ID [1], we completely revamped the UI around the `vat` field. It's now mostly made of: - the VAT field inlined with a "+" button adding additional_identifiers - the additional identifiers that comes below with input-text-like display. The feature should stay in one
Original PR description
## [FIX] base: Fix vat label css With the wrapping div the label lost it's label style. task-6352123 ## [FIX] l10n_*: Fix xpath after multi ID *…
## [FIX] base: Fix vat label css With the wrapping div the label lost it's label style. task-6352123 ## [FIX] l10n_*: Fix xpath after multi ID * l10n_br,l10n_my_ubl_pint,l10n_ca,l10n_ph,l10n_in,l10n_rs_edi In the multi ID [1], we completely revamped the UI around the `vat` field. It's now mostly made of: - the VAT field inlined with a "+" button adding additional_identifiers - the additional identifiers that comes below with input-text-like display. The feature should stay in one block, therefore we added an "identifiers" div wrapping all these fields/buttons/labels. This way other fields can easily xpath before or after the whole block. We also have a vat_div identifiers that is meant for feature needed to be inlined with the vat and the "+". This PR and its Enterprise counterpart fix some xpath that were still incorrect after [1] and [2] in following modules: l10n_br, l10n_my_ubl_pint, l10n_ca, l10n_ph, l10n_in, l10n_rs_edi, l10n_mx_edi_stock [1]: https://github.com/odoo/odoo/pull/262274 [2]: https://github.com/odoo/odoo/pull/271906 task-6352123
In the multi ID [1], we completely revamped the UI around the `vat` field. It's now mostly made of: - the VAT field inlined with a "+" button adding additional_identifiers - the additional identifiers that comes below with input-text-like display. The feature should stay in one block, therefore we added an "identifiers" div wrapping all these fields/buttons/labels. This way other fields can easily xpath before or after the whole block. We also have a vat_div identifiers that is meant for feat
Original PR description
In the multi ID [1], we completely revamped the UI around the `vat` field. It's now mostly made of: - the VAT field inlined with a "+" button adding additional_identifiers - the additional identifiers that comes below with input-text-like display. The feature should stay in one block, therefore we added an "identifiers" div wrapping all these fields/buttons/labels. This way other fields can easily xpath before or after the whole block. We also have a vat_div identifiers that is meant for feature needed to be inlined with the vat and the "+". This PR and its Community counterart fix some xpath that were still incorrect after [1] and [2] in following modules: l10n_br, l10n_my_ubl_pint, l10n_ca, l10n_ph, l10n_in, l10n_rs_edi, l10n_mx_edi_stock [1]: https://github.com/odoo/odoo/pull/262274 [2]: https://github.com/odoo/odoo/pull/271906 task-6352123
The avatar card tours create a time off relative to "today" and assert the "Back on" out-of-office indicator. When the test runs on a Friday or Saturday, today+1 is a weekend, so the leave's date_to lands on that weekend day's 00:00 and the "currently on leave" window closes at midnight. Once the run crosses that boundary the leave is no longer active, the indicator disappears and the tour fails at the "Back on" step, deterministically on that weekday. Freeze setUpClass to a fixed mid-week da
Original PR description
The avatar card tours create a time off relative to "today" and assert the "Back on" out-of-office indicator. When the test runs on a Friday or Saturday, today+1 is a weekend, so the leave's date_to lands on that weekend day's 00:00 and the "currently on leave" window closes at midnight. Once the run crosses that boundary the leave is no longer active, the indicator disappears and the tour fails at the "Back on" step, deterministically on that weekday. Freeze setUpClass to a fixed mid-week day so the time off always ends on a working day. https://runbot.odoo.com/odoo/error/242512 Forward-Port-Of: odoo/odoo#273073
Currently, an error occurs on an invoice when user selects a payment term and removes the currency. Steps to replicate: - Install account - Turn on multiple currencies - Open invoices. - Create a new invoice - Add a line - Add a customer - Save - Select payment term as `30% Now, Balance 60 Days` - Remove the currency. Error: ``` ValueError: Expected singleton: res.currency() ``` Cause: - This error only occurs when the selected payment term contains at least two due term l
Original PR description
Currently, an error occurs on an invoice when user selects a payment term and removes the currency. Steps to replicate: - Install account - Turn on multiple currencies - Open invoices. - Create a new…
Currently, an error occurs on an invoice when user selects a payment term and removes the currency. Steps to replicate: - Install account - Turn on multiple currencies - Open invoices. - Create a new invoice - Add a line - Add a customer - Save - Select payment term as `30% Now, Balance 60 Days` - Remove the currency. Error: ``` ValueError: Expected singleton: res.currency() ``` Cause: - This error only occurs when the selected payment term contains at least two due term lines [1]. - When the selected payment term has atleast two lines the check [1] assigns `on_balance_line` as false and the `else` block is evaluated where currency being an empty recordset (as the user removed it) causes the error from [line] when trying to perform `round()` on an empty res.currency recordset. Solution: - As the currency is a required field, user will not be able to save the record until a currency is assigned. - Used journal's currency or company's currency as a fallback when computing payment terms if the current currency is empty. [1]: https://github.com/odoo/odoo/blob/177002c0aca95de2de6458bb65bedf5c74541ac0/addons/account/models/account_payment_term.py#L229 [line]: https://github.com/odoo/odoo/blob/177002c0aca95de2de6458bb65bedf5c74541ac0/addons/account/models/account_payment_term.py#L240 sentry-7569922293 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#272073
**Current behavior before PR,** Computing `main_user_id` of a partner involved filtering active users within a loop. To avoid losing the prefetching, we manually forced all partner users to be kept in the prefetch during each iteration. This caused performance issues as the recordset grew large (e.g., during auto-subscription). **Desired behavior after PR is merged,** All partner users are prefetched and filtered once, removing the need for a repetitive manual prefetch. **Benchmark,*
Original PR description
**Current behavior before PR,** Computing `main_user_id` of a partner involved filtering active users within a loop. To avoid losing the prefetching, we manually forced all partner users to be kept…
**Current behavior before PR,** Computing `main_user_id` of a partner involved filtering active users within a loop. To avoid losing the prefetching, we manually forced all partner users to be kept in the prefetch during each iteration. This caused performance issues as the recordset grew large (e.g., during auto-subscription). **Desired behavior after PR is merged,** All partner users are prefetched and filtered once, removing the need for a repetitive manual prefetch. **Benchmark,** The following observations were recorded when auto-subscribing users to a discuss channel at different scales. The _Before_ and _After_ results represent the max values from three consecutive tests. | Records | Before | After | | :--------| -------: | ---------: | | 3k | ~2.3s | <90ms | | 5k | ~3.8s | <160ms | | 10k | ~7.6s | <300ms | part of task-6116079 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#271549
Issue: ---------------------------------------- When changing multiple times the hours of a slot to include out-of-schedule time. Steps to reproduce: ---------------------------------------- - Have planning_field_service installed - Have an employee with a schedule from 7am to 3pm - In planning view, create a new slot for this employee from 7am to 3pm (8h) - Change the starting hour to 6am (8h + 1h of break time) - Change it back to 7am - The slot shows 7h07 of allocated hours and 53
Original PR description
Issue: ---------------------------------------- When changing multiple times the hours of a slot to include out-of-schedule time. Steps to reproduce: ---------------------------------------- - Have…
Issue: ---------------------------------------- When changing multiple times the hours of a slot to include out-of-schedule time. Steps to reproduce: ---------------------------------------- - Have planning_field_service installed - Have an employee with a schedule from 7am to 3pm - In planning view, create a new slot for this employee from 7am to 3pm (8h) - Change the starting hour to 6am (8h + 1h of break time) - Change it back to 7am - The slot shows 7h07 of allocated hours and 53 minutes of break time Cause: ---------------------------------------- Since 8ca9faabfdf7d15883ba52da47bd8c562cf601de the compute of `allocated_percentage` is overriden in `planning_field_service`. The new compute uses `break_time` to recompute `allocated_percentage`. `break_time` is the not work time over the whole duration of the slot, including hours out of schedule. But the definition of `allocated_percentage` in `planning` is: the percentage of slot hours in schedule which are actually worked. So when changing the start to 6am `allocated_percentage` is still supposed ot be 100% because the employee is working 100% of the hours he is supposed to work considering its schedule. With the actual code `allocated_percentage` is actually computed as 8/9 = 0.88888... because it will take into account the hours out of schedule. As `allocated_percentage` is not recomputed if `allocated_hours` or `break_time` aren't modified by the user. It is then used [here](https://github.com/odoo/enterprise/blob/ae5008bdaf1b87269083f82280c7df44390129ff/planning/models/planning_slot.py#L2865-L2867) to compute the allocated_hours and the number of hours in schedule is divided base onthe percentage. Solution: ---------------------------------------- We only consider the hours in schedule to recompute `allocated_percentage`. `allocated_percentage` was used in `_onchange_break_time()` to get the previous ratio and calculate the allocated hours from which we deduct the break time. We cannot do this now so we also need to compute the working hours. ----------------------------------------- # [FIX] planning_field_service: handle input of negative break_time Issue: ---------------------------------------- When inputting negative break_time for a slot, it's possible to get a traceback. Steps to reproduce: ---------------------------------------- - Have planning_field_service installed - Have an employee with a schedule from 7am to 3pm - In planning view, create a new slot for this employee from 7am to 3pm (8h) - Input 9h of break time - Input -1h of break time - Traceback Cause: ---------------------------------------- When `slot.allocated_hours` is 0 and we input a negative value in `break_time`, the code in `_onchange_break_time()` will give `allocated_hours` the positive value of `break_time` making them opposite. Then in [`_compute_allocated_percentage()`](https://github.com/odoo/enterprise/blob/188dcc5078be7c7fee1a52f86505144d3b6309cf/planning_field_service/models/planning_slot.py#L98) we divide by their sum, which equals 0. Solution: ---------------------------------------- We compute the divider part and check if it's zero in `_compute_allocated_percentage()`. Also add a `max()` in `_onchange_break_time()` to convert the negative break time in allocated hours and resets `break_time` to zero. This ensures the same behavior as inputting negative values in `allocated_hours`. opw-6273559 Forward-Port-Of: odoo/enterprise#122209 Forward-Port-Of: odoo/enterprise#121168
The following error is raised in the POS when paying with an Adyen terminal: ``` TypeError: Cannot read properties of undefined (reading 'uuid') at Proxy.handleAdyenStatusResponse ``` Adyen delivers webhook notifications at-least-once, so the ADYEN_LATEST_RESPONSE event can fire several times for a single payment, running handleAdyenStatusResponse concurrently. After the await on get_latest_adyen_status, a previous (duplicate) notification may already have resolved the payment line, so ge
Original PR description
The following error is raised in the POS when paying with an Adyen terminal: ``` TypeError: Cannot read properties of undefined (reading 'uuid') at Proxy.handleAdyenStatusResponse ``` Adyen delivers…
The following error is raised in the POS when paying with an Adyen terminal: ``` TypeError: Cannot read properties of undefined (reading 'uuid') at Proxy.handleAdyenStatusResponse ``` Adyen delivers webhook notifications at-least-once, so the ADYEN_LATEST_RESPONSE event can fire several times for a single payment, running handleAdyenStatusResponse concurrently. After the await on get_latest_adyen_status, a previous (duplicate) notification may already have resolved the payment line, so getPendingPaymentLine no longer returns it and the subsequent line.uuid dereference crashes. opw-6237987 patched the same root cause on a single line by adding an optional chaining operator in isPaymentSuccessful, which only moved the crash to the next dereference. Fetch the pending line once at the start of handleAdyenStatusResponse and bail out when it is gone, so every dereference below is safe. The same guard is added to the remaining branches of _adyen_handle_response for consistency with the existing Reject branch. opw-6237987 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#271181 Forward-Port-Of: odoo/odoo#269720
Images placed inside device-style shapes are now cropped to match the shape’s proportions instead of always being forced into a square crop first. This reduces unnecessary cutting of the image and makes previews look more natural and accurate.
Original PR description
Scenario: - insert image with ~ 1:2 ratio (height bigger than width) - set shape "iPhone `#2`" to that image Result: the image should fit without much cropping the 0.46:1 aspect ratio of the shape, but it is cropped 1:1 before being applied to it. Cause: when the image has a set aspect ratio, we are always cropping it to 1:1 aspect ratio in postProcessCroppedCanvas but it should be cropped to the shape aspect ratio as it was done in previous version. Fix: go back to what was done in saas-18.3 and apply the shape aspect ratio and not just square (1:1) aspect ratio. opw-5415137 Forward-Port-Of: odoo/odoo#250922
When a business card is scanned, the city name was previously left out even though the other details were captured. This fix makes the city field import correctly, so contact records are more complete and accurate.
Original PR description
Previously, when user scans any business card, every information was fetched except for the city name. After this commit the city field will be properly fetched. task-6332914 Forward-Port-Of: odoo/enterprise#121766
Purchase order lines now keep very small unit prices with their full precision instead of rounding them too early. This makes purchase pricing behave consistently with sales and avoids losing small but important cost differences.
Original PR description
Commit 07da917f6e331 introduced `min_display_digits` on product price fields, allowing small prices to be stored without forcing the global `Product Price` decimal precision to be increased. For…
Commit 07da917f6e331 introduced `min_display_digits` on product price fields, allowing small prices to be stored without forcing the global `Product Price` decimal precision to be increased. For example, a product can have a cost of `0.001235`. The value is kept on the product because `standard_price` uses `min_display_digits="Product Price"`. However, when this product is added to a purchase order line, the purchase price computation still explicitly rounds the computed unit price using the currency decimals and the `Product Price` decimal precision. This is inconsistent with sales: sale order lines preserve very small unit prices correctly. **Current behavior before PR:** A product with `standard_price = 0.001235` keeps that value on the product form. When adding the product to a purchase order line, the computed `price_unit` is rounded by `purchase.order.line`, so the small price is lost. The same issue can happen with vendor prices: a supplierinfo price with more precision than the currency decimals is rounded before being assigned to the purchase order line. **Desired behavior after PR is merged:** Purchase order lines preserve the computed unit price precision, just like sale order lines already do. A product cost or vendor price such as `0.001235` remains `0.001235` on the purchase order line instead of being rounded to currency/Product Price precision. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#270860 Forward-Port-Of: odoo/odoo#267941
Invoices for Saudi Arabia and the UAE will now show the invoice title in the customer’s language instead of always using English. This improves the printed document for Arabic-speaking customers and makes the invoice feel properly localized.
Original PR description
### Issue: On invoices in SA and AE, the invoice title was always rendered in English even when the customer's language is Arabic ### Cause: In 19.2, the report view `report_invoice_document` was…
### Issue: On invoices in SA and AE, the invoice title was always rendered in English even when the customer's language is Arabic ### Cause: In 19.2, the report view `report_invoice_document` was refactored to require `t-set` declarations before `t-call` In 19.1, `o` was reassigned early with the customer language via `t-value="o.with_context(lang=lang)"`, so all subsequent calls on `o` inherited the correct language https://github.com/odoo/odoo/blob/3d2d8cc498a56faac31e95fb854a94e4011d812d/addons/account/views/report_invoice.xml#L4-L6 After the refactor, `o` no longer carries the customer language context at the point where `l10n_gcc_settings` is evaluated `_l10n_gcc_get_invoice_title()` was therefore called with the connected user's language instead of the customer's ### Steps to reproduce: - Install `l10n_sa` or `l10n_ae` and switch to the corresponding company - Create and confirm an Invoice (any data) - Set the customer language to Arabic - Print the Invoice Before the fix, the invoice title is displayed in English opw-6333472 Forward-Port-Of: odoo/odoo#272865
This update makes sure users can only access detailed accounting move lines if they belong to the correct accounting groups. It reduces the risk of showing sensitive accounting data to users who should only have limited access, such as portal users.
Original PR description
Using check_access on the model alone is not enough, as some groups (like portal) could have access to the model itself but rely on record rules (which we now bypass) for filtering access to actual records. This check is there for extra-safety (the access rules to account.report should anyway prevent access) ; we fix it by explicitly checking the user has the proper accounting groups. Forward-Port-Of: odoo/enterprise#120749
This fix prevents PoS combo products from being treated as items that must be separately registered in eTIMS. As a result, businesses in Kenya can sell combos normally without seeing a false warning or having payments blocked.
Original PR description
Steps to reproduce ------------------ 1. Install l10n_ke_edi_oscu_pos. 2. Select the Kenyan company. 3. Enable eTIMS on the PoS. 4. Register the products inside a combo, but not the combo itself. 5.…
Steps to reproduce ------------------ 1. Install l10n_ke_edi_oscu_pos. 2. Select the Kenyan company. 3. Enable eTIMS on the PoS. 4. Register the products inside a combo, but not the combo itself. 5. Sell the combo in the PoS. Observation ----------- We see a warning that the combo must be registered to eTIMS, and the order can't be validated. What's happening ---------------- In the PoS a combo adds a 0 price parent line for the combo product, but the combo is not a real item to send to eTIMS, only the products inside it are, and (as per step 4) the combo is not registered. `checkEtimsFields` sees the combo as not registered, so it raises the warning in `showUnregisteredProductsWarning` and blocks the payment in `validateOrder`. Fix --- In the backend, we skip sending the parent combo line to eTIMS, and on the frontend, we make the combo parent line not need eTIMS registration, so the warning and the block don't apply to it. opw-6253306 Forward-Port-Of: odoo/enterprise#122179 Forward-Port-Of: odoo/enterprise#119362
This fix corrects how withholding tax is allocated when one payment covers multiple invoices. The deducted amount is now distributed proportionally, preventing any single invoice from being charged more than its fair share. It also improves the reliability of withholding display and journal selection in the payment flow.
Original PR description
Deducted withholding amount was computed from the withholding tax line of the payment journal entry. However, in the case of grouped payments, a single withholding tax line can correspond to multiple invoices, causing the deducted withholding amount to exceed the withholding amount of an individual invoice. To address this, the deducted withholding amount is now allocated proportionally based on the reconciled payment amount. Additionally, `_onchange_withhold` has been replaced by an extension of `_compute_journal_id` and also 'display_withholding' will be added in depends of `_compute_amount` which was previously missing.
This change ensures invoices sent to Guatemala’s Infile service are encoded correctly and marked with the right content type. As a result, customer and product names containing accented or special characters are preserved and the invoices are less likely to be rejected or corrupted.
Original PR description
**Steps to reproduce:** * Install the **l10n_gt_edi** module. * Configure a Guatemalan company with valid Infile credentials in the settings. * Create a product or customer with special characters…
**Steps to reproduce:**
* Install the **l10n_gt_edi** module.
* Configure a Guatemalan company with valid Infile credentials in the settings.
* Create a product or customer with special characters (e.g. `ñ`, `á`, `é`) in their name.
* Create a customer invoice containing this product/customer.
* Confirm the invoice to trigger the EDI send to the SAT (Infile).
**Observed behavior:**
* Infile intermittently rejects the invoice due to validation errors, or accepts it but the resulting certified XML has truncated or malformed text exactly where the special characters were located.
**Cause:**
* Odoo uses the `requests.post()` library to send the XML payload to Infile. By default, `requests` encodes string payloads using `latin-1` unless told otherwise.
* Because the request was missing the explicit `Content-Type: application/xml` header and the XML string was not explicitly encoded to `utf-8` before sending, Infile parsed the payload using an incorrect encoding. This caused it to drop or misinterpret special characters, leading to validation failures or corrupted XML content.
**Fix:**
* Explicitly include the `'Content-Type': 'application/xml'` header in the request to Infile.
* Explicitly encode the `xml_data` payload to `utf-8` (`xml_data.encode('utf-8')`) before passing it to `requests.post()` to guarantee the correct encoding is sent over the wire.
opw-6315654
Forward-Port-Of: odoo/enterprise#121729This update fixes an error that could prevent users from downloading the PDF for certain Guatemalan vendor bills marked as FESP. It ensures the necessary totals are calculated correctly and the PDF template uses the right field, so the document can be generated successfully.
Original PR description
**Steps to reproduce:** - Install the `l10n_gt_edi` module and switch to a `GT Company`. - Create a new vendor bill with: - Vendor: GT Company - GT Document Type: `FESP` - Add taxes `VAT Withholding…
**Steps to reproduce:** - Install the `l10n_gt_edi` module and switch to a `GT Company`. - Create a new vendor bill with: - Vendor: GT Company - GT Document Type: `FESP` - Add taxes `VAT Withholding 12%` and `ISR Withholding 5%` in Invoice lines. - `Confirm` the bill and `Send to SAT`. - From the gear icon, click `Download` > `PDF`. **Error1:** `KeyError: 'gran_total'` **Error2:** `KeyError: 'retencion_grand_total'` **Root Cause:** In commit [1], the code at [2] missed calling `_l10n_gt_edi_add_base_values()` before `_l10n_gt_edi_add_withholding_values()`. However, `_l10n_gt_edi_add_withholding_values()` uses the `gran_total` value, which is initialized by `_l10n_gt_edi_add_base_values()`, resulting in a `KeyError`. Additionally, the report template at [3] references `retencion_grand_total` instead of the correct key `retencion_gran_total`, causing another `KeyError`. **Fix:** This commit prevents errors and ensures users can successfully download the PDF by applying a fix similar to [4], [1]: https://github.com/odoo/enterprise/commit/44afd19e4ed0827e343af0e584c81e579935c9e8 [2]: https://github.com/odoo/enterprise/blob/9846b337cfe1876017c7c2ce3041569d7a2ac03f/l10n_gt_edi/models/account_move.py#L305-L328 [3]: https://github.com/odoo/enterprise/blob/9846b337cfe1876017c7c2ce3041569d7a2ac03f/l10n_gt_edi/views/report_invoice.xml#L72 [4]: https://github.com/odoo/enterprise/blob/9846b337cfe1876017c7c2ce3041569d7a2ac03f/l10n_gt_edi/models/account_move.py#L790-L800 opw-6323049 Forward-Port-Of: odoo/enterprise#122398 Forward-Port-Of: odoo/enterprise#122030
This fix prevents a crash when translating a report’s XML in Studio on databases where English (en_US) is not installed. It ensures users can continue translating reports even if only other languages are available.
Original PR description
Init a db with a language different from en_US install other languages, except en_US Try to translate via studio a report's XML This gives a crash, because the baseLang is not installed After this commit, there is no crash. opw-6239938 Forward-Port-Of: odoo/enterprise#122329 Forward-Port-Of: odoo/enterprise#122026
The GSTR-1 Excel export now works correctly when a user selects only the main company after generating the report for multiple companies. This prevents the export from failing with an error and ensures the report can be downloaded reliably.
Original PR description
Steps to reproduce: - Install `l10n_in_reports` module(Indian Localisation) - Create a branch in `IN Company` > Select both - Create separate invoices for each company - Created the GSTR-1 report for…
Steps to reproduce:
- Install `l10n_in_reports` module(Indian Localisation)
- Create a branch in `IN Company` > Select both
- Create separate invoices for each company
- Created the GSTR-1 report for both company
- While generating Excel, select only main company
Traceback:
```py
File "/home/odoo/src/enterprise/19.0/l10n_in_reports/models/account_return.py", line 2537, in action_generate_gstr1_xlsx
gstr1_json = self._get_l10n_in_gstr1_json()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/enterprise/19.0/l10n_in_reports/models/account_return.py", line 1071, in _get_l10n_in_gstr1_json
'b2cs': _get_b2cs_json(AccountMoveLine.search(self._get_section_domain('b2cs'))),
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/enterprise/19.0/l10n_in_reports/models/account_return.py", line 672, in _get_b2cs_json
for line, line_tax_details in tax_details.items():
^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'items'
```
Cause:
This issue occurs because, while generating the GSTR-1 Excel report for a particular month, [journal_items] contains account moves from both companies. This happens because the [domain] fetches records for both companies, resulting in move [lines] from both companies being included.
However, while generating the Excel report, only one company is selected. As a result, [tax_details_by_move] does not contain the move data for the branch company, which returns None, causing the error to be raised.
Solution:
Pass an empty `{}` for `tax_details` when only a single company is selected.
[journal_items]: https://github.com/odoo/enterprise/blob/3c3641d9f0753c1ca62285667c4a2786c15e2444/l10n_in_reports/models/account_return.py#L877
[domain]: https://github.com/odoo/enterprise/blob/770ffaac14bfcd2c54a7ce6aca27e0010e7884d4/l10n_in_reports/models/account_return.py#L1387-L1393
[lines]:
https://github.com/odoo/enterprise/blob/3c3641d9f0753c1ca62285667c4a2786c15e2444/l10n_in_reports/models/account_return.py#L1074
[tax_details_by_move]:
https://github.com/odoo/enterprise/blob/3c3641d9f0753c1ca62285667c4a2786c15e2444/l10n_in_reports/models/account_return.py#L880
opw-6242824
Forward-Port-Of: odoo/enterprise#118614This update corrects how the current year result is classified and reported in Luxembourg balance sheet statements. It also simplifies the calculation of the “Profit or loss brought forward” line so the report is more accurate and easier to maintain.
Original PR description
This commit addresses the account type for the current year earnings and simplifies the calculation for the "Result brought forward" line in the Luxembourg balance sheet reports.
Modifications:
* Changed the account type of account 142 ("Result for the financial year") from `equity_unaffected` to standard `equity`.
* Simplified the formula for the Balance Sheet line "Profit or loss brought forward" (codes `LU_BS_319` and `LU_BSABR_319`).
* The new formula simply targets the `14` accounts while explicitly excluding `142`.
Community PR: odoo/odoo#272362
Ticket [link](https://www.odoo.com/odoo/project.task/6059571)
opw-6059571
Forward-Port-Of: odoo/enterprise#122097
Forward-Port-Of: odoo/enterprise#121891Time Off now opens correctly on mobile and in small browser windows for users who do not have an employee record. This prevents an error screen and ensures the module remains accessible in this edge case.
Original PR description
Steps to reproduce: 1. Access the database from a mobile device (or a small browser window) 2. Sign in as a user who has access to the Time Off module, but doesn't have an employee record 3. Open Time Off 4. Observe the traceback When we try to access Time Off with a user who has no employee record, we get a traceback due to receiving an empty dictionary from the backend. The error occurs because we try to iterate over this dictionary, even though we normally expect an array from the request we make. This commit will ensure we always return an array to the frontend, preventing the error. [opw-6295568](https://www.odoo.com/odoo/project/49/tasks/6295568?debug=assets) Forward-Port-Of: odoo/odoo#269882
This update corrects how the current year’s earnings are classified in Luxembourg accounting reports and simplifies one balance sheet line used for carried-forward profit or loss. It helps ensure the financial statements are calculated more accurately and consistently.
Original PR description
This commit addresses the account type for the current year earnings and simplifies the calculation for the "Result brought forward" line in the Luxembourg balance sheet reports.
Modifications:
* Changed the account type of account 142 ("Result for the financial year") from `equity_unaffected` to standard `equity`.
* Simplified the formula for the Balance Sheet line "Profit or loss brought forward" (codes `LU_BS_319` and `LU_BSABR_319`).
* The new formula simply targets the `14` accounts while explicitly excluding `142`.
Enterprise PR: odoo/enterprise#121891
Ticket [link](https://www.odoo.com/odoo/project.task/6059571)
opw-6059571
Forward-Port-Of: odoo/odoo#272824
Forward-Port-Of: odoo/odoo#272362This change prevents invoice email notifications from crashing when they are rendered in a different language than the one used while saving the invoice. It ensures invoices created with Quick Edit can be confirmed and notified reliably, even across users with different languages.
Original PR description
**Steps to Reproduce:** - Install the Accounting and Contacts modules. - Enable Quick Encoding for Customer Invoices and Vendor Bills in the company settings. - Create a new customer: Assign a…
**Steps to Reproduce:**
- Install the Accounting and Contacts modules.
- Enable Quick Encoding for Customer Invoices and Vendor Bills in the company
settings.
- Create a new customer: Assign a salesperson.
- Ensure:
- The salesperson is not a login user.
- The customer language, salesperson's language, and Login user's language
are different. Example:
- Customer language: English
- Salesperson language: French
- Login user language: French
- Create a customer invoice using the Upload Document functionality.
- Select the customer created above.
- Use Quick Edit mode and enter an amount and Click Confirm.
**Issue:**
- When the invoice notification is rendered in a language different from the one
used during the write operation, the notification rendering flow calls
_notify_by_email_prepare_rendering_context().
- During rendering, the code executes:
```
self.tax_totals.get('total_amount_currency', 0)
```
- Since tax_totals is protected, the ORM returns False instead of the expected
dictionary, leading to:
```
AttributeError: 'bool' object has no attribute 'get'
```
**Root Cause:**
- This issue occurs in Quick Edit mode because tax_totals is [not read-only](https://github.com/odoo/odoo/blob/1f7a62d38303a992f501b4ecdb1bee437f7279b8/addons/account/views/account_move_views.xml#L1359)
in Quick Edit mode and is included in [the values](https://github.com/odoo/odoo/blob/1f7a62d38303a992f501b4ecdb1bee437f7279b8/addons/web/static/src/model/relational_model/record.js#L708) sent by the web client during write().
- During create()/write(), _get_protected_vals() marks tax_totals as protected.
- Since tax_totals is a [@api.depends_context('lang')](https://github.com/odoo/odoo/blob/1f7a62d38303a992f501b4ecdb1bee437f7279b8/addons/account/models/account_move.py#L975) computed field, it
maintains a separate cache per language. [During write()](https://github.com/odoo/odoo/blob/1f7a62d38303a992f501b4ecdb1bee437f7279b8/addons/account/models/account_move.py#L3955), the [field becomes
protected](https://github.com/odoo/odoo/blob/1f7a62d38303a992f501b4ecdb1bee437f7279b8/addons/account/models/account_move.py#L3863) by [env.protecting()](https://github.com/odoo/odoo/blob/1f7a62d38303a992f501b4ecdb1bee437f7279b8/odoo/orm/fields.py#L1738). While the protection is still active, the mail
notification flow renders the email using the recipient's language. If the
corresponding language-specific cache entry for tax_totals is not available,
the ORM cannot recompute the protected field and returns False instead
of the expected dictionary.
- The rendering code assumes tax_totals is always a dictionary and directly
calls .get(), leading to the crash.
**Solution:**
- Exclude tax_totals from _get_protected_vals().
- tax_totals is already handled explicitly after create()/write(), so protecting
it is unnecessary. This allows the field to be recomputed during notification
rendering when required.
**Result:**
- Invoice notifications render correctly in all languages.
- No RPC crash occurs when rendering notifications after Quick Edit.
**Runbot reproduction: [video](https://github.com/user-attachments/assets/5f045efb-37de-40aa-b135-1368b1601d61)**
**opw-6209647**
Forward-Port-Of: odoo/odoo#266335Miscellaneous changes
Related: https://github.com/odoo/enterprise/pull/122299 Related: https://github.com/odoo/design-themes/pull/1305
Original PR description
Related: https://github.com/odoo/enterprise/pull/122299 Related: https://github.com/odoo/design-themes/pull/1305
Related: https://github.com/odoo/odoo/pull/273112 Related: https://github.com/odoo/design-themes/pull/1305
Original PR description
Related: https://github.com/odoo/odoo/pull/273112 Related: https://github.com/odoo/design-themes/pull/1305
7 changes
Enhancements to existing features
This update makes sure the label shown for the reconciliation setting is consistent across accounting models. It improves clarity for users by displaying the same updated wording everywhere, avoiding confusion from mixed old and new labels.
Original PR description
Since this PR https://github.com/odoo/odoo/pull/249536 "Allow Reconcilation" became "Payment Reconciliation" This change in labels didn't take effect in the account.move.line model. This commit fixes this issue by ensuring that the label of is_account_reconcile field matches that of the account.account.reconcile field. task-6306159
Resolved issues and error corrections
This update fixes an issue in Guatemalan electronic invoicing where names with accented or special characters could be rejected or arrive corrupted. By sending the invoice in the correct format, Odoo helps ensure invoices are certified reliably and customer or product names stay intact.
Original PR description
**Steps to reproduce:** * Install the **l10n_gt_edi** module. * Configure a Guatemalan company with valid Infile credentials in the settings. * Create a product or customer with special characters…
**Steps to reproduce:**
* Install the **l10n_gt_edi** module.
* Configure a Guatemalan company with valid Infile credentials in the settings.
* Create a product or customer with special characters (e.g. `ñ`, `á`, `é`) in their name.
* Create a customer invoice containing this product/customer.
* Confirm the invoice to trigger the EDI send to the SAT (Infile).
**Observed behavior:**
* Infile intermittently rejects the invoice due to validation errors, or accepts it but the resulting certified XML has truncated or malformed text exactly where the special characters were located.
**Cause:**
* Odoo uses the `requests.post()` library to send the XML payload to Infile. By default, `requests` encodes string payloads using `latin-1` unless told otherwise.
* Because the request was missing the explicit `Content-Type: application/xml` header and the XML string was not explicitly encoded to `utf-8` before sending, Infile parsed the payload using an incorrect encoding. This caused it to drop or misinterpret special characters, leading to validation failures or corrupted XML content.
**Fix:**
* Explicitly include the `'Content-Type': 'application/xml'` header in the request to Infile.
* Explicitly encode the `xml_data` payload to `utf-8` (`xml_data.encode('utf-8')`) before passing it to `requests.post()` to guarantee the correct encoding is sent over the wire.
opw-6315654
Forward-Port-Of: odoo/enterprise#121729This change prevents an error that could appear when deleting a newly created Receipt. It makes the status bar handle cases where nothing is selected, so users no longer see a traceback during this action.
Original PR description
# How to reproduce - Create a new Receipt - Save - Delete the new Receipt # The issue A traceback is shown : `TypeError: Cannot read properties of undefined (reading 'label')` # Cause This is caused…
# How to reproduce - Create a new Receipt - Save - Delete the new Receipt # The issue A traceback is shown : `TypeError: Cannot read properties of undefined (reading 'label')` # Cause This is caused by the custom status bar for pickings `StockPickingLockedStatusBarField`. In its template, we replace the display of the current label : https://github.com/odoo/odoo/blob/490c355ae0bc77c1106e22b3afb2206583980324/addons/stock/static/src/fields/stock_picking_locked_statusbar_field.xml#L20-L23 https://github.com/odoo/odoo/blob/490c355ae0bc77c1106e22b3afb2206583980324/addons/stock/static/src/fields/stock_picking_locked_statusbar_field.xml#L4-L9 The issue is that the base implementation of the current label properly handles the case were no item is currently selected: https://github.com/odoo/odoo/blob/7630f8fe2d5198b7a1ed538241795dc26a497fa0/addons/web/static/src/views/fields/statusbar/statusbar_field.js#L298-L300 But the picking implementation does not : https://github.com/odoo/odoo/blob/490c355ae0bc77c1106e22b3afb2206583980324/addons/stock/static/src/fields/stock_picking_locked_statusbar_field.js#L12-L14 And it seems that the template is quickly rendered without any selected item before deletion. opw-6345192 Forward-Port-Of: odoo/odoo#273030
Employees can now submit an expense even if they do not have a manager assigned, avoiding an error that blocked the process. They can also continue adding comments and attachments on their own expenses after they are no longer in draft, making it easier to provide explanations or extra proof when needed.
Original PR description
# [FIX] hr_expense: Submitting an expense without a manager doesn't work If a user tries to submit an expense without having a manager, this will fail with "You are neither a Manager nor a HR Officer". To fix this, we are not going to check when the manager is the user that expense is linked to. --------- # [FIX] hr_expense: Employee cant use chatter on his own expenses An employee that created his expense was only able to add attachments and post message in the chatter when the expense was in draft. After this, it will still be able to attach attachment and post message without having the right to edit the expense. This is better as the employee will be able to answer questions that have been asked or add more proof if required. [task-4966942](https://www.odoo.com/odoo/all-tasks/4966942) Forward-Port-Of: odoo/odoo#273067 Forward-Port-Of: odoo/odoo#224575
This change prevents an error that could occur when generating the Excel version of the GSTR-1 report for one company while data from another company is also present. It ensures the report can be exported normally without interruption, improving reliability for businesses working with multiple Indian company records.
Original PR description
Steps to reproduce: - Install `l10n_in_reports` module(Indian Localisation) - Create a branch in `IN Company` > Select both - Create separate invoices for each company - Created the GSTR-1 report for…
Steps to reproduce:
- Install `l10n_in_reports` module(Indian Localisation)
- Create a branch in `IN Company` > Select both
- Create separate invoices for each company
- Created the GSTR-1 report for both company
- While generating Excel, select only main company
Traceback:
```py
File "/home/odoo/src/enterprise/19.0/l10n_in_reports/models/account_return.py", line 2537, in action_generate_gstr1_xlsx
gstr1_json = self._get_l10n_in_gstr1_json()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/enterprise/19.0/l10n_in_reports/models/account_return.py", line 1071, in _get_l10n_in_gstr1_json
'b2cs': _get_b2cs_json(AccountMoveLine.search(self._get_section_domain('b2cs'))),
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/enterprise/19.0/l10n_in_reports/models/account_return.py", line 672, in _get_b2cs_json
for line, line_tax_details in tax_details.items():
^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'items'
```
Cause:
This issue occurs because, while generating the GSTR-1 Excel report for a particular month, [journal_items] contains account moves from both companies. This happens because the [domain] fetches records for both companies, resulting in move [lines] from both companies being included.
However, while generating the Excel report, only one company is selected. As a result, [tax_details_by_move] does not contain the move data for the branch company, which returns None, causing the error to be raised.
Solution:
Pass an empty `{}` for `tax_details` when only a single company is selected.
[journal_items]: https://github.com/odoo/enterprise/blob/3c3641d9f0753c1ca62285667c4a2786c15e2444/l10n_in_reports/models/account_return.py#L877
[domain]: https://github.com/odoo/enterprise/blob/770ffaac14bfcd2c54a7ce6aca27e0010e7884d4/l10n_in_reports/models/account_return.py#L1387-L1393
[lines]:
https://github.com/odoo/enterprise/blob/3c3641d9f0753c1ca62285667c4a2786c15e2444/l10n_in_reports/models/account_return.py#L1074
[tax_details_by_move]:
https://github.com/odoo/enterprise/blob/3c3641d9f0753c1ca62285667c4a2786c15e2444/l10n_in_reports/models/account_return.py#L880
opw-6242824
Forward-Port-Of: odoo/enterprise#118614This update corrects how the current year result is classified in Luxembourg accounting and simplifies the calculation of the balance sheet’s carried-forward profit or loss line. It helps ensure the report reflects the right figures more reliably in local financial statements.
Original PR description
This commit addresses the account type for the current year earnings and simplifies the calculation for the "Result brought forward" line in the Luxembourg balance sheet reports.
Modifications:
* Changed the account type of account 142 ("Result for the financial year") from `equity_unaffected` to standard `equity`.
* Simplified the formula for the Balance Sheet line "Profit or loss brought forward" (codes `LU_BS_319` and `LU_BSABR_319`).
* The new formula simply targets the `14` accounts while explicitly excluding `142`.
Enterprise PR: odoo/enterprise#121891
Ticket [link](https://www.odoo.com/odoo/project.task/6059571)
opw-6059571
Forward-Port-Of: odoo/odoo#272824
Forward-Port-Of: odoo/odoo#272362This update corrects how the current year result is classified and simplifies a balance sheet line in the Luxembourg reports. It helps ensure the financial statements show the carried-forward profit or loss more accurately and consistently.
Original PR description
This commit addresses the account type for the current year earnings and simplifies the calculation for the "Result brought forward" line in the Luxembourg balance sheet reports.
Modifications:
* Changed the account type of account 142 ("Result for the financial year") from `equity_unaffected` to standard `equity`.
* Simplified the formula for the Balance Sheet line "Profit or loss brought forward" (codes `LU_BS_319` and `LU_BSABR_319`).
* The new formula simply targets the `14` accounts while explicitly excluding `142`.
Community PR: odoo/odoo#272362
Ticket [link](https://www.odoo.com/odoo/project.task/6059571)
opw-6059571
Forward-Port-Of: odoo/enterprise#122097
Forward-Port-Of: odoo/enterprise#1218912 changes
Enhancements to existing features
This update adds a new integration point when an activity is marked as done. It makes it easier for other features to automatically link or process the related message, improving consistency across activity-related workflows.
Original PR description
Add a hook in `_action_done` to allow other modules to link/process message for every activity.
Resolved issues and error corrections
**Steps to reproduce:** * Install the **l10n_gt_edi** module. * Configure a Guatemalan company with valid Infile credentials in the settings. * Create a product or customer with special characters (e.g. `ñ`, `á`, `é`) in their name. * Create a customer invoice containing this product/customer. * Confirm the invoice to trigger the EDI send to the SAT (Infile). **Observed behavior:** * Infile intermittently rejects the invoice due to validation errors, or accepts it but the resulting cert
Original PR description
**Steps to reproduce:** * Install the **l10n_gt_edi** module. * Configure a Guatemalan company with valid Infile credentials in the settings. * Create a product or customer with special characters…
**Steps to reproduce:**
* Install the **l10n_gt_edi** module.
* Configure a Guatemalan company with valid Infile credentials in the settings.
* Create a product or customer with special characters (e.g. `ñ`, `á`, `é`) in their name.
* Create a customer invoice containing this product/customer.
* Confirm the invoice to trigger the EDI send to the SAT (Infile).
**Observed behavior:**
* Infile intermittently rejects the invoice due to validation errors, or accepts it but the resulting certified XML has truncated or malformed text exactly where the special characters were located.
**Cause:**
* Odoo uses the `requests.post()` library to send the XML payload to Infile. By default, `requests` encodes string payloads using `latin-1` unless told otherwise.
* Because the request was missing the explicit `Content-Type: application/xml` header and the XML string was not explicitly encoded to `utf-8` before sending, Infile parsed the payload using an incorrect encoding. This caused it to drop or misinterpret special characters, leading to validation failures or corrupted XML content.
**Fix:**
* Explicitly include the `'Content-Type': 'application/xml'` header in the request to Infile.
* Explicitly encode the `xml_data` payload to `utf-8` (`xml_data.encode('utf-8')`) before passing it to `requests.post()` to guarantee the correct encoding is sent over the wire.
opw-6315654
Forward-Port-Of: odoo/enterprise#1217291 change
Resolved issues and error corrections
This update ensures invoices sent through the Guatemalan Infile connection use the correct XML format and character encoding. As a result, names and product descriptions with accents or special characters are transmitted reliably, reducing invoice rejections and preventing corrupted certified XML.
Original PR description
**Steps to reproduce:** * Install the **l10n_gt_edi** module. * Configure a Guatemalan company with valid Infile credentials in the settings. * Create a product or customer with special characters…
**Steps to reproduce:**
* Install the **l10n_gt_edi** module.
* Configure a Guatemalan company with valid Infile credentials in the settings.
* Create a product or customer with special characters (e.g. `ñ`, `á`, `é`) in their name.
* Create a customer invoice containing this product/customer.
* Confirm the invoice to trigger the EDI send to the SAT (Infile).
**Observed behavior:**
* Infile intermittently rejects the invoice due to validation errors, or accepts it but the resulting certified XML has truncated or malformed text exactly where the special characters were located.
**Cause:**
* Odoo uses the `requests.post()` library to send the XML payload to Infile. By default, `requests` encodes string payloads using `latin-1` unless told otherwise.
* Because the request was missing the explicit `Content-Type: application/xml` header and the XML string was not explicitly encoded to `utf-8` before sending, Infile parsed the payload using an incorrect encoding. This caused it to drop or misinterpret special characters, leading to validation failures or corrupted XML content.
**Fix:**
* Explicitly include the `'Content-Type': 'application/xml'` header in the request to Infile.
* Explicitly encode the `xml_data` payload to `utf-8` (`xml_data.encode('utf-8')`) before passing it to `requests.post()` to guarantee the correct encoding is sent over the wire.
opw-6315654
Forward-Port-Of: odoo/enterprise#1217292 changes
Resolved issues and error corrections
This change ensures invoices sent to Guatemala’s Infile service keep special characters like ñ, á, and é intact. It reduces failed submissions and prevents certified XML files from being corrupted by using the correct XML content type and UTF-8 encoding.
Original PR description
**Steps to reproduce:** * Install the **l10n_gt_edi** module. * Configure a Guatemalan company with valid Infile credentials in the settings. * Create a product or customer with special characters…
**Steps to reproduce:**
* Install the **l10n_gt_edi** module.
* Configure a Guatemalan company with valid Infile credentials in the settings.
* Create a product or customer with special characters (e.g. `ñ`, `á`, `é`) in their name.
* Create a customer invoice containing this product/customer.
* Confirm the invoice to trigger the EDI send to the SAT (Infile).
**Observed behavior:**
* Infile intermittently rejects the invoice due to validation errors, or accepts it but the resulting certified XML has truncated or malformed text exactly where the special characters were located.
**Cause:**
* Odoo uses the `requests.post()` library to send the XML payload to Infile. By default, `requests` encodes string payloads using `latin-1` unless told otherwise.
* Because the request was missing the explicit `Content-Type: application/xml` header and the XML string was not explicitly encoded to `utf-8` before sending, Infile parsed the payload using an incorrect encoding. This caused it to drop or misinterpret special characters, leading to validation failures or corrupted XML content.
**Fix:**
* Explicitly include the `'Content-Type': 'application/xml'` header in the request to Infile.
* Explicitly encode the `xml_data` payload to `utf-8` (`xml_data.encode('utf-8')`) before passing it to `requests.post()` to guarantee the correct encoding is sent over the wire.
opw-6315654
Forward-Port-Of: odoo/enterprise#121729In a multi-company setup with a website per company, the unsubscribe link in mass mailing emails could send recipients to the login page instead of the unsubscribe confirmation page. ### Steps to reproduce 1. Enable multi-company and create a second company `Company B`. 2. Create two websites with different domains, one per company: - `Website A` on the main company, domain `http://website-a.test` - `Website B` on `Company B`, domain `http://website-b.test` 3. Set the system para
Original PR description
In a multi-company setup with a website per company, the unsubscribe link in mass mailing emails could send recipients to the login page instead of the unsubscribe confirmation page. ### Steps to…
In a multi-company setup with a website per company, the unsubscribe link in mass mailing emails could send recipients to the login page instead of the unsubscribe confirmation page.
### Steps to reproduce
1. Enable multi-company and create a second company `Company B`.
2. Create two websites with different domains, one per company:
- `Website A` on the main company, domain `http://website-a.test`
- `Website B` on `Company B`, domain `http://website-b.test`
3. Set the system parameter `web.base.url` to `http://website-a.test`. System parameters are global, so this value applies to the whole database regardless of the company you switch to.
4. Create a contact and set its `Company` field to `Company B`.
5. In Email Marketing, create a mailing with recipient model `Contact`, target the contact above, pick any template with an unsubscribe link, and send it.
6. Open the email in an incognito window and click the unsubscribe link: you land on the login page instead of the unsubscribe page.
### Cause
Mass mailing builds the unsubscribe link in two steps.
First, each email body is rendered for its recipient. While rendering, relative URLs like `/unsubscribe_from_list` are turned into absolute URLs by prepending a base URL. That base URL comes from the recipient record itself: `recipient.get_base_url()`. The `website` module overrides this so that, when the record has a company, it returns that company's website domain. For a contact in `Company B`, the body ends up with `http://website-b.test/unsubscribe_from_list`.
Second, right before sending, `mail_mail._prepare_outgoing_list` replaces that placeholder URL with a per-recipient signed URL pointing to `/confirm_unsubscribe`. It does this by plain string replacement: it looks for `{base_url}/unsubscribe_from_list` in the body and swaps it. The `base_url` used here came from `self.mailing_id.get_base_url()`. A mailing has no company, so its base URL falls back to the global `web.base.url`, which in our setup is `http://website-a.test`.
The two base URLs no longer match. The body contains the website B URL, but the replacement code searches for the website A URL. The search fails, the placeholder stays in the email, and the recipient clicks a link to `/unsubscribe_from_list`. That route only redirects to `/mailing/my`, which requires being logged in, so the user lands on the login page.
### Fix
Compute the base URL from the recipient record (the same record used when rendering the body) instead of the mailing. The two URLs then agree and the replacement works. Fall back to the mailing's base URL if there is no recipient model on the mail.
opw-4914203
Forward-Port-Of: odoo/odoo#273190
Forward-Port-Of: odoo/odoo#2640553 changes
Resolved issues and error corrections
The Timesheet app now correctly grays out days that are unavailable in the user’s own schedule. This fixes a display issue where removed working days could still appear available, helping users avoid entering time on days they should not work.
Original PR description
To reproduce: ============= - modify Mitchel Admin's working schedule and remove a day of work - open timesheet app as Mitchel Admin - the removed day is not grayed out as unavailable Porblem: ======== the method `get_unavailabily` was handling only the case when calling it with `groupby=employee_id` otherwise it returns the company's unvailability Solution: ========= when the "My Timesheet" action is opened, the method `get_unavailabily` is now called with a specific context key, allowing to return the current user's unavailability instead of the company's one. opw-5949236 Forward-Port-Of: odoo/enterprise#113984
The payment step now checks that the point of sale is actually set up as a kiosk and that an IoT payment device is configured before continuing. This reduces payment errors and helps prevent invalid configurations from reaching customers at checkout.
Original PR description
This commit makes the payment endpoint more robust by verifying the POS config is indeed a kiosk, and that it has an IoT payment method configured.
This update fixes invoice transmission to Guatemala’s Infile service when names or product descriptions contain accented or special characters. It ensures the XML is sent in the right format so invoices are less likely to be rejected and certified documents keep the correct text.
Original PR description
**Steps to reproduce:** * Install the **l10n_gt_edi** module. * Configure a Guatemalan company with valid Infile credentials in the settings. * Create a product or customer with special characters…
**Steps to reproduce:**
* Install the **l10n_gt_edi** module.
* Configure a Guatemalan company with valid Infile credentials in the settings.
* Create a product or customer with special characters (e.g. `ñ`, `á`, `é`) in their name.
* Create a customer invoice containing this product/customer.
* Confirm the invoice to trigger the EDI send to the SAT (Infile).
**Observed behavior:**
* Infile intermittently rejects the invoice due to validation errors, or accepts it but the resulting certified XML has truncated or malformed text exactly where the special characters were located.
**Cause:**
* Odoo uses the `requests.post()` library to send the XML payload to Infile. By default, `requests` encodes string payloads using `latin-1` unless told otherwise.
* Because the request was missing the explicit `Content-Type: application/xml` header and the XML string was not explicitly encoded to `utf-8` before sending, Infile parsed the payload using an incorrect encoding. This caused it to drop or misinterpret special characters, leading to validation failures or corrupted XML content.
**Fix:**
* Explicitly include the `'Content-Type': 'application/xml'` header in the request to Infile.
* Explicitly encode the `xml_data` payload to `utf-8` (`xml_data.encode('utf-8')`) before passing it to `requests.post()` to guarantee the correct encoding is sent over the wire.
opw-6315654
Forward-Port-Of: odoo/enterprise#12172916 changes
Enhancements to existing features
Belgian payroll now better handles extra hours worked by part-time employees, while keeping track of the usual full-time limits in the company. It also adds clearer payroll warnings so unusual cases can be caught earlier, helping avoid validation issues and payroll mistakes.
Original PR description
Introduce support for part-time additional hours in Belgian payroll (hours worked beyond the contractual part-time schedule, without exceeding the normal full-time working limits in the company)
- Add 3 dedicated work entry types (0%, +50%, +100%)
- Add payslip warnings for:
- monthly limit (>12h)
- daily limit (>9h)
- weekly limit (reference schedule)
- invalid type on Sundays/public holidays
- overlap with working time
Related PRs:
odoo: https://github.com/odoo/odoo/pull/269726
upgrade: https://github.com/odoo/upgrade/pull/10581
task-5484105The Belgian payroll configuration now groups certain time-based benefits, such as private car, meal vouchers, and representation fees, into categories instead of simple yes/no flags. This makes the setup more consistent and easier to manage in payroll rules and payslip calculations.
Original PR description
In this commit, we converted time type benefits (private_car, meal_voucher, representation_fees) from boolean fields into categories. task-6193618
When the Shopee connector was introduced, Shopee documented `buyer_user_id` as an int32. We therefore store it in an `Integer` field, which maps to a PostgreSQL int32 column. However, feedback showed that Shopee can send ids exceeding the int32 bounds, leading to a traceback when creating new contacts. Shopee has since updated their documentation to confirm the field is actually an int64. This commit changes the `shopee_buyer_identifier` field type to be `Char` and cleans the stable workar
Original PR description
When the Shopee connector was introduced, Shopee documented `buyer_user_id` as an int32. We therefore store it in an `Integer` field, which maps to a PostgreSQL int32 column. However, feedback showed that Shopee can send ids exceeding the int32 bounds, leading to a traceback when creating new contacts. Shopee has since updated their documentation to confirm the field is actually an int64. This commit changes the `shopee_buyer_identifier` field type to be `Char` and cleans the stable workaround. opw-6325948 See also: - stable: https://github.com/odoo/enterprise/pull/121498 - upgrade: https://github.com/odoo/upgrade/pull/10578
For an accountant, the dmfa report is too detailed, he needs a grouped summary. task: 6307733
Original PR description
For an accountant, the dmfa report is too detailed, he needs a grouped summary. task: 6307733
Enable testing of DIMONA declarations without making actual API calls to ONSS by using the sandbox environment in the settings. Go to Payroll → Reporting → Create Declarations From JSON. Here you can create a declaration in the same format received from the government. You can also go to Payroll → Reporting → DIMONA and create any DIMONA declaration without sending real API calls. Create an employee and click the Check DIMONA button. A wizard will appear, allowing you to enter the fake respon
Original PR description
Enable testing of DIMONA declarations without making actual API calls to ONSS by using the sandbox environment in the settings. Go to Payroll → Reporting → Create Declarations From JSON. Here you can create a declaration in the same format received from the government. You can also go to Payroll → Reporting → DIMONA and create any DIMONA declaration without sending real API calls. Create an employee and click the Check DIMONA button. A wizard will appear, allowing you to enter the fake response you need. Task Id: 6069261
Payroll calculations now ignore worked day lines for company executives, so their payslips are handled more appropriately. This reduces unnecessary payroll data on executive slips and helps keep calculations and reports clearer.
Original PR description
task-6332908
This update aligns the data cleaning and data merge records with the same way Odoo Community stores references to related records. It improves consistency between editions and helps these tools work more reliably with linked data.
Original PR description
Adapt to Odoo community, by applying the same res_id reference change to data_cleaning.record and data_merge.record. Community: https://github.com/odoo/odoo/pull/268906.
The payslip calendar button now includes a Gantt-style timeline view, giving managers a clearer way to see payroll-related dates and scheduling at a glance. This makes it easier to review and plan payroll work without changing the underlying payroll process.
Original PR description
task-6348465
Belgian working schedules now only allow time types that count as working time or support reorganization measures. This helps keep schedule settings aligned with local payroll rules and reduces the risk of choosing an invalid time type.
Original PR description
In this commit, we introduce an extr domain/restraint on the time types that can be selected for belgian working schedules. Now, atop the existing domain, in belgium localization you can only select time types that count as working time, or that contribute to a reorganization measure. task-6333928
The Point of Sale barcode lookup test flow was updated to match the new quick-create product buttons, "Add & New" and "Add & Close." This keeps the automated tour working correctly after the interface change and helps prevent false test failures.
Original PR description
In this commit: =============== new buttons `Add & New` and `Add & Close` are added in quick create product view so adapt changes in tour Task-6260673 Related Comm. PR:https://github.com/odoo/odoo/pull/267661
This update hides the employee record column from standard payslip views to reduce confusion for most users, while still keeping it available in debug mode. It also increases the number of salary computation lines shown by default, which helps users in cases where payslips contain many entries.
Original PR description
Problem: - The column "employee record" on payslips worked day lines is confusing for most users and unnecessary. - The salary computation tab only shows 40 lines by default but in belgium it's always more Solution: - Show the employee record in debug mode only, by setting the `groups` field attribute to `base.group_no_one` on the view. - Increase the number of payslips lines to 200, by using the `limit` list attribute on the view. Task-6348587
Resolved issues and error corrections
Issue: The `test_overtime_ruleset_flow` tour test was failing because the `amount_rate` field could not be found. Reason: - Couldn't find the amount_rate field as it was located in the Payroll tab and the tour did not navigate to that tab before interacting with the field. - The tour also used some selectors and values that were no longer valid, causing some steps to fail. Fix: - Open the Payroll tab before interacting with the `amount_rate` field. - Set the overtime leave request dur
Original PR description
Issue: The `test_overtime_ruleset_flow` tour test was failing because the `amount_rate` field could not be found. Reason: - Couldn't find the amount_rate field as it was located in the Payroll tab and the tour did not navigate to that tab before interacting with the field. - The tour also used some selectors and values that were no longer valid, causing some steps to fail. Fix: - Open the Payroll tab before interacting with the `amount_rate` field. - Set the overtime leave request duration type to "Custom Hours". - Replace the unavailable "Salary-exempt" employee type with "Employee". - Use the checkbox input selector to interact with the attendance_based field. - Explicitly open the dropdown before clicking on `action_continue` button. - Remove the unnecessary final `action_continue` step.
The Knowledge setup tour has been updated to use the Add button when confirming property changes. This avoids losing recent edits by accidentally clicking outside the popover, making the guided setup more reliable.
Original PR description
Previously, the knowledge_properties_tour used to click outside the property definition popover to save changes. This now discards recent changes, so the tour explicitly clicks the add button instead.
The Belgian payroll process now delays Dimona OUT notifications for employees with code 495 until a departure reason has been entered. This avoids sending an end-of-employment notice too early and reduces manual corrections in the Dimona portal.
Original PR description
This commit will prevent the automatic sending of Dimona OUT notifications upon contract end date changes unless a departure reason is specified for employees with code 495. Why: Currently, the system triggers a Dimona OUT transmission immediately when a contract end date is modified. Now employees with the code 495 and requiring the 'Departure Reason' to be set ensures that the legal notification is only sent when a factual termination of employment has been confirmed, reducing the need for manual corrections in the Dimona portal. What: - Modified the trigger logic for Dimona OUT generation in the Belgian payroll module. - Added a conditional check for the employee code (495). task-6127189
Code cleanup and technical improvements
This change updates how certain background services are started so they begin automatically when the app is created. It simplifies startup and reduces the risk of services being initialized too late, improving reliability for affected areas.
Original PR description
This commit introduces a new plugin which starts the legacy services. Before this plugin, we needed to start the services after the app creation but now, this is done during the creation.
This change updates a small set of interface templates to use the newer Owl data-binding syntax. It helps keep the product compatible with the latest framework version and reduces maintenance risk, without changing business behavior.
Original PR description
* = ['event_iot'] As part of the migration from `owl 2` to `owl 3`, this commit replaces uses of `t-custom-model` with `t-model` or `t-model.proxy`.
3 changes
Resolved issues and error corrections
## **Issue:** When validating a delivery, users with Sales: Own Documents Only and Inventory Administrator access rights can encounter an access error if the delivery belongs to a sale order owned by another salesperson. ## **Steps to reproduce:** - Install sale_subscription_stock. - Create a user with Sales: Own Documents Only and Inventory Administrator access rights. - Create a sale order as another user. - Validate the delivery with the restricted user. ## **Solution:** During _a
Original PR description
## **Issue:** When validating a delivery, users with Sales: Own Documents Only and Inventory Administrator access rights can encounter an access error if the delivery belongs to a sale order owned by…
## **Issue:** When validating a delivery, users with Sales: Own Documents Only and Inventory Administrator access rights can encounter an access error if the delivery belongs to a sale order owned by another salesperson. ## **Steps to reproduce:** - Install sale_subscription_stock. - Create a user with Sales: Own Documents Only and Inventory Administrator access rights. - Create a sale order as another user. - Validate the delivery with the restricted user. ## **Solution:** During _action_done(), [This line](https://github.com/odoo/enterprise/blob/19.0/sale_subscription_stock/models/stock_picking.py#L45) is checking subscription_state. Since the user does not have read access to the sale order, reading this field raises an access error and prevents the delivery from being validated. As the method only needs to read the subscription state, access the field with sudo() to avoid the unnecessary access error while preserving the existing business logic. Runbot Video : [Video](https://drive.google.com/file/d/1d7U2jTCxaaVk2YJcy3bi2SlYuT-yXMsu/view?usp=drive_link) OPW - 6295712
Steps to reproduce =================== - Install documents_hr. - Log in with admin. - Create a new company `Test`. - Go to Document and choose the new company (top right). - Go to `My Drive`: a folder named `Employees - Test` has been created. This new folder should be created in the `Company` root instead of the `My Drive,` which will hold all the employee folders. Technical =========== When the main employee folder is created via `_generate_employee_documents_main_folders` `ow
Original PR description
Steps to reproduce =================== - Install documents_hr. - Log in with admin. - Create a new company `Test`. - Go to Document and choose the new company (top right). - Go to `My Drive`: a folder named `Employees - Test` has been created. This new folder should be created in the `Company` root instead of the `My Drive,` which will hold all the employee folders. Technical =========== When the main employee folder is created via `_generate_employee_documents_main_folders` `owner_id` falls back to the current user, which leads to computing the `user_folder_id` as `My drive,` and so that's why the newly created folder starts appearing there instead of the `Company` root. This PR addresses the issue and sets the `owner_id` to False, which leads to show the main employee folder in the company root. Task-6267352
This update ensures invoices sent to Guatemala’s Infile service are encoded properly, so names and product details with characters like ñ, á, and é are preserved. It helps prevent invoice rejections and avoids corrupted text in certified XML documents.
Original PR description
**Steps to reproduce:** * Install the **l10n_gt_edi** module. * Configure a Guatemalan company with valid Infile credentials in the settings. * Create a product or customer with special characters…
**Steps to reproduce:**
* Install the **l10n_gt_edi** module.
* Configure a Guatemalan company with valid Infile credentials in the settings.
* Create a product or customer with special characters (e.g. `ñ`, `á`, `é`) in their name.
* Create a customer invoice containing this product/customer.
* Confirm the invoice to trigger the EDI send to the SAT (Infile).
**Observed behavior:**
* Infile intermittently rejects the invoice due to validation errors, or accepts it but the resulting certified XML has truncated or malformed text exactly where the special characters were located.
**Cause:**
* Odoo uses the `requests.post()` library to send the XML payload to Infile. By default, `requests` encodes string payloads using `latin-1` unless told otherwise.
* Because the request was missing the explicit `Content-Type: application/xml` header and the XML string was not explicitly encoded to `utf-8` before sending, Infile parsed the payload using an incorrect encoding. This caused it to drop or misinterpret special characters, leading to validation failures or corrupted XML content.
**Fix:**
* Explicitly include the `'Content-Type': 'application/xml'` header in the request to Infile.
* Explicitly encode the `xml_data` payload to `utf-8` (`xml_data.encode('utf-8')`) before passing it to `requests.post()` to guarantee the correct encoding is sent over the wire.
opw-6315654
Forward-Port-Of: odoo/enterprise#1217295 changes
Resolved issues and error corrections
This change ensures batch payment sequences are created only when a company is actually created, so they are linked to the correct company. It also adjusts the payment prefix to use the correct yearly numbering setup, preventing sequence issues later on.
Original PR description
Previously, batch payment sequence will be created by simply select to create new company due to having lambda in default. Hence, the created sequence does not have a correct company_id set as company hasn't yet created. Switch to creating sequence in ``create`` function to avoid this issue. Also use ``range_year`` for payment prefix because it was set to use date range. 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 fix prevents an error that could appear when changing a product’s bill of materials type in one company while old sales exist in another company. It ensures the check only applies to the correct company, avoiding unnecessary blocks for legitimate updates.
Original PR description
### Steps to reproduce: - Have two companies: company1 and company2 - Create a producct P available in both company1 and company2 - with company1, create a kit bom for a product P - with company2,…
### Steps to reproduce: - Have two companies: company1 and company2 - Create a producct P available in both company1 and company2 - with company1, create a kit bom for a product P - with company2, create and confirm a sale order for 1 unit of P - with company1, change the bom type of P from kit to manufature #### > UserError: As long as there are some sale order lines that must be delivered/invoiced and are related to these bills of materials, you can not remove them. ### Cause of the issue: Changing the bom type from a kit (phantom type) to a non kit will launch a call of the `_ensure_bom_is_free` in order to ensure data integrity if the kit bom was used by a relevant sale order line: https://github.com/odoo/odoo/blob/f4c76be062bec47b68ee42505d7d42fed31ac0f2/addons/sale_mrp/models/mrp_bom.py#L15-L18 https://github.com/odoo/odoo/blob/f4c76be062bec47b68ee42505d7d42fed31ac0f2/addons/sale_mrp/models/mrp_bom.py#L24-L42 However, this check does not take the company of the bom into account and in the present flow, the company of the bom is different from the company of the supposedly problematic sol. opw-6290304 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
When shoppers switch to or from in-store pickup, the checkout now immediately updates taxes and totals to match the selected warehouse. This prevents customers from seeing outdated prices or tax amounts during delivery selection and makes the checkout and payment steps consistent.
Original PR description
Backport of : https://github.com/odoo/odoo/pull/269057 to V18 When an international customer selects an in-store pickup location, the order's fiscal position changes to the fiscal position matching…
Backport of : https://github.com/odoo/odoo/pull/269057 to V18 When an international customer selects an in-store pickup location, the order's fiscal position changes to the fiscal position matching the pickup warehouse. However, the order-line taxes and checkout summary are not recomputed immediately. **Steps to reproduce:** 1. Configure a French company and website. 2. Configure a product priced at 100 ( just an example , any price will do ) EUR excluding 20% French VAT. 3. Configure an export fiscal position removing VAT for Japan. 4. Configure an international delivery method. 5. Configure an in-store pickup method with a warehouse located in France. 6. Checkout using a Japanese delivery address. 7. Select the international delivery method. 8. Switch to pickup in store. **Current behavior:** - The order fiscal position changes to the French fiscal position. - Product-line taxes and the checkout summary remain based on the export fiscal position. - French VAT only appears later on the payment step. - Switching back to international delivery can similarly leave stale totals. **Expected behavior:** - Selecting the French pickup location immediately applies French VAT. - Switching back to international delivery immediately removes French VAT. - Totals displayed during delivery selection match the payment-step totals. **Cause:** The Click & Collect flow explicitly recomputes `fiscal_position_id` when selecting or leaving an in-store pickup location, but it does not recompute the order-line taxes and prices. Additionally, the pickup-location route does not return updated order-summary values, so the checkout page cannot refresh its displayed totals. **Solution:** - Recompute taxes and prices when the in-store fiscal position changes. - Restrict the recomputation to draft website orders. - Return the updated order summary after selecting a pickup location. - Refresh the checkout summary using the returned values. **Tests cover:** - Japanese delivery with export fiscal position and no VAT. - Switching to a French pickup location immediately applying 20% VAT. - Switching back to international delivery removing VAT. - Delivery-step totals matching payment-step recomputation. - Pickup-location route returning updated summary values. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
WebP images are now checked against the same maximum size limit as other image formats when uploaded. This prevents very large files from being accepted on the website and helps keep server-side image handling consistent and reliable.
Original PR description
Since 17.0, `webp` images can be uploaded at any resolution, whereas every other format is refused above IMAGE_MAX_RESOLUTION (50 Mpx) when the attachment is created on the server. Root cause…
Since 17.0, `webp` images can be uploaded at any resolution, whereas every other format is refused above IMAGE_MAX_RESOLUTION (50 Mpx) when the attachment is created on the server. Root cause =========== `ImageProcess` grouped webp together with empty sources and SVG and set `self.image = False`, returning before the `verify_resolution` check. As a result the resolution limit enforced for `png/jpeg/...` was never applied to `webp`. Fix === Split `webp` out of the skip branch: it is still not processed as before, but its resolution is now read from the RIFF header with `get_webp_size()` and checked against `IMAGE_MAX_RESOLUTION`, so oversized webp images are refused on upload like any other format. Steps to reproduce =================== 1. Edit any page with the website editor 2. Upload a `webp` image larger than 50 Mpx (e.g. 8000x8000) => The image is accepted, while a `png/jpeg` of the same size is refused task-4134430 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#273010
This fix ensures that when a Point of Sale order line quantity is changed, the correct fiscal position is applied while recalculating taxes and prices. It prevents refunded orders from ending up with different amounts than they had originally, keeping totals consistent and accurate.
Original PR description
When changing the quantity of a pos order line the fiscal position set on the order was not used when recomputing the line price and taxes. Steps to reproduce: ------------------- * Create a tax with 15% rate and another with 10% rate * Create a fiscal position that maps the 15% tax to the 10% tax * Setup a PoS to be able to use that fiscal position * Open the PoS, add a product with the 15% tax, set the fiscal position and validate the order * Refund the order in the backend and change the quantity of the line from -1 to 0 and back to -1. > Observation: The price is not the same as before Why the fix: ------------ The fiscal position was not applied when recomputing the line's price and taxes. opw-6253311 Forward-Port-Of: odoo/odoo#270135
3 changes
Resolved issues and error corrections
Callbacks were changed to use a single shared callback instead of a bunch of callbacks that captured a specific container. Cloudlfare since introduced a change that breaks this change by not making "this" available inside callbacks. We thus go back to the previous implementation that did not rely on implementation details of the external widget. related: 5aa5cf62a9d3f2b0c862b0aab337b22367843fa6
Original PR description
Callbacks were changed to use a single shared callback instead of a bunch of callbacks that captured a specific container. Cloudlfare since introduced a change that breaks this change by not making "this" available inside callbacks. We thus go back to the previous implementation that did not rely on implementation details of the external widget. related: 5aa5cf62a9d3f2b0c862b0aab337b22367843fa6
This change prevents an error when EasyPost returns a tracking record with an empty tracker value. Users will now avoid a traceback and can continue working without interruption when tracking information is incomplete.
Original PR description
The PR https://github.com/odoo/enterprise/pull/111833 handled the specific case when the tracker data is missing from the EasyPost response, however in certain cases `tracker` key exists, but it has a `None` value, which leads to a traceback when trying to access the stock move:
```
File "/home/odoo/src/enterprise/18.0/delivery_easypost/models/easypost_request.py", line 392, in get_tracking_link
public_url = shipment.get('tracker', {}).get('public_url')
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'get'
```
This commit provides a fallback to avoid getting the error from the side of the user.
opw-6270242This change corrects how invoices are counted against the Italian declaration-of-intent limit when the DoI tax is used together with another tax on the same line. As a result, the invoice total is now properly deducted from the customer’s plafond, preventing incorrect remaining limits.
Original PR description
- Create a declaration of intent in the customer's contact - Issue an invoice that includes both the 0% E (DoI tax) and any other tax - You will see how the plafond is not updated and the amount of this invoice is not deducted from it The method _compute_l10n_it_edi_doi_amount specifically exclude from the doi amount lines with the doi tax and another tax. However it should be possible to use both on a single line. We can use the amount subtotal because the doi is always 0%. opw-6253475 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr