Thursday, July 9, 2026
37 changes · saas-19.4
Resolved issues and error corrections
Belgian payroll no longer applies a special public holiday eligibility rule for time credit contracts because that rule had no legal basis. This helps ensure payroll calculations follow the correct Belgian legal interpretation.
Original PR description
The specific code related to the eligibility to public holiday for time credit contracts has no legal base. This commit removes it. task-6370653 Forward-Port-Of: odoo/enterprise#123303
The AI module’s markdown-related tests are now skipped when the optional markdown rendering library is not available. This prevents build or test failures caused by a missing optional component, improving reliability without changing user-facing functionality.
Original PR description
markdown2 is an optional dependency, so `markdown_format` can fail to process markdown, in which case all the markdown tests fail. Skip the markdown rendering test if there's no markdown rendering to test. Forward-Port-Of: odoo/enterprise#123484 Forward-Port-Of: odoo/enterprise#123002
The Swiss payroll time off request form now consistently shows the start date field. This prevents confusion and ensures employees can always enter the required date when requesting leave.
Original PR description
The time off request view was showing the request_date_from field conditionally, which makes no sense as you would always need to pick a date for a time off no matter which unit the request uses. runbot-241099 Forward-Port-Of: odoo/enterprise#122278
The SEPA Direct Debit payment option no longer shows the backend-oriented “(provider)” suffix to customers. This keeps checkout and payment screens clearer and more professional for users selecting this payment method.
Original PR description
Commit e90e1cd0 mistakenly suffixed the name of the SEPA Direct Debit `payment.method` record with "(provider)" while making payment methods provider-specific, aligning it with the `account.payment.method` record. However, `payment.method` records are customer-facing and should therefore not display hints intended for backend users.
Knowledge article PDF downloads now exclude unwanted interface elements such as scrollbars and open menus. This makes exported articles look cleaner and more professional, especially for longer content or when the browser is zoomed in.
Original PR description
The Download PDF option of an article prints the page with the browser. On screen, the article body is inside .o_scroll_view_lg, which scrolls when the content is longer than the screen:…
The Download PDF option of an article prints the page with the browser. On screen, the article body is inside .o_scroll_view_lg, which scrolls when the content is longer than the screen: https://github.com/odoo/enterprise/blob/79f8defa04476e1b939dc8bb5449a775137aed62/knowledge/static/src/scss/knowledge_views.scss#L170-L177 The print stylesheet used to force overflow: visible on every div, so this container did not scroll when printing. It also hid every child of the body except the action manager, so the navbar and open dropdowns were left out of the print. Commit https://github.com/odoo/enterprise/commit/69612c80ea0aec5ccf2c2857449da03e61273457 rewrote knowledge_print.scss to scope its rules to the Knowledge view and removed both rules. The scroll container now keeps its fixed height and its scrollbar when printing, so the scrollbar is drawn in the print preview and on every page of the PDF. The dropdown opened to reach Download PDF is printed on top of the article when it overlaps the page area, which happens when the browser is zoomed in. Add overflow: visible to the print rule of knowledge_print.scss that already targets .o_scroll_view and .o_scroll_view_lg with position: static. That rule exists to undo the screen positioning of the scroll containers when printing, so the overflow reset belongs there. Its selector is also more specific than the screen one, so the value applies without !important, like position: static already does. Restore the rule that hides the body children other than the action manager, scoped to the Knowledge view like the rest of the file since the print stylesheet is now loaded on every page. Before: <img width="497" height="703" alt="image" src="https://github.com/user-attachments/assets/44aa3366-3fc8-4382-8aa2-84625fa4b6d8" /> After: <img width="497" height="703" alt="image" src="https://github.com/user-attachments/assets/8b6eb2bc-37a3-4666-b871-0e6149c41fea" /> Steps to reproduce: 1. Open the Knowledge app and create an article 2. Paste enough text in the article to fill more than one PDF page 3. Zoom the browser to 200% 4. Click the three dots in the top right corner, then Download PDF 5. Check the print preview or the saved PDF => A scrollbar is drawn on the right edge of every page and the dropdown menu is printed on top of the article Ticket [link](https://www.odoo.com/odoo/project.task/6279174) opw-6279174 Forward-Port-Of: odoo/enterprise#120249
Facebook feed comments now show a still preview for GIF content instead of leaving it invisible. When users click the preview, they are taken to the related video on Facebook, making comments easier to understand and engage with.
Original PR description
Bug === When opening the comments modal of the feed view, the GIF images are not visible. Technical ========= The API does not return the GIF, it only returns the MP4 and the JPG. So we show the fixed image, and when clicking on it, it opens the video on Facebook. Task-6241607 Forward-Port-Of: odoo/enterprise#123181 Forward-Port-Of: odoo/enterprise#118619
The point of sale invoice toggle now only triggers India-specific logic when the session is actually operating in India. This prevents avoidable errors in other countries and keeps payment workflows more reliable.
Original PR description
Toggle invoice button was making a call in IN localization even when not in a IN country. This was causing an error in runbot 940146. This commit fixes the issue by checking if the country is IN before making the call. In `pos_settle_due` the method signature was not correct. Forward-Port-Of: odoo/enterprise#123539
Helpdesk closing reminder emails are now only sent to tickets in stages that are actually eligible for automatic closing. This prevents customers from receiving misleading warnings about tickets that would not be closed under the team’s configured rules.
Original PR description
**Problem:** When a team restricts automatic closing to specific stages (from_stage_ids), the closing-reminder email is still sent to every inactive ticket in the team, including tickets in stages…
**Problem:** When a team restricts automatic closing to specific stages (from_stage_ids), the closing-reminder email is still sent to every inactive ticket in the team, including tickets in stages that are never auto-closed. **Steps to reproduce:** 1. On a helpdesk team, enable Automatic Closing with a reminder and set "In Stages" (from_stage_ids) to one specific stage 2. Leave a ticket inactive in a different, non-folded stage until it reaches the reminder threshold (auto_close_day - reminder_delay) **Current behavior:** The ticket gets a "your ticket will be closed soon" reminder even though it is not in an auto-close stage and will never be closed. **Expected behavior:** Only tickets that would actually be auto-closed (those in from_stage_ids) should receive the reminder. **Cause of the issue:** The reminder selection filters on auto_close_ticket_reminder and the reminder date only; unlike the auto-close selection, it does not apply the team's from_stage_ids condition. **Fix:** Reuse the same stage condition used to select tickets for closing when selecting tickets for the reminder, so the reminded set stays consistent with the set that will be auto-closed. opw-6291237 Forward-Port-Of: odoo/enterprise#120732
Users can no longer save an IoT report printer setup without choosing an actual printer device. This prevents later printing failures caused by incomplete printer configuration.
Original PR description
Community PR: https://github.com/odoo/odoo/pull/273723 Before this commit, you could configure an IoT report printer but not select any IoT printer device, which would cause printing to fail later on. After this commit, the field is required so the user must select a printer device before saving. task-6333695
The Frontdesk module now declares the dependency it needs for its scheduling timeline view. This helps ensure the feature loads reliably when Frontdesk is installed or updated.
Original PR description
runbot-237869 Forward-Port-Of: odoo/enterprise#122292
Fixes an issue where using the mute button during VoIP demo calls could cause the call interface to crash. Demo calls now better simulate microphone behavior, improving reliability for demonstrations and testing.
Original PR description
Since commit [1], clicking the "mute" button during demo calls crashed. This is because the mocked SIP.js object now includes a `peerConnection` which was the guard against actually toggling microphone input. Now we do mock microphone toggling as well, preventing the crash, and making demo calls more realistic at the same time too. [1]: https://github.com/odoo/enterprise/commit/351dac8a19b581bc0892f18c3048228471c28238 Related to task-6361911
This update fixes a missing text string in the Stripe expense integration so users see the intended message instead of a deprecated or incomplete one. It is a small correction that improves clarity without changing business workflows.
Original PR description
Add missing string runbot-941402 Forward-Port-Of: odoo/enterprise#123638 Forward-Port-Of: odoo/enterprise#123495
Canadian check printing now hides check numbers on payment stubs when using pre-numbered checks. This keeps stubs consistent with the printed check and avoids duplicate or misleading check number information.
Original PR description
The check itself respected the check_manual_sequencing field, but the stubs did not. Hide the numbers on stubs as well, exactly like on US checks. task-6343701 Forward-Port-Of: odoo/enterprise#122565
This change fixes a flaky test in the HTML editor toolbar, preventing occasional false failures during automated testing. It makes the test more reliable by checking the order of internal updates instead of relying on timing-sensitive screen changes.
Original PR description
### Description of the issue/feature this PR addresses: - Resolve non-deterministic failures in the 'toolbar should not open between double and triple click' Hoot test. - Because browser-level selectionchange events are dispatched asynchronously in the event loop, asserting on the presence of `.o-we-toolbar` in the DOM leads to timing race conditions. ### Solution: - Resolves the flakiness by introducing a wrapper method `triggerDebouncedUpdateToolbar` in `ToolbarPlugin` and refactoring the test to track method call sequences instead of asserting on DOM elements. This verifies the scheduled debounced updates in a deterministic sequence. task: https://runbot.odoo.com/odoo/error/243145 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#274498 Forward-Port-Of: odoo/odoo#273303
Currently, if you have an error in the response, we don't try to get the error message, we just give the type of error. Let us do that. Partial fw-port of https://github.com/odoo/odoo/commit/4bfe16cd45828a864a159b566d7983246e7e03a5 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#273754
Original PR description
Currently, if you have an error in the response, we don't try to get the error message, we just give the type of error. Let us do that. Partial fw-port of https://github.com/odoo/odoo/commit/4bfe16cd45828a864a159b566d7983246e7e03a5 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#273754
Before this commit, selecting one or more rows in a list view disabled text selection on the whole list, which also prevented users from selecting the totals displayed in the footer. This commit fixes the issue on the list footer, so totals remain selectable even when rows are selected. task:6240238 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#272126
Original PR description
Before this commit, selecting one or more rows in a list view disabled text selection on the whole list, which also prevented users from selecting the totals displayed in the footer. This commit fixes the issue on the list footer, so totals remain selectable even when rows are selected. task:6240238 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#272126
Remove useless assignation of state from frontend in `_check_pos_order` because its overrided just after in the process. Forward-Port-Of: odoo/odoo#272925 Forward-Port-Of: odoo/odoo#272176
Original PR description
Remove useless assignation of state from frontend in `_check_pos_order` because its overrided just after in the process. Forward-Port-Of: odoo/odoo#272925 Forward-Port-Of: odoo/odoo#272176
A paid order can reach `sync_from_ui` more than once. In that case the order falls into the else branch of `sync_from_ui` and its payments are re-processed through `process_saved_payments`, which was not idempotent and led to two issues: - The change/return cash payment is generated server-side in `_process_payment_lines` and has no uuid, so `_update_lines` cannot deduplicate it. Each extra sync therefore created an additional return payment. It is now removed before being recomputed, which a
Original PR description
A paid order can reach `sync_from_ui` more than once. In that case the order falls into the else branch of `sync_from_ui` and its payments are re-processed through `process_saved_payments`, which was…
A paid order can reach `sync_from_ui` more than once. In that case the order falls into the else branch of `sync_from_ui` and its payments are re-processed through `process_saved_payments`, which was not idempotent and led to two issues: - The change/return cash payment is generated server-side in `_process_payment_lines` and has no uuid, so `_update_lines` cannot deduplicate it. Each extra sync therefore created an additional return payment. It is now removed before being recomputed, which also keeps it correct when the payments are edited after payment (new return amount, or no change at all). - `_update_lines` replays the client commands as-is. On a second sync, a delete command (`[2, id]`) targets a payment that the first sync already removed, and `_create_pm_change_log` crashed with a MissingError while reading the deleted record. Update/delete/unlink commands referencing records that no longer exist are now skipped. Note that delete/unlink commands only carry 2 elements, so the check runs before the `len(line) < 3` guard. Steps to reproduce: - Pay an order, then re-sync it (or edit its payments and sync again). => the return payment was duplicated, or a MissingError was raised. opw-6327912 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#272539
This PR is needed for the fix of https://github.com/odoo/odoo/pull/272411 **Problem:** lot's standard price are not correct when the product is fifo and move have different values and multiple lots **Steps to reproduce:** - product fifo tracked and valued by lots - 20 IN @ 100 (all in lot 1) - 10 IN @ 10 (5 in lot 1 and 5 in lot 2) - on the product form click on the lot/serial number smart button and select lot 1 **Current behavior:** the average cost of lot1 is 64 back o
Original PR description
This PR is needed for the fix of https://github.com/odoo/odoo/pull/272411 **Problem:** lot's standard price are not correct when the product is fifo and move have different values and multiple lots…
This PR is needed for the fix of https://github.com/odoo/odoo/pull/272411 **Problem:** lot's standard price are not correct when the product is fifo and move have different values and multiple lots **Steps to reproduce:** - product fifo tracked and valued by lots - 20 IN @ 100 (all in lot 1) - 10 IN @ 10 (5 in lot 1 and 5 in lot 2) - on the product form click on the lot/serial number smart button and select lot 1 **Current behavior:** the average cost of lot1 is 64 back on the product form the standard price is 55 **Expected behavior:** the average cost of lot 1 should be 20 * 100 (from move1) + 5 * 10 (from move 2) / 25 = 2050 / 25 = 82 the standard price of the product should be 2100 / 30 = 70 **Cause of the issue:** Because the product is fifo, to compute the avg_cost of the lot we call _run_fifo() https://github.com/odoo/odoo/blob/456026b5ef99388b1cf5bdd78cee8d1ad3d51304/addons/stock_account/models/stock_lot.py#L47 which calls _run_fifo_get_stack() to get the fifo stack specific to this lot. https://github.com/odoo/odoo/blob/456026b5ef99388b1cf5bdd78cee8d1ad3d51304/addons/stock_account/models/product.py#L545 Issue 1) run_fifo_get_stack() stores the on hand quantity (for the lot if a lot is given as param) in fifo_stack_size and, as long as there is moves and fifo_stack_size>0, adds move (starting from the last one in date) to the stack and removes the quantity of the move from fifo_stack_size. It then returns the moves stack and the remaning quantity on the first move of the stack (for the rest we know it's the full quantity) https://github.com/odoo/odoo/blob/456026b5ef99388b1cf5bdd78cee8d1ad3d51304/addons/stock_account/models/product.py#L612-L618 Inside run_fifo_get_stack(), to do this, because we're only considering the quantities from this specific lot we should only remove the quantity from the move that went in lot, but currently we're removing the quantity from the entire move. https://github.com/odoo/odoo/blob/456026b5ef99388b1cf5bdd78cee8d1ad3d51304/addons/stock_account/models/product.py#L615-L618 So, at the first iteration of the while loop (for the move with 10 quantities), instead of doing fifo_stack_size(25) -= 5, we do fifo_stack_size(25) -= 10 The next move is the last one, so it's the one on which remaining_qty_on_first_stack_move will be based on. remaining_qty_on_first_stack_move will be the minimum between the move's quantity and the fifo_stack_size. So because the fifo_stack_size is now wrongfully 15 instead of 20 that's the value that will be returned by _run_fifo_get_stack. So inside run_fifo(), qty_on_first_move will be 15 instead of 20 https://github.com/odoo/odoo/blob/456026b5ef99388b1cf5bdd78cee8d1ad3d51304/addons/stock_account/models/product.py#L545 Issue 2) Another issue is that inside _run_fifo when calling _get_valued on the move, we don't use the lot parameter. So we use the entire quantity of the move instead of the quantity specific to the lot. https://github.com/odoo/odoo/blob/b07ff5843ee87741b293d9e67f72a77a2ed2ed88/addons/stock_account/models/product.py#L561-L562 And we use the full value of the move instead of the pro rata of the value for the quantity specific to the lot As a consequence, inside _run_fifo the computation for the fifo_cost will be 15 (because of issue1) * 100 $ [first iteration of the while loop] \+ 10 (because of issue 2) * 10$ [second iteration of the while loop] = 1600$ Instead of 20 *100 + 5 *10$ = 2050$ Therefore the avg_cost of the lot is wrong and the standard price of the product will also be false. side note: those two issues balance each other if the price unit of the moves are the same needed for PR of opw-6311341 Forward-Port-Of: odoo/odoo#274913 Forward-Port-Of: odoo/odoo#273728
Toggle invoice button was making a call in IN localization even when not in a IN country. This was causing an error in runbot 940146. This commit fixes the issue by checking if the country is IN before making the call. In `pos_settle_due` the method signature was not correct. The linked enterprise commit also fix it. Forward-Port-Of: odoo/odoo#275055
Original PR description
Toggle invoice button was making a call in IN localization even when not in a IN country. This was causing an error in runbot 940146. This commit fixes the issue by checking if the country is IN before making the call. In `pos_settle_due` the method signature was not correct. The linked enterprise commit also fix it. Forward-Port-Of: odoo/odoo#275055
### Description: When trying to install the module `l10n_es_edi_verifactu` on a database that already has moves, it is possible to encounter a timeout or a memory error. This is caused by the compute `l10n_es_edi_verifactu_state` and `l10n_es_edi_verifactu_clave_regimen`, both compute linked to the new model `l10n_es_edi_verifactu.document`. ### Reference: opw-6293590 Forward-Port-Of: odoo/odoo#273416 Forward-Port-Of: odoo/odoo#271550
Original PR description
### Description: When trying to install the module `l10n_es_edi_verifactu` on a database that already has moves, it is possible to encounter a timeout or a memory error. This is caused by the compute `l10n_es_edi_verifactu_state` and `l10n_es_edi_verifactu_clave_regimen`, both compute linked to the new model `l10n_es_edi_verifactu.document`. ### Reference: opw-6293590 Forward-Port-Of: odoo/odoo#273416 Forward-Port-Of: odoo/odoo#271550
Receipt template is also generated in the backend, so we need to use t-out instead of t-esc. runbot error: 941385 Forward-Port-Of: odoo/odoo#275082
Original PR description
Receipt template is also generated in the backend, so we need to use t-out instead of t-esc. runbot error: 941385 Forward-Port-Of: odoo/odoo#275082
Posting a message updates discuss_channel.last_interest_dt. Writing it on the channel row inside the request transaction holds a lock on that hot row for the whole transaction, so parallel posters pile up on it and crash with: could not serialize access due to concurrent update Instead, under the message-post controller (mail_post_check_concurrency), record the new value as an append-only row in discuss.channel.last.interest.update. An INSERT never serializes against parallel posters a
Original PR description
Posting a message updates discuss_channel.last_interest_dt. Writing it on the channel row inside the request transaction holds a lock on that hot row for the whole transaction, so parallel posters…
Posting a message updates discuss_channel.last_interest_dt. Writing it on the channel row inside the request transaction holds a lock on that hot row for the whole transaction, so parallel posters pile up on it and crash with:
could not serialize access due to concurrent update
Instead, under the message-post controller (mail_post_check_concurrency), record the new value as an append-only row in discuss.channel.last.interest.update. An INSERT never serializes against parallel posters and commits atomically with the message. The value is synced onto discuss_channel.last_interest_dt afterwards by a post-commit hook (a fresh transaction, hence a fresh snapshot that no longer conflicts), guarded by a non-blocking advisory lock per channel. The appended rows are durable, so a cron (ir_cron_discuss_channel_sync_last_interest_dt) drains anything the post-commit hook skipped, failed on, or never reached because its worker died — guaranteeing the channel is eventually bumped (a lost bump would mean a message is never surfaced). Reads and sorting keep using the indexed channel column.
With last_interest_dt no longer writing the channel row in the request transaction, livechat_failure goes back to a plain write, guarded so only the first agent message flips it; any rare residual conflict is handled by the regular request retry.
task-6321278
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prBefore this PR: When navigating pages or creating events, sync notifications were shown every time, even when no sync operation was performed. This was unnecessary and could be confusing. Technical- In commit https://github.com/odoo/odoo/commit/fb306b6386edf27ec09977ceb2a8e18a89cb9b9d, notifications were based on pending status. After this PR: -Sync notifications are shown only for actual sync operations that take more than 1 second. -"Sync in progress..." is updated to "Syncing". -Re
Original PR description
Before this PR: When navigating pages or creating events, sync notifications were shown every time, even when no sync operation was performed. This was unnecessary and could be confusing. Technical- In commit https://github.com/odoo/odoo/commit/fb306b6386edf27ec09977ceb2a8e18a89cb9b9d, notifications were based on pending status. After this PR: -Sync notifications are shown only for actual sync operations that take more than 1 second. -"Sync in progress..." is updated to "Syncing". -Removed the message "This may take some time" from the notification. Task-6334724
Before this commit, when losing connection to the server, the "Offline UI" introduced in [1] would disable all buttons in Discuss. This prevents navigating the Discuss channels, even if we potentially have local knowledge of the messages in those channels. It also prevents using Thread actions like: - Channel Members - Pinned Messages - Attachments - Threads Which may also only need data that is available locally. This commit fixes the issue by marking the appropriate buttons as availa
Original PR description
Before this commit, when losing connection to the server, the "Offline UI" introduced in [1] would disable all buttons in Discuss. This prevents navigating the Discuss channels, even if we potentially have local knowledge of the messages in those channels. It also prevents using Thread actions like: - Channel Members - Pinned Messages - Attachments - Threads Which may also only need data that is available locally. This commit fixes the issue by marking the appropriate buttons as available offline (`data-available-offline`), which prevents the Offline UI service from disabling them. [1] https://github.com/odoo/odoo/pull/229492 task-6185454 Forward-Port-Of: odoo/odoo#275090 Forward-Port-Of: odoo/odoo#273122
The following use case has been observed: 0. Customer start a payment from /shop/payment. 1. We received the webhook that notifies that the payment succeeded. 2. The payment post-processing cron start (it gather all the transactions that need to be processed, including the customer new transaction) 3. Meanwhile, the customer is redirected back by the payment provider to Odoo, which then redirect to /payment/status and start the payment post-processing for that specific transaction 4. The
Original PR description
The following use case has been observed: 0. Customer start a payment from /shop/payment. 1. We received the webhook that notifies that the payment succeeded. 2. The payment post-processing cron…
The following use case has been observed: 0. Customer start a payment from /shop/payment. 1. We received the webhook that notifies that the payment succeeded. 2. The payment post-processing cron start (it gather all the transactions that need to be processed, including the customer new transaction) 3. Meanwhile, the customer is redirected back by the payment provider to Odoo, which then redirect to /payment/status and start the payment post-processing for that specific transaction 4. The customer initiated payment processing finishes, he is redirected back to /my/orders/... page. 5. The payment post-processing cron finally start processing the same customer transaction and process it (a second time). In that case, as the transactions to be post-processed backlog was quite high, there is consequent time between the time we gather all the TXs to post-process and actually process the customer transaction. Also we don't end up with a `SerializationError` as the cron do commit after each transaction post-processing. This commit force invalidate individual transaction cache values and recheck if it effectively still need to be post-processed before doing it. opw-6332192 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#274725 Forward-Port-Of: odoo/odoo#274010
Steps to reproduce: - - Create a sale order. - Link a project using the Project field. - Confirm the sale order. - Click on the Project smart button. Issue: - The Project smart button is displayed since the sale order has a linked project. However, clicking on it does nothing. Cause: - A sale order without order lines can still have projects linked through the project_id field. The action should not assume that no order lines means there are no projects to display. Solution: -
Original PR description
Steps to reproduce: - - Create a sale order. - Link a project using the Project field. - Confirm the sale order. - Click on the Project smart button. Issue: - The Project smart button is displayed since the sale order has a linked project. However, clicking on it does nothing. Cause: - A sale order without order lines can still have projects linked through the project_id field. The action should not assume that no order lines means there are no projects to display. Solution: - Remove the unnecessary order line check and allow the existing logic to open the linked projects. task-6209658 Forward-Port-Of: odoo/odoo#270752
This commit adds an index to speed up the task name_search in timesheets when project_timesheet_holidays is installed. Forward-Port-Of: odoo/odoo#273925
Original PR description
This commit adds an index to speed up the task name_search in timesheets when project_timesheet_holidays is installed. Forward-Port-Of: odoo/odoo#273925
Before this commit, when attempting to "Pay with Demo" a cart as a public user, the transaction fails and redirects to the shipping address form. This commit fixes the issue by adding a dummy phone number.
Original PR description
Before this commit, when attempting to "Pay with Demo" a cart as a public user, the transaction fails and redirects to the shipping address form. This commit fixes the issue by adding a dummy phone number.
SurveyResult binds a click listener on each .filter-add-answer icon when it starts. The response tables are rendered by a separate interaction, SurveyResultPagination, which swaps the tbody through a t-out directive on every page change and on Show All. Those new rows are nodes SurveyResult never bound, so their filter icon does nothing and the page reloads on the unfiltered view. The direct binding comes from https://github.com/odoo/odoo/commit/dfc1c742e35f75f2c386c4ef50d5584537ac1ed4, which r
Original PR description
SurveyResult binds a click listener on each .filter-add-answer icon when it starts. The response tables are rendered by a separate interaction, SurveyResultPagination, which swaps the tbody through a…
SurveyResult binds a click listener on each .filter-add-answer icon when it starts. The response tables are rendered by a separate interaction, SurveyResultPagination, which swaps the tbody through a t-out directive on every page change and on Show All. Those new rows are nodes SurveyResult never bound, so their filter icon does nothing and the page reloads on the unfiltered view. The direct binding comes from https://github.com/odoo/odoo/commit/dfc1c742e35f75f2c386c4ef50d5584537ac1ed4, which replaced the jQuery delegated handlers that used to survive re-renders. https://github.com/odoo/odoo/commit/c2f0f681714fcb936ce058e8dd4f1b1e9fa7448c reattaches them on tab change but not on pagination or Show All, so only the first page works. Bind updateContent on .pagination_wrapper, which holds the page links and the Show All button and stays outside the re-rendered tbody. A click on either bubbles up and rebinds .filter-add-answer on the rows that were just rendered. Steps to reproduce: 1. Install survey 2. Create a survey with a Date question 3. Share it and record more than ten responses so the responses table spans several pages 4. Open the survey results page and click the list icon on the date question to show the User Responses table 5. Move to page 2 and click the filter icon on any row => The page reloads on the unfiltered view and the selected date is not applied Ticket [link](https://www.odoo.com/odoo/project.task/6238514) opw-6238514 Forward-Port-Of: odoo/odoo#268569
Set message_type as 'comment' only when creating a new message. Updating content should not change it. Task-6368820 Part of Task-3704380 Forward-Port-Of: odoo/odoo#275208 Forward-Port-Of: odoo/odoo#274988
Original PR description
Set message_type as 'comment' only when creating a new message. Updating content should not change it. Task-6368820 Part of Task-3704380 Forward-Port-Of: odoo/odoo#275208 Forward-Port-Of: odoo/odoo#274988
Steps to reproduce: - Have an embedded file (e.g. in knowledge upload a file) - Click on edit icon - Try to write something: traceback occurs This happens becuase commit [1] adapts xml templates to owl3 rendering context but one change got missed out `t-on- keydown.stop="onKeydownNameInput"`. This leads to traceback. This commit replaces `t-on-keydown.stop="onKeydownNameInput"` to `t-on-keydown.stop="this.onKeydownNameInput"`. [1]: https://github.com/odoo/odoo/commit/f8c3ca4a7dd25182e
Original PR description
Steps to reproduce: - Have an embedded file (e.g. in knowledge upload a file) - Click on edit icon - Try to write something: traceback occurs This happens becuase commit [1] adapts xml templates to owl3 rendering context but one change got missed out `t-on- keydown.stop="onKeydownNameInput"`. This leads to traceback. This commit replaces `t-on-keydown.stop="onKeydownNameInput"` to `t-on-keydown.stop="this.onKeydownNameInput"`. [1]: https://github.com/odoo/odoo/commit/f8c3ca4a7dd25182e93604733da1847fc019095c task-6323879 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Previously, the default value of `withhold` was determined by checking only whether `withholding_residual` was non-zero. In over-deduction scenarios, `withholding_residual` becomes negative, causing the default payment category to be incorrectly set to `withhold` or `withhold_pay`. Additionally, after a withholding-only payment with an over-deduction, the payment wizard proposed an incorrect payment amount because the negative `withholding_residual` was added back to the payment amount. With
Original PR description
Previously, the default value of `withhold` was determined by checking only whether `withholding_residual` was non-zero. In over-deduction scenarios, `withholding_residual` becomes negative, causing the default payment category to be incorrectly set to `withhold` or `withhold_pay`. Additionally, after a withholding-only payment with an over-deduction, the payment wizard proposed an incorrect payment amount because the negative `withholding_residual` was added back to the payment amount. With this commit, the default `withhold` value is assigned only when `withholding_residual` is positive, and the payment wizard now correctly shows the remaining amount to pay after considering over-deduction.
## Problem If the `property_cost_method` on a product category defaults to the value in `ir_default`, the query that builds the avco report will fail to properly parse the default value. This is specifically due to the defaults in the `json_value` column being stored as varchar, so strings are surrounded with quotation marks. ## Solution We will adjust the query in the avco report to unpack the `json_value` field as text correctly, stripping it of its quotation marks. ## Steps to reprodu
Original PR description
## Problem If the `property_cost_method` on a product category defaults to the value in `ir_default`, the query that builds the avco report will fail to properly parse the default value. This is specifically due to the defaults in the `json_value` column being stored as varchar, so strings are surrounded with quotation marks. ## Solution We will adjust the query in the avco report to unpack the `json_value` field as text correctly, stripping it of its quotation marks. ## Steps to reproduce (runbot 19.3) 1. In settings, set the default costing method to avco or fifo 2. Create a product, and set the category to one of the default ones (like 'Goods'). Do not set a cost 3. Create a PO for the product, and receive 1 unit at $10 4. Head to Inventory > Reporting > Stock, and look up the new product. Click on the unit cost, and notice that there is no line for the receipt opw-6331178 Forward-Port-Of: odoo/odoo#273527
### Summary When `dev_mode` includes `reload`, `ThreadedServer`'s FSWatcher reacts to a file change by sending the process a `SIGHUP` to trigger a phoenix restart. `signal_handler` turns `SIGHUP` into `KeyboardInterrupt`, which `ThreadedServer.run()`'s wait-loop catches. The catch is too narrow — a reload `SIGHUP` can kill the process through **three** windows that all sit outside the wait-loop's `try/except`, so the exception escapes `run()`/`main()`. Under Docker's default `restart: no`, PID
Original PR description
### Summary When `dev_mode` includes `reload`, `ThreadedServer`'s FSWatcher reacts to a file change by sending the process a `SIGHUP` to trigger a phoenix restart. `signal_handler` turns `SIGHUP`…
### Summary When `dev_mode` includes `reload`, `ThreadedServer`'s FSWatcher reacts to a file change by sending the process a `SIGHUP` to trigger a phoenix restart. `signal_handler` turns `SIGHUP` into `KeyboardInterrupt`, which `ThreadedServer.run()`'s wait-loop catches. The catch is too narrow — a reload `SIGHUP` can kill the process through **three** windows that all sit outside the wait-loop's `try/except`, so the exception escapes `run()`/`main()`. Under Docker's default `restart: no`, PID 1 dies and the container stays down. ### The three windows 1. **Teardown duplicate (exit 130).** One file change can emit several FS events; the FSWatcher's `if not odoo.phoenix:` dedup races across threads and fires more than one `SIGHUP`. The first begins the phoenix teardown; the second lands during `stop()` / `watcher.stop()` / `_reexec()` and `KeyboardInterrupt` escapes. 2. **Exec-gap (exit 129).** `os.execve()` resets caught signal handlers to their default disposition (`SIGHUP` terminates) but preserves `SIG_IGN`; a `SIGHUP` arriving after the exec but before the re-exec'd process re-installs its handler kills the process outright. 3. **Startup (exit 130).** In the re-exec'd process, a `SIGHUP` anywhere in the startup section that precedes the wait-loop — `start()`, `preload_registries()` **and** `cron_spawn()` — escapes `run()`. ### Reproducer (deterministic) Boot a `ThreadedServer` (`--workers 0`) on any initialised db, then signal PID 1 a few times in quick succession: ```bash docker exec <container> sh -c 'i=0; while [ $i -lt 8 ]; do kill -HUP 1; sleep 0.1; i=$((i+1)); done' ``` Unpatched the process exits 130 or 129. Patched it stays up after one clean phoenix reload. Verified live on 17.0 and 18.0: stock `server.py` dies; the patched `server.py` survives sustained bursts (20/20 across repeated reload cycles on each version); `SIGINT`/`SIGTERM` still exit 0. ### Fix Minimal, in `signal_handler` + `run()` + `_reexec()`; `SIGINT`/`SIGTERM` untouched; one new instance attribute, no new module globals: - **Teardown duplicate:** ignore a `SIGHUP` once `quit_signals_received` is set (a restart/shutdown is already pending; the re-exec reloads fresh code). - **Startup:** a per-instance `in_preload` flag marks the entire startup section (`start()` + `preload_registries()` + `cron_spawn()`); a `SIGHUP` there sets the phoenix flag + counter and returns instead of raising, so the wait-loop exits right after startup and runs the normal restart. - **Exec-gap:** `signal.signal(signal.SIGHUP, signal.SIG_IGN)` just before `os.execve` so a `SIGHUP` in the gap is dropped rather than terminating the process. ### Related - #21209 (merged) — introduced the phoenix flag; did not guard these windows. - #206898 (merged), #207930 (open) — PreforkServer reload. ### CLA Covered by Codeforward B.V.'s corporate CLA; #269240 adds me to its contributor list (pending merge). Forward-Port-Of: odoo/odoo#273895 Forward-Port-Of: odoo/odoo#269247
This update resolves a problem where users couldn't delete expenses that had attached files. The fix ensures that expenses with attachments can now be successfully deleted, preventing data loss and improving the user experience. This change impacts the HR Expense module.
Original PR description
To reproduce: - Create an expense - Add an attachment - Try to delete the expense --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#274973 Forward-Port-Of: odoo/odoo#274710
This update fixes a problem where receipts sometimes printed blank or were cut prematurely. A small delay was added after sending the receipt image to allow the printer to fully process the data. The update also modernizes the printer SDK for better stability and future compatibility.
Original PR description
Previously, printing a receipt could sometimes result in blank paper being dispensed or the paper being cut prematurely. This occurred because the sequence of line feeds and cut commands was dispatched immediately after sending the image payload, before the printer hardware had sufficient time to process and spool the bitmap. To resolve this, a 200ms delay is introduced after the bitmap is sent. Additionally, the arbitrary `printAndLineFeed` calls are replaced with a precise `printAndFeedPaper` and explicit `partialCut` command. This ensures the hardware has fully rendered the receipt before advancing the paper and engaging the blade. Finally, the internal imin SDK (`lib/imin-printer/imin-printer.js`) is updated to handle websocket connection timeouts gracefully and to expose new hardware APIs for future tracking. owp-6242801 Forward-Port-Of: odoo/odoo#274146 Forward-Port-Of: odoo/odoo#270765