Friday, May 8, 2026
125 changes
7 changes
Resolved issues and error corrections
This update resolves an issue where moving workorders in the Kanban view incorrectly recalculated dates and times. The fix eliminates unnecessary date recalculations, improving the accuracy of workorder planning and scheduling within the MRP module. It also addresses minor UI improvements for the workorder list view.
Original PR description
Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update streamlines the work order planning process by reordering and renaming menus for better usability. It also fixes an issue where the Gantt chart displayed all employees, even those without assigned work orders, and now accurately reflects work order assignments through improved employee search functionality. The update restores additional views from the Gantt and Kanban views.
Original PR description
Some ui fixes for the new workorder planning Task: 6143389
This update ensures that imported records open with the same context as the original import action. Previously, imported invoices lacked the correct default settings, leading to incorrect column visibility and data defaults. This fix maintains consistency and simplifies the import process for users.
Original PR description
**Problem:** After importing records through the Import action, the list view that opens with the imported records does not inherit the context of the originating action. Column visibility and…
**Problem:**
After importing records through the Import action, the list view that opens with the imported records does not inherit the context of the originating action. Column visibility and default values that depend on that context (e.g. `default_move_type` on the shared invoice list) end up wrong.
**Steps to reproduce:**
1. Go to Accounting → Customers → Invoices
2. Click "Favorites → Import records"
3. Upload a CSV containing at least one valid customer invoice row
4. Run the import and look at the "Imported records" list that opens
**Current behavior:**
The imported records list opens with an empty context. Columns rendered conditionally on `default_move_type` (invoice-type-specific columns on `account.view_invoice_tree`) are not shown as they are when opening the list from the menu, and records created from that list have no default move type.
**Expected behavior:**
The imported records list should open with the same context as the action the user started the import from (e.g.
`{ default_move_type: 'out_invoice' }` for customer invoices), so columns and defaults match the previous view.
**Cause of the issue:**
`openRecords()` in `import_action.js` builds the follow-up `ir.actions.act_window` but never forwards `this.model.context`. The model already holds the context passed through the import action's `params.context`, but it is dropped when the redirect action is dispatched, so the window action opens with an empty context.
**Fix:**
Forwarding the context the import was launched with keeps the user inside the same functional scope (invoice type, default partner, company, etc.) when they land on the imported records list. Column visibility logic and default values that rely on that context behave identically to opening the list through the normal menu flow.
opw-6120758
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
Forward-Port-Of: odoo/odoo#261309This update significantly speeds up the inventory valuation report by optimizing how it calculates accruals. The changes batch computations and remove unnecessary loops, resulting in a much faster report generation time. This improves the user experience and reduces processing time for large inventories.
Original PR description
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 Forward-Port-Of: odoo/odoo#249624 Forward-Port-Of: odoo/odoo#247625
This update fixes an issue where users couldn't reliably edit text within editable buttons in the website builder. The change wraps button content in a span and removes it before saving, preventing duplication of branding and ensuring accurate text insertion. This improves the user experience and consistency when customizing website content.
Original PR description
Commit 072a8e4fd061ff23902e6e448a577624cb27e188 fixes edition of buttons by wrapping the editable button in an editable span. But it allows user to write outside the savable node, and allows user to…
Commit 072a8e4fd061ff23902e6e448a577624cb27e188 fixes edition of buttons by wrapping the editable button in an editable span. But it allows user to write outside the savable node, and allows user to copy website builder's branding attributes (which causes issues when pasted). This commit adds a span inside the button instead of outside, and removes it before saving the content. Steps to reproduce: - Open website buider on `/product/item-1` - Place the cursor in the "Add to cart" button - Press left arrow, repeat until out of the button - Bug: You can write text there, but it won't be saved ##### - Open website buider on `/product/item-1` - Select some text in the "Add to cart" button - Copy (`ctrl+c`) - Paste (`ctrl+v`) - Bug: Some content seems duplicated: the branding of the savable button has been duplicated inside it and the automatic replication between identical fields is based on this branding, thus replicates the button's content inside it Similar issue about copy+pasted branding: ec93d48ab17b4a72f61fa358e5a81d2abcb18897 Forward-Port-Of: odoo/odoo#257849
This update resolves an issue where purchase users couldn't see the available stock for products due to access restrictions in the stock forecast calculation. The PR adds temporary access rights (sudos) to ensure purchase users can accurately view stock levels when working with sales orders. A related test case was also corrected to ensure accurate stock availability calculations.
Original PR description
If a user with purchase rights but not sale rights opens a product, they won't see the free to use stock because the outgoing stock is based on the SO lines, which the purchase user can't access. This PR adds 2 sudos to `_compute_forecasted_without_stock`, one in purchase and one in sale. The sudos only affect a `_read_group` call and the result is not propagated outside of the compute function runbot error 243227 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update fixes a bug in how Odoo calculates product costs when using FIFO stock valuation and lot tracking, particularly in complex branch setups. The issue stemmed from incorrect fallback cost calculations leading to inaccurate inventory values and potential cost discrepancies. This ensures more reliable inventory tracking and reporting.
Original PR description
Databases that are configured to have products be evaluated by lot and FIFO can experience weird behavior when the product's cost or `standard_price` is updated. The current code doesn't account for…
Databases that are configured to have products be evaluated by lot and FIFO can experience weird behavior when the product's cost or `standard_price` is updated. The current code doesn't account for the fact that we allow users to dip into negative quantities and there aren't enough safeguards against this. This leads to the following bug that I found: The FIFO algorithm can't be calculated when there is no quantity. Odoo uses a fallback cost whenever quantity is less than zero, but this is incorrect when the product is evaluated by lots. Current behavior would calculate the fallback based on the product's standard price instead of the lot's standard price, leading to self-propagating calculation errors (e.g. cost going up to the trillions) Videos of the bug: Bug: ( Lot value defaults back to the product's standard price ) https://drive.google.com/file/d/1gUtjzdLpjeJts8HcxbTZ9MG4bSjRYmeT/view?usp=drive_link Related tickets: opw-6011189 Forward-Port-Of: odoo/odoo#263127 Forward-Port-Of: odoo/odoo#256113
3 changes
Resolved issues and error corrections
This update fixes an issue where Peppol invoices were incorrectly identifying branch companies as the sender instead of the parent company. The change ensures that the UBL/CII file accurately reflects the parent company's data, complying with Peppol regulations and improving invoice accuracy for international transactions. This resolves a prior error impacting data consistency.
4 changes
Resolved issues and error corrections
This fix resolves an issue where rental dates were incorrectly included in price calculations for non-rental products within rental orders. The update ensures that only the standard date is used when determining prices, improving accuracy and preventing pricing errors. This change focuses on a technical detail to ensure correct rental pricing.
Original PR description
1 change
Resolved issues and error corrections
This pull request corrects an error in the CFDI (Mexican electronic invoice) generation process when calculating payroll for employees with IMSS (Mexican Social Security Institute) disabilities. The fix ensures the correct XML node is populated to declare these disabilities, resolving issues with incorrect invoice amounts and preventing validation errors.
3 changes
Resolved issues and error corrections
This update corrects a bug where importing a product with a changed subscription type could bypass a necessary warning. Previously, the system processed the import without alerting the user, leading to potential inconsistencies. Now, a warning is raised when attempting to modify the subscription type of a product that has already been sold, ensuring data integrity.
7 changes
Resolved issues and error corrections
This update resolves a technical issue preventing invoices with Early Payment Discounts (EPD) and 0% tax from passing schematron validation, a requirement for Peppol compliance. The fix ensures accurate VAT breakdowns are generated, addressing a previous error where duplicate tax categories were created and a hardcoded tax code was used. This ensures invoices meet regulatory standards and avoids potential export failures.
Original PR description
Before this commit, creating an invoice with an Early Payment Discount (EPD) as a payment term could cause the schematron validation of the generated invoice to fail when an invoice line had a 0% tax. The issue was caused by generating two TaxSubtotal nodes for the same TaxCategory (0%, exemption code 'E'): - one for the 0% VAT - one for the EPD discount applied to the total amount However, Peppol requires a single VAT breakdown (TaxSubtotal) per VAT category (in this case: E) Additionally, when VAT was set to 0%, the allowance charge TaxSubtotal incorrectly used 'S' as a hardcoded tax category code. This commit fixes both issues. task-5900496 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Original PR description
### Issue before this commit: The XML export for branch companies incorrectly identified the branch as the sender, even when a Peppol parent company was configured. ### Steps to reproduce the issue:…
### Issue before this commit: The XML export for branch companies incorrectly identified the branch as the sender, even when a Peppol parent company was configured. ### Steps to reproduce the issue: 1. Download Accounting, Contacts and l10n_be 2. Create a branch for a Belgium company 3. Enable Peppol sending on the parent company 4. Enable Peppol sending on the branch company using the parent company endpoint 5. Switch to branch company 6. Create a customer invoice in the branch company using a customer who is on the Peppol network (meaning insert a valid VAT number and then verify button in the Accounting tab) 7. Confirm and send the invoice via Peppol 8. Download the resulting xml file and check the "AccountingSupplierParty" nodes. It contains the data of the branch and not the ones of the parent company ### Cause of the issue: The EDI export logic was fetching the supplier data directly from the invoice's company record without checking for a delegated Peppol parent company, ignoring the hierarchical relationship defined in the settings. ### Reason to introduce the fix: This fix ensures that the AccountingSupplierParty in the UBL/CII file correctly reflects the parent company's data when applicable. opw-6030526 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#260389
This update ensures that imported records open with the same context as the original import action. Previously, imported lists didn't inherit the correct settings like default invoice types, leading to incorrect column visibility and default values. Now, imported records will display with the appropriate context, improving the user experience and data accuracy.
Original PR description
**Problem:** After importing records through the Import action, the list view that opens with the imported records does not inherit the context of the originating action. Column visibility and…
**Problem:**
After importing records through the Import action, the list view that opens with the imported records does not inherit the context of the originating action. Column visibility and default values that depend on that context (e.g. `default_move_type` on the shared invoice list) end up wrong.
**Steps to reproduce:**
1. Go to Accounting → Customers → Invoices
2. Click "Favorites → Import records"
3. Upload a CSV containing at least one valid customer invoice row
4. Run the import and look at the "Imported records" list that opens
**Current behavior:**
The imported records list opens with an empty context. Columns rendered conditionally on `default_move_type` (invoice-type-specific columns on `account.view_invoice_tree`) are not shown as they are when opening the list from the menu, and records created from that list have no default move type.
**Expected behavior:**
The imported records list should open with the same context as the action the user started the import from (e.g.
`{ default_move_type: 'out_invoice' }` for customer invoices), so columns and defaults match the previous view.
**Cause of the issue:**
`openRecords()` in `import_action.js` builds the follow-up `ir.actions.act_window` but never forwards `this.model.context`. The model already holds the context passed through the import action's `params.context`, but it is dropped when the redirect action is dispatched, so the window action opens with an empty context.
**Fix:**
Forwarding the context the import was launched with keeps the user inside the same functional scope (invoice type, default partner, company, etc.) when they land on the imported records list. Column visibility logic and default values that rely on that context behave identically to opening the list through the normal menu flow.
opw-6120758
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
Forward-Port-Of: odoo/odoo#261309This update fixes an issue where automatically selected courses for multi-category restaurant items always chose the lowest sequence number, regardless of the active category filter. Now, the system correctly picks the course linked to the currently selected category, ensuring accurate order processing. Additionally, a new feature prevents the creation of unnecessary courses when adding items to orders with `use_course_allocation` enabled.
Original PR description
When a product belongs to multiple categories, each linked to a different course, the automatic course selection was always picking the one with the lowest sequence, regardless of context. The expected behavior is to pick the course tied to the currently active category filter, not an arbitrary one. This commit implements that logic. In addition, when `use_course_allocation` is enabled, adding a first course to an order that already contains products no longer creates an extra course. --- Task: https://www.odoo.com/odoo/project/1737/tasks/6187108 Forward-Port-Of: odoo/odoo#262683
When computing the price of a non-rental product in a rental order, the rental dates are added to the price computation kwargs. However, the rental dates and the date kwargs are incompatible when…
When computing the price of a non-rental product in a rental order, the rental dates are added to the price computation kwargs.
However, the rental dates and the date kwargs are incompatible when fetching applicable rules for a product.
One restricts rules to a range, whereas the other restricts rules to a specific date.
For non-rental products, the rental dates should not be forwarded; only the date argument should be.
```python
Traceback (most recent call last):
File "/Users/lipiraux/dev/odoo/master/odoo/odoo/http/router.py", line 432, in serve_db
return retrying(serve_func, env=request.env)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
File "/Users/lipiraux/dev/odoo/master/odoo/addons/sale/controllers/product_configurator.py", line 72, in sale_product_configurator_get_values
**self._get_product_information(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
File "/Users/lipiraux/dev/odoo/master/enterprise/sale_renting/models/product_pricelist.py", line 40, in _compute_price_rule
results = super()._compute_price_rule(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/lipiraux/dev/odoo/master/odoo/addons/product/models/product_pricelist.py", line 201, in _compute_price_rule
rules = self._get_applicable_rules(products, quantity, date=date, uom=uom, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/lipiraux/dev/odoo/master/odoo/addons/product/models/product_pricelist.py", line 273, in _get_applicable_rules
self._get_applicable_rules_domain(
File "/Users/lipiraux/dev/odoo/master/enterprise/sale_renting/models/product_pricelist.py", line 242, in _get_applicable_rules_domain
assert not kwargs.get("date"), "Incompatible arguments"
^^^^^^^^^^^^^^^^^^^^^^
AssertionError: Incompatible arguments
```
task-6020137This update resolves an issue where the custom declaration field wasn't automatically filled for international shipments using the World Express Pro service within the BPost module. Now, the necessary customs information is correctly populated, ensuring accurate shipping documentation and compliance with international regulations. This improves the reliability and efficiency of international order processing.
Original PR description
Before this commit, the bpost module was not filling the custom declaration in case of international shipping (World Express Pro) After this commit, the section is filled opw-4932970 Forward-Port-Of: odoo/enterprise#115368 Forward-Port-Of: odoo/enterprise#101476
This update fixes an issue where route planning for resources always started from the user's location. Now, routes begin from the resource's actual location when a location is available, ensuring more accurate and relevant route visualizations. This improves the planning process for field teams.
Original PR description
Currently, the routings per resource are always starting from the current user's location. With this commit: - If the view is not grouped by resource, no routing is shown - If the view is grouped by resource and the user is not located, no routing is shown for that resource - Else, the routing start from the located resource's geolocation task-6176479 Forward-Port-Of: odoo/enterprise#115674
This update resolves an issue where duplicate serial numbers appeared in the picking view after scanning a new barcode. The fix ensures the system waits for a necessary process to complete, correctly displaying only the intended serial number. This improves data accuracy and prevents confusion for users.
Original PR description
Problem: When entering the barcode interface from a picking and scanning a different serial number than one already reserved, a new line gets created in certain situations. When exiting the barcode…
Problem: When entering the barcode interface from a picking and scanning a different serial number than one already reserved, a new line gets created in certain situations. When exiting the barcode interface without validating the picking, both serial numbers show up on the picking view. However, the first serial number’s `stock.move.line` was deleted, so only one serial number should be there. When exiting the barcode interface a call to `post_barcode_process` is made, where the extra `stock.move.line` is deleted, but it doesn’t wait for the call to finish. https://github.com/odoo/enterprise/blob/d5a52cb79c9c41d792685d2858cfeb6aee147642/stock_barcode/static/src/models/barcode_picking_model.js#L1896 Purpose: By overriding `beforeQuit` to add the `_onExit` call, the component now waits for the `post_barcode_process` call to finish before navigating back to the picking view. This helps ensure the UI displays the updated data. Steps to reproduce on Runbot: Create a product tracked by serial numbers. Have 2 units on hand: serial 001 with a package, and serial 002 without a package. (This is needed so the barcode app will create a new line). Create a delivery for 1 unit of our test product and mark it as todo. Ensure that serial 001 is reserved. Click the Barcode smart button and scan the barcode for serial 002. Click the back button. Observe that both serial numbers are shown on the picking. Refresh the page and observe only serial 002 is now shown. opw-6105740 Forward-Port-Of: odoo/enterprise#116686 Forward-Port-Of: odoo/enterprise#115491
Original PR description
Several error are logged in the chatter when signing a payslip that includes an IMSS incapacity time off. Steps to reproduce: * Install l10n_mx_hr_payroll_account modules * Switch to "INNOVACION…
Several error are logged in the chatter when signing a payslip that includes an IMSS incapacity time off.
Steps to reproduce:
* Install l10n_mx_hr_payroll_account modules
* Switch to "INNOVACION VALOR Y DESARROLLO SA SA" company
* Go to Employees and open Cesar Osbaldo Cruz Solorzano
* Click on "Time Off" smart button and create a new time off with
"Disability due to illness (IMSS)" type for "02/01/2026"(Any date).
* Go to Payroll > Payslips > Payslips and create a new pay run
* Select Salary Structure 'Mexico: Regular Pay', Pay Schedule 'Monthly'
and the Period '01/01/2026 -> 01/31/2026'
* Click on Continue, select Cesar and click on Select
* Open the payslip, click on "Validate" and "Ok"
* Mark as paid, open the "Journal Entry" from the smart button and click
on "Post".
* Back to the payslip, and click on "Generate CFDI" button.
* An error is added to the chatter.
### Missing node to declare disabilities
Translated message
```py
An error occurred while signing the CFDI document with the government:
Code: NOM111 Message: Unclassified error. Extra Info: The "Incapacidades"
(Disabilities) node must be reported if the perception key 014
"Subsidios por Incapacidad" (Disability Subsidies) is included, or if
the deduction key 006 "Descuento por incapacidad" (Disability Deduction)
is included.
```
Legal Context:
According to Mexican law, IMSS disabilities must be declared in a specific XML node.
There are two primary scenarios for reporting these amounts:
* Deduction (Type 006): The employer does not pay for these days, as the IMSS is responsible for the payment to the employee. This is the most common scenario.
* Perception (Type 014): The employer pays for these days as a superior benefit. For example, by law, the IMSS does not pay for the first 3 days of a disability due to illness, and employers are not obligated to cover them either. However, companies offering superior benefits may choose to pay these days as a "Disability Subsidy."
Solution:
The chosen approach is to configure the Deduction node.
For the `l10n_mx_regular_pay_imss_disabilities` rule, the `l10n_mx_concept` has been set to `l10n_mx_concept_d6` (D06 - Disability Deduction). This ensures the required node is added.
### Missing "ImporteMonetario" attribute
Translated message
```
An error occurred while signing the CFDI document with the government:
Code: NOM95 Message: The attribute "Deduccion:Importe" does not match
the sum of the "Incapacidad:ImporteMonetario" nodes, as the key
expressed in "Nomina.Deducciones.Deduccion.TipoDeduccion" is "006".
```
Problem:
The "Incapacidades" node requires the "ImporteMonetario" attribute, which should represent the sum of the monetary value associated with the disabilities.
Solution:
Add the "ImporteMonetario" attribute and calculate its value using `l10n_mx_daily_salary`.
### Invalid "DiasIncapacidad" format
```py
An error occurred while signing the CFDI document with the government:
Code : 301 Message : XML mal formado Extra Info : Element
'{http://www.sat.gob.mx/nomina12}Incapacidad', attribute
'DiasIncapacidad': '4.0' is not a valid value of the local atomic type.
```
Problem:
Altough the defaultdict where the values are sum up, `number_of_days` is a float field, and when we get back the value, it is a float, adding for example 4.0 instead of 4, which is not a valid value.
Solution:
Cast the value to int.
### Duplicate deduction on disabilities
```py
Wrong python code defined for:
- Employee: Cesar Osbaldo Cruz Solorzano
- Version: False
- Payslip: Salary Slip - Cesar Osbaldo Cruz Solorzano - 05/01/2026 - 05/15/2026
- Salary rule: ISR (Income Tax) (ISR)
- Error: TypeError('cannot unpack non-iterable NoneType object') while
evaluating
"
def find_rates(x, rates):
for low, high, fix, rate in rates:
if low <= x <= high:
return low, high, fix, rate
gross = categories['GROSS']
result = 0
if gross:
isr_table = payslip._rule_parameter('l10n_mx_isr_tables')[version.schedule_pay]
low, high, fix, rate = find_rates(gross, isr_table)
result = -((gross - low) * rate + fix)
period_factor = payslip._rule_parameter('l10n_mx_schedule_table')[version.schedule_pay]
if period_factor >= 15:
period_factor = (period_factor / 30) * (365 / 12)
min_wage = payslip._rule_parameter('l10n_mx_daily_min_wage') * period_factor
if gross <= min_wage:
result_qty = 0.0
"
```
Problem:
The IMSS incapacity amount is being deducted twice:
1. During "Worked Days" calculation, the IMSS incapacity is already not considered because the work entries belong to the "Unpaid Work Entry Types" of "Mexico: Regular Pay" structure.
2. During "Salary Computation", the `IMSS_DISABLE` salary rule deducts another time because it is in the `TAXABLE_ALW` category, and this one is deducted in the `NET` rule.
When the incapacity covers more than half of the period (e.g., 20 days in a monthly schedule), the double deduction causes the NET to become negative. This prevents the ISR rule from finding a correct stage in the tax tables, leading to a traceback.
Example: For a monthly wage of 30,000.0 and 5 incapacity days:
- The total amount in "Worked Days" is 25,000.0 (incapacities already deducted).
- The IMSS_DISABLE rule calculates -5,000.0, and when the NET rule is calculated, the incapacities are deducted again. Total NET becomes 16,843.84 instead of the expected 20,834.85.
Solution:
Change the rule category to `INTERMEDIARY_COMPUTATION` and avoid the double deduction when the `NET` is calculated, as it is already considered in the "Worked Days".
### Absenteeism and Disabilities
By law, the calculation of IMSS contributions depends on these two types of unpaid days:
* Disabilities: Refers to medical leave issued by the Institute (IMSS).
* Absenteeism: Refers to unjustified leave; apply for periods of fewer than 8 days.
Source: [Artículo 31](https://www.imss.gob.mx/sites/all/statics/pdf/leyes/LSS.pdf)
Translated text:
> Article 31. When wages are not paid due to the employee's absence from work, but the employment relationship persists, the monthly contribution shall be adjusted according to the following rules:
> I. If the employee's absences are for periods of fewer than eight consecutive or non-consecutive days, contributions shall be calculated and paid for such periods only for the sickness and maternity insurance...
If the employee's absences are for periods of eight consecutive days or more, the employer shall be released from the payment of employer-employee contributions...
> IV. In the case of absences covered by medical disabilities issued by the Institute, it shall not be mandatory to cover the employer-employee contributions, except regarding the retirement branch.
The following table summarizes the contribution requirements based on the type of absence:
Insurance Branch | Section I (Absenteeism) | Section IV (Disability)
--------------------------------|-------------------------|------------------------
Sickness and Maternity | Paid | Not Paid
Disability and Life | Not Paid | Not Paid
Severance and Old Age | Not Paid | Not Paid
Work Risk | Not Paid | Not Paid
Daycare and Social Benefits | Not Paid | Not Paid
INFONAVIT | Not Paid | Paid
Retirement | Not Paid | Paid
The type of unpaid day to be considered depends on the specific insurance branch being calculated within the employer-employee contributions.
Incorrect values in the XML
The signing process completes without errors, but some amounts in the generated XML are incorrect.
Problem:
The introduction of the Deduction 006 (Disability) directly impacts the calculation of the SubTotal and Total attributes in the Comprobante node.
For a monthly payslip with a wage of 30,000.00 (daily salary of 1,000.00) and 5 disability days (work risk), the values are calculated incorrectly as follows:
Attribute | Calculation | Actual Value | Correct Value
---------------------|----------------------------------|--------------|--------------
Comprobante:SubTotal | Sum of Perceptions (P01) | 25000.00 | 30000.00 (1)
Comprobante:Total | SubTotal - Total Deductions (2) | 15803.74 | 20803.74
(1) Must include the 5,000.00 from disabilities to balance the deduction.
(2) Total Deductions = D06 (5,000.00) + ISR (3,451.65) + IMSS (744.61) = 9,196.26.
The Total is currently undercalculated because the 5,000.00 is being deducted from the SubTotal that already had those 5,000.00 excluded.
Solution:
Since the `SubTotal` is derived from Perceptions, and the "(P01) Salaries, Wages, Stripes, and Day Labor" amount is driven by the `GROSS_WITHOUT_HOLIDAY` rule, the disability amount must be added. This balances the Deduction 006, ensuring `SubTotal` is correct.
* Add test for CFDI with incapacities.
target: 19.0
task-6066160Original PR description
__ ## Short functional explanation of the error When we have a subscription product that has already been sold. If we try to import a product with the same ID but where we change the subscription…
__ ## Short functional explanation of the error When we have a subscription product that has already been sold. If we try to import a product with the same ID but where we change the subscription type of the product, the import is executed without issue. However, this leads to undesired behavior: when we go to the product page and try to manually change the subscription type (set it back to subscription), the change is not applied as a warning is raised. ## Reproduction Steps Make sure you have debug mode enabled. 1. Create a product, and check the Subscription box. 2. Click on Orders and create a Quotation with this product, then confirm. 3. Go to Products > Products. Select the list view and search for the product you just created. Select it, and click Actions > Export. 4. Check the import compatible field. Select the fields to export: name, id and recurring_invoice. Upon exporting, a file is downloaded. 5. Access that file and change the recurring_invoice to FAUX or FALSE if your computer is in English. Save the changes. 6. Unselect the product and click on the cog, top right > Import. Click on Upload Data File and select the file that you have downloaded upon exporting, then import. ### Expected behavior A user warning is raised: we shouldn't be able to change the subscription type of the product when it has already been sold. ### Unexpected behavior The import is processed normally. Then, when we access the product page, and try to check the Subscriptions box again, a warning is raised. ## Origin of the issue Nothing prevents the import from occurring in that case. __ opw-6143789
This update resolves an issue preventing the POS scale integration with the new 19.2 IoT Box. The IoT box now sends scale data differently, triggering an error. This fix ensures the scale functionality continues to work correctly for all users.
Original PR description
Steps to reproduce - Use a localisation other than a european one (l10n_eu_iot_scale_cert must not be installed) - Setup the scale for the POS - Open the POS - Add a product to be weighted by scale to the order - Sell one of the weighted product Error: value.toFixed is not a function Cause: New versions of the IoT box send response status via data.status instead of data.status.status. [opw-6121011](https://www.odoo.com/odoo/project/49/tasks/6121011)
This update resolves an issue where branch users were unable to create transactions in parent company journals with foreign currencies. The fix ensures branch users can accurately handle currency conversions, improving usability and preventing access errors. This change impacts the account module.
Original PR description
**Problem:** When a branch user with no access to the parent company tries to create a transaction for a parent company's journal with a foreign currency set, this will raise an access error. **Steps…
**Problem:** When a branch user with no access to the parent company tries to create a transaction for a parent company's journal with a foreign currency set, this will raise an access error. **Steps to Reproduce:** - Make a branch of "My Company (San Francisco)" - Set user "Marc Demo" to only have access to the branch - Add a new bank journal set to "EUR" currency - Switch to Marc Demo - Try to add a transaction in the new bank journal **Root Cause:** When a transaction is created, Odoo determines the amount in company currency by converting it from the foreign currency. The method to convert currency uses "with_company()" to use the company's rates, but the allowed companies of the branch user does not have access to the parent company, causing an access error. **Solution:** If the company is the parent company of the active company, get the currency `inverse_rate` from the active company instead. Since branches use the rate of the parent, this will return the same result but without an access error. Ticket [link](https://www.odoo.com/odoo/project.task/6186901) opw-6186901 Forward-Port-Of: odoo/odoo#263425
This update resolves an issue where branch users without parent company access would encounter errors when creating transactions in foreign currency journals. The fix ensures proper access rights are used during currency conversion, allowing branch users to manage transactions accurately. This improves usability and avoids disruptions for users operating within branch environments.
Original PR description
**Problem:** When a branch user with no access to the parent company tries to create a transaction for a parent company's journal with a foreign currency set, this will raise an access error. **Steps to Reproduce:** - Make a branch of "My Company (San Francisco)" - Set user "Marc Demo" to only have access to the branch - Add a new bank journal set to "EUR" currency - Switch to Marc Demo - Try to add a transaction in the new bank journal **Root Cause:** When a transaction is created, Odoo determines the amount in company currency by converting it from the foreign currency. The method to convert currency uses "with_company()" to use the company's rates, but the allowed companies of the branch user does not have access to the parent company, causing an access error. **Solution:** Call the currency conversion with sudo() to ensure access to the relevant companies. Ticket [link](https://www.odoo.com/odoo/project.task/6186901) opw-6186901
This update fixes an issue where the cost of service sale order lines wasn't being calculated correctly when adding new lines to existing orders. The change ensures that the product's cost is accurately reflected, regardless of whether timesheets are associated or the product has a standard price. This improves the accuracy of pricing for service-based sales.
Original PR description
Steps to reproduce: --------------------------------------- 1. Install the `sale_timesheet_margin` module 2. Create a product as follows: * Type: Service * Invoicing Policy: Prepaid/Fixed Price *…
Steps to reproduce:
---------------------------------------
1. Install the `sale_timesheet_margin` module
2. Create a product as follows:
* Type: Service
* Invoicing Policy: Prepaid/Fixed Price
* Create on order: Nothing
* Cost: Add some cost to the product (e.g., 30)
3. Create and Confirm Sale Order with Product (Add Cost field in SOL from the optional field)
4. Now add a new Sales Order Line (SOL) with the same product
Observation:
---------------------------------------
The cost of the recently created Sales Order Line (SOL) is 0.0, which is not correctly calculated based on the product's cost.
Issue:
---------------------------------------
The `_compute_purchase_price` method has a filter (`service_non_timesheet_sols`) that excludes certain sale order lines from the parent's purchase price computation. When a new sale order line is added to an already confirmed sale order (state='sale'), the new line inherits the parent SO's state immediately. That means, the new line matches the filter criteria and gets excluded from parent computation. The `purchase_price` is never calculated from the product's `standard_price`
Solution:
---------------------------------------
The added condition, like EITHER:
1. Has timesheets recorded (`sol.timesheet_ids` is truthy) → Preserve existing cost
2. OR product has NO standard price (`not sol.product_id.standard_price`) → Use timesheet-based costing
Code intentionally skips the computation of `service_non_timesheet_sols` lines to preserve existing values
opw-5351724This update corrects a bug in how backorder receipts are valued, ensuring consistent USD pricing regardless of exchange rate differences between the bill date and receipt date. The change updates the calculation method for `receipt_value` to accurately reflect the correct exchange rate at the time of receipt, resolving discrepancies in stock valuation.
Original PR description
Configuration: - Costing method: FIFO, automated valuation - Multi-currency: PO in a foreign currency (e.g. EUR), company currency USD - Two different exchange rates: one active at bill date, one at…
Configuration:
- Costing method: FIFO, automated valuation
- Multi-currency: PO in a foreign currency (e.g. EUR), company currency USD
- Two different exchange rates: one active at bill date, one at receipt date
- Bill posted before any goods are received
Steps to reproduce:
- Set EUR as a secondary currency with two different rates:
- Rate 1 on January 1st: 1 EUR = 1 USD
- Rate 2 on January 8th: 1 EUR = 2 USD
- Create a PO in EUR for 20 units @ 10,000 EUR
- Post the vendor bill dated January 3rd (rate 1 applies: 1 EUR = 1 USD)
- Receive 10 units on a date after January 8th and create a backorder
- Receive the remaining 10 units from the backorder on the same date
- Inspect the stock valuation layers and interim account journal entries for both receipts
Prior to this commit:
The two receipts, identical in quantity, date, and PO price, would produce different unit costs in USD. The backorder receipt would be incorrectly valued due to a wrong exchange rate being used when computing `receipt_value` in `_get_price_unit()`.
Receipt 2 (backorder):
SVL 1 value: $100,000 USD
Converted to EUR at receipt date (1 USD = 0.5 EUR):
receipt_value = $100,000 × 0.5 = 50,000 EUR (wrong rate)
total_invoiced_value = 200,000 EUR
remaining_value = 200,000 - 50,000 = 150,000 EUR
remaining_qty = 20 - 10 = 10
price_unit = 150,000 / 10 = 15,000 EUR
Converted to USD at bill date (1 EUR = 1 USD):
price_unit = $15,000 USD
SVL value = $15,000 × 10 = $150,000
This bug only affects backorder receipts. The first receipt always gets `receipt_value = 0` (no prior SVLs exist), so the problematic conversion never runs.
After this commit:
`receipt_value` is now computed using `_get_currency_convert_date()` instead of `layer.create_date`. This ensures `receipt_value` and `total_invoiced_value` are both expressed in EUR at the same reference rate.
Receipt 2 (backorder):
SVL 1 value: $100,000 USD
Converted to EUR at bill date (1 EUR = 1 USD):
receipt_value = $100,000 × 1.0 = 100,000 EUR (correct rate)
total_invoiced_value = 200,000 EUR
remaining_value = 200,000 - 100,000 = 100,000 EUR
remaining_qty = 20 - 10 = 10
price_unit = 100,000 / 10 = 10,000 EUR
Converted to USD at bill date (1 EUR = 1 USD):
price_unit = $10,000 USD
SVL value = $10,000 × 10 = $100,000
Both receipts now produce identical unit costs regardless of exchange rate differences between bill date and receipt date.
OPW: 5426718
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prThis update corrects a previous issue where product manufacturing quantities were incorrectly linked to planned production levels. Now, the system accurately reflects the actual quantity of products that have been produced, providing more reliable inventory data and reporting. This ensures better decision-making regarding stock levels and production planning.
Original PR description
* Before: the manufactured quantity on product use the planned quantity * After: Use actual produced quantity Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update resolves an issue where employees with capped leave accrual plans were sometimes blocked from requesting future time off. The fix adjusts how future leave accruals are calculated, ensuring employees can accurately see and request time off beyond their capped balance. This improves the user experience for employees managing their leave entitlements.
Original PR description
**Issue Summary:** Employees on capped accrual plans can sometimes be blocked from requesting time off in the future, even if they currently have enough available time. This happens when they've…
**Issue Summary:** Employees on capped accrual plans can sometimes be blocked from requesting time off in the future, even if they currently have enough available time. This happens when they've previously used more time off than the cap allows at one time. It's important to note that the cap sets the maximum balance an employee can hold at once, not a limit on the total amount they can accrue over time. For example, if the cap is 12 days, an employee can never hold more than 12 days at a time. However, as long as they continue using time off regularly, they can keep accruing more, theoretically without limit. To clarify what "future" means here: it refers to any date after the accrual plan's nextcall, which is the next scheduled update to the employee's balance. So even if they have time available now, they might not be able to request leave for dates beyond that point. Fix 1: See accruals even if the future leaves would be capped. - `_get_future_leaves_on` gives the difference between today's allocation and the allocation in the future after accruals. - However, if there's an accrual cap, and today's allocation is at the cap, Odoo can't see accruals in the future since no days would be accrued. - We want to see future accruals even if we're at the cap. - Solution: Calculate the future accruals as though it had no cap, then cap the gained leaves to the accrual cap. Fix 2: Base accruals on virtual leaves, not real leaves. - When leaves are virtual (not validated), `max_leaves` is too low because it's getting capped to 2, whereas with validated leaves it's 3 successfully. - This is the result of method `_process_accrual_plans` calling `_add_days_to_allocation` with the `leaves_taken` argument. It doesn't see non-validated leaves, but it should so that future leaves are correct. - Solution: Give `_add_days_to_allocation` virtual leaves instead of real leaves. Fix 3: Show correct max leaves for capped accruals in the Time Off Dashboard. - The `max_leaves` on leave types is computed based on the user's employee, and appears in the display name when creating new leaves in the dashboard. - `max_leaves` after Fix 1 will now report the full leaves amount, which in the Dashboard context is wrong since it will say "X out of [max_leaves]" but we need `max_leaves` to reflect the cap. - Solution: Add logic in `get_allocation_data` to cap `max_leaves` based on accrual cap. opw-4720344 Co-authored-by: Dirk Douglas <dido@odoo.com> Co-authored-by: Harrison Hutton <hahu@odoo.com>
This update corrects a bug where new job applications created with an email address would incorrectly duplicate the email as the applicant's name in the system. The fix ensures that the applicant's provided name is used when creating the partner record, improving data accuracy and usability within the recruitment process. This resolves an issue that impacted partner ordering in POS testing scenarios.
Original PR description
## Issue When creating a job application with a new email address, a `res.partner` is created with both its name and email set to the email address, even if a `partner_name` is provided. ## Steps to…
## Issue
When creating a job application with a new email address, a `res.partner` is created with both its name and email set to the email address, even if a `partner_name` is provided.
## Steps to reproduce
1. Install *Recruitment* (`hr_recruitment`) and *Contacts* (`contacts`)
2. In Recruitment, create a job application:
- Any Subject
- Name N
- Email E
3. Save the job application
4. Go to Contacts
5. **The partner created from the job application has both its name and email set to the Email E used to create the job application.**
## Cause
The `_inverse_partner_email` passes the email address to `find_or_create` to create the new res.partner:
https://github.com/odoo/odoo/blob/fc58ff23f491a2063b10ffcd6393a08b90dc7975/addons/hr_recruitment/models/hr_applicant.py#L317-L324
This method is implemented to parse both a name and an email address in the same string.
https://github.com/odoo/odoo/blob/fc58ff23f491a2063b10ffcd6393a08b90dc7975/odoo/addons/base/models/res_partner.py#L937-L945
We can thus provide both the `partner_name` and the `email_from` to the method to create a user with a name and an email address properly set.
## POS tests modifications
Before this first commit, some partners in `hr_recruitment` demo data were created with their email address as their name. This is the case, for example, for "Johan Duck", whose name was set to `coincoin@gmail.example.com`.
<img width="627" height="86" alt="260296" src="https://github.com/user-attachments/assets/e4bab843-8ba3-4930-af20-ca8603983929" />
In the POS tours, the list of loaded partners is limited to 100 partners and ordered by their order count (which is often null), __and their name__.
https://github.com/odoo/odoo/blob/e7345340efbd66473da70ccf6680181b158047ce/addons/point_of_sale/models/pos_config.py#L845-L865
By "renaming" the partners from `hr_recruitment`, they started appearing higher up in the list because their name now starts with capital letters whereas their email began with lower letters, which are sorted after capital letters by the `ORDER BY` SQL clause. As a result, partners from multiple tours were pushed out of the 100 first partners, meaning they were no longer loaded during the tours, causing the tests to fail.
One solution, which is already used in other tests, is to give the test partners names that make them appear higher in the partner list, ensuring they remain within the first 100 loaded partners.
opw-6111598