Friday, August 7, 2026
32 changes · saas-19.2
Enhancements to existing features
This commit adds 3 new `Tax Exemption Reason Code`: - VATEX-FR-F - VATEX-FR-I - VATEX-FR-J task-6333649 Forward-Port-Of: odoo/odoo#280537 Forward-Port-Of: odoo/odoo#278086
Original PR description
This commit adds 3 new `Tax Exemption Reason Code`: - VATEX-FR-F - VATEX-FR-I - VATEX-FR-J task-6333649 Forward-Port-Of: odoo/odoo#280537 Forward-Port-Of: odoo/odoo#278086
Doing an euclidean division on floats with the native operators is unreliable: because of IEEE-754 representation errors, `value1 % value2` can return a spurious remainder (e.g. `50.4 % 16.8 == 16.799999999999997` instead of 0.0) and `int(value1 / value2)` can truncate the quotient one step too low (e.g. `int(0.3 / 0.1) == 2` instead of 3). `float_div` returns the `(quotient, remainder)` pair free of those errors. The key is to never run a lossy `%` or `//` on the raw floats. Instead both ope
Original PR description
Doing an euclidean division on floats with the native operators is unreliable: because of IEEE-754 representation errors, `value1 % value2` can return a spurious remainder (e.g. `50.4 % 16.8 ==…
Doing an euclidean division on floats with the native operators is unreliable: because of IEEE-754 representation errors, `value1 % value2` can return a spurious remainder (e.g. `50.4 % 16.8 == 16.799999999999997` instead of 0.0) and `int(value1 / value2)` can truncate the quotient one step too low (e.g. `int(0.3 / 0.1) == 2` instead of 3). `float_div` returns the `(quotient, remainder)` pair free of those errors. The key is to never run a lossy `%` or `//` on the raw floats. Instead both operands are first snapped onto the precision grid with `float_round` and then scaled to integers: since a grid-snapped value is a multiple of `rounding`, dividing it by `rounding` counts how many grid steps it spans. That division is still noisy (`4.35 / 0.05 == 86.99999999999999`), so the result is passed through `builtins.round` to coerce it to the exact integer step count. The euclidean division itself is then a plain integer `divmod`, which is exact, and the remainder is scaled back to real units. This is why the correction is applied to the inputs and not to the output: rounding the result of a native `%` would only round an already-corrupt value, and would still misreport the quotient in the corner cases the util exists to handle. Dividing by `rounding` is meaningful for any precision, not only powers of ten: the grid step can be `0.05`, `0.25`, `0.5`, `0.03`, ... and `value / step` counts the steps in every case. This mirrors the normalize/denormalize scheme `float_round` already uses internally. The util shares `float_round`'s inherent limitation: the scaled step count must stay representable as an exact `float` integer, so exactness is lost past ~2**53 grid steps (extreme magnitudes at a fine precision). This is the IEEE-754 double-precision ceiling and is well outside any realistic quantity or price range. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#280883 Forward-Port-Of: odoo/odoo#277160
Resolved issues and error corrections
A help tip in the timesheet leaderboard was not showing because of an internal setup error. This fix makes the tip visible again, helping users better understand the leaderboard information.
Original PR description
The tip inside the timesheet leaderboard was never visible due to incorrect function arguments assignment. This commit fixes the issue. task-6448478
Documentation and clarification updates
Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#280427 Forward-Port-Of: odoo/odoo#278458
Original PR description
Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#280427 Forward-Port-Of: odoo/odoo#278458
This fix prevents a barcode batch picking test from moving to the next product before the first scanned quantity has finished updating. It helps ensure batch picking quantities are validated correctly and avoids intermittent failures caused by timing issues.
Original PR description
Problem: When scanning the first product, the second move line is clicked immediately after.…
Problem: When scanning the first product, the second move line is clicked immediately after. https://github.com/odoo/enterprise/blob/bfb8bab7636a84c829f16087771e00bf31ad2cce/stock_barcode_picking_batch/static/tests/tours/tour_test_barcode_batch_flows.js#L1529-L1541 If this happens before the first scan has finished, its quantity is incorrectly applied to the second move line that is clicked. This causes a 0 - 3 split instead of a 1 - 2 split, which results in there only being 6 move lines instead of 7. We updated our quantity on the `currentLine` https://github.com/odoo/enterprise/blob/bfb8bab7636a84c829f16087771e00bf31ad2cce/stock_barcode/static/src/models/barcode_model.js#L1478 When finding `currentLine`, we go through `_findLine` and use `this.selectedLineVirtualId`, which is the one that is currently selected in the UI https://github.com/odoo/enterprise/blob/bfb8bab7636a84c829f16087771e00bf31ad2cce/stock_barcode/static/src/models/barcode_model.js#L1705-L1712 Purpose: By adding this step, we wait until the first line’s quantity to be updated before it moves on and clicks on the second product. runbot-941211 Forward-Port-Of: odoo/enterprise#126847 Forward-Port-Of: odoo/enterprise#124162
Users can now disconnect a Belgian CodaBox connection using either the fidu password or a valid IAP token. This aligns the client with existing server support and reduces friction when revoking access.
Original PR description
The user should be able to revoke the CodaBox connection by either entering the fidu password or by using a valid iap_token. This was implemented in the iap server but not in the client side, after this commit the user should be able to either revoke by using the fidu password or by using the iap_token. task-6348433 Forward-Port-Of: odoo/enterprise#126698
Payroll list views now always show the warning column instead of hiding it behind an optional menu with a blank label. This removes a confusing interface issue and makes payslip or pay run warnings easier for users to notice.
Original PR description
Currently, in the payslip and payrun view, we can see empty label in optional dropdown. Having empty label isn't UX friendly. This empty label is refered to payslip warnings. In this PR expected to change visibility of warning fields, The visibility must be always visible and the field is no longer optional. This condition applies to PayRun and Paylist ListViews. task-6424657
This fixes payroll payslip calculations so worked day lines can correctly consider inactive or archived related records when needed. It helps prevent missing payroll information and supports more accurate payslip results in edge cases involving archived employee or contract data.
Google Reserve availability responses now prevent available spots from exceeding total spots, even when appointment capacity settings are inconsistent. This avoids sending confusing or invalid availability data for rare misconfigured appointment setups.
Original PR description
This commit makes sure that we never send more "spots_open" than there are "spots_total" when Google Reserve asks for availabilities. This could happen in very rare case when customers create configurations that do not make sense (for example a table of 6 but no management of capacities and configuring 125 spots per resource). Task-6449615 Forward-Port-Of: odoo/enterprise#126855
Bank reconciliation now safely handles imported statement lines whose payment reference contains only spaces. This prevents an error during account matching and makes reconciliation more reliable for data brought in outside the standard user interface.
Original PR description
When reconciling bank statements with an account, the system will look for past statement lines already reconciled with that account and create a reconciliation model based on common substring in…
When reconciling bank statements with an account, the system will look for past statement lines already reconciled with that account and create a reconciliation model based on common substring in payment_ref. If this payment refs contains only spaces (eg. ' '), it will trigger an index out of range traceback. This is explained by the fact that spaces are striped then '' is considered as False in some filtering leaving the list empty. From the UI, putting ' ' is not supposed to be possible because spaces are striped before write but there is many ways to import statement lines which may lead to this hence the decision of handling this scenario to make the code more robust. Steps to reproduce: 1/ Create two statement lines with payment_ref as ' ' (you can force it using a write) 2/ Click "Set account" on first one and pick 100000 Issued Capital 3/ Do the same for the second statement line => Traceback In this commit, we do not check for common substring if there is less than two labels. opw-6379977 Forward-Port-Of: odoo/enterprise#125779
Task-6429727 Forward-Port-Of: odoo/odoo#279204
Original PR description
Task-6429727 Forward-Port-Of: odoo/odoo#279204
When there is no default confirmation template, An error is raised: AttributeError: 'bool' object has no attribute 'exists'. This happens because default_template is False, So calling default_template.exists() results in the error. The issue occurs during the upgrade process. ``` File "/home/odoo/src/odoo/19.0/odoo/orm/models.py", line 3142, in _init_column value = field.default(self) File "/home/odoo/src/odoo/19.0/addons/website_sale/models/website.py", line 52, in _default_confi
Original PR description
When there is no default confirmation template,
An error is raised:
AttributeError: 'bool' object has no attribute 'exists'. This happens because default_template is False,
So calling default_template.exists() results in the error. The issue occurs during the upgrade process.
```
File "/home/odoo/src/odoo/19.0/odoo/orm/models.py", line 3142, in _init_column
value = field.default(self)
File "/home/odoo/src/odoo/19.0/addons/website_sale/models/website.py", line 52, in _default_confirmation_email_template
if default_template.exists():
AttributeError: 'bool' object has no attribute 'exists'
```
Description of the issue/feature this PR addresses:
Current behavior before PR:
Desired behavior after PR is merged:
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#240874
Forward-Port-Of: odoo/odoo#237686After removing sale_order_many2one widget https://github.com/odoo/odoo/commit/0ecaa6e4c359681daf90c1757bcf71ba5e4d305c , there's no need for multiple sale_order_id definitions in the form view. In this commit, cleaning the redundant field definitions and restrict visibility of Sale Order smart button. task-4661781 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#280740 Forward-Port-Of: odoo/odoo#255367
Original PR description
After removing sale_order_many2one widget https://github.com/odoo/odoo/commit/0ecaa6e4c359681daf90c1757bcf71ba5e4d305c , there's no need for multiple sale_order_id definitions in the form view. In this commit, cleaning the redundant field definitions and restrict visibility of Sale Order smart button. task-4661781 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#280740 Forward-Port-Of: odoo/odoo#255367
Before this commit, this test was sometimes failing. `edit("...")` validates the value by default (i.e. is followed by enter). It may happen that the dropdown is already open when doing so, and in this case, the first value is selected. However, it may often happen that it isn't open yet, so nothing happens. To turn tests more robust, we typically turn off the auto confirm and call runAllTimers() to ensure the dropdown is open, then select the value. That's also what we did here. runbot er
Original PR description
Before this commit, this test was sometimes failing. `edit("...")` validates the value by default (i.e. is followed by enter). It may happen that the dropdown is already open when doing so, and in this case, the first value is selected. However, it may often happen that it isn't open yet, so nothing happens.
To turn tests more robust, we typically turn off the auto confirm and call runAllTimers() to ensure the dropdown is open, then select the value. That's also what we did here.
runbot error-944120
Description of the issue/feature this PR addresses:
Current behavior before PR:
Desired behavior after PR is merged:
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#280384# Issue The test `test_absence_management_with_timeoff` fails if demo data is enabled. It was introduced by : https://github.com/odoo/odoo/pull/272089 # Cause `self.env.user` has an 'Europe/Brussels' tz when demo data is enabled. This changes the date used in the `search_count` at then end of the test : 2026-01-14 00:00 => 2026-01-13 23:00 So we check at the wrong date runbot-941523 Forward-Port-Of: odoo/odoo#279764
Original PR description
# Issue The test `test_absence_management_with_timeoff` fails if demo data is enabled. It was introduced by : https://github.com/odoo/odoo/pull/272089 # Cause `self.env.user` has an 'Europe/Brussels' tz when demo data is enabled. This changes the date used in the `search_count` at then end of the test : 2026-01-14 00:00 => 2026-01-13 23:00 So we check at the wrong date runbot-941523 Forward-Port-Of: odoo/odoo#279764
During the forward port of #278378, the dynamic NSI file path variable was overwritten by an old hardcoded one, breaking the IoT package build. Forward-Port-Of: odoo/odoo#280885
Original PR description
During the forward port of #278378, the dynamic NSI file path variable was overwritten by an old hardcoded one, breaking the IoT package build. Forward-Port-Of: odoo/odoo#280885
Before this commit, this test sometimes failed because it couldn't find a dialog containing "camera" within 200ms. In the test scenario, we click to open the BarcodeDialog, which uses the BarcodeVideoScanner. The latter, in its `onMounted`, checks whether it has the necessary permission, which isn't the case as the `getUserMedia` function is mocked in the test to return a rejected promise. As a consequence, the `onError` callback given in props is called, which changes the state of the parent
Original PR description
Before this commit, this test sometimes failed because it couldn't find a dialog containing "camera" within 200ms. In the test scenario, we click to open the BarcodeDialog, which uses the…
Before this commit, this test sometimes failed because it couldn't find a dialog containing "camera" within 200ms. In the test scenario, we click to open the BarcodeDialog, which uses the BarcodeVideoScanner. The latter, in its `onMounted`, checks whether it has the necessary permission, which isn't the case as the `getUserMedia` function is mocked in the test to return a rejected promise. As a consequence, the `onError` callback given in props is called, which changes the state of the parent component, which re-renders itself so display "Unable to access camera" instead of the BarcodeVideoScanner. To make this test more robust, we do 2 things: 1) load the zxing library before running the test, which avoids the BarcodeVideoScanner component to load it in onWillStart. 2) explicitly wait for the 2 animationFrames, as in the scenario, we must wait for the BarcodeDialog to be rendered twice, and those renderings are now synchronous. runbot error-237933 Forward-Port-Of: odoo/odoo#280613
Currently, if you have a partner with Belgian VAT as peppol eas, but no peppol endpoint, you get a traceback when you open the Send&Print. It can happen easily, if you have customers without VAT or company registry, that were created 2 years ago, when we put Belgian VAT as default. Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com
Original PR description
Currently, if you have a partner with Belgian VAT as peppol eas, but no peppol endpoint, you get a traceback when you open the Send&Print. It can happen easily, if you have customers without VAT or company registry, that were created 2 years ago, when we put Belgian VAT as default. Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#280344 Forward-Port-Of: odoo/odoo#280234
A `product.pricelist.item` targeting a product or a template that is not loaded in the PoS was applied to every product of the session. `computeRuleIndexes` deduced which kind of rule an item was from the many2one that resolved to a live record. That getter returns `undefined` when the targeted record is not in the local store, so such an item fell through every branch and ended up in the global rules, overriding the price of unrelated products. The targeted record is legitimately absent i
Original PR description
A `product.pricelist.item` targeting a product or a template that is not loaded in the PoS was applied to every product of the session. `computeRuleIndexes` deduced which kind of rule an item was from the many2one that resolved to a live record. That getter returns `undefined` when the targeted record is not in the local store, so such an item fell through every branch and ended up in the global rules, overriding the price of unrelated products. The targeted record is legitimately absent in two cases: the product was archived and removed by `filter_local_data` while the rule itself was kept, and, on an incremental reload, the item domain drops its product and category filters, so items of products that were never loaded in this PoS might be sent to the client. opw-6344491 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#280742 Forward-Port-Of: odoo/odoo#279491
Before this commit, it was possible that get_limited_partners_loading returned a partner if a module that overrode the method was installed. runbot-944636 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#280800 Forward-Port-Of: odoo/odoo#280628
Original PR description
Before this commit, it was possible that get_limited_partners_loading returned a partner if a module that overrode the method was installed. runbot-944636 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#280800 Forward-Port-Of: odoo/odoo#280628
Currently, users encounter a traceback when attempting to print the traceability report for a manufacturing order. ## Steps to produce: - Install Manufacturing without demo data. - Enable Lots & Serial Numbers in Settings. - Create two products: Car and Engine. - Configure Engine to use Unique Serial Number tracking (Inventory →Traceability). - Set the on-hand quantity of Engine to 1 with serial number 0001. - Create a BoM for Car using Engine as a component. - Create and confirm a man
Original PR description
Currently, users encounter a traceback when attempting to print the traceability report for a manufacturing order. ## Steps to produce: - Install Manufacturing without demo data. - Enable Lots &…
Currently, users encounter a traceback when attempting to print the traceability report for a manufacturing order. ## Steps to produce: - Install Manufacturing without demo data. - Enable Lots & Serial Numbers in Settings. - Create two products: Car and Engine. - Configure Engine to use Unique Serial Number tracking (Inventory →Traceability). - Set the on-hand quantity of Engine to 1 with serial number 0001. - Create a BoM for Car using Engine as a component. - Create and confirm a manufacturing order for Car. - Click `Consumed` for the component and click Produce All. - Navigate to Lots & Serial Numbers → Engine → 0001 → Traceability. - Click the arrow next to the manufacturing order reference, then click Print. ## Observed Behavior: An `Arbitrary Uncaught Python Exception` traceback is raised, resulting in a 404 error. ## Root Cause: This issue occurs because, when the user clicks the arrow button in the traceability report, the template [1] invokes the `onClickUpDownStream` function. This function adds the URL `/stock/output_format/stock/active_id` to the context , as shown in [2]. Later, when the user clicks the Print button, `onClickPrint()` [3] constructs the print URL using the `controllerUrl` value by replacing the active model and active ID placeholders with values from the context. However, the URL stored in the context contains `/active_id` instead of `:active_id`. As a result, the placeholder replacement does not occur, leaving the URL unchanged. This causes the print action to use an invalid URL, ultimately resulting in a 404 error. As shown in [4], `controllerUrl` is assigned directly from the context. [1]: https://github.com/odoo/odoo/blob/a398ade607940a281552f8cba2c1cf80bb0e77f6/addons/stock/static/src/client_actions/stock_traceability_report_backend.xml#L52-L56 [2]: https://github.com/odoo/odoo/blob/a398ade607940a281552f8cba2c1cf80bb0e77f6/addons/stock/static/src/client_actions/stock_traceability_report_backend.js#L105-L118 [3]: https://github.com/odoo/odoo/blob/a398ade607940a281552f8cba2c1cf80bb0e77f6/addons/stock/static/src/client_actions/stock_traceability_report_backend.js#L120-L131 [4]: https://github.com/odoo/odoo/blob/a398ade607940a281552f8cba2c1cf80bb0e77f6/addons/stock/static/src/client_actions/stock_traceability_report_backend.js#L53-L55 ## Solution: Pass the correct URL in the context so that the active ID placeholder can be replaced correctly during the print action. This ensures that the generated print URL is valid, allowing the user to print the report without encountering any errors. opw-6372834 Forward-Port-Of: odoo/odoo#279844 Forward-Port-Of: odoo/odoo#276449
`_selection_target_model()` searched all records of ir_model and due to some prefetch issues, multiple queries ran depending on the number of models in db. By using search_fetch we eliminate this. Partial backport of odoo/odoo#281215
Original PR description
`_selection_target_model()` searched all records of ir_model and due to some prefetch issues, multiple queries ran depending on the number of models in db. By using search_fetch we eliminate this. Partial backport of odoo/odoo#281215
Steps to reproduce ------------------ 1. Install `l10n_pe_pos`. 2. Create a contact with the identification type DNI and a number. 3. Sell a product to this contact and print the receipt. -> the receipt shows "RUC" in front of the number, even though the number is a DNI and not a RUC. Why it's happening ------------------ Since `aeaca097ae39` the number of the contact is printed with a label in front of it, before there was no label at all. This label is the `vat_label` of the country,
Original PR description
Steps to reproduce ------------------ 1. Install `l10n_pe_pos`. 2. Create a contact with the identification type DNI and a number. 3. Sell a product to this contact and print the receipt. -> the…
Steps to reproduce ------------------ 1. Install `l10n_pe_pos`. 2. Create a contact with the identification type DNI and a number. 3. Sell a product to this contact and print the receipt. -> the receipt shows "RUC" in front of the number, even though the number is a DNI and not a RUC. Why it's happening ------------------ Since `aeaca097ae39` the number of the contact is printed with a label in front of it, before there was no label at all. This label is the `vat_label` of the country, so "RUC" for Peru. But in Peru each contact can have a different identifier, and the type is on the contact in `l10n_latam_identification_type_id`. The fix ------- In `l10n_pe_pos` we set `partner_vat_label` with the name of the identification type of the contact. If the contact has no identification type we keep the number alone. Before vs After for a customer identified with DNI ------------------------------------------------- <img width="465" height="203" alt="Capture d’écran 2026-07-30 à 14 45 17" src="https://github.com/user-attachments/assets/85c921df-c1fd-430b-b4e6-341bc183bd61" /> <img width="467" height="253" alt="Capture d’écran 2026-07-30 à 14 49 36" src="https://github.com/user-attachments/assets/3ac243c6-04fe-47a4-a662-c59b88276db7" /> opw-6422619
Before this commit, the unread badge of the Chat action could stay empty after a click on "Mark as Unread" in the meeting view: FAILED: [17/24] Tour discuss.meeting_view_public_tour Step .o-mail-Meeting [title='Chat']:has(.badge:contains(1)) This happens because a mark as read and a mark as unread write the same fields of the channel member in two requests, and the server applies them in the order it receives them, not the order they are sent. Under CI load, a mark as read sent be
Original PR description
Before this commit, the unread badge of the Chat action could stay empty after a click on "Mark as Unread" in the meeting view:
FAILED: [17/24] Tour discuss.meeting_view_public_tour
Step .o-mail-Meeting [title='Chat']:has(.badge:contains(1))
This happens because a mark as read and a mark as unread write the same fields of the channel member in two requests, and the server applies them in the order it receives them, not the order they are sent. Under CI load, a mark as read sent before the click reached the server after the mark as unread, marking the member read again and hiding the badge through its bus push.
This commit requests the mark as unread through the queue of the mark
as read, which sends one request at a time.
This also drops the check the mark as read made against a mark as unread requested in between, as the queue keeps only the last request and replaces the waiting one.
https://runbot.odoo.com/odoo/error/944432The current implementation of the Peppol XML export incorrectly populates the <cac:InvoicePeriod> nodes with internal deferred entry dates. These dates are intended for the vendor's revenue recognition process, and the customer has nothing to do with these dates. This commit ensures that: - deferred entries are never created when importing vendor bills. - <cac:InvoicePeriod> is no longer exported in invoices (for now). task-6014315 --- I confirm I have signed the CLA and read the
Original PR description
The current implementation of the Peppol XML export incorrectly populates the <cac:InvoicePeriod> nodes with internal deferred entry dates. These dates are intended for the vendor's revenue recognition process, and the customer has nothing to do with these dates. This commit ensures that: - deferred entries are never created when importing vendor bills. - <cac:InvoicePeriod> is no longer exported in invoices (for now). task-6014315 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#279164 Forward-Port-Of: odoo/odoo#265796
Issue: The MyInvois payload computed `cbc:PrepaidAmount` as `amount_total - amount_residual`, treating every reconciled payment as a prepayment. A payment made on or after the invoice date is an ordinary settlement, not a deposit, but the code recognized it as one anyway. The values reported for `PrepaidAmount` were wrong regardless of the invoice date, and for a fully paid invoice this also collapsed `PayableAmount` to 0.00, which LHDN rejects. Root Cause: LHDN only considers a reconciled
Original PR description
Issue: The MyInvois payload computed `cbc:PrepaidAmount` as `amount_total - amount_residual`, treating every reconciled payment as a prepayment. A payment made on or after the invoice date is an…
Issue: The MyInvois payload computed `cbc:PrepaidAmount` as `amount_total - amount_residual`, treating every reconciled payment as a prepayment. A payment made on or after the invoice date is an ordinary settlement, not a deposit, but the code recognized it as one anyway. The values reported for `PrepaidAmount` were wrong regardless of the invoice date, and for a fully paid invoice this also collapsed `PayableAmount` to 0.00, which LHDN rejects. Root Cause: LHDN only considers a reconciled payment a genuine deposit if it was received before the invoice date. The code applied no date condition at all, so any payment reconciled against the invoice was added to `PrepaidAmount` and reduced `PayableAmount` accordingly. Fix: Only sum reconciled payment partials whose date is strictly earlier than the invoice date as prepaid, so regular payments are no longer misclassified as deposits. As a safety net, if the valid prepaid sum still covers the full invoice amount (e.g. a full advance payment), reset it to 0 so `PayableAmount` always reflects the full amount_total instead of being reported as 0. Also omit the `PrepaidPayment` node entirely when there is no genuine prepayment, rather than emitting it with a 0.00 amount. [Task-6404296](https://www.odoo.com/odoo/my-tasks/6404296) Forward-Port-Of: odoo/odoo#280569 Forward-Port-Of: odoo/odoo#278010
The getter `getLoadedDataSources` was filtering out datasources that are not 'ready' but they should actually filter out datasources that were already loaded (so ready) but invalid. Task: 6387729 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#279153 Forward-Port-Of: odoo/odoo#276255
Original PR description
The getter `getLoadedDataSources` was filtering out datasources that are not 'ready' but they should actually filter out datasources that were already loaded (so ready) but invalid. Task: 6387729 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#279153 Forward-Port-Of: odoo/odoo#276255
Steps to reproduce: - From the website editor, open the Theme tab. - Upload a custom font. - Open the media dialog and go to the "Documents" tab. Issue: The uploaded font files appeared in the Documents tab. When a zip file was uploaded, every font it contained appeared individually, along with the generated "CSS font face" attachment. Cause: Fonts uploaded through `/website/theme_upload_font` are created as public attachments. The Documents tab of the media dialog lists every public
Original PR description
Steps to reproduce: - From the website editor, open the Theme tab. - Upload a custom font. - Open the media dialog and go to the "Documents" tab. Issue: The uploaded font files appeared in the…
Steps to reproduce: - From the website editor, open the Theme tab. - Upload a custom font. - Open the media dialog and go to the "Documents" tab. Issue: The uploaded font files appeared in the Documents tab. When a zip file was uploaded, every font it contained appeared individually, along with the generated "CSS font face" attachment. Cause: Fonts uploaded through `/website/theme_upload_font` are created as public attachments. The Documents tab of the media dialog lists every public attachment that is not an image or an asset, so the font files (mimetype `font/...`), their font face declaration (mimetype `text/css`) and googleFontMetadata (server caches it as public attachment) were listed. Fix: Exclude those attachments from the Documents tab domain: - whose mimetype starts with `font/`, - whose description matches the font face declarations created in `snippets.options.js`. - whose name equals "googleFontMetadata". task-[4771523](https://www.odoo.com/odoo/project/974/tasks/4771523) Forward-Port-Of: odoo/odoo#280563 Forward-Port-Of: odoo/odoo#275838
Steps to reproduce: - Go to Edit mode - Go to the Theme tab - Open a color preset to customize it - Change the "Headings" color => The color of "Title" did not change in the preview By changing the tag from "h3" to "h1", the color in the preview is now correctly updated in the theme tab. "fs-4" is added to keep the previous size. task-6299680 Forward-Port-Of: odoo/odoo#278056
Original PR description
Steps to reproduce: - Go to Edit mode - Go to the Theme tab - Open a color preset to customize it - Change the "Headings" color => The color of "Title" did not change in the preview By changing the tag from "h3" to "h1", the color in the preview is now correctly updated in the theme tab. "fs-4" is added to keep the previous size. task-6299680 Forward-Port-Of: odoo/odoo#278056
Microsoft issues a new refresh token on every access token refresh (rolling 90-day sliding window). The previous code discarded it, causing users to be forced to re-authenticate every 90 days once the original token expired. Closes #253543 Forward-Port-Of: odoo/odoo#280535 Forward-Port-Of: odoo/odoo#268284
Original PR description
Microsoft issues a new refresh token on every access token refresh (rolling 90-day sliding window). The previous code discarded it, causing users to be forced to re-authenticate every 90 days once the original token expired. Closes #253543 Forward-Port-Of: odoo/odoo#280535 Forward-Port-Of: odoo/odoo#268284
**Steps to reproduce:** - Install l10n_pl_edi and enable Allow KSeF integration from **Accounting** settings. - Switch to a Polish company. - Create an EU customer with a valid VAT number. - Create a sale order containing a service product taxed with 0% Steel (or any tax that has a tag of K11). - Confirm the sale order and create a down payment invoice. - Send the invoice to KSeF and inspect the generated XML. **Observed behavior:** The generated KSeF XML does not contai
Original PR description
**Steps to reproduce:** - Install l10n_pl_edi and enable Allow KSeF integration from **Accounting** settings. - Switch to a Polish company. - Create an EU customer with a valid VAT number. - Create a…
**Steps to reproduce:** - Install l10n_pl_edi and enable Allow KSeF integration from **Accounting** settings. - Switch to a Polish company. - Create an EU customer with a valid VAT number. - Create a sale order containing a service product taxed with 0% Steel (or any tax that has a tag of K11). - Confirm the sale order and create a down payment invoice. - Send the invoice to KSeF and inspect the generated XML. **Observed behavior:** The generated KSeF XML does not contain the `P_13_8` field. **Cause:** For invoices involving the tax of tag `K11` (mainly these taxes are used for the supplies that are outside the territory of Poland), the value corresponding to `P_13_8` was not being assigned during XML generation, causing the tag to be omitted from the exported KSeF document. **Fix:** Populate the value of `P_13_8` during KSeF XML generation for invoices, ensuring the field is correctly included in the exported XML. This PR updates the computation of tag `P_13_10` with its test case to ensure consistency with the expected reporting logic, where the tag is computed solely from `K_31`. Here is the [Documentation](https://ksef.podatki.gov.pl/media/gtjhkeek/information-sheet-on-the-fa-3-logical-structure-04032026.pdf) link for the reference of the Ksef structure. **opw**-6294181 Forward-Port-Of: odoo/odoo#280830 Forward-Port-Of: odoo/odoo#276887
Issue: --- Fiscal position is wrongly set to `self.env.user.partner_id.country_id` instead of `partner_shipping` country, if `partner_shipping_id` is not changed in the checkout process. Steps: 1- Create two auto detect fiscal positions: France, Germany 2- Set portal user's partner address country to France. 3- Using portal user, shop from website, and create a delivery address. 4- Pay and confirm the order. 5- Using the admin user, you check the SO's FP which is correctly set to
Original PR description
Issue: --- Fiscal position is wrongly set to `self.env.user.partner_id.country_id` instead of `partner_shipping` country, if `partner_shipping_id` is not changed in the checkout process. Steps: 1-…
Issue: --- Fiscal position is wrongly set to `self.env.user.partner_id.country_id` instead of `partner_shipping` country, if `partner_shipping_id` is not changed in the checkout process. Steps: 1- Create two auto detect fiscal positions: France, Germany 2- Set portal user's partner address country to France. 3- Using portal user, shop from website, and create a delivery address. 4- Pay and confirm the order. 5- Using the admin user, you check the SO's FP which is correctly set to Germany. 6- Using portal user, again shop from website, and don't change address. Keep previous shipping address which is Germany. 7- Confirm and pay the order. 8- Using admin user, check the new SO's FP. It's set to France. Cause: --- `_compute_fiscal_position_id` in SO depends on `partner_shipping_id`. When the `partner_shipping_id` is not changed, the fiscal position value set in create will remain. This value is set in `Website._prepare_sale_order_values()`. The `fiscal_position_id` is set to self.fiscal_position_id, which is `_get_fiscal_position(self.env.user.partner_id)`. Fix: --- If the user has already a SO, we can use last SO's shipping address and invoice address to calculate FP in `_prepare_sale_order_values`. opw-6357638 Forward-Port-Of: odoo/odoo#279716 Forward-Port-Of: odoo/odoo#276485