Wednesday, September 10, 2025
15 changes · saas-18.3
Enhancements to existing features
Mexican CFDI e-invoices are now generated from invoice lines in the same way the SAT validates them, reducing the risk of rejection due to rounding or total mismatches. Any small difference from the original document is handled through discounts where possible, or by adding an adjustment line when needed.
Original PR description
Simplify the CFDI generation. Now the totals are always computed from the lines. That way, it's impossible for the SAT to refuse a CFDI since it's built in the way the SAT checks the validity of the file. The difference between the CFDI total and the original documents is put using the discount if available. If not, we add a fake line in the CFDI. task-id: 4926200
Users with Invoicing & Banks access can now start an online bank synchronization when a bank journal is configured for online feeds and not yet connected. This makes bank connection setup available to the right finance users directly from the journal dashboard, reducing reliance on higher-access users.
Original PR description
Before this commit: - Users with "Invoicing & Banks" access rights could not create a bank synchronization, and the "Connect Bank" button was not visible. After this commit: - Users with "Invoicing & Banks" access rights can now create a bank synchronization if the journal has "Bank Feeds = Online Synchronization" and the bank is not yet connected. - The "Connect Bank" button is now visible to them. task-4840544 Forward-Port-Of: odoo/enterprise#87408
Resolved issues and error corrections
The editor now adds a blank paragraph before inserted items like banners or tables of contents so they do not block full-content deletion. This prevents users from being unable to clear an editable area when selecting everything and pressing backspace.
Original PR description
**Current behavior before PR:** If the first child of an editable element was `contenteditable="false"`, selecting all content and pressing backspace would not remove everything. This was due to a Chromium bug where non-editable elements as the first child are not fully selected. **Desired behavior after PR is merged:** When inserting elements such as a banner or table of contents, a paragraph is added before them. This ensures that the editable element never starts with a non-editable child. task: 5010666
Point of Sale cash out receipts now print correctly when using printers connected through the hardware proxy. This prevents staff from seeing a successful cash-out message while the receipt silently fails to print.
Original PR description
When the printer comes form the hardware_proxy, the receipt was not printing for a cash out. Steps to reproduce: ------------------- * Connect an ePos printer * Open pos * Create and validate a cash out > Observation: Notification says 'Succesfully...' Console log says 'No printer device available...' Why the fix: ------------ Introduced by this pr: https://github.com/odoo/odoo/pull/209274 This protection wasn't working for our usecase where the device is set after this check in this call `this.printHtml(el, options)`. A hoot test will be added during fw-port in 18.3 opw-4841441 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#222155
This fix prevents invoice creation from crashing when a company has no country set and VAT number verification is enabled. The system now safely handles missing company country information, helping users continue invoicing even if company setup data is incomplete.
Original PR description
The system crashes with an error when a user tries to create an invoice. **Steps to produce:-** - Install `Accounting` module and switch to `BE Company`. - Go to `Settings > Users & Companies >…
The system crashes with an error when a user tries to create an invoice.
**Steps to produce:-**
- Install `Accounting` module and switch to `BE Company`.
- Go to `Settings > Users & Companies > Companies` and remove the country from the BE company.
- Create a new customer with:-
- Country as `Belgium`.
- Tax ID as `DE123456788`.
- `Accounting > configuration > settings > enable Verify VAT Numbers`.
- Now try to make `invoice` with customer as previously created customer.
**Error:-**
`TypeError : argument of type 'bool' is not iterable`
**Root cause:-**
- At [1], the code attempts to access `company.country_id`, but since the country was manually removed from the company, it evaluates to null record, leading to the error.
**Solution:-**
- Add a safeguard to ensure `company.country_id` also exist before accessing `country_group_codes`.
[1] -https://github.com/odoo/odoo/blob/4c2330f3cc0d1a0046e28d351f894763aeea57d2/addons/base_vat/models/res_partner.py#L764
**sentry-6851141424**
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prFixes an issue where unbuilding manufacturing orders for non-storable finished products or by-products could create duplicate product movement records. This keeps inventory and manufacturing records accurate and avoids confusion when reviewing unbuild operations.
Original PR description
When creating a unbuild order for non storable product, it will generate two stock.move.line going form Stock>Production. ** Steps to reproduce ** - Create an untracked product (is_storable = False).…
When creating a unbuild order for non storable product, it will generate two stock.move.line going form Stock>Production.
** Steps to reproduce **
- Create an untracked product (is_storable = False).
- Create a BOM (the components don't matter).
- Create a manufacturing order & produce it for the untracked product.
- Unbuild the manufacturing order.
- Manufacturing Order> Unbuilds>(Select the Unbuild (UB/...))>Product Moves
- Two move lines are created from stock to production for the untracked product when only one should have been created.
** Cause of the issue **
Clicking on unbuild, will launch a call of the action_unbuild method. During this call,
the moves of the unbuild for the final product of the MO are created and confirmed here:
https://github.com/odoo/odoo/blob/7dd7351d492babdfb7c671960c5e90755fbc2233/addons/mrp/models/mrp_unbuild.py#L181-L182
During this confirmation process and since the product is not storable, (hence move should by pass reservation) therse moves will be assigned and the related move line created:
https://github.com/odoo/odoo/blob/e4d9ef3f39bd62a8db6854270b4cf6a35936b8d4/addons/stock/models/stock_move.py#L1759-L1762
https://github.com/odoo/odoo/blob/7dd7351d492babdfb7c671960c5e90755fbc2233/addons/stock/models/stock_move.py#L1581-L1583
However, in the rest of the action_unbuild call, since we don't expect the move to be assigned by the action_confirm we create and associate manually a second move line to our unbuild move:
https://github.com/odoo/odoo/blob/de2216ae52cee40d0851b4b8c0b71cb7e1d5ec89/addons/mrp/models/mrp_unbuild.py#L196-L198
** Observation **
During this commit
https://github.com/odoo/odoo/commit/7dda6bb92715ea25b2818a62fec5e646f3678b81#diff-31912cb536cbf184f8f475ccdfb5e42c30796a3f0430eea35751519434a67ba8L156
An "if condition" was removed that allowed untracked product to skip the manual assignation ("consu" product are untracked), since they already been assigned during consume_move._action_confirm().
This fix reintroduce the condition, for all move with their quantity (1) updated.
Which resolve the issue for non stored product since their quantity is updated during _action_confirmation>_action_assign
(1) https://github.com/odoo/odoo/commit/7dda6bb92715ea25b2818a62fec5e646f3678b81#diff-55c6314416a6a400da6acd5018d161a55eeeb0e3008fec8828121e3dd12be0ebR325
opw-4830965
Forward-Port-Of: odoo/odoo#213305Invoices created for a child contact now use the invoice sending method configured on the parent company contact. This prevents invoices from being sent by email when the customer is set up to receive them through Peppol, improving billing accuracy for grouped customer contacts.
Original PR description
**Steps to reproduce** - Have a partner with Invoice Sending configured 'by Peppol' - Create a child contact for that partner - Make 2 invoices for the child contact - Select both and click 'Send' **Issue** The system will try to send invoice by mail, even if Peppol is correctly setup This occurs because when retrieving the default sending method we only look at the partner of the move, that, being a child contact, does not have invoicing info opw-4925876 Forward-Port-Of: odoo/odoo#225725 Forward-Port-Of: odoo/odoo#225097
Kiosk ordering now only shows online payment methods that have been configured for that kiosk. This prevents customers from choosing unsupported payment options that could mark an order as paid without properly progressing it through preparation workflows.
Original PR description
Currently, you are able to see online payment methods in the kiosk if you have at least a terminal method registered. Since you're able to see them you can also select it. Once paid you are…
Currently, you are able to see online payment methods in the kiosk if you have at least a terminal method registered. Since you're able to see them you can also select it. Once paid you are redirected to the confirmation screen saying that the order is being prepared but the order is not sent to the preparation display, although the order is paid in the backend. Steps to reproduce: ------------------- * Create a payent method using terminal, for easier setup use stripe, you'll only need to setup serial number on the payment method but you do not need to do the whole stripe setup * Create an online payment method (use demo for example) * Change the kiosk settings to use those two payment methods * Change the settings of the preparation display to use the kiosk * Open preparation display * Open kiosk, make on order, and select the online payment method * Scan QR code and pay > You are redirected to the confirmation page saying that the order is being prepared while not sent to the preparation display Why the fix: ------------ The fix to send the order to the backend is in the other part of this fix. Here we decide to only allow to use the online payment methods that have been set on the config. Previously if two were existing but only one setup you were able to select any of them. We also make a change to the `filterPaymentMethods` method. This method is called when pressing the pay button and is indirectly responsible for the fact that if there's only one payment method then we directly start the payment process. Prior to this fix if we only had a terminal method setup and clicked to pay an order we directly had the screen telling us to follow the instructions on the terminal. However if we only had a online payment method, when clicking on pay, we would directly have the screen prompting us to pay at the register, we could never select the payment method. With the fix, when there's only one payment method and it's online, clicking on pay will show the qr code. opw-5001998 Enterprise: https://github.com/odoo/enterprise/pull/92825 Forward-Port-Of: odoo/odoo#224755 Forward-Port-Of: odoo/odoo#223689
When receipt items are moved into a new wave or picking, their related quality checks now move with them or are recreated for the correct transfer. This prevents staff from missing required quality checks on the new transfer or completing them from the wrong receipt.
Original PR description
*{quality_control,stock}_picking_batch ### Steps to reproduce: - Got to Quality > Quality control > Control Point - Create a quality control point: - Operation: receipt - Control per quantity or…
*{quality_control,stock}_picking_batch
### Steps to reproduce:
- Got to Quality > Quality control > Control Point
- Create a quality control point:
- Operation: receipt
- Control per quantity or product
- Create a and confirm a receipt transfer with 2 products
- Go to the receipt list view > select your receipt > Wheel action > Add to wave > Add to a new wave > Add only one of the move line to the wave
#### > A new picking is created and the move line reassigned to it but the related quality check picking_id is not updated.
> In particular, there is no "quality check" button on the new picking and the "quality check" button of the first picking allows you to process a QC related to the wave transfer.
### Cause of the issue:
While the move lines or move are can be moved to a new picking during the `_add_to_wave` call:
https://github.com/odoo/odoo/blob/605e47a85561614c17fe2e6f59618610f87c69bb/addons/stock_picking_batch/models/stock_move_line.py#L69-L90 Nothing is done with respect to the quality check which pciking_id field is not computed:
https://github.com/odoo/enterprise/blob/d73f7ef6fe61ccddbe1fe4e32c1670611ba3c5d2/quality/models/quality.py#L185
### Fix:
While the quality check measured on move_line are linked to a move line, the quality checks measured on products and operation are not. For the first kind, we rely on an override of the write method of stock move lines to reassign the check to the apporpiate picking. For the other kinds, we add a post batch hook to unlink the obsolete checks and recreate the appropiate one. Note that since operation and product types are created during the action confirm of moves and since certain moves will be created and auto confirm during the new picking creation here: https://github.com/odoo/odoo/blob/73fd3af560c967f41339bfc4c71a51dc5baba4a8/addons/stock_picking_batch/models/stock_move_line.py#L90 https://github.com/odoo/odoo/blob/73fd3af560c967f41339bfc4c71a51dc5baba4a8/addons/stock/models/stock_picking.py#L857 https://github.com/odoo/odoo/blob/73fd3af560c967f41339bfc4c71a51dc5baba4a8/addons/stock/models/stock_picking.py#L1263-L1267 https://github.com/odoo/enterprise/blob/b99d7073a34b24d4d3b863278e68f292fdd3c0b0/quality_control/models/stock_move.py#L12-L15 we rely on the `extra_move_mode` to avoid quality check creation during this step (as they will be created in the hook).
Enterprise: https://github.com/odoo/enterprise/pull/92951
opw-5009635
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#224947
Forward-Port-Of: odoo/odoo#223852The Print button on purchase orders now chooses the correct document based on the order status. Confirmed orders print the Purchase Order report instead of the earlier RFQ document, reducing confusion and helping users send the right paperwork.
Original PR description
Before this commit: ------------------------- - The 'Print' button in the Purchase Order form always triggered the RFQ report, regardless of the order state. - This caused confusion for users…
Before this commit: ------------------------- - The 'Print' button in the Purchase Order form always triggered the RFQ report, regardless of the order state. - This caused confusion for users expecting the Purchase Order report when the order was already confirmed. Steps to reproduce: ------------------------- 1. Install 'purhcase' module. 2. Confirm a purchase order (move it to the 'Purchase Order' state). 3. Click on 'Print' button . 4. Notice that the RFQ report is printed instead of the PO report. Cause of the issue ------------------------- - The print button was hardcoded to always prints the RFQ report—even for confirmed purchase orders. After this commit: ----------------------- - The system now prints the Purchase Order report when the order is confirmed. - The Print button behavior dynamically changes based on the order state - This improves user experience by ensuring the correct document is printed according to the current state of the order. Task Id: 4905350 Forward-Port-Of: odoo/odoo#221148
Installing the Peru electronic invoicing module is now more reliable on large databases. The change reduces memory usage during setup and avoids an installation error related to tax group updates, helping businesses complete upgrades or deployments without interruption.
Original PR description
### [PERF] l10n_pe_edi: Avoid OOM during installation ### Description: Installing `l10n_pe_edi` on large databases with many moves and move lines could cause out-of-memory (OOM) errors. This happens…
### [PERF] l10n_pe_edi: Avoid OOM during installation ### Description: Installing `l10n_pe_edi` on large databases with many moves and move lines could cause out-of-memory (OOM) errors. This happens because several stored fields need to be computed at installation. ### Fix: This fix adds the columns via SQL, preventing Odoo from computing and populating the field for all existing records. This reduces memory usage and avoids installation failures. ____ ### [FIX] l10n_pe_edi: Fix error during post-init hook ### Description: During installation, the `l10n_pe_edi` module's post-init hook attempts to update tax groups, setting the new `l10n_pe_edi_code` field. This can cause an error if a tax group doesn't exist and needs to be created, because the name field is missing in the list of values given to the `_load_records` function. ### Fix: This fix filters the tax groups to only update existing ones. This prevents `_load_records` from trying to create new groups, which avoids the installation error. ___ ### Reference: opw-4982181 Forward-Port-Of: odoo/enterprise#91997
When receipt items are moved into a new wave transfer, their related quality checks now move with them or are recreated on the correct transfer. This ensures staff see and process quality checks from the right receipt, avoiding missed or misplaced inspections.
Original PR description
*{quality_control,stock}_picking_batch ### Steps to reproduce: - Got to Quality > Quality control > Control Point - Create a quality control point: - Operation: receipt - Control per quantity or…
*{quality_control,stock}_picking_batch
### Steps to reproduce:
- Got to Quality > Quality control > Control Point
- Create a quality control point:
- Operation: receipt
- Control per quantity or product
- Create a and confirm a receipt transfer with 2 products
- Go to the receipt list view > select your receipt > Wheel action > Add to wave > Add to a new wave > Add only one of the move line to the wave
#### > A new picking is created and the move line reassigned to it but the related quality check picking_id is not updated.
> In particular, there is no "quality check" button on the new picking and the "quality check" button of the first picking allows you to process a QC related to the wave transfer.
### Cause of the issue:
While the move lines or move are can be moved to a new picking during the `_add_to_wave` call:
https://github.com/odoo/odoo/blob/605e47a85561614c17fe2e6f59618610f87c69bb/addons/stock_picking_batch/models/stock_move_line.py#L69-L90 Nothing is done with respect to the quality check which pciking_id field is not computed:
https://github.com/odoo/enterprise/blob/d73f7ef6fe61ccddbe1fe4e32c1670611ba3c5d2/quality/models/quality.py#L185
### Fix:
While the quality check measured on move_line are linked to a move line, the quality checks measured on products and operation are not. For the first kind, we rely on an override of the write method of stock move lines to reassign the check to the apporpiate picking. For the other kinds, we add a post batch hook to unlink the obsolete checks and recreate the appropiate one. Note that since operation and product types are created during the action confirm of moves and since certain moves will be created and auto confirm during the new picking creation here: https://github.com/odoo/odoo/blob/73fd3af560c967f41339bfc4c71a51dc5baba4a8/addons/stock_picking_batch/models/stock_move_line.py#L90 https://github.com/odoo/odoo/blob/73fd3af560c967f41339bfc4c71a51dc5baba4a8/addons/stock/models/stock_picking.py#L857 https://github.com/odoo/odoo/blob/73fd3af560c967f41339bfc4c71a51dc5baba4a8/addons/stock/models/stock_picking.py#L1263-L1267 https://github.com/odoo/enterprise/blob/b99d7073a34b24d4d3b863278e68f292fdd3c0b0/quality_control/models/stock_move.py#L12-L15 we rely on the `extra_move_mode` to avoid quality check creation during this step (as they will be created in the hook).
Community: https://github.com/odoo/odoo/pull/223852
opw-5009635
Forward-Port-Of: odoo/enterprise#93605
Forward-Port-Of: odoo/enterprise#92951Fixed an issue where opening an embedded list view from a Knowledge article could accidentally save hidden view settings and later cause an error when editing the article. Users can now return to and edit articles with embedded list views without interruption.
Original PR description
Steps to reproduce =================== 1. Insert any list view in the knowledge article. 2. Click on open view from the article. 3. Come back and click edit. -> Traceback occurs Technical…
Steps to reproduce =================== 1. Insert any list view in the knowledge article. 2. Click on open view from the article. 3. Come back and click edit. -> Traceback occurs Technical ============= When we open a view from an embedded view in the article, we add `orderBy` from the action context to the action props if it exists. As the action prop is initialized and assigned directly from `embeddedState.additionalViewProps` without copying, it mutates the original object, changing the `data-embedded-props` attribute in the DOM and marking the body of the article as unsaved from `StateManager.changeState`. The action continues, and the action service commits those unsaved changes to the article. Once it is saved and the action is executed, when we get back to the article and click on edit, we check for `additionalViewProps` to be undefined/empty for all other views except calendar. As the DOM already has saved data in attributes, we get `orderBy` in `additionalViewProps`, and thus a manual error is thrown in the `editView` function. After this commit =============== Clone `additionalViewProps` when preparing the view action props. Task-4921282 Forward-Port-Of: odoo/enterprise#91113
DHL and USPS delivery integrations now retrieve package details correctly when working from sales orders. This helps ensure accurate shipping information and reduces errors during order processing.
Original PR description
This commit fixes the same issue in #89771, but for sale orders instead of pickings. opw-4979982 Forward-Port-Of: odoo/enterprise#94186
Imported FEC accounting entries are now included when users open a sales journal from the accounting dashboard. This ensures sales-related imported entries are visible in the expected journal view, reducing confusion and missing-record concerns after imports.
Original PR description
**PROBLEM** When importing a FEC files, moves are created with the `move_type` `entry`. They don't appear in the action of the journal of type `sale` when clicking on the dashboard. **STEP TO REPRODUCE** 1. on a local database install `l10n_fr_fec_import` (you need to import a FEC file given by our client, dont do it on the runbot please !) 2. select the french demo company 3. import the FEC file (accounting/settings/import a file) (for file, see [ticket](https://www.odoo.com/odoo/project/49/tasks/4848763) ) 4. goes in the dashboard, and click on the `Ventes Marchandises` journal. 5. notice the entries does not appear in the action. **CAUSE** When importing a FEC file, all moves are created with the `entry`. The domain for `sale` journal doesn't include the move of type `entry`. **FIX** Adding `entry` in the `sale` journal domain. opw-4848763 Forward-Port-Of: odoo/odoo#222208