Daily updates from Odoo
Navigate
Branch
Wednesday, April 1, 2026
354 changes
17 changes
Enhancements to existing features
The sickness relapse checkbox in Belgian payroll processing now defaults to unchecked instead of checked. This change reflects the updated 56-day sickness period policy, where relapse situations are less common and the system now assumes "no relapse" by default, reducing manual corrections needed by HR staff.
Original PR description
Because the sickness period is now 56 days, the heuristic has switched to "mostly always a no," so the relapse checkbox is unchecked by default. Task: 6081595
The payroll system now hides worked day details from the payslip summary widget when they're not needed for certain pay structures, such as bonus-only payments. This change reduces clutter and confusion for pay officers by dynamically showing only relevant information based on the pay structure type.
Original PR description
In order to improve the experience of pay officers and prevent any confusion, some pay structures will not require the display of individual work day lines such as bonuses. Accordingly, the worked day widgets will be dynamic. Task: 6030842
Resolved issues and error corrections
Fixed a bug that caused the AI email composer feature to crash when users selected multiple records before composing an email. The issue occurred because the system couldn't properly handle multiple record IDs. Now the AI feature only activates when a single record is selected, preventing the error and improving the user experience.
Original PR description
Currently an exception is generated when the user tries to click the AI icon in the email composer with multiple records. Steps to produce an error: - Install the `crm` module with the demo data - Go…
Currently an exception is generated when the user tries to click the AI icon in the email composer with multiple records. Steps to produce an error: - Install the `crm` module with the demo data - Go to the CRM list view and select multiple records - Click in `Email` from action > click the `AI` icon on the email composer. Error: `TypeError: int() argument must be a string, a bytes-like object or a real ...` This error is generated because when retrieving the `originalRecordId` from the line [1], the code attempts to remove the first and last characters of a string representation of a list. In the single-selection case, the value is "[4]", so slicing off `[` and `]` correctly yields "4". However, when the user selects multiple records, the value becomes "[4, 5]". Slicing the first and last characters in this case produces "4, 5", and passing this string to Number() results in NaN. As a result, `record_id` becomes `None` when calling `create_ai_draft_channel` method, and passing this None value to int() subsequently raises an error. This commit fixes the issue by assigning `recordId` and `recordModel` only when a single record exists. The record IDs are parsed from their string representation using `JSON.parse`, and the first ID is returned when the list contains exactly one element, or false otherwise. sentry-7201070069 Forward-Port-Of: odoo/enterprise#104873
This fix allows users to preview sales orders for upsells that don't contain recurring products. Previously, the system prevented previewing such orders, which limited flexibility when creating upsells with non-recurring items. The change enables this preview capability while maintaining all existing validation rules.
Original PR description
When you have an upsell that does not have recurring products, you cannot preview the SO, so we've allow it in this specific case as it is allowed by the constraint on the model Forward-Port-Of: odoo/enterprise#112453
This fix resolves an issue where the IP (Individual Pension) salary rule was not appearing on employee payslips in the Belgian payroll system. The underlying calculation has been corrected to properly include the IP field, ensuring employees can now see this important compensation component on their payslip documents.
Original PR description
-**Issue**: The IP salary rule was not visible on payslip. -**Fix**: Computation has been adjusted to include the correct field. Forward-Port-Of: odoo/enterprise#110936
This update reverts a previous change to the HR Contract Salary module that affected email functionality. The revert addresses issues introduced in an earlier update and restores the system to a more stable state for salary configuration and applicant management.
Original PR description
Revert https://github.com/odoo/enterprise/pull/111815 Forward-Port-Of: odoo/enterprise#112632
Demo Stripe accounts were not automatically becoming verified when users clicked Connect, remaining in a restricted state. This fix addresses a verification document requirement that was blocking the demo flow. Users can now properly test the Stripe expense feature without manual workarounds.
Original PR description
Step to reproduce: - Click on Connect (demo) - The accounts stay Restricted (even after 5m) This is due to the requirement `company.verification.document` which is present as a pending_verification even when no document is given. Giving it a document such as `file_identity_document_success` which should "marks that document requirement as satisfied" also doesn't work. A work-around is to set the business type to individual since they dont have this requirement. This is a temporary fix, as we want to keep a flow similar to what would have been done in reality. But this is preventing users from testing the feature in 19.0 up to master. Forward-Port-Of: odoo/enterprise#112612
This fix corrects how payment installments are ordered in Peru's electronic invoicing (EDI) documents. Previously, when invoices had multiple payment installments with different due dates, they could appear in the wrong order in the XML file if they weren't created in chronological sequence. Now installments are automatically sorted by their due date, ensuring the correct payment schedule is always reflected in the electronic invoice.
Original PR description
**Steps to reproduce:** * Install `l10n_pe_edi`. * Set SUNAT as the signature provider. * Create a customer invoice. * Select a payment term with multiple installments (e.g. 50% (15 days) / 30% (10…
**Steps to reproduce:**
* Install `l10n_pe_edi`.
* Set SUNAT as the signature provider.
* Create a customer invoice.
* Select a payment term with multiple installments (e.g. 50% (15 days) / 30% (10 days) / 20% (5 days)).
* Confirm the invoice and generate the EDI standard UBL document.
**Observed behavior:**
* The XML `<cac:PaymentTerms>` instalment nodes (Cuota001, Cuota002, etc.) are ordered according to the database insertion order of the receivable lines.
* If the payment term lines are created in a non-chronological order, the installments in the XML mix up the `Cuota` ID, amount, and `PaymentDueDate`.
**Cause:**
* `_add_invoice_payment_terms_nodes` iterates over `invoice.line_ids` to generate the installments, but does not sort the receivable account lines by their `date_maturity`.
**Fix:**
* Explicitly call `.sorted('date_maturity')` on the receivable lines before generating the `invoice_date_due_vals_list`.
opw-6035589
Forward-Port-Of: odoo/enterprise#112162This fix resolves crashes that occurred when printing vendor bills with Colombian DIAN support documents, either when duplicating bills or before sending them to DIAN. The system now properly handles cases where DIAN document information hasn't been created yet, displaying a placeholder message instead of failing.
Original PR description
**Steps to reproduce:** * Install the **l10n_co_dian** module. * Enable DIAN 2.1 operation mode: **Support Documents** in settings. * Create a vendor bill using a **DIAN support document** journal. * Confirm the vendor bill. * Click **Print**. **Observed behavior:** * Printing fails with `ValueError: can only parse strings`. **Cause:** * The report template unconditionally called `_l10n_co_dian_get_extra_invoice_report_values()`, which parses `l10n_co_dian_attachment_id.raw` via `etree.fromstring()`. * On duplicated bills, `l10n_co_dian_document_ids` (and thus the computed `l10n_co_dian_attachment_id`) is empty, so `.raw` is `False`. **Fix:** * Wrap the QR code / CUFE / signing section in the report template with `t-if='o.l10n_co_dian_attachment_id'` so it is only rendered when the DIAN attachment exists. opw-5930173 Forward-Port-Of: odoo/enterprise#109912 Forward-Port-Of: odoo/enterprise#108645
A bug was fixed where products were being incorrectly deleted when a product template had only one product variant. This ensures that products are properly retained during website generation, preventing accidental data loss.
Original PR description
product.product records were being removed when they should not have been in the case that the product.template only has one product.product record. This commit fixes this issue by accounting for the case where there is only one product.product record. Forward-Port-Of: odoo/enterprise#112519
This fix resolves a system error that occurred when creating employee contracts with work schedules that have zero working hours. Previously, the system would crash when trying to calculate hourly wages in this scenario. The fix prevents this error, allowing users to create contracts even with empty work schedules.
Original PR description
When a working schedule has 0 working hours, creating a contract raises a traceback during hourly wage computation. Steps to reproduce the error: - Install ``l10n_au_hr_payroll`` module - Switch to ``My Australian Company`` - Create a working schedule without any working hours - Create an employee and assign this working schedule > Save - Click on Contracts smart button Traceback: ```py ZeroDivisionError: float division by zero ``` https://github.com/odoo/enterprise/blob/bd746aa43f549c4f7813a849e00447b55e084f21/l10n_au_hr_payroll/models/hr_contract.py#L113-L115 The hourly wage is computed using the working schedule’s hours per day. When this value is 0, it results in the above traceback. sentry-7355577930 Forward-Port-Of: odoo/enterprise#112450 Forward-Port-Of: odoo/enterprise#111629
This fix resolves an issue where AI-powered conversations with agents were broken in the AI app. The update corrects how the system identifies conversation participants, preventing the app from incorrectly treating conversations as self-chats, which was causing unwanted side effects like out-of-office banners appearing. Agent workflows that depend on proper participant identification now work correctly.
Original PR description
Override AI thread correspondent computation to keep the base behavior but clear the correspondent when it resolves to the current user in ai_composer/ai_chat. This avoids self-chat fallback side effects (like OOO banner) while preserving agent flows that rely on a real non-self correspondent. source of this crash: https://github.com/odoo/enterprise/pull/108217 Forward-Port-Of: odoo/enterprise#112392 Forward-Port-Of: odoo/enterprise#111736
This fix corrects how shifts are split when using the daily view in the planning schedule. Previously, splitting a shift within a single day would incorrectly snap the resulting shifts to standard working hours (8am-5pm), creating duplicate time entries outside the original shift. Now, shifts split within a day are properly divided at the exact requested time without adding extra hours.
Original PR description
Since odoo/enterprise#69963, splitting a shift in Gantt view snaps the resulting shifts to the standard working hours (e.g., 08:00 to 17:00). This behavior makes sense when splitting a multi-day shift across a day off, where we want to generate a full working day for the day off as well. However, when splitting a shift within a single day (day scale), this behavior is not wanted, otherwise creating two shifts as follows: 1. A shift from [Original Start] to 5pm 2. A shift from 8am to [Original End] Clearly, the shift is duplicated with the wrong timeframes and adding time outside the original shift's hours. This commits ensures that, when splitting a shift in hours (i.e., when using `day` view scale), the shift is appropriately split at the time requested. For instance: 1. A shift from [Original Start] to [Split Time] 2. A shift from [Split Time] to [Original End] task-5387243 Forward-Port-Of: odoo/enterprise#105991
This fix resolves an issue in Web Studio where invisible field attributes were being lost when users added group restrictions to fields. Previously, when a field was restricted to certain user groups, the original invisible condition would disappear from the editor, even though it was still applied to the actual view. Now the system properly preserves these invisible attributes so users can see and edit them correctly.
Original PR description
Steps to reproduce ================== - Install contacts,web_studio - Login as admin - Go to contacts - Open any record - Open studio - Click on any field - Add the "Role / Portal" group - Toggle the…
Steps to reproduce ================== - Install contacts,web_studio - Login as admin - Go to contacts - Open any record - Open studio - Click on any field - Add the "Role / Portal" group - Toggle the "Show invisible Elements" checkbox - Click on the same field => The field is marked as invisible - Add an invisible condition => The invisible condition is lost (but still applied on the view) Cause of the issue ================== In studio, when fetching the view, the invisible attribute is set to True when the user does not have access to the field (when he is not part of the groups). The goal is to make the field invisible in studio unless the "Show invisible Elements" is toggled. But this causes the actual value of the invisible attribute to be lost. Note that this also applies to the column_invisible attribute. Solution ======== If an invisible/column_invisible attribute is present on the nodes with missing access, we copy the actual value to the `actual_invisible` attribute. We then use that value in the editor, when present. opw-6026971 Forward-Port-Of: odoo/enterprise#112084 Forward-Port-Of: odoo/enterprise#111299
This fix prevents the system from crashing during upgrades when predefined document folders (like Legal) have been deleted. The system now properly handles inactive folders instead of throwing an error, ensuring smooth upgrades to version 19.2 for users who have the Documents Sign module installed.
Original PR description
While embedding sign into predefined folders we need to consider if they are active or not. Otherwise during…
While embedding sign into predefined folders we need to consider if they are active or not. Otherwise during [upgrade](https://github.com/odoo/upgrade/blob/master/migrations/documents_sign/saas%7E19.2.1.0/post-migrate.py) to `saas~19.2` with module `documents_sign` installed, it will try to get document actions of predefined folder [here](https://github.com/odoo/enterprise/blob/6d334a17d10faec33d60f4a8d7d263c091bb456e/documents/models/documents_document.py#L1592), so if the folder is inactive it will not be able to read the folder [here](https://github.com/odoo/enterprise/blob/6d334a17d10faec33d60f4a8d7d263c091bb456e/documents/models/documents_document.py#L1494).
Steps to reproduce:
1/ Install `documents_sign` in 19.0
2/ Delete the folder `Legal` (documents.document_legal_folder)
3/ Upgrade to `saas~19.2`
As result we will get traceback similar to this:
```
2026-03-19 16:17:50,553 4059246 INFO test_documents_sign odoo.modules.migration: module documents_sign: Running migration [saas~19.2.1.0>] post-migrate
2026-03-19 16:17:50,593 4059246 WARNING test_documents_sign odoo.modules.loading: Transient module states were reset
2026-03-19 16:17:50,594 4059246 ERROR test_documents_sign odoo.registry: Failed to load registry
2026-03-19 16:17:50,594 4059246 CRITICAL test_documents_sign odoo.service.server: Failed to initialize database `test_documents_sign`.
Traceback (most recent call last):
File "/home/odoo/src/odoo/saas-19.2/odoo/service/server.py", line 1598, in preload_registries
registry = Registry.new(dbname, update_module=update_module, install_modules=config['init'], upgrade_modules=config['update'], reinit_modules=config['reinit'])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/saas-19.2/odoo/tools/func.py", line 65, in locked
return func(inst, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/saas-19.2/odoo/orm/registry.py", line 202, in new
load_modules(
File "/home/odoo/src/odoo/saas-19.2/odoo/modules/loading.py", line 465, in load_modules
load_module_graph(
File "/home/odoo/src/odoo/saas-19.2/odoo/modules/loading.py", line 231, in load_module_graph
migrations.migrate_module(package, 'post')
File "/home/odoo/src/odoo/saas-19.2/odoo/modules/migration.py", line 220, in migrate_module
exec_script(self.cr, installed_version, pyfile, pkg.name, stage, stageformat[stage] % version)
File "/home/odoo/src/odoo/saas-19.2/odoo/modules/migration.py", line 257, in exec_script
mod.migrate(cr, installed_version)
File "/home/odoo/src/upgrade/migrations/documents_sign/saas~19.2.1.0/post-migrate.py", line 7, in migrate
_post_init_hook(util.env(cr))
File "/home/odoo/src/enterprise/saas-19.2/documents_sign/__init__.py", line 40, in _post_init_hook
folders_to_process._embed_action(sign_action.id)
File "/home/odoo/src/enterprise/saas-19.2/documents/models/documents_document.py", line 1621, in _embed_action
folder.action_folder_embed_action(folder.id, action_id)
File "/home/odoo/src/enterprise/saas-19.2/documents/models/documents_document.py", line 1592, in action_folder_embed_action
return self.get_documents_actions(folder_id)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/enterprise/saas-19.2/documents/models/documents_document.py", line 1496, in get_documents_actions
raise UserError(_('This folder does not exist or is not accessible.'))
odoo.exceptions.UserError: This folder does not exist or is not accessible.
```
For fixing the issue we skip inactive folders.
tbg-2508This fix ensures that when Provident Fund (PF) is disabled in payroll settings, it no longer appears in the Salary Configurator tool. Previously, the disabled PF benefit could still be displayed and cause errors when users tried to update their salary package. Now the system properly hides PF and prevents related technical errors.
Original PR description
Before: - PF toggle disabled in payroll settings, but “Provident Fund” could still appear in Salary Configurator (Extra Benefits). - Hiding PF from displayed values could make `/salary_package/update_salary` crash with missing `l10n_in_pf_employee_amount`. After: - When `l10n_in_provident_fund` is disabled, PF benefit is filtered out from `_get_benefits_values`. - Empty benefit types are removed, so “Extra Benefits” no longer shows if it only contained PF. - PF initial value is dropped from payload values. - Missing PF value is defaulted to `0.0` in `_get_new_version_values`, preventing update/submit errors. task-6008086
This update fixes how annual leave provisions are calculated in Turkish payroll. The provision now applies only to active employees after their first year, uses clearer rate displays, and is properly included in net salary calculations. This ensures more accurate and transparent payroll processing for Turkish operations.
Original PR description
## Before: - Annual Leave Provision showed a confusing rate value. - It could be triggered too early around the first-year period. - “Excluded from Net” was checked. ## After: - Annual Leave Provision is applied only for active employees after one year. - The amount is based on monthly working days, while the displayed rate stays clear at 100%. - “Excluded from Net” is unchecked. Task-6033568
15 changes
Resolved issues and error corrections
Fixed an access error that prevented Field Service users from adding customers to tasks. The issue occurred when the system tried to update partner information without proper permissions. The fix securely handles these updates so Field Service users can now complete this common task without errors.
Original PR description
Steps to Reproduce: - 1. Log in with a user having only "Field Service > User" access. 2. Create a new task in an field service project. 3. Add a customer on the task. 4. Access error is raised. Issue: - - Field service users could not create a task with a customer. - An access error appeared during task creation. Cause: - - When a customer was added to the task, the partner_phone inverse method was triggered. - This method attempted to write on the partner record. Solution: - - Used sudo() in the inverse method to update the partner phone securely, bypassing restricted access. task-5039657 Forward-Port-Of: odoo/enterprise#112650 Forward-Port-Of: odoo/enterprise#93969
This fix corrects how payment installments are ordered in Peru's electronic invoicing (EDI) documents. Previously, when invoices had multiple payment installments with different due dates, they could appear in the wrong order in the XML document if they weren't created in chronological sequence. Now installments are automatically sorted by their maturity date, ensuring the correct payment schedule is always reflected in the electronic invoice.
Original PR description
**Steps to reproduce:** * Install `l10n_pe_edi`. * Set SUNAT as the signature provider. * Create a customer invoice. * Select a payment term with multiple installments (e.g. 50% (15 days) / 30% (10…
**Steps to reproduce:**
* Install `l10n_pe_edi`.
* Set SUNAT as the signature provider.
* Create a customer invoice.
* Select a payment term with multiple installments (e.g. 50% (15 days) / 30% (10 days) / 20% (5 days)).
* Confirm the invoice and generate the EDI standard UBL document.
**Observed behavior:**
* The XML `<cac:PaymentTerms>` instalment nodes (Cuota001, Cuota002, etc.) are ordered according to the database insertion order of the receivable lines.
* If the payment term lines are created in a non-chronological order, the installments in the XML mix up the `Cuota` ID, amount, and `PaymentDueDate`.
**Cause:**
* `_add_invoice_payment_terms_nodes` iterates over `invoice.line_ids` to generate the installments, but does not sort the receivable account lines by their `date_maturity`.
**Fix:**
* Explicitly call `.sorted('date_maturity')` on the receivable lines before generating the `invoice_date_due_vals_list`.
opw-6035589
Forward-Port-Of: odoo/enterprise#112162The ESG Activity Type model had a confusing description that was identical to the standard Activity Type model. This fix updates the description to "Activity Type ESG" to clearly distinguish it as an ESG-specific feature. This helps users understand which activity type model they're working with in the system.
Original PR description
Before this commit, the description of `esg.activity.type` model is the same than the `activity.type` one defined model which could be confusing. This commit updates the description of `esg.activity.type` model to set Activity Type ESG to explicitly mention that model is used in ESG. Forward-Port-Of: odoo/enterprise#112680
Demo Stripe accounts in the expense module were not automatically verifying when users clicked Connect, remaining in a restricted state indefinitely. This fix resolves the verification document requirement issue that was blocking users from testing the Stripe integration feature. Users can now properly test the expense and Stripe payment functionality without workarounds.
Original PR description
Step to reproduce: - Click on Connect (demo) - The accounts stay Restricted (even after 5m) This is due to the requirement `company.verification.document` which is present as a pending_verification even when no document is given. Giving it a document such as `file_identity_document_success` which should "marks that document requirement as satisfied" also doesn't work. A work-around is to set the business type to individual since they dont have this requirement. This is a temporary fix, as we want to keep a flow similar to what would have been done in reality. But this is preventing users from testing the feature in 19.0 up to master. Forward-Port-Of: odoo/enterprise#112612
This update reverts a previous change to the salary configuration system that affected how emails are handled. The revert restores the system to its previous working state, ensuring that salary-related communications function as expected for HR teams managing employee contracts.
Original PR description
Revert https://github.com/odoo/enterprise/pull/111815
This fix resolves a system error that occurred when creating employee contracts with work schedules that have zero working hours. Previously, the system would crash when trying to calculate hourly wages in this scenario. Now the system handles this edge case gracefully, allowing users to create contracts even with empty work schedules.
Original PR description
When a working schedule has 0 working hours, creating a contract raises a traceback during hourly wage computation. Steps to reproduce the error: - Install ``l10n_au_hr_payroll`` module - Switch to ``My Australian Company`` - Create a working schedule without any working hours - Create an employee and assign this working schedule > Save - Click on Contracts smart button Traceback: ```py ZeroDivisionError: float division by zero ``` https://github.com/odoo/enterprise/blob/bd746aa43f549c4f7813a849e00447b55e084f21/l10n_au_hr_payroll/models/hr_contract.py#L113-L115 The hourly wage is computed using the working schedule’s hours per day. When this value is 0, it results in the above traceback. sentry-7355577930 Forward-Port-Of: odoo/enterprise#112450 Forward-Port-Of: odoo/enterprise#111629
Fixed an issue where splitting a shift within a single day in the planning calendar was incorrectly snapping to standard working hours (8am-5pm), causing duplicate shifts with wrong timeframes. Now when splitting a shift in the daily view, it correctly divides at the exact time requested without adding extra hours outside the original shift.
Original PR description
Since odoo/enterprise#69963, splitting a shift in Gantt view snaps the resulting shifts to the standard working hours (e.g., 08:00 to 17:00). This behavior makes sense when splitting a multi-day shift across a day off, where we want to generate a full working day for the day off as well. However, when splitting a shift within a single day (day scale), this behavior is not wanted, otherwise creating two shifts as follows: 1. A shift from [Original Start] to 5pm 2. A shift from 8am to [Original End] Clearly, the shift is duplicated with the wrong timeframes and adding time outside the original shift's hours. This commits ensures that, when splitting a shift in hours (i.e., when using `day` view scale), the shift is appropriately split at the time requested. For instance: 1. A shift from [Original Start] to [Split Time] 2. A shift from [Split Time] to [Original End] task-5387243 Forward-Port-Of: odoo/enterprise#105991
This fix resolves an error that occurred when viewing the General Ledger consolidation report with multiple companies selected. The system was trying to use account code information that wasn't being retrieved from the database, causing the report to fail. Now the report correctly displays consolidation data across multiple companies without errors.
Original PR description
### Issue before this commit: When opening the General Ledger consolidation with multiple companies selected, a traceback was displayed with a KeyError: 'account_code'. ### Steps to reproduce the…
### Issue before this commit: When opening the General Ledger consolidation with multiple companies selected, a traceback was displayed with a KeyError: 'account_code'. ### Steps to reproduce the issue: 1. Select two or more companies from multi company menu 2. Accounting / Reporting / Ledgers / General Ledger 3. Posted Entries, Accrual Basis button 4. Pick Consolidation 5. Error ### Cause of the issue: When more than one company is selected, the General Ledger consolidation groups journal entries by multiple parameters in an increasingly strict hierarchy. One of these parameters is account_code, which is required only in a multi-company context (as account_id alone is sufficient when a single company is selected). However, the SQL query was not properly adapted to handle this case. The account_code field was used as a grouping key but was not retrieved from the database, resulting in a KeyError. ### Reason to introduce the fix: To ensure that the General Ledger consolidation can be correctly displayed in a multi-company context and to prevent runtime errors. opw-5933074 Forward-Port-Of: odoo/enterprise#109036
This fix resolves a bug where products were being incorrectly deleted when a product template had only one variant. The issue has been corrected to properly handle single-product scenarios, ensuring products are no longer unintentionally removed from your catalog.
Original PR description
product.product records were being removed when they should not have been in the case that the product.template only has one product.product record. This commit fixes this issue by accounting for the case where there is only one product.product record.
This update fixes issues with the bank reconciliation feature on mobile devices. When a bank transaction is fully reconciled, unnecessary buttons like "Reconcile" are now properly hidden on mobile (they were already hidden on desktop), preventing errors when users accidentally click them. Additionally, the reconciliation details now display correctly instead of showing "[object Object]" text.
Original PR description
Currently, when a line is fully reconciled, we display all the moves, name of the reconciliation, and we hide the `Reconcile`, `Set Partner`, ... buttons, has the line is reconciled, we don't need the buttons. But in mobile, we still display the buttons (like `Reconcile`), leading to a traceback when clicking on it. Furthermore, instead of showing the moves name, we show a `[object Object]`. This bug was probably introduced here: https://github.com/odoo/enterprise/pull/101692 task-6058911
Fixed an issue where the IP (Individual Pension) salary rule was not appearing on employee payslips in the Belgian payroll system. The computation logic has been corrected to properly display this important salary component, ensuring employees can see the complete breakdown of their compensation.
Original PR description
-**Issue**: The IP salary rule was not visible on payslip. -**Fix**: Computation has been adjusted to include the correct field.
Fixed an issue where users couldn't preview sales orders for subscription upsells that don't contain recurring products. The system now allows previewing these upsells, making the workflow smoother for sales teams managing non-recurring add-on sales.
Original PR description
When you have an upsell that does not have recurring products, you cannot preview the SO, so we've allow it in this specific case as it is allowed by the constraint on the model
Users with proper permissions were unable to check out visitors from the Frontdesk app due to an incorrectly configured access control filter. This fix corrects the permission logic so authorized users can now successfully complete the visitor checkout process without encountering error pages.
Original PR description
## Short functional explanation of the error When a user checks in, a mail is sent in the chatter, containing a button 'Check out Visitor'. When a user who should have access to the Check Out feature clicks on the button, we are redirected to a 'Not Found' page. ## Reproduction Steps 1. Go to Frontdesk. Click on Open Desk and check in a visitor. 2. Go back to the Frontdesk app. Click on visitors. 3. Click on the visitor you just checked in. 4. Click on the 'Check Out Visitor' button in the chatter. ### Expected behavior A page should appear with the text: 'The visitor has been successfully checked out'. ### Unexpected behavior A 'Not found' page pops up. ## Origin of the issue We filter users who can benefit from the check-out feature using groups. However, the group used to perform this filter is written incorrectly, leading to a condition that is always True, and always returning a request not found. __ opw-5937326 Forward-Port-Of: odoo/enterprise#108331
Fixed a bug that caused the AI email composer to crash when users selected multiple records and clicked the AI icon. The issue occurred because the system couldn't properly handle multiple record IDs. Now the AI composer only activates when a single record is selected, preventing the error and improving the user experience.
Original PR description
Currently an exception is generated when the user tries to click the AI icon in the email composer with multiple records. Steps to produce an error: - Install the `crm` module with the demo data - Go…
Currently an exception is generated when the user tries to click the AI icon in the email composer with multiple records. Steps to produce an error: - Install the `crm` module with the demo data - Go to the CRM list view and select multiple records - Click in `Email` from action > click the `AI` icon on the email composer. Error: `TypeError: int() argument must be a string, a bytes-like object or a real ...` This error is generated because when retrieving the `originalRecordId` from the line [1], the code attempts to remove the first and last characters of a string representation of a list. In the single-selection case, the value is "[4]", so slicing off `[` and `]` correctly yields "4". However, when the user selects multiple records, the value becomes "[4, 5]". Slicing the first and last characters in this case produces "4, 5", and passing this string to Number() results in NaN. As a result, `record_id` becomes `None` when calling `create_ai_draft_channel` method, and passing this None value to int() subsequently raises an error. This commit fixes the issue by assigning `recordId` and `recordModel` only when a single record exists. The record IDs are parsed from their string representation using `JSON.parse`, and the first ID is returned when the list contains exactly one element, or false otherwise. sentry-7201070069
This fix resolves a crash that occurred when trying to print vendor bills using Colombian DIAN support documents before they were sent to the tax authority. The system now displays a helpful message indicating that the tax code will be generated once the document is submitted, instead of failing with an error.
Original PR description
**Steps to reproduce:** * Install the **l10n_co_dian** module. * Enable DIAN 2.1 operation mode: **Support Documents** in settings. * Create a vendor bill using a **DIAN support document** journal. * Confirm the vendor bill. * Click **Print** before sending to DIAN. **Observed behavior:** * Printing fails with `AttributeError: 'bool' object has no attribute 'replace'`. **Cause:** * The method `_l10n_co_dian_get_extra_invoice_report_values()` unconditionally accessed `document.datetime.replace()`. * Before sending to DIAN, `_l10n_co_dian_get_last_accepted_document()` returns an empty recordset, so `document.datetime` evaluates to `False`. **Fix:** * Add a check for empty document recordset in `_l10n_co_dian_get_extra_invoice_report_values()` and return a placeholder message indicating the CUDS code will be created once the document is sent, similar to contingency invoice handling.
13 changes
Resolved issues and error corrections
This update fixes two issues in the Dutch tax reporting module. First, it corrects a bug where the wrong user identifier was being used when adding followers to tax documents, which caused incorrect people to receive notifications. Second, it improves the automated tax status processing to ensure all records are properly handled instead of only the last one.
Original PR description
The method call that is supposed to subscribe the current user to the closing entry when posting XBLR used the User id as a Contact id. This caused random contacts to be added as followers of the chatter thread and as a result receiving notifications for it. The fix is simply using the id of the User's Contact instead. Also, as discussed with prro on Discord, fixed the cron clearing its dictionary each loop. opw-5886621 Forward-Port-Of: odoo/enterprise#107843
This fix corrects an error in Pakistan payroll tax calculations that was causing employees with yearly salaries over 2,200,000 PKR to be charged excessive taxes. The tax calculation was incorrectly accumulating amounts across tax brackets instead of resetting properly at each bracket level, resulting in overstated tax amounts. This fix ensures employees are taxed correctly according to Pakistan's official tax bracket rules.
Original PR description
Currently, payslip computation for Pakistan localization calculates incorrect tax when the yearly cost exceeds 2,200,000. ### **Steps to Reproduce:** 1) Install…
Currently, payslip computation for Pakistan localization calculates incorrect tax when the yearly cost exceeds 2,200,000. ### **Steps to Reproduce:** 1) Install `l10n_pk_hr_payroll_account`,`hr_contract_salary` with demo data. 2) Switch to PK company. 3) Create an employee and a running contract with yearly cost 2,200,001 4) Create a payslip and compute it from the Salary Computation tab. ### **Observed Behavior:** 'Tax Bracket Yearly' is computed as `122000.24` ### **Expected Behavior:** 'Tax Bracket Yearly' should be `116000.24` ### **Root Cause:** since [commit](https://github.com/odoo/enterprise/pull/98345/commits/62f5e216518d83317618d7dbc0be4db92d1881a3), the tax computation relies on [_l10n_pk_get_tax](https://github.com/odoo/enterprise/blob/a9656336583a4d5c5b12d4d6120ec62ba1cf9151/l10n_pk_hr_payroll/models/hr_payslip.py#L9-L20) , In this method, the `result` is incorrectly accumulated with `fix` when iterating through brackets, leading to an inflated tax value. [official pakistan document](https://download1.fbr.gov.pk/Docs/20258181281745641WHT-RateCard.pdf) ### **Fix:** Use `result = fix` instead of `result += fix` so that the cumulative tax is correctly reset at each bracket. **opw-5979265** Forward-Port-Of: odoo/enterprise#110939
Fixed an issue where subscription product billing periods were not showing when products were displayed as cards on website pages. The billing period information is now properly included when products are added to pages using the website editor, ensuring customers see complete pricing details just like they do on the shop page.
Original PR description
Steps to reproduce: 1) Go to the Website app. 2) Add a product snippet to any page using the editor. 3) See product card of any subscription product. Issue: - The billing period is not displayed for subscription products in the product snippet, unlike on the shop page. Cause: - `temporal_unit_display` is not included in the `combination_info`which is passed in data used by the product snippet. Fix: - Include `temporal_unit_display` in `combination_info`. opw-6070943 Forward-Port-Of: odoo/enterprise#112171
Fixed an error that prevented Field Service users from adding customers to tasks. The issue occurred when the system tried to update customer phone information without proper permissions. The fix allows Field Service users to complete this common task without encountering access errors.
Original PR description
Steps to Reproduce: - 1. Log in with a user having only "Field Service > User" access. 2. Create a new task in an field service project. 3. Add a customer on the task. 4. Access error is raised. Issue: - - Field service users could not create a task with a customer. - An access error appeared during task creation. Cause: - - When a customer was added to the task, the partner_phone inverse method was triggered. - This method attempted to write on the partner record. Solution: - - Used sudo() in the inverse method to update the partner phone securely, bypassing restricted access. task-5039657 Forward-Port-Of: odoo/enterprise#112549 Forward-Port-Of: odoo/enterprise#93969
This update fixes an issue where the "Load more" line in financial reports was being incorrectly hidden when users enabled the "Hide lines at 0" option. The fix ensures that the "Load more" line remains visible so users can access additional data, while still properly hiding rows with zero values as intended.
Original PR description
When activating the 'Hide if 0' option, the 'Load more' line is hidden. Fix: Filtering out the lines with empty columns (Load more lines) from the zero lines. Steps: - Open GL (occurs with other reports as well), and open configuration for this report - Set Load more limit to 1, and hide if zero to optional - Go back to GL report and select the 'Hide lines at 0' option -> Load more lines are hidden as long as the zero lines opw-5953725 Forward-Port-Of: odoo/enterprise#109380
Fixed an issue where splitting a shift within a single day in the planning calendar was incorrectly snapping to standard working hours, causing duplicate shifts with wrong timeframes. Now when splitting a shift in the daily view, it correctly divides at the exact time requested without adding extra hours outside the original shift.
Original PR description
Since odoo/enterprise#69963, splitting a shift in Gantt view snaps the resulting shifts to the standard working hours (e.g., 08:00 to 17:00). This behavior makes sense when splitting a multi-day shift across a day off, where we want to generate a full working day for the day off as well. However, when splitting a shift within a single day (day scale), this behavior is not wanted, otherwise creating two shifts as follows: 1. A shift from [Original Start] to 5pm 2. A shift from 8am to [Original End] Clearly, the shift is duplicated with the wrong timeframes and adding time outside the original shift's hours. This commits ensures that, when splitting a shift in hours (i.e., when using `day` view scale), the shift is appropriately split at the time requested. For instance: 1. A shift from [Original Start] to [Split Time] 2. A shift from [Split Time] to [Original End] task-5387243 Forward-Port-Of: odoo/enterprise#105991
This fix ensures that when scanning barcodes from the main menu, the system uses the correct company's barcode nomenclature (such as GS1) instead of defaulting to the user's primary company. This resolves issues where valid barcodes were not being recognized when working with multiple companies that have different barcode formats.
Original PR description
### Issue: The company used in the main barcode menu is the `company_id` of the user rather than the current contextual company of the session. This is problematic as we might endup using the wrong…
### Issue: The company used in the main barcode menu is the `company_id` of the user rather than the current contextual company of the session. This is problematic as we might endup using the wrong barcode nomenclature. ### Steps to reproduce: - Have 2 companies: company 1 and company 2 - Set the barcode nomenclature of company 1: default, company 2: GS1 - Incarnate a user allowed in both companies but with default company 1 - With company 2, create a product and set its barcode to 36939282410106 - From the main menu open the barcode app and scan 0136939282410106 #### > No product was found (even thought it is correct in GS1) ### Cause of the issue: Scanning from the main barcode menu will trigger a call of the `main_menu` method relying on the nomenclature of the contextual company of the request: https://github.com/odoo/enterprise/blob/804ea21c225a7a1e0763bac188f027adeb3ab78f/stock_barcode/static/src/main_menu/main_menu.js#L98-L99 https://github.com/odoo/enterprise/blob/804ea21c225a7a1e0763bac188f027adeb3ab78f/stock_barcode/controllers/stock_barcode.py#L15-L21 However, when opening the main barcode menu from the app menu, no contextual warehouse was set to the view: https://github.com/odoo/enterprise/blob/804ea21c225a7a1e0763bac188f027adeb3ab78f/stock_barcode/views/stock_barcode_views.xml#L6-L11 As such, the environment of the request will be set here: https://github.com/odoo/odoo/blob/9393b0db6791fe5a7f576cff55705e315fb3dd11/odoo/http.py#L2083 based on the company of the user rather than the one of the context: https://github.com/odoo/odoo/blob/9393b0db6791fe5a7f576cff55705e315fb3dd11/odoo/api.py#L694-L722 ### Fix: Setting the company slices the `current_company` in first position of the `allowed_company_ids`: https://github.com/odoo/odoo/blob/260c69ed64f8663b6935b9863c86aac6dbecd961/addons/web/static/src/webclient/switch_company_menu/switch_company_menu.js#L33-L39 https://github.com/odoo/odoo/blob/260c69ed64f8663b6935b9863c86aac6dbecd961/addons/web/static/src/webclient/switch_company_menu/switch_company_menu.js#L68-L81 which can be recovered from the cookies via the `_get_allowed_company_ids`: https://github.com/odoo/enterprise/blob/43f65ff2f3c6177cc69647bbb85bb40a84409457/stock_barcode/controllers/stock_barcode.py#L432-L442 precisely used by the `_get_barcode_nomenclature`: https://github.com/odoo/enterprise/blob/43f65ff2f3c6177cc69647bbb85bb40a84409457/stock_barcode/controllers/stock_barcode.py#L485-L491 Note that passing the context in the arguments of the `main_menu` JSON route will not really solve the issue by it self since the context is no longer shared with the request: c8cd1d4a83de7a5798cbb910a788fbb6fe208d2f ### Additional Issue: The type `dest_location` does not exist on barcode types: https://github.com/odoo/odoo/blob/485a64b6a1e91feb4310f282c6dd1cd021f1780b/addons/barcodes_gs1_nomenclature/models/barcode_rule.py#L16-L20 so that the type used by these lines can not work: https://github.com/odoo/enterprise/blob/1dedc5bbcee43bfd13e55206e3d7364f715ca9be/stock_barcode/controllers/stock_barcode.py#L29-L30 https://github.com/odoo/enterprise/blob/1dedc5bbcee43bfd13e55206e3d7364f715ca9be/stock_barcode/controllers/stock_barcode.py#L52-L56 ### Steps to reproduce: - In the settings enable: Multi-Steps Routes - Set the barcode nomenclature to GS1 - Set your warehouse in receipt in two steps and add a barcode to the WH/Input: 3033710074365 - From the main menu open the barcode app and scan 4133033710074365 #### > No product or picking was found (even thought it is correct in GS1 that should create an internal transfer with WH/INPUT as destination) opw-5847529 Forward-Port-Of: odoo/enterprise#112302 Forward-Port-Of: odoo/enterprise#111662
This update fixes a technical error that occurred when importing sales orders with subscription discounts into the Point of Sale system. The fix ensures subscription discount lines are properly handled as notes during the import process, preventing the system from crashing when using subscription features with POS.
Original PR description
This is a test for the related community fix and an override of the **isSaleOrderLineNote** method to add the subscription specific **subscription_discount** lines to be treated as a note when importing it from the Sales module. https://github.com/odoo/odoo/pull/247846 opw-5582448 Forward-Port-Of: odoo/enterprise#107002
This update corrects two critical issues in Spain's Form 347 tax reporting. First, it now properly shows partners with negative amounts below the -3,005.06 € threshold, which were previously hidden. Second, it separates insurance operations into distinct Sales and Purchase sections, ensuring amounts from both transaction types are correctly reported in their respective categories.
Original PR description
Before this PR: - Partners were only shown if their total was positive and above 3,005.06 €. Negative totals were hidden, even if they were lower than -3,005.06 €. - Insurance operations only took Purchase journal amounts into account. Amounts from Sales journals were ignored, and there was no distinction between the two types of operations. After this PR: - The report now uses the absolute value of the total. Partners with amounts exceeding 3,005.06 €, whether positive or negative, are now shown correctly. - Insurance operations are now divided into two distinct sections: Sales and Purchases. Amounts from both Sales and Purchase journals are now correctly taken into account and reported in their respective sections. task-5214023 Forward-Port-Of: odoo/enterprise#112136 Forward-Port-Of: odoo/enterprise#100413
This fix corrects a bug where users could incorrectly change the "Recurring" setting on subscription products that have confirmed sales orders. The system now properly prevents these changes and displays the correct warning message, ensuring data integrity for subscription products.
Original PR description
**Problem:** When attempting to change "Recurring" on products in the form view, if there are confirmed SOs, the change should be reverted and a message should appear explaining this. However, there is a bug in how the change is reverted where it takes the current form value of the field. This cannot be trusted as it's possible to trigger another onchange before the first one resolves, so the second onchange is based on the wrong value. **Steps to Reproduce:** - w/Demo Data, go to product "Office Cleaning Service (SUB)" (This is a subscription product which has confirmed SOs) - Quickly click the checkbox for "Recurring" twice -> Two warnings appear, but Recurring is False and can be saved **Solution:** Instead of reading the current form value and setting its opposite, we can revert to the current value on the server. Forward-Port-Of: odoo/enterprise#110877
This fix ensures that when you change the salesperson assigned to a subscription, the update automatically applies to all contacts associated with that company, not just the main company record. This keeps customer information consistent across the portal and eliminates the need for manual updates to individual contacts.
Original PR description
Before this commit, changing the salesperson on a subscription only updated the company partner, leaving child contacts with outdated salesperson info. After this commit, updating the subscription's salesperson also updates all child contacts of the company, ensuring consistency across the portal and reducing manual work. An unit test was added to ensure this behavior. task-5917271 Forward-Port-Of: odoo/enterprise#111499 Forward-Port-Of: odoo/enterprise#108339
This fix corrects an issue where Belgian payroll actions (Dimona and Part Time registrations) were being triggered for all new employees regardless of their contract country. Now these actions only apply to employees with Belgian contracts, preventing unnecessary processing for non-Belgian staff.
Original PR description
Previously, planned actions (Dimona/Part Time) were triggered for all new employees with a contract start date, regardless of country. Now, the trigger is filtered to only apply to Belgian contracts. task-5942339
This fix ensures that when an employee's first or last name is updated in the Swiss payroll system, the legal name field used for payslips is automatically recalculated. Previously, payslips were showing outdated employee names because the legal name field wasn't being refreshed when names were changed.
Original PR description
## Issue When using the Swiss localization, updating the *First Name* and/or *Last Name* on an employee's page does not update the `hr.employee.legal_name` field. It is an issue, as that field is the…
## Issue
When using the Swiss localization, updating the *First Name* and/or *Last Name* on an employee's page does not update the `hr.employee.legal_name` field. It is an issue, as that field is the one used when creating payslips.
## Steps to reproduce
1. Install *Switzerland - Swissdec Certified ELM 5.0 - Payroll* (`l10n_ch_hr_payroll`) and create a Swiss company
2. Create an Employee
- Company: Swiss company
- Name: "LastName FirstName"
3. In the *Personal* tab, the *First Name* and *Last Name* are filled with the given first and last names. This also sets the (hidden) `hr.employee.legal_name` field to *"LastName FirstName"*
4. Modify the *First Name* and/or the *Last Name* field(s) to any new name(s)
5. In Payroll > Payslips > Payslips, create a new Payslip
- Employee: FirstName LastName
6. **The name given to the Payslip is wrong, it uses the initial `legal_name` (_"LastName FirstName"_)**
## Cause
In 18.0, the `hr.employee.legal_name` was updated by the `_compute_legal_name` overridden in `l10n_ch_hr_paryoll_elm_transmission`.
https://github.com/odoo/enterprise/blob/2953e5cd7666bd45547f26863253f107473aed0b/l10n_ch_hr_payroll_elm_transmission/models/hr_employee.py#L176-L184
That module was removed in 18.4, and the behavior updating the `legal_name` was lost.
opw-58822229 changes
Enhancements to existing features
This update adds missing modules to the Weblate translation configuration file, ensuring that more parts of the system can be translated by the community. This improves the ability to localize Odoo in different languages by expanding which modules are included in the translation management system.
Original PR description
Related: https://github.com/odoo/odoo/pull/254667 Forward-Port-Of: odoo/enterprise#111401 Forward-Port-Of: odoo/enterprise#111141
Resolved issues and error corrections
This update fixes a bug where the wrong contacts were being added as followers to tax report entries, causing them to receive unwanted notifications. Additionally, a cron job that processes tax submission status has been improved to correctly handle multiple records instead of only processing the last one.
Original PR description
The method call that is supposed to subscribe the current user to the closing entry when posting XBLR used the User id as a Contact id. This caused random contacts to be added as followers of the chatter thread and as a result receiving notifications for it. The fix is simply using the id of the User's Contact instead. Also, as discussed with prro on Discord, fixed the cron clearing its dictionary each loop. opw-5886621 Forward-Port-Of: odoo/enterprise#107843
Fixed an issue where subscription product billing periods were not showing when products were added to website pages using the product snippet editor. The billing period information is now properly displayed on product cards, matching the behavior shown on the shop page.
Original PR description
Steps to reproduce: 1) Go to the Website app. 2) Add a product snippet to any page using the editor. 3) See product card of any subscription product. Issue: - The billing period is not displayed for subscription products in the product snippet, unlike on the shop page. Cause: - `temporal_unit_display` is not included in the `combination_info`which is passed in data used by the product snippet. Fix: - Include `temporal_unit_display` in `combination_info`. opw-6070943 Forward-Port-Of: odoo/enterprise#112171
This update fixes failing tests in the Italian XML export module by adding required tax identification fields that are now validated during the export process. Previously, tests were passing without these mandatory fields, but a recent validation improvement now requires them to be present, ensuring exported documents comply with Italian tax authority standards.
Original PR description
Description of the issue this commit addresses: Previously, the testing of the xml exports was only done by generating the file and checking its content against a hardcoded one but a fix[^1] changed that so the tests use the real export flow during which an xsd validation is done. As the tests did not expect to go trough the validation, some mandatory values were not present and it now results in a failing validation (caught in except). [^1]: https://github.com/odoo/enterprise/pull/108548 Desired behavior after this commit is merged: The tests set the l10n_it_codice_fiscale field from which are populated the mandatory CodiceFiscaleDichiarante, CodiceFiscale and CFDichiarante for the xsd validation. opw-5707544
This fix resolves an issue where the "Load more" line in financial reports was being incorrectly hidden when the "Hide lines at 0" option was enabled. The fix ensures that "Load more" lines remain visible even when hiding zero-value lines, allowing users to access additional report details as needed.
Original PR description
When activating the 'Hide if 0' option, the 'Load more' line is hidden. Fix: Filtering out the lines with empty columns (Load more lines) from the zero lines. Steps: - Open GL (occurs with other reports as well), and open configuration for this report - Set Load more limit to 1, and hide if zero to optional - Go back to GL report and select the 'Hide lines at 0' option -> Load more lines are hidden as long as the zero lines opw-5953725 Forward-Port-Of: odoo/enterprise#109380
This fix corrects an error in Pakistan payroll tax calculations that was causing inflated tax amounts for employees earning over 2.2 million annually. The tax computation was incorrectly accumulating values across tax brackets instead of properly resetting them, resulting in employees being overtaxed. This update ensures accurate tax calculations in compliance with official Pakistan tax regulations.
Original PR description
Currently, payslip computation for Pakistan localization calculates incorrect tax when the yearly cost exceeds 2,200,000. ### **Steps to Reproduce:** 1) Install…
Currently, payslip computation for Pakistan localization calculates incorrect tax when the yearly cost exceeds 2,200,000. ### **Steps to Reproduce:** 1) Install `l10n_pk_hr_payroll_account`,`hr_contract_salary` with demo data. 2) Switch to PK company. 3) Create an employee and a running contract with yearly cost 2,200,001 4) Create a payslip and compute it from the Salary Computation tab. ### **Observed Behavior:** 'Tax Bracket Yearly' is computed as `122000.24` ### **Expected Behavior:** 'Tax Bracket Yearly' should be `116000.24` ### **Root Cause:** since [commit](https://github.com/odoo/enterprise/pull/98345/commits/62f5e216518d83317618d7dbc0be4db92d1881a3), the tax computation relies on [_l10n_pk_get_tax](https://github.com/odoo/enterprise/blob/a9656336583a4d5c5b12d4d6120ec62ba1cf9151/l10n_pk_hr_payroll/models/hr_payslip.py#L9-L20) , In this method, the `result` is incorrectly accumulated with `fix` when iterating through brackets, leading to an inflated tax value. [official pakistan document](https://download1.fbr.gov.pk/Docs/20258181281745641WHT-RateCard.pdf) ### **Fix:** Use `result = fix` instead of `result += fix` so that the cumulative tax is correctly reset at each bracket. **opw-5979265** Forward-Port-Of: odoo/enterprise#110939
This fix corrects how shifts are split when using the daily view in the planning schedule. Previously, splitting a shift within a single day would incorrectly snap the resulting shifts to standard working hours (8am-5pm), creating duplicate shifts with wrong timeframes. Now, shifts are properly split at the exact time requested, preserving the original shift boundaries.
Original PR description
Since odoo/enterprise#69963, splitting a shift in Gantt view snaps the resulting shifts to the standard working hours (e.g., 08:00 to 17:00). This behavior makes sense when splitting a multi-day shift across a day off, where we want to generate a full working day for the day off as well. However, when splitting a shift within a single day (day scale), this behavior is not wanted, otherwise creating two shifts as follows: 1. A shift from [Original Start] to 5pm 2. A shift from 8am to [Original End] Clearly, the shift is duplicated with the wrong timeframes and adding time outside the original shift's hours. This commits ensures that, when splitting a shift in hours (i.e., when using `day` view scale), the shift is appropriately split at the time requested. For instance: 1. A shift from [Original Start] to [Split Time] 2. A shift from [Split Time] to [Original End] task-5387243 Forward-Port-Of: odoo/enterprise#105991
This update corrects how the Spanish Form 347 tax report handles partner thresholds and insurance operations. Partners with negative amounts are now properly included if they exceed the 3,005.06 € threshold in absolute value, and insurance operations are now correctly split between sales and purchases with amounts from both journal types properly accounted for. This ensures accurate tax reporting compliance for Spanish businesses.
Original PR description
Before this PR: - Partners were only shown if their total was positive and above 3,005.06 €. Negative totals were hidden, even if they were lower than -3,005.06 €. - Insurance operations only took Purchase journal amounts into account. Amounts from Sales journals were ignored, and there was no distinction between the two types of operations. After this PR: - The report now uses the absolute value of the total. Partners with amounts exceeding 3,005.06 €, whether positive or negative, are now shown correctly. - Insurance operations are now divided into two distinct sections: Sales and Purchases. Amounts from both Sales and Purchase journals are now correctly taken into account and reported in their respective sections. task-5214023 Forward-Port-Of: odoo/enterprise#112136 Forward-Port-Of: odoo/enterprise#100413
This fix corrects a bug where users could incorrectly change the "Recurring" setting on subscription products that have confirmed sales orders. Previously, rapid clicks on the setting could bypass the intended protection. The fix now properly validates changes against the server's current value instead of the form's temporary state, ensuring the system correctly prevents unauthorized modifications.
Original PR description
**Problem:** When attempting to change "Recurring" on products in the form view, if there are confirmed SOs, the change should be reverted and a message should appear explaining this. However, there is a bug in how the change is reverted where it takes the current form value of the field. This cannot be trusted as it's possible to trigger another onchange before the first one resolves, so the second onchange is based on the wrong value. **Steps to Reproduce:** - w/Demo Data, go to product "Office Cleaning Service (SUB)" (This is a subscription product which has confirmed SOs) - Quickly click the checkbox for "Recurring" twice -> Two warnings appear, but Recurring is False and can be saved **Solution:** Instead of reading the current form value and setting its opposite, we can revert to the current value on the server. Forward-Port-Of: odoo/enterprise#110877
8 changes
Enhancements to existing features
This update adds missing modules to the Weblate translation configuration file, ensuring that all relevant modules are properly included in the translation management system. This improves the translation workflow by making sure no modules are overlooked when managing multilingual content across the platform.
Original PR description
Related: https://github.com/odoo/odoo/pull/254667 Forward-Port-Of: odoo/enterprise#111181 Forward-Port-Of: odoo/enterprise#111141
Resolved issues and error corrections
This update fixes an error in how Pakistan payroll taxes are calculated for employees earning over 2.2 million annually. The system was incorrectly adding tax amounts instead of replacing them at each income bracket, resulting in overstated tax calculations. This fix ensures employees are taxed according to official Pakistan tax bracket rules.
Original PR description
Currently, payslip computation for Pakistan localization calculates incorrect tax when the yearly cost exceeds 2,200,000. ### **Steps to Reproduce:** 1) Install…
Currently, payslip computation for Pakistan localization calculates incorrect tax when the yearly cost exceeds 2,200,000. ### **Steps to Reproduce:** 1) Install `l10n_pk_hr_payroll_account`,`hr_contract_salary` with demo data. 2) Switch to PK company. 3) Create an employee and a running contract with yearly cost 2,200,001 4) Create a payslip and compute it from the Salary Computation tab. ### **Observed Behavior:** 'Tax Bracket Yearly' is computed as `122000.24` ### **Expected Behavior:** 'Tax Bracket Yearly' should be `116000.24` ### **Root Cause:** since [commit](https://github.com/odoo/enterprise/pull/98345/commits/62f5e216518d83317618d7dbc0be4db92d1881a3), the tax computation relies on [_l10n_pk_get_tax](https://github.com/odoo/enterprise/blob/a9656336583a4d5c5b12d4d6120ec62ba1cf9151/l10n_pk_hr_payroll/models/hr_payslip.py#L9-L20) , In this method, the `result` is incorrectly accumulated with `fix` when iterating through brackets, leading to an inflated tax value. [official pakistan document](https://download1.fbr.gov.pk/Docs/20258181281745641WHT-RateCard.pdf) ### **Fix:** Use `result = fix` instead of `result += fix` so that the cumulative tax is correctly reset at each bracket. **opw-5979265** Forward-Port-Of: odoo/enterprise#110939
Fixed an issue where subscription product billing periods were not showing when products were displayed as snippets on website pages, even though they appeared correctly on the shop page. This ensures customers see complete pricing information including billing frequency when browsing subscription products anywhere on the website.
Original PR description
Steps to reproduce: 1) Go to the Website app. 2) Add a product snippet to any page using the editor. 3) See product card of any subscription product. Issue: - The billing period is not displayed for subscription products in the product snippet, unlike on the shop page. Cause: - `temporal_unit_display` is not included in the `combination_info`which is passed in data used by the product snippet. Fix: - Include `temporal_unit_display` in `combination_info`. opw-6070943 Forward-Port-Of: odoo/enterprise#112171
Ecuador's tax withholding percentages have been updated for 2026 in compliance with the new government resolution. The system's automated tests have been updated to reflect these new tax rates to ensure accurate tax calculations and reporting for Ecuadorian businesses.
Original PR description
In accordance with the implementation of the new withholding tax percentages according to "Resolución N.º NAC-DGERCGC26-00000009" for Ecuador, following internal implementation guidelines by TRESCLOUD. Unit tests are updated to be based on the new withholding percentages. BP #110343 Forward-Port-Of: odoo/enterprise#110879 Forward-Port-Of: odoo/enterprise#110712
This fix corrects how the Master Production Schedule (MPS) calculates safety inventory levels for component products when they have indirect demand from parent products. Previously, safety stock targets were not being properly considered when determining production quantities for components, leading to incorrect demand forecasts. This update ensures that safety inventory requirements are accurately factored into the production planning calculations.
Original PR description
Steps to reproduce: ------------------- * Enable "Master Production Schedule" in Inventory settings * Create tracked Product "Child" and set up a vendor * Create tracked Product "Parent" and set up a…
Steps to reproduce: ------------------- * Enable "Master Production Schedule" in Inventory settings * Create tracked Product "Child" and set up a vendor * Create tracked Product "Parent" and set up a bom as component "Child" and Lead Time: 2 days * Create tracked Product "GParent" and set up a bom as component "Parent" and Lead Time: 2 days * Open MPS and add your three products: - Child, Parent: activate indirect demand - Parent: Safety Stock Target of 10 * Add 1 in the forecast demand for "Gparent" on third column -> Will have 20 Indirect Demand Forecast of Child in the first column and -9 on the second Observation: ------------- Usefull comment form the function : https://github.com/odoo/enterprise/blob/b332af45a46b2295797a5096f68b7953554a495b/mrp_mps/models/mrp_mps.py#L424-L447 When creating a demand from the MPS, it will always take the first date of the interval (ex: Week 10 (2-8/Mar), it will create the demand for the 2 of Mars) When calculating the production schedule. we wil we calculate each product for each date_range: https://github.com/odoo/enterprise/blob/ea805995f66e007c0aef6b473a2b16dbe54d73bc/mrp_mps/models/mrp_mps.py#L488 https://github.com/odoo/enterprise/blob/ea805995f66e007c0aef6b473a2b16dbe54d73bc/mrp_mps/models/mrp_mps.py#L509 When calculating the values for a product, we will set the indirect demand qty for it component The demand will created the demand in function of the date of when the parent need and the lead time (it will for the previous date range because of the lead time): https://github.com/odoo/enterprise/blob/ea805995f66e007c0aef6b473a2b16dbe54d73bc/mrp_mps/models/mrp_mps.py#L554 https://github.com/odoo/enterprise/blob/ea805995f66e007c0aef6b473a2b16dbe54d73bc/mrp_mps/models/mrp_mps.py#L555 If the demand is not equal to the resplensih_qty we will create another demand to compensate, it will use the first date of range minus the lead time it will send it to the previous date range: https://github.com/odoo/enterprise/blob/ea805995f66e007c0aef6b473a2b16dbe54d73bc/mrp_mps/models/mrp_mps.py#L556-L560 In our case this will create the issue, since it will try to compensate each time on the previous week. opw-5413838 Forward-Port-Of: odoo/enterprise#107671
This fix resolves an issue where the "Load more" line was being hidden when users enabled the "Hide lines at 0" option in financial reports. The update ensures that "Load more" lines remain visible even when zero-value lines are hidden, allowing users to access additional data when needed.
Original PR description
When activating the 'Hide if 0' option, the 'Load more' line is hidden. Fix: Filtering out the lines with empty columns (Load more lines) from the zero lines. Steps: - Open GL (occurs with other reports as well), and open configuration for this report - Set Load more limit to 1, and hide if zero to optional - Go back to GL report and select the 'Hide lines at 0' option -> Load more lines are hidden as long as the zero lines opw-5953725 Forward-Port-Of: odoo/enterprise#109380
This fix corrects a bug where users could incorrectly change the "Recurring" setting on subscription products that have confirmed orders. Previously, rapid clicks on the setting could bypass the intended protection. The fix now properly validates against the server's current value instead of the form's temporary value, ensuring the setting cannot be changed when orders exist.
Original PR description
**Problem:** When attempting to change "Recurring" on products in the form view, if there are confirmed SOs, the change should be reverted and a message should appear explaining this. However, there is a bug in how the change is reverted where it takes the current form value of the field. This cannot be trusted as it's possible to trigger another onchange before the first one resolves, so the second onchange is based on the wrong value. **Steps to Reproduce:** - w/Demo Data, go to product "Office Cleaning Service (SUB)" (This is a subscription product which has confirmed SOs) - Quickly click the checkbox for "Recurring" twice -> Two warnings appear, but Recurring is False and can be saved **Solution:** Instead of reading the current form value and setting its opposite, we can revert to the current value on the server. Forward-Port-Of: odoo/enterprise#110877
This update fixes two issues in the Dutch tax reporting module. First, it corrects a bug where wrong contacts were being added as followers to tax documents, causing them to receive unwanted notifications. Second, it improves the automated tax status processing to ensure all records are properly handled instead of only the last one.
Original PR description
The method call that is supposed to subscribe the current user to the closing entry when posting XBLR used the User id as a Contact id. This caused random contacts to be added as followers of the chatter thread and as a result receiving notifications for it. The fix is simply using the id of the User's Contact instead. Also, as discussed with prro on Discord, fixed the cron clearing its dictionary each loop. opw-5886621
4 changes
Enhancements to existing features
This update refines the M3.1 design system styling by introducing a new outlined box style for views outside of groups. The changes revert previous M3 modifications to templates and restore previous layouts with necessary adjustments, improving visual consistency across the application while addressing some remaining styling refinements needed in specific areas.
Original PR description
In some view outside the groups we want the boxes anyway so we introduce the `o_outlined` class. This commit reverts the changes made for M3 to the arch, and bring back the previous template with some adaptation when needed. Note: * clipboard: more refactoring needed in some case icons are not visible * M3: some class are still present task-6054024 Co-authored-by: Luca Vitali <luvi@odoo.com> Co-authored-by: Romain Estievenart <res@odoo.com>
The spreadsheet printing functionality has been enhanced with a proper printing wizard that is now built into the spreadsheet tool itself. This improvement allows us to remove outdated printing code and assets from Odoo, making the system cleaner and more maintainable while providing users with a better printing experience.
Original PR description
A real printing wizard was introduced in o_spreadsheet, we can now remove the `useSpreadsheetPrint` hook in odoo as well as the print asset bundle. Task: 5891329
Resolved issues and error corrections
Fixed a display issue in the Australian payroll ATO submission wizard where the checkbox for accepting Terms & Conditions could become misaligned with its text depending on window width. The checkbox now stays properly aligned on the same line as the text, improving the user experience when submitting payslips or payruns to the Australian Tax Office.
Original PR description
- Step to reproduce: with l10n_au_hr_payroll_account installed and validated payslips or payruns click "Sign & Submit to ATO" -> wizard opens with checkbox to accept T&C, mght be misaligned depending on window width. - Cause: if text fills full width then checkbox is moved above. - Solution: using d-flex and utilities, force checkbox on same line as text and allow text to split if necessary. Task: 6051482
This fix resolves crashes that occurred when generating receipts for Colombian POS orders sent to DIAN (tax authority). The issue was caused by incorrect QR code paths and outdated code references. The fix ensures receipts generate properly without errors.
Original PR description
1. When generating the full receipt for a pos order sent to DIAN the receipt generation crashes because the qr code url is a relative path, which makes wkhtmltopdf crash. 2. For invoiced pos orders we were still using old code which would also crash because the `'barcode_src`' key is not returned by `_l10n_co_dian_get_extra_invoice_report_values` anymore Forward-Port-Of: odoo/enterprise#112133
24 changes
New functionality added to Odoo
New automated tests have been added to verify the tax report closing journal functionality works correctly. These tests ensure that tax closing processes operate as expected and help prevent future issues with tax reporting features.
Original PR description
Ticket Adhoc side: 114344
The Lazada sales module now has a proper icon displayed in the Odoo interface. This visual update helps users quickly identify and recognize the Lazada integration module among other available modules, improving the overall user experience.
Original PR description
Add Lazada icon to the module
Resolved issues and error corrections
This update corrects a bug where payroll-related planned actions (Dimona and Part Time registrations) were being triggered for all new employees regardless of their country. The fix ensures these actions now only apply to employees with Belgian contracts, preventing unnecessary processing for non-Belgian staff.
Original PR description
Previously, planned actions (Dimona/Part Time) were triggered for all new employees with a contract start date, regardless of country. Now, the trigger is filtered to only apply to Belgian contracts. task-5942339 Forward-Port-Of: odoo/enterprise#111788
This fix corrects an error in Pakistan payroll tax calculations that was causing employees with yearly salaries above 2,200,000 PKR to be charged excessive taxes. The tax calculation was incorrectly accumulating amounts across tax brackets instead of resetting properly at each bracket level, resulting in overstated tax amounts. This fix ensures employees are taxed according to Pakistan's official tax bracket rules.
Original PR description
Currently, payslip computation for Pakistan localization calculates incorrect tax when the yearly cost exceeds 2,200,000. ### **Steps to Reproduce:** 1) Install…
Currently, payslip computation for Pakistan localization calculates incorrect tax when the yearly cost exceeds 2,200,000. ### **Steps to Reproduce:** 1) Install `l10n_pk_hr_payroll_account`,`hr_contract_salary` with demo data. 2) Switch to PK company. 3) Create an employee and a running contract with yearly cost 2,200,001 4) Create a payslip and compute it from the Salary Computation tab. ### **Observed Behavior:** 'Tax Bracket Yearly' is computed as `122000.24` ### **Expected Behavior:** 'Tax Bracket Yearly' should be `116000.24` ### **Root Cause:** since [commit](https://github.com/odoo/enterprise/pull/98345/commits/62f5e216518d83317618d7dbc0be4db92d1881a3), the tax computation relies on [_l10n_pk_get_tax](https://github.com/odoo/enterprise/blob/a9656336583a4d5c5b12d4d6120ec62ba1cf9151/l10n_pk_hr_payroll/models/hr_payslip.py#L9-L20) , In this method, the `result` is incorrectly accumulated with `fix` when iterating through brackets, leading to an inflated tax value. [official pakistan document](https://download1.fbr.gov.pk/Docs/20258181281745641WHT-RateCard.pdf) ### **Fix:** Use `result = fix` instead of `result += fix` so that the cumulative tax is correctly reset at each bracket. **opw-5979265** Forward-Port-Of: odoo/enterprise#112642 Forward-Port-Of: odoo/enterprise#110939
This update fixes an issue with how tax closing journals are configured in the accounting system. The fix ensures that tax closing journals are properly set up when creating or updating company chart templates, which helps prevent errors during tax period closing processes.
Fixed an issue preventing Field Service users from adding customers to tasks. When users attempted to assign a customer to a task, the system was blocking the action due to insufficient permissions. The fix allows Field Service users to complete this common workflow while maintaining proper security controls through permission-based restrictions.
Original PR description
Steps to Reproduce: - 1. Log in with a user having only "Field Service > User" access. 2. Create a new task in an field service project. 3. Add a customer on the task. 4. Access error is raised. Issue: - - Field service users could not create a task with a customer. - An access error appeared during task creation. Cause: - - When a customer was added to the task, the partner_phone inverse method was triggered. - This method attempted to write on the partner record. Solution: - - Used sudo() in the inverse method to update the partner phone securely, bypassing restricted access. task-5039657 Forward-Port-Of: odoo/enterprise#112549 Forward-Port-Of: odoo/enterprise#93969
The description for the ESG Activity Type model has been updated to clearly identify it as "Activity Type ESG" instead of using the generic description shared with the standard Activity Type model. This change reduces confusion by making it explicit that this model is specifically used for ESG (Environmental, Social, and Governance) activities.
Original PR description
Before this commit, the description of `esg.activity.type` model is the same than the `activity.type` one defined model which could be confusing. This commit updates the description of `esg.activity.type` model to set Activity Type ESG to explicitly mention that model is used in ESG.
This fix resolves an issue where the "Load more" line in financial reports was being incorrectly hidden when the "Hide lines at 0" option was enabled. The update ensures that "Load more" lines remain visible even when zero-value lines are hidden, allowing users to access additional data as needed.
Original PR description
When activating the 'Hide if 0' option, the 'Load more' line is hidden. Fix: Filtering out the lines with empty columns (Load more lines) from the zero lines. Steps: - Open GL (occurs with other reports as well), and open configuration for this report - Set Load more limit to 1, and hide if zero to optional - Go back to GL report and select the 'Hide lines at 0' option -> Load more lines are hidden as long as the zero lines opw-5953725 Forward-Port-Of: odoo/enterprise#109380
Demo Stripe accounts were staying in a restricted state and couldn't be automatically verified due to a document requirement issue. This fix enables users to test the Stripe payment feature in demo mode by adjusting how account verification requirements are handled, allowing the feature to be properly tested before the permanent solution is implemented.
Original PR description
Step to reproduce: - Click on Connect (demo) - The accounts stay Restricted (even after 5m) This is due to the requirement `company.verification.document` which is present as a pending_verification even when no document is given. Giving it a document such as `file_identity_document_success` which should "marks that document requirement as satisfied" also doesn't work. A work-around is to set the business type to individual since they dont have this requirement. This is a temporary fix, as we want to keep a flow similar to what would have been done in reality. But this is preventing users from testing the feature in 19.0 up to master.
This fix resolves an error that occurred when users tried to undo a rescheduled calendar event in the Resource Booking feature. The system was attempting to save invalid data to the database, causing the undo operation to fail. With this fix, users can now successfully undo calendar event changes without encountering errors.
Original PR description
Currently, an error occurs when user tries to undo a calendar event. Steps to replicate: - Install `appointment` with demo data. - Navigate to `Appointments > Schedule > Resource Booking`. - Drag to…
Currently, an error occurs when user tries to undo a calendar event. Steps to replicate: - Install `appointment` with demo data. - Navigate to `Appointments > Schedule > Resource Booking`. - Drag to create a calendar event. - Reschedule the event to a later time (drag and drop forward). - Click Undo on the notification that appears. Error: `ValueError: Invalid field 'originId' in 'calendar.event'` `KeyError: 'originId'` Cause: - The key `originId` was patched in the `getschedule()` [1] and later when user tried to undo the calendar event, the [fallbackschedule] included the key `originId` and made an [orm] call with it. - The [line] tries to write the data into the database where `originId` field doesnt exist and causes the error to occur. Solution: - Remove the `originId` key from `fallbackdata` before the orm call. [1]: https://github.com/odoo/enterprise/blob/e61eef059983bb0cdec4f156fb9283198b379863/appointment/static/src/views/gantt/gantt_renderer.js#L110-L116 [fallbackschedule]: https://github.com/odoo/enterprise/blob/e61eef059983bb0cdec4f156fb9283198b379863/web_gantt/static/src/gantt_renderer.js#L1425 [orm]: https://github.com/odoo/enterprise/blob/e61eef059983bb0cdec4f156fb9283198b379863/web_gantt/static/src/gantt_renderer.js#L1473-L1477 [line]: https://github.com/odoo/enterprise/blob/e61eef059983bb0cdec4f156fb9283198b379863/web_gantt/models/models.py#L248 sentry-7020359653 Forward-Port-Of: odoo/enterprise#100570
The barcode scanning app was crashing when users tried to confirm quantities for archived products. This fix ensures archived products are included in search results, allowing users to successfully add and confirm quantities without errors, maintaining consistent behavior across the app.
Original PR description
Currently, when a user confirms the quantity of an archived product using the product selector in the barcode app, a traceback error occurs. ## Steps to replicate: - Install Inventory - Go to…
Currently, when a user confirms the quantity of an archived product using the product selector in the barcode app, a traceback error occurs. ## Steps to replicate: - Install Inventory - Go to Settings and enable Multi-Step Routes > Set Warehouse Routes. - Configure 2 steps for outgoing shipments. - Go to Inventory and create a new delivery with - **Source Location:** WH/Stock - **Product:** [E-COM10] Pedal Bin with demand 1 - Mark as Todo then Archive the Pedal Bin product. - Open that delivery in barcode app - Pencil icon > +1 > Confirm ## Observed behavior: TypeError: Cannot read properties of undefined (reading 'qty_available') ## Root cause: After this [commit], an override was added to the product selector. As a result, when [2] calls the `search_read` method, it only retrieves non-archived products Consequently, if the result is an empty array, attempting to access `qty_available` causes the type error mentioned above. ## Solution: Adding` active_test = false `to the context ensures that archived products are included in search results. This prevents empty results and avoids the error. It also allows quantities to be added and confirmed,maintaining the same behavior as when using the increment button followed by validation, ensuring consistency. [commit]: https://github.com/odoo/enterprise/commit/6aa814f59f8641d7b57af160e38b50d5bdfc8a97 [2]- https://github.com/odoo/enterprise/blob/e13b44b353e734a6533f7d627ed69b6e7b033ee2/stock_barcode/static/src/js/stock_barcode_sml_form.js#L40-L45 opw-5980428 Forward-Port-Of: odoo/enterprise#112495 Forward-Port-Of: odoo/enterprise#109204
This fix corrects how shifts are split when using the daily view in the planning schedule. Previously, splitting a shift within a single day would incorrectly snap the resulting shifts to standard working hours (8am-5pm), creating duplicate time entries outside the original shift. Now, shifts split within a day are correctly divided at the exact requested time without adding extra hours.
Original PR description
Since odoo/enterprise#69963, splitting a shift in Gantt view snaps the resulting shifts to the standard working hours (e.g., 08:00 to 17:00). This behavior makes sense when splitting a multi-day shift across a day off, where we want to generate a full working day for the day off as well. However, when splitting a shift within a single day (day scale), this behavior is not wanted, otherwise creating two shifts as follows: 1. A shift from [Original Start] to 5pm 2. A shift from 8am to [Original End] Clearly, the shift is duplicated with the wrong timeframes and adding time outside the original shift's hours. This commits ensures that, when splitting a shift in hours (i.e., when using `day` view scale), the shift is appropriately split at the time requested. For instance: 1. A shift from [Original Start] to [Split Time] 2. A shift from [Split Time] to [Original End] task-5387243 Forward-Port-Of: odoo/enterprise#105991
This fix resolves an issue where uploading empty XML files would cause the system to crash with an error. Users can now upload empty XML files without encountering errors, and the system will gracefully skip PDF extraction when file content is missing. This improves the reliability of the document upload process.
Original PR description
Currently an error is generated and the file is not generated when the user uploads an empty XML file (e.g., ref file [1]). Error: `AttributeError: 'bool' object has no attribute 'decode'` This error occurs because the uploaded file contains no raw data. As a result, the system fails to retrieve the file content during PDF extraction from the XML at line [2]. This commit fixes the issue by skipping PDF extraction from the XML when the document has no raw data. The process now returns False early if the document contains no raw content. [1]: https://drive.google.com/file/d/1hRbgEsTL-iWhiAO245z_10HRH6nh3rUQ/view?usp=sharing [2]: https://github.com/odoo/enterprise/blob/00e2e658312eda2d3dae04eb966fd538972e5243/documents_account/models/documents_document.py#L52 sentry-7173452999 Forward-Port-Of: odoo/enterprise#103801
This fix resolves a system error that occurred when creating employee contracts with work schedules that have zero working hours. Previously, the system would crash when trying to calculate hourly wages in these cases. Now the system handles this scenario gracefully, allowing users to create and manage contracts without interruption.
Original PR description
When a working schedule has 0 working hours, creating a contract raises a traceback during hourly wage computation. Steps to reproduce the error: - Install ``l10n_au_hr_payroll`` module - Switch to ``My Australian Company`` - Create a working schedule without any working hours - Create an employee and assign this working schedule > Save - Click on Contracts smart button Traceback: ```py ZeroDivisionError: float division by zero ``` https://github.com/odoo/enterprise/blob/bd746aa43f549c4f7813a849e00447b55e084f21/l10n_au_hr_payroll/models/hr_contract.py#L113-L115 The hourly wage is computed using the working schedule’s hours per day. When this value is 0, it results in the above traceback. sentry-7355577930 Forward-Port-Of: odoo/enterprise#112450 Forward-Port-Of: odoo/enterprise#111629
Fixed an issue where scanning a barcode with a different serial number than the reserved one would incorrectly use the original reserved serial number instead of creating a new lot. Now when processing batches in barcode mode, if a scanned serial number doesn't match the reserved one, the system correctly creates a new lot as configured, ensuring accurate inventory tracking.
Original PR description
Issue ----- When processing batches in barcode, scanning a BC with a different SN than the reserved one does not lead to creating a new lot in stock. The reserved one is still the one getting taken…
Issue
-----
When processing batches in barcode, scanning a BC with a different SN than the reserved one does not lead to creating a new lot in stock. The reserved one is still the one getting taken regardless of setting.
Steps to reproduce
-----
- Enable GS1 nomenclature, lots & batches
- Go to Inventory > Configuration > Operation Types > Delivery Orders
- Enable Lots/Serial Numbers > Create New
- Create a product
- Barcode 23456789012344
- Tracked by SN
- 1 in stock (SN 1234)
- Create a delivery for the product and add it to a batch
- Open the batch in barcode
- Scan 012345678901234410BATCHSN1
- Confirm the delviery
- Go back to the picking and see the lines' details
> The line used the reserved SN
Cause
-----
The existing line gets matched in `_findLine`
https://github.com/odoo/enterprise/blob/45d3a537c3b2eaccee425d959e89d26229e376cd/stock_barcode/static/src/models/barcode_model.js#L1085
because none of the conditions before
https://github.com/odoo/enterprise/blob/45d3a537c3b2eaccee425d959e89d26229e376cd/stock_barcode/static/src/models/barcode_model.js#L1402
get matched. This is unexpected but necessary for batches, as it ensures barcode correctly swaps to the correct picking in the batch. If the line was not matched we would be creating a new line in the same picking than the last scanned line, regardless of which picking the reservation is made in.
Because a line is matched, we have to force its' `lot_id` to `false` so that the new one gets created (`lot_name` is used for display but `lot_id` takes precedence).
-----
Ticket:
opw-5216921
Forward-Port-Of: odoo/enterprise#112210
Forward-Port-Of: odoo/enterprise#109671Fixed an automated test that was failing when running without demo data. The test was being interrupted by a worksheet template wizard that only appears when there's a single worksheet. The fix pre-creates a worksheet before running the test to prevent the wizard from appearing, ensuring the test runs reliably in all scenarios.
Original PR description
When there is only one worksheet, the ‘**Explore Worksheets Using an Example Template**’ wizard opens. Because of this, the test fails without demo data. If we add steps for this wizard, it won’t open when there is more than one worksheet, which will again cause the test to fail. Also, we cannot add this conditon on step. Therefore, to ignore this wizard, i created a worksheet before running the tour so that the wizard does not open. https://github.com/odoo/enterprise/blob/85bd9d80a1a784f1baff1493b2eaec4a17ea9c9b/industry_fsm_report/models/project_task.py#L122-L135 task-4489657 runbot issue-240933 Forward-Port-Of: odoo/enterprise#112469
This fix resolves an issue where shifts in the Planning module remained in draft status even after a rental order was created and confirmed. The shift status now correctly updates to published immediately when a new rental order is created, ensuring the Planning view accurately reflects the current state of shifts and maintaining consistency with other order creation methods.
Original PR description
**Issue 1** **Steps to Reproduce:** Create a shift in Planning. Click New Order. Save and confirm the rental order. Check the shift in Planning it is still in draft. **Issue:** The shift stays in draft even after the rental order is confirmed. **Cause** When creating a rental order from a shift, the shift is not marked as planned. It only gets linked to the order after saving, so it never updates its status. **Fix:** Mark the shift as published when confirming a new rental order. This makes the shift show the correct status right away and keeps it consistent with the “Add to Last Order” button. task-5075839 Forward-Port-Of: odoo/enterprise#99642
This update corrects how the Spanish tax report (Form 347) calculates and displays partner transaction amounts. Previously, negative amounts were incorrectly hidden from the report, and insurance operations were only partially tracked. Now the report correctly shows all partners with significant transactions regardless of whether amounts are positive or negative, and properly separates insurance sales and purchases into distinct sections.
Original PR description
Before this PR: - Partners were only shown if their total was positive and above 3,005.06 €. Negative totals were hidden, even if they were lower than -3,005.06 €. - Insurance operations only took Purchase journal amounts into account. Amounts from Sales journals were ignored, and there was no distinction between the two types of operations. After this PR: - The report now uses the absolute value of the total. Partners with amounts exceeding 3,005.06 €, whether positive or negative, are now shown correctly. - Insurance operations are now divided into two distinct sections: Sales and Purchases. Amounts from both Sales and Purchase journals are now correctly taken into account and reported in their respective sections. task-5214023 Forward-Port-Of: odoo/enterprise#112136 Forward-Port-Of: odoo/enterprise#100413
This update improves the error message that appears when users try to set an upsell start date on or after the next invoice date. The clearer message helps users better understand why their date selection isn't allowed and how to fix it, reducing confusion during subscription management.
Original PR description
Update the error message when an upsell start date is on or after the next invoice date, so it be more clear for the users. task-5893032 Forward-Port-Of: odoo/enterprise#106757
This fix corrects how payment installments are ordered in Peru's electronic invoicing system (EDI). Previously, when invoices had multiple payment installments with different due dates, they could appear in the wrong order in the electronic document if they weren't created in chronological sequence. Now installments are automatically sorted by their due date, ensuring the correct payment schedule is always transmitted to tax authorities.
Original PR description
**Steps to reproduce:**
* Install `l10n_pe_edi`.
* Set SUNAT as the signature provider.
* Create a customer invoice.
* Select a payment term with multiple installments (e.g. 50% (15 days) / 30% (10 days) / 20% (5 days)).
* Confirm the invoice and generate the EDI standard UBL document.
**Observed behavior:**
* The XML `<cac:PaymentTerms>` instalment nodes (Cuota001, Cuota002, etc.) are ordered according to the database insertion order of the receivable lines.
* If the payment term lines are created in a non-chronological order, the installments in the XML mix up the `Cuota` ID, amount, and `PaymentDueDate`.
**Cause:**
* `_add_invoice_payment_terms_nodes` iterates over `invoice.line_ids` to generate the installments, but does not sort the receivable account lines by their `date_maturity`.
**Fix:**
* Explicitly call `.sorted('date_maturity')` on the receivable lines before generating the `invoice_date_due_vals_list`.
opw-6035589This fix ensures that when you change the salesperson assigned to a subscription, the update automatically applies to all contact records associated with that company, not just the main company record. This keeps customer information consistent across the system and eliminates the need for manual updates to individual contacts.
Original PR description
Before this commit, changing the salesperson on a subscription only updated the company partner, leaving child contacts with outdated salesperson info. After this commit, updating the subscription's salesperson also updates all child contacts of the company, ensuring consistency across the portal and reducing manual work. An unit test was added to ensure this behavior. task-5917271 Forward-Port-Of: odoo/enterprise#111499 Forward-Port-Of: odoo/enterprise#108339
Subscription products with zero price on the product form but priced through pricelists can now be added to the cart when the "Prevent Sale of Zero Priced Product" setting is enabled. The fix ensures the system correctly checks pricing information from subscription plans when validating whether a product can be purchased.
Original PR description
A subscription product that has a price of zero on the product form and the price is set on the pricelist instead cannot be added to the cart when the `Prevent Sale of Zero Priced Product` setting is…
A subscription product that has a price of zero on the product form and the price is set on the pricelist instead cannot be added to the cart when the `Prevent Sale of Zero Priced Product` setting is enabled Steps to reproduce: 1. Install eCommerce and Subscriptions 2. Go to Settings and enable `Prevent Sale of Zero Priced Product` 3. Go to Subscriptions > Products and create a new product "subscription" with Sales Price $0.00 and publish it to the website 4. Go to Subscriptions > Pricelists and edit pricelist "Benelux" 5. In the Recurring Prices tab, create a new entry for product "subscription" with a Fixed Price of $20.00 and a monthly Recurring Plan 6. Log in as portal user, go to the shop and look for "subscription" (pricelist "Benelux" should be selected) 7. Try to add it to the cart 8. Nothing happens and an error is displayed in the log Issue: When we check if a product can be added to the cart https://github.com/odoo/odoo/blob/b1f4647313eb2dbdbbe98b51649604b4e650a8aa/addons/website_sale/controllers/cart.py#L116-L120 we do not use the plan_id specified in kwargs We reach this code https://github.com/odoo/odoo/blob/b1f4647313eb2dbdbbe98b51649604b4e650a8aa/addons/website_sale/models/product_product.py#L146-L147 which will prevent the addition of a product in the cart if the option `prevent_zero_price_sale` is enabled and if `_get_contextual_price` returns zero Calling `_get_contextual_price` tries to find a `product.pricelist.item` by building a domain in `_get_applicable_rules_domain` but calling this method without a plan_id eventually reaches https://github.com/odoo/enterprise/blob/252c5ab78b51d0d2f06178cf92f0489b4a46958f/sale_subscription/models/product_pricelist.py#L69-L72 which restricts the domain to pricelists that are not subscription plans Therefore, we cannot find any pricelist that applies to the product and we consider that the product cannot be added to the cart Solution: We need to use the plan_id selected by the customer in order to correctly check if a product can be added to the cart. Use the plan_id in kwargs to update the request context so we can check if a product can be added to the cart according to the plan_id the user has selected. Use this plan_id in `_get_applicable_rules` in order to correctly select the applicable `product.pricelist.item`. opw-5993614
This fix resolves two issues when setting up recurring prices for subscription products in a multi-company environment. Users can now successfully add recurring price lines without encountering company inconsistency errors, and recurring plans with specific company assignments now appear correctly in the selection list.
Original PR description
## Issues When adding a line in the *Recurring prices* tab (`product.pricelist.item`) of a product with a `company_id`, a "company inconsistencies" error appears. Also, recurring plans with their…
## Issues When adding a line in the *Recurring prices* tab (`product.pricelist.item`) of a product with a `company_id`, a "company inconsistencies" error appears. Also, recurring plans with their *Company* field set do not appear in the list of recurring plans when adding a line in the *Recurring prices* tab. ## Steps to reproduce 1. Install *Subscription* (`sale_subscription`) 2. Create a second company 3. Create a subscription product and set a company in the *Company* field (`company_id`). 4. In the *Recurring prices* tab, add a line (any recurring plan, any price) 5. **An _Invalid Operation_ error appears: _"Uh-oh! You’ve got some company inconsistencies here"_** For the second issue, after the same 3 first steps: 1. Create a *Recurring Plan* RP with its *Company* field set to the current company 2. On the *Recurring prices* tab of the subscription product, try to add a line with the Recurring plan RP 3. **The Recurring plan RP is missing from the list of available plans.** ## Cause When adding a line to the *Recurring prices* tab, a new `product.pricelist.item` is created, with no `pricelist_id`. The `ProductPricelistItem._compute_company_id` from `sale_subscription` filters out the items that don't have a `pricelist_id`, which is the case for the line we create. Also, the (potentially new) plan has no `company_id` in most cases. https://github.com/odoo/enterprise/blob/ccab0c261040ed995d12dca891caae9596bbe1eb/sale_subscription/models/product_pricelist_item.py#L18-L26 By filtering the items with no `pricelist_id`, nothing is passed to the `super()._compute_company_id`, even though it would also handle cases where the item has a `product_tmpl_id`: https://github.com/odoo/odoo/blob/9c8112d794af1ba84ade8af124967495c2ff8995/addons/product/models/product_pricelist_item.py#L170-L173 opw-5981629 opw-6051978
A test in the Knowledge module was failing when demo data was enabled because it used a hardcoded sequence number that didn't account for additional articles created by the system. The fix now calculates the expected sequence number dynamically based on actual data, ensuring tests pass consistently regardless of demo data settings.
Original PR description
In the `test_article_create` test, a new article is created without specifying a parent and sequence number. The test then asserts the sequence number assigned to this article using a constant. When no sequence number is provided, the system automatically assigns one by taking the highest existing sequence among articles with the same parent and incrementing it by 1. When demo data is enabled, additional users are created along with their corresponding onboarding articles. As the onboarding articles does not have any parent, the onboarding article are included in the computation of the sequence number of the new article we create in the test. These extra articles impacts the sequence number of the new article, causing the test assertion to fail. To resolve this, the test computes the expected sequence number dynamically based on the current state of the data. This ensures consistent behavior regardless of whether demo data is present. runbot-error-id~231695
7 changes
Resolved issues and error corrections
This fix corrects the indicators used when exporting Spanish tax declarations (Mod 347) to the AEAT tax authority. Previously, the system incorrectly used 'X' for both substitutive and complementary declarations, causing AEAT to reject the files. Now it correctly uses 'C' for complementary and 'S' for substitutive declarations, ensuring tax reports are properly recognized by the Spanish tax authority.
Original PR description
Currently, the BOE export for `Mod 347` uses incorrect indicators for `Substitutive` and `Complementary declarations`. **Steps to reproduce:** - Install the `l10n_es_reports` module and switch to the…
Currently, the BOE export for `Mod 347` uses incorrect indicators for `Substitutive` and `Complementary declarations`. **Steps to reproduce:** - Install the `l10n_es_reports` module and switch to the `ES company` - Navigate to Accounting > Reporting > Tax Report - From the smart button, select `Report: Tax Report (Mod 347) (ES)` - Download the BOE file using the dropdown. - In the wizard: - Enable `Substitutive Declaration` or `Complementary Declaration` - Set `Previous Report Number` (e.g., 123456789) - Click `Generate BOE` - Upload the generated .txt file to the `AEAT portal`. (AEAT credentials are required) **Observation:** AEAT does not recognize 'X' as a valid indicator for substitutive or complementary declarations and interprets the file as a standard return. **Root Cause:** At [1], the BOE Mod 347 generation writes 'X' for both substitute and complementary declarations. **Fix:** This commit ensures the file contains correct indicators: - 'C' for `complementary declarations` - 'S' for `substitute declarations` This aligns Modelo 347 with AEAT specifications and ensures consistency with the implementation of Modelo 349 at [2]. Ref: https://sede.agenciatributaria.gob.es/Sede/en_gb/ayuda/consultas-informaticas/declaraciones-informativas-ayuda-tecnica/modificar-declaracion-informativa-mediante-fichero.html [1]: https://github.com/odoo/enterprise/blob/c5332bef593cc3fa1b5013a0dac56ccd67e4da14/l10n_es_reports/models/aeat_tax_reports.py#L1061-L1062 [2]: https://github.com/odoo/enterprise/blob/c5332bef593cc3fa1b5013a0dac56ccd67e4da14/l10n_es_reports/models/aeat_tax_reports.py#L1490-L1491 opw-6048711 Forward-Port-Of: odoo/enterprise#112566
This fix corrects a bug in the subscription product management system where users could incorrectly change the "Recurring" setting on products that have active orders. Previously, rapid clicks on the setting could bypass the intended protection. The fix now properly validates against the server's current value instead of the form's temporary state, ensuring the system correctly prevents unauthorized changes.
Original PR description
**Problem:** When attempting to change "Recurring" on products in the form view, if there are confirmed SOs, the change should be reverted and a message should appear explaining this. However, there is a bug in how the change is reverted where it takes the current form value of the field. This cannot be trusted as it's possible to trigger another onchange before the first one resolves, so the second onchange is based on the wrong value. **Steps to Reproduce:** - w/Demo Data, go to product "Office Cleaning Service (SUB)" (This is a subscription product which has confirmed SOs) - Quickly click the checkbox for "Recurring" twice -> Two warnings appear, but Recurring is False and can be saved **Solution:** Instead of reading the current form value and setting its opposite, we can revert to the current value on the server. Forward-Port-Of: odoo/enterprise#110877
This update resolves a memory leak issue in the Account Reports module where the system was continuously preloading sections without stopping, preventing the system from freeing up memory. The fix ensures that preloading stops when the report component is closed, allowing the system to properly clean up and reclaim memory resources.
Original PR description
The preloading of sections would never stop, this is an issue since this would prevent the garbage collector from collecting this big class and all it's objects. We fix this by making sure to stop the reploading when the component is destroyed. It's important to do it this way rather than clearing the timeout as the destruction could happened when the report is loading so the timeout would be unset and a new one would be started. Forward-Port-Of: odoo/enterprise#112628
This fix resolves an issue where closing a POS session with only future orders (orders with scheduled delivery dates) would fail to generate the required accounting records. The system was incorrectly excluding all future orders instead of just unpaid ones, preventing proper financial tracking. Now, paid future orders are correctly included in the account move when sessions are closed.
Original PR description
Before this commit, when all orders coming from Urban Piper in a POS session are paid future orders (i.e. have a delivery_datetime), closing the session would not generate an account move. The cause was that the code was excluding future orders when creating the account move. The fix is to exclude only unpaid orders instead. How to reproduce: - Set up Urban Piper (a test account needed). - Place an order from the Urban Piper platform. - Receive the order, accept it, and mark it as ready. - Close the session. - The session will not have an account move. opw-5995985
This fix resolves an error that occurred when opening the "Move to Work Center" dialog in the Shop Floor interface. The dialog component was incorrectly requiring a function parameter that isn't always needed, causing the system to crash in debug mode. By making this parameter optional, the dialog now works correctly whether it loads work centers on-demand or uses pre-loaded data.
Original PR description
**Steps to reproduce:** * Install the *Manufacturing (`mrp`)* module. * Enable *developer (debug) mode*. * Open the *Shop Floor* interface. * Select work center as `Assembly 1` * In the bottom-right…
**Steps to reproduce:**
* Install the *Manufacturing (`mrp`)* module.
* Enable *developer (debug) mode*.
* Open the *Shop Floor* interface.
* Select work center as `Assembly 1`
* In the bottom-right corner, click the *gear icon*.
* Select **Move to Work Center** from the *gear icon*.
**Observed behavior:**
* A traceback occurs when opening the *Move to Work Center* dialog.
* The following Owl error is raised:
`OwlError: Invalid props for component 'MrpWorkcenterDialog': 'loadWorkcenters' is missing (should be a function)
Error: Invalid props for component 'MrpWorkcenterDialog': 'loadWorkcenters' is missing (should be a function)`
**Cause:**
* `MrpWorkcenterDialog` is opened in *two different ways*:
https://github.com/odoo/enterprise/blob/7805022e77ff80a74563b7ff0032d8975c00b709/mrp_workorder/static/src/mrp_display/mrp_display.js#L469-L480
* One caller opens the dialog and provides `loadWorkcenters`.
In this flow, the dialog fetches work centers by calling this
function.
https://github.com/odoo/enterprise/blob/7805022e77ff80a74563b7ff0032d8975c00b709/mrp_workorder/static/src/mrp_display/dialog/mrp_menu_dialog.js#L68-L76
* Another caller opens the dialog and directly provides a
`workcenters` list. In this flow, the dialog already has the data
and does not need `loadWorkcenters`.
* Therefore, the real behavior is that `loadWorkcenters` is only
required *sometimes*, not always.
* However, the component props defined it as mandatory:
`loadWorkcenters: { type: Function }`
* In *debug mode*, Owl strictly validates component props by comparing
what the component declares in `static props` with what the caller
provides. When the dialog is opened without `loadWorkcenters`, Owl
detects that a required prop is missing and raises an
*Invalid props* error.
**Fix:**
* Mark `loadWorkcenters` as *optional* in the component props so the
dialog works correctly in both supported flows:
* Lazy loading of work centers via `loadWorkcenters`.
* Using preloaded `workcenters` data.
---
opw-6010261Ecuador's withholding tax percentages have been updated for 2026 in compliance with the new government resolution. The system's automated tests have been updated to reflect these new tax rates, ensuring accurate tax calculations and reporting for Ecuadorian businesses using the electronic invoicing and tax reporting features.
Original PR description
In accordance with the implementation of the new withholding tax percentages according to "Resolución N.º NAC-DGERCGC26-00000009" for Ecuador, following internal implementation guidelines by TRESCLOUD. Unit tests are updated to be based on the new withholding percentages. BP #110343 Forward-Port-Of: odoo/enterprise#110712
This fix resolves an issue where customer discounts were being applied twice when creating sales orders from field service tasks. Previously, discounted prices were being set as the unit price and then discounted again at the sales order line level, resulting in incorrect final prices. The fix ensures discounts are applied only once by using the correct pricing logic based on whether discounts are enabled in settings.
Original PR description
Currently, when the user creates a task for a customer with a discount pricelist, the discount is applied twice for the service. <h2>Steps to produce:</h2> * Install `industry_fsm_sale` and enable…
Currently, when the user creates a task for a customer with a discount pricelist, the discount is applied twice for the service. <h2>Steps to produce:</h2> * Install `industry_fsm_sale` and enable `Discounts` and `Pricelists` in settings. * Create a pricelist with a price rule of type discount that applies 10 percent discount to every product. * Go to Customers > Acme Corporation > Sales & Purchase and set the pricelist. * Go to Field Service > Create a Task, and set `Customer` to Acme Corporation. * Add a timesheet with Time Spent 1 > Mark the task as Done > Sale Order <h2>Observed behavior:</h2> The discount is applied twice to the product on SO: **Product**: Service on Timesheets **Unit Price**: `$40` (excluding tax) **First discount:** The 10 percent discount on the unit price of the product. Product unit price is set from `$40 -> $36 ` **Second discount:** The 10 percent discount on the SO line itself. `$36 -> $32.4 ` The untaxed amount is: `$32.40` which should be `$36.00` <h2>Root cause:</h2> This happens because, at line [1], the unit price is already set to the final price from the pricelist when the sale order line is created. Since discounts are enabled, [2] applies an additional discount to that same price, causing the discount to be applied twice. <h2>Solution:</h2> When creating the sales order: * **Discount setting is on:** use list price so the discount is applied from the sales order. * **Discount setting is off:** set the product unit price to the discounted price. [1]- https://github.com/odoo/enterprise/blob/224d2453cc975a3e333825370beaf30d27d89f10/industry_fsm_sale/models/project_task.py#L658 [2]- https://github.com/odoo/odoo/blob/76717e588bfd012b42e859bfc829257d899c6165/addons/sale/models/sale_order_line.py#L788 opw-5432088
3 changes
Resolved issues and error corrections
This fix corrects the indicators used when exporting Spanish tax declarations (Modelo 347) to the AEAT tax authority. Previously, the system incorrectly used 'X' for both substitutive and complementary declarations, causing AEAT to reject the files. Now it properly uses 'C' for complementary and 'S' for substitutive declarations, ensuring tax reports are correctly recognized by the Spanish tax authority.
Original PR description
Currently, the BOE export for `Mod 347` uses incorrect indicators for `Substitutive` and `Complementary declarations`. **Steps to reproduce:** - Install the `l10n_es_reports` module and switch to the…
Currently, the BOE export for `Mod 347` uses incorrect indicators for `Substitutive` and `Complementary declarations`. **Steps to reproduce:** - Install the `l10n_es_reports` module and switch to the `ES company` - Navigate to Accounting > Reporting > Tax Report - From the smart button, select `Report: Tax Report (Mod 347) (ES)` - Download the BOE file using the dropdown. - In the wizard: - Enable `Substitutive Declaration` or `Complementary Declaration` - Set `Previous Report Number` (e.g., 123456789) - Click `Generate BOE` - Upload the generated .txt file to the `AEAT portal`. (AEAT credentials are required) **Observation:** AEAT does not recognize 'X' as a valid indicator for substitutive or complementary declarations and interprets the file as a standard return. **Root Cause:** At [1], the BOE Mod 347 generation writes 'X' for both substitute and complementary declarations. **Fix:** This commit ensures the file contains correct indicators: - 'C' for `complementary declarations` - 'S' for `substitute declarations` This aligns Modelo 347 with AEAT specifications and ensures consistency with the implementation of Modelo 349 at [2]. Ref: https://sede.agenciatributaria.gob.es/Sede/en_gb/ayuda/consultas-informaticas/declaraciones-informativas-ayuda-tecnica/modificar-declaracion-informativa-mediante-fichero.html [1]: https://github.com/odoo/enterprise/blob/c5332bef593cc3fa1b5013a0dac56ccd67e4da14/l10n_es_reports/models/aeat_tax_reports.py#L1061-L1062 [2]: https://github.com/odoo/enterprise/blob/c5332bef593cc3fa1b5013a0dac56ccd67e4da14/l10n_es_reports/models/aeat_tax_reports.py#L1490-L1491 opw-6048711
This fix corrects an overly strict warning that appeared when generating payslips for employees whose contracts partially overlap with the payslip period. Previously, the system required the contract to fully contain the payslip dates; now it correctly allows payslip generation as long as there is at least one day of overlap between the contract and payslip period. This resolves false warnings that prevented legitimate payslip processing.
Original PR description
[FIX] hr_payroll: fix payslip warning bug Bug reproduction: 1 - Select Hong Kong (actually there is nothing about Hong Kong, you can select other companies as well) 2 - Create an employee and make…
[FIX] hr_payroll: fix payslip warning bug
Bug reproduction:
1 - Select Hong Kong (actually there is nothing about Hong Kong, you can select other companies as well)
2 - Create an employee and make its contract from 01-01-2025 to 05-03-2026 (DD/MM/YYYY) format.
3 - Generate payslip for March, the warning of "The period selected does not match the contract validity period" popups.
4 - But we do not want that, even though there is 1 overlapping day in contract with payslip we can continue.
Bug cause:
1 - In >= v.17 (not in v.19), there was a warning, when the contract dates do not fully contains the payslip dates, the warning was appearing.
2 - In v.19 it is not the case, when there is a contract that overlaps at least one dat of the payslip then we are fine, if no overlap then no contract on payslip warning should appear
Bug solution:
1 - I replaced old warning "The period selected does not match the contract validity period" with the one in v.19 "No running contract over payslip period"
Tests:
1 - There was a unit test about old warning (test_payslip_warnings), I changed that parts.
2 - I added further steps to the existing test about the new warning that should appear (No running contract over payslip period)
Note: Implemented feature: need to check what happens after v.17, should be removed in v.19 latest, maybe before as well.
task - 6006693The account reports feature had a memory leak where background data loading would continue indefinitely, preventing the system from freeing up memory. This fix ensures the loading process stops when the report is closed, allowing the system to properly reclaim memory and improve overall application performance.
Original PR description
The preloading of sections would never stop, this is an issue since this would prevent the garbage collector from collecting this big class and all it's objects. We fix this by making sure to stop the reploading when the component is destroyed. It's important to do it this way rather than clearing the timeout as the destruction could happened when the report is loading so the timeout would be unset and a new one would be started.