diff --git a/customers/create.php b/customers/create.php new file mode 100644 index 0000000..0858f91 --- /dev/null +++ b/customers/create.php @@ -0,0 +1,54 @@ + 'Method Not Allowed']); + exit; +} + +$data = json_decode(file_get_contents('php://input'), true); + +$first_name = $data['first_name'] ?? null; +$last_name = $data['last_name'] ?? null; +$email = $data['email'] ?? null; +$phone = $data['phone'] ?? null; +$address = $data['address'] ?? null; + +if (!$first_name || !$last_name || !$email) { + http_response_code(400); + echo json_encode(['error' => 'Missing required fields: first_name, last_name, email']); + exit; +} + +if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { + http_response_code(400); + echo json_encode(['error' => 'Invalid email format']); + exit; +} + +try { + $pdo = db(); + + $stmt = $pdo->prepare("SELECT id FROM customers WHERE email = ?"); + $stmt->execute([$email]); + if ($stmt->fetch()) { + http_response_code(409); + echo json_encode(['error' => 'Customer with this email already exists']); + exit; + } + + $stmt = $pdo->prepare("INSERT INTO customers (first_name, last_name, email, phone, address) VALUES (?, ?, ?, ?, ?)"); + $stmt->execute([$first_name, $last_name, $email, $phone, $address]); + + $id = $pdo->lastInsertId(); + + http_response_code(201); + echo json_encode(['success' => 'Customer created successfully', 'id' => $id]); + +} catch (PDOException $e) { + http_response_code(500); + echo json_encode(['error' => 'Database error: ' . $e->getMessage()]); +} diff --git a/customers/delete.php b/customers/delete.php new file mode 100644 index 0000000..3b9cd6e --- /dev/null +++ b/customers/delete.php @@ -0,0 +1,33 @@ + 'Customer ID is required']); + exit; +} + +try { + $pdo = db(); + + $stmt = $pdo->prepare("SELECT id FROM customers WHERE id = ?"); + $stmt->execute([$id]); + if (!$stmt->fetch()) { + http_response_code(404); + echo json_encode(['error' => 'Customer not found']); + exit; + } + + $stmt = $pdo->prepare("DELETE FROM customers WHERE id = ?"); + $stmt->execute([$id]); + + echo json_encode(['success' => 'Customer deleted successfully']); + +} catch (PDOException $e) { + http_response_code(500); + echo json_encode(['error' => 'Database error: ' . $e->getMessage()]); +} diff --git a/customers/read.php b/customers/read.php new file mode 100644 index 0000000..b3facf8 --- /dev/null +++ b/customers/read.php @@ -0,0 +1,31 @@ +prepare("SELECT * FROM customers WHERE id = ?"); + $stmt->execute([$id]); + $customer = $stmt->fetch(PDO::FETCH_ASSOC); + + if ($customer) { + echo json_encode($customer); + } else { + http_response_code(404); + echo json_code(['error' => 'Customer not found']); + } + } else { + $stmt = $pdo->query("SELECT * FROM customers"); + $customers = $stmt->fetchAll(PDO::FETCH_ASSOC); + echo json_encode($customers); + } + +} catch (PDOException $e) { + http_response_code(500); + echo json_encode(['error' => 'Database error: ' . $e->getMessage()]); +} diff --git a/customers/update.php b/customers/update.php new file mode 100644 index 0000000..5ef685b --- /dev/null +++ b/customers/update.php @@ -0,0 +1,67 @@ + 'Method Not Allowed']); + exit; +} + +$id = $_GET['id'] ?? null; + +if (!$id) { + http_response_code(400); + echo json_encode(['error' => 'Customer ID is required']); + exit; +} + +$data = json_decode(file_get_contents('php://input'), true); + +$first_name = $data['first_name'] ?? null; +$last_name = $data['last_name'] ?? null; +$email = $data['email'] ?? null; +$phone = $data['phone'] ?? null; +$address = $data['address'] ?? null; + +if (!$first_name || !$last_name || !$email) { + http_response_code(400); + echo json_encode(['error' => 'Missing required fields: first_name, last_name, email']); + exit; +} + +if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { + http_response_code(400); + echo json_encode(['error' => 'Invalid email format']); + exit; +} + +try { + $pdo = db(); + + $stmt = $pdo->prepare("SELECT id FROM customers WHERE id = ?"); + $stmt->execute([$id]); + if (!$stmt->fetch()) { + http_response_code(404); + echo json_encode(['error' => 'Customer not found']); + exit; + } + + $stmt = $pdo->prepare("SELECT id FROM customers WHERE email = ? AND id != ?"); + $stmt->execute([$email, $id]); + if ($stmt->fetch()) { + http_response_code(409); + echo json_encode(['error' => 'Another customer with this email already exists']); + exit; + } + + $stmt = $pdo->prepare("UPDATE customers SET first_name = ?, last_name = ?, email = ?, phone = ?, address = ? WHERE id = ?"); + $stmt->execute([$first_name, $last_name, $email, $phone, $address, $id]); + + echo json_encode(['success' => 'Customer updated successfully']); + +} catch (PDOException $e) { + http_response_code(500); + echo json_encode(['error' => 'Database error: ' . $e->getMessage()]); +} diff --git a/db/schema.sql b/db/schema.sql new file mode 100644 index 0000000..d1282da --- /dev/null +++ b/db/schema.sql @@ -0,0 +1,80 @@ +-- Initial schema for CheersPOS System + +CREATE TABLE IF NOT EXISTS `roles` ( + `id` INT AUTO_INCREMENT PRIMARY KEY, + `name` VARCHAR(255) NOT NULL UNIQUE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +-- Insert default roles +INSERT IGNORE INTO `roles` (`name`) VALUES + ('Admin'), + ('Manager'), + ('Inventory Manager'), + ('Cashier'), + ('HR Manager'), + ('Customer Manager'); + +CREATE TABLE IF NOT EXISTS `users` ( + `id` INT AUTO_INCREMENT PRIMARY KEY, + `username` VARCHAR(255) NOT NULL UNIQUE, + `password` VARCHAR(255) NOT NULL, + `email` VARCHAR(255) NOT NULL UNIQUE, + `role_id` INT, + `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (`role_id`) REFERENCES `roles`(`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +CREATE TABLE IF NOT EXISTS `products` ( + `id` INT AUTO_INCREMENT PRIMARY KEY, + `name` VARCHAR(255) NOT NULL, + `description` TEXT, + `price` DECIMAL(10, 2) NOT NULL, + `cost` DECIMAL(10, 2) NOT NULL DEFAULT 0.00, + `quantity` INT NOT NULL DEFAULT 0, + `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +CREATE TABLE IF NOT EXISTS `customers` ( + `id` INT AUTO_INCREMENT PRIMARY KEY, + `first_name` VARCHAR(255) NOT NULL, + `last_name` VARCHAR(255) NOT NULL, + `email` VARCHAR(255) NOT NULL UNIQUE, + `phone` VARCHAR(50), + `address` TEXT, + `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +CREATE TABLE IF NOT EXISTS `sales` ( + `id` INT AUTO_INCREMENT PRIMARY KEY, + `customer_id` INT, + `subtotal` DECIMAL(10, 2) NOT NULL, + `tax_total` DECIMAL(10, 2) NOT NULL DEFAULT 0.00, + `total_amount` DECIMAL(10, 2) NOT NULL, + `sale_date` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (`customer_id`) REFERENCES `customers`(`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +CREATE TABLE IF NOT EXISTS `sale_items` ( + `id` INT AUTO_INCREMENT PRIMARY KEY, + `sale_id` INT, + `product_id` INT, + `quantity` INT NOT NULL, + `price` DECIMAL(10, 2) NOT NULL, + FOREIGN KEY (`sale_id`) REFERENCES `sales`(`id`) ON DELETE CASCADE, + FOREIGN KEY (`product_id`) REFERENCES `products`(`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +CREATE TABLE IF NOT EXISTS `taxes` ( + `id` INT AUTO_INCREMENT PRIMARY KEY, + `name` VARCHAR(255) NOT NULL UNIQUE, + `rate` DECIMAL(5, 2) NOT NULL COMMENT 'Percentage' +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +CREATE TABLE IF NOT EXISTS `sale_taxes` ( + `id` INT AUTO_INCREMENT PRIMARY KEY, + `sale_id` INT, + `tax_id` INT, + `tax_amount` DECIMAL(10, 2) NOT NULL, + FOREIGN KEY (`sale_id`) REFERENCES `sales`(`id`) ON DELETE CASCADE, + FOREIGN KEY (`tax_id`) REFERENCES `taxes`(`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; diff --git a/db/setup.php b/db/setup.php new file mode 100644 index 0000000..2f94c9f --- /dev/null +++ b/db/setup.php @@ -0,0 +1,42 @@ + PDO::ERRMODE_EXCEPTION, + PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, + ]); + + // Create the database if it doesn't exist + $pdo->exec("CREATE DATABASE IF NOT EXISTS `" . DB_NAME . "`"); + + // Reconnect to the specific database + $pdo = db(); + + $sql = file_get_contents(__DIR__ . '/schema.sql'); + $pdo->exec($sql); + echo "Database schema created successfully.\n"; + + // Check if 'cost' column exists in 'products' table and add it if not + $stmt = $pdo->query("SHOW COLUMNS FROM `products` LIKE 'cost'"); + $column_exists = $stmt->fetch(PDO::FETCH_ASSOC); + + if (!$column_exists) { + $pdo->exec("ALTER TABLE `products` ADD `cost` DECIMAL(10, 2) NOT NULL DEFAULT 0.00 AFTER `price`"); + echo "Column 'cost' added to 'products' table successfully.\n"; + } + + // Check if 'subtotal' column exists in 'sales' table and add columns if not + $stmt = $pdo->query("SHOW COLUMNS FROM `sales` LIKE 'subtotal'"); + $column_exists = $stmt->fetch(PDO::FETCH_ASSOC); + + if (!$column_exists) { + $pdo->exec("ALTER TABLE `sales` ADD `subtotal` DECIMAL(10, 2) NOT NULL AFTER `customer_id`"); + $pdo->exec("ALTER TABLE `sales` ADD `tax_total` DECIMAL(10, 2) NOT NULL DEFAULT 0.00 AFTER `subtotal`"); + echo "Columns 'subtotal' and 'tax_total' added to 'sales' table successfully.\n"; + } + +} catch (PDOException $e) { + die("Database setup failed: " . $e->getMessage() . "\n"); +} \ No newline at end of file diff --git a/employees/create.php b/employees/create.php new file mode 100644 index 0000000..3f45166 --- /dev/null +++ b/employees/create.php @@ -0,0 +1,55 @@ + 'Method Not Allowed']); + exit; +} + +$data = json_decode(file_get_contents('php://input'), true); + +$first_name = $data['first_name'] ?? null; +$last_name = $data['last_name'] ?? null; +$email = $data['email'] ?? null; +$phone = $data['phone'] ?? null; +$role_id = $data['role_id'] ?? null; +$hire_date = $data['hire_date'] ?? null; + +if (!$first_name || !$last_name || !$email || !$role_id) { + http_response_code(400); + echo json_encode(['error' => 'Missing required fields: first_name, last_name, email, role_id']); + exit; +} + +if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { + http_response_code(400); + echo json_encode(['error' => 'Invalid email format']); + exit; +} + +try { + $pdo = db(); + + $stmt = $pdo->prepare("SELECT id FROM employees WHERE email = ?"); + $stmt->execute([$email]); + if ($stmt->fetch()) { + http_response_code(409); + echo json_encode(['error' => 'Employee with this email already exists']); + exit; + } + + $stmt = $pdo->prepare("INSERT INTO employees (first_name, last_name, email, phone, role_id, hire_date) VALUES (?, ?, ?, ?, ?, ?)"); + $stmt->execute([$first_name, $last_name, $email, $phone, $role_id, $hire_date]); + + $id = $pdo->lastInsertId(); + + http_response_code(201); + echo json_encode(['success' => 'Employee created successfully', 'id' => $id]); + +} catch (PDOException $e) { + http_response_code(500); + echo json_encode(['error' => 'Database error: ' . $e->getMessage()]); +} diff --git a/employees/delete.php b/employees/delete.php new file mode 100644 index 0000000..2aeaa86 --- /dev/null +++ b/employees/delete.php @@ -0,0 +1,33 @@ + 'Employee ID is required']); + exit; +} + +try { + $pdo = db(); + + $stmt = $pdo->prepare("SELECT id FROM employees WHERE id = ?"); + $stmt->execute([$id]); + if (!$stmt->fetch()) { + http_response_code(404); + echo json_encode(['error' => 'Employee not found']); + exit; + } + + $stmt = $pdo->prepare("DELETE FROM employees WHERE id = ?"); + $stmt->execute([$id]); + + echo json_encode(['success' => 'Employee deleted successfully']); + +} catch (PDOException $e) { + http_response_code(500); + echo json_encode(['error' => 'Database error: ' . $e->getMessage()]); +} diff --git a/employees/read.php b/employees/read.php new file mode 100644 index 0000000..5d653d7 --- /dev/null +++ b/employees/read.php @@ -0,0 +1,31 @@ +prepare("SELECT e.*, r.name as role_name FROM employees e LEFT JOIN roles r ON e.role_id = r.id WHERE e.id = ?"); + $stmt->execute([$id]); + $employee = $stmt->fetch(PDO::FETCH_ASSOC); + + if ($employee) { + echo json_encode($employee); + } else { + http_response_code(404); + echo json_encode(['error' => 'Employee not found']); + } + } else { + $stmt = $pdo->query("SELECT e.*, r.name as role_name FROM employees e LEFT JOIN roles r ON e.role_id = r.id"); + $employees = $stmt->fetchAll(PDO::FETCH_ASSOC); + echo json_encode($employees); + } + +} catch (PDOException $e) { + http_response_code(500); + echo json_encode(['error' => 'Database error: ' . $e->getMessage()]); +} diff --git a/employees/update.php b/employees/update.php new file mode 100644 index 0000000..888723c --- /dev/null +++ b/employees/update.php @@ -0,0 +1,68 @@ + 'Method Not Allowed']); + exit; +} + +$id = $_GET['id'] ?? null; + +if (!$id) { + http_response_code(400); + echo json_encode(['error' => 'Employee ID is required']); + exit; +} + +$data = json_decode(file_get_contents('php://input'), true); + +$first_name = $data['first_name'] ?? null; +$last_name = $data['last_name'] ?? null; +$email = $data['email'] ?? null; +$phone = $data['phone'] ?? null; +$role_id = $data['role_id'] ?? null; +$hire_date = $data['hire_date'] ?? null; + +if (!$first_name || !$last_name || !$email || !$role_id) { + http_response_code(400); + echo json_encode(['error' => 'Missing required fields: first_name, last_name, email, role_id']); + exit; +} + +if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { + http_response_code(400); + echo json_encode(['error' => 'Invalid email format']); + exit; +} + +try { + $pdo = db(); + + $stmt = $pdo->prepare("SELECT id FROM employees WHERE id = ?"); + $stmt->execute([$id]); + if (!$stmt->fetch()) { + http_response_code(404); + echo json_encode(['error' => 'Employee not found']); + exit; + } + + $stmt = $pdo->prepare("SELECT id FROM employees WHERE email = ? AND id != ?"); + $stmt->execute([$email, $id]); + if ($stmt->fetch()) { + http_response_code(409); + echo json_encode(['error' => 'Another employee with this email already exists']); + exit; + } + + $stmt = $pdo->prepare("UPDATE employees SET first_name = ?, last_name = ?, email = ?, phone = ?, role_id = ?, hire_date = ? WHERE id = ?"); + $stmt->execute([$first_name, $last_name, $email, $phone, $role_id, $hire_date, $id]); + + echo json_encode(['success' => 'Employee updated successfully']); + +} catch (PDOException $e) { + http_response_code(500); + echo json_encode(['error' => 'Database error: ' . $e->getMessage()]); +} diff --git a/index.php b/index.php index 4a0bf53..644d040 100644 --- a/index.php +++ b/index.php @@ -1,103 +1,225 @@ - - + - - - New Style - - - - + + + CheersPOS System + -
-
-

Welcome!

-

This is your new landing page.

-

Runtime: PHP — UTC

+ +

CheersPOS System

+ + + +
+

Welcome to the AI Retail Management Solution. Select an option above to get started.

-
- + + + - + \ No newline at end of file diff --git a/inventory/update.php b/inventory/update.php new file mode 100644 index 0000000..d160bf0 --- /dev/null +++ b/inventory/update.php @@ -0,0 +1,48 @@ + 'Method Not Allowed']); + exit; +} + +$data = json_decode(file_get_contents('php://input'), true); + +$product_id = $data['product_id'] ?? null; +$quantity = $data['quantity'] ?? null; + +if (!$product_id || !isset($quantity)) { + http_response_code(400); + echo json_encode(['error' => 'Missing required fields: product_id, quantity']); + exit; +} + +if (!is_numeric($quantity) || $quantity < 0) { + http_response_code(400); + echo json_encode(['error' => 'Invalid quantity']); + exit; +} + +try { + $pdo = db(); + + $stmt = $pdo->prepare("SELECT id FROM products WHERE id = ?"); + $stmt->execute([$product_id]); + if (!$stmt->fetch()) { + http_response_code(404); + echo json_encode(['error' => 'Product not found']); + exit; + } + + $stmt = $pdo->prepare("UPDATE products SET quantity = ? WHERE id = ?"); + $stmt->execute([$quantity, $product_id]); + + echo json_encode(['success' => 'Inventory updated successfully']); + +} catch (PDOException $e) { + http_response_code(500); + echo json_encode(['error' => 'Database error: ' . $e->getMessage()]); +} diff --git a/products/create.php b/products/create.php new file mode 100644 index 0000000..cc0541e --- /dev/null +++ b/products/create.php @@ -0,0 +1,36 @@ + 'Method Not Allowed']); + exit; +} + +$data = json_decode(file_get_contents('php://input'), true); + +if (empty($data['name']) || !isset($data['price']) || !isset($data['cost']) || !isset($data['quantity'])) { + http_response_code(400); + echo json_encode(['error' => 'Missing required fields: name, price, cost, and quantity']); + exit; +} + +$name = $data['name']; +$description = $data['description'] ?? null; +$price = $data['price']; +$cost = $data['cost']; +$quantity = $data['quantity']; + +try { + $pdo = db(); + $stmt = $pdo->prepare("INSERT INTO products (name, description, price, cost, quantity) VALUES (?, ?, ?, ?, ?)"); + $stmt->execute([$name, $description, $price, $cost, $quantity]); + + http_response_code(201); + echo json_encode(['message' => 'Product created successfully', 'id' => $pdo->lastInsertId()]); +} catch (PDOException $e) { + http_response_code(500); + echo json_encode(['error' => 'Database error: ' . $e->getMessage()]); +} diff --git a/products/delete.php b/products/delete.php new file mode 100644 index 0000000..6931ebd --- /dev/null +++ b/products/delete.php @@ -0,0 +1,34 @@ + 'Method Not Allowed']); + exit; +} + +$id = $_GET['id'] ?? null; + +if (!$id) { + http_response_code(400); + echo json_encode(['error' => 'Missing required parameter: id']); + exit; +} + +try { + $pdo = db(); + $stmt = $pdo->prepare("DELETE FROM products WHERE id = ?"); + $stmt->execute([$id]); + + if ($stmt->rowCount() > 0) { + echo json_encode(['message' => 'Product deleted successfully']); + } else { + http_response_code(404); + echo json_encode(['error' => 'Product not found']); + } +} catch (PDOException $e) { + http_response_code(500); + echo json_encode(['error' => 'Database error: ' . $e->getMessage()]); +} diff --git a/products/read.php b/products/read.php new file mode 100644 index 0000000..35fac97 --- /dev/null +++ b/products/read.php @@ -0,0 +1,28 @@ +prepare("SELECT * FROM products WHERE id = ?"); + $stmt->execute([$id]); + $product = $stmt->fetch(); + if ($product) { + echo json_encode($product); + } else { + http_response_code(404); + echo json_encode(['error' => 'Product not found']); + } + } else { + $stmt = $pdo->query("SELECT * FROM products"); + $products = $stmt->fetchAll(); + echo json_encode($products); + } +} catch (PDOException $e) { + http_response_code(500); + echo json_encode(['error' => 'Database error: ' . $e->getMessage()]); +} diff --git a/products/update.php b/products/update.php new file mode 100644 index 0000000..707d49b --- /dev/null +++ b/products/update.php @@ -0,0 +1,48 @@ + 'Method Not Allowed']); + exit; +} + +$data = json_decode(file_get_contents('php://input'), true); + +if (empty($data['id'])) { + http_response_code(400); + echo json_encode(['error' => 'Missing required field: id']); + exit; +} + +$id = $data['id']; + +// Fetch the existing product to see which fields are being updated +$pdo = db(); +$stmt = $pdo->prepare("SELECT * FROM products WHERE id = ?"); +$stmt->execute([$id]); +$product = $stmt->fetch(); + +if (!$product) { + http_response_code(404); + echo json_encode(['error' => 'Product not found']); + exit; +} + +$name = $data['name'] ?? $product['name']; +$description = $data['description'] ?? $product['description']; +$price = $data['price'] ?? $product['price']; +$cost = $data['cost'] ?? $product['cost']; +$quantity = $data['quantity'] ?? $product['quantity']; + +try { + $stmt = $pdo->prepare("UPDATE products SET name = ?, description = ?, price = ?, cost = ?, quantity = ? WHERE id = ?"); + $stmt->execute([$name, $description, $price, $cost, $quantity, $id]); + + echo json_encode(['message' => 'Product updated successfully']); +} catch (PDOException $e) { + http_response_code(500); + echo json_encode(['error' => 'Database error: ' . $e->getMessage()]); +} diff --git a/sales/create.php b/sales/create.php new file mode 100644 index 0000000..248230d --- /dev/null +++ b/sales/create.php @@ -0,0 +1,106 @@ + '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()]); +} \ No newline at end of file diff --git a/taxes/create.php b/taxes/create.php new file mode 100644 index 0000000..d35506d --- /dev/null +++ b/taxes/create.php @@ -0,0 +1,48 @@ + 'Method Not Allowed']); + exit; +} + +$data = json_decode(file_get_contents('php://input'), true); + +$name = $data['name'] ?? null; +$rate = $data['rate'] ?? null; + +if (!$name || !isset($rate)) { + http_response_code(400); + echo json_encode(['error' => 'Missing required fields: name, rate']); + exit; +} + +if (!is_numeric($rate) || $rate < 0 || $rate > 100) { + http_response_code(400); + echo json_encode(['error' => 'Invalid rate. Must be a number between 0 and 100.']); + exit; +} + +try { + $pdo = db(); + + $stmt = $pdo->prepare("INSERT INTO taxes (name, rate) VALUES (?, ?)"); + $stmt->execute([$name, $rate]); + + $id = $pdo->lastInsertId(); + + http_response_code(201); + echo json_encode(['success' => 'Tax created successfully', 'id' => $id]); + +} catch (PDOException $e) { + if ($e->errorInfo[1] == 1062) { // Duplicate entry + http_response_code(409); + echo json_encode(['error' => 'A tax with this name already exists.']); + } else { + http_response_code(500); + echo json_encode(['error' => 'Database error: ' . $e->getMessage()]); + } +} diff --git a/taxes/delete.php b/taxes/delete.php new file mode 100644 index 0000000..fb2ae9f --- /dev/null +++ b/taxes/delete.php @@ -0,0 +1,42 @@ + 'Tax ID is required']); + exit; +} + +try { + $pdo = db(); + + $stmt = $pdo->prepare("SELECT id FROM taxes WHERE id = ?"); + $stmt->execute([$id]); + if (!$stmt->fetch()) { + http_response_code(404); + echo json_encode(['error' => 'Tax not found']); + exit; + } + + // Check if the tax is being used in any sale + $stmt = $pdo->prepare("SELECT id FROM sale_taxes WHERE tax_id = ?"); + $stmt->execute([$id]); + if ($stmt->fetch()) { + http_response_code(400); + echo json_encode(['error' => 'Cannot delete tax because it is associated with existing sales.']); + exit; + } + + $stmt = $pdo->prepare("DELETE FROM taxes WHERE id = ?"); + $stmt->execute([$id]); + + echo json_encode(['success' => 'Tax deleted successfully']); + +} catch (PDOException $e) { + http_response_code(500); + echo json_encode(['error' => 'Database error: ' . $e->getMessage()]); +} diff --git a/taxes/read.php b/taxes/read.php new file mode 100644 index 0000000..01d066f --- /dev/null +++ b/taxes/read.php @@ -0,0 +1,31 @@ +prepare("SELECT * FROM taxes WHERE id = ?"); + $stmt->execute([$id]); + $tax = $stmt->fetch(PDO::FETCH_ASSOC); + + if ($tax) { + echo json_encode($tax); + } else { + http_response_code(404); + echo json_encode(['error' => 'Tax not found']); + } + } else { + $stmt = $pdo->query("SELECT * FROM taxes ORDER BY name"); + $taxes = $stmt->fetchAll(PDO::FETCH_ASSOC); + echo json_encode($taxes); + } + +} catch (PDOException $e) { + http_response_code(500); + echo json_encode(['error' => 'Database error: ' . $e->getMessage()]); +} diff --git a/taxes/update.php b/taxes/update.php new file mode 100644 index 0000000..86b376a --- /dev/null +++ b/taxes/update.php @@ -0,0 +1,61 @@ + 'Method Not Allowed']); + exit; +} + +$id = $_GET['id'] ?? null; + +if (!$id) { + http_response_code(400); + echo json_encode(['error' => 'Tax ID is required']); + exit; +} + +$data = json_decode(file_get_contents('php://input'), true); + +$name = $data['name'] ?? null; +$rate = $data['rate'] ?? null; + +if (!$name || !isset($rate)) { + http_response_code(400); + echo json_encode(['error' => 'Missing required fields: name, rate']); + exit; +} + +if (!is_numeric($rate) || $rate < 0 || $rate > 100) { + http_response_code(400); + echo json_encode(['error' => 'Invalid rate. Must be a number between 0 and 100.']); + exit; +} + +try { + $pdo = db(); + + $stmt = $pdo->prepare("SELECT id FROM taxes WHERE id = ?"); + $stmt->execute([$id]); + if (!$stmt->fetch()) { + http_response_code(404); + echo json_encode(['error' => 'Tax not found']); + exit; + } + + $stmt = $pdo->prepare("UPDATE taxes SET name = ?, rate = ? WHERE id = ?"); + $stmt->execute([$name, $rate, $id]); + + echo json_encode(['success' => 'Tax updated successfully']); + +} catch (PDOException $e) { + if ($e->errorInfo[1] == 1062) { // Duplicate entry + http_response_code(409); + echo json_encode(['error' => 'A tax with this name already exists.']); + } else { + http_response_code(500); + echo json_encode(['error' => 'Database error: ' . $e->getMessage()]); + } +}