Daily updates from Odoo
Saturday, June 13, 2026
29 changes
1 change
Resolved issues and error corrections
This update resolves an issue preventing valid vendor bills from being created when using the GT company VAT affiliation. The system was incorrectly filtering document types, blocking legitimate purchase invoices. This change now allows all legally valid document types for purchase invoices, ensuring accurate recording of vendor transactions.
Original PR description
Currently, the system restricts fiscal document types for both sales and purchases based on the company’s VAT affiliation, which prevents valid vendor bills from being recorded. **Steps to…
Currently, the system restricts fiscal document types for both sales and purchases based on the company’s VAT affiliation, which prevents valid vendor bills from being recorded. **Steps to reproduce:** - Install the `l10n_gt_edi` module and switch to a `GT company`. - Navigate to Accounting > Vendors > Bills. - Create a vendor bill. - Try to select a document type such as `FPEQ` or `FCAP`. **Observation:** The system hides valid vendor document types (e.g., `FPEQ`, `FCAP`) if they do not match the company’s VAT affiliation. **Root Cause:** At [1], the method `_compute_l10n_gt_edi_available_doc_types` filters document types using the company’s VAT affiliation (`l10n_gt_edi_vat_affiliation`) for all move types. This logic is correct for sales (where the company is the issuer), but incorrect for purchases (where the vendor determines the document type). As a result, valid purchase document types are wrongly excluded. **Fix:** This commit updates the computation logic to: - Apply affiliation-based filtering only for sales (`out_*`). - Bypass the restriction for purchases (`in_*`), allowing all valid document types. This ensures that vendor bills can include any legally valid document type regardless of the company’s affiliation, while preserving the existing restrictions for sales workflows. [1]: https://github.com/odoo/enterprise/blob/7792926504a823590fbbe574a96994002a92fc17/l10n_gt_edi/models/account_move.py#L162-L166 opw-6099863 Forward-Port-Of: odoo/enterprise#120363 Forward-Port-Of: odoo/enterprise#113133
2 changes
Enhancements to existing features
This update now automatically logs the reasons why orders aren't synchronized with Lazada, eliminating the need for manual investigation. Previously, understanding synchronization issues required examining order details and interpreting code. This change provides clearer insights into order status, improving operational efficiency.
Original PR description
Before this commit, the only way to know why an order was not synchronized was to inspect the order details and infer the reason from the code. This commit now logs those reasons. Forward-Port-Of: odoo/enterprise#120212
Resolved issues and error corrections
This update fixes an issue where LATAM invoices weren't correctly displaying company-specific document layouts in the header. By adjusting how custom headers are handled, the invoice now accurately reflects the chosen layout, ensuring consistent branding for Argentinian and other LATAM businesses. This improves the professional appearance of invoices.
Original PR description
Problem: When printing an invoice for a Latin American (LATAM) company, the company's document layout is not used in the header of the invoice. For example, if an Argentinian company has set up a…
Problem: When printing an invoice for a Latin American (LATAM) company, the company's document layout is not used in the header of the invoice. For example, if an Argentinian company has set up a Bubble layout as its document layout, the header of the invoice will not have the bubble. Steps to reproduce: 1. Install l10n_ar 2. Create an invoice using Electronic Sales Journal 3. Set document layout to Bubble in the company settings 4. Print the invoice 5. Notice that the header of the invoice does not have the bubble Cause: Most LATAM localizations use custom headers for their reports. In report_templates of l10n_latam_invoice_document, it checks if custom_header is set to decide whether to display the custom header. If custom_header is set, the div with class "header" will be hidden, and the custom header will be displayed after the div with class "header". Since the div with class "header" contains the background image that corresponds to the document layout, the background image will not be displayed when div with class "header" is hidden. Solution: Instead of hiding the entire div with class "header" when custom_header is set, only hide the table inside the header. This way, the background image of the document layout will still be displayed even when a custom header is used. opw-6204062
6 changes
Resolved issues and error corrections
This update resolves an issue preventing the automatic creation of vendor partners when importing electronic invoices (like XRechnungen) that use email addresses as Peppol EAS endpoints. The fix allows for the '@' character in email addresses, correcting a validation error that was previously blocking import functionality. This ensures seamless import of invoices with standard email-based Peppol EAS configurations.
Original PR description
### Issue When importing an electronic bill (such as a German XRechnung) that uses the Peppol EAS 'EM' (Email) with an email address as the endpoint, the import fails during the automatic partner…
### Issue When importing an electronic bill (such as a German XRechnung) that uses the Peppol EAS 'EM' (Email) with an email address as the endpoint, the import fails during the automatic partner creation An error is logged in the chatter stating that the Peppol endpoint is not valid and should contain only letters and digits Since 'EM' stands for Email, the system should allow the '@' character and validate the endpoint format ### Cause While the export logic supported the 'EM' EAS, the validation flow triggered during automatic partner creation on import was too restrictive The global regex `PEPPOL_ENDPOINT_INVALIDCHARS_RE` did not include the '@' character, causing the validation to fail for any email address Additionally, there was no specific format check implemented for the 'EM' EAS type to ensure the endpoint is a valid email string ### Steps to reproduce - Install `account_edi_ubl_cii` - Go to Accounting / Vendors / Bills - Upload an electronic invoice containing an EM EAS and an email endpoint (you can use the added test file or the one from the ticket) Before the fix, an error is raised in the chatter and the partner cannot be created automatically opw-6205745
This update ensures Polish company invoices sent to KSeF (a Polish tax system) correctly include a required field ('PrefiksPodatnika') in the FA(3) XML format. This is necessary for legal compliance with Polish tax regulations for common EU transactions like intra-Community sales and triangular transactions, ensuring accurate reporting to the tax authorities.
Original PR description
Steps to reproduce 1. Configure a Polish company with KSeF enabled. 2. Create a customer invoice using a tax tagged with K_21 (0% EU G, intra-Community supply of goods), K_12 (0% EU S, services taxed…
Steps to reproduce 1. Configure a Polish company with KSeF enabled. 2. Create a customer invoice using a tax tagged with K_21 (0% EU G, intra-Community supply of goods), K_12 (0% EU S, services taxed in the buyer's EU country) or Triangular Sale. 3. Send the invoice to KSeF and download the generated FA(3) XML. Issue The Podmiot1 (seller) block in the rendered FA(3) XML omits the PrefiksPodatnika element, see https://github.com/odoo/odoo/blob/89219a843545d8bb0cad6ea806a1167cee6289da/addons/l10n_pl_edi/data/fa3_template.xml#L34-L42. According to the official Ministry of Finance documentation (https://ksef.podatki.gov.pl/media/4u1bmhx4/information-sheet-on-the-fa-3-logical-structure.pdf, page 11), this conditional field must carry the value "PL" when the invoice documents: - the intra-Community supply of goods, - the provision of services referred to in Article 100 sec. 1 item 1 of the Act for EU VAT taxpayers, - the supply carried out under a simplified triangular transaction by the second taxpayer (Article 135 sec. 1 item 4 (b) and (c)). The XSD marks the element as optional (minOccurs="0", fixed="PL") so KSeF accepts the XML, but the seller's tax reporting is still legally non-compliant for the three cases above, and the field is missing from the KSeF PDF viewer rendering. opw-6213178 Forward-Port-Of: odoo/odoo#264659
This update optimizes how Odoo retrieves related mailings for testing, addressing a performance bottleneck that caused crashes when processing large campaigns. The change significantly improves the speed and stability of mass mailing operations, particularly for campaigns with many mailings. This resolves a technical issue impacting campaign delivery.
Original PR description
**Description of the issue/feature this PR addresses:** The method _get_ab_testing_siblings_mailings currently scans all mailings in a campaign to apply a simple filter, which becomes expensive on databases with many large mailings. **Steps to reproduce bug:** 1) Run this script to get [enough sufficiently large mailings](https://gist.github.com/brcut-odoo/bb0d6d334bfe110afe16021d17d1b443) 2) Open one of the mailings and recieve a crash from the _get_ab_testing_siblings_mailings **Current behavior before PR** https://drive.google.com/file/d/19xftvzsGSQ9DxB67LNiLkKApzsD192ax/view?usp=drive_link **Current behavior after PR** https://drive.google.com/file/d/1apTJ0rWTKaATYa67ZmmN-7bKhrw4KuTx/view?usp=drive_link opw-6245908 Forward-Port-Of: odoo/odoo#268283
This update resolves an error that occurred when calculating payroll for employees with contracts exceeding 35 years. The fix adjusts a key parameter in the payroll rules to accommodate Mexican labor law, specifically allowing for additional holiday days based on seniority beyond the initial 35-year limit. This ensures accurate payroll calculations for all employees.
Original PR description
**Steps to reproduce:** 1. Install l10n_mx_hr_payroll. 2. Create an employee with a contract date over 35 years ago (e.g., 1985). 3. Create a payslip for this employee. 4. Click on "Compute Sheet".…
**Steps to reproduce:**
1. Install l10n_mx_hr_payroll.
2. Create an employee with a contract date over 35 years ago (e.g., 1985).
3. Create a payslip for this employee.
4. Click on "Compute Sheet".
```Error: KeyError(36) while evaluating```
**Cause:**
The rule parameter [rule_parameter_holiday_table](https://github.com/odoo/enterprise/blob/c02c4571bb7db7197b07539ba390d4d20fdce9fe/l10n_mx_hr_payroll/data/hr_rule_parameters_data.xml#L722-L758) defines values
only up to 35 years. Seniority exceeding this range causes a KeyError.
**Solution:**
Extended the `rule_parameter_holiday_2024` table from 35 to 60 years,
following the Mexican Federal Labor Law (LFT) reform formula
(+2 days every 5-year milestone from year 6 onwards).
**NOTE:**(Alternative approach)
```python
@staticmethod
def _get_mx_holiday_days(years_worked):
if years_worked <= 0:
return 0
if years_worked <= 5:
return 12 + (years_worked - 1) * 2
five_year_periods = (years_worked - 6) // 5
return 22 + five_year_periods * 2
```
This approach removes the need for XML data maintenance and handles
all future seniority values mathematically without any cap issues.
opw-6090590
Forward-Port-Of: odoo/enterprise#113536This update fixes a bug that prevented proper error messages from being displayed when IoT scale operations encountered problems. Previously, the system didn't correctly handle 'error' status updates, leading to a poor user experience. This ensures users receive clear notifications about scale issues, allowing for quicker resolution.
Original PR description
This completes odoo/enterprise#11196, which missed error message handling for new IoT Boxes errors. `message_body` was undefined on `data.status` when `data.status === "error"`. <img width="1871" height="942" alt="image" src="https://github.com/user-attachments/assets/30b54c5b-da0d-497d-8d9e-912f7139140b" /> Forward-Port-Of: odoo/enterprise#119425 Forward-Port-Of: odoo/enterprise#119228
This update resolves an issue where stock relocation incorrectly swapped the order of reservations for deliveries. After moving stock, reservations were reassigned in the wrong sequence, leading to incorrect quantities. The fix reverses the order of reassignment to ensure reservations are maintained in the original priority after stock relocation.
Original PR description
Version: ---------- - 18.0+ Steps to reproduce: ------------------- - Install `stock` module - Enable `Storage Locations` from Inventory settings - Create a tracked storable product with on-hand 8…
Version: ---------- - 18.0+ Steps to reproduce: ------------------- - Install `stock` module - Enable `Storage Locations` from Inventory settings - Create a tracked storable product with on-hand 8 units in `Shelf 1` - Create Delivery 1 for 5 units and click `Mark as To Do` - Create Delivery 2 for 5 units and click `Mark as To Do` - Verify reservations: - Delivery 1 reserves 5 units - Delivery 2 reserves remaining 3 units - Relocate all 8 units from `Shelf 1` to `Shelf 2` using the `Relocate` action from `stock quant` - Reopen both deliveries Issue: ------ After relocating stock between internal locations, reservations are reassigned in the wrong order: - Delivery 2 becomes fully reserved with 5 units - Delivery 1 is reduced to 3 reserved units This incorrectly swaps the original reservation priority between deliveries. Cause: ------ The relocation wizard starts from: `stock.quant.relocate.action_relocate_quants()` which calls `move_quants()`: https://github.com/odoo/odoo/blob/d3eebbd1c27e8a039bb55cdf2a82d464e06ffa8c/addons/stock/wizard/stock_quant_relocate.py#L70 `move_quants()` validates an internal stock move through `_action_done()`: https://github.com/odoo/odoo/blob/d3eebbd1c27e8a039bb55cdf2a82d464e06ffa8c/addons/stock/models/stock_quant.py#L1572 During validation, `_synchronize_quant()` moves the stock quantity from `Shelf 1` to `Shelf 2`. However, the already reserved delivery move lines still reference `Shelf 1`. This temporarily makes the source quant negative (`available_qty < 0`), triggering `_free_reservation()`: https://github.com/odoo/odoo/blob/d3eebbd1c27e8a039bb55cdf2a82d464e06ffa8c/addons/stock/models/stock_move_line.py#L695-L700 Inside `_free_reservation()`, move lines are ordered using `current_picking_first`: https://github.com/odoo/odoo/blob/d3eebbd1c27e8a039bb55cdf2a82d464e06ffa8c/addons/stock/models/stock_move_line.py#L816-L821 Since both deliveries share the same scheduled date, the fallback ordering uses `-cand.id`, causing Delivery 2 (higher id) to be processed before Delivery 1 (lower id). The reservation cleanup therefore happens in this order: - Remove Delivery 2 reservation (3 qty) - Remove Delivery 1 reservation (5 qty) The corresponding moves are then added to `move_to_reassign` in the same order: `[Delivery 2, Delivery 1]` https://github.com/odoo/odoo/blob/d3eebbd1c27e8a039bb55cdf2a82d464e06ffa8c/addons/stock/models/stock_move_line.py#L849 Later, `move_to_reassign._action_assign()` processes the moves in recordset order: - Delivery 2 reserves 5 units first - Delivery 1 only gets the remaining 3 units As a result, reservation priority is unintentionally reversed after relocation. Fix: ---- Before calling `_action_assign()`, reverse `move_to_reassign` This ensures reassignment preserves the original reservation order: - Delivery 1 is reassigned first and recovers 5 units - Delivery 2 receives the remaining 3 units The reservation state therefore remains consistent before and after internal stock relocation. --- opw-6218256 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#265169
20 changes
New functionality added to Odoo
This update adds a new field to Odoo invoices for Brazil, allowing users to specify the required 'cClassTrib' tax classification code. This is necessary to comply with Brazilian tax regulations when submitting electronic invoices (EDI) through Avalara, ensuring accurate tax reporting.
Original PR description
Purpose: In Brazil, the tax classification code, cClassTrib, is necessary to classify specific taxes during EDI requests. To support this requirement, a tax classification code field, c_class_trib, is added to the operation type's taxes settings, allowing users to define specific taxation classification per tax and override Avalara's default value when submitting NF-e invoices to the EDI. task-6206607
Enhancements to existing features
This pull request enhances the user experience for US-specific reports and tax forms. The l10n_us modules have been renamed for clarity and consistency, and key menu items related to 1099 reporting have been reorganized under the "United States" section. This simplifies navigation and improves the overall usability of the system for US-based businesses.
Original PR description
*1099, check_printing, payment_nacha, reports Improvements: - Renamed l10n_us related modules to be prefixed by "United States - " for consistency - move the 1099 Boxes and 1099 Report menu items to be under the parent menu section, United States - Set the Comparison Period to be Ascending for reports if the current company is US or Canada task-6182444
This update introduces a new rule for calculating superannuation contributions in Australia, aligning with Australian Taxation Office (ATO) requirements. Specifically, it now separates qualifying earnings (QE) from ordinary time earnings (OTE) and calculates superannuation streams per pay run, effective July 1st, 2026.
Original PR description
Added new salary rule for Qualifying earnings. Super Streams now per payrun. task-6012509 Forward-Port-Of: odoo/enterprise#117367
Resolved issues and error corrections
This update fixes an issue where purchase transactions were incorrectly identified as intra-state, leading to inaccurate reporting. The change separates sales and purchase transactions during computation, ensuring the correct transaction type is assigned for all transactions, including vendor bills. A migration script has also been added to update existing databases.
Original PR description
Previously, for purchase journals, `l10n_in_state_id` was always computed using the current company `state_id`. However, in `_compute_l10n_in_transaction_type`, the `l10n_in_state_id` was compared with the company `state_id` for both sales and purchases. As a result, all purchase transactions were always computed as intra-state, including inter-state vendor bills. This commit handles sales and purchase transactions separately while computing `l10n_in_transaction_type` to ensure the correct transaction type is assigned. Migration also added to update it in existing dbs. Forward-Port-Of: odoo/enterprise#118297
This update resolves an issue preventing Belgian employees on flexible work schedules from correctly requesting multi-day leave. The fix ensures that the system doesn't incorrectly subtract normal work intervals when processing leave requests for flexible employees, allowing for accurate leave calculations. This improves the functionality for a key segment of our Belgian users.
Original PR description
## Steps to reproduce: - Install l10n_be_hr_payroll module - Create a flexible working schedule and set the company to the Belgian company - Create an employee and assign the created schedule to him…
## Steps to reproduce: - Install l10n_be_hr_payroll module - Create a flexible working schedule and set the company to the Belgian company - Create an employee and assign the created schedule to him - Try to take a multi-day leave for this employee - Notice number of days is 0 - Try to validate the leave - An exception is raised 'The following employees are not supposed to work during that period' ## Cause: When fetching the work intervals for a belgian flexible employee we first fetch the normal work intervals then we call the same method but to filter the time credit attendance and since for the flexible employee there are not specific attendances we return the same normal work intervals and it will subtract those from the main work intervals which will result in an empty intervals to be returned ## Fix: Check if the working schedule is flexible and if so we don't check the time credit attendances at all. opw-6237642 Forward-Port-Of: odoo/enterprise#118870 Forward-Port-Of: odoo/enterprise#118528
This update resolves an issue where users could view financial budgets created in other companies within the Odoo Enterprise system. The fix adds a security rule to the budget model, ensuring that users only see budgets associated with companies they are actively connected to, improving data security and user experience.
Original PR description
**Steps to reproduce:** - Install the `account_reports` module. - Create a new company. - Navigate to Accounting > Configuration > Financial Budgets. - Create a new budget record. - Switch to another company. - Open the list view of Financial Budgets. **Observation:** The budget record created in another company is still visible. **Root Cause:** The model `account.report.budget` does not have any record rule restricting access based on company. As a result, users can see financial budgets belonging to other companies even if they are not connected to them. **Fix:** This commit allows users to hide financial budgets from companies they are not connected to by adding a record rule on `account.report.budget` opw-6083892 Forward-Port-Of: odoo/enterprise#120149 Forward-Port-Of: odoo/enterprise#114771
This update resolves a performance issue that caused significant lag when hovering over account reports with many columns. The change optimizes CSS styling to reduce unnecessary calculations, resulting in a smoother and faster user experience. This improves the responsiveness of a key business reporting tool.
Original PR description
Forward-Port-Of: odoo/enterprise#120038 Forward-Port-Of: odoo/enterprise#119242
This update ensures that Quality Checks and Mass Produce options remain accessible on the Shop Floor, regardless of whether production is automatically closed. Previously, disabling auto-close would hide these critical features, preventing users from completing quality checks and generating serial numbers. Now, these options are consistently available to ensure smooth production workflows.
Original PR description
### *Why this commit*: --- Ensures Quality Checks and Mass Produce options remain available on the Shop Floor regardless of the "Auto-close Production" setting. ### *Steps to Reproduce* --- 1. Define…
### *Why this commit*: --- Ensures Quality Checks and Mass Produce options remain available on the Shop Floor regardless of the "Auto-close Production" setting. ### *Steps to Reproduce* --- 1. Define a product tracked by Serial Numbers with a Manufacturing BoM. 2. Create a Quality Control Point for the product on the Manufacturing operation. 3. In Inventory Configuration, disable "Auto-close Production" on the Manufacturing operation type. 4. Create a Manufacturing Order (MO) and open it in the Shop Floor view. 5. If the MO has no operations, try to use Mass Produce. ### *Before this PR* --- When auto_close_production was set to False, the Shop Floor card footer incorrectly hid both the Quality Checks and Mass Produce buttons. This blocked users from registering Serial Numbers and completing mandatory quality check steps. Additionally, for products without BoM operations, clicking Mass Produce triggered quality check validation instead leading to errors, preventing the generation of serial numbers. ### *After this PR* --- The visibility logic for Shop Floor actions is now decoupled from the closing permission. The workflow follows this corrected sequence: Mass Produce: Stays visible to allow serial registration and backorder creation even if the MO cannot be closed from the Shop Floor. Quality Checks: Remain accessible to ensure all mandatory tests are passed before production progresses. Close Production: Only appears if "Auto-close Production" is enabled on the operation type. OPW: 5473839 Forward-Port-Of: odoo/enterprise#119875 Forward-Port-Of: odoo/enterprise#103926
This update corrects a problem in the POS system where test products were incorrectly converting prices due to missing company information. By setting the correct company ID for test products, the system now displays the accurate 5.10 PEN price, resolving a failure in the refund process. This ensures accurate pricing and functionality within the Odoo Enterprise system.
Original PR description
Description of the issue this commit addresses: The POS frontend converts prices using the product's currency_id. Test products created without a company_id had their currency_id fall back to the main company, causing the 5.10 PEN price to be converted unexpectedly and the l10n_pe_edi_pos refund tour to fail its orderline check. --- Desired behavior after this commit is merged: This commit sets the test product's company_id to the PE test company so its currency_id resolves to PEN. This prevents unintended currency conversion in the POS UI and restores the expected displayed price (5.10) in the refund tour. --- runbot-[242597](https://runbot.odoo.com/odoo/error/242597) Forward-Port-Of: odoo/enterprise#119834
This update fixes an issue where barcode scanning incorrectly displayed delivered quantities on sales orders. The fix ensures that quantities are accurately reflected when using lots and serial numbers, preventing backorders and ensuring accurate order fulfillment. This improves the reliability of the barcode inventory process.
Original PR description
Currently when user adds adds quantity in barcode using lots it leads to incorrect sale order quantities. ## Steps to replicate: - Install Sales and Barcode (no demo data). - Enable Lots & Serial…
Currently when user adds adds quantity in barcode using lots it leads to incorrect sale order quantities.
## Steps to replicate:
- Install Sales and Barcode (no demo data).
- Enable Lots & Serial Numbers in settings.
- Create Test Product with Tracking by Lots.
- Go to Inventory > Products>Lots & Serial Numbers and create 3 lots for the product.
- Update each lot’s on-hand quantity to 10 from the product page.
- Create and confirm a Sales Order for the product (lines: qty 3 and 2 units).
- Open the delivery in the Barcode app:
- Scan lot 2 > increase qty to 3 using +1 button
- Scan lot 3 > increase qty to 2 using +1 button
- Validate and go to the sale order.
## Observed Behavior:
The sale order delivered quantities are flipped and a backorder is created even though the quantity for the product is satisfied.
## Root cause:
The issue occurs because when a sales order is confirmed, the system defaults to
using lot 1 on the delivery receipt. When a user scans lot 2, the `_processBarcode` function is triggered, which calls `_findLine` at [1] to select the appropriate line on the receipt.
As the loop in `_findLine` iterates through `pageLines` with values like:
```
[{display_name: "Test product", quantity: 3, lot_id: { name: 'lot1' }},
{display_name: "Test product", quantity: 2, lot_id: { name: 'lot1' }}]
```
During the first iteration, `foundLine` is set at [2] for the line with quantity 3 . Since the subsequent if condition is not satisfied, the loop hits the continue block at [3].
On the next iteration, the line with quantity 2 causes `foundLine` to be overwritten at [2], and the continue block is executed again at [3].
This results in the line with quantity 2 being selected as the line to update at the end of the function.
When the user manually increases the quantity to 3, the line that originally required quantity 2 is updated and fulfilled.
Later, when lot 3 is scanned, the line that required quantity 3 is selected for update, and manually increasing the quantity to 2 before validating the order leads to a backorder and causes the delivered quantities to be flipped.
[1]:
https://github.com/odoo/enterprise/blob/81eaeb4b18d849c644160234def6c69013591abe/stock_barcode/static/src/models/barcode_model.js#L1335-L1337 [2]:
https://github.com/odoo/enterprise/blob/81eaeb4b18d849c644160234def6c69013591abe/stock_barcode/static/src/models/barcode_model.js#L1690-L1699 [3]:
https://github.com/odoo/enterprise/blob/81eaeb4b18d849c644160234def6c69013591abe/stock_barcode/static/src/models/barcode_model.js#L1727-L1729
## Solution:
Avoid grouping lines from different moves unless using batch transfers. This ensures that backorders are not created when the barcode lines are fulfilled.
opw-5423943
Forward-Port-Of: odoo/enterprise#120098
Forward-Port-Of: odoo/enterprise#109032This update resolves a technical issue that prevented the calculation of vacation days for employees with contracts exceeding 35 years. The original system had a limitation in its holiday table data, causing an error. The fix replaces the outdated table with a dynamic calculation based on Mexican labor law, ensuring accurate vacation day computation for all employees.
Original PR description
**Steps to reproduce:** 1. Install l10n_mx_hr_payroll. 2. Create an employee with a contract date over 35 years ago (e.g., 1985). 3. Create a payslip for this employee. 4. Click on "Compute Sheet". ```Error: KeyError(36) while evaluating``` **Cause:** The rule parameter [rule_parameter_holiday_table](https://github.com/odoo/enterprise/blob/c02c4571bb7db7197b07539ba390d4d20fdce9fe/l10n_mx_hr_payroll/data/hr_rule_parameters_data.xml#L722-L758) defines values only up to 35 years. Seniority exceeding this range causes a KeyError. **Solution:** Removed the rule parameter table and replaced with a `staticmethod` `_get_mx_holiday_days` on `HrPayslip` that computes vacation days dynamically using the Mexican Federal Labor Law (LFT) reform formula. opw-6090590 Forward-Port-Of: odoo/enterprise#113536
This update ensures that double holiday pay is accurately calculated when employees have a double holiday entitlement. Previously, the system wasn't properly prorating this pay based on legal leave rights, leading to potential inaccuracies. This fix corrects this calculation to ensure compliance and accurate payroll processing.
Original PR description
If you have a double holiday attest, we need to prorate the amount based on legal leave rights. The proration with regards to the previous work time rate wasn't done. Forward-Port-Of: odoo/enterprise#120403
This change prevents guest contact archiving during order validation from stopping picking confirmation emails. The original system silently removed guest contacts, disrupting the automated email notifications. This reversion restores the expected email flow for related pickings.
Original PR description
Archiving guest contacts upon SO validation breaks mail confirmations for related pickings. When a guest contact is archived, the ORM automatically filters it out from any search https://github.com/odoo/odoo/blob/e8a372b71dc91a3e3649e572380f59ee648c5bdc/odoo/orm/fields_relational.py#L673-L677 As a result, the partner is silently dropped from the `partner_ids` Many2Many on the mail composer even though we do write it https://github.com/odoo/odoo/blob/e8a372b71dc91a3e3649e572380f59ee648c5bdc/addons/mail/wizard/mail_compose_message.py#L538-L539 and the picking confirmation email is never sent. A potential fix would have been to disable this filtering at the ORM level but that would have impacted any flow that relies on archived partners being excluded. This reverts commit 5616a5bbf78c4a50b412a57609c5ff50b80b854d. opw-6232937 Forward-Port-Of: odoo/enterprise#120359 Forward-Port-Of: odoo/enterprise#119563
This update resolves an issue where extremely long invoice reference strings in the general ledger report were causing wkhtmltopdf to generate excessively large PDF files, leading to system errors. By limiting the length of the reference string, we prevent the report from becoming bloated and ensure reliable PDF generation.
Original PR description
The display name of the account.report.line in the general ledger report has the format of: INVOICE NAME (invoice refs) In the case where a client has hundreds of sales orders batched to a single…
The display name of the account.report.line in the general ledger report has the format of: INVOICE NAME (invoice refs) In the case where a client has hundreds of sales orders batched to a single invoice, the ref can become extremely long, e.g.: INV/2026/00001 (S12123, S12152, S12159, S12140, S12165, S12161, S12162, S12110, S12099, S12124, S12145, S12128, S12114, S12131, S12097, S12185, S12154, S12133, S12190, S12118, S12116, S12102, S12155, S12153, S12158, S12150, S12100, S12142, S12121, S12122, S12111, S12187, S12172, S12177, S12095, S12117, S12144, S12137, S12092, S12138, S12186, S12182, S12112, S12148, S12183, S12101, S12178, S12119, S12169, S12115, S12146, S12093, S12126, S12160, S12163, S12129, S12098, S12151, S12096, S12174, S12120, S12130, S12147, S12180, S12191, S12164, S12141, S12105, S12136, S12139, S12109, S12106, S12104, S12103, S12175, S12179, S12188, S12113, S12173, S12167, S12171, S12134, S12094, S12184, S12166, S12170, S12125, S12135, S12143, S12176, S12189, S12156, S12181, S12107, S12157, S12132, S12149, S12127, S12108, S12168...) Because the length of the account.report.line is unchecked in account_general_ledger.py label builder, the pdf can clog to one or two account.report.lines per page, skyrocketing the pdf page length. As wkhtmltopdf processes the report from html to pdf it makes a system call openat() to the /tmp/report.footer.tmp.x.html file for EACH page of the pdf. You can see the TODO comment in the spoolTo function in wkhtmltopdf (both in Odoo and the original repo) saying that the header and footer need to be freed, on each page processing, not just null pointed. https://github.com/odoo/wkhtmltopdf/blob/2c884bd1545b8a639847de22f24754ee5a6fc44c/src/lib/pdfconverter.cc#L794 I verified that that the number of openat calls to the /tmp/report.footer.tmp.x.html file equals the exact number of pages in the pdf to be generated if the report HAD generated successfully by setting the footer input into _run_wkhtmltopdf to None, generating the report without footers, then separately running an strace on wkhtmltopdf when the report fails to generate. See related ticket linked at bottom. The linux machine used on sh instances has a ulimit -n of 1024 file descriptors. Because the footer file descriptors accumulate, once a pdf has about 1010+ pages (~a dozen fd's are allocated for other purposes), over 1024 file descriptors are opened and the system fails with: Wkhtmltopdf failed (error code: -6). Message: QEventDispatcherUNIXPrivate(): Unable to create thread pipe: Too many open files QEventDispatcherUNIXPrivate(): Can not continue without a thread pipe Since wkhtmltopdf is archived and Odoo has a replacement in development, I suggest that we limit the display_name of the account.report.line to 200 to keep the bloat minimized, preventing one account.report.line's name from taking up an entire page of the general ledger pdf. This allows many more batched invoices to be shown in the report and a much greater time range of data to be printed without hitting the fd limit. I suggest changing it at the general ledger report level rather than in the account.move.line _compute_display_name function, as we probably still want to see the full display_names at the invoice level. On runbot, the machine has different memory constraints than on sh / local, so it hits the following error before the one above: Wkhtmltopdf failed (error code: -11). Memory limit too low or maximum file number of subprocess reached. Message : Steps to Reproduce on 19.0 newdb: 1. newdb -n test_gl -v 19.0 2. ensure ulimit is set to 1024 in shell that runs odoo instance by running ulimit -n 1024 to mimic ulimit of sh environment 3. run db with python3 odoo-bin, ensuring high enough memory constraints to simulate multi worker sh instance, i.e. --limit-memory-soft=12884901888 --limit-memory-hard=1288490188 4. install sales, accounting, stock 5. install demo data 6. create invoices with 100+ associated sales orders 7. generate the pdf 8. Increase the amount of invoices till the general ledger page count hits ~1010+, where you will hit the error. Notes: opw-ticket-6201508 closes #118067 Forward-Port-Of: odoo/enterprise#120137 Forward-Port-Of: odoo/enterprise#118067
This update resolves an issue where canceling a Global Invoice on a Mexican POS order prevented the creation of a new Global Invoice for the same order after a partial refund. The fix ensures that the refund process correctly updates CFDI documents, allowing for seamless invoice management following a refund.
Original PR description
Steps to reproduce 1. With a Mexican POS configured, create a POS order and sign a Global Invoice for it. 2. Open a new session and partially return the order; close the session. 3. On the original…
Steps to reproduce 1. With a Mexican POS configured, create a POS order and sign a Global Invoice for it. 2. Open a new session and partially return the order; close the session. 3. On the original order, cancel the Global Invoice through the CFDI page. 4. Try to create a new Global Invoice for the original order. Issue The wizard raises "Orders <REFUND-NAME> are already sent or not eligible for CFDI." Validating the refund auto-signs an `invoice_sent` CFDI on the refund pos.order because its parent is `global_sent`, see `_l10n_mx_edi_check_autogenerate_cfdi_refund` at https://github.com/odoo/enterprise/blob/5af8048f0b0956a024d7eaeb10600eec74bdf3ee/l10n_mx_edi_pos/models/pos_order.py#L98. Cancelling the GI only flips its own document to `ginvoice_cancel`; the refund's `invoice_sent` doc stays untouched, so the refund's computed `l10n_mx_edi_cfdi_state` stays `'sent'`. The chain check in `_l10n_mx_edi_check_orders_for_global_invoice` at https://github.com/odoo/enterprise/blob/5af8048f0b0956a024d7eaeb10600eec74bdf3ee/l10n_mx_edi_pos/models/pos_order.py#L184 then rejects the refund as already sent and the new GI cannot be created. opw-6181136 Forward-Port-Of: odoo/enterprise#120349 Forward-Port-Of: odoo/enterprise#117211
This update resolves a crash issue that occurred during pivot table autofill operations, specifically with formulas like `=PIVOT(1)`. The fix ensures simple `=PIVOT(...)` formulas remain consistent, preventing unexpected crashes and improving the overall stability of the spreadsheet edition.
Original PR description
Current behavior before PR: - Autofill on formulas like `=PIVOT(1)` could crash after the refactor in e34c0a3, the new logic tried to process all pivot formulas. - However, simple `=PIVOT(...)` cases do not require any change in formula during autofill. Desired behavior after PR is merged: - Add an early return for pivot formulas that are not `PIVOT.VALUE` or `PIVOT.HEADER`, avoiding unnecessary processing. - Ensure `=PIVOT(...)` formulas remain unchanged during autofill, preventing crashes and keeping behavior consistent. Task: [6158888](https://www.odoo.com/odoo/project/2328/tasks/6158888) Forward-Port-Of: odoo/enterprise#119390
This update fixes an error in how Odoo validates invoice dates for Colombian DIAN reports. Previously, the system incorrectly interpreted dates due to timezone differences, causing validation failures. Now, the system uses Bogota local time for accurate date comparisons, ensuring correct DIAN report generation.
Original PR description
**Steps to reproduce:** * Install `l10n_co_edi` module with DEMO DIAN mode enabled. * Go to Accounting > Vendor > Bills and create a new bill. * Select any Colombian partner different from…
**Steps to reproduce:** * Install `l10n_co_edi` module with DEMO DIAN mode enabled. * Go to Accounting > Vendor > Bills and create a new bill. * Select any Colombian partner different from `Consumidor Final`. * Set the invoice date to 6 days in the past. * Select the DIAN Support Documents journal and a product with UNSPSC category. * Confirm the bill and click `Send Support Document to DIAN` after 5 PM Colombia time. **Observed behavior:** * An error is raised stating the issue date cannot be older than 6 days or more than 6 days in the future, even though the invoice date is within the allowed window in Colombia local time. **Cause:** * The date window validation in `_check_move_configuration` used `fields.Datetime.now()` which returns UTC time. Since Colombia is UTC-5, after 5 PM local time the UTC clock has already rolled over to the next calendar day, making a 6-day-old invoice appear 7 days old and failing the validation incorrectly. **Fix:** * Convert the current UTC datetime to the `America/Bogota` timezone and extract its local date before computing the allowed date window. * Compare directly against `move.invoice_date` (a `date` field) instead of using `fields.Datetime.to_datetime()`, keeping the comparison consistent as `date` vs `date`. opw-6011502 Forward-Port-Of: odoo/enterprise#120384 Forward-Port-Of: odoo/enterprise#115256
This update resolves an issue preventing valid vendor bills from being created in the GT accounting system. The system was incorrectly restricting document types based on company affiliation. This change now allows all legally valid document types to be used for purchase bills, ensuring accurate record-keeping.
Original PR description
Currently, the system restricts fiscal document types for both sales and purchases based on the company’s VAT affiliation, which prevents valid vendor bills from being recorded. **Steps to…
Currently, the system restricts fiscal document types for both sales and purchases based on the company’s VAT affiliation, which prevents valid vendor bills from being recorded. **Steps to reproduce:** - Install the `l10n_gt_edi` module and switch to a `GT company`. - Navigate to Accounting > Vendors > Bills. - Create a vendor bill. - Try to select a document type such as `FPEQ` or `FCAP`. **Observation:** The system hides valid vendor document types (e.g., `FPEQ`, `FCAP`) if they do not match the company’s VAT affiliation. **Root Cause:** At [1], the method `_compute_l10n_gt_edi_available_doc_types` filters document types using the company’s VAT affiliation (`l10n_gt_edi_vat_affiliation`) for all move types. This logic is correct for sales (where the company is the issuer), but incorrect for purchases (where the vendor determines the document type). As a result, valid purchase document types are wrongly excluded. **Fix:** This commit updates the computation logic to: - Apply affiliation-based filtering only for sales (`out_*`). - Bypass the restriction for purchases (`in_*`), allowing all valid document types. This ensures that vendor bills can include any legally valid document type regardless of the company’s affiliation, while preserving the existing restrictions for sales workflows. [1]: https://github.com/odoo/enterprise/blob/7792926504a823590fbbe574a96994002a92fc17/l10n_gt_edi/models/account_move.py#L162-L166 opw-6099863 Forward-Port-Of: odoo/enterprise#120413 Forward-Port-Of: odoo/enterprise#113133
This update resolves an issue where the timesheet assistant wouldn't function correctly when rules were created without a specified template. The fix ensures that all timesheet rules require a template, guaranteeing accurate display name generation and overall timesheet assistant operation. This improves the reliability of the timesheet feature.
Original PR description
## [FIX] timesheet_grid: make template field required in AW rule Before this commit, the template field in AW rule was not required and if one rule without any template is set, timesheet assistant will not be able to work correctly to build the display name for the key events found. This commit makes sure the template field is required. ## [FIX] timesheet_grid: ignore rules without template defined Before this commit, when the user creates a rule without any template set, the timesheet assistant will no longer work because it assumes the template is required. This commit adds a condition in the domain when we fetch all AW rules, to ignore the ones without template set. Forward-Port-Of: odoo/enterprise#119744 Forward-Port-Of: odoo/enterprise#119411
This update fixes an issue where both units of a quality check were incorrectly moved to the failure location after a partial QC failure. The fix ensures that only the quantity of goods actually failing is moved, preventing the other unit from being misdirected. This ensures accurate inventory tracking and prevents potential stock discrepancies.
Original PR description
Version: ---------- - 18.0+ Steps to reproduce: ------------------- 1. Install *quality_control* module. 2. Go to *Settings* and enable *Storage Locations*. 3. Open Quality module go to the Quality…
Version:
----------
- 18.0+
Steps to reproduce:
-------------------
1. Install *quality_control* module.
2. Go to *Settings* and enable *Storage Locations*.
3. Open Quality module go to the Quality control -> Quality points
4. Create a *Quality Point* with:
* *Product* set.
* *Control per* set to *Quantity*.
* *Operation* set to *Receipts*.
* *Failure Location* set to *WH/Stock/Shelf1*.
5. Create a *Receipt* with demand of *2 units* for the product used in QP.
6. Mark the quality check as *To Do*.
7. Update the *Done Quantity* to *1*.
8. Open the quality check and click *Fail*.
9. Update the *Done Quantity* back to *2* and save.
10. Open the quality check again, click *Pass*, and validate the receipt.
11. Open the *Detailed Operations* to inspect move lines.
Issue:
------
* Both units (failed and passed) are moved to the *failure location*.
Cause:
------
When a user fails a move line via the QC wizard, the flow is:
do_fail() → show_failure_message() → confirm_fail()
→ check._move_to_failure_location(failure_location_id, failed_qty)
Inside `_move_to_failure_location`, when `failed_qty == move_line.quantity`,
the condition:
https://github.com/odoo/enterprise/blob/a33f580455a54a81d89a848f7b493d9dcc9ba2b2/quality_control/models/quality.py#L458
e.g. 1 == 1
was True even when `move.product_uom_qty = 2` (demand still 2). It only
compared the done quantities, ignoring that unfulfilled demand remained.
As a result, `move.location_dest_id` was set to the failure location.
Later, when the user increases the quantity from 1 to 2 on the move form,
the flow is:
_set_quantity → process_increase → _set_quantity_done → _prepare_move_line_vals
In `_prepare_move_line_vals` :
'location_dest_id': self.location_dest_id.id,
https://github.com/odoo/odoo/blob/47bf284e1e9d8be0d4255418e0a3f67c74fa5114/addons/stock/models/stock_move.py#L1688
The new move line inherits `move.location_dest_id` directly, which at this
point is already the failure location.
When the user then calls `do_pass()` on the second unit, `do_pass()` only
writes `quality_state = 'pass'` and never touches `location_dest_id`. So
the second (passed) move line silently retains the failure location.
Solution:
---------
Add the guard `move.product_uom_qty <= move_line.quantity` to the condition
so the entire move's destination is only redirected when there is genuinely
no remaining unfulfilled demand:
When demand > done qty, the else-branch runs instead: it reduces the
original move's demand and creates a new separate move pointing to the
failure location, leaving the original move's `location_dest_id` pointing
to stock. Any subsequent move lines created on the original move therefore
correctly inherit the stock destination.
---
opw-6080871
Forward-Port-Of: odoo/enterprise#120394
Forward-Port-Of: odoo/enterprise#112859