PDO::ERRMODE_EXCEPTION] ); } catch (PDOException $e) { http_response_code(500); echo json_encode(['error' => 'DB Connection failed: ' . $e->getMessage()]); exit(); } // Parse request $method = $_SERVER['REQUEST_METHOD']; $parts = explode('/', trim($_SERVER['PATH_INFO'] ?? '', '/')); $resource = array_shift($parts); $id = array_shift($parts); // Ensure resource is 'invoices' if ($resource !== 'invoices') { http_response_code(404); echo json_encode(['error' => 'Resource not found']); exit(); } // Decode JSON input $input = json_decode(file_get_contents('php://input'), true); // Helper: fetch a single invoice with its lines function fetchInvoice(PDO $pdo, $invoiceId) { // Fetch invoice meta $stmt = $pdo->prepare("SELECT * FROM invoices WHERE id = ?"); $stmt->execute([$invoiceId]); $invoice = $stmt->fetch(PDO::FETCH_ASSOC); if (!$invoice) return null; // Fetch lines $stmt = $pdo->prepare(" SELECT il.id, il.menu_item_id, il.quantity, mi.name, mi.price FROM invoice_items il JOIN menu_items mi ON mi.id = il.menu_item_id WHERE il.invoice_id = ? "); $stmt->execute([$invoiceId]); $lines = $stmt->fetchAll(PDO::FETCH_ASSOC); $invoice['lines'] = $lines; return $invoice; } switch ($method) { case 'GET': if ($id) { // GET /invoices/{id} $invoice = fetchInvoice($pdo, $id); if (!$invoice) { http_response_code(404); echo json_encode(['error' => 'Invoice not found']); } else { echo json_encode($invoice); } } else { // GET /invoices // List all invoices without lines $stmt = $pdo->query("SELECT id, created_at FROM invoices ORDER BY created_at DESC"); $invs = $stmt->fetchAll(PDO::FETCH_ASSOC); echo json_encode($invs); } break; case 'POST': // POST /invoices // Expect payload { lines: [ { menu_item_id, quantity }, ... ] } if (empty($input['lines']) || !is_array($input['lines'])) { http_response_code(400); echo json_encode(['error' => 'Invoice lines are required']); exit(); } try { $pdo->beginTransaction(); // Create invoice record $stmt = $pdo->prepare("INSERT INTO invoices () VALUES ()"); $stmt->execute(); $invoiceId = $pdo->lastInsertId(); // Insert each line $stmtLine = $pdo->prepare(" INSERT INTO invoice_items (invoice_id, menu_item_id, quantity) VALUES (?, ?, ?) "); foreach ($input['lines'] as $line) { if (empty($line['menu_item_id']) || empty($line['quantity'])) { throw new Exception("menu_item_id and quantity required for each line"); } $stmtLine->execute([ $invoiceId, $line['menu_item_id'], $line['quantity'] ]); } $pdo->commit(); http_response_code(201); echo json_encode(['message' => 'Invoice created', 'id' => $invoiceId]); } catch (Exception $e) { $pdo->rollBack(); http_response_code(500); echo json_encode(['error' => 'Failed to create invoice: ' . $e->getMessage()]); } break; case 'DELETE': // DELETE /invoices/{id} if (!$id) { http_response_code(400); echo json_encode(['error' => 'Invoice ID is required']); exit(); } $stmt = $pdo->prepare("DELETE FROM invoices WHERE id = ?"); $stmt->execute([$id]); echo json_encode(['message' => 'Invoice deleted']); break; default: http_response_code(405); echo json_encode(['error' => 'Method not allowed']); break; }