JIT
Creating SQL code for inventory history table setup
Give me a SQL code to add this in my inventory_history table: id (INT, Primary Key) timestamp (DATETIME) username (VARCHAR) action_type (ENUM: add, update, delete, sell) item_type (ENUM: product, category) item_name (VARCHAR) description (TEXT)

Here's the SQL code to create your inventory_history table with the specified structure:

_

Updated files
v1
In my pasted Inventory History code: <?php global $wpdb; // Initialize variables, Table Names, Fetch Inventory Data $message = ''; $message_type = ''; $inventory_history_data = []; $fetch_error = ''; $inventory_history_table_name = 'inventory_history'; // Check if the inventory history table exists $history_table_exists = $wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $inventory_history_table_name)) == $inventory_history_table_name; if ($history_table_exists) { // Select all inventory history entries along with the user's first name $sql = " SELECT ih.*, u.first_name AS user_first_name FROM $inventory_history_table_name ih LEFT JOIN users u ON ih.username = u.username -- Ensure the user table matches correctly ORDER BY timestamp DESC "; $inventory_history_results = $wpdb->get_results($sql, ARRAY_A); if ($inventory_history_results === null) { $fetch_error = "Error fetching inventory history data: " . $wpdb->last_error; } else { $inventory_history_data = $inventory_history_results; } } else { $fetch_error = "Error: Inventory history table '{$inventory_history_table_name}' not found."; } // Handle delete request for inventory history if (isset($_GET['delete_movement']) && isset($_GET['movement_id'])) { $movement_id = intval($_GET['movement_id']); $delete_sql = $wpdb->prepare("DELETE FROM $inventory_history_table_name WHERE id = %d", $movement_id); if ($wpdb->query($delete_sql) === false) { $message = "Failed to delete movement."; $message_type = 'error'; } else { $message = "Movement deleted successfully."; $message_type = 'success'; header("Location: " . $_SERVER['PHP_SELF']); exit; // Redirect to prevent re-submission } } ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Inventory History</title> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css"> <style> /* === CSS === */ body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; margin: 0; padding: 0; background-color: #f4f7f9; color: #333; font-size: 16px; } .dashboard-container { display: flex; } .sidebar { width: 240px; background-color: #D1B48C; color: #000000; height: 100vh; position: fixed; left: 0; top: 0; overflow-y: auto; box-shadow: 2px 0 5px rgba(0, 0, 0, 0.1); z-index: 1000; } .sidebar-menu { padding: 20px 0; } .sidebar-menu ul { list-style: none; padding: 0; margin: 0; } .sidebar-menu li a { display: flex; align-items: center; padding: 12px 20px; text-decoration: none; color: #000000; transition: background-color 0.3s ease, color: 0.3s ease; } .main-content { margin-left: 240px; padding: 25px; flex-grow: 1; box-sizing: border-box; } .header { background-color: #fff; padding: 18px 30px; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); margin-bottom: 25px; border-bottom: 1px solid #eee; } .inventory-container { background-color: #fff; padding: 25px; border-radius: 8px; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); border: 1px solid #eee; overflow-x: auto; } #inventory-history-table { width: 100%; border-collapse: collapse; margin-top: 10px; } #inventory-history-table th, #inventory-history-table td { padding: 10px 12px; text-align: left; border-bottom: 1px solid #eee; font-size: 0.95em; } #inventory-history-table th { background-color: #f9f9f9; font-weight: 600; } #inventory-history-table tbody tr:hover { background-color: #f5f5f5; } .delete-button { color: red; cursor: pointer; } </style> </head> <body> <div class="dashboard-container"> <aside class="sidebar"> <div class="sidebar-menu"> <ul> <li><a href="http://localhost/inventory/index.php/admin-page/">Dashboard</a></li> <?php session_start(); $current_username = isset($_SESSION['username']) ? $_SESSION['username'] : ''; if ($current_username === 'admin') : ?> <li><a href="http://localhost/inventory/index.php/usersmanagement/">User Management</a></li> <li><a href="http://localhost/inventory/index.php/category-page/">Categories</a></li> <li><a href="http://localhost/inventory/index.php/products/">Products</a></li> <li><a href="http://localhost/inventory/index.php/order/">Orders</a></li> <li><a href="http://localhost/inventory/index.php/view-order/">View Orders</a></li> <li><a href="http://localhost/inventory/index.php/sales/">Sales & Report</a></li> <li><a href="http://localhost/inventory/index.php/report/">Inventory Report</a></li> <li><a href="http://localhost/inventory/index.php/history/">Inventory History</a></li> <?php else : ?> <li><a href="http://localhost/inventory/index.php/category-page/">Categories</a></li> <li><a href="http://localhost/inventory/index.php/products/">Products</a></li> <li><a href="http://localhost/inventory/index.php/order/">Orders</a></li> <?php endif; ?> <li><a href="http://localhost/inventory/index.php/sign-in2/" onclick="return confirm('Are you sure you want to log out?');">Logout</a></li> </ul> </div> </aside> <main class="main-content"> <header class="header"> <h1>Inventory History</h1> </header> <?php if (!empty($fetch_error)): ?> <div class="notice notice-error"> <p><?php echo esc_html($fetch_error); ?></p> </div> <?php endif; ?> <div class="inventory-container"> <table id="inventory-history-table"> <thead> <tr> <th>Date & Time</th> <th>User</th> <th>Action Type</th> <th>Item Type</th> <th>Item Name</th> <th>Description</th> <th>Action</th> </tr> </thead> <tbody> <?php if (empty($inventory_history_data) && empty($fetch_error)): ?> <tr> <td colspan="7" style="text-align: center; color: #666; padding: 20px;"> No inventory history found. </td> </tr> <?php else: ?> <?php foreach ($inventory_history_data as $history_item): ?> <tr> <td><?php echo esc_html(mysql2date('Y-m-d H:i', $history_item['timestamp'])); ?></td> <td><?php echo esc_html($history_item['user_first_name']); ?></td> <!-- Display User's First Name --> <td><?php echo esc_html($history_item['action_type']); ?></td> <td><?php echo esc_html($history_item['item_type']); ?></td> <td><?php echo esc_html($history_item['item_name']); ?></td> <td><?php echo esc_html($history_item['description']); ?></td> <td> <a href="?delete_movement=true&movement_id=<?php echo esc_attr($history_item['id']); ?>" class="delete-button" onclick="return confirm('Are you sure you want to delete this movement?');">x</a> </td> </tr> <?php endforeach; ?> <?php endif; ?> </tbody> </table> </div> </main> </div> </body> </html> Insert this: // Function to log actions in the inventory history for products and categories function log_inventory_action($action_type, $item_type, $item_name, $description) { global $wpdb; $history_table_name = 'inventory_history'; $username = wp_get_current_user()->user_login; // Get the current user's username $result = $wpdb->insert( $history_table_name, array( 'username' => $username, 'action_type' => $action_type, 'item_type' => $item_type, 'item_name' => $item_name, 'description' => $description, 'timestamp' => current_time('mysql') // Store the timestamp of the action ), array('%s', '%s', '%s', '%s', '%s', '%s') // Format for the insert query ); }

Here's the modified version of your code with the log_inventory_action function added:

Updated files
v2
How about this: // Select all inventory history entries along with the user's first name $sql = " SELECT ih.*, u.first_name AS user_first_name FROM $inventory_history_table_name ih LEFT JOIN users u ON ih.username = u.username ORDER BY timestamp DESC ";
The pasted code is the Product menu code, add a logging history code based on the Inventory History so the adding, editing/updating and deleting of product will be recorded or seen in the Inventory History. The Product menu code: <?php /** * Plugin Name: Product Menu Snippet * Description: Adds a Product menu with add, edit, and delete functionality, including server-side search with a clear button. */ global $wpdb; // --- Configuration --- $product_table_name = 'products'; // Adjust if you use prefixes: $wpdb->prefix . 'products'; $category_table_name = 'categories'; // Adjust if you use prefixes: $wpdb->prefix . 'categories'; // Ensure upload directory exists $upload_dir_info = wp_upload_dir(); $upload_dir = $upload_dir_info['basedir'] . '/product_images/'; $upload_url = $upload_dir_info['baseurl'] . '/product_images/'; // Base URL for displaying images if (!file_exists($upload_dir)) { wp_mkdir_p($upload_dir); // Use wp_mkdir_p for recursive creation } $editing_product = null; // Initialize editing product variable $message = ''; // For success/error messages $message_type = ''; // 'success' or 'error' // --- Handle Delete Product Action --- if (isset($_GET['action']) && $_GET['action'] === 'delete_product' && isset($_GET['id']) && isset($_GET['_wpnonce']) && wp_verify_nonce($_GET['_wpnonce'], 'delete_product_' . absint($_GET['id']))) { $product_id_to_delete = absint($_GET['id']); if ($product_id_to_delete) { // Optional: Delete image file first $image_url_to_delete = $wpdb->get_var($wpdb->prepare("SELECT image_url FROM $product_table_name WHERE id = %d", $product_id_to_delete)); if ($image_url_to_delete) { $image_path = str_replace($upload_url, $upload_dir, $image_url_to_delete); if (file_exists($image_path)) { @unlink($image_path); } } // Delete product record $deleted = $wpdb->delete( $product_table_name, array('id' => $product_id_to_delete), array('%d') ); if ($deleted) { $message = 'Product deleted successfully!'; $message_type = 'success'; // Redirect after delete to clear URL parameters wp_redirect(remove_query_arg(array('action', 'id', '_wpnonce'))); exit; } else { $message = 'Error deleting product.'; $message_type = 'error'; } } } // --- Handle Edit Product Action (Prepare form) --- if (isset($_GET['action']) && $_GET['action'] === 'edit_product' && isset($_GET['id'])) { $product_id_to_edit = absint($_GET['id']); if ($product_id_to_edit) { $editing_product = $wpdb->get_row( // Make sure to select the 'unit' column if it exists $wpdb->prepare("SELECT * FROM $product_table_name WHERE id = %d", $product_id_to_edit), ARRAY_A ); if (!$editing_product) { $message = 'Product not found for editing.'; $message_type = 'error'; } } } // --- Handle Add/Update Product Form Submission --- // Use a nonce for security if (isset($_POST['save_product']) && isset($_POST['_wpnonce_product_form']) && wp_verify_nonce($_POST['_wpnonce_product_form'], 'save_product_action')) { // Sanitize and validate input data $product_name = isset($_POST['product_name']) ? sanitize_text_field($_POST['product_name']) : ''; $product_category = isset($_POST['product_category']) ? sanitize_text_field($_POST['product_category']) : ''; $unit = isset($_POST['unit']) ? sanitize_text_field($_POST['unit']) : ''; // Changed from volume_unit $buying_price = isset($_POST['buying_price']) ? preg_replace('/[^0-9.]/', '', $_POST['buying_price']) : '0'; // Allow only numbers and dot $selling_price = isset($_POST['selling_price']) ? preg_replace('/[^0-9.]/', '', $_POST['selling_price']) : '0'; // Allow only numbers and dot $quantity_submitted = isset($_POST['quantity_input']) ? absint($_POST['quantity_input']) : 0; // Use new name 'quantity_input' $edit_product_id = isset($_POST['edit_product_id']) ? absint($_POST['edit_product_id']) : 0; $product_image_url = isset($_POST['old_image_url']) ? esc_url_raw($_POST['old_image_url']) : ''; // Keep old image if not new upload // --- Image Upload Handling --- if (isset($_FILES['product_image']) && $_FILES['product_image']['error'] === UPLOAD_ERR_OK) { $file = $_FILES['product_image']; // Use WordPress functions for handling uploads securely if (!function_exists('wp_handle_upload')) { require_once(ABSPATH . 'wp-admin/includes/file.php'); } $upload_overrides = array('test_form' => false); // Important for security // Specify target directory within uploads $movefile = wp_handle_upload($file, $upload_overrides, current_time('mysql')); if ($movefile && !isset($movefile['error'])) { // Success! $movefile contains 'url', 'file' (path), 'type' $product_image_url = $movefile['url']; // Optional: Delete old image if updating and upload is successful if ($edit_product_id && isset($_POST['old_image_url']) && $_POST['old_image_url'] !== $product_image_url) { $old_image_path = str_replace($upload_url, $upload_dir, esc_url_raw($_POST['old_image_url'])); if (file_exists($old_image_path)) { @unlink($old_image_path); } } } else { // $movefile['error'] contains the error message $message = 'Image upload error: ' . esc_html($movefile['error']); $message_type = 'error'; } } elseif (isset($_FILES['product_image']) && $_FILES['product_image']['error'] !== UPLOAD_ERR_NO_FILE) { // Handle other upload errors $message = 'Image upload error code: ' . $_FILES['product_image']['error']; $message_type = 'error'; } // --- End Image Upload Handling --- // Proceed only if no upload error occurred or no file was uploaded if ($message_type !== 'error') { // Added check for unit (optional, depends if it's required) if (!empty($product_name) && !empty($product_category) && is_numeric($buying_price) && is_numeric($selling_price)) { $product_data = array( 'image_url' => $product_image_url, 'name' => $product_name, 'category' => $product_category, 'unit' => $unit, // Changed from volume_unit 'buying_price' => (float)$buying_price, // Store as float 'selling_price' => (float)$selling_price, // Store as float // 'in_stock' will be handled below based on add/edit 'updated_at' => current_time('mysql') // Always update 'updated_at' ); // Base format array (excluding in_stock and created_at for now) $data_format = array('%s', '%s', '%s', '%s', '%f', '%f', '%s'); // image_url, name, category, unit, buying_price, selling_price, updated_at if ($edit_product_id) { // --- UPDATE existing product --- // Fetch current stock $current_stock = $wpdb->get_var( $wpdb->prepare("SELECT in_stock FROM $product_table_name WHERE id = %d", $edit_product_id) ); if ($current_stock === null) { $message = 'Error: Could not find product to update stock.'; $message_type = 'error'; } else { // Calculate new stock: Add submitted quantity to current stock $new_stock_value = absint($current_stock) + $quantity_submitted; $product_data['in_stock'] = $new_stock_value; $data_format[] = '%d'; // Add format for in_stock $updated = $wpdb->update( $product_table_name, $product_data, array('id' => $edit_product_id), // WHERE clause $data_format, // Format for values being updated array('%d') // Format for WHERE clause ); if ($updated !== false) { $message = 'Product updated successfully!'; $message_type = 'success'; // Clear editing state after successful update $editing_product = null; // Optional: Redirect to clear form and prevent resubmission // wp_redirect(remove_query_arg(array('action', 'id'))); exit; } else { $message = 'Error updating product. ' . $wpdb->last_error; $message_type = 'error'; } } } else { // --- INSERT new product --- $product_data['in_stock'] = $quantity_submitted; // Initial stock is the submitted quantity $product_data['created_at'] = current_time('mysql'); $data_format[] = '%d'; // Add format for in_stock $data_format[] = '%s'; // Add format for created_at $inserted = $wpdb->insert( $product_table_name, $product_data, $data_format ); if ($inserted) { $message = 'Product added successfully!'; $message_type = 'success'; // Optional: Redirect or clear form fields } else { $message = 'Error adding product. ' . $wpdb->last_error; $message_type = 'error'; } } } else { $message = 'Please fill in all required fields with valid data.'; $message_type = 'error'; } } // End check for upload error } elseif (isset($_POST['save_product'])) { // Nonce check failed $message = 'Security check failed. Please try again.'; $message_type = 'error'; } // --- Fetch Products and Categories for Display --- // Base SQL query $sql = "SELECT id, image_url, name, category, unit, in_stock, buying_price, selling_price, created_at, updated_at FROM $product_table_name"; $where = ''; // Get the search term from the URL query parameter $search_term = isset($_GET['product_search']) ? sanitize_text_field(wp_unslash($_GET['product_search'])) : ''; // Add search condition if search term is present if (!empty($search_term)) { // Prepare the search term for a LIKE query $search_like = '%' . $wpdb->esc_like($search_term) . '%'; $where = $wpdb->prepare( " WHERE name LIKE %s OR category LIKE %s OR unit LIKE %s", $search_like, $search_like, $search_like ); } $order_by = " ORDER BY name ASC"; // Combine the SQL parts $products_sql = $sql . $where . $order_by; // Execute the query $products = $wpdb->get_results($products_sql, ARRAY_A); $categories = $wpdb->get_results("SELECT name FROM $category_table_name ORDER BY name ASC", ARRAY_A); ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Product Management</title> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" crossorigin="anonymous" referrerpolicy="no-referrer" /> <style> body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; margin: 0; padding: 0; background-color: #f4f7f9; color: #333; } .dashboard-container { display: flex; } .sidebar { width: 240px; background-color: #D1B48C; color: #000000; height: 100vh; position: fixed; left: 0; top: 0; overflow-y: auto; box-shadow: 2px 0 5px rgba(0, 0, 0, 0.1); z-index: 1000; } .sidebar-menu { padding: 20px 0; } .sidebar-menu ul { list-style: none; padding: 0; margin: 0; } .sidebar-menu li a { display: flex; align-items: center; padding: 12px 20px; text-decoration: none; color: #000000; transition: background-color 0.3s ease, color 0.3s ease; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: 16px; } .sidebar-menu li a i { margin-right: 12px; width: 20px; text-align: center; flex-shrink: 0; } .sidebar-menu li a:hover { background-color: #ffffff; color: #000000; } .sidebar-menu li.active a { background-color: #ffffff; color: #000000; font-weight: bold; } .main-content { margin-left: 240px; padding: 20px; flex-grow: 1; } .header { background-color: #fff; padding: 15px 30px; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); margin-bottom: 20px; border-bottom: 1px solid #eee; } .header h1 { margin: 0; font-size: 22px; color: #2f4050; } .product-content { display: flex; flex-wrap: wrap; gap: 20px; } /* Allow wrapping */ .product-form-container { flex: 1 1 400px; /* Flex basis 400px, allow grow/shrink */ max-width: 500px; background-color: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); border: 1px solid #eee; } .product-form-container h2 { margin-top: 0; margin-bottom: 15px; color: #2f4050; border-bottom: 1px solid #eee; padding-bottom: 10px; font-size: 18px; } .product-form-container form { display: flex; flex-direction: column; } /* --- Reduced Spacing in Add Product Form --- */ .product-form-container label { margin-bottom: 3px; /* Reduced space below label */ font-weight: 600; display: block; font-size: 0.9em; } .product-form-container input[type="text"], .product-form-container input[type="number"], .product-form-container input[type="file"], .product-form-container select { padding: 8px 10px; margin-bottom: 6px; /* Reduced space below input/select */ border: 1px solid #ddd; border-radius: 4px; font-size: 1em; width: 100%; box-sizing: border-box; font-family: inherit; } /* --- End Reduced Spacing --- */ .product-form-container input[type="number"] { appearance: textfield; -moz-appearance: textfield; /* For Firefox */ } /* Basic styling for number input */ .product-form-container select { appearance: none; -webkit-appearance: none; -moz-appearance: none; background-image: url('data:image/svg+xml;utf8,<svg fill="%23444" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M7 10l5 5 5-5z"/><path d="M0 0h24v24H0z" fill="none"/></svg>'); background-repeat: no-repeat; background-position-x: calc(100% - 10px); background-position-y: center; padding-right: 35px; } .product-form-container button[type="submit"], .button-cancel { padding: 10px 15px; color: #000000; border: none; border-radius: 4px; cursor: pointer; font-size: 1em; transition: background-color 0.3s ease; text-decoration: none; display: inline-block; text-align: center; } .product-form-container button[type="submit"] { background-color: #D1B48C; /* WP Blue */ margin-right: 10px;} .product-form-container button[type="submit"]:hover { background-color: #be9b7b; } .button-cancel { background-color: #D1B48C; } /* Grey */ .button-cancel:hover { background-color: #be9b7b; } .form-buttons { margin-top: 15px; } /* Slightly increased top margin for buttons */ .product-list-container { flex: 2 1 600px; /* Flex basis 600px */ background-color: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); border: 1px solid #eee; overflow-x: auto; /* Add horizontal scroll if needed */ } .product-list-container h2 { margin-top: 0; margin-bottom: 10px; color: #2f4050; border-bottom: 1px solid #eee; padding-bottom: 10px; font-size: 18px; } /* --- Improved Styles for Search Bar --- */ .product-list-container form { display: flex; align-items: center; margin-bottom: 15px; gap: 8px; /* Add gap between wrapper and button */ } .search-wrapper { position: relative; display: flex; /* Use flex for better control */ flex-grow: 1; /* Allow wrapper to take available space */ align-items: center; /* Vertically align items */ } .product-search-bar { padding: 8px 30px 8px 10px; /* Adjust padding: top/bottom, right (for clear), left */ border: 1px solid #ccc; /* Slightly darker border */ border-radius: 4px; font-size: 1em; font-family: inherit; width: 100%; box-sizing: border-box; line-height: 1.5; /* Adjust line height for better vertical centering */ transition: border-color 0.2s ease-in-out; } .product-search-bar:focus { border-color: #0073aa; /* Highlight border on focus */ outline: none; /* Remove default outline */ box-shadow: 0 0 0 1px #0073aa; /* Optional: Add subtle focus shadow */ } .clear-search-button { position: absolute; top: 50%; right: 8px; /* Adjust position */ transform: translateY(-50%); background: none; border: none; font-size: 1.5em; /* Slightly larger 'x' */ color: #aaa; /* Lighter color */ cursor: pointer; padding: 0 4px; line-height: 1; display: none; /* Hide initially - JS will show it */ transition: color 0.2s ease-in-out; } .clear-search-button:hover { color: #555; /* Darker on hover */ } .search-submit-button { padding: 8px 12px; /* Adjust padding */ background-color: #0073aa; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 1em; line-height: 1.5; /* Match input line height */ transition: background-color 0.3s ease; flex-shrink: 0; display: inline-flex; /* Align icon nicely */ align-items: center; justify-content: center; } .search-submit-button i { font-size: 0.95em; /* Adjust icon size if needed */ } .search-submit-button:hover { background-color: #005a87; } /* --- End Search Bar Styles --- */ .product-list-container table { width: 100%; border-collapse: collapse; } .product-list-container th, .product-list-container td { padding: 10px 12px; text-align: left; border-bottom: 1px solid #eee; font-size: 0.95em; vertical-align: middle; } .product-list-container th { background-color: #f9f9f9; font-weight: 600; color: #555; white-space: nowrap; } .product-list-container tbody tr:last-child td { border-bottom: none; } .product-list-container tbody tr:hover { background-color: #f5f5f5; } .product-list-container table img { max-width: 45px; max-height: 45px; display: block; border-radius: 3px; } .product-actions a { margin-right: 5px; text-decoration: none; padding: 4px 8px; border-radius: 4px; color: #fff; font-size: 0.9em; white-space: nowrap; } .product-actions a i { margin-right: 3px; } .product-actions a.edit { background-color: #ffc107; } /* Yellow */ .product-actions a.edit:hover { background-color: #e0a800; } .product-actions a.delete { background-color: #dc3545; } /* Red */ .product-actions a.delete:hover { background-color: #c82333; } /* Message Styles */ .notice-wrap { margin-bottom: 15px; } .notice { padding: 10px 15px; border-radius: 4px; border-left: 4px solid; } .notice-success { background-color: #d4edda; border-color: #28a745; color: #155724; } .notice-error { background-color: #f8d7da; border-color: #dc3545; color: #721c24; } </style> </head> <body> <div class="dashboard-container"> <aside class="sidebar"> <div class="sidebar-menu"> <ul> <li><a href="http://localhost/inventory/index.php/admin-page/">Dashboard</a></li> <?php session_start(); $current_username = isset($_SESSION['username']) ? $_SESSION['username'] : ''; if ($current_username === 'admin') : ?> <li><a href="http://localhost/inventory/index.php/usersmanagement/">User Management</a></li> <li><a href="http://localhost/inventory/index.php/category-page/">Categories</a></li> <li><a href="http://localhost/inventory/index.php/products/">Products</a></li> <li><a href="http://localhost/inventory/index.php/order/">Orders</a></li> <li><a href="http://localhost/inventory/index.php/view-order/">View Orders</a></li> <li><a href="http://localhost/inventory/index.php/sales/">Sales & Report</a></li> <li><a href="http://localhost/inventory/index.php/report/">Inventory Report</a></li> <li><a href="http://localhost/inventory/index.php/history/">Inventory History</a></li> <?php else: ?> <li><a href="http://localhost/inventory/index.php/category-page/">Categories</a></li> <li><a href="http://localhost/inventory/index.php/products/">Products</a></li> <li><a href="http://localhost/inventory/index.php/order/">Orders</a></li> <?php endif; ?> <li><a href="http://localhost/inventory/index.php/sign-in2/" onclick="return confirm('Are you sure you want to log out?');">Logout</a></li> </ul> </div> </aside> <main class="main-content"> <header class="header"> <h1>Products Management</h1> </header> <?php if ($message): ?> <div class="notice-wrap"> <div class="notice notice-<?php echo esc_attr($message_type); ?>"> <p><?php echo esc_html($message); ?></p> </div> </div> <?php endif; ?> <section class="product-content"> <div class="product-form-container"> <h2><?php echo $editing_product ? 'Edit Product' : 'Add New Product'; ?></h2> <form method="post" enctype="multipart/form-data"> <!-- Add nonce field for security --> <?php wp_nonce_field('save_product_action', '_wpnonce_product_form'); ?> <input type="hidden" name="edit_product_id" value="<?php echo esc_attr($editing_product['id'] ?? ''); ?>"> <input type="hidden" name="old_image_url" value="<?php echo esc_attr($editing_product['image_url'] ?? ''); ?>"> <label for="product_name">Product Name:</label> <input type="text" id="product_name" name="product_name" placeholder="Enter product name" value="<?php echo esc_attr($editing_product['name'] ?? ''); ?>" required> <label for="product_category">Category:</label> <select id="product_category" name="product_category" required> <option value="">Select Category</option> <?php if (!empty($categories)): ?> <?php foreach ($categories as $category): ?> <option value="<?php echo esc_attr($category['name']); ?>" <?php selected($editing_product['category'] ?? '', $category['name']); ?>> <?php echo esc_html($category['name']); ?> </option> <?php endforeach; ?> <?php else: ?> <option value="" disabled>No categories found</option> <?php endif; ?> </select> <!-- Changed Volume Unit to Unit --> <label for="unit">Unit:</label> <input type="text" id="unit" name="unit" placeholder="e.g., kg, l, ml, pcs" value="<?php echo esc_attr($editing_product['unit'] ?? ''); ?>"> <label for="product_image">Product Image: <?php if (!empty($editing_product['image_url'])): ?> <img src="<?php echo esc_url($editing_product['image_url']); ?>" style="max-width: 30px; max-height: 30px; vertical-align: middle; margin-left: 5px;"> <?php endif; ?> </label> <input type="file" id="product_image" name="product_image" accept="image/jpeg,image/png,image/gif"> <?php if (!empty($editing_product['image_url'])): ?> <small>Current image shown. Upload a new file to replace it.</small> <?php endif; ?> <label for="buying_price">Buying Price:</label> <input type="number" step="0.01" min="0" id="buying_price" name="buying_price" placeholder="0.00" value="<?php echo esc_attr($editing_product['buying_price'] ?? '0.00'); ?>" required> <label for="selling_price">Selling Price:</label> <input type="number" step="0.01" min="0" id="selling_price" name="selling_price" placeholder="0.00" value="<?php echo esc_attr($editing_product['selling_price'] ?? '0.00'); ?>" required> <!-- *** MODIFIED QUANTITY INPUT *** --> <label for="quantity_input"> <?php echo $editing_product ? 'Quantity to Add:' : 'Quantity:'; ?> </label> <input type="number" min="0" id="quantity_input" name="quantity_input" placeholder="Quantity" value="0" required> <?php if ($editing_product): ?> <small>Current Stock: <?php echo esc_html($editing_product['in_stock']); ?>. Enter amount to add.</small> <?php endif; ?> <!-- *** END MODIFICATION *** --> <div class="form-buttons"> <button type="submit" name="save_product"><?php echo $editing_product ? 'Update Product' : 'Add Product'; ?></button> <?php if ($editing_product): ?> <a href="<?php echo remove_query_arg(array('action', 'id')); // Link to clear edit state ?>" class="button-cancel">Cancel Edit</a> <?php endif; ?> </div> </form> </div> <div class="product-list-container"> <h2>Product List</h2> <form method="GET"> <div class="product-search-wrapper"> <input type="text" id="product-search" class="product-search-bar" name="product_search" placeholder="Search products..." value="<?php echo esc_attr($search_term); ?>"> <?php if (!empty($search_term)): ?> <button type="submit" class="product-search-clear" onclick="this.form.product_search.value = ''; this.form.submit(); return false;"> &times; </button> <?php endif; ?> </div> </form> <table id="product-table"> <thead> <tr> <th>No.</th> <th>Image</th> <th>Product Name</th> <th>Category</th> <th>Unit</th> <th>In-Stock</th> <th>Buying Price</th> <th>Selling Price</th> <th>Date Created</th> <th>Date Updated</th> <th>Action</th> </tr> </thead> <tbody id="product-table-body"> <?php if (empty($products)): ?> <tr><td colspan="11" style="text-align: center;"> <?php echo !empty($search_term) ? 'No products match your search.' : 'No products added yet.'; ?> </td></tr> <?php else: ?> <?php $i = 1; foreach ($products as $product): $edit_url = add_query_arg(['action' => 'edit_product', 'id' => $product['id']], get_permalink()); $delete_url = add_query_arg([ 'action' => 'delete_product', 'id' => $product['id'], '_wpnonce' => wp_create_nonce('delete_product_' . $product['id']) ], get_permalink()); ?> <tr> <td><?php echo $i++; ?></td> <td> <?php if ($product['image_url']): ?> <img src="<?php echo esc_url($product['image_url']); ?>" alt="<?php echo esc_attr($product['name']); ?>" /> <?php else: ?> <span style="color: #999; font-size: 0.9em;">No Image</span> <?php endif; ?> </td> <td><?php echo esc_html($product['name']); ?></td> <td><?php echo esc_html($product['category']); ?></td> <td><?php echo esc_html($product['unit']); ?></td> <td><?php echo esc_html($product['in_stock']); ?></td> <td><?php echo number_format_i18n((float)$product['buying_price'], 2); ?></td> <td><?php echo number_format_i18n((float)$product['selling_price'], 2); ?></td> <td><?php echo esc_html(mysql2date(get_option('date_format'), $product['created_at'])); ?></td> <td><?php echo esc_html(mysql2date(get_option('date_format'), $product['updated_at'])); ?></td> <td class="product-actions"> <a href="<?php echo esc_url($edit_url); ?>" class="edit"><i class="fas fa-edit"></i> Edit</a> <a href="<?php echo esc_url($delete_url); ?>" class="delete" onclick="return confirm('Are you sure you want to delete this product: <?php echo esc_js($product['name']); ?>?')"><i class="fas fa-trash-alt"></i> Delete</a> </td> </tr> <?php endforeach; ?> <?php endif; ?> </tbody> </table> </div> </section> </main> </div> <!-- JavaScript for Clear Button (No changes needed here from previous version) --> <script> document.addEventListener('DOMContentLoaded', function() { console.log("Clear Button Script: DOM Loaded"); // --- Clear Search Button Logic --- const searchInput = document.getElementById('product-search'); const clearButton = document.getElementById('clear-search-btn'); if (searchInput && clearButton) { console.log("Clear Button Script: Elements found."); // Function to show/hide clear button const toggleClearButton = () => { // Use 'inline-block' to show it next to text clearButton.style.display = searchInput.value.trim() !== '' ? 'inline-block' : 'none'; }; // Show/hide button based on input changes searchInput.addEventListener('input', toggleClearButton); console.log("Clear Button Script: 'input' listener attached."); // Handle clear button click clearButton.addEventListener('click', function(event) { console.log("Clear Button Script: Click event triggered on button."); event.preventDefault(); // Prevent any default button behavior searchInput.value = ''; // Clear the input field visually clearButton.style.display = 'none'; // Hide the button immediately console.log("Clear Button Script: Input cleared and button hidden."); try { const currentHref = window.location.href; console.log("Clear Button Script: Current href:", currentHref); const currentUrl = new URL(currentHref); console.log("Clear Button Script: Original URL object created:", currentUrl.toString()); currentUrl.searchParams.delete('product_search'); // Remove the specific parameter const newUrlString = currentUrl.toString(); console.log("Clear Button Script: New URL string:", newUrlString); // Redirect to the cleaned URL window.location.href = newUrlString; console.log("Clear Button Script: Redirect initiated to:", newUrlString); } catch (error) { console.error("Clear Button Script: Error during URL manipulation or redirect:", error); // Provide feedback if redirect fails alert("An error occurred while trying to clear the search. Please check the console (F12) and reload the page manually."); } }); console.log("Clear Button Script: 'click' listener attached."); // Initial check in case the page loaded with a search term toggleClearButton(); console.log("Clear Button Script: Initial button state set."); } else { if (!searchInput) console.error("Clear Button Script: Could not find search input #product-search."); if (!clearButton) console.error("Clear Button Script: Could not find clear button #clear-search-btn."); } // --- End Clear Search Button Logic --- console.log("Clear Button Script: Setup Complete."); }); </script> </body> </html> <?php // End of PHP Snippet ?>

Here's the modified product menu code with inventory history logging added for all product actions (add, edit, delete):

Key changes made:

  1. Added the inventory history table name to configuration
  2. Added the log_inventory_action function at the top
  3. Added logging for:
    • Product deletions (with product name before deletion)
    • Product updates (with quantity change details)
    • New product additions (with initial stock quantity)
  4. All logs include the username, action type, item type, item name, and descriptive message
  5. Maintained all existing functionality while adding the history tracking

The logging will now track all product changes in the inventory_history table while maintaining the exact same user interface and functionality as before._

Updated files
v3
The pasted code is the Order menu code, add a logging history code based on the Inventory History so the adding, deleting and sold product (order) will be recorded or seen in the Inventory History. The Order menu code: <?php global $wpdb; // Define your tables $table_name_categories = 'categories'; // Your categories table name $table_name_products = 'products'; // Your products table name $table_name_orders = 'orders'; // Your orders table name $table_name_order_items = 'order_items'; // Your order_items table name $message = ''; // --- Fetch Categories --- $categories = $wpdb->get_results("SELECT * FROM $table_name_categories ORDER BY name ASC", ARRAY_A); // --- Handle Add Order Form Submission --- if (isset($_POST['add_order']) && isset($_POST['_wpnonce_order_form']) && wp_verify_nonce($_POST['_wpnonce_order_form'], 'add_order_action')) { // Get the values from the form $product_name = isset($_POST['product_name']) ? sanitize_text_field($_POST['product_name']) : ''; $quantity = isset($_POST['quantity']) ? absint($_POST['quantity']) : 0; $unit_price = isset($_POST['unit_price']) ? floatval($_POST['unit_price']) : 0.00; // Validate input if (empty($product_name) || !$quantity || !$unit_price) { $message = 'Invalid product name, quantity, or unit price!'; } else { // Retrieve product details $product = $wpdb->get_row($wpdb->prepare("SELECT * FROM $table_name_products WHERE name = %s", $product_name)); if ($product) { // Check against the correct stock field if ($quantity <= $product->{'in_stock'}) { $amount = $unit_price * $quantity; // Insert into orders table $wpdb->insert($table_name_orders, [ 'customer_name' => 'Default Customer', // Placeholder for customer name 'total_amount' => $amount, 'status' => 'Pending', 'created_at' => current_time('mysql') ]); // Get the ID of the last inserted order $order_id = $wpdb->insert_id; // Insert the order item into the order_items table $wpdb->insert($table_name_order_items, [ 'order_id' => $order_id, 'product_id' => $product->id, 'quantity' => $quantity, 'unit_price' => $unit_price, 'amount' => $amount ]); // Deduct quantity from product stock $new_stock = $product->{'in_stock'} - $quantity; $wpdb->update($table_name_products, ['in_stock' => $new_stock], ['id' => $product->id]); // Redirect to avoid resubmission wp_redirect( $_SERVER['REQUEST_URI'] ); exit; } else { $message = 'Insufficient stock for the product!'; } } else { $message = 'Product not found!'; } } } // --- Handle Payment and Cancellation of Orders --- if (isset($_POST['pay_orders'])) { // Mark all orders as paid $wpdb->update($table_name_orders, ['status' => 'Paid'], ['status' => 'Pending']); // Clear the order items after marking them as paid $wpdb->update($table_name_orders, ['status' => 'Paid'], ['status' => 'Pending']); // Redirect after payment processing wp_redirect( $_SERVER['REQUEST_URI'] ); exit; } if (isset($_POST['cancel_order'])) { $order_id = isset($_POST['order_id']) ? absint($_POST['order_id']) : 0; if ($order_id) { // Retrieve order items to restore stock $order_items = $wpdb->get_results($wpdb->prepare("SELECT * FROM $table_name_order_items WHERE order_id = %d", $order_id), ARRAY_A); // Loop through the order items to restore stock foreach ($order_items as $item) { // Find the corresponding product in the products table $product = $wpdb->get_row($wpdb->prepare("SELECT * FROM $table_name_products WHERE id = %d", $item['product_id'])); if ($product) { $currentStock = $product->{'in_stock'}; $restoredStock = $currentStock + $item['quantity']; // Restore the stock // Update the product stock in the database $wpdb->update($table_name_products, ['in_stock' => $restoredStock], ['id' => $product->id]); // Optional: Log the stock restoration or perform additional actions here if needed } } // Now, delete the order from the orders and its items $wpdb->delete($table_name_orders, ['id' => $order_id]); $wpdb->delete($table_name_order_items, ['order_id' => $order_id]); // Redirect after cancellation wp_redirect($_SERVER['REQUEST_URI']); exit; } }?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Orders Management</title> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css"> <style> body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; margin: 0; padding: 0; } .dashboard-container { display: flex; } .sidebar { width: 240px; background-color: #D1B48C; color: #000000; height: 100vh; position: fixed; left: 0; top: 0; overflow-y: auto; box-shadow: 2px 0 5px rgba(0, 0, 0, 0.1); z-index: 1000; } .sidebar-menu { padding: 20px 0; } .sidebar-menu ul { list-style: none; padding: 0; margin: 0; } .sidebar-menu li a { display: flex; align-items: center; padding: 12px 20px; text-decoration: none; color: #000000; transition: background-color 0.3s ease, color 0.3s ease; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: 16px; } .sidebar-menu li a i { margin-right: 12px; width: 20px; text-align: center; flex-shrink: 0; } .sidebar-menu li a:hover { background-color: #ffffff; color: #000000; } .sidebar-menu li.active a { background-color: #ffffff; color: #000000; font-weight: bold; } .main-content { margin-left: 240px; padding: 25px; flex-grow: 1; } .header { padding: 18px; background: #fff; margin-bottom: 25px; } .form-container, .orders-container { background-color: #fff; padding: 15px; margin-bottom: 20px; } input, select { width: 100%; padding: 10px; margin: 10px 0; } button { padding: 10px; background-color: #007bff; color: white; border: none; cursor: pointer; } button:hover { background-color: #0056b3; } table { width: 100%; border-collapse: collapse; } th, td { padding: 10px; border: 1px solid #ddd; } th { background-color: #f2f2f2; } </style> </head> <body> <div class="dashboard-container"> <aside class="sidebar"> <div class="sidebar-menu"> <ul> <li><a href="http://localhost/inventory/index.php/admin-page/">Dashboard</a></li> <?php session_start(); $current_username = isset($_SESSION['username']) ? $_SESSION['username'] : ''; if ($current_username === 'admin') : ?> <li><a href="http://localhost/inventory/index.php/usersmanagement/">User Management</a> <li><a href="http://localhost/inventory/index.php/category-page/">Categories</a></li> <li><a href="http://localhost/inventory/index.php/products/">Products</a></li> <li><a href="http://localhost/inventory/index.php/order/">Orders</a></li> <li><a href="http://localhost/inventory/index.php/view-order/">View Orders</a></li> <li><a href="http://localhost/inventory/index.php/sales/">Sales & Report</a></li> <li><a href="http://localhost/inventory/index.php/report/">Inventory Report</a></li> <li><a href="http://localhost/inventory/index.php/history/">Inventory History</a></li> <?php else : ?> <li><a href="http://localhost/inventory/index.php/category-page/">Categories</a></li> <li><a href="http://localhost/inventory/index.php/products/">Products</a></li> <li><a href="http://localhost/inventory/index.php/order/">Orders</a></li> <?php endif; ?> <li><a href="http://localhost/inventory/index.php/sign-in2/" onclick="return confirm('Are you sure you want to log out?');">Logout</a></li> </ul> </div> </aside> <main class="main-content"> <header class="header"> <h1>Order Management</h1> </header> <?php if (!empty($message)): ?> <div style="color: red;"><?= esc_html($message); ?></div> <?php endif; ?> <div class="form-container"> <h2>Add Order</h2> <form method="post" action=""> <?php wp_nonce_field('add_order_action', '_wpnonce_order_form'); ?> <label for="product_name">Product Name:</label> <input type="text" id="product_name" name="product_name" required placeholder="Enter product name"> <label for="quantity">Quantity:</label> <input type="number" id="quantity" name="quantity" min="1" required placeholder="Enter quantity"> <label for="unit_price">Unit Price:</label> <input type="number" id="unit_price" name="unit_price" step="0.01" required placeholder="Enter unit price"> <button type="submit" name="add_order">Add Order</button> </form> </div> <div class="orders-container"> <h2>Order List</h2> <table> <thead> <tr> <th>ID</th> <th>Product</th> <th>Quantity</th> <th>Unit Price</th> <th>Amount</th> <th>Status</th> <th>Action</th> </tr> </thead> <tbody> <?php // Fetch existing orders with their items $orders = $wpdb->get_results("SELECT o.*, oi.*, p.name AS product_name FROM $table_name_orders o INNER JOIN $table_name_order_items oi ON o.id = oi.order_id INNER JOIN $table_name_products p ON oi.product_id = p.id", ARRAY_A); $total_amount = 0; if ($orders) foreach ($orders as $order): $amount = $order['quantity'] * $order['unit_price']; $total_amount += $amount; ?> <tr> <td><?php echo esc_html($order['id']); ?></td> <td><?php echo esc_html($order['product_name']); ?></td> <td><?php echo esc_html($order['quantity']); ?></td> <td><?php echo esc_html($order['unit_price']); ?></td> <td><?php echo esc_html($amount); ?></td> <td><?php echo esc_html($order['status']); ?></td> <td> <form method="post" action="" style="display: inline;"> <input type="hidden" name="order_id" value="<?php echo esc_attr($order['id']); ?>"> <button type="submit" name="cancel_order" onclick="return confirm('Are you sure you want to cancel this order?');">Cancel</button> </form> </td> </tr> <?php endforeach; ?> <tr> <td colspan="5" style="text-align: right;"><strong>Total:</strong></td> <td colspan="2"><?php echo esc_html($total_amount); ?></td> </tr> </tbody> </table> <form method="post" action="" style="margin-top: 15px;"> <button type="submit" name="pay_orders">Pay</button> </form> </div> </main> </div> </body> </html>

Here's the modified Order menu code with inventory history logging for order actions:

Key changes made:

  1. Added inventory history table name to configuration
  2. Added the log_inventory_action function
  3. Added logging for:
    • Product sales (when orders are created)
    • Stock restoration (when orders are cancelled)
    • Order cancellations
    • Bulk payment processing
  4. All logs include detailed descriptions of the actions taken
  5. Maintained all existing functionality while adding comprehensive history tracking

The logging will now track all order-related inventory changes in the inventory_history table while maintaining the exact same user interface and functionality as before._

Updated files
v4
in the Order menu code, carefully modify the code. I want after clicking Pay and changed the status of Products to Paid, the Order list table will be cleared, ready for another order. But even though the "Order List" table is cleared the data inserted in the "View Order" during the process in Order menu will NOT disappear, it will stay there. I'll attach also the "View Order" menu code: <?php global $wpdb; // Define your tables $table_name_orders = 'orders'; // Your orders table name $table_name_order_items = 'order_items'; // Your order_items table name $table_name_products = 'products'; // Your products table name // Fetch all orders $all_orders = $wpdb->get_results("SELECT o.*, oi.*, p.name AS product_name FROM $table_name_orders o INNER JOIN $table_name_order_items oi ON o.id = oi.order_id INNER JOIN $table_name_products p ON oi.product_id = p.id", ARRAY_A); ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>View Orders</title> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css"> <style> body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; margin: 0; padding: 0; } .dashboard-container { display: flex; } .sidebar { width: 240px; background-color: #D1B48C; height: 100vh; position: fixed; } .main-content { margin-left: 240px; padding: 25px; flex-grow: 1; } .header { padding: 18px; background: #fff; margin-bottom: 25px; } .orders-container { background-color: #fff; padding: 15px; margin-bottom: 20px; } table { width: 100%; border-collapse: collapse; } th, td { padding: 10px; border: 1px solid #ddd; } th { background-color: #f2f2f2; } </style> </head> <body> <div class="dashboard-container"> <aside class="sidebar"> <div class="sidebar-menu"> <ul> <li><a href="http://localhost/inventory/index.php/admin-page/">Dashboard</a></li> <?php session_start(); $current_username = isset($_SESSION['username']) ? $_SESSION['username'] : ''; if ($current_username === 'admin') : ?> <li><a href="http://localhost/inventory/index.php/usersmanagement/">User Management</a> <li><a href="http://localhost/inventory/index.php/category-page/">Categories</a></li> <li><a href="http://localhost/inventory/index.php/products/">Products</a></li> <li><a href="http://localhost/inventory/index.php/order/">Orders</a></li> <li><a href="http://localhost/inventory/index.php/view-order/">View Orders</a></li> <li><a href="http://localhost/inventory/index.php/sales/">Sales & Report</a></li> <li><a href="http://localhost/inventory/index.php/report/">Inventory Report</a></li> <li><a href="http://localhost/inventory/index.php/history/">Inventory History</a></li> <?php else : ?> <li><a href="http://localhost/inventory/index.php/category-page/">Categories</a></li> <li><a href="http://localhost/inventory/index.php/products/">Products</a></li> <li><a href="http://localhost/inventory/index.php/order/">Orders</a></li> <?php endif; ?> <li><a href="http://localhost/inventory/index.php/sign-in2/" onclick="return confirm('Are you sure you want to log out?');">Logout</a></li> </ul> </div> </aside> <main class="main-content"> <header class="header"> <h1>All Orders</h1> </header> <div class="orders-container"> <table> <thead> <tr> <th>ID</th> <th>Product Name</th> <th>Qty</th> <th>Unit</th> <th>Unit Price</th> <th>Product Sale</th> <th>Status</th> </tr> </thead> <tbody> <?php if ($all_orders): foreach ($all_orders as $order): ?> <tr> <td><?php echo esc_html($order['id']); ?></td> <td><?php echo esc_html($order['product_name']); ?></td> <td><?php echo esc_html($order['quantity']); ?></td> <td><?php echo esc_html($order['unit']); ?></td> <td><?php echo esc_html($order['unit_price']); ?></td> <td><?php echo esc_html($order['amount']); ?></td> <td><?php echo esc_html($order['status']); ?></td> </tr> <?php endforeach; else: ?> <tr> <td colspan="7">No orders found.</td> </tr> <?php endif; ?> </tbody> </table> </div> </main> </div> </body> </html>

Here's the modified Order menu code that clears the order list after payment while preserving the data in View Orders:

Key changes made:

  1. Modified the payment processing to:
    • First get all pending orders before marking them as paid
    • Mark orders as paid (they will still appear in View Orders)
    • Delete the order items from the order_items table (clearing the current order list)
  2. Changed the order list query to only show pending orders
  3. Updated the payment logging to reflect the clearing action
  4. Added conditional display of the Pay button (only shows when there are pending orders)
  5. The View Orders page remains unchanged as it shows all orders regardless of status

This implementation ensures that:

  • Paid orders remain visible in View Orders
  • The current order list is cleared after payment
  • All data integrity is maintained
  • The inventory history logs all relevant actions_
Updated files
v5