Daily updates from Odoo
Wednesday, January 14, 2026
17 changes · 18.0
New functionality added to Odoo
This update ensures Argentinian users can correctly issue credit notes by adding document type 110 - CREDIT NOTE TICKET, as required by AFIP regulations. Previously, this option was missing, causing errors when creating credit notes. This change improves compliance and usability for Odoo users in Argentina.
Original PR description
**Description of the issue/feature this PR addresses:** This PR adds the AFIP document type 110 - CREDIT NOTE TICKET, which is required for the Argentinian localization **Current behavior before…
**Description of the issue/feature this PR addresses:** This PR adds the AFIP document type 110 - CREDIT NOTE TICKET, which is required for the Argentinian localization **Current behavior before PR:** When users in Argentina tried to create a credit note for a ticket, the corresponding document type was not available as an option. **Desired behavior after PR is merged:** After this change, users can now select "110 - CREDIT NOTE TICKET" to issue the document correctly. [HERE](https://app.screencastify.com/watch/fVBWwSD6DAcodKO57qUZ) is a video replicating the issue 1) In localization Argentina, check document types and see that 110 CREDIT NOTE TICKET exists 2) Create a new journal as shown in the video 3) Create an invoice selecting that journal, and (83) TICKET as Document Type 4) Confirm the invoice and try to create a credit note. See that (110) CREDIT NOTE TICKET does not appear as an option --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update introduces a new module to seamlessly sync POS receipts with the JoFotara portal in Jordan. This allows businesses to automatically generate and manage e-receipts for their Point of Sale transactions, improving accounting accuracy and customer satisfaction. The changes include new models and overrides to support UBL 2.1 invoice generation from POS orders.
Original PR description
This commit add a new module to sync receipts with JoFotara portal. task-4213323 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update allows businesses to seamlessly handle self-billed invoices – invoices created by customers for their own accounting – through the Peppol network. It enables the export, import, and automated receipt of these invoices, streamlining accounting processes and improving data verification for vendors.
Original PR description
Self-billed invoices are invoices which are created by the customer on behalf of the vendor. These can be used in certain business flows, typically when the customer needs to create an invoice…
Self-billed invoices are invoices which are created by the customer on behalf of the vendor. These can be used in certain business flows, typically when the customer needs to create an invoice internally for accounting purposes. Peppol provides the ability for customers to send self-billed invoices to the vendor over the Peppol network. This way the vendor can verify whether the invoice is correct. See the Peppol documentation at https://docs.peppol.eu/poacc/self-billing/3.0/bis-sb/ #### This PR provides (1) the ability to export vendor bills as self-billed invoices conformant to the BIS3 standard (2) the ability to import BIS3 self-billed invoices as customer invoices (3) the ability to send vendor bills as self-billed invoices over Peppol (4) the ability to receive self-billed invoices from Peppol in a specified Sales journal. #### Configuration Purchase journals now have a `Is Self Billing` boolean field. Self-billing journals have a per-partner sequence, and can send vendor bills as self-billing invoices via Peppol if the option is activated in the Peppol configuration. We also add the self-billed invoice Peppol document type IDs in the list of documents which the user can select or deselect to allow/prevent reception of those document types. Backport of https://github.com/odoo/odoo/pull/222658 Enterprise PR: https://github.com/odoo/enterprise/pull/97803 Upgrade PR: https://github.com/odoo/upgrade/pull/8886 task-5153851
Enhancements to existing features
This update enables public users to directly access documents without needing to create a user account. When a public user shares a document with a partner, the system now allows the partner to register and create a user account linked to that partner, streamlining the document sharing process. This improves usability for partners who don't want to create a full Odoo user.
Original PR description
Purpose ======= We can share a document to a partner without a user, and with `access_via_link == 'none'`. In that situation, the partner is forced to create a user, but if he clicks on signup, then the new user won't be linked to the partner set on the `documents.access` (a new partner will be created). Now, when inviting a member, if he doesn't have a user, we invite him to create a user. If the partner has a user, then we just redirect him to the login page. Task-5242208
Resolved issues and error corrections
This update resolves an issue where users could incorrectly modify attendance records. The change now prevents unauthorized updates to attendance data, ensuring data integrity and accuracy. Test coverage has been added to guarantee this fix.
Original PR description
Closes [odoo/odoo#226007](https://github.com/odoo/odoo/issues/226007). Description of the issue/feature this PR addresses: Prevents a user from updating their attendance record by changing the employee to the one whose attendance is not managed by the current user. Current behavior before PR: - Assign the Officer Group of Attendance group to a user. - Assign the user as the attendance manager of itself. - Login with that user. - Create an attendance record for the employee and save it. - Try to change the employee and save; an error will be thrown as expected. - Go to the Attendance menu; the record will still be saved. Desired behavior after PR is merged: This commit ensures that un-allowed write does not take place + test coverage added. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#226335
This update resolves an issue where scheduled notifications and other mail-related processes would fail when records were deleted. The fix ensures that notifications are skipped when a record is deleted, preventing errors and improving the user experience by avoiding misleading notifications.
Original PR description
RATIONALE When a cascade delete occurs in DB, ORM methods are not called. More specifically loosely connected records using res_model / res_id pair are not removed when unlink override exists. SPECIFICATIONS Fix various use case in mail * notifications sent for scheduled messages; * failure notifications management; * activities mark as done; Task-5138556 Forward-Port-Of: odoo/odoo#238623 Forward-Port-Of: odoo/odoo#233071
This update resolves a bug in our expense reporting feature that caused incorrect journal entries and access errors. The fix ensures the report correctly uses the relevant expense line information (AML ID and company) for accurate navigation and data display.
Original PR description
Steps to reproduce: 1. Edit the first account.move in expenses account by adding Analytic Distribution to first aml. 2. Open General Ledger & group by Analytic Plan. 3. Click "View journal Entry" for the Bill line. Before this commit: When grouping financial reports by Analytic Plans, the temporary table generation logic incorrectly prioritized `account_analytic_line` over `account_move_line` ids and companies. This caused the report to use Analytic IDs as row identifiers, leading to "Identity Theft" where clicking a row opened an unrelated Journal Item (sharing the same integer ID) or raised Access Errors due to company mismatches. After this commit: The report table now uses the aml id as intended and redirects to the expected journal entry. opw-5413138 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/enterprise#103930
This update fixes incorrect tax codes used in Odoo's account_edi_ubl module, specifically related to Bebat (battery recycling) and EPD charges. It ensures accurate reporting of recycling taxes by using the correct codes (CAV for Bebat and 64 for EPD), aligning with regulatory requirements. This improves the accuracy of financial reporting for these specific transactions.
Original PR description
[FIX] account_edi_ubl_cii: EPD allowance/charge code should be 64, not 66 64 stands for "Special agreement" 66 stands for "New outlet discount" opw-5478324 [FIX] account_edi_ubl_cii: Bebat allowanceChargeReasonCode should be CAV Bebat is a non-profit organization in Belgium that collects, sorts, and recycles used batteries. Currently, whatever the recycling tax applied, we report is as AEO for "Collection and recycling - The service of collection and recycling products." However, since Bebat is about recycling batteries, we have to use CAV instead for "Battery collection and recycling - The service of collecting and recycling batteries." opw-5474752 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update fixes an error in how price differences are calculated for subcontracted products. Previously, the system incorrectly compared costs in different currencies, leading to inaccurate price difference invoices. Now, the system converts component costs to the invoice currency, ensuring accurate price difference calculations and preventing erroneous invoice lines.
Original PR description
Problem: When computing the price difference on a vendor bill for a subcontracted product, the component cost is considered in the company's currency regardless of the currency of the invoice. This…
Problem: When computing the price difference on a vendor bill for a subcontracted product, the component cost is considered in the company's currency regardless of the currency of the invoice. This means the price difference calculation directly compares two different currencies without converting them, resulting in some incorrect values for the price difference invoice lines. Solution: We will convert the component cost to the invoice currency when computing price difference. Steps to reproduce (runbot 18): - Product with - Standard price auto - BoM: sbc, one component with nonzero value (e.g. $1) - Nonzero value (e.g. $5) - Another currency 1. Create a PO for the subcontracted product 2. Set the Invoice currency to something other than the company default 3. Confirm the PO and validate the sbc and receipt 4. Create the vendor bill, and bill for the correct value (Whatever $4 is in the invoice currency) A price difference line will be erroneously generated for some nonsense value, when we expect 0 price difference. opw-5232917
This update fixes a discrepancy in eWaybill invoices for India by including reverse charge (RC) amounts in the total invoice value. Previously, the eWaybill data didn't align with Odoo and the Indian government's system. This change ensures accurate reporting and compliance with GST regulations.
Original PR description
For export invoices, the total invoice value in the eWaybill JSON did not include reverse charge amounts for GST, leading to a mismatch with the value shown in Odoo and the eWaybill generated by the Indian government system. This commit adjusts the JSON computation to include the reverse charge amounts in the total invoice value for exports, aligning it with the government-generated eWaybill, while preserving the existing reverse charge flow. task-5068199
This update resolves a validation error that occurred when creating partial backorders within wave transfers. The issue stemmed from the system incorrectly processing ongoing batches, leading to a user error. This fix ensures that wave transfers are correctly validated, preventing disruptions in the stock management process.
Original PR description
## How to reproduce: - Enable Wave transfert in setting - Go to the Receipt Operation type: - Create Backorder: always - Automatic Batches: Enabled - Wave Grouping: Products - Create and confirm…
## How to reproduce:
- Enable Wave transfert in setting
- Go to the Receipt Operation type:
- Create Backorder: always
- Automatic Batches: Enabled
- Wave Grouping: Products
- Create and confirm (don't validate) 2 Receipts for 10 units of a storable product P
- The 2 receipt should have been added to a new wave transfer with 2 lines for P
- On the first line, set the quantity to 0
- On the second line, set the quantity to 1
- Try to validate the wave transfer ==>> UserError "The following transfers cannot be added to batch transfer WAVE/XXXX. Please check their states and operation types."
## Issue:
Backorders are generated before the current batch is marked 'done' (it waits for empty pickings to be detached). The auto-batch logic incorrectly identifies the current 'in_progress' batch as a candidate for the new backorders, attempting a merge that violates validation constraints.
## Solution:
Exclude the current wave/batch from the auto_wave search domain using a context variable passed during validation.
OPW-5413921
---
Test result before fix:
```
2026-01-13 10:37:26,541 27952 INFO oes_test_18.0 odoo.addons.stock_picking_batch.tests.test_auto_waving: Starting TestAutoWaving.test_auto_wave_skip_current_batch ...
2026-01-13 10:37:26,820 27952 INFO oes_test_18.0 odoo.addons.stock_picking_batch.tests.test_auto_waving: ======================================================================
2026-01-13 10:37:26,820 27952 ERROR oes_test_18.0 odoo.addons.stock_picking_batch.tests.test_auto_waving: ERROR: TestAutoWaving.test_auto_wave_skip_current_batch
Traceback (most recent call last):
File "/home/odoo/Odoo/src/18.0/odoo/addons/stock_picking_batch/tests/test_auto_waving.py", line 440, in test_auto_wave_skip_current_batch
wave.action_done()
File "/home/odoo/Odoo/src/18.0/odoo/addons/stock_picking_batch/models/stock_picking_batch.py", line 264, in action_done
return pickings.with_context(**context).button_validate()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/Odoo/src/18.0/odoo/addons/stock_picking_batch/models/stock_picking.py", line 145, in button_validate
res = super().button_validate()
^^^^^^^^^^^^^^^^^^^^^^^^^
...
File "/home/odoo/Odoo/src/18.0/odoo/odoo/fields.py", line 1418, in __set__
records.write({self.name: write_value})
File "/home/odoo/Odoo/src/18.0/odoo/addons/stock_picking_batch/models/stock_picking.py", line 112, in write
self.batch_id._sanity_check()
File "/home/odoo/Odoo/src/18.0/odoo/addons/stock_picking_batch/models/stock_picking_batch.py", line 323, in _sanity_check
raise UserError(_(
odoo.exceptions.UserError: The following transfers cannot be added to batch transfer WAVE/00012. Please check their states and operation types.
```
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prA bug was preventing employees from taking future leave when their accrued balance was below the maximum limit. This update corrects the calculation of available leave days, ensuring employees can continue to accrue and take leave as intended. The fix ensures accurate leave allocation based on accrual plan rules.
Original PR description
Accrual plan for leave days gets blocked, even when the remaining leave balance is below the cap. As a result, no additional leaves are accrued beyond a certain point, even though they should be. #…
Accrual plan for leave days gets blocked, even when the remaining leave balance is below the cap. As a result, no additional leaves are accrued beyond a certain point, even though they should be.
# Steps to reproduce:
Go to time off app
* Create a new leave type.
* Create a new accrual plan with:
- one milestone :
- 2 days accrued per month
- Cap: 10 days
- start accruing 1 days after
- No expiration
- Carry over: All
* Create and validate a leave allocation
- 1 year ago
- new leave type
- new accrual plan
* Take the maximum number of leaves available.
* Advance the computer calendar by 1 year.
* Again, take the maximum number of leaves.
* Advance the computer calendar by another year.
* Try to take a future leave.
-> Issue: It’s not possible to take a future leave, the number of accrued days has stopped increasing. The accrual plan appears blocked.
Objective : The accrual plan should continue to allocate leave days even if leaves have been consumed regularly, as long as the remaining leaves are under the cap.
## Issue
Before going further: the property `leaves_taken` of the `hr.leave.allocation` is supposed to contain the number of leaves this allocation cover until "today".
In the `_test_get_allocation_future_leaves1` added test, in the last line of the test :
`assert_virtual_leaves_equal(self, leave_type_day, 2, self.employee_emp, date='2023-02-01')`
When calling `get_allocation_data` with a `target_date` set in the future, the result is wrong. Here is how it works :
`get_allocation_data`
...
.....`_get_consumed_leaves` (1)
...........`_get_future_leaves_on` (2)
...............`_process_accrual_plans` (3)
....................`_compute_leaves` (4)
.........................`_get_consumed_leaves` (5)
..............................`get_future_leaves_on` (6)
...................................`process_accrual_plans` (7)
**A)** The method **(2)** try to calculate the added number of days each allocation will have on `target_date`. So it creates a copy of the allocation in memory using the 'new' method:
`fake_allocation = self.env['hr.leave.allocation'].with_context(default_date_from=accrual_date).new(origin=self)`
It will then update it to `target_date` using `_process_accrual_plans` and will return the difference of days between the
updated `fake_allocation` and the current allocation (`self`)
**B)** Before iterating over each accrual date, the `_process_accrual_plans` **(3)** will get the `leaves_taken` property which is a computed field. It will trigger `_compute_leaves`.
**C)** The method **(4)** will call `_get_consumed_leaves`, and so the nightmare begins.
**D)** The method **(6)** will create a second `fake_allocation` based on the origin of the first `fake_allocation` (see **A)**).
**E)** This time, `_process_accrual_plans` **(7)** will also look at the `leaves_taken`, but won't trigger the `_compute_leaves` probably because the current allocation is a `fake_allocation` of a `fake_allocation`, and one property of the `new` method is that `Two new records with the same origin record are considered equal.`. Therefore, the `leaves_taken` is considered to be already computed (but it's not).
So `_process_accrual_plans` read the `leaves_taken` which is 0 (probably the default value of `leaves_taken`), but it should be 20 !
**F)** As the value of `leaves_taken` is wrong, the fake_allocation n°2 is also wrong, and its `number_of_day` is 10 but the `number_of_days` of the origin allocation is 20. So `get_future_leaves_on` **(6)** will return -10 which makes no sense, and all the previous calls computations will be wrong. And the final `virtual_remaining_leaves` value will be 0 instead of 2.
## Source of the issue
In the `_process_accrual_plans` method, for each allocation, `leaves_taken` is only computed once at the start of the loop over the allocation "important" dates (see `nextcall` property of `hr.leave.allocation`). At this moment, the method calculates the `leaves_taken` the allocation will have on the `accrual_date` parameter. Yet, this property can change depending on the date the allocation is on (`nextcall` property) which leads to some issues in the computation of the `allocation.number_of_days`.
## Solution
For each allocation, compute the `leaves_taken` at every iteration trough the values of `nextcall`. BUT, this can trigger an infinite loop as computing `leaves_taken` calls `_get_consumed_leaves` which calls `_get_future_leaves_on`, which calls `_process_accrual_plans` ... To avoid this, this PR add the context variable `precomputed_allocations` (will be converted into a function parameter in master) which will prevent `_get_consumed_leaves` from calling `_get_future_leaves_on` for the allocations already up to date (contained by this very `precomputed_allocations` context variable).
**For r+: Needs a few changes at 18.0 (hours per day of employee is retrieved differently for example)**
opw-4934391
opw-5226806
Forward-Port-Of: odoo/odoo#239836This update corrects a potential issue in how the system determines the period for ELM (Electronic Ledger Message) transmission in Switzerland. By using a reference date, the system now accurately locks the payroll period, ensuring correct reporting to tax authorities. This improves the reliability of financial data and reduces the risk of errors.
Original PR description
Forward-Port-Of: odoo/enterprise#104269
This update fixes an issue where products created through the website were automatically published without a category assigned. The change removes code that forced publication and now ensures products remain unpublished until a category is selected, aligning with the user's expected experience. This improves consistency and prevents accidental product listings.
Original PR description
**Description:** Products created from the website frontend were automatically published even without a category assigned, contradicting the "Unpublished" placeholder expectation. The issue had three root causes: 1. JavaScript (new_content.js) forced default_is_published: true 2. XML action context contained website_published: True 3. Both caused products to be published regardless of category **Fixed by:** - Removed default_is_published from JS product creation handler - Removed website_published from action context. **After this PR:** Now products remain unpublished until a category is assigned, matching the intended UX indicated by the placeholder text. opw-5408903 SEE ALSO: Enterprise PR:https://github.com/odoo/enterprise/pull/103778 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
A bug was preventing users from clicking the 'Validate' button after an invalid barcode scan in stock picking. This was caused by a misconfigured fix that blocked further validation attempts. This update reverts the previous fix and utilizes the framework's mutex mechanism for reliable, sequential barcode validation, ensuring accurate stock updates.
Original PR description
### Steps to reproduce: - In the settings enable: Multi-Steps route - Create a product tracked by SN - In the barcode app > Operations > Internal transfers > New - Scan you tracked product - Click on…
### Steps to reproduce: - In the settings enable: Multi-Steps route - Create a product tracked by SN - In the barcode app > Operations > Internal transfers > New - Scan you tracked product - Click on Validate > Invalid operation - Scan a Serial number #### > You can not click on validate anymore ### Cause of the issue: The issue has been introduced in 41c6e7a90fd4f0cf84e74cf0ed036f4da0ec6112 in a try to avoid concurrency issue when calling the barcode validation too quickly. To be more precise, this commit added a `isValidating` property to the barcode model that is set prior to the rpc call and suppose to remove after in order tobypass subsequence calls of the `validate` method when a call is already in progress: https://github.com/odoo/enterprise/blob/099c7b94ad08f83873c05ec528e16fbf806f47f2/stock_barcode/static/src/models/barcode_model.js#L477-L494 However, in the present case and since orm call returns an error, the call of the validate method is interupted at this orm call and the line https://github.com/odoo/enterprise/blob/099c7b94ad08f83873c05ec528e16fbf806f47f2/stock_barcode/static/src/models/barcode_model.js#L494 is not executed so that the this.Validating stays true and the button can not be clicked nor executed anymore: https://github.com/odoo/enterprise/blob/099c7b94ad08f83873c05ec528e16fbf806f47f2/stock_barcode/static/src/models/barcode_model.js#L131-L133 ### Fix: We revert the incorrect fix: 42d77e751cb5e049ea1e81b44fca0d07e8f45b32 and we rather rely on the Mutex class of the JS framework just as done in the `_processBarcode`: https://github.com/odoo/enterprise/blob/099c7b94ad08f83873c05ec528e16fbf806f47f2/stock_barcode/static/src/models/barcode_model.js#L505-L507 This will ensure that the validation calls will be processed sequentially and since the `button_validate` of stock pickings is ignored on done pickings because of the first soft fix https://github.com/odoo/odoo/pull/204790 : https://github.com/odoo/odoo/blob/1664daf894ec878b64af8ab75c0d10f05e00df80/addons/stock/models/stock_picking.py#L1134-L1135 we have the guarantee that the records will not be validated twice. ### Note: We had to also adapt this line in 18.0+: https://github.com/odoo/enterprise/blob/e04ecb45cc99f74e9956a0c1e669bb2c05816fde/stock_barcode/static/src/models/barcode_picking_model.js#L921-L925 Since the wrapper is equivalent to itself while `super.validate()` calls the `_validate` of the `BarcodeModel` and not of the `BarcodePickingModel` and since we need to bypass the regular validate call to avoid an infinite loop: https://github.com/odoo/enterprise/blob/6b0585d2776392c32b190f6e77761d805da49802/stock_barcode/static/src/models/barcode_picking_model.js#L931-L935 opw-5388297 Forward-Port-Of: odoo/enterprise#103835
This update corrects a previous issue where all fixed taxes were incorrectly converted to allowance charges during UBL exports. Now, fixed taxes that don't affect the tax base (like 'recupel') are properly represented as separate invoice lines, aligning with the changes introduced in Odoo v18+. This ensures accurate tax reporting for UBL invoices.
Original PR description
Context : In v18+, fixed taxes are handled differently depending on whether they affect the tax base or not. Before this commit : All fixed taxes were systematically converted into allowance charges during UBL exports. This behaviour was incorrect, as some fixed taxes (e.g., recupel) do not affect the tax base and should instead be represented as separate invoice lines. This commit aligns the v17 behavior with the logic introduced in v18+ by distinguishing between the two cases: - Fixed taxes that affect the base are converted into allowance charges. - Fixed taxes that do not affect the base are converted into additional invoice lines. task-5405115 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#240706
This update automatically corrects discrepancies between check amounts and payment amounts when using third-party checks for vendor payments. Previously, users had to manually adjust payment amounts, leading to errors and delays. This change ensures accurate accounting and eliminates the need for manual intervention.
Original PR description
Current behavior: when using third-party checks to create vendor payments, withholding amounts are creating a difference between the checks amount and the payment amount, resulting in a warning and requiring manual adjustment of the payment amount until the amount minus withholdings matches checks amount. Solution: adding an automated adjustment algorithm to the wizard. task-4257629 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr