Skip to content

Suresh-Note/PharmaStock_Optimizer

Repository files navigation

πŸ’Š PharmaStock Optimizer

AI-Powered Pharmaceutical Inventory Management & Sales Analytics Platform

Python Streamlit SQLAlchemy XGBoost Docker Tests


An industrial-grade inventory management system combining real-time stock tracking, interactive sales analytics, and XGBoost-based stockout prediction to optimize pharmaceutical supply chains.


πŸ“Έ Screenshots

πŸ” Secure Login

Screenshot 2026-04-21 173304

πŸ“Š Dashboard Overview

Real-time inventory metrics and color-coded stock levels across 33 medicines. image

Screenshot 2026-04-21 173348

πŸ“¦ Inventory Management

View and edit inventory with ML-predicted Days_to_Stockout for every medicine.

View Inventory Manage Inventory
Screenshot 2026-04-21 173435
Screenshot 2026-04-21 173457

|

πŸ›’ Orders & Payments

Shopping cart with live stock validation and automatic inventory deduction. Screenshot 2026-04-21 173512

πŸ“ˆ Sales Analytics

Interactive filtering by date, month, or year β€” switch between bar and line chart views.

Bar Chart View Line Chart View
Screenshot 2026-04-21 173546
Screenshot 2026-04-21 173600

|

πŸ’Š Medicine Reference

Per-medicine details: ATC code, uses, cautions, dosage, alternatives, and live stock count. Screenshot 2026-04-21 173626

🏭 Supplier View

Medicines grouped by supplier with stock-level visualization. Screenshot 2026-04-21 173644


πŸ“‹ Table of Contents


πŸ” Overview

PharmaStock Optimizer addresses a critical challenge in pharmaceutical retail β€” predicting when medicines will go out of stock before it happens. Traditional inventory systems rely on static reorder points, but demand for medicines varies by season, external factors, and trends.

This platform integrates XGBoost regression models trained on 33,000+ historical sales records to dynamically predict stockout timelines, enabling pharmacies to:

  • 🎯 Proactively reorder before critical shortages
  • πŸ“‰ Reduce wastage from overstocking perishable medicines
  • πŸ“Š Analyze sales trends with interactive, filterable visualizations
  • 🏒 Manage supplier relationships with per-supplier medicine mappings

πŸ— Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                     Streamlit UI (app.py)                    β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚Dashboard β”‚ β”‚Inventory β”‚ β”‚  Sales   β”‚ β”‚Supplierβ”‚ β”‚Meds  β”‚  β”‚
β”‚  β”‚  Page    β”‚ β”‚  Page    β”‚ β”‚  Page    β”‚ β”‚  Page  β”‚ β”‚ Page β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”¬β”€β”€β”€β”€β”˜ β””β”€β”€β”¬β”€β”€β”€β”˜  β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€
β”‚       β”‚       Service Layer (services/)     β”‚         β”‚      β”‚
β”‚  β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β–Όβ”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β–Όβ”€β”€β”€β”€β”    β”‚      β”‚
β”‚  β”‚ Inventory β”‚ β”‚  Sales  β”‚ β”‚  Orders  β”‚ β”‚Supplierβ”‚    β”‚      β”‚
β”‚  β”‚  Service  β”‚ β”‚ Service β”‚ β”‚ Service  β”‚ β”‚Service β”‚    β”‚      β”‚
β”‚  β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”¬β”€β”€β”€β”€β”˜    β”‚      β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€
β”‚       β”‚    Data Layer                       β”‚         β”‚      β”‚
β”‚  β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β” β”Œβ”€β”€β–Όβ”€β”€β”€β”  β”‚
β”‚  β”‚         SQLAlchemy ORM (database/)            β”‚ β”‚ JSON β”‚  β”‚
β”‚  β”‚  Models: User β”‚ Medicine β”‚ Inventory β”‚ Sale   β”‚ β”‚ Data β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                     β”‚                                        β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”‚
β”‚  β”‚             Cross-Cutting Concerns                  β”‚     β”‚
β”‚  β”‚  Auth (bcrypt+RBAC) β”‚ ML (XGBoost) β”‚ Logging        β”‚     β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Design Patterns

Pattern Implementation
Layered Architecture UI β†’ Service β†’ ORM β†’ Database
Repository Pattern Service classes abstract all data access
Dependency Injection SQLAlchemy sessions injected into services
Configuration as Code Pydantic BaseSettings with .env override
Context Manager get_session() handles commit/rollback/close

πŸ›  Tech Stack

Layer Technology Purpose
Frontend Streamlit Interactive web UI
Visualization Plotly Express Interactive charts
ORM SQLAlchemy 2.0 Database abstraction
Database SQLite (WAL mode) Relational storage
Validation Pydantic v2 Input/config validation
Machine Learning XGBoost Stockout forecasting
Authentication bcrypt Salted password hashing
Configuration pydantic-settings Environment management
Testing pytest Unit test suite
Containerization Docker Production deployment

✨ Key Features

πŸ“Š Dashboard

Real-time inventory overview with color-coded stock charts and sidebar metrics (total medicines, low stock, expired).

πŸ“¦ Inventory Management

CRUD operations with AI-powered stockout prediction on every update.

πŸ›’ Orders & Payments

Shopping cart with cumulative stock validation and automatic inventory deduction.

πŸ“ˆ Sales Analytics

Filter by date / month / year with interactive bar and line charts across 33,000+ sales records.

🏭 Supplier Management

View medicines grouped by supplier with stock visualizations.

πŸ’Š Medicine Reference

33 medicines with ATC codes, dosage, cautions, alternatives, and real-time stock display.

πŸ” Authentication & RBAC

bcrypt hashing, role-based access (admin/user), session timeout, email recovery.


πŸš€ Getting Started

Prerequisites

  • Python 3.10+
  • pip package manager

Installation

# Clone the repository
git clone https://github.com/Suresh-Note/PharmaStock_Optimizer.git
cd PharmaStock_Optimizer/pharma_stock

# Install dependencies
pip install -r requirements.txt

# Configure environment
cp .env.example .env
# Edit .env with your SMTP credentials

Configure .env

SMTP_EMAIL=your_email@gmail.com
SMTP_PASSWORD=your_gmail_app_password

Run

# Run the modular app
streamlit run app.py

# Or run the legacy single-file version
streamlit run PharmaStock.py

Run Tests

python -m pytest tests/ -v

πŸ“ Project Structure

PharmaStock_Optimizer/
β”œβ”€β”€ docs/
β”‚   └── screenshots/                # UI screenshots for documentation
β”‚
└── pharma_stock/
    β”œβ”€β”€ app.py                      # Entry point (thin router)
    β”œβ”€β”€ config.py                   # Centralized Pydantic settings
    β”œβ”€β”€ PharmaStock.py              # Legacy single-file version
    β”‚
    β”œβ”€β”€ database/                   # Data access layer
    β”‚   β”œβ”€β”€ connection.py           # SQLAlchemy engine + session factory
    β”‚   └── models.py               # ORM models (User, Medicine, Inventory, Sale)
    β”‚
    β”œβ”€β”€ auth/                       # Authentication module
    β”‚   β”œβ”€β”€ security.py             # bcrypt hashing + session management
    β”‚   β”œβ”€β”€ email.py                # SMTP email service
    β”‚   └── service.py              # Auth orchestration (register/login/delete)
    β”‚
    β”œβ”€β”€ services/                   # Business logic layer
    β”‚   β”œβ”€β”€ inventory.py            # Inventory CRUD + summary
    β”‚   β”œβ”€β”€ sales.py                # Sales filtering + queries
    β”‚   β”œβ”€β”€ orders.py               # Cart management + order processing
    β”‚   └── suppliers.py            # Supplier-medicine mappings
    β”‚
    β”œβ”€β”€ ml/                         # Machine learning pipeline
    β”‚   └── forecasting.py          # XGBoost training + stockout prediction
    β”‚
    β”œβ”€β”€ pages_ui/                   # Streamlit page modules
    β”‚   β”œβ”€β”€ dashboard.py            # Dashboard view
    β”‚   β”œβ”€β”€ inventory_page.py       # Inventory management
    β”‚   β”œβ”€β”€ sales_page.py           # Sales analytics
    β”‚   β”œβ”€β”€ medicines_page.py       # Medicine reference
    β”‚   └── suppliers_page.py       # Supplier view
    β”‚
    β”œβ”€β”€ utils/                      # Cross-cutting utilities
    β”‚   β”œβ”€β”€ logger.py               # Structured logging
    β”‚   β”œβ”€β”€ exceptions.py           # Custom exception hierarchy
    β”‚   └── validators.py           # Pydantic input schemas
    β”‚
    β”œβ”€β”€ data/
    β”‚   β”œβ”€β”€ medicines_info.json     # Medicine reference data
    β”‚   └── expanded_sales_data.csv # Historical sales dataset (33K rows)
    β”‚
    β”œβ”€β”€ tests/                      # pytest test suite (24 tests)
    β”‚   β”œβ”€β”€ conftest.py             # Fixtures (in-memory DB, sample data)
    β”‚   β”œβ”€β”€ test_auth.py            # Auth service tests (9 tests)
    β”‚   β”œβ”€β”€ test_inventory.py       # Inventory CRUD tests (9 tests)
    β”‚   └── test_forecasting.py     # ML prediction tests (4 tests)
    β”‚
    β”œβ”€β”€ Dockerfile                  # Production container
    β”œβ”€β”€ docker-compose.yml          # Container orchestration
    β”œβ”€β”€ requirements.txt            # Python dependencies
    └── .env                        # Environment secrets (not committed)

πŸ—„ Database Schema

Inventory β€” Current stock levels (33 medicines)

Column Type Description
Medicine_Name TEXT (PK) Medicine identifier
ATC_Code TEXT ATC classification
Stock_Available INTEGER Current units in stock
Price_per_Unit REAL Current price
Reorder_Level INTEGER Low-stock threshold
Days_to_Stockout INTEGER ML-predicted days
Expiry_Date DATE Batch expiry

Sales β€” Historical records (~33,000 rows)

Column Type Description
Date TEXT Sale date (YYYY-Mon-DD)
Month TEXT Full month name
Year INTEGER Sale year
Medicine_Name TEXT Medicine identifier
Stock_Sold INTEGER Units sold
External_Factor TEXT Demand factor

users β€” Registered accounts (RBAC-enabled)

Column Type Description
username TEXT (PK) Unique identifier
email TEXT Recovery email
password TEXT bcrypt hash
role TEXT "admin" or "user"
created_at DATETIME Registration timestamp

πŸ€– Machine Learning

XGBoost Stockout Prediction

Per-medicine regression models predict daily sales volume:

Input:  Day index (days since first recorded sale)
Output: Predicted units sold per day
Model:  XGBRegressor (100 estimators, squared error)

Process:

  1. Train one model per medicine from historical sales data
  2. Starting from current stock, iterate day-by-day subtracting predicted sales
  3. Day count when stock reaches zero = Days to Stockout

Safeguards:

  • Models cached with @st.cache_resource (1-hour TTL)
  • 365-day iteration cap prevents infinite loops
  • Negative predictions clamped to zero

πŸ” Security

Feature Implementation
Password Hashing bcrypt with configurable rounds (default: 12)
RBAC Admin/user roles stored in database
Session Timeout Configurable expiry (default: 30 minutes)
Credential Storage .env file, excluded from Git
SQL Injection SQLAlchemy parameterized queries
Custom Exceptions Structured error hierarchy (never leaks internals)

πŸ§ͺ Testing

24 tests covering 3 modules:

Module Tests Coverage
test_auth.py 9 Password hashing, register, login, delete, RBAC
test_inventory.py 9 CRUD, stock deduction, summary, properties
test_forecasting.py 4 Bounds, clamping, mock predictions
python -m pytest tests/ -v
# ======================= 24 passed in 8.91s ========================

Tests use in-memory SQLite databases β€” no effect on production data.


🐳 Docker Deployment

# Build and run
docker-compose up --build

# Or manually
docker build -t pharmastock .
docker run -p 8501:8501 --env-file .env pharmastock

The container includes a health check endpoint at /_stcore/health.


🀝 Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/your-feature)
  3. Run tests (python -m pytest tests/ -v)
  4. Commit changes (git commit -m 'Add your feature')
  5. Push and open a Pull Request

πŸ‘¨β€πŸ’» Author

Suresh Kanchamreddy

GitHub LinkedIn


Built with ❀️ using Streamlit · SQLAlchemy · XGBoost · Pydantic · Docker

About

ML-powered pharmacy inventory system that forecasts medicine demand, prevents overstocking and stockouts, and reduces drug wastage. Built with Python, XGBoost, FastAPI, and Streamlit for end-to-end intelligent stock management in pharmacies and hospitals.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors