Reports, dashboards and forecasting

Dashboard

Dashboard shows role-aware KPI cards (stock on hand, open orders, pending putaway/picking/QC, near-expiry and expired stock, low stock), trend charts (inward/outward), pending-work lists and alerts. Filter by warehouse and date range. Figures refresh automatically while the tab is visible (polling pauses when hidden). Each user sees only warehouses assigned to them.

Report catalogue

Reports lists 31 reports grouped by category. Every report respects the user's warehouse access; sensitive reports (valuation, reconciliation) need an extra permission.

CategoryReports
InventoryCurrent stock · Stock by status · Inventory valuation (standard cost) · Movement ledger summary · Ledger reconciliation · Inventory aging · Slow & non-moving stock · Low stock
Expiry & traceabilityNear-expiry stock · Expired stock · Batch traceability · Product recall – customers by batch · FEFO compliance · Expiry & damage losses
OperationsGoods receipts · Supplier performance · Putaway performance · Picking performance & accuracy · Packing · Dispatches · Transfers · Adjustments · Stock count variance · Returns · Damaged stock movements · Quality inspections
AnalyticsWarehouse utilisation · Inward / outward trend · Inventory turnover (approximate) · Stock-out analysis · Order fulfilment & turnaround

Definitions live in app/Reports/definitions.php (title, filters, columns, totals, SQL builder); app/Services/ReportService.php runs them with paging, sorting, totals and warehouse scoping.

Using a report

  1. Open the report, set filters (warehouse, dates, product, category, status, search, days – depending on the report) and press Run.
  2. Sort by clicking column headers; totals appear in the footer.
  3. Export: CSV (UTF-8 with BOM, formula-safe) or XLSX (generated without external libraries; needs the PHP zip extension). Exports are audited.
  4. Print / PDF: the print view uses a clean layout; choose Save as PDF in the browser print dialog. There is no server-side PDF engine.
  5. Saved filters: save the current filter set under a name and reuse it later (per user).

Approximations (stated in each report's description)

  • FEFO compliance treats stock still in the receiving area as available.
  • Inventory turnover divides dispatches by current on-hand stock (historical average stock is not stored).
  • Warehouse utilisation is current state only.

Forecasting

Forecasting computes demand forecasts locally (no external services). Demand = daily dispatched quantity from the ledger over the last 180 days.

MethodUsed when
Simple moving average (7 and 28 days)always
Single exponential smoothing (α 0.3)always
Holt linear trend≥ 56 days of history
Weekly seasonality index≥ 8 full weeks of history

Each method is backtested (one-step-ahead) and the one with the lowest mean absolute error (MAE) is used; MAE and MAPE are shown. Products with fewer than 14 days of history show insufficient history instead of a forecast.

Derived figures:

  • Safety stock = 1.65 × σ(daily demand) × √(lead time days) (≈95% service level)
  • Reorder point = average daily demand × lead time + safety stock
  • Suggested order qty = reorder point + 30 days of demand − (available + in transit), never below 0
  • Days of stock = available ÷ average daily demand
  • Stock-out risk: HIGH if days of stock < lead time; MEDIUM if < lead time + 7 days or position ≤ reorder point; otherwise LOW
  • Expiry risk: batches are consumed in FEFO order at the forecast rate; quantity that cannot be consumed before its expiry date is flagged as at risk

Forecasts are cached (forecast_cache) and refreshed nightly by cron or with Refresh. They are estimates, not guarantees; lead time comes from the product master, so keep it current.

Scheduled reports and email

Administration → Email & Schedules

  • SMTP: host, port, encryption (TLS/SSL), username, password (stored encrypted, never shown again), From name/address. Send test verifies settings. All sends are recorded in the email log.
  • Schedules: pick a report, format (CSV or XLSX attachment), frequency (daily, weekly on a weekday, monthly on a day – short months use their last day), time, timezone, recipients, and filters (warehouse, relative period, days). Run now sends immediately.
  • Scheduled reports run with the permissions and warehouse access of the user who created the schedule.
  • Failed deliveries retry up to 3 attempts, 15 minutes apart, then wait for the next regular slot. Run history shows each attempt and its error.

Cron

cron/cron.php (CLI only, every 5 minutes) runs: due schedules, expiry/low-stock alerts (daily), forecast refresh (daily), cleanup (daily: expired tokens, idempotency keys, read notifications > 90 days, temporary files > 1 day) and the automatic daily backup when enabled. A database lock prevents overlapping runs; daily jobs run once per day. Hosts without CLI cron can call jobs/run?token=… (token in config/config.php, at most once per minute). See installation.md.