Daily updates from Odoo
Wednesday, March 18, 2026
105 changes
16 changes
Resolved issues and error corrections
This update fixes an issue where backorders were incorrectly doubling labour costs in the accounting system. When a backorder is created, the system was inadvertently posting labour twice. The fix ensures labour costs are only recorded once per workorder time entry, preventing inaccurate financial reporting.
Original PR description
When the Manufacturing operation type is configured with Create Backorder = Always, `mrp.production.pre_button_mark_done()` re-enters `button_mark_done()` in the same server execution path. This can trigger `_post_labour()` twice, causing two posted “<MO> - Labour” journal entries and doubling labour costs in Accounting. Labour costs should be posted only once per workorder time entry. Ensure labour is only posted once by skipping workorder times that were already linked to an accounting entry. This prevents a second execution from creating a duplicate labour journal entry. A test was added to cover the partial production flow when backorder is set to “Always.” Related ticket: opw-5931754 --- Forward-Port-Of: odoo/odoo#253689 Forward-Port-Of: odoo/odoo#250237
This update resolves an issue where downpayment products weren't correctly linked to downpayment lines in sales orders. The fix ensures that downpayment products are properly added when a downpayment is made, addressing a previous reporting problem related to settlement processing. This improves the accuracy of sales order data.
Original PR description
Step to reproduce - install pos_sale - create a SO (make sure it is in draft) - open pos, make sure it has downpayment product - do a downpayment for that SO - go to backend, open SO Observation: - The downpayment product is not linked to downpayment line Cause: - After refactor [1], downpayment product is not added in sale line [1] https://github.com/odoo/odoo/commit/175daa5db6a3f16be6b636a36e2b8462306b2eb4 Fix: - Added the product when creating downpayment line **Note:** - Actual issue reported was different, and was side effect of this issue - there, the downpayment was not considered when trying to settle SO from pos opw-5934461 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#250548
A recent change in required field validation caused an error when starting a new pay run in the Hong Kong payroll module. This update ensures that date fields are validated before the system attempts to process them, resolving the 'value.toFormat is not a function' error. This prevents users from being unable to initiate pay runs.
Original PR description
Currently, an error occurs when a user starts a new pay run. Steps to Reproduce: - Install `l10n_hk_hr_payroll_empf` module with demo data. - Switch to the `Hong Kong` company. - Go to `Payroll` >…
Currently, an error occurs when a user starts a new pay run. Steps to Reproduce: - Install `l10n_hk_hr_payroll_empf` module with demo data. - Switch to the `Hong Kong` company. - Go to `Payroll` > `Payslips` > `Pay Runs`. - Click `New`, remove the `period value`, and click `Continue`. `TypeError: value.toFormat is not a function` After this recent [commit] that changed the required field validation behavior, when the date field is empty and it attempts to serialize the date [1], which raises the error here [2]. Although the start and end date field is required, the ORM call is executed without the value for the date field. This commit ensures that, similar to the base PayslipBatchFormController [3], the fields are validated before making the ORM call. [commit]: https://github.com/odoo/enterprise/commit/cd0f5f31e9427cb96092671bbcbb52dfbb3c03f8 [1]- https://github.com/odoo/enterprise/blob/431d1b513f26188f693abd949f78a893514205f0/l10n_hk_hr_payroll_empf/static/src/views/payslip_run_form/hr_payslip_run_form.js#L13-L14 [2]: https://github.com/odoo/odoo/blob/3263a7f54948d57f13176cf0416b1419150e9d87/addons/web/static/src/core/l10n/dates.js#L536 [3]: https://github.com/odoo/enterprise/blob/431d1b513f26188f693abd949f78a893514205f0/hr_payroll/static/src/views/payslip_run_form/hr_payslip_run_form.js#L16-L20 sentry-7207509338 Forward-Port-Of: odoo/enterprise#108885
This update enhances the way error messages are handled within the Odoo account_peppol module. Previously, messages were based solely on error codes, making debugging difficult. Now, the system captures and uses the full server error, providing more detailed information for troubleshooting and improving client support.
Original PR description
Before this commit, all messages where mapped based on the error code and not from the server error. Schematron/XSD issues really need the full error to make easy for debugging/client. OPW-5980046 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#252252
This update fixes a bug where the product search bar didn't function correctly on mobile devices. The issue was due to a missing configuration in the search template, which prevented the search from executing. The fix ensures that product searches work as expected across all device views, improving the user experience for mobile shoppers.
Original PR description
Steps to produce: --- - Install `website_sale` module. - Go to `website > shop`. - Open the `Customizable Desk` product page. - From the website editor, `enable the search bar` for the product page.…
Steps to produce: --- - Install `website_sale` module. - Go to `website > shop`. - Open the `Customizable Desk` product page. - From the website editor, `enable the search bar` for the product page. - Switch to `mobile view`. - Now search for `drawer` in product search. Issue: --- - In mobile view, the search does not work. When performing a search, nothing happens, and the request is not executed. Root cause: --- - At [1], in the search template definition, the action attribute is missing in the search form. Solution: --- - Set the form action using keep(search=0) instead of leaving it undefined. - This ensures that the search behaves correctly depending on the context (global or category-scoped). [1]https://github.com/odoo/odoo/blob/51f59a293de1e86f66f30257f8fc0c419463d18c/addons/website_sale/views/templates.xml#L2239-L2259 opw-5992052 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#254221 Forward-Port-Of: odoo/odoo#251694
This fix resolves an issue where orders created through the MPS weren't consistently grouped into single RFQs, leading to duplicate RFQs being generated. The update ensures that the system correctly handles date formats when searching for existing purchase orders, preventing the creation of new POs unnecessarily. This improves order management efficiency.
Original PR description
Issue ----- Orders created through the MPS aren't grouped in a single RFQ. Steps to reproduce ----- - Create a product with a vendor - Add it to the MPS with the buy route - Change the forecast to 2…
Issue ----- Orders created through the MPS aren't grouped in a single RFQ. Steps to reproduce ----- - Create a product with a vendor - Add it to the MPS with the buy route - Change the forecast to 2 - Order - Change the forecast to 5 - Order - Go to RFQs > There are 2 different RFQs Cause ----- When doing `_run_buy`, no existing PO is found https://github.com/odoo/odoo/blob/98e3020bcffaf449291d1e6664ba613761f37331/addons/purchase_stock/models/stock_rule.py#L102 so a new one gets created. The reason why the existing PO is not found is because we add `date_planned_mps` to the search domain https://github.com/odoo/enterprise/blob/42102423069c2cebbc01eb4d1d8f9b6215358639/mrp_mps/models/stock_rule.py#L10-L15 However, `values['date_planned']` is a datetime.date, whereas `date_planned_mps` is a datetime.datetime in DB. https://github.com/odoo/enterprise/blob/42102423069c2cebbc01eb4d1d8f9b6215358639/mrp_mps/models/purchase_order.py#L10 This poses some problems with timezones, as the client and db dates might differ. We can avoid the problem by converting the date to datetime. ----- Ticket: opw-5171041 Forward-Port-Of: odoo/enterprise#106968
This update resolves an issue where the Documents Activity view became unusable after exiting Studio, preventing users from filtering or adding new activities. The fix ensures the view correctly loads necessary data, restoring full functionality and preventing frustrating user experiences.
Original PR description
Problem: When returning to the Documents Activity view after closing Studio, the view becomes unusable with an error that `folderId` is `undefined`. Users are forced to refresh the page or switch…
Problem: When returning to the Documents Activity view after closing Studio, the view becomes unusable with an error that `folderId` is `undefined`. Users are forced to refresh the page or switch views to fix it. Specifically: - Filters can no longer be selected. - Adding new activities throws UI errors (even if technically successful). Cause: The `getSelectedFolder` method returned undefined because the `searchPanel` logic was skipped. The Activity view does not display the `searchPanel`, so the model failed to run `_fetchSections` which retrieves the data used by `getSelectedFolder`. Under normal circumstances, the view relies on data already loaded by the Kanban or List views, but that data is unavailable here. Solution: - Force the search model to load the data explicitly, ensuring the view initializes correctly regardless of the `searchPanel` visibility. We kept the dependency upon `_fetchSections` rather than removing it, as it is required by the `search_model` to maintain other features like `breadcrumbs`. - Add a test to verify the fix and prevent regression. Co-authored-by: Pierre-Yves Dufays <pydu@odoo.com> Co-authored-by: Charlier Florian <flch@odoo.com>
This update resolves an error that occurred when users attempted to change the employee within the salary simulation feature. The fix ensures the system correctly handles versioning during this process, preventing a runtime error. This improves the stability and usability of the salary simulation functionality.
Original PR description
Currently, an error occurs when user tries to change simulation employee in salary simulation. Steps to replicate: - Install `hr_contract_salary_payroll` with demo. - Open any employee (e.g.- Abigail…
Currently, an error occurs when user tries to change simulation employee in salary simulation.
Steps to replicate:
- Install `hr_contract_salary_payroll` with demo.
- Open any employee (e.g.- Abigail Peterson).
- Click `Simulation` > Change `Yearly Employer Cost` to `Gross Per Month`.
- Try to change the Employee, error will occur.
Error:
```
File '/home/odoo/odoo19/enterprise/hr_contract_salary_payroll/models/hr_contract_salary_offer.py', line 157, in _compute_offer_values_from_template
version = offer._get_version()
^^^^^^^^^^^^^^^^^^^^
File '/home/odoo/odoo19/enterprise/hr_contract_salary/utils/hr_version.py', line 39, in hr_version_context_wrapper
raise RuntimeError(
RuntimeError: Method '_get_version' must be called within a savepoint context. Use `hr_version_context(...)` context manager before calling this method.
```
Cause:
- The method `_get_version()` has the decorator `@requires_hr_version_context()` which makes the method to be callable within a savepoint context for `hr.version` [1] i.e. it can only be called within a `hr_version_context()` block.
- As here the method was not called under the `hr_version_context()`it raises an error from [here].
Solution:
- Used the `hr_version_context()`block instead of savepoint (similar to [this]).
[this]: https://github.com/odoo/enterprise/pull/108005/changes#diff-97aeb940d5058abc95cb617e5a2015320c37e8d50a15cffc2c08eac1839ac16dL98-R100
[here]: https://github.com/odoo/enterprise/blob/626598abe4fdbc8391a428928e197e7735cbb298/hr_contract_salary/utils/hr_version.py#L39-L42
[1]: https://github.com/odoo/enterprise/blob/626598abe4fdbc8391a428928e197e7735cbb298/hr_contract_salary/utils/hr_version.py#L14-L17
sentry-7335824597This update fixes a problem causing incorrect stock synchronization for Amazon listings, leading to phantom orders. The solution allows users to manually specify the fulfillment channel (FBA or FBM) for each listing, resolving a known Amazon issue and improving order accuracy. This ensures correct stock management and prevents revenue loss.
Original PR description
When configuring a listing on Amazon Seller Central, the user must choose **one** of the available fulfillment channels that Amazon offers. We distinguish two kinds: Fulfillment by Amazon (FBA) and…
When configuring a listing on Amazon Seller Central, the user must choose **one** of the available fulfillment channels that Amazon offers. We distinguish two kinds: Fulfillment by Amazon (FBA) and Fulfillment by Merchant (FBM). However, Amazon suffers from a known issue of ghost listings. A ghost listing occurs when an offer is presumably sold via FBA, but in fact stores stock information for both FBM and FBA creating unwanted FBM orders. To avoid ghost listings, the first solution was to disable stock synchronization as soon as an offer contained stock in the Amazon location of Odoo. However, if a merchant decided to change the fulfillment channel, it became impossible to sync the stock anymore. See also e7c01c7097d90e731c5408cee4d3595ed810c8fa. To resolve this issue, we decided to use the Amazon API to fetch information about the fulfillment channel of a listing. However, Amazon doesn't give a clear answer for a given listing. Therefore, after some research, the assumption was that an offer was FBM if the listing contained a `merchant_shipping_group`, as the merchant shipping group is a setting specific to FBM listings. See also e6d620e4b200cadabb00ce37ab03289cfeb4ae58. However, this assumption was flawed because Amazon can keep the shipping group even if the listing switches to FBA. This in turn enabled stock synchronization, leading to ghost listings. To fix this issue we give the possibility to users to manually set the correct fulfillment channel of an offer when it becomes ambiguous. opw-5480254 See also: - https://github.com/odoo/upgrade/pull/9692 Forward-Port-Of: odoo/enterprise#106662
This update fixes a discrepancy in invoice status after SDI validation for Italian tax invoices. Previously, the system didn't automatically update the invoice's status to reflect the Public Administration's (PA) state, leading to potential rejection issues. This change ensures accurate status tracking and prevents invoices from being incorrectly flagged as rejected.
Original PR description
### Issue: After the SDI validation, the state was never updated to match the PA state, resulting in a mismatch with the actual status ### Cause: When `l10n_it_edi_state` is set to `forwarded`, the cron `cron_l10n_it_edi_download_and_update` doesn't consider that a new state could occur However, invoices sent to Public Administration can still be rejected after being forwarded It is not possible to reproduce the issue with the demo system, as it only sets the state to `forwarded` Ticket [link](https://www.odoo.com/odoo/project.task/5391891) opw-5391891 Forward-Port-Of: odoo/odoo#254406 Forward-Port-Of: odoo/odoo#253525
This update corrects a bug in the DIAN invoice processing workflow. Previously, the system incorrectly deleted the original invoice document, potentially leading to data loss. This fix ensures the correct invoice document is protected during the update process, maintaining data integrity.
Original PR description
**PROBLEM** In some configurations, `_l10n_co_dian_cron_update_event_status()` would delete the original document of the invoice. **CAUSE** The logic that tried to exclude the original document from the code that unlinks duplicated documents is wrong. It protect the oldest document of `self` instead of `move`. So the document of the move we are currently working on is not protected, and could be deleted. **STEP TO REPRODUCE** 1. Setup DIAN. 2. Create multiples invoices and send them to DIAN. 3. Run _l10n_co_dian_cron_update_event_status() If the original document of the invoice have the same commercial_status as some other document, it could be destroyed. opw-5447147 Forward-Port-Of: odoo/enterprise#110455
This update fixes an issue where time off leaves were incorrectly displaying instead of accurate return dates. The change ensures that employee profiles now show the correct return date for worked-time leaves, improving the accuracy of leave scheduling and reporting.
Original PR description
Issue: - When a time off type was configured as , adding a leave for today caused the employee form to display instead of a real date. Fix: - Compute leave dates for all validated leaves, including worked-time leaves. - Ensure the date is always computed using the first working interval after the leave end date. Impact: - Employee profiles now display a correct return date for worked-time leaves. task-5421688 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#254040 Forward-Port-Of: odoo/odoo#241329
This update resolves an issue where users on Firefox couldn't hear incoming calls through their softphones. The fix ensures the system correctly processes incoming call tracks as soon as they're available, regardless of the session establishment timing. This improves the Odoo VoIP functionality for Firefox users.
Original PR description
Steps to reproduce the bug: - Install voip and open the Odoo backend on Firefox - Setup your voip settings - Call your softphone number, thanks to your smartphone - Once the softphone opens with the…
Steps to reproduce the bug: - Install voip and open the Odoo backend on Firefox - Setup your voip settings - Call your softphone number, thanks to your smartphone - Once the softphone opens with the call, answer => The caller can hear you but you cannot hear the caller. This happens since [1]. Before that commit, we had something like "when the session is established, listen to tracks being added to the call and also set up the audio". After that commit, this became "when the session is established *or is establishing*, listen to tracks being added to the call... *but don't set up the audio otherwise*". The problem is that on Firefox, the timing is such as the tracks of incoming calls are being added just before the session is establishing (or established), meaning we listen to tracks being added too late. Note that commit [1] was further diluted afterwards by commits like [2] (doing stuff with the audio before establishing) and [3] (which simply removed the "established" part, relying on "establishing" being done). Later on, commit [4] prepared some other work by moving and improving things around and it actually fixed this issue here by chance. What did the trick is listening to tracks being added from the start: as soon as SIP.js notifies that the remote stream exists. This commit fixes the issue in impacted versions (19.1 and 19.2) by backporting the relevant part: listening to tracks being added as soon as possible and not once establishing/established. A test was added. [1]: https://github.com/odoo/enterprise/commit/d24d7f3406ca47e7ac529d69957b0ad481d553bf [2]: https://github.com/odoo/enterprise/commit/71d78810ae7f6c9169912276da18e04ad4f7bef0 [3]: https://github.com/odoo/enterprise/commit/942f32316ab02d8c739fe7fdd5ec2bdde472a68e [4]: https://github.com/odoo/enterprise/commit/33fc327c1c74ee874d546a98879dbbf468809850 task-5902700 Forward-Port-Of: odoo/enterprise#110833
This update resolves issues related to physical card processing, specifically for UK users, improving the reliability of expense tracking. It includes fixes for missing ETA information and shipping status errors, ensuring accurate expense reporting and preventing test failures.
Original PR description
Forward-Port-Of: odoo/enterprise#110263
This update resolves issues where the AI chat experienced unexpected errors and crashes, providing a better user experience. Now, the AI chat displays informative messages like 'oops' or 'Connection Interrupted' when errors occur, ensuring smoother operation and preventing data loss during interruptions.
Original PR description
Steps to reproduce: 1. Open the Website Editor 2. Select some text 3. Click the AI tool from the toolbar 4. Send a message in the chat window 5. Observe a non-standard error dialog showing 500 HTTP…
Steps to reproduce:
1. Open the Website Editor
2. Select some text
3. Click the AI tool from the toolbar
4. Send a message in the chat window
5. Observe a non-standard error dialog showing 500 HTTP error
The AI chat was not properly handling server errors and connection
interruptions, causing unhandled exceptions to be thrown to the user.
This commit improves error handling for both public and internal AI chat
by:
- The generator function handles error, such that it still yields data
even in error.
- Simulate RPCError for both the fetch of the streaming endpoint and during
error when streaming (error data is converted to RPCError).
- Properly provide error handler for StreamInterruptedError.
- Use a dedicated cursor for the LLM agent loop, wrapped in try/finally. When
the loop crashes, a new cursor is opened in the finally block to persist the
last text response. This ensures the loop cursor can roll back DB updates from
already-executed tool calls without losing the response message.
The following behavior will now be observed during error in the UI.
- Public AI chat:
- Initial fetch failed: shows "oops" message
- Stream interrupted:
- Server handled: shows "oops" message
- Server stopped: shows "Connection Interrupted" dialog
- Internal AI chat:
- Initial fetch failed: show RPCError dialog
- Stream interrupted:
- Server handled: shows RPCError dialog
- Server stopped: shows "Connection Interrupted" dialog
We also include a fix in the livechat where the ai spinner never goes away
when posting of message failed.
TASK-ID: 5886825
Forward-Port-Of: odoo/enterprise#105875This update fixes an error in the calculation of the mobility budget for Belgian HR contracts. The previous calculation incorrectly treated the budget as a fixed amount instead of a percentage, leading to inaccurate cost projections. This change ensures the yearly mobility budget cost is computed correctly, providing more reliable financial reporting.
Original PR description
Forward-Port-Of: odoo/enterprise#110827
24 changes
Resolved issues and error corrections
This update fixes a problem where image uploads would fail and cause a confusing user experience. Now, when you discard an image upload, the process stops cleanly, preventing errors and ensuring a smoother user experience. The fix ensures files are no longer uploaded after discarding the media dialog.
Original PR description
Steps to Reproduce: 1. Open the website module. 2. Open the media upload dialog to upload an image by either double-clicking the logo or replacing the existing image. 3. Upload a large file. 4. Abort…
Steps to Reproduce: 1. Open the website module. 2. Open the media upload dialog to upload an image by either double-clicking the logo or replacing the existing image. 3. Upload a large file. 4. Abort the upload before it finishes by clicking the 'Discard' button in the media dialog box. After performing these steps, a traceback is observed. Before this commit: - Image upload failures would throw uncaught exceptions. - These exceptions would interrupt the flow and result in a poor user experience with no clear feedback. - Even after clicking the discard button the image was still getting uploaded. After this commit: - Uploads can be safely aborted when the media dialog is discarded. - Ongoing XHR requests and RPC calls are properly cancelled. - The upload loop stops immediately when an abort is triggered with no traceback. - Users get a predictable and clean exit instead of a broken state. - Files are no longer uploaded after clicking Discard. ### task-4752497 Forward-Port-Of: odoo/odoo#250065 Forward-Port-Of: odoo/odoo#219081
This update fixes an issue where upload widgets within dropdown menus on smaller screens wouldn't function correctly. The fix ensures that dropdowns remain open while users initiate uploads, improving the user experience for mobile and tablet users. This resolves a bug preventing users from uploading documents from purchase orders.
Original PR description
## Issue: On small screens, when an upload widget is placed inside a dropdown (e.g., Upload Bill from a Purchase Order), the action does not work Clicking the dropdown item closes the dropdown immediately, which prevents the widget action from completing ## Cause: Widget actions require an accessible anchor element to function properly. However, dropdown items automatically close the dropdown on click As a result, the widget is triggered but immediately detached from the DOM before its action can fully execute ## Steps to reproduce: - Install `purchase_stock` (to have the Upload Bill widget available) - Create and confirm a Purchase Order (the Receive button must be available) - Reduce the browser width until the action buttons collapse into the three-dots menu - Click Upload Bill and try to upload a document opw-5918379 Forward-Port-Of: odoo/odoo#251492
This update corrects a naming error in the ZUGFeRD eInvoice XML file generated by our system. Previously, the file name didn't meet validator requirements, causing issues with several e-invoice validation services. Now, the ZUGFeRD file is correctly named, ensuring compatibility with key validation tools and facilitating accurate e-invoice processing.
Original PR description
Fix the name of the embedded xml for zugferd eInvoice format. Before this PR: For the validator https://www.portinvoice.com/en/, the error > No, the file is called zugferd.xml. The following naming conventions are > permitted: “factur-x.xml”, “xrechnung.xml”, “zugferd-invoice.xml”, > “ZUGFeRD-invoice.xml”, “order-x.xml”, “cida.xml” And also: > The XML has a valid profile? No This corresponds to the document_context, as the french factur-x and the german ZUGFeRD are a common standard, we can put the same context. After this PR: The ZUGFeRD file passes on different validators. Validators: * https://erechnungs-validator.de/ * https://easyfirma.net/e-rechnung/validieren * https://www.portinvoice.com/en/ * https://demo.verapdf.org/ task-6010416 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#253704 Forward-Port-Of: odoo/odoo#252681
This update fixes an issue where unbuilding products from different companies resulted in incorrect pricing due to a mismanaged company context. The fix ensures that component pricing accurately reflects the company from which the unbuild order originates, resolving discrepancies in inventory valuation reports.
Original PR description
Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#249790
This update corrects a previous issue where event ticket prices were fixed and not recalculated within the Point of Sale system. Now, event tickets will dynamically adjust their price based on either the event's defined price or the customer's active pricelist, ensuring accurate pricing at the POS. This improves the overall POS experience and pricing accuracy for event tickets.
Original PR description
Event tickets in POS would have their price locked to the price defined in the event itself. They would be filtered out of any price recalculation inside the POS to keep the POS from recalculating the price based on the `product_template` and to keep the price defined in the event itself. This PR will add event tickets back into price recalculation. It will set the price to the price defined inside the event if no pricelist is applicable, or use the pricelist to calculate the price if there is one applicable. Task-[5092613](https://www.odoo.com/odoo/project/1737/tasks/5092613) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#248454
This update fixes an issue where group leave durations were incorrectly calculated when overlapping with existing approved leave requests. The fix ensures that group leave durations accurately reflect all allocated time off, resolving a discrepancy in how the system processed conflicting leave types. This improves the reliability of time off scheduling.
Original PR description
Problem ------------------------ When an employee has approved leaves, and a group leave is created that overlaps with the approved leave and overrides it, the duration of the new group leave is not…
Problem ------------------------ When an employee has approved leaves, and a group leave is created that overlaps with the approved leave and overrides it, the duration of the new group leave is not computed correctly. The duration does not include the overridden days. To reproduce: 1. Create allocated leave for employee and approve and validate it. 2. Go to Management > Time Off and create a group leave for the employee that includes the approved time off dates. The dates of all leaves are updated correctly, but the duration of the group leave is incorrect. Objective --------------------------- Even though conflicting leaves were correctly split in the multi leave generation wizard, the resource.calendar.leaves table was not synchronized within the same transaction. Because the leave types required allocation, the duration was computed by subtracting the old time off days from the new leave's duration, since they were treated as unavailable. Solution -------------------------- Manually unlink the resource.calendar.leaves records associated with the conflicting leaves before calculating the new duration. The clears the employee's schedule in the database so that the dates are correctly processed as available. The calendar blocks for the remaining days of the approved time off and the new group leave are generated when the leaves are created. Task: 5911074 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#253425 Forward-Port-Of: odoo/odoo#249527
This update fixes an issue where certain salary deductions (specifically 'ATTACH_SALARY') were not being correctly processed in the net calculation for Odoo's Kenyan payroll module. The changes ensure that these deductions are accurately accounted for, improving payroll accuracy and compliance.
Original PR description
**Behavior before this commit** Some salary rules (e.g. `ATTACH_SALARY`) were ignored in the NET calculation. **Behavior after this commit** - Four rules are now added to the "Total deductions" line: their sequence and category has been changed. - The sign of these lines has also been switched: an attachment of salary of a positive amount should be added to the amount of total deductions, which is then deducted from the net.  opw-5894647 Forward-Port-Of: odoo/enterprise#110367 Forward-Port-Of: odoo/enterprise#107033
This update fixes an issue where certain valid Non-Resident (NRI) GSTINs were not recognized by the partner autocomplete feature. The change updates the validation logic to accept a wider range of NRI GSTIN formats, ensuring accurate data entry for international business partners. This improves the usability of the system for users dealing with NRI clients.
Original PR description
Currently, certain `valid GSTINs` for Non-Resident taxpayers are not recognized by the partner `autocomplete` feature. **Steps to reproduce:** - Install the `l10n_in` and `partner_autocomplete`…
Currently, certain `valid GSTINs` for Non-Resident taxpayers are not recognized by the partner `autocomplete` feature. **Steps to reproduce:** - Install the `l10n_in` and `partner_autocomplete` modules. - Navigate to Settings > Users & Companies > Companies. - Click `New` and set `Tax ID` to `9922JPN29001OSU`. - Wait for 5–10 seconds. **Observation:** The partner autocomplete does not trigger, although it is valid and verifiable on the official GST portal: https://services.gst.gov.in/services/searchtp **Root Cause:** The issue was already fixed in core validation by PR [1], but the GSTIN validation logic used in partner autocomplete was not updated. At [2], the GSTIN validation regex for NRI taxpayers only supports formats ending with `NRX` (X = any alphanumeric character). However, certain valid GSTINs follow a revised structure and therefore are not matched by the existing regex. **Fix**: This commit ensures that valid NRI GSTIN formats are accepted during validation by applying a fix similar to [1] to the partner autocomplete GSTIN validation at [2]. Related IAP PR: https://github.com/odoo/iap-apps/pull/1491 [1]: https://github.com/odoo/odoo/pull/251760 [2]: https://github.com/odoo/odoo/blob/3016c08a7aa8701ec9b0092b5aafc282b16dd9f3/addons/partner_autocomplete/static/src/js/partner_autocomplete_core.js#L36-L52 Forward-Port-Of: odoo/odoo#253799
This update fixes an issue where time off leaves weren't displaying the correct return dates for employees. The fix ensures that all validated leaves, including worked-time leaves, now accurately calculate and display the employee's expected return date, improving the accuracy of employee schedules and reporting.
Original PR description
Issue: - When a time off type was configured as , adding a leave for today caused the employee form to display instead of a real date. Fix: - Compute leave dates for all validated leaves, including worked-time leaves. - Ensure the date is always computed using the first working interval after the leave end date. Impact: - Employee profiles now display a correct return date for worked-time leaves. task-5421688 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#241329
This update corrects a data issue in NACHA payment files by prioritizing the actual bank account holder's name over the customer's name in Odoo. Using the correct account holder name ensures accurate bank identification and avoids potential payment processing errors. This improves the reliability of US payments.
Original PR description
The NACHA entry detail was using the partner's name (res.partner.name) for the Individual Name field. This should instead prioritize the Account Holder Name (acc_holder_name) from the bank account, as this reflects the actual name on the bank account which may differ from the partner's name in Odoo. The code now uses bank.acc_holder_name if set, and falls back to payment.partner_id.name if not set. Forward-Port-Of: odoo/enterprise#108414 Forward-Port-Of: odoo/enterprise#105582
This update fixes an error in how credit notes calculate the cost of goods sold (COGS). Previously, the calculation was incorrect when the invoice's unit of measure differed from the product's. This change ensures accurate COGS reporting for credit notes, improving financial reporting accuracy.
Original PR description
…f uom **Problem:** partial cogs are computed incorrectly when the uom of the invoice is different than the one of the product **Steps to reproduce:** -1) created a stored product with category std…
…f uom **Problem:** partial cogs are computed incorrectly when the uom of the invoice is different than the one of the product **Steps to reproduce:** -1) created a stored product with category std price perpetual -2) set a cost of 1 and an on hand quantity of 12 -3) for the invoicing policy select 'delivered quantities' -4) in the sales tab add the packaging 'pack of 6' -5) confirm a sale order for 2 packs of 6 Problem A: -6a) validate the delivery -7a) create and confirm an invoice for all the quanity -8b) on the delivery create a return for a quantity of 6 and validate -9b) select 'create invoice' on the sale order -10b) confirm the credit note Problem B: -6b) change the quantity to 6 units on the delivery -7b) validate with backorder -8b) create and confirm an invoice for the delivered quantity (1 pack of 6) -9b) validate the back order -10b) create and confirm an invoice for the remaining (1 pack of 6) **Current behavior:** Problem A : the cogs lines are : - crediting stock valuation of 54$ - debiting expenses of 54$ Problem B: the cogs lines are: - debiting stock valuation of 24 - crediting expenses of 24 **Expected behavior:** Problem A: the cogs lines should be: - debiting stock valuation of 6 - crediting expenses of 6 Problem B: the cogs lines should be: - crediting stock valuation of 6 - debiting expenses of 6 **Cause of the issue:** Both problems have the same cause. To compute the price unit for the cogs we call _get_cogs_value() https://github.com/odoo/odoo/blob/b071bc3cb9e1d91d9d0fbce7961c3c75f28ef874/addons/stock_account/models/account_move.py#L122 Inside _get_cogs_value, in the computation of the return value: https://github.com/odoo/odoo/blob/b071bc3cb9e1d91d9d0fbce7961c3c75f28ef874/addons/stock_account/models/account_move_line.py#L74 - price_unit is computed (in both use cases) using _get_cogs_price_unit https://github.com/odoo/odoo/blob/b071bc3cb9e1d91d9d0fbce7961c3c75f28ef874/addons/stock_account/models/account_move_line.py#L68 and is expressed in the uom of the product https://github.com/odoo/odoo/blob/b071bc3cb9e1d91d9d0fbce7961c3c75f28ef874/addons/stock_account/models/stock_move.py#L238-L240 - self.quantity is expressed in the uom of the invoice (pack of 6) - cogs_qty is computed using _get_cogs_qty() https://github.com/odoo/odoo/blob/b071bc3cb9e1d91d9d0fbce7961c3c75f28ef874/addons/stock_account/models/account_move_line.py#L66 and is expressed in the uom of the invoices (pack of 6) Because of this, in both use cases, the computation is incorrect. **fix:** we use the uom of the product everywhere because _get_cogs_value() should return the price unit in the products uom https://github.com/odoo/odoo/blob/b071bc3cb9e1d91d9d0fbce7961c3c75f28ef874/addons/stock_account/models/account_move_line.py#L51-L52 opw-5901706 Forward-Port-Of: odoo/odoo#250154
This update fixes an issue where timesheets were incorrectly calculating hours for employees on past contracts. The change ensures that timesheets accurately reflect the employee's historical working hours based on their contract period, resolving a discrepancy between current and past contract data.
Original PR description
Currently on creating a time off that falls under a past contract still generates timesheet hours based on the employee's current contract. ### **Steps to Reproduce:** 1) Install…
Currently on creating a time off that falls under a past contract still generates timesheet hours based on the employee's current contract. ### **Steps to Reproduce:** 1) Install `project_timesheet_holidays` module with demo data. 2) Create an employee with two contracts/versions: - Past contract: 1 Jan 2025 to 31 Dec 2025 with standard 40h/week (8h/day). - Current contract: 1 Jan 2026 to indefinite with standard 35h/week (7h/day). 3) Create and validate Time off for this employee in the past (e.g, 29 Dec 2025) 4) Navigate to `Timesheets>All Timesheets`, search for this employee and switch list view for clear view. ### **Observed Behavior:** 7:00 hours are displayed on the timesheet, pulling from the employee's current active contract calendar. ### **Expected Behavior:** 8:00 hours should be displayed, as the leave date falls under the 40h/week past contract. ### **Root Cause:** In the `_generate_timesheets`, the caledar values is fetched using `employee_id.resource_calendar_id` see[1], which always points to the employee's currently active calendar. Furthermore, this calendar is not explicitly passed to `_list_work_time_per_day` see[1], causing the method to fall back on the current default. [1]- https://github.com/odoo/odoo/blob/c2595e47e3b36120f4c3da8bfe8c16f6c5969a70/addons/project_timesheet_holidays/models/hr_leave.py#L36-L55 ### **Fix:** Change the logic to use `leave.resource_calendar_id`, which correctly computes and retrieves the resource calendar active during the specific `date_from` and `date_to` of the leave and pass this `calendar` to `_list_work_time_per_day` to ensure the correct historical hours are used for timesheet generation. **opw-5922695** Forward-Port-Of: odoo/odoo#248207
This update resolves a performance issue where replacing background images could cause the website to hang. The fix replaces a fragile regex-based approach with a more efficient method using CSSOM to remove transform styles, resulting in faster image updates and a smoother user experience. This improves overall website responsiveness.
Original PR description
__Before commit__ Transform-related CSS properties are removed from an image element by manipulating the raw `style` attribute string with a regex which is fragile and costly in performance. __Steps to reproduce (saas-19.2)__ This regex was added in [18.0][1] but is only a real issue since `resetImageTransformation` was called in `on_will_save_media_dialog_handlers` in [saas-19.2][2]: 1. Add a section block. 2. Add a background image. 3. Open the media dialog and replace the background image. => The website will hang for a while. __Fix:__ Use `.style.removeProperty()` instead to speed up the process and to make it less error prone. [1]: https://github.com/odoo/odoo/commit/85698bf4f591fc9280f054b9a255a7d [2]: https://github.com/odoo/odoo/commit/781c0ae77de01f0df8667e0191f6c34 Forward-Port-Of: odoo/odoo#254020 Forward-Port-Of: odoo/odoo#253843
This update fixes an error in the monthly VAT reports for Italian companies (l10n_it) that resulted in incorrect credit and debit calculations. The fix ensures accurate reporting by correctly handling carryovers from previous periods, specifically addressing issues triggered by VP8 calculations.
Original PR description
The VP14 formulas for both debit and credit were incorrect, leading to wrong values in the monthly VAT report For example, this occurs when there is a carryover from the previous period in VP8 ## Steps to reproduce: - Install l10n_it_reports and switch to the IT company - Create and confirm a Bill (Bill Date: 01/01/2026, Price: 100, Taxes: 10% G) - Create and confirm an Invoice (Invoice Date: 01/02/2026, Price: 200, Taxes: 10%) - Go to Reporting → Tax Report and select Monthly VAT Report (IT) - Select January, then click Returns - Select the period 01/01–31/12 with Monthly periodicity - Review the December and January tax returns by setting all errors to Reviewed, then Validate → Close (to trigger the VP8 carryover) - Return to the report view for February 2026 Check the VP14 credit value: it should be 0 (since the computed amount is negative) opw-6032147 Forward-Port-Of: odoo/odoo#254150
This update resolves an issue where the Point of Sale system in Mexico incorrectly flagged an error when setting an invoice to public for customers without a ZIP code or country. The fix ensures the necessary data is correctly shared with the underlying database, preventing the error and allowing users to properly set invoices to public.
Original PR description
## Issue In the POS of a Mexican company, when requesting an invoice, the user is asked to set the invoice to public or not. If the customer is missing a recognized ZIP code or country, setting the…
## Issue
In the POS of a Mexican company, when requesting an invoice, the user is asked to set the invoice to public or not. If the customer is missing a recognized ZIP code or country, setting the invoice to public **should not** raise an error, but it does. This is because the `l10n_mx_edi_cfdi_to_public` field is not correctly updated in the ORM, which leads to the UserError below being triggered, as `l10n_mx_edi_cfdi_to_public` is always set to `False` if it's not updated by its `_compute` method.
https://github.com/odoo/enterprise/blob/dd89c2c72039c9910cc0a303bca332f4103c08f6/l10n_mx_edi/models/account_move_send.py#L54-L55
## Cause
The said field is not properly updated because it is a *compute field*. Such fields are not transferred to the ORM because of the two following conditions from the POS:
1. https://github.com/odoo/odoo/blob/5c2280d089f248dff67df980bee1ce6a4156f2c9/addons/point_of_sale/static/src/app/models/related_models.js#L205-L206
2. https://github.com/odoo/odoo/blob/5c2280d089f248dff67df980bee1ce6a4156f2c9/addons/point_of_sale/static/src/app/models/related_models.js#L895-L896
## Solution
To minimize behavioral changes, the required field (`l10n_mx_edi_cfdi_to_public`) is simply added at the end of the
serialization process.
Once this field is correctly shared with the ORM, the UserError is not longer raised when the *Invoice to Public* field is set to "Yes" in the POS.
## Versions >= 19.1
Since https://github.com/odoo/odoo/pull/216523, the error would only be displayed **after** moving onto the FeedbackScreen. Since then, the validation is only computed after moving the POS to the next screen.
**To correctly prevent the user from confirming an order with invalid data, we now check the constraints everytime the customer or the invoicing method is updated:**
- If a customer is selected, trying to set *"Invoice to public"* to *"No"*
will raise an error if the user does not have a ZIP code and a country set.
- If *"Invoice to public"* is set to *"No"*, trying to remove the current
customer or select a customer with a missing ZIP code or country will raise an error.
## Steps to reproduce the initial error:
1. Install the following app and module:
- Point of Sale (`point_of_sale`)
- Mexican Localization for the Point of Sale (`l10n_mx_edi_pos`)
2. Set the company to a Mexican one (e.g., *ESCUELA KEMPER URGATE*)
3. Open the POS app
4. Open a register
5. Select a product and click *Add*
6. Click *Payment*
7. Set the Customer to a new customer with only a name
(no Country/ZIP Code)
- Click "Cash" to set the Remaining to 0
8. Toggle the *Invoice* button, set the *Invoice to Public* to *"Yes"* and click *Ok*
9. Click *Validate*.
10. An error *"Invalid Operation, CFDI not set to Public"* appears.
opw-5171035
Forward-Port-Of: odoo/enterprise#101365
Forward-Port-Of: odoo/enterprise#99871This update fixes an issue where orders created through the MPS weren't consistently grouped into single RFQs. The change ensures that date formats are handled correctly, preventing the creation of duplicate RFQs and improving order management. This improves the accuracy of RFQ reporting.
Original PR description
Issue ----- Orders created through the MPS aren't grouped in a single RFQ. Steps to reproduce ----- - Create a product with a vendor - Add it to the MPS with the buy route - Change the forecast to 2…
Issue ----- Orders created through the MPS aren't grouped in a single RFQ. Steps to reproduce ----- - Create a product with a vendor - Add it to the MPS with the buy route - Change the forecast to 2 - Order - Change the forecast to 5 - Order - Go to RFQs > There are 2 different RFQs Cause ----- When doing `_run_buy`, no existing PO is found https://github.com/odoo/odoo/blob/98e3020bcffaf449291d1e6664ba613761f37331/addons/purchase_stock/models/stock_rule.py#L102 so a new one gets created. The reason why the existing PO is not found is because we add `date_planned_mps` to the search domain https://github.com/odoo/enterprise/blob/42102423069c2cebbc01eb4d1d8f9b6215358639/mrp_mps/models/stock_rule.py#L10-L15 However, `values['date_planned']` is a datetime.date, whereas `date_planned_mps` is a datetime.datetime in DB. https://github.com/odoo/enterprise/blob/42102423069c2cebbc01eb4d1d8f9b6215358639/mrp_mps/models/purchase_order.py#L10 This poses some problems with timezones, as the client and db dates might differ. We can avoid the problem by converting the date to datetime. ----- Ticket: opw-5171041 Forward-Port-Of: odoo/enterprise#106968
This update significantly speeds up stock forecasting by optimizing how the system calculates product availability. The change reduces processing time from 90 seconds to just 10 seconds, improving the responsiveness of stock reports. This enhancement is crucial for efficient inventory management.
Original PR description
Before this commit, computing `product_availability` and `product_availability_state` required calling the `get_report_lines` method from the `stock.forecasted_product_product` model. In pickings…
Before this commit, computing `product_availability` and `product_availability_state` required calling the `get_report_lines` method from the `stock.forecasted_product_product` model. In pickings containing moves linked to many incoming and outgoing moves, the `reconcile_out_with_ins` function caused performance issues. The reconciliation logic worked as follows: 1. For each `out_move`, attempt to match it with an `in_move` if the `in_move` references the `out_move` in its `move_dests`. 2. If the demand of the `out_move` is not fully satisfied, add it to `unreconciled_outs`. 3. Loop over `unreconciled_outs` (after attempting to reconcile them using the initial prodcedure) to reconcile against the remaining `in_moves`. The performance bottleneck was that even when an `in_move` directly referenced an `out_move`, the code would unnecessarily loop over **all** `in_moves` to filter out the `in_moves` that has the `out_move` in its `move_dest`. --- To improve performance, an **inverse mapping** from `out_move` IDs to their corresponding `in_moves` is introduced. - Reconciliation now starts by iterating only over the relevant `in_moves`. - If the demand is still unmet, the algorithm attempts reconciliation against the remaining `in_moves`. - This reduces the time complexity to **O(N + M)**, since `in_moves` with zero quantities are removed and never revisited. **Implementation details:** - An `OrderedSet` is used for the inverse mapping to preserve the original query order. - Benefits of `OrderedSet`: - **O(1)** removal (assuming no collisions) - Maintains insertion order, ensuring the same order as the query result. --- | Metric | Before PR | After PR | |---------------|-----------|----------| | Execution Time| ~90 sec | ~10 sec | The benchmark above is done on a `stock.picking` record that queried in the `_get_report_lines` method **5331** `out_moves` and **8922** `in_moves`. opw-4951469 Forward-Port-Of: odoo/odoo#235801 Forward-Port-Of: odoo/odoo#224002
This update ensures that shift emails are automatically sent to employees in their preferred language, regardless of the user's language settings. Previously, emails were defaulted to the current user's language, causing confusion. This fix improves communication and user experience for international teams.
Original PR description
Steps to reproduce: ------------------------- 1. Install Planning and Contacts. 2. Install any language other than English (e.g., Arabic). 3. Change an employee's contact language to that language.…
Steps to reproduce: ------------------------- 1. Install Planning and Contacts. 2. Install any language other than English (e.g., Arabic). 3. Change an employee's contact language to that language. 4. Create a shift for that employee and click "Send". 5. Check the message in Settings > Technical > Discuss > Messages. Issue: --------- The email is sent in the language of the current user rather than the language of the employee receiving the shift. Cause: --------- The mail template rendering logic ([_render_lang](https://github.com/odoo/odoo/blob/0dbfa8b99d5c28a7d84e781a7f23b226fd964e95/addons/mail/models/mail_render_mixin.py#L549-L566)) fails to determine a valid language on the planning slot record because it is not directly linked to a `partner_id`. As a result, it falls back to the current user's language. Solution: ------------ Explicitly pass the employee partner's language in the mail context so that the email is sent in the correct language. opw-5928676 Forward-Port-Of: odoo/enterprise#110778 Forward-Port-Of: odoo/enterprise#109619
This update fixes an issue where refund payments were incorrectly created as 'inbound' instead of 'outbound'. When processing refunds with the 'Identify Customer on the Card' payment method, the system now accurately classifies refund payments, ensuring correct accounting and reporting within the invoicing system. This improves the reliability of financial data.
Original PR description
Step to reproduce: - Install point_of_sale - Enable Identify Customer on the Card payment method - Create an order with a customer and refund it - Use Card as the payment method - Close the POS…
Step to reproduce: - Install point_of_sale - Enable Identify Customer on the Card payment method - Create an order with a customer and refund it - Use Card as the payment method - Close the POS session - Go to Invoicing → Customers → Payments Observation: - Two payment records are created - Both payments have payment_type = inbound - The refund payment should be outbound Cause: - When Identify Customer is enabled, `_create_split_account_payment` is used to create payment records - The method does not adjust payment_type for refund transactions Fix: - Add helpers to swap destination and outstanding accounts - Set `force_outstanding_account_id` instead of `outstanding_account_id`, as the former has priority - Ensure refund payments are created as `outbound` few related fix: https://github.com/odoo/odoo/commit/303a9061da85048f14a3ca7b1e13df0ab34da99e https://github.com/odoo/odoo/commit/718fac6832ecd343bf26d41fa5ae5b1ab74f4228 https://github.com/odoo/odoo/commit/684415b9ff2e151506da561016dbfa991bfa8dc8 opw-5437456 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#254079 Forward-Port-Of: odoo/odoo#247760
This update resolves an issue where downpayment products weren't correctly linked to downpayment lines in sales orders. The fix adds the product to the downpayment line during creation, ensuring accurate tracking and settlement of downpayments. This improves the functionality of the POS system.
Original PR description
Step to reproduce - install pos_sale - create a SO (make sure it is in draft) - open pos, make sure it has downpayment product - do a downpayment for that SO - go to backend, open SO Observation: - The downpayment product is not linked to downpayment line Cause: - After refactor [1], downpayment product is not added in sale line [1] https://github.com/odoo/odoo/commit/175daa5db6a3f16be6b636a36e2b8462306b2eb4 Fix: - Added the product when creating downpayment line **Note:** - Actual issue reported was different, and was side effect of this issue - there, the downpayment was not considered when trying to settle SO from pos opw-5934461 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#250548
This update enhances the PEPPOL integration by providing more detailed error messages. Previously, messages were solely based on error codes, making debugging difficult. Now, the system captures and displays the full server error, simplifying troubleshooting and improving the client experience. This change addresses a key issue identified in Schematron validation.
Original PR description
Before this commit, all messages where mapped based on the error code and not from the server error. Schematron/XSD issues really need the full error to make easy for debugging/client. OPW-5980046 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#252252
This update significantly speeds up Odoo's email processing, particularly when handling large volumes of records. The change optimizes how email messages are grouped, reducing processing time by a substantial margin. This results in faster email sending and receiving, improving overall system responsiveness.
Original PR description
opw-5969596 Replace per-record recordset concatenation in _mail_group_by_operation_for_mail_message_operation with an id-first aggregation strategy. Collect ids per access operation, then browse once per operation and restore prefetch. This avoids repeated recordset additions in a loop, which are expensive on large batches. | No. records | Before | After | |------------|--------|-------| | 57,725 | 9,351.744 ms | 143.174 ms | | 1,122 | 4.563 ms | 2.732 ms | | 2,093 | 11.194 ms | 2.747 ms | Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#253048
This update fixes an issue where manually adjusted prices in point-of-sale (POS) settlements weren't being correctly applied. Previously, when settling a quotation, prices were automatically reverted to the base price, regardless of user-defined changes. Now, the system accurately reflects the user's manually set prices during settlement.
Original PR description
**Steps to reproduce:** - Create a product tracked by lot, set it's price to 1000 - Create a quotation add a line with the created product and change the price to 1200 - Add another line with the…
**Steps to reproduce:** - Create a product tracked by lot, set it's price to 1000 - Create a quotation add a line with the created product and change the price to 1200 - Add another line with the same product and change it's price to 600 - Go to PoS and settle this quotation - The lines' prices will be 1000 and 600 instead of 1200 and 600 **Why the fix:** In the event of a settle with a product tracked by lots, we are setting the price of all *related_lines* (lines with the same product in this case) to it's base price, not taking into account the fact that this price has been modified by the user when making the quotation. This only happens for related lines, which explains why one line's price is still 600 while the other was reverted to the base price of 1000 instead of being 1200 as it was previously set. To avoid this, we now set the price_unit back to the base one only if the price hasn't been changed manually. opw-5223463 Forward-Port-Of: odoo/odoo#252480 Forward-Port-Of: odoo/odoo#238295
This update resolves an issue where scanning a packaging barcode didn't correctly associate with the related lot, leading to incorrect inventory tracking. The fix ensures that packaging barcodes are properly linked to lots during scanning, improving the accuracy of stock management.
Original PR description
When scaning a lot after a packaging, the lot won't recognize the packaging and will not work properly ### Steps to reproduce: * In the settings enable packagings * Create a storable product P with…
When scaning a lot after a packaging, the lot won't recognize the packaging and will not work properly ### Steps to reproduce: * In the settings enable packagings * Create a storable product P with Units as uom, a barcode and tracked by lots * Create new lots with barcode for Product P * Inventory > Configuration > Product > Units & Packagings * Click on pack of 6 > Packaging Barcodes > New * Create one for your product with a different barcode * Go to barcode > Operations > eg. internal transfer > New * Scan packaging barcode * Scan one of the lots -> Issue, the lot create a new line, and will not find the packaging ### Observation: When scanning a barcode, it will first try to find a match with existing lines, In our case, it will find a match with the line of the packaging, but since the line is considered as "completed" since there was no expected quantity since we create a new picking: https://github.com/odoo/enterprise/blob/13d815457d47846d5391c9a2dc1ed244ef64b6c4/stock_barcode/static/src/models/barcode_picking_model.js#L1497-L1501 It will erase the line, to avoid to overfill a completed line: https://github.com/odoo/enterprise/blob/13d815457d47846d5391c9a2dc1ed244ef64b6c4/stock_barcode/static/src/models/barcode_model.js#L1459-L1460 and since, it decided to ignore that line, it will not find another lines, and will create a new one : https://github.com/odoo/enterprise/blob/13d815457d47846d5391c9a2dc1ed244ef64b6c4/stock_barcode/static/src/models/barcode_model.js#L1535 Additional Issues ----------------- Issue 1 : When scaning a packaging, lot1, packaging, lot2, all the packagings will be linked to the first lot, which doesn't allow us to scan multiple lots. Issue 2 : When having sublines with different uoms, it will add the quantity without considering the differences in uoms ### Steps to reproduce: * In the settings enable packagings * Create a storable product P with Units as uom, a barcode and tracked by lots * Create new lots with barcode for Product P * Inventory > Configuration > Product > Units & Packagings * Click on pack of 6 > Packaging Barcodes > New * Create one for your product with a different barcode * Create a packaging 2 with barcode for product A * Go to barcode > Operations > eg. internal transfer > New * Scan packaging 1 barcode * Scan one of the lot 1 * Scan packaging 1 * Scan lot 2 -> Issue 1, the packaging 2 will be link to lot 1, it won't be possible to link any packaging to another lot. * Scan packaging 2 -> Issue 2, it create a subline (excpeted), but the sum that appear on the main grouped line is wrong, it doesn't considere the difference in uoms ### Observation: Issue one : When scanning a barcode, it will first try to find a match with existing lines, since the uom is the same it will not be erased by the full line check https://github.com/odoo/enterprise/blob/13d815457d47846d5391c9a2dc1ed244ef64b6c4/stock_barcode/static/src/models/barcode_model.js#L1456-L1460 and since, it found a line, it will just add it's self to the line Issue Two: When creating the group lines it will first calculate the sum of all the quantities: https://github.com/odoo/enterprise/blob/8774388a7b1b2ca2c08c752026ac1a20dbc10347/stock_barcode/static/src/models/barcode_model.js#L248-L254 And after inside of groupSublines it will choose the main line and it's uom and use the previous sum for the total quantity: https://github.com/odoo/enterprise/blob/8774388a7b1b2ca2c08c752026ac1a20dbc10347/stock_barcode/static/src/models/barcode_picking_model.js#L1456-L1461 opw-5189492 opw-5408372 Forward-Port-Of: odoo/enterprise#108666 Forward-Port-Of: odoo/enterprise#98701
4 changes
Resolved issues and error corrections
This update fixes a bug where project timesheets didn't accurately reflect labor costs when changing the employee assigned to a manufacturing order. The fix automatically updates the AAL (analytic accounting line) linked to the work center, ensuring accurate timesheet calculations and reporting. This ensures project costs are correctly tracked.
Original PR description
### Steps to reproduce: - Create an MTO product and another Service product that create a project and task - Create a quotation with both products - Create two employees with different hourly cost - Go to Manufacturing order - Configure an employee to manufacture the product at a work station. - Observe the project dashboard - Go back to the MO and change the employee on the work station - Notice the project dashboard Timesheets section doesn't have any change on the amount ### Cause: This is happening because when changing the employee we don't modify anything in the AAL linked to the work station. As we only modify the AAL when the duration change. ### Fix: We call _create_analytic_entry when we change the employee on the work station to change the amount and the employee_id for the AAL. opw-5939321 Forward-Port-Of: odoo/enterprise#109695
This update fixes a problem causing incorrect stock synchronization for Amazon listings, leading to phantom orders. The fix allows users to manually specify the fulfillment channel (FBA or FBM) for listings, resolving a known Amazon issue and improving order accuracy. This ensures correct inventory management and prevents revenue loss.
Original PR description
When configuring a listing on Amazon Seller Central, the user must choose **one** of the available fulfillment channels that Amazon offers. We distinguish two kinds: Fulfillment by Amazon (FBA) and…
When configuring a listing on Amazon Seller Central, the user must choose **one** of the available fulfillment channels that Amazon offers. We distinguish two kinds: Fulfillment by Amazon (FBA) and Fulfillment by Merchant (FBM). However, Amazon suffers from a known issue of ghost listings. A ghost listing occurs when an offer is presumably sold via FBA, but in fact stores stock information for both FBM and FBA creating unwanted FBM orders. To avoid ghost listings, the first solution was to disable stock synchronization as soon as an offer contained stock in the Amazon location of Odoo. However, if a merchant decided to change the fulfillment channel, it became impossible to sync the stock anymore. See also e7c01c7097d90e731c5408cee4d3595ed810c8fa. To resolve this issue, we decided to use the Amazon API to fetch information about the fulfillment channel of a listing. However, Amazon doesn't give a clear answer for a given listing. Therefore, after some research, the assumption was that an offer was FBM if the listing contained a `merchant_shipping_group`, as the merchant shipping group is a setting specific to FBM listings. See also e6d620e4b200cadabb00ce37ab03289cfeb4ae58. However, this assumption was flawed because Amazon can keep the shipping group even if the listing switches to FBA. This in turn enabled stock synchronization, leading to ghost listings. To fix this issue we give the possibility to users to manually set the correct fulfillment channel of an offer when it becomes ambiguous. opw-5480254 See also: - https://github.com/odoo/upgrade/pull/9692 Forward-Port-Of: odoo/enterprise#106662
This update fixes a problem causing users to receive duplicate push notifications from Social Marketing. The fix ensures the Firebase SDK and service worker work together correctly, preventing redundant popup displays. It also resolves a subscription error, improving push notification reliability across browsers.
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#110823 Forward-Port-Of: odoo/enterprise#96029
This update resolves an issue where tax calculations were incorrect during the reconciliation process for certain journal entries, specifically those involving reverse charges. The fix ensures that tax amounts are accurately reflected in the resulting accounting entries, improving data integrity and financial reporting. This impacts users utilizing the reconciliation feature with specific tax configurations.
Original PR description
## ISSUE 1: **Steps to reproduce [l10n_be easier]:** - Create a journal entry: ``` 440 : supplier 0 300 False 499 : suspense account 300 0 False ``` - Accounting > Reconcile: select the entry and in…
## ISSUE 1: **Steps to reproduce [l10n_be easier]:** - Create a journal entry: ``` 440 : supplier 0 300 False 499 : suspense account 300 0 False ``` - Accounting > Reconcile: select the entry and in the wizard > account 600 tax 12% (purchase) - Validate - Check the last entry created **Issue:** There is no invert tag set on the tax line **Cause:** The tax repartition line was not propagated in the rec wizard, therefore in https://github.com/odoo/odoo/blob/a456d9c7cbdf17edb5db2c73306b62150e46a7a7/addons/account/models/account_move_line.py#L814-L815 The line was never set to properly (same of is_refund) ## ISSUE2: **Steps to reproduce:** - create a journal entry ``` 440 : supplier 0 300 False 499 : suspense account 300 0 False ``` - Accounting > Reconcile: select the entry and in the wizard > account 600 tax 21% EU M (Purchases) - Validate - Check the last entry created **Issue:** No issue in 17.0. But we added the test to cover the flow. A fix for this issue will be applied as of 18.0. opw-4976780 Forward-Port-Of: odoo/enterprise#93839 Forward-Port-Of: odoo/enterprise#92556
17 changes
Resolved issues and error corrections
This update ensures that shift notifications are automatically sent to employees in their preferred language, regardless of the user's language settings. Previously, emails were defaulted to the current user's language, causing confusion. This fix improves communication and user experience for international teams.
Original PR description
Steps to reproduce: ------------------------- 1. Install Planning and Contacts. 2. Install any language other than English (e.g., Arabic). 3. Change an employee's contact language to that language.…
Steps to reproduce: ------------------------- 1. Install Planning and Contacts. 2. Install any language other than English (e.g., Arabic). 3. Change an employee's contact language to that language. 4. Create a shift for that employee and click "Send". 5. Check the message in Settings > Technical > Discuss > Messages. Issue: --------- The email is sent in the language of the current user rather than the language of the employee receiving the shift. Cause: --------- The mail template rendering logic ([_render_lang](https://github.com/odoo/odoo/blob/0dbfa8b99d5c28a7d84e781a7f23b226fd964e95/addons/mail/models/mail_render_mixin.py#L549-L566)) fails to determine a valid language on the planning slot record because it is not directly linked to a `partner_id`. As a result, it falls back to the current user's language. Solution: ------------ Explicitly pass the employee partner's language in the mail context so that the email is sent in the correct language. opw-5928676 Forward-Port-Of: odoo/enterprise#110778 Forward-Port-Of: odoo/enterprise#109619
This update resolves an issue preventing new employee creation when generating BVG-LLP reports. The fix addresses a technical problem within Odoo's reporting system related to how it handles multiple report records with the same month, preventing a critical error. This ensures employees can be correctly created within the Swiss payroll process.
Original PR description
Steps to reproduce: ---------------------------------- 1. Install `l10n_ch_hr_payroll_elm_transmission` module 2. Switch to Swiss company 3. Navigate to Payroll > Transmission > BVG-LLP Basis…
Steps to reproduce:
----------------------------------
1. Install `l10n_ch_hr_payroll_elm_transmission` module
2. Switch to Swiss company
3. Navigate to Payroll > Transmission > BVG-LLP Basis Declaration
4. Create two Reports with same Year and Month
5. Now try to create new Employee from the employee app
Observation:
----------------------------------
Tracaback Occurs:
```
File '/home/odoo/src/enterprise/19.0/l10n_ch_hr_payroll/models/l10n_ch_employee_monthly_values.py', line 319, in _compute_bvg_lpp_annual_basis
existing_declaration = max(existing_declaration, key=lambda r: r.month) if existing_declaration else False
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File '/home/odoo/src/odoo/19.0/odoo/orm/models.py', line 5934, in ensure_one
raise ValueError('Expected singleton: %s' % self)
ValueError: Expected singleton: l10n.ch.lpp.basis.report(1, 2)
```
Issue:
----------------------------------
In the following code:
https://github.com/odoo/enterprise/blob/44a26539093f9313d9cd5f823c11866e3c98ec97/l10n_ch_hr_payroll_elm_transmission/models/l10n_ch_employee_monthly_values.py#L319-L320
Python's max() function doesn't just call the key function once per item. When there are ties (equal key values), it may need to compare the original objects, and during this process, Odoo's recordset operations combine records, causing the lambda receives `r` as a combined recordset. To access `.month` on a multi-record recordset it gives singleton error.
Solution:
----------------------------------
Creates tuples of (month, recordset) pairs and uses max() to compare month integers directly, avoiding the singleton error.
opw-5391742
Forward-Port-Of: odoo/enterprise#102335This update resolves an issue where the bulk payment feature would crash if a bank account wasn't linked. A new user message now alerts users to ensure their payment journal is connected to a bank before checking batch status, improving the user experience and preventing errors.
Original PR description
This commit: https://github.com/odoo/enterprise/commit/c9cc89f58f7d98396afac3bdacfeff9b00a02a21 introduce the initiate bulk payments feature. When selecting a batch you can also check the status of this batch. But for the moment, if you select a batch that is not connected to a bank, the action will traceback with a redirect. This commit will add a user error to warn the user than the journal needs to be connected to a bank. task-6009083 Forward-Port-Of: odoo/enterprise#110474 Forward-Port-Of: odoo/enterprise#109956
This update simplifies invoice processing by automatically enabling self-billing for all users within the Odoo system. Previously, this feature required a separate module. Additionally, the xRechung functionality has been removed, ensuring invoices are only sent to government entities as intended.
Original PR description
Everybody is now able to receive self billing invoices even without the additional module. So the service should be added to the base module. Also remove xRechung because users are not supposed to receive it, only government. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#254341
This update resolves an issue where the delivery process would fail if Sendcloud, our shipping provider, didn't respond to a request for shipping prices. The fix prevents a system error (traceback) from occurring, ensuring smoother and more reliable delivery processing. This improvement enhances the overall reliability of our shipping functionality.
Original PR description
Sendcloud sometimes doesn't respod when asking for `shipping-price`. So when we try to retrieve the first element of the response, we raise an `IndexError`. ----- Ticket: opw-5951749 Forward-Port-Of: odoo/enterprise#109252
This update fixes an issue where sales order margins were incorrectly calculated due to a misunderstanding of the product's cost method. The fix ensures margins are accurately determined based on the company associated with the sales order line, regardless of the user's default company setting. This improves the reliability of margin reporting.
Original PR description
Steps to reproduce: - Have 2 companies: - Company A with a property_cost_method 'average' - Company B with a property_cost_method 'standard' - Create a sales order in B - Set the default company of the user to A. - Under certain scenarios, when we confirm the sales order, there will be a `flush_all`. - When that's the case, margins are recomputed with `line.product_id.categ_id.property_cost_method` as `average` instead of `standard`. In other words, it will take the property_cost_method from the `user.company_id` (A), instead of the property_cost_method from the `line.company_id` (B). This fix ensures the `property_cost_method` considered is the one related to the company of the sale order line. A similar issue was fixed on https://github.com/odoo/odoo/pull/192890 OPW-5939464 Forward-Port-Of: odoo/odoo#253764 Forward-Port-Of: odoo/odoo#252161
This update resolves issues with how invoices handle discounts and down payments when submitting data to the Viettel system. Specifically, it corrects errors caused by negative values and ensures that note lines are now correctly included in the invoice submission process. This improves the accuracy and reliability of invoice data transmission.
Original PR description
Previously, the invoice logic did not properly handle the following scenarios: - Global discount: when a global discount was applied, negative values were sent to Sinvoice, resulting in a BAD_REQUEST_ITEM_VALUES_NEGATIVE error. - Down payment: when an invoice included a down payment to deduct the amount, negative values were sent to Sinvoice, triggering the same BAD_REQUEST_ITEM_VALUES_NEGATIVE error. - Note lines: note lines on the invoice were not being uploaded/included in the invoice submission. This commit fixes the handling of global discounts and down payments by ensuring negative values are properly transformed before being sent to Sinvoice, and adds support for uploading note lines in the invoice. task-5875158 Forward-Port-Of: odoo/odoo#253867 Forward-Port-Of: odoo/odoo#251913
This update corrects a problem causing incorrect stock synchronization for Amazon listings, specifically addressing 'ghost listings' that led to unwanted orders. The fix allows users to manually specify the fulfillment channel (FBA or FBM) for listings, resolving a previous flawed assumption and improving order accuracy.
Original PR description
When configuring a listing on Amazon Seller Central, the user must choose **one** of the available fulfillment channels that Amazon offers. We distinguish two kinds: Fulfillment by Amazon (FBA) and…
When configuring a listing on Amazon Seller Central, the user must choose **one** of the available fulfillment channels that Amazon offers. We distinguish two kinds: Fulfillment by Amazon (FBA) and Fulfillment by Merchant (FBM). However, Amazon suffers from a known issue of ghost listings. A ghost listing occurs when an offer is presumably sold via FBA, but in fact stores stock information for both FBM and FBA creating unwanted FBM orders. To avoid ghost listings, the first solution was to disable stock synchronization as soon as an offer contained stock in the Amazon location of Odoo. However, if a merchant decided to change the fulfillment channel, it became impossible to sync the stock anymore. See also e7c01c7097d90e731c5408cee4d3595ed810c8fa. To resolve this issue, we decided to use the Amazon API to fetch information about the fulfillment channel of a listing. However, Amazon doesn't give a clear answer for a given listing. Therefore, after some research, the assumption was that an offer was FBM if the listing contained a `merchant_shipping_group`, as the merchant shipping group is a setting specific to FBM listings. See also e6d620e4b200cadabb00ce37ab03289cfeb4ae58. However, this assumption was flawed because Amazon can keep the shipping group even if the listing switches to FBA. This in turn enabled stock synchronization, leading to ghost listings. To fix this issue we give the possibility to users to manually set the correct fulfillment channel of an offer when it becomes ambiguous. opw-5480254 See also: - https://github.com/odoo/upgrade/pull/9692 Forward-Port-Of: odoo/enterprise#106662
This update fixes a problem causing users to see multiple notification popups when receiving push notifications through Social Marketing. The fix ensures notifications are displayed correctly across browsers and resolves a subscription error, improving the overall 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#110823 Forward-Port-Of: odoo/enterprise#96029
This update resolves an issue where the Public Administration (PA) invoice status wasn't correctly updated after SDI validation, leading to potential rejection errors. The fix ensures the system accurately reflects the invoice's state, improving the reliability of the Italian tax reporting process. This change impacts the l10n_it_edi module.
Original PR description
### Issue: After the SDI validation, the state was never updated to match the PA state, resulting in a mismatch with the actual status ### Cause: When `l10n_it_edi_state` is set to `forwarded`, the cron `cron_l10n_it_edi_download_and_update` doesn't consider that a new state could occur However, invoices sent to Public Administration can still be rejected after being forwarded It is not possible to reproduce the issue with the demo system, as it only sets the state to `forwarded` Ticket [link](https://www.odoo.com/odoo/project.task/5391891) opw-5391891 Forward-Port-Of: odoo/odoo#253525
This update resolves an issue where downpayment invoices generated with fixed taxes incorrectly lacked tax line items. This prevented proper invoice generation for Peppol compliance, leading to errors. The fix removes the problematic downpayment processing related to fixed taxes, ensuring accurate invoice creation.
Original PR description
When making a downpayment for an order containing product using fixed taxes, the downpayment invoice would contain line without tax associated This is an issue when sending these invoices to Peppol. Steps to reproduce: ------------------- * Create a fixed tax of 5€ * Set this tax on any product along another tax * Create a sale order for this product * Make a downpayment of 10% * The invoice created has a line without any tax set > Observation: When sending to Peppol we get an error Why the fix: ------------ We remove the downpayment part that concerns fixed tax to avoid having lines without tax set. opw-5853070
This update prevents users from deleting tax groups that are currently in use within the system. Previously, deleting a tax group could cause errors. Now, a validation error is displayed, ensuring data integrity and preventing potential issues with financial reporting. This change improves the stability and reliability of the accounting module.
Original PR description
Before this PR: - Group of taxes can be deleted by a user, even if they are used. After this PR: - If a user tries to delete a group of taxes in use, a validation error is raised. - Fixed a test case in POS and deactivated the tax instead of deleting the tax. Related PR: https://github.com/odoo/enterprise/pull/105174 task-5472834
This update resolves an issue where tax calculations were incorrect during the reconciliation process for certain journal entries, specifically those involving reverse charges. The fix ensures that tax amounts are accurately reflected in the reconciled entries, improving financial reporting accuracy. This primarily impacts users utilizing the VAT (Value Added Tax) reconciliation feature.
Original PR description
## ISSUE 1: **Steps to reproduce [l10n_be easier]:** - Create a journal entry: ``` 440 : supplier 0 300 False 499 : suspense account 300 0 False ``` - Accounting > Reconcile: select the entry and in…
## ISSUE 1: **Steps to reproduce [l10n_be easier]:** - Create a journal entry: ``` 440 : supplier 0 300 False 499 : suspense account 300 0 False ``` - Accounting > Reconcile: select the entry and in the wizard > account 600 tax 12% (purchase) - Validate - Check the last entry created **Issue:** There is no invert tag set on the tax line **Cause:** The tax repartition line was not propagated in the rec wizard, therefore in https://github.com/odoo/odoo/blob/a456d9c7cbdf17edb5db2c73306b62150e46a7a7/addons/account/models/account_move_line.py#L814-L815 The line was never set to properly (same of is_refund) ## ISSUE2: **Steps to reproduce:** - create a journal entry ``` 440 : supplier 0 300 False 499 : suspense account 300 0 False ``` - Accounting > Reconcile: select the entry and in the wizard > account 600 tax 21% EU M (Purchases) - Validate - Check the last entry created **Issue:** No issue in 17.0. But we added the test to cover the flow. A fix for this issue will be applied as of 18.0. opw-4976780 Forward-Port-Of: odoo/enterprise#93839 Forward-Port-Of: odoo/enterprise#92556
This update resolves a problem where the system incorrectly flagged invoices for EC Sales List compliance checks when customers were registered as intra-EU. The fix ensures that the system accurately identifies and reports on invoices related to intra-EU sales, improving data accuracy and compliance.
Original PR description
The EC Sales List return check "Only intra-EU customers" is reviewed when an invoice that match the condition for the warning same_country is present. To Reproduce: - Create a company in Belgium - Create a customer in Belgium with "Intra-Community" as a Fiscal Position - Create an invoice with this customer (in the previous month of the current month, for example February if the current date is in March - Open the Tax Returns - Open the EC Sales List Return - The Only intra-EU customers check is reviewed when it should show an anomaly.
This update resolves an issue where component consumption in manufacturing orders wasn't working correctly, leading to incorrect quantity updates and a missing warning message. The fix ensures that component stock is accurately tracked and consumed during the production process, improving the reliability of manufacturing operations.
Original PR description
# Product Configuration *Manufactured Product* - Storable - Tracked by Quantity - Manufacture Route - Has a BOM with atleast 1 component *Component Product* - Storable - Tracked By Lot # How to…
# Product Configuration
*Manufactured Product*
- Storable
- Tracked by Quantity
- Manufacture Route
- Has a BOM with atleast 1 component
*Component Product*
- Storable
- Tracked By Lot
# How to reproduce
- Ensure there is available stock for the component product in a lot
- Create a MO for the Manufatured Product
- Confirm the MO
- Click "Details" on the component product
- Remove the reserved quant and add a new one
- Increase the quantity of this new quant to more than "To Consume"
- Save
- Observe that "Consumed" = The quantity you just set on the quant
- Click on "Produce All"
# The issue
- The Consumed quantity is reset to the "To Consume" quantity.
- Furthermore, a warning popup should be displayed when clicking on "Produce All" but there is none.
- Finally, depending on the version you may get this error message : "You need to supply Lot/Serial Number for products and 'consume' them: - Component Product" even though a lot is already assigned
# Why
All these issues stem from the fact that move_raw_ids.picked from mrp.production is set to False instead of True.
This issue was introduced by this commit (https://github.com/odoo/odoo/commit/ef592464983d66ac76bc71a9886462f1f47dc28d) that changed the way the picked value is set.
In write(self, vals) de stock_move, we have :
```py
if self.env.context.get('force_manual_consumption') and 'quantity' in vals:
moves_to_update = self.filtered(lambda move: move.product_uom_qty != vals['quantity'])
if moves_to_update:
moves_to_update.write({'manual_consumption': True, 'picked': True})
```
Followed a bit later by :
```py
res = super().write(vals)
```
This usually works fine except when vals contains edition commands for move_line_ids. Then, the first write will correclty set picked to True, but then picked will be reevaluted after the second write with :
```py
@api.depends('move_line_ids.picked', 'state')
def _compute_picked(self):
for move in self:
if move.state == 'done' or any(ml.picked for ml in move.move_line_ids):
move.picked = True
else:
move.picked = False
```
If all the resulting move_line_ids from the commands edition have picked set to False, then move.picked will also be set to False.
opw-5937171
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prThis update corrects an issue where incorrect folio numbering occurred when Chilean accounting (l10n_cl_edi) wasn't configured. The fix ensures folios are properly generated, preventing negative numbering and associated sequence corruption, which could have caused errors in financial reporting. This improves data accuracy and reliability for Chilean operations.
Original PR description
`l10n_cl_edi` overrides `account.move._get_last_sequence()` to ensure the folio belongs to an available in-use CAF. When no CAF exists at all, `l10n_latam.document.type._get_start_number()` returns 0 and the fallback builds a previous sequence using start_nb - 1. Formatting -1 as `:06d` yields “-00001”, which then propagates to “FAC -00002”, “-00003” and corrupts the sequence chain. In addition, returning an invalid “last sequence” may force `sequence.mixin` to search for a free number under the UNIQUE constraint by retrying increments inside a savepoint and rolling back on UniqueViolation, which is costly when many values are already taken see [ _locked_increment()](https://github.com/odoo/odoo/blob/18.0/addons/account/models/sequence_mixin.py#L352). Now we only reset to the CAF start when an in-use CAF actually exists (start_nb > 0). opw-5918758 Forward-Port-Of: odoo/enterprise#108909
This update resolves an issue where Odoo incorrectly generated UBL/QR invoices for customers in other countries (like Colombia). By defaulting the receiver identification type to '0', the system now creates valid XMLs that meet SUNAT requirements, ensuring accurate invoice processing for multi-country businesses.
Original PR description
In multi-country databases, a Peruvian company can invoice a foreign customer (e.g., a Colombian company) whose identification type is defined by another localization. Those records typically have an…
In multi-country databases, a Peruvian company can invoice a foreign customer (e.g., a Colombian company) whose identification type is defined by another localization. Those records typically have an empty l10n_pe_vat_code, since there are no cross-country dependencies between LATAM identification types. In that case, the generated UBL leaves the receiver identity type empty and SUNAT returns an error like: ``` 2015/2015 - El XML no contiene el tag o no existe informacion del tipo de documento de identidad del receptor... (missing schemeID value). ``` Odoo already defines schemeID = 0 for some foreign identification types in l10n_pe data, but it cannot cover identification types coming from other countries’ localizations (e.g. Colombia): https://github.com/odoo/odoo/blob/18.0/addons/l10n_pe/data/l10n_latam_identification_type_data.xml#L4 This change ensures that, when the partner is not from Peru and the PE VAT code is missing, we fallback the receiver identification type to "0" in: - PartyIdentification/ID/@schemeID - AccountingCustomerParty/AdditionalAccountID - the QR payload identification type field This prevents generating invalid UBL/QR content for foreign customers in multi-country setups. Forward-Port-Of: odoo/enterprise#105115
10 changes
Resolved issues and error corrections
This update ensures that NACHA payment files use the correct bank account holder's name instead of the customer's name in Odoo. Prioritizing the account holder name improves payment accuracy and compliance with NACHA regulations, preventing potential payment processing issues.
Original PR description
The NACHA entry detail was using the partner's name (res.partner.name) for the Individual Name field. This should instead prioritize the Account Holder Name (acc_holder_name) from the bank account, as this reflects the actual name on the bank account which may differ from the partner's name in Odoo. The code now uses bank.acc_holder_name if set, and falls back to payment.partner_id.name if not set. Forward-Port-Of: odoo/enterprise#108414 Forward-Port-Of: odoo/enterprise#105582
This update resolves an issue where night shift slots (e.g., 20PM - 4AM) weren't visible in the weekly planning view. The fix adjusts how the system calculates display hours for multi-day shifts, ensuring all scheduled time is accurately represented. This improves the planning experience for employees with flexible work arrangements.
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 Forward-Port-Of: odoo/enterprise#99784
This update fixes a bug where project timesheets didn't accurately reflect changes in employee costs when switching workers on a manufacturing order. The fix ensures that the AAL (analytic accounting line) associated with the work center is updated correctly, accurately tracking labor costs in the project dashboard. This ensures accurate project costing and reporting.
Original PR description
### Steps to reproduce: - Create an MTO product and another Service product that create a project and task - Create a quotation with both products - Create two employees with different hourly cost - Go to Manufacturing order - Configure an employee to manufacture the product at a work station. - Observe the project dashboard - Go back to the MO and change the employee on the work station - Notice the project dashboard Timesheets section doesn't have any change on the amount ### Cause: This is happening because when changing the employee we don't modify anything in the AAL linked to the work station. As we only modify the AAL when the duration change. ### Fix: We call _create_analytic_entry when we change the employee on the work station to change the amount and the employee_id for the AAL. opw-5939321 Forward-Port-Of: odoo/enterprise#109695
This update ensures that shift notifications are automatically sent to employees in their preferred language, regardless of the user's language settings. Previously, emails were defaulted to the current user's language, causing confusion. This fix improves communication and user experience for international teams.
Original PR description
Steps to reproduce: ------------------------- 1. Install Planning and Contacts. 2. Install any language other than English (e.g., Arabic). 3. Change an employee's contact language to that language.…
Steps to reproduce: ------------------------- 1. Install Planning and Contacts. 2. Install any language other than English (e.g., Arabic). 3. Change an employee's contact language to that language. 4. Create a shift for that employee and click "Send". 5. Check the message in Settings > Technical > Discuss > Messages. Issue: --------- The email is sent in the language of the current user rather than the language of the employee receiving the shift. Cause: --------- The mail template rendering logic ([_render_lang](https://github.com/odoo/odoo/blob/0dbfa8b99d5c28a7d84e781a7f23b226fd964e95/addons/mail/models/mail_render_mixin.py#L549-L566)) fails to determine a valid language on the planning slot record because it is not directly linked to a `partner_id`. As a result, it falls back to the current user's language. Solution: ------------ Explicitly pass the employee partner's language in the mail context so that the email is sent in the correct language. opw-5928676 Forward-Port-Of: odoo/enterprise#110778 Forward-Port-Of: odoo/enterprise#109619
This update resolves an issue preventing new employee creation when generating the BVG-LLP Basis Declaration report. The fix addresses a technical problem with how Odoo compares report records, ensuring the system correctly handles multiple reports with the same month.
Original PR description
Steps to reproduce: ---------------------------------- 1. Install `l10n_ch_hr_payroll_elm_transmission` module 2. Switch to Swiss company 3. Navigate to Payroll > Transmission > BVG-LLP Basis…
Steps to reproduce:
----------------------------------
1. Install `l10n_ch_hr_payroll_elm_transmission` module
2. Switch to Swiss company
3. Navigate to Payroll > Transmission > BVG-LLP Basis Declaration
4. Create two Reports with same Year and Month
5. Now try to create new Employee from the employee app
Observation:
----------------------------------
Tracaback Occurs:
```
File '/home/odoo/src/enterprise/19.0/l10n_ch_hr_payroll/models/l10n_ch_employee_monthly_values.py', line 319, in _compute_bvg_lpp_annual_basis
existing_declaration = max(existing_declaration, key=lambda r: r.month) if existing_declaration else False
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File '/home/odoo/src/odoo/19.0/odoo/orm/models.py', line 5934, in ensure_one
raise ValueError('Expected singleton: %s' % self)
ValueError: Expected singleton: l10n.ch.lpp.basis.report(1, 2)
```
Issue:
----------------------------------
In the following code:
https://github.com/odoo/enterprise/blob/44a26539093f9313d9cd5f823c11866e3c98ec97/l10n_ch_hr_payroll_elm_transmission/models/l10n_ch_employee_monthly_values.py#L319-L320
Python's max() function doesn't just call the key function once per item. When there are ties (equal key values), it may need to compare the original objects, and during this process, Odoo's recordset operations combine records, causing the lambda receives `r` as a combined recordset. To access `.month` on a multi-record recordset it gives singleton error.
Solution:
----------------------------------
Creates tuples of (month, recordset) pairs and uses max() to compare month integers directly, avoiding the singleton error.
opw-5391742
Forward-Port-Of: odoo/enterprise#102335This update ensures that all attendees of appointments – internal users and organizers – receive booking notifications, regardless of whether the booking syncs with Google or Outlook. Previously, notifications were limited, but this change ensures consistent communication for all involved parties.
Original PR description
In [1] we prevented cancelation emails from being sent when the booking was synced via google or outlook calendar. However this means even followers who would not be notified by the mail provider (not assisting to the meeting) would not be notified. As well as the organizer who is doing to booking/cancelling from the perspective of the mail provider, as the meeting is created from their account. Instead we should keep sending the "appointment booked" template in all cases as it is only followed by internal users to whom it is always relevant. As for cancelation templates, it should stil be sent to internal users. Partners of the meeting however need not be notified and may be unsubscribed if syncing is enabled, as cancellation typically only happens once. task-5152917 [1]: https://github.com/odoo/enterprise/pull/60913 Forward-Port-Of: odoo/enterprise#96638
This update resolves an issue where tax calculations were incorrect during the reconciliation process for certain journal entries, specifically those involving reverse charges. The fix ensures that tax amounts are accurately reflected in the reconciled entries, improving financial reporting accuracy. This impacts users utilizing the reconciliation feature within the Enterprise edition.
Original PR description
## ISSUE 1: **Steps to reproduce [l10n_be easier]:** - Create a journal entry: ``` 440 : supplier 0 300 False 499 : suspense account 300 0 False ``` - Accounting > Reconcile: select the entry and in…
## ISSUE 1: **Steps to reproduce [l10n_be easier]:** - Create a journal entry: ``` 440 : supplier 0 300 False 499 : suspense account 300 0 False ``` - Accounting > Reconcile: select the entry and in the wizard > account 600 tax 12% (purchase) - Validate - Check the last entry created **Issue:** There is no invert tag set on the tax line **Cause:** The tax repartition line was not propagated in the rec wizard, therefore in https://github.com/odoo/odoo/blob/a456d9c7cbdf17edb5db2c73306b62150e46a7a7/addons/account/models/account_move_line.py#L814-L815 The line was never set to properly (same of is_refund) ## ISSUE2: **Steps to reproduce:** - create a journal entry ``` 440 : supplier 0 300 False 499 : suspense account 300 0 False ``` - Accounting > Reconcile: select the entry and in the wizard > account 600 tax 21% EU M (Purchases) - Validate - Check the last entry created **Issue:** No issue in 17.0. But we added the test to cover the flow. A fix for this issue will be applied as of 18.0. opw-4976780 Forward-Port-Of: odoo/enterprise#93839 Forward-Port-Of: odoo/enterprise#92556
This update corrects a problem causing incorrect stock synchronization for Amazon listings, leading to phantom orders. The fix allows users to manually specify the fulfillment channel (FBA or FBM) for listings, resolving a known 'ghost listing' issue. This ensures accurate stock management and order fulfillment.
Original PR description
When configuring a listing on Amazon Seller Central, the user must choose **one** of the available fulfillment channels that Amazon offers. We distinguish two kinds: Fulfillment by Amazon (FBA) and…
When configuring a listing on Amazon Seller Central, the user must choose **one** of the available fulfillment channels that Amazon offers. We distinguish two kinds: Fulfillment by Amazon (FBA) and Fulfillment by Merchant (FBM). However, Amazon suffers from a known issue of ghost listings. A ghost listing occurs when an offer is presumably sold via FBA, but in fact stores stock information for both FBM and FBA creating unwanted FBM orders. To avoid ghost listings, the first solution was to disable stock synchronization as soon as an offer contained stock in the Amazon location of Odoo. However, if a merchant decided to change the fulfillment channel, it became impossible to sync the stock anymore. See also e7c01c7097d90e731c5408cee4d3595ed810c8fa. To resolve this issue, we decided to use the Amazon API to fetch information about the fulfillment channel of a listing. However, Amazon doesn't give a clear answer for a given listing. Therefore, after some research, the assumption was that an offer was FBM if the listing contained a `merchant_shipping_group`, as the merchant shipping group is a setting specific to FBM listings. See also e6d620e4b200cadabb00ce37ab03289cfeb4ae58. However, this assumption was flawed because Amazon can keep the shipping group even if the listing switches to FBA. This in turn enabled stock synchronization, leading to ghost listings. To fix this issue we give the possibility to users to manually set the correct fulfillment channel of an offer when it becomes ambiguous. opw-5480254 See also: - https://github.com/odoo/upgrade/pull/9692 Forward-Port-Of: odoo/enterprise#106662
This update corrects an issue where incorrect folio numbering occurred when a Chilean Accounting (l10n_cl_edi) configuration was not set up. The fix ensures that folios are generated correctly, avoiding potential errors and disruptions in accounting processes. This improves data accuracy and reliability for Chilean clients.
Original PR description
`l10n_cl_edi` overrides `account.move._get_last_sequence()` to ensure the folio belongs to an available in-use CAF. When no CAF exists at all, `l10n_latam.document.type._get_start_number()` returns 0 and the fallback builds a previous sequence using start_nb - 1. Formatting -1 as `:06d` yields “-00001”, which then propagates to “FAC -00002”, “-00003” and corrupts the sequence chain. In addition, returning an invalid “last sequence” may force `sequence.mixin` to search for a free number under the UNIQUE constraint by retrying increments inside a savepoint and rolling back on UniqueViolation, which is costly when many values are already taken see [ _locked_increment()](https://github.com/odoo/odoo/blob/18.0/addons/account/models/sequence_mixin.py#L352). Now we only reset to the CAF start when an in-use CAF actually exists (start_nb > 0). opw-5918758 Forward-Port-Of: odoo/enterprise#108909
This update resolves an issue where Odoo generated invalid UBL/QR invoices for foreign customers. Specifically, it ensures the receiver identification type defaults to '0' when a Peruvian company invoices a customer with a foreign identification type, preventing errors from the Peruvian tax authority (SUNAT). This ensures proper invoice generation and compliance for multi-country operations.
Original PR description
In multi-country databases, a Peruvian company can invoice a foreign customer (e.g., a Colombian company) whose identification type is defined by another localization. Those records typically have an…
In multi-country databases, a Peruvian company can invoice a foreign customer (e.g., a Colombian company) whose identification type is defined by another localization. Those records typically have an empty l10n_pe_vat_code, since there are no cross-country dependencies between LATAM identification types. In that case, the generated UBL leaves the receiver identity type empty and SUNAT returns an error like: ``` 2015/2015 - El XML no contiene el tag o no existe informacion del tipo de documento de identidad del receptor... (missing schemeID value). ``` Odoo already defines schemeID = 0 for some foreign identification types in l10n_pe data, but it cannot cover identification types coming from other countries’ localizations (e.g. Colombia): https://github.com/odoo/odoo/blob/18.0/addons/l10n_pe/data/l10n_latam_identification_type_data.xml#L4 This change ensures that, when the partner is not from Peru and the PE VAT code is missing, we fallback the receiver identification type to "0" in: - PartyIdentification/ID/@schemeID - AccountingCustomerParty/AdditionalAccountID - the QR payload identification type field This prevents generating invalid UBL/QR content for foreign customers in multi-country setups. Forward-Port-Of: odoo/enterprise#105115
14 changes
Resolved issues and error corrections
This update resolves several issues within the timesheet grid component, primarily focusing on the systray interface. Key improvements include fixing display errors, enhancing usability with expanded descriptions and clearer labels, and streamlining the user experience for time entry and record management.
Original PR description
Task-5956044 Forward-Port-Of: odoo/enterprise#109651
This update resolves an issue where the Point of Sale system in Mexico incorrectly flagged invoices as invalid when the customer was missing a ZIP code or country. The fix ensures the 'Invoice to Public' setting is correctly transmitted to the ORM, preventing the error and allowing users to properly set invoices to public status.
Original PR description
## Issue In the POS of a Mexican company, when requesting an invoice, the user is asked to set the invoice to public or not. If the customer is missing a recognized ZIP code or country, setting the…
## Issue
In the POS of a Mexican company, when requesting an invoice, the user is asked to set the invoice to public or not. If the customer is missing a recognized ZIP code or country, setting the invoice to public **should not** raise an error, but it does. This is because the `l10n_mx_edi_cfdi_to_public` field is not correctly updated in the ORM, which leads to the UserError below being triggered, as `l10n_mx_edi_cfdi_to_public` is always set to `False` if it's not updated by its `_compute` method.
https://github.com/odoo/enterprise/blob/dd89c2c72039c9910cc0a303bca332f4103c08f6/l10n_mx_edi/models/account_move_send.py#L54-L55
## Cause
The said field is not properly updated because it is a *compute field*. Such fields are not transferred to the ORM because of the two following conditions from the POS:
1. https://github.com/odoo/odoo/blob/5c2280d089f248dff67df980bee1ce6a4156f2c9/addons/point_of_sale/static/src/app/models/related_models.js#L205-L206
2. https://github.com/odoo/odoo/blob/5c2280d089f248dff67df980bee1ce6a4156f2c9/addons/point_of_sale/static/src/app/models/related_models.js#L895-L896
## Solution
To minimize behavioral changes, the required field (`l10n_mx_edi_cfdi_to_public`) is simply added at the end of the
serialization process.
Once this field is correctly shared with the ORM, the UserError is not longer raised when the *Invoice to Public* field is set to "Yes" in the POS.
## Versions >= 19.1
Since https://github.com/odoo/odoo/pull/216523, the error would only be displayed **after** moving onto the FeedbackScreen. Since then, the validation is only computed after moving the POS to the next screen.
**To correctly prevent the user from confirming an order with invalid data, we now check the constraints everytime the customer or the invoicing method is updated:**
- If a customer is selected, trying to set *"Invoice to public"* to *"No"*
will raise an error if the user does not have a ZIP code and a country set.
- If *"Invoice to public"* is set to *"No"*, trying to remove the current
customer or select a customer with a missing ZIP code or country will raise an error.
## Steps to reproduce the initial error:
1. Install the following app and module:
- Point of Sale (`point_of_sale`)
- Mexican Localization for the Point of Sale (`l10n_mx_edi_pos`)
2. Set the company to a Mexican one (e.g., *ESCUELA KEMPER URGATE*)
3. Open the POS app
4. Open a register
5. Select a product and click *Add*
6. Click *Payment*
7. Set the Customer to a new customer with only a name
(no Country/ZIP Code)
- Click "Cash" to set the Remaining to 0
8. Toggle the *Invoice* button, set the *Invoice to Public* to *"Yes"* and click *Ok*
9. Click *Validate*.
10. An error *"Invalid Operation, CFDI not set to Public"* appears.
opw-5171035
Forward-Port-Of: odoo/enterprise#101365
Forward-Port-Of: odoo/enterprise#99871This update restores essential VAT checks within the Belgian tax reporting module, addressing previous issues that caused warnings during XML uploads to Intervat. A new check has been added to ensure returns only pass if all VAT validation warnings are cleared, improving data accuracy and compliance.
Original PR description
Since the implementation of returns, some VAT checks were no longer being executed. This led to warnings when uploading the XML to Intervat. To catch these issues beforehand, this commit: - Restores the warning checks directly on the report. - Adds a new check on the VAT return that passes only if no warnings are raised. task-5883037 Forward-Port-Of: odoo/enterprise#107152
This update fixes an issue where reporting queries were using outdated currency rates, leading to inaccurate financial reports. The change ensures that the correct, same-day currency rate is used in all CTA queries, improving the reliability and accuracy of financial data. This impacts the trial balance and other account reports.
Original PR description
We use currency rate at day x - 1 to be applicable at a date x, which shouldn't be applicable in the cta queries. Use same-day rate for the CTA query. task-5969168 Forward-Port-Of: odoo/enterprise#108879
This update ensures shift emails are automatically sent to employees in their preferred language, regardless of the user's settings. Previously, emails defaulted to the current user's language, causing confusion. This change improves communication and user experience for international teams.
Original PR description
Steps to reproduce: ------------------------- 1. Install Planning and Contacts. 2. Install any language other than English (e.g., Arabic). 3. Change an employee's contact language to that language.…
Steps to reproduce: ------------------------- 1. Install Planning and Contacts. 2. Install any language other than English (e.g., Arabic). 3. Change an employee's contact language to that language. 4. Create a shift for that employee and click "Send". 5. Check the message in Settings > Technical > Discuss > Messages. Issue: --------- The email is sent in the language of the current user rather than the language of the employee receiving the shift. Cause: --------- The mail template rendering logic ([_render_lang](https://github.com/odoo/odoo/blob/0dbfa8b99d5c28a7d84e781a7f23b226fd964e95/addons/mail/models/mail_render_mixin.py#L549-L566)) fails to determine a valid language on the planning slot record because it is not directly linked to a `partner_id`. As a result, it falls back to the current user's language. Solution: ------------ Explicitly pass the employee partner's language in the mail context so that the email is sent in the correct language. opw-5928676 Forward-Port-Of: odoo/enterprise#110778 Forward-Port-Of: odoo/enterprise#109619
This update ensures that quality checks are only performed on tracked products when a lot or serial number is assigned. Previously, users could initiate quality checks without this information, leading to an error message prompting assignment. Additionally, the quality check display now intelligently filters checks based on whether any moves have been picked.
Original PR description
This commit fixes the behavior when the user tries to do quality checks for tracked products without setting their lot/sn on the picking. Before this commit: Nothing happens if the user tries to do quality checks if lots are not set on the tracked products. After this commit: A User Error is raised telling the user to assign lots/sn to the tracked products. Additional improvement: Before this commit, when having quality checks and user click on `Quality Checks` button, all quality checks appear regardless of whether all moves are picked or only some of them are picked. After this commit, clicking on `Quality Checks` button will only show quality checks related to picked move lines if at least one move line is picked, otherwise it will show all quality checks. Task-5730239 Forward-Port-Of: odoo/enterprise#110697 Forward-Port-Of: odoo/enterprise#104945
This update fixes a problem causing incorrect stock synchronization for Amazon listings, leading to phantom orders. The fix allows users to manually specify the fulfillment channel (FBA or FBM) for listings, resolving a known 'ghost listing' issue. This ensures accurate stock management and order fulfillment.
Original PR description
When configuring a listing on Amazon Seller Central, the user must choose **one** of the available fulfillment channels that Amazon offers. We distinguish two kinds: Fulfillment by Amazon (FBA) and…
When configuring a listing on Amazon Seller Central, the user must choose **one** of the available fulfillment channels that Amazon offers. We distinguish two kinds: Fulfillment by Amazon (FBA) and Fulfillment by Merchant (FBM). However, Amazon suffers from a known issue of ghost listings. A ghost listing occurs when an offer is presumably sold via FBA, but in fact stores stock information for both FBM and FBA creating unwanted FBM orders. To avoid ghost listings, the first solution was to disable stock synchronization as soon as an offer contained stock in the Amazon location of Odoo. However, if a merchant decided to change the fulfillment channel, it became impossible to sync the stock anymore. See also e7c01c7097d90e731c5408cee4d3595ed810c8fa. To resolve this issue, we decided to use the Amazon API to fetch information about the fulfillment channel of a listing. However, Amazon doesn't give a clear answer for a given listing. Therefore, after some research, the assumption was that an offer was FBM if the listing contained a `merchant_shipping_group`, as the merchant shipping group is a setting specific to FBM listings. See also e6d620e4b200cadabb00ce37ab03289cfeb4ae58. However, this assumption was flawed because Amazon can keep the shipping group even if the listing switches to FBA. This in turn enabled stock synchronization, leading to ghost listings. To fix this issue we give the possibility to users to manually set the correct fulfillment channel of an offer when it becomes ambiguous. opw-5480254 See also: - https://github.com/odoo/upgrade/pull/9692 Forward-Port-Of: odoo/enterprise#106662
This update fixes an issue where barcode-created manufacturing orders incorrectly used product UoMs instead of the specified BoM UoMs. Now, MOs created through the barcode app accurately reflect the BoM's component quantities, ensuring correct inventory tracking. This resolves a previous traceback and improves order accuracy.
Original PR description
Previous behaviour: * Traceback if MO created with a BoM whose lines have UoMs that don't correspond to those of the products, then UoM setting disabled and MO viewed in the barcode app. * BoM line UoMs ignored in favour of product UoMs when creating MO in the barcode app. New behaviour: * No traceback. * Stock moves in MOs properly created with the corresponding BoM line UoMs. Task ID: [4674196](https://www.odoo.com/odoo/my-tasks/4674196) Forward-Port-Of: odoo/enterprise#110740 Forward-Port-Of: odoo/enterprise#90408
This update corrects a bug in the DIAN invoice processing workflow that was causing original invoices to be accidentally deleted. The previous logic incorrectly protected the oldest document, leading to the deletion of the current invoice. This fix ensures invoices are properly protected during the update process, preventing data loss.
Original PR description
**PROBLEM** In some configurations, `_l10n_co_dian_cron_update_event_status()` would delete the original document of the invoice. **CAUSE** The logic that tried to exclude the original document from the code that unlinks duplicated documents is wrong. It protect the oldest document of `self` instead of `move`. So the document of the move we are currently working on is not protected, and could be deleted. **STEP TO REPRODUCE** 1. Setup DIAN. 2. Create multiples invoices and send them to DIAN. 3. Run _l10n_co_dian_cron_update_event_status() If the original document of the invoice have the same commercial_status as some other document, it could be destroyed. opw-5447147 Forward-Port-Of: odoo/enterprise#110455
An error preventing users from downloading audit reports as PDFs has been resolved. This was caused by removing compatibility shims used in the PDF generation process. The update corrects a migration issue, allowing users to successfully export audit reports without encountering errors.
Original PR description
Currently, the user gets an error page when exporting an audit report to PDF. This occurs because the compatibility shims that converted the old PyPDF (1.x) syntax to the new API were recently removed, and one instruction in `accountant_knowledge` was incorrectly migrated.
Steps to reproduce:
1. Create an audit report
2. Open the audit report
3. In the Knowledge editor, click on the "More Actions" button
4. In the dropdown, click on "Download Annual Report"
=> The user gets an error and the following message is printed in the console:
```
File "/home/odoo/src/enterprise/accountant_knowledge/controller/main.py",
line 484, in export_article_to_pdf
page.merge_page(empty_pdf_for_page_numbers[k])
~~~~~~~~~~~~~~~~~~~~~~~~~~^^^
TypeError: 'PdfReader' object is not subscriptable
```
To fix the issue, we update the incorrect call so the user can export an audit report to PDF without errors.
Reference: odoo/enterprise#107138This update corrects a previous issue where overtime records weren't being properly processed when an employee had multiple overtime entries within a single interval. The change ensures accurate tracking of all overtime hours, leading to more reliable employee time reporting. This improves the accuracy of payroll and attendance data.
Original PR description
Overtime intervals can contain multiple overtime records. Iterate over each overtime in the interval instead of unpacking a single record. Task Id : 6014640
This update fixes an issue where orders created through the MPS weren't being grouped correctly into RFQs. The fix ensures that all related orders are combined into a single RFQ, improving order management and reporting. This resolves a discrepancy in RFQ listings.
Original PR description
Issue ----- Orders created through the MPS aren't grouped in a single RFQ. Steps to reproduce ----- - Create a product with a vendor - Add it to the MPS with the buy route - Change the forecast to 2…
Issue ----- Orders created through the MPS aren't grouped in a single RFQ. Steps to reproduce ----- - Create a product with a vendor - Add it to the MPS with the buy route - Change the forecast to 2 - Order - Change the forecast to 5 - Order - Go to RFQs > There are 2 different RFQs Cause ----- When doing `_run_buy`, no existing PO is found https://github.com/odoo/odoo/blob/98e3020bcffaf449291d1e6664ba613761f37331/addons/purchase_stock/models/stock_rule.py#L102 so a new one gets created. The reason why the existing PO is not found is because we add `date_planned_mps` to the search domain https://github.com/odoo/enterprise/blob/42102423069c2cebbc01eb4d1d8f9b6215358639/mrp_mps/models/stock_rule.py#L10-L15 However, `values['date_planned']` is a datetime.date, whereas `date_planned_mps` is a datetime.datetime in DB. https://github.com/odoo/enterprise/blob/42102423069c2cebbc01eb4d1d8f9b6215358639/mrp_mps/models/purchase_order.py#L10 This poses some problems with timezones, as the client and db dates might differ. We can avoid the problem by converting the date to datetime. ----- Ticket: opw-5171041 Forward-Port-Of: odoo/enterprise#110068 Forward-Port-Of: odoo/enterprise#106968
This update fixes a critical issue where AI chat failures resulted in confusing error messages for users. The changes now provide more user-friendly 'oops' messages for initial fetch failures and a clear 'Connection Interrupted' dialog for stream interruptions. It also ensures the AI spinner stops spinning when messages fail to post.
Original PR description
Steps to reproduce: 1. Open the Website Editor 2. Select some text 3. Click the AI tool from the toolbar 4. Send a message in the chat window 5. Observe a non-standard error dialog showing 500 HTTP…
Steps to reproduce:
1. Open the Website Editor
2. Select some text
3. Click the AI tool from the toolbar
4. Send a message in the chat window
5. Observe a non-standard error dialog showing 500 HTTP error
The AI chat was not properly handling server errors and connection
interruptions, causing unhandled exceptions to be thrown to the user.
This commit improves error handling for both public and internal AI chat
by:
- The generator function handles error, such that it still yields data
even in error.
- Simulate RPCError for both the fetch of the streaming endpoint and during
error when streaming (error data is converted to RPCError).
- Properly provide error handler for StreamInterruptedError.
- Use a dedicated cursor for the LLM agent loop, wrapped in try/finally. When
the loop crashes, a new cursor is opened in the finally block to persist the
last text response. This ensures the loop cursor can roll back DB updates from
already-executed tool calls without losing the response message.
The following behavior will now be observed during error in the UI.
- Public AI chat:
- Initial fetch failed: shows "oops" message
- Stream interrupted:
- Server handled: shows "oops" message
- Server stopped: shows "Connection Interrupted" dialog
- Internal AI chat:
- Initial fetch failed: show RPCError dialog
- Stream interrupted:
- Server handled: shows RPCError dialog
- Server stopped: shows "Connection Interrupted" dialog
We also include a fix in the livechat where the ai spinner never goes away
when posting of message failed.
TASK-ID: 5886825
Forward-Port-Of: odoo/enterprise#110478
Forward-Port-Of: odoo/enterprise#105875This update fixes an issue where users were receiving blank PDF reports when attempting to print the planning report. The fix ensures the report data is correctly prepared before printing, guiding users to use the designated Print button for accurate report generation.
Original PR description
**Problem:** When users in debug mode manually add the planning report action through Settings/Technical/Reports and then print from the list or form view, they receive a blank/invalid PDF report.…
**Problem:** When users in debug mode manually add the planning report action through Settings/Technical/Reports and then print from the list or form view, they receive a blank/invalid PDF report. **Steps to reproduce:** 1. Go to Settings app and enable debug mode 2. Navigate to Technical → Reports 3. Search for "slot_report" 4. Click "Add to print menu" button 5. Refresh the browser 6. Go to Planning app and switch to list view 7. Select a few planning.slot records 8. Click Print → Planning **Current behavior:** A blank or invalid PDF is generated. **Expected behavior:** Users should receive a clear error message directing them to use the correct print method from the calendar view. **Cause of the issue:** The planning report requires a pre-processed data structure (weeks, grouped slots per day/week, and group-by mappings) that is only prepared by the action_print_plannings() method called from the custom Print button in the calendar view. The standard print menu invokes _render_qweb_pdf() directly without this data preparation, and there is no mechanism to pass this complex data structure through the standard print workflow. This results in the template receiving empty data contexts, producing blank reports. **Fix:** Block the planning report from being printed through _render_qweb_pdf() when called without the proper data context. This is done by checking if the report name is 'planning.slot_report' and raising a UserError with a clear message directing users to use the Print button in the calendar view instead. This prevents the generation of invalid reports while guiding users to the correct workflow that properly prepares the required data. opw-5477184 Forward-Port-Of: odoo/enterprise#108772 Forward-Port-Of: odoo/enterprise#105168
5 changes
Resolved issues and error corrections
This update corrects a bug in the DIAN invoice processing workflow. Previously, the system incorrectly deleted the original invoice document, potentially leading to data loss. The fix ensures the correct invoice document is protected, preventing accidental deletion during the update process.
Original PR description
**PROBLEM** In some configurations, `_l10n_co_dian_cron_update_event_status()` would delete the original document of the invoice. **CAUSE** The logic that tried to exclude the original document from the code that unlinks duplicated documents is wrong. It protect the oldest document of `self` instead of `move`. So the document of the move we are currently working on is not protected, and could be deleted. **STEP TO REPRODUCE** 1. Setup DIAN. 2. Create multiples invoices and send them to DIAN. 3. Run _l10n_co_dian_cron_update_event_status() If the original document of the invoice have the same commercial_status as some other document, it could be destroyed. opw-5447147
This update resolves issues where overtime calculations were incorrect due to timezone discrepancies, leading to crashes and orphaned overtime records. The fix ensures accurate overtime intervals are generated and handled, regardless of the employee's location, improving data integrity and reliability.
Original PR description
Steps to reproduce (singleton crash): Create an employee in a UTC+ timezone (e.g. Asia/Shanghai or Australia/Adelaide) with an overtime ruleset containing a paid rule. Generate work entries for a…
Steps to reproduce (singleton crash): Create an employee in a UTC+ timezone (e.g. Asia/Shanghai or Australia/Adelaide) with an overtime ruleset containing a paid rule. Generate work entries for a period, then create two consecutive midnight-to-midnight attendances in the employee's local timezone. Creating the second attendance crashes with: "ValueError: Expected singleton: hr.attendance.overtime.line(...)". Steps to reproduce (stale overtime lines): With the same setup, delete the attendance after it generated overtime lines. The overtime lines remain in the database instead of being removed. The singleton crash occurred because `end_of_day` in `_get_overtime_intervals` was computed as a naive datetime, implicitly treated as UTC. For UTC+ timezones, the actual local end of day is earlier than UTC midnight. As a result, overtime intervals were computed with a stop time extending past the real local midnight into UTC time. When consecutive attendances were processed together, these extended intervals overlapped. The `Intervals` class (`keep_distinct=True`) merges overlapping intervals into a single entry with a multi-record recordset as payload. The subsequent `overtime.rule_ids.work_entry_type_id` and `overtime.status` calls expected a singleton but received a multi-record set, causing the crash. The same multi-record issue also affected the iteration in `_set_real_overtime_intervals` and the overtime work entry loop in `_get_attendance_intervals`. The stale overtime lines issue occurred because `_get_overtimes_to_update_domain` (hr_attendance) built its search date range from raw UTC `.date()` values instead of the employee's local timezone. For UTC+ employees whose attendance spans local midnight, the overtime line is dated in the next local calendar day. Since the domain was derived from UTC dates, that next local day fell outside the search range, so the overtime line was never found and deleted when the attendance was removed. Solution: - In `_get_overtime_intervals`, localize `end_of_day` to the employee's timezone before converting to UTC, so overtime intervals are correctly bounded by the local end of day. - In `_set_real_overtime_intervals` and the overtime loop in `_get_attendance_intervals`, iterate over individual records from potentially multi-record `Intervals` payloads to avoid singleton errors. - In `_get_overtimes_to_update_domain` (hr_attendance), localize check_in/check_out to the employee's timezone before computing the date range so overtime lines for dates that only exist in local time are correctly included in the delete-and-recreate cycle. opw-5931665
This update corrects a visual discrepancy between how the AI livechat snippet is displayed in the editor and how it appears to users. The issue stemmed from mismatched code structures, leading to inconsistent rendering. This fix ensures the AI livechat snippet displays correctly across different devices and configurations.
Original PR description
Scenario: - add ai livechat snippet block - switch to mobile - enable "Fallback Button" - save Result: the rendering is different between edition and real usage of AI livechat snippet. Cause: structure and classes don't match Fix: make the structure and classes match. opw-5458575 pr note: I copied `ai_website_livechat.AILivechatComponent` in `ai_website_livechat.s_ai_livechat_edit` but it might make more sense to just render the owl widget with a class that neuter the AI (this way we don't need to update both template at each change)
This update ensures that NACHA payment files accurately reflect the actual account holder's name, rather than the customer's name in Odoo. Prioritizing the bank account holder's name improves payment processing accuracy and compliance with NACHA regulations.
Original PR description
The NACHA entry detail was using the partner's name (res.partner.name) for the Individual Name field. This should instead prioritize the Account Holder Name (acc_holder_name) from the bank account, as this reflects the actual name on the bank account which may differ from the partner's name in Odoo. The code now uses bank.acc_holder_name if set, and falls back to payment.partner_id.name if not set. Forward-Port-Of: odoo/enterprise#108414 Forward-Port-Of: odoo/enterprise#105582
This update ensures that the PIN code is now displayed for both physical and virtual expense cards. Previously, users were blocked from completing transactions using virtual cards (via digital wallets) because they couldn't access the necessary PIN information. This change improves the user experience and ensures seamless payment processing.
Original PR description
Before this commit: - Currently, we show the PIN code for physical expense cards only, not for virtual cards. - In some case transactions are made via virtual cards (through digital wallets) also requires a PIN. The users will be blocked because they currently can't access this information. After this commit: - Now we show the PIN code for both physical and virtual cards. task-5926462
8 changes
Resolved issues and error corrections
This update resolves an issue where the bank statement import process would fail when the currency in a CAMT file didn't match the bank's journal currency. The fix now validates for missing currency data, preventing errors and ensuring accurate bank statement imports. This improves the reliability of the import process.
Original PR description
Currently, an error occurs when the currency in the CAMT file differs from the bank journal currency. **Steps to reproduce:** - Install `account_bank_statement_import` module. - Create a new country…
Currently, an error occurs when the currency in the CAMT file differs from the bank journal currency. **Steps to reproduce:** - Install `account_bank_statement_import` module. - Create a new country with EUR as currency and switch to it. - In the Bank journal, upload this CAMT file: https://drive.google.com/file/d/1hKZIUPwdtcWAvxcoTLPFGpW-F5LnqDy9/view?usp=drive_link **Error:** `TypeError - unsupported operand type(s) for /: 'NoneType' and 'float'` **Cause:** When the `<Bal>` or `<Ntry>` amounts in the CAMT file are in a different currency, `get_value_and_currency_name` [1] cannot fetch a matching amount for the journal currency. This returns `None`, which leads to an invalid division during exchange rate computation. **Fix:** This commit handles missing currency data in CAMT files by raising a validation error instead of throwing a traceback. [1] - https://github.com/odoo/enterprise/blob/e7ae981000a4e53dc608c76605d8b2dbfb972c6a/account_bank_statement_import_camt/lib/camt.py#L632-L638 sentry-6874016845
This update corrects an issue where the QR code generated for self-ordering pickup orders incorrectly included table information in the downloaded PDF. The fix ensures QR codes are generated without table IDs, resolving a problem that prevented proper order scanning at the pickup zone. This improves the reliability of the self-ordering process.
Original PR description
Step to reproduce: - setup Restaurant and do the following config - set "self-ordering" -> "Qr Menu + Ordering" - set "service At" -> "pickup zone" - save and print the qr-code ( option is right there below these configs) Observation: - in downloaded pdf, we see a wrong url, which includes table_id, which shouldn't be. - QRs do not have table_id Cause: - there is issue in `generate_qr_codes_page` method, which uses table_id even if ordering mode is "pickup zone" Fix: - we only use table_id when ordering_mode = 'table'. **Before:** <img width="1002" height="397" alt="image" src="https://github.com/user-attachments/assets/e6dc50e5-6384-45b8-8ee5-817526769dc2" /> **After** <img width="1021" height="405" alt="image" src="https://github.com/user-attachments/assets/0be9b902-3870-4fc7-a409-e01265b7a1b3" /> opw-5095607 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#247184
This update resolves an issue preventing new employee creation when generating the BVG-LLP Basis Declaration report. The fix addresses a technical problem related to how Odoo processes multiple reports with the same month, ensuring correct employee data is recorded. This improves the reliability of payroll reporting for Swiss companies.
Original PR description
Steps to reproduce: ---------------------------------- 1. Install `l10n_ch_hr_payroll_elm_transmission` module 2. Switch to Swiss company 3. Navigate to Payroll > Transmission > BVG-LLP Basis…
Steps to reproduce:
----------------------------------
1. Install `l10n_ch_hr_payroll_elm_transmission` module
2. Switch to Swiss company
3. Navigate to Payroll > Transmission > BVG-LLP Basis Declaration
4. Create two Reports with same Year and Month
5. Now try to create new Employee from the employee app
Observation:
----------------------------------
Tracaback Occurs:
```
File '/home/odoo/src/enterprise/19.0/l10n_ch_hr_payroll/models/l10n_ch_employee_monthly_values.py', line 319, in _compute_bvg_lpp_annual_basis
existing_declaration = max(existing_declaration, key=lambda r: r.month) if existing_declaration else False
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File '/home/odoo/src/odoo/19.0/odoo/orm/models.py', line 5934, in ensure_one
raise ValueError('Expected singleton: %s' % self)
ValueError: Expected singleton: l10n.ch.lpp.basis.report(1, 2)
```
Issue:
----------------------------------
In the following code:
https://github.com/odoo/enterprise/blob/44a26539093f9313d9cd5f823c11866e3c98ec97/l10n_ch_hr_payroll_elm_transmission/models/l10n_ch_employee_monthly_values.py#L319-L320
Python's max() function doesn't just call the key function once per item. When there are ties (equal key values), it may need to compare the original objects, and during this process, Odoo's recordset operations combine records, causing the lambda receives `r` as a combined recordset. To access `.month` on a multi-record recordset it gives singleton error.
Solution:
----------------------------------
Creates tuples of (month, recordset) pairs and uses max() to compare month integers directly, avoiding the singleton error.
opw-5391742
Forward-Port-Of: odoo/enterprise#102335This update corrects a bug in the Odoo portal's task search functionality. Previously, searching by assignees didn't return accurate results due to a naming error in the search criteria. This fix ensures that tasks assigned to a specific user are correctly displayed when searching by assignee, improving user task visibility.
Original PR description
# How to reproduce - On the website go to My Account > Tasks - In the search bar, select Search In Assignees - Search for an assignee # The problem Nothing shows up even if the is a task with the assignee that was searched # Why In the dictionnary of the different possible searches, the name of the Search in Assignee entry was "users" instead of "user_ids" opw-5503738 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update corrects a problem where Amazon listings were incorrectly syncing stock levels, leading to phantom orders. The fix allows users to manually specify the fulfillment channel (FBA or FBM) for each listing, resolving a known 'ghost listing' issue. This ensures accurate stock management and order fulfillment on Amazon.
Original PR description
When configuring a listing on Amazon Seller Central, the user must choose **one** of the available fulfillment channels that Amazon offers. We distinguish two kinds: Fulfillment by Amazon (FBA) and…
When configuring a listing on Amazon Seller Central, the user must choose **one** of the available fulfillment channels that Amazon offers. We distinguish two kinds: Fulfillment by Amazon (FBA) and Fulfillment by Merchant (FBM). However, Amazon suffers from a known issue of ghost listings. A ghost listing occurs when an offer is presumably sold via FBA, but in fact stores stock information for both FBM and FBA creating unwanted FBM orders. To avoid ghost listings, the first solution was to disable stock synchronization as soon as an offer contained stock in the Amazon location of Odoo. However, if a merchant decided to change the fulfillment channel, it became impossible to sync the stock anymore. See also e7c01c7097d90e731c5408cee4d3595ed810c8fa. To resolve this issue, we decided to use the Amazon API to fetch information about the fulfillment channel of a listing. However, Amazon doesn't give a clear answer for a given listing. Therefore, after some research, the assumption was that an offer was FBM if the listing contained a `merchant_shipping_group`, as the merchant shipping group is a setting specific to FBM listings. See also e6d620e4b200cadabb00ce37ab03289cfeb4ae58. However, this assumption was flawed because Amazon can keep the shipping group even if the listing switches to FBA. This in turn enabled stock synchronization, leading to ghost listings. To fix this issue we give the possibility to users to manually set the correct fulfillment channel of an offer when it becomes ambiguous. opw-5480254 See also: - https://github.com/odoo/upgrade/pull/9692 Forward-Port-Of: odoo/enterprise#106662
This update corrects a bug where compensation account move lines weren't created for dropshipped products when the purchase price differed from the bill price. The fix ensures accurate accounting for these transactions, preventing valuation discrepancies and ensuring proper expense recognition. This impacts dropshipping functionality.
Original PR description
**Problem:** compensation amls are not created for dropshipped products when there is a difference between the price of the PO and the price on the bill **Context:** For non dropship avco real time…
**Problem:** compensation amls are not created for dropshipped products when there is a difference between the price of the PO and the price on the bill **Context:** For non dropship avco real time products: When you create a PO for a product @ 10 - stock interim received is credited of 10 - stock valuation is debitted of 10 And you then validate a bill for a price of 8 - stock interim received is debitted of 8 - account payable is creditted of 8 This leaves stock interim received with credit of 2 and stock valuation is over valued by 2. So we create 2 extra account move lines - One debit of 2 for stock interim received - One credit of 2 for stock valuation (or Expenses if the product is not in stock anymore because then it's the expense account which was over valuated) nb: if the product is still in stock those 2 lines are created via stock valuation layer In the case of a dropshipped product, the product is not in stock anymore so it should be creditting expense, but no extra amls are created at all. **Steps to reproduce:** - enable the "dropshipping" and "anglo saxon accounting" settings - create a storable product with avco automated category - in the inventory tab, select the dropship route - in the purchase tab, set a vendor - create and a confirm a quotation for this product - on the linked purchase order, set a unit price of 10$ and confirm - validate the dropship move - create a bill for the purchase order - set the price to 8$ and confirm - navigate to journal items and search for your product **Current behavior:** no compensation account move lines were created **Expected behavior:** 2 account move lines should have been created: - One debitting 2 in stock interim received - One creditting 2 in expense **Cause of the issue:** *the following logic was introduced by* https://github.com/odoo/odoo/pull/126536 to create those extra amls and layers, _apply_price_difference() is called inside _post() https://github.com/odoo/odoo/blob/32408a8dea43f57bba1a56c775ae228131720749/addons/purchase_stock/models/account_invoice.py#L129 There we have 2 problems : Problem 1: When fetching the layers linked to the account move line, we fetch both the incoming and the outgoing valuation layers because they are both linked to the dropship move. https://github.com/odoo/odoo/blob/455b289abd691ccb274dfce43c1b4347add20a41/addons/purchase_stock/models/account_move_line.py#L46 But we only want the incoming layer because the outgoing layer should not interfere with the bill. nb: In a standard case like the one of the steps to reproduce, it would work to leave both layers, but : - it works for the wrong reasons : the quantity of the aml would first be consumed on the incoming layer and nothing would happen with the second layer as the quantity of the incoming layer is the same as the one of the aml. - it would probably break in more complex use cases. So it feels unnecessarily risky to leave it like that. Problem 2: Inside _generate_price_difference_vals we call _replay_history which returns two values that are assigned to two variables. https://github.com/odoo/odoo/blob/455b289abd691ccb274dfce43c1b4347add20a41/addons/purchase_stock/models/account_move_line.py#L82 The second variable, layers_and_invoices_qties is a default dict which keys are tuples (layer L, invoice I) mapped with [the initial quantity invoiced by I on L, the remanining qty invoiced by I on L] (here 'remaining' is related to invoice and has nothing to do with stock qties) https://github.com/odoo/odoo/blob/455b289abd691ccb274dfce43c1b4347add20a41/addons/purchase_stock/models/account_move_line.py#L168-L171 So in our very basic use case, with a single invoice and a single layer, we should have a key (our layer, our invoice) linked to the value [1,1]. But this key is not in the dictonary. *The reason is the following :* inside _replay_history the parameter "history" contains the layers and the amls (in our case 1 layer and one aml which is self). Each layer is added to qty_to_invoice_per_layer https://github.com/odoo/odoo/blob/455b289abd691ccb274dfce43c1b4347add20a41/addons/purchase_stock/models/account_move_line.py#L177-L178 https://github.com/odoo/odoo/blob/455b289abd691ccb274dfce43c1b4347add20a41/addons/purchase_stock/models/account_move_line.py#L191-L192 Then, for each aml: the layers are added to layer_to_consume, alongside their remaining quantity. https://github.com/odoo/odoo/blob/455b289abd691ccb274dfce43c1b4347add20a41/addons/purchase_stock/models/account_move_line.py#L215-L221 And for each layer which has a quantity billed by the invoice, a key is added to layers_and_invoices_qties https://github.com/odoo/odoo/blob/455b289abd691ccb274dfce43c1b4347add20a41/addons/purchase_stock/models/account_move_line.py#L222-L231 In our case, the move linked to the layer is the dropship move so _is_in() will be false and the layer won't be added to layers_to_consume. https://github.com/odoo/odoo/blob/455b289abd691ccb274dfce43c1b4347add20a41/addons/purchase_stock/models/account_move_line.py#L220-L221 So the key will not be created. *The consequence is the following:* Later in _generate_price_difference_vals() we acces the value of this key (the key that should be there (layer, invoice)) https://github.com/odoo/odoo/blob/455b289abd691ccb274dfce43c1b4347add20a41/addons/purchase_stock/models/account_move_line.py#L91 to get the invoiced qty which will later be used to determine which quantity is still in stock and which is out of stock (giving us the quantities for the compensation layers and amls) but as the key does not exist, invoicing_layer_qty will have a value of 0 so we will exit the loop and no amls or svls will be created https://github.com/odoo/odoo/blob/455b289abd691ccb274dfce43c1b4347add20a41/addons/purchase_stock/models/account_move_line.py#L92-L93 opw-5498878
This update ensures that Odoo generates the correct XML format for Swiss payment transactions (iso20022_ch) according to industry standards. It addresses a mismatch in the XML schema used for payment validation, ensuring compliance with Swiss banking regulations and accurate payment processing. This resolves an issue where the payment XML was not properly structured.
Original PR description
**PROBLEM** According to documentation (https://www.six-group.com/dam/download/banking-services/standardization/sps/ig-credit-transfer-sps-2025-en.pdf) PstlAdr must be structured. This isn't the case when generating a xml for the payment method iso20022_ch. **STEP TO REPRODUCE** 1. install l10n_ch and account_iso20022. 2. Create a swiss contact with a full address. And activate payment on the bank account of this contact. 3. Select the Company CH, and set a bank account in the bank journal configuration. 4. Create a vendor payment to the swiss contact. 5. Create a batch payment with it, and validate to get the xml. 6. Open the xml, and notice the PstlAdr isn't structured. Ticket [link](https://www.odoo.com/odoo/project.task/5880247) opw-5880247
This update ensures that reason messages provided by Public Administrators when refusing invoices are now displayed on the invoice header. Previously, these messages were ignored. This change aligns with Italian tax regulations (Fattura Elettronica) and provides clearer information for users.
Original PR description
When a Public Administrator business refuses an invoice, they also give a reason message (EsitoCommittente/Descrizione), which comes through the IAP to Odoo as an XML tag aside the Outcome code (EsitoCommittente/Esito). Before this PR, the message was ignored, now we show it in the invoice's header. ref: https://www.fatturapa.gov.it/export/documenti/messaggi/v1.1/MessaggiTypes_v1.1.xsd <img width="823" height="232" alt="image" src="https://github.com/user-attachments/assets/8f222f6b-1615-4dd2-a5dd-25e0991ea037" /> <img width="942" height="206" alt="image" src="https://github.com/user-attachments/assets/cdf109ff-40d0-4c50-bdc7-51fb4ea15c98" /> Ticket [link](https://www.odoo.com/odoo/project.task/6041276) opw-6041276
2 changes
Resolved issues and error corrections
This update resolves a bug that prevented users from previewing draft invoices when no invoice date was specified. The fix ensures that the invoice preview correctly uses today's date as a default, mirroring the behavior when the invoice is confirmed. This improves the usability of the invoice preview feature.
Original PR description
## Issue When clicking the *Preview* button on a draft invoice with an early discount payment term and no invoice date, the following traceback would appear: ``` File…
## Issue
When clicking the *Preview* button on a draft invoice with an early discount payment term and no invoice date, the following traceback would appear:
```
File ".../addons/account/models/account_payment_term.py", line 274, in _get_last_discount_date
return date_ref + relativedelta(days=self.discount_days or 0) if self.early_discount else False
~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
TypeError: unsupported operand type(s) for +: 'bool' and 'relativedelta'
```
## Steps to reproduce
1. Install *Accounting* (`account_accountant`)
2. In Accounting > Configuration > Payment Terms, chose a Payment Term PT and toggle its *Early Discount* field
3. In Accounting > Customers > Invoices, create **but do not confirm** a new Invoice
- Any Customer
- Payment Term PT
- Any Product
- **No Invoice Date**
4. Click the *Preview* button
5. **A _500: Internal Server Error_ traceback appears**
## Cause
The traceback occurs in `AccountPaymentTerm._get_last_discount_date`:
https://github.com/odoo/odoo/blob/6cc36886c612c7ed8878117637ee11bc6234d0e4/addons/account/models/account_payment_term.py#L272-L274
where `date_ref` is False. This method is called by `AccountMove._is_eligible_for_early_payment_discount`:
https://github.com/odoo/odoo/blob/6cc36886c612c7ed8878117637ee11bc6234d0e4/addons/account/models/account_move.py#L2026-L2032
where `self.invoice_date` is False, because that field is not required, and the user can click the *Preview* button before a date is set. If the invoice is confirmed before being previewed, the issue does not occur, as confirming an invoice with no date will use today's date by default. This is done in `AccountMove._post`:
https://github.com/odoo/odoo/blob/6cc36886c612c7ed8878117637ee11bc6234d0e4/addons/account/models/account_move.py#L3967-L3971
## Fix
We can apply the same behavior as if the invoice was confirmed, and use today's date by default if no invoice date is given when trying to preview a draft invoice. The same logic should be applied to `_get_last_discount_date_formatted` for the date to be correctly evaluated in `account/views/report_invoice.xml`:
https://github.com/odoo/odoo/blob/6cc36886c612c7ed8878117637ee11bc6234d0e4/addons/account/views/report_invoice.xml#L252-L254
where `o.invoice_date` is also `False`, leading to `AccountPaymentTerm._get_last_discount_date_formatted` to return None:
https://github.com/odoo/odoo/blob/6cc36886c612c7ed8878117637ee11bc6234d0e4/addons/account/models/account_payment_term.py#L276-L280
which then displays the default date (`2024-01-01`) instead of *today + the early discount time limit*.
## Test
[The test](https://github.com/odoo/odoo/blob/6cc36886c612c7ed8878117637ee11bc6234d0e4/addons/account/tests/test_early_payment_discount.py#L92-L116) added by https://github.com/odoo/odoo/commit/572a6a82576a91005d9eedb673acfb088eb52cd1 and edited by https://github.com/odoo/odoo/commit/abe7fb51235dc3d47e6352505065fcd15100b21b does not follow the same execution flow as the *Preview* button. In the test case, the `reference_date` passed to the `is_eligible_for_early_payment_discount` method is `False`, skipping the problematic section of the condition. When using the *Preview* button, a `reference_date` is passed from `AccountMoveLine._get_epd_data` since https://github.com/odoo/odoo/commit/b9abe46c1492b09e369434e76ec8196c6b02dd19:
https://github.com/odoo/odoo/blob/6cc36886c612c7ed8878117637ee11bc6234d0e4/addons/account/models/account_move_line.py#L3287-L3295
opw-6008959This update resolves an issue where vendor bills imported from XML incorrectly applied two taxes (G and S) to products, particularly when a product had a default service tax. The fix ensures only the relevant tax is applied based on the product type, preventing duplicate tax calculations and improving data accuracy.
Original PR description
**Issue**: Importing a vendor bill from XML may lead to two taxes being applied to the same product if: - The product exists in the database. - It matches a product reference in the XML. - The…
**Issue**: Importing a vendor bill from XML may lead to two taxes being applied to the same product if: - The product exists in the database. - It matches a product reference in the XML. - The product has a default service tax (e.g. 22% S). **Steps to reproduce**: - Create a product with a service tax (22% S). - Ensure you have a test XML referencing that product (see tests for an example). - Go to Accounting > Vendors > Bills. - Upload the XML file. - Observe that the product line has two taxes: 22% G (from XML) and 22% S (from product). **Cause**: Two taxes are applied because: - The tax defined in the product: [Line 875 in `account_move_line.py`](https://github.com/odoo/odoo/blob/767341d4ec6aaa4fbd379827da4baf04e561eb32/addons/account/models/account_move_line.py#L875) which is triggered by [L1285C1-L1288C30 in `account_move.py`](https://github.com/odoo/odoo/blob/e705690d2340245a0d18b7e76347575dde9ea2be/addons/l10n_it_edi/models/account_move.py#L1285C1-L1288C30) - Then, the XML tax is also added: [L1012C1-L1016C44 in `account_move.py`](https://github.com/odoo/odoo/blob/e705690d2340245a0d18b7e76347575dde9ea2be/addons/l10n_it_edi/models/account_move.py#L1012C1-L1016C44) An attempt to reset the `tax_ids` after setting the product is already present: [Line 1319](https://github.com/odoo/odoo/blob/e705690d2340245a0d18b7e76347575dde9ea2be/addons/l10n_it_edi/models/account_move.py#L1319), but it is ineffective because the original `tax_ids` are re-applied afterward, dues to side effects. **Solution**: There are two possible ways to fix this: - Make sure `move_line.tax_ids = []` works as intended - Clean the `move_line.tax_ids` recordset. Chose the second option as it's simpler and avoids modifying unrelated code **Additional Notes**: The tax extracted from the XML does not take into account whether the product is a good or a service. For example, if the tax rate is 22%, the logic return taxes[0] if taxes else taxes will always return 22% G, even if the product should be taxed as 22% S. To solve this, an extra domain filter is added based on the product type to ensure only applicable taxes are considered. opw-4844469 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: BACKPORT OF #218309 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr