Daily updates from Odoo
Monday, March 16, 2026
12 changes · 18.0
New functionality added to Odoo
This update adds the capability to generate UBL (Universal Business Language) invoices from Point of Sale (PoS) orders. This allows businesses to comply with specific tax regulations and reporting requirements for electronic invoices, particularly in countries like Colombia. The changes include new templates and logic to create UBL files from PoS transactions, streamlining the invoicing process.
Original PR description
task: 4038651
This update enables direct electronic invoicing for POS sales and returns in Colombia, streamlining the process for businesses. It adapts existing DIAN EDI functionality to work with POS data, eliminating the need to manage invoices in the Accounting App. A key feature is sharing a single DIAN sequence, optimizing costs for businesses.
Original PR description
In Colombia, all POS Sales/Returns must be supported by an Electronic Document. Currently, the only way to connect the DIAN EDI and POS flows is to manage invoices directly in the Accounting App.…
In Colombia, all POS Sales/Returns must be supported by an Electronic Document. Currently, the only way to connect the DIAN EDI and POS flows is to manage invoices directly in the Accounting App. This pr adds the possibility to generate and send the electronic documents directly to DIAN without leaving the POS store. This pr will not create intermediate invoices/credit notes that are supposed to be sent to DIAN, instead we adapted the already existing ubl-generation implementation (in `l10n_co_dian`) to be able to generate the correct files using data from `pos.order` models (implementation can be found in `models/account_edi_xml_ubl_dian.py`). During this process we created some 'common' functions that generate data for the ubl file independent of what model is used (`account.move` or `pos.order`), these common functions are a first step for the future refactoring of the ubl models. An important thing to note here is that the common functions are only used for the pos orders, generating documents for invoices is still done using the original implementation. Another important feature of this implementation is the possibility to share a single sequence, defined on the journal, between pos orders and account moves. This was implemented because in Colombia (and other latam countries) the sequence gets assigned to a company by the government, and can therefore be expensive. Important to note is that sharing a sequence is only possible if the company has never sent documents to DIAN before (~ no existing edi documents). task-4038651
Resolved issues and error corrections
This update fixes an issue where consolidated POS invoices were incorrectly showing a zero payable amount due to pre-payment mapping. To comply with MyInvois requirements, the update now ensures the Total Amount Payable accurately reflects the invoice's total amount, regardless of prior payments. This ensures proper data transmission to the MyInvois tax officer.
Original PR description
For POS consolidated invoices, the PrePayment Amount was mapped to the payment linked to the document. This incorrectly decreased the Total Amount Payable to 0, since POS orders are already paid at the counter. MyInvois tax officer and helpdesk requires that the Total Amount Payable (cbc:PayableAmount) to reflect the total amount of the issued e-document , regardless of prior payments. This commit forces the PaidAmount to 0 for consolidated documents, ensuring the PayableAmount correctly matches the TaxInclusiveAmount as expected by the MyInvois API. task-[6021698](https://www.odoo.com/odoo/all-tasks/6021698)
This update resolves errors in the Guatemalan e-invoicing system (l10n_gt_edi) related to 'Timbre de prensa' taxes. The fix ensures that the tax amount is correctly calculated and formatted when sending invoices to the SAT, preventing reporting issues.
Original PR description
**Steps to reproduce:** - Install accountant and l10n_gt_edi - Switch to a Guatemalan company (e.g. GT Company) - In Accounting settings, set "Web Services" of Guatemala Localization to "Test" or…
**Steps to reproduce:**
- Install accountant and l10n_gt_edi
- Switch to a Guatemalan company (e.g. GT Company)
- In Accounting settings, set "Web Services" of Guatemala Localization to "Test" or "Production" ("Demo" mode doesn't trigger any error)
- Set "Infile Credentials" (real credentials are required)
- Create a "Timbre de prensa" tax:
* Tax Name: [anything]
* Tax Computation: Percentage
* Amount: 0.5000 %
* Included in Price: Tax Excluded
* GT Taxable Unit Code: 1
* GT Tax Short Name: TIMBRE DE PRENSA
- Create an invoice:
* Customer: [a Guatemalan customer] (e.g. Empresa Guatemalteca S. A.)
* GT Document Type: FACT - Factura Electrónica
* Invoice Lines:
- Taxes: [the default 12% IVA tax (incl) and "Timbre de prensa" (excl)]
- Confirm the invoice
- Send the invoice to SAT
**Issue:**
Several errors are returned by the SAT service:
- "FEL-GUI-24 | 2.7 | 2.7.1 | No. 2 | Error - Monto Gravable calculado incorrectamente para el impuesto [IVA]. Cod. Unidad Gravable [1] (Detalle linea No. 1)."
- "FEL-GUI-37 | 2.11 | 2.11.1 | No. 2 | Error - Monto Gravable calculado incorrectamente para el impuesto [TIMBRE DE PRENSA]. (Detalle linea No. 1)."
**Cause 1:**
In the XML sent to the SAT, the amount of the "Timbre de prensa" is included in the unit price, but it should not.
**Cause 2:**
Depending on the sequence of the taxes, the "Timbre de prensa" tax can be declared before the IVA tax in the XML, which seems to also raise this error.
**Solution 1:**
If there is a "Timbre de prensa" tax, its amount is excluded from the gross unit price that is computed.
**Solution 2:**
Order the IVA taxes first.
opw-5208714This update resolves an issue preventing users from creating valid batch payments to US contacts. The fix ensures the necessary ABA routing number is included in the generated XML files, which is required for successful payment processing. This improves compatibility with US banking systems.
Original PR description
**PROBLEM** Users can't create a valid batch payment to US contacts. The ABA routing number is not included in the created xml. **STEP TO REPRODUCE** 1. Create a us contact, setting up its bank account with an ABA number. 2. Create a batch payment to this contact. 3. Open the xml, and notice it doesn't include the ABA number (should be included in <ClrSySMmbId><MmbId>. this fix backport https://github.com/odoo/enterprise/pull/90378 opw-5727613
This update fixes an issue where night shift slots (e.g., 20PM - 4AM) weren't correctly displayed in the weekly planning view. The change adjusts how the system interprets multi-day slots, ensuring all scheduled shifts, including those outside standard hours, are accurately shown. This improves the usability of the planning tool for employees with flexible schedules.
Original PR description
**Steps to reproduce** 1. Have an employee using a flexible schedule 2. Create a slot from e.g. 20PM to 4AM for this employee. Make sure this is the only slot that week for the employee. 3. Publish…
**Steps to reproduce** 1. Have an employee using a flexible schedule 2. Create a slot from e.g. 20PM to 4AM for this employee. Make sure this is the only slot that week for the employee. 3. Publish the Schedule and send it to the employee. Open the outgoing mail to access the link to the planning view. Issue: the slot is not visible in the week view. **Cause** https://github.com/odoo/enterprise/blob/04a885dbb6eed96297cb5ce9a155ebf8e169427c/planning/controllers/main.py#L193-L194 The `event_hour_min` and `event_hour_max` returned by `planning_get` and used to control the min/max hours displayed in the week view, didn't account for slots over multiple days. For a slot between 20pm and 4am, the `event_hour_max` should be the end of the day, and the `event_hour_min` should be the start of the day. **Solution** - we change the `event_hour_min` and `event_hour_max` for multi-day slots to display the full days in the week view - the previous point has the drawback of displaying the full days for non-flexible employees even when not necessary. This is because `slots_start_datetime` and `slots_end_datetime` contained the `planning.slot` start and end. Instead, we can look at the actual slot values displayed (by `_get_slots_vals`). For example, a 5 day slot for a non-flexible employee may contain actual slot values corresponding to a typical 8-17 working day. opw-5245985
This update fixes an issue where the Field Service onboarding tour would stop after redirects within the portal. The change ensures the tour state is preserved in the user's session, allowing the tour to resume seamlessly when returning to the Field Service app. This enhances the user experience for new Field Service users.
Original PR description
**Steps to reproduce:**
1. Go to Field Service app.
2. Check the worksheet template in settings and start the onboarding tour
of Field Service.
**Issue:**
The backend tour is not resuming on the frontend side.
**Fix:**
This commit ensures the tour is enabled and the current tour is added to the frontend session. When the tour resumes, it will fetch the tour enabled and current tour details from the session.
**Technical:**
In the tour service, the tour resumes only if the mode is set to "auto" or toursEnabled is present in the session. To handle this, we added the tour details to the session.
tour_service.js
``` js
if (tourState.getCurrentConfig().mode === "auto" || toursEnabled) {
resumeTour();
}
````
task-4489657This update fixes an issue where multiple email addresses associated with a contact were being overwritten when creating a helpdesk ticket. The change ensures that all email addresses linked to a contact are correctly captured, improving the reliability of ticket creation and communication. This resolves a potential data loss scenario.
Original PR description
Prerequisites: ------------------------------ 1. Set up incoming mail server with Create a New Record set to Helpdesk Ticket 2. From Settings, create one Alias Domain Steps to reproduce:…
Prerequisites: ------------------------------ 1. Set up incoming mail server with Create a New Record set to Helpdesk Ticket 2. From Settings, create one Alias Domain Steps to reproduce: ------------------------------ 1. Install Helpdesk module 2. Open Helpdesk Team > Settings 3. Inside Channels, Set the mail used for the incoming server and the alias created 4. Set Accept Emails From to Everyone 5. Create a new contact with multiple emails (eg: `a@b.com`, `c@d.com`) 6. From Fiest mail (eg: `a@b.com`), Send one mail to mail set in the helpdesk team alias mail. 7. Open Incoming mail sever > Click on Fetch Now 8. Open Created Contact Observation: ------------------------------ The contact's email field is overwritten. The second email address (e.g. `c@d.com`) is lost Issue: ------------------------------ After `create`, since `partner_email` was stored with a value that differs from `partner_id.email`, the inverse method `_inverse_partner_email` kicks in. This is where `_get_partner_email_update()` is called. In `_get_partner_email_update()` `tools.email_normalize()` only handles a single email. When the partner has multiple email, the normalization keeps both, while the ticket email normalizes to just have one mail. The strict `!=` comparison fails, triggering the unwanted update. https://github.com/odoo/enterprise/blob/7c23efafe368787c858db31cec075f642ae6715b/helpdesk/models/helpdesk_ticket.py#L363-L369 Solution: ------------------------------ Instead of comparing the full normalized strings, we should check whether the ticket's normalized email is contained within the set of the partner's normalized emails Note for reviewer ----------------------------- After discussion with the PO (LNA), his opinion is that having multiple email addresses in a single field is not a good practice. This use case is only semi-supported in Odoo, it may work in some cases, but it is not reliable. The recommended approach is to create separate contacts for each email address. That said, we should also avoid automatically clearing or altering the existing value in the field. Based on this, I have implemented a minimal fix that prevents altering the existing value in the field. I am leaving it up to the review to decide whether this fix is worth keeping from a technical standpoint. opw-5478067
This update fixes an issue where the cost of kits was incorrectly calculated in sales orders. Previously, when a kit contained multiple components, the cost was multiplied by the batch size, leading to inaccurate pricing. This change ensures the correct cost is applied, resolving a discrepancy between expected and actual costs.
Original PR description
### Issue: When a kit BoM has `product_qty` > 1 (e.g. 12 Kit X = 12 Comp A + 12 Comp B), the SO line cost after confirmation is multiplied by the batch size. Selling 1 Kit X shows a cost of 360…
### Issue: When a kit BoM has `product_qty` > 1 (e.g. 12 Kit X = 12 Comp A + 12 Comp B), the SO line cost after confirmation is multiplied by the batch size. Selling 1 Kit X shows a cost of 360 instead of 30. ### Cause: The method `_compute_average_price` uses `bom.explode(self, 1)`, which returns raw BoM line quantities for one full batch. It accumulates the total batch cost but returns it without dividing by `bom.product_qty`. ### Steps to Reproduce: - Costing Method = AVCO, Inventory Valuation = Automated - Comp A (cost 10), Comp B (cost 20), Kit X (cost 0) - Kit BoM: 12 Kit X = 12 x Comp A + 12 x Comp B - Create and confirm a SO for 1 x Kit X - Expected SO line cost: 30 - Actual SO line cost: 360 Solution: This fix mirrors the normalization already done in `_compute_bom_price`, which correctly divides by `bom.product_qty` and converts UoMs. opw-5969310 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#253406
This update fixes an issue where manually adjusted lot quantities during manufacturing order production weren't accurately reflected. The change ensures that the specified quantity on the move line is correctly consumed from the lot, preventing discrepancies in stock levels. This improves the reliability of production tracking.
Original PR description
**Issue** Lots manually indicated on stock move lines can be overridden when producing a Manufacturing Order. **Steps to reproduce** - Create a storable product P tracked by lot - Create two lots for…
**Issue** Lots manually indicated on stock move lines can be overridden when producing a Manufacturing Order. **Steps to reproduce** - Create a storable product P tracked by lot - Create two lots for product P with 2 units each - Create a MO for a product consuming two units P and confirm it - On the raw move, manually set 1 unit for each lot - Click on "Produce All" - Check the move line associated to the product P -> 2 units associated to the first lot consumed instead of 1 unit each **Cause** While producing: https://github.com/odoo/odoo/blob/0fe2023dc57b6cc02bd399d3c8fc5d6c8ed6e833/addons/mrp/models/mrp_production.py#L2109-L2110 It sets the quantities: https://github.com/odoo/odoo/blob/0fe2023dc57b6cc02bd399d3c8fc5d6c8ed6e833/addons/mrp/models/mrp_production.py#L2246 This calls `_set_quantity_done_prepare_vals` with a qty of 2: https://github.com/odoo/odoo/blob/0fe2023dc57b6cc02bd399d3c8fc5d6c8ed6e833/addons/stock/models/stock_move.py#L2264 which will, for each move line: - Take the quantity indicated by move line: https://github.com/odoo/odoo/blob/0fe2023dc57b6cc02bd399d3c8fc5d6c8ed6e833/addons/stock/models/stock_move.py#L2274 https://github.com/odoo/odoo/blob/0fe2023dc57b6cc02bd399d3c8fc5d6c8ed6e833/addons/stock/models/stock_move.py#L2296-L2297 - Then take all the available quantity left for the lot associated to the move line: https://github.com/odoo/odoo/blob/0fe2023dc57b6cc02bd399d3c8fc5d6c8ed6e833/addons/stock/models/stock_move.py#L2302-L2309 https://github.com/odoo/odoo/blob/0fe2023dc57b6cc02bd399d3c8fc5d6c8ed6e833/addons/stock/models/stock_move.py#L2326-L2327 Instead of first taking all the quantity indicated by the move line, before checking available quantity **Solution** Assume that move lines being created in mrp without changing the producing quantity are manually created opw-[5946439](https://www.odoo.com/web#id=5946439&view_type=form&model=project.task)
This update fixes an issue where manually adjusted lot quantities during manufacturing order production were not accurately reflected. The change ensures that the specified lot quantity is correctly consumed first, resolving discrepancies in product tracking. This improves the reliability of inventory management within the manufacturing process.
Original PR description
**Issue** Lots manually indicated on stock move lines can be overridden when producing a Manufacturing Order. **Steps to reproduce** - Create a storable product P tracked by lot - Create two lots for…
**Issue** Lots manually indicated on stock move lines can be overridden when producing a Manufacturing Order. **Steps to reproduce** - Create a storable product P tracked by lot - Create two lots for product P with 2 units each - Create a MO for a product consuming two units P and confirm it - On the raw move, manually set 1 unit for each lot - Click on "Produce All" - Check the move line associated to the product P -> 2 units associated to the first lot consumed instead of 1 unit each **Cause** While producing: https://github.com/odoo/odoo/blob/0fe2023dc57b6cc02bd399d3c8fc5d6c8ed6e833/addons/mrp/models/mrp_production.py#L2109-L2110 It sets the quantities: https://github.com/odoo/odoo/blob/0fe2023dc57b6cc02bd399d3c8fc5d6c8ed6e833/addons/mrp/models/mrp_production.py#L2246 This calls `_set_quantity_done_prepare_vals` with a qty of 2: https://github.com/odoo/odoo/blob/0fe2023dc57b6cc02bd399d3c8fc5d6c8ed6e833/addons/stock/models/stock_move.py#L2264 which will, for each move line: - Take the quantity indicated by move line: https://github.com/odoo/odoo/blob/0fe2023dc57b6cc02bd399d3c8fc5d6c8ed6e833/addons/stock/models/stock_move.py#L2274 https://github.com/odoo/odoo/blob/0fe2023dc57b6cc02bd399d3c8fc5d6c8ed6e833/addons/stock/models/stock_move.py#L2296-L2297 - Then take all the available quantity left for the lot associated to the move line: https://github.com/odoo/odoo/blob/0fe2023dc57b6cc02bd399d3c8fc5d6c8ed6e833/addons/stock/models/stock_move.py#L2302-L2309 https://github.com/odoo/odoo/blob/0fe2023dc57b6cc02bd399d3c8fc5d6c8ed6e833/addons/stock/models/stock_move.py#L2326-L2327 Instead of first taking all the quantity indicated by the move line, before checking available quantity **Solution** Assume that move lines being created in mrp without changing the producing quantity are manually created opw-[5946439](https://www.odoo.com/web#id=5946439&view_type=form&model=project.task)
This update resolves duplicate notification popups and a critical error preventing push notification subscriptions. By updating Firebase configurations and ensuring proper service worker setup, the system now reliably delivers push notifications across browsers, enhancing the user experience.
Original PR description
When the user sends a push notification through Social Marketing, the application displays two notification popups because: 1. The Firebase SDK automatically displays a notification popup if the…
When the user sends a push notification through Social Marketing, the application displays two notification popups because: 1. The Firebase SDK automatically displays a notification popup if the request made to Firebase includes a `notification` field. 2. Our service worker displays a notification popup when receiving a background message from Firebase. To prevent duplicate notifications, we will remove the custom event listeners in the service worker and update the request made to Firebase so that the Firebase SDK opens a notification for us. Furthermore, this PR fixes the error `Failed to execute 'subscribe' on 'PushManager': Subscription failed - no active Service Worker` occurring when the user accepts the push notifications. To fix that issue, we will: 1. Ensure that the service worker reaches the `ready` state before communicating with it. 2. Set the service worker's scope to `/` so it controls all pages on the origin, ensuring push subscriptions succeed and the worker can communicate with any page. Finally, we will use the legacy `importScripts` syntax to load Firebase dependencies because the ECMAScript module syntax is not supported for service workers in Firefox. This approach improves push notification compatibility across browsers. Task-5124645 Forward-Port-Of: odoo/enterprise#96029