# Stock Request/Delivery Workflow - Complete Implementation

## Overview
This document verifies the complete request/receive workflow has been properly implemented.

## Implementation Summary

### Files Created/Modified:
1. **`backend/admin_stock_request_api.php`** - NEW backend API
2. **`purchase_manager/ingredients.php`** - Updated with request viewing & delivery modals
3. **`admin/ingredients.php`** - Updated with request stock feature
4. **`purchase_manager/pm-theme-enhanced.css`** - Added styling for tables

## Workflow Steps

### Phase 1: Admin Requests Stock (Admin Interface)
**File**: `admin/ingredients.php`

1. Admin logs in and views ingredients
2. Sees ingredient with "low" stock status
3. Clicks "Request Stock" button
   - Modal opens: `#requestModal`
   - Shows: Ingredient name, current stock, minimum stock
   - Inputs: quantity_needed, priority (high/medium/low), notes
4. Admin submits form
   - Calls: `admin_stock_request_api.php?action=create_request`
   - Sends: `{ingredient_id, quantity_requested, priority, notes, requested_by: 'admin'}`
   - Backend: Inserts row into `stock_requests` table with status='pending'
   - Response: Success message displayed

**Test Verification**:
- [ ] Low stock items show "Request Stock" button
- [ ] Modal opens with correct fields
- [ ] Form submission succeeds
- [ ] Success message displays

---

### Phase 2: PM Receives Pending Requests (PM Dashboard)
**File**: `purchase_manager/ingredients.php`

1. PM logs in and visits Ingredients page
2. Page loads: `loadIngredients()` + `loadPendingCount()`
   - Calls: `admin_stock_request_api.php?action=get_requests`
   - Fetches: All pending requests from stock_requests table
   - Response includes: ingredient_id, ingredient_name, quantity_requested, priority, created_at, notes
3. Badge updates: `#pendingBadge` shows count of pending requests
4. PM clicks "Pending Requests" button
   - Modal opens: `#pendingRequestsModal`
   - Table displays: All pending requests sorted by priority/date
   - Each row has: ingredient name, qty, priority (color-coded badge), requested date, notes
   - Action button: "Receive" for each request

**Test Verification**:
- [ ] Badge shows correct pending count on page load
- [ ] Pending Requests modal opens
- [ ] Table displays requests with correct data
- [ ] Priority badges show correct colors (high=red, medium=yellow, low=blue)
- [ ] Requests sorted by priority then date

---

### Phase 3: PM Confirms Delivery (Auto-Update Stock)
**File**: `purchase_manager/ingredients.php`

1. PM clicks "Receive" button on a pending request
   - Function calls: `openReceiveModal(requestId, ingredientName, unit, quantityRequested)`
   - Modal opens: `#receiveDeliveryModal`
   - Form auto-fills: ingredient name, unit, current stock (from allIngredients array)
   - PM enters: quantity_delivered, invoice_ref
   - PM clicks "Confirm Receipt & Update Stock"
   
2. Form submit calls: `confirmDeliveryReceipt(event)`
   - Gets values: ingredientId, requestId, quantityDelivered, invoiceRef
   - Makes 2 API calls in sequence:

   **Call 1**: Update Stock
   ```
   POST admin_ingredients_api.php?action=update_stock
   {id: ingredientId, quantity_received: quantityDelivered}
   ```
   - Backend: current_stock = current_stock + quantity_received
   - Success: Stock amount updated in ingredients table

   **Call 2**: Fulfill Request
   ```
   POST admin_stock_request_api.php?action=fulfill_request
   {request_id: requestId, quantity_delivered: quantityDelivered, invoice_ref: invoiceRef}
   ```
   - Backend: Sets status='fulfilled', fulfilled_by=user_id, fulfilled_at=NOW()
   - Stores: actual quantity_delivered and invoice reference

3. Post-submission:
   - Success message displayed
   - Receive modal closes
   - Ingredients table refreshes: `loadIngredients()`
   - Badge count updates: `loadPendingCount()`

**Test Verification**:
- [ ] Receive modal opens  with ingredient data
- [ ] Current stock pre-fills correctly
- [ ] Stock update API call succeeds
- [ ] Fulfill request API call succeeds  
- [ ] Ingredients table refreshes with new stock amount
- [ ] Request disappears from pending modal
- [ ] Badge count decrements
- [ ] Success message shows

---

## API Endpoints Reference

### `admin_stock_request_api.php`

#### 1. Create Request (Admin)
```
POST /backend/admin_stock_request_api.php?action=create_request
Content-Type: application/json

{
  "ingredient_id": 5,
  "quantity_requested": 50,
  "priority": "high",
  "notes": "Urgent: running low",
  "requested_by": "admin"
}

Response:
{
  "success": true,
  "message": "Stock request created successfully",
  "request_id": 123
}
```

#### 2. Get Pending Requests (PM)
```
GET /backend/admin_stock_request_api.php?action=get_requests

Response:
{
  "success": true,
  "requests": [
    {
      "id": 123,
      "ingredient_id": 5,
      "ingredient_name": "Tomato",
      "unit": "kg",
      "quantity_requested": "50.00",
      "priority": "high",
      "notes": "Urgent",
      "requested_by": "admin",
      "created_at": "2026-03-12 14:30:00",
      "current_stock": "12.00",
      "status": "pending"
    }
  ],
  "count": 1
}
```

#### 3. Fulfill Request (PM)
```
POST /backend/admin_stock_request_api.php?action=fulfill_request
Content-Type: application/json

{
  "request_id": 123,
  "quantity_delivered": 50,
  "invoice_ref": "INV-2026-001"
}

Response:
{
  "success": true,
  "message": "Request marked as fulfilled successfully"
}
```

---

## Database Schema

### stock_requests Table
```sql
CREATE TABLE stock_requests (
  id INT PRIMARY KEY AUTO_INCREMENT,
  ingredient_id INT NOT NULL,
  quantity_requested DECIMAL(10,2) NOT NULL,
  priority ENUM('low','medium','high') DEFAULT 'medium',
  notes TEXT,
  status ENUM('pending','fulfilled','cancelled') DEFAULT 'pending',
  requested_by VARCHAR(50) NOT NULL,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  fulfilled_by VARCHAR(50),
  quantity_delivered DECIMAL(10,2),
  invoice_ref VARCHAR(100),
  fulfilled_at TIMESTAMP NULL,
  FOREIGN KEY (ingredient_id) REFERENCES ingredients(id),
  INDEX idx_status (status),
  INDEX idx_ingredient (ingredient_id),
  INDEX idx_created (created_at)
);
```

---

## CSS Classes

- `.requests-table` - Main table styling for pending requests
- `.badge` - Base badge styling
- `.badge.priority-high` - Red background (#fee2e2, #991b1b text)
- `.badge.priority-medium` - Yellow background (#fef3c7, #92400e text)
- `.badge.priority-low` - Blue background (#e0f2fe, #0c4a6e text)
- `#pendingBadge` - Red circular badge on Pending Requests button

---

## JavaScript Functions

### Admin Side (`admin/ingredients.php`)
- `openRequestModal(id, name, currentStock, minimumStock, unit)` - Opens request modal
- `closeRequestModal()` - Closes request modal
- `submitStockRequest(e)` - Submits request to API

### PM Side (`purchase_manager/ingredients.php`)
- `viewPendingRequests()` - Fetches and displays pending requests
- `updatePendingBadge(count)` - Updates badge count
- `loadPendingCount()` - Loads pending count on page init
- `closePendingRequestsModal()` - Closes pending modal
- `openReceiveModal(...)` - Opens receive delivery modal
- `closeReceiveModal()` - Closes receive modal
- `confirmDeliveryReceipt(e)` - Confirms delivery and updates stock

---

## Validation Checklist

### Admin Functionality
- [ ] Low stock items show "Request Stock" button
- [ ] Modal displays all required fields
- [ ] Form validation (quantity > 0)
- [ ] Priority dropdown works
- [ ] Notes textarea accepts text
- [ ] Submit button calls API with correct parameters
- [ ] Success message shows after submission
- [ ] Modal closes after successful submission

### PM Functionality  
- [ ] Badge updates on page load
- [ ] Pending Requests modal displays
- [ ] Table shows all pending requests  
- [ ] Priority badges color-coded
- [ ] Requests sorted by priority then date
- [ ] Receive button opens delivery modal
- [ ] Delivery modal auto-fills ingredient data
- [ ] Current stock shows correctly
- [ ] Quantity delivered field required
- [ ] Submit triggers both API calls
- [ ] Stock updates in ingredients table
- [ ] Request removed from pending list
- [ ] Badge count decrements
- [ ] Success message displays

### API Functionality
- [ ] `create_request` inserts into stock_requests table
- [ ] `get_requests` returns pending requests with all fields
- [ ] `fulfill_request` updates request status and stores delivery info
- [ ] Proper error handling and validation
- [ ] Database table auto-created if not exists

---

## Testing Scenarios

### Scenario 1: Complete Request/Delivery Cycle
1. Login as Admin
2. Go to Ingredients page
3. Find low stock item
4. Click "Request Stock"
5. Fill form: qty=100, priority=high, notes="Needed ASAP"
6. Submit and verify success message
7. Logout and login as PM
8. Go to Ingredients page
9. Verify badge shows "1"
10. Click Pending Requests
11. Verify table shows the request
12. Click "Receive"
13. Verify modal shows correct ingredient
14. Enter quantity delivered: 100, invoice: INV-001
15. Submit and verify:
    - Stock updated (current_stock += 100)
    - Request disappears from pending
    - Badge count becomes 0
    - Success message shown

### Scenario 2: Multiple Requests with Priority Sorting
1. Admin creates 3 requests: 1 high, 1 medium, 1 low priority
2. PM views pending requests
3. Verify high priority appears first
4. Verify within same priority, sorted by creation date (newest first)

### Scenario 3: Partial Delivery
1. Admin requests 100 units
2. PM receives only 60 units
3. Verify stock increased by 60
4. Request marked fulfilled with delivered=60, requested=100

---

## Known Limitations & Future Enhancements

- No partial fulfillment tracking (stores both quantities but no status distinction)
- No automatic email notifications (could add mail service)
- No request cancellation from PM side
- No amendment of requests after creation
- Activity logs optional (gracefully fails if table absent)

---

## Troubleshooting

### Badge shows 0 but pending requests visible
- Check `loadPendingCount()` is called during page init
- Verify API returns correct count

### Receive modal data doesn't populate
- Check `allIngredients` array is loaded before modal opens
- Verify ingredient ID matching logic

### Stock not updating after delivery
- Check both API calls (update_stock and fulfill_request) succeed
- Verify ingredient ID passed to update_stock is correct
- Check admin_ingredients_api.php?action=update_stock API works

### Requests still show after fulfill
- Check `loadPendingCount()` called after delivery
- Verify stock_requests table status='pending' filter works
- Check fulfilled_at timestamp is set

