'Method Not Allowed']); exit; } $data = json_decode(file_get_contents('php://input'), true); $customer_id = $data['customer_id'] ?? null; $items = $data['items'] ?? []; $tax_ids = $data['tax_ids'] ?? []; if (empty($items)) { http_response_code(400); echo json_encode(['error' => 'Sale must have at least one item']); exit; } try { $pdo = db(); $pdo->beginTransaction(); // 1. Calculate subtotal and check stock $subtotal = 0; foreach ($items as $item) { $product_id = $item['product_id'] ?? null; $quantity = $item['quantity'] ?? null; if (!$product_id || !$quantity || $quantity <= 0) { throw new Exception('Invalid item data'); } $stmt = $pdo->prepare("SELECT price, quantity FROM products WHERE id = ? FOR UPDATE"); $stmt->execute([$product_id]); $product = $stmt->fetch(PDO::FETCH_ASSOC); if (!$product) { throw new Exception("Product with ID $product_id not found"); } if ($product['quantity'] < $quantity) { throw new Exception("Not enough stock for product ID $product_id"); } $subtotal += $product['price'] * $quantity; } // 2. Calculate taxes $tax_total = 0; $taxes_to_apply = []; if (!empty($tax_ids)) { $sql = "SELECT id, rate FROM taxes WHERE id IN (" . implode(',', array_fill(0, count($tax_ids), '?')) . ")"; $stmt = $pdo->prepare($sql); $stmt->execute($tax_ids); $taxes = $stmt->fetchAll(PDO::FETCH_ASSOC); foreach ($taxes as $tax) { $tax_amount = ($subtotal * $tax['rate']) / 100; $tax_total += $tax_amount; $taxes_to_apply[] = ['id' => $tax['id'], 'amount' => $tax_amount]; } } $total_amount = $subtotal + $tax_total; // 3. Update product quantities foreach ($items as $item) { $stmt = $pdo->prepare("UPDATE products SET quantity = quantity - ? WHERE id = ?"); $stmt->execute([$item['quantity'], $item['product_id']]); } // 4. Insert into sales table $stmt = $pdo->prepare("INSERT INTO sales (customer_id, subtotal, tax_total, total_amount) VALUES (?, ?, ?, ?)"); $stmt->execute([$customer_id, $subtotal, $tax_total, $total_amount]); $sale_id = $pdo->lastInsertId(); // 5. Insert into sale_items $stmt = $pdo->prepare("INSERT INTO sale_items (sale_id, product_id, quantity, price) VALUES (?, ?, ?, (SELECT price FROM products WHERE id = ?))"); foreach ($items as $item) { $stmt->execute([$sale_id, $item['product_id'], $item['quantity'], $item['product_id']]); } // 6. Insert into sale_taxes if (!empty($taxes_to_apply)) { $stmt = $pdo->prepare("INSERT INTO sale_taxes (sale_id, tax_id, tax_amount) VALUES (?, ?, ?)"); foreach ($taxes_to_apply as $tax) { $stmt->execute([$sale_id, $tax['id'], $tax['amount']]); } } $pdo->commit(); http_response_code(201); echo json_encode(['success' => 'Sale created successfully', 'sale_id' => $sale_id, 'total_amount' => $total_amount]); } catch (Exception $e) { if ($pdo->inTransaction()) { $pdo->rollBack(); } http_response_code(400); echo json_encode(['error' => $e->getMessage()]); }