================================================================================ MPUMALANGA PVC - CLIENTS MODULE ================================================================================ Last Updated: 2026-03-26 Path: /app/clients/ ================================================================================ WHAT THIS SECTION DOES ----------------------- Manages the list of clients (customers) who receive quotes and invoices. A client record stores contact and company details that get pulled into all quotes, invoices, PDFs, and the dashboard. DATABASE TABLE: clients ----------------------- record_id int - Primary key (NO AUTO_INCREMENT - see known issues) name text - Client/company name address text - Physical address email text - Email address contact_person text - Name of main contact contact_number text - Phone number vat_number text - VAT registration number (optional) reg_number text - Company registration number (optional) date_time varchar(50) - Auto-set to current timestamp on insert ================================================================================ FILES ================================================================================ home.php -------- What it does: Lists all clients in a configurable data table with an Edit button per row. How it works: Uses the table class: new table("clients") and add_action_button("edit_clients.php"). The table class queries the clients table and renders columns based on the user's saved view settings in user_table_views. Known issues: - The page title is set to "JOB CARDS" instead of "CLIENTS" - minor bug. -------------------------------------------------------------------------------- add_clients.php --------------- What it does: Form to create a new client. Fields: Name, Address, Email, Contact Person, Contact Number, VAT Number, Reg Number. How it works: Standard form page. User fills in fields and clicks SAVE. The save() JavaScript function collects all text/email inputs and POSTs to save_clients.php. Notes: - VAT Number and Reg Number are optional fields (no validation). - The heading has a typo: "Company Detials" instead of "Company Details". JS Functions on this page: save(url) - Collects all input[type=text] and input[type=email] values into a payload. - Creates a hidden form and submits it via POST to the given URL. - NOTE: This version only collects type="text", "date", "email". Hidden inputs are NOT collected. This is fine for add (no hidden fields needed). -------------------------------------------------------------------------------- save_clients.php ---------------- What it does: Backend handler. Receives POST data from add_clients.php and inserts a new client record into the database, then redirects to home.php. How it works: - Applies apostrophe escaping to $_POST['name'] using str_replace before inserting (prevents SQL breaking on names like O'Brien). - Runs INSERT INTO clients with all POST fields. - Redirects to home.php unconditionally after the INSERT. KNOWN ISSUE (fixed 2026-03): Original code used "if ($client_id > 0) { header(redirect) }" but the clients table has no AUTO_INCREMENT so mysqli_insert_id() always returned 0, meaning the redirect never fired. Fixed by making the redirect unconditional. The db class exits on any SQL error, so a missing redirect only means the save succeeded but the page went blank. -------------------------------------------------------------------------------- edit_clients.php ---------------- What it does: Pre-filled form to edit an existing client. Loads the client by record_id from the URL (?record_id=X) and pre-fills all fields. How it works: - Queries clients table: SELECT * WHERE record_id = $_GET['record_id'] - Renders all fields with value="" - The record_id is stored in a hidden input (uses the HTML "hidden" attribute on a type="text" field, not type="hidden" - still works but is unusual). - SAVE button POSTs to update_clients.php. Known issues: - Field values are not escaped with htmlspecialchars(), so special characters like quotes or < in client names could break the HTML rendering. JS Functions on this page: save(url) - Same as add_clients.php. -------------------------------------------------------------------------------- update_clients.php ------------------ What it does: Backend handler. Receives POST data from edit_clients.php and updates the client record, then redirects to home.php. How it works: - Runs UPDATE clients SET ... WHERE record_id = $_POST['record_id'] - Redirects to home.php unconditionally after the UPDATE. KNOWN ISSUE (fixed 2026-03): Same redirect bug as save_clients.php. UPDATE returns a result object, not an insert_id, so the original "if ($client_id > 0)" check always failed. Fixed by making the redirect unconditional. -------------------------------------------------------------------------------- import.php ---------- THIS FILE IS EMPTY. No functionality has been built. If there is a nav link pointing here, it will show a blank page. Intended purpose unknown - likely a CSV import feature that was never completed. ================================================================================ KNOWN ISSUES SUMMARY ================================================================================ 1. home.php page title says "JOB CARDS" - should be "CLIENTS". 2. "Company Detials" typo in add and edit forms. 3. edit_clients.php does not use htmlspecialchars() on echoed values. 4. import.php is empty. 5. No client deactivation/deletion feature exists. 6. SQL injection present in all save/update handlers. ================================================================================