Daily updates from Odoo
Monday, September 22, 2025
69 changes
8 changes
Resolved issues and error corrections
This fix stops customers from editing rental dates after a rental product has already been added to the cart. It prevents checkout-disrupting errors when invalid date ranges are entered and keeps rental orders consistent.
Original PR description
An error currently occurs when an user attempts to change the rental start date to a value later than the end date while a product is already in the cart. **Steps to replicate:** * Install…
An error currently occurs when an user attempts to change the rental start date to a value later than the end date while a product is already in the cart. **Steps to replicate:** * Install `website_sale`, `stock` , `sale_renting` with demo data * Rental > Products > Printer > Sales > Turn `Out of stock: continue selling` off * Website > Shop > Printer > Select dates when printer is available * Add printer to cart > Set start date greater than end date by typing `ValueError: min() iterable argument is empty` **Cause:** This error occurs because [1] causes the `availabilities` list to be empty at [2] when retrieving combination information. This issue occurs in version `18.4` and later because the date picker remains editable after the product is added to the cart. The changes in [3] remove the `disabled` attribute after the product is added, allowing users to modify the date. **Solution:** * Prevent users from editing dates after a product is added to the cart, as done in version `18.3`, since all products must share the same dates as the one already in the cart, as specified in [4]. [1]: https://github.com/odoo/enterprise/blob/246a49ff3fd2baa636f3e7d80a75a01e77060ee1/website_sale_stock_renting/models/product_product.py#L79 [2]: https://github.com/odoo/enterprise/blob/246a49ff3fd2baa636f3e7d80a75a01e77060ee1/website_sale_stock_renting/models/website.py#L14-L19 [3]: https://github.com/odoo/odoo/commit/bbb2d98d9ab97ce729d59b9858b63daccf5434e2#diff-39e02d03a8b765b4e3afc68627aeb33f11b587163638fedfb92ed5657c3336e7R230 [4]: https://github.com/odoo/enterprise/blob/246a49ff3fd2baa636f3e7d80a75a01e77060ee1/website_sale_renting/views/templates.xml#L100 **Sentry-6803401968**
Fixed an issue where Saudi Arabia invoice PDFs could omit the company logo when another localization module was installed. This ensures printed invoices keep the correct branding and presentation for customers.
Original PR description
steps to reproduce: ------------------- 1. Install `l10n_sa_edi` and `l10n_latam_invoice_document` 2. Create and confirm an invoice. 3. Print the invoice PDF issue: ------ The company logo is not…
steps to reproduce:
-------------------
1. Install `l10n_sa_edi` and `l10n_latam_invoice_document`
2. Create and confirm an invoice.
3. Print the invoice PDF
issue:
------
The company logo is not printed on the invoice PDF.
cause of the issue:
-------------------
The `l10n_latam_invoice_document` hides the standard company logo if
`company_header` is set to true:
https://github.com/odoo/odoo/blob/0f6cb037e05db86e808682659a12442464b2cdd2/addons/l10n_latam_invoice_document/views/report_templates.xml#L6-L8
In the case of `l10n_sa`, the custom_header value is set because of this condition:
https://github.com/odoo/odoo/blob/0f6cb037e05db86e808682659a12442464b2cdd2/addons/l10n_sa/views/report_invoice.xml#L23
However, the condition in `l10n_latam_invoice_documnet` expects
a callable record instead of static XML data, which is incorrect:
https://github.com/odoo/odoo/blob/022fcbcf40a28afa56010f6130c26bb0503d5467/addons/l10n_latam_invoice_document/views/report_templates.xml#L9-L14
solution:
---------
Renaming the variable to `custom_header_sa` resolves the issue.
<details>
<summary>Click here to see:</summary>
Before:
<img src="https://github.com/user-attachments/assets/f4606a44-10ce-4038-92a3-2c8ec2a69edf"/>
After:
<img src="https://github.com/user-attachments/assets/70055155-63f2-4fec-aaf6-3bf5587f5591"/>
</details>
opw-4977422
Forward-Port-Of: odoo/odoo#225476This fixes bus notifications so users receive updates for both their direct groups and any groups they inherit through roles. It prevents cases where administrators or other users with implied permissions missed automatic Discuss channel updates until manually reloading.
Original PR description
To target users of a group, bus notifications are sent on group records. To do so, user groups are added to its bus subscription. However, since odoo/odoo#179354, only explicit groups are added, not every implied group. It's incorrect. For example, sending on the user channel doesn't notify administrators while it should. Steps to reproduce (note that the steps are only working for admin): - Click the gear button on the sidebar in discuss page to navigate to the channel kanban view as admin - Click the `New` button and create a channel with an internal users group as `Auto Subscribe Groups` - Go back to the discuss main page. The new channel will not be pinned unless you reload the page See: https://github.com/odoo/odoo/pull/179354/files#r1954163704 Forward-Port-Of: odoo/odoo#217543
Importing spreadsheet files no longer fails when text fields contain values that look like dates. This helps users re-import exported records, such as pricelists, without errors caused by automatic spreadsheet date formatting.
Original PR description
*: test_import_export ### Steps to reproduce: - Go to Sales/Prodcuts/Pricelists - Create a new pricelist with a rule with a set Valid Period - Export that record adding the Pricelist Rule/Start Date…
*: test_import_export ### Steps to reproduce: - Go to Sales/Prodcuts/Pricelists - Create a new pricelist with a rule with a set Valid Period - Export that record adding the Pricelist Rule/Start Date (item_ids/date_start) as XLSX format - Delete the record and test the import the XLSX file #### Uncaught Promise: > Invalid props for component 'ImportDataColumnError' :'resultNames' is undefined (should be a array) ### Cause of the Issue: The issue is raised by the error message: https://github.com/odoo/odoo/blob/32bdff8bc603a03038d3f9e38463809883319305/addons/base_import/models/base_import.py#L1428-L1432 which is not properly handled by the `ImportDataColumnError` component. However, in the present situation, the issue is just that this error message itself should not be raised in the first place. #### Details: Since commit 630b2683d3aad203b0bbf7d2d63b88cd4d3bd9d7, date and datetime formatted cells in spreadsheets are no longer Char field. Instead, they are imported as date and datetime objects. This was intended to allow importing columns with mixed encodings (e.g., some values stored as strings, others as dates in the spreadsheet). However, a side effect of this change is that if a char-type field contains values that a spreadsheet interprets as dates or datetimes, the import fails. For example, an account move name "21/12/2025" may be interpreted as a date. Attempting to perform a join on this string expected value causes a traceback here: https://github.com/odoo/odoo/blob/32bdff8bc603a03038d3f9e38463809883319305/addons/base_import/models/base_import.py#L1628-L1632 To address this discrepancy, commit 91dca74b3e395c8ee410db18784990ba3a6a7e6e introduced a check raising an error if the imported field type is not appropriate to carry a `date/datetime` value. This fix has two major issues: 1) It still does not handle the above use case correctly—it remains impossible to import "21/12/2025" as a record name. 2) (The present issue) It does not properly check the type of related fields. For example, a field like "company_id/partner_id/membership_start" is not considered as an allowed date field. The current check on allowed date fields being overly simplistic: https://github.com/odoo/odoo/blob/32bdff8bc603a03038d3f9e38463809883319305/addons/base_import/models/base_import.py#L1416-L1421 ### Fix: We propose reverting commit 91dca74b3e395c8ee410db18784990ba3a6a7e6e. And instead of recursively computing the related model and the appropriate types of related fields (including property-type relational fields), we will simply stringify values when they are written into char-like fields (e.g., char or text). Note: this may also require an adjustment in master for the html type. opw-4935423 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#226807
The Danish minimal balance sheet and profit and loss reports were corrected so report formulas no longer include extra signs that could produce wrong values. Report labels and translations were also cleaned up for clearer, more consistent presentation.
Original PR description
In the minimal reports of l10n_dk, it appears that some expression ended with a sign and the report engine was given wrong value. This commit will remove the extra sign to correct the report and also remove the letter or number before the name. This commit will remove the extra sign to correct the report and also remove the letter or number before the name. This commit will change the translation accordingly to the other commits task-4949062 Forward-Port-Of: odoo/enterprise#94350 Forward-Port-Of: odoo/enterprise#91135
Date filters in timesheet forecasting now handle local time zones correctly. This prevents records from being missed or incorrectly included for users in time zones ahead of or behind UTC, improving report accuracy.
Original PR description
This commit fixes the timezone issues with the Date filters, in which we were comparing a UTC DateTime value to a local timezone's Date. In certain timezones, this leads to off-by-one errors in the records fetched from the DB, depending on how far ahead or behind UTC that timezone is. Specifically, we remove the UTC conversion within the filter domains. opw-5068870 Forward-Port-Of: odoo/enterprise#94032
Timesheet date filters now use the user's local date instead of a UTC timestamp. This prevents entries from appearing under the wrong day or week for users in time zones where the previous behavior caused off-by-one date shifts.
Original PR description
This commit fixes issues with the timesheet Date filters, in which the `date` field of account.analytic.line records, which is stored as the local timezone's date, is being compared to a UTC DateTime value. This leads to off-by-one errors. For example, if you are in Berlin and try to filter for all timesheet entries from "Today", you will only find entries from the previous day. Similarly, for the "This Week" and "Last Week" filters, which would be shifted by one day. The filter domains have been changed to compare the `date` to the local timezone's "today". opw-5003310 Forward-Port-Of: odoo/odoo#225753
Website form file upload fields now respect the configured maximum number of files. This lets visitors upload multiple files when allowed, while preventing invalid limits below one.
Original PR description
Steps to Reproduce: - Open the website module. - Drop a basic form snippet. - Change the field type of any field to 'File Upload'. - Set the `Max # of files` to any value greater than 1 and save the changes. - Attempt to upload more than one file. Observed Issue: Users are unable to upload more than one file. Before this commit: The `Max # of files` option available in the snippet settings had no effect. Even when set to more than one, the file input would only allow replacing the previously uploaded file, preventing users from adding multiple files. After this commit: The `Max # of files` setting now functions as intended. When the limit is set to more than one, users can select multiple files, up to the configured limit and within the maximum file size. If the limit is set to one, users can only upload a single file. task-4626847 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
11 changes
Resolved issues and error corrections
Odoo now blocks invalid custom view changes before they can be saved. This prevents Web Studio from failing to open when a malformed customization is entered through technical settings, reducing disruption for users managing forms.
Original PR description
This error occurs when a user modifies a Studio-generated custom form view by updating it through the technical settings and adds an invalid XPath expression. As a result, Web Studio fails to open and load the view. **Steps to replicate:** * Install `contacts` and `web_studio` * Open form view for any contact and Add/remove any field using studio. * Go to technical>User Interface>Views> `Odoo Studio:res.partner.form customization` * Add the following line:`<xpath expr='/form[1]/field[6]'/>` inside data and save. * Go to contact form view and open studio. `ValueError:The element <xpath expr='/form[1]/field[6]'/> cannot be located in the main view` **Solution** * Prevent users from saving changes to a view by raising a validation error when an invalid XPath expression is detected. **Sentry-6678221213**
This fixes an issue where Saudi Arabia invoice PDFs could print without the company logo when certain localization modules were installed together. Businesses using Saudi invoicing get properly branded customer invoices again, improving document presentation and consistency.
Original PR description
steps to reproduce: ------------------- 1. Install `l10n_sa_edi` and `l10n_latam_invoice_document` 2. Create and confirm an invoice. 3. Print the invoice PDF issue: ------ The company logo is not…
steps to reproduce:
-------------------
1. Install `l10n_sa_edi` and `l10n_latam_invoice_document`
2. Create and confirm an invoice.
3. Print the invoice PDF
issue:
------
The company logo is not printed on the invoice PDF.
cause of the issue:
-------------------
The `l10n_latam_invoice_document` hides the standard company logo if
`company_header` is set to true:
https://github.com/odoo/odoo/blob/0f6cb037e05db86e808682659a12442464b2cdd2/addons/l10n_latam_invoice_document/views/report_templates.xml#L6-L8
In the case of `l10n_sa`, the custom_header value is set because of this condition:
https://github.com/odoo/odoo/blob/0f6cb037e05db86e808682659a12442464b2cdd2/addons/l10n_sa/views/report_invoice.xml#L23
However, the condition in `l10n_latam_invoice_documnet` expects
a callable record instead of static XML data, which is incorrect:
https://github.com/odoo/odoo/blob/022fcbcf40a28afa56010f6130c26bb0503d5467/addons/l10n_latam_invoice_document/views/report_templates.xml#L9-L14
solution:
---------
Renaming the variable to `custom_header_sa` resolves the issue.
<details>
<summary>Click here to see:</summary>
Before:
<img src="https://github.com/user-attachments/assets/f4606a44-10ce-4038-92a3-2c8ec2a69edf"/>
After:
<img src="https://github.com/user-attachments/assets/70055155-63f2-4fec-aaf6-3bf5587f5591"/>
</details>
opw-4977422
Forward-Port-Of: odoo/odoo#225476Bus notifications now include both direct and inherited user groups when deciding who should receive real-time updates. This ensures administrators and other users with implied group access see new auto-subscribed Discuss channels immediately without needing to reload.
Original PR description
To target users of a group, bus notifications are sent on group records. To do so, user groups are added to its bus subscription. However, since odoo/odoo#179354, only explicit groups are added, not every implied group. It's incorrect. For example, sending on the user channel doesn't notify administrators while it should. Steps to reproduce (note that the steps are only working for admin): - Click the gear button on the sidebar in discuss page to navigate to the channel kanban view as admin - Click the `New` button and create a channel with an internal users group as `Auto Subscribe Groups` - Go back to the discuss main page. The new channel will not be pinned unless you reload the page See: https://github.com/odoo/odoo/pull/179354/files#r1954163704 Forward-Port-Of: odoo/odoo#217543
Duplicate detection now ignores company differences when a database only has one company. This lets users find and merge duplicate records that were previously missed, improving data cleanup accuracy.
Original PR description
**Issue** In single company databases, it wasn't possible to find duplicate records with different `company_id` values to merge them (in multi company databases, it is possible to enable the "Cross-Company" option on the deduplication rule). **Change** Always ignore the company field in single company databases. opw-4794408 Forward-Port-Of: odoo/enterprise#94797 Forward-Port-Of: odoo/enterprise#93184
This fix prevents certain Spanish balance sheet accounts from being counted twice in the “Other current payables” section. As a result, companies using the Spanish SME balance sheet report will see more accurate liability totals that better match their accounting records.
Original PR description
In **`balance_pymes_line_32300`** (`CURRENT LIABILITIES > Current payables > Other current payables`), amounts are **doubled** because account **551** is included twice. * **Formula using…
In **`balance_pymes_line_32300`** (`CURRENT LIABILITIES > Current payables > Other current payables`), amounts are **doubled** because account **551** is included twice.
* **Formula using `account_codes`:**
```xml <field name="formula">-1034 - 1044 - 190 - 192 - 194 - 500 - 501 - 505 ...551 - 5566 - 5595 - 5598 - 560 - 561 - 569</field> ```
→ Explicitly includes account **551**.
* **Formula using `domain`:**
```xml <field name="formula" eval="['|', ('account_id.code','=like','550%'), '|', ('account_id.code','=like','551%'), '|', ('account_id.code','=like','554%'), ('account_id.code','=like','5525%')]"/> ```
→ Includes **all accounts starting with 551**, so **551** is also counted here.
This overlap causes the balance to be counted twice, inflating the reported value.
**steps to reproduce:**
1. With a Spanish company, go to **Accounting > Dashboard > Bank > Transaction > New**.
2. Select an account, search for **55100**, and add it.
3. Go to **Reporting > Balance Sheet > Other current payables**.
4. Notice that the reported amount is **double** the actual accounting data.
Overlapping formulas: specific account `551` and `5525` are counted in `account_codes`, while the `domain` formula already includes `551%`, leading to duplication.
**Fix**
Remove explicit account codes from `account_codes` if they are already covered by the `domain` prefixes to avoid double-counting. and also made sure to correct the same issue in the whole report.
opw-5075035Fixed an issue where importing spreadsheets could fail when text fields contained values that looked like dates, or when related date fields were used. This makes XLSX imports more reliable for records such as pricelists, product data, and names that may resemble dates.
Original PR description
*: test_import_export ### Steps to reproduce: - Go to Sales/Prodcuts/Pricelists - Create a new pricelist with a rule with a set Valid Period - Export that record adding the Pricelist Rule/Start Date…
*: test_import_export ### Steps to reproduce: - Go to Sales/Prodcuts/Pricelists - Create a new pricelist with a rule with a set Valid Period - Export that record adding the Pricelist Rule/Start Date (item_ids/date_start) as XLSX format - Delete the record and test the import the XLSX file #### Uncaught Promise: > Invalid props for component 'ImportDataColumnError' :'resultNames' is undefined (should be a array) ### Cause of the Issue: The issue is raised by the error message: https://github.com/odoo/odoo/blob/32bdff8bc603a03038d3f9e38463809883319305/addons/base_import/models/base_import.py#L1428-L1432 which is not properly handled by the `ImportDataColumnError` component. However, in the present situation, the issue is just that this error message itself should not be raised in the first place. #### Details: Since commit 630b2683d3aad203b0bbf7d2d63b88cd4d3bd9d7, date and datetime formatted cells in spreadsheets are no longer Char field. Instead, they are imported as date and datetime objects. This was intended to allow importing columns with mixed encodings (e.g., some values stored as strings, others as dates in the spreadsheet). However, a side effect of this change is that if a char-type field contains values that a spreadsheet interprets as dates or datetimes, the import fails. For example, an account move name "21/12/2025" may be interpreted as a date. Attempting to perform a join on this string expected value causes a traceback here: https://github.com/odoo/odoo/blob/32bdff8bc603a03038d3f9e38463809883319305/addons/base_import/models/base_import.py#L1628-L1632 To address this discrepancy, commit 91dca74b3e395c8ee410db18784990ba3a6a7e6e introduced a check raising an error if the imported field type is not appropriate to carry a `date/datetime` value. This fix has two major issues: 1) It still does not handle the above use case correctly—it remains impossible to import "21/12/2025" as a record name. 2) (The present issue) It does not properly check the type of related fields. For example, a field like "company_id/partner_id/membership_start" is not considered as an allowed date field. The current check on allowed date fields being overly simplistic: https://github.com/odoo/odoo/blob/32bdff8bc603a03038d3f9e38463809883319305/addons/base_import/models/base_import.py#L1416-L1421 ### Fix: We propose reverting commit 91dca74b3e395c8ee410db18784990ba3a6a7e6e. And instead of recursively computing the related model and the appropriate types of related fields (including property-type relational fields), we will simply stringify values when they are written into char-like fields (e.g., char or text). Note: this may also require an adjustment in master for the html type. opw-4935423 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#226807
Payroll users with Administrator access can now cancel payslips that are marked as done, as intended. This fixes an incorrect permission check that previously blocked authorized payroll administrators unless they were full system admins.
Original PR description
steps to reproduce: ------------------- 1. Install payroll 2. Create a user and grant "Administrator" access to Payroll. 3. Log in as the new user and try to cancel a 'Done' payslip. issue: ------ A UserError is raised: "Cannot cancel a payslip that is done." observation: ------------ A user with Payroll "Administrator" access is unable to cancel a payroll payslip cause of the issue: ------------------- During cancellation, the system checks whether the user is "Admin" instead of verifying if the user has Payroll "Administrator" access. https://github.com/odoo/enterprise/blob/13832d80570956e504e1c09f41acbeb0bc4baedc/hr_payroll/models/hr_payslip.py#L509-L513 solution: ---------- Check that the user has Payroll "Administrator" access. opw-5040029 Forward-Port-Of: odoo/enterprise#95049 Forward-Port-Of: odoo/enterprise#93831
Date filters in timesheet forecast reports now respect each user's local timezone more accurately. This prevents records from being incorrectly included or excluded by one day for users in timezones far from UTC, improving report reliability.
Original PR description
This commit fixes the timezone issues with the Date filters, in which we were comparing a UTC DateTime value to a local timezone's Date. In certain timezones, this leads to off-by-one errors in the records fetched from the DB, depending on how far ahead or behind UTC that timezone is. Specifically, we remove the UTC conversion within the filter domains. opw-5068870 Forward-Port-Of: odoo/enterprise#94032
Timesheet and attendance reports now match entries against the user's local date instead of UTC time. This prevents “Today,” “This Week,” and “Last Week” filters from showing the wrong day for users in certain time zones.
Original PR description
This commit fixes issues with the timesheet Date filters, in which the `date` field of account.analytic.line records, which is stored as the local timezone's date, is being compared to a UTC DateTime value. This leads to off-by-one errors. For example, if you are in Berlin and try to filter for all timesheet entries from "Today", you will only find entries from the previous day. Similarly, for the "This Week" and "Last Week" filters, which would be shifted by one day. The filter domains have been changed to compare the `date` to the local timezone's "today". opw-5003310 Forward-Port-Of: odoo/odoo#225753
This fix ensures online orders use the correct warehouse when a customer switches from Click and Collect to standard delivery before payment. It prevents quotations from incorrectly staying tied to the Click and Collect warehouse, improving order fulfillment accuracy.
Original PR description
Steps: - Activate Click and Collect, then create a new warehouse. - For the product, add quantities in both locations. - Assign the second warehouse to Click and Collect. - Go to the website, add the product to the cart, choose Click and Collect as the delivery method, then switch it to Delivery and confirm payment. Issue: - When checking the quotation, it still uses the warehouse linked to Click and Collect. Cause: - Warehouse recomputation logic is called after _remove_delivery_line which resets the delivery_type of sale order. Since delivery_type is reset the sale order filter for warehouse recomputation does not work as intended. Fix: - Moved warehouse recomputation logic to _set_delivery_method which will filter the sale order before _remove_delivery_line. opw - 4965726, 5004170 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#225989
The Planning app now calculates weekly progress for flexible employees using only the part of a shift that falls within the displayed week. This prevents shifts spanning multiple weeks from overstating allocated hours, giving managers a more accurate view of weekly capacity.
Original PR description
### Steps to reproduce: - Install Planning app - Create a shift for a flexible employee that starts on Friday and end on the following Tuesday for example - Go to the gantt view for the week that the shift should start at - Notice the progress bar is showing the whole allocated hours not just the week's hours ### Cause: This mainly happening because when the employee is flexible we are getting the value by multiplying the hours_per_day of his schedule by the period.days and the period is the shift period ### Fix: We use the interval we are just checking as the period now so if the shift is extended to the next week we are just going to use the end of the week as the interval end not the shift's end_datetime opw-5022800 Forward-Port-Of: odoo/enterprise#93404
7 changes
Resolved issues and error corrections
The trial balance period comparison now calculates end balance columns correctly for Profit and Loss accounts, using only the latest displayed year instead of adding prior years together. This prevents misleading balances and keeps previous years' amounts in the appropriate unaffected earnings account, improving financial report accuracy.
Original PR description
When activating the period comparison with the trial balance, the end balance columns used to sum the values of the displayed periods, which should not be the case for Profit and Loss accounts. Indeed, only the last displayed year should be used in the end balance, while the previous years' amount must be displayed in the unaffected earnings account. We used to optimize the query by computing in python the end balance on some conditions (for example analytic groupby filter). This wasn't actually totally working, for example the end balance columns used to display amounts in both debit and credit columns. This optimization is no longer possible since the P&L accounts of the previous fiscal years need to be displayed in the unaffected earnings account. task-4728887 Forward-Port-Of: odoo/enterprise#94600
Bank synchronization now avoids importing or creating entries on dates that are protected by an accounting lock date. This prevents bank transactions and opening balances from being placed on incorrect dates, helping preserve accurate financial records after connecting a bank feed.
Original PR description
If you have a company with a lock date set, and you connect a bank that has transactions dated to the day of the lock date, these transactions will be fetched, which do not make sense because nothing…
If you have a company with a lock date set, and you connect a bank that has transactions dated to the day of the lock date, these transactions will be fetched, which do not make sense because nothing should be created in a period covered by a lock date. As a result, these transactions would be created at a wrong date (if the current month is the first after the lock date or if the sequence has a monthly reset, then they would be appended to the current month, else if the sequence reset annually, then they would be created at the current date). Additionally, the potential opening balance would be created at a wrong date too, since it would try to create it one day prior to the oldest transaction. The date which the opening balance is created would not be the same as the transactions above, which adds a layer to the mess created. To prevent this, at initialization, we set the last sync date one day after the lock date, not the same day. As for the opening balance, we do not try to set it one day prior to the oldest transaction, but the same day. The `internal_index` computed will ensure it is displayed as the first transaction of that journal. Finally, the test related to statement creation were adapted to this new behavior. Some ordering based on `date` in other tests were changed to `internal_index` to unify the test file with these changes. opw-4890538 Forward-Port-Of: odoo/enterprise#94648 Forward-Port-Of: odoo/enterprise#93543
The Spanish Mod347 tax report now includes withholding taxes when calculating report totals. This prevents understated figures for affected customer or supplier transactions, helping businesses submit more accurate tax reporting.
Original PR description
Withholding taxes should be taken into account in mod347 tax report. Steps: - Create a bill for a spanish customer - Set the amount of 40000, tax 21% and 15% withholding tax - Go to mod347 tax report -> Line "B - Sales of goods and services greater than 3.005,06 €" is showing 42,400.00 instead of 48,400.00 (same goes for other lines with similar configuration) Before this commit, custom engines domains were only including aml with payable or receivable account. With this commit, we include tax lines that are of type 'retencion' in the custom engines domains. opw-4448662 Forward-Port-Of: odoo/enterprise#94338
Single-company databases can now find and merge duplicate records even when those records have different company values. This prevents missed duplicates and helps keep customer or business data cleaner without requiring multi-company settings.
Original PR description
**Issue** In single company databases, it wasn't possible to find duplicate records with different `company_id` values to merge them (in multi company databases, it is possible to enable the "Cross-Company" option on the deduplication rule). **Change** Always ignore the company field in single company databases. opw-4794408 Forward-Port-Of: odoo/enterprise#94797 Forward-Port-Of: odoo/enterprise#93184
The project timesheet forecast reports now apply date filters consistently for users in different time zones. This prevents records from being incorrectly included or excluded by one day, improving report accuracy for planning and review.
Original PR description
This commit fixes the timezone issues with the Date filters, in which we were comparing a UTC DateTime value to a local timezone's Date. In certain timezones, this leads to off-by-one errors in the records fetched from the DB, depending on how far ahead or behind UTC that timezone is. Specifically, we remove the UTC conversion within the filter domains. opw-5068870 Forward-Port-Of: odoo/enterprise#94032
This fix ensures that changes made to the Time Spent field in the timesheet list view remain visible when users move focus away with Shift+Tab. It prevents newly entered or edited time values from appearing to revert, reducing confusion and helping users trust that their timesheet updates are preserved.
Original PR description
Steps to reproduce: ----------------- 1. Go to Timesheet → My Timesheet → List View → New OR Edit already filled time. 2. Change time in the Time Spent field. 3. Press Shift + Tab. Observation:…
Steps to reproduce: ----------------- 1. Go to Timesheet → My Timesheet → List View → New OR Edit already filled time. 2. Change time in the Time Spent field. 3. Press Shift + Tab. Observation: ----------------- The focus changes, but the Time Spent field reverts to its old value instead of keeping the newly entered one. Issue: ----------------- - For new records, the component retrieves the value only from the state, which is updated in the `onWillUpdateProps` lifecycle. This lifecycle triggers only on saving or editing, not when simply changing focus. https://github.com/odoo/enterprise/blob/e14b991927df14f41535e92dd01ea2ecac44a404/timesheet_grid/static/src/components/timesheet_display_timer/timesheet_display_timer.js#L123-L128 - The same behavior occurs when editing existing records, leading to incorrect value display. https://github.com/odoo/enterprise/blob/e14b991927df14f41535e92dd01ea2ecac44a404/timesheet_grid/static/src/components/timesheet_display_timer/timesheet_display_timer.js#L31-L33 Solution: ----------------- - For new records, since the default value is 0, the fix makes the component fall back to the updated record value if the state value is not yet available. - For existing records, if the timer is running, the timer’s value is displayed. otherwise, the component falls back to the updated record value. opw-4922847 Forward-Port-Of: odoo/enterprise#94729
Point of Sale sessions using Worldline terminals now continue receiving cancellation confirmations even if the browser page was refreshed during payment. This prevents orders from getting stuck and adds clearer error messages for payment terminal issues.
Original PR description
This PR fixes a bug where the point of sale didn't receive notifications from the Worldline payment terminal for the cancellations if the browser webpage was refreshed How to reproduce: 1. Open a POS session with Worldline terminal 2. Send a transaction to the terminal 3. Refresh the browser webpage before paying 4. Click on "Cancel" on the POS screen --> your order will be stuck and never receive the confirmation This PR removes the check for the iot longpolling action identifier which changes on refresh of the webpage + adds more error messages for Worldline terminals Related PR in >= saas-18.3: https://github.com/odoo/enterprise/pull/94629 task-5075860 Forward-Port-Of: odoo/enterprise#94670 Forward-Port-Of: odoo/enterprise#94635
5 changes
Resolved issues and error corrections
Odoo now recognizes Ecuadorian supplier invoice XML files downloaded from the SRI even when the invoice is wrapped inside a CDATA section. This allows vendor bills to be populated automatically from those files, avoiding manual entry for affected Ecuadorian companies.
Original PR description
### Issue: Ecuadorian customer can download their invoice's XML from the SRI, but the file contains the invoice in a wrapper tag (`<![CDATA[ ... ]]>`) that prevent the extraction of the data to fill…
### Issue: Ecuadorian customer can download their invoice's XML from the SRI, but the file contains the invoice in a wrapper tag (`<![CDATA[ ... ]]>`) that prevent the extraction of the data to fill the vendor bill form view. #### Steps to reproduce: - Install "l10n_ec_edi" and switch to an Ecuadorian company - Have a file downloaded from the SRI. - Go to Accounting > Vendor > Bills - Click "Upload" and select the file - The generated move is not populated with the data ### Cause: We are expecting the XML to not be in the tag `CDATA` and it gets ignored. ### Solution: The change is in `_get_import_file_type` to detect the new type of file as `'l10n_ec.factura'`. The CDATA content can be fetched by getting the content of the tag `comprobante`. We then try to convert the content of `comprobante` to XML. If it's possible, we have an XML on which we can do the same check as before to know if it's an Ecuadorian invoice. We then replace the `file_data['xml_tree']` by the content of `CDATA` to have the correct XML for the data extraction. opw-5004636 Forward-Port-Of: odoo/enterprise#94184
Spanish Mod347 tax reports now include withholding tax lines, so reported totals match invoices that use retentions. This prevents underreported sales or purchase amounts in affected Spanish tax declarations.
Original PR description
Withholding taxes should be taken into account in mod347 tax report. Steps: - Create a bill for a spanish customer - Set the amount of 40000, tax 21% and 15% withholding tax - Go to mod347 tax report -> Line "B - Sales of goods and services greater than 3.005,06 €" is showing 42,400.00 instead of 48,400.00 (same goes for other lines with similar configuration) Before this commit, custom engines domains were only including aml with payable or receivable account. With this commit, we include tax lines that are of type 'retencion' in the custom engines domains. opw-4448662 Forward-Port-Of: odoo/enterprise#95066 Forward-Port-Of: odoo/enterprise#94338
Odoo now ignores the company field when looking for duplicate records in databases that only use one company. This helps users find and merge duplicates that were previously missed because they had different company values.
Original PR description
**Issue** In single company databases, it wasn't possible to find duplicate records with different `company_id` values to merge them (in multi company databases, it is possible to enable the "Cross-Company" option on the deduplication rule). **Change** Always ignore the company field in single company databases. opw-4794408 Forward-Port-Of: odoo/enterprise#94797 Forward-Port-Of: odoo/enterprise#93184
This update fixes an error that could occur when point-of-sale orders used Avatax external tax calculations. By removing an outdated internal reference, POS tax processing can continue reliably without triggering a system error.
Original PR description
Since [this PR](https://github.com/odoo/enterprise/pull/82623), defination of `_get_lines_eligible_for_external_taxes` was removed but a reference to it still remained, causing the following error when calling the `_get_line_data_for_external_taxes` method:. `AttributeError: 'pos.order' object has no attribute '_get_lines_eligible_for_external_taxes'` Fix: Removed reference to `_get_lines_eligible_for_external_taxes` from `_get_line_data_for_external_taxes` at [1]. [1]- https://github.com/odoo/enterprise/blob/9a1544d19c1f5f3546c04022a11601df43199d10/pos_avatax/models/pos_order.py#L15-L18 sentry-6843827499 Forward-Port-Of: odoo/enterprise#93490
Fixes Danish minimal financial reports so report lines use the correct names and calculation values. This helps prevent incorrect report output and keeps translations aligned with the corrected labels.
Original PR description
In the minimal reports of l10n_dk, it appears that some expression ended with a sign and the report engine was given wrong value. This commit will remove the extra sign to correct the report and also remove the letter or number before the name. This commit will remove the extra sign to correct the report and also remove the letter or number before the name. This commit will change the translation accordingly to the other commits task-4949062 Forward-Port-Of: odoo/enterprise#94350 Forward-Port-Of: odoo/enterprise#91135
11 changes
Resolved issues and error corrections
Fixed an issue where Saudi Arabia invoice PDFs could omit the company logo when another localization module was installed. This ensures printed invoices display the correct company branding for customers and compliance documents.
Original PR description
steps to reproduce: ------------------- 1. Install `l10n_sa_edi` and `l10n_latam_invoice_document` 2. Create and confirm an invoice. 3. Print the invoice PDF issue: ------ The company logo is not…
steps to reproduce:
-------------------
1. Install `l10n_sa_edi` and `l10n_latam_invoice_document`
2. Create and confirm an invoice.
3. Print the invoice PDF
issue:
------
The company logo is not printed on the invoice PDF.
cause of the issue:
-------------------
The `l10n_latam_invoice_document` hides the standard company logo if
`company_header` is set to true:
https://github.com/odoo/odoo/blob/0f6cb037e05db86e808682659a12442464b2cdd2/addons/l10n_latam_invoice_document/views/report_templates.xml#L6-L8
In the case of `l10n_sa`, the custom_header value is set because of this condition:
https://github.com/odoo/odoo/blob/0f6cb037e05db86e808682659a12442464b2cdd2/addons/l10n_sa/views/report_invoice.xml#L23
However, the condition in `l10n_latam_invoice_documnet` expects
a callable record instead of static XML data, which is incorrect:
https://github.com/odoo/odoo/blob/022fcbcf40a28afa56010f6130c26bb0503d5467/addons/l10n_latam_invoice_document/views/report_templates.xml#L9-L14
solution:
---------
Renaming the variable to `custom_header_sa` resolves the issue.
<details>
<summary>Click here to see:</summary>
Before:
<img src="https://github.com/user-attachments/assets/f4606a44-10ce-4038-92a3-2c8ec2a69edf"/>
After:
<img src="https://github.com/user-attachments/assets/70055155-63f2-4fec-aaf6-3bf5587f5591"/>
</details>
opw-4977422
Forward-Port-Of: odoo/odoo#225476This fixes bus notifications so users receive updates through both their direct groups and any groups they inherit. Administrators and other users with implied group membership will now see relevant Discuss channel updates immediately without needing to reload.
Original PR description
To target users of a group, bus notifications are sent on group records. To do so, user groups are added to its bus subscription. However, since odoo/odoo#179354, only explicit groups are added, not every implied group. It's incorrect. For example, sending on the user channel doesn't notify administrators while it should. Steps to reproduce (note that the steps are only working for admin): - Click the gear button on the sidebar in discuss page to navigate to the channel kanban view as admin - Click the `New` button and create a channel with an internal users group as `Auto Subscribe Groups` - Go back to the discuss main page. The new channel will not be pinned unless you reload the page See: https://github.com/odoo/odoo/pull/179354/files#r1954163704 Forward-Port-Of: odoo/odoo#217543
Bookkeeper and related accounting users can now open India tax returns without access errors on document summary lines. This keeps tax return review and navigation smooth for permitted users.
Original PR description
Before: - Bookkeeper users (`group_account_user`) encountered an access error of gstr document summary line when opening tax returns. - The error occurred because access rights were missing for the given model. Fix: - Added access rights for readonly, basic and accounting users. - Bookkeeper users can now view and navigate their permitted tax return records without errors. Impact: - Ensures smooth access to tax returns for Bookkeeper role.
This fixes an issue where changing an employee's check-in or check-out time could incorrectly reset approved extra hours to zero. Extra hours now recalculate when attendance times change, unless the user has intentionally edited the extra-hours value themselves.
Original PR description
**Steps to reproduce** - Automatically approved attendances. - Create an attendance and save it. - Note the "Extra hours" displayed. - From the form view, change the check in or check out and save…
**Steps to reproduce** - Automatically approved attendances. - Create an attendance and save it. - Note the "Extra hours" displayed. - From the form view, change the check in or check out and save it. - Issue: "Extra hours" are 0. Expected: they should be the same as "Worked extra hours", as the user has not manually modified the field. **Cause** Issue since cc81bb59f87540cf4dd8da65510417d8023ef65b The problem is that a 0 value for `overtime_hours` was computed for the `NewId` record used during edition in the interface. This meant `validated_overtime_hours` was also set to this value https://github.com/odoo/odoo/blob/cc81bb59f87540cf4dd8da65510417d8023ef65b/addons/hr_attendance/models/hr_attendance.py#L171 and sent on save, which meant the value was not further recomputed in `_update_overtime`. https://github.com/odoo/odoo/blob/cc81bb59f87540cf4dd8da65510417d8023ef65b/addons/hr_attendance/models/hr_attendance.py#L408 **Change** We avoid a recomputation of `validated_overtime_hours` in the interface (which wasn't useful anyway, it was set to 0) to avoid it being interpreted as a manual change by the user. opw-5003488 Forward-Port-Of: odoo/odoo#226393 Forward-Port-Of: odoo/odoo#222689
Duplicate records can now be found and merged in single-company databases even when their company value differs. This helps teams clean up data more reliably without needing multi-company settings or workarounds.
Original PR description
**Issue** In single company databases, it wasn't possible to find duplicate records with different `company_id` values to merge them (in multi company databases, it is possible to enable the "Cross-Company" option on the deduplication rule). **Change** Always ignore the company field in single company databases. opw-4794408 Forward-Port-Of: odoo/enterprise#94797 Forward-Port-Of: odoo/enterprise#93184
The Spanish Mod347 tax report now includes withholding tax lines when calculating report amounts. This prevents understated totals for affected customer or vendor transactions, helping businesses file more accurate Spanish tax reports.
Original PR description
Withholding taxes should be taken into account in mod347 tax report. Steps: - Create a bill for a spanish customer - Set the amount of 40000, tax 21% and 15% withholding tax - Go to mod347 tax report -> Line "B - Sales of goods and services greater than 3.005,06 €" is showing 42,400.00 instead of 48,400.00 (same goes for other lines with similar configuration) Before this commit, custom engines domains were only including aml with payable or receivable account. With this commit, we include tax lines that are of type 'retencion' in the custom engines domains. opw-4448662 Forward-Port-Of: odoo/enterprise#95066 Forward-Port-Of: odoo/enterprise#94338
This pull request resolves several user-facing issues, including payment checkout errors, invoice tax handling problems, and website editing layout glitches. It improves reliability for businesses using online payments, Indonesian e-Faktur invoicing, point of sale, events emails, and website snippets.
Customers using self-ordering will no longer see time slots that are already full or have passed. This prevents invalid selections and makes the ordering experience clearer and more reliable.
Original PR description
When selecting a preset in pos_Self_order the slots were not filtered. Issues: - Full slots were still displayed - Slots in the past were still displayed
This fix stops the Point of Sale restaurant flow from treating every product category as needing preparation when no kitchen printer or preparation display category is configured. Staff can now add and pay for orders without seeing an unnecessary “send to preparation” prompt, reducing confusion during checkout.
Original PR description
Steps to reproduce: - Open a pos restaurant config that has no prep printer/display. - Add an orderline. - The order button appear and if you try to pay the popup ask for send to preparation is shown. Issue: If there is no preparationCategories for a config getOrderChanges consider that all the available categories are the preparationCategories. Fix: If there is no preparationCategories, set the orderline uiState hasChange to false. Note: When no preparation printer category is defined, no categories is to be return by default. For the preparation display, if no preparation categories is selected preparationCategories will return all the available categories. Task-5016231 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#222950
The Danish minimal balance sheet and profit and loss reports were corrected so report formulas no longer include extra signs that could produce wrong values. Report line names and translations were also cleaned up for clearer presentation and consistency.
Original PR description
In the minimal reports of l10n_dk, it appears that some expression ended with a sign and the report engine was given wrong value. This commit will remove the extra sign to correct the report and also remove the letter or number before the name. This commit will remove the extra sign to correct the report and also remove the letter or number before the name. This commit will change the translation accordingly to the other commits task-4949062 Forward-Port-Of: odoo/enterprise#94350 Forward-Port-Of: odoo/enterprise#91135
Searching from the Help page now completes reliably instead of triggering an error. This prevents users from seeing a traceback and keeps the help experience smooth when looking for support content.
Original PR description
Steps to reproduce: 1. Navigate to the Help menu. 2. Search for any term in the search bar. - A traceback occurs. Issue: The search method did not wait for the RPC call to complete and returned a promise prematurely, leading to an unhandled traceback. Fix: Ensure the method properly awaits the RPC call before returning the result.
15 changes
Resolved issues and error corrections
This fix prevents the Inventory replenishment screen from crashing when all warehouses have been removed. It helps users continue working safely in unusual stock configurations instead of seeing an error message.
Original PR description
When there is no warehouse and user clicks on the replenishment, A traceback will appear. Steps to reproduce the error: - Install ``stock`` module - Go to Inventory > Configuration > Settings >…
When there is no warehouse and user clicks on the replenishment, A traceback will appear. Steps to reproduce the error: - Install ``stock`` module - Go to Inventory > Configuration > Settings > Enable Multi-Step Routes - Create new product > Click on ``On Hand`` smart button > Add Negative On Hand Quantity (e.g. -10) - Go to Inventory > Configuration > Rules > Delete all Rules - Go to Inventory > Configuration > Warehouses > Delete Warehouse - Go to Inventory > Operations > Replenishment Traceback: ``` NotNullViolation: null value in column 'warehouse_id' of relation 'stock_warehouse_orderpoint' violates not-null constraint ``` https://github.com/odoo/odoo/blob/54204e664ed1924f512ba4626be010e39c2d17a3/addons/stock/models/stock_orderpoint.py#L538-L545 When there is no warehouse available, the ``warehouse_id`` is set to False. when the method tries to create orderpoints using this ``False`` value for ``warehouse_id``. So, It will raise the above traceback. sentry-6682818532 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fixes an error that could stop users from planning a manufacturing order after recording actual time on one of its work orders. The plan action now handles work orders without scheduling data correctly, helping production teams continue planning without interruption.
Original PR description
When user clicks the plan button in the mo, A traceback will appear. Steps to reproduce the error: - Create a new MO > Select any product > Add 2 workorders - Confirm - Set Real duration in any…
When user clicks the plan button in the mo,
A traceback will appear.
Steps to reproduce the error:
- Create a new MO > Select any product > Add 2 workorders
- Confirm
- Set Real duration in any workorder
- Click on Plan button
Traceback:
```
File "/home/odoo/src/odoo/addons/mrp/models/mrp_production.py", line 1583, in _plan_workorders
'date_start': min([workorder.leave_id.date_from for workorder in workorders]),
TypeError: '<' not supported between instances of 'datetime.datetime' and 'bool'
```
The error occurs due to changes introduced in the following commit: https://github.com/odoo/odoo/commit/e587fecca81081a1861b353b85f1d8ed68503973
After this commit, modifying the real duration of a work order sets its status to ``In Progress``.
As a result, the resource calendar leave is no longer created for that workorder. https://github.com/odoo/odoo/blob/3fb37cbc59adc2caace8efcdae418d2466a9b750/addons/mrp/models/mrp_workorder.py#L529-L530
So, here ``leave_id.date_from`` becomes False.
https://github.com/odoo/odoo/blob/3fb37cbc59adc2caace8efcdae418d2466a9b750/addons/mrp/models/mrp_production.py#L1575-L1576
So, It will lead to the above traceback.
sentry-6595147036
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prThis fix prevents Colombian electronic invoices from failing unexpectedly when no signing certificate is configured. Users will avoid a system error during invoice sending in this setup, making the missing configuration easier to handle.
Original PR description
The variable `cert_sudo` was being used outside of the for loop If no certificate is present, the loop is skipped, and `cert_sudo` remains undefined, resulting in the UnboundLocalError. **Steps to…
The variable `cert_sudo` was being used outside of the for loop If no certificate is present, the loop is skipped, and `cert_sudo` remains undefined, resulting in the UnboundLocalError. **Steps to replicate** Install the Sales,Accounting apps and l10n_co_dian module. * Go to Settings Open `Users and Companies` > `Companies` and create a New Company. * Enter the name: YourCompany (Colombia) and in the `Country field`, select `Colombia`. * Enter arbitrary values for the `Company ID` fields and save. * Switch to `YourCompany (Colombia)` from dashboard. * Go to Settings>Accounting section>Colombian Electronic Invoicing section. * In Operation Modes, add a line. * Set Software Mode to `DIAN 2.1: Electronic Invoices` and set `Software PIN` and `Testing ID` randomly and save. * Go to Contacts app and search for `Deco Addict`. * Open the Sales and Purchase page. * In the `Obligaciones y Responsabilidades` field, select `0-47`. * Enter an arbitrary value for Company ID and save. * Go back to contacts and now search for `YourCompany (Colombia)`. * Enter arbitrary letters in the Identification field and select any option in the `City` field. * Go to the Sales and Purchase page and Fill in `Obligaciones y Responsabilidades` and save. * Open Accounting and Select Configuration > Journals>Customer Invoices. * Go to the Advanced Settings page. * Fill all fields under the `Resolución DIAN section` with arbitrary values and save. * Create a new Customer Invoice by pressing the New button under Customer Invoices from accounting dashboard. * Set the customer to `Deco Addict`. * Add a random product in the product lines then save and press confirm. * Press Send, then in the template preview, press Continue > Send. **Error:** `UnboundLocalError: local variable 'cert_sudo' referenced before assignment` **Solution:** Added a check to ensure that certificates_sudo is not empty before entering the block where cert_sudo is used. Sentry-6515616912
This fixes an error that could prevent the Partner Ledger report from opening when users selected a custom horizontal group containing multiple journals. Accounting teams can now use this reporting configuration without hitting a system error.
Original PR description
When creating a custom horizontal group in accounting module with multiple journals, query with wrong syntax will be fired from `_get_query_sums` method **Steps to reproduce:** Install accounting…
When creating a custom horizontal group in accounting module with multiple journals, query with wrong syntax will be fired from `_get_query_sums` method
**Steps to reproduce:**
Install accounting module
* `Configuration>Accounting>Horizontal Groups`
* Create new group and put arbitrary `group name`
* On `Reports` field add `Partner Ledger` then add a line and on `field` select `Journal` hit Save and close.
* Go to `Reporting>Partner Reports>Partner Ledger`
* Select `Horizontal Group > The name of the group you created`
**Error:**
`psycopg2.errors.SyntaxError: syntax error at or near 'WITH'
LINE 27: WITH partner_sums AS (`
**Solution:**
Modify the `WITH partner_sums AS( .....) `
with `SELECT * FROM ( WITH partner_sums AS(...) as sub` this prevents invalid syntax of
```sql
WITH partner_sums AS (...)
SELECT * FROM partner_sums
...
UNION ALL
WITH partner_sums AS (...)
SELECT * FROM partner_sums
...
```
and now instead it does which is a valid syntax
```sql
SELECT * FROM (
WITH partner_sums AS (...) SELECT * FROM partner_sums
) AS sub
UNION ALL
SELECT * FROM (
WITH partner_sums AS (...) SELECT * FROM partner_sums
) AS sub
...
```
Sentry-6529855325Bank synchronization now starts after the company's accounting lock date, preventing transactions from being imported into periods that should no longer change. Opening balances are also dated consistently with the first synced transaction, reducing the risk of incorrect or confusing bank statement entries.
Original PR description
If you have a company with a lock date set, and you connect a bank that has transactions dated to the day of the lock date, these transactions will be fetched, which do not make sense because nothing…
If you have a company with a lock date set, and you connect a bank that has transactions dated to the day of the lock date, these transactions will be fetched, which do not make sense because nothing should be created in a period covered by a lock date. As a result, these transactions would be created at a wrong date (if the current month is the first after the lock date or if the sequence has a monthly reset, then they would be appended to the current month, else if the sequence reset annually, then they would be created at the current date). Additionally, the potential opening balance would be created at a wrong date too, since it would try to create it one day prior to the oldest transaction. The date which the opening balance is created would not be the same as the transactions above, which adds a layer to the mess created. To prevent this, at initialization, we set the last sync date one day after the lock date, not the same day. As for the opening balance, we do not try to set it one day prior to the oldest transaction, but the same day. The `internal_index` computed will ensure it is displayed as the first transaction of that journal. Finally, the test related to statement creation were adapted to this new behavior. Some ordering based on `date` in other tests were changed to `internal_index` to unify the test file with these changes. opw-4890538 Forward-Port-Of: odoo/enterprise#93543
Fixes an issue where edited time entries in the Timesheet list view could appear to revert when users moved focus with Shift+Tab. This helps employees keep confidence that their entered time is retained accurately while creating or updating timesheets.
Original PR description
Steps to reproduce: ----------------- 1. Go to Timesheet → My Timesheet → List View → New OR Edit already filled time. 2. Change time in the Time Spent field. 3. Press Shift + Tab. Observation:…
Steps to reproduce: ----------------- 1. Go to Timesheet → My Timesheet → List View → New OR Edit already filled time. 2. Change time in the Time Spent field. 3. Press Shift + Tab. Observation: ----------------- The focus changes, but the Time Spent field reverts to its old value instead of keeping the newly entered one. Issue: ----------------- - For new records, the component retrieves the value only from the state, which is updated in the `onWillUpdateProps` lifecycle. This lifecycle triggers only on saving or editing, not when simply changing focus. https://github.com/odoo/enterprise/blob/e14b991927df14f41535e92dd01ea2ecac44a404/timesheet_grid/static/src/components/timesheet_display_timer/timesheet_display_timer.js#L123-L128 - The same behavior occurs when editing existing records, leading to incorrect value display. https://github.com/odoo/enterprise/blob/e14b991927df14f41535e92dd01ea2ecac44a404/timesheet_grid/static/src/components/timesheet_display_timer/timesheet_display_timer.js#L31-L33 Solution: ----------------- - For new records, since the default value is 0, the fix makes the component fall back to the updated record value if the state value is not yet available. - For existing records, if the timer is running, the timer’s value is displayed. otherwise, the component falls back to the updated record value. opw-4922847
Fixes an issue where orders could keep using the Click and Collect warehouse even after the customer switched to standard delivery. This helps ensure quotations and fulfilled orders use the correct warehouse, reducing fulfillment errors.
Original PR description
Steps: - Activate Click and Collect, then create a new warehouse. - For the product, add quantities in both locations. - Assign the second warehouse to Click and Collect. - Go to the website, add the product to the cart, choose Click and Collect as the delivery method, then switch it to Delivery and confirm payment. Issue: - When checking the quotation, it still uses the warehouse linked to Click and Collect. Cause: - Warehouse recomputation logic is called after _remove_delivery_line which resets the delivery_type of sale order. Since delivery_type is reset the sale order filter for warehouse recomputation does not work as intended. Fix: - Moved warehouse recomputation logic to _set_delivery_method which will filter the sale order before _remove_delivery_line. opw - 4965726, 5004170 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The timesheet and attendance timesheet filters for Today, This Week, and Last Week now use the user’s local date instead of a UTC-based date. This prevents entries from appearing under the wrong day or week for users in time zones where the previous logic caused off-by-one errors.
Original PR description
This commit fixes issues with the timesheet Date filters, in which the `date` field of account.analytic.line records, which is stored as the local timezone's date, is being compared to a UTC DateTime value. This leads to off-by-one errors. For example, if you are in Berlin and try to filter for all timesheet entries from "Today", you will only find entries from the previous day. Similarly, for the "This Week" and "Last Week" filters, which would be shifted by one day. The filter domains have been changed to compare the `date` to the local timezone's "today". opw-5003310
This fix ensures date filters in timesheet forecasting return the correct records regardless of a user’s time zone. It prevents off-by-one-day errors that could cause forecasts or timesheet data to appear missing or incorrectly included.
Original PR description
This commit fixes the timezone issues with the Date filters, in which we were comparing a UTC DateTime value to a local timezone's Date. In certain timezones, this leads to off-by-one errors in the records fetched from the DB, depending on how far ahead or behind UTC that timezone is. Specifically, we remove the UTC conversion within the filter domains. opw-5068870
This fix stops users from repeatedly validating an online POS payment while the order is still syncing. It prevents checkout errors on slow connections and makes online payments more reliable for cashiers and customers.
Original PR description
Currently, an error occurs when validating an online payment if the network is slow. **Steps to Reproduce:** 1) Install POS (with demo data) and the Demo Payment module. 2) Go to Payment Methods and…
Currently, an error occurs when validating an online payment if the network is slow.
**Steps to Reproduce:**
1) Install POS (with demo data) and the Demo Payment module.
2) Go to Payment Methods and create a new online payment method for any shop (e.g., a clothing shop). Set the Payment Provider to `Demo`.
3) Open a POS session for the clothing shop, select any product, and proceed to payment.
4) Open Inspect → Network tab, create a custom slow network profile(e.g., `set both download and upload speed to 1 KB/s`), and switch to that network.
5) Select the online payment method you just created and continuously click on Validate.
Error:
ValueError: Expected singleton: pos.order('p', 'o', 's', '.', 'o', 'r', 'd', 'e', 'r', '_', '4')
**Root Cause:**
When an online payment is validated, the `_isOrderValid` and `addNewPaymentLine` methods are called.
- With a slow network, the order ID is still temporary(e.g., e74a3369-7dcd-4234-b35e-04daa149ffe6) as the order is not synced completely, when the code at [1] is executed.
- Due to multiple clicks, `_isOrderValid` forces a call to `update_online_payments_data_with_server` at [2] before order is synced.
- This eventually passes the temporary ID to `get_and_set_online_payments_data` at [3], causing the issue.
**Fix:**
Prevent multiple clicks on Validate until the order is successfully synced.
[1]- https://github.com/odoo/odoo/blob/eb88370e2fc1887e8c88dfd8dbeadce23bb7abe5/addons/pos_online_payment/static/src/overrides/pos_overrides/components/payment_screen/payment_screen.js#L11-L17
[2]- https://github.com/odoo/odoo/blob/eb88370e2fc1887e8c88dfd8dbeadce23bb7abe5/addons/pos_online_payment/static/src/overrides/pos_overrides/components/payment_screen/payment_screen.js#L87
[3]- https://github.com/odoo/odoo/blob/eb88370e2fc1887e8c88dfd8dbeadce23bb7abe5/addons/pos_online_payment/static/src/overrides/pos_overrides/models/pos_store.js#L18-L26
**sentry-6849786792**This fixes Saudi e-invoicing so that a duplicate submission response is treated as a successful send instead of an error. It helps prevent invoices that were already received by the authority from being incorrectly shown as failed, reducing manual follow-up for accounting teams.
Original PR description
Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Duplicating multiple Point of Sale configurations at once no longer causes an error. The update also ensures each duplicated shop gets its own cash payment method, preventing payment setup conflicts.
Original PR description
This issue occurs due to changes introduced in commit [4ac2702](https://github.com/odoo/odoo/commit/4ac2702c31f0e95f33f9ad554e7350bef9dab8bd), which added the `copy_data` method. The technique…
This issue occurs due to changes introduced in commit [4ac2702](https://github.com/odoo/odoo/commit/4ac2702c31f0e95f33f9ad554e7350bef9dab8bd),
which added the `copy_data` method. The technique allowed
duplicating multiple POS configs at once.
When performing a `search_count` on `pos.config` to check for existing records
with matching `payment_method_ids`, the domain was incorrectly using
('id', '!=', self.id).
This works fine if self is a `singleton record`, but `fails` if self contains
`multiple records`.
**Steps to Produce:-**
- Install the `Point of sale`.
- `Point of sale > Configuration > Payment methods`.
- Select `Card` and `Customer Account`, and delete them.
- Now, go to `Dashboard` and then open the `list view` of `Point of Sale`.
- Select `Furniture Shop` and `Clothes Shop` and then try to duplicate them.
**Error:-**
`ValueError: Expected singleton: pos.config(6, 7)`
**Solution:-**
- This commit fixes the above issues by:-
- Replacing `('id', '!=', self.id)` with `('id', 'not in', self.ids)` to
safely handle multi-record sets.
- Also found another issue, like when we duplicate pos in batch, then it assign
the same `cash payment method` to `multiple pos`.
- This commit also fixes the above issue by overriding the `copy_data()`
method.
- Assign a unique name to each duplicate (e.g., "Shop (copy)").
- Assign an `unused cash payment method` to each config, or `create` one if
none are available.
**Sentry - 6673398556**Cancelling a sales order after multiple nested product returns no longer causes the system to crash. This improves reliability for sales and warehouse teams handling complex return flows.
Original PR description
The system crashes with a `RecursionError` during the `Sale Order` cancellation with nested `returns`. **Steps to produce:-** - Install the `Purchase Stock` and `Sales` modules. - Create a new `Sales Order` (SO) with `Product A`. - Confirm the `Sales Order` and click on the `Delivery` button. - Click on `Return > Return all`. - In the new window, also click on `Return > Return all`. - Return to the `Sales Order` and attempt to `Cancel` it. **Error:-** `RecursionError: maximum recursion depth exceeded` **Solution:-** - Added a check for the self not already visited in the method `_get_upstream_documents_and_responsibles` to prevent revisiting the same move multiple times and `avoid infinite recursion`. **Sentry - 6693197358** I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Field Service sales orders now use the product's currency when calculating prices, instead of incorrectly reusing the sales order currency. This ensures prices are converted correctly when products and orders use different currencies, preventing incorrect invoice amounts.
Original PR description
### Steps to reproduce: - Open Field Service module. - Create a new task. In the Customer field, select “Bloem GmbH”. - Open the task’s project. - In the Invoicing tab, create a new line for any…
### Steps to reproduce: - Open Field Service module. - Create a new task. In the Customer field, select “Bloem GmbH”. - Open the task’s project. - In the Invoicing tab, create a new line for any employee and any service. - Return to the task and in the Timesheets tab, add a new timesheet. - Click the Mark as done button. - Click the Sales order button. ### Cause: When creating the sale order out of the fsm task we use _get_tax_included_unit_price to get the price of the SO line but we are passing the order currency twice to this method so it doesn't convert the price as when it checks the currency and the product_currency it found they are the same so no need to convert https://github.com/odoo/odoo/blob/6653355b8bc063ceadf08af17fbf2c4a250553e6/addons/account/models/product.py#L239-L240 ### Fix: We pass the product currency instead of the order currency in order to be able to convert the price according to the currencies opw-5045071 Forward-Port-Of: odoo/enterprise#94947
This fix prevents users from deleting the default barcode nomenclature that the barcode scanner setup depends on. This avoids crashes when re-enabling barcode scanning in Inventory settings, keeping configuration changes reliable.
Original PR description
The system will crash with error when user tries to enable barcode scanner in settings. **Steps to produce: -** - Install `Inventory` module. - `Inventory > configuration > products > Barcode…
The system will crash with error when user tries to enable barcode scanner in settings.
**Steps to produce: -**
- Install `Inventory` module.
- `Inventory > configuration > products > Barcode Nomenclatures`.
- Delete the `Default Nomenclature` record.
- Go to settings uncheck `Barcode Scanner` and save settings.
- Now, again `enable` that and save.
Error: -
```py
ValueError: External ID not found in the system: barcodes.default_barcode_nomenclature
ParseError: while parsing /home/odoo/src/enterprise/saas-18.4/stock_barcode/data/data.xml:40, somewhere inside <record id='scale_up_alias_1' model='barcode.rule'>
<field name='name'>Scale Up Receipt</field>
<field name='type'>alias</field>
<field name='pattern'>WH-RECEIPTS</field>
<field name='alias'>WHIN</field>
<field name='barcode_nomenclature_id' ref='barcodes.default_barcode_nomenclature'/>
<field name='sequence'>0</field>
</record>
```
**Root cause: -**
- At [1], the records use the ref of `default_barcode_nomenclature` which is defined in barcode module. So, when the ref is deleted and we are trying to use it then it gives error.
**Solution: -**
- This commit resolves the error by prevent the deletion of `default nomenclature`.
[1]: https://github.com/odoo/enterprise/blob/400171c9cebc46ecdd907ada210c65f3bbd2dd66/stock_barcode/data/data.xml#L40-L71
**sentry-6823596992**
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr12 changes
Resolved issues and error corrections
Marketing automation campaigns with invalid filter rules no longer trigger a system error when users add a new activity. Instead, the campaign now warns users about the invalid condition so they can correct it and continue working.
Original PR description
An error occurs when a user enters a `malformed domain` in a campaign and then creates a new activity, due to an unhandled `literal_eval` exception. **In the following code:**…
An error occurs when a user enters a `malformed domain` in a campaign and then creates a new activity, due to an unhandled `literal_eval` exception. **In the following code:** https://github.com/odoo/enterprise/blob/0a34ac7363b8270bb745a9e9bebba836af52d63f/marketing_automation/models/marketing_activity.py#L142-L143 **Steps to reproduce:** * Install `marketing_automation` and turn on developer mode. * `Marketing automation > New>Start from Scratch > Create Campaign` * Add condition> paste [this domain](https://drive.google.com/file/d/1HKWlgsQt-oGN7SGdgtfghYOMGNslDSag/view?usp=sharing) in the code editor. * After `Created on` is added click on it and select the `Created on` field again from dropdown menu this will allow you to save. * Press `Add new activity`. `ValueError:malformed node or string on line 1: <ast.Call object at 0x7af0f19a1210>` **Solution** * Add `eval_domain` helper to handle errors from malformed domain strings. * Trigger a validation error for invalid domains on the campaign page and during activity creation. Sentry-6688190469
Testing the AvaTax Brazil production connection no longer crashes when the account has insufficient credits. Instead, users receive a controlled error message, making setup issues easier to understand and preventing disruptive traceback screens.
Original PR description
If there are insufficient credits and the user attempts to test the connection for AvaTax Brazil in the production environment, a traceback will be raised. Steps to reproduce the error: - Install ``l10n_br_avatax`` module and switch to BR company - Go to Invoicing > Configuration > Settings > AvaTax Brazil > Environment: Production > Set Avatax Portal Email, API ID and API Key > Save - Click on Test Connection Traceback: ``` InsufficientCreditError: null ``` https://github.com/odoo/odoo/blob/b10303a136f87e17f621f1294f1e197c3ed67c98/addons/iap/tools/iap_tools.py#L138 When the user clicks the Test Connection button, the ``_l10n_br_iap_request`` method is called, which then calls the ``iap_jsonrpc`` method. This call raises an ``InsufficientCreditError`` if there are not enough credits. sentry-6721351360
This fix stops users from removing every website from the system, even if the default website reference was deleted. It prevents website pages from crashing and ensures the Website app always has at least one site available.
Original PR description
Currently, an error occurs when the user deletes all the websites and tries to open the website. Steps to Reproduce: - Install website - Navigate to Settings>Technical>External Identifier and Search `default_website`, delete that record - Navigate to website>configuration>websites - Delete all available website. - Tries to access or open the website Error: ValueError: Expected singleton: website() Root Cause: Since https://github.com/odoo/odoo/commit/60adaf5632ddfe3f68da369a2e9642ad639da37e , the check preventing the deletion of the last website was changed. The new constraint only prevents the deletion of the default website via the external identifier website.default_website. But if the user deleted the external identifier of the default website and deleted all the websites it leads to a traceback. Solution: This commit ensures that at least one website exists. sentry-5900356108
Field service tasks now use the product's currency when creating related sales order lines. This ensures prices are converted correctly when the product and sales order use different currencies, avoiding incorrect invoicing amounts.
Original PR description
### Steps to reproduce: - Open Field Service module. - Create a new task. In the Customer field, select “Bloem GmbH”. - Open the task’s project. - In the Invoicing tab, create a new line for any employee and any service. - Return to the task and in the Timesheets tab, add a new timesheet. - Click the Mark as done button. - Click the Sales order button. ### Cause: When creating the sale order out of the fsm task we use _get_tax_included_unit_price to get the price of the SO line but we are passing the order currency twice to this method so it doesn't convert the price as when it checks the currency and the product_currency it found they are the same so no need to convert https://github.com/odoo/odoo/blob/6653355b8bc063ceadf08af17fbf2c4a250553e6/addons/account/models/product.py#L239-L240 ### Fix: We pass the product currency instead of the order currency in order to be able to convert the price according to the currencies opw-5045071
This fix prevents users from hitting an error when drilling into graph or pivot report data that points to a form view that is not available. It keeps reporting navigation stable by only including form views when they actually exist, while still showing records in list view.
Original PR description
This error occurs in 18.2 when a user creates a course record for any attendee. Steps to Reproduce: - Install the website_slide module. - Go to Reporting > Attendees. - Go to either the Graph or…
This error occurs in 18.2 when a user creates a course record for any attendee.
Steps to Reproduce:
- Install the website_slide module.
- Go to Reporting > Attendees.
- Go to either the Graph or Pivot View and click on any count value.
- Open any attendee record and click on New.
SyntaxError: syntax error at or near ")"
LINE 18: WHERE SCP.id IN ()
^
This error occurs because when the user clicks on New to create the attendee's course record, the system triggers the compute method before saving the record. Since the record has not been saved yet, the self.id is empty, which causes the error.
In the list and kanban views, clicking on any attendee record does not open any form view. However, in the graph and pivot views, clicking on an attendee record opens a form view that does not exist, resulting in an error.
This commit ensures that if the form view is present, it will be included in the graph and pivot views. The list view is always included to display the records. The form view may contain computed methods, which can lead to errors if the view is not properly defined.
Sentry-6465821899
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prThe website editor now handles font size and text style changes more cleanly, reducing unwanted formatting artifacts and extra undo steps. It also prevents style changes in header areas where they could accidentally damage the page structure.
Original PR description
This PR is a follow-up of https://github.com/odoo/odoo/pull/129791 It permits to: - prevent unnecessary elements on text option change - remove font size classes / style on text style change - set font size class in a single command - remove dead code to delete empty class attribute - clean dom after text style change in `<li>` - unwrap sub text style element on text style change - hide text style dropdown for text element in the header task-1958098
When a purchase bill is reset to Draft, its GSTR-2B reconciliation information is now returned to the starting state. This prevents outdated return period links or exception flags from carrying over, helping teams reconcile GST data more reliably.
Original PR description
When a purchase invoice (bill) is reset to Draft: - Reset GSTR-2B reconciliation status to "pending" - Unlink from GST return period - Clear any existing exceptions This ensures that the bill returns to its initial stage for proper reconciliation. Task ID: 5095582
This fix prevents Firefox from keeping the wrong hidden product value when a website editor switches product variant display modes. It helps ensure shoppers and editors can continue selecting variants and adding products to the cart without needing to refresh the page.
Original PR description
### Problem: Switching the variants view from "Options" to "Product List" using the web editor, in Firefox, causes an error stating that the `product_template_id` doesn't exist. Add to cart and switching variants won't work until refreshing the page. This issue occurs only in Firefox because it incorrectly preserves hidden input values during DOM replacement. It assigns the value of the first hidden input (`product_id`) to the new `product_template_id` input, based on its position in the DOM. ### How to reproduce: * Create a product with variants. * Go to the product page in website shop using Firefox. * Open website editor on Customize. * Switch the variants view from Options to Product List. ### Solution: Disable autocomplete on the `product_template_id` input to prevent Firefox from preserving and reusing the previous value during DOM updates. opw-4901316
Sales orders for field service products with zero-priced lines now show as invoiced once the related invoice is created. This prevents teams from seeing completed orders incorrectly marked as still needing invoicing.
Original PR description
Steps: - Install sale and fsm module. - Enable anglo-saxon from the setting. - Create a service type product with fsm project as template. - Select that product on SO and set unit price to 0 on SOL. - Confirm that order and create and post invoice. Issue: - Sale order status still shows `To invoice` even though we create SOL related invoice. Cause: - In [PR] we made invoice status for anglo-saxon line `To Invoice` so it always say `To Invoice` even user create related invoice. Fix: - Make those lines `Invoiced` if there is related invoice by checking qty_invoiced is greater or equal to qty. [PR]: https://github.com/odoo/enterprise/pull/70132 opw-5055540
This fix stops users from changing the amount in currency on posted invoice journal items except where appropriate for draft tax lines. It helps prevent invoices from showing inconsistent totals or related accounting details after manual edits.
Original PR description
- Create an invoice with some products and post it - Go to Accounting > Journal items and ser for the ones belonging to the invoice. - Set the checkbox for the product sales one and set whatever tax…
- Create an invoice with some products and post it - Go to Accounting > Journal items and ser for the ones belonging to the invoice. - Set the checkbox for the product sales one and set whatever tax grid (you'll have to reveal that column). - Accept the changes. - Now go back to the invoice. - You'll see a new tracking message. Something like Journal Item #1093 updated - It contains a link and from that link you can go to the journal item form. - In that form you can edit the *amount in currency* field. Issue: - If a user do so, it leaves inconsistent invoice amounts: totals aren't recomputed, analytic lines aren't recomputed either. How it should behave: - Amount in currency shouldn't be editable here. Mainly when the journal entry is already posted! opw-4951629 A vídeo showing the issue: 📹️ https://www.loom.com/share/f7cd1d8f4138458f9b6c190233b0b9df?sid=eec77c17-a4a6-4698-8604-10aaa7e33f47 MT-10887 cc @moduon --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#223187
This fixes an issue where users with employees in multiple companies could hit a validation error when adding timesheets to Helpdesk tickets. The system now preserves the correct company information instead of replacing it with a blank value when the linked project has no company set.
Original PR description
Steps to Reproduce: ------------------ - Open Helpdesk. - Go to Configuration → Helpdesk Teams. - Create a new team. - Enable the Billing feature and assign a project to this team. - Set the…
Steps to Reproduce: ------------------ - Open Helpdesk. - Go to Configuration → Helpdesk Teams. - Create a new team. - Enable the Billing feature and assign a project to this team. - Set the project’s Company field to Null. - Create an employee for the current user in another company. - Ensure the user has employees in both companies. - Create a new ticket (or open an existing one) in the newly created team. - Try creating a new timesheet → a Validation Error is raised. Root Cause: ----------------- When a user has employees associated with multiple companies and tries to log a timesheet with multi-company enabled, a validation error occurs. **This happens because:** - The default company is derived from the project linked to the Helpdesk team. Since the company_id field on the project is no longer required, it may be Null, leading to an error when fetching the correct [employee for the company](https://github.com/odoo/odoo/blob/6a36015e2ee69aafe3880bf1fff38439af5cd673/addons/hr_timesheet/models/hr_timesheet.py#L214-L216 ). - Additionally, the [company check](https://github.com/odoo/enterprise/blob/83a1b88c8cae4db5c9b1bf82ee7ebb4e13c41b2a/helpdesk_timesheet/models/analytic.py#L81-L82) is incorrect. The code is checking whether the `company_id` key exists in a `list of vals`, whereas it should be checked directly on the vals dict itself. Issue Faced: ------------- In version 18.3, timesheets are created during migration [here](https://github.com/odoo/upgrade/blob/24f85bbc3408bf10b1cee93e4c395edf806beaa8/migrations/helpdesk_timesheet/saas~18.3.1.0/post-migrate.py#L44-L58 ). Even though the correct company_id is passed, it gets overridden during the process. and If the associated project does not have a company set, the company_id becomes False [here](https://github.com/odoo/enterprise/blob/83a1b88c8cae4db5c9b1bf82ee7ebb4e13c41b2a/helpdesk_timesheet/models/analytic.py#L81-L82), which results in a Validation Error because the [here](https://github.com/odoo/odoo/blob/6a36015e2ee69aafe3880bf1fff38439af5cd673/addons/hr_timesheet/models/hr_timesheet.py#L214-L216) unable to determine the correct employee linked to the company. OPW: 5004092
Sendcloud deliveries now allow customs HS codes up to 12 characters, matching Sendcloud's current API limits. This helps prevent international parcels, especially shipments to the US, from being delayed because valid customs codes were shortened or rejected.
Original PR description
**PROBLEM** We limit the `hs_code` length to 8 characters, but if we refer to the [sendcloud v2 api doc](https://api.sendcloud.dev/docs/sendcloud-public-api/branches/v2/parcels/schemas/parcel-item), we see that `hs_code` length can be up to 12 characters. Some clients have issue with parcels being held longer in custom when sending them to the US. [opw-5051585](https://www.odoo.com/odoo/project/49/tasks/5051585)