Production-ready Warehouse Management System on Odoo 19 Community Edition, purpose-built for an internal-stock trust (no sales, no invoices, no money). Runs natively on Windows — no Docker required.
What's in the box:
- 🏗 Visual rack builder — Rack → Compartment → Slot, plus open Floor Zones, with a per-rack flexible grid (4-way D-pad merging)
- 📦 Scan-driven workflows — Scan Receipt / Scan Return / Scan Issue (FIFO across slots) / Scan-Validate
- 🧾 Audit trail invariant — every stock-moving action records
wms_taken_by/wms_ordered_by/wms_storekeeper_idon the resultingstock.pickingplus a chatter message - 👥 Tiered role security — 3 base roles (Manager / Store Keeper / Repair Tech) + optional Buyer, layered with 5 capability sub-groups (scan-receive / scan-issue / file-damage / submit-audit / manage-catalog), plus an admin-maintained roster of human keepers
- 🔧 Damage / Repair workflow — smart recommendation engine (urgent buy / repair / note only) + one-click Create Repair Order, full state machine (draft → in_repair → done / scrapped / cancelled) with chatter audit on every transition
- 🏷 Thermal labels — customisable 4×1 inch (100×25 mm) die-cut layout (logo / title / SKU / barcode), inline barcode, printer gap-sensor aware
- 🔁 Returnability classification — product Kind (Raw / Packaging / Fluid / Finished Good / WIP / Consumable / Tool / Spare) drives whether Scan Return accepts it
- 📈 Buying recommendations — daily-average usage + 7-day buffer for non-returnables; concurrent-users heuristic for tools/spares
- 📊 Reports — Where-is-it / Warehouse map / Oldest stock (FIFO) / Slot occupancy / Cycle count due / Movement history / Low stock alerts / Dead stock / Reorder summary
- 🖥 Executive Dashboard at
/wms/dashboard— one manager-only screen: health, stock totals, attention badges, today's activity - 🔎 Smart Find at
/wms/find— type a name / SKU / barcode → slot + qty, or tap a chip ("low stock", "expiring", "dead stock", "damaged", "under repair") - 💰 Cost / value reports — Stock Value, Consumption Value (broken down by purpose: Cows / Pooja / Maintenance / …), Product Lifecycle, plus value-at-risk on Expiry / Damage / Dead Stock
- 🎯 Issue dimensions — every Scan Issue captures a configurable Department (Gaushala / Veterinary / Dairy / Fodder / …), an optional Purpose and Animal/cow, driving consumption-by-department pivots (the legacy Issued for tag is auto-derived for back-compat)
- 🔒 Issue approvals — a min-life re-request guard (same department, same product, too soon) and a configurable high-value threshold route an issue to a manager-only Approvals queue; the keeper types a reason but cannot self-approve, and approval re-checks stock before issuing
- ↩️ Returnable items — tools / spares can be marked returnable with an expected-return period; a daily alert + Returns-due report surface overdue items, and Scan Return clears them
- 🔔 Alert hardening — low-stock / expiry / backup-stale / restore-fail / health-CRITICAL alerts delivered to every WMS Manager's Discuss Inbox (via
message_notify), with optional email viawms_reports.alert_email - ↩️ One-click Undo within a configurable window (default 15 min) — compensating internal transfer, no deletes
- 🧪 One-button Self-Diagnostics — DB / backup-file / disk / duplicate-SKU / orphan-slot / negative-stock probes in one screen
- 📐 Opt-in slot capacity enforcement (
wms_location.enforce_capacity) - 🤖 Offline AI demand forecasting — statsmodels-based, runs locally, no external API
- 🛡️ Off-site encrypted backup copy —
BACKUP_OFFSITE_DIR(USB, network share, OneDrive sync folder — all just paths), SHA-256 verified after copy - ☁️ Google Drive cloud backup (optional) — every encrypted backup set uploaded to an
Inventory_BackupsDrive folder (drive.fileminimal scope,sha256Checksum-verified, tiered retention), plus an in-app Backup Now button
One-shot installer — installs PostgreSQL 15/16/17 (auto-detected; winget installs 17 by default), Python 3.12, wkhtmltopdf, Git
via winget, clones Odoo 19 source, sets up a Python venv, and initialises
the database. Takes ~10 minutes the first time.
# From an Administrator PowerShell:
git clone https://github.com/udhay8005/Inventory-management.git
cd Inventory-management
copy .env.example .env # edit and change DB_PASSWORD
scripts\install-native.ps1Then start the server:
scripts\start-native.ps1Open http://localhost:8069. Sign in as admin / admin (change the password
immediately under your user profile). In Apps install in this order:
wms_location— racks, slots, floor zones, role groupswms_fifo— FIFO removal across slotswms_barcode— scan wizards, barcode aliases, storekeeper roster, thermal labelswms_repair_damage— damage / repair / return workflowswms_ai_forecast— offline statsmodels forecasting + reorderwms_reports— SQL-view dashboardswms_training— Help Center, guided tours, visual academy, SOPs
The admin user is added to WMS / Manager on first install. To onboard
a Store Keeper:
- WMS → Configuration → Store Keepers — add the human names that will appear in audit forms (Ramesh, Lakshmi, Suresh, etc.). The roster is what keepers pick from at scan time; it's not Odoo accounts.
- Settings → Users & Companies → Users → Create — make ONE shared Odoo login per shift (e.g.
storekeeper) and assign role WMS / Store Keeper. - The keeper signs in, picks their name from the on-duty roster in every wizard; the picking records who-physically-did-it (audit) + who-the-Odoo-account-is (login).
Two-tier role model: pick a base role, then layer capability sub-groups on top of Store Keeper as needed.
Three base roles + an optional Buyer role:
- WMS / Manager (
group_wms_manager) — full admin: racks, slots, products, roster, label layout, repair lifecycle, all reports - WMS / Store Keeper (
group_wms_user) — runs the desk; capability sub-groups gate which scan / damage / audit / catalog wizards they can open - WMS / Repair Tech (
group_repair_tech) — handles in-repair items (start / mark done / scrap / cancel); no scan wizards, no catalog edits - WMS / Buyer (
group_buyer, optional) — reads reorder summary + buying recommendations; does not move stock
Then layer capabilities (all sub-groups of Store Keeper, namespace wms_location.*):
group_wms_can_scan_receive— Scan Receipt / Scan Returngroup_wms_can_scan_issue— Scan Issue (FIFO across slots)group_wms_can_file_damage— file a Damage event, create Repair Order from itgroup_wms_can_submit_audit— submit cycle-count auditsgroup_wms_can_manage_catalog— barcode aliases, storekeeper roster entries
Full role model + ACL detail in 08-security.md.
Every action that moves stock records the audit triplet:
- Reported by / Taken by / Delivered by — the human who physically handled the goods
- Authorised by / Ordered by — who approved the move
- Store Keeper on duty — who was running the desk (picked from the roster)
These fields are mirrored onto the resulting stock.picking plus a chatter
message, so reports keyed off stock.picking read damage / repair / receipt
moves the same way. The damage and repair workflows refuse to leave draft
when any of the three fields is blank.
# Core server lifecycle
scripts\start-native.ps1 # Start the server
scripts\start-native.ps1 -Upgrade wms_barcode # Restart upgrading a module
scripts\start-native.ps1 -Dev "reload,qweb" # Dev mode (auto-reload)
scripts\stop-native.ps1 # Graceful stop
# Run as an auto-starting Windows service (recommended for production)
scripts\install-odoo-service.ps1 # Create Odoo-WMS service (UAC) — auto-start + restart-on-failure
scripts\uninstall-odoo-service.ps1 # Remove the service
scripts\set-user-passwords.ps1 -Users "admin,storekeeper" # Set strong unique passwords (printed once)
# Backup + recovery
scripts\backup-native.ps1 # Dump DB + zip filestore
scripts\reset-pg-password.ps1 # Forgot postgres password? Run this (UAC).
# Optional add-ons (run in a separate PowerShell window)
scripts\start-ai-worker.ps1 # Out-of-process forecast worker
scripts\start-tunnel.ps1 # Quick Cloudflare HTTPS tunnel
scripts\start-tunnel.ps1 -Mode Named # Permanent tunnel (needs CLOUDFLARE_TUNNEL_TOKEN in .env)PostgreSQL 15/16/17 (auto-detected; winget installs 17 by default) runs as a Windows
service (postgresql-x64-15/16/17) and auto-starts on boot, so the database is
always there waiting.
Inventory_mngt/
├── .odoo/ Odoo 19 source clone (created by install-native.ps1)
├── .venv/ Python venv with all deps (ditto)
├── .runtime/ data_dir + logs (ditto)
├── config/odoo.native.conf Native Odoo config (generated by install-native.ps1)
├── requirements.txt Project Python extras (statsmodels, pandas, reportlab, ...)
├── scripts/
│ ├── install-native.ps1 One-shot installer
│ ├── start-native.ps1 Start Odoo
│ ├── stop-native.ps1 Stop Odoo
│ └── backup-native.ps1 Dump + zip
├── ai_worker/ Optional out-of-process forecast runner (statsmodels)
│ Run natively via scripts\start-ai-worker.ps1
├── docs/ Architecture & design notes
└── addons/
├── wms_location/ Rack/Compartment/Slot model + role groups + rack builder OWL component
├── wms_fifo/ FIFO removal across slots + partial index
├── wms_barcode/ scan wizards + barcode aliases + storekeeper roster + label printing
├── wms_repair_damage/ damage / repair / return flows + recommendation engine
├── wms_ai_forecast/ offline statsmodels forecasting + reorder
├── wms_reports/ SQL-view dashboards (Where-is-it, FIFO age, occupancy, ...)
└── wms_training/ Help Center, guided tours, visual academy, SOPs
Start here — onboarding & operations:
- 📘 Installation & Setup Guide — deploy from scratch (15 phases, with checkpoints + troubleshooting)
- ⚡ Admin Quick Start — the ~15-minute admin path
- 🧰 Store Keeper Quick Start — the ~10-minute operator path
- 📜 Historical v19.0.5 sign-off — preserved as the v19.0.5 production-readiness record; see CHANGELOG for the current release
- 💾 Backup & Recovery Guide — encrypted backups + weekly restore drill
- 🎓 Training Guide — the in-app Help & Training academy
- 🔐 Security Policy — supported versions + how to report a vulnerability
Architecture, design notes, and operational guides:
docs/01-architecture.md— stack & layeringdocs/02-data-model.md— why we extendstock.locationdocs/03-workflows.md— inbound / outbound / repair flowsdocs/04-barcode-flow.md— scanner integration + carton aliasesdocs/05-ai-prediction.md— algorithm choice + offline footprintdocs/06-reports.md— every dashboard, what it shows, howdocs/07-deployment.md— production deploy + restoredocs/08-security.md— role model, ACLs, record rulesdocs/09-roadmap.md— phased build plandocs/10-testing.md— test strategydocs/11-maintenance.md— upgrades, tuning, FAQdocs/12-mobile-access.md— phones / tablets / off-sitedocs/13-operations-playbook.md— daily / weekly / monthly opsdocs/14-sku-naming.md— product code conventionsdocs/15-onboarding-script.md— first-day Store Keeper trainingdocs/16-hardware-guide.md— scanners + thermal printersdocs/17-ci-cd.md— GitHub Actions pipeline + release flowdocs/20-end-to-end-flow.md— full lifecycle ASCII diagramdocs/22-gdrive-backup.md— Google Drive off-site backup: setup, Backup Now, restoredocs/PRODUCTION-READINESS-v19.0.5.md— historical sign-off record (v19.0.5)docs/RUN-AS-SERVICE.md— run Odoo as an auto-starting Windows servicedocs/LABEL-PRINTING.md— thermal 4×1 labels + printer gap calibrationdocs/ISSUE-DIMENSIONS.md— Department / Purpose / Animal on every Scan Issue + consumption-by-departmentdocs/UOM-BY-KIND.md— product Kind sets the base unit at onboarding (fluid → Litre, feed → kg, else Units)docs/RETURNABLE-ITEMS.md— returnable items, expected-return SLA, overdue alert + Returns-due reportdocs/ISSUE-APPROVALS.md— min-life re-request guard + high-value threshold → manager-only Approvals queue
The simplest local path:
# Right-click PowerShell → Run as Administrator, then:
New-NetFirewallRule -DisplayName "WMS Odoo" -Direction Inbound -LocalPort 8069 -Protocol TCP -Action Allow…then phones on the same WiFi can open http://<host-IP>:8069. For
permanent HTTPS over the internet, run a Cloudflare named tunnel via
cloudflared.exe — see docs/12-mobile-access.md.
The scan wizards are mobile-responsive and open the device camera for the optional item photo (required for liquid / weight / volume items).
USB / Bluetooth HID barcode scanners "just work" — they keyboard-type into the focused field on the scan wizards. Any thermal printer your host OS can see will print the generated PDF labels. Tested with True-Ally 4×1 inch (100×25 mm) die-cut direct-thermal stock on a TSC TE244 (gap-sensor); layout is admin- configurable so other label sizes work too. See docs/LABEL-PRINTING.md.
.venv\Scripts\activate
python .odoo\odoo-bin -c config\odoo.native.conf -d wms_test --test-enable --stop-after-init `
-i wms_location,wms_fifo,wms_barcode,wms_repair_damage,wms_ai_forecast,wms_reports,wms_training `
--without-demo=all --test-tags wmsscripts\backup-native.ps1 # Writes .\backups\wms-<timestamp>.dump.gpg + filestore zip
# Restore — see docs/07-deployment.md
scripts/restore-native.ps1 -BackupPath backups/wms-<timestamp>.dump.gpgA weekly restore drill (scripts/restore-drill.ps1) verifies the most recent encrypted backup is still recoverable - the drill never touches the production database. See docs/18-restore-drill.md for the runbook.
Optionally, every encrypted backup set is also uploaded to Google Drive after the local backup completes (verified via Drive's sha256Checksum; failure-safe — a Drive error never fails the local backup). Setup + restore runbook: docs/22-gdrive-backup.md.
GitHub Actions pipeline (Ubuntu runner — installs PostgreSQL + Python + Odoo source natively, mirroring the local Windows setup). See docs/17-ci-cd.md.
make lint # black, isort, flake8, xml well-formedness (needs make + WSL or Git Bash)
make test # full Odoo test suite (slow)
make format # auto-fix styleOr use the underlying tools directly:
.venv\Scripts\activate
black --check addons\ scripts\ ai_worker\
isort --check-only addons\ scripts\ ai_worker\
flake8 addons\Branch protection on main requires a pull request. Workflow:
- Feature work lands on
test→ CI runs on every push - When
testis green, open a PRtest → main - After merge, the
Releaseworkflow auto-tags the highest version found across alladdons/*/__manifest__.pyand publishes a GitHub Release with a changelog generated fromlast_tag..HEAD --no-merges
To cut a new release: bump the version on whichever module changed (the highest version across all manifests becomes the project version).
LGPL-3 (matches Odoo CE).