Daily updates from Odoo
Monday, April 20, 2026
32 changes · saas-19.2
Enhancements to existing features
This change makes POS order updates more reliable by processing them one at a time, which helps keep order data consistent during changes like edits and removals. It also removes unnecessary ZIP and address checks on the screen, since the system now fills in default values automatically when needed.
Original PR description
In this commit: ------------------- - We have added logic to execute API calls using a mutex for order updates (such as line updates and removals). This ensures that each update is processed (sequentially), allowing us to properly track and maintain order consistency. - We removed the ZIP and address validation on the UI since the backend already assigns default values if they are missing. So, there’s no need to restrict the user on the UI. task:5941742 Forward-Port-Of: odoo/enterprise#114059 Forward-Port-Of: odoo/enterprise#108694
When users reload the chart of accounts after new taxes or tax tags are added, Odoo now shows a more helpful message that points them to the right Apps menu and localization modules. This makes it easier to understand what needs updating and reduces confusion during setup or upgrades.
Original PR description
Previously, when new taxes with new tax tags were introduced, reloading the chart of accounts would raise a generic UserError suggesting to update the localization app. This could be confusing for users, as it did not indicate which app needed to be updated. With this commit, the UserError is replaced by a RedirectWarning that guides users directly to the Apps menu with the relevant localization modules, making the resolution clearer and more user-friendly. Forward-Port-Of: odoo/odoo#259694 Forward-Port-Of: odoo/odoo#257515
Resolved issues and error corrections
This update prevents an error when incoming Chilean electronic invoices are processed without a specific LATAM purchase journal configured. It ensures the system selects a valid default journal so invoices can be created and recorded normally.
Original PR description
Currently, when receiving a DTE XML fetched by the fetchmail server, if there is no purchase journal with `l10n_latam_use_documents` enabled, an empty recordset (account.journal()) is set in the default context values. This prevents the proper computation of the field and raises an error, since the `journal_id` is mandatory on account moves. Steps to reproduce: - Ensure you have no purchase journal with `l10n_latam_use_documents` enabled - Simulate the reception of a DTE XML via the fetchmail server - Observe the error: "NotNullViolation: null value in column 'journal_id'" opw-5950116 opw-6111041 Forward-Port-Of: odoo/enterprise#112168
This change corrects how landed costs are calculated when a bill is entered in a different currency than the company’s currency. It prevents the amount from being overstated, so the landed cost now matches the intended purchase price and avoids incorrect inventory costing.
Original PR description
Issue introduced by commit daf196e365f481ffcc8b56664fa361fa9c9bbda9
Steps to reproduce:
- Enable two currencies (e.g., USD and EUR)
- Set exchange rate: 2 EUR = 1 USD
- Set current company currency to USD
- Create a service product "Landed Cost":
- Purchase tab:
- Mark as "Is a Landed Cost"
- Cost: $10
- Create a bill:
- Vendor: any vendor
- Currency: EUR
- Add 1 unit of "Landed Cost" → correctly shows 20 EUR
- Click the "Create Landed Cost" button
Expected behavior:
Landed cost should be calculated as $10
Actual behavior:
Landed cost is incorrectly calculated as $40, because the AML (Account Move Line) price subtotal is multiplied by the currency exchange rate (2) instead of dividing.
opw-6121706
opw-6121407
Opw-6124771
Opw-6123193
Forward-Port-Of: odoo/odoo#259632When users save certain website snippets as custom snippets, they will now appear both in the block list and in the inner content list when appropriate. This restores the expected behavior and makes reusable snippets easier to find and use while editing a website.
Original PR description
Steps to reproduce: 1. Go to Website > Edit mode. 2. Drag and drop a `Map` from `Inner Content` snippets. 3. Save it as a custom snippet. Current behavior: - The custom snippet is saved only as inner content and does not appear as a block in custom snippets. Expected behavior: - The snippet should be available both as a block and as inner content, consistent with behavior in `saas-18.3`. Issue: - Custom inner content snippets were systematically extracted from `snippet_custom`. As a result, snippets that can serve both purposes were only kept as inner content, preventing their usage as blocks. Solution: - Update the logic to: 1. Keep dual-purpose snippets in `snippet_custom` (block usage). 2. Also add them to `snippet_custom_content` (inner content usage). 3. Remove only inner-only snippets from the block category to avoid display issues. task-6064917 Forward-Port-Of: odoo/odoo#259588 Forward-Port-Of: odoo/odoo#256777
This change prevents database synchronization from failing with an error when the user no longer has access, when a new document arrives from a remote database, or when the remote database cannot be reached. Instead, the sync now finishes cleanly and correctly reflects any loss of access from the remote side.
Original PR description
The aim of this commit is to allow a db_user to synchronize a database without facing a Traceback. Context: - A new document has been received by a remote db and we try to synchronize it. - The current user access has been removed from the remote db. - The database is unreachable. Before this commit: In all 3 previous cases, an access error would be raised because a db_user can't write on a database. After this commit: The synchronization finish gracefully and the db_user should have lost his access if it was removed from the remote db. task-id: 6046087 Forward-Port-Of: odoo/enterprise#114129 Forward-Port-Of: odoo/enterprise#113826
This change updates the rules for creating asset entries so they depend on how an account is configured, not on whether it was used in older records. This prevents customers with legacy asset data from being blocked from creating new assets, and also keeps certain configured accounts out of the depreciation selection list.
Original PR description
This commit fixes the `can_create_asset` flag on accounts to limit the creation of asset based on if account is used as an accumulated depreciation on another account, instead of used by an asset. This requirement came after users with old assets couldn't create assets using some accounts because they were used by the old assets with no possible way to change that. Better to limit on configuration data instead of business data. Also now, accounts that have models set do not show up in the accumulated depreciation dropdown. no-task
This update adds the unit of measure information to the data sent to ECPay, so invoice lines are easier to understand. As a result, the printed invoice now shows the item’s unit alongside the existing product details, reducing confusion for recipients.
Original PR description
Issue: -- The documents returned by the ECpay API can be confusing as it does not include the measurement (UOM). The make it clearer a description is provided to ECpay through the json with the Key "ItemRemark" Current behavior: -- displayed data in PDF 品名 數量 單價 金額 備註 test 1 5 5 Expected behavior: -- displayed data in PDF 品名 數量 單價 金額 備註 test 1 5 5 商品單位: Units opw-6070269 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#259536
This change prevents an employee holiday pay field from being read too early during payroll updates. As a result, the value is now calculated at the right time, which avoids incorrect payroll results and related test failures.
Original PR description
…ield The computed, non-stored field `l10n_be_holiday_pay_recovered_n1` had tracking enabled. When writing to any field on the employee, the `write` method calls `_track_prepare` for tracked fields if `mail_notrack` is not set in the context. `_track_prepare` reads the current value of tracked fields to store initial values. Because `l10n_be_holiday_pay_recovered_n1` is non-stored with no dependencies, this triggered a computation at the very beginning of the test, before payslips existed. Later, when payslips were created, the field was never recomputed, causing incorrect values and test failures. Previously, the `tracking_disable` context prevented early computation. The fix removes the tracking attribute entirely, so the field is only computed when accessed, avoiding premature reads and fixing the tests. task: 6095445 Forward-Port-Of: odoo/enterprise#114063 Forward-Port-Of: odoo/enterprise#113015
The Dutch ICP report now uses the same rounding method as the export files, rounding amounts down to whole numbers. This removes confusing differences between the report and the submitted export, helping users verify figures more easily.
Original PR description
Description of the issue this commit addresses: The Dutch tax authority lets ICP amounts be rounded down which is the behavior of the exports but not of the report itself meaning the values to not match and is quite confusing. --- Desired habevior after this commit is merged: The integer rounding DOWN is added on the ICP report to restore matching values --- task-6065382 Forward-Port-Of: odoo/enterprise#114277 Forward-Port-Of: odoo/enterprise#112953
The Point of Sale session report now calculates discount amounts more accurately when fiscal positions change the taxes applied to an order. This ensures the report matches the real sales data and avoids incorrect discount figures in end-of-session summaries.
Original PR description
Steps: ---- - Create a fiscal position with 2 different taxes - Add a line in POS - Apply fiscal position and add line discount - Finish the order cycle - Download the session report Issue: ---- - The discount amount was calculated incorrectly in the session report Cause: ---- - The discount amount calculation used taxes before applying the fiscal position Fix: ---- - Used `tax_ids_after_fiscal_position` for tax calculation while computing the discount amount task-5421215 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#256704 Forward-Port-Of: odoo/odoo#244650
This change fixes a testing issue where repeated test attempts could accidentally reuse leftover state from a previous run and cause confusing failures. By recreating the test for each retry, the test process is more reliable and easier to trust.
Original PR description
The autoretry don't recreate the test instance meaning that some pollution can remain there breaking the next test with a strange error. This pr recreates the test instance for each retry to avoid this kind of issue, and move the retry mechanism to the suite level. The core part of the fix is `test = test.__class__(test._testMethodName) # re-create the test to reset its state` While on it, moving the retry mechanism in the test suite since it makes more sense and allow a better control on what is retried or not since we don't rely on inheritance, and avoid dirty code with super(test) call to recreate the instance and execute it again. The tests needs to be adapted since the retry attribute is now in the loop, but we can have a quite reliable way to know if we are in a retry or not using inspect. Forward-Port-Of: odoo/odoo#258833
If the connection drops while waiting for a Viva.com payment confirmation, the POS now keeps checking instead of stopping too early. This reduces the risk of a customer being charged on Viva.com without the payment being confirmed in the point of sale, while also showing a one-time warning that connectivity was lost.
Original PR description
When a payment was sent to Viva.com and the connection dropped before receiving confirmation, the polling loop in waitForPaymentConfirmation would stop because _handleOdooConnectionFailure set the payment status to "retry" and rejected the promise. This left the payment debited on Viva's side but unconfirmed in the POS. Now the polling uses a direct silent ORM call instead of _call_viva_com to avoid triggering _handleOdooConnectionFailure. On connection failure, the poll silently retries on the next interval until a definitive success/failure response is received. A one-time warning notification informs the user that connectivity was lost. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#259564
This change prevents discounts from being recalculated and cleared on optional sales lines when a portal customer updates the quantity. It helps preserve the expected pricing on quotes and avoids confusing changes for customers and sales teams.
Original PR description
Issue: --- Discount compute depends on `product_uom_qty`. On optional lines, this recompute will reset the discount on lines, when portal user updates the quanity. Cause: --- `discount` needs to depend on `product_uom_qty` because discount needs to be computed based on the quantity due to pricelist rules. Fix: --- We can prevent this compute if the quantity update comes from portal. opw-6078083 Forward-Port-Of: odoo/odoo#259696
This change fixes an issue where exporting account reports could fail when a fiscal year date was included. Users will now be able to export these reports without encountering a JSON processing error.
Original PR description
When calling export_file with a fiscal year set we pass a fiscal year into it. This function then calls json.dumps with the date object passed into it through a dictionary, which json.dumps cannot process and users experience an error. https://drive.google.com/file/d/1VBOIAxuzcXT5b5BBnLDqd6ibWqOPxe4P/view?usp=drive_link
The website editor now correctly treats buttons with size or shape classes as custom buttons. This prevents the wrong style from being shown in the button settings popover and keeps the editor behavior aligned with how those buttons are actually built.
Original PR description
Before this commit: Since the removal of button style options for the preset primary and secondary styling, the type of a primary/secondary button with size or shape defined in the class should be "custom". The fix is made to saas-18.4 cause the custom button option is removed in saas-18.3 and reintroduced only from saas-18.4. The button option removal commit: https://github.com/odoo/odoo/commit/a7b71d700e4997e4a2f646e2ae12f58f20058dc4 The button custom option reintroduction: https://github.com/odoo/odoo/commit/ea22b28bbae009c9eab4ff397affa9a3cb71037a After this commit: when the button has size or shape classes, we consider it as "custom" button. task-6061443 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#257410 Forward-Port-Of: odoo/odoo#256015
Users can now edit website profiles from mobile devices without encountering an error. This aligns the mobile experience with the desktop flow, so profile updates work consistently across devices.
Original PR description
# How to reproduce - Install the eLearning module - On the website, go to the Courses tab - View a user (Administrator for example) - In mobile view, click on Edit # The problem An traceback is shown and the user cannot edit their profile # Why This commit (https://github.com/odoo/odoo/commit/69785c1a64d61f2831804bcdcc4887ad43d27fbb) improved the profile edition. It is mentioned that they moved away from the simple bootstrap modal and used an OWL view instead. However, for the mobile view, they left a call to a modal that does not exist. This fix removes the call to the undefined modal and replaces it with the same OWL Dialog used in the desktop view (thanks to the .o_wprofile_editor class) opw-5960586 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#251503
This change prevents a rare error that could happen when Odoo reloads payment-related records after an internal cache refresh. It improves stability during payment registration and related accounting flows, so users are less likely to encounter interruptions when processing payments.
Original PR description
The issue originates from `_get_batches` in `account_payment_register`, where a prefetch collection is built using `OrderedSet`. After an ORM cache invalidation, accessing fields on the resulting records could raise an error because `with_prefetch()` expects the iterable of IDs to be reversible, which `OrderedSet` does not support. This commit implements `__reversed__` on it, making it compatible with `with_prefetch()` while preserving its intended behavior. A unit test is also added in `l10n_account_withholding_tax` to cover the prefetch traversal scenario. task-[6108453](https://www.odoo.com/odoo/project/967/tasks/6108453)
This fix stops Odoo from creating a refund entry when a Stripe payment was only authorized but not actually captured. It helps keep accounting records accurate and avoids showing refunds for money that was never collected.
Original PR description
When an uncaptured Stripe payment is voided, the system will still generate the refund payment entry. Steps to reproduce: - Configure the Stripe payment provider - enable "Capture Manually" - generate webhook - Create a sales order - Generate a payment link and pay with Card - Back to the SO, click 'Void Transaction' Issue: Refund payment entry will be created even if no payment has been collected for the transaction. opw-5866924 Forward-Port-Of: odoo/odoo#259945 Forward-Port-Of: odoo/odoo#259230
This update fixes an issue where users could not select a Sale Order Item on billable timesheet lines. It also restores the expected timesheet behavior while keeping the system compatible with related sales line types.
Original PR description
To reproduce:
- on runbot, in timesheet list view, try editing the `Sale Order Item` of any billable line
- it's not possible to select any value (no result are returned)
Since odoo/odoo@cd6325d7476b, the domain for `so_line` field is not casted as string anymore, so the `unquote('commercial_partner_id')` ends up being serialized as string during response marshaling, changing it to the following invalid domain part:
`[('order_partner_id.commercial_partner_id', '=', 'commercial_partner_id')]`
We need to force the domain as string to ensure the dynamic `commercial_partner_id` value is correctly evaluated on user-side.
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prThis update fixes a typo in an internal SQL constraint warning message so the text now refers to the correct model naming. It does not change business behavior, but it improves clarity and reduces confusion when reviewing warnings or logs.
Original PR description
In this commit: --------------- - Corrected a typo in the SQL constraint warning message, updated `model.Constraint` to `models.constraint`. Forward-Port-Of: odoo/odoo#259980 Forward-Port-Of: odoo/odoo#259867
Opening a channel from the Kanban view now takes users to the chat window instead of causing a traceback in Discuss. This fixes a navigation issue that could block access to channels in certain notification settings.
Original PR description
Steps to reproduce:
* Open Discuss
* Go to Configuration > Notifications
* Set it to `All Messages`
* Go to Channels menu
* Click on any record (not member)
-> Traceback
This happens since [1] because it tries to read `message_unread_counter_ui` on `self_member_id` even when it is undefined.
This commit fixes the issue by opening the chat window instead.
[1]: https://github.com/odoo/odoo/pull/249755
Task-6128253
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prThis fix prevents valid VAT numbers from being shortened when exporting invoices to the Italian tax system. It ensures the full customer VAT is preserved, which avoids incorrect XML data being sent to the Tax Agency.
Original PR description
**Steps to reproduce:** * Install `l10n_it_edi` module. * Create a partner with country **Spain** and VAT `A95758389`. * Create an invoice and send it to the Tax Agency, and download XML. **Observed behavior:** * The exported XML contains `5758389` in <IdCodice> instead of `A95758389` — the first two characters of the VAT are silently dropped. **Cause:** * In `_l10n_it_edi_get_values`, the EU branch that strips the country-code prefix used a bare `else` after the `isdecimal()` check, unconditionally removing the first two characters of any VAT that does not start with two digits. Spanish NIFs like `A95758389` start with `A9` (letter + digit), which is not a country-code prefix but was treated as one, corrupting the value. **Fix:** * Remove country prefix from normalized VAT by `removeprefix(normalized_country)` Instead of removing the first two characters. It will ensure that only the country prefix will be removed. opw-6089198 Forward-Port-Of: odoo/odoo#258626
This fix ensures that when a subscription payment is completed, the related invoice is automatically matched with the payment and no longer stays marked as unpaid. It improves the customer experience by keeping invoice status accurate when businesses use a setup that skips bank reconciliation.
Original PR description
Currently, when a subscription payment is processed through a provider configured to use as outstanding account the bank default account, the resulting invoice may remain in an 'open' state even…
Currently, when a subscription payment is processed through a provider configured to use as outstanding account the bank default account, the resulting invoice may remain in an 'open' state even though the payment transaction is 'done'. This type of configuration is usually done when users want to skip the bank reconciliation process, and just create payments without the need to reconcile the payments with transactions. Steps to reproduce: - In Settings, under Sales > Invoicing, disable Automatic Invoice - Activate demo payment method - In the main Bank account add the default account as outstanding account for demo payment method. - Create a sales order with a subscription product - Open Preview - Pay - Go back to the sales order and open the created invoice Issue: The invoice is created and the payment is registered, but the invoice remains 'Not Paid'. Analysis: The invoice and the payment move lines are not automatically reconciled during the post-processing of the transaction, leaving the invoice unbalanced. opw-5869303 Forward-Port-Of: odoo/enterprise#110656
Odoo now ignores LinkedIn image entries that do not include a download link during account import. This prevents the connection process from crashing and helps more LinkedIn accounts connect successfully.
Original PR description
When importing a LinkedIn account, Odoo fetches the image metadata of the organization page and expects each returned image to contain `downloadUrl`. For some LinkedIn accounts this key is missing from the image response, which makes the callback crash with `KeyError: 'downloadUrl'` and prevents the account from being connected. LinkedIn's current Images API documentation describes `downloadUrl` as an optional field, so the import flow should not assume it is always present. This patch skips image entries without `downloadUrl` instead of crashing. opw-6099244 Forward-Port-Of: odoo/enterprise#113812
When a new app or model is created in Studio with chatter enabled, the activity shortcuts for Late, Today, and Future are now automatically available. This fixes an issue where those filters showed all records instead of only the expected activities, making the activity menu accurate and useful.
Original PR description
Steps to reproduce
==================
- Install studio
- Create a new app
- Create a new model
- Keep the Chatter toggled (use_mail)
- Exit studio
- Create three records, one with an activity in the past, one today and one in the future
- Click on the clock status icon in the top right
- There should be a section with the new model
- Click on 1 Late => every records is displayed
- Same for Today and Future
Cause of the issue
==================
https://github.com/odoo/odoo/blob/b6434b91a7f94075e1372ec827787504ef7aa4f0/addons/mail/static/src/core/web/activity_menu.js#L39-L77
For this feature to work, the activities_{overdue,today,upcoming_all} filter should be present
Solution
========
We add them to the search view. They are all pretty much implemented the same way in every model.
opw-6069150
Forward-Port-Of: odoo/enterprise#113792
Forward-Port-Of: odoo/enterprise#113011The Reference field in Inventory move history can no longer be edited in the user interface when the change would not be saved. This avoids confusion for users and ensures the screen reflects what can actually be updated.
Original PR description
### Issue before this commit: Before this commit, the Reference field displayed on stock.move.line was editable in the user interface, even if the modification made by the user was not persisted.…
### Issue before this commit: Before this commit, the Reference field displayed on stock.move.line was editable in the user interface, even if the modification made by the user was not persisted. After saving and reloading the Move History view, the original value was restored. ### Steps to reproduce the issue: 1. Go to Move history in Inventory app 2. Try to change the name of a line and save 3. If you go back to the Move history you can see that the name is not changed ### Cause of the issue: The issue was caused by a mismatch between the stock.move.line.reference field and its target field stock.move.reference. The field on stock.move.line is a related field that appears editable (readonly=False), but the underlying stock.move.reference field was not writable. As a result, user could edit the field but the modifications were ignored, preventing changes from being effectively saved. ### Reason to introduce the fix: The fix ensures that the reference field in stock.move and in stock.move.line are readonly. opw-6055708 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#256434
This update corrects how tax rounding amounts are calculated when creating invoices for down payments. It helps ensure the invoice total stays exact while avoiding incorrect tax values in the export format used for electronic invoices.
Original PR description
'total_excluded_currency' is for the base amount. 'base_amount_currency' should be used only when getting the base per tax. When dealing with a down payment, a distortion in the taxes amounts might be introduced to ensure the total of the invoice is exactly the expected one. opw-6060486 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#259426
This change prevents an error that could appear when a user clears the scope on an emission source record. It ensures the related flow fields stay empty when no scope is selected, so users can edit records without interruptions.
Original PR description
Currently, an error occurs when the user removes the scope of the emission source. **Steps to Reproduce:** - Install the `esg` module. - Create an `emission source` record or open an `existing one`.…
Currently, an error occurs when the user removes the scope of the emission source. **Steps to Reproduce:** - Install the `esg` module. - Create an `emission source` record or open an `existing one`. - Remove the `scope` value and click anywhere. `ValueError: Compute method failed to assign esg.emission.source(<NewId origin=1>,).activity_flow_direct_indirect` **Cause:** Error started occurring in 19.0 due to a change in selection field behavior. Since from [commit](https://github.com/odoo/odoo/pull/214422/commits/8d2a42ac419fdf7943a0c11beb8c5de6c6f85bef), selection fields no longer display an “empty” value. To remove a value from a selection field, the user must clear the field, similar to a many2one field. when the user removes the scope value, The system attempts to compute the activity flow, but since the scope is False, it does not match any case [1]. As a result, the method fails to assign a value to activity_flow_direct_indirect, raising an error. This commit ensures that the activity flow and activity flow direct indirect are initialized to False. If no condition matches, the field remains False, preventing the assignment failure. [1]: https://github.com/odoo/enterprise/blob/eaf4b7559b8eb6c538820d6e54f583a41077ac3d/esg/models/esg_emission_source.py#L79-L89 Forward-Port-Of: odoo/enterprise#114079
This update prevents an error in Australian payroll when an employee’s schedule pay has been removed from a contract that still has a wage set. It ensures payroll records continue to work normally instead of failing with a crash, improving reliability for affected users.
Original PR description
This error occurs when the schedule pay is removed from an employee contract with a defined wage. Steps to reproduce: - Install `l10n_au_hr_payroll` module with demo data - Switch to `My Australian…
This error occurs when the schedule pay is removed from an employee contract with a defined wage.
Steps to reproduce:
- Install `l10n_au_hr_payroll` module with demo data
- Switch to `My Australian Company`
- Open any Employee > Payroll > `Wage` remove `schedule pay`
Traceback:
```py
File "/home/odoo/src/enterprise/saas-19.2/l10n_au_hr_payroll/models/hr_version.py", line 549, in _compute_wage
version.wage = Payslip._l10n_au_convert_amount(daily_wage, "daily", version.schedule_pay)
File "/home/odoo/src/enterprise/saas-19.2/l10n_au_hr_payroll/models/hr_payslip.py", line 511, in _l10n_au_convert_amount
coefficient = PERIODS_PER_YEAR[period_from] / PERIODS_PER_YEAR[period_to]
KeyError: False
```
We are encountering this error because the `schedule pay` is removed, causing the field to become `False`. This False value is then passed to the `_l10n_au_convert_amount` [method], resulting in a `KeyError`.
[method]: https://github.com/odoo/enterprise/blob/92c584cc1426ac70f6f77aa8216c17004fa42d35/l10n_au_hr_payroll/models/hr_payslip.py#L500-L509
sentry-7401189447
Forward-Port-Of: odoo/enterprise#113623Fixed an issue where posting a credit note could fail when automatic currency exchange adjustments were created. The system now skips an unnecessary analytic validation for these automatically generated moves, so the credit note can be posted successfully.
Original PR description
**Issue:** When a user posts a credit note with a currency exchange difference relative to the reversed move, the resulting exchange move lines lack the mandatory analytic distribution. This triggers…
**Issue:** When a user posts a credit note with a currency exchange difference relative to the reversed move, the resulting exchange move lines lack the mandatory analytic distribution. This triggers a validation error, preventing the credit note from being posted. **Steps to reproduce:** - Set "mandatory" applicability on any analytic plan. - Set two different currency rates on two different dates for any foreign currency. - Create and post an invoice on the first date (ensure the mandatory analytic distribution is set). - Create a credit note from that invoice using the second date. - Click on the post button on the credit note. Result: A validation error occurs even though the credit note itself has the mandatory analytic plan set, because the auto-generated exchange move does not. **Fix:** Since the context key validate_analytic is set to True by the post button action, it must be manually set to False during the automatic creation of exchange difference moves to bypass the mandatory plan check. OPW-6081632 Forward-Port-Of: odoo/odoo#259624 Forward-Port-Of: odoo/odoo#259381
This change makes sure a required period is always selected when aggregate withholding limits are enabled. It prevents invoice creation errors caused by leaving that field empty, improving reliability for users configuring Indian withholding rules.
Original PR description
Previously, if `is_aggregate_limit` was set to True while `aggregate_period` was left empty, it would raise a traceback during invoice creation. Although `aggregate_period` has a default value, it can still be manually cleared. With this commit, `aggregate_period` is enforced as mandatory whenever `is_aggregate_limit` is enabled, preventing such errors. Forward-Port-Of: odoo/odoo#259737 Forward-Port-Of: odoo/odoo#259634