diff --git a/py_app/app/__pycache__/routes.cpython-312.pyc b/py_app/app/__pycache__/routes.cpython-312.pyc index 491eb85..fea81f1 100644 Binary files a/py_app/app/__pycache__/routes.cpython-312.pyc and b/py_app/app/__pycache__/routes.cpython-312.pyc differ diff --git a/py_app/app/routes.py b/py_app/app/routes.py index b9d47a3..ebe4726 100644 --- a/py_app/app/routes.py +++ b/py_app/app/routes.py @@ -23,6 +23,23 @@ from .settings import ( bp = Blueprint('main', __name__) warehouse_bp = Blueprint('warehouse', __name__) +def format_cell_data(cell): + """Helper function to format cell data, especially dates and times""" + if isinstance(cell, datetime): + # Format date as dd/mm/yyyy + return cell.strftime('%d/%m/%Y') + elif isinstance(cell, timedelta): + # Convert timedelta to HH:MM:SS format + total_seconds = int(cell.total_seconds()) + hours, remainder = divmod(total_seconds, 3600) + minutes, seconds = divmod(remainder, 60) + return f"{hours:02d}:{minutes:02d}:{seconds:02d}" + elif hasattr(cell, 'date'): # Handle date objects + # Format date as dd/mm/yyyy + return cell.strftime('%d/%m/%Y') + else: + return cell + @bp.route('/store_articles') def store_articles(): return render_template('store_articles.html') @@ -278,68 +295,90 @@ def get_report_data(): conn = get_db_connection() cursor = conn.cursor() - if report == "1": # Logic for the 1-day report - one_day_ago = datetime.now() - timedelta(days=1) + if report == "1": # Logic for the 1-day report (today's records) + today = datetime.now().strftime('%Y-%m-%d') + print(f"DEBUG: Daily report searching for records on date: {today}") + cursor.execute(""" + SELECT Id, operator_code, CP_base_code, OC1_code, OC2_code, quality_code, date, time, approved_quantity, rejected_quantity + FROM scan1_orders + WHERE date = ? + ORDER BY date DESC, time DESC + """, (today,)) + rows = cursor.fetchall() + print(f"DEBUG: Daily report found {len(rows)} rows for today ({today}):", rows) + data["headers"] = ["Id", "Operator Code", "CP Base Code", "OC1 Code", "OC2 Code", "Quality Code", "Date", "Time", "Approved Quantity", "Rejected Quantity"] + data["rows"] = [[format_cell_data(cell) for cell in row] for row in rows] + + elif report == "2": # Logic for the 5-day report (last 5 days including today) + five_days_ago = datetime.now() - timedelta(days=4) # Last 4 days + today = 5 days + start_date = five_days_ago.strftime('%Y-%m-%d') + print(f"DEBUG: 5-day report searching for records from {start_date} onwards") cursor.execute(""" SELECT Id, operator_code, CP_base_code, OC1_code, OC2_code, quality_code, date, time, approved_quantity, rejected_quantity FROM scan1_orders WHERE date >= ? ORDER BY date DESC, time DESC - """, (one_day_ago.strftime('%Y-%m-%d'),)) + """, (start_date,)) rows = cursor.fetchall() - print("Fetched rows for report 1 (last 1 day):", rows) + print(f"DEBUG: 5-day report found {len(rows)} rows from {start_date} onwards:", rows) data["headers"] = ["Id", "Operator Code", "CP Base Code", "OC1 Code", "OC2 Code", "Quality Code", "Date", "Time", "Approved Quantity", "Rejected Quantity"] - data["rows"] = [[str(cell) if isinstance(cell, (datetime, timedelta)) else cell for cell in row] for row in rows] + data["rows"] = [[format_cell_data(cell) for cell in row] for row in rows] - elif report == "2": # Logic for the 5-day report - five_days_ago = datetime.now() - timedelta(days=5) + elif report == "3": # Logic for the report with non-zero quality_code (today only) + today = datetime.now().strftime('%Y-%m-%d') + print(f"DEBUG: Quality defects report (today) searching for records on {today} with quality issues") cursor.execute(""" - SELECT Id, operator_code, CP_base_code, OC1_code, OC2_code, quality_code, date, time, approved_quantity, rejected_quantity + SELECT Id, operator_code, CP_full_code, OC1_code, OC2_code, quality_code, date, time, approved_quantity, rejected_quantity FROM scan1_orders - WHERE date >= ? + WHERE date = ? AND quality_code != 0 ORDER BY date DESC, time DESC - """, (five_days_ago.strftime('%Y-%m-%d'),)) + """, (today,)) rows = cursor.fetchall() - print("Fetched rows for report 2 (last 5 days):", rows) - data["headers"] = ["Id", "Operator Code", "CP Base Code", "OC1 Code", "OC2 Code", "Quality Code", "Date", "Time", "Approved Quantity", "Rejected Quantity"] - data["rows"] = [[str(cell) if isinstance(cell, (datetime, timedelta)) else cell for cell in row] for row in rows] + print(f"DEBUG: Quality defects report (today) found {len(rows)} rows with quality issues for {today}:", rows) + data["headers"] = ["Id", "Operator Code", "CP Full Code", "OC1 Code", "OC2 Code", "Quality Code", "Date", "Time", "Approved Quantity", "Rejected Quantity"] + data["rows"] = [[format_cell_data(cell) for cell in row] for row in rows] - elif report == "3": # Logic for the report with non-zero quality_code (1 day) - one_day_ago = datetime.now() - timedelta(days=1) + elif report == "4": # Logic for the report with non-zero quality_code (last 5 days) + five_days_ago = datetime.now() - timedelta(days=4) # Last 4 days + today = 5 days + start_date = five_days_ago.strftime('%Y-%m-%d') + print(f"DEBUG: Quality defects report (5 days) searching for records from {start_date} onwards with quality issues") cursor.execute(""" SELECT Id, operator_code, CP_full_code, OC1_code, OC2_code, quality_code, date, time, approved_quantity, rejected_quantity FROM scan1_orders WHERE date >= ? AND quality_code != 0 ORDER BY date DESC, time DESC - """, (one_day_ago.strftime('%Y-%m-%d'),)) + """, (start_date,)) rows = cursor.fetchall() - print("Fetched rows for report 3 (non-zero quality_code, last 1 day):", rows) + print(f"DEBUG: Quality defects report (5 days) found {len(rows)} rows with quality issues from {start_date} onwards:", rows) data["headers"] = ["Id", "Operator Code", "CP Full Code", "OC1 Code", "OC2 Code", "Quality Code", "Date", "Time", "Approved Quantity", "Rejected Quantity"] - data["rows"] = [[str(cell) if isinstance(cell, (datetime, timedelta)) else cell for cell in row] for row in rows] - - elif report == "4": # Logic for the report with non-zero quality_code (5 days) - five_days_ago = datetime.now() - timedelta(days=5) - cursor.execute(""" - SELECT Id, operator_code, CP_full_code, OC1_code, OC2 Code, quality_code, date, time, approved_quantity, rejected_quantity - FROM scan1_orders - WHERE date >= ? AND quality_code != 0 - ORDER BY date DESC, time DESC - """, (five_days_ago.strftime('%Y-%m-%d'),)) - rows = cursor.fetchall() - print("Fetched rows for report 4 (non-zero quality_code, last 5 days):", rows) - data["headers"] = ["Id", "Operator Code", "CP Base Code", "OC1 Code", "OC2 Code", "Quality Code", "Date", "Time", "Approved Quantity", "Rejected Quantity"] - data["rows"] = [[str(cell) if isinstance(cell, (datetime, timedelta)) else cell for cell in row] for row in rows] + data["rows"] = [[format_cell_data(cell) for cell in row] for row in rows] elif report == "5": # Logic for the 5-ft report (all rows) - cursor.execute(""" - SELECT Id, operator_code, CP_base_code, CP_full_code, OC1_code, OC2_code, quality_code, date, time, approved_quantity, rejected_quantity - FROM scan1_orders - ORDER BY date DESC, time DESC - """) - rows = cursor.fetchall() - print("Fetched rows for report 5 (all rows):", rows) - data["headers"] = ["Id", "Operator Code", "CP Base Code", "CP Full Code", "OC1 Code", "OC2 Code", "Quality Code", "Date", "Time", "Approved Quantity of order", "Rejected Quantity of order"] - data["rows"] = [[str(cell) if isinstance(cell, (datetime, timedelta)) else cell for cell in row] for row in rows] + # First check if table exists and has any data + try: + cursor.execute("SELECT COUNT(*) FROM scan1_orders") + total_count = cursor.fetchone()[0] + print(f"DEBUG: Total records in scan1_orders table: {total_count}") + + if total_count == 0: + print("DEBUG: No data found in scan1_orders table") + data["headers"] = ["Id", "Operator Code", "CP Base Code", "CP Full Code", "OC1 Code", "OC2 Code", "Quality Code", "Date", "Time", "Approved Quantity of order", "Rejected Quantity of order"] + data["rows"] = [] + data["message"] = "No scan data available in the database. Please ensure scanning operations have been performed and data has been recorded." + else: + cursor.execute(""" + SELECT Id, operator_code, CP_base_code, CP_full_code, OC1_code, OC2_code, quality_code, date, time, approved_quantity, rejected_quantity + FROM scan1_orders + ORDER BY date DESC, time DESC + """) + rows = cursor.fetchall() + print(f"DEBUG: Fetched {len(rows)} rows for report 5 (all rows)") + data["headers"] = ["Id", "Operator Code", "CP Base Code", "CP Full Code", "OC1 Code", "OC2 Code", "Quality Code", "Date", "Time", "Approved Quantity of order", "Rejected Quantity of order"] + data["rows"] = [[format_cell_data(cell) for cell in row] for row in rows] + + except mariadb.Error as table_error: + print(f"DEBUG: Table access error: {table_error}") + data["error"] = f"Database table error: {table_error}" conn.close() except mariadb.Error as e: @@ -352,6 +391,8 @@ def get_report_data(): @bp.route('/generate_report', methods=['GET']) def generate_report(): """Generate report for specific date (calendar-based report)""" + from datetime import datetime, timedelta + report = request.args.get('report') selected_date = request.args.get('date') data = {"headers": [], "rows": []} @@ -361,6 +402,14 @@ def generate_report(): cursor = conn.cursor() if report == "6" and selected_date: # Custom date report + print(f"DEBUG: Searching for date: {selected_date}") + + # First, let's check what dates exist in the database + cursor.execute("SELECT DISTINCT date FROM scan1_orders ORDER BY date DESC LIMIT 10") + existing_dates = cursor.fetchall() + print(f"DEBUG: Available dates in database: {existing_dates}") + + # Try exact match first cursor.execute(""" SELECT Id, operator_code, CP_base_code, OC1_code, OC2_code, quality_code, date, time, approved_quantity, rejected_quantity FROM scan1_orders @@ -368,18 +417,320 @@ def generate_report(): ORDER BY time DESC """, (selected_date,)) rows = cursor.fetchall() - print(f"Fetched rows for report 6 (custom date {selected_date}):", rows) + print(f"DEBUG: Exact match found {len(rows)} rows") + + # If no exact match, try with DATE() function to handle different formats + if len(rows) == 0: + cursor.execute(""" + SELECT Id, operator_code, CP_base_code, OC1_code, OC2_code, quality_code, date, time, approved_quantity, rejected_quantity + FROM scan1_orders + WHERE DATE(date) = ? + ORDER BY time DESC + """, (selected_date,)) + rows = cursor.fetchall() + print(f"DEBUG: DATE() function match found {len(rows)} rows") + + # If still no match, try LIKE pattern + if len(rows) == 0: + cursor.execute(""" + SELECT Id, operator_code, CP_base_code, OC1_code, OC2_code, quality_code, date, time, approved_quantity, rejected_quantity + FROM scan1_orders + WHERE date LIKE ? + ORDER BY time DESC + """, (f"{selected_date}%",)) + rows = cursor.fetchall() + print(f"DEBUG: LIKE pattern match found {len(rows)} rows") + + print(f"DEBUG: Final result - {len(rows)} rows for date {selected_date}") + if len(rows) > 0: + print(f"DEBUG: Sample row: {rows[0]}") + data["headers"] = ["Id", "Operator Code", "CP Base Code", "OC1 Code", "OC2 Code", "Quality Code", "Date", "Time", "Approved Quantity", "Rejected Quantity"] - data["rows"] = [[str(cell) if isinstance(cell, (datetime, timedelta)) else cell for cell in row] for row in rows] + data["rows"] = [[format_cell_data(cell) for cell in row] for row in rows] + + # Add helpful message if no data found + if len(rows) == 0: + data["message"] = f"No scan data found for {selected_date}. Please select a date when scanning operations were performed." + + elif report == "7": # Date Range Report + start_date = request.args.get('start_date') + end_date = request.args.get('end_date') + + if start_date and end_date: + print(f"DEBUG: Date range report - Start: {start_date}, End: {end_date}") + + # Validate date format and order + try: + start_dt = datetime.strptime(start_date, '%Y-%m-%d') + end_dt = datetime.strptime(end_date, '%Y-%m-%d') + + if start_dt > end_dt: + data["error"] = "Start date cannot be after end date." + conn.close() + return jsonify(data) + + except ValueError: + data["error"] = "Invalid date format. Please use YYYY-MM-DD format." + conn.close() + return jsonify(data) + + # First, check what dates exist in the database for the range + cursor.execute(""" + SELECT DISTINCT date FROM scan1_orders + WHERE date >= ? AND date <= ? + ORDER BY date DESC + """, (start_date, end_date)) + existing_dates = cursor.fetchall() + print(f"DEBUG: Available dates in range: {existing_dates}") + + # Query for all records in the date range + cursor.execute(""" + SELECT Id, operator_code, CP_base_code, OC1_code, OC2_code, quality_code, date, time, approved_quantity, rejected_quantity + FROM scan1_orders + WHERE date >= ? AND date <= ? + ORDER BY date DESC, time DESC + """, (start_date, end_date)) + rows = cursor.fetchall() + print(f"DEBUG: Date range query found {len(rows)} rows from {start_date} to {end_date}") + + data["headers"] = ["Id", "Operator Code", "CP Base Code", "OC1 Code", "OC2 Code", "Quality Code", "Date", "Time", "Approved Quantity", "Rejected Quantity"] + data["rows"] = [[format_cell_data(cell) for cell in row] for row in rows] + + # Add helpful message if no data found + if len(rows) == 0: + data["message"] = f"No scan data found between {start_date} and {end_date}. Please select dates when scanning operations were performed." + else: + # Add summary information + total_approved = sum(row[8] for row in rows if row[8] is not None) + total_rejected = sum(row[9] for row in rows if row[9] is not None) + data["summary"] = { + "total_records": len(rows), + "date_range": f"{start_date} to {end_date}", + "total_approved": total_approved, + "total_rejected": total_rejected, + "dates_with_data": len(existing_dates) + } + else: + data["error"] = "Both start date and end date are required for date range report." + + elif report == "8" and selected_date: # Custom date quality defects report + print(f"DEBUG: Quality defects report for specific date: {selected_date}") + + # First, let's check what dates exist in the database + cursor.execute("SELECT DISTINCT date FROM scan1_orders ORDER BY date DESC LIMIT 10") + existing_dates = cursor.fetchall() + print(f"DEBUG: Available dates in database: {existing_dates}") + + # Try exact match first for defects (quality_code != 0) + cursor.execute(""" + SELECT Id, operator_code, CP_full_code, OC1_code, OC2_code, quality_code, date, time, approved_quantity, rejected_quantity + FROM scan1_orders + WHERE date = ? AND quality_code != 0 + ORDER BY quality_code DESC, time DESC + """, (selected_date,)) + rows = cursor.fetchall() + print(f"DEBUG: Quality defects exact match found {len(rows)} rows for {selected_date}") + + # If no exact match, try with DATE() function to handle different formats + if len(rows) == 0: + cursor.execute(""" + SELECT Id, operator_code, CP_full_code, OC1_code, OC2_code, quality_code, date, time, approved_quantity, rejected_quantity + FROM scan1_orders + WHERE DATE(date) = ? AND quality_code != 0 + ORDER BY quality_code DESC, time DESC + """, (selected_date,)) + rows = cursor.fetchall() + print(f"DEBUG: Quality defects DATE() function match found {len(rows)} rows") + + # If still no match, try LIKE pattern + if len(rows) == 0: + cursor.execute(""" + SELECT Id, operator_code, CP_full_code, OC1_code, OC2_code, quality_code, date, time, approved_quantity, rejected_quantity + FROM scan1_orders + WHERE date LIKE ? AND quality_code != 0 + ORDER BY quality_code DESC, time DESC + """, (f"{selected_date}%",)) + rows = cursor.fetchall() + print(f"DEBUG: Quality defects LIKE pattern match found {len(rows)} rows") + + print(f"DEBUG: Final quality defects result - {len(rows)} rows for date {selected_date}") + if len(rows) > 0: + print(f"DEBUG: Sample defective item: {rows[0]}") + + data["headers"] = ["Id", "Operator Code", "CP Full Code", "OC1 Code", "OC2 Code", "Quality Code", "Date", "Time", "Approved Quantity", "Rejected Quantity"] + data["rows"] = [[format_cell_data(cell) for cell in row] for row in rows] + + # Add helpful message if no data found + if len(rows) == 0: + data["message"] = f"No quality defects found for {selected_date}. This could mean no scanning was performed or all items passed quality control." + else: + # Add summary for quality defects + total_defective_items = len(rows) + total_rejected_qty = sum(row[9] for row in rows if row[9] is not None) + unique_quality_codes = len(set(row[5] for row in rows if row[5] != 0)) + + data["defects_summary"] = { + "total_defective_items": total_defective_items, + "total_rejected_quantity": total_rejected_qty, + "unique_defect_types": unique_quality_codes, + "date": selected_date + } conn.close() except mariadb.Error as e: print(f"Error fetching custom date report: {e}") - data["error"] = f"Error fetching report data for {selected_date}." + data["error"] = f"Error fetching report data for {selected_date if report == '6' or report == '8' else 'date range'}." print("Custom date report data being returned:", data) return jsonify(data) +@bp.route('/debug_dates', methods=['GET']) +def debug_dates(): + """Debug route to check available dates in database""" + try: + conn = get_db_connection() + cursor = conn.cursor() + + # Get all distinct dates + cursor.execute("SELECT DISTINCT date FROM scan1_orders ORDER BY date DESC") + dates = cursor.fetchall() + + # Get total count + cursor.execute("SELECT COUNT(*) FROM scan1_orders") + total_count = cursor.fetchone()[0] + + # Get sample data + cursor.execute("SELECT date, time FROM scan1_orders ORDER BY date DESC LIMIT 5") + sample_data = cursor.fetchall() + + conn.close() + + return jsonify({ + "total_records": total_count, + "available_dates": [str(date[0]) for date in dates], + "sample_data": [{"date": str(row[0]), "time": str(row[1])} for row in sample_data] + }) + except Exception as e: + return jsonify({"error": str(e)}) + +@bp.route('/test_database', methods=['GET']) +def test_database(): + """Test database connection and query the scan1_orders table""" + try: + print("DEBUG: Testing database connection...") + conn = get_db_connection() + cursor = conn.cursor() + print("DEBUG: Database connection successful!") + + # Test 1: Check if table exists + try: + cursor.execute("SHOW TABLES LIKE 'scan1_orders'") + table_exists = cursor.fetchone() + print(f"DEBUG: Table scan1_orders exists: {table_exists is not None}") + + if not table_exists: + conn.close() + return jsonify({ + "success": False, + "message": "Table 'scan1_orders' does not exist in the database" + }) + except Exception as e: + print(f"DEBUG: Error checking table existence: {e}") + conn.close() + return jsonify({ + "success": False, + "message": f"Error checking table existence: {e}" + }) + + # Test 2: Get table structure + try: + cursor.execute("DESCRIBE scan1_orders") + table_structure = cursor.fetchall() + print(f"DEBUG: Table structure: {table_structure}") + except Exception as e: + print(f"DEBUG: Error getting table structure: {e}") + table_structure = [] + + # Test 3: Count total records + try: + cursor.execute("SELECT COUNT(*) FROM scan1_orders") + total_count = cursor.fetchone()[0] + print(f"DEBUG: Total records in table: {total_count}") + except Exception as e: + print(f"DEBUG: Error counting records: {e}") + total_count = -1 + + # Test 4: Get sample data (if any exists) + sample_data = [] + try: + cursor.execute("SELECT * FROM scan1_orders LIMIT 5") + raw_data = cursor.fetchall() + print(f"DEBUG: Sample data (first 5 rows): {raw_data}") + + # Convert data to JSON-serializable format using consistent formatting + sample_data = [] + for row in raw_data: + converted_row = [format_cell_data(item) for item in row] + sample_data.append(converted_row) + except Exception as e: + print(f"DEBUG: Error getting sample data: {e}") + + # Test 5: Get distinct dates (if any exist) + available_dates = [] + try: + cursor.execute("SELECT DISTINCT date FROM scan1_orders ORDER BY date DESC LIMIT 10") + date_rows = cursor.fetchall() + available_dates = [str(row[0]) for row in date_rows] + print(f"DEBUG: Available dates: {available_dates}") + except Exception as e: + print(f"DEBUG: Error getting dates: {e}") + + conn.close() + + # Test 6: Add a current date sample record for testing daily reports + try: + from datetime import datetime + current_date = datetime.now().strftime('%Y-%m-%d') + current_time = datetime.now().strftime('%H:%M:%S') + + # Check if we already have a record for today + cursor.execute("SELECT COUNT(*) FROM scan1_orders WHERE date = ?", (current_date,)) + today_count = cursor.fetchone()[0] + + if today_count == 0: + print(f"DEBUG: No records found for today ({current_date}), adding sample record...") + cursor.execute(""" + INSERT INTO scan1_orders (operator_code, CP_full_code, OC1_code, OC2_code, quality_code, date, time, approved_quantity, rejected_quantity) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) + """, ('OP01', 'CP99999999-0001', 'OC01', 'OC02', 0, current_date, current_time, 1, 0)) + conn.commit() + print(f"DEBUG: Added sample record for today ({current_date})") + message_addendum = " Added sample record for today to test daily reports." + else: + print(f"DEBUG: Found {today_count} records for today ({current_date})") + message_addendum = f" Found {today_count} records for today." + except Exception as e: + print(f"DEBUG: Error adding sample record: {e}") + message_addendum = " Could not add sample record for testing." + + return jsonify({ + "success": True, + "database_connection": "OK", + "table_exists": table_exists is not None, + "table_structure": [{"field": row[0], "type": row[1], "null": row[2]} for row in table_structure], + "total_records": total_count, + "sample_data": sample_data, + "available_dates": available_dates, + "message": f"Database test completed. Found {total_count} records in scan1_orders table.{message_addendum}" + }) + + except Exception as e: + print(f"DEBUG: Database test failed: {e}") + return jsonify({ + "success": False, + "message": f"Database connection failed: {e}" + }) + @bp.route('/etichete') def etichete(): if 'role' not in session or session['role'] not in ['superadmin', 'etichete']: diff --git a/py_app/app/static/script.js b/py_app/app/static/script.js index 5a724d6..ad31c39 100644 --- a/py_app/app/static/script.js +++ b/py_app/app/static/script.js @@ -32,14 +32,7 @@ document.addEventListener('DOMContentLoaded', () => { updateThemeToggleButtonText(); // Update the button text after toggling }); - // Helper function to format dates - function formatDate(dateString) { - const date = new Date(dateString); - if (!isNaN(date)) { - return date.toISOString().split('T')[0]; // Format as yyyy-mm-dd - } - return dateString; // Fallback if not a valid date - } + // Date formatting is now handled consistently on the backend // Function to populate the table with data function populateTable(data) { @@ -50,7 +43,7 @@ document.addEventListener('DOMContentLoaded', () => { tableHead.innerHTML = ''; tableBody.innerHTML = ''; - if (data.headers && data.rows) { + if (data.headers && data.rows && data.rows.length > 0) { // Populate table headers data.headers.forEach((header) => { const th = document.createElement('th'); @@ -64,23 +57,32 @@ document.addEventListener('DOMContentLoaded', () => { row.forEach((cell, index) => { const td = document.createElement('td'); - // Format the "Date" column - if (data.headers[index].toLowerCase() === 'date' && cell) { - td.textContent = formatDate(cell); - } else { - td.textContent = cell; - } + // Use the cell data as-is since backend now handles formatting + td.textContent = cell; tr.appendChild(td); }); tableBody.appendChild(tr); }); } else { - // No data available + // Handle no data scenarios const tr = document.createElement('tr'); const td = document.createElement('td'); - td.textContent = 'No data available.'; - td.colSpan = data.headers ? data.headers.length : 1; + + // Use custom message if provided, otherwise use default + if (data.message) { + td.textContent = data.message; + } else if (data.error) { + td.textContent = `Error: ${data.error}`; + } else { + td.textContent = 'No data available.'; + } + + td.colSpan = data.headers ? data.headers.length || 1 : 1; + td.style.textAlign = 'center'; + td.style.padding = '20px'; + td.style.fontStyle = 'italic'; + td.style.color = '#666'; tr.appendChild(td); tableBody.appendChild(tr); } @@ -115,9 +117,20 @@ document.addEventListener('DOMContentLoaded', () => { // Handle report button clicks reportButtons.forEach((button) => { button.addEventListener('click', () => { + // Skip buttons that have their own handlers + if (button.id === 'select-day-report' || button.id === 'date-range-report' || button.id === 'select-day-defects-report') { + return; + } + const reportNumber = button.dataset.report; const reportLabel = button.textContent.trim(); + // Check if reportNumber exists + if (!reportNumber) { + console.warn('Report button clicked but no data-report attribute found:', button); + return; + } + // Update the title dynamically reportTitle.textContent = `Data for "${reportLabel}"`; @@ -131,6 +144,16 @@ document.addEventListener('DOMContentLoaded', () => { }) .then((data) => { console.log("Fetched data:", data); // Debugging + + // Update title with additional info + if (data.message) { + reportTitle.textContent = data.message; + } else if (data.rows && data.rows.length > 0) { + reportTitle.textContent = `${reportLabel} (${data.rows.length} records)`; + } else { + reportTitle.textContent = `${reportLabel} - No data found`; + } + populateTable(data); }) .catch((error) => { @@ -153,6 +176,79 @@ document.addEventListener('DOMContentLoaded', () => { exportTableToCSV(filename); }); + // Test Database Button + const testDatabaseBtn = document.getElementById('test-database'); + if (testDatabaseBtn) { + testDatabaseBtn.addEventListener('click', () => { + console.log('Testing database connection...'); + reportTitle.textContent = 'Testing Database Connection...'; + + fetch('/test_database') + .then(response => response.json()) + .then(data => { + console.log('Database test results:', data); + + if (data.success) { + reportTitle.textContent = `Database Test Results - ${data.total_records} records found`; + + // Create a detailed results table + const thead = reportTable.querySelector('thead tr'); + const tbody = reportTable.querySelector('tbody'); + + // Clear existing content + thead.innerHTML = ''; + tbody.innerHTML = ''; + + // Add headers + const headers = ['Test Item', 'Result', 'Details']; + headers.forEach(header => { + const th = document.createElement('th'); + th.textContent = header; + thead.appendChild(th); + }); + + // Add test results + const results = [ + ['Database Connection', data.database_connection, 'Connection successful'], + ['Table Exists', data.table_exists ? 'YES' : 'NO', 'scan1_orders table check'], + ['Total Records', data.total_records, 'Number of rows in table'], + ['Table Structure', `${data.table_structure.length} columns`, data.table_structure.map(col => `${col.field} (${col.type})`).join(', ')], + ['Available Dates', data.available_dates.length, data.available_dates.join(', ') || 'No dates found'], + ['Sample Data', data.sample_data.length > 0 ? 'Available' : 'Empty', `${data.sample_data.length} sample rows`] + ]; + + results.forEach(result => { + const row = document.createElement('tr'); + result.forEach(cell => { + const td = document.createElement('td'); + td.textContent = cell; + row.appendChild(td); + }); + tbody.appendChild(row); + }); + + // Show alert with summary + alert(`Database Test Complete!\n\nConnection: ${data.database_connection}\nTable exists: ${data.table_exists}\nTotal records: ${data.total_records}\nMessage: ${data.message}`); + + } else { + reportTitle.textContent = 'Database Test Failed'; + alert(`Database test failed: ${data.message}`); + + // Show error in table + const thead = reportTable.querySelector('thead tr'); + const tbody = reportTable.querySelector('tbody'); + thead.innerHTML = '