OVES Odoo Multi-Company Inventory Audit — Finding & Remediation Plan¶
Audit date: 2026-07-02
System: enterprise.omnivoltaic.com (Odoo 18 Enterprise)
Prepared by: WorkBuddy AI
Status: Confirmed — Awaiting Remediation
0. The Inquiry — Template for Future Investigations¶
This section captures the original inquiry that triggered the audit, rephrased into a structured form. It is included as a template so the team can learn how to frame effective inquiries when investigating operational issues in Odoo. A well-structured inquiry gives the analyst (human or AI) the context needed to verify against live data — and dramatically shortens the time to root cause.
The Inquiry (Rephrased)¶
1. Business Context — What is the setup?
OVES operates as a group of independent legal entities sharing a single Odoo 18 instance. Each company has its own finance, logistics, and sales organizations. The single-instance setup must not erase the legal boundaries between entities.
- HM (Shenzhen) — Manufacturing
- HK (Hong Kong, China) — International trade
- OVT (Togo), OVTZ (Tanzania), OVK (Kenya), etc. — Local distributor companies in various countries
2. Intended Process — What should happen?
HM manufactures and sells to the local companies. The typical flow is: HM sells first to the HK entity, then HK sells on to the local companies. Each leg is a proper inter-company transaction:
- HM sells and ships → HM warehouse inventory is consumed
- Local company buys and receives → product appears in their respective inventory
3. Observed Problem — What actually happened?
Our team has not properly set up this flow. The symptoms we observe:
- Odoo appears to have created a "Partners" central warehouse concept that may have simulated a central purchase process
- We did not properly execute the ship/receive transactions
- The Partners warehouse was empty (0 products on hand)
- Operators then performed stock moves FROM the empty Partners warehouse
- This caused negative stock levels at Partners
4. Specific Observation — A concrete example
OVT (Togo) tried to perform a stock move from the Partners warehouse, which had 0 products on hand. Even after the stock move was executed, OVT still shows zero stock. The move did not result in any actual inventory appearing at the destination.
5. Hypothesis — What I think went wrong
The "central warehouse" concept was misapplied. By treating Partners as a real warehouse and doing direct stock moves from it — instead of running the proper SO/PO/ship/receive chain — we bypassed the financial and inter-company controls. Goods never actually existed at Partners, so moves from it created negative quants and left destination warehouses empty.
6. The Ask — What I need from the analyst
Please review the actual Odoo data and advise whether my analysis is correct. Specifically:
- Confirm or correct my understanding of how Partners/总仓库 was used
- Verify whether the ship/receive transactions were actually executed
- Confirm whether OVT's stock is truly zero and why
- Identify the root cause
- Advise on remediation
Why This Inquiry Was Effective¶
The inquiry above worked because it followed a structure that any analyst (human or AI) can act on without guessing. Future investigations should follow the same pattern:
- Business context first — explain the setup so the analyst doesn't have to infer it. Name the entities, their roles, and the constraints (e.g., "single instance must not erase company boundaries").
- Intended process explicit — state what should happen, step by step. This gives the analyst a baseline to compare against.
- Observed problem separated from hypothesis — describe what you see (symptoms) separately from what you think caused it (root cause). This lets the analyst verify each independently.
- Concrete example — give one specific instance (OVT, Partners warehouse, zero stock). This anchors the investigation and gives the analyst a starting query.
- Hypothesis stated openly — don't hide your guess. Say "I think X happened" so the analyst can confirm or challenge it with data.
- Explicit ask — list exactly what you need back (confirm/correct, verify, identify root cause, advise). Vague asks produce vague answers.
Anti-pattern to avoid: "Something is broken, please fix it." An inquiry with no context, no intended process, and no concrete example forces the analyst to spend most of their time reconstructing the problem rather than solving it.
TL;DR¶
The team treated a virtual supplier location (Partners/总仓库, id=4, usage=supplier) as a real central warehouse, bypassing the entire SO/PO/ship/receive chain. This caused 100+ products to accumulate massive negative stock, and left OVT (Togo) with zero inventory despite goods having "shipped" from the source. The user's original analysis was correct in every particular.
1. Business Context¶
OVES operates as a group of independent legal entities sharing a single Odoo 18 instance. Each company has its own finance, logistics, and sales organizations. The single-instance setup must not erase the legal boundaries between entities.
| Company | Country | Currency | Role |
|---|---|---|---|
| Oves Shenzhen (HM) | China | CNY | Manufacturing |
| Oves Holdings (HK) | Hong Kong, China | USD | International trade |
| Oves Togo (OVT) | Togo | CFA | Local distributor |
| Oves Kenya (OVK) | Kenya | KES | Local distributor |
| Oves Tanzania (OVTZ) | Tanzania | TZS | Local distributor |
| Oves Philippines | Philippines | PHP | Local distributor |
| Oves Ethiopia | Ethiopia | ETB | Local distributor |
Intended trade flow: HM manufactures → sells to HK → HK sells to local companies. Each leg is a proper inter-company transaction with SO/PO + ship + receive.
2. The Problem (As Reported)¶
User's original hypothesis:
"Odoo created a central warehouse concept (Partners) that might have simulated a central purchase process. But we did not properly do the ship/receive transactions, so the Partners warehouse was empty. Then people started to do stock moves from it, causing negative stock levels. OVT tried to do a stock move from the Partners warehouse, which had 0 products — as a result, even after the stock move, OVT still has zero stock."
3. Evidence Gathered (Live Odoo Data)¶
3.1 Partners/总仓库 (id=4) — the problem location¶
| Attribute | Value | Significance |
|---|---|---|
| Usage type | supplier |
Virtual location — cannot hold positive stock |
| Company ownership | false (none) |
No company boundary enforced |
| Positive quants (ever) | 0 | Never held a single unit of real stock |
| Negative quants | 100+ products | Massive holes from one-way outbound moves |
3.2 Worst negative balances at Partners/总仓库¶
| Product | Quantity |
|---|---|
| L220 (OVES-B06-0132) | −55,000 |
| HS2506-SPSF-16 | −25,231 |
| SHS40_12W_L22_S2 | −19,493 |
| Mini Torch | −17,508 |
| MB2-290 | −17,128 |
| 2W灯泡 | −15,380 |
| RD (OVES-B07-0130) | −13,500 |
| MB2-200 | −11,440 |
| ...and 90+ more |
3.3 OVT Warehouse (id=103) — completely empty¶
- Stock quants in OVT Warehouse: 0
- Stock moves ever recorded for Oves Togo (company_id=4): 0
OVT has never had a single stock move recorded in the system — not one receipt, not one delivery.
3.4 L220 trace — where did the goods go?¶
| Location | Quantity | Company |
|---|---|---|
| Partners/总仓库 (supplier) | −55,000 | none |
| Inter-company transit | +55,000 / −55,000 (nets to 0) | none |
| OVT Warehouse | 0 | Oves Togo |
The 55,000 units left Partners/总仓库, entered inter-company transit, left transit — and arrived nowhere. The final destination move (transit → OVT Warehouse) was never completed.
3.5 Inter-company PO flow — missing¶
Only two POs from HK buying from HM exist — both empty (amount 0) and never confirmed:
| PO | Vendor | Buyer | State | Amount |
|---|---|---|---|---|
| P00771 | HM | HK | draft | 0.00 |
| P00772 | HM | HK | cancel | 0.00 |
HK has never actually purchased anything from HM through the proper PO flow.
3.6 Inter-company SO flow — stops at HK¶
The HK→Local leg of the trade does not exist in the SO/PO records:
- HK → OVT (Togo): zero SOs
- HK → OVTZ (Tanzania): zero SOs
- HK → Philippines: zero SOs
- HK → Ethiopia: zero SOs
- OVT buying from HK: zero POs
3.7 Stock moves are gone — but the damage remains¶
Searching stock.move for location_id = 4 returns 0 results. But the quants prove moves happened. The moves were archived/deleted, but the stock quants they created were never reverted. Orphan negative quants with no visible move history.
4. Confirmation of Root Cause¶
Confirmed: The use of the virtual warehouse was incorrect.
The team set up Partners/总仓库 as a fake central warehouse to bypass the entire inter-company trade document chain. Goods were pulled from it via direct internal stock moves — no Purchase Order, no Sales Order, no Delivery Order, no Receipt, no invoice, no accounting entry.
Hypothesis vs. evidence¶
| Hypothesis | Verdict |
|---|---|
| "Odoo created central warehouse concept (Partners)" | ✅ Confirmed |
| "We did not properly do ship/receive transactions" | ✅ Confirmed — zero completed inter-company POs |
| "Partners was empty, stock moves caused negatives" | ✅ Confirmed — 0 positive quants, 100+ negatives |
| "OVT tried to move from Partners (0), OVT still 0" | ✅ Confirmed — 0 quants, 0 moves at OVT |
5. Five Specific Errors Identified¶
| # | Error | Why it's wrong |
|---|---|---|
| 1 | Type mismatch | Partners/总仓库 is usage=supplier (virtual), but named "总仓库" (Central Warehouse) and used as if usage=internal (real). |
| 2 | Direct stock moves instead of PO receipts | Goods should have been received FROM a supplier location via Purchase Order → Receipt. Direct stock.move bypasses all financial and inter-company controls. |
| 3 | No vendor partner on the "supply" | Partners/总仓库 has no partner_id — there's no vendor identity saying "this came from HM" vs "this came from HK". |
| 4 | No company ownership | Partners/总仓库 has company_id = false (no company). Moves could be booked under any company — boundaries not enforced. |
| 5 | Bypassed inter-company transit | Proper flow uses transit location (id=6/214/215) as the bridge. Partners/总仓库 was used as a shortcut, skipping transit. |
6. Correct Flow¶
Partners/总仓库 should never have been a "warehouse" at all. The correct setup is:
- Each OVES company has its own real internal warehouse (HM总仓, HK Warehouse, OVT Warehouse, OVK STOCK, etc.) — these already exist.
- Inter-company trade goes through SO/PO + transit:
HM creates SO (customer=HK) → HK auto-creates PO (vendor=HM)
HM creates Delivery Order → source: HM总仓, dest: Inter-company transit
HM ships → HM总仓 stock ↓, transit stock ↑
HK creates Receipt → source: Inter-company transit, dest: HK Warehouse
HK receives → transit stock ↓, HK Warehouse stock ↑
(same pattern for HK → OVT / OVK / OVTZ / PH / ET)
- Partners/总仓库 is only used for genuine external vendors (e.g., HM buying raw materials from 东莞亿为新能源). The negative quant there is normal and expected, backed by a real PO.
- No direct stock moves between companies, ever. Operators must use the SO/PO/picking UI — Odoo's inter-company rules enforce this automatically once configured.
7. Remediation Plan¶
Q1: Can the existing mess be fixed with WB AI's help?¶
Yes, mostly. WB AI does the technical heavy lifting; the user provides business decisions. Work proceeds in approval-gated batches.
What WB AI CAN do: - Quantify the full scope (pull all negative quants, build reconciliation matrix) - Trace where goods actually went - Propose corrective moves (reverse or write off) - Execute corrections in batches of ≤10 products with approval per batch - Verify post-correction state - Generate audit trail
What needs human decision: - Decide who bears the loss (write-off allocation) — User + Finance - Verify physical stock at OVT/OVTZ — Local warehouse managers - Decide ownership of disputed goods — User + Sales - Approve write-offs above threshold — User - Restore deleted stock moves — Irreversible
Execution Pre-Conditions (Go/No-Go Gate)¶
WB AI proposes the process — WB AI does not execute until ALL four conditions below are satisfied. This is a hard gate. No execution step (Phase C cleanup, Phase D prevention config) may run until the team has signed off on each item.
| # | Pre-Condition | What it means | Sign-off |
|---|---|---|---|
| 1 | Proper setup requirements are met | All prerequisite configuration is in place before any execution: backup of current state taken, inter-company transit locations verified, target warehouse per company confirmed, negative-stock setting documented (current state) so it can be reverted if needed. WB AI produces a pre-execution setup checklist; team confirms each item. | OVES warehouse lead + Finance |
| 2 | Team understands what WB is about to do | Before each batch, WB AI produces a plain-language action sheet: "I will move X units of product Y from location A to location B, expected result Z, reversal path R." Team reviews and explicitly approves. No blind execution. Walkthrough session recorded or minuted. | OVES operations manager |
| 3 | Team can see the results of remedies | Every execution batch produces a before/after snapshot: quants before, quants after, delta, document references (stock.move IDs, inventory adjustment IDs). Team receives a per-batch report and can verify in the Odoo UI themselves. No "trust the AI" — visibility is mandatory. | OVES warehouse lead |
| 4 | Reversal path, or sandbox simulation first | Two options, at least one must be active: (a) Reversal — every corrective action is paired with a documented reverse action (e.g., if we create an inventory adjustment, we record the offsetting adjustment that would undo it). If a correction goes wrong, the reverse action is executed within the same approval flow. (b) Sandbox simulation — if reversal on production is not safe (e.g., write-offs that hit accounting), the correction is first simulated in the existing Test Company environment (companies id=14 and id=2 mimic seller/buyer transactions). The team reviews the simulation result, then approves a controlled production run. | User + Finance |
Sandbox first, production second. Wherever a Test Company simulation is feasible, it runs first — no exceptions. The OVES Odoo instance already has Test Company (id=14) and OV Kenya(Test) (id=2) set up to mimic seller/buyer transactions. These are the simulation grounds. A correction that works in sandbox and is reviewed by the team is then eligible for a controlled production run.
Phased Plan¶
| Phase | What | Who | Duration | Gate |
|---|---|---|---|---|
| A. Quantify | Pull full negative quant list, trace destinations, build reconciliation matrix | WB AI (read-only) | ~30 min | None — read-only |
| B. Decide | User reviews matrix; decides write-off vs reversal per category | User + Finance | 1-2 days | None — decision only |
| C. Cleanup | Execute corrections in batches ≤10 products, with approval per batch | WB AI + User | 1-2 weeks | GO/NO-GO GATE — all 4 pre-conditions |
| D. Prevent | Turn off negative stock, configure inter-company rules, restrict access | WB AI + User | 2-3 days | GO/NO-GO GATE — all 4 pre-conditions |
| E. Monitor | Scheduled scan + alerts; WB AI weekly audit | WB AI | Ongoing | None — read-only |
| F. Document | Write canonical flow doc + operator training material | WB AI + User | 2-3 days | None — documentation only |
Recommended sequence: Do NOT do cleanup before prevention. Clean up first → operators keep making new mistakes → never catch up. Instead: 1. Layer 1 prevention stops the bleeding 2. Layer 3 quick wins restrict access 3. Then cleanup in a controlled environment 4. Then Layer 2 inter-company rules 5. Then monitoring + docs
8. Prevention Layers¶
| Layer | What | Effort | Impact |
|---|---|---|---|
| Layer 1 | Turn off "Allow Negative Stock" on all internal locations | 10 minutes | Single biggest win — would have prevented 100% of current mess |
| Layer 2 | Configure Inter-Company Rules for each company pair (HM↔HK, HK↔Local) | 1-2 days | Eliminates 90% of future errors — system auto-creates matching PO/SO |
| Layer 3 | Multi-company access rules: OVT user only sees OVT warehouses; restrict raw stock.move creation; hide Partners/总仓库 from operators |
1 day | Eliminates root cause — operators can't do cross-company moves |
| Layer 4 | Scheduled action: daily negative quant scan + email alert; WB AI weekly audit; monthly reconciliation report | Ongoing | Early detection — catch issues before they grow |
| Layer 5 | Canonical flow documentation + operator training + decision tree | 2-3 days | Sustainable — operators know what NOT to do |
9. Appendix — Key Location IDs¶
| Location | ID | Usage | Company |
|---|---|---|---|
| Partners | 2 | view | none |
| Partners/总仓库 | 4 | supplier | none |
| Partners/Customers | 5 | customer | none |
| Inter-company transit | 6, 214, 215 | transit | none |
| HM总仓/库存 | 126 | internal | HM (17) |
| HM研发仓/库存 | 186 | internal | HM (17) |
| OVT Warehouse | 103 | internal | Oves Togo (4) |
| OVK STOCK | 113 | internal | Oves Kenya (11) |
| OVES/Stock | 280 | internal | Oves Tanzania (19) |
Methodology¶
All evidence was gathered via read-only Odoo XML-RPC queries against stock.location, stock.quant, stock.move, sale.order, purchase.order, and res.company. No data was modified during the audit.
Disclaimer: This document is an evidence-based audit finding prepared by WorkBuddy AI from live Odoo data on 2026-07-02. It is intended for internal OVES team review and remediation planning. It does not constitute financial or legal advice. Write-off decisions, loss allocation, and physical inventory counts require human judgment and approval. All remediation actions on the Odoo system must be approved by an authorized OVES manager before execution.