← Back to Projects

Warehouse Inventory Tracking System

Login: User: witsadmin | Pwd: WitsAdmin123!
Warehouse Inventory Tracking System

Warehouse Inventory Tracking System — Project Plan


1. Project Overview

A web-based inventory tracking system for Carnation Company (the operator) to manage frozen goods received and dispatched on behalf of their customers:

  • Matthew's Foods

  • Abzal Fine Desserts

  • Jane's Pies and Cakes

Carnation Company logs all inbound and outbound movements, tracks inventory by SKU and Lot Number, and generates date-based reports — all from a single desktop-accessible interface.


2. Tech Stack

| Layer | Technology |

|---|---|

| **Backend** | Django (Python) |

| **Frontend** | Django Templates |

| **Styling** | Tailwind CSS + DaisyUI (via CDN — no build step) |

| **Database** | SQLite (development) → PostgreSQL (production) |

| **Authentication** | Django built-in auth + role-based middleware |

| **Reports/Export** | openpyxl (Excel), reportlab (PDF) |

Tailwind + DaisyUI (CDN Setup)

No npm, no Node.js, no watchers required. Simply included in base.html:


<link href="https://cdn.jsdelivr.net/npm/daisyui@4/dist/full.min.css" rel="stylesheet" />

<script src="https://cdn.tailwindcss.com"></script>

> **Note:** CDN usage means no CSS purging (slightly larger bundle). Perfectly acceptable for an internal desktop tool with a small user base.

3. User Roles

| Role | Permissions |

|---|---|

| **Super Admin** | Full access — user management, client management, all reports, all inventory actions |

| **Editor** | Can create and edit inventory entries (inbound/outbound) |

| **Viewer** | Read-only access to inventory and reports |

- Total users: 5

  • Login accessible from any browser (desktop-first)

4. Core Modules & Features

4.1 Authentication

  • Login / Logout

  • Role-based access control (middleware-enforced)

  • Session management

4.2 Client Management

  • Add, edit, and view sub-clients (e.g. Matthew's Foods)

  • All inventory is tagged to a specific client

  • Managed by Super Admin only

4.3 SKU Management

  • Manually input SKU codes and product names per client

  • SKUs are tied to Lot Numbers and Best Before Dates

  • View all SKUs per client

4.4 Inbound (Receiving Goods)

  • Record BOL (Bill of Lading) reference number

  • Input fields: Client, SKU, Lot Number, Quantity, Date Received, Best Before Date

  • Supports multiple SKU entries per BOL

  • Inventory quantity updated automatically on submission

4.5 Outbound (Dispatching Goods)

  • FIFO (First In, First Out) dispatch logic — oldest lot dispatched first

  • Input fields: Client, SKU, Quantity requested

  • System auto-suggests the correct Lot # based on FIFO order

  • Splits across multiple lots automatically if needed

  • Records: SKU, Lot #, Quantity pulled, Date dispatched, User who dispatched

4.6 Dashboard

  • Real-time inventory levels per Client → SKU → Lot #

  • Filter by client, SKU, or date range

  • Visual indicators for items approaching shelf life expiry

4.7 Reports

  • Date-based inventory snapshot (stock levels on any given date)

  • Full movement history (all inbound/outbound per client, SKU, and lot)

  • Exportable to CSV / Excel / PDF


5. Workflow


BOL Received

    → Record BOL Ref + Client + SKU + Lot # + Quantity + Best Before Date

        → Inventory Updated (quantity added to correct Lot)

Dispatch Request

    → Select Client + SKU + Quantity

        → FIFO Logic Identifies Correct Lot(s)

            → Confirm Dispatch

                → Inventory Deducted + Movement Logged

Generate Report

    → Select Client + Date Range

        → Snapshot or Movement History Exported


6. Project Structure


inventory_project/

│

├── manage.py

├── requirements.txt

│

├── config/                      # Project-level settings

│   ├── settings.py

│   ├── urls.py

│   └── wsgi.py

│

├── apps/

│   ├── accounts/                # Auth, users, roles

│   │   ├── models.py

│   │   ├── views.py

│   │   └── urls.py

│   │

│   ├── clients/                 # Carnation's sub-clients

│   │   ├── models.py

│   │   ├── views.py

│   │   └── urls.py

│   │

│   ├── inventory/               # Core inventory logic

│   │   ├── models.py

│   │   ├── views.py

│   │   ├── fifo.py              # FIFO dispatch logic

│   │   └── urls.py

│   │

│   └── reports/                 # Reporting and export

│       ├── views.py

│       └── urls.py

│

├── templates/

│   ├── base.html                # Tailwind + DaisyUI CDN loaded here

│   ├── accounts/

│   ├── clients/

│   ├── inventory/

│   └── reports/

│

└── static/

    └── css/custom.css           # Minor style overrides only

7. Database Models


# accounts/models.py

class User(AbstractUser):

    ROLES = [

        ('super_admin', 'Super Admin'),

        ('editor', 'Editor'),

        ('viewer', 'Viewer'),

    ]

    role = models.CharField(max_length=20, choices=ROLES)

# clients/models.py

class Client(models.Model):

    name = models.CharField(max_length=200)   # e.g. Matthew's Foods

    created_at = models.DateTimeField(auto_now_add=True)

# inventory/models.py

class SKU(models.Model):

    client = models.ForeignKey(Client, on_delete=models.CASCADE)

    sku_code = models.CharField(max_length=100)

    product_name = models.CharField(max_length=200)

class Lot(models.Model):

    sku = models.ForeignKey(SKU, on_delete=models.CASCADE)

    lot_number = models.CharField(max_length=100)

    best_before_date = models.DateField()

    quantity_on_hand = models.PositiveIntegerField(default=0)

class InboundLog(models.Model):

    lot = models.ForeignKey(Lot, on_delete=models.CASCADE)

    bol_reference = models.CharField(max_length=100)

    quantity = models.PositiveIntegerField()

    date_received = models.DateField()

    created_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)

class OutboundLog(models.Model):

    lot = models.ForeignKey(Lot, on_delete=models.CASCADE)

    quantity = models.PositiveIntegerField()

    date_dispatched = models.DateField()

    created_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)


8. Page & URL Map

| URL | Page | Access |

|---|---|---|

| `/login` | Login page | Public |

| `/dashboard` | Live inventory overview | All |

| `/clients/` | Client list | Super Admin |

| `/clients/add` | Add new client | Super Admin |

| `/skus/` | SKU list per client | Editor+ |

| `/skus/add` | Add new SKU | Editor+ |

| `/inbound/` | Receive goods — BOL entry form | Editor+ |

| `/inbound/history` | Inbound movement history | All |

| `/outbound/` | Dispatch goods — FIFO form | Editor+ |

| `/outbound/history` | Outbound movement history | All |

| `/reports/` | Report generator + export | All |

| `/users/` | User management | Super Admin |

9. FIFO Dispatch Logic


# inventory/fifo.py

def get_fifo_lots(sku, quantity_needed):

    """

    Returns lots ordered by oldest best_before_date first.

    Splits across multiple lots if needed.

    """

    lots = Lot.objects.filter(

        sku=sku,

        quantity_on_hand__gt=0

    ).order_by('best_before_date')  # oldest first

    dispatch_plan = []

    remaining = quantity_needed

    for lot in lots:

        if remaining <= 0:
            break         take = min(lot.quantity_on_hand, remaining)         dispatch_plan.append({'lot': lot, 'quantity': take})         remaining -= take     return dispatch_plan

10. Dependencies (requirements.txt)


Django>=5.0
psycopg2-binary       # PostgreSQL driver (production) openpyxl              # Excel export reportlab             # PDF export python-decouple       # Environment variable management whitenoise            # Static file serving

11. Estimated Timeline (~15–17 Hours)

| Phase | Task | Est. Hours |

|---|---|---|

| 1 | Project setup, settings, base template with DaisyUI | 1.5 hrs |

| 2 | Auth — login, logout, role-based access middleware | 2 hrs |

| 3 | Client & SKU management (CRUD) | 2 hrs |

| 4 | Inbound flow — BOL entry, lot creation, inventory update | 2.5 hrs |

| 5 | Outbound flow — FIFO dispatch form + confirmation | 2.5 hrs |

| 6 | Dashboard — live inventory view per client/SKU/lot | 2 hrs |

| 7 | Reports — filters, date range, Excel/PDF export | 2 hrs |

| 8 | Testing, polish, deployment prep | 1.5 hrs |

| | **Total** | **~16 hrs** |

12. Open Questions (Confirm Before Starting)

  1. Warehouses — One location or multiple? Should inventory be tracked per warehouse?

  2. Units of measure — Cases, pallets, lbs, or generic units?

  3. Shelf life alerts — Should the system flag or notify when items are near expiry?

  4. BOL document — Record BOL number only, or allow PDF upload attachment?

  5. Deployment target — Local server, shared hosting, or cloud VPS (e.g. DigitalOcean, Render)?

  6. App name — Confirm final name for the system (currently placeholder: Inventory Management System)


Plan prepared for Heritcon LLC — Subject to revision as requirements are refined.