Monday, September 21, 2026
22 changes · 18.0
Resolved issues and error corrections
When adding an attribute to a product, Odoo will no longer automatically add every possible value for that attribute. It will only prefill a value when there is exactly one option, preventing unwanted bulk selections and reducing manual cleanup for users.
Original PR description
Description of the issue/feature this PR addresses: - Create a attribute A with 100 values (for exemple list of certification) - Create a new product, add this attribute --> Issue all 100 values (100) is auto added. This commit limit the auto complete, the autocomplete works if there are only one value. 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
This fix prevents Peruvian PLE sales and purchase ledgers from counting selective consumption tax twice when it affects later taxes. It keeps ledger taxable base amounts aligned with electronic invoices sent to SUNAT, improving tax reporting accuracy for affected transactions.
Original PR description
When a tax affects the base of the subsequent ones — `include_base_amount`, which is how the ISC is set up in Peru — Odoo links the tax line it generates to those subsequent taxes, so the ISC tax…
When a tax affects the base of the subsequent ones — `include_base_amount`, which is how the ISC is set up in Peru — Odoo links the tax line it generates to those subsequent taxes, so the ISC tax line ends up carrying the IGV in its `tax_ids`. The PLE ledgers build their base columns by summing every move line related to a given tax group, so that ISC tax line was added to `base_igv` as well and the ISC ended up reported twice: once inside the taxable base and once in its own column. A line of 1000.00 with 100.00 of ISC and 198.00 of IGV was declared with a base of 1100.00 instead of 1000.00. `l10n_pe_edi` already subtracts the ISC from the `cbc:TaxableAmount` of the CPE sent to SUNAT, so the electronic invoice and the ledger disagreed on the very same document. ### What changed The base taxes are now joined only for base lines, instead of repeating the condition on each of the twelve `base_*` columns. Besides keeping tax lines out of the base columns, this also stops a tax line from being counted once per subsequent tax: an ISC followed by both the IGV and the ICBPER produced two rows in the join, and its own column was reported twice. ### Scope `_get_ple_report_data` is shared, so this covers the sales ledger 14.1 and the purchase ledgers 8.1 and 8.2. A configuration where no tax affects the base of a later one is unaffected: the standard Peruvian chart template has no purchase ISC, so ordinary IGV-only purchases report exactly the same values as before. ### Tests - `test_sale_report_isc_base`: an ISC preceding the IGV, on an invoice and on a credit note; the base column excludes the ISC. - `test_sale_report_isc_reported_once`: an ISC followed by the IGV and the ICBPER is reported once. Both fail without the fix. Supersedes odoo/enterprise#128300, which targeted 19.0. Forward-Port-Of: odoo/enterprise#131475
This fixes credit notes using Spain's TicketBAI/Batuz reporting when an equivalence surcharge tax is applied. The surcharge percentage is now sent as a positive value, preventing tax agency rejections and allowing affected refunds to be submitted successfully.
Original PR description
In credit notes, `TipoRecargoEquivalencia` was multiplied by the reversal sign, producing negative values (e.g. -1.40) that violate the Batuz `Tipo3.2Type` pattern and get rejected by the tax agency (`B4_2000001: cvc-pattern-valid`). Unlike `BaseImponible`/`CuotaImpuesto` (amounts that must be negative), `TipoRecargoEquivalencia` is a percentage and must stay positive, as `TipoImpositivo` does. Steps to reproduce: 1. Configure a Spanish company with TicketBAI (Bizkaia). 2. Create a credit note (out_refund) with an equivalence surcharge tax. 3. Send it to TicketBAI; the send fails with a schema validation error. Task: MT-15939 OPW: https://www.odoo.com/es_ES/my/tasks/6573801 @jco-odoo could you review? It's essential to be able to send to Tbai/Batuz with equivalence surcharge tax.
This fix prevents invoice confirmation from crashing when an Ecuadorian company has a VAT value that is not a valid RUC number. It improves reliability for Ecuador electronic invoicing by safely handling incorrect company identification data instead of showing an error.
Original PR description
When the VAT of an Ecuadorian company's partner contains characters other than decimal digits, confirming an invoice raises a traceback. Steps to reproduce the error: - Install ``l10n_ec_edi`` module…
When the VAT of an Ecuadorian company's partner contains characters other than decimal digits, confirming an invoice raises a traceback. Steps to reproduce the error: - Install ``l10n_ec_edi`` module and switch to EC Company - Open the partner of EC Company > Set a VAT containing non-digit characters - Create a new invoice > fill the required fields > Confirm Traceback: ```py ValueError: invalid literal for int() with base 10: 'E' ``` During invoice confirmation, ``_l10n_ec_set_authorization_number()`` method is called to generate the authorization number at [1], It builds the ``key_value`` using the vat of company's partner at [2]. The generated ``key_value`` is then passed to ``_l10n_ec_get_check_digit`` method, which converts each character of ``key_value`` to an integer using ``int()`` at below line. https://github.com/odoo/enterprise/blob/799e9e94efcc338a8f3a6b7ab85cf77f9898f005/l10n_ec_edi/models/account_move.py#L830 When the VAT contains a character that cannot be converted to an integer, It will raises the above traceback. To build the ``key_value``, the company's partner vat should be RUC consisting of 13 digits. Ref: https://www.sri.gob.ec/o/sri-portlet-biblioteca-alfresco-internet/descargar/fb95cafc-a8ca-4a4c-afb6-12c4153165f0/FICHA%2520TECNICA%2520COMPROBANTES%2520ELECTR%25C3%2593NICOS%2520ESQUEMA%2520OFFLINE.pdf Solution: If the identification type of the company's partner is not RUC, return an empty string. [1]: https://github.com/odoo/enterprise/blob/799e9e94efcc338a8f3a6b7ab85cf77f9898f005/l10n_ec_edi/models/account_move.py#L806 [2]: https://github.com/odoo/enterprise/blob/799e9e94efcc338a8f3a6b7ab85cf77f9898f005/l10n_ec_edi/models/account_move.py#L825-L826 sentry-7642961403 Related Community PR: https://github.com/odoo/odoo/pull/280047
Ecuadorian company VAT numbers are now checked earlier to ensure they contain only digits. This prevents invoice confirmation from failing with an unexpected system error and gives users a clear validation message instead.
Original PR description
When the VAT of an Ecuadorian company's partner contains characters other than decimal digits, confirming an invoice raises a traceback. Steps to reproduce the error: - Install ``l10n_ec_edi`` module…
When the VAT of an Ecuadorian company's partner contains characters other than decimal digits, confirming an invoice raises a traceback. Steps to reproduce the error: - Install ``l10n_ec_edi`` module and switch to EC Company - Open the partner of EC Company > Set a VAT containing non-digit characters - Create a new invoice > fill the required fields > Confirm Traceback: ```py ValueError: invalid literal for int() with base 10: 'E' ``` During invoice confirmation, ``_l10n_ec_set_authorization_number()`` method is called to generate the authorization number at [1], It builds the ``key_value`` using the vat of company's partner at [2]. The generated ``key_value`` is then passed to ``_l10n_ec_get_check_digit`` method, which converts each character of ``key_value`` to an integer using ``int()`` at below line. https://github.com/odoo/enterprise/blob/799e9e94efcc338a8f3a6b7ab85cf77f9898f005/l10n_ec_edi/models/account_move.py#L830 When the VAT contains a character that cannot be converted to an integer, It will raises the above traceback. [1]: https://github.com/odoo/enterprise/blob/799e9e94efcc338a8f3a6b7ab85cf77f9898f005/l10n_ec_edi/models/account_move.py#L806 [2]: https://github.com/odoo/enterprise/blob/799e9e94efcc338a8f3a6b7ab85cf77f9898f005/l10n_ec_edi/models/account_move.py#L825-L826 Solution: Raise the ValidationError when the vat contains non-digit character. sentry-7642961403 Related Enterprise PR: https://github.com/odoo/enterprise/pull/126519 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fixes an internal HR leave test that could fail in certain future years because it depended on the current date. The change makes the test use a fixed date, improving reliability of quality checks without changing user-facing leave behavior.
Original PR description
test_no_carried_over_leaves_for_flexible_resource derives its target date from date.today(), so the window it inspects, [12/30 of next year, the 12/31 carryover date], starts on a different weekday every year. Since odoo/odoo@1e4f78a7e318a2a5195f9d94d22c094f2aabfb09, the flexible hours algorithm anchors the weekly budget on the Monday of the week containing the start of the requested range and charges hours_per_day for every day of that week preceding it. On the 40h/week, 8h/day flexible calendar of the test the 40 hours are therefore already consumed when the range starts on a Saturday: no work interval is generated and closest_allocation_duration is 0 where the test expects 2. A Sunday start gives 1. 12/30 falls on a weekend for the tests run in 2027 and 2028. Freeze the test at 2024-01-01, like the other tests of this file, so the window always falls mid-week. runbot-944214
Fixes an issue where closing a website visitor live chat request could show an error instead of closing normally. This improves reliability for website operators handling live chat conversations.
Original PR description
Problem: Closing the chat window of a chat request sent to a website visitor crashes with `TypeError: Cannot read properties of undefined (reading '_proxy')`. Cause: When a record is deleted,…
Problem:
Closing the chat window of a chat request sent to a website visitor crashes
with `TypeError: Cannot read properties of undefined (reading '_proxy')`.
Cause:
When a record is deleted, `MAKE_UPDATE` clears it from the relations holding
it. Holders still alive come from `recordByLocalId` as proxies, holders already
deleted in the same update come from `deletingRecordsByLocalId` as raw records.
On a raw record, `usingRecord[one] = undefined` overwrites the `RecordList`
instead of emptying it, and the next read of that field crashes.
Regression from [7432827d09e6](https://github.com/odoo/odoo/commit/7432827d09e667bb1e2670c7bb719fe24edec59d).
Solution:
Backport of [7b457e243bdf](https://github.com/odoo/odoo/commit/7b457e243bdfcdd4c4b61b4771643c1985bde9cf)
from 19.0: always work on the raw record and remove the deleted record from
its `RecordList`, for `one` and `many` fields alike.
Steps to reproduce:
Set a Livechat channel on the website and add yourself as an operator.
Website > Reporting > Visitors > click `Chat` on a visitor.
Close the chat window. => Error dialog with the `TypeError` above.
opw-6564629This fix ensures Factur-X invoice files include the required customer name even when an invoicing address has no name set. It falls back to the related commercial partner name, reducing validation failures and helping businesses send compliant electronic invoices.
Original PR description
Description of the issue/feature this PR addresses: The Factur-X Refactoring (https://github.com/odoo/odoo/pull/284123) introduced an error that can result in the generated XMLs not being compliant due to the partner name being missing (BT-44) Current behavior before PR: When a contact has an invoicing address without a name set, then the new Factur-X generation does not fall back to the parent name, leaving the corresponding XML entry empty, which is therefore pruned, leaving the Factur-X without a BT-44 and thus failing BR-07 Desired behavior after PR is merged: The new generation method uses the same data source and fallback method as the old Factur-X generator, pulling the `display_name` of the `commercial_partner_id` if the address doesn't have a `name`. This greatly reduces the chance of a generated Factur-X failing BR-07. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Vietnam Profit and Loss reporting is updated to match Circular 99/2025/TT-BTC, including the new investment property gain/loss line and revised numbering for the official printed form. Revenue, cost, and other income calculations are adjusted to avoid double counting and better align with the chart of accounts, while period comparisons remain available without an unsupported growth percentage column.
Original PR description
Circular 99/2025/TT-BTC (effective FY2026) replaces Circular 200/2014/TT-BTC. The Profit & Loss statement (Mẫu B02-DN) gains a new mandatory line, "Lãi/lỗ của hoạt động bán, thanh lý bất động sản đầu…
Circular 99/2025/TT-BTC (effective FY2026) replaces Circular 200/2014/TT-BTC. The Profit & Loss statement (Mẫu B02-DN) gains a new mandatory line, "Lãi/lỗ của hoạt động bán, thanh lý bất động sản đầu tư" (mã số 21), computed from the new 5117/6327 sub-accounts (see the paired l10n_vn commit). Financial income, financial expenses and the interest memo line shift to mã số 22/23/24 accordingly, the "Net profit from operating activities" formula is updated to include the new line, and all following line numbers/labels are renumbered to match the printed form. The interest memo line itself is renamed from "Chi phí lãi vay" to "Chi phí đi vay" (Borrowing costs), per the gazette text. Also, per revised guidance: - Revenue and cost of goods sold now exclude the new investment property sub-accounts (5117/6327), so those amounts aren't double-counted between the main lines and the new gain/loss line. - Other income is now computed from the "income_other" account type instead of a hardcoded account code, matching how the chart of accounts already classifies it. Both the Balance Sheet and Profit and Loss VN reports also declare an extra "Code" string column (for the printed-form mã số) alongside "Balance". Core's growth-comparison heuristic only turns on the auto growth-% column when there are exactly 2 total columns; with Code+Balance that becomes 4 once a comparison period is added, so the % never renders even though the underlying side-by-side comparison values are fine. account.report exposes filter_growth_comparison as a toggle independent from filter_period_comparison for exactly this case (see Trial Balance and the Deferred reports), so both reports set it to False: period comparison stays available, only the auto growth-% column is suppressed. Task-6518304
Default invoice terms and conditions pages can now keep interactive accordion blocks created in the website editor. This prevents the content from breaking after saving and avoids errors when users add new accordion items.
Original PR description
# How to reproduce - Go to Settings > Default Terms & Conditions > Preview - Open the editor - Add a Content Block - Add an Accordion in that Block - Save # The issue The accordion gets messed up and…
# How to reproduce - Go to Settings > Default Terms & Conditions > Preview - Open the editor - Add a Content Block - Add an Accordion in that Block - Save # The issue The accordion gets messed up and trying to add a new item to that accordion raises a traceback # Cause `invoice_terms_html` is an html field with some sanitization enabled : https://github.com/odoo/odoo/blob/c11ca6d10cac99b367078823dafef46808346267/addons/account/models/company.py#L172 This sanitization will remove the accordion snippet's buttons that controls the functionality of the snippet : https://github.com/odoo/odoo/blob/c11ca6d10cac99b367078823dafef46808346267/addons/website/views/snippets/s_accordion.xml#L9 This issue was already addressed by : https://github.com/odoo/odoo/commit/b6b4db5fb5690436a4284f6a22abf9f3b346a324 But it is not enough in the case of the accordion. The buttons will be removed by the lxml clean.Cleaner : https://github.com/odoo/odoo/blob/c11ca6d10cac99b367078823dafef46808346267/odoo/tools/mail.py#L364 # Proposed Solution Disable sanitization entirely, like for blog's content, which can also be edited in the website editor : https://github.com/odoo/odoo/blob/c11ca6d10cac99b367078823dafef46808346267/addons/website_blog/models/website_blog.py#L29 opw-6500378
Fixed an error that prevented French companies using electronic invoicing from sending multiple invoices at once. Users can now select several invoices and open the batch sending wizard without the process crashing.
Original PR description
Sending several invoices at once from the list view of a French company crashes instead of opening the batch sending wizard. Steps to reproduce: - Activate French Electronic Invoicing - Create a French customer with a valid PDP endpoint - Post two invoices for that customer, select them in the invoice list and click 'Send' Issue: The batch sending wizard raises ``` AttributeError: 'account.move.send.batch.wizard' object has no attribute 'company_id' ``` opw-6558940
Peppol activation now checks that the required contact email is in a valid format before proceeding. This prevents users from entering unusable email addresses and helps avoid registration or communication issues.
Original PR description
Currently, while activating peppol, we have email as a required field, but we don't validate the email format so user can enter any string for email which is invalid. This commit adds a validation for the email format by using regex for email defined in `odoo.tools`. task-6158448 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The Peppol activation flow now uses corrected English text. This improves the professionalism and clarity of the setup experience for English-speaking users.
Original PR description
There were some minor English mistakes on the Peppol activation wizard that might make Odoo look cheap and untrustworthy to English-speaking audiences. This commit fixes these english mistakes. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix prevents French e-invoicing test checks from failing when an optional French PDP component is not installed. It keeps automated validation aligned with the installed configuration, reducing false failures in development and release pipelines.
Original PR description
### Issue: Tests in `TestCIIFR` fail when run without `l10n_fr_pdp` installed The expected XML files contain `PMT`, `PMD` and `AAB` notes that are only generated when `l10n_fr_pdp` is installed ### Cause: The note generation for FR e-invoicing lives in `l10n_fr_pdp` When it is not installed, the notes are absent from the generated XML but still present in the expected test files When `l10n_fr_pdp` is not installed, the expected tree is stripped of `PMT`, `PMD` and `AAB` notes before comparison ### Steps to reproduce: - Install `l10n_fr_account` without `l10n_fr_pdp` - Run `TestCIIFR` from `l10n_account_edi_ubl_cii_tests/tests/test_xml_cii_fr.py` Before the fix, the affected tests fail on the `cbc:Note` comparison runbot-945999
Sorting contacts by name now gives the expected order when users work in a language other than English. The contact list now prioritizes reliable sorting, with a temporary trade-off that names may not display in the selected language in this view.
Original PR description
Problem: When sorting by name in the contact list view when a different language is selected, the records were not sorted correctly. Steps to reproduce: 1. Select another language than English in the…
Problem: When sorting by name in the contact list view when a different language is selected, the records were not sorted correctly. Steps to reproduce: 1. Select another language than English in the user preferences. 2. Go to Contacts app. 3. Click on the "Name" column to sort by name. 4. Observe that the records are not sorted correctly. Cause: The field used for name was "display_name" which is a computed field that is not stored in the database. The field was used so that the name is displayed in the correct language, but it cannot be used for sorting. When used for sorting, the database will use the value of the field in the default language, and will show the records in the selected language, which will result in incorrect sorting. Solution: Use the field "complete_name" instead of "display_name" for showing the name in the list view. This will enable sorting by name correctly, but will not show the name in the correct language. As discussed in the task, this is an acceptable compromise for now. Reverts odoo/odoo#257539 opw-6475119
Point-of-sale refunds now deduct loyalty points that were originally earned on the refunded purchase, closing a loophole that let customers keep rewards after getting their money back. The update also keeps refund displays clear for cashiers and customers, while preserving proper eWallet and gift card refund handling.
Original PR description
Description of the issue/feature this PR addresses: When a customer earned loyalty points on a POS order and then refunded that order, the points were never deducted. This allowed a trivial exploit:…
Description of the issue/feature this PR addresses: When a customer earned loyalty points on a POS order and then refunded that order, the points were never deducted. This allowed a trivial exploit: buy a product to earn points, refund it to get the money back, and keep the points. Repeating this cycle let customers accumulate unlimited loyalty points at no cost to themselves. Current behavior before PR: The root cause was that the refund flow in POS only copied product lines with negative quantities into the new refund order. It never touched couponPointChanges, so _postProcessLoyalty had nothing to process and confirm_coupon_programs was never called for the refund. A secondary issue was that _updatePrograms() runs reactively on every order change and calls pointsForPrograms(), which skips lines where totalProductQty < rule.minimum_qty. For refund lines with negative quantities this condition is always true, so the result was always 0 points — silently overwriting any couponPointChanges we tried to set. Desired behavior after PR is merged: The fix works at two levels: - Server-side (pos_order.py): override action_pos_order_paid() to call _reverse_loyalty_points_for_refund() when the paid order is a refund (negative total linked to an original order via refunded_order_id). This reads the original order's loyalty.history, computes a ratio for partial refunds, and directly deducts points from the loyalty card. Points are allowed to go negative intentionally — this prevents the fraud pattern where a customer earns points, spends them on a reward, then refunds the original purchase to reclaim the money while keeping the reward. Expired or inactive cards are skipped since they carry no meaningful balance. An idempotency guard prevents double-processing on retries. - Client-side (pos_store.js): override _updatePrograms() to detect refund orders and route them to _updateProgramsForRefund() instead of the normal pointsForPrograms() path. This reads couponPointChanges from the original order, negates them proportionally, and sets them on the refund order so the loyalty points widget at the bottom of the product screen correctly shows the deduction in real time. After sync, postSyncAllOrders skips confirm_coupon_programs for refund orders (since the server already handled it) and instead re-reads the updated card balance from the server. The order summary widget (order_summary.xml) and receipt template (order_receipt.xml) are updated to display a deducted line alongside the existing won and spent lines, so cashiers and customers can see the point reversal clearly. Fixes #257767 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fixes an error that could interrupt the website configurator when a user chooses to add an online store. The setup now handles the website address correctly, allowing the configuration and related demo data loading to complete without a traceback.
Original PR description
Since [1], the registry is loaded without a request context, so a module installation now goes through the fallback of `get_current_website` that reads the url stored on the current thread. That…
Since [1], the registry is loaded without a request context, so a module installation now goes through the fallback of `get_current_website` that reads the url stored on the current thread. That value is a full url, not the `domain:port` the method expects, so IDNA-encoding it splits it on the dots of the path rather than on those of a host name and raises `UnicodeError` as soon as one of the resulting parts reaches 64 characters. The thread url is now reduced to its `domain:port` part. Steps to reproduce: - Start the server locally on a database with demo data, served on `http://localhost:8069`, with only `Website` installed - Create a new website - In the configurator, choose `I want an online store` - Go through each step - After the last step, a traceback appears while loading the accounting demo data: the configurator should apply without error [1]: https://github.com/odoo/odoo/commit/1ae80f9fb18c9c9e67fe0367b94f0d882c711570 Also reported here: https://github.com/odoo/odoo/issues/286432
The Guatemala electronic invoicing setup now applies fiscal positions in a consistent order. This prevents occasional incorrect tax selection on invoices and makes related invoice processing and tests more reliable.
Original PR description
Test TestGtFlow.test_gt_edi_basic_invoice nondeterministically fails, but the reported error has always the same values. Turns out the code is picking the wrong fiscal position to apply taxes on the prices of the invoice. `res.partner._get_fiscal_position()` searches auto_apply fiscal positions without explicit order, so it relies on the model's default order-by sequence. `account.fiscal.position-gt.csv` carries two records into the database without sequence number, so the order they are returned in is nondeterministic. The resultset is afterwards stable sorted (no tie-breaker between equal sequence numbers) and filtered, so the wrong/unexpected tax can be applied randomly. Explicit sequence numbers are added to account.fiscal.position-gt.csv so the fiscal positions are always returned in-order (domestic first). This approach matches the convention of the other fiscal-position CSVs. runbot-945738
The Attendances dashboard now shows unavailable days based on the working schedule that applied during each employee contract period. This prevents misleading greyed-out days when an employee's schedule changed over time, helping managers review attendance history more accurately.
Original PR description
Issue: ---------------------------------------- On the Attendances dashboard view, days marked unavailable (greyed out) for an employee don't match the working schedule that was actually in effect…
Issue: ---------------------------------------- On the Attendances dashboard view, days marked unavailable (greyed out) for an employee don't match the working schedule that was actually in effect during each displayed period. Steps to reproduce: ---------------------------------------- - Create two working schedules with different days off (e.g. "Monday off" and "Friday off") - Give an employee a contract on the first schedule, close it, then start a new contract on the second schedule. - Open the Attendances dashboard for a period spanning both contracts - The greyed off day is always the one from the current schedule Cause: ---------------------------------------- `_gantt_unavailability()` computes unavailable intervals via `_get_unavailable_intervals()`, which only looks at the resource's current calendar for the whole requested range, ignoring the different calendars that applied during earlier contract periods. Solution: ---------------------------------------- `calendar_periods_by_employee` already contains the periods with their corresponding calendar. We use it to call `_unavailable_intervals_batch()` on each calendar with their interval and combine the results. opw-6460004
Fiscal positions with the same priority will now be evaluated in a stable order. This prevents inconsistent tax or accounting rule selection after data imports where sequence values are duplicated.
Original PR description
The algorithm to find the right fiscal position works on top of deterministically ordered fiscal position records. This invariant is not enforced by the functional code. Importing data without explicit sequence number results in multiple records ending up with the same value in this column. Sorting by column 'sequence' is not good enough to have repetitive results in this case. The fiscal position algorithm can return a different record due to database implementation details. Adding field "id" to the default ordering ensures the order of fiscal position records remains deterministic. This is because insertion order is preserved and locked into order-preserving id-values when importing data. runbot-945738
Validated time off requests now create all-day calendar events with a duration that matches the actual date range. This prevents events from being shortened incorrectly when their start time changes, such as during Google Calendar synchronization.
Original PR description
**Problem:** When modifying the start time of an all-day Calendar Event created from the Validation of a Time Off Request, the end time will be shortened dramatically, no longer spanning the correct…
**Problem:** When modifying the start time of an all-day Calendar Event created from the Validation of a Time Off Request, the end time will be shortened dramatically, no longer spanning the correct timespan. In the case of the ticket referred to below, this occurs during Google Calendar sync. **Cause:** When a Calendar Event is created from a Time Off Request being Validated, its duration is set according to the amount of days the Time Off Request spans multiplied by the employee's daily work hours as defined on their contract, even if the Calendar Event will be an all-day event. When the start time of a Calendar Event is modified, the end time is recomputed according to the duration added to the new start time. As such, if the duration of the Event does not match the duration of the dates covered, it will be shortened dramatically. **Purpose:** Modify the values defined when creating a Calendar Event as a result of a Validated Time Off Request so that, if the created Event will be an all day Event, the duration is computed according to `calendar.event._get_duration`. **Steps to Reproduce in Runbot:** 1. Create and Validate a Time Off Request of the Paid Time Off leave type spanning multiple days. 2. Modify the start time of the Calendar Event that is created as a result of the validation. (This step will likely require a nonstandard flow as the start time field is normally hidden for all-day Calendar Events) opw-6426586 Forward-Port-Of: odoo/odoo#284552
This fix improves logging when the French PDP integration receives an unsupported lifecycle status. Instead of showing an empty value, the system now records the actual status code, making investigations and support easier.
Original PR description
Currently we just log `None` in case we receive a lifecycle with an unsupported (on community side) status. After this commit we log the status code at least. task-None before fix <img width="711" height="120" alt="image" src="https://github.com/user-attachments/assets/1f939cf4-17b7-49cb-8b31-5cc594fdeadd" /> after fix <img width="700" height="116" alt="image" src="https://github.com/user-attachments/assets/1b8b3853-f2da-4426-9c49-1d135d1c7824" /> Forward-Port-Of: odoo/odoo#286429