Daily updates from Odoo
Wednesday, October 8, 2025
26 changes · 19.0
Enhancements to existing features
Mexican payroll now uses payslip issue checks to warn users when required information is missing for CFDI generation. This helps payroll teams identify and resolve data problems earlier, reducing failed or delayed electronic payslip processing.
Original PR description
We now have a "issues" system on the payslips. Let's use it to signal what is missing for the correct generation of the CFDI. Task: 5068311
When users upload XML bills from bank reconciliation, the system now automatically activates the bill currency if it was inactive. This removes a manual step, speeds up bill upload, and makes the reconciliation workflow smoother.
Original PR description
Before: - When the user uploads an XML file from the bank reconciliation widget using 'Upload Bills' button and a currency of that bill is not active, then we ask the user to activate that currency manually. - Since users know the currency of Bill at the moment, we should directly activate the currency. After: - Now we activate the currency of Bill directly if it is not active, without asking to the user. Impact: - Improves user experience by not manually activating the currency of the bill. - Save users' time when uploading Bills in the bank reconciliation line. Task-5108103 Forward-Port-Of: odoo/enterprise#95513
Resolved issues and error corrections
The New User Invite email template now generates website and email links correctly. This prevents recipients from receiving malformed links, making onboarding invitations work as expected.
Original PR description
Website and email links were malformed on the New User Invite email template. Later versions also have this issue on the other templates will change those in forward ports. Renderer was treating the string formatting as a string itself when using the double curly braces on variables. Removed the curly braces so the variable was properly evaluated and inserted into the string. opw-4977756 Forward-Port-Of: odoo/odoo#221487
This fix prevents an IoT device from immediately losing its server configuration after being paired again in a specific recovery scenario. It helps avoid failed setup loops and reduces manual reconfiguration for users managing IoT boxes.
Original PR description
Steps to reproduce: 1. Pair your IoT 2. From the IoT homepage, clear the server configuration 3. From the DB, delete the IoT box record 4. Pair your IoT again EXPECTED BEHAVIOUR: - IoT pairs succesfully ACTUAL BEHAVIOUR: - IoT pairs but then immediately clears the server configuration This commit introduces a simply sanity check to workaround the issue, by simply ignoring a `server_clear` message if it was received less than 5 seconds after connecting to the websocket. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#230244
Credit notes created after a sales order down payment now correctly reverse the cost of goods sold. This keeps inventory and expense accounting accurate when customers are refunded after partial upfront payment.
Original PR description
**Problem:** When we do a downpayment on an invoice then pay the rest and do a credit note, the credit note does not reverse the cogs **Steps to reproduce:** - create a storable product invoiced on…
**Problem:** When we do a downpayment on an invoice then pay the rest and do a credit note, the credit note does not reverse the cogs **Steps to reproduce:** - create a storable product invoiced on ordered quantity - set the category of the product as avco and "inventory valuation" of the category as automated - set an onhand quantity and a positive cost - create a SO for 1 quantity of this product and confirm - click on create invoice, select downpayment percentage and 25% - click on create draft and confirm it - click on create invoice, select regular, create draft - confirm and select credit note - write something in the reason field and click on reserve - confirm it **Current behavior:** if you open the "Journal Items" page of the credit note you'll see that there is no line revresing the cogs (there would be if we didn't do a downpayment but invoiced all at once) **Expected behavior:** There should be: - A line crediting "600000 Expenses" (or the account that was debited for the cogs on the original invoice) with the amount being the cost of your product. - A line debiting "110300 stock interim (delivered)"(or the account that was credited for the cogs on the original invoice) with the amount being the cost of your product. **Cause of the issue:** Since this commit https://github.com/odoo/odoo/pull/163251/commits/d7b0510908d341c205461ca18b1730c93b88e445 (slightly modfified for efficieny reasons by this commit https://github.com/odoo/odoo/commit/4f9c52c03c65a497937053530e8d6c775d305e35), when _stock_account_prepare_anglo_saxon_out_lines_vals is called on the account move (the credit note) it calls _get_anglo_saxon_price_ctx. https://github.com/odoo/odoo/blob/76a8d6bc28eb5998bd976b3c41bf9772d325c8bf/addons/stock_account/models/account_move.py#L114 One of the invoice lines of the account move is linked via sale_line_ids attribute to a sale order line that is a downpayment. As a consequence, inside _get_anglo_saxon_price_ctx, move_is_downpayment will be populated with this line. https://github.com/odoo/odoo/blob/76a8d6bc28eb5998bd976b3c41bf9772d325c8bf/addons/sale_stock/models/account_move.py#L136-L139 Then _stock_account_prepare_anglo_saxon_out_lines_vals calls _stock_account_get_anglo_saxon_price_unit. https://github.com/odoo/odoo/blob/76a8d6bc28eb5998bd976b3c41bf9772d325c8bf/addons/stock_account/models/account_move.py#L131 Inside this method, because move_is_downpayment is populated, is_line_reversing will stay false https://github.com/odoo/odoo/blob/76a8d6bc28eb5998bd976b3c41bf9772d325c8bf/addons/sale_stock/models/account_move.py#L163-L164 As a consequence, - qty_to_invoice will become - qty_to_invoice - account_move will be populated - therefore posted_cogs will be populated https://github.com/odoo/odoo/blob/76a8d6bc28eb5998bd976b3c41bf9772d325c8bf/addons/sale_stock/models/account_move.py#L166-L174 So _compute average price will be called with a qty_invoiced of 1 instead of 0 and a qty_to_invoice of -1 instead of 1. So it will return 0 instead of the cost of the product because "missing" will be negative. https://github.com/odoo/odoo/blob/76a8d6bc28eb5998bd976b3c41bf9772d325c8bf/addons/stock_account/models/product.py#L915 **fix** The use case of this commit https://github.com/odoo/odoo/pull/163251/commits/d7b0510908d341c205461ca18b1730c93b88e445 is this one : - SO for qty of 10 (product invoiced on delivered qty). - 100% downpayment. - deliver 6. - invoice. In that case the invoice is actually a credit note but it still has to include the cogs (not reversed), so move_is_downpayment needs to be populated However in our use case the cogs has to be reversed (so move_is_downpayment has to be None). One difference between those two use case is that in our use case the account move has a reversed_entry_id. opw-5041783 Forward-Port-Of: odoo/odoo#229774 Forward-Port-Of: odoo/odoo#226809
This fixes ISO 20022 payment files for Danish banks by allowing the required local clearing instruction to be added when configured. Businesses using Danish bank payments can avoid rejected payment files by setting the appropriate clearing option, while behavior stays unchanged if no option is set.
Original PR description
The denmark banks were refusing ISO20022 documents because there was a missing field: "//PmtInf/PmtTpInf/LclInstrm/Cd" or "//PmtInf/CdtTrfTxInf/PmtTpInf/LclInstrm/Cd". One of those field should be filled by either 'ONCL' or 'SDCL' which means 'Over Night Clearing' or 'Same Day Clearing'. To fix this we added a config parameter with a key: account_iso20022.local_instrument_code where we can set OCNL or SDCL to add the required field to the iso document. If nothing is set, the field will not be added. opw-5073076 Forward-Port-Of: odoo/enterprise#96190 Forward-Port-Of: odoo/enterprise#95903
This update brings the spreadsheet engine up to its latest version with fixes for chart animations, dashboard chart menus, formatting conversion, sheet renaming, mobile formula access, headers, and pivot measures. Users should see smoother spreadsheet dashboards and fewer small interruptions when editing or presenting spreadsheet content.
Original PR description
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/86fc4428f8 [REL] 19.0.5 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0)…
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/86fc4428f8 [REL] 19.0.5 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/47bb54fc70 [FIX] chart: zoomable chart should be animated [Task: 5079057](https://www.odoo.com/odoo/2328/tasks/5079057) https://github.com/odoo/o-spreadsheet/commit/301b2ca0ec [IMP] carousel: allow full screen toggle in carousel [Task: 5078831](https://www.odoo.com/odoo/2328/tasks/5078831) https://github.com/odoo/o-spreadsheet/commit/975b3487fe [MOV] figures: rename `fullScreenChart` to `fullScreenFigure` [Task: 5078831](https://www.odoo.com/odoo/2328/tasks/5078831) https://github.com/odoo/o-spreadsheet/commit/0cea053f34 [FIX] format: wrong internal format conversion [Task: 5126306](https://www.odoo.com/odoo/2328/tasks/5126306) https://github.com/odoo/o-spreadsheet/commit/a2df5684dd [FIX] spreadsheet: prevent sheet name edit from losing focus [Task: 5109129](https://www.odoo.com/odoo/2328/tasks/5109129) https://github.com/odoo/o-spreadsheet/commit/0c0386b3ec [FIX] Evaluation: remove spread relations [Task: 5105030](https://www.odoo.com/odoo/2328/tasks/5105030) https://github.com/odoo/o-spreadsheet/commit/297ca4a894 [FIX] headers: can add lots of headers [Task: 5092626](https://www.odoo.com/odoo/2328/tasks/5092626) https://github.com/odoo/o-spreadsheet/commit/030841ec5e [FIX] composer: show FX icon in inactive mobile composer [Task: 5092659](https://www.odoo.com/odoo/2328/tasks/5092659) https://github.com/odoo/o-spreadsheet/commit/23f44838cb [FIX] chart: fix button hover background in dashboard menu [Task: 5082189](https://www.odoo.com/odoo/2328/tasks/5082189) https://github.com/odoo/o-spreadsheet/commit/242c9a7966 [FIX] pivot: add deferred calculated measure [Task: 5096156](https://www.odoo.com/odoo/2328/tasks/5096156) Co-authored-by: Anthony Hendrickx (anhe) <anhe@odoo.com> Co-authored-by: Alexis Lacroix (laa) <laa@odoo.com> Co-authored-by: Lucas Lefèvre (lul) <lul@odoo.com> Co-authored-by: Dhrutik Patel (dhrp) <dhrp@odoo.com> Co-authored-by: Adrien Minne (adrm) <adrm@odoo.com> Co-authored-by: Ronak Mukeshbhai Bharadiya <rmbh@odoo.com> Co-authored-by: Florian Damhaut (flda) <flda@odoo.com> Co-authored-by: Rémi Rahir (rar) <rar@odoo.com> Co-authored-by: Pierre Rousseau (pro) <pro@odoo.com> Co-authored-by: Vincent Schippefilt (vsc) <vsc@odoo.com>
Live chat visitors can no longer start calls or invite guests from chat threads. This prevents unsupported visitor actions and keeps live chat interactions aligned with intended permissions.
Original PR description
This commit removes the possibility for live chat visitors to start a call and invite guests. task-4849019 Forward-Port-Of: odoo/odoo#229924 Forward-Port-Of: odoo/odoo#228531
This fix prevents Chilean electronic invoice XMLs received by email from failing when they contain accented characters such as Ó. Businesses can process these vendor documents more reliably without manual intervention caused by import errors.
Original PR description
### Issue:
The invoice XMLs having special characters like "Ó" received in DTE emails will trigger a traceback.
### Cause:
`.decode('utf-8')` will try decoding the bytes in utf-8 but Ó is not UTF-8, so there is a traceback:
```
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xcd in position 1734: invalid continuation byte
```
In any case, it crashes at the next line: `xml_content = etree.fromstring(xml_dte)` because the XML specifies the encoding (i.e. unicode) but the true encoding is `utf-8` so an error is raised:
```
ValueError: Unicode strings with encoding declaration are not supported. Please use bytes input or XML fragments without declaration.
```
### Solution:
Remove `.decode('utf-8')` when decoding. The method `fromstring` accepts bytes and will use the encoding specified in the XML.
opw-5124661
Forward-Port-Of: odoo/enterprise#96410This fixes an inventory valuation issue where FIFO product costs could be updated from the manually set cost instead of the actual valuation average. After revaluation, product cost now stays aligned with inventory value, improving accuracy for stock accounting and reporting.
Original PR description
**Steps to reproduce:** - create a storable product with fifo category - update the cost to 200 - click on the on hand smart button and add a quant of 1 quantity - update the cost to 300 - click on…
**Steps to reproduce:** - create a storable product with fifo category - update the cost to 200 - click on the on hand smart button and add a quant of 1 quantity - update the cost to 300 - click on the on hand smart button and update the quantity to 2 - the value should be 500, which makes a 250 value per product - open Inventory/valuation and search your product - group by product, select your product and click on "+" icon to open the revaluation widget - add 200 (so +100 per unit) - go back to the product form **Current behavior:** the cost is now at 400 **Expected behavior:** the cost should be at 350 (250 + 100) If we change the standard_price we should change it in accordance with the valuation **Cause of the issue:** In action_validate_revaluation, during the update of the standard_price, the current standard_price (set by the user and disconnected from the valuation) is used in the computation. https://github.com/odoo/odoo/blob/5118f7cb80744f901d7028dc75c29aba9591b83b/addons/stock_account/wizard/stock_valuation_layer_revaluation.py#L127 opw-5028848 Forward-Port-Of: odoo/odoo#229977 Forward-Port-Of: odoo/odoo#228457
Fixes an issue where automatic replenishment could create purchase orders with slightly inflated quantities when product packaging used different unit multiples. This helps businesses avoid unnecessary over-ordering and keeps inventory purchases aligned with actual demand.
Original PR description
**Steps to reproduce:** - enable "units of measure & packagings" settings - navigate to "units and packagings" and create a new one called "pack of 2" - set a quantity of 2 and the reference unit as…
**Steps to reproduce:** - enable "units of measure & packagings" settings - navigate to "units and packagings" and create a new one called "pack of 2" - set a quantity of 2 and the reference unit as "units" - create a new storable product - next to "sale price" change the unit to "pack of 6" - in the sales tab add "pack of 2" in the packagings - in the purchase tab add a vendor - click on the reordering rule smart button and create a new one - set the min and max to 0 and set the replenishment multiple to "pack of 2" (you might have to make this column visible using the filters) - create and confirm a quotation for 1 pack of 6 **Current behavior:** a new Purchase Order is created for a quantity of 1.02 **Expected behavior:** it should be a quantity of 1 **Cause of the issue:** qty_multiple is rounded (in _compute_quantity) before the computation of remainder. https://github.com/odoo/odoo/blob/7a0a246016d50ae80e49f3502a97e82d414ab0b0/addons/stock/models/stock_orderpoint.py#L373-L376 In cases of repeating decimal numbers (like 0.3333333 in our example), this leads to the remainder not being 0 even though it should be 0. opw-5040144 Forward-Port-Of: odoo/odoo#230013 Forward-Port-Of: odoo/odoo#228014
Appointment bookings with multiple staff members now calculate manual confirmation thresholds using the combined capacity of all assigned users. This prevents bookings from being unnecessarily marked as requests when enough total capacity is still available, and adds test coverage for this behavior.
Original PR description
While the fix has been already implemented in 19.0 in [1], this commit forwards-port the test of the original commit, as it differs from the one included (modified) in [1] and treats the case of…
While the fix has been already implemented in 19.0 in [1], this commit forwards-port the test of the original commit, as it differs from the one included (modified) in [1] and treats the case of managing capacity, and some other use cases not covered by the test in [1]. A small error is also corrected in a separate commit, as the appointment used to get the phone question was wrong in a test related to the original issue. ORIGINAL ISSUE ============== Introduced in https://github.com/odoo/enterprise/commit/bce7e94650c337a9046958a7689c81db5b2a4c73, We now handle capacity when booking users. They have each a max capacity of user_capacity for each slot. However, when it comes to the manual confirmation treshold, we do not account for the total capacity of all users combined, but consider the maximum to be user_capacity! This can lead to a lot of 'request' meetings as we reach the manual confirmation percentage very quickly. STEPS TO REPRODUCE ================== 1. Create an appointment type based on users, with 'manage capacities' enabled, 'manual confirmation' enabled and 'when over' 50% total capacity. Set 2 users and 3 'seats max'. This way, the total capacity of your appointment is 2 * 3 = 6 per slot. 2. As a public user, take an appointment for 2 capacity in the front end 3. The meeting will end up as a 'request', even though the capacity booked is 2/6 < 50%, and should be 'booked' FIX === We now multiply the number of users on the appointment type by the user_capacity when computing the total capacity and comparing it to the asked capacity on booking an appointment. 1 : https://github.com/odoo/enterprise/commit/b19e26b0333180ba7a487e14e06385693cf7ab16 Task-4930778 Forward-Port-Of: odoo/enterprise#89876
UPS shipping rate checks during ecommerce express checkout no longer fail when shoppers have only provided the limited address details required at that stage. This helps customers continue checkout smoothly before entering full street and phone information later.
Original PR description
Express checkout in ecommerce does an initial rate check with shipping connectors that does not require all of the fields normally required by that shipping connector. For UPS, this meant express checkout was failing due to an unnecessary `street` and `phone` field check since the only required delivery fields for express checkout are: (city, zip, country_code, state_code) For more info, see: https://github.com/odoo/odoo/blob/b403d5d74dd545f926a38a6aa6d18118d34e83b7/addons/website_sale/controllers/delivery.py#L181-L188 opw-[4447700](https://www.odoo.com/web#id=4447700&view_type=form&model=project.task) Forward-Port-Of: odoo/enterprise#78788
Fixes an error that could stop users from validating payments in Point of Sale when using Kenya OSCU electronic invoicing. This ensures sales can be completed normally for Kenyan companies without the checkout process failing.
Original PR description
**Steps to reproduce:** 1. Install `l10n_ke_edi_oscu_pos`. 2. Set company to a Kenya (KE) company. 3. Open POS → Clothes shop → add a product → go to Payment → try to Validate → traceback occurs.…
**Steps to reproduce:**
1. Install `l10n_ke_edi_oscu_pos`.
2. Set company to a Kenya (KE) company.
3. Open POS → Clothes shop → add a product → go to Payment
→ try to Validate → traceback occurs.
**Issue:**
- A traceback is raised when validating a payment in the POS screen.
`undefined
TypeError: Cannot read properties of undefined (reading 'services')
at OrderPaymentValidation.beforePostPushOrderResolve`
**Cause:**
- ` this.env` and `this.orm` is not directly accessible in `OrderPaymentValidation`.
https://github.com/odoo/enterprise/blob/8ca771eb28a1fac13037c0d45e8d716d3dfc6ed2/l10n_ke_edi_oscu_pos/static/src/app/utils/order_payment_validation.js#L7-L24
**Solution:**
- Use `this.pos.env` instead of `this.env`, and `this.pos.data.call` instead of
`this.orm.call` to correctly access the environment and execute data calls
during payment validation.
> Reference:
https://github.com/odoo/enterprise/blob/5a794a6e69ba884862b4a3f399143d1392caa6f0/pos_barcodelookup/static/src/overrides/components/product_screen/product_screen.js#L8-L10
[Related Community PR](https://github.com/odoo/odoo/pull/230069)
**opw - 5137557**Opening the Quality Points button from a product in Point of Sale no longer causes an error. The system now opens the correct quality control view, preventing disruption for users reviewing product quality rules.
Original PR description
**Step to Reproduce** 1- Install point_of_sale and quality_control. 2- Open POS -> Product -> Product 3- Open any product and click the Quality Points smart button → traceback occurs **Issue**…
**Step to Reproduce** 1- Install point_of_sale and quality_control. 2- Open POS -> Product -> Product 3- Open any product and click the Quality Points smart button → traceback occurs **Issue** `UncaughtPromiseError > OwlError Uncaught Promise > The following error occurred in onWillStart: ""quality.point"."product_variant_count" field is undefined."` **Root Cause** https://github.com/odoo/odoo/blob/a729578afb7fed79aac2d622aae4da4c0917f8e5/addons/point_of_sale/views/product_view.xml#L23-L25 - View reference is passed in the context. - When this context is propagated to `action_see_quality_control_point`, https://github.com/odoo/enterprise/blob/7b777bffbebfb6503bb348005e9ce076825926e4/quality_control/models/quality.py#L579-L584 https://github.com/odoo/enterprise/blob/2e08282ca275bf1e66c58e28391f11f8bd7884d2/quality_control/views/quality_views.xml#L859-L868 - Than traceback occurs because the action does not pass a `view_id`. - When the context contains `list_view_ref`, it attempts to load the product template list view with the `quality.point` model. - This leads to a traceback since the fields defined in that view do not exist on the `quality.point` model. **Solution** - Pass a proper `view_id` from the Python side to ensure the correct view is loaded, preventing `list_view_ref` from forcing to load an invalid template. **opw-** **5090505** Forward-Port-Of: odoo/enterprise#95040
Point of Sale now handles unusually large payment amounts without crashing during order validation. The fix also ensures the confirmation prompt closes correctly after approval, helping cashiers complete sales smoothly.
Original PR description
**Steps to reproduce:** 1. Install the POS module. 2. Open POS and add a product. 3. Proceed to the payment page. 4. Make a payment greater than (total cost of order * 1000). 5. Try to validate the…
**Steps to reproduce:**
1. Install the POS module.
2. Open POS and add a product.
3. Proceed to the payment page.
4. Make a payment greater than (total cost of order * 1000).
5. Try to validate the payment → traceback occurs.
**Issue:**
- A traceback is raised when validating a payment in the POS screen.
`undefined
TypeError: Cannot read properties of undefined (reading 'utils')
at OrderPaymentValidation.isOrderValid `
**Cause:**
- ` this.env` is not directly accessible in `OrderPaymentValidation`.
> Reference:
https://github.com/odoo/odoo/blob/33c789eeed3b307e40c0f7ab2c6bc07c33867498/addons/pos_online_payment/static/src/app/utils/order_payment_validation.js#L25-L28
**Solution:**.
- Use `this.pos.env` instead of `this.env` to correctly access the environment
during payment validation,
> NOTE
- After fixing the traceback, the 'Large Payment Amount' confirmation dialog
appears correctly. However, when clicking 'OK', the dialog was not closing
because the callback function `validateOrder` returned `False` even for valid
orders. This caused the dialog to reopen in an infinite loop.
https://github.com/odoo/odoo/blob/d309b52e5b19727b3e91ed91afd44e392a3b851a/addons/web/static/src/core/confirmation_dialog/confirmation_dialog.js#L71-L91
- Add return `True` in `validateOrder`, because even when the order was valid,
it returned `False`, causing the `ConfirmationDialog` to reopen repeatedly
when clicking "OK". Returning `True` ensures the dialog closes properly after
successful validation.
> Reference:
https://github.com/odoo/odoo/blob/4cd1ad3aa46ad4645fc7b5e530b79d53382de6d5/addons/point_of_sale/static/src/app/utils/order_payment_validation.js#L108-L138
[Related Enterprise PR](https://github.com/odoo/enterprise/pull/96284)
opw-5137557This fixes Indian HR leave calculations so sandwich leave counts all applicable non-working days around a leave period, not just the nearest day. It also ensures half-day leave is recorded as 0.5 days instead of a full day, improving payroll and absence accuracy.
Original PR description
**Steps to reproduce:** - Install l10n_in and l10n_in_hr_holidays module - Time off > configuration > Public holidays - Create a public holiday for Independence Day (15/08/2025) - Go to Time off >…
**Steps to reproduce:** - Install l10n_in and l10n_in_hr_holidays module - Time off > configuration > Public holidays - Create a public holiday for Independence Day (15/08/2025) - Go to Time off > configuration > 'Time off Types', - Create a Time off type with - 'Sandwich leave' ticked and `Take Time Off in` to half a day - Go to Time off > Management > Time off - Case 1: Create a paid time off leave for the employee from 13/08 to 17//08/2025 - Case 2: Create a paid time off with any date and mark it as a half-day **Observation:** - Case 1: You will see Duration 3 days with the sandwich leave policy. - Case 2: Half-day leave shows 1 day instead of 0.5 **Root Cause:** - Case 1: For the sandwich leave rule, here we checked only one day after and before, leave start and leave end, respectively. It will cause an issue if an employee applies leave that starts or ends with 3 non-working days. https://github.com/odoo/odoo/blob/5d2f1510c08d5570fc2c6c8de0cb4042bacf12d6/addons/l10n_in_hr_holidays/models/hr_leave.py#L39-L46 - Case 2: We forcefully added a 1-day leave, without checking if the leave is half day or not. https://github.com/odoo/odoo/blob/5d2f1510c08d5570fc2c6c8de0cb4042bacf12d6/addons/l10n_in_hr_holidays/models/hr_leave.py#L19 **Solution:** - Case 1: Extend the sandwich leave logic to check every day before and after until a working day is found. - Case 2: Fixed duration calculation to add 0.5 for half-day leaves. opw-5025766 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#226883
Point of Sale now correctly shows and allows selection of product variant options that use the Image display type. This prevents sales staff from being blocked when selling products configured with these newer variant options.
Original PR description
**Steps to reproduce:** - Make a variant category, make it an Image - Add it to a product, go to PoS and order the product - The product variants will not be shown and can't be selected **Why the fix:** Since 19.0, there is a new kind of variant, Image, but it was not taken in the conditional statement for the product popup for the variants. As it didn't fall into any category, nothing was shown. At the moment this is basically the same as the Color option, but with an extra label below to provide more information. This it will be IMP later on with images like in the Sales module. opw-5099123
Duplicated leads without an assigned salesperson now remain eligible for rule-based assignment. This prevents sales opportunities from being missed when teams rely on automated assignment rules.
Original PR description
Currently, leads are not automatically assigned via rule-based assignment when duplicating an existing lead, even if the duplicated lead matches the assignment criteria. **Pre-requisites:** 1) Set up…
Currently, leads are not automatically assigned via rule-based assignment
when duplicating an existing lead, even if the duplicated lead matches
the assignment criteria.
**Pre-requisites:**
1) Set up rule-based lead assignment in the CRM settings.
2) Configure the sales team's assignment domain:
`[("user_id", "=", False)]`
3) Configure the sales team members' domain:
`[("probability", ">=", 10)]`
**Steps to Reproduce:**
1) Create a lead that matches the above assignment rules.
2) Remove the salesperson (user_id) and sales team from the lead.
3) Duplicate the lead.
4) Update the probability to a valid value (e.g., ≥ 10).
5) Manually trigger the `Rule-Based Assignment`.
**Issue:**
The original lead gets assigned, but the duplicated one does not.
**Cause:**
When duplicating, the system sets date_open to the current date by default,
even if the duplicated and original leads have no assigned users.
https://github.com/odoo/odoo/blob/3e7d85cf25386615dea559d954cebb1424b62f35/addons/crm/models/crm_lead.py#L929-L931
However, `rule-based assignment` only considers leads where `date_open` is False https://github.com/odoo/odoo/blob/3e7d85cf25386615dea559d954cebb1424b62f35/addons/crm/models/crm_team_member.py#L136-L141
**Solution:**
Set `date_open` to False during duplication if the original lead has no `user_id`.
This ensures the new lead remains eligible for assignment.
opw-5003529
Forward-Port-Of: odoo/odoo#229512
Forward-Port-Of: odoo/odoo#227387This fixes Razorpay payment failures that could occur when a provider was configured with both standard credentials and OAuth. The payment flow now uses the correct authentication method, helping customers complete payments on mobile without 403 errors.
Original PR description
In a specific context, Razorpay rejects connections using both Key ID/Secret and an access token simultaneously. To reproduce, it's require a real production Razorpay account since Oauth is not available in test mode. Step to reproduce: - Configure Key ID/Secret and connect via OAuth on the Razorpay payment provider. - On iOS/Android, making a payment on the website triggers a "403 Forbidden" error because Razorpay redirect to /payment/razorpay/return and the signature from Razorpay not correspond to the expected signature computed with the Key Secret. This fix prioritizes call with Key ID/Secret over token authentication. opw-5100194 opw-4989944 opw-5039880 opw-5099580 Forward-Port-Of: odoo/odoo#229468
Invoices using the Saudi Arabia localization can now be printed or sent without triggering an error. The report date formatting was corrected so PDF generation works as expected for customer invoices.
Original PR description
Steps to Reproduce: - Open any customer invoice for l10n_sa localisation. - Click the Send or Print button. - The system shows a traceback instead of generating the PDF report. Issue: - The problem was caused by a wrong date format setting in the report template. Fix: - Updated the date field setup in the report so it formats correctly when printing or sending invoices https://drive.google.com/file/d/1eY3F78YVQzutLikTigXAR0I0_2DwWILs
Outgoing stock movements split across multiple lots or serial numbers now allocate costs only to the relevant lot. This prevents overstated or distorted lot costs and gives businesses more accurate inventory valuation.
Original PR description
Description of the issue/feature this PR addresses: If "out" moves have more than one lot (i.e. two move lines for one move), then the lot cost calculations go way askew. Current behavior before PR: Lot cost calculations work by taking a subset of a stock move value, up to the quantity of just that lot. When recalcing lot cost, for "in moves" the value correctly uses a "portion" of the cost from the move. But for "out moves", it does not - assuming the FULL move is for a single lot. If multiple lots or serial numbers are on a single move, then it should apportion that too. Desired behavior after PR is merged: The out moves check the move lines for those for the specific lot, and only include a portion of the out in the calculation. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Saudi invoices that include section lines can now be printed without causing an error. This ensures businesses using Saudi localization can generate compliant invoice documents reliably, even when invoices are organized into sections.
Original PR description
### Issue: Printing a Saudi invoice with section lines results in a traceback. ### Steps to reproduce: - Install l10n_sa and switch to a Saudi company - Create an invoice with section lines for a Saudi partner - Click "Print" ### Cause: To compute the totals for the section lines, we try to use the field `child_ids` but it was removed in [this commit](https://github.com/odoo/odoo/commit/572680aa30d41900223f1bea36e410e5c0270b37) for performance issues. ### Solution: Use `_get_section_lines()` added by the same commit. opw-5140406
This fix prevents scheduled inventory valuation closing from crashing when the required journal or valuation account has not been configured. Businesses get a safer process with clearer handling of incomplete settings, reducing unexpected accounting interruptions.
Original PR description
When the journal is not set in the inventory valuation settings, running the cron ``Stock Account: Inventory Valuation Closing`` results in a traceback. Steps to reproduce the error: - Install…
When the journal is not set in the inventory valuation settings, running the cron ``Stock Account: Inventory Valuation Closing`` results in a traceback. Steps to reproduce the error: - Install ``accountant`` and ``stock`` modules - Go to Settings > Inventory Valuation > Periodicity: Daily > Unset the Journal > Save - Run the cron ``Stock Account: Inventory Valuation Closing`` Traceback: ```py NotNullViolation: null value in column "journal_id" of relation "account_move" violates not-null constraint ``` https://github.com/odoo/odoo/blob/4cd1ad3aa46ad4645fc7b5e530b79d53382de6d5/addons/stock_account/models/res_company.py#L57-L63 This occurs because when the journal is unset, ``journal_id`` becomes null, leading to the above error when the cron runs. Error also occurs when the Valuation Account is unset. Traceback: ```py CheckViolation: new row for relation "account_move_line" violates check constraint "account_move_line_check_accountable_required_fields" ``` sentry-6925934391 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Google address suggestions can list address details in different orders, which sometimes caused checkout address completion to fail. This fix picks recognized address fields more reliably, preventing errors and improving address handling for customers in countries with different locality formats.
Original PR description
Versions -------- - 18.0+ Steps ----- 1. Enable Google address autocomplete; 2. go eCommerce checkout; 3. add an address during the delivery step; 4. autocomplete a bunch of addresses. > [!Note] > I…
Versions -------- - 18.0+ Steps ----- 1. Enable Google address autocomplete; 2. go eCommerce checkout; 3. add an address during the delivery step; 4. autocomplete a bunch of addresses. > [!Note] > I haven't been able to reproduce it myself, but others have. > It appears that the order Google provides place types isn't always the same. Issue ----- You may get a `KeyError`, trying to fetch `standard_data['country']`. Cause ----- The fields get sorted by type, and we try to sort `country` before `state`, so that the `country` key should be present when we get to `state`. The likely issue is that Google often provides multiple types per field, and we only keep the first one, assuming it to be the most relevant one, but the API documentation makes no guarantees about the array's order[^1]. For example, if a field were to have `political` in front of `country`, we would keep the `political` type, only to ignore it later on, as we have no mapping for it. [^1]: https://developers.google.com/maps/documentation/places/web-service/place-types#address-types Solution -------- 1. Iterate over the types, and get the first one that's part of `FIELDS_MAPPING` 2. Before searching for a `state`, ensure `country` has already been set, otherwise log a warning. 3. Extra: add `postal_town` as a type, which gets used instead of `locality` in some countries like Sweden. opw-4880651 Forward-Port-Of: odoo/odoo#230134 Forward-Port-Of: odoo/odoo#217171
Loyalty discounts and coupons now use a consistent date when checking expiration, preventing valid checkout payments from failing because of timezone differences. Expired coupons are also removed at the right time, so order totals stay accurate before payment is completed.
Original PR description
Versions -------- - 17.0+ Steps ----- 1. Have a database with GeoIP enabled; 2. have a promotion program that gives a discount on a specific product; 3. use a VPN to browse /shop from California…
Versions -------- - 17.0+ Steps ----- 1. Have a database with GeoIP enabled; 2. have a promotion program that gives a discount on a specific product; 3. use a VPN to browse /shop from California before 7:00 UTC; 4. add the product to your cart; 5. go to checkout; 6. pay for the order. Issue ----- Order cannot be confirmed due to incomplete payment. Cause ----- The `_frontend_pre_dispatch` method of `website` adds a timezone value to the context based on the request's `geoip`. This context value then gets used to find applicable loyalty programs via `Date.context_today`, and applies them to the order. Then after payment was initiated, the order gets validated again using server time (UTC), which now considers the applied program expired, and removes the reward before confirming the order. Consequently, with the discount removed, the paid amount no longer matches the order total, thus the order remains unconfirmed. Solution -------- If the order has a confirmed transaction, use its `create_date` to verify loyalty expiration dates. For time zone, instead of `Date.context_today`, using whatever `tz` value is in the context, use a helper function which retrieves the current day in the company's timezone. For website orders, if defined, use the eCommerce salesperson's time zone instead. Also fix an issue where expired coupon lines weren't getting removed from the order. opw-4765873 opw-4781346 opw-4939268 Forward-Port-Of: odoo/odoo#229749 Forward-Port-Of: odoo/odoo#222428