Daily updates from Odoo
Friday, June 5, 2026
132 changes
20 changes
Enhancements to existing features
This update allows for easier customization of Unsplash image access within our SaaS environment. Previously, a key limitation prevented modules from overriding the Unsplash access key, now patchable methods have been added for retrieval. This change ensures greater flexibility and control over image sourcing for SaaS users.
Original PR description
__Before commit__ The Unsplash querying logic was moved out of the controller in odoo/odoo@e5151524. The Unsplash access key was now retrieved directly using the ICP instead of using the dedicated method of the controller. This made it impossible for a module to override the access key used by `_fetch_unsplash_images`, which is required on SaaS. __After commit__ Add some patchable methods to retrieve the Unsplash access key and app ID.
Resolved issues and error corrections
This update corrects a bug where analytic accounts weren't consistently linked to invoice cost lines, leading to unbalanced accounting reports. The fix ensures that both invoice and stock valuation cogs lines include the correct analytic account, accurately reflecting inventory costs in project reports. This improves the reliability of financial reporting.
Original PR description
Steps to reproduce: - Activate Anglo-Saxon accounting - Create a product with track inventory and an automated inventory valuation product category - Define MTO on the product - Add this product to…
Steps to reproduce: - Activate Anglo-Saxon accounting - Create a product with track inventory and an automated inventory valuation product category - Define MTO on the product - Add this product to an Analytic Distribution Model (i.e. Legal) - Create a SO for this product - Create and confirm the PO related to it, the Analytic account is set on the PO. - Confirm the reception of the product - This creates a Stock valuation layer with the Analytic account - Confirm the SO - Confirm the delivery of the product - This creates a Stock valuation layer with the Analytic account too - Create the Invoice Issue: Missing analytic account on the 110300 Stock Interim (Delivered) creating unabalanced analytic accounting Other: test_report_invoice_items_anglo_saxon_automatic_valuation introduced in this PR https://github.com/odoo/odoo/pull/205777 checks that in a project's analytic report, the values based on cogs lines are displayed in the cost section. With this fix, both cogs lines will have an analytic account so their impact on the project analytic report will even out. This made the test fail. To keep the benefit of this test, we simulate that the user manually removes the analytic account on some of the cogs lines (those targetting stock interim received). opw-6060567 Forward-Port-Of: odoo/odoo#267810 Forward-Port-Of: odoo/odoo#261798
A recent issue prevented users from clicking the translate button in the CRM module, resulting in an error. This fix ensures the translation dialog opens correctly, regardless of the record type (especially in DynamicList views), by correctly handling data saving processes. This improves the user experience and prevents data entry issues.
Original PR description
Currently, an error occurs when the user clicks on the translate button. **Steps to Reproduce:** - Install the `CRM` module. - Go to `settings` and in `Languages` add 1 more language. - Go to `CRM` >…
Currently, an error occurs when the user clicks on the translate button. **Steps to Reproduce:** - Install the `CRM` module. - Go to `settings` and in `Languages` add 1 more language. - Go to `CRM` > `Configuration` > `Pipeline` > `Tags`. - Click `New` and, in the `Name` field click the `translate button` on the right. **Behavior in 18.0** When the tag name is not set, the translation dialog opens immediately. If a tag name is entered, the translation dialog shows the translated value on the second click. **Behavior in saas-19.1** `AssertionError: Invalid falsy real id` Error: After this [recent commit], when the user clicks on the translate button, if the record has a root record, the root record is saved before opening the translation dialog. However, in the case of an editable DynamicList view, the record does not have a root record so saving the record returns a promise instead of the resolved value [1]. Because of this promise, the condition fails [2], and the translation dialog is opened with a falsy ID since the record is not yet saved [3]. In saas-19.1, this issue raises Invalid falsy real id error after [this commit](https://github.com/odoo/odoo/commit/4290724a4c8c57fba4f4d3d688d38f65dadcc38f). This commit ensures that await is used so the resolved value is returned after the record is saved before opening the translation dialog. [recent commit]: https://github.com/odoo/odoo/commit/5245ec39a12e7d3a10fcc4c2c92b0f7dbf52d3be [1]: https://github.com/odoo/odoo/blob/9e3fc9568fcebcb1de6486d2ab7134e8a12087b7/addons/web/static/src/views/fields/translation_button.js#L23 [2]: https://github.com/odoo/odoo/blob/9e3fc9568fcebcb1de6486d2ab7134e8a12087b7/addons/web/static/src/views/fields/translation_button.js#L24-L26 [3]: https://github.com/odoo/odoo/blob/9e3fc9568fcebcb1de6486d2ab7134e8a12087b7/addons/web/static/src/views/fields/translation_button.js#L29-L41 sentry-7384270487 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#267914
This update fixes an issue where the DIAN-compliant electronic invoices generated for Colombia were incorrectly using a generic line number instead of the correct document ID. This resulted in rejections from external validation tools. The fix ensures the invoices now accurately reflect the required document ID as specified by DIAN regulations, allowing for proper processing and compliance.
Original PR description
### Issue When generating the attached document (AttachedDocument) for Colombia, the parent document reference tag <cbc:ID> incorrectly exported a generic line counter instead of the actual document…
### Issue
When generating the attached document (AttachedDocument) for Colombia, the parent document reference tag <cbc:ID> incorrectly exported a generic line counter instead of the actual document identification number
While the DIAN platform itself accepted the file, this caused rejections in external validation tools and third-party software because they could not resolve the link back to the original invoice
DIAN Documentation: https://www.dian.gov.co/impuestos/factura-electronica/Documents/Anexo_tecnico_factura_electronica_vr_1_7_2020.pdf
On page 213 there is an example for ParentDocumentLineReference
On page 216 there is the specification that does not show any check
Example of the incorrect XML structure:
```xml
<cac:ParentDocumentLineReference>
<cbc:LineID>1</cbc:LineID>
<cac:DocumentReference>
<cbc:ID>1</cbc:ID>
</cac:DocumentReference>
</cac:ParentDocumentLineReference>
```
Expected XML structure:
```xml
<cac:ParentDocumentLineReference>
<cbc:LineID>1</cbc:LineID>
<cac:DocumentReference>
<cbc:ID>SETP990001021</cbc:ID>
</cac:DocumentReference>
</cac:ParentDocumentLineReference>
```
### Cause
In the template, the value for <cbc:ID> was retrieved using `parent_document.get('id')` which fetched the sequential loop index https://github.com/odoo/enterprise/blob/cd25713fd2c35737d98db29df72b2d07ae9146e8/l10n_co_dian/views/templates.xml#L272-L275
The dictionary parsing logic did not extract the true document identifier from the XML tree response or the original XML data https://github.com/odoo/enterprise/blob/13dc30679e382df5845993c880a97df600c39ed4/l10n_co_dian/models/l10n_co_dian_document.py#L429-L432
### Steps to reproduce
- Install `l10n_co_dian`
- Setup DIAN configuration
- Generate an attached document for a commercial event or invoice
- Open the generated XML file
Before the fix, the `<cac:ParentDocumentLineReference>/<cac:DocumentReference>/<cbc:ID>` tag contains a technical integer like "1" instead of the official document sequence number
opw-6164321
Forward-Port-Of: odoo/enterprise#118319This update fixes a limitation where imported vendor bills from the Italian tax agency (SDI) couldn't be edited. Now, users can modify these bills through the system, ensuring accurate reporting and compliance with Italian tax regulations. This change addresses a specific workflow for importing bills and allows for necessary adjustments.
Original PR description
- Install l10n_it_edi - Create and confirm vendor bill - Use studio to make the field l10n_it_edi_transaction editable - Input any value - The reset to draft button disappears In _compute_show_reset_to_draft_button we hide the reset to draft button if l10n_it_edi_transaction is populated in order to filter out moves already sent to the tax agency. Normally invoices and bills sent to the SDI cannot be modified. However it is possible to import vendor bills from the SDI, and their transaction field is also imported. It should be possible to modified those imported invoices. opw-6222891 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#265748
This update resolves an issue where POS users were unable to process Mollie payments due to restricted access to Mollie API keys. By using a sudoed provider for Mollie API calls, all POS users can now successfully initiate payments without needing specific system-level permissions. This ensures a smoother payment experience for our POS customers.
Original PR description
Description of the issue/feature this PR addresses: POS users can trigger Mollie terminal payments without having access to the mollie_api_key field, which is only available to base.group_system. Use a sudoed Mollie provider when checking the API key and when calling the Mollie API, matching the access pattern used by other POS terminal integrations to avoid this issue. Current behavior before PR: POS user tries to initiate a payment via mollie, receives and AccessError. Desired behavior after PR is merged: POS user can successfully initiate a payment without the need for the base.group_system. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#264646
This update resolves a crash that occurred when generating ZATCA invoices for sale orders with multiple down-payment references. The fix prevents a software error caused by attempting to process both reversed and active down-payment invoices simultaneously. It ensures the final invoice can be correctly sent to ZATCA, improving the reliability of financial reporting.
Original PR description
Sending the final invoice of a sale order to ZATCA crashed with `ValueError: Expected singleton: account.move(a, b)` when the sale order had multiple down-payment references. Steps to reproduce: 1.…
Sending the final invoice of a sale order to ZATCA crashed with `ValueError: Expected singleton: account.move(a, b)` when the sale order had multiple down-payment references. Steps to reproduce: 1. Configure a SA company and setup ZATCA 2. Create a sale order and confirm it 3. Deliver the product line. 3. From the sale order, create a down-payment invoice (fixed amount, e.g. 115) and post it (DP1). 4. On DP1, click "Credit Note" and choose "Full refund and new draft invoice"; validate. DP1 becomes `reversed` and a new draft down-payment DP2 is created. Post DP2. 5. From the sale order, create the final regular invoice and post it. 6. Send the final invoice to ZATCA (or generate its XML) -> `ValueError: Expected singleton: account.move(a, b)`. Root cause: _l10n_sa_get_line_prepayment_vals looks up the related down-payment move through the down-payment sale order line shared with the product line. The filter matched any out_invoice with _is_downpayment() == True, so the reversed DP1 and the active DP2 both ended up in the recordset, and reading .name raised the singleton error. Prefer non-reversed down-payment moves when available, but fall back to reversed ones if no alternative exists (e.g. when generating a credit note of the final invoice after the original down-payment was itself reversed). opw-6116265 Forward-Port-Of: odoo/odoo#264435 Forward-Port-Of: odoo/odoo#259384
This update resolves an issue where refunded orders were still appearing in the 'orders to settle' list when the customer account balance was zero. The fix ensures that orders and their associated refunds are removed from this list when the customer account balance is fully reconciled, streamlining the settlement process for users.
Original PR description
Currently, if you refund an order made on the customer account with the customer account as well, you can still see the order in the list of orders to settle. Steps to reproduce: -------------------…
Currently, if you refund an order made on the customer account with the customer account as well, you can still see the order in the list of orders to settle. Steps to reproduce: ------------------- * Open shop * Make an order using the customer account for a customer, don't invoice it * Refund one of the order using the customer account, don't invoice it * Make a new order using the customer account * In the customer list, find the customer used and select "Settle Orders" > The 2 orders are present in the list Why the fix: ------------ Originally the list would only show the orders for chich the customers have due (>0). https://github.com/odoo/enterprise/commit/bf4b6043b999b4a081b1afa73fc4113bf4db28f8 But recently the code we also see the refunds in the list as well. https://github.com/odoo/enterprise/commit/12af23d5382e972facfaa999e4c5ab30c97e8d1f However this new behavior is not visible if, with the refund, the customer account temporarily falls to 0. So currently we have some refunds that impact the amount to settle and some that don't. Originally we were thinking that either we should show all refunds in that list (given they use the customer account) or we shouldn't show any as it was previously. Both solutions are not ideal. * Showing them all would get the list bigger than it is and would require the customer to select the order and its refund(s) and settle them together. Since refunds are not usually done right after the order they would not be close it that list. However this solution would enable the option to remove the orders from the list requiring a few step from the customer. * Showing none isn't idea either with this use case as it means that we still see orders that were cancelled out by their refunds. To remove to order the customer has two options. Either going backend and searching the order and its refund(s) and invoice them, either settling the order but that means that now there's money deposited on the customer account. Any of the two option isn't perfect a it still requires manual intervention from the customer and wouldn't work on previous data. Creating a server action to correct those data wouldn't have been feasible either. Instead, the approach we're taking is the following: When loading the list of order to settle we want to remove the orders and the potential refunds were the customer account is evened out. We only need to look at the orders of the partners that contains refunds for which the customer account was used. If the sum of the transactions made on the customer account is 0 we can say that the order and its refunds have cancelled out each other (in terms of customer account) and we don't show them if the list of orders remaining to settle. opw-6170830 Forward-Port-Of: odoo/enterprise#117725
This update resolves a validation issue with the company's XBRL reports submitted to the NBB. The fix adds missing data points to ensure the reports pass validation, preventing potential delays or errors in reporting. This ensures compliance and accurate financial reporting.
Original PR description
This commit adds missing explanatory disclosure datapoints to the generated XBRL report. The missing disclosures resulted in failing validation when report is submitted to NBB. The datapoints are only added if the original value was non-zero. For example, the tangible assets disclosures are only added if the tangible assets in balance sheet is non-zero. Additionally, only disclosures that were reported as causing a failing validation were added. task-5977199 Forward-Port-Of: odoo/enterprise#117853
This update resolves a bug that prevented quality checks from running correctly when modifying manufacturing operations on a sales order. The change adjusts how the system handles lot references, ensuring compatibility with recent Odoo updates and preventing errors related to outdated field names. This ensures quality checks function reliably after product modifications.
Original PR description
## Steps to reproduce: - Install the `quality_mrp` module. - Create a new product. - Create a Quality Point with: Type: Measure, Control per: Product/Operation Operations: Manufacturing - Create and…
## Steps to reproduce: - Install the `quality_mrp` module. - Create a new product. - Create a Quality Point with: Type: Measure, Control per: Product/Operation Operations: Manufacturing - Create and confirm MO for the product. - Update the Quality Point: Remove the 'manufacturing' operation type and add 'receipts' type. Change Control per to 'Quantity'. - Open the MO and start a quality check. - Enter an invalid measure and try to validate it. ## Error: `AttributeError - 'mrp.production' object has no attribute 'lot_producing_id'` ## Cause: Since commit https://github.com/odoo/odoo/commit/4bb4e08066449177f89382718ceadd840ce90d0e, the `lot_producing_id` field on MO was replaced by the Many2many field `lot_producing_ids`. Invalid references to the removed field lead to an error. ## Fix: This commit uses the first lot/serial from the MO. Note: Multiple produced lots are only possible for serial-tracked products. sentry-7511513479 Forward-Port-Of: odoo/enterprise#119231
This update fixes an issue where the cost of goods sold (COGS) was incorrectly calculated when products were delivered and returned. Previously, returns were not properly accounted for, leading to inaccurate COGS figures. Now, returns are correctly deducted, ensuring accurate COGS calculations for invoices, particularly when dealing with multiple deliveries and returns.
Original PR description
When the cogs are computed using the Stock Moves values, we would not differentiate between deliveries and returns, taking both in the cogs value computation. This meant that when doing multiple…
When the cogs are computed using the Stock Moves values, we would not differentiate between deliveries and returns, taking both in the cogs value computation. This meant that when doing multiple deliveries with returns before posting the invoice, if the deliveries/returns had different cost, the COGS would be an average of all of them. Example: Delivery $10 -> Return $10 -> Delivery $20 ==> COGS $13.33
## HOW TO REPRODUCE
- Create Product FIFO Perpetual, cost=10, onHand=1
- Create Sale order for 1 unit
- Deliver and return
- Change cost from 10 to 20:
- Set on hand to 0
- Change product cost to 20
- Set on hand to 1
- Duplicate SO delivery and validate
- Create and Post Invoice => COGS == 13.33
## FIX EXPLANATION
Returns / Refunds are counted negatively.
So when we compute the moves value, instead of doing `(10 + 10 + 20) / (1 + 1 + 1)`, we do `(10 - 10 + 20) / (1 - 1 + 1)`.
We need to propagate this logic to the cogs quantity, so that we don't believe that we invoiced 3 units while only 1 (1-1+1) was delivered.
---
Note:
For the update in test `test_fifo_delivered_invoice_post_delivery_with_return`, I put back the original values modified by 5978bc5dc683d317f4ab87f6c9c9d843568bf4ea
---
<img width="1852" height="363" alt="image" src="https://github.com/user-attachments/assets/ea9f16b2-a818-4c21-b3c3-aa296792f477" />
<img width="1203" height="787" alt="image" src="https://github.com/user-attachments/assets/7348d15a-b840-4ee0-b1da-2b954cdb3d5e" />
---
## Test result without fix:
```
2026-05-28 11:57:45,899 36667 INFO oes_test_19.0 odoo.addons.sale_stock.tests.test_anglo_saxon_valuation: Starting TestAngloSaxonValuation.test_fifo_invoice_with_delivery_with_return ...
2026-05-28 11:57:47,138 36667 INFO oes_test_19.0 odoo.addons.sale_stock.tests.test_anglo_saxon_valuation: ======================================================================
2026-05-28 11:57:47,138 36667 ERROR oes_test_19.0 odoo.addons.sale_stock.tests.test_anglo_saxon_valuation: FAIL: TestAngloSaxonValuation.test_fifo_invoice_with_delivery_with_return
Traceback (most recent call last):
File "/home/odoo/Odoo/src/19.0/odoo/addons/sale_stock/tests/test_anglo_saxon_valuation.py", line 1099, in test_fifo_invoice_with_delivery_with_return
self.assertRecordValues(invoice.line_ids, [
File "/home/odoo/Odoo/src/19.0/odoo/odoo/tests/common.py", line 727, in assertRecordValues
self.assertSequenceEqual(expected_reformatted, record_reformatted, seq_type=list)
AssertionError: Lists differ: [{'ac[22 chars]t': 0, 'credit': 50}, {'account_id': 9141, 'de[114 chars]: 0}] != [{'ac[22 chars]t': 0.0, 'credit': 50.0}, {'account_id': 9141,[132 chars]0.0}]
First differing element 2:
{'account_id': 9138, 'debit': 0, 'credit': 20}
{'account_id': 9138, 'debit': 0.0, 'credit': 13.33}
- [{'account_id': 9162, 'credit': 50, 'debit': 0},
+ [{'account_id': 9162, 'credit': 50.0, 'debit': 0.0},
? ++ ++
- {'account_id': 9141, 'credit': 0, 'debit': 50},
+ {'account_id': 9141, 'credit': 0.0, 'debit': 50.0},
? ++ ++
- {'account_id': 9138, 'credit': 20, 'debit': 0},
? ^^
+ {'account_id': 9138, 'credit': 13.33, 'debit': 0.0},
? ^^^^^ ++
- {'account_id': 9168, 'credit': 0, 'debit': 20}]
? ^^
+ {'account_id': 9168, 'credit': 0.0, 'debit': 13.33}]
? ++ ^^^^^
```
---
OPW-6213321
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#268128
Forward-Port-Of: odoo/odoo#266917This update dynamically adjusts the number of pages processed when uploading PDFs to the AI chat feature. Previously, uploads were limited to 5 pages. Now, the system can handle entire documents, improving the efficiency of AI-powered conversations. This change ensures agents can fully utilize the AI's capabilities with PDF attachments.
Original PR description
Prior to this commit, when uploading a document (i.e. during a chat with an agent). Only a part of its pages would get parsed and sent to the API (5 pages). With this commit, the number of pages is made dynamic by the use of a new context key `ai_max_pdf_pages`. This variable is still set for the document autosorting features since it is not required to read the full document. Default value is None (no limit). Forward-Port-Of: odoo/enterprise#119338
This update resolves an issue preventing Verifactu documents from being generated when invoicing a Point of Sale order directly. Previously, the system required a cancellation step before invoicing, which caused errors. Now, the system correctly handles invoicing directly, ensuring Verifactu documents are created seamlessly.
Original PR description
**Steps to reproduce:** - Setup a Verifactu installation and a Spanish company - Go to the PoS, make a Sale - Keep the ticket - Go to the /pos/ticket URL and enter the ticket informations - Last step…
**Steps to reproduce:** - Setup a Verifactu installation and a Spanish company - Go to the PoS, make a Sale - Keep the ticket - Go to the /pos/ticket URL and enter the ticket informations - Last step also works when requesting an invoice in the backend on the order - Go to the order in the backend, an error is shown, the cancellation didn't go through **Veri*Factu documents can only be generated for paid or posted Point of Sale Orders.** **Why the fix:** When we directly invoice an order, we do not go through the verification of being paid and done. This is why is works, but when making the invoice after the sale is done, we cancel the order first, then we register the invoice instead. When trying to cancel the order, we check if the order is either paid or done, but it is currently invoiced as we just generated the invoice. We now allow no errors if the order is in the invoiced state, and let it pass through. With this flow we get the same result as the direct invoice from the PoS. The new cancellation on the order and submission on the invoice may take a bit of time to get accepted but they will be eventually. opw-6139200 Forward-Port-Of: odoo/odoo#267869 Forward-Port-Of: odoo/odoo#264272
This update resolves an issue where validating delivery costs on confirmed sales orders (with 'Lock Confirmed Sales' enabled) would trigger an error. The fix prevents the system from incorrectly applying carrier prices to delivery lines when a real-cost invoicing policy is used, ensuring smooth order processing even on locked sales.
Original PR description
Sale module has setting `Lock Confirmed Sales`, which particularly doesn't allow order line modification on a confirmed order. However, when a delivery carrier is set up with Invoicing Policy = Real cost, validating the picking pushes the actual carrier price onto the delivery line, writing `price_unit` and `name`. On a locked SO this raises a UserError. Fix it by excluding the delivery line's `price_unit` and `name` from the protected fields, only when the write originates from `_add_delivery_cost_to_so`. The code path is identified by the context `allow_delivery_cost_update`, so a regular UI edit of those fields on a locked SO is still blocked. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#266511 Forward-Port-Of: odoo/odoo#265721
This update fixes an issue where payments for Mexican invoices were being sent to CFDI multiple times, leading to inaccurate payment records. The change ensures the 'Update Payments' button only appears after the invoice payment is fully reconciled, preventing duplicate submissions and maintaining accurate financial reporting.
Original PR description
Issue: Sending payments to SAT before its full amount is reconciled allow sending the same invoice payment several times to CFDI. Steps to reproduce: - In a Mexican company - Create an invoice A of…
Issue: Sending payments to SAT before its full amount is reconciled allow sending the same invoice payment several times to CFDI. Steps to reproduce: - In a Mexican company - Create an invoice A of $40 to Inmobiliaria CVA - Confirm and send to CFDI - Go to bank, create a new Bank transaction of $80 - reconcile with Invoice A - Go to invoice A => click on button "Update payments" (it doesn't appear in previous versions) - Then sheet CFDI and Download There is the first XML sent to CFDI with payment for invoice A - Create an invoice B of $40 to Inmobilira CVA - Confirm and send to CFDI - reconcile the transaction with Invoice B - Go to invoice B - Click on button "Update payments" - Then sheet CFDI and Download There is the second XML sent to CFDI with payment for invoices A and B Invoice A payment was sent twice to CFDI Expected behavior: - The "Update payment" button should appear only once the invoice payment is fully reconciled. Current behavior: - The update payment button appear once the invoice is reconciled with a payment. The method `_l10n_mx_edi_cfdi_invoice_get_payments_diff` is called twice, once to check whether it's needed to display the "Update button" and once when you try to update the payment (called only after clicking on said button). opw-5432421 Forward-Port-Of: odoo/enterprise#119244 Forward-Port-Of: odoo/enterprise#108355
This update fixes a crash issue in the Point of Sale interface when a large number of customers are stored in the browser cache. The change limits the number of partners rendered during searches, improving performance and stability, particularly when dealing with extensive customer lists. This ensures a smoother user experience for POS operations.
Original PR description
Currently, it's possible to experience very slow loading speed of the partner list and/or browser crashes in the POS when there are thousands of customers stored in the browser cache. This appears to…
Currently, it's possible to experience very slow loading speed of the partner list and/or browser crashes in the POS when there are thousands of customers stored in the browser cache.
This appears to be caused by a few reasons compounding together:
1. While we limit the number of customers in the initial render of the list, there is no limit during the search. Therefore, if there are thousands of customers matching the search pattern loaded in the browser cache, the browser will attempt to render equally as many `PartnerLine` components.
2. A 100 ms debounce time is fast enough to trigger the render after each key stroke. 200~300ms is the industry standard for Software UI debounce.
3. For each customer rendered in the list, we may perform a search for its parent partner amongst all loaded customers with the function `PosStore.getPartnerCredit()`.
This PR aims at reducing the number of partner lines rendered in a short period of time and thus, at improving speed and avoiding crashes.
Steps to reproduce:
1. Create a fresh db + install the point_of_sale with demo data
2. Populate the res.partner model by a factor of 100 to reach 4000+ partners
3. Update the following system parameter to make sure that we load all partners in the browser cache when we open the POS session:
- `point_of_sale.limited_customer_count` -> 5000
4. Open a POS session and and click on the `Customer` button to render the partner list
5. Type `adm` in the search bar at normal typing speed
6. Crash
Ticket: opw-5435973
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#258667This update fixes an error in the import of Italian vendor invoices (l10n_it_edi) where pension fund tax was incorrectly applied to all invoice lines with the same VAT rate. The fix extracts the specific tax exemption reason from the invoice data, ensuring the correct tax is applied to the first line, leading to accurate financial reporting.
Original PR description
In `l10n_it_edi` vendor bill import, the pension fund tax was incorrectly applied to all invoice lines sharing the same VAT rate, even though they have different `l10n_it_tax_exemption_reason`s, resulting in wrong entries and document total. We now extract the Tax Exemption reason from the `DatiCassaPrevidenziale` node, and use it to search the correct tax. Steps to reproduce: 1. Install `account` and `l10n_edi_it` 2. In the `4% INPS` tax, set `TC22` in pension fund type and `N2.2` in exoneration 3. Import bill from the ticket 4. See the pension fund tax is applied to all the lines. It should only be applied only to the first one. Ticket [link](https://www.odoo.com/odoo/project.task/6212975) opw-6212975 Forward-Port-Of: odoo/odoo#267066 Forward-Port-Of: odoo/odoo#265821
This update resolves a crash that occurred when the Discuss app was initially loaded with demo data. The issue stemmed from an infinite loop within the app's data storage, triggered by how new conversations were added. By tracking changes to the data storage more accurately, this fix prevents the crash and ensures stable operation.
Original PR description
Backport of https://github.com/odoo/odoo/pull/267790 Before this commit, when loading discuss app initially with demo data, sometimes there was a crash from maximum stack. This happens due to…
Backport of https://github.com/odoo/odoo/pull/267790 Before this commit, when loading discuss app initially with demo data, sometimes there was a crash from maximum stack. This happens due to infinite loop in discuss store with field `livechats`, which as a computed inverse `appAsLivechat`: - Initially the field `livechats` has 2 conversations `[1, 2]` - When adding conversation `3`, the `appAsLivechat` auto-computes to add this conversation to `livechats`, which triggers these field commands: 1. `appAsLivechat`: `[["REPLACE", 3]]` 2. `livechats`: `[["ADD.noinv", DiscussApp]]` This is fine by itself, but somehow the `"ADD.noinv"` triggers a `[["DELETE.noinv", 1]]` on the inverse field `appAsLivechat`, which is then turned by the versioning system into a `[["REPLACE", [3]]]`, which in turn does a `[["DELETE.noinv", 1]]` and so on infinitely. The `"DELETE.noinv"` is turned into `"REPLACE"` by the versioning of fields, which is ok, but it does it mistakenly with only considering new field `[3]` rather than having also `[1, 2]` that was there before. The history lacks `[1, 2]` so that's why it can't `"REPLACE"` with these values, even though the saved data already has them, but then the store is aware of deletion of these records, hence the infinite loop. The underlying issue is that live chats `[1, 2]` were added in store without any track in history. This comes from some internal operations on record lists that apply related change on inverse, but this is done immediately with `.add()` or `.delete()` which doesn't reach the tracking of history of field version in `updateFields()`. This commit fixes the issue by converting the `[inverse].add()` and `[inverse].delete()` into `updateFields()`, so that this is the same operation but it makes it tracked by the field version history. Task-6073452
This update fixes an issue where discounts entered with commas (used as decimal separators in some regions) were incorrectly interpreted as zero. The change ensures that discount values, regardless of the decimal separator used, are accurately applied to orders, preventing revenue loss and improving order accuracy.
Original PR description
Before this commit, if comma was used as decimal separator, the fixed discount valu was added to the order as zero discount. opw-6268557 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#267954
This update resolves an issue where inserting certain website snippets (like alerts) within restricted editable areas created HTML errors. The fix prevents the snippet from being broken down into invalid elements, ensuring the website builder functions correctly and produces valid HTML. This improves the overall stability and usability of the website building tool.
Original PR description
### [FIX] website: prevent inserting block snippet with powerbox in inlines Inserting block snippet with powerbox when the selection is inside an editable part limited to an element that can only…
### [FIX] website: prevent inserting block snippet with powerbox in inlines Inserting block snippet with powerbox when the selection is inside an editable part limited to an element that can only contain inline nodes leads to invalid html (like `<div>` inside `<span>`). This commit disables insertion of block snippets when the selection is such a part of the document. Steps to reproduce: - Open website builder - Put cursor in "copyright" at the bottom of the footer - Type `/alert` and press enter - Bug: `<div>` element is inserted inside `<span>`, that is invalid html task-6259092 ### [FIX] website: prevent unwrapping `s_blockquote` on insert with powerbox When the snippet `s_blockquote` was inserted with the powerbox or pasted from clipboard in an unbreakable element which does not allow blocks as children, the `<blockquote>` element itself was abandonned and its children were inserted instead. This lead to insertion of a broken snippet. This commit marks the `s_blockquote` snippet as "unsplittable" so that always stays in one piece when inserted. Steps to reproduce: - Open website builder - Put cursor in a link - Type `/blockquote` and press enter - Bug: the snippet's children are inserted, instead of snippet itself task-6259092 Forward-Port-Of: odoo/odoo#267111
14 changes
Resolved issues and error corrections
This update resolves a critical issue where the Swedish SIE 4 report export would crash due to excessive memory usage. The fix dramatically improves performance by optimizing the database query and reducing the amount of data processed in Python, allowing for handling of large datasets efficiently.
Original PR description
### Description of the issue/feature this PR addresses: Prevent Out of Memory (OOM) crashes and drastically improve execution speed when generating the Swedish SIE4 verification export for massive…
### Description of the issue/feature this PR addresses: Prevent Out of Memory (OOM) crashes and drastically improve execution speed when generating the Swedish SIE4 verification export for massive datasets. ### Current behavior before PR: When exporting a large volume of journal entries (e.g., 190,000+ account moves), the `_export_l10n_se_sie4_verification` method relies on iterating through heavy ORM recordsets and accessing relational child fields (move.line_ids) inside a loop. This triggers a severe N+1 query problem, maxing out server RAM and causing an OOM crash. ### Desired behavior after PR is merged: The method now utilizes a hybrid data extraction approach: - The ORM is used strictly to safely evaluate domains (multi-company rules, dates, states) and fetch a lightweight list of valid move_ids. - A single SQL query with JOIN statements fetches all parent moves, child lines, and account codes in exactly one database query. - itertools.groupby chunks the flat, lightweight dictionary results back into their respective journal entries. The export now handles massive datasets in seconds with minimal memory overhead, while remaining perfectly secure. ### Benchmark: For Memory: | # Input Data | Before PR | After PR | | -------- | -------- | -------- | | ~190,000 moves | MemoryError | 407MB| | ~200,000 moves | 1.8GB | 174.8 MB| For Speed: | # Input Data | Before PR | After PR | | -------- | -------- | -------- | | ~190,000 moves | MemoryError | 5.10s | | ~200,000 moves | 1m29s| 5.3s| ### Reference: opw-6067999 Forward-Port-Of: odoo/enterprise#118849 Forward-Port-Of: odoo/enterprise#113227
This update fixes an issue where generated invoices for Colombia (l10n_co_dian) were incorrectly exporting a generic line number instead of the required document ID. This prevented the invoices from passing validation checks with DIAN and external systems. The fix ensures the correct document ID is used, resolving compatibility problems.
Original PR description
### Issue When generating the attached document (AttachedDocument) for Colombia, the parent document reference tag <cbc:ID> incorrectly exported a generic line counter instead of the actual document…
### Issue
When generating the attached document (AttachedDocument) for Colombia, the parent document reference tag <cbc:ID> incorrectly exported a generic line counter instead of the actual document identification number
While the DIAN platform itself accepted the file, this caused rejections in external validation tools and third-party software because they could not resolve the link back to the original invoice
DIAN Documentation: https://www.dian.gov.co/impuestos/factura-electronica/Documents/Anexo_tecnico_factura_electronica_vr_1_7_2020.pdf
On page 213 there is an example for ParentDocumentLineReference
On page 216 there is the specification that does not show any check
Example of the incorrect XML structure:
```xml
<cac:ParentDocumentLineReference>
<cbc:LineID>1</cbc:LineID>
<cac:DocumentReference>
<cbc:ID>1</cbc:ID>
</cac:DocumentReference>
</cac:ParentDocumentLineReference>
```
Expected XML structure:
```xml
<cac:ParentDocumentLineReference>
<cbc:LineID>1</cbc:LineID>
<cac:DocumentReference>
<cbc:ID>SETP990001021</cbc:ID>
</cac:DocumentReference>
</cac:ParentDocumentLineReference>
```
### Cause
In the template, the value for <cbc:ID> was retrieved using `parent_document.get('id')` which fetched the sequential loop index https://github.com/odoo/enterprise/blob/cd25713fd2c35737d98db29df72b2d07ae9146e8/l10n_co_dian/views/templates.xml#L272-L275
The dictionary parsing logic did not extract the true document identifier from the XML tree response or the original XML data https://github.com/odoo/enterprise/blob/13dc30679e382df5845993c880a97df600c39ed4/l10n_co_dian/models/l10n_co_dian_document.py#L429-L432
### Steps to reproduce
- Install `l10n_co_dian`
- Setup DIAN configuration
- Generate an attached document for a commercial event or invoice
- Open the generated XML file
Before the fix, the `<cac:ParentDocumentLineReference>/<cac:DocumentReference>/<cbc:ID>` tag contains a technical integer like "1" instead of the official document sequence number
opw-6164321
Forward-Port-Of: odoo/enterprise#118319A recent change incorrectly configured the Gantt view for appointments, causing new bookings to default to midnight instead of the intended start time. This fix corrects the override to the correct method, ensuring bookings now use the expected time logic. This resolves a scheduling issue impacting appointment creation.
Original PR description
The [commit] replaced the `onAddClicked` method with `_onNewClicked`, and updated all related calls and overrides accordingly. However, the appointment Gantt view override was mistakenly changed to override a non-existent `_onAddClicked` method, leaving the custom logic unused. As a result, bookings created through the `New` button in the Gantt view used midnight (12:00 AM) instead of the time derived from the custom logic as the default start datetime. This commit fixes the issue by correctly overriding `_onNewClicked`. [commit]: https://github.com/odoo/enterprise/commit/bc779c9ec5295f8d1fe06e8432c518c78c606ea2 Forward-Port-Of: odoo/enterprise#118799
This update enables users to modify vendor bills imported from the Italian tax agency (SDI). Previously, these bills were treated as final and unchangeable. This change ensures compliance with Italian regulations by allowing adjustments to imported invoices before they are submitted to the tax authority, resolving a limitation in the system.
Original PR description
- Install l10n_it_edi - Create and confirm vendor bill - Use studio to make the field l10n_it_edi_transaction editable - Input any value - The reset to draft button disappears In _compute_show_reset_to_draft_button we hide the reset to draft button if l10n_it_edi_transaction is populated in order to filter out moves already sent to the tax agency. Normally invoices and bills sent to the SDI cannot be modified. However it is possible to import vendor bills from the SDI, and their transaction field is also imported. It should be possible to modified those imported invoices. opw-6222891 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#265748
This update resolves an issue where POS users couldn't successfully initiate Mollie payments. By using a special, elevated provider for Mollie API calls, the system now correctly handles payment requests without requiring specific system-level access. This ensures a smoother payment experience for all POS users.
Original PR description
Description of the issue/feature this PR addresses: POS users can trigger Mollie terminal payments without having access to the mollie_api_key field, which is only available to base.group_system. Use a sudoed Mollie provider when checking the API key and when calling the Mollie API, matching the access pattern used by other POS terminal integrations to avoid this issue. Current behavior before PR: POS user tries to initiate a payment via mollie, receives and AccessError. Desired behavior after PR is merged: POS user can successfully initiate a payment without the need for the base.group_system. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#264646
This update resolves an issue where refunded orders were still visible in the 'Orders to Settle' list when linked to a customer account. The fix ensures that orders and their associated refunds are removed from this list when the customer account balance is zero, streamlining the settlement process for users.
Original PR description
Currently, if you refund an order made on the customer account with the customer account as well, you can still see the order in the list of orders to settle. Steps to reproduce: -------------------…
Currently, if you refund an order made on the customer account with the customer account as well, you can still see the order in the list of orders to settle. Steps to reproduce: ------------------- * Open shop * Make an order using the customer account for a customer, don't invoice it * Refund one of the order using the customer account, don't invoice it * Make a new order using the customer account * In the customer list, find the customer used and select "Settle Orders" > The 2 orders are present in the list Why the fix: ------------ Originally the list would only show the orders for chich the customers have due (>0). https://github.com/odoo/enterprise/commit/bf4b6043b999b4a081b1afa73fc4113bf4db28f8 But recently the code we also see the refunds in the list as well. https://github.com/odoo/enterprise/commit/12af23d5382e972facfaa999e4c5ab30c97e8d1f However this new behavior is not visible if, with the refund, the customer account temporarily falls to 0. So currently we have some refunds that impact the amount to settle and some that don't. Originally we were thinking that either we should show all refunds in that list (given they use the customer account) or we shouldn't show any as it was previously. Both solutions are not ideal. * Showing them all would get the list bigger than it is and would require the customer to select the order and its refund(s) and settle them together. Since refunds are not usually done right after the order they would not be close it that list. However this solution would enable the option to remove the orders from the list requiring a few step from the customer. * Showing none isn't idea either with this use case as it means that we still see orders that were cancelled out by their refunds. To remove to order the customer has two options. Either going backend and searching the order and its refund(s) and invoice them, either settling the order but that means that now there's money deposited on the customer account. Any of the two option isn't perfect a it still requires manual intervention from the customer and wouldn't work on previous data. Creating a server action to correct those data wouldn't have been feasible either. Instead, the approach we're taking is the following: When loading the list of order to settle we want to remove the orders and the potential refunds were the customer account is evened out. We only need to look at the orders of the partners that contains refunds for which the customer account was used. If the sum of the transactions made on the customer account is 0 we can say that the order and its refunds have cancelled out each other (in terms of customer account) and we don't show them if the list of orders remaining to settle. opw-6170830 Forward-Port-Of: odoo/enterprise#117725
This update dynamically adjusts the number of pages processed when uploading PDFs to the AI chat feature. Previously, uploads were limited to 5 pages. Now, the system can handle entire documents, improving the efficiency of AI-powered conversations. This change ensures agents can fully utilize the AI's capabilities with PDF attachments.
Original PR description
Prior to this commit, when uploading a document (i.e. during a chat with an agent). Only a part of its pages would get parsed and sent to the API (5 pages). With this commit, the number of pages is made dynamic by the use of a new context key `ai_max_pdf_pages`. This variable is still set for the document autosorting features since it is not required to read the full document. Default value is None (no limit). Forward-Port-Of: odoo/enterprise#119338
This update fixes an issue where check amounts were not being properly rounded when generated in the Philippines. The change ensures that check amounts are displayed accurately, removing the "ONLY" suffix and improving the overall payment process for PH customers. This ensures compliance with local regulations and provides a more professional customer experience.
Original PR description
Current behaviour: --- When paying with checks, the amount is not rounded in the check amount in words string. Steps to reproduce: --- 1. Switch to PH company 2. Set setting Check Layout as "Print Check - PH" 3. Create a new vendor bill 4. Add a product with a specific price like 91490.15 5. Confirm the bill, click on Register Payment 6. Select Payment Method "Checks", Create Payment 7. Go to the payment, Amount in Words is wrong 8. Ninety-One Thousand Four Hundred Ninety And 15000000001/100 ONLY Expected behaviour: --- The decimal amount should be rounded, and "ONLY" shouldn't appear. Fix: --- Rounded the pay amount And backported: https://github.com/odoo/enterprise/commit/bb6c9848665709c14c5113b2c98976f869cd473b opw-6058344 Forward-Port-Of: odoo/enterprise#117679 Forward-Port-Of: odoo/enterprise#116717
This update resolves a critical issue preventing Odoo's financial reports from passing validation with the National Bank of Belgium (NBB). The fix adds missing data points to the XBRL report, ensuring compliance and accurate submissions. This change specifically addresses datapoints related to balance sheet figures.
Original PR description
This commit adds missing explanatory disclosure datapoints to the generated XBRL report. The missing disclosures resulted in failing validation when report is submitted to NBB. The datapoints are only added if the original value was non-zero. For example, the tangible assets disclosures are only added if the tangible assets in balance sheet is non-zero. Additionally, only disclosures that were reported as causing a failing validation were added. task-5977199 Forward-Port-Of: odoo/enterprise#117853
This update fixes an error in the import of Italian vendor invoices (l10n_it_edi) where pension fund tax was incorrectly applied to all invoice lines with the same VAT rate. The fix now accurately extracts the tax exemption reason from the invoice data, ensuring the correct tax is applied to each line, leading to accurate financial reporting.
Original PR description
In `l10n_it_edi` vendor bill import, the pension fund tax was incorrectly applied to all invoice lines sharing the same VAT rate, even though they have different `l10n_it_tax_exemption_reason`s, resulting in wrong entries and document total. We now extract the Tax Exemption reason from the `DatiCassaPrevidenziale` node, and use it to search the correct tax. Steps to reproduce: 1. Install `account` and `l10n_edi_it` 2. In the `4% INPS` tax, set `TC22` in pension fund type and `N2.2` in exoneration 3. Import bill from the ticket 4. See the pension fund tax is applied to all the lines. It should only be applied only to the first one. Ticket [link](https://www.odoo.com/odoo/project.task/6212975) opw-6212975 Forward-Port-Of: odoo/odoo#267066 Forward-Port-Of: odoo/odoo#265821
This update resolves an issue where Romanian E-Factura invoices were being rejected due to exceeding character limits for product names, descriptions, and notes. The system has been updated to enforce a maximum of 100 characters for names, 200 for descriptions, and 300 for notes, ensuring compliance with Romanian regulations. This prevents invoice errors and successful E-Factura transmission.
Original PR description
**Steps to reproduce:** - Install Accounting and l10n_ro_edi - Switch to a Romanian localization (e.g. RO Company) - Configure Romanian E-Factura - Create an invoice with a product having a name…
**Steps to reproduce:** - Install Accounting and l10n_ro_edi - Switch to a Romanian localization (e.g. RO Company) - Configure Romanian E-Factura - Create an invoice with a product having a name longer than 100 chars - Confirm the invoice - Send E-Factura to SPV - Fetch E-Factura status **Issue:** The invoice is rejected with the following error: "[BR-RO-L100]-The allowed maximum number of characters for the Item name (BT-153) is 100." **Similar issue with the product description:** "[BR-RO-L200]-The allowed maximum number of characters for the Item description (BT-154) is 200." **Similar issue with the note (i.e. Terms and Conditions):** "[BR-RO-L300]-The allowed maximum number of characters for the Invoice note (BT-22) is 300." **Solution:** Truncate the name of the product to 100 chars in the electronic invoice, the description of the product to 200 and the note to 300. opw-5964904 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#268192 Forward-Port-Of: odoo/odoo#265811
This update resolves a problem where validating delivery costs on confirmed sales orders (with real-cost carrier pricing) would trigger an error. The fix prevents the system from incorrectly updating delivery line prices and names on locked orders, ensuring smooth order processing. This improves the user experience for sales teams managing confirmed orders.
Original PR description
Sale module has setting `Lock Confirmed Sales`, which particularly doesn't allow order line modification on a confirmed order. However, when a delivery carrier is set up with Invoicing Policy = Real cost, validating the picking pushes the actual carrier price onto the delivery line, writing `price_unit` and `name`. On a locked SO this raises a UserError. Fix it by excluding the delivery line's `price_unit` and `name` from the protected fields, only when the write originates from `_add_delivery_cost_to_so`. The code path is identified by the context `allow_delivery_cost_update`, so a regular UI edit of those fields on a locked SO is still blocked. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#266511 Forward-Port-Of: odoo/odoo#265721
This update fixes a performance issue in the Point of Sale interface where a large number of customers in the browser cache could cause slow loading and browser crashes. The change limits the number of partners rendered during searches, improving speed and stability for users.
Original PR description
Currently, it's possible to experience very slow loading speed of the partner list and/or browser crashes in the POS when there are thousands of customers stored in the browser cache. This appears to…
Currently, it's possible to experience very slow loading speed of the partner list and/or browser crashes in the POS when there are thousands of customers stored in the browser cache.
This appears to be caused by a few reasons compounding together:
1. While we limit the number of customers in the initial render of the list, there is no limit during the search. Therefore, if there are thousands of customers matching the search pattern loaded in the browser cache, the browser will attempt to render equally as many `PartnerLine` components.
2. A 100 ms debounce time is fast enough to trigger the render after each key stroke. 200~300ms is the industry standard for Software UI debounce.
3. For each customer rendered in the list, we may perform a search for its parent partner amongst all loaded customers with the function `PosStore.getPartnerCredit()`.
This PR aims at reducing the number of partner lines rendered in a short period of time and thus, at improving speed and avoiding crashes.
Steps to reproduce:
1. Create a fresh db + install the point_of_sale with demo data
2. Populate the res.partner model by a factor of 100 to reach 4000+ partners
3. Update the following system parameter to make sure that we load all partners in the browser cache when we open the POS session:
- `point_of_sale.limited_customer_count` -> 5000
4. Open a POS session and and click on the `Customer` button to render the partner list
5. Type `adm` in the search bar at normal typing speed
6. Crash
Ticket: opw-5435973
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#258667This update resolves an issue where inserting certain website snippets (like alerts) within restricted editable areas created invalid HTML. The fix prevents the snippet from being broken down into smaller elements, ensuring the website builder generates valid and functional code. This improves the reliability and usability of the website design tool.
Original PR description
### [FIX] website: prevent inserting block snippet with powerbox in inlines Inserting block snippet with powerbox when the selection is inside an editable part limited to an element that can only…
### [FIX] website: prevent inserting block snippet with powerbox in inlines Inserting block snippet with powerbox when the selection is inside an editable part limited to an element that can only contain inline nodes leads to invalid html (like `<div>` inside `<span>`). This commit disables insertion of block snippets when the selection is such a part of the document. Steps to reproduce: - Open website builder - Put cursor in "copyright" at the bottom of the footer - Type `/alert` and press enter - Bug: `<div>` element is inserted inside `<span>`, that is invalid html task-6259092 ### [FIX] website: prevent unwrapping `s_blockquote` on insert with powerbox When the snippet `s_blockquote` was inserted with the powerbox or pasted from clipboard in an unbreakable element which does not allow blocks as children, the `<blockquote>` element itself was abandonned and its children were inserted instead. This lead to insertion of a broken snippet. This commit marks the `s_blockquote` snippet as "unsplittable" so that always stays in one piece when inserted. Steps to reproduce: - Open website builder - Put cursor in a link - Type `/blockquote` and press enter - Bug: the snippet's children are inserted, instead of snippet itself task-6259092 Forward-Port-Of: odoo/odoo#267111
19 changes
New functionality added to Odoo
This update implements the required Belgian Registered Cash Register (Caisse Enregistreuse Certifiée) v2 specifications for Odoo POS systems. It ensures accurate fiscal data transmission to the FPS Finance system, handling sales, refunds, and other transactions with the necessary compliance features and robust error handling.
Original PR description
Implement the Belgian Registered Cash Register (Caisse Enregistreuse Certifiée) v2 specification as required by FPS Finance for certified POS restaurant systems. The implementation is split into a…
Implement the Belgian Registered Cash Register (Caisse Enregistreuse Certifiée) v2 specification as required by FPS Finance for certified POS restaurant systems. The implementation is split into a core module and five bridge modules: l10n_be_pos_blackbox (main module): - FDM (Fiscal Data Module) communication layer that signs every fiscal event by sending a structured message to the blackbox device and receiving a hash + VSC counter in return. M110 (sale), M111 (refund), M112 (partial refund), M121 (order), M122 (cost-centre change), M123 (pre-bill), M130 (money in/out), M131 (drawer open), M140/M141 (work in/out), M150 (invoice), M160 (copy), M180/M181 (X/Z turnover report), M182/M183 (user X/Z report), UC230 (sale correction). M160 (copy), M180/M181 (X/Z turnover report), M182/M183 (user X/Z report), UC230 (sale correction). - Input generator that encodes all line-level fiscal data (PLU hash, VAT groups, price rounding, grouping IDs) according to the spec. - Fiscal receipt template (XML) that renders the blackbox hash, VSC counter, POS system identifier, and event sequence number on every printed receipt. - X/Z daily report views with fiscal totals per VAT category. - Training-mode support: activates the FDM training flag so the device does not count test transactions. - Inspect popup (debug) for examining raw FDM messages. - Error/warning popup system with traceback messages from the device. - LocalStorage queue to replay pending mutations after a network outage. - pos_config / pos_session overrides: enforce blackbox constraints (only EUR, no rounding, mandatory restaurant mode, etc.), manage device pairing, and accumulate per-session fiscal counters. - Extensive unit-test suite: >6 000 lines covering the input generator's grouping-ID logic, price-consistency rules, and every mutation type against golden JSON fixtures. - Browser tour tests (oracle + regression tours). l10n_be_pos_blackbox_hr: - Clock-in / clock-out flows for employees trigger M140/M141 work in/out mutations; employee INSZ/NISS number is required and stored on hr.employee; pos_session accumulates per-employee work records. l10n_be_pos_blackbox_loyalty: - Gift-card and discount reward lines are mapped to the correct MPV fiscal codes (UC260/UC261); loyalty products are flagged so the input generator can calculate their contribution to the signed total correctly. l10n_be_pos_blackbox_self_order: - Intercepts self-order confirmation on kiosk screens to sign the order with the FDM before the confirmation page is shown; adds a controller to expose the required blackbox data to the kiosk frontend. l10n_be_pos_blackbox_settle_due: - Handles the "settle due" payment flow: products used to represent deferred payments are flagged and treated as zero-VAT lines in the signed message. l10n_be_pos_blackbox_urban_piper: - Patches the Urban Piper ticket-screen and pos_store so that online orders routed through Urban Piper are also signed before finalisation. task-id: 5864870 community PR: https://github.com/odoo/odoo/pull/229692 Forward-Port-Of: odoo/enterprise#96130
This update integrates support for the new Belgian blackbox v2 system, allowing Odoo to seamlessly track and manage transactions for Belgian retailers. Key changes include customizable workflows and data handling to meet specific blackbox requirements, ensuring accurate reporting and compliance.
Original PR description
Refactor several POS core methods into overridable hooks so that l10n_be_pos_blackbox (v2) can intercept and extend critical flows to implement the new blackbox requirements. point_of_sale: -…
Refactor several POS core methods into overridable hooks so that l10n_be_pos_blackbox (v2) can intercept and extend critical flows to implement the new blackbox requirements. point_of_sale: - pos_store.js: extract posBackOnline(), openCashbox(), getSelfOrderToPrint(), and resetCashier() as dedicated methods; setCashier() now returns a boolean; preSyncAllOrders() now returns the orders array, and the sync loop skips an order when it returns falsy (allows blackbox to block premature syncing); add orderReceiptComponent class property so the receipt component can be substituted by submodules. - order_payment_validation.js: extract canPrintReceipt getter (makes it overridable); fix absolute import path for error_handlers; fix typo "occured" → "occurred". - pos_session.py: load product.template / product.product before account.tax in _load_pos_data_models to satisfy the blackbox data dependency order; include account_move id in the invoice list returned by the session sales-details report. pos_hr: - Split setCashier() into setCashier() + setCashierUpdateSession() so the session-update side-effect can be called independently by the blackbox during clock-in/out flows. Return true from setCashier() consistently with the base method. pos_loyalty: - Override displayPrice on order lines so gift-card trigger products always display a positive price, even when the order is a refund. pos_restaurant: - Refactor mergeOrders() into _mergeOrders() + _mergeLines() private helpers; add getLinesToMerge() hook so blackbox can filter which lines participate in a merge; mergeOrders() now returns the destination order; extract syncRestoredOrders() for overridability; replace the while-loop-with-guard-counter with a plain for-of loop. pos_self_order: - Add orderReceiptComponent property; extract handleKioskSessionStatusChange() so the kiosk status-change behaviour can be overridden by the blackbox self-order bridge. task-id: 5864870 enterprise PR: https://github.com/odoo/enterprise/pull/96130 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#229692
Resolved issues and error corrections
This update ensures that mobile self-order receipts are always signed before printing, resolving an issue where orders were lost due to customers closing the browser before confirmation. The fix pushes signatures to the blackbox server-side, regardless of the customer's browsing behavior, improving order accuracy and preventing lost data.
Original PR description
Mobile self-order clients never land on the confirmation page, so their orders were never sent to the blackbox fiscal data module and receipts were printed unsigned. Fix this by: - Overriding `getSelfOrderToPrint` to push the order to the blackbox if it has no signature yet, called when the payment notification arrives. - Restricting `beforePrintOrder` in the confirmation page to kiosk mode only, since mobile orders are now signed via `getSelfOrderToPrint`. task-id: 6172108 community PR: https://github.com/odoo/odoo/pull/263238 Forward-Port-Of: odoo/enterprise#116544
This update resolves an issue where the Profitability report's Cost of Goods Sold dashboard didn't display data when multiple invoices were associated with a project. The fix ensures the report correctly identifies and displays all related journal entries, regardless of the number of invoices.
Original PR description
Steps to reproduce: ------------------- 1. Install `sale_project_stock` and Accounting. 2. Create a storable product with **Real-time valuation** and configure the COGS account in the product…
Steps to reproduce: ------------------- 1. Install `sale_project_stock` and Accounting. 2. Create a storable product with **Real-time valuation** and configure the COGS account in the product category expense account. (Ensure you have enabled automatic & analytic accounting from accounting>config.) 3. Create a project with a specific analytic account and ensure the project is billable. 4. Create a sale order with the created product and set the same analytic account in the analytic distribution. 5. Confirm the order, deliver the product, generate the invoice, and post it. 6. Open the project and go to the *Profitability* report. 7. Click on the **Cost of Goods Sold** dashboard item. 8. Repeat steps 4–7 with multiple invoices. Issue: ------ When there is only one invoice, clicking the COGS dashboard item correctly displays the related move lines. However, when there are multiple invoices, the action opens with empty results. Cause: ------ `_get_action_for_profitability_section` sets `res_id` only when a single record exists. When multiple records are present, `res_id` becomes `False`, which causes the action to open without results. https://github.com/odoo/odoo/blob/8f79d407724f40ba8e48f1747b2e87311b7fb49e/addons/project_account/models/project_project.py#L78-L83 Solution: --------- When `res_id` is not set, search `account.move` records using the domain to retrieve the relevant move IDs, then apply a proper domain to display all related COGS journal items. opw-5949261 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#267097 Forward-Port-Of: odoo/odoo#253639
This update fixes an issue where the DIAN-compliant electronic invoices generated for Colombia were incorrectly using a generic line number instead of the actual document ID. This caused validation errors with DIAN and external systems. The fix ensures the correct document ID is used, allowing invoices to pass DIAN validation and integrate seamlessly with other software.
Original PR description
### Issue When generating the attached document (AttachedDocument) for Colombia, the parent document reference tag <cbc:ID> incorrectly exported a generic line counter instead of the actual document…
### Issue
When generating the attached document (AttachedDocument) for Colombia, the parent document reference tag <cbc:ID> incorrectly exported a generic line counter instead of the actual document identification number
While the DIAN platform itself accepted the file, this caused rejections in external validation tools and third-party software because they could not resolve the link back to the original invoice
DIAN Documentation: https://www.dian.gov.co/impuestos/factura-electronica/Documents/Anexo_tecnico_factura_electronica_vr_1_7_2020.pdf
On page 213 there is an example for ParentDocumentLineReference
On page 216 there is the specification that does not show any check
Example of the incorrect XML structure:
```xml
<cac:ParentDocumentLineReference>
<cbc:LineID>1</cbc:LineID>
<cac:DocumentReference>
<cbc:ID>1</cbc:ID>
</cac:DocumentReference>
</cac:ParentDocumentLineReference>
```
Expected XML structure:
```xml
<cac:ParentDocumentLineReference>
<cbc:LineID>1</cbc:LineID>
<cac:DocumentReference>
<cbc:ID>SETP990001021</cbc:ID>
</cac:DocumentReference>
</cac:ParentDocumentLineReference>
```
### Cause
In the template, the value for <cbc:ID> was retrieved using `parent_document.get('id')` which fetched the sequential loop index https://github.com/odoo/enterprise/blob/cd25713fd2c35737d98db29df72b2d07ae9146e8/l10n_co_dian/views/templates.xml#L272-L275
The dictionary parsing logic did not extract the true document identifier from the XML tree response or the original XML data https://github.com/odoo/enterprise/blob/13dc30679e382df5845993c880a97df600c39ed4/l10n_co_dian/models/l10n_co_dian_document.py#L429-L432
### Steps to reproduce
- Install `l10n_co_dian`
- Setup DIAN configuration
- Generate an attached document for a commercial event or invoice
- Open the generated XML file
Before the fix, the `<cac:ParentDocumentLineReference>/<cac:DocumentReference>/<cbc:ID>` tag contains a technical integer like "1" instead of the official document sequence number
opw-6164321
Forward-Port-Of: odoo/enterprise#118319This update resolves an issue where new appointments created through the Gantt view were defaulting to midnight instead of the intended booking time. The team corrected a misconfiguration that incorrectly targeted a non-existent method, now properly overriding the correct method to ensure accurate start times for bookings.
Original PR description
The [commit] replaced the `onAddClicked` method with `_onNewClicked`, and updated all related calls and overrides accordingly. However, the appointment Gantt view override was mistakenly changed to override a non-existent `_onAddClicked` method, leaving the custom logic unused. As a result, bookings created through the `New` button in the Gantt view used midnight (12:00 AM) instead of the time derived from the custom logic as the default start datetime. This commit fixes the issue by correctly overriding `_onNewClicked`. [commit]: https://github.com/odoo/enterprise/commit/bc779c9ec5295f8d1fe06e8432c518c78c606ea2 Forward-Port-Of: odoo/enterprise#118799
This update resolves an issue where manually adjusted taxes on vendor bills generating COGS lines were being incorrectly recalculated and reset. The fix prevents product taxes from being applied to COGS lines, ensuring accurate tax calculations for internal operations. This improves the reliability of financial reporting.
Original PR description
Issue: After manually modifying the taxes on a vendor bill that generates COGS lines, confirming the vendor bill causes the taxes to revert to their original values before the manual edit. This…
Issue: After manually modifying the taxes on a vendor bill that generates COGS lines, confirming the vendor bill causes the taxes to revert to their original values before the manual edit. This happens because the product’s purchase taxes are applied to the generated COGS lines, which triggers the tax recomputation logic and overwrites the manually adjusted tax amounts. However, COGS lines represent internal operations and should not have taxes applied to them Steps to reproduce: 1. Turn on Anglo-Saxon accounting 2. Turn on automatic accounting 3. Make a FIFO product category and make the valuation automatic 4. Make a new product and set the FIFO product category on it 5. Make sure the product has a vendor tax set 6. Make a purchase order for 10 of the FIFO product category at $10 7. Create and validate the receipt for 10 8. Make a sales order for 6 of the FIFO product category at $10 9. Create and validate the delivery for 6 10. Create the vendor bill for 10 the purchase order created above (make sure that there is a tax set on the vendor bill; the vendor tax that was set on the product). Make this vendor bill set for 10 at $20 11. Edit the tax at the bottom of the total 12. Confirm the vendor bill 13. Notice that the tax at the bottom of the total changes 14. Reset the vendor bill 15. Remove the purchase tax from the product 16. Confirm the vendor bill again and notice that the tax at the bottom of the total does not change this time Cause: On confirmation, the COGS lines on the vendor bill will be generated and “_compute_tax_ids” will be triggered on those lines. Since COGS lines have a “product_id” set on them, those lines will receive the purchase tax set on the product. Setting the “tax_ids” on those COGS lines will cause tax computation to trigger again, which will reset the manually edited tax amount to the new computed amount. However, since COGS lines come in pairs that are equal and opposite in amount, the taxes from both COGS lines will cancel out, and the new computed tax amount does not change Solution: Skip setting the purchase taxes of the product onto COGS lines in “_compute_tax_ids” opw-6110692 Forward-Port-Of: odoo/odoo#268269 Forward-Port-Of: odoo/odoo#265352
This update fixes a limitation where imported vendor bills from the Italian tax agency (SDI) could not be edited. Now, users can modify these bills through the system, ensuring accurate reporting and compliance with Italian tax regulations. This change addresses a previous issue and improves the flexibility of the Italian tax reporting process.
Original PR description
- Install l10n_it_edi - Create and confirm vendor bill - Use studio to make the field l10n_it_edi_transaction editable - Input any value - The reset to draft button disappears In _compute_show_reset_to_draft_button we hide the reset to draft button if l10n_it_edi_transaction is populated in order to filter out moves already sent to the tax agency. Normally invoices and bills sent to the SDI cannot be modified. However it is possible to import vendor bills from the SDI, and their transaction field is also imported. It should be possible to modified those imported invoices. opw-6222891 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#265748
This update resolves an issue where POS users were unable to process Mollie payments due to incorrect access permissions. By using a sudoed Mollie provider, the system now correctly handles API key requests and calls, allowing POS users to complete payments seamlessly. This change aligns with the access controls used for other POS integrations.
Original PR description
Description of the issue/feature this PR addresses: POS users can trigger Mollie terminal payments without having access to the mollie_api_key field, which is only available to base.group_system. Use a sudoed Mollie provider when checking the API key and when calling the Mollie API, matching the access pattern used by other POS terminal integrations to avoid this issue. Current behavior before PR: POS user tries to initiate a payment via mollie, receives and AccessError. Desired behavior after PR is merged: POS user can successfully initiate a payment without the need for the base.group_system. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#264646
This update resolves an issue where refunded orders were still visible in the 'orders to settle' list when the customer account balance was zero. The fix ensures that orders and their associated refunds are removed from this list when the customer account balance is fully reconciled, streamlining the settlement process for users.
Original PR description
Currently, if you refund an order made on the customer account with the customer account as well, you can still see the order in the list of orders to settle. Steps to reproduce: -------------------…
Currently, if you refund an order made on the customer account with the customer account as well, you can still see the order in the list of orders to settle. Steps to reproduce: ------------------- * Open shop * Make an order using the customer account for a customer, don't invoice it * Refund one of the order using the customer account, don't invoice it * Make a new order using the customer account * In the customer list, find the customer used and select "Settle Orders" > The 2 orders are present in the list Why the fix: ------------ Originally the list would only show the orders for chich the customers have due (>0). https://github.com/odoo/enterprise/commit/bf4b6043b999b4a081b1afa73fc4113bf4db28f8 But recently the code we also see the refunds in the list as well. https://github.com/odoo/enterprise/commit/12af23d5382e972facfaa999e4c5ab30c97e8d1f However this new behavior is not visible if, with the refund, the customer account temporarily falls to 0. So currently we have some refunds that impact the amount to settle and some that don't. Originally we were thinking that either we should show all refunds in that list (given they use the customer account) or we shouldn't show any as it was previously. Both solutions are not ideal. * Showing them all would get the list bigger than it is and would require the customer to select the order and its refund(s) and settle them together. Since refunds are not usually done right after the order they would not be close it that list. However this solution would enable the option to remove the orders from the list requiring a few step from the customer. * Showing none isn't idea either with this use case as it means that we still see orders that were cancelled out by their refunds. To remove to order the customer has two options. Either going backend and searching the order and its refund(s) and invoice them, either settling the order but that means that now there's money deposited on the customer account. Any of the two option isn't perfect a it still requires manual intervention from the customer and wouldn't work on previous data. Creating a server action to correct those data wouldn't have been feasible either. Instead, the approach we're taking is the following: When loading the list of order to settle we want to remove the orders and the potential refunds were the customer account is evened out. We only need to look at the orders of the partners that contains refunds for which the customer account was used. If the sum of the transactions made on the customer account is 0 we can say that the order and its refunds have cancelled out each other (in terms of customer account) and we don't show them if the list of orders remaining to settle. opw-6170830 Forward-Port-Of: odoo/enterprise#117725
This update fixes an issue where check amounts weren't being properly rounded in the Philippines (PH) version of Odoo. Previously, the check amount in words displayed with an incorrect decimal format, including 'ONLY'. Now, the decimal amounts are rounded, ensuring accurate check printing and compliance with PH regulations.
Original PR description
Current behaviour: --- When paying with checks, the amount is not rounded in the check amount in words string. Steps to reproduce: --- 1. Switch to PH company 2. Set setting Check Layout as "Print Check - PH" 3. Create a new vendor bill 4. Add a product with a specific price like 91490.15 5. Confirm the bill, click on Register Payment 6. Select Payment Method "Checks", Create Payment 7. Go to the payment, Amount in Words is wrong 8. Ninety-One Thousand Four Hundred Ninety And 15000000001/100 ONLY Expected behaviour: --- The decimal amount should be rounded, and "ONLY" shouldn't appear. Fix: --- Rounded the pay amount And backported: https://github.com/odoo/enterprise/commit/bb6c9848665709c14c5113b2c98976f869cd473b opw-6058344 Forward-Port-Of: odoo/enterprise#117679 Forward-Port-Of: odoo/enterprise#116717
This update resolves an issue where the company's XBRL reports were failing validation with the National Bank of Belgium (NBB). The fix adds crucial explanatory data points to the report, ensuring compliance and successful submission. Only data points related to failing validations were added, preventing unnecessary complexity.
Original PR description
This commit adds missing explanatory disclosure datapoints to the generated XBRL report. The missing disclosures resulted in failing validation when report is submitted to NBB. The datapoints are only added if the original value was non-zero. For example, the tangible assets disclosures are only added if the tangible assets in balance sheet is non-zero. Additionally, only disclosures that were reported as causing a failing validation were added. task-5977199 Forward-Port-Of: odoo/enterprise#117853
This update streamlines the order placement process in our Point of Sale system by running background syncing instead of waiting for preparation requests. This prevents delays and allows users to seamlessly transition back to the floor screen. The changes also ensure accurate order tracking and prevent users from selecting tables while orders are still syncing.
Original PR description
### Before this commit: - Clicking the Order button waited for preparation-related RPC calls, delaying the transition back to the floor screen. - Tables could still be selected while their orders were syncing. - syncingOrders used order.id, which caused inconsistent tracking. ### After this commit: - Order submission no longer blocks the UI; sync runs in the background. - syncingOrders now uses order.uuid for consistent tracking. - Tables being synced are marked and cannot be selected. - Fixed course deselection to use the correct order instance. - Updated tests to ignore syncing tables. Task:6030427 Forward-Port-Of: odoo/odoo#256883
This update corrects a bug that prevented quality checks from running correctly when a measure check on a manufacturing order (MO) failed. The change adjusts how the system handles lot references, ensuring compatibility with recent Odoo updates. This resolves an error related to outdated field references and improves the reliability of quality control processes.
Original PR description
## Steps to reproduce: - Install the `quality_mrp` module. - Create a new product. - Create a Quality Point with: Type: Measure, Control per: Product/Operation Operations: Manufacturing - Create and…
## Steps to reproduce: - Install the `quality_mrp` module. - Create a new product. - Create a Quality Point with: Type: Measure, Control per: Product/Operation Operations: Manufacturing - Create and confirm MO for the product. - Update the Quality Point: Remove the 'manufacturing' operation type and add 'receipts' type. Change Control per to 'Quantity'. - Open the MO and start a quality check. - Enter an invalid measure and try to validate it. ## Error: `AttributeError - 'mrp.production' object has no attribute 'lot_producing_id'` ## Cause: Since commit https://github.com/odoo/odoo/commit/4bb4e08066449177f89382718ceadd840ce90d0e, the `lot_producing_id` field on MO was replaced by the Many2many field `lot_producing_ids`. Invalid references to the removed field lead to an error. ## Fix: This commit uses the first lot/serial from the MO. Note: Multiple produced lots are only possible for serial-tracked products. sentry-7511513479 Forward-Port-Of: odoo/enterprise#119231
This update fixes an error in the import of Italian vendor invoices (l10n_it_edi) where pension fund tax was incorrectly applied to all invoice lines with the same VAT rate. The fix extracts the specific tax exemption reason from the invoice data, ensuring the correct tax is applied to each line, improving invoice accuracy and financial reporting.
Original PR description
In `l10n_it_edi` vendor bill import, the pension fund tax was incorrectly applied to all invoice lines sharing the same VAT rate, even though they have different `l10n_it_tax_exemption_reason`s, resulting in wrong entries and document total. We now extract the Tax Exemption reason from the `DatiCassaPrevidenziale` node, and use it to search the correct tax. Steps to reproduce: 1. Install `account` and `l10n_edi_it` 2. In the `4% INPS` tax, set `TC22` in pension fund type and `N2.2` in exoneration 3. Import bill from the ticket 4. See the pension fund tax is applied to all the lines. It should only be applied only to the first one. Ticket [link](https://www.odoo.com/odoo/project.task/6212975) opw-6212975 Forward-Port-Of: odoo/odoo#267066 Forward-Port-Of: odoo/odoo#265821
This update resolves an issue where users were encountering errors when attempting to use property fields within auto-fields. The fix restricts property field selection, ensuring data integrity and preventing errors in the Sign module. This improves the user experience and stability of the system.
Original PR description
Currently, an error occurs when user tries to select a property field in auto field. Steps to replicate: - Install `sale_management` and `sign`. - Open Sales > Products > Products > Open any product.…
Currently, an error occurs when user tries to select a property field in auto field.
Steps to replicate:
- Install `sale_management` and `sign`.
- Open Sales > Products > Products > Open any product.
- From the Gear icon, Click Edit Properties and save the record.
- Enable Debug mode if you are using a version lower than 19.0 .
- Open Sign > Configuration > Field Types.
- Create a new Field > Give a name > Select model as `Product`.
- Select Field as `Property > Property 1` and click save.
Error:
- saas-18.3 and later:
```
File '/home/odoo/odoo18/enterprise/sign/models/sign_item_type.py', line 57, in _check_auto_field_exists
auto_field_value = record.mapped(sign_type.auto_field)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File '/home/odoo/odoo18/community/odoo/orm/models.py', line 5472, in mapped
field = records._fields[field_name]
^^^^^^^^^^^^^^^
AttributeError: 'Property' object has no attribute '_fields'. Did you mean: 'field'?
```
- saas-18.2:
```
File '/home/odoo/odoo18/enterprise/sign/models/sign_item_type.py, line 41, in _check_auto_field_exists
auto_field_value = record.mapped(sign_type.auto_field)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File '/home/odoo/odoo18/community/odoo/orm/models.py', line 5744, in mapped
if len(records) > PREFETCH_MAX:
^^^^^^^^^^^^
TypeError: object of type 'bool' has no len()
```
Cause:
- As the user gave auto fill field as a Property field the [line] called `mapped()` to access its value, this caused the error to occur.
- This occurs because `mapped()` expects a `recordset` (models.Model), but instead it receives a Property object, which does not have `_fields`.
Solution:
- Using `'allow_properties': 'False'`, the property fields wont appear in the list of field selection.
[line]: https://github.com/odoo/enterprise/blob/cdaeb79e1f623831fffa553dbb658698367c7e19/sign/models/sign_item_type.py#L41
sentry-7378769090
Forward-Port-Of: odoo/enterprise#113091This update resolves an issue preventing Verifactu documents from being generated when invoicing a Point of Sale order after the sale is completed. Previously, the system required a cancellation step, but now it allows invoicing directly, ensuring consistent functionality. The change improves the process of generating Verifactu documents for Spanish businesses.
Original PR description
**Steps to reproduce:** - Setup a Verifactu installation and a Spanish company - Go to the PoS, make a Sale - Keep the ticket - Go to the /pos/ticket URL and enter the ticket informations - Last step…
**Steps to reproduce:** - Setup a Verifactu installation and a Spanish company - Go to the PoS, make a Sale - Keep the ticket - Go to the /pos/ticket URL and enter the ticket informations - Last step also works when requesting an invoice in the backend on the order - Go to the order in the backend, an error is shown, the cancellation didn't go through **Veri*Factu documents can only be generated for paid or posted Point of Sale Orders.** **Why the fix:** When we directly invoice an order, we do not go through the verification of being paid and done. This is why is works, but when making the invoice after the sale is done, we cancel the order first, then we register the invoice instead. When trying to cancel the order, we check if the order is either paid or done, but it is currently invoiced as we just generated the invoice. We now allow no errors if the order is in the invoiced state, and let it pass through. With this flow we get the same result as the direct invoice from the PoS. The new cancellation on the order and submission on the invoice may take a bit of time to get accepted but they will be eventually. opw-6139200 Forward-Port-Of: odoo/odoo#267869 Forward-Port-Of: odoo/odoo#264272
This update resolves an issue where validating delivery costs on confirmed sales orders with real-cost carrier invoices caused errors. The fix prevents the system from incorrectly updating delivery line prices and names when a locked order is being processed, ensuring smooth order management. This improves the user experience for sales teams.
Original PR description
Sale module has setting `Lock Confirmed Sales`, which particularly doesn't allow order line modification on a confirmed order. However, when a delivery carrier is set up with Invoicing Policy = Real cost, validating the picking pushes the actual carrier price onto the delivery line, writing `price_unit` and `name`. On a locked SO this raises a UserError. Fix it by excluding the delivery line's `price_unit` and `name` from the protected fields, only when the write originates from `_add_delivery_cost_to_so`. The code path is identified by the context `allow_delivery_cost_update`, so a regular UI edit of those fields on a locked SO is still blocked. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#266511 Forward-Port-Of: odoo/odoo#265721
This update fixes an issue where inserting certain website snippets (like alerts) within limited editable areas resulted in broken HTML. The fix prevents the creation of invalid HTML structures, ensuring snippets insert correctly and reliably within the website builder. This improves the overall user experience and stability of the website building tool.
Original PR description
### [FIX] website: prevent inserting block snippet with powerbox in inlines Inserting block snippet with powerbox when the selection is inside an editable part limited to an element that can only…
### [FIX] website: prevent inserting block snippet with powerbox in inlines Inserting block snippet with powerbox when the selection is inside an editable part limited to an element that can only contain inline nodes leads to invalid html (like `<div>` inside `<span>`). This commit disables insertion of block snippets when the selection is such a part of the document. Steps to reproduce: - Open website builder - Put cursor in "copyright" at the bottom of the footer - Type `/alert` and press enter - Bug: `<div>` element is inserted inside `<span>`, that is invalid html task-6259092 ### [FIX] website: prevent unwrapping `s_blockquote` on insert with powerbox When the snippet `s_blockquote` was inserted with the powerbox or pasted from clipboard in an unbreakable element which does not allow blocks as children, the `<blockquote>` element itself was abandonned and its children were inserted instead. This lead to insertion of a broken snippet. This commit marks the `s_blockquote` snippet as "unsplittable" so that always stays in one piece when inserted. Steps to reproduce: - Open website builder - Put cursor in a link - Type `/blockquote` and press enter - Bug: the snippet's children are inserted, instead of snippet itself task-6259092 Forward-Port-Of: odoo/odoo#267111
6 changes
Resolved issues and error corrections
This update corrects a bug in the VAT report generation that was incorrectly displaying '01' for invoices with 'No Sujeto por reglas de localización' taxes (like PT VAT). The fix ensures the correct '17' operation code is used, aligning with Spanish VAT regulations and SII data, improving the accuracy of tax reporting.
Original PR description
**Steps to reproduce:** * Install the **l10n_es_edi_sii** module. * Create a **Portuguese customer**. * Go to **Settings** and enable **EU Intra-community Distance Selling**, then refresh the tax…
**Steps to reproduce:** * Install the **l10n_es_edi_sii** module. * Create a **Portuguese customer**. * Go to **Settings** and enable **EU Intra-community Distance Selling**, then refresh the tax mapping. * Create a customer invoice with a **"No Sujeto por reglas de localización"** tax (e.g. **23.0% PT VAT**). * Go to **Accounting → Reporting → Tax Report → OSS Sales**. * Export the **VAT Record Books (XLSX)** file and open it. **Observed behavior:** * The "Clave de Operación" column shows "01" for lines with no_sujeto_loc taxes instead of "17". * The SII JSON for the same invoice correctly shows "ClaveRegimenEspecialOTrascendencia": "17". **Cause:** * In `_l10n_es_libros_get_common_line_vals()`, `operation_code` was computed manually as `'02' if exempt_reason else '01'`, which only handled the E2 exempt case and defaulted everything else to "01". * This missed OSS/no_sujeto_loc taxes (e.g. FR VAT, PT VAT) that should produce "17" per the Spanish VAT regime code table. **Fix:** * Extract operation code computation into a new dedicated method `_l10n_es_libros_get_operation_code()`. * For customer invoices, delegate to the existing `_l10n_es_get_regime_code()` method already used by SII, which correctly returns "17" for OSS-tagged taxes, "02" for E2 exempt, and "01" otherwise. * For vendor bills, mirror the SII logic by checking whether the invoice taxes include tags from `mod_303_casilla_10_balance` or `mod_303_casilla_11_balance` (intra-community indicators), returning "09" if so and "01" otherwise. opw-6197141,6216485 Forward-Port-Of: odoo/enterprise#117236
This update resolves an issue preventing users from correctly inserting dynamic fields into SMS templates within Marketing Automation. The fix ensures the system properly recognizes the correct data source (`mailing_model_real`) for SMS templates, allowing users to build campaigns with accurate, personalized messages. This improves the overall reliability of the SMS marketing feature.
Original PR description
The SMS template form view in Marketing Automation was missing the `dynamic_placeholder_model_reference_field` option on the `body_plaintext` field. Without this option, the dynamic placeholder hook falls back to looking for a `model` field in the record data, but `mailing.mailing` uses `mailing_model_real` instead. Steps To Reproduce: - Install marketing_automation_sms and CRM modules (also activate Leads). - Start a new Campaign in Marketing Automation. - Set Target to Lead/Opportunity. - Add New Activity > Activity Type = SMS > SMS Template = create one. - In the SMS template dialog, click the "Insert Field" button. - Error appears: "You need to select a model before opening the dynamic placeholder selector." Ticket [link](https://www.odoo.com/odoo/project.task/5488849) opw-5488849 Forward-Port-Of: odoo/enterprise#104423
This update resolves an issue where refund flows failed with 'Can't change customer' errors when using DIAN POS. The fix ensures the final consumer partner is always loaded into POS memory, preventing blank customer labels and allowing refunds to process smoothly. This improves the reliability of the POS system for Colombian businesses.
Original PR description
When DIAN POS is enabled, l10n_co_edi_pos auto-assigns the `Consumidor Final` partner to new POS orders. However, POS only preloads a limited partner set in frontend memory. If `Consumidor Final` is not part of that set, the order gets a partner id whose full partner data is not loaded in the UI. This causes the customer label to appear blank and refund flows to fail with "Can't change customer" mentioning `undefined`. To avoid this, always include the final consumer partner in `get_limited_partners_loading()`. This matches the approach already present in newer branches. opw-6238935 Forward-Port-Of: odoo/enterprise#119321 Forward-Port-Of: odoo/enterprise#118408
This update resolves an error that occurred when users attempted to use property fields within auto-fill fields in the Sign module. The fix restricts property field selection, ensuring data integrity and preventing the application from crashing. This change improves the stability of the Sign module.
Original PR description
Currently, an error occurs when user tries to select a property field in auto field. Steps to replicate: - Install `sale_management` and `sign`. - Open Sales > Products > Products > Open any product.…
Currently, an error occurs when user tries to select a property field in auto field.
Steps to replicate:
- Install `sale_management` and `sign`.
- Open Sales > Products > Products > Open any product.
- From the Gear icon, Click Edit Properties and save the record.
- Enable Debug mode if you are using a version lower than 19.0 .
- Open Sign > Configuration > Field Types.
- Create a new Field > Give a name > Select model as `Product`.
- Select Field as `Property > Property 1` and click save.
Error:
- saas-18.3 and later:
```
File '/home/odoo/odoo18/enterprise/sign/models/sign_item_type.py', line 57, in _check_auto_field_exists
auto_field_value = record.mapped(sign_type.auto_field)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File '/home/odoo/odoo18/community/odoo/orm/models.py', line 5472, in mapped
field = records._fields[field_name]
^^^^^^^^^^^^^^^
AttributeError: 'Property' object has no attribute '_fields'. Did you mean: 'field'?
```
- saas-18.2:
```
File '/home/odoo/odoo18/enterprise/sign/models/sign_item_type.py, line 41, in _check_auto_field_exists
auto_field_value = record.mapped(sign_type.auto_field)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File '/home/odoo/odoo18/community/odoo/orm/models.py', line 5744, in mapped
if len(records) > PREFETCH_MAX:
^^^^^^^^^^^^
TypeError: object of type 'bool' has no len()
```
Cause:
- As the user gave auto fill field as a Property field the [line] called `mapped()` to access its value, this caused the error to occur.
- This occurs because `mapped()` expects a `recordset` (models.Model), but instead it receives a Property object, which does not have `_fields`.
Solution:
- Using `'allow_properties': 'False'`, the property fields wont appear in the list of field selection.
[line]: https://github.com/odoo/enterprise/blob/cdaeb79e1f623831fffa553dbb658698367c7e19/sign/models/sign_item_type.py#L41
sentry-7378769090
Forward-Port-Of: odoo/enterprise#113091This update resolves a problem where users attempting to access archived documents through various methods (widgets, direct URLs, notifications) would incorrectly receive a 'not found' error and be directed to the 'All' view. This fix ensures archived documents are correctly displayed, improving the user experience and preventing frustration.
Original PR description
When a user tries to access an archived document via * a many2one widget * `/odoo/documents.document/<id>` * a discuss notification they end up in "All" with a toast specifying that the document was not found. Follow-up of Task-6068437 (follow up of Task-5386466). Task-6214488 Forward-Port-Of: odoo/enterprise#119302 Forward-Port-Of: odoo/enterprise#117229
This update fixes an issue where check amounts were not being properly rounded when generated in the Philippines (PH). Previously, the check amount in words displayed an incorrect decimal format with 'ONLY' appended. This change ensures that check amounts are rounded to the nearest cent, presenting a more accurate and professional representation for financial reporting.
Original PR description
Current behaviour: --- When paying with checks, the amount is not rounded in the check amount in words string. Steps to reproduce: --- 1. Switch to PH company 2. Set setting Check Layout as "Print Check - PH" 3. Create a new vendor bill 4. Add a product with a specific price like 91490.15 5. Confirm the bill, click on Register Payment 6. Select Payment Method "Checks", Create Payment 7. Go to the payment, Amount in Words is wrong 8. Ninety-One Thousand Four Hundred Ninety And 15000000001/100 ONLY Expected behaviour: --- The decimal amount should be rounded, and "ONLY" shouldn't appear. Fix: --- Rounded the pay amount And backported: https://github.com/odoo/enterprise/commit/bb6c9848665709c14c5113b2c98976f869cd473b opw-6058344 Forward-Port-Of: odoo/enterprise#117679 Forward-Port-Of: odoo/enterprise#116717
9 changes
Enhancements to existing features
This update enhances how Odoo identifies partners during UBL imports, primarily by using exact name matches and bank account details. This prevents incorrect partner matches and ensures accurate VAT data is applied, leading to more reliable data import and reconciliation.
Original PR description
Before this commit: Partner was searched using contains on the name, which could match unrelated partners with similar names (e.g. `Global Tech` matching `Global Technologies Ltd`). With this update: - Partner retrieval now uses an exact name match to avoid incorrect matches caused by partial name search. - For UBL imports for Peppol, bank details are also used to help identify the partner by matching the bank account number. The retrieval logic has also been improved: 1. If VAT exists in the XML: - If a partner found with no VAT then enrich that partner by filing VAT from xml - If a partner found with a different VAT than the one in the XML, then a new partner will be created Also fix the test case where it finds `partner_1` through the `bank account number` and creates a new partner instead of returning the correct `partner_2`. task-5485563 Forward-Port-Of: odoo/odoo#261759 Forward-Port-Of: odoo/odoo#250309
Resolved issues and error corrections
This update fixes a bug that allowed users to validate internal transfer barcodes without scanning the destination location. Previously, deleting a line would cause validation to succeed even if the location wasn't scanned. The fix ensures validation only occurs after a destination location has been scanned, improving data accuracy and preventing incorrect transfer confirmations.
Original PR description
Currently, when a user deletes a line and validates internal movement in the barcode system, the system allows validation even though specifying the destination location after each scan is required.…
Currently, when a user deletes a line and validates internal movement in the barcode system, the system allows validation even though specifying the destination location after each scan is required. ## Steps to produce: - Install the Inventory module - Go to Settings and enable Storage Locations. - Inventory > Configuration > Operation Types > Internal Transfers > Barcode App - Configure the Destination Location to require scanning after each product. - Create an Internal Transfer for Pedal Bin, demand 1. - Mark the transfer as To Do and open it in the Barcode app. - Add quantity using +1, then scan the barcode for the Pedal Bin(Barcode: 6016478556493). - Delete the newly added line and attempt to Validate. ## Observed Behavior: The system should prevent transfer validation when the destination location has not been scanned and display a notification to the user, similar to the behavior before user deleted the newly added line. ## Root cause: This issue occurs because when the delete button is pressed, the deleteLine function [1] removes the line, but the deleted line becomes the selected line due to [2] being triggered before the UI updates. As a result, the selected line is now undefined. Since the selected line is undefined, it fails to meet the condition at [3] during validation. This prevents notifications from being triggered and allows the transfer to be validated before the destination location has been scanned. [1]: https://github.com/odoo/enterprise/blob/3476d15bf8e75eb6530658dd623861b60963ab40/stock_barcode/static/src/models/barcode_model.js#L826-L836 [2] : https://github.com/odoo/enterprise/blob/327d4478128f33fb2e0c477533bd4983178abf17/stock_barcode/static/src/components/line.js#L129-L133 [3]: https://github.com/odoo/enterprise/blob/6ff158ca3a6d2d2b3d285a7f8317622844811688/stock_barcode/static/src/models/barcode_picking_model.js#L945-L948 ## Solution: We can prevent users from validating if any line has an unscanned destination location when destination-location scanning is mandatory after scanning each product. To enforce this behavior, we can track whether a line has been modified and whether a destination location has been scanned and applied to that line. This allows us to identify which lines still require destination location scanning before validation can proceed. However, line state information is currently discarded and recreated on every save. As a result, information about lines that were updated and already had their destination location scanned is lost. This may incorrectly require users to rescan the destination location, even though it was previously scanned. To address this, we preserve the destination-scanned and modified state by carrying it forward from existing lines to their corresponding newly created versions using a loop. This ensures that destination location scan status is retained and users are not asked to rescan unnecessarily. opw-6069614 Forward-Port-Of: odoo/enterprise#119263 Forward-Port-Of: odoo/enterprise#113618
This update resolves an issue where VAT reports were incorrectly displaying a default '01' code for 'No Sujeto por reglas de localización' taxes, impacting the accuracy of sales reporting. The fix ensures the correct '17' operation code is used, aligning with Spanish VAT regulations and SII data. This improves the reliability of VAT record book exports.
Original PR description
**Steps to reproduce:** * Install the **l10n_es_edi_sii** module. * Create a **Portuguese customer**. * Go to **Settings** and enable **EU Intra-community Distance Selling**, then refresh the tax…
**Steps to reproduce:** * Install the **l10n_es_edi_sii** module. * Create a **Portuguese customer**. * Go to **Settings** and enable **EU Intra-community Distance Selling**, then refresh the tax mapping. * Create a customer invoice with a **"No Sujeto por reglas de localización"** tax (e.g. **23.0% PT VAT**). * Go to **Accounting → Reporting → Tax Report → OSS Sales**. * Export the **VAT Record Books (XLSX)** file and open it. **Observed behavior:** * The "Clave de Operación" column shows "01" for lines with no_sujeto_loc taxes instead of "17". * The SII JSON for the same invoice correctly shows "ClaveRegimenEspecialOTrascendencia": "17". **Cause:** * In `_l10n_es_libros_get_common_line_vals()`, `operation_code` was computed manually as `'02' if exempt_reason else '01'`, which only handled the E2 exempt case and defaulted everything else to "01". * This missed OSS/no_sujeto_loc taxes (e.g. FR VAT, PT VAT) that should produce "17" per the Spanish VAT regime code table. **Fix:** * Extract operation code computation into a new dedicated method `_l10n_es_libros_get_operation_code()`. * For customer invoices, delegate to the existing `_l10n_es_get_regime_code()` method already used by SII, which correctly returns "17" for OSS-tagged taxes, "02" for E2 exempt, and "01" otherwise. * For vendor bills, mirror the SII logic by checking whether the invoice taxes include tags from `mod_303_casilla_10_balance` or `mod_303_casilla_11_balance` (intra-community indicators), returning "09" if so and "01" otherwise. opw-6197141,6216485 Forward-Port-Of: odoo/enterprise#117236
This update resolves an issue where users were encountering errors when attempting to use property fields within auto-fill fields in the sign module. The fix restricts property field selection, ensuring data integrity and preventing the original error. This improves the usability of the sign module.
Original PR description
Currently, an error occurs when user tries to select a property field in auto field. Steps to replicate: - Install `sale_management` and `sign`. - Open Sales > Products > Products > Open any product.…
Currently, an error occurs when user tries to select a property field in auto field.
Steps to replicate:
- Install `sale_management` and `sign`.
- Open Sales > Products > Products > Open any product.
- From the Gear icon, Click Edit Properties and save the record.
- Enable Debug mode if you are using a version lower than 19.0 .
- Open Sign > Configuration > Field Types.
- Create a new Field > Give a name > Select model as `Product`.
- Select Field as `Property > Property 1` and click save.
Error:
- saas-18.3 and later:
```
File '/home/odoo/odoo18/enterprise/sign/models/sign_item_type.py', line 57, in _check_auto_field_exists
auto_field_value = record.mapped(sign_type.auto_field)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File '/home/odoo/odoo18/community/odoo/orm/models.py', line 5472, in mapped
field = records._fields[field_name]
^^^^^^^^^^^^^^^
AttributeError: 'Property' object has no attribute '_fields'. Did you mean: 'field'?
```
- saas-18.2:
```
File '/home/odoo/odoo18/enterprise/sign/models/sign_item_type.py, line 41, in _check_auto_field_exists
auto_field_value = record.mapped(sign_type.auto_field)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File '/home/odoo/odoo18/community/odoo/orm/models.py', line 5744, in mapped
if len(records) > PREFETCH_MAX:
^^^^^^^^^^^^
TypeError: object of type 'bool' has no len()
```
Cause:
- As the user gave auto fill field as a Property field the [line] called `mapped()` to access its value, this caused the error to occur.
- This occurs because `mapped()` expects a `recordset` (models.Model), but instead it receives a Property object, which does not have `_fields`.
Solution:
- Using `'allow_properties': 'False'`, the property fields wont appear in the list of field selection.
[line]: https://github.com/odoo/enterprise/blob/cdaeb79e1f623831fffa553dbb658698367c7e19/sign/models/sign_item_type.py#L41
sentry-7378769090
Forward-Port-Of: odoo/enterprise#113091This update resolves a validation error that occurred during production recording when a subcontractor deleted and recreated a move line. The previous process incorrectly invalidated the cache, leading to missing data. This change ensures data integrity during editing and recording of subcontracting production.
Original PR description
**Issue** In subcontracting, deleting a raw move line and adding a new one in the same editing flow can lead to a validation error during production recording. **Steps to reproduce** - Create a…
**Issue** In subcontracting, deleting a raw move line and adding a new one in the same editing flow can lead to a validation error during production recording. **Steps to reproduce** - Create a subcontracting product with a comp A - Create and confirm a purchase order of that product (with the subcontracting partner) - Open the associated delivery - Open the move details (hamburger button) - Delete the move line linked to the comp A - Create a new move line for a comp B with a quantity of 1 - Record the production -> A validation error occurs: the mandatory field `product_uom_id` is not set. **Cause** The regression comes from this commit: https://github.com/odoo/odoo/commit/54f10b56f577ad9ed5575bd396dba7d20d22fc2e While assigning `move_raw_ids`, the inverse method is triggered: https://github.com/odoo/odoo/blob/9267b2d1a9b2d2d6a33eceab07d572406c68c723/addons/mrp_subcontracting/models/mrp_production.py#L34 At this stage, newly added lines are still virtual records (`line`): https://github.com/odoo/odoo/blob/9267b2d1a9b2d2d6a33eceab07d572406c68c723/addons/mrp_subcontracting/models/mrp_production.py#L38 The previous implementation directly unlinked removed move lines (see commit https://github.com/odoo/odoo/commit/54f10b56f577ad9ed5575bd396dba7d20d22fc2e): https://github.com/odoo/odoo/blob/9267b2d1a9b2d2d6a33eceab07d572406c68c723/addons/mrp_subcontracting/models/mrp_production.py#L40-L43 Which will eventually flush and invalidate all the cache: https://github.com/odoo/odoo/blob/0e78b4fd2ab904f2e12107cb6ff7cc11d512259f/odoo/models.py#L4666 And since `line` is a virtual record (not in db), its associated values will be reset, among those, `product_uom_id`. Later, when the move line is reassigned: https://github.com/odoo/odoo/blob/0e78b4fd2ab904f2e12107cb6ff7cc11d512259f/addons/mrp_subcontracting/models/mrp_production.py#L49 https://github.com/odoo/odoo/blob/0e78b4fd2ab904f2e12107cb6ff7cc11d512259f/odoo/models.py#L5223-L5228 the validation fails because the virtual line no longer contains the required values. **Additional note** An alternative could have been using Command but since this line: https://github.com/odoo/odoo/blob/0e78b4fd2ab904f2e12107cb6ff7cc11d512259f/addons/mrp_subcontracting/models/mrp_production.py#L42 can not be converted to: `Command.set([line.id for line in lines])` because `lines` may also contain virtual records. This causes an invalid quantity for the move. Indeed, even if the command operator would update the quantity on the `move_line` correctly, it won't for the quantity of the `move` because of its associated compute method: https://github.com/odoo/odoo/blob/26ba95ac1c5bbb24975efb1a6f53c1ab47b61532/addons/stock/models/stock_move.py#L399-L400 that relies on `.ids`, which is `[]` on virtual records. Therefore, keep the change minimal. opw-6133281 Forward-Port-Of: odoo/odoo#263058
This update resolves a bug where backorder receipts were incorrectly valued due to inconsistent exchange rate calculations. The fix ensures that receipt values and total invoice amounts are consistently converted to EUR using the correct exchange rate at the time of receipt, regardless of the bill date. This improves accuracy in stock valuation and financial reporting.
Original PR description
Configuration: - Costing method: FIFO, automated valuation - Multi-currency: PO in a foreign currency (e.g. EUR), company currency USD - Two different exchange rates: one active at bill date, one at…
Configuration:
- Costing method: FIFO, automated valuation
- Multi-currency: PO in a foreign currency (e.g. EUR), company currency USD
- Two different exchange rates: one active at bill date, one at receipt date
- Bill posted before any goods are received
Steps to reproduce:
- Set EUR as a secondary currency with two different rates:
- Rate 1 on January 1st: 1 EUR = 1 USD
- Rate 2 on January 8th: 1 EUR = 2 USD
- Create a PO in EUR for 20 units @ 10,000 EUR
- Post the vendor bill dated January 3rd (rate 1 applies: 1 EUR = 1 USD)
- Receive 10 units on a date after January 8th and create a backorder
- Receive the remaining 10 units from the backorder on the same date
- Inspect the stock valuation layers and interim account journal entries for both receipts
Prior to this commit:
The two receipts, identical in quantity, date, and PO price, would produce different unit costs in USD. The backorder receipt would be incorrectly valued due to a wrong exchange rate being used when computing `receipt_value` in `_get_price_unit()`.
Receipt 2 (backorder):
SVL 1 value: $100,000 USD
Converted to EUR at receipt date (1 USD = 0.5 EUR):
receipt_value = $100,000 × 0.5 = 50,000 EUR (wrong rate)
total_invoiced_value = 200,000 EUR
remaining_value = 200,000 - 50,000 = 150,000 EUR
remaining_qty = 20 - 10 = 10
price_unit = 150,000 / 10 = 15,000 EUR
Converted to USD at bill date (1 EUR = 1 USD):
price_unit = $15,000 USD
SVL value = $15,000 × 10 = $150,000
This bug only affects backorder receipts. The first receipt always gets `receipt_value = 0` (no prior SVLs exist), so the problematic conversion never runs.
After this commit:
`receipt_value` is now computed using `_get_currency_convert_date()` instead of `layer.create_date`. This ensures `receipt_value` and `total_invoiced_value` are both expressed in EUR at the same reference rate.
Receipt 2 (backorder):
SVL 1 value: $100,000 USD
Converted to EUR at bill date (1 EUR = 1 USD):
receipt_value = $100,000 × 1.0 = 100,000 EUR (correct rate)
total_invoiced_value = 200,000 EUR
remaining_value = 200,000 - 100,000 = 100,000 EUR
remaining_qty = 20 - 10 = 10
price_unit = 100,000 / 10 = 10,000 EUR
Converted to USD at bill date (1 EUR = 1 USD):
price_unit = $10,000 USD
SVL value = $10,000 × 10 = $100,000
Both receipts now produce identical unit costs regardless of exchange rate differences between bill date and receipt date.
OPW: 5426718
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#267590
Forward-Port-Of: odoo/odoo#262577This update fixes an issue where check amounts weren't being properly rounded in the Philippines (PH) version of Odoo. Previously, the check amount in words displayed with extra decimal places and 'ONLY'. Now, the decimal amounts are rounded correctly, ensuring accurate check formatting for PH transactions.
Original PR description
Current behaviour: --- When paying with checks, the amount is not rounded in the check amount in words string. Steps to reproduce: --- 1. Switch to PH company 2. Set setting Check Layout as "Print Check - PH" 3. Create a new vendor bill 4. Add a product with a specific price like 91490.15 5. Confirm the bill, click on Register Payment 6. Select Payment Method "Checks", Create Payment 7. Go to the payment, Amount in Words is wrong 8. Ninety-One Thousand Four Hundred Ninety And 15000000001/100 ONLY Expected behaviour: --- The decimal amount should be rounded, and "ONLY" shouldn't appear. Fix: --- Rounded the pay amount And backported: https://github.com/odoo/enterprise/commit/bb6c9848665709c14c5113b2c98976f869cd473b opw-6058344 Forward-Port-Of: odoo/enterprise#117679 Forward-Port-Of: odoo/enterprise#116717
This update resolves a frustrating issue where carousels would automatically cycle while editing website pages. The fix prevents this behavior in edit mode, ensuring a smoother and more stable editing experience for our users. This improves usability and reduces editing interruptions.
Original PR description
Commit [3ba3e45] paused carousels upon focus, and resumed it upon focusout. However, that behavior should be disabled in edit mode, as cycling is disabled (moving through the slides is only done manually). Otherwise, the carousel cycles and, after each slide, takes the focus, which makes editing the page a nightmare. [3ba3e45]: https://github.com/odoo/odoo/commit/3ba3e45b2ab995412e1a7ced2c46b9294dc353b8 task-6264462 Forward-Port-Of: odoo/odoo#268046
This update resolves an issue where validating delivery costs on confirmed sales orders with real-cost carrier invoices caused an error. The fix prevents the system from incorrectly updating price and name fields on delivery lines when a locked order is being processed, ensuring smooth order management. This improves the user experience for sales teams.
Original PR description
Sale module has setting `Lock Confirmed Sales`, which particularly doesn't allow order line modification on a confirmed order. However, when a delivery carrier is set up with Invoicing Policy = Real cost, validating the picking pushes the actual carrier price onto the delivery line, writing `price_unit` and `name`. On a locked SO this raises a UserError. Fix it by excluding the delivery line's `price_unit` and `name` from the protected fields, only when the write originates from `_add_delivery_cost_to_so`. The code path is identified by the context `allow_delivery_cost_update`, so a regular UI edit of those fields on a locked SO is still blocked. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#266511 Forward-Port-Of: odoo/odoo#265721
3 changes
Resolved issues and error corrections
This update corrects a bug in the VAT reporting module that was incorrectly assigning a '01' operation code to invoices with 'No Sujeto por reglas de localización' (PT VAT) taxes. The fix ensures that these invoices are correctly identified with the standard '17' code, aligning with Spanish VAT regulations and SII reporting. This ensures accurate VAT reporting for our Portuguese customers.
Original PR description
**Steps to reproduce:** * Install the **l10n_es_edi_sii** module. * Create a **Portuguese customer**. * Go to **Settings** and enable **EU Intra-community Distance Selling**, then refresh the tax…
**Steps to reproduce:** * Install the **l10n_es_edi_sii** module. * Create a **Portuguese customer**. * Go to **Settings** and enable **EU Intra-community Distance Selling**, then refresh the tax mapping. * Create a customer invoice with a **"No Sujeto por reglas de localización"** tax (e.g. **23.0% PT VAT**). * Go to **Accounting → Reporting → Tax Report → OSS Sales**. * Export the **VAT Record Books (XLSX)** file and open it. **Observed behavior:** * The "Clave de Operación" column shows "01" for lines with no_sujeto_loc taxes instead of "17". * The SII JSON for the same invoice correctly shows "ClaveRegimenEspecialOTrascendencia": "17". **Cause:** * In `_l10n_es_libros_get_common_line_vals()`, `operation_code` was computed manually as `'02' if exempt_reason else '01'`, which only handled the E2 exempt case and defaulted everything else to "01". * This missed OSS/no_sujeto_loc taxes (e.g. FR VAT, PT VAT) that should produce "17" per the Spanish VAT regime code table. **Fix:** * Extract operation code computation into a new dedicated method `_l10n_es_libros_get_operation_code()`. * For customer invoices, delegate to the existing `_l10n_es_get_regime_code()` method already used by SII, which correctly returns "17" for OSS-tagged taxes, "02" for E2 exempt, and "01" otherwise. * For vendor bills, mirror the SII logic by checking whether the invoice taxes include tags from `mod_303_casilla_10_balance` or `mod_303_casilla_11_balance` (intra-community indicators), returning "09" if so and "01" otherwise. opw-6197141,6216485 Forward-Port-Of: odoo/enterprise#117236
This update fixes a calculation error in Odoo's Point of Sale integration with UrbanPiper. Previously, tax calculations on online orders with 'Tax Included' were incorrect, leading to inaccurate pricing. The fix ensures the unit price reflects the total amount, including tax, for a more accurate customer experience.
Original PR description
Steps to reproduce: --- - Configure Point of Sale with UrbanPiper credentials. - Sync a product priced at 100 with a 5% GST (tax type = Tax Included). - Place a test order. Issue: --- - Wrong calculation in order line: - unit_price: 95.24 - Tax Excl. price: 90.70 - Tax Incl. price: 95.24 - Expected: - unit_price: 100 - Tax Excl. price: 95.24 - Tax Incl. price: 100 Cause: --- - While computing the unit_price with Tax Included, the tax amount was not added back. Fix: --- - Ensure unit_price includes the tax amount when tax type is Tax Included. task-5031196 Forward-Port-Of: odoo/enterprise#92854
This update fixes an issue where check amounts were not being properly rounded in the Philippines (PH) version of Odoo. Previously, the check amount in words displayed with an incorrect decimal format, including 'ONLY'. This change ensures that check amounts are rounded to the nearest cent, presenting a more accurate and professional representation of payments.
Original PR description
Current behaviour: --- When paying with checks, the amount is not rounded in the check amount in words string. Steps to reproduce: --- 1. Switch to PH company 2. Set setting Check Layout as "Print Check - PH" 3. Create a new vendor bill 4. Add a product with a specific price like 91490.15 5. Confirm the bill, click on Register Payment 6. Select Payment Method "Checks", Create Payment 7. Go to the payment, Amount in Words is wrong 8. Ninety-One Thousand Four Hundred Ninety And 15000000001/100 ONLY Expected behaviour: --- The decimal amount should be rounded, and "ONLY" shouldn't appear. Fix: --- Rounded the pay amount And backported: https://github.com/odoo/enterprise/commit/bb6c9848665709c14c5113b2c98976f869cd473b opw-6058344 Forward-Port-Of: odoo/enterprise#117679 Forward-Port-Of: odoo/enterprise#116717
15 changes
New functionality added to Odoo
This update adds camera support within the Odoo Manufacturing (MRP) module, allowing users to visually inspect products and quality control processes. This enhancement improves accuracy and efficiency in identifying defects and ensuring product standards are met. The change is part of a broader Obox integration.
Original PR description
We now support scales and cameras in mrp using an Obox. see odoo/obox#181 task-6241713
This update adds a new feature to the bank reconciliation widget that allows users to automatically reconcile bank statements on-demand. Previously, reconciliation was triggered only by a scheduled cron job. Now, users can quickly reconcile outstanding transactions, improving efficiency and reducing manual effort.
Original PR description
Add a "Run Auto Reconciliation" entry to the bank reconciliation widget cogs menu, allowing users to trigger the automatic reconciliation without waiting for the next cron run. Selecting the entry opens a wizard pre-filled with the active journal and a default starting date of today minus one month. On validation, the wizard collects the unreconciled bank statement lines of the chosen journal between the selected date and today, and runs _cron_try_auto_reconcile_statement_lines on them. A success notification is displayed and the bank reco view will reload the affected records. task-6095773
Enhancements to existing features
This update allows users to automatically associate return reasons with barcode scans during picking. By adding a return reason ID to the OBTRETU barcode, the system now correctly creates returns and links them to the selected reason, streamlining the return process.
Original PR description
This commit adapts OBTRETU to also fetch and select the return reason with the barcode. Details: Here we have added the `return.reason` ID after the OBTRETU barcode. When this barcode is scanned, it will also scan the return reason and pass that ID in the context of `_returnProducts`. Then it will retrieve that context and set it on the generated return for this delivery. For example is user select `return.reason` with ID 4 new barcode will be OBTRETU:4, so when user scan this QR in picking it will create return and set `return.reason` with ID 4. task-4160966 Community PR: https://github.com/odoo/odoo/pull/234112
This update streamlines the invoicing process by automatically reconciling invoices created directly from sales orders. Previously, this required manual steps; now, a new system passes a context key, enabling automatic reconciliation within the accounting system. This improves efficiency and reduces the risk of errors when generating invoices from sales transactions.
Original PR description
This commit will allow to automatically reconcile the invoice create from the sale order by passing a context key that will be used in the create_invoices function. task-5502964 Forward-Port-Of: odoo/enterprise#117875 Forward-Port-Of: odoo/enterprise#108546
This update adds detailed labels to LLM requests, identifying the source (like agents or web search) and the specific model used. This enhanced tracking allows us to better understand how our AI tools are being utilized and optimize token usage for cost efficiency.
Original PR description
Tag each completion request with a human-readable label identifying what issued it (the agent, web search, AI field, AI server action, ...) so token usage can be attributed to a given source-model combination. Agent-driven requests are prefixed with "Agent:" to set them apart from feature calls. Example: ``` AI: [Agent: Ask AI] gemini-2.5-flash-lite request [0.68s] - Tokens: 115 in (0 cached)|5 out|0 reasoning AI: [Agent: Ask AI] gemini-3-flash-preview request [2.64s] - Tokens: 5295 in (4050 cached)|79 out|186 reasoning AI: [web search] gemini-3-flash-preview request [21.24s] - Tokens: 562 in (226 cached)|708 out|1343 reasoning AI: [Agent: Odoo Image Generation Agent] gemini-2.5-flash-image request [8.25s] - Tokens: 423 in (0 cached)|1324 out|0 reasoning ``` Forward-Port-Of: odoo/enterprise#118811
This update enhances the creation of TSS (Tax Service Statements) in the Odoo Enterprise system by requiring user confirmation before creation. Once created through Fiskaly, the associated IDs are made read-only, and a copy button is added for easy record retrieval. This improves data accuracy and simplifies tracking.
Original PR description
In this commit: -------------- - We have introduced a “Create TSS” button. The system now asks for user confirmation before creating the TSS and client. - Once the TSS and client are successfully created in Fiskaly, the fields displaying their IDs become read-only. Additionally, a Copy button has been added to allow users to easily copy these values for later investigation or reference. task- 5457231
Resolved issues and error corrections
This update ensures all survey results spreadsheets now include a 'Participant' column, linking responses to the correct respondent. This was previously missing for surveys without login requirements, allowing for better tracking of survey data. The change preserves anonymity for truly anonymous surveys by leaving the column blank when no respondent information is available.
Original PR description
Problem: The "Analyze Results" spreadsheet only added a participant column when the survey required login (users_login_required). For surveys that do not require login, such as recruitment screening or surveys launched from CRM, no participant column was produced at all, so the exported answers could not be tied to a respondent. The response already stores partner_id, email and nickname, and the Participations list shows them regardless of login, so the omission was an oversight rather than anonymity protection. Solution: Always emit a "Participant" column, filled with the partner name and falling back to email then nickname. Responses carrying no identity stay blank, preserving anonymity for genuinely anonymous surveys.
This change fixes a problem where DHL shipping labels weren't using the correct template dimensions, resulting in labels printed in the wrong size (8x4 instead of 6x4). The code now maps the selected label template to the correct DHL API format, ensuring accurate label dimensions are generated.
Original PR description
Issue ----- Labels generated with DHL do not respect the template (dimensions) set on the delivery method. Steps to reproduce ----- - Set up DHL - set label template as 6X4_A4_PDF - Create a delivery…
Issue
-----
Labels generated with DHL do not respect the template (dimensions) set on the
delivery method.
Steps to reproduce
-----
- Set up DHL
- set label template as 6X4_A4_PDF
- Create a delivery using the method
- Validate the delivery
> The generated label is in 8x4 inch format instead of 6x4 full page
Explanation
-----
All info below was found in DHL's API doc from the following YAML file
https://developer.dhl.com/sites/default/files/2026-05/dpdhl-express-api-3.3.0.yaml
There are 2 issues with the current implementation regarding the label format.
1. The formats defined on the model (the `ProviderDHL` `delivery.carrier`) do not match the ones of the API. From the API, the accepted values are the following:
- ECOM26_84_A4_001
- ECOM26_84_001
- ECOM_TC_A4
- ECOM26_A6_002
- ECOM26_84CI_001
- ECOM26_84CI_002
- ECOM26_84CI_003
- ECOM_A4_RU_002
- ECOM26_84_LBBX_001
- ECOM26_64_LBBX_001
(values taken from the excerpt below)
```
templateName:
description: >-
Please enter DHL Express document template name.
<BR> Sample Transport label
templates:<BR> ECOM26_84_A4_001
<BR> ECOM26_84_001 - default<BR>
ECOM_TC_A4<BR> ECOM26_A6_002<BR>
ECOM26_84CI_001<BR> ECOM26_84CI_002 - supported
single customer barcode<BR> ECOM26_84CI_003 -
to be used if customer barcodes are used<BR>
ECOM_A4_RU_002<BR>
ECOM26_84_LBBX_001 - supported for loose BBX shipment<BR>
ECOM26_64_LBBX_001 - supported for loose BBX shipment<BR>
[...]
type: string
maxLength: 25
example: ECOM26_84_001
```
[...]: additional info unrelated to labels (useful only for other `typeCode` values)
Since `ProviderDHL` is a model, the `dhl_label_template` selection values cannot be changed and must thus be mapped to the corresponding API values.
- 8X4_A4_PDF => ECOM26_84_A4_001
- 8X4_thermal => ECOM26_84_001
- 8X4_A4_TC_PDF => ECOM_TC_A4
- 6X4_thermal => ECOM26_A6_002
- 6X4_A4_PDF => ECOM26_A6_002
- 8X4_CI_PDF => ECOM26_84CI_001
- 8X4_CI_thermal => ECOM26_84CI_001
- 8X4_RU_A4_PDF => ECOM_A4_RU_002
- 6X4_PDF => ECOM26_A6_002
- 8X4_PDF => ECOM26_84_001
Couple notes about this matching:
- There is no 6x4 in the API, so A6 is used instead (A6 is 105x148mm, 4x6 is 101.6x152.4mm so not a perfect match but the best option still)
- ECOM26_84_001 and ECOM26_A6_002 are used as default values for the respective formats when there is no exact match possible (eg 6x4 only has one option in the API, the default one)
- "A4" is being ignored, because of point 2
2. There is a specific field to force the label to be in A4 format (according to the API, see excerpt below)
```
fitLabelsToA4:
description: >-
To print respective Transport Label and Waybill document into
A4 margin PDF.<BR> Note:
ECOM26_A6_002,ECOM26_84CI_001,ECOM26_84CI_002,ARCH_6X4,ARCH_8X4
template. <BR> This option is applicable only
for PDF encodingFormat selection.<BR> false:
Transport Label and Waybill document will use default margin
settings (default behavior) <BR> true:
Transport Label and Waybill document will print into A4 margin
PDF
type: boolean
example: false
```
-----
Ticket:
opw-6148713
Forward-Port-Of: odoo/enterprise#117281This update resolves an issue where large product weights (over 150kg) triggered errors when calculating shipping rates through Sendcloud in the e-commerce flow. The fix ensures that the system correctly identifies the need to split orders into multiple packages, preventing errors and improving order processing.
Original PR description
Issue ----- Traceback when trying to get a rate through the e-commerce if the order has to be split into multiple packages due to weight being too high. Steps to reproduce ----- - Setup Sendcloud…
Issue ----- Traceback when trying to get a rate through the e-commerce if the order has to be split into multiple packages due to weight being too high. Steps to reproduce ----- - Setup Sendcloud delivery method - make it available in e-commerce - Create a 150kg product and publish it - Go to e-commerce - Add the product to cart - Checkout the cart > Traceback Cause ----- We retrieve the order's weight through the context. https://github.com/odoo/enterprise/blob/d9a9339e1f30f1e5cc37ebb88949451a6652f83b/delivery_sendcloud/models/delivery_carrier.py#L108 If the call to `_get_shipping_rate` returns that the delivery requires multiple packages, we go into https://github.com/odoo/enterprise/blob/d9a9339e1f30f1e5cc37ebb88949451a6652f83b/delivery_sendcloud/models/delivery_carrier.py#L126-L128 If `order_weight` was not present in the context, this will cause an error in `sendcloud_convert_weight` since it expects a numerical value but receives the `None` fallback. This context key is only present when going through `choose.delivery.carrier` (so not in the e-commerce flow). https://github.com/odoo/odoo/blob/058e640e6687ed3f709dc846f0fa7a1f45226849/addons/delivery/wizard/choose_delivery_carrier.py#L69 ----- Ticket: opw-6210398 Forward-Port-Of: odoo/enterprise#119186 Forward-Port-Of: odoo/enterprise#117028
This update fixes a bug in the Thai accounting localization module that prevented users from exporting the P.P.30 - VAT Report. The missing export buttons have been restored, allowing users to generate reports in various formats. This ensures accurate tax reporting compliance for Thai businesses.
Original PR description
Current behavior: -- Missing buttons in the P.P.30 report Expected behavior: -- When clicking on the wheel icon for the P.P.30 - VAT Report, the 3 buttons should show Export for RD Prep, Sales Tax Report, Purchase Tax Report Steps to reproduce: -- In Master version, 1.Install Thai accounting localization module. 2. Navigate to Accounting > Reporting > Tax Report. 3. Select Report: P.P. 30 - VAT Report (TH) from the report dropdown. 4. Click on the gear icon next to "Tax Return". 5. Observe that the export options are missing and only "Copy to Documents" and "Insert in article" are available. Cause of the issue: -- Wrongfully removed the buttons. Caused by commit: https://github.com/odoo/enterprise/commit/ccee902284ab2fd91217ae9a59c1557b7f49433f opw-6267145
This update fixes an issue where the DIAN-compliant electronic invoices generated for Colombia were incorrectly using a generic line number instead of the correct document ID. This prevented the invoices from passing validation checks by the DIAN platform and external systems. The fix ensures invoices now accurately reflect the required document ID, resolving compatibility problems.
Original PR description
### Issue When generating the attached document (AttachedDocument) for Colombia, the parent document reference tag <cbc:ID> incorrectly exported a generic line counter instead of the actual document…
### Issue
When generating the attached document (AttachedDocument) for Colombia, the parent document reference tag <cbc:ID> incorrectly exported a generic line counter instead of the actual document identification number
While the DIAN platform itself accepted the file, this caused rejections in external validation tools and third-party software because they could not resolve the link back to the original invoice
DIAN Documentation: https://www.dian.gov.co/impuestos/factura-electronica/Documents/Anexo_tecnico_factura_electronica_vr_1_7_2020.pdf
On page 213 there is an example for ParentDocumentLineReference
On page 216 there is the specification that does not show any check
Example of the incorrect XML structure:
```xml
<cac:ParentDocumentLineReference>
<cbc:LineID>1</cbc:LineID>
<cac:DocumentReference>
<cbc:ID>1</cbc:ID>
</cac:DocumentReference>
</cac:ParentDocumentLineReference>
```
Expected XML structure:
```xml
<cac:ParentDocumentLineReference>
<cbc:LineID>1</cbc:LineID>
<cac:DocumentReference>
<cbc:ID>SETP990001021</cbc:ID>
</cac:DocumentReference>
</cac:ParentDocumentLineReference>
```
### Cause
In the template, the value for <cbc:ID> was retrieved using `parent_document.get('id')` which fetched the sequential loop index https://github.com/odoo/enterprise/blob/cd25713fd2c35737d98db29df72b2d07ae9146e8/l10n_co_dian/views/templates.xml#L272-L275
The dictionary parsing logic did not extract the true document identifier from the XML tree response or the original XML data https://github.com/odoo/enterprise/blob/13dc30679e382df5845993c880a97df600c39ed4/l10n_co_dian/models/l10n_co_dian_document.py#L429-L432
### Steps to reproduce
- Install `l10n_co_dian`
- Setup DIAN configuration
- Generate an attached document for a commercial event or invoice
- Open the generated XML file
Before the fix, the `<cac:ParentDocumentLineReference>/<cac:DocumentReference>/<cbc:ID>` tag contains a technical integer like "1" instead of the official document sequence number
opw-6164321
Forward-Port-Of: odoo/enterprise#118319This update corrects a bug in the appointment Gantt view that caused new bookings to default to midnight instead of the intended start time. The fix replaces a mistaken override with the correct method, ensuring accurate booking start times are used.
Original PR description
The [commit] replaced the `onAddClicked` method with `_onNewClicked`, and updated all related calls and overrides accordingly. However, the appointment Gantt view override was mistakenly changed to override a non-existent `_onAddClicked` method, leaving the custom logic unused. As a result, bookings created through the `New` button in the Gantt view used midnight (12:00 AM) instead of the time derived from the custom logic as the default start datetime. This commit fixes the issue by correctly overriding `_onNewClicked`. [commit]: https://github.com/odoo/enterprise/commit/bc779c9ec5295f8d1fe06e8432c518c78c606ea2 Forward-Port-Of: odoo/enterprise#118799
This update fixes an issue where check amounts weren't being properly rounded in the Philippines (PH) version of Odoo. Previously, the check amount in words displayed with a decimal component and 'ONLY'. Now, the decimal is rounded, ensuring accurate check formatting and compliance with PH regulations.
Original PR description
Current behaviour: --- When paying with checks, the amount is not rounded in the check amount in words string. Steps to reproduce: --- 1. Switch to PH company 2. Set setting Check Layout as "Print Check - PH" 3. Create a new vendor bill 4. Add a product with a specific price like 91490.15 5. Confirm the bill, click on Register Payment 6. Select Payment Method "Checks", Create Payment 7. Go to the payment, Amount in Words is wrong 8. Ninety-One Thousand Four Hundred Ninety And 15000000001/100 ONLY Expected behaviour: --- The decimal amount should be rounded, and "ONLY" shouldn't appear. Fix: --- Rounded the pay amount And backported: https://github.com/odoo/enterprise/commit/bb6c9848665709c14c5113b2c98976f869cd473b opw-6058344 Forward-Port-Of: odoo/enterprise#117679 Forward-Port-Of: odoo/enterprise#116717
This update resolves an issue where the company's XBRL reports were failing validation by the NBB due to missing data disclosures. The changes add the necessary disclosures, ensuring reports pass validation and comply with regulatory requirements. This prevents potential delays or errors in report submission.
Original PR description
This commit adds missing explanatory disclosure datapoints to the generated XBRL report. The missing disclosures resulted in failing validation when report is submitted to NBB. The datapoints are only added if the original value was non-zero. For example, the tangible assets disclosures are only added if the tangible assets in balance sheet is non-zero. Additionally, only disclosures that were reported as causing a failing validation were added. task-5977199 Forward-Port-Of: odoo/enterprise#117853
Code cleanup and technical improvements
This update replaces `useState` with `proxy` across several Odoo addons (Owl3) to enhance stability and performance. This refactoring primarily impacts the web_enterprise, web_gantt, web_grid, and web_studio modules, ensuring a smoother user experience and more reliable operation.
Original PR description
In Owl3, uses of `useState` or replace with `proxy`. This commit changes all those uses for addons in the range [w..]. *: web_enterprise,web_gantt,web_grid,web_map,web_mobile,web_studio,web_studio_ai_fields,website_generator,website_helpdesk_forum,website_knowledge,whatsapp,
5 changes
Resolved issues and error corrections
This update corrects a bug where previously validated manual bank statement entries continued to be incorrectly suggested for matching with new transactions. The fix ensures that only the most recent bank statement line is considered for reconciliation, improving the accuracy of financial reporting. This resolves a potential issue with mismatched accounts.
Original PR description
Currently, after validating a transaction with a manual operation, the aml resulting from the manual operation can still be selected and matched with other transactions. Steps to reproduce: - Create a transaction for 500 dollars - Create a manual counterpart line for the bank statement line with label "test123" and validate - Create another transaction of -1000 dollars and label "test123" Issue: The manual counterpart line matched before is being suggested against the new transaction. The perfect match reconciliation model will reconcile the manual counterpart line with the new bank statement line. Adding test for community branch opw-6045050 Forward-Port-Of: odoo/enterprise#117462 Forward-Port-Of: odoo/enterprise#115847
This update corrects a bug in the VAT record book export that was incorrectly displaying '01' for invoices with 'No Sujeto por reglas de localización' taxes (like Portuguese VAT). The fix ensures the correct '17' operation code is used, aligning with Spanish VAT regulations and the SII data format. This ensures accurate reporting of sales tax.
Original PR description
**Steps to reproduce:** * Install the **l10n_es_edi_sii** module. * Create a **Portuguese customer**. * Go to **Settings** and enable **EU Intra-community Distance Selling**, then refresh the tax…
**Steps to reproduce:** * Install the **l10n_es_edi_sii** module. * Create a **Portuguese customer**. * Go to **Settings** and enable **EU Intra-community Distance Selling**, then refresh the tax mapping. * Create a customer invoice with a **"No Sujeto por reglas de localización"** tax (e.g. **23.0% PT VAT**). * Go to **Accounting → Reporting → Tax Report → OSS Sales**. * Export the **VAT Record Books (XLSX)** file and open it. **Observed behavior:** * The "Clave de Operación" column shows "01" for lines with no_sujeto_loc taxes instead of "17". * The SII JSON for the same invoice correctly shows "ClaveRegimenEspecialOTrascendencia": "17". **Cause:** * In `_l10n_es_libros_get_common_line_vals()`, `operation_code` was computed manually as `'02' if exempt_reason else '01'`, which only handled the E2 exempt case and defaulted everything else to "01". * This missed OSS/no_sujeto_loc taxes (e.g. FR VAT, PT VAT) that should produce "17" per the Spanish VAT regime code table. **Fix:** * Extract operation code computation into a new dedicated method `_l10n_es_libros_get_operation_code()`. * For customer invoices, delegate to the existing `_l10n_es_get_regime_code()` method already used by SII, which correctly returns "17" for OSS-tagged taxes, "02" for E2 exempt, and "01" otherwise. * For vendor bills, mirror the SII logic by checking whether the invoice taxes include tags from `mod_303_casilla_10_balance` or `mod_303_casilla_11_balance` (intra-community indicators), returning "09" if so and "01" otherwise. opw-6197141,6216485 Forward-Port-Of: odoo/enterprise#117236
This update resolves an issue where users were encountering errors when attempting to use property fields within auto-fields in the Sign module. The fix restricts property field selection, ensuring data integrity and preventing errors during configuration.
Original PR description
Currently, an error occurs when user tries to select a property field in auto field. Steps to replicate: - Install `sale_management` and `sign`. - Open Sales > Products > Products > Open any product.…
Currently, an error occurs when user tries to select a property field in auto field.
Steps to replicate:
- Install `sale_management` and `sign`.
- Open Sales > Products > Products > Open any product.
- From the Gear icon, Click Edit Properties and save the record.
- Enable Debug mode if you are using a version lower than 19.0 .
- Open Sign > Configuration > Field Types.
- Create a new Field > Give a name > Select model as `Product`.
- Select Field as `Property > Property 1` and click save.
Error:
- saas-18.3 and later:
```
File '/home/odoo/odoo18/enterprise/sign/models/sign_item_type.py', line 57, in _check_auto_field_exists
auto_field_value = record.mapped(sign_type.auto_field)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File '/home/odoo/odoo18/community/odoo/orm/models.py', line 5472, in mapped
field = records._fields[field_name]
^^^^^^^^^^^^^^^
AttributeError: 'Property' object has no attribute '_fields'. Did you mean: 'field'?
```
- saas-18.2:
```
File '/home/odoo/odoo18/enterprise/sign/models/sign_item_type.py, line 41, in _check_auto_field_exists
auto_field_value = record.mapped(sign_type.auto_field)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File '/home/odoo/odoo18/community/odoo/orm/models.py', line 5744, in mapped
if len(records) > PREFETCH_MAX:
^^^^^^^^^^^^
TypeError: object of type 'bool' has no len()
```
Cause:
- As the user gave auto fill field as a Property field the [line] called `mapped()` to access its value, this caused the error to occur.
- This occurs because `mapped()` expects a `recordset` (models.Model), but instead it receives a Property object, which does not have `_fields`.
Solution:
- Using `'allow_properties': 'False'`, the property fields wont appear in the list of field selection.
[line]: https://github.com/odoo/enterprise/blob/cdaeb79e1f623831fffa553dbb658698367c7e19/sign/models/sign_item_type.py#L41
sentry-7378769090
Forward-Port-Of: odoo/enterprise#113091This update resolves a bug where cancelled journal entries were incorrectly displayed in the reconciliation view, preventing successful reconciliation and causing data inconsistencies. The fix removes a previous refactor that inadvertently allowed cancelled entries to appear, ensuring accurate reconciliation processes.
Original PR description
Issue: Cancelled journal entries were visible in the "Journal Items to Reconcile" view (action_move_line_posted_unreconciled) because the action domain had no filter to exclude them. This caused…
Issue: Cancelled journal entries were visible in the "Journal Items to Reconcile" view (action_move_line_posted_unreconciled) because the action domain had no filter to exclude them. This caused reconciliation failures, no reconciliation happened, and the cancelled record remained in the view. This regression was introduced during a refactor to allow draft entries in the reconciliation view, where the posted-state condition was removed from the domain: Enterprise commit: https://github.com/odoo/enterprise/commit/003cffabda7d91a6d10d58942ed972ca5e17366d As a result, cancelled journal items also became visible, causing reconciliation attempts to fail while the records remained in the view. Also, we are not allowed to reconcile cancelled move lines, and we already have the validation for this [here](https://github.com/odoo/odoo/blame/a236f67776616f6facdefb0117a6ffdde9b7c84c/addons/account/models/account_move_line.py#L2627) Issue is reproducible on runbot. Here is the video reference: https://drive.google.com/file/d/1ojIDxHn5Yst8gVFy8JyhwtJoDSSSJsmK/view?usp=sharing - OPW: 6247870 Forward-Port-Of: odoo/enterprise#118843 Forward-Port-Of: odoo/enterprise#118773
This update fixes an issue where check amounts weren't being properly rounded in the Philippines (PH) version of Odoo. Previously, the check amount in words displayed with an incorrect decimal format, including 'ONLY'. Now, the decimal amounts are rounded correctly, ensuring accurate check printing and compliance with local regulations.
Original PR description
Current behaviour: --- When paying with checks, the amount is not rounded in the check amount in words string. Steps to reproduce: --- 1. Switch to PH company 2. Set setting Check Layout as "Print Check - PH" 3. Create a new vendor bill 4. Add a product with a specific price like 91490.15 5. Confirm the bill, click on Register Payment 6. Select Payment Method "Checks", Create Payment 7. Go to the payment, Amount in Words is wrong 8. Ninety-One Thousand Four Hundred Ninety And 15000000001/100 ONLY Expected behaviour: --- The decimal amount should be rounded, and "ONLY" shouldn't appear. Fix: --- Rounded the pay amount And backported: https://github.com/odoo/enterprise/commit/bb6c9848665709c14c5113b2c98976f869cd473b opw-6058344 Forward-Port-Of: odoo/enterprise#117679 Forward-Port-Of: odoo/enterprise#116717
8 changes
Enhancements to existing features
This update introduces a new button to streamline the reregistration process for French users, particularly those transitioning between Peppol and PDP systems. It addresses a previous testing issue where changes to the demo company's Peppol settings caused problems during the reregistration flow. This enhancement improves usability and simplifies a key business operation.
Original PR description
#### [IMP] l10n_fr_pdp: fix visibility for peppol (non-PDP) #### [IMP] account_peppol,l10n_fr_pdp: reregister This commit adds a button so that users can reregister more easily. This is i.e. useful to switch from Peppol to PDP for French users. #### meta task-6265603
Resolved issues and error corrections
This update addresses a frustrating user experience when previewing large files in Odoo. Previously, users experienced long delays while the file preview loaded without any visual feedback. This fix now displays a loading indicator during file preview, providing a smoother and more responsive experience for users.
Original PR description
When previewing a big file, the download might take long and the rendering might take even more time. The UI is blocked until the iframe is ready, but there is no feedback for the user. This commit adds some loading feedback until the iframe is rendered. Steps to reproduce: - Go to a Knowledge article - Upload a file with `/file` - Add a huge JSON file (~30MB) - Save - Click on the file icon => The preview opened but took ages to be displayed without giving any feedback to the user task-6014223
This update significantly speeds up the process of deleting website-related fields in Odoo. Previously, this check could take minutes, blocking user actions. Now, it completes in milliseconds by focusing only on fields that actually contain website form markup, improving overall system responsiveness.
Original PR description
Summary ======= `_check_if_used_in_website_form`, the ondelete hook on `ir.model.fields` that guards against deleting a field referenced by a website form, performs poorly on realistic databases. It…
Summary
=======
`_check_if_used_in_website_form`, the ondelete hook on
`ir.model.fields` that guards against deleting a field referenced by
a website form, performs poorly on realistic databases. It can take
multiple minutes to validate a single field deletion, blocking user
actions such as removing a Studio field.
This commit restricts the scan to columns that can actually contain
website form markup, bringing the hook from multi-minute to
sub-second without any loss of coverage.
The Problem
===========
Deleting any `ir.model.fields` record triggers this validation hook,
which must ensure the field is not referenced inside any website
form. The implementation iterates every stored HTML column returned
by `website._get_html_fields()` and runs one case-insensitive
`ILIKE '%data-model_name="<model>"%'` search per column against
`<model>.<html_field>`, then parses each match with `lxml` and
validates it with XPath.
Two root issues cause the multi-minute cost:
- **Unbounded scan surface**: all stored HTML columns are scanned
(~95 on realistic databases), even though the vast majority of them
declare `sanitize=True` and `sanitize_form=True` (the defaults).
When both flags are True, `<form>` tags are stripped on write and
the column can never physically contain website form markup.
- **Per-column `ILIKE` cost**: `ILIKE` on large TEXT/JSONB columns
performs a sequential scan. A single large HTML column is enough
to make the hook run for several minutes on its own.
Improvements
============
- Scan only columns that can actually contain forms:
- `ir.ui.view.arch_db` , primary target; all website forms are
stored there.
- HTML fields whose sanitization either is disabled
(`sanitize=False`, e.g. `blog.post.content`,
`website.custom_code_head`) or explicitly allows forms
(`sanitize_form=False`, e.g.
`product.template.website_description`, `hr.job.description`,
`event.event.description`). Any other HTML field strips `<form>`
on write and will never contain a form.
- Batch searches: group the deleted fields by model once and emit a
single `OR`-domain search per candidate column, instead of one
search per (field, column) pair.
- Parse each returned record with `lxml` and validate with XPath
directly. The `ILIKE` domain already filters out non-matching rows
DB-side.
Benchmarks
==========
Profiled on a database containing ~95 stored HTML columns and ~5.2k
views. The hook was invoked read-only via
`field._check_if_used_in_website_form()` on a custom field.
| Metric | Before | After |
| :----------------------------- | ---------: | ---------: |
| Hook wall time | ~444 s | ~173 ms |
| HTML columns scanned | 95 | 5 |
| SQL queries issued | 96 | 6 |
Key results:
- Hook wall time reduced from multi-minute to sub-second
(~2,570× faster on the profiled database).
- Scan surface reduced from ~95 columns to a handful (1 +
the form-capable HTML fields installed on the database, typically
under 10).
opw-6086536This update fixes a bug preventing users from searching for products in the webshop using their 'Ecommerce Description'. Previously, this field wasn't included in the search functionality. This change ensures customers can find products more effectively based on their descriptions, improving the shopping experience.
Original PR description
Steps to produce: --- - Install `website_sale` module. - Create a product and set an `Ecommerce Description` in the Sales tab. - Go to the webshop and search using a term from the ecommerce description. Issue: --- - Products cannot be found when searching by their ecommerce description. The `description_ecommerce` field is not included in the website search fields. In saas-19.3, this issue has already been resolved in [commit], where the same approach was used. [commit]: https://github.com/odoo/odoo/commit/9394e17a07cb125914fba137405c152bee2d7618 Before: --- <img width="558" height="116" alt="image" src="https://github.com/user-attachments/assets/87730a2e-e326-49a6-be4f-04a167b07d53" /> After: --- <img width="560" height="157" alt="image" src="https://github.com/user-attachments/assets/17ed4abe-6abe-4981-aa1e-6069754ca479" /> opw-6260876 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update resolves an issue where Android 14 users couldn't access their device's camera when using file input fields. The fix ensures users can now select photos directly from their camera, improving usability on this platform. This change addresses a compatibility problem with recent Android versions.
Original PR description
Since Android 14 we don't have option to take a photo on clicking on file input in Chrome.
This for example will allow only images but no option "Camera"
```html
<input type="file" accept="image/*/>
```
A workaround is to use a dummy mimetype (`*/*`), example `dummy/allowAndroidCamera` The fix will be applied on image widget in addition to the original `acceptedFileExtensions` to not override the existing `accept` attribute
Linked url
- https://blog.addpipe.com/html-file-input-accept-video-camera-option-is-missing-android-14-15/
- https://stackoverflow.com/questions/77876374/html-input-type-file-not-working-to-pull-up-camera-for-pixel-android-14-comb/79163998#79163998
- https://issues.chromium.org/issues/40937303
opw-6040375
backport of https://github.com/odoo/odoo/pull/265750
Forward-Port-Of: odoo/odoo#266850This update resolves inconsistencies in Odoo's lot valuation system when products are valued without assigned lots. Previously, discrepancies arose with negative lot quantities, but this fix now allows for negative lot valuations, enabling more flexible stock management. It ensures accurate valuation even when physical lot quantities don't perfectly match the valued amounts.
Original PR description
There have been multiple issues that happened when enabling/disabling lot valuation. Odoo is flexible with the reservation/consumption of lots on StockQuant without lots. This means that while your…
There have been multiple issues that happened when enabling/disabling lot valuation. Odoo is flexible with the reservation/consumption of lots on StockQuant without lots. This means that while your product is valued by lot/SN, you can still end up with a discrepancy between your lot quantity on hand and your lot quantity valued. You can be in a situation where you don't have any negative lots on hand, but the valuation shows the negative amount. If you tried to fix the discrepancy by setting the StockQuant to zero, you are blocked because a lot/SN is required. If you tried to disable the valuation by lot configuration, it was allowed (because no negative quants on hand), but the valuation remaining data would be broken. This PR aims to fix the methods '_svl_empty_stock' and '_svl_replenish_stock' by supporting negative lots. OPW-4888289 --- One way to break the lot valuation: https://github.com/user-attachments/assets/b5f0d8c5-d798-4110-9564-951d0be9dcc6 --- After this PR: - `_svl_empty_stock` simply set the valuation for the lot/product to 0, it's not an OUT/IN svl, and no need to call `_run_fifo` or `_run_fifo_vacuum` (perf++). - The user can enable/disable lot valuation with negative lots - When enabling the lot valuation, the lot valuation will be replenished even if the global quantity is 0. - The user can disable lot valuation when they have a quant without lot. - The user can NOT enable lot valuation when they have a quant without lot. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update strengthens the process for obtaining SIREN numbers used for KYC compliance in France. Previously, the system relied on a simple first nine digits of the company ID, which was unreliable for some users. Now, a validation helper method is implemented to ensure accurate SIREN data capture, improving the integrity of the French KYC process.
Original PR description
Currently we just take the first 9 numbers of the `company_id` and say it is the SIREN. On IAP we have some people who just seem to have put their company name. After this commit we use a helper method that does some simple validation at least. task-None
This update fixes a potential problem where users could accidentally trigger mass email campaigns without proper targeting, leading to unwanted spam. The change restricts the 'Retry' button's functionality when a mailing is linked to a marketing automation campaign, ensuring emails are sent according to campaign filters. A new test has been added to prevent future issues.
Original PR description
When a mailing is managed by a marketing automation campaign, its target domain is dynamically handled by the campaign's activities. If a user clicks the "Retry" button directly on the mailing…
When a mailing is managed by a marketing automation campaign, its target domain is dynamically handled by the campaign's activities. If a user clicks the "Retry" button directly on the mailing template, it bypasses the campaign filters and queues the mailing for the entire target model, causing unintended mass spam. This commit fixes the issue by: 1. Raising a UserError in `action_retry_failed` if the mailing is linked to marketing automation (`use_in_marketing_automation`). 2. Hiding the "Retry" button in the frontend view to prevent confusion. 3. Adding a unit test to ensure this edge case is caught in the future. Steps to reproduce: 1. Create a marketing campaign with a filter and an email activity. 2. Run the activity and ensure at least one email trace fails. 3. Open the mailing template via the "Templates" smart button. 4. Click the "Retry" button on the template form. 5. The mailing is placed in the standard queue, bypassing the domain and targeting all records of the underlying model. OPW-6220106 Forward-Port-Of: odoo/enterprise#119391 Forward-Port-Of: odoo/enterprise#118759
1 change
Resolved issues and error corrections
This update fixes a potential problem where users could accidentally trigger mass email campaigns bypassing campaign filters. The change prevents users from directly retrying failed mailings linked to marketing automation, reducing the risk of unintended spam and ensuring emails are delivered correctly through the campaign's intended targeting. A unit test has also been added for future maintenance.
Original PR description
When a mailing is managed by a marketing automation campaign, its target domain is dynamically handled by the campaign's activities. If a user clicks the "Retry" button directly on the mailing…
When a mailing is managed by a marketing automation campaign, its target domain is dynamically handled by the campaign's activities. If a user clicks the "Retry" button directly on the mailing template, it bypasses the campaign filters and queues the mailing for the entire target model, causing unintended mass spam. This commit fixes the issue by: 1. Raising a UserError in `action_retry_failed` if the mailing is linked to marketing automation (`use_in_marketing_automation`). 2. Hiding the "Retry" button in the frontend view to prevent confusion. 3. Adding a unit test to ensure this edge case is caught in the future. Steps to reproduce: 1. Create a marketing campaign with a filter and an email activity. 2. Run the activity and ensure at least one email trace fails. 3. Open the mailing template via the "Templates" smart button. 4. Click the "Retry" button on the template form. 5. The mailing is placed in the standard queue, bypassing the domain and targeting all records of the underlying model. OPW-6220106 Forward-Port-Of: odoo/enterprise#118759