Tuesday, August 26, 2025
13 changes · saas-18.3
Enhancements to existing features
Xendit payment forms now report token creation errors immediately, such as invalid customer input, instead of continuing with unusable payment data. This helps customers understand and correct issues sooner, reducing failed payment attempts and confusion during checkout.
Original PR description
Previously, if error was found during token creation (i.e. invalid input) , it's not immediately reported but instead invalid data will be used for further process. Now, any errors caught early will be reported immediately back. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#224036
Resolved issues and error corrections
Customers using mobile self-ordering will now see their order screen update after payment is completed, even if they close the payment page before confirmation finishes. This prevents confusion and reduces the chance of customers or staff thinking a completed payment did not go through.
Original PR description
Before this commit, if a user closed the payment page on mobile after finalizing the payment but before the payment was confirmed, the self order UI would not update once the payment was confirmed. After this commit, the self-order UI is correctly updated after the payment process, even if the payment page was closed. opw-4911434 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#222954
This update brings the spreadsheet component up to the latest version and fixes several issues affecting everyday use. Users should see better read-only viewing, improved copy-paste from Excel, correct chart exports to XLSX, and cleaner menu alignment.
Original PR description
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/ec2777d8c [REL] 18.3.18 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0)…
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/ec2777d8c [REL] 18.3.18 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/3dc59d0e4 [FIX] Composer: Allow to select text in readonly mode [Task: 5028187](https://www.odoo.com/odoo/2328/tasks/5028187) https://github.com/odoo/o-spreadsheet/commit/16a09225b [FIX] TopBar: Fix readonly mode view [Task: 502818](https://www.odoo.com/odoo/2328/tasks/502818) https://github.com/odoo/o-spreadsheet/commit/cd892dce6 [FIX] xlsx: correctly export aggregated charts [Task: 4954426](https://www.odoo.com/odoo/2328/tasks/4954426) https://github.com/odoo/o-spreadsheet/commit/7f17b4364 [FIX] Clipboard: clear useless function argument [](https://www.odoo.com/odoo/2328/tasks/) https://github.com/odoo/o-spreadsheet/commit/b0411dc8b [FIX] clipboard: fix copy-paste from Excel [Task: 4730469](https://www.odoo.com/odoo/2328/tasks/4730469) https://github.com/odoo/o-spreadsheet/commit/4fb36137d [FIX] Figure: icon of the menu item is not vertically aligned [Task: 4992687](https://www.odoo.com/odoo/2328/tasks/4992687) https://github.com/odoo/o-spreadsheet/commit/e27fa3ee3 [FIX] menu: Fix menu item alignment [Task: 5028721](https://www.odoo.com/odoo/2328/tasks/5028721) 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>
Restricted website editors can now edit permitted website content without triggering an access rights pop-up when saving. The change prevents editor-only controls from being attached to page elements that restricted users are not allowed to modify directly.
Original PR description
Steps to reproduce: - Install website_event, with demo data - Change Marc Demo's website access to "Restricted Editor" - Log into Marc Demo and visit an event's website page e.g."Live Music Festival"…
Steps to reproduce: - Install website_event, with demo data - Change Marc Demo's website access to "Restricted Editor" - Log into Marc Demo and visit an event's website page e.g."Live Music Festival" - user is able to edits is footer contents,make a change - try to save. Observation: A pop-up for access right appears Cause: after this fix odoo/odoo@11e94cb059901ffc3c521a431259d627beb69e1e , we allow website to be editable for restricted user if, user can modify other models, which are editable from website,like event. And, if website is editable, we brand the ir.ui.views nodes, https://github.com/odoo/odoo/blob/3ceb04bf2aa90442430f5bf321bac4a9d872752c/addons/website/models/ir_qweb.py#L93-L94 but restricted user do not have access to ir.ui.view model, causing access issue Note: if a node is branded, that means it is editable Fix: Brand ir.ui.view nodes only if user has full access to website editor opw-4659114 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#224038 Forward-Port-Of: odoo/odoo#221202
This fix ensures tips added after payment in restaurant point of sale are recorded as part of the correct payment instead of appearing as change or a closing discrepancy. It helps receipts, session closing, and accounting entries reflect the customer transaction accurately.
Original PR description
Steps to reproduce: ------------------- 1. Enable tipping after payment 2. Make an order, pay it with customer account, then tip an amount X 3. On the receipt, that amount X is shown as 'change'!! 4.…
Steps to reproduce: ------------------- 1. Enable tipping after payment 2. Make an order, pay it with customer account, then tip an amount X 3. On the receipt, that amount X is shown as 'change'!! 4. Close the PoS session 5. On backend, go to Sessions, and choose the session you just closed 6. It won't be closed, as there are still a diff of X amount, so click 'Close Session & Post Entries' (the purple button), and confirm the prompt about posting the diff X into the receivable PoS account 7. Go to journal items (the magical button), and observe that the tip amount X is on a different move line labeled 'Difference at closing PoS session', and is not even in the name of the customer Why the problem: ---------------- Before 17.4, we had a function `set_tip` on the backend that updated the payment line to add the tip amount whenever we tip after [1]. However, after commit 2a5f1ab, the logic of `set_tip` was moved to the frontend [2], or most of it, as it seems that we missed moving the logic that updates the payment line. The fix: -------- We now restore the method `set_tip` that was before 2a5f1abf2e98ee09fa7a912b87d71879b5ff260b, which will update the payment line and the order. [1]: https://github.com/odoo-dev/odoo/blob/636606d12cec79a0196ed0f9b7bb71a78d4fe65a/addons/pos_restaurant/models/pos_order.py#L206 [2]: https://github.com/odoo/odoo/blob/d5baeec9b60bdf3a5ab9d1243f46e957c0489877/addons/pos_restaurant/static/src/app/tip_screen/tip_screen.js#L90-L96 opw-4736154 Forward-Port-Of: odoo/odoo#220797 Forward-Port-Of: odoo/odoo#217320
Fixed a Point of Sale issue where sessions could error or become stuck when the default preset required a customer and the user dismissed the customer or register prompt. The preset is now applied first, allowing staff to continue preparing an order while still requiring a customer before payment.
Original PR description
**Steps to reproduce:** - Enable presets, chose the 3 default ones - The default should be a preset that requires a customer (like delivery) - Go in the PoS, and instead of opening the register,…
**Steps to reproduce:** - Enable presets, chose the 3 default ones - The default should be a preset that requires a customer (like delivery) - Go in the PoS, and instead of opening the register, discard - An error shows up - Go back to the PoS and open the register - Try to select a client, an error shows up **Problem:** When the default preset needs a client to operate, if we do not set the customer as soon as possible when opening the PoS, an error will show up. So if we press discard on either the open register pop up or the client pop up that comes right after, we have an error. Another bug was that only on a new database or in incognito mode, with the same config, an error would be raised as the cashier is only set after looking at the preset but is retrieved from the cache before setting the preset. Meaning that if the cashier was in the cache, it will work fine, but if it was not, the PoS will crash. **Why the fix:** When we have a default preset that requires a customer, we try to read the data from the preset before it is set. The way it worked before this fix is, we set a customer and once this is done, we set the preset. The problem with this is if we do NOT select a customer and exit the PoS, we try to read data from the preset, which has not been set as we did not chose a customer. If we then open the PoS again, we will not be able to pick a customer from the automatic pop up, as it does not appear. So we will be locked in a PoS with no preset with no way of putting it back on without closing the register. We will also have an error if we try and select a customer manually, as it tries to access some of the preset data. The way it works after this commit is that we set the preset before chosing the customer. If we chose discard, we can go on with the order, but we will have to pick a customer before paying for the order, as a pop up prevents us from doing so if a customer is not selected. This is how it was done before the 18.3 refactoring. This way, the preset will always be active, even if no customer are selected. opw-4989001
Bank reconciliation now applies the configured analytic distribution to early payment discount lines, matching the behavior of manually registered payments. This ensures discount-related accounting entries are categorized correctly for reporting and analysis.
Original PR description
# Steps to reproduce: - Configure an early discount payment term (e.g., 2/7 Net 30). - Configure the analytic distribution model with the account used when a discount is granted (e.g., 657000 on the…
# Steps to reproduce: - Configure an early discount payment term (e.g., 2/7 Net 30). - Configure the analytic distribution model with the account used when a discount is granted (e.g., 657000 on the BE fiscal position). - Create an invoice using the early discount payment term. - On bank reconciliation, register the transaction taking into account the early payment discount (e.g., 98% of the invoice amount_total). On the third line with account 657000, corresponding to the early discount payment, the analytic distribution model does not apply. In contrast, when manually registering a payment for the invoice, the analytic is correctly applied. When the bank reconciliation lines are created, _lines_check_apply_early_payment_discount gets its values for the early payment lines from _get_invoice_counterpart_amls_for_early_payment_discount_per_payment_term_line, which does not check if there is an analytic distribution model. enterprise pr: https://github.com/odoo/enterprise/pull/90641 opw-4868986 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#217933
This fix ensures that when an Extra Hours time off request is refused or cancelled and later reset, the related overtime entry is recreated. Employees' extra hours balances are deducted correctly again, preventing inaccurate balances after leave changes.
Original PR description
When refusing or cancelling a time off request of type Extra Hours, the linked hr.attendance.overtime record was hard deleted. As a result, if the leave was later reset, the extra hours were not deducted again. This fix ensures that a new hr.attendance.overtime record is recreated when resetting the leave, restoring the correct impact on the employee's extra hours balance. Related task: 4966880. 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#220619
The Documents app now recognizes older redirected links when users open shared document content. This keeps previously shared or migrated document links working, reducing broken access for customers and partners.
Original PR description
We do not currently check for `documents.redirect` records when accessing the `/documents/content/<access_token>` endpoint. This commit fixes this by redirecting if a `document.redirect` with the appropriate `access_token` was created for backwards compatibility. opw-4517698 Forward-Port-Of: odoo/enterprise#92342 Forward-Port-Of: odoo/enterprise#92313
Fixes an issue in the Attendance Gantt view where adjusting the checkout time by dragging the second half of a time block could save the current time instead of the selected time. This helps ensure attendance records reflect the employee's intended checkout time and avoids inaccurate timesheets.
Original PR description
Steps to Produce: - Go to the Attendance interface and select week. - Drag the second half of the column to adjust checkout. - Save the change. Issue: - Dragging on half cell deletes the checkout value from the context. - As a result, the system sets the checkout time to the current time instead of the dragged value. - This leads to incorrect attendance records. Fix: - Ensure the checkout value remains in the context when dragging the cell. - Preserve the modified checkout time so it reflects the user's intended change instead of defaulting to the current time. Task-4958060 Forward-Port-Of: odoo/enterprise#91119
Subscription invoices created after a customer pays through the portal are now correctly sent for official electronic signing. This restores required compliance behavior for localizations such as Mexico and avoids invoices being created without the needed government validation.
Original PR description
## Steps to reproduce: - Make sure the Mexican localization is installed and properly set up for signing invoices - Make sure the payment providers are set up (it can be demo, the customer uses…
## Steps to reproduce: - Make sure the Mexican localization is installed and properly set up for signing invoices - Make sure the payment providers are set up (it can be demo, the customer uses Stripe but it can be reproduced with any - Make sure the online payment setting is active - Go to subscription module - Do a new order - In other info, add the online payment checkmark - Confirm the order - Generate the payment link or go into the preview - Make the payment ## Issue: The invoice is generated, but is not signed by the government (no edi is generated), as it used to. ## Cause: The flow works in 17.0 but for the wrong reason. Before this [commit](https://github.com/odoo/enterprise/pull/70562), two mails were sent. And during the chain of triggers of the second email, edi document was generated with `orders._send_success_mail(tx.invoice_ids, tx)`. https://github.com/odoo/enterprise/pull/70562/files#diff-8778c8dce7ca1c24de19f26f11ac0c5410c6c2a4d121c3815682a2323cbb09c2L177 After the removal of the method, it should still work since we still have `payment.transaction._send_invoice` which calls `_generate_and_send_invoices` and should trigger the sub calls necessary for generating the edi stuff. But in `_create_or_link_to_invoice`, we check that the transaction has no invoice_ids linked (make sense with the name of the method). However, at this stage, we already created the invoice in https://github.com/odoo/enterprise/blob/2f3698b250092ad376344e959d46bdc0eebf1a81/sale_subscription/controllers/portal.py#L419-L424 And unfortunately, it will be effectively possible to "let the post process of transaction create" the invoices only in Master (the code is not ready yet). For now it would be too risky for a stable version to make such change. ## Solution: We ensure EDI documents are generated whenever a `subscription_action` is set. To achieve this, modify the `_post_subscription_action` hook to call `_subscription_post_success_payment` for any `subscription_action`, including `assign_token`. From `_subscription_post_success_payment`, we can call `_generate_and_send_invoices` on any invoice that has an EDI associated with it, which sends & signs the required EDI documents. opw-4648189 Forward-Port-Of: odoo/enterprise#84815
Creating a new bank statement line could fail when no outstanding accounts were configured. The update skips the affected lookup in that case, allowing accounting users to create bank records without encountering an error.
Original PR description
**Steps to reproduce:** - Install Accounting. - Accounting dashboard → Bank → create a record. - Observe the error. **Error:** ``` psycopg2.errors.SyntaxError: syntax error at or near ")" LINE 16: AND aml.account_id IN () ``` **Cause:** When outstanding accounts is empty, tuple(outstanding_accounts.ids) evaluates to (). This results in an invalid SQL clause `aml.account_id IN ()`, which results in the syntax error at [1]. **Fix:** Ensure the query is only executed with non-empty outstanding accounts, preventing the generation of an empty `IN ()` clause. [1] - https://github.com/odoo/enterprise/blob/c21dfdf0b88bc570ba7e27f6e4c13ff5fdcd31cb/account_accountant/models/account_bank_statement.py#L319-L327 sentry-6834430336
Quality IoT can now distinguish between multiple connected cameras, allowing more than one camera to be used at the same time. Existing camera configurations are preserved through a temporary legacy identifier, and camera communication is made more reliable to avoid websocket errors.
Original PR description
Due to an issue with the `CameraInterface`, the same identifier would be chosen for any connected camera (`camera-2`), meaning only one camera could be used at once. To fix this, the `camera.id`…
Due to an issue with the `CameraInterface`, the same identifier would be chosen for any connected camera (`camera-2`), meaning only one camera could be used at once. To fix this, the `camera.id` property is used as the identifier instead. The `libcamera` documentation says the following: > The camera ID is a free-form string that identifies a camera in the > system. IDs are guaranteed to be unique and stable: the same camera, > when connected to the system in the same way > (e.g. in the same USB port), will have the same ID across both > unplug/replug and system reboots. However, we will also still return the last camera with the `camera-2` identifier, so that existing device configurations in the backend don't get lost. In master we will remove this legacy identifier. You can see the legacy camera with the others in the list below: <img width="801" height="385" alt="image" src="https://github.com/user-attachments/assets/6f3a6408-bcb4-46b0-980e-b5a8881f6df0" /> In addition, another small fix was made to the `CameraDriver` to ensure a string is sent rather than raw bytes, this prevents a traceback when communicating over the websocket. task-4792552 Forward-Port-Of: odoo/enterprise#93076