Gas Reporting

Water Usage

Wash Compliance

Manuals & Guides

System documentation for leadership and management. Not visible to technicians.

System Purpose

The Inventory Management System tracks stock levels, deliveries, usage, and reorder workflows for Richter's Lawn Care (RLC) and GreenX (GX). It solves three problems:

  1. Visibility — managers see real-time stock status (in-stock / low / out) across departments (Lawn, Tree, Pest, Fleet, General)
  2. Accountability — every movement is logged as a transaction, creating a full audit trail
  3. Compliance — weekly physical counts are tracked per company, with automated compliance checks and escalation tasks

Design Philosophy: Reference Model

TEOD (Truck End-of-Day) forms log what technicians used in the field, but this data is reference only. It does not change stock levels. The source of truth for inventory quantities is the weekly physical count submitted by managers.

This is intentional. Field usage data is approximate (generic labels like "Lawn Fertilizer (bags)" with no SKU). Actual stock is confirmed by a human walking the warehouse.

Data Flow

TEOD Form Submit
  └─→ logInventoryUsage()
        └─→ inventory_transactions (type = 'usage_reference', prev/new qty = 0)
             └─→ Reference only. Does NOT update current_quantity.

Weekly Physical Count
  └─→ POST /api/inventory/count
        ├─→ inventory_counts (count header record)
        ├─→ inventory_count_items (per-item counted vs. previous quantity)
        ├─→ inventory_transactions (type = 'count', records difference)
        └─→ UPDATE inventory_items.current_quantity = counted value  ← SOURCE OF TRUTH

Vendor Delivery (via PO Receive)
  └─→ POST /api/inventory/purchase-orders/:id/receive
        ├─→ UPDATE purchase_order_items.quantity_received
        ├─→ UPDATE inventory_items.current_quantity += received
        ├─→ inventory_transactions (type = 'delivery')
        └─→ PO status → 'partial' or 'complete'

Vendor Delivery (direct, no PO)
  └─→ POST /api/inventory/deliveries
        ├─→ inventory_deliveries + inventory_delivery_items
        ├─→ UPDATE inventory_items.current_quantity += received
        ├─→ inventory_transactions (type = 'delivery')
        └─→ Auto-resolves open low-stock tasks if stock exceeds threshold

Manual Transaction
  └─→ POST /api/inventory/transactions
        ├─→ inventory_transactions (type = 'use', 'receive', 'adjust', or 'return')
        └─→ UPDATE inventory_items.current_quantity  ← direct update

Key Tables

Table Purpose
inventory_items Master item catalog. Fields: id, company, department, sku, name, unit, current_quantity, reorder_threshold, reorder_quantity, cost_per_unit, supplier, vendor_id, storage_location, is_active, requires_count, image_url, last_count_date, last_count_by. Stock status is computed: out_of_stock (qty ≤ 0), low_stock (qty ≤ threshold), ok (above threshold).
inventory_transactions All movements. Fields: id, item_id, transaction_type, quantity, previous_quantity, new_quantity, employee_id, employee_name, notes, source_form, source_submission_id, company, created_at. Types: delivery, usage_reference, count, use, receive, adjust, return.
inventory_counts Physical count header records. Fields: id, company, department, manager_id, manager_name, submission_date, notes, source (local_form or submission_form), created_at.
inventory_count_items Per-item detail for a count. Fields: id, count_id, item_id, previous_quantity, counted_quantity, difference (or system_quantity/variance in detail view).
purchase_orders PO management. Fields: id, po_number (auto: PO-YYYY-NNNN), vendor_id, status, company, expected_date, order_date, received_date, subtotal, tax, shipping, total, notes, created_by, created_by_name. Statuses: draftsubmittedpartialcomplete (also cancelled).
purchase_order_items PO line items. Fields: id, po_id, item_id, quantity_ordered, quantity_received, unit_cost, line_total, notes.
reorder_requests Restock and new-item requests. Fields: id, request_type (restock or new_item), item_id, item_name, item_description, quantity, urgency (normal/high/critical/low), status (pending/approved/rejected/po_created), company, department, suggested_vendor_id, estimated_cost, reason, notes, requested_by, requested_by_name, approved_by, rejected_by, rejection_reason, po_id.
vendors Vendor directory. Fields: id, name, code, contact_name, email, phone, address, website, payment_terms, notes, categories (JSON array), is_preferred, is_active.
inventory_alerts Low-stock alert configuration per item. Fields: id, item_id, alert_type, threshold, notification_method, cooldown_hours, last_triggered_at, is_active.
inventory_orders Auto-generated reorder records from low-stock detection during counts. Fields: id, item_id, requested_quantity, requested_by, requested_by_name, reason, status, task_id, company.
inventory_deliveries Direct delivery records (non-PO). Fields: id, delivery_date, supplier, invoice_number, po_number, received_by, received_by_name, company, notes, total_items, total_cost.
inventory_delivery_items Line items for direct deliveries. Fields: id, delivery_id, item_id, quantity_received, quantity_ordered, unit_cost, line_total, order_id.
inventory_categories Department-based category taxonomy. Fields: department, name, sort_order, is_active.
po_number_sequence Auto-increment sequence for PO numbering per year.

Role Permissions Matrix

Capability Technician Lead Tech Manager Office Leadership/Owner
View inventory items ✓ (own dept + General) ✓ (all) ✓ (all)
View transactions ✓ (own dept)
Submit reorder request
Create inventory items
Edit inventory items
Soft-delete items
Submit physical count
Edit count items
Delete counts
Create/submit POs
Receive deliveries
Cancel POs
Delete POs
Approve/reject reorder requests
Manage vendors
Delete vendors
Upload item images (R2)

Department Visibility (RBAC)

Non-leadership users see inventory scoped to their department plus General:

  • Lawn / Lawn Care → Lawn + General
  • Tree / Tree Care → Tree + General
  • Pest / Pest Control → Pest + General
  • Fleet / Mechanic → Fleet + General
  • Office / Admin / Leadership → all departments

Multi-Tenant Scoping

Items have a company field: RLC, GX, or BOTH. Non-leadership users are automatically filtered to their company. Leadership sees everything. The BOTH value means the item is shared across brands (e.g., common supplies).

Automated Behaviors

  1. Low-stock task creation — when a physical count puts an item at or below its reorder threshold, a task is auto-created and assigned to the company's manager with 48-hour due date
  2. Low-stock alert cooldown — alerts respect a cooldown period (default 24 hours) to avoid spam
  3. Compliance task auto-resolve — submitting a count auto-resolves any open inventory_compliance task for that company
  4. Delivery auto-resolve — receiving a delivery that pushes stock above the reorder threshold auto-completes open low-stock tasks for that item
  5. Reorder → PO conversion — approving a restock request with a vendor auto-creates a draft PO with line items