2026-01-30 10:43:51 -06:00
2026-01-28 12:53:59 -06:00
2026-01-24 18:19:37 -06:00
2026-01-30 00:19:54 -06:00
2026-01-22 00:36:01 -06:00
2026-01-24 18:23:29 -06:00
2026-01-22 00:36:01 -06:00
2026-01-26 11:49:27 -06:00
2026-01-29 12:40:25 -06:00
2026-01-22 00:36:01 -06:00
2026-01-22 00:36:01 -06:00

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

pip install flask werkzeug --break-system-packages

2. Initialize Database

cd /path/to/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

python app.py

Access at: http://localhost:5000


📱 Accessing from Scanner Devices

For Zebra MC9300 scanners or tablets on the same network:

  1. Find your server's IP address:

    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)


🏗️ Modular Architecture

ScanLook uses a modular system designed to grow into a full WMS. Modules can be enabled/disabled per user.

Current Modules:

  • Counts - Cycle Counts and Physical Inventory

Planned Modules:

  • Shipping
  • Receiving
  • Transfers
  • Production

Module Access

  • Admins assign modules to users via User Management
  • Users only see modules they have access to on the home screen
  • Route guards prevent URL bypassing

👥 User Roles

Owner (Level 1)

  • Super admin privileges
  • Manage all users (admins and staff)
  • Access to all modules
  • 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 and module assignments

Staff/Counter (Level 3)

  • Access assigned modules only
  • Select active count session
  • Scan locations and lots
  • Enter weights
  • Edit/delete their own scans
  • View their progress

🔄 Core Workflow (Counts Module)

Phase 1: Session Setup (Admin)

  1. Log in as admin
  2. Navigate to Admin Console
  3. Create new count session:
    • Session name: "January 17, 2026 - Daily Cycle Count"
    • Type: Cycle Count OR Full Physical Inventory
  4. Upload MASTER baseline CSV from NetSuite:
    • Format: Item, Description, Lot Number, Location, Bin Number, On Hand
  5. Session status: Active
  6. Counters can now begin

Phase 2: Counting (Staff)

  1. Log in as staff
  2. Select Counts module from home screen
  3. Select active session
  4. Start a new bin - scan or enter bin number
  5. Scan lot barcode
  6. 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
    • 🔵 DUPLICATE: Lot already scanned (same or different location)
  7. Enter weight
  8. Save → returns to scan input (autofocus)
  9. Repeat for all lots in bin
  10. Click "Finish Location" to finalize

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:

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 (Global):

  • Admin can refresh unlimited times
  • Shared across all sessions
  • 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

Duplicate Detection

  • Status 00: First scan of lot (no duplicate)
  • Status 01: Duplicate in same location by same user
  • Status 03: Found in different location
  • Status 04: Both same location duplicate AND different location

Count Types

Cycle Count:

  • Shows expected lots for the bin
  • Staff can see what should be there
  • Good for regular inventory checks

Full Physical Inventory:

  • Blind count (no expected list shown)
  • Staff only sees what they've scanned
  • Missing lots determined after finalization

Real-Time Dashboard

  • Active sessions with progress stats
  • Location completion tracking
  • 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
  • Session archival (archived sessions are read-only)

🗂️ Database Schema

Core Tables:

  • Users: Authentication and role management
  • Modules: Available system modules
  • UserModules: Per-user module access
  • CountSessions: Count session metadata
  • BaselineInventory_Master: Session-specific baseline (immutable)
  • BaselineInventory_Current: Global refreshable baseline
  • LocationCounts: Bin-by-bin progress tracking
  • ScanEntries: Every lot scan with status tracking
  • MissingLots: Expected lots not found after finalization

Key Relationships:

  • Users → UserModules → Modules (many-to-many)
  • CountSessions → BaselineInventory_Master (one-to-many)
  • CountSessions → LocationCounts → ScanEntries (hierarchical)

🔧 Technology Stack

  • Backend: Python 3.13 + Flask
  • Database: SQLite (auto-initializes on first run)
  • Frontend: HTML5 + CSS3 + Vanilla JavaScript
  • Templates: Jinja2
  • Icons: Font Awesome 6.5
  • Deployment: Docker (Linux)

📂 Project Structure

scanlook/
├── app.py                 # Main Flask application & routes
├── db.py                  # Database helper functions
├── utils.py               # Decorators (login_required, role_required)
├── blueprints/
│   ├── counting.py        # Counts module routes
│   ├── sessions.py        # Session management routes
│   ├── users.py           # User management routes
│   ├── data_imports.py    # CSV upload routes
│   └── admin_locations.py # Admin location management
├── database/
│   ├── init_db.py         # Database initialization & schema
│   └── scanlook.db        # SQLite database (created at runtime)
├── static/
│   ├── css/
│   │   ├── style.css      # Base/desktop styles
│   │   ├── mobile.css     # Mobile overrides (360-767px)
│   │   └── scanner.css    # MC9300 scanner overrides (<360px)
│   ├── js/
│   │   └── main.js        # Client-side JavaScript
│   ├── manifest.json      # PWA manifest
│   └── sw.js              # Service worker
└── templates/
    ├── base.html          # Base template with navbar
    ├── login.html         # Login page
    ├── home.html          # Module selection (landing page)
    ├── admin_dashboard.html
    ├── staff_dashboard.html
    ├── manage_users.html
    ├── create_session.html
    ├── session_detail.html
    ├── my_counts.html
    └── count_location.html

🎨 Design Philosophy

Desktop-First, Multi-Device 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

CSS Architecture:

  • style.css - Base/desktop styles (768px+)
  • mobile.css - Phone overrides (360-767px)
  • scanner.css - MC9300 scanner overrides (<360px)

Color Coding:

  • Green (--color-success): Perfect match
  • ⚠️ Yellow (--color-warning): Wrong location / Expected
  • Red (--color-danger): Missing or ghost lot
  • 🔵 Blue (--color-duplicate): Duplicate scan
  • 🟠 Orange (--color-orange): Weight variance

🐳 Docker Deployment

# Build
docker build -t scanlook .

# Run (preserves database between updates)
docker run -d \
  -p 5000:5000 \
  -v /path/to/data:/app/database \
  -e SCANLOOK_SECRET_KEY=your-secret-key \
  scanlook

Important: Only /app/database is volume-mounted to preserve data between container updates.


🔐 Security Considerations

  • Passwords hashed with Werkzeug
  • Session management via Flask sessions
  • SQL injection prevention (parameterized queries)
  • Role-based access control
  • Module-based access control with route guards
  • Soft deletes preserve audit trail

🎯 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

  • Additional WMS modules (Shipping, Receiving, Transfers, Production)
  • Multi-branch support
  • Direct NetSuite API integration
  • Photo capture for variance proof
  • Barcode generation for location labels
  • Native mobile apps
  • Offline mode with sync

📝 Version History

  • v0.12.0 - Modular architecture with user-based module access
  • v0.11.x - CSS refactoring, multi-device support, duplicate detection
  • v0.10.x - Global CURRENT baseline, session archival
  • v0.9.x - Core counting workflow, dual baseline system

🔧 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 🚀

Description
Repository for the ScanLook scanning project
Readme 13 MiB
Languages
HTML 43%
Python 39.8%
CSS 16.3%
JavaScript 0.7%
Shell 0.2%