# ScanLook - Inventory Management System **Barcode-based inventory counting system designed for food production facilities** Replace 5 days of manual year-end physical inventory with a weekend project. Track variances, location errors, phantom lots, and ghost inventory in real-time. --- ## 🚀 Quick Start ### 1. Install Dependencies ```bash pip install flask werkzeug --break-system-packages ``` ### 2. Initialize Database ```bash cd /home/claude/scanlook python database/init_db.py ``` This creates the database with default users: - **Owner**: `owner` / `owner123` - **Admin**: `admin` / `admin123` - **Staff**: `staff1` / `staff123` - **Staff**: `staff2` / `staff123` ### 3. Run Application ```bash python app.py ``` Access at: **http://localhost:5000** --- ## 📱 Accessing from Scanner Devices For Zebra Android scanners or tablets on the same network: 1. Find your server's IP address: ```bash hostname -I ``` 2. On scanner device, open browser and navigate to: ``` http://YOUR_SERVER_IP:5000 ``` 3. Scanner trigger acts as Enter key (keyboard wedge mode) --- ## 👥 User Roles ### Owner (Level 1) - Super admin privileges - Manage all admins - View all sessions across branches ### Admin (Level 2) - Create count sessions - Upload MASTER baseline (morning snapshot) - Upload CURRENT baseline (refresh anytime) - View real-time dashboard - Export variance reports - Manage staff users ### Staff/Counter (Level 3) - Select active count session - Scan locations and lots - Enter weights - Edit/delete their own scans - View their progress --- ## 🔄 Core Workflow ### Phase 1: Session Setup (Admin) 1. **Log in as admin** 2. **Create new count session**: - Session name: "January 17, 2026 - Daily Cycle Count" - Type: Cycle Count OR Full Physical Inventory 3. **Upload MASTER baseline** CSV from NetSuite: - Format: `Item, Description, Lot Number, Location, Bin Number, On Hand` - Creates baseline version 1 4. Session status: **Active** 5. Counters can now begin ### Phase 2: Counting (Staff) 1. **Log in as staff** 2. **Select active session** 3. **Scan location barcode** (e.g., R903B) - System marks location "in progress" - Shows: "Counting R903B" 4. **Scan lot barcode** 5. System checks lot against MASTER baseline: - ✅ **MATCH**: Expected here, location correct - ⚠️ **WRONG LOCATION**: Lot exists but system says different location - ❌ **GHOST LOT**: Not in system at all 6. **Enter weight** 7. Save → returns to scan input (autofocus) 8. Repeat for all lots in location 9. Click **"Finish Location"** ### Phase 3: Admin Monitoring **Real-Time Dashboard Shows:** - Total locations & completion percentage - Active counters with current location - Variance summary (matches, wrong locations, missing, ghost lots) **Optional CURRENT Baseline Refresh:** - Admin uploads new CSV from NetSuite - System recalculates CURRENT status for all scans - Shows what changed in system after count - Proves count was correct, lot moved later --- ## 📊 CSV Import Format **Required columns:** ```csv Item,Description,Lot Number,Location,Bin Number,On Hand 100001,Beef MDM,20260108-132620-PO25146,Wisconsin G & H,R903B,2030 100001,Beef MDM,20260108-132700-PO25146,Wisconsin G & H,R903B,2030 100001,Beef MDM,20260106-150649-PO24949,Wisconsin G & H,R905C,2065 ``` **Column Descriptions:** - **Item**: SKU or item number - **Description**: Product description - **Lot Number**: Unique lot identifier - **Location**: Warehouse location name - **Bin Number**: Specific bin/rack location code - **On Hand**: Current quantity in pounds --- ## 🎯 Key Features ### Dual Baseline System **MASTER Baseline**: - Uploaded once at session start (e.g., 6:00 AM) - Never changes during session - What counters validate against - Represents "what should have been there when we started" **CURRENT Baseline**: - Admin can refresh unlimited times - Only affects admin dashboard/reporting - Counters never see it - Shows "where is it in the system NOW" - Identifies movement after count ### Variance Detection - **Perfect Match**: Right location, weight within tolerance - **Weight Variance**: Right location, weight differs (calculates %) - **Wrong Location**: Lot exists but scanned in different location - **Ghost Lot**: Scanned but not in baseline at all - **Missing/Phantom**: In baseline but not found during count ### Blind Counting - Counters don't see expected quantities - Prevents bias - Ensures honest count ### Real-Time Dashboard - Active counters with current location - Progress by location - Variance counts updating live - Dual view (MASTER vs CURRENT) after refresh ### Audit Trail - Every scan timestamped with user - Soft deletes tracked - Edits tracked with modified timestamp - Baseline version tracking --- ## 🗂️ Database Schema ### Tables: - **Users**: Authentication and role management - **CountSessions**: Count session metadata - **BaselineInventory_Master**: Morning baseline (never changes) - **BaselineInventory_Current**: Refreshable baseline (soft delete) - **LocationCounts**: Location-by-location progress - **ScanEntries**: Every lot scan with dual status tracking - **MissingLots**: Expected lots not found ### Indexes: Optimized for fast lookups on lot numbers, locations, and statuses. --- ## 🔧 Technology Stack - **Backend**: Python 3.13 + Flask - **Database**: SQLite - **Frontend**: HTML5 + CSS3 + Vanilla JavaScript - **Templates**: Jinja2 --- ## 📂 Project Structure ``` scanlook/ ├── app.py # Main Flask application ├── database/ │ ├── init_db.py # Database initialization │ └── scanlook.db # SQLite database (created) ├── static/ │ ├── css/ │ │ └── style.css # Main stylesheet │ └── js/ │ └── main.js # Client-side JavaScript └── templates/ ├── base.html # Base template ├── login.html # Login page ├── admin_dashboard.html ├── staff_dashboard.html ├── create_session.html ├── session_detail.html ├── count_session.html └── count_location.html ``` --- ## 🎨 Design Philosophy **Mobile-First, Warehouse-Optimized:** - High contrast dark theme for warehouse lighting - Large touch targets (44px minimum) - Autofocus on scan inputs - Scanner trigger = Enter key - Visual feedback with color-coded statuses - Minimal typing required **Color Coding:** - ✅ Green: Perfect match - ⚠️ Yellow: Wrong location - ❌ Red: Missing or ghost lot - 🔵 Blue: Weight variance --- ## 🚧 Current Status: Phase 1 Complete (MVP) ### ✅ Implemented: - User authentication (3 roles) - Session creation - MASTER baseline upload - Location scanning - Lot scanning with MASTER status - Weight entry - Basic dashboard - Real-time progress tracking - Mobile-optimized UI ### 🔜 Next Phases: - **Phase 2**: CURRENT baseline refresh & dual status recalculation - **Phase 3**: Missing lot detection, enhanced dashboard - **Phase 4**: Excel export with multiple tabs - **Phase 5**: Data retention automation, user management - **Phase 6**: Docker deployment --- ## 📝 Development Notes ### Default Accounts (Testing) All passwords should be changed in production! ### Security Considerations - Passwords are hashed with Werkzeug - Session management via Flask sessions - SQL injection prevention (parameterized queries) - Soft deletes preserve audit trail ### Data Retention - Plan: Keep data for 30 days - Nightly cleanup job (to be implemented) - Archive old sessions --- ## 🎯 Success Metrics **Current State (Year-End Physical):** - Duration: 5 days - Data entry: Manual, error-prone - Variance resolution: Weeks later **Target State (with ScanLook):** - Duration: 1 weekend (2 days max) - Data entry: Zero (all scanned) - Variance resolution: Real-time flagging - Accuracy: 99%+ (no handwriting errors) - Time savings: 60%+ --- ## 💡 Future Enhancements - Multi-branch support - Direct NetSuite API integration - Photo capture for variance proof - Barcode generation for location labels - Native mobile apps - Offline mode with sync --- ## 📧 Support This is a custom internal tool. Contact your system administrator for support. **Built with ❤️ for efficient inventory management** *Inspired by BomLook from the FoxPro days* 🚀