findAll('name ASC'); Response::success('Categories retrieved', $categories); } public function createCategory() { // Check permissions $this->requireAuth(['admin', 'manager']); // Get and validate request data $data = $this->getRequestData(); $this->validateRequiredFields($data, ['name']); // Sanitize input $data = $this->sanitizeInput($data); // Create category $categoryModel = new Category(); try { $categoryId = $categoryModel->insert([ 'name' => $data['name'], 'description' => $data['description'] ?? '', 'status' => 'active' ]); // Log activity Logger::logActivity($this->user['user_id'], 'create_category', "Created category: {$data['name']}"); Response::success('Category created', [ 'id' => $categoryId, 'name' => $data['name'] ]); } catch (Exception $e) { Response::error('Failed to create category: '.$e->getMessage()); } } /** * @param $id */ public function getCategory($id) { if (!$id) { Response::error('Category ID is required', 400); } $categoryModel = new Category(); $category = $categoryModel->findById($id); if (!$category) { Response::error('Category not found', 404); } Response::success('Category retrieved', $category); } /** * @param $id */ public function updateCategory($id) { // Check permissions $this->requireAuth(['admin', 'manager']); if (!$id) { Response::error('Category ID is required', 400); } // Get and validate request data $data = $this->getRequestData(); $this->validateRequiredFields($data, ['name']); // Sanitize input $data = $this->sanitizeInput($data); // Update category $categoryModel = new Category(); // Check if category exists $category = $categoryModel->findById($id); if (!$category) { Response::error('Category not found', 404); } try { $categoryModel->update($id, [ 'name' => $data['name'], 'description' => $data['description'] ?? $category['description'], 'status' => $data['status'] ?? $category['status'] ]); // Log activity Logger::logActivity($this->user['user_id'], 'update_category', "Updated category ID: {$id}"); Response::success('Category updated'); } catch (Exception $e) { Response::error('Failed to update category: '.$e->getMessage()); } } /** * @param $id */ public function deleteCategory($id) { // Check permissions $this->requireAuth(['admin']); if (!$id) { Response::error('Category ID is required', 400); } // Check if category has products $productModel = new Product(); $count = $productModel->countByCategoryId($id); if ($count > 0) { Response::error('Cannot delete category with associated products', 400); } // Delete category $categoryModel = new Category(); try { $categoryModel->delete($id); // Log activity Logger::logActivity($this->user['user_id'], 'delete_category', "Deleted category ID: {$id}"); Response::success('Category deleted'); } catch (Exception $e) { Response::error('Failed to delete category: '.$e->getMessage()); } } // Product methods public function getProducts() { $categoryId = isset($_GET['category']) ? intval($_GET['category']) : null; $productModel = new Product(); $products = $productModel->getAll($categoryId); Response::success('Products retrieved', $products); } public function createProduct() { // Check permissions $this->requireAuth(['admin', 'manager']); // Get and validate request data $data = $this->getRequestData(); $this->validateRequiredFields($data, ['name', 'sku', 'price', 'cost']); // Sanitize input $data = $this->sanitizeInput($data); // Create product $productModel = new Product(); try { $productId = $productModel->create($data); // Log activity Logger::logActivity( $this->user['user_id'], 'create_product', "Created product: {$data['name']} (SKU: {$data['sku']})" ); Response::success('Product created', ['id' => $productId]); } catch (Exception $e) { Response::error('Failed to create product: '.$e->getMessage()); } } /** * @param $id */ public function getProduct($id) { if (!$id) { Response::error('Product ID is required', 400); } $productModel = new Product(); $product = $productModel->getById($id); if (!$product) { Response::error('Product not found', 404); } Response::success('Product retrieved', $product); } /** * @param $id */ public function updateProduct($id) { // Check permissions $this->requireAuth(['admin', 'manager']); if (!$id) { Response::error('Product ID is required', 400); } // Get and validate request data $data = $this->getRequestData(); // Sanitize input $data = $this->sanitizeInput($data); // Update product $productModel = new Product(); try { $productModel->update($id, $data); // Log activity Logger::logActivity( $this->user['user_id'], 'update_product', "Updated product ID: {$id}" ); Response::success('Product updated'); } catch (Exception $e) { Response::error('Failed to update product: '.$e->getMessage()); } } /** * @param $id */ public function deleteProduct($id) { // Check permissions $this->requireAuth(['admin']); if (!$id) { Response::error('Product ID is required', 400); } // Delete product $productModel = new Product(); try { $result = $productModel->delete($id); // Log activity $action = $result === 'deleted' ? 'delete_product' : 'deactivate_product'; $message = $result === 'deleted' ? "Deleted product ID: {$id}" : "Deactivated product ID: {$id}"; Logger::logActivity($this->user['user_id'], $action, $message); if ($result === 'deleted') { Response::success('Product deleted'); } else { Response::success('Product deactivated due to existing transactions'); } } catch (Exception $e) { Response::error('Failed to delete product: '.$e->getMessage()); } } public function getLowStock() { $productModel = new Product(); $products = $productModel->getLowStock(); Response::success('Low stock products retrieved', $products); } public function getTransactions() { $productId = isset($_GET['product_id']) ? intval($_GET['product_id']) : null; $type = isset($_GET['type']) ? $this->sanitizeInput($_GET['type']) : null; $inventory = new Inventory(); $transactions = $inventory->getTransactions($productId, $type); Response::success('Inventory transactions retrieved', $transactions); } public function createTransaction() { // Check permissions $this->requireAuth(['admin', 'manager']); // Get and validate request data $data = $this->getRequestData(); $this->validateRequiredFields($data, ['product_id', 'type', 'quantity']); // Sanitize input $data = $this->sanitizeInput($data); // Create transaction $productModel = new Product(); $inventory = new Inventory(); try { $this->db->beginTransaction(); // Get product $product = $productModel->getById($data['product_id']); if (!$product) { throw new Exception('Product not found'); } // Process different transaction types $newQuantity = $product['quantity']; $type = $data['type']; $quantity = intval($data['quantity']); switch ($type) { case 'purchase': $newQuantity += $quantity; break; case 'sale': if ($product['quantity'] < $quantity) { throw new Exception('Insufficient stock'); } $newQuantity -= $quantity; break; case 'adjustment': $newQuantity = $quantity; break; case 'return': $newQuantity += $quantity; break; default: throw new Exception('Invalid transaction type'); } // Update product quantity $productModel->updateStock( $data['product_id'], $newQuantity, $data['notes'] ?? '', $this->user['user_id'] ); // Record transaction $transactionId = $inventory->recordTransaction( $data['product_id'], $type, $quantity, $data['reference_id'] ?? null, $data['notes'] ?? '', $this->user['user_id'] ); $this->db->commit(); // Log activity Logger::logActivity( $this->user['user_id'], 'inventory_transaction', "Created {$type} transaction for product ID: {$data['product_id']}" ); Response::success('Inventory transaction created', ['id' => $transactionId]); } catch (Exception $e) { $this->db->rollBack(); Response::error('Failed to create transaction: '.$e->getMessage()); } } }