| Availability |
Odoo Online
Odoo.sh
On Premise
|
| Odoo Apps Dependencies |
•
Invoicing (account)
• Point of Sale (point_of_sale) • Discuss (mail) • Inventory (stock) |
| Lines of code | 101 |
| Technical Name |
pos_default_accounts_at |
| License | OPL-1 |
| Website | https://www.arure.tech |
| Availability |
Odoo Online
Odoo.sh
On Premise
|
| Odoo Apps Dependencies |
•
Invoicing (account)
• Point of Sale (point_of_sale) • Discuss (mail) • Inventory (stock) |
| Lines of code | 101 |
| Technical Name |
pos_default_accounts_at |
| License | OPL-1 |
| Website | https://www.arure.tech |
POS Income & Expense GL
Set a default Income and Expense general-ledger account on each pos.config. At close-of-day, the journal entry routes every untaxed sales line to the configured income account and every stock-expense line to the configured expense account — overriding the per-product / per-category defaults. One setting per shop.
Why this module exists
By default, Odoo POS derives the sales account from each product (or its product category) and the stock-expense (cost-of-goods-sold / COGS) account from the product's expense account. For multi-shop retailers, chain operations, and franchise networks running several POS configurations — one per outlet, region, brand, or country — this means every product has to be configured with the right accounts for every outlet's accounting expectations. That doesn't scale.
This module flips that. Set the income account and the expense account once, on the POS configuration (the shop). At close-of-day, the journal entry uses those accounts on every sales line and every stock-expense line — regardless of what each product specifies.
Two new fields. Two narrow override hooks on pos.session. Zero copy-paste of standard Odoo internals. Five minutes to install, zero migration steps.
At a glance
|
On the POS configuration
2 GL account fields
Income account and Expense account, both
Many2one to account.account, scoped to the company. |
At close-of-day
Account substitution
Sales lines route to the configured income account; stock-expense (COGS) lines route to the configured expense account. Per-tax accounts are untouched.
|
When unset
Standard Odoo behaviour
Leave either field empty and the journal entry uses Odoo's normal per-product / per-category derivation. Switch on per shop, only where you need it.
|
What you get on day one
Every item listed here is verified working on a fresh Odoo 19 instance. No vapourware, no roadmap claims.
|
01
Income account on
pos.configMany2one to account.account, domain-scoped to the configured company and active accounts only. When set, every untaxed sales line on the close-of-day journal entry posts to this account. |
02
Expense account on
pos.configMany2one to account.account, same domain. When set and Anglo-Saxon accounting is enabled, every stock-expense (cost-of-goods-sold) line posts to this account. |
|
03
Surfaces in standard POS Settings
A bridge on
res.config.settings exposes both fields under Settings → Point of Sale → Accounting, beside the Invoice Journal field. No custom menu, no extra navigation. |
04
Substitution at
_get_sale_valsOverride hook on
pos.session._get_sale_vals. Calls super, then replaces the account_id on the sales-line dict when the override is set. 4 lines. |
|
05
Substitution at
_get_stock_expense_valsOverride hook on
pos.session._get_stock_expense_vals. Substitutes the configured expense-account recordset before delegating to super. 4 lines. |
06
Per-shop, not global
Each
pos.config has its own pair of accounts. Set them on Outlet A and leave Outlet B untouched — Outlet B keeps standard per-product derivation. |
|
07
Optional, never breaking
Both fields default to empty. With both unset, the module is a no-op — Odoo's standard close-of-day flow runs unchanged. Roll out one shop at a time without changing the others.
|
08
Zero external dependencies
Depends only on standard Odoo (
base, point_of_sale, account). No Python deps, no external services, no telemetry, no SaaS. |
v14 ancestor — what we improved
| Concept | v14 | v19 (this module) |
|---|---|---|
| Hook strategy | 159-line copy of _accumulate_amounts | Two 4-line overrides on dedicated hooks |
| Settings UI | Form-only | Settings → PoS → Accounting |
| Field domain | Unscoped | Company-scoped, active only |
| Test coverage | None | 7 unit tests, both hooks + bridge |
See it running
Real screenshots from a fresh Odoo 19 test instance after the module is installed and a POS session is closed.
Set the accounts on a POS configuration
Open Point of Sale → Configuration → Point of Sale, choose your shop, scroll to the new Default GL accounts section, set Income Account and Expense Account.
Same fields in standard Settings
The bridge also surfaces them under Settings → Point of Sale → Accounting, beside the existing Invoice Journal field — where accountants expect to find them.
The journal entry produced on close-of-day
After a POS session closes, the journal entry's account-id columns show the configured income and expense accounts on every sales and stock-expense line — not the per-product defaults Odoo would otherwise have used. End-state proof that the override hooks fired.
Models & fields
| Model | Field | Type | Notes |
|---|---|---|---|
pos.config | income_account_id | Many2one(account.account) | Company-scoped, active only |
pos.config | expense_account_id | Many2one(account.account) | Company-scoped, active only |
res.config.settings | pos_income_account_id | Many2one (related) | Bridge to Settings UI |
res.config.settings | pos_expense_account_id | Many2one (related) | Bridge to Settings UI |
pos.session | _get_sale_vals / _get_stock_expense_vals | Method overrides | 4 + 4 lines, super-delegating |
Technical requirements
| Odoo | 19.0 — Community or Enterprise. Tested on .sh and on-premise. Not available on Odoo Online (SaaS) per Odoo's third-party-app policy. |
| PostgreSQL | 12 or later. No extensions required. |
| Dependencies | Standard Odoo only — base, point_of_sale, account. No Python deps. No external services. |
| Multi-company | Account fields are company-scoped via the field domain. Each shop's overrides isolate to its own company. |
| Anglo-Saxon accounting | The expense-account override only fires when stock-expense lines are produced — i.e., when Anglo-Saxon accounting is enabled and the shop sells stockable products. The income-account override fires regardless. |
Install in three minutes
- Install POS Income & Expense GL from the App Store.
- Open Settings → Point of Sale → Accounting, choose the POS configuration in the dropdown, set Income Account and Expense Account, save.
- Open the POS, ring up a transaction, close the session.
- Open the resulting journal entry — confirm sales lines hit the configured income account and stock-expense lines hit the configured expense account.
Full step-by-step instructions are in the bundled README.md; the smoke-test checklist is in SANDBOX_SMOKE_TEST.md.
Risk-free trial: up to 90 days
Odoo's standard policy gives you a 60-day refund window with a 15-day vendor SLA to fix or refund. We extend that with our own 30-day no-questions-asked satisfaction guarantee on top.
Total: up to 90 days in which you can claim a full refund. Issue claims are acknowledged within 1 business day; fix-or-refund within 15 days.
See the bundled REFUND_POLICY.md for the full text and severity definitions.
Support channels
| Channel | For | Response SLA |
|---|---|---|
| support@arure.tech | Bug reports, refund requests, anything that needs an audit trail. | 1 business day |
| WhatsApp +1 858 463 4405 | Quick configuration questions, sanity checks, status updates. | Same business day, Mon–Fri 09–19 IST |
| Odoo App Store claims | Formal claims and refunds under Odoo's published policy. | Per Odoo 15-day SLA |
Both email and WhatsApp feed the same support queue. There is no phone hotline, no live chat overlay, and no 24/7 ops. Severity definitions for S1–S4 are in the bundled SUPPORT.md.
Maintenance commitment
This module receives bug fixes and security patches:
- Until 12 months after Odoo 21 ships (currently estimated at September 2027 at earliest), or
- 18 months after the last paid purchase of v19, whichever is later.
Discontinuation, if it ever happens, is announced in CHANGELOG.md and the listing description at least 90 days in advance.
Frequently asked
pos.session only. Sale orders, invoices, and e-commerce checkouts continue to use Odoo's standard per-product / per-category derivation.account.tax.repartition.line) are untouched._accumulate_amounts?_accumulate_amounts is the long monolithic builder for the close-of-day journal entry. Copy-pasting it (as a v14 ancestor of this concept did) makes every Odoo upgrade fragile. The two narrow methods we override exist precisely as account-substitution hooks and have been stable across recent Odoo versions.License
Odoo Proprietary License (OPL-1). Per-database license. Source code is delivered as part of the App Store package; it is not redistributable.
Trademarks
Odoo is a registered trademark of Odoo S.A. This module is an independent extension developed by Arure Technologies and is not affiliated with, endorsed by, or sponsored by Odoo S.A.
Odoo Proprietary License v1.0 This software and associated files (the "Software") may only be used (executed, modified, executed after modifications) if you have purchased a valid license from the authors, typically via Odoo Apps, or if you have received a written agreement from the authors of the Software (see the COPYRIGHT file). You may develop Odoo modules that use the Software as a library (typically by depending on it, importing it and using its resources), but without copying any source code or material from the Software. You may distribute those modules under the license of your choice, provided that this license is compatible with the terms of the Odoo Proprietary License (For example: LGPL, MIT, or proprietary licenses similar to this one). It is forbidden to publish, distribute, sublicense, or sell copies of the Software or modified copies of the Software. The above copyright notice and this permission notice must be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Please log in to comment on this module