Skip to main content
Nerve Centre KPIs · Audit Profile · Sentiment Settings Odoo merchants run storefront, stock, and books in one database, so the health questions span commerce AND finance. This audit answers: (1) is the XML-RPC / JSON-RPC credential healthy and scoped to Sales + Inventory + Accounting, (2) is revenue recognised - confirmed sale.order rows actually becoming posted account.move customer invoices, (3) is stock integrity holding - no negative on-hand, no published out-of-stock leaking sales, catalogue rows complete, and (4) where does revenue leak when Odoo is joined to ads / marketplace / email / ecom siblings (single-DB joins are unusually clean because Odoo is the source of record).

What this audit checks

Authentication & access

  • API key / password authenticates against the configured database (authenticate→uid on /xmlrpc/2/common; version() probe succeeds)
  • host_url resolves and serves the expected Odoo major version (16 / 17 / 18 in scope)
  • Integration user has read access to sale.order, product.product, account.move, res.partner, stock.quant
  • Edition matches configured value - Accounting (account.move analytics) requires Enterprise; finance checks no-op on Community

Revenue recognition & GL health

  • Confirmed sale.order (state=sale/done) with no posted account.move out_invoice after 7d - revenue not recognised in the books
  • Posted customer invoices overdue (invoice_date_due < today AND payment_state != paid) above receivables threshold
  • Draft account.move (out_invoice) older than the close cadence - invoicing backlog stuck before posting
  • Refund / credit-note value (out_refund) as a share of out_invoice value above threshold - returns or fulfilment quality problem

Stock integrity

  • stock.quant rows with quantity < 0 (negative on-hand) - oversell / stock-move integrity failure
  • Published products with available_quantity <= 0 - out-of-stock leaking onto the live storefront
  • Products below configured reorder point and falling - restock before stockout
  • Slow-moving inventory value (no stock-move in 90d) above share-of-inventory threshold - tied-up working capital

Catalogue & merchandising quality

  • Published product.product missing image_1920 (no image) - conversion + SEO leak
  • Published products with empty description_sale - thin content, weak organic ranking
  • product.product with empty default_code (internal reference / SKU) - breaks cross-channel SKU joins
  • Published products with list_price = 0 or null - unsellable or mis-priced storefront rows

Cross-channel: revenue-at-risk (the killer area)

  • Active ad spend (google_ads / amazon_ads product_ad) on products whose Odoo available_quantity <= 0 (sibling = ad_platform)
  • Price / title drift between Odoo product (source of record) and marketplace/ecom listing on default_code=sku (sibling = marketplace / ecommerce_platform)
  • Repeat ecom customers absent from Odoo res.partner after 7d, by email (sibling = ecommerce_platform)
  • Confirmed ecom-channel orders with no matching Odoo sale.order, or B2B partner VAT mismatch vs ecom (sibling = ecommerce_platform)
  • Email-attributed share of confirmed Odoo revenue dropping > 25% vsP (sibling = email_marketing)

Severity thresholds

SignalWarnCritical
unrecognised_revenue_orders_count110
overdue_receivables_pct515
refund_credit_rate_pct35
negative_onhand_count15
published_out_of_stock_count110
catalogue_incomplete_pct515
slow_mover_inventory_pct1020
cancellation_rate_pct58
ads_spend_on_oos_amount1100

Data sources

  • POST https://{host_url}/xmlrpc/2/common - authenticate (uid) + version() auth/identity probe
  • POST https://{host_url}/xmlrpc/2/object - execute_kw search_read / read_group / search_count over sale.order, product.product, account.move, res.partner, stock.quant
  • POST https://{host_url}/jsonrpc - JSON-RPC equivalent of execute_kw (service=object) - same models/fields