Friday, September 11, 2026
9 changes · master
Enhancements to existing features
Point of Sale now applies employee role permissions more consistently across planning, settle-due, appointment, barcode lookup, sales planning, and UrbanPiper-related screens. This helps businesses limit sensitive actions to authorized staff and reduce operational mistakes at checkout and order management.
Original PR description
**= planning, settle_due, urban_piper Following this commit: ==== - Restricted POS features based on the employee's assigned role. task-6317141 Community PR : https://github.com/odoo/odoo/pull/284182 Upgrade PR : https://github.com/odoo/upgrade/pull/11117
AI agents can now build their knowledge from attachments, documents, knowledge articles, and web pages without first copying everything into attachments. This makes the AI knowledge system more flexible, improves cross-source answers, and avoids showing not-yet-processed content in search results.
Original PR description
Before, `ai.embedding` was geared specifically towards `ai.agent.source` and its attachments: every source had to materialise an `ir.attachment` before it could be vectorised, and RAG retrieval could…
Before, `ai.embedding` was geared specifically towards `ai.agent.source` and its attachments: every source had to materialise an `ir.attachment` before it could be vectorised, and RAG retrieval could only look at one model at a time. This PR generalises the embedding layer so that any model can be embedded and retrieved, and converts the existing source types to use it. ### `ai.embedding.mixin` New mixin owning the `embedding_ids` one2many and the embedding lifecycle. A model inheriting it implements the hooks: content extraction, chunking (tabular-aware), duplicate detection by checksum, domain of the records to embed, and the embedding models to use. Embedding creation is cron-driven, which supersedes `_update_sources_status`. `ai.embedding` itself loses `attachment_id`/`checksum` and gains `res_model`/`res_id`, so a chunk can point at any record. ### Direct embedding of every source type | Source | Before | Now | |---|---|---| | Attachment | embedding logic carried by `ir.attachment` | `ir.attachment` inherits the mixin | | Document | copied into an attachment, then embedded | `documents.document` embedded directly | | Knowledge article | HTML extracted into an attachment | `knowledge.article` embedded directly | | Web page | fetched into an attachment | `ai.web.page` embedded directly | The attachment-copy flows (`_sync_sources_content`, `_recreate_attachments_for_sources`) are dropped. Each model only picks up the records actually linked to an agent source. ### Retrieval - `_get_similar_chunks` now takes a `target_by_model` mapping instead of a single `res_model`, so one similarity search spans embeddings of heterogeneous models. `ai.agent.source._get_rag_target` is the overridable hook returning the (model, id) pair a source is embedded through, and `_get_models_map` builds the mapping. - Chunks whose `embedding_vector` is still NULL are excluded from retrieval. Their similarity was NULL and `NULLS FIRST` is the default for `ORDER BY ... DESC`, so between the creation of a source and the next cron run they outranked every genuine match and took all the `top_n` slots. ### Citations Inline citations reference `ai.agent.source` ids instead of attachment ids, and the link rendering is delegated to `_get_source_link`, implemented per source type (attachment/url in `ai`, document in `ai_documents_source`, article in `ai_knowledge`) instead of a hardcoded `/web/content` URL. The prompt instructions are updated accordingly. ### Also in this PR - `ai.agent.source.type` becomes a computed field, derived from whichever record field is set (`attachment_id`, `web_page_id`, ...). - `ai_app` accepts `.md` files as agent sources: the allowed extensions are extracted into a single `allowedExtensions` getter used both by the file input `accept` attribute and by the client-side validation. Markdown attachments are indexed as plain text, so no server-side change is needed. task-6283960 Upgrade PR: odoo/upgrade#10929
Approval requests no longer require approvers to act in a predefined sequence, so any assigned approver can approve when ready. This removes waiting statuses and next-approver handoffs, making approval workflows faster and less dependent on a strict order.
Original PR description
Previously, there was a sequence or ordering in approvals, the user was not able to approve if it is order hasn't come yet. 1 - Sequence field is deleted, there is no waiting status anymore. 2 - Setting the next approver mechanisms are dropped Test: Unit test to check random ordering in approvals task-6563332
Payroll runs now open directly on the payslips step, removing the previous multi-step flow and making payroll processing more direct. Key payroll actions have been moved to the main toolbar, with list and kanban views updated to keep important status, journal, and action information easy to access.
Original PR description
This PR aims to to completely remove the payrun steps logic (which could be visualized as bubbles in the header of any payrun views). Instead of having the `versions -> time -> payslips` flow, we now…
This PR aims to to completely remove the payrun steps logic (which could be visualized as bubbles in the header of any payrun views). Instead of having the `versions -> time -> payslips` flow, we now always end up on the payslips step by default, which is now the only step left! The payrun button used to validate/mark as paid/pay the payrun has been moved next to the "New" button at the top right corner. Since it relied on a custom compiler and rendering context, we had to move all of that from the payrun layout/payrun mixing to the payrun control panel. Other minor UI changes have been introduced, such as: - Added the states and the journal button in the payrun list view - Added back the action buttons (the one needing a custom compiler) on the kanban view cards - Added some columns on the payrun list view - Added back the paid time off allocation wizard - Added a variant to the t-menu of the kanban cards (that gets generated to a PayRunButtonBox) to make its three vertical dots render as a "More" button instead. - etc. (see the task's escalidraw) task-6486910
Odoo’s PayPal integration now supports guided seller onboarding, more local and alternative payment methods, and saved payment details for eligible merchants. This helps businesses activate PayPal faster, offer customers more ways to pay, and support repeat or subscription-style payments more easily.
Original PR description
**[IMP] payment_paypal: add seller onboarding via OAuth** First party Integrated Sign-Up enables partners to integrate the seller onboarding into their software allowing to seamlessly and securely…
**[IMP] payment_paypal: add seller onboarding via OAuth** First party Integrated Sign-Up enables partners to integrate the seller onboarding into their software allowing to seamlessly and securely onboard sellers before activating PayPal payments. In this commit, we integrate First party Integrated Sign-Up to Odoo. --- **[IMP] payment_paypal: add payment methods** We currently only support PayPal Wallet, but PayPal can also be integrated as a regular payment provider, offering many payment methods, and worldwide coverage. In this commit, we add the following payment methods: - Via PayPal's JS SDK: Pay Later, Venmo, and Advanced Credit and Debit Cards. - Via Orders API: Bancontact, BLIK, EPS, iDEAL, Multibanco, MyBank, Przelewy24, and Trustly. We also migrate PayPal Wallet integration from JS SDK to Orders API to uniformize the look of payment methods through different payment providers. --- **[IMP] payment_paypal: add tokenization support** Before this commit, customers had to re-enter their payment details for every PayPal transaction, and merchants could not charge them offline (e.g., for subscriptions or invoice follow-ups). This commit introduces the ability to tokenize PayPal Wallet and PayPal-provided cards. Tokenization is available if the merchant's account has the advanced vaulting capability enabled. We also handle the case where PayPal creates the vault asynchronously, generating the token via a webhook rather than the immediate checkout response. --- task-6095035
This update improves Odoo VoIP reliability when users receive calls across multiple browser tabs or devices, reducing duplicate call records and missed rings. It also adds QR-code setup for Linphone mobile calling and exposes a protected recovery payload so phone service tenants can be rebuilt if accidentally deleted.
Employee, payroll, and project document folders are now created and connected to the right business records automatically, reducing setup gaps and manual synchronization. HR and payroll access now relies on role-based groups, so new officers can access the relevant company folders without extra updates, while uploaded documents are linked to the correct employee or project more reliably.
Original PR description
### HR refactor Every feature of the HR bridges had to check `documents_hr_settings` and the existence of the company folder before doing anything. Those guards were fragile, easy to forget, and made…
Invoices and sales orders in the South Korea localization can now record the proof of issuance used for each transaction, such as tax invoice, credit card, or cash receipt. This improves VAT report accuracy and reduces manual setup by using customer or vendor defaults while simplifying the tax list businesses need to manage.
Original PR description
South Korean tax law classifies each transaction under a specific proof of issuance (세금계산서, 계산서, 신용카드, 현금영수증, ...), and which VAT report box a transaction is reported under depends on that…
South Korean tax law classifies each transaction under a specific proof of issuance (세금계산서, 계산서, 신용카드, 현금영수증, ...), and which VAT report box a transaction is reported under depends on that classification, not just on its taxes. Add `l10n_kr_issuance_type` to `account.move` so this can be recorded per invoice and used to drive VAT report generation. Since a given customer or vendor typically uses the same proof of issuance across transactions, add `l10n_kr_default_issuance_type` on `res.partner` (under Customer Invoices) so users don't have to pick it manually every time. `sale.order` carries the same field and passes it along when an invoice is created from the order, so issuance type can be set from the Sales app without needing access to Accounting. Also add: - `l10n_kr_edocument_number` on `account.move`, next to Customer Reference, to record the e-document number issued for the transaction. - South Korea's Tax ID label (`res.country.vat_label`) as "BRN" (Business Registration Number), matching local terminology. Now that proof of issuance is tracked separately, the `account.tax` templates no longer need one tax per rate/issuance-type combination: collapsed ~64 taxes (e.g. separate `10% TI`, `10% CR`, `10% Card` sales taxes) down to ones keyed only by rate and nature (standard, zero-rated, exempt, fixed-asset, non-deductible, deemed/recycled input VAT, ...), carrying just the base VAT tag. `general_tax_report.xml` and `simplified_tax_report.xml` were updated to derive their per-issuance-type boxes from `l10n_kr_issuance_type` on the move directly instead. [task-6216393](https://www.odoo.com/odoo/my-tasks/6216393)
Loyalty programs can now set an expiration period for earned points, helping businesses manage outstanding rewards more accurately. Customers can see when their points expire, and the system uses points nearing expiration first so balances better reflect usable rewards.
Original PR description
Loyalty points had no expiry, and `loyalty.history` was only a log kept beside the balance: `loyalty.card.points` was a stored column, and the rows recorded what an order earned and spent without either side being authoritative. Expiring points needs to know which points are which, so the history becomes the balance itself. `points` is now computed from it, and a row records one movement in one direction. A line spending points links to the award it draws from, so it stops counting once those points expire, and a spend with no award behind it never expires. Awards are drawn from oldest expiry first, so the points closest to lapsing are used before the ones that are not. Programs of type `loyalty` gain an `expire_after` delay in days, and the portal shows the customer when each award expires. task-4711900 Enterprise PR: https://github.com/odoo/enterprise/pull/125634 Upgrade PR: https://github.com/odoo/upgrade/pull/10869
### HR refactor Every feature of the HR bridges had to check `documents_hr_settings` and the existence of the company folder before doing anything. Those guards were fragile, easy to forget, and made the bridges harder to extend. As recently done for the other bridges, an installed bridge is now always used: the "Employees" folder of a company is required and created with it, and every employee of an active company gets their folder(s). Sharing relies on functional groups rather than on a copy of the HR (resp. payroll) officers on each folder, so a new officer reaches the folders of their companies without any resynchronisation. All payroll documents now end up in the employee's Payroll folder, which belongs to documents_hr_payroll alone. ### Documents mixin for employees and projects Employee and Project *folders* are now also linked to the record they belong to and documents inherit that link from their parent folder. Therefore, documents uploaded in such folders will automatically be linked to the record. Task-6344800 Task-6310302