0 AND b.expiry_date >= CURDATE() GROUP BY d.id ORDER BY d.name_en ASC"; $stmt = $pdo->query($sql); echo json_encode($stmt->fetchAll(PDO::FETCH_ASSOC)); break; case 'get_batches': $drug_id = $_GET['drug_id'] ?? 0; if (!$drug_id) throw new Exception("Drug ID required"); $sql = "SELECT b.*, s.name_en as supplier_name FROM pharmacy_batches b LEFT JOIN suppliers s ON b.supplier_id = s.id WHERE b.drug_id = ? AND b.quantity > 0 ORDER BY b.expiry_date ASC"; $stmt = $pdo->prepare($sql); $stmt->execute([$drug_id]); echo json_encode($stmt->fetchAll(PDO::FETCH_ASSOC)); break; case 'add_stock': if ($_SERVER['REQUEST_METHOD'] !== 'POST') throw new Exception("Invalid method"); $drug_id = $_POST['drug_id'] ?? 0; $batch_number = $_POST['batch_number'] ?? ''; $expiry_date = $_POST['expiry_date'] ?? ''; $quantity = $_POST['quantity'] ?? 0; $cost_price = $_POST['cost_price'] ?? 0; $sale_price = $_POST['sale_price'] ?? 0; $supplier_id = !empty($_POST['supplier_id']) ? $_POST['supplier_id'] : null; if (!$drug_id || !$batch_number || !$expiry_date || !$quantity) { throw new Exception("Missing required fields"); } $stmt = $pdo->prepare("INSERT INTO pharmacy_batches (drug_id, batch_number, expiry_date, quantity, cost_price, sale_price, supplier_id, received_date) VALUES (?, ?, ?, ?, ?, ?, ?, CURDATE())"); $stmt->execute([$drug_id, $batch_number, $expiry_date, $quantity, $cost_price, $sale_price, $supplier_id]); echo json_encode(['success' => true, 'message' => 'Stock added successfully']); break; case 'search_drugs': $q = $_GET['q'] ?? ''; $sql = "SELECT d.id, d.name_en, d.name_ar, d.sku, d.price as default_price, (SELECT sale_price FROM pharmacy_batches pb WHERE pb.drug_id = d.id AND pb.quantity > 0 AND pb.expiry_date >= CURDATE() ORDER BY pb.expiry_date ASC LIMIT 1) as batch_price, COALESCE(SUM(b.quantity), 0) as stock FROM drugs d LEFT JOIN pharmacy_batches b ON d.id = b.drug_id AND b.quantity > 0 AND b.expiry_date >= CURDATE() WHERE (d.name_en LIKE ? OR d.name_ar LIKE ? OR d.sku LIKE ?) GROUP BY d.id LIMIT 20"; $stmt = $pdo->prepare($sql); $term = "%$q%"; $stmt->execute([$term, $term, $term]); echo json_encode($stmt->fetchAll(PDO::FETCH_ASSOC)); break; case 'create_sale': if ($_SERVER['REQUEST_METHOD'] !== 'POST') throw new Exception("Invalid method"); $input = json_decode(file_get_contents('php://input'), true); if (empty($input['items'])) throw new Exception("No items in sale"); $pdo->beginTransaction(); try { // Create Sale Record $stmt = $pdo->prepare("INSERT INTO pharmacy_sales (patient_id, visit_id, total_amount, payment_method, status) VALUES (?, ?, ?, ?, 'completed')"); $stmt->execute([ $input['patient_id'] ?? null, $input['visit_id'] ?? null, $input['total_amount'] ?? 0, $input['payment_method'] ?? 'cash' ]); $sale_id = $pdo->lastInsertId(); // Process Items foreach ($input['items'] as $item) { $drug_id = $item['drug_id']; $qty_needed = $item['quantity']; $unit_price = $item['price']; // Or fetch from batch? Use provided price for now. // Fetch available batches (FIFO) $batch_stmt = $pdo->prepare("SELECT id, quantity FROM pharmacy_batches WHERE drug_id = ? AND quantity > 0 ORDER BY expiry_date ASC FOR UPDATE"); $batch_stmt->execute([$drug_id]); $batches = $batch_stmt->fetchAll(PDO::FETCH_ASSOC); $qty_remaining = $qty_needed; foreach ($batches as $batch) { if ($qty_remaining <= 0) break; $take = min($batch['quantity'], $qty_remaining); // Deduct from batch $update = $pdo->prepare("UPDATE pharmacy_batches SET quantity = quantity - ? WHERE id = ?"); $update->execute([$take, $batch['id']]); // Add to sale items $item_stmt = $pdo->prepare("INSERT INTO pharmacy_sale_items (sale_id, drug_id, batch_id, quantity, unit_price, total_price) VALUES (?, ?, ?, ?, ?, ?)"); $item_stmt->execute([$sale_id, $drug_id, $batch['id'], $take, $unit_price, $take * $unit_price]); $qty_remaining -= $take; } if ($qty_remaining > 0) { throw new Exception("Insufficient stock for drug ID: $drug_id"); } } $pdo->commit(); echo json_encode(['success' => true, 'sale_id' => $sale_id]); } catch (Exception $e) { $pdo->rollBack(); throw $e; } break; case 'get_sales': // List recent sales $sql = "SELECT s.*, p.name as patient_name FROM pharmacy_sales s LEFT JOIN patients p ON s.patient_id = p.id ORDER BY s.created_at DESC LIMIT 50"; $stmt = $pdo->query($sql); echo json_encode($stmt->fetchAll(PDO::FETCH_ASSOC)); break; case 'get_sale_details': $sale_id = $_GET['sale_id'] ?? 0; if (!$sale_id) throw new Exception("Sale ID required"); $stmt = $pdo->prepare("SELECT s.*, p.name as patient_name FROM pharmacy_sales s LEFT JOIN patients p ON s.patient_id = p.id WHERE s.id = ?"); $stmt->execute([$sale_id]); $sale = $stmt->fetch(PDO::FETCH_ASSOC); if (!$sale) throw new Exception("Sale not found"); $items_stmt = $pdo->prepare("SELECT i.*, d.name_en as drug_name FROM pharmacy_sale_items i JOIN drugs d ON i.drug_id = d.id WHERE i.sale_id = ?"); $items_stmt->execute([$sale_id]); $sale['items'] = $items_stmt->fetchAll(PDO::FETCH_ASSOC); echo json_encode($sale); break; default: throw new Exception("Invalid action"); } } catch (Exception $e) { http_response_code(400); echo json_encode(['error' => $e->getMessage()]); }