diff --git a/add_customer.php b/add_customer.php new file mode 100644 index 0000000..3cb368a --- /dev/null +++ b/add_customer.php @@ -0,0 +1,140 @@ +prepare($sql); + $stmt->execute([ + $_POST['name'], + $_POST['email'], + $_POST['phone'], + $_POST['address'] + ]); + $message = '
Customer added successfully!
'; + } catch (PDOException $e) { + $message = '
Error adding customer: ' . $e->getMessage() . '
'; + } +} + +?> + + + + + + Add Customer + + + + + + + + +
+
+

Add New Customer

+ Back to Customers +
+ + + +
+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
+
+
+ + +
+ + + + diff --git a/add_item.php b/add_item.php new file mode 100644 index 0000000..d79166e --- /dev/null +++ b/add_item.php @@ -0,0 +1,184 @@ +prepare($sql); + $stmt->execute([ + $_POST['name'], + $_POST['sku'], + $_POST['barcode'], + $_POST['brand'], + $_POST['category'], + $_POST['unit'], + $_POST['purchase_price'], + $_POST['sale_price'], + $_POST['tax_percentage'], + $_POST['stock_quantity'], + $_POST['alert_quantity'] + ]); + $message = '
Product added successfully!
'; + } catch (PDOException $e) { + $message = '
Error adding product: ' . $e->getMessage() . '
'; + } +} + +?> + + + + + + Add Item + + + + + + + + +
+
+

Add New Product

+
+ + + +
+
+
+
+
+ + +
+
+ + +
+
+
+
+ + +
+
+ + +
+
+
+
+ + +
+
+ + +
+
+
+
+ + +
+
+ + +
+
+
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+
+ + +
+ + + + diff --git a/customers.php b/customers.php new file mode 100644 index 0000000..bd2ef13 --- /dev/null +++ b/customers.php @@ -0,0 +1,136 @@ +query("SELECT * FROM customers ORDER BY name ASC"); +$customers = $stmt->fetchAll(); + +?> + + + + + + Customers + + + + + + + + + +
+
+

Customers

+ Add New Customer +
+ +
+
+ + + + + + + + + + + + + + + + + + + +
NameEmailPhoneActions
+ + +
+
+
+ + +
+ + + + + + + + diff --git a/db/migrate.php b/db/migrate.php new file mode 100644 index 0000000..f55e344 --- /dev/null +++ b/db/migrate.php @@ -0,0 +1,36 @@ +exec($sql); + echo "Success.\n"; + } catch (PDOException $e) { + echo "Error running migration " . basename($file) . ": " . $e->getMessage() . "\n"; + // Stop on error + return; + } + } +} + +run_migrations(); + diff --git a/db/migrations/001_initial_schema.sql b/db/migrations/001_initial_schema.sql new file mode 100644 index 0000000..2a74b62 --- /dev/null +++ b/db/migrations/001_initial_schema.sql @@ -0,0 +1,93 @@ +CREATE TABLE IF NOT EXISTS `products` ( + `id` INT AUTO_INCREMENT PRIMARY KEY, + `name` VARCHAR(255) NOT NULL, + `sku` VARCHAR(100), + `barcode` VARCHAR(100), + `brand` VARCHAR(100), + `category` VARCHAR(100), + `unit` VARCHAR(50), + `purchase_price` DECIMAL(10, 2) NOT NULL, + `sale_price` DECIMAL(10, 2) NOT NULL, + `tax_percentage` DECIMAL(5, 2) DEFAULT 0.00, + `stock_quantity` INT NOT NULL DEFAULT 0, + `alert_quantity` INT 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, + `name` VARCHAR(255) NOT NULL, + `email` VARCHAR(255), + `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, + `total_amount` DECIMAL(10, 2) NOT NULL, + `discount` DECIMAL(10, 2) DEFAULT 0.00, + `tax_amount` DECIMAL(10, 2) DEFAULT 0.00, + `payable_amount` DECIMAL(10, 2) NOT NULL, + `payment_method` VARCHAR(50) DEFAULT 'cash', + `sale_date` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (`customer_id`) REFERENCES `customers`(`id`) ON DELETE SET NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +CREATE TABLE IF NOT EXISTS `sale_items` ( + `id` INT AUTO_INCREMENT PRIMARY KEY, + `sale_id` INT NOT NULL, + `product_id` INT NOT NULL, + `quantity` INT NOT NULL, + `price_per_unit` DECIMAL(10, 2) NOT NULL, + `total_price` DECIMAL(10, 2) NOT NULL, + FOREIGN KEY (`sale_id`) REFERENCES `sales`(`id`) ON DELETE CASCADE, + FOREIGN KEY (`product_id`) REFERENCES `products`(`id`) ON DELETE RESTRICT +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +CREATE TABLE IF NOT EXISTS `expenses` ( + `id` INT AUTO_INCREMENT PRIMARY KEY, + `description` TEXT NOT NULL, + `amount` DECIMAL(10, 2) NOT NULL, + `expense_date` DATE, + `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +CREATE TABLE IF NOT EXISTS `users` ( + `id` INT AUTO_INCREMENT PRIMARY KEY, + `name` VARCHAR(255) NOT NULL, + `email` VARCHAR(255) NOT NULL UNIQUE, + `password` VARCHAR(255) NOT NULL, + `role` ENUM('admin', 'cashier', 'manager') DEFAULT 'cashier', + `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +CREATE TABLE IF NOT EXISTS `suppliers` ( + `id` INT AUTO_INCREMENT PRIMARY KEY, + `name` VARCHAR(255) NOT NULL, + `contact_person` VARCHAR(255), + `phone` VARCHAR(50), + `email` VARCHAR(255), + `address` TEXT, + `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +CREATE TABLE IF NOT EXISTS `purchases` ( + `id` INT AUTO_INCREMENT PRIMARY KEY, + `supplier_id` INT, + `total_amount` DECIMAL(10, 2) NOT NULL, + `purchase_date` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (`supplier_id`) REFERENCES `suppliers`(`id`) ON DELETE SET NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +CREATE TABLE IF NOT EXISTS `purchase_items` ( + `id` INT AUTO_INCREMENT PRIMARY KEY, + `purchase_id` INT NOT NULL, + `product_id` INT NOT NULL, + `quantity` INT NOT NULL, + `price_per_unit` DECIMAL(10, 2) NOT NULL, + `total_price` DECIMAL(10, 2) NOT NULL, + FOREIGN KEY (`purchase_id`) REFERENCES `purchases`(`id`) ON DELETE CASCADE, + FOREIGN KEY (`product_id`) REFERENCES `products`(`id`) ON DELETE RESTRICT +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; \ No newline at end of file diff --git a/includes/dashboard_data.php b/includes/dashboard_data.php new file mode 100644 index 0000000..48d9a5c --- /dev/null +++ b/includes/dashboard_data.php @@ -0,0 +1,24 @@ +query("SELECT SUM(payable_amount) as total_sales FROM sales"); + $data['total_sales'] = $stmt->fetchColumn() ?: 0; + + // Total Purchases + $stmt = $pdo->query("SELECT SUM(total_amount) as total_purchases FROM purchases"); + $data['total_purchases'] = $stmt->fetchColumn() ?: 0; + + // Total Expenses + $stmt = $pdo->query("SELECT SUM(amount) as total_expenses FROM expenses"); + $data['total_expenses'] = $stmt->fetchColumn() ?: 0; + + // Net Profit + $data['net_profit'] = $data['total_sales'] - ($data['total_purchases'] + $data['total_expenses']); + + return $data; +} diff --git a/index.php b/index.php index 7205f3d..99dab69 100644 --- a/index.php +++ b/index.php @@ -4,147 +4,135 @@ declare(strict_types=1); @error_reporting(E_ALL); @date_default_timezone_set('UTC'); -$phpVersion = PHP_VERSION; -$now = date('Y-m-d H:i:s'); +require_once 'includes/dashboard_data.php'; + +$dashboard_data = get_dashboard_data(); + ?> - - - New Style - - - - - - - - - - - - - - - - - - - + + + Admin Dashboard + + + -
-
-

Analyzing your requirements and generating your website…

-
- Loading… -
-

AI is collecting your requirements and applying the first changes.

-

This page will update automatically as the plan is implemented.

-

Runtime: PHP — UTC

+ + + +
+
+

Dashboard

+
+ Refresh +
+
+ +
+
+
+
+
Total Sales
+

+
+
+
+
+
+
+
Total Purchases
+

+
+
+
+
+
+
+
Total Expenses
+

+
+
+
+
+
+
+
Net Profit
+

+
+
+
-
- + + + + + - + \ No newline at end of file diff --git a/pos.php b/pos.php new file mode 100644 index 0000000..f25f539 --- /dev/null +++ b/pos.php @@ -0,0 +1,271 @@ +query("SELECT * FROM products WHERE stock_quantity > 0 ORDER BY name ASC"); +$products = $stmt_products->fetchAll(); + +$stmt_customers = $pdo->query("SELECT * FROM customers ORDER BY name ASC"); +$customers = $stmt_customers->fetchAll(); + +?> + + + + + + POS Terminal + + + + + + + + +
+
+
+
+
+ +
+ +
+
+
+

+
+
+ +
+
+
+
+
+
+
+
+ + +
+
Cart
+ + + + + + + + + + + + +
ItemQtyPriceTotal
+
+
+
Total:
+
0.00
+
+
+ +
+
+
+
+
+
+ + + + + diff --git a/process_sale.php b/process_sale.php new file mode 100644 index 0000000..3864eb2 --- /dev/null +++ b/process_sale.php @@ -0,0 +1,65 @@ + false, 'message' => 'Cart is empty.']; + echo json_encode($response); + exit; + } + + $pdo = db(); + $pdo->beginTransaction(); + + try { + // 1. Calculate total amount + $total_amount = 0; + foreach ($cart_data as $item) { + $total_amount += $item['sale_price'] * $item['quantity']; + } + + // 2. Insert into sales table + $sql = "INSERT INTO sales (customer_id, total_amount, payable_amount) VALUES (?, ?, ?)"; + $stmt = $pdo->prepare($sql); + $stmt->execute([$customer_id, $total_amount, $total_amount]); + $sale_id = $pdo->lastInsertId(); + + // 3. Insert into sale_items and update stock + $sql_item = "INSERT INTO sale_items (sale_id, product_id, quantity, price_per_unit, total_price) VALUES (?, ?, ?, ?, ?)"; + $stmt_item = $pdo->prepare($sql_item); + + $sql_stock = "UPDATE products SET stock_quantity = stock_quantity - ? WHERE id = ?"; + $stmt_stock = $pdo->prepare($sql_stock); + + foreach ($cart_data as $item) { + $item_total = $item['sale_price'] * $item['quantity']; + $stmt_item->execute([$sale_id, $item['id'], $item['quantity'], $item['sale_price'], $item_total]); + $stmt_stock->execute([$item['quantity'], $item['id']]); + } + + $pdo->commit(); + $response = ['success' => true, 'message' => 'Sale processed successfully!', 'sale_id' => $sale_id]; + + } catch (PDOException $e) { + $pdo->rollBack(); + $response = ['success' => false, 'message' => 'Error processing sale: ' . $e->getMessage()]; + } + +} else { + $response = ['success' => false, 'message' => 'Invalid request method.']; +} + +echo json_encode($response); diff --git a/sale_details.php b/sale_details.php new file mode 100644 index 0000000..4d2bc23 --- /dev/null +++ b/sale_details.php @@ -0,0 +1,155 @@ +prepare("SELECT sales.*, customers.name as customer_name FROM sales LEFT JOIN customers ON sales.customer_id = customers.id WHERE sales.id = ?"); +$stmt->execute([$sale_id]); +$sale = $stmt->fetch(); + +if (!$sale) { + header('Location: sales.php'); + exit; +} + +// Get sale items +$stmt_items = $pdo->prepare("SELECT sale_items.*, products.name as product_name FROM sale_items JOIN products ON sale_items.product_id = products.id WHERE sale_items.sale_id = ?"); +$stmt_items->execute([$sale_id]); +$sale_items = $stmt_items->fetchAll(); + +?> + + + + + + Sale Details + + + + + + + + +
+
+

Sale Details #

+ Back to Sales +
+ +
+
+
+
+

Customer:

+

Date:

+
+
+

Total:

+
+
+
+
Items Purchased
+ + + + + + + + + + + + + + + + + + + +
ProductQuantityPrice per UnitTotal
+
+
+ + +
+ + + + diff --git a/sales.php b/sales.php new file mode 100644 index 0000000..eaf65cb --- /dev/null +++ b/sales.php @@ -0,0 +1,136 @@ +query("SELECT sales.*, customers.name as customer_name FROM sales LEFT JOIN customers ON sales.customer_id = customers.id ORDER BY sale_date DESC"); +$sales = $stmt->fetchAll(); + +?> + + + + + + Sales + + + + + + + + + +
+
+

Sales History

+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + +
Sale IDCustomerTotal AmountDateActions
+ +
+
+
+ + +
+ + + + + + + + diff --git a/view_items.php b/view_items.php new file mode 100644 index 0000000..bac5877 --- /dev/null +++ b/view_items.php @@ -0,0 +1,142 @@ +query("SELECT * FROM products ORDER BY created_at DESC"); +$products = $stmt->fetchAll(); + +?> + + + + + + View Items + + + + + + + + + +
+
+

Inventory Items

+ Add New Item +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameSKUStockPriceCategoryBrandActions
+ + +
+
+
+ + +
+ + + + + + + +