Daily updates from Odoo
Sunday, August 16, 2026
10 changes
3 changes
Resolved issues and error corrections
The Timesheet Assistant now keeps always-active work events, such as Google Meet meetings, from being interrupted by automatic AFK suggestions. This makes time suggestions and meeting descriptions more accurate for users reviewing their timesheets.
Original PR description
## Previous Behavior Before this PR: Users could have their always-active event split by an AFK event inside of Timesheet Assistant. AFK event durations were also inaccurate, and the Google Meet…
## Previous Behavior Before this PR: Users could have their always-active event split by an AFK event inside of Timesheet Assistant. AFK event durations were also inaccurate, and the Google Meet description was incorrect. ## Steps to Reproduce: 1. Generate an always-active event (e.g., join a meeting in Google Meet). 2. Generate non-key events (e.g., visit a website without an ActivityWatch rule). 3. Go AFK. 4. Generate a new non-key event. 5. The Timesheet Assistant will show three suggestions in the following order: an always-active suggestion, an AFK suggestion, and another always-active suggestion for the same activity. ## New Expected Behavior After this PR: The Timesheet Assistant now blocks the creation of AFK suggestions when the previous key event is marked as always-active. AFK event durations have been updated to ensure their values are accurate. The Google Meet description has also been corrected. task-[6431526](https://www.odoo.com/odoo/project/4105/tasks/6431526) Forward-Port-Of: odoo/enterprise#127028
Helpdesk tickets no longer show an SLA as reached immediately after it is assigned. The status now updates only when the ticket reaches the relevant target stage, giving teams more accurate SLA reporting while keeping lateness tracked separately.
Original PR description
### Steps to Reproduce: 1. Go to Helpdesk and create an SLA 2. Create a new Ticket 3. Use Studio to add the field `sla_reached` 4. Apply the SLA 5. Notice that the field is True ### Description of…
### Steps to Reproduce: 1. Go to Helpdesk and create an SLA 2. Create a new Ticket 3. Use Studio to add the field `sla_reached` 4. Apply the SLA 5. Notice that the field is True ### Description of the issue/feature this PR addresses: **Issue:** The `_compute_sla_reached` method in on `helpdesk_ticket.py` determines whether an SLA has been reached by checking if `exceeded_hours` is less than 0 on its `helpdesk.sla.status` records. Since every newly assigned SLA has a future deadline, `exceeded_hours` starts as negative (AKA <0), so the ticket is immediately flagged as `sla_reached = True` before any progress has been made. Conversely, a ticket that reaches its target stage after the deadline has `exceeded_hours >= 0`, so it's incorrectly flagged as `sla_reached = False` even though the SLA target was genuinely reached (it was just late). **Solution:** Change the domain in `_compute_sla_reached` to check `reached_datetime != False` instead of `exceeded_hours < 0`, matching the field already listed in the method's `@api.depends` and the same field `_sla_reach()` sets when a ticket enters its target stage. This makes `sla_reached` reflect actual stage progression rather than a time-remaining calculation. ### Current behavior before PR: A newly created ticket with a pending SLA shows `sla_reached = True` and `sla_success = True` immediately upon creation, before the ticket has moved to any target stage. SImilarly, a ticket that reaches its target stage after the SLA deadline is incorrectly marked `sla_reached = False`. ### Desired behavior after PR: `sla_reached` is False on ticket creation and only becomes True once the ticket actually enters the SLA's target stage. Lateness continues to be tracked separately and correctly via `sla_reached_late` opw-6361851 Forward-Port-Of: odoo/enterprise#127309 Forward-Port-Of: odoo/enterprise#126432
Mexican Point of Sale global invoices now ignore cancelled refund orders, so only completed refunds affect the invoice totals. This prevents invoice creation errors caused by subtracting unpaid cancelled refunds and helps businesses generate CFDI global invoices reliably.
Original PR description
Steps to reproduce: ------------------- 1. Install `l10n_mx_edi_pos` and set the company to Mexico. 2. In PoS, make an order with one product and pay it. 3. Open the order in the backend, click…
Steps to reproduce: ------------------- 1. Install `l10n_mx_edi_pos` and set the company to Mexico. 2. In PoS, make an order with one product and pay it. 3. Open the order in the backend, click "Return Products" to make a refund, but don't pay it, cancel it instead. 4. From the same order, click "Return Products" again to make a second refund, and pay it normally. 5. Go to the orders list, select the main order and the paid refund (not the cancelled one), then Actions > Create Global Invoice. -> Observation: error in the global invoice. In the CFDI tab of the main order the line is "Send Global In Error", and hovering on it the detail says "Failed to distribute some negative lines". Why: ---- When we make the global invoice, we remove the refunds from the order. A cancelled refund was never paid, so we should not count it. But we were counting it too. So we removed the refund amount twice in our case, one for the paid refund, and one for the cancelled one, and we end up with an order with negative amount that cannot be distributed. The fix: -------- We now skip the cancelled orders when we search the refunds, the same way it is done above when we collect the refunded orders. opw-6261404 Forward-Port-Of: odoo/enterprise#127808 Forward-Port-Of: odoo/enterprise#120996
3 changes
Resolved issues and error corrections
Helpdesk tickets no longer show an SLA as reached immediately after it is assigned. The status now changes only when the ticket reaches the relevant SLA stage, giving teams more accurate SLA reporting and separating late completion from actual completion.
Original PR description
### Steps to Reproduce: 1. Go to Helpdesk and create an SLA 2. Create a new Ticket 3. Use Studio to add the field `sla_reached` 4. Apply the SLA 5. Notice that the field is True ### Description of…
### Steps to Reproduce: 1. Go to Helpdesk and create an SLA 2. Create a new Ticket 3. Use Studio to add the field `sla_reached` 4. Apply the SLA 5. Notice that the field is True ### Description of the issue/feature this PR addresses: **Issue:** The `_compute_sla_reached` method in on `helpdesk_ticket.py` determines whether an SLA has been reached by checking if `exceeded_hours` is less than 0 on its `helpdesk.sla.status` records. Since every newly assigned SLA has a future deadline, `exceeded_hours` starts as negative (AKA <0), so the ticket is immediately flagged as `sla_reached = True` before any progress has been made. Conversely, a ticket that reaches its target stage after the deadline has `exceeded_hours >= 0`, so it's incorrectly flagged as `sla_reached = False` even though the SLA target was genuinely reached (it was just late). **Solution:** Change the domain in `_compute_sla_reached` to check `reached_datetime != False` instead of `exceeded_hours < 0`, matching the field already listed in the method's `@api.depends` and the same field `_sla_reach()` sets when a ticket enters its target stage. This makes `sla_reached` reflect actual stage progression rather than a time-remaining calculation. ### Current behavior before PR: A newly created ticket with a pending SLA shows `sla_reached = True` and `sla_success = True` immediately upon creation, before the ticket has moved to any target stage. SImilarly, a ticket that reaches its target stage after the SLA deadline is incorrectly marked `sla_reached = False`. ### Desired behavior after PR: `sla_reached` is False on ticket creation and only becomes True once the ticket actually enters the SLA's target stage. Lateness continues to be tracked separately and correctly via `sla_reached_late` opw-6361851 Forward-Port-Of: odoo/enterprise#126432
Fixes issues in the Timesheet Assistant that could cause errors when deleting entries or when existing timesheets were not created through the assistant. It also prevents internal event data from being unintentionally changed, making the assistant more stable for users.
Original PR description
## [FIX] timesheet_grid: avoid altering consumedEvents Before this commit, the objects inside consumedEvents attribute are altered because we keep the reference of those objects. This commit avoid altering the consumed events. ## [FIX] timesheet_grid: use recordsByStart instead of records
Timesheet activity suggestions now handle away-from-keyboard periods more accurately, so breaks are less likely to be missed or overwritten by other activity. This helps users and managers get a more reliable view of worked time and inactive periods.
Original PR description
## Previous Behavior Before this Commit 1. When key and non‑key events were merged to build the final suggestion timeline, key events always took priority over AFK events, even when the key event was…
## Previous Behavior Before this Commit 1. When key and non‑key events were merged to build the final suggestion timeline, key events always took priority over AFK events, even when the key event was not “always active.” This caused AFK events to be incorrectly overridden. 2. During event normalization, certain events were lost entirely, resulting in important events not being counted. 3. When merging two event timelines, zero‑duration gaps were treated as valid, preventing proper merging of surrounding events. 4. ActivityWatch sometimes produced empty gaps instead of AFK events, causing breaks to go unrecorded. ## New Expected Behavior After this Commit 1. Events now follow the updated priority system: a. Always‑active key events b. Always‑active non‑key events c. Non‑key AFK events d. Other key events e. Other non‑key events 2. Events are now shortened or split so that the latest event always has priority, while minimizing unnecessary event removal. 3. Zero‑duration gaps are skipped when merging event lists. 4. Any gap larger than 3 minutes, between the first and last event and containing no events is automatically filled with an AFK event. ## Additional Notes Because point 4 introduces additional AFK events, several tests were updated to reflect the new behavior. task-[6455412](https://www.odoo.com/odoo/project/4105/tasks/6455412)
1 change
Resolved issues and error corrections
Swiss Payroll now refreshes employee payroll snapshots only when payroll-related information changes. This reduces unnecessary system notes and improves performance for companies using Swiss Payroll without changing payroll results.
Original PR description
### Description Employee monthly payroll snapshots are recomputed on every write to `hr.employee`, regardless of whether the modified fields impact payroll. This generates unnecessary chatter entries and introduces avoidable compute overhead, as `_create_or_update_snapshot` performs several expensive computations and updates many snapshot fields. ### Solution Only call `_create_or_update_snapshot` when a payroll-related field is modified. This avoids unnecessary snapshot recomputations, keeps the chatter clean, and improves the performance of databases using Swiss Payroll. opw-6285407
2 changes
Enhancements to existing features
Timesheet users can now select multiple assistant suggestions by holding the mouse button and moving over them, making batch actions like deleting suggestions or creating timesheets quicker. The update also prevents an unwanted new Odoo page from opening when using Ctrl-click on a suggestion.
Original PR description
Currently when the user uses ctrl + click on a suggestion, a new odoo page is opened. This is an undesirable side effect and it is removed in this commit. Also, users have to manually click on each suggestion when they want to remove them in batch, or create one timesheet for a bunch of suggestion. This commit lets user hover over suggestion with the mouse button pressed to select them. task-6385047 Forward-Port-Of: odoo/enterprise#127311 Forward-Port-Of: odoo/enterprise#124642
Resolved issues and error corrections
This fix prevents new Helpdesk tickets from being incorrectly shown as having already met their SLA. SLA completion is now marked only when the ticket reaches the required stage, while late completion remains tracked separately.
Original PR description
### Steps to Reproduce: 1. Go to Helpdesk and create an SLA 2. Create a new Ticket 3. Use Studio to add the field `sla_reached` 4. Apply the SLA 5. Notice that the field is True ### Description of…
### Steps to Reproduce: 1. Go to Helpdesk and create an SLA 2. Create a new Ticket 3. Use Studio to add the field `sla_reached` 4. Apply the SLA 5. Notice that the field is True ### Description of the issue/feature this PR addresses: **Issue:** The `_compute_sla_reached` method in on `helpdesk_ticket.py` determines whether an SLA has been reached by checking if `exceeded_hours` is less than 0 on its `helpdesk.sla.status` records. Since every newly assigned SLA has a future deadline, `exceeded_hours` starts as negative (AKA <0), so the ticket is immediately flagged as `sla_reached = True` before any progress has been made. Conversely, a ticket that reaches its target stage after the deadline has `exceeded_hours >= 0`, so it's incorrectly flagged as `sla_reached = False` even though the SLA target was genuinely reached (it was just late). **Solution:** Change the domain in `_compute_sla_reached` to check `reached_datetime != False` instead of `exceeded_hours < 0`, matching the field already listed in the method's `@api.depends` and the same field `_sla_reach()` sets when a ticket enters its target stage. This makes `sla_reached` reflect actual stage progression rather than a time-remaining calculation. ### Current behavior before PR: A newly created ticket with a pending SLA shows `sla_reached = True` and `sla_success = True` immediately upon creation, before the ticket has moved to any target stage. SImilarly, a ticket that reaches its target stage after the SLA deadline is incorrectly marked `sla_reached = False`. ### Desired behavior after PR: `sla_reached` is False on ticket creation and only becomes True once the ticket actually enters the SLA's target stage. Lateness continues to be tracked separately and correctly via `sla_reached_late` opw-6361851 Forward-Port-Of: odoo/enterprise#127309 Forward-Port-Of: odoo/enterprise#126432
1 change
Resolved issues and error corrections
Fixes an issue where running task or ticket timers could jump between values, show negative time, or calculate the wrong elapsed time after repeated stop/start and page reloads. This keeps the visible timer reliable for employees tracking work time and reduces the risk of incorrect timesheet entries.
Original PR description
A running task/ticket timer can sometimes stutter, show negative values, and track the wrong elapsed time. ### Steps to reproduce On a record with a timesheet timer (for example, a Field Service…
A running task/ticket timer can sometimes stutter, show negative values, and track the wrong elapsed time. ### Steps to reproduce On a record with a timesheet timer (for example, a Field Service task): 1. Start the timer and let it run for about 15-20 seconds. 2. Stop it and confirm the dialog. 3. Start it again. This creates a new `timer_start`. 4. Reload the page. The timer starts jumping every second between two different values. As it keeps running, it can even show negative values such as `00:00:-57`. If the problem does not appear right away, repeat steps 2-4 a few times. It usually shows up after a few stop/start/reload cycles. ### Cause The timer shown in the button bar is the `timer_start_field` widget. It starts a `setInterval` that updates a shared `TimerReactive` object once per second. While a form is loading, Odoo renders it several times in a row (for example: a first render, another when the chatter is loaded, and another when the record data comes back from the server). Rendering a form builds all of its fields to produce the display, so each of these renders creates its own `timer_start_field`. Odoo keeps and mounts only the render that ends up on screen; the earlier ones are thrown away before being mounted. The interval is started while the field renders, from the record observer set up in `setup`, before the field is mounted. So the fields that are later thrown away also start an interval. Those intervals keep running for the rest of the session. Each one updates the same shared `TimerReactive` object using the `timer_start` it was created with. As long as every instance has the same `timer_start`, they all write the same value and the problem stays hidden. After the timer is stopped and started again, the old instances keep the old `timer_start` while the mounted one uses the new one. Every second they overwrite each other's value, so the timer jumps between two different elapsed times. When the instance with the newer `timer_start` writes right after one with an older start, it tries to show a smaller elapsed time than what is already there, and the subtraction in `TimerReactive` produces a negative number of seconds. ### Fix Move the per-second timer update into a `useEffect`. The effect only runs after the field is mounted, and Owl automatically cleans it up when the field is unmounted or when `timer_start` or `timer_pause` change. This means fields that are destroyed before they are mounted never start an interval, so only the mounted field updates the shared timer. `onRecordChange` no longer starts or stops the interval. It only updates the displayed timer value to match the current record. opw-6209405