# Hospital Logistics

> When the user wants to optimize hospital supply chain operations, manage medical materials, optimize PAR levels, or improve hospital inventory management. Also use when the user mentions "hospital supply chain," "materials management," "PAR levels," "OR inventory," "clinical logistics," "hospital distribution," "medical supplies," "stockroom management," "two-bin system," "floor stock," or "hospi…

- **Type:** Skill
- **Install:** `agentstack add skill-kishorkukreja-awesome-supply-chain-hospital-logistics`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [kishorkukreja](https://agentstack.voostack.com/s/kishorkukreja)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [kishorkukreja](https://github.com/kishorkukreja)
- **Source:** https://github.com/kishorkukreja/awesome-supply-chain/tree/main/skills/hospital-logistics

## Install

```sh
agentstack add skill-kishorkukreja-awesome-supply-chain-hospital-logistics
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Hospital Logistics

You are an expert in hospital logistics and healthcare materials management. Your goal is to optimize the flow of medical supplies, pharmaceuticals, and equipment throughout healthcare facilities while maintaining patient safety, regulatory compliance, and cost efficiency.

## Initial Assessment

Before optimizing hospital logistics, understand:

1. **Facility Characteristics**
   - Type of facility? (acute care, specialty hospital, health system)
   - Number of beds and patient volume?
   - Departments and service lines? (OR, ER, ICU, med-surg)
   - Number of locations? (main campus, clinics, satellite facilities)

2. **Current Supply Chain Structure**
   - Centralized vs. decentralized inventory?
   - Materials management system in use? (ERP, MMM system)
   - PAR level methodology current state?
   - Distribution model? (requisition, exchange cart, case cart)

3. **Inventory & Cost Profile**
   - Total inventory investment?
   - Inventory turns by category?
   - Annual supply spend? (% of operating budget)
   - High-dollar items? (implants, specialty devices)

4. **Challenges & Goals**
   - Current pain points? (stockouts, excess, expiry, waste)
   - Service level targets?
   - Cost reduction goals?
   - Compliance concerns? (Joint Commission, FDA)

---

## Hospital Logistics Framework

### Supply Chain Models in Healthcare

**1. Traditional Requisition Model**
- Departments order from central storeroom
- Staff shops from supply room
- High labor cost, variable inventory
- Pros: Flexibility
- Cons: Inefficient, overstocking, poor control

**2. Exchange Cart System**
- Pre-filled carts exchanged on schedule
- Departments receive full cart, return empty
- Better control and efficiency
- Ideal for: Med-surg floors, standard supplies

**3. Case Cart System**
- Custom kits for each surgical procedure
- Assembled in central supply or by vendor
- Used primarily in OR
- Reduces waste, improves efficiency

**4. Just-In-Time (JIT) Delivery**
- Supplies delivered directly to point of use
- Minimal on-hand inventory
- Requires reliable supplier performance
- Examples: Stockless programs, vendor-managed inventory

**5. Two-Bin (Kanban) System**
- Visual replenishment system
- When bin 1 empty, use bin 2 and trigger reorder
- Simple, effective for high-use items
- Reduces stockouts and overstock

---

## PAR Level Optimization

### Understanding PAR Levels

**PAR (Periodic Automatic Replenishment):**
- Target inventory level maintained at point of use
- Replenished to PAR on regular schedule
- Key metric in hospital materials management

**PAR Formula:**
```
PAR Level = (Average Daily Usage × Replenishment Cycle Days) + Safety Stock
```

**Example:**
```
Item: IV Start Kit
Average daily usage: 15 kits
Replenishment cycle: 3 days (Monday, Wednesday, Friday)
Lead time variability: 1 day safety buffer
PAR Level = (15 × 3) + (15 × 1) = 45 + 15 = 60 kits
```

### Python Implementation

```python
import pandas as pd
import numpy as np
from scipy import stats

def calculate_par_level(avg_daily_usage, replenishment_cycle_days,
                        service_level=0.95, usage_variability=None):
    """
    Calculate optimal PAR level for hospital supply item

    Parameters:
    - avg_daily_usage: Average daily consumption
    - replenishment_cycle_days: Days between replenishment
    - service_level: Target service level (e.g., 0.95 for 95%)
    - usage_variability: Std dev of daily usage (if known)

    Returns:
    - Dictionary with PAR level and components
    """

    # Expected usage during cycle
    expected_usage = avg_daily_usage * replenishment_cycle_days

    # Safety stock calculation
    if usage_variability is not None:
        # Statistical approach if variability known
        z_score = stats.norm.ppf(service_level)
        std_during_cycle = usage_variability * np.sqrt(replenishment_cycle_days)
        safety_stock = z_score * std_during_cycle
    else:
        # Rule of thumb: 1 day's worth for weekly replenishment
        # 0.5 days for more frequent (2-3x/week)
        if replenishment_cycle_days >= 7:
            safety_stock = avg_daily_usage * 2
        elif replenishment_cycle_days >= 3:
            safety_stock = avg_daily_usage * 1
        else:
            safety_stock = avg_daily_usage * 0.5

    par_level = expected_usage + safety_stock

    return {
        'par_level': round(par_level, 0),
        'expected_usage': round(expected_usage, 0),
        'safety_stock': round(safety_stock, 0),
        'replenishment_qty_avg': round(expected_usage, 0)
    }

# Example usage
result = calculate_par_level(
    avg_daily_usage=15,
    replenishment_cycle_days=3,
    service_level=0.95,
    usage_variability=5  # daily std dev
)

print(f"PAR Level: {result['par_level']} units")
print(f"Expected cycle usage: {result['expected_usage']} units")
print(f"Safety stock: {result['safety_stock']} units")
```

### PAR Level Optimization Across Locations

```python
def optimize_par_levels_multi_location(usage_data_df):
    """
    Optimize PAR levels across multiple hospital locations

    usage_data_df: DataFrame with columns:
        - location: Department/floor name
        - item_id: Product identifier
        - daily_usage: Historical daily usage list
        - replenishment_days: Days between replenishment
        - unit_cost: Cost per unit
    """

    results = []

    for idx, row in usage_data_df.iterrows():
        usage_array = np.array(row['daily_usage'])

        avg_daily = np.mean(usage_array)
        std_daily = np.std(usage_array)

        # Calculate PAR
        par_calc = calculate_par_level(
            avg_daily_usage=avg_daily,
            replenishment_cycle_days=row['replenishment_days'],
            service_level=0.95,
            usage_variability=std_daily
        )

        # Calculate inventory metrics
        avg_inventory = par_calc['par_level'] / 2  # On average
        inventory_value = avg_inventory * row['unit_cost']
        annual_usage = avg_daily * 365
        turns = annual_usage / avg_inventory if avg_inventory > 0 else 0

        results.append({
            'location': row['location'],
            'item_id': row['item_id'],
            'avg_daily_usage': round(avg_daily, 1),
            'std_daily_usage': round(std_daily, 1),
            'cv': round(std_daily / avg_daily, 2) if avg_daily > 0 else 0,
            'current_par': row.get('current_par', 0),
            'recommended_par': par_calc['par_level'],
            'par_change': par_calc['par_level'] - row.get('current_par', 0),
            'avg_inventory': round(avg_inventory, 0),
            'inventory_value': round(inventory_value, 2),
            'annual_turns': round(turns, 1)
        })

    results_df = pd.DataFrame(results)

    # Summary statistics
    summary = {
        'total_current_value': results_df['inventory_value'].sum() if 'current_par' in usage_data_df.columns else 0,
        'total_recommended_value': results_df['inventory_value'].sum(),
        'potential_savings': 0,  # Calculate based on current vs recommended
        'avg_turns': results_df['annual_turns'].mean()
    }

    return results_df, summary

# Example usage
usage_data = pd.DataFrame({
    'location': ['OR-1', 'OR-1', 'ICU', 'ICU', 'ER'],
    'item_id': ['IV-001', 'Suture-003', 'IV-001', 'Cath-002', 'Gloves-L'],
    'daily_usage': [
        [12, 15, 10, 18, 14],
        [5, 6, 4, 7, 5],
        [25, 30, 22, 28, 26],
        [8, 10, 7, 9, 8],
        [45, 50, 42, 48, 46]
    ],
    'replenishment_days': [3, 7, 2, 3, 2],
    'unit_cost': [15.50, 8.75, 15.50, 125.00, 0.25],
    'current_par': [60, 45, 75, 35, 120]
})

results_df, summary = optimize_par_levels_multi_location(usage_data)
print(results_df[['location', 'item_id', 'current_par', 'recommended_par', 'par_change']])
```

---

## Operating Room (OR) Supply Management

### Case Cart Optimization

**Case Cart Process:**
1. Physician preference cards define items per procedure
2. Carts picked and assembled in central supply
3. Delivered to OR before case
4. Unused items returned, cleaned, restocked

**Optimization Opportunities:**
- Standardize preference cards
- Reduce variation in similar procedures
- Track utilization rates
- Eliminate rarely-used items

```python
def analyze_case_cart_utilization(procedure_data_df):
    """
    Analyze OR case cart utilization and identify waste

    procedure_data_df: DataFrame with:
        - procedure_type: Type of surgery
        - item_id: Product on preference card
        - quantity_picked: Items placed on cart
        - quantity_used: Items actually used
        - unit_cost: Cost per item
        - num_cases: Number of times procedure performed
    """

    results = []

    for idx, row in procedure_data_df.iterrows():
        qty_picked = row['quantity_picked']
        qty_used = row['quantity_used']

        utilization_rate = qty_used / qty_picked if qty_picked > 0 else 0
        waste_qty = qty_picked - qty_used
        waste_per_case = waste_qty
        annual_waste_qty = waste_per_case * row['num_cases']
        annual_waste_value = annual_waste_qty * row['unit_cost']

        # Recommendation
        if utilization_rate  0 else 'Purchase'
        }
    }

# Example: Hip implant analysis
hip_implant = {
    'annual_usage': 200,
    'purchase_price': 3500,
    'consignment_fee_pct': 0.05,  # 5% consignment fee
    'purchase_holding_cost_rate': 0.20,  # 20% annual holding cost
    'avg_inventory_months': 2  # 2 months safety stock
}

analysis = consignment_vs_purchase_analysis(hip_implant)
print("Purchase Model:")
print(f"  Annual product cost: ${analysis['purchase_model']['annual_product_cost']:,.2f}")
print(f"  Annual holding cost: ${analysis['purchase_model']['annual_holding_cost']:,.2f}")
print(f"  Total: ${analysis['purchase_model']['total_annual_cost']:,.2f}")
print(f"  Inventory value: ${analysis['purchase_model']['avg_inventory_value']:,.2f}")
print("\nConsignment Model:")
print(f"  Annual cost: ${analysis['consignment_model']['annual_cost']:,.2f}")
print(f"  Inventory value: $0 (vendor-owned)")
print(f"\nRecommendation: {analysis['comparison']['recommendation']}")
print(f"Annual savings: ${analysis['comparison']['annual_savings']:,.2f}")
print(f"Cash freed: ${analysis['comparison']['inventory_freed']:,.2f}")
```

---

## Inventory Classification & Management

### ABC-VEN Analysis for Healthcare

**ABC Classification:** Value-based (standard)
- A: High-value items (70-80% of spend)
- B: Medium-value items
- C: Low-value items

**VEN Classification:** Criticality-based (healthcare-specific)
- V (Vital): Life-saving, essential for patient care
- E (Essential): Important but not immediately life-threatening
- N (Non-essential): Desirable but not critical

**Combined ABC-VEN Matrix:**

```python
def abc_ven_classification(items_df):
    """
    Perform ABC-VEN analysis for hospital inventory

    items_df: DataFrame with:
        - item_id: Product identifier
        - annual_usage: Units per year
        - unit_cost: Cost per unit
        - criticality: 'V', 'E', or 'N'
    """

    # ABC analysis
    items_df = items_df.copy()
    items_df['annual_value'] = items_df['annual_usage'] * items_df['unit_cost']
    items_df = items_df.sort_values('annual_value', ascending=False)

    total_value = items_df['annual_value'].sum()
    items_df['cumulative_value'] = items_df['annual_value'].cumsum()
    items_df['cumulative_pct'] = (items_df['cumulative_value'] / total_value) * 100

    def classify_abc(pct):
        if pct  0:
            usage_per_year = num_events  # Assuming data is annual
            time_between_uses = 365 / num_events if num_events > 0 else 999
        else:
            usage_per_year = 0
            time_between_uses = 999

        # Calculate expiry risk
        expiry_risk_score = row['par_level'] / (row['expiry_months'] / usage_per_year) if usage_per_year > 0 else 0

        # Waste from expiry
        if time_between_uses > (row['expiry_months'] * 30):
            # Likely to expire before use
            annual_expiry_waste = row['par_level'] * (12 / row['expiry_months']) * row['unit_cost']
        else:
            annual_expiry_waste = 0

        # Recommendation
        if usage_per_year == 0 and row['expiry_months']  2:
            recommended_par = max(1, int(row['par_level'] / 2))
            recommendation = f"Reduce PAR to {recommended_par} - expiry risk"
        elif usage_per_year > 12:
            recommendation = "Maintain PAR - frequent usage"
        else:
            recommendation = "Current PAR appropriate"

        results.append({
            'cart_location': row['cart_location'],
            'item_id': row['item_id'],
            'current_par': row['par_level'],
            'annual_usage_events': usage_per_year,
            'days_between_uses': round(time_between_uses, 0),
            'expiry_months': row['expiry_months'],
            'annual_expiry_waste': round(annual_expiry_waste, 2),
            'recommendation': recommendation
        })

    results_df = pd.DataFrame(results)

    total_waste = results_df['annual_expiry_waste'].sum()

    return results_df, {'total_annual_expiry_waste': round(total_waste, 2)}

# Example crash cart data
crash_cart_data = pd.DataFrame({
    'cart_location': ['ICU-Floor-3', 'ICU-Floor-3', 'ER-Main', 'ER-Main', 'Med-Surg-2'],
    'item_id': ['Epinephrine-1mg', 'Atropine-1mg', 'Epinephrine-1mg', 'Narcan-2mg', 'Epinephrine-1mg'],
    'par_level': [10, 8, 10, 15, 8],
    'usage_events': [[1, 2], [], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], [1]],
    'expiry_months': [18, 24, 18, 12, 18],
    'unit_cost': [8.50, 6.25, 8.50, 42.00, 8.50]
})

cart_results, cart_summary = optimize_crash_cart_inventory(crash_cart_data)
print("Crash Cart Optimization Results:")
print(cart_results)
print(f"\nTotal annual waste from expiry: ${cart_summary['total_annual_expiry_waste']:,.2f}")
```

---

## Stockout Prevention & Service Levels

### Stockout Analysis & Prevention

```python
def stockout_root_cause_analysis(stockout_data_df):
    """
    Analyze stockout events and identify root causes

    stockout_data_df: DataFrame with:
        - item_id: Product
        - stockout_date: When stockout occurred
        - location: Where it occurred
        - root_cause: Category (PAR_too_low, Delivery_delay, Demand_spike, etc.)
        - clinical_impact: High/Medium/Low
        - duration_hours: How long stockout lasted
    """

    # Root cause frequency
    root_cause_summary = stockout_data_df.groupby('root_cause').agg({
        'item_id': 'count',
        'duration_hours': 'mean'
    }).rename(columns={'item_id': 'occurrences'})

    root_cause_summary['avg_duration_hours'] = root_cause_summary['duration_hours'].round(1)

    # Clinical impact
    impact_summary = stockout_data_df.groupby('clinical_impact').size()

    # Most frequently stocked-out items
    frequent_stockouts = stockout_data_df.groupby('item_id').size().sort_values(ascending=False)

    # Corrective actions by root cause
    def corrective_action(cause):
        actions = {
            'PAR_too_low': 'Increase PAR level based on usage data',
            'Delivery_delay': 'Add safety stock buffer, evaluate supplier performance',
            'Demand_spike': 'Improve demand forecasting, add safety stock for variability',
            'Ordering_error': 'Implement automated replenishment, staff training',
            'Supplier_shortage': 'Identify alternative suppliers, increase lead time buffer',
            'Product_recall': 'Maintain recall reserve stock for critical items',
            'Inventory_error': 'Implement cycle counting, improve inventory accuracy'
        }
        return actions.get(cause, 'Investigate and implement preventive measures')

    root_cause_summary['corrective_action'] = root_cause_summary.index.map(corrective_action)

    return {
        'root_cause_summary': root_cause_summary,
        'impact_summary': impact_summary,
        'frequent_

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [kishorkukreja](https://github.com/kishorkukreja)
- **Source:** [kishorkukreja/awesome-supply-chain](https://github.com/kishorkukreja/awesome-supply-chain)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-kishorkukreja-awesome-supply-chain-hospital-logistics
- Seller: https://agentstack.voostack.com/s/kishorkukreja
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
