Daily updates from Odoo
Friday, July 24, 2026
56 changes · saas-19.4
Security fixes and vulnerability patches
Employee payroll information for Switzerland, Indonesia, and Turkey is now limited to users with payroll access. This helps prevent non-payroll staff from viewing sensitive payroll-related fields in employee records.
Original PR description
This commit adds `groups="hr_payroll.group_hr_payroll_user"` to all fields displayed inside payroll tab in the form view of employee to make sure those fields are only accessible to payroll users. runbot-error-234071 Forward-Port-Of: odoo/enterprise#124828 Forward-Port-Of: odoo/enterprise#122293
New functionality added to Odoo
Spreadsheet users can now display the readable name of a selected global filter, such as a customer name, instead of only its internal ID. This makes spreadsheet reports easier to understand and share with business users.
Original PR description
Before this commit: If you use ODOO.FILTER.VALUE and have a customer set in the global filter, it returns the id of the customer. That can be useful in some cases but in others you might simply want the label. Task: 6167605 Forward-Port-Of: odoo/enterprise#124746 Forward-Port-Of: odoo/enterprise#115984
Enhancements to existing features
When users choose a project in the timesheet timer, Odoo now automatically fills in the task they most recently logged time on for that project. Helpdesk projects get the same convenience for tickets, helping users start timers faster while still allowing them to choose a different item in one click.
Original PR description
When selecting a project in the timesheet timer, the task on which the user most recently logged time for that project is now prefilled, as they are most likely to keep logging time on it. If not, selecting a different task only requires one click. For Helpdesk projects, where the timer shows the ticket field instead of the task field, the most recently timesheeted ticket is prefilled in the same way. task-6359030 Forward-Port-Of: odoo/enterprise#124010
The employee time-off Gantt view now loads availability information in grouped batches and only for the requested date range. This makes large employee schedules much faster to open, reducing wait times from several seconds to around one second in the reported case.
Original PR description
At odoo, our friendly kitchen chef needs to know who is off on any given day. To know that, they use the holiday gantt view and display all employees and check the sum. For 200+ employees working at GR2, `get_gantt_data` takes 7+ seconds `_unavailable_intervals_batch` is called for each individual version, which means it's not batched. Ultimatly, it leads to lots of sql queries that could be grouped together. With this commit, the calls are batched per calendar before: ~7s after: ~900ms-1s Forward-Port-Of: odoo/enterprise#125385 Forward-Port-Of: odoo/enterprise#124820
Since [website builder refactor], a date field or a datetime that appears in the page is not editable from website builder. This commit re-introduces the ability to do so. [website builder refactor]: 9fe45e2b7ddbbfd0445ffe25a859e67a316d02b2 task-6230582 Forward-Port-Of: odoo/odoo#277849 Forward-Port-Of: odoo/odoo#270325
Original PR description
Since [website builder refactor], a date field or a datetime that appears in the page is not editable from website builder. This commit re-introduces the ability to do so. [website builder refactor]: 9fe45e2b7ddbbfd0445ffe25a859e67a316d02b2 task-6230582 Forward-Port-Of: odoo/odoo#277849 Forward-Port-Of: odoo/odoo#270325
After this advisory: https://services.gst.gov.in/services/advisoryandreleases/read/661 It has become mandatory to pass `shipToGSTIN`, i.e. GST number of the ship-to partner during the generation of the e-waybill for `Bill-to-Ship-to` (type-2) and `Combination` (type-4) transaction types. task-6236778 Forward-Port-Of: odoo/odoo#266388
Original PR description
After this advisory: https://services.gst.gov.in/services/advisoryandreleases/read/661 It has become mandatory to pass `shipToGSTIN`, i.e. GST number of the ship-to partner during the generation of the e-waybill for `Bill-to-Ship-to` (type-2) and `Combination` (type-4) transaction types. task-6236778 Forward-Port-Of: odoo/odoo#266388
Task: 6167605 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#277060 Forward-Port-Of: odoo/odoo#261793
Original PR description
Task: 6167605 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#277060 Forward-Port-Of: odoo/odoo#261793
This commit adds `company_register` VAT Registry (VAT ID) to the invoice header for [legal reasons](https://lex.uz/ru/docs/4948595#5225819). Also, the condition for `TIN` has been updated to be 14 digits if the contact is a person and 9 digits if it is a company. task-6205255 Forward-Port-Of: odoo/odoo#273885
Original PR description
This commit adds `company_register` VAT Registry (VAT ID) to the invoice header for [legal reasons](https://lex.uz/ru/docs/4948595#5225819). Also, the condition for `TIN` has been updated to be 14 digits if the contact is a person and 9 digits if it is a company. task-6205255 Forward-Port-Of: odoo/odoo#273885
Resolved issues and error corrections
Fixed an issue that could make bank statement CSV imports fail when the system performed a trial import before saving. This helps users import bank statement lines more reliably and avoids confusing “record deleted” errors.
Original PR description
odoo/odoo#255059 made execute_import's savepoint flushing, so a dryrun rollback now properly invalidates the ORM cache instead of leaving it. That exposed a pre-existing bug here: we created the statement with line_ids pointing at .line records dryrun had already rolled back, raising "Record does not exist or has been deleted". To fix this issue we run as dryrun as False to allow the execute_import's savepoint do the work and rollbacked in finally. Steps to reproduce: - Just import a account.bank.statement.line OPW-6410352
Product managers can now automatically fill product details from barcode lookups without needing full system administrator access. This lets authorized product teams create and maintain products more efficiently while avoiding unnecessary admin permissions.
Original PR description
Currently when a user with a product manager rights that is not admin tries to look up the product with barcode information is not auto filled. ## Steps to replicate: - Install stock with demo data -…
Currently when a user with a product manager rights that is not admin tries to look up the product with barcode information is not auto filled. ## Steps to replicate: - Install stock with demo data - Barcode Database > Setup barcode lookup credentials - Users > Marc Demo > Give Marc Demo > Master Data > Products > Create - Login as `Marc Demo` - Products > Barcode: `850049670180` > Click anywhere else ## Observed Behaviour: Information on the product template is not autofilled, as it would be when using a System Admin user(Mitchell Admin). ## Root cause: This issue occurs because barcode lookup is gated behind a check for System Admin rights. Although users in the Product Manager group have permission to create products, they do not satisfy this condition, so the barcode lookup never executes at [1]. [1]- https://github.com/odoo/enterprise/blob/c66995fda83e19b28a38312af8efdc1601881cf0/product_barcodelookup/models/product_template.py#L17-L22 ## Why this is an issue: The original restriction (task [2] and commit [3]) was intended to limit barcode lookup to users who can create products, preventing unnecessary API calls. This was a valid assumption in 17.3-18.0, where creating products in POS required System Admin rights but now after commit [4] this is no longer the case. In v18, task [5] introduced the Product Manager group, making product creation independent of System Admin rights or module rights. Later, v18.3 exposed these Master Data access rights to non-debug users through commit [6]. As a result, there are users who are legitimately responsible for product creation and maintenance (regardless of POS usage) they can no longer use barcode lookup unless they are also granted full System Admin privileges, which provides broader access than required. ## Solution: Remove the group-based permission check so that access is determined solely by product edit permissions. This ensures that only users with the ability to modify products can use the API call, preserving the original security intent. As a result, users no longer need unnecessary administrative privileges toperform barcode lookups. [2]: https://www.odoo.com/odoo/project/49/tasks/3911024 [3]: https://github.com/odoo/enterprise/commit/444df3e48cb8d479d3b5d4a03a4bfefa48650910 [4]: https://github.com/odoo/odoo/commit/821bbc4504fd80a508e2412c7490ee60dd03f7b8 [5]: https://github.com/odoo/odoo/commit/d4886faf12ccaf63d5e899c20df2543d1ce046ab [6]: https://github.com/odoo/odoo/commit/e74eaf628498155243db73ea229eaf5e74c24f2a opw-6290999 Forward-Port-Of: odoo/enterprise#121915
Fixed an issue where Chilean electronic delivery guides could fail when printing deliveries for kits whose components use different units of measure. The guide now prices component lines from the product when needed, avoiding invalid unit conversions and helping users complete deliveries without errors.
Original PR description
When a kit is delivered, each component move is linked to the kit's sale order line. Pricing the delivery guide in "sale order" mode converted the component quantity into the kit's sale UoM. For a component sold in a different UoM category than the kit, this cross-category conversion raises a UserError. Steps to reproduce: - Create a BoM for a kit product with a component in a different UoM category - Create a customer with Delivery Guide Price = "From Sale Order" - Sold the kit in a sale order and deliver it - On the delivery, print the delivery guide -> error This fix makes the guide price for a component move to be "product" if the component's product is different from the related sale line product, avoiding the cross-category UoM conversion. opw-6327895 Forward-Port-Of: odoo/enterprise#125199 Forward-Port-Of: odoo/enterprise#122776
The Related Entries button for confirmed assets has been renamed to Related Items and now keeps users in the journal item list instead of opening an unhelpful detail form. This makes reviewing asset-related accounting lines clearer and reduces unnecessary navigation.
Original PR description
If you create an asset and confirm it, you can see the Related Entries using the smart button Related Entries. The list view that opens is clickable, but it opens a quite useless form view of the Journal Items. - Rename breadcrumb button to Related Items - Make it behave like action_account_moves_all, to not open form view Ticket: [6385260](https://www.odoo.com/odoo/project/967/tasks/6385260) Forward-Port-Of: odoo/enterprise#124672
This fixes an intermittent issue in automated barcode scrap checks where the entered scrap quantity could be lost before saving. The change helps keep test results reliable and reduces false failures in inventory and manufacturing barcode workflows.
Original PR description
These barcode scrap tours randomly trigger "You can only enter positive quantities." on runbot: the quantity set with a raw input.value is dropped when the field re-renders before the scrap is saved, so it scraps 0. Dispatching an input event keeps the typed value. error-238911 Forward-Port-Of: odoo/enterprise#124952
Fixed an issue where importing a Chilean electronic invoice file containing multiple documents could put all invoice lines and references onto the first vendor bill. Each bill now only uses its own document data, helping prevent incorrect totals and reconciliation problems.
Original PR description
When importing an EnvioDTE XML containing several DTEs (journal upload or incoming DTE mail server), one vendor bill is created per DTE, but the first bill receives the invoice lines and references…
When importing an EnvioDTE XML containing several DTEs (journal upload or incoming DTE mail server), one vendor bill is created per DTE, but the first bill receives the invoice lines and references of ALL the DTEs in the file, causing the total amount mismatch.
Cause: `_split_xml_into_new_attachments()` creates new attachments for the documents beyond the first one but leaves the original `file_data['xml_tree']` untouched; the decoder must scope itself to the first document (as l10n_it_edi and l10n_es_edi_facturae do), which `_l10n_cl_import_dte()` never did.
e.g. l10n_es_edi_facturae:633:
```python
# Only decode the first invoice of the Factura-e file.
tree = tree.xpath('//Invoice')[0]
```
Fix: scope the tree to the first DTE node before filling the bill. Kept behind a `len > 1` guard so files with a bare <DTE> root (matched by `xpath('//ns0:DTE')` but not by `findall('.//ns0:DTE')`) keep working.
Introduced in: https://github.com/odoo/enterprise/pull/75327.
opw-6378954
Forward-Port-Of: odoo/enterprise#124691The project forecasting view was updated so it connects to the current subtask button. This prevents the button customization from pointing to an outdated action and helps users access subtasks reliably.
Original PR description
Issue --- The inherited xpath still targets the old action-based subtask button Fix --- Update the inherited xpath to target action_open_subtasks. task-5966684 Forward-Port-Of: odoo/enterprise#124063 Forward-Port-Of: odoo/enterprise#123035
Fixed an issue where testing a CSV import of bank statement lines could fail because temporary imported records were incorrectly reused after rollback. This makes bank statement imports more reliable and prevents confusing errors during import validation.
Original PR description
odoo/odoo#255059 made execute_import's savepoint flushing, so a dryrun rollback now properly invalidates the ORM cache instead of leaving it. That exposed a pre-existing bug here: we created the statement with line_ids pointing at .line records dryrun had already rolled back, raising "Record does not exist or has been deleted". To fix this issue we run as dryrun as False to allow the execute_import's savepoint do the work and rollbacked in finally. Steps to reproduce: - Just import a account.bank.statement.line OPW-6410352
Odoo Studio now allows users to rename fields with labels using Arabic or other non-Latin characters without causing an invalid technical name error. This prevents a confusing failure when customizing views for multilingual users.
Original PR description
Steps: - Install web_studio - Add any field (example char field) to any view - Rename it in arabic, example `السَّلَامُ عَلَيْكُمْ` - Error Custom field names cannot contain double underscores Webclient (view_editor_model) escape every non-alphabetic chars, so new label value contains nothing but a space which will be replaced by a _ this new label value will be concatenated to `x_studio_`. Resulting to the string `x_studio__`. A solution should be to prevent changing the technical name if the new label value (escaped) is empty. opw-6311027 Forward-Port-Of: odoo/enterprise#124445 Forward-Port-Of: odoo/enterprise#121343
Testing a CSV bank statement import no longer tries to create a temporary bank statement that can disappear during the test rollback. This prevents a misleading missing-record error when the import data is valid, making the import preview more reliable for accounting users.
Original PR description
Problem: When testing importing a bank statement, an error gets thrown although the import is correct. Steps: 1. Go to Accounting 2. Go to Bank -> Import 3. Download the Import Template 4. Try…
Problem: When testing importing a bank statement, an error gets thrown although the import is correct. Steps: 1. Go to Accounting 2. Go to Bank -> Import 3. Download the Import Template 4. Try importing the template 5. Select to Create New Values in case of absent values 6. Test the import 7. Notice the error "Record *** does not exist ..." Cause: When testing an import of bank statement, the importing of the bank statement lines is done first and then they are linked to a new bank statement, if needed. https://github.com/odoo/enterprise/blob/831cc0201b128d82ce08a3f97b207859d8904870/account_bank_statement_import_csv/wizard/account_bank_statement_import_csv.py#L140-L145 This gets rolled back in case of testing (dryrun) https://github.com/odoo/enterprise/blob/831cc0201b128d82ce08a3f97b207859d8904870/account_bank_statement_import_csv/wizard/account_bank_statement_import_csv.py#L152 However, because the importing of the bank statement lines is a full test import of its own: https://github.com/odoo/enterprise/blob/831cc0201b128d82ce08a3f97b207859d8904870/account_bank_statement_import_csv/wizard/account_bank_statement_import_csv.py#L140 it gets rolled back before the lines can be linked to a new bank statement, resulting in the error of missing records. This didn't happen before because the BaseImport would not flush the cache when rolling back the changes, so the statement lines would still be in the cache and then can get linked to the statement. But after this commit: odoo/odoo@06889bd , where the savepoint in the BaseImport changed to a flushing savepoint: https://github.com/odoo/odoo/commit/06889bd62465fa20c79084b3027e0e917a55a8c8#diff-f7ea8dfd301f732f65b95439f68b7d124dd274fb2130a2aba037c9c17ceb963fL1441-R1439 when the importing of bank statement lines gets rolled back, the lines get flushed from the cache and cannot be linked to the newly created bank statement. Solution: There's no need to test linking the imported lines to a newly created bank statement. We can skip creating the bank statement if it is a test import (dryrun). opw-6404000
The timesheet completion percentage now updates immediately when timesheets are added, changed, or removed. This keeps project or task progress information accurate on screen without requiring users to refresh the page.
Original PR description
Issue: The percentage is only updated after reloading the page. Cause: The percentage computation is performed inside `loadTimesheets`, which is only called when the timesheets are loaded. Fix: Move the percentage computation into a helper function and invoke it whenever a timesheet is added, updated, or removed. task-6401186 Forward-Port-Of: odoo/enterprise#125312 Forward-Port-Of: odoo/enterprise#125074
Applying an Engineering Change Order with attached documents could fail because the system saved the wrong document reference. This fix ensures the correct attachment is linked, allowing changes with documents to be applied reliably.
Original PR description
When applying an ECO, `action_apply` copies each ECO document onto the product template and fills `origin_attachment_id` with `attach.id`. That field is a many2one to `ir.attachment`, but `attach` is a `product.document`. Steps to reproduce: - Create an `mrp.eco` record and start a new revision - Upload a document on the ECO, note its product.document id - Make sure no ir.attachment exists with that same id - Move the ECO to its final stage and hit "Apply Changes" - Observe the error The very same change was already applied on master by 3a39186f883, but was never backported. opw-6387343 Forward-Port-Of: odoo/enterprise#124950
AI-assisted create and update actions now recover gracefully when entered values break database rules, allowing the assistant to retry instead of failing outright. The update also improves access to needed model information so AI workflows can create related records more reliably for internal users.
Original PR description
Prior to this commit, the create and update tool calls could cause an unrecoverable error if the model tried to use values which were causing an SQL constraint to fail. With this commit, we add a try..except block with a savepoint to treat the SQL constraint errors as regular errors, ensuring that the model is able to retry if it misses a check. task-6196137 Forward-Port-Of: odoo/enterprise#121607
This fix ensures the BA zone in French VAT reports is sent in the expected free-text format rather than as a standard value. It helps avoid formatting or submission issues when preparing compliant French tax reports.
Original PR description
The value inside the BA zone needs to be a "TexteLibre1" and not a value no task id Forward-Port-Of: odoo/enterprise#125335
Employees can now have their analytic distribution updated without triggering a save error. The change removes unsupported tracking from this payroll accounting field, preventing errors while keeping the field available for employee records.
Original PR description
Problem: Users cannot change analytic distribution set on employees. Users encounter an error when trying to change it. Steps to reproduce: 1. Enable analytic accounting 2. Try to edit the analytic…
Problem: Users cannot change analytic distribution set on employees. Users encounter an error when trying to change it. Steps to reproduce: 1. Enable analytic accounting 2. Try to edit the analytic distribution field on an Employee 3. Notice the error being thrown when trying to save Cause: Analytic distribution field is a JSON field and JSON field and tracking is not supported on JSON fields. https://github.com/odoo/odoo/blob/2aa35eb9c7a709126dca65e81ca6e823706fbb19/addons/mail/models/mail_tracking_value.py#L172 Tracking is supported for other fields but is not supported for JSON fields, so setting tracking=True on a JSON fields leads to an error being thrown. The error gets thrown whenever the field is edited. Caused by 88a3e70 , as a result of this comment https://github.com/odoo/odoo/blob/0133e46f89df7dce8c39d2bacd29579d57a83fad/addons/hr/models/hr_version.py#L443 that mentioned that whitelisted fields should have tracking set to true. However, that's not necessary. opw-6405122 Forward-Port-Of: odoo/enterprise#125135
Belgian EC Sales List XML and PDF exports now use the foreign VAT number set on the relevant fiscal position instead of the company’s domestic VAT number. This helps companies reporting in another country submit compliant declarations with the correct declarant reference.
Original PR description
### Issue before this commit: When a company generates an EC Sales List for a foreign country (e.g., a Luxembourgish company running a Belgian report), the exported XML and PDF files incorrectly…
### Issue before this commit: When a company generates an EC Sales List for a foreign country (e.g., a Luxembourgish company running a Belgian report), the exported XML and PDF files incorrectly display the company's primary domestic VAT number instead of the foreign VAT number defined in the fiscal position in the tag DeclarantReference. ### Steps to reproduce the issue: 1. Download Accounting and l10n_lu 2. Switch to LU company 3. Go to Fiscal Positions in settings and create the Belgian position (insert country as Belgium and Foreign Tax ID as BE0477472701) 4. A pop up will appear saying: Click to create the taxes for this country. so click there to create the taxes 5. Go to Invoices and create a new invoice and be sure that: 1. be sure the customer has a VAT number in their profile 2. in tab Other Info the Fiscal Position is set to Belgium 3. the tax applied is 0% EU S (BE) 4. date of invoice is in June 6. Open the tax return in 1 July 7. Open EC Sales List June 2026 (BE) and mark as reviewed all the lines 8. Click on Validate 9. Open the XML and PDF file created and see that the tag DeclarantReference is wrong because it reports the data of LU company instead of BE company ### Cause of the issue: The `export_to_xml_sales_report` method relied on legacy code (company.partner_id.vat) to fetch the VAT number. It failed to use the centralized `get_vat_for_export(options)` method, thereby completely bypassing the foreign VAT logic correctly implemented in other tax reports. ### Reason to introduce the fix: To ensure tax compliance by appling the correct VAT number from the foreign fiscal position. opw-6170447 Forward-Port-Of: odoo/enterprise#125210 Forward-Port-Of: odoo/enterprise#124698
Audit reports now refresh the number of invalid records when a check is reviewed successfully. This prevents users from seeing outdated issue counts after a check has been corrected, improving confidence in audit results.
Original PR description
Problem: Sometimes after an audit check passes (gets reviewed successfully), the count of invalid records in the audit report is not updated. Steps to reproduce: 1. Add a check for an audit cycle 2. Make sure the check's domain is satisified by at least one record 3. Check the audit report and see the check you added 4. The check status should show an anomaly and the count of invalid records will be greater than 0 5. Now, edit the check so that the domain is not satisfied by any record 6. Check the audit report again and see the check you edited 7. The check status should show "Reviewed" but the count of invalid records will still be greater than 0, which is not correct Cause: When updating the status of an audit check, the count of invalid records is not updated, only the status gets updated. opw-6264177 Forward-Port-Of: odoo/enterprise#123976 Forward-Port-Of: odoo/enterprise#119227
Users opening an account report from the VAT return check can now refresh the page without triggering an error. This improves reliability for accounting workflows by preserving the report view correctly.
Original PR description
Opening an account report through the VAT return button on an account.return.check record returns an inline client action whose report_id only exists in context. On refresh, Odoo will throw an error because it will try to rebuild the action context based off of the URL which is deficient. This will not effect reports opened via the menu since those follow a different pathway. This fix anchors the inline action to the "path" property stored on the client action. A helper method was added for deriving the action_id from a given report. opw-6366964 Forward-Port-Of: odoo/enterprise#125246 Forward-Port-Of: odoo/enterprise#124560
### Issue before this commit: Sending a TicketBAI invoice to a customer with a Spanish address and a VAT number starting with 'N' (Non-resident entity) resulted in a rejection with error B4_2000027. The XML incorrectly generated the national <DesgloseFactura> tag instead of the required <DesgloseTipoOperacion> tag. ### Steps to reproduce the issue: 1. Download Accounting, l10n_es and l10n_es_edi_tbai 2. Change name to ES Company into “NOMBRE APELLIDOUNO APELLIDODOS” (this is to make sure t
Original PR description
### Issue before this commit: Sending a TicketBAI invoice to a customer with a Spanish address and a VAT number starting with 'N' (Non-resident entity) resulted in a rejection with error B4_2000027.…
### Issue before this commit: Sending a TicketBAI invoice to a customer with a Spanish address and a VAT number starting with 'N' (Non-resident entity) resulted in a rejection with error B4_2000027. The XML incorrectly generated the national <DesgloseFactura> tag instead of the required <DesgloseTipoOperacion> tag. ### Steps to reproduce the issue: 1. Download Accounting, l10n_es and l10n_es_edi_tbai 2. Change name to ES Company into “NOMBRE APELLIDOUNO APELLIDODOS” (this is to make sure the certificate for Ticketbai works) 3. Go to Settings → Spain Localization → set Tax Agency for = Bizkaia 4. Change VAT number for customer Mulhacén Digital S.L. into N0011452J (must be a foreign entity ID) 5. Go to Settings > Technical > System Parameters and set the parameter 'l10n_es_edi_tbai.epigrafe' to 165360 6. Create a new invoice for that client and try to send it to TicketBAI 7. Error: B4_1000002: Todos los registros incluidos en la petición son incorrectos. B4_2000027: La factura contiene un Tipo de desglose incorrecto. Ha de ser a nivel de operación cuando la factura es completa y, además, existe destinatario extranjero (tipo IDOtro o que sea NIF que empiece por N) o la Clave de IVA es 02. ### Cause of the issue: The _l10n_es_is_foreign() method evaluated these customers as domestic because their country was set to Spain and their VAT did not start with "ESN". It failed to recognize a standalone "N" prefix as a valid foreign identifier. https://github.com/odoo/odoo/blob/75ae45861e2f417aa2b90bdb2b2869718e091c09/addons/l10n_es/models/res_partner.py#L7-L10 ### Reason to introduce the fix: Adding the 'N' prefix to the _l10n_es_is_foreign() check ensures the system correctly treats these entities as foreign for tax purposes. This generates the correct XML structure automatically, without forcing users to unnaturally prepend "ES" to a legally valid NIF. opw-6326359 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#277816 Forward-Port-Of: odoo/odoo#275231
Issue: - After confirming a sale order with a reward applied (e.g. an ewallet reward), unlocking it, and editing it so the reward line's cost changes (e.g. adding a product and re-claiming the reward), the coupon's point balance updates correctly. - However, the corresponding loyalty.history record's used value is never refreshed, so it keeps showing the old cost instead of the new one. Steps to reproduce: - Enable Loyalty and Lock Confirmed Sales in Sales settings. - Create an ewallet ty
Original PR description
Issue: - After confirming a sale order with a reward applied (e.g. an ewallet reward), unlocking it, and editing it so the reward line's cost changes (e.g. adding a product and re-claiming the…
Issue: - After confirming a sale order with a reward applied (e.g. an ewallet reward), unlocking it, and editing it so the reward line's cost changes (e.g. adding a product and re-claiming the reward), the coupon's point balance updates correctly. - However, the corresponding loyalty.history record's used value is never refreshed, so it keeps showing the old cost instead of the new one. Steps to reproduce: - Enable Loyalty and Lock Confirmed Sales in Sales settings. - Create an ewallet type loyalty.program and generate an ewallet for a partner with e.g. 1000 points. - Create a sale order for that partner, add a product worth 100, and claim the ewallet reward (reward line created with points_cost = 100). - Confirm the order. loyalty.history shows used = 100 (correct), card balance shows 900 (correct). - Unlock the order, add a second product worth 100, and claim the reward again (same reward line updates to points_cost = 200). - Lock the order again. - Check the loyalty.card: balance is correctly 800. - Check loyalty.history for that order: used still shows 100 instead of 200. Fix: - Updated _update_loyalty_history() in sale_order.py to create a new history line if none exists for the given card and order combination. - Updated write() in sale_order_line.py to correctly sync history lines when a reward line is modified on a confirmed order, handling both same-coupon updates via delta and coupon changes by subtracting the old coupon cost and adding the new one separately. - Added test_loyalty_history_created_on_post_confirm_reward to verify that a history line is created when a reward is claimed on a confirmed order where no history line existed before. - Added test_loyalty_history_updated_on_points_cost_write to verify that history.used is updated by the correct delta when points_cost changes on a reward line of a confirmed order. Impact: - Ensures a coupon's usage history stays accurate after a confirmed order is unlocked and edited. - Prevents the loyalty.history used field from silently going stale while the actual point balance is correct. - Not scoped to ewallet specifically — since points_cost semantics are the same across program types, this also corrects the same class of staleness for other reward types (discount, gift_card, etc.) when a reward line's cost changes post-confirmation. Forward-Port-Of: odoo/odoo#277450 Forward-Port-Of: odoo/odoo#273688
2 props were misconfigured: - `countryID` Previous fix: https://github.com/odoo/odoo/commit/319bb52dcb022bd67b0d7349d5720221d6e1d7c4 made it so `country_id` would correctly register as a "many2one", but this made it conflict when it was passed as a `countryId` prop which expects it to be a number, rather than a many2one object. - `selectedLocationId` OWL3 conversion in https://github.com/odoo/odoo/commit/55fd748ada717df5b27376c81a8eba53d9b8ddac incorrectly converted `selectedLocationId` to
Original PR description
2 props were misconfigured: - `countryID` Previous fix: https://github.com/odoo/odoo/commit/319bb52dcb022bd67b0d7349d5720221d6e1d7c4 made it so `country_id` would correctly register as a "many2one",…
2 props were misconfigured: - `countryID` Previous fix: https://github.com/odoo/odoo/commit/319bb52dcb022bd67b0d7349d5720221d6e1d7c4 made it so `country_id` would correctly register as a "many2one", but this made it conflict when it was passed as a `countryId` prop which expects it to be a number, rather than a many2one object. - `selectedLocationId` OWL3 conversion in https://github.com/odoo/odoo/commit/55fd748ada717df5b27376c81a8eba53d9b8ddac incorrectly converted `selectedLocationId` to `optional(false) https://github.com/odoo/odoo/blob/f5c1d2210f18d1644a7ce67fca806f5c5db3df69/addons/website_sale_stock/static/src/js/location_selector/location_selector_dialog/location_selector_dialog.js#L11-L16 Steps to reproduce: - Create new Sales Order - Add a customer + product of type "Goods" - Click "Add shipping" and select "Pick up in store" delivery method - Click on Pencil button in same row as "Pickup Point" field Expected Behavior: Pickup Location selector dialog should open Actual Behavior: Stacktrace due to `"selectedLocationId", "message": "value is not a string"` or `"countryId", "message": "value is not a number"` Note that error doesn't occur when selecting pick up points via the website (i.e. ecommerce flow), possibly due to the props enforcement not occurring in the front end. opw-6321167 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
On a Purchase Order, if you duplicate the delivery, change its Operation Type and validate it, it will still count towards the received quantity on the po. Steps to reproduce: ------------------- * Create a PO and confirm it * Open the receipt, validate and duplicate it * Go on the duplicated receipt and change its Operation Type * Confirm the duplicated receipt. -> the Received Qty on the Po counted the duplicated and modified transfer. Observation: ------------- When we duplicat
Original PR description
On a Purchase Order, if you duplicate the delivery, change its Operation Type and validate it, it will still count towards the received quantity on the po. Steps to reproduce: ------------------- *…
On a Purchase Order, if you duplicate the delivery, change its Operation Type and validate it, it will still count towards the received quantity on the po. Steps to reproduce: ------------------- * Create a PO and confirm it * Open the receipt, validate and duplicate it * Go on the duplicated receipt and change its Operation Type * Confirm the duplicated receipt. -> the Received Qty on the Po counted the duplicated and modified transfer. Observation: ------------- When we duplicate a stock.picking, we will call ```copy``` and copy all its ```move_ids``` (stock.move), and in stock.move we will copy the ```purchase_line_id``` : https://github.com/odoo/odoo/blob/754898c58fded0e3c3c30702f15258f1dadcfa6c/odoo/models.py#L5868 https://github.com/odoo/odoo/blob/754898c58fded0e3c3c30702f15258f1dadcfa6c/odoo/models.py#L5881-L5892 https://github.com/odoo/odoo/blob/3e6d93bef49bb2718e8aa1756f95c2a6117c8d55/addons/purchase_stock/models/stock_move.py#L13-L15 the ```purchase_line_id``` will keep the link with the pol. The fields are copied since they have ```copy=True``` https://github.com/odoo/odoo/blob/754898c58fded0e3c3c30702f15258f1dadcfa6c/addons/stock/models/stock_picking.py#L614 https://github.com/odoo/odoo/blob/754898c58fded0e3c3c30702f15258f1dadcfa6c/odoo/fields.py#L304 Because new stock moves are linked directly to the Purchase Order Line (POL), the qty_received calculation aggregates all associated move quantities. https://github.com/odoo/odoo/blob/cfc63060926db4cec773c159b8ecf97dc0b36d1a/addons/purchase_stock/models/purchase_order_line.py#L73-L76 opw-6088239 Forward-Port-Of: odoo/odoo#276250 Forward-Port-Of: odoo/odoo#259570
Selecting an online media-library illustration for a product image (or any field using the media dialog) saved the wrong image, or failed with "Please try to reupload this image" or a "raw is undefined" crash. Steps to reproduce ================== 1. Open a product and edit its image 2. In "Select a media", search a term (e.g. "new") 3. Click one of the online library illustrations => The wrong image is saved, or an error notification is shown Root cause ========== Library media r
Original PR description
Selecting an online media-library illustration for a product image (or any field using the media dialog) saved the wrong image, or failed with "Please try to reupload this image" or a "raw is…
Selecting an online media-library illustration for a product image (or any field using the media dialog) saved the wrong image, or failed with "Please try to reupload this image" or a "raw is undefined" crash. Steps to reproduce ================== 1. Open a product and edit its image 2. In "Select a media", search a term (e.g. "new") 3. Click one of the online library illustrations => The wrong image is saved, or an error notification is shown Root cause ========== Library media results carry a media-library id, not a local ir.attachment id. imageSave persists them as real attachments (save_library_media, run inside super.save) but then reads them back using the original media-library id. That id either collides with an unrelated local attachment, e.g. a type='url' demo record with no raw, hence the wrong image and the "reupload" warning or matches no record at all, so the read returns undefined and accessing .raw throws. Fix === Use the ids of the attachments actually created by the render step, carried on the rendered <img> elements (dataset.attachmentId), instead of the media-library ids. opw-6353273 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#274372
Problem: Some users with limited access rights cannot access invoices they created, after another user duplicates their sales order and invoices it. Steps to reproduce: 1. Create a user with minimal access rights (only access rights to their own sales orders and invoices). 2. Sign in as that user and create a sales order and confirm it. 3. Create an invoice for that sales order and validate it. 4. Sign in as an administrator and create a duplicate sales order for that sales order, but as
Original PR description
Problem: Some users with limited access rights cannot access invoices they created, after another user duplicates their sales order and invoices it. Steps to reproduce: 1. Create a user with minimal…
Problem: Some users with limited access rights cannot access invoices they created, after another user duplicates their sales order and invoices it. Steps to reproduce: 1. Create a user with minimal access rights (only access rights to their own sales orders and invoices). 2. Sign in as that user and create a sales order and confirm it. 3. Create an invoice for that sales order and validate it. 4. Sign in as an administrator and create a duplicate sales order for that sales order, but assign it to a different user (not the one created in step 1). 5. Confirm the duplicate sales order, create an invoice for it and validate it. 6. Sign in as the user created in step 1 and try to access the invoice created in step 3. 7. Note the access error Cause: When reading an account.move record, the system searches for duplicate moves and adds them to the duplicated_ref_ids field. However, it does not check if the user has read access to those duplicate moves, which leads to access errors when trying to access the main account.move record (which the user has read access to) because the system tries to read the duplicate moves (which the user does not have read access to). opw-6374566 Forward-Port-Of: odoo/odoo#277823 Forward-Port-Of: odoo/odoo#276547
Problem: _select_chart_template ranks generic_coa first when no country is given, but compared t[1]['name'] (the display name) against the template code 'generic_coa'. The comparison never matched, so the sort key was constant and the mapping order was left untouched — whichever localized chart came first in the ORM cache won. Solution: Compare t[0] (the template code) instead so the fallback actually takes effect. --- I confirm I have signed the CLA and read the PR guidelines at www.od
Original PR description
Problem: _select_chart_template ranks generic_coa first when no country is given, but compared t[1]['name'] (the display name) against the template code 'generic_coa'. The comparison never matched, so the sort key was constant and the mapping order was left untouched — whichever localized chart came first in the ORM cache won. Solution: Compare t[0] (the template code) instead so the fallback actually takes effect. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#277991
currently the xpaths are targeting a \<strong\> tag. Those are available in the translations, and can be erased depending on language, user preference, default customization. Once removed you can no longer print invoices with the default report. This fix should make it target the first element of the div instead of the strong, avoiding that conflict and allowing the customer to translate however he feels like. opw-6383047 Description of the issue/feature this PR addresses: Current be
Original PR description
currently the xpaths are targeting a \<strong\> tag. Those are available in the translations, and can be erased depending on language, user preference, default customization. Once removed you can no longer print invoices with the default report. This fix should make it target the first element of the div instead of the strong, avoiding that conflict and allowing the customer to translate however he feels like. opw-6383047 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#277581
**Steps to reproduce:** - Create two companies - Create aliases for each company - Receive a bounced email on the alias of the second company - Recipient of the bounce email will be from the first company **Issue:** `self.env.company` is used in `message_route` for catchall mails without checking if it corresponds to the received domain, making it defaults to the 'main' company instead. **Fix:** Try to find the company of the given mail address using the `'mail.alias.domain'` and app
Original PR description
**Steps to reproduce:** - Create two companies - Create aliases for each company - Receive a bounced email on the alias of the second company - Recipient of the bounce email will be from the first company **Issue:** `self.env.company` is used in `message_route` for catchall mails without checking if it corresponds to the received domain, making it defaults to the 'main' company instead. **Fix:** Try to find the company of the given mail address using the `'mail.alias.domain'` and apply it on the body rendering and `_routing_create_bounce_email` function. similar fix in `account` module: https://github.com/odoo/odoo/commit/b7e0d8914d35af12a96593e484889e48c0613078 opw-5180433 Forward-Port-Of: odoo/odoo#244296
Issue: In "l10n standalone" for l10n_ke, .`test_cogs_kit_multi_steps_first_step_validated` failed. Steps to reproduce: - install `l10_ke_edi_oscu_stock` and `sale_mrp` - run `test_cogs_kit_multi_steps_first_step_validated` Cause: `l10_ke_edi_oscu_stock` override the compute for product `invoice_policy`. Product from Kenyan company or withour company are by default set to invoice on delivery. Therefore, setting a two steps delivery require to validate picking then shipping bef
Original PR description
Issue:
In "l10n standalone" for l10n_ke, .`test_cogs_kit_multi_steps_first_step_validated` failed.
Steps to reproduce:
- install `l10_ke_edi_oscu_stock` and `sale_mrp`
- run `test_cogs_kit_multi_steps_first_step_validated`
Cause:
`l10_ke_edi_oscu_stock` override the compute for product `invoice_policy`. Product from
Kenyan company or withour company are by default set to invoice on delivery. Therefore,
setting a two steps delivery require to validate picking then shipping before invoicing.
As products are not required to be invoiced on delivery by any l10n, it is possible to force
test products to have invoice_policy set to 'order' and not to depend on l10n default value.
runbot-940390
Forward-Port-Of: odoo/odoo#277268Steps to reproduce : - Enable Self-Ordering - Open PoS - Open the Product Info popup for any product. - Toggle the Self-Ordering option (enable or disable). - Singleton Error! Issue : A singleton error occurs when enabling or disabling the Self-Ordering option for a product from the POS Product Info popup. Cause : We never checked whether the config had an active session before loading product data. Fix : Added a check to skip configs that don't have an active session before
Original PR description
Steps to reproduce : - Enable Self-Ordering - Open PoS - Open the Product Info popup for any product. - Toggle the Self-Ordering option (enable or disable). - Singleton Error! Issue : A singleton error occurs when enabling or disabling the Self-Ordering option for a product from the POS Product Info popup. Cause : We never checked whether the config had an active session before loading product data. Fix : Added a check to skip configs that don't have an active session before trying to load product data for them. task - 6348769
Current behavior before PR, [1](https://github.com/odoo/odoo/pull/261837) introduced a rule with higher specificity, overriding the animation-delays of the specific dots in the typing indicator. This caused all dots to jump together at the same time. Desired behavior after PR is merged, the different animation-delays are moved inside the specific rule to correctly apply the delay. Before/After, <img width="125" height="160" alt="bug" src="https://github.com/user-attachments/asset
Original PR description
Current behavior before PR, [1](https://github.com/odoo/odoo/pull/261837) introduced a rule with higher specificity, overriding the animation-delays of the specific dots in the typing indicator. This caused all dots to jump together at the same time. Desired behavior after PR is merged, the different animation-delays are moved inside the specific rule to correctly apply the delay. Before/After, <img width="125" height="160" alt="bug" src="https://github.com/user-attachments/assets/8011fe05-6e78-45d6-aee7-a82b7c9bfdd1" /> <img width="125" height="160" alt="expected" src="https://github.com/user-attachments/assets/f367311f-b9a4-4d18-9be1-ae1e7d059a9a" /> --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#277944
Steps to Reproduce --- - Create a normal parent task with one normal sub-task and one template sub-task. - Open the parent task form view and observe the Sub-tasks stat button count and notebook tab, check the subtask view as well. - Create a template parent task with one normal sub-task and one template sub-task, then repeat the same checks. Issue --- - Task templates are handled like regular subtasks in the subtask count, notebook, and subtask view, without taking the parent task t
Original PR description
Steps to Reproduce --- - Create a normal parent task with one normal sub-task and one template sub-task. - Open the parent task form view and observe the Sub-tasks stat button count and notebook tab,…
Steps to Reproduce --- - Create a normal parent task with one normal sub-task and one template sub-task. - Open the parent task form view and observe the Sub-tasks stat button count and notebook tab, check the subtask view as well. - Create a template parent task with one normal sub-task and one template sub-task, then repeat the same checks. Issue --- - Task templates are handled like regular subtasks in the subtask count, notebook, and subtask view, without taking the parent task type into account. - test_create_project_from_template_with_task_template_without_project creates a template subtask without a project under a regular task. With the child_ids domain only keeping valid template , a template task is no longer included when its parent is not a template. Current Behaviour --- - For a normal parent task, both the normal sub-task and the template sub-task are counted and shown in the opened subtask view and notebook. - For a template parent task, the same filtering is applied, even though template subtasks should remain accessible in that context. Expected Behaviour --- - For a normal parent task, only real sub-tasks should be counted and shown in the subtask view and notebook, and on the project kanban card. - For a template parent task, template subtasks should remain available in the subtask view and notebook according to the parent template context. -In the project kanban card, tasks must not be counted when their parent task is a template, even if the child task itself is not a template. Fix --- - Apply template-aware filtering to subtask counting,project kanban task count and subtask view behavior, depending on whether the parent task is a normal task or a template task. - Update the test so the task template without a project is under task_template_inside_template instead of the regular task. task-5966684 Forward-Port-Of: odoo/odoo#275901 Forward-Port-Of: odoo/odoo#252403
**Problem:** After partially invoicing a timesheet-delivered sale order line, a second invoice for the remaining delivered quantity can no longer be created. **Steps to reproduce:** 1. Install Sales and Timesheets 2. Sell a service invoiced on delivered timesheets 3. Log a timesheet covering the whole period 4. Create an invoice, reduce its quantity to part of the delivered amount, and post it 5. Create an invoice again for the rest **Current behavior:** "Cannot create an invoice. N
Original PR description
**Problem:** After partially invoicing a timesheet-delivered sale order line, a second invoice for the remaining delivered quantity can no longer be created. **Steps to reproduce:** 1. Install Sales…
**Problem:** After partially invoicing a timesheet-delivered sale order line, a second invoice for the remaining delivered quantity can no longer be created. **Steps to reproduce:** 1. Install Sales and Timesheets 2. Sell a service invoiced on delivered timesheets 3. Log a timesheet covering the whole period 4. Create an invoice, reduce its quantity to part of the delivered amount, and post it 5. Create an invoice again for the rest **Current behavior:** "Cannot create an invoice. No items are available to invoice." is raised, even though qty_delivered - qty_invoiced is still positive. **Expected behavior:** A second invoice is created for the remaining delivered quantity. **Cause of the issue:** Since opw-6001094, `_recompute_qty_to_invoice` runs on every invoice creation, not only when a timesheet period is provided. It re-derives `qty_to_invoice` from un-invoiced timesheets alone. Posting the first invoice already linked every timesheet of the line (the linking ignores the invoiced quantity), so no un-invoiced timesheet is left, and `qty_to_invoice` is forced to 0 — discarding the still-billable remainder. **Fix:** Forcing the quantity to zero is only meaningful when the invoice is restricted to a timesheet period, where a line whose timesheets all fall outside that period genuinely has nothing to invoice. Without a period, the standard delivered-versus-invoiced quantity is the authoritative measure of what remains to bill, so the timesheet-based recomputation must not override it. opw-6295941 Forward-Port-Of: odoo/odoo#274677
Steps to reproduce: ------------------------- 1. Install hr_timesheet and create a second company (e.g., Company B). 2. Create a global project (no company assigned) with timesheets enabled. 3. Share the project with edit access to a portal user belonging to Company A.4 4. Create a task, switch to Company B, and log a timesheet on the task. 5. Log in as the portal user and try to access the project. Issue: ------- An `Access to unauthorized or invalid companies exception` is raised,
Original PR description
Steps to reproduce: ------------------------- 1. Install hr_timesheet and create a second company (e.g., Company B). 2. Create a global project (no company assigned) with timesheets enabled. 3. Share…
Steps to reproduce: ------------------------- 1. Install hr_timesheet and create a second company (e.g., Company B). 2. Create a global project (no company assigned) with timesheets enabled. 3. Share the project with edit access to a portal user belonging to Company A.4 4. Create a task, switch to Company B, and log a timesheet on the task. 5. Log in as the portal user and try to access the project. Issue: ------- An `Access to unauthorized or invalid companies exception` is raised, preventing the portal user from accessing a project they are legitimately shared on. Cause: ---------- https://github.com/odoo/odoo/blob/b7b3292b6a46c3dbc17aeee0183df0af318bf810/addons/project/controllers/portal.py#L159-L173 During `_prepare_project_sharing_session_info`, hr_timesheet overrides the company determination logic through `_get_project_sharing_company()`. https://github.com/odoo/odoo/blob/b7b3292b6a46c3dbc17aeee0183df0af318bf810/addons/hr_timesheet/controllers/project.py#L13-L18 For global projects, the company is derived from an existing timesheet if one exists. As a result, creating a timesheet in another company causes that company to be injected into the sharing session as the current company. Since the portal user does not have access to that company, opening the project triggers an access error. Solution: ---------- Remove the `_get_project_sharing_company()` override. The base implementation already falls back to the portal user's own company when the project has no company assigned, ensuring the sharing session only contains companies the portal user is allowed to access. https://github.com/odoo/odoo/blob/b7b3292b6a46c3dbc17aeee0183df0af318bf810/addons/project/controllers/portal.py#L141-L142 This allows portal users from Company A to continue accessing global projects without errors. opw-6253960 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#277640 Forward-Port-Of: odoo/odoo#272161
The test read the field content for the last urgent save right after resolving modifyImagePromise, without waiting for the DOM to actually reflect the new image src. This raced the async update of the editable content, so beforeUnload sometimes ran before the image src were updated, sending stale content and failing intermittently. Wait for the updated image to appear in the DOM before triggering the last beforeUnload, instead of relying on a fixed animationFrame wait. runbot-243773 ---
Original PR description
The test read the field content for the last urgent save right after resolving modifyImagePromise, without waiting for the DOM to actually reflect the new image src. This raced the async update of the editable content, so beforeUnload sometimes ran before the image src were updated, sending stale content and failing intermittently. Wait for the updated image to appear in the DOM before triggering the last beforeUnload, instead of relying on a fixed animationFrame wait. runbot-243773 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#278032
Before this commit, validating transfers of several companies at once could assign a lot of one company to the move lines of another one, because the search for existing lots used a variable left over from a previous loop (the last move line iterated) instead of the company of the group of lines being checked. Steps to reproduce: - in a multi-company database, create a product tracked by lots - create a lot with the same name for that product in each company - create one receipt per compan
Original PR description
Before this commit, validating transfers of several companies at once could assign a lot of one company to the move lines of another one, because the search for existing lots used a variable left…
Before this commit, validating transfers of several companies at once could assign a lot of one company to the move lines of another one, because the search for existing lots used a variable left over from a previous loop (the last move line iterated) instead of the company of the group of lines being checked. Steps to reproduce: - in a multi-company database, create a product tracked by lots - create a lot with the same name for that product in each company - create one receipt per company with that lot name typed in the detailed operations, select both receipts in the Transfers list view and validate them together The lines of one company are linked to the lot of the other company and the validation is blocked by "Incompatible companies on records". When the lot only exists in one of the companies, the search misses it and the validation fails on the lot uniqueness constraint while recreating a lot that already exists. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#277227 Forward-Port-Of: odoo/odoo#276688
The `tax_ids` field on `pos.order.line` is defined with `readonly=True`. When editing a POS order from the backend (e.g. during a return/exchange flow), the `_onchange_product_id` method correctly sets `tax_ids` from the product, and the computed `tax_ids_after_fiscal_position` displays the mapped taxes in the UI. However, because `tax_ids` is readonly, the web client does not include it in the save payload. As a result, the taxes are silently dropped on save and `tax_ids_after_fiscal_position`
Original PR description
The `tax_ids` field on `pos.order.line` is defined with `readonly=True`. When editing a POS order from the backend (e.g. during a return/exchange flow), the `_onchange_product_id` method correctly…
The `tax_ids` field on `pos.order.line` is defined with `readonly=True`. When editing a POS order from the backend (e.g. during a return/exchange flow), the `_onchange_product_id` method correctly sets `tax_ids` from the product, and the computed `tax_ids_after_fiscal_position` displays the mapped taxes in the UI. However, because `tax_ids` is readonly, the web client does not include it in the save payload. As a result, the taxes are silently dropped on save and `tax_ids_after_fiscal_position` recomputes to empty. Steps to reproduce: 1. Create and pay a POS order with a product that has taxes 2. Go to the backend (Point of Sale > Orders) and open that order 3. Initiate a return for the order 4. In the return order, add a new product (exchange scenario) 5. Observe that taxes are correctly shown on the new line 6. Click Save 7. The taxes disappear from the order line The fix adds `force_save="1"` to the `tax_ids` field in both the list and form views of `pos.order.line`, consistent with how `price_subtotal` and `price_subtotal_incl` are already handled in the same views. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#269944 Forward-Port-Of: odoo/odoo#253680
Issue: When an invoice (sales journal) uses "Switzerland" localization and the invoice is issued to a customer outside Switzerland/Liechtenstein, no payment reference is generated. This causes the invoice PDF to hide payment communication and bank account details. Other localizations like Belgian companies, uses Belgian references, the reference is always generated regardless of customer country. Steps to reproduce: - Configure a Swiss company with a QR IBAN bank account - Set the sales
Original PR description
Issue: When an invoice (sales journal) uses "Switzerland" localization and the invoice is issued to a customer outside Switzerland/Liechtenstein, no payment reference is generated. This causes the…
Issue: When an invoice (sales journal) uses "Switzerland" localization and the invoice is issued to a customer outside Switzerland/Liechtenstein, no payment reference is generated. This causes the invoice PDF to hide payment communication and bank account details. Other localizations like Belgian companies, uses Belgian references, the reference is always generated regardless of customer country. Steps to reproduce: - Configure a Swiss company with a QR IBAN bank account - Set the sales journal Communication Standard to Switzerland - Create and confirm an invoice for a non swiss customer (US, BE) - Observe in the pdf and in the other info tab -> no payment reference or payment details Cause: `get_l10n_ch_qrr_number()` was using on `l10n_ch_is_qr_valid()`, which conflicts QR-bill printability (partner country, currency) with payment reference generation. When the customer is outside CH/LI, `l10n_ch_is_qr_valid()` is False and no QRR reference is generated. Solution: Decouple QRR reference generation from QR bill printability. The Swiss communication standard now generates a QRR format reference when a QR-IBAN is configured, regardless of customer's country or currency. opw-6222417 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#272617 Forward-Port-Of: odoo/odoo#266861
There is a flickering when hovering the chart granularity popover. How to reproduce: - open a dashboard with a time-based chart (like the Sales dashboard) - hover it and click on the "Month" button - hover the popover with the granularity suggestions => flickering The issue seems to come from the way Chrome handles the <select> popover as the element is not recognized as a child element of the <select> parent. As such, the pseudo-class `:focus-within` does not work as intended and th
Original PR description
There is a flickering when hovering the chart granularity popover. How to reproduce: - open a dashboard with a time-based chart (like the Sales dashboard) - hover it and click on the "Month" button - hover the popover with the granularity suggestions => flickering The issue seems to come from the way Chrome handles the <select> popover as the element is not recognized as a child element of the <select> parent. As such, the pseudo-class `:focus-within` does not work as intended and the chart menu flickers between a visible/hidden state. As a fix, we rely on another pseudo-class `:open` that applies to the <select> tag, its open state being correctly handled by the browser. Task-6288876 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#274619
Problem: After updating a file name, the link popover still shows the original file name. Cause: The link popover always displays the attachment name instead of the current link content. Solution: Use the link content as the title for the link popover. Steps to reproduce: - Go to To-Do → Create New. - Upload a file. - Change its title. - Observe that the title shown in the link popover still uses the original file name. task-6213840 --- I confirm I have signed the CLA and
Original PR description
Problem: After updating a file name, the link popover still shows the original file name. Cause: The link popover always displays the attachment name instead of the current link content. Solution: Use the link content as the title for the link popover. Steps to reproduce: - Go to To-Do → Create New. - Upload a file. - Change its title. - Observe that the title shown in the link popover still uses the original file name. task-6213840 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#277064 Forward-Port-Of: odoo/odoo#264127
Reverse charge taxes (Inversione Contabile) should have the translated code ending with 'IC' (the acronym), not 'CI'. Suggested by partner: eLBati task-none Forward-Port-Of: odoo/odoo#277892 Forward-Port-Of: odoo/odoo#276270
Original PR description
Reverse charge taxes (Inversione Contabile) should have the translated code ending with 'IC' (the acronym), not 'CI'. Suggested by partner: eLBati task-none Forward-Port-Of: odoo/odoo#277892 Forward-Port-Of: odoo/odoo#276270
When creating an activity in a custom app made with studio, no image is shown, and instead the alt text is shown with a missing image. This fixes the issue by showing a placeholder icon if no module is found for the activity group. opw-6282451 Previous behavior: <img width="1315" height="568" alt="image" src="https://github.com/user-attachments/assets/1e4fc1d5-3a35-4193-80fc-f6d161776e2e" /> New behavior: <img width="1315" height="568" alt="image" src="https://github.com/user-attac
Original PR description
When creating an activity in a custom app made with studio, no image is shown, and instead the alt text is shown with a missing image. This fixes the issue by showing a placeholder icon if no module is found for the activity group. opw-6282451 Previous behavior: <img width="1315" height="568" alt="image" src="https://github.com/user-attachments/assets/1e4fc1d5-3a35-4193-80fc-f6d161776e2e" /> New behavior: <img width="1315" height="568" alt="image" src="https://github.com/user-attachments/assets/6ed5ca8b-8481-470f-b7c6-dd59c616125e" /> (Original PR: https://github.com/odoo/odoo/pull/268957 Re-based on 17.0 as its the earliest version affected, so it can be forward-ported to future versions) Forward-Port-Of: odoo/odoo#269654
### Issue: When sending an invoice to KSEF, the `AdresL1` field in the XML contains the country name for both buyer and seller The KSEF portal already derives the country name from `KodKraju` (country code), causing it to appear twice on portal documents ### Cause: `_display_address` uses the default PL `address_format` which includes `%(country_name)s` The format is not overridden for the FA3 XML export context, so the country name is always appended to `AdresL1` ### Steps to reproduc
Original PR description
### Issue: When sending an invoice to KSEF, the `AdresL1` field in the XML contains the country name for both buyer and seller The KSEF portal already derives the country name from `KodKraju` (country code), causing it to appear twice on portal documents ### Cause: `_display_address` uses the default PL `address_format` which includes `%(country_name)s` The format is not overridden for the FA3 XML export context, so the country name is always appended to `AdresL1` ### Steps to reproduce: - Install `l10n_pl_edi` - Configure KSEF (see video on the ticket) - Create and send an invoice to KSEF - Check `AdresL1` in the generated XML Before the fix, `AdresL1` includes the country name The KSEF portal also shows the country name twice for both buyer and seller opw-6369708 Forward-Port-Of: odoo/odoo#275922
Steps to reproduce the bug: - Have a database with sale_management installed and at least two companies (Company 1 and Company 2) - Confirm sale orders with storable products under each company - Install the stock module (which triggers sale_stock as a bridge module) Problem: The installation raised a RedirectWarning ("Please create a warehouse for company 2") and aborted. During sale_stock installation, _init_column initialises the new `warehouse_id` column on `sale.order` via SQL. Ord
Original PR description
Steps to reproduce the bug:
- Have a database with sale_management installed and at least two companies (Company 1 and Company 2)
- Confirm sale orders with storable products under each company
- Install the stock module (which triggers sale_stock as a bridge module)
Problem:
The installation raised a RedirectWarning ("Please create a warehouse for company 2") and aborted. During sale_stock installation, _init_column initialises the new `warehouse_id` column on `sale.order` via SQL. Orders belonging to companies that have no warehouse yet (company 2, since `create_missing_warehouse` only creates one for the first company at that point) remain NULL. The stored-field recompute then calls write(), which fires _check_warehouse. That constraint calls _warehouse_redirect_warning() for each company without a warehouse, raising a RedirectWarning that aborts the install.
opw-6302537
Forward-Port-Of: odoo/odoo#270962
Forward-Port-Of: odoo/odoo#270480Test "clicking after the link's text content" can sporadically fail because the presence of the `o_link_in_selection` class might be checked too early. [1] This commit waits for the expected change to avoid this issue. [1]: https://runbot.odoo.com/runbot/build/118180973 runbot-944288
Original PR description
Test "clicking after the link's text content" can sporadically fail because the presence of the `o_link_in_selection` class might be checked too early. [1] This commit waits for the expected change to avoid this issue. [1]: https://runbot.odoo.com/runbot/build/118180973 runbot-944288
**PROBLEM** In some cases, third party checks are marked as being "on hand" but they are not. **CAUSE** We retrieve the last operation (accounting.payment) related to the check to determine the current journal of the check. To do this, we order the payment by date, then by write_date, and then by id. If the incoming and outgoing payment are done the same day, the last operation taken into account will be the one with the freshest write_date. If the incoming payment is modified, we wrongly c
Original PR description
**PROBLEM** In some cases, third party checks are marked as being "on hand" but they are not. **CAUSE** We retrieve the last operation (accounting.payment) related to the check to determine the current journal of the check. To do this, we order the payment by date, then by write_date, and then by id. If the incoming and outgoing payment are done the same day, the last operation taken into account will be the one with the freshest write_date. If the incoming payment is modified, we wrongly consider it as the last operation, assigning a journal to the check. **FIX** We check if there is more incoming operations than outgoing operations. If it's not the case, then the check is not on hand, so we remove the current journal. opw-6277377 Forward-Port-Of: odoo/odoo#275866
**Description of the issue/feature this PR addresses:** [FIX] account: prevent access error for branch users When a user restricted to a branch company opens the accounting dashboard, they may encounter an AccessError preventing the app from loading. This occurs because the dashboard logic attempts to read the `fiscalyear_lock_date` from the journal's company. In a branch setup, this configuration often belongs to the parent company, which the user typically does not have read acc
Original PR description
**Description of the issue/feature this PR addresses:** [FIX] account: prevent access error for branch users When a user restricted to a branch company opens the accounting dashboard, they may…
**Description of the issue/feature this PR addresses:** [FIX] account: prevent access error for branch users When a user restricted to a branch company opens the accounting dashboard, they may encounter an AccessError preventing the app from loading. This occurs because the dashboard logic attempts to read the `fiscalyear_lock_date` from the journal's company. In a branch setup, this configuration often belongs to the parent company, which the user typically does not have read access to. The system then blocks the action and gives an AccessError. This commit resolves the issue by adding `.sudo()` when reading the `fiscalyear_lock_date`. This safely bypasses the record rule restriction, allowing the dashboard to fetch the necessary accounting configuration without requiring the user to have broad access to the parent company. **Steps to reproduce:** - As Mitchell Admin: - Settings > Users & Companies > Companies > My Company (San Francisco) > Branches > create a branch - Settings > Users & Companies > Users > Marc Demo > Access Rights > change “Companies” and “Default Company” to only the newly created branch - As Marc Demo: - Attempt to access Accounting app > observe Access Error **Current behavior before PR:** - Users belonging to only a branch company are unable to access the Accounting dashboard **Desired behavior after PR is merged:** - Users belonging to only a branch company are able to access the Accounting dashboard opw-6369616 Forward-Port-Of: odoo/odoo#277877
Documentation and clarification updates
Signing the Odoo Individual Contributor License Agreement v1.0. Adds `doc/cla/individual/dsonnet.md`. --- I confirm I have read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#270526
Original PR description
Signing the Odoo Individual Contributor License Agreement v1.0. Adds `doc/cla/individual/dsonnet.md`. --- I confirm I have read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#270526
Adds Corvanis corporate CLA entry so legal/cla can validate contributions from Corvanis contributors. This change only adds: - doc/cla/corporate/corvanis.md - No functional code changes. Forward-Port-Of: odoo/odoo#276949
Original PR description
Adds Corvanis corporate CLA entry so legal/cla can validate contributions from Corvanis contributors. This change only adds: - doc/cla/corporate/corvanis.md - No functional code changes. Forward-Port-Of: odoo/odoo#276949