Wednesday, July 22, 2026
159 changes
13 changes
Enhancements to existing features
In this commit, we continue cleaning and aligning continuous production BoM with normal BoM alongside some UX changes and improvements. In case of a continuous production BoM: - Marking a WO as done, doesn't update qty producing - Interacting with the WO card in shopfloor also will not update qty producing, because it used to mess up component's consumption. Move demand should only be updated when we update MO's quantity producing. In General: - No production state tracking in the
Original PR description
In this commit, we continue cleaning and aligning continuous production BoM with normal BoM alongside some UX changes and improvements. In case of a continuous production BoM: - Marking a WO as done, doesn't update qty producing - Interacting with the WO card in shopfloor also will not update qty producing, because it used to mess up component's consumption. Move demand should only be updated when we update MO's quantity producing. In General: - No production state tracking in the chatter for WO Form - Allow splitting when WO is done - Ensuring that if there are 2 users working on the same time and one of them marks the WO is done, the other won't be able to update the `qty_produced` on accident and will be shown an error to avoid inconsistencies. Task: 6384174 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Resolved issues and error corrections
## Steps to Reproduce: - Install `stock_picking_batch` with demo data. - Inventory > Operations > Batch Transfers. - Open any record and click on "Print labels". ## Error: `AttributeError: 'stock.move.line' object has no attribute 'action_open_label_layout'` ## Cause: Since commit https://github.com/odoo/odoo/commit/e177fc82faf8ab3577678a587efe51d18e4369f2, the `action_open_label_layout` method is shared by `stock.picking`, `stock.picking.batch`, and `mrp.production` models. However,
Original PR description
## Steps to Reproduce: - Install `stock_picking_batch` with demo data. - Inventory > Operations > Batch Transfers. - Open any record and click on "Print labels". ## Error: `AttributeError: 'stock.move.line' object has no attribute 'action_open_label_layout'` ## Cause: Since commit https://github.com/odoo/odoo/commit/e177fc82faf8ab3577678a587efe51d18e4369f2, the `action_open_label_layout` method is shared by `stock.picking`, `stock.picking.batch`, and `mrp.production` models. However, `stock.picking.batch` mistakenly calls the method on stock move lines instead of stock moves, while the method expects `stock.move` records. ## Fix: This commit calls the method on move ids, ensuring the label layout wizard get the expected records. sentry-7620773909
Miscellaneous changes
This reverts commit 787223c. In the point of sale, concurrent sales of the same product can happen, e.g. if several physical points of sales are open at the same time, each with their own session. In the case where the underlying product's valuation is tracked automatically and perpetually, the creation of the pos order leads to the creation of the stock picking, which in turn leads to a search for the next available svl. Because of the flush_all, this can cause lots of retry failures and ass
Original PR description
This reverts commit 787223c. In the point of sale, concurrent sales of the same product can happen, e.g. if several physical points of sales are open at the same time, each with their own session. In the case where the underlying product's valuation is tracked automatically and perpetually, the creation of the pos order leads to the creation of the stock picking, which in turn leads to a search for the next available svl. Because of the flush_all, this can cause lots of retry failures and associated delay/latency/overall perceived slowness for the end user. opw-6206709 Forward-Port-Of: odoo/odoo#276517 Forward-Port-Of: odoo/odoo#275264
4 changes
Resolved issues and error corrections
When an attachment is added to an email template and is linked to a journal, and then you try to send an invoice, the attachment is shown in the attachments box but is not sent via peppol, the reason is that we were filtering to send only manually added attachments, and the email attachment was not considered "manual". task-id-6241354 Forward-Port-Of: odoo/odoo#272472
Original PR description
When an attachment is added to an email template and is linked to a journal, and then you try to send an invoice, the attachment is shown in the attachments box but is not sent via peppol, the reason is that we were filtering to send only manually added attachments, and the email attachment was not considered "manual". task-id-6241354 Forward-Port-Of: odoo/odoo#272472
4 changes
Resolved issues and error corrections
### [FIX] web: fix mocked dates in tests Dates are mocked in all unit tests by default; either to a default static value, or to one defined in the test/suite. To do so, the `window.Date` constructor is overridden to have the arguments auto-filled with the current mock date paramters. Before this commit, an additional offset was always added to the given arguments to reflect: - the time elapsed from the beginning of the test; - any virtual offset added by a helper such as 'advanceTime
Original PR description
### [FIX] web: fix mocked dates in tests Dates are mocked in all unit tests by default; either to a default static value, or to one defined in the test/suite. To do so, the `window.Date` constructor…
1 change
Resolved issues and error corrections
Before this commit, when clicking on refresh and the kyc_status on IAP was 'fail', we put the status on the db to 'fail' and ended the process. This implies creating a new record IAP side even if it is useless and also implies that there could be cases where there would be a mismatch between iap and Odoo. e.g. The client starts a verification process, he ends up refusing to sign the documents. On IAP, the kyc status would be equal to 'fail'. Then the user have a possibility to submit a manual
Original PR description
Before this commit, when clicking on refresh and the kyc_status on IAP was 'fail', we put the status on the db to 'fail' and ended the process. This implies creating a new record IAP side even if it is useless and also implies that there could be cases where there would be a mismatch between iap and Odoo. e.g. The client starts a verification process, he ends up refusing to sign the documents. On IAP, the kyc status would be equal to 'fail'. Then the user have a possibility to submit a manual verification and when submitting it status would go to 'processing'. The problem is that in the meantime (after refusing but before submitting manual verification), if the user clicks on the refresh button it would ends the process on Odoo and then not going to 'success' on the DB even if it is the case on IAP after Support reviewed the request. task-6307255 Forward-Port-Of: odoo/odoo#276191
2 changes
Resolved issues and error corrections
Steps to reproduce the bug: - Install l10n_ke_edi_oscu_stock - Run Test_sale_mrp_kit_bom_cogs Problem: ```self.assertAlmostEqual(stock_out_aml.credit, 1.53, msg="Should not include the value of consumable component") AssertionError: 3.07 != 1.53 within 7 places (1.5399999999999998 difference) : Should not include the value of consumable component ``` The test delivered 1 whole unit of every component of Kit A regardless of the fractional quantity actually needed to produce a single kit
Original PR description
Steps to reproduce the bug: - Install l10n_ke_edi_oscu_stock - Run Test_sale_mrp_kit_bom_cogs Problem: ```self.assertAlmostEqual(stock_out_aml.credit, 1.53, msg="Should not include the value of…
1 change
Resolved issues and error corrections
When a relational property has a domain the server cannot evaluate, opening its definition editor crashes. The editor calls search_count on that domain to show how many records match, both when it opens and on every later render. The server raises a ValueError and the call has no error handling, so the whole editor goes down. The bad domain stays saved on the property, so reopening the editor fails the same way and the property can no longer be edited or deleted. Wrap the search_count call in _
Original PR description
When a relational property has a domain the server cannot evaluate, opening its definition editor crashes. The editor calls search_count on that domain to show how many records match, both when it…
In Multiwebsite settings, when the public user interactions needs email generation (appointment or event flow), the email links are generated with a base url that does not corresponds to the one from which the request started. - Have website A and website B - Create an event and assign it to website B - As public user, access the event and register to it - Check the generated email Issue: button links in the email will redirect to the wrong website, so users will encounter an issue when
Original PR description
In Multiwebsite settings, when the public user interactions needs email generation (appointment or event flow), the email links are generated with a base url that does not corresponds to the one from which the request started. - Have website A and website B - Create an event and assign it to website B - As public user, access the event and register to it - Check the generated email Issue: button links in the email will redirect to the wrong website, so users will encounter an issue when managing the event. This occurs because the record `event.registration` has no website_id field and the base url is taken from the company default website (website A) opw-4146760 opw-4336369 Forward-Port-Of: odoo/odoo#276984 Forward-Port-Of: odoo/odoo#274051
**Steps to reproduce:** 1. Create a Sales Order. 2. Create a 50% down payment invoice. 3. Create a credit note for the down payment invoice. 4. Reset the credit note to Draft and cancel it. 5. Create the final invoice from the Sales Order. **Issue:** The final invoice is generated for 100% of the order amount, acting as if the down payment invoice does not exist. **Expected behavior:** The final invoice should only include the remaining 50% of the order amount because a valid 50% do
Original PR description
**Steps to reproduce:** 1. Create a Sales Order. 2. Create a 50% down payment invoice. 3. Create a credit note for the down payment invoice. 4. Reset the credit note to Draft and cancel it. 5. Create…
**Steps to reproduce:** 1. Create a Sales Order. 2. Create a 50% down payment invoice. 3. Create a credit note for the down payment invoice. 4. Reset the credit note to Draft and cancel it. 5. Create the final invoice from the Sales Order. **Issue:** The final invoice is generated for 100% of the order amount, acting as if the down payment invoice does not exist. **Expected behavior:** The final invoice should only include the remaining 50% of the order amount because a valid 50% down payment invoice still exists. **Why this happens:** - The `price_unit` on the Sales Order's down payment line is manually updated during `action_post()` based on the sum of posted invoices minus posted credit notes. - When the credit note is posted, `price_unit` drops to 0. However, when that credit note is subsequently reset to draft and cancelled, it triggers `button_cancel()` which only refreshed the line's display name and failed to recalculate `price_unit`. As a result, `price_unit` remained at 0 even though the credit note was no longer active, causing the final invoice to deduct nothing. opw-6373578 Forward-Port-Of: odoo/odoo#277386 Forward-Port-Of: odoo/odoo#275684
Steps to reproduce: - Open the website editor. - Go to the Theme tab. - Inspect the Primary or Secondary color picker title. => The title prop is undefined. - Go to a product page with several product images. - Edit the carousel thumbnail position option. => The Left and Bottom button titles are undefined. Before this commit, some builder option titles were passed as OWL expressions instead of translated string props. After this commit, these titles use translated string props and are
Original PR description
Steps to reproduce: - Open the website editor. - Go to the Theme tab. - Inspect the Primary or Secondary color picker title. => The title prop is undefined. - Go to a product page with several product images. - Edit the carousel thumbnail position option. => The Left and Bottom button titles are undefined. Before this commit, some builder option titles were passed as OWL expressions instead of translated string props. After this commit, these titles use translated string props and are properly available to the builder components. task-6034856 Forward-Port-Of: odoo/odoo#275940 Forward-Port-Of: odoo/odoo#275235
When an attachment is added to an email template and is linked to a journal, and then you try to send an invoice, the attachment is shown in the attachments box but is not sent via peppol, the reason is that we were filtering to send only manually added attachments, and the email attachment was not considered "manual". task-id-6241354 Forward-Port-Of: odoo/odoo#272472
Original PR description
When an attachment is added to an email template and is linked to a journal, and then you try to send an invoice, the attachment is shown in the attachments box but is not sent via peppol, the reason is that we were filtering to send only manually added attachments, and the email attachment was not considered "manual". task-id-6241354 Forward-Port-Of: odoo/odoo#272472
Currently, we only load the XML data from the exported POS order in the field `l10n_jo_edi_pos_computed_xml` when`l10n_jo_edi_pos_error` is False. It should be the opposite. The field `l10n_jo_edi_pos_computed_xml` is only used when we call `download_l10n_jo_edi_pos_computed_xml()` from the anchor "Download XML" , and that anchor is only visible when `l10n_jo_edi_pos_error` is True. If the request succeeds, then the XML file will be stored in the field `l10n_jo_edi_pos_xml_attachment_i
Original PR description
Currently, we only load the XML data from the exported POS order in the field `l10n_jo_edi_pos_computed_xml` when`l10n_jo_edi_pos_error` is False. It should be the opposite. The field `l10n_jo_edi_pos_computed_xml` is only used when we call `download_l10n_jo_edi_pos_computed_xml()` from the anchor "Download XML" , and that anchor is only visible when `l10n_jo_edi_pos_error` is True. If the request succeeds, then the XML file will be stored in the field `l10n_jo_edi_pos_xml_attachment_id` anyway. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#276918
Owl 3 refs are signal, not objects with `.el`. Replace `this.content.el` with `this.content()` so preview updates keep targeting the actual element. 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
Original PR description
Owl 3 refs are signal, not objects with `.el`. Replace `this.content.el` with `this.content()` so preview updates keep targeting the actual element. 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
In this commit [1], the default-9 palette have been modified to dark for a POC, and has not been reverted to it's original color. This PR revert to the original colors. [1]: a26f2cef490408eb7c73623317f1b42050aa0f41 task-6325919
Original PR description
In this commit [1], the default-9 palette have been modified to dark for a POC, and has not been reverted to it's original color. This PR revert to the original colors. [1]: a26f2cef490408eb7c73623317f1b42050aa0f41 task-6325919
**Steps to reproduce:** - Create an attribute of type always, 2 values A and B for it - The two values should have an extra price, like 100 for A and 150 for B - Create an attribute of type dynamic, 2 values C and D for it - C should have an extra price of 100 and 150 for D - Make a product with both of those product, set the price to 100 2 possibilities: - In the PoS, click the product, on the product popup, the price is 100 - This 100 is the product's price and does not change ev
Original PR description
**Steps to reproduce:** - Create an attribute of type always, 2 values A and B for it - The two values should have an extra price, like 100 for A and 150 for B - Create an attribute of type dynamic,…
**Steps to reproduce:** - Create an attribute of type always, 2 values A and B for it - The two values should have an extra price, like 100 for A and 150 for B - Create an attribute of type dynamic, 2 values C and D for it - C should have an extra price of 100 and 150 for D - Make a product with both of those product, set the price to 100 2 possibilities: - In the PoS, click the product, on the product popup, the price is 100 - This 100 is the product's price and does not change even if we change the values - Order that product and buy it with variants A and C - Click on the product again, the price is 300, which is correct - When we click on D, the price is reset to 100, but should be 350 **Why the fix:** When computing the popup's title, we try to get the current product based on the variants choices in the popup. If the product is found, we take that, because it means that it's already in the database. https://github.com/odoo/odoo/blob/0d7f5058664b501779b833609468e535b34356bf/addons/point_of_sale/static/src/app/components/popups/product_configurator_popup/product_configurator_popup.js#L260 If we do not find it, we just take the product template, which does not contain the current extra prices, which is why we got a price of 100 in the exemple. The product is not found because in the case of dynamic variants, the product is only created once it has been ordered at least once. Which means that for this newly created product, it is not yet in the database, so we take the product template instead of the product itself. We now also add the extra price for a product if it is undefined, meaning it has not been found in the database yet. We can't directly update the getter for the priceExtra, as it's also used to build the payload. As the rest of the code works fine with dynamic products with extra price the way it is sent now, we only change the title instead of changing the entire logic and computation. opw-6326125 Forward-Port-Of: odoo/odoo#273411
Before this commit: In some cases, an element may have a invisible `/n` first child from the html. When inserting content to it, the insert function doesn't check if the first child is visible, and then split the element wrongly. After this commit: we now check if the previous sibling of the current node is invisible, if so, we don't split the parent element. task-6352841 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/o
Original PR description
Before this commit: In some cases, an element may have a invisible `/n` first child from the html. When inserting content to it, the insert function doesn't check if the first child is visible, and then split the element wrongly. After this commit: we now check if the previous sibling of the current node is invisible, if so, we don't split the parent element. task-6352841 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#277619 Forward-Port-Of: odoo/odoo#273958
all_sm is referenced by two branches of the outer UNION, so PostgreSQL materializes it (a CTE used more than once is an optimization fence). Every query on report_stock_quantity therefore builds the forecast for all products/warehouses first and filters afterwards, so predicates like product_id can't reach the stock_move scan. This hurts single-product lookups such as _read_group() in mrp_report_bom_structure._get_stock_availability(), called repeatedly per component while rendering a BoM rep
Original PR description
all_sm is referenced by two branches of the outer UNION, so PostgreSQL materializes it (a CTE used more than once is an optimization fence). Every query on report_stock_quantity therefore builds the…
all_sm is referenced by two branches of the outer UNION, so PostgreSQL materializes it (a CTE used more than once is an optimization fence). Every query on report_stock_quantity therefore builds the forecast for all products/warehouses first and filters afterwards, so predicates like product_id can't reach the stock_move scan.
This hurts single-product lookups such as _read_group() in mrp_report_bom_structure._get_stock_availability(), called repeatedly per component while rendering a BoM report: each call does a full stock_move scan plus two sorts that spill to disk.
Marking all_sm NOT MATERIALIZED lets the planner inline it and push the product_id/warehouse_id filter down to an index scan, removing the full scan, the GENERATE_SERIES expansion and the on-disk sorts. warehouse_cte stays materialized (small and cheap).
Query generated from the _read_group:
```SQL
SELECT MIN("report_stock_quantity"."date")
FROM "report_stock_quantity"
WHERE (
(
(
(
("report_stock_quantity"."state" = 'forecast')
AND ("report_stock_quantity"."date" >= '2026-07-08')
)
AND ("report_stock_quantity"."product_id" = 15743)
)
AND ("report_stock_quantity"."product_qty" >= 1.0)
)
AND ("report_stock_quantity"."warehouse_id" = 4)
)
AND ("report_stock_quantity"."company_id" IN (1))
```
Before:
800 ms by _read_group in _get_stock_availability().
For opening a BoM overview with hundred of components takes 17 sec.
After:
25 ms by _read_group in _get_stock_availability().
Same BoM overview drops to 3 sec to open.
cc @Aurelienvd
I can send you EXPLAIN ANALYZE, but I prefer to not putting them here to avoid data leakage.
Forward-Port-Of: odoo/odoo#277235
Forward-Port-Of: odoo/odoo#275022Currently, we only load the XML data from the exported POS order in the field `l10n_jo_edi_pos_computed_xml` when`l10n_jo_edi_pos_error` is False. It should be the opposite. The field `l10n_jo_edi_pos_computed_xml` is only used when we call `download_l10n_jo_edi_pos_computed_xml()` from the anchor "Download XML" , and that anchor is only visible when `l10n_jo_edi_pos_error` is True. If the request succeeds, then the XML file will be stored in the field `l10n_jo_edi_pos_xml_attachment_i
Original PR description
Currently, we only load the XML data from the exported POS order in the field `l10n_jo_edi_pos_computed_xml` when`l10n_jo_edi_pos_error` is False. It should be the opposite. The field `l10n_jo_edi_pos_computed_xml` is only used when we call `download_l10n_jo_edi_pos_computed_xml()` from the anchor "Download XML" , and that anchor is only visible when `l10n_jo_edi_pos_error` is True. If the request succeeds, then the XML file will be stored in the field `l10n_jo_edi_pos_xml_attachment_id` anyway. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#276918
Before this commit, the maximum weight and volume allowed on a delivery method were checked against transfers using the quantity in the unit of the move, while the weight and volume of a product are expressed per reference unit. The same checks on sale orders already use the quantity in the reference unit. Steps to reproduce: - create a delivery method with a maximum weight of 10 kg - create a product in Units weighing 1 kg with Dozens in its allowed units - create a delivery transfer of 2
Original PR description
Before this commit, the maximum weight and volume allowed on a delivery method were checked against transfers using the quantity in the unit of the move, while the weight and volume of a product are…
Before this commit, the maximum weight and volume allowed on a delivery method were checked against transfers using the quantity in the unit of the move, while the weight and volume of a product are expressed per reference unit. The same checks on sale orders already use the quantity in the reference unit. Steps to reproduce: - create a delivery method with a maximum weight of 10 kg - create a product in Units weighing 1 kg with Dozens in its allowed units - create a delivery transfer of 2 Dozen of the product and select the carrier on the transfer The 24 kg shipment is weighed as 2 kg, so the carrier is proposed on the transfer although it exceeds its maximum weight, and it is correctly refused on a sale order for the same quantity. With a unit smaller than the reference one, valid carriers are hidden instead. Solution: Use the quantity in the reference unit of the product, as done for sale orders and everywhere else the shipment weight is computed. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#277425
**Steps to reproduce:** - Create an attribute of type always, 2 values A and B for it - The two values should have an extra price, like 100 for A and 150 for B - Create an attribute of type dynamic, 2 values C and D for it - C should have an extra price of 100 and 150 for D - Make a product with both of those product, set the price to 100 2 possibilities: - In the PoS, click the product, on the product popup, the price is 100 - This 100 is the product's price and does not change ev
Original PR description
**Steps to reproduce:** - Create an attribute of type always, 2 values A and B for it - The two values should have an extra price, like 100 for A and 150 for B - Create an attribute of type dynamic,…
**Steps to reproduce:** - Create an attribute of type always, 2 values A and B for it - The two values should have an extra price, like 100 for A and 150 for B - Create an attribute of type dynamic, 2 values C and D for it - C should have an extra price of 100 and 150 for D - Make a product with both of those product, set the price to 100 2 possibilities: - In the PoS, click the product, on the product popup, the price is 100 - This 100 is the product's price and does not change even if we change the values - Order that product and buy it with variants A and C - Click on the product again, the price is 300, which is correct - When we click on D, the price is reset to 100, but should be 350 **Why the fix:** When computing the popup's title, we try to get the current product based on the variants choices in the popup. If the product is found, we take that, because it means that it's already in the database. https://github.com/odoo/odoo/blob/0d7f5058664b501779b833609468e535b34356bf/addons/point_of_sale/static/src/app/components/popups/product_configurator_popup/product_configurator_popup.js#L260 If we do not find it, we just take the product template, which does not contain the current extra prices, which is why we got a price of 100 in the exemple. The product is not found because in the case of dynamic variants, the product is only created once it has been ordered at least once. Which means that for this newly created product, it is not yet in the database, so we take the product template instead of the product itself. We now also add the extra price for a product if it is undefined, meaning it has not been found in the database yet. We can't directly update the getter for the priceExtra, as it's also used to build the payload. As the rest of the code works fine with dynamic products with extra price the way it is sent now, we only change the title instead of changing the entire logic and computation. opw-6326125 Forward-Port-Of: odoo/odoo#273411
### [FIX] web: fix mocked dates in tests Dates are mocked in all unit tests by default; either to a default static value, or to one defined in the test/suite. To do so, the `window.Date` constructor is overridden to have the arguments auto-filled with the current mock date paramters. Before this commit, an additional offset was always added to the given arguments to reflect: - the time elapsed from the beginning of the test; - any virtual offset added by a helper such as 'advanceTime'. The issue is that the spec of the Date constructor wants that the returned date object has to match all given arguments, and any omitted argument will be defaulted to the current date/time. This was not the case in tests, as the offset was always added, regardless of the given arguments. With this commit: only the arguments that are NOT given and that have been defaulted to current (mocked) date/time will be offset by the adequate value. Furthermore: as these mocked parameters are meant to reflect UTC values, the offset now also considers the *actual* browser offset to generate a local date from the mock date parameters. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#277041 Forward-Port-Of: odoo/odoo#275391
### Issue before this commit: Sending a TicketBAI invoice to a customer with a Spanish address and a VAT number starting with 'N' (Non-resident entity) resulted in a rejection with error B4_2000027. The XML incorrectly generated the national <DesgloseFactura> tag instead of the required <DesgloseTipoOperacion> tag. ### Steps to reproduce the issue: 1. Download Accounting, l10n_es and l10n_es_edi_tbai 2. Change name to ES Company into “NOMBRE APELLIDOUNO APELLIDODOS” (this is to make sure t
Original PR description
### Issue before this commit: Sending a TicketBAI invoice to a customer with a Spanish address and a VAT number starting with 'N' (Non-resident entity) resulted in a rejection with error B4_2000027.…
### Issue before this commit: Sending a TicketBAI invoice to a customer with a Spanish address and a VAT number starting with 'N' (Non-resident entity) resulted in a rejection with error B4_2000027. The XML incorrectly generated the national <DesgloseFactura> tag instead of the required <DesgloseTipoOperacion> tag. ### Steps to reproduce the issue: 1. Download Accounting, l10n_es and l10n_es_edi_tbai 2. Change name to ES Company into “NOMBRE APELLIDOUNO APELLIDODOS” (this is to make sure the certificate for Ticketbai works) 3. Go to Settings → Spain Localization → set Tax Agency for = Bizkaia 4. Change VAT number for customer Mulhacén Digital S.L. into N0011452J (must be a foreign entity ID) 5. Go to Settings > Technical > System Parameters and set the parameter 'l10n_es_edi_tbai.epigrafe' to 165360 6. Create a new invoice for that client and try to send it to TicketBAI 7. Error: B4_1000002: Todos los registros incluidos en la petición son incorrectos. B4_2000027: La factura contiene un Tipo de desglose incorrecto. Ha de ser a nivel de operación cuando la factura es completa y, además, existe destinatario extranjero (tipo IDOtro o que sea NIF que empiece por N) o la Clave de IVA es 02. ### Cause of the issue: The _l10n_es_is_foreign() method evaluated these customers as domestic because their country was set to Spain and their VAT did not start with "ESN". It failed to recognize a standalone "N" prefix as a valid foreign identifier. https://github.com/odoo/odoo/blob/75ae45861e2f417aa2b90bdb2b2869718e091c09/addons/l10n_es/models/res_partner.py#L7-L10 ### Reason to introduce the fix: Adding the 'N' prefix to the _l10n_es_is_foreign() check ensures the system correctly treats these entities as foreign for tax purposes. This generates the correct XML structure automatically, without forcing users to unnaturally prepend "ES" to a legally valid NIF. opw-6326359 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#275231
When an attachment is added to an email template and is linked to a journal, and then you try to send an invoice, the attachment is shown in the attachments box but is not sent via peppol, the reason is that we were filtering to send only manually added attachments, and the email attachment was not considered "manual". task-id-6241354 Forward-Port-Of: odoo/odoo#272472
Original PR description
When an attachment is added to an email template and is linked to a journal, and then you try to send an invoice, the attachment is shown in the attachments box but is not sent via peppol, the reason is that we were filtering to send only manually added attachments, and the email attachment was not considered "manual". task-id-6241354 Forward-Port-Of: odoo/odoo#272472
Currently, we only load the XML data from the exported POS order in the field `l10n_jo_edi_pos_computed_xml` when`l10n_jo_edi_pos_error` is False. It should be the opposite. The field `l10n_jo_edi_pos_computed_xml` is only used when we call `download_l10n_jo_edi_pos_computed_xml()` from the anchor "Download XML" , and that anchor is only visible when `l10n_jo_edi_pos_error` is True. If the request succeeds, then the XML file will be stored in the field `l10n_jo_edi_pos_xml_attachment_i
Original PR description
Currently, we only load the XML data from the exported POS order in the field `l10n_jo_edi_pos_computed_xml` when`l10n_jo_edi_pos_error` is False. It should be the opposite. The field `l10n_jo_edi_pos_computed_xml` is only used when we call `download_l10n_jo_edi_pos_computed_xml()` from the anchor "Download XML" , and that anchor is only visible when `l10n_jo_edi_pos_error` is True. If the request succeeds, then the XML file will be stored in the field `l10n_jo_edi_pos_xml_attachment_id` anyway. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#276918
Steps to reproduce the bug: - Install l10n_ke_edi_oscu_stock - Run Test_sale_mrp_kit_bom_cogs Problem: ```self.assertAlmostEqual(stock_out_aml.credit, 1.53, msg="Should not include the value of consumable component") AssertionError: 3.07 != 1.53 within 7 places (1.5399999999999998 difference) : Should not include the value of consumable component ``` The test delivered 1 whole unit of every component of Kit A regardless of the fractional quantity actually needed to produce a single kit (0.34/0.14/0.2 units for Component A/B/BB respectively). This went unnoticed under the default invoice_policy 'order', since qty_delivered never drives the invoiced quantity in that case. l10n_ke_edi_oscu_stock forces invoice_policy to 'delivery' for storable products that have no explicit company_id, which is the case for the products created in this test. With invoice_policy 'delivery', _compute_kit_quantities() correctly reads the over-delivered components as enough stock to form 2 complete kits (min ratio 2.94, floored to 2) instead of 1, doubling the invoiced quantity and the resulting COGS (3.07 instead of 1.53). runbot-243633
Firefox has a strict limit of ~640,000 characters for history state serialization and throws NS_ERROR_ILLEGAL_VALUE past it. Chrome and Safari throw DataCloneError past their own undocumented limits (~500MB and ~64MB respectively). When a debounced push() exceeded these limits, the error was unhandled and broke navigation. Catch these two specific errors and log them instead of crashing, while still resetting the push state and re-throwing any other unexpected error. opw-6182687
Original PR description
Firefox has a strict limit of ~640,000 characters for history state serialization and throws NS_ERROR_ILLEGAL_VALUE past it. Chrome and Safari throw DataCloneError past their own undocumented limits (~500MB and ~64MB respectively). When a debounced push() exceeded these limits, the error was unhandled and broke navigation. Catch these two specific errors and log them instead of crashing, while still resetting the push state and re-throwing any other unexpected error. opw-6182687
When a relational property has a domain the server cannot evaluate, opening its definition editor crashes. The editor calls search_count on that domain to show how many records match, both when it opens and on every later render. The server raises a ValueError and the call has no error handling, so the whole editor goes down. The bad domain stays saved on the property, so reopening the editor fails the same way and the property can no longer be edited or deleted. Wrap the search_count call in _updateMatchingRecordsCount (property_definition.js) in a try/catch and show no count when it fails. This is the only place the editor counts matching records, so guarding it here handles a bad domain from any source, the field selector or the code editor. The field selector still shows its warning on the invalid path, so the user can fix or delete the property. Steps to reproduce: 1. On a model that has a Properties field, add a Many2one property and set its Model to a model that itself has a Properties field. 2. Open the property Domain and click New Rule. 3. In the field selector pick the Properties entry, then close the selector. => An error dialog appears and the property can no longer be edited or deleted. Ticket [link](https://www.odoo.com/odoo/project.task/6101311) opw-6101311