Thursday, July 3, 2025
35 changes · saas-18.4
Enhancements to existing features
Live chat conversations now show the expertise or qualifications that caused them to be routed to a specific agent. This helps agents understand the context behind each handoff and supports better reporting on chat assignment decisions.
Original PR description
provide a way for the agent to understand why the conversation was forwarded to them based on their qualifications; also useful for the reporting task-4889092 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Live chat operators can now see a visitor's recent conversations, making it easier to handle follow-up questions and give consistent answers. This history also helps teams spot repeated misuse or spam patterns from the same visitor.
Original PR description
visitors sometimes ask follow-up questions or want to have a refresher on the information they got from a previous conversation; also allows us to identify visitors who might have been abusing/spamming the live chat. task-4889093 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Uruguayan electronic invoices now send the mandatory item name consistently and avoid duplicating product names in generated PDF reports. Longer product names and extra descriptions are split into the correct fields for DGI, improving invoice readability and compliance with field limits.
Original PR description
This PR aims to improve the way we create NomItem and DscItem lines on the XML files we send to DGI in order to generate the PDF report. We have two fields to inform to DGI in an electronic invoice,…
This PR aims to improve the way we create NomItem and DscItem lines on the XML files we send to DGI in order to generate the PDF report. We have two fields to inform to DGI in an electronic invoice, NomItem which is mandatory an has a maximum of 80 characters to send, and DscItem that is optional an has a limit of 1000 chars. So we ensure NomItem is always sent, and the description will be filled like this: First, if the product name is longer than 80 chars, DscItem field will contain the characters that didn't fit in the NomItem field (characters from the 80th) Then it will contain the description of the product and the addenda content if it exists. Plus, I refactor the method _l10n_uy_edi_cfe_D_global_discount so it is also aligned with what I mentioned before. Another reason for this improvement is that, as the description of a product contains the product name at the beginning, we faced some issues when a user added a description on the fly in the line of the product, and then confirmed and printed the report. In this case, the name of the product was duplicated in the report. With this change, the description will only contain the the part of the product name that exceeds the 80th character. Example:  Forward-Port-Of: odoo/enterprise#80993
US payroll now includes additional state-specific employer tax and surcharge rates for Alabama, Colorado, and Washington. This helps payroll calculations better reflect current local requirements and improves accuracy for affected employees and companies.
Original PR description
Added salary rules for state: - US: Alabama ESA rate - US: Colorado Support Surcharge rate - US: Colorado Solvency Surcharge rate - US: Washington EAF Rate task-4814709 Forward-Port-Of: odoo/enterprise#87708
Starshipit shipping labels no longer block order processing when the final shipping cost is not immediately available. Odoo temporarily records a zero cost, then automatically retrieves the final amount later and updates the delivery order and related sales order line, improving reliability and billing accuracy.
Original PR description
**Description of the issue/feature this PR addresses:** This PR enhances the Starshipit integration to reliably handle scenarios where the exact shipping cost is not immediately available from…
**Description of the issue/feature this PR addresses:** This PR enhances the Starshipit integration to reliably handle scenarios where the exact shipping cost is not immediately available from Starshipit after label creation. Cost is fetched via a cron job and correctly applied to both the stock.picking's carrier_price and, crucially, the corresponding Sales Order delivery line. First commit removes the 3-tries loop, and was already reviewed on this [PR](https://github.com/odoo/enterprise/pull/85088). **Current behavior before PR:** When confirming a picking with a Starshipit Delivery method, the exact Shipping cost was not instantly available. The previous code had 3 attempts to retrieve it, before stopping the process, asking the user to try at a later time. **Desired behavior after PR is merged:** The price fetching becomes non-blocking. If Starshipit did not return an immediate `total_shipping_price`, a temporary price of 0.0 will be used. A Cron job will then run on all pickings with a 0.0 carrier price in order to fetch the exact price from Starshipit, and update the SO delivery lines. opw-4748113 When merging on `master`, further improvement might be to introduce a `starshipit_pending_price` boolean field instead of running the CRON job on all 0.0 carrier price pickings. With the new view `view_picking_form_inherit_stock` being introduced, runbot tests fail when migrating to saas-18.1. (Because view is not yet present in the saas-18.1 codebase) **How to test?** - On a runbot DB, install the `delivery_starshipit` module - Configure the DB to interact with the connector - Place a Sales Order with a delivery method configured to use Starshipit. - Confirm the Delivery. The shipping price, if not available, will be temporarily set to 0.0. - Run the Cron Job manually. You can check and activate the Cron by navigating to Settings > Technical > Automation > Scheduled Actions. - Check that the SO has been updated with the actual shipping price from Starshipit. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/enterprise#89184 Forward-Port-Of: odoo/enterprise#86383
Resolved issues and error corrections
Sales orders that create projects from templates now reuse the correct analytic account instead of creating unnecessary extra accounts. This keeps project accounting consistent and also ensures a needed account is created when a timesheet-enabled template becomes a regular project.
Original PR description
Prior to this commit, when an SO containing products configured to generate projects based on project templates was confirmed, it would generate one analytic account per generated project. Which is not consistent with the previous behavior. It was due to the fact that in 'hr_timesheet' module, we always created a new analytic account each time a new project is created from a project template, even if an analytic account is already passed in the create values or if the project template was not timesheetable. Also, when converting a project template having timesheets enabled and no account_id set to a regular project, it did not create a new analytic account, this is now fixed. version-18.4 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Fixes a website editor issue where editing or adding content inside a block could accidentally stop the parent block's behavior and prevent it from restarting. This improves reliability when building pages, especially for dynamic blocks like blog posts and floating blocks.
Original PR description
Since [1] interactions are stopped when a child element is edited. This causes issues such as not being restarted (e.g. a blog posts block is stopped right after drop when its content gets added to the DOM) - never to be restarted. This commit adapts the condition to make interactions opt-in for that feature, by implementing `isImpactedBy` in addition to `shouldStop`, and restricting this behavior to the restarting of interactions (not plain stop). Additionally, this commit also fixes the floating block's Add Card action missing id, and puts some renders into `start` rather that `setup`. [1]: https://github.com/odoo/odoo/commit/7240e2dccc441d61937bd5cebfa559dd2eb529d2 task-4367641
This fixes how deferred accounting entries are handled when an invoice is reset to draft with Audit Trail enabled. Posted deferred entries are now cancelled as intended instead of being reversed, keeping accounting records consistent with audit-trail rules.
Original PR description
**Steps to reproduce:** - Install accountant - In Accounting settings, activate "Audit Trail" - Create an invoice: * Customer: [any] * Invoice Lines: - Product: [any] - Start Date: [2 months ago] -…
**Steps to reproduce:**
- Install accountant
- In Accounting settings, activate "Audit Trail"
- Create an invoice:
* Customer: [any]
* Invoice Lines:
- Product: [any]
- Start Date: [2 months ago]
- End Date: [2 months later]
- Confirm the invoice
=> Deferred Entries are created. Posted for the previous months and in draft for the future ones.
- Reset the invoice to draft
**Issue:**
The draft entires are correctly unlinked, but the posted ones are reversed instead of being cancelled.
**Cause:**
This fix https://github.com/odoo/odoo/commit/cc448bf77aa3d11e634e6bab6da1690a1b67a723 is supposed to cancel the deferred entries when the move is protected by the audi trail.
However we never get into the `elif move._is_protected_by_audit_trail():` branch because its condition is also included in the previous `if not move._can_be_unlinked():` branch.
Linked enterprise PR (test): https://github.com/odoo/enterprise/pull/88992
opw-4891975
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#217228
Forward-Port-Of: odoo/odoo#216628Customers using the QR code self-invoice flow in Point of Sale can now update existing customer records with the details they enter, such as VAT information. This prevents staff from having to manually correct customer data later and keeps invoice information accurate.
Original PR description
When doing a self invoice with the QR code on the PoS receipt, if a partner was linked to the order, the record would not be updated with the values entered in the self invoice form. Steps to reproduce: ------------------- * Enable the self service invoice feature in the PoS settings. * Open a PoS session. * Make and order with a partner set on it. * Finalize the order and scan the QRCode on the receipt. * Fill the form with some new informations (like a new VAT number) > Observation: Check the partner on the backend, the values are not updated. Why the fix: ------------ We update all the mandatory and optionnal fields of the partner record with the values entered in the self invoice form. opw-4676244 Forward-Port-Of: odoo/odoo#216956 Forward-Port-Of: odoo/odoo#214552
Users opening records from a company branch that was not currently selected no longer hit an error page. Odoo now correctly identifies and activates the relevant company or branch, making multi-company navigation more reliable.
Original PR description
When we get an access error due to multi-company rules, odoo will try to set the appropriate company in the company switcher. If any company has branches, these will also be set. However, currently, if we have multiple branches and we try to access a record that belongs to any branch but the last one, we get a traceback. Steps to reproduce: 1. Create 2 branches of a company 2. Create an employee in the first branch (copy the link to employee) 3. Uncheck the branches in the company selector 4. Try to access the employee created in step 2 via a link > Traceback This is because we are trying to access an index that is out of range of `allowedCompanies`. To fix this, we use `find()` to find the appropriate company by its id. opw-4846979 Forward-Port-Of: odoo/odoo#216162 Forward-Port-Of: odoo/odoo#215554
Point of Sale invoice creation now handles selected orders from different salespeople without crashing. This lets teams create invoices in bulk for the same customer more reliably, even when orders were handled by multiple users.
Original PR description
The error occurred because multiple POS orders with different `user_id` were grouped together for invoice creation, and the code attempted to access `self.user_id.id`, which expects a single record…
The error occurred because multiple POS orders with different `user_id` were grouped together for invoice creation, and the code attempted to access `self.user_id.id`, which expects a single record but received multiple (`res.users(1, 2)`). Steps to Replicate: - Open any POS shop (Ex: Furniture Shop) and select a Customer. - Add any item to the order and complete the order. - Close the session, go to Backend and open POS orders. - Make sure the states of the orders are all in `to invoice` state, and check that salesperson should not be all the same (atleast one salesperson should be different and the customer should be same). - Select all the Orders, click `Create Invoices` and click Create and see the error. Error: `ValueError: Expected singleton: res.users(1, 2)` Solution: - Solved the error by grouping the POS orders by both `user_id` and `fiscal_position_id`, ensuring each group contains orders from only one user, which prevents the singleton error when accessing `user_id.id` during invoice creation. sentry-6590469396 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#208833
This change prevents errors when creating records that need an email alias, such as projects, in multi-company databases where one company has no domain set. Odoo now correctly treats the missing domain as empty instead of incorrectly reusing another company's domain, avoiding setup failures.
Original PR description
Before this commit, creating a mail alias mixin (typically a project) with an unspecified domain in a multi-company setup could lead to access errors "We could not create alias Inactive Alias because domain <client domain> belongs to company <company 1> while the owner document belongs to company <company 2>" Steps to reproduce: 1. Start with a clean DB 2. install an app that uses mail (e.g. CRM or Project) 3. Create a second company 4. Set a domain for the 1st company (the one created by default) 5. Erase the domain of the second company (the one created at step 3) 6. Try to install the Field Service app After this commit, not specifying the domain gets correctly interpreted and a default None value is used. opw-4051655 Forward-Port-Of: odoo/odoo#173999
Landed costs are now allocated only to the quantities still in stock for each lot or serial number. This prevents sold-out lots from receiving extra value and keeps inventory valuation accurate after remaining products are sold.
Original PR description
**Problem:** the split of the landed cost between lots doesn't take into account if a lot has no quantity left or if it has less than it's initial quantity **Steps to reproduce:** - enable the "lot &…
**Problem:** the split of the landed cost between lots doesn't take into account if a lot has no quantity left or if it has less than it's initial quantity **Steps to reproduce:** - enable the "lot & Serial Numbers" and "landed costs" settings - create a storable product, tracked by lot - in general information activate "valuation by Lot/Serial Number" - select FIFO as the category - create a request for quotation for this product for a quantity of 5 and a unit price of 10.000 - confirm and click on the receipt smart button - on the move line click on the Lots/serial number widget on the right - create 4 lots (L1 with 1 units, L2 with 2 units, L3 and L4 with 1) - save and validate the picking - create a sale order for a quantity of 2 of this product, confirm it and validate the picking - create a new service product, in "purchase" check "is a landed cost" - open accounting/vendors/bills, create a new one for the same vendor as the purhase order - add a line with the landed cost and a price of 5000 (quantity of 1) - set a bill date and save - clik on "create landed costs" - in the "transfers" field write the refernce of the receipt of the PO - open inventory/reporting/valuation and type your product in the search bar **Current behavior:** 4 lines were created : a line of 600 for L1 a line of 1200 for L2 a line of 600 for L3 a line of 600 for L4 an additional issue, is that if we now sell the 3 remaining quantity and search our product in inventory/reporting/valuation the quantity will be zero but total value will be 600 **Expected behavior:** the spliting should adapt to the remaining quantities like it does when lots are not involved (for instance when there is a landed cost linked to a PO with a quantity of 5 but only 4 of those products are still in stock the value of the landed cost valuation line linked to this product is 4/5 of the landed cost) So here it should be : no line for L1 (no remaining quantity in L1) a line of 1000 for L2 (only 1 remaining, so a third of the 3000 (3/5 * 5000)) a line of 1000 for L3 a line of 1000 for l4 **Cause of the issue:** the quantity used is the one of the initial stock move line so it doesn't take into account the current number of product in the lot opw-4828963 Forward-Port-Of: odoo/odoo#216437 Forward-Port-Of: odoo/odoo#215521
Barcode receiving now correctly leaves unreceived items open when only part of a purchase delivery is validated. This prevents remaining products from being incorrectly marked as received, improving inventory accuracy for subcontracted purchase flows.
Original PR description
Issue ----- In barcode processing reception of subcontracted products doesn't create a back order for the remaining products. Steps to reproduce ----- - Create 2 products, one subcontracted and one…
Issue ----- In barcode processing reception of subcontracted products doesn't create a back order for the remaining products. Steps to reproduce ----- - Create 2 products, one subcontracted and one storable - Create a purchase order for the 2 products & confirm it - Go to barcode and open the delivery - Only validate the reception of the subcontracted product --> No backorder is created for the remaining product, it is considered received Cause ----- Commit db8b33e changed the compute of the move's picked status to not update for subcontracted moves. So the move line has picked set to True but not the move itself. When we validate the operation in barcode, we go through this pre hook https://github.com/odoo/odoo/blob/1d256123da587d625c0527ca3a18cd82e7161df5/addons/stock/models/stock_picking.py#L1193 Since the move has a quantity but picked is still False, the full picking is being picked at once https://github.com/odoo/odoo/blob/1d256123da587d625c0527ca3a18cd82e7161df5/addons/stock/models/stock_picking.py#L1206-L1207 ----- Ticket: opw-4726229 Forward-Port-Of: odoo/odoo#216566 Forward-Port-Of: odoo/odoo#212687
Point of Sale now keeps the selected ship-later date unchanged for users in affected time zones. This prevents orders from being scheduled one day earlier than intended, reducing delivery mistakes and customer confusion.
Original PR description
This is a fix to the bug when a shipping date in picked in specific timezones, the previous day is set. The steps to reproduce: 1- Setup a database with point_of_sale app installed 2- In configuration -> Setting, check Allow Ship Later option for a pos shop. 3- Change the browser timezone to a US timezone. In chrome it can be in Console -> Sensors -> Location. 4- Open POS register, select a product, choose payment and use Ship Later, to pick a date. 5- The previous day is picked which is the bug. The reason is that the shippingDate is parsed into shipping_date which is an object. We now manually deserialize and serialize the date to avoid automatic timezone handling. opw-4853757 Forward-Port-Of: odoo/odoo#216980 Forward-Port-Of: odoo/odoo#215140
This fix prevents checkout errors when a website has delivery methods tied to different companies or no company at all. Customers can now select valid delivery options more reliably, reducing failed orders caused by company assignment mismatches.
Original PR description
Description of the issue/feature this PR addresses: Error during checkout when using delivery methods with mixed company assignments. Current behavior before PR: If you create a delivery method assigned to company X, and then create another without a company (i.e., assigned to the website company or left empty), the checkout process fails when trying to select a delivery method. Steps to reproduce: 1. Create a delivery method and assign it to company X. 2. Create another delivery method with no company or assign it to the website's company. 3. Go to the website and try to place an order. 4. The checkout will fail when selecting the delivery method. Desired behavior after PR is merged: Checkout handles delivery methods consistently, even when companies are mixed or missing. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#216917 Forward-Port-Of: odoo/odoo#216515
This fixes a website form issue where fields meant to appear only for specific dropdown choices stayed visible all the time. Businesses can now rely on conditional form questions to show or hide correctly based on a visitor's selection, reducing confusion and improving data collection.
Original PR description
Problem:
After (https://github.com/odoo/odoo/commit/82fac504803fd17520a1289eb1e38bc7662c54a2), in a form, if a field is set to be visible only when another select field has a specific value (e.g., "x"), that field remains always visible regardless of the selected value.
Cause:
`isFieldVisible` evaluates visibility using the form's default values. This happens because `getFormDataIncludingDisabledFields` returns a cloned form, and cloning a form does not preserve field values.
Solution:
Remove disabled attribute from the `formEl` fields and create
`FormData` then revert the changes.
Steps to reproduce:
- Add a form
- Change a field ("A") type to selection
- Set another field ("B") to be visible only when "A" has a specific value
- Save
- Change the selection to a value that should hide "B"
> "B" remains visible
opw-4874379
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#216787Fixes an error that occurred when converting multiple duplicated CRM leads into opportunities with deduplication enabled. Sales teams can now process duplicate leads in bulk without the workflow failing due to records already merged or removed.
Original PR description
Currently, when mass converting leads that contain duplicates, you are met with an error. ### Steps to reproduce * Install `crm` * Activate leads in CRM settings * Pick a lead in the list of leads…
Currently, when mass converting leads that contain duplicates, you are met with an error. ### Steps to reproduce * Install `crm` * Activate leads in CRM settings * Pick a lead in the list of leads and duplicate it * Select both the original and the duplicate leads → Action → Convert to Opportunity * In the wizard, ensure that "Apply deduplication" is enabled You will be met with the following error message: ``` Missing Record Record does not exist or has been deleted. (Record: crm.lead(...), User: ...) ``` ### Cause When mass converting leads with "Apply deduplication" enabled, the system processes each selected lead and attempts to deduplicate it by merging it with matching leads and deleting the duplicates. However, if one of the selected leads is also identified as a duplicate and gets deleted earlier in the loop, the process fails when it later tries to access the already-deleted lead. Although logic to skip already processed leads exists, there's a small mistake: it compares the lead record (`lead`) to a set of IDs (`merged_lead_ids`), which always fails. opw-4893775 Forward-Port-Of: odoo/odoo#216527
Vendor credit notes used to create landed costs will now keep their refund amount as negative. This prevents inventory value from being overstated when a vendor bill is refunded and the related landed cost is applied.
Original PR description
Before this PR, creating a landed cost in the following scenario incorrectly increased the stock valuation instead of reducing it: - Create a Purchase Order with a valuated product and a landed cost…
Before this PR, creating a landed cost in the following scenario incorrectly increased the stock valuation instead of reducing it: - Create a Purchase Order with a valuated product and a landed cost product in the order lines. - Validate the receipt of the PO. - Create the vendor bill from the PO and confirm it. - Create a landed cost from the vendor bill by clicking "CREATE LANDED COSTS" and selecting the receipt in the landed cost. - Validate the landed cost. - Create a credit note from the vendor bill. - Create a landed cost from the credit note by clicking "CREATE LANDED COSTS" and selecting the same receipt. - Validate the landed cost. In this scenario, the refund amount is treated as a positive landed cost, causing the stock valuation to increase again. This can lead to the landed cost being applied twice by mistake, overstating inventory value. After this PR, the landed cost line amounts for credit notes are correctly set as negative, which reduces the stock valuation instead of increasing it. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr OPW #4844792 @qrtl QT5401 Forward-Port-Of: odoo/odoo#216602 Forward-Port-Of: odoo/odoo#212669
This fix allows administrators to create public holidays even when they overlap with an existing time-off request date range. It prevents an unnecessary blocking error, making holiday setup smoother and avoiding administrative delays.
Original PR description
## Steps to Reproduce: - Create a new time-off request for a specific date range using the admin panel. - Try creating public holidays that overlap with the selected date range. ## Fix: - To resolve the above issue, we will pass a context variable to skip the thrown error. Task: 4770292 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#208558
This fix stops users from using online payment methods when processing refunds from the backend, a flow that is not supported. It prevents refund payments from creating issues that can block closing a Point of Sale session.
Original PR description
**Problem:** When refunding an order that has been done in the frontend from the backend, then when trying to pay for it again using an online payment method, it will currently work. The problem is…
**Problem:** When refunding an order that has been done in the frontend from the backend, then when trying to pay for it again using an online payment method, it will currently work. The problem is that doing this will prevent the user from closing their session afterwards. The issue is that refunding through online payment method is not supported but is going though either way. **Steps to reproduce:** - Have an online payment method. - Go to your POS session and make a purchase, pay for it in cash. - Go back to the backend, to orders and chose your order. - Return the products and click payment to pay for it again. - Chose your online payment method and make the payment. - Try to close your POS session, an error prevents you from doing so. **Why the fix:** The problem is that an error should be thrown when trying to pay the refund with an online payment method. But this error is never reached. It was reached before this commit https://github.com/odoo-dev/odoo/commit/2dce0f22e92299b17162343e3629dcdab8a697b5 This commit is fixing an error that has since been avoided by this commit https://github.com/odoo-dev/odoo/commit/0c8f0d730465028657ff8da28e7ab14e2df08f69 The use case does not even go through the fixed *create* function anymore, so there should be no problem reverting the fix. Before said commit, we set the *online_account_payment_id* whether it exists or not. This then allows us to check if one of them is None later on. If it is, it means we can't create the online payment, as we can't create one without an accounting payment. After said commit, we didn't add it if the accounting payment didn't exist, so the error was never thrown as the code couldn't be reached. opw-4815049 Forward-Port-Of: odoo/odoo#213117
Odoo now handles email-based conversations on records more reliably by preserving external recipients in replies and including the original author when needed. It also removes internal aliases from displayed recipient lists, reducing confusion and making reply-all behavior match normal email expectations.
Original PR description
Purpose Improve email to email discussions, aka discussion on Odoo records between people using emails. See individual commit for more details. * be sure to include external recipients in email headers * be sure to include author when they are not followers * avoid adding aliases as external recipients Task-4873049 Forward-Port-Of: odoo/odoo#215410
When Indian e-invoicing is added after an invoice PDF was already created, Odoo now regenerates the PDF instead of reusing the old version. This ensures the official IRN section appears correctly on the invoice sent to customers.
Original PR description
Steps To Regenerate - Make a customer invoice along with E-invoicing feature on and any valid tax. - When sending invoice without selecting E-invoicing, creates a normal PDF without IRN. - If later E-invoicing was selected for the same and sent, it still reused the old existing PDF without updating the IRN section. In this commit The old generated invoice PDF is cleared so that a new one is generated with IRN and the invoice record is updated accordingly. taskId-4844613 Forward-Port-Of: odoo/odoo#213490
Point of Sale now ignores loyalty programs that have already reached their usage limit, preventing customers from seeing points they cannot earn and avoiding creation of empty loyalty cards. The loyalty program screen also shows current usage next to the limit, making it clearer when a program has been fully used.
Original PR description
Currently, loyalty cards with 0 points are being created for programs that have exceeded their max usage. Loyalty points are also erroneously being displayed for usage-exceeded programs when the tab…
Currently, loyalty cards with 0 points are being created for programs that have exceeded their max usage. Loyalty points are also erroneously being displayed for usage-exceeded programs when the tab is opened for the first time. And, it is not clear to the user when the max usage has been exceeded. Steps to reproduce ----- 1. Create a loyalty program with a limited usage 2. Validate orders with the program up to the max usage 3. Refresh the tab and start another order with a new customer 4. Won points are still being displayed in the left pane 5. Validate the order, a loyalty card with 0 points is created Cause ----- Programs over the max usage are not being filtered out. Fix ----- Apply similar logic from https://github.com/odoo/odoo/pull/208134 and filter out programs over the max usage in `_get_program_ids()` Also, add the `total_order_count` to the form view next to `max_usage` so that it is clear that when the max usage is hit.  opw-4744372 Forward-Port-Of: odoo/odoo#212239 Forward-Port-Of: odoo/odoo#210507
Restaurant preparation tickets were sometimes printed without saying which course had been fired, leaving kitchen staff without clear instructions. This fix ensures the ticket includes the course number and adds automated checks so the issue does not return.
Original PR description
- Since this PR (https://github.com/odoo/odoo/pull/212490), when clicking `Fire course` in restaurant generate empty preparation ticket. This commit fix this issue by ensuring the preparation ticket…
- Since this PR (https://github.com/odoo/odoo/pull/212490), when clicking `Fire course` in restaurant generate empty preparation ticket. This commit fix this issue by ensuring the preparation ticket contains "Course x fired".
- Improve `preparation_receipt_util` to generate preparation receipt as close as the one we generate with a real printer.
- Add test to make sure the preparation ticket contains the course that is being fired.
Steps to reproduce:
- Configure a preparation printer linked to your pos.config
- Open POS
- Open a table
- Add items, organized by courses
- Click on order btn
- The whole order is sent to the kitchen (good)
- Go back on the table, click on 'fire course' btn
- The preparation printer prints a ticket to warn the kitchen that they need to prepare the next course but it does not contain the course number that is being fired
task-id: 4897844
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#216227Stock transfers now keep their original source reference when items from different replenishment orders are grouped together. Instead of removing the source information, the system adds the additional reference so warehouse teams retain clearer traceability.
Original PR description
**Current behavior:** During the assignment of a picking, if any of its moves have an origin that does not match its own, the origin will be cleared altogether. **Expected behavior:** The different…
**Current behavior:** During the assignment of a picking, if any of its moves have an origin that does not match its own, the origin will be cleared altogether. **Expected behavior:** The different origin should be appended to the existing origin string (as is done in batch replenishment, for example). **Steps to reproduce:** 1. Create 2 products, create a secondary warehouse 2. Create an orderpoint for each product, make the route on both of them the (first?) pointed to by `resupply_route_ids` on the primary warehouse 3. Set `qty_to_order` 1 on each of the orderpoints, and one at a time click the 'Order' button 4. The move generated for each replenishment action will ultimately be added to a single picking -> in the end see that its `origin` field is cleared **Cause of the issue:** We currently decide to clear the picking origin during assignment if any of its moves have a different origin. **Fix:** Instead, append the different origin string to the picking. opw-4749519 Forward-Port-Of: odoo/odoo#212674
This fix prevents saved image size values from being forced back when editing email template content. Users can now resize an image back to its default size without the editor unexpectedly keeping the previous dimensions.
Original PR description
Problem: When resized images (e.g., with `style.width: 50%`) are processed by `convert_inline`, `width` and `height` attributes may be added for email client compatibility. These attributes override resizing changes, forcing the last saved dimensions and preventing fallback to the image's default size. Solution: Remove `width` and `height` attributes from the content inserted into the editor. They will be correctly re-applied on save if needed. Steps to reproduce: - Create a new email template - Add an image - Resize the image to 100% - Save - Resize the image back to default - The image keeps the 100% size opw-4863515 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#213786
When a new Argentine company is created, Odoo will now install the more commonly used Responsable Inscripto chart of accounts by default instead of the less common Monotributista option. This reduces setup mistakes and better matches typical Argentine business needs.
Original PR description
### Description of the issue/feature this PR addresses: Odoo will try to auto install a Coa when creating a database or creating a new company where country is defined The problem is that in…
### Description of the issue/feature this PR addresses: Odoo will try to auto install a Coa when creating a database or creating a new company where country is defined The problem is that in Argentina we have different CoA depending on the AFIP Responsibility, and the one that is currently installed by default is the 'ar_base' (Responsable Monotributista): the less used one. In this case we prefer to do not install any CoA and let the user to install it manually (as it was working in older versions, but it is not possible). For that reason we made this change force to install 'ar_ri' (Responsable Inscripto) CoA by default instead ### Current behavior before PR: 1. Create a new company with country AR 2. Will automatically install the "Responsable Monotributista" Coa ### Desired behavior after PR is merged: Now will install the "Responsable Inscripto" Coa --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#215916
Fixes an issue where GSTR-2B JSON files attached during bill creation were not properly linked to the new bills. Bookkeepers can now open these attachments without encountering a 404 error, improving reliability during GST reconciliation.
Original PR description
**Before this PR:** - The GSTR-2B JSON was attached to the message but not linked to the newly created bills (`res_id` was not set). - As a result, when a Bookkeeper user created a new GSTR-2B bill and tried to open the attachment, it raised a 404 error: `"The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again."` **After this PR:** - The issue is resolved. - During GSTR-2B matching, unattached message attachments are now properly linked to the newly created bills by updating their res_model and res_id fields. Task ID : 4831758 Forward-Port-Of: odoo/enterprise#89250 Forward-Port-Of: odoo/enterprise#86785
Barcode receipt validation now correctly leaves unreceived items open when only subcontracted products are processed. This prevents remaining products on the purchase receipt from being incorrectly marked as received, improving inventory accuracy and follow-up purchasing operations.
Original PR description
Issue ----- In barcode processing reception of subcontracted products doesn't create a back order for the remaining products. Steps to reproduce ----- - Create 2 products, one subcontracted and one…
Issue ----- In barcode processing reception of subcontracted products doesn't create a back order for the remaining products. Steps to reproduce ----- - Create 2 products, one subcontracted and one storable - Create a purchase order for the 2 products & confirm it - Go to barcode and open the delivery - Only validate the reception of the subcontracted product --> No backorder is created for the remaining product, it is considered received Cause ----- Commit db8b33e changed the compute of the move's picked status to not update for subcontracted moves. So the move line has picked set to True but not the move itself. When we validate the operation in barcode, we go through this pre hook https://github.com/odoo/odoo/blob/1d256123da587d625c0527ca3a18cd82e7161df5/addons/stock/models/stock_picking.py#L1193 Since the move has a quantity but picked is still False, the full picking is being picked at once https://github.com/odoo/odoo/blob/1d256123da587d625c0527ca3a18cd82e7161df5/addons/stock/models/stock_picking.py#L1206-L1207 ----- Ticket: opw-4726229 Forward-Port-Of: odoo/enterprise#89029 Forward-Port-Of: odoo/enterprise#86979
Fixes an error that could block users when adding a rental product with variants during subscription renewal. The configurator now only uses rental dates when they are actually available, keeping the rental sales flow usable before dates are set.
Original PR description
Versions -------- - 18.0+ Steps ----- 1. Create a rental product with multiple variants; 2. create a subscription order via the Rental app; 3. add the rental product; 4. confirm & invoice the subscription; 5. renew the subscription; 6. add the rental product to the renewal. Issue ----- > `Uncaught Promise > value.setZone is not a function` Cause ----- Commit 76526bdb3835 implemented the `_getAdditionalDialogProps` method for using OWL in the product configurator. In our flow, it simply checks whether the order is a rental order, and if so, it attempts to serialize its rental dates. Issue is that rental dates are not a required field as long as the order hasn't been confirmed yet, causing the traceback. Solution -------- Instead of checking whether it is a rental order, verify that the order has rental dates before attempting to serialize them. opw-4898437 Forward-Port-Of: odoo/enterprise#89016 Forward-Port-Of: odoo/enterprise#88629
The Kenya payroll SHIF/NHIF report now uses the selected month to include the correct payslips, preventing payslips from one month appearing in another month's report. The report wizard text was also simplified by removing a potentially confusing explanatory line.
Original PR description
- load payslip according to the Month value, currently, may payslip appears on june selection - remove the line 'the selection will cover ...' task-4775801 Forward-Port-Of: odoo/enterprise#89128 Forward-Port-Of: odoo/enterprise#85609
EasyPost shipping labels now include the related Odoo delivery reference, making it easier for users to match carrier records and physical labels with the correct Odoo delivery. This reduces confusion when reviewing shipments in the carrier dashboard or handling printed labels.
Original PR description
Issue ----- When using the Easypost delivery service, we don't pass the move reference to the carrier. This makes it hard for the user to match the deliveries found on the carrier dashboard with the…
Issue ----- When using the Easypost delivery service, we don't pass the move reference to the carrier. This makes it hard for the user to match the deliveries found on the carrier dashboard with the corresponding Odoo move. Steps to reproduce ----- - Set an Easypost delivery method up - Create a sale - Add delivery product & get a rate - Confirm the sale - Go to the linked delivery & confirm it --> The printed label has no reference field Discussion ----- As per EasyPost: > The reference field within the shipment body is used for transmissions of electronic data between the shipper and EasyPost, and typically does not get expressed anywhere on the physical label. To get data to the label, you need to leverage the "print_custom" fields outlined in the options section of the shipment. See also https://docs.easypost.com/docs/shipments/options Visual comparison ----- DPD UK labels, before and after the change:  USPS labels, before and after the change:  ----- Ticket: opw-4681615 Forward-Port-Of: odoo/enterprise#88941
Helpdesk email conversations now handle recipient details more accurately. External recipients and message authors are kept in the right email headers, while helpdesk aliases are not mistakenly treated as external contacts, reducing missed or misrouted replies.
Original PR description
See community PR for more details. Task- Forward-Port-Of: odoo/enterprise#88900
Bookkeeper users can now process customer follow-ups even when customer contact information such as email or address is missing. This prevents access errors in automatic follow-ups and manual reminders, helping accounting teams continue collection workflows without unnecessary interruptions.
Original PR description
Before this commit, a Bookkeeper user wasn't able to create a followup for a user with missing information (email or address) That error append using the manual_reminder and the Process Automatic…
Before this commit, a Bookkeeper user wasn't able to create a followup for a user with missing information (email or address) That error append using the manual_reminder and the Process Automatic Follow-ups For the Automatic Follow-ups action, the user wasn't able to access the 'missing information view' For the Followup Button (manual_reminder), that's in the follow-up report view, the user wasn't able to access either the 'manual_reminder view' or the 'missing information view' ## Steps in runbot 17.0: - Create an invoice with a past due date and a new customer (leave email empty) - Go in Accounting > Customers > Follow-up Reports - Select the In need of action report for your new customer - In Actions, click on Process Automatic Follow-ups - An AccessError should be displayed ## To test the manual reminder: - Create the invoice as before and go to Follow-up Reports - Open the report linked to your new customer - Click on the Follow up Button - An AccessError should be displayed opw-4848745 Forward-Port-Of: odoo/enterprise#88168