Wednesday, May 13, 2026
16 changes · saas-19.3
New functionality added to Odoo
This update introduces ECPay, a new payment provider specifically designed for transactions in Taiwan. ECPay supports various payment methods including credit cards, bank transfers, and increasingly popular local options like convenience stores and mobile wallets, expanding our payment options for Taiwanese customers.
Original PR description
This change integrates a new payment provider: ECPay for payments in Taiwan. Supported Payment methods of the provider: - card: credit/debit card - bank transfer - wechat pay - [NEW] Convenience Stores (eg. 7/11, OK Mart etc.) - [NEW] Mobile Wallet (eg. iPASS Money, Jkopay etc.) - [NEW] TWQR Note: - Tokenization and Refund is not implemented in this commit. Task-5168802 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#235069
Enhancements to existing features
This update enhances the system's partner suggestion feature by prioritizing partners who have recently communicated within a discussion thread. The system now considers message recency when ranking suggestions, making it more likely that you'll see individuals you've interacted with most recently. This improves efficiency and connection within the platform.
Original PR description
backport of https://github.com/odoo/odoo/pull/262708 This commit adds a compare criteria to the `partnerCompareRegistry` used to sort partner suggestions. With this new criteria, partners that have recently authored a message in the thread will be ranked higher in the suggestion list, with the internal ordering depending on message recency. task-5932229 Forward-Port-Of: odoo/odoo#263783
Resolved issues and error corrections
This update resolves an issue where rapid actions triggered duplicate entries being created in the database for account return checks. The fix prevents multiple simultaneous processes from attempting to create the same record, ensuring data integrity. This improves the stability and efficiency of the account reporting feature.
Original PR description
Issue -------------- When refreshing checks on account returns (e.g. from rapid successive clicks or component re-renders), multiple concurrent RPC calls to `refresh_checks` were being dispatched to…
Issue
--------------
When refreshing checks on account returns (e.g. from rapid successive clicks or component re-renders), multiple concurrent RPC calls to `refresh_checks` were being dispatched to the server. This created a race condition that resulted in duplicate `account.return.check` records being generated in the database.
steps to reproduce demonstrated in video: https://drive.google.com/file/d/1-A0ZHdYGdv-UL0dqClqK6Kos_iVXoZai/view?usp=sharing
When this happen the `runAllReturnChecks` method fires parallel RPC calls to [`refresh_checks`](https://github.com/odoo/enterprise/blob/55bfd499660d3eda0abfc9e8ed8c9a2befbd394b/account_reports/models/account_return.py#L1974-L1992) on the server. In the case of instant multiple RPC calls, parallel threads are dispatched which causes the data preparation stage to run simultaneously.
Because both threads run in parallel, Thread 2 runs its [preparation and existing ](https://github.com/odoo/enterprise/blob/55bfd499660d3eda0abfc9e8ed8c9a2befbd394b/account_reports/models/account_return.py#L1986-L1987 )check mechanism before Thread 1 has reached the actual `create()` function [trigger](https://github.com/odoo/enterprise/blob/55bfd499660d3eda0abfc9e8ed8c9a2befbd394b/account_reports/models/account_return.py#L1998-L1999). Consequently, Thread 2's existence check fails to find the record (since Thread 1 hasn't committed it to the database yet), and it considers the record eligible for creation—even though the exact same record is already prepared for creation by Thread 1. This race condition leads to duplicate `account.return.check` records.
Logs to demonstrate the thread execution:
--------
```python
2026-04-16 08:30:51,493 14 INFO bsra_4165887_upg werkzeug: 202.131.97.106 - - [16/Apr/2026 08:30:51] "GET /websocket?version=19.0-2 HTTP/1.0" 400 - 1 0.000 0.002
2026-04-16 08:30:51,662 14 INFO bsra_4165887_upg werkzeug: 202.131.97.106 - - [16/Apr/2026 08:30:51] "POST /web/dataset/call_kw/account.report/dispatch_report_action#account.report.dispatch_report_action HTTP/1.0" 200 - 17 0.006 0.012
2026-04-16 08:30:51,847 14 INFO bsra_4165887_upg werkzeug: 202.131.97.106 - - [16/Apr/2026 08:30:51] "POST /web/dataset/call_kw/account.return/get_views#account.return.get_views HTTP/1.0" 200 - 26 0.009 0.025
2026-04-16 08:30:52,099 14 INFO bsra_4165887_upg werkzeug: 202.131.97.106 - - [16/Apr/2026 08:30:52] "POST /web/dataset/call_kw/account.return/web_read_group#account.return.web_read_group HTTP/1.0" 200 - 95 0.029 0.064
2026-04-16 08:30:52,320 14 INFO bsra_4165887_upg werkzeug: 202.131.97.106 - - [16/Apr/2026 08:30:52] "POST /web/dataset/call_kw/account.return/get_next_returns_ids#account.return.get_next_returns_ids HTTP/1.0" 200 - 2 0.001 0.004
THREAD NAME: odoo.service.http.request.137360481711808 Thread ID: 137360481711808
REFRESH CHECK START:--------------------------------------------
Thread ID: 137360481711808 -------------DATA PREPARING STAGE------------
Thread ID: 137360481711808
Thread ID: 137360481711808 RECORD EXISTING CHECK: None
2026-04-16 08:30:53,842 14 INFO bsra_4165887_upg werkzeug: 202.131.97.106 - - [16/Apr/2026 08:30:53] "GET /odoo/tax-report/tax-return?debug=1 HTTP/1.0" 200 - 29 0.020 0.021
2026-04-16 08:30:54,066 14 INFO bsra_4165887_upg werkzeug: 202.131.97.106 - - [16/Apr/2026 08:30:54] "GET /web/webclient/load_menus HTTP/1.0" 200 - 4 0.002 0.009
2026-04-16 08:30:54,351 14 INFO bsra_4165887_upg werkzeug: 202.131.97.106 - - [16/Apr/2026 08:30:54] "GET /web/manifest.webmanifest HTTP/1.0" 200 - 6 0.003 0.005
2026-04-16 08:30:54,493 14 INFO bsra_4165887_upg werkzeug: 202.131.97.106 - - [16/Apr/2026 08:30:54] "GET /web/webclient/translations?hash=bb5aa713d587cc7dd07b13d1d7efc2c525517e99&lang=en_US HTTP/1.0" 200 - 1 0.000 0.002
2026-04-16 08:30:54,586 14 INFO bsra_4165887_upg werkzeug: 202.131.97.106 - - [16/Apr/2026 08:30:54] "GET /web/bundle/web_tour.interactive?lang=en_US&debug=1 HTTP/1.0" 200 - 1 0.001 0.003
2026-04-16 08:30:54,640 14 INFO bsra_4165887_upg werkzeug: 202.131.97.106 - - [16/Apr/2026 08:30:54] "POST /web/action/load_breadcrumbs HTTP/1.0" 200 - 7 0.003 0.006
2026-04-16 08:30:54,710 14 INFO bsra_4165887_upg werkzeug: 202.131.97.106 - - [16/Apr/2026 08:30:54] "POST /web/dataset/call_kw/ir.http/lazy_session_info#ir.http.lazy_session_info HTTP/1.0" 200 - 2 0.001 0.004
2026-04-16 08:30:54,753 14 INFO bsra_4165887_upg werkzeug: 202.131.97.106 - - [16/Apr/2026 08:30:54] "GET /bus/websocket_worker_bundle?v=19.0-2 HTTP/1.0" 304 - 3 0.004 0.006
2026-04-16 08:30:54,766 14 INFO bsra_4165887_upg werkzeug: 202.131.97.106 - - [16/Apr/2026 08:30:54] "GET /web/image?model=res.users&field=avatar_128&id=2 HTTP/1.0" 304 - 9 0.012 0.013
2026-04-16 08:30:54,777 14 INFO bsra_4165887_upg werkzeug: 202.131.97.106 - - [16/Apr/2026 08:30:54] "POST /mail/data HTTP/1.0" 200 - 34 0.034 0.020
2026-04-16 08:30:54,824 14 INFO bsra_4165887_upg werkzeug: 202.131.97.106 - - [16/Apr/2026 08:30:54] "POST /web/dataset/call_kw/account.return/get_views#account.return.get_views HTTP/1.0" 200 - 3 0.001 0.010
2026-04-16 08:30:54,934 14 INFO bsra_4165887_upg werkzeug: 202.131.97.106 - - [16/Apr/2026 08:30:54] "POST /web/dataset/call_kw/account.return/web_read_group#account.return.web_read_group HTTP/1.0" 200 - 88 0.029 0.051
2026-04-16 08:30:55,107 14 INFO bsra_4165887_upg werkzeug: 202.131.97.106 - - [16/Apr/2026 08:30:55] "POST /web/dataset/call_kw/account.return/get_next_returns_ids#account.return.get_next_returns_ids HTTP/1.0" 200 - 2 0.001 0.005
THREAD NAME: odoo.service.http.request.137360513177280 Thread ID: 137360513177280
REFRESH CHECK START:--------------------------------------------
Thread ID: 137360513177280 -------------DATA PREPARING STAGE------------
Thread ID: 137360513177280
Thread ID: 137360513177280 RECORD EXISTING CHECK: None
2026-04-16 08:30:55,589 14 INFO bsra_4165887_upg werkzeug: 202.131.97.106 - - [16/Apr/2026 08:30:55] "GET /websocket?version=19.0-2 HTTP/1.0" 400 - 1 0.001 0.006
2026-04-16 08:30:56,702 14 INFO bsra_4165887_upg werkzeug: 202.131.97.106 - - [16/Apr/2026 08:30:56] "GET /web/service-worker.js HTTP/1.0" 200 - 1 0.000 0.003
2026-04-16 08:30:58,893 14 INFO bsra_4165887_upg werkzeug: 202.131.97.106 - - [16/Apr/2026 08:30:58] "GET /websocket?version=19.0-2 HTTP/1.0" 400 - 1 0.006 0.023
2026-04-16 08:31:05,296 14 INFO bsra_4165887_upg werkzeug: 202.131.97.106 - - [16/Apr/2026 08:31:05] "GET /websocket?version=19.0-2 HTTP/1.0" 400 - 1 0.001 0.002
Thread ID: 137360481711808 DATA to_create: 168
Thread ID: 137360481711808 done process create
2026-04-16 08:31:10,132 14 INFO bsra_4165887_upg werkzeug: 202.131.97.106 - - [16/Apr/2026 08:31:10] "POST /web/dataset/call_kw/account.return/refresh_checks#account.return.refresh_checks HTTP/1.0" 200 - 513 11.611 6.039
Thread ID: 137360513177280 DATA to_create: 168
Thread ID: 137360513177280 done process create
```
- OPW: 5917459
Forward-Port-Of: odoo/enterprise#114045This update refines how Odoo automatically matches bank statements to invoices and payments. Previously, it prioritized the closest date, which wasn't always accurate. Now, it only matches if there's one prior statement candidate, ensuring more reliable reconciliation and reducing potential errors in financial reporting.
Original PR description
Before this pr, we decided that when there was multiple candidates, we would take the one closer to the date of the statement line but it is not always what we want. We decided to change that so that it would match only if there is one candidate prior the date of the statement line. Exemple: Invoice 1 the 10/06 and invoice 2 the 20/06 → Payment the 05/06 → no matching (0 before) → Payment the 15/06 → match with invoice 1 (only 1 before) → Payment the 25/06 → no matching (More than 1 invoice open before) task-6143809 Forward-Port-Of: odoo/enterprise#115888 Forward-Port-Of: odoo/enterprise#115284
This update fixes an issue where loyalty point transactions in POS orders were only recorded as a net difference, not the individual earned and spent amounts. The change ensures that the loyalty history accurately reflects the complete transaction, providing a more precise record of customer loyalty activity. This improves reporting and data accuracy for managing customer rewards.
Original PR description
When a loyalty card both earned and spent points in the same POS order, the history entry only reflected the net difference instead of the gross amounts. The root cause was that the JS payload sent only a single `points` field representing the net change. Fix by tracking `points_earned` and `points_spent` separately in `couponData` and sending them to the server. opw-6041420 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#262314 Forward-Port-Of: odoo/odoo#256022
This update fixes a recurring issue where Odoo would repeatedly retry sending eTIMS transactions, leading to an error (924). The change improves reliability by intelligently handling network interruptions and ensuring that invoice numbers are not duplicated, preventing delays and data inconsistencies. This ensures smoother eTIMS processing for Kenyan customers.
Original PR description
When the network drops after eTIMS processes a transaction but before Odoo receives the confirmation, Odoo would retry with the same invoice number, causing eTIMS error 924 (Invoice number already…
When the network drops after eTIMS processes a transaction but before Odoo receives the confirmation, Odoo would retry with the same invoice number, causing eTIMS error 924 (Invoice number already exists). For POS orders, the old code decremented the sequence on any error (including timeout), so the next retry consumed the same invcNo. If eTIMS had already recorded the original send, the retry was rejected with 924. Fix by introducing a fetch-first strategy: on retry, if a pending invcNo is found in l10n_ke_order_json, call selectInvoiceDetails before sending. If eTIMS already has the invoice, recover the receipt data directly without resending. If eTIMS does not have it, resend with the same invcNo safely. On timeout errors, the sequence is no longer decremented so the invcNo is preserved in l10n_ke_order_json for the next idempotent retry. For customer invoices, the existing fetch-first logic only bailed out on TIM (timeout) errors, falling through on CON (connection) errors and retrying blindly. Additionally, if saveTrnsSalesOsdc returned 924, there was no recovery path and the invoice number would be cleared. Fix by also bailing on CON in the fetch block, and adding an explicit 924 handler that calls selectInvoiceDetails to recover the existing receipt instead of failing. opw-6105693 Forward-Port-Of: odoo/enterprise#115649
This update fixes a bug that occurred when users tried to reschedule marketing activities, specifically within automated campaigns. The change prevents errors related to missing parent information, ensuring campaigns run smoothly and reliably. This improves the stability of our marketing automation features.
Original PR description
**Steps to reproduce:** - Create a new marketing campaign with two activities - Set them to occur some number of days after the beginning - Save the campaign and start it - Modify one of the…
**Steps to reproduce:** - Create a new marketing campaign with two activities - Set them to occur some number of days after the beginning - Save the campaign and start it - Modify one of the activities to occur some number of days after the other activity and save - Modify the child activity by changing the number of days after its parent that it should run and save - An error will be thrown **Issue:** The trace related to the child activity has no parent when trying to reschedule it in `_update_schedule_date`. This causes an issue when trying to get the first mailing_trace_ids using index 0 in this line: `base_dt_str = trace.parent_id.schedule_date or trace.parent_id.mailing_trace_ids[0].write_date or trace.participant_id.create_date` **Fix:** Prevent the activity hierarchy to be modified on started campaigns. We also change the indexing to avoid further out of range issue and properly default on the participant create value. Trying to match existing traces to their parents has too many edge cases when trying to avoid duplicates, and might often need to reset the whole trace chain to work properly. This approach avoids user mistakes on running campaigns, but if a user tries to launch a test (even on draft campaign) he won't be able to modify the hierarchy further without deleting/recreating some activities/traces. So we should ignore this for test traces, but it could impact the behavior between test and actual executions. opw-5362978 Forward-Port-Of: odoo/enterprise#107556
This update optimizes the PDF generation process for Odoo's SA (Saudi Arabia) edition, addressing a significant performance bottleneck. Previously, PDF creation was delaying checkout, but ZATCA now only requires XML and QR codes. This change dramatically speeds up the checkout process for SA users.
Original PR description
For SA companies, wkhtmltopdf PDF generation was accounting for ~47% of the sync_from_ui response time (~3.1s out of ~6.5s total), blocking the cashier at every order. The PDF is not needed during checkout: ZATCA requires only the signed XML and returns the QR code. The PDF can be generated on demand when the invoice is first viewed or downloaded. opw-6019994 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#261417 Forward-Port-Of: odoo/odoo#253641
This update resolves an error that occurred when calculating overtime deductions for employees with specific filing statuses (other than 'single' or 'jointly'). The fix ensures the system correctly handles different filing status values, preventing a crash. This improves the accuracy of overtime calculations for a wider range of employee scenarios.
Original PR description
Issue: ---------------------------------------- When having an employee with `l10n_us_filing_status` not in `['single', 'jointly']` and evaluating the rule parameter…
Issue: ---------------------------------------- When having an employee with `l10n_us_filing_status` not in `['single', 'jointly']` and evaluating the rule parameter `l10n_us_qualified_overtime_deduction_cap` an error occurs. Cause: ---------------------------------------- `l10n_us_filing_status` can have 5 values: `['single', 'jointly', 'separately', 'head', 'survivor']` But only `['single', 'jointly']` are defined for `l10n_us_qualified_overtime_deduction_cap` ([src](https://github.com/odoo/enterprise/blob/2d2056766441157dc45ebc37b677841c44e5c513/l10n_us_hr_payroll/data/hr_rule_parameters_data.xml#L48)). When running the rule "Qualified Overtime", the custom Python crashes because we read a key that is not there: https://github.com/odoo/enterprise/blob/2d2056766441157dc45ebc37b677841c44e5c513/l10n_us_hr_payroll/data/hr_salary_rule_data.xml#L56 Solution: ---------------------------------------- In the custom Python condition, we first check if the key is there. The custom Python computation also tries to read the key, but it is run only if the condition is validated. So we don't need to change it. Also fixed indentation of test 069. opw-6129657 Forward-Port-Of: odoo/enterprise#116913 Forward-Port-Of: odoo/enterprise#115754
This update resolves an issue where Swedish characters in import files were being incorrectly interpreted, resulting in misformatted account data. The fix ensures that account names are imported accurately, specifically addressing the 'vriga imm anl tillg' error for account 1090. This improves data integrity for Swedish businesses using the Odoo Enterprise system.
Original PR description
Issue: Non-ASCII charatcter from sie file were lost on import. Steps to reproduce: - in a Swedish company - import the SIE4 exemple file from sie website: https://sie.se/wp-content/uploads/2024/01/SIE4-Exempelfil-Sample-file-1.zip Current behavior: - The account 1090 is imported as "vriga imm anl tillg" instead of "Övriga imm anl tillg" Expected behavior: - The account 1090 is imported as "Övriga imm anl tillg" Cause: CP437 uses 8 bits to represent data. Ö is \x99. However, file was imported using either UTF-8 or ISO-8859-1, where Ö is \xC396 and \x99 doesn't link to anything. This commit update the test file as it was save in cp437 but read as UTF-8. opw-6167408 Forward-Port-Of: odoo/enterprise#116722
This update resolves an issue where users couldn't send messages from opportunities when a company partner was assigned. The previous system incorrectly checked for a direct match between the user and the assigned partner, failing when the user was a child contact. This change uses a more robust 'child_of' filter to ensure proper access, allowing messages to be sent correctly from company partners.
Original PR description
Steps to reproduce: 1) Create a partner contact form 2) Create a child contact for this partner, and grant it portal access 3) Create a customer contact form 4) Create an opportunity for the customer, with the previously created partner as "assigned partner" 5) Connect on the portal account of the partner 6) Send a message from an opportunity When a company partner is assigned to an opportunity (instead of a specific contact person), posting a message in the chatter raised a 404 NotFound error. _mail_get_operation_for_mail_message_operation was using a strict equality check (partner_assigned_id == user.partner_id), which fails when the assigned partner is the company and the user is a child contact under it. Replace the equality check with a child_of domain filter on commercial_partner_id, consistent with the logic already used in _assert_portal_write_access. Forward-Port-Of: odoo/odoo#259973 Forward-Port-Of: odoo/odoo#252854
This update resolves several errors that could occur when Odoo processes NOTI files for Belgian payroll. These errors were preventing accurate tax calculations and reporting for businesses using the l10n_be_hr_payroll module. The fix ensures more reliable and accurate payroll processing for Belgian users.
Original PR description
Forward-Port-Of: odoo/enterprise#116871
This update fixes a bug in the Belgium Payroll DMFA report that incorrectly displayed 'Days Per Week' as 5 when employees worked fewer than 5 days. The fix ensures the report accurately reflects the employee's actual working schedule, improving the accuracy of tax reporting.
Original PR description
## Issue When generating a DMFA report with a working schedule with more or less than 5 days a week, the *Days Per Week* value in the report is still appearing as 5. ## Steps to reproduce 1. Install…
## Issue
When generating a DMFA report with a working schedule with more or less than 5 days a week, the *Days Per Week* value in the report is still appearing as 5.
## Steps to reproduce
1. Install *Belgium - Payroll* (`l10n_be_hr_payroll`)
2. In Payroll's Settings:
- set *ONSS Registration Number* to `0830123456`
- set *DMFA Employer Class* to `083`
- create a *Work Address DMFA code* (any name, any numeral code, but set the *Working Address* to the Belgian company used for the rest of the steps)
3. In Employees' Settings, set the *Company Working Hours* to a new Working Schedule, with 9 hours/day, 4 days/week. E.g from Monday to Thursday included:
- Work from 8:00 to 12:00
- Lunch from 12:00 to 13:00
- Work from 13:00 to 18:00
4. Create an Employee E for the Belgian company:
- In the *Payroll* tab, set the start date of the contract to 01/01/2026.
- In the *Personal* tab, set the *NISS Number* to `85073003328`
5. Create the payslip for January 2026 for the Employee E.
6. In Payroll > Reporting > Belgium > DMFA, create a new DMFA for the first quarter of 2026 and generate the PDF report
7. **In the generated PDF report, the _Days per Week_ line is set to 5.**
## Cause
The number of days was calculated by multiplying `5` with the `work_time_rate` of the related calendar. This is inaccurate in the case of a company where employees are only expected to work 4 days a week.
opw-6103934
Forward-Port-Of: odoo/enterprise#116963
Forward-Port-Of: odoo/enterprise#113804This update fixes a display issue where the number of ECOs listed on a Bill of Materials (BoM) was incorrect. The fix ensures that the count accurately reflects the ECOs directly associated with the current BoM version, resolving a misleading display for users. This improves the accuracy of BoM information and simplifies understanding of related changes.
Original PR description
Steps to Reproduce (Fresh Database): -------------------------------------- 1. Install `Manufacturing` (mrp) and `PLM` (mrp_plm) modules 2. Create a product > New -- Name: "Test Product" > Save 3.…
Steps to Reproduce (Fresh Database):
--------------------------------------
1. Install `Manufacturing` (mrp) and `PLM` (mrp_plm) modules
2. Create a product > New -- Name: "Test Product" > Save
3. Create BoM v1
- Go to Manufacturing > Products > Bills of Materials > New --Product: Test Product
- Add component: any
4. Create and apply ECO 1 on BoM v1
- Go to PLM > ECOs > New-- Product: Test Product | Apply on: Bill of Materials
- BoM: Test Product (v1) > Confirm > Apply Changes
- This creates BoM v2 (previous_bom_id = BoM v1)
5. Create and apply ECO 2 on BoM v2
- Same as step 4 but select BoM v2
- This creates BoM v3 (previous_bom_id = BoM v2)
6. Create a separate unrelated BoM for the same product
- Go to Manufacturing > Bills of Materials > New
- Product: Test Product | Component: "Component B" > Save
7. Create ECO 3 on the separate BoM
- Go to PLM > ECOs > New - Product: Test Product | Apply on: Bill of Materials
- BoM: select the separate BoM from step 6 > Confirm
Observed Bug:
-------------
- Open BoM v3 > ECO(s) stat button shows count = 2
- Click the button > opens 3 records (ECO 3 incorrectly included)
Explain:-
----------
The ECO stat button on the BoM form was showing a mismatched count vs
the actual records opened when clicking it. This happened because
[button_mrp_eco](https://github.com/odoo/enterprise/blob/55bfd499660d3eda0abfc9e8ed8c9a2befbd394b/mrp_plm/models/mrp_bom.py#L56) was using all keys from [_get_previous_boms](https://github.com/odoo/enterprise/blob/55bfd499660d3eda0abfc9e8ed8c9a2befbd394b/mrp_plm/models/mrp_bom.py#L67)() as the
domain, which includes BoMs from unrelated lineages of the same product
template, while [_compute_eco_data](https://github.com/odoo/enterprise/blob/55bfd499660d3eda0abfc9e8ed8c9a2befbd394b/mrp_plm/models/mrp_bom.py#L20) only counts ECOs belonging to the
current BoM's version lineage.
Fixed by filtering the domain to only include BoM IDs whose lineage set
contains the current BoM ID, making the opened records consistent with
the displayed count.
Before Fix
<img width="1901" height="875" alt="image" src="https://github.com/user-attachments/assets/3208aed5-ebd3-47a3-a457-a7d61b7743cb" />
```
In [24]: labo = self.env['mrp.bom'].browse(710)
In [25]: previous_boms_mapping = labo._get_previous_boms()
In [26]: Test = ['&', ('bom_id', 'in', list(previous_boms_mapping.keys())), ('type', '=', 'bom')]
In [27]: Test
Out[27]:
['&',
('bom_id',
'in',
[710,
1991,
2049,
1913,
1840,
1823,
1676,
1759,
1794,
1651,
1604,
1544,
1537,
1527,
1506,
1460,
1265,
1259,
1196,
1221,
1223,
1060,
1029,
960,
858,
850,
791,
739,
723,
698]),
('type', '=', 'bom')]
```
With My Fix
<img width="1824" height="947" alt="image" src="https://github.com/user-attachments/assets/0d68fdbc-7e42-4ce4-a326-2fb030ba1d06" />
```
In [15]: labo = self.env['mrp.bom'].browse(710)
In [16]: previous_boms_mapping = labo._get_previous_boms()
In [17]: previous_boms_mapping
Out[17]:
{710: {710},
1991: set(),
2049: set(),
1913: set(),
1840: set(),
1823: set(),
1676: set(),
1759: set(),
1794: set(),
1651: set(),
1604: set(),
1544: set(),
1537: set(),
1527: set(),
1506: set(),
1460: set(),
1265: set(),
1259: set(),
1196: set(),
1221: set(),
1223: set(),
1060: set(),
1029: set(),
960: set(),
858: set(),
850: set(),
791: set(),
739: set(),
723: set(),
698: {710}}
In [18]: relevant_bom_ids = [
...: bom_id
...: for bom_id, current_bom_set in previous_boms_mapping.items()
...: if labo.id in current_bom_set
...: ]
In [19]: relevant_bom_ids
Out[19]: [710, 698]
```
Task-6065020
Forward-Port-Of: odoo/enterprise#114039This update resolves an issue where users were experiencing errors when opening account records. The fix ensures that payment IDs returned in a key calculation are filtered based on user access rights, preventing unauthorized access and improving stability. This change was made to align with existing security practices.
Original PR description
the computed fields _compute_reconciled_payment_ids return payment ids with a sql request that by pass the access rule. This lead in an error while opening some account.move as for https://github.com/odoo/enterprise/pull/99410 invoice_ids in sale.order the result return by the sql query should be filtered according to the access right. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#261595
This update fixes a calculation error in employee timesheets, ensuring accurate tracking of working hours across contract versions. The change updates how the system determines the valid working schedule for each employee, resolving discrepancies in remaining hours displayed.
Original PR description
Steps to reproduce: ------------------------------------ 1. Install Timesheets Module with demo data 2. Create a new Employee with: * Payroll Page > Contract > Start from 1st March * Payroll Page >…
Steps to reproduce:
------------------------------------
1. Install Timesheets Module with demo data
2. Create a new Employee with:
* Payroll Page > Contract > Start from 1st March
* Payroll Page > Working hours set to 'Standard 40 hours/week'
3. Go to Timesheets > All Timesheets
4. Add Timesheet for any task as follows:
* Select a date in a past week (e.g., 14th April)
* Hours: 8 hours
* Select the newly created employee
5. Go to Timesheets > All Timesheets:
* Filter by the new employee
* Navigate to the same past week
* Observe the remaining hours for the employee (e.g, -32:00)
6. Open the newly created employee form:
* Click on '+' to create a new contract version
* Set the version date before the timesheet date (e.g., 12th April)
* Change Working Hours to Standard 38 hours/week.
7. Repeat Step 5
Observation:
------------------------------------
The Remaining Hours shows -32:00, meaning the system still uses the 40 hours/week schedule instead of the updated one. The expected value should be -30:00 based on the 38 hours/week schedule.
Issue:
------------------------------------
The method `_get_contracts_valid_periods` determines which working calendar applies for which time period. It uses `contract.contract_date_start` and `contract.contract_date_end` to build calendar validity intervals, but these are the contract employment dates (shared across all versions of the same contract), NOT the version-specific effective dates.
Both versions share the same `contract_date_start`, so both claim the entire period as valid. The 40h calendar produces larger work intervals that win when combined via Intervals union, so the old 40h schedule is used instead of the current 38h one.
Solution:
------------------------------------
Replace `contract.contract_date_start` / `contract.contract_date_end` with `contract.date_start` / `contract.date_end`
These dates represent each version's effective validity period, computed from `date_version` and bounded by the next version's start date. Using these ensures each calendar is only valid during the period its version was actually in effect correctly splitting the working hours at version boundaries.
opw-6142137
Forward-Port-Of: odoo/odoo#264114
Forward-Port-Of: odoo/odoo#260614