document.addEventListener('DOMContentLoaded', () => { const reportButtons = document.querySelectorAll('.report-btn'); const reportTitle = document.getElementById('report-title'); const reportTable = document.getElementById('report-table'); const exportCsvButton = document.getElementById('export-csv'); const exportPdfButton = document.getElementById('export-pdf'); const themeToggleButton = document.getElementById('theme-toggle'); const body = document.body; // Helper function to update the theme toggle button text function updateThemeToggleButtonText() { if (body.classList.contains('dark-mode')) { themeToggleButton.textContent = 'Change to Light Mode'; } else { themeToggleButton.textContent = 'Change to Dark Mode'; } } // Check and apply the saved theme from localStorage const savedTheme = localStorage.getItem('theme'); if (savedTheme) { body.classList.toggle('dark-mode', savedTheme === 'dark'); } // Update the button text based on the current theme updateThemeToggleButtonText(); // Toggle the theme on button click themeToggleButton.addEventListener('click', () => { const isDarkMode = body.classList.toggle('dark-mode'); localStorage.setItem('theme', isDarkMode ? 'dark' : 'light'); updateThemeToggleButtonText(); // Update the button text after toggling }); // Date formatting is now handled consistently on the backend // Function to populate the table with data function populateTable(data) { const tableHead = reportTable.querySelector('thead tr'); const tableBody = reportTable.querySelector('tbody'); // Clear existing table content tableHead.innerHTML = ''; tableBody.innerHTML = ''; if (data.headers && data.rows && data.rows.length > 0) { // Populate table headers data.headers.forEach((header) => { const th = document.createElement('th'); th.textContent = header; tableHead.appendChild(th); }); // Populate table rows data.rows.forEach((row) => { const tr = document.createElement('tr'); row.forEach((cell, index) => { const td = document.createElement('td'); // Use the cell data as-is since backend now handles formatting td.textContent = cell; tr.appendChild(td); }); tableBody.appendChild(tr); }); } else { // Handle no data scenarios const tr = document.createElement('tr'); const td = document.createElement('td'); // 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); } } // Function to export table data as CSV function exportTableToCSV(filename) { let csv = []; const rows = reportTable.querySelectorAll('tr'); // Loop through each row in the table rows.forEach((row) => { const cells = row.querySelectorAll('th, td'); const rowData = Array.from(cells).map((cell) => `"${cell.textContent.trim()}"`); csv.push(rowData.join(',')); }); // Create a Blob from the CSV data const csvBlob = new Blob([csv.join('\n')], { type: 'text/csv' }); // Create a link element to trigger the download const downloadLink = document.createElement('a'); downloadLink.href = URL.createObjectURL(csvBlob); downloadLink.download = filename; // Append the link to the document, trigger the download, and remove the link document.body.appendChild(downloadLink); downloadLink.click(); document.body.removeChild(downloadLink); } // 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' || button.id === 'date-range-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}"`; // Fetch data for the selected report fetch(`/get_report_data?report=${reportNumber}`) .then((response) => { if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return response.json(); }) .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) => { console.error('Error fetching report data:', error); reportTitle.textContent = 'Error loading data.'; }); }); }); // Bind the export functionality to the CSV button if (exportCsvButton) { exportCsvButton.addEventListener('click', () => { const rows = reportTable.querySelectorAll('tr'); if (rows.length === 0) { alert('No data available to export.'); return; } const reportTitleText = reportTitle.textContent.trim(); const filename = `${reportTitleText.replace(/\s+/g, '_')}.csv`; // Generate a filename based on the report title 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 = 'Error'; tbody.innerHTML = `${data.message}`; } }) .catch(error => { console.error('Database test error:', error); reportTitle.textContent = 'Database Test Error'; alert(`Error testing database: ${error.message}`); }); }); } // Placeholder for PDF export functionality if (exportPdfButton) { exportPdfButton.addEventListener('click', () => { alert('Exporting current report as PDF...'); // Add logic to export the current report as PDF }); } }); document.addEventListener('DOMContentLoaded', () => { const templateList = document.getElementById('template-list'); const createTemplateBtn = document.getElementById('create-template-btn'); // Example: Handle the "Create New Template" button click if (createTemplateBtn) { createTemplateBtn.addEventListener('click', () => { window.location.href = '/create_template'; }); } // Example: Handle the "Edit" and "Delete" buttons if (templateList) { templateList.addEventListener('click', (event) => { if (event.target.classList.contains('edit-btn')) { const templateId = event.target.closest('li').dataset.id; window.location.href = `/edit_template/${templateId}`; } else if (event.target.classList.contains('delete-btn')) { const templateId = event.target.closest('li').dataset.id; if (confirm('Are you sure you want to delete this template?')) { fetch(`/delete_template/${templateId}`, { method: 'POST' }) .then(response => response.text()) .then(data => { alert(data); // Optionally, remove the template from the list event.target.closest('li').remove(); }); } } }); } }); document.addEventListener('DOMContentLoaded', () => { const setDimensionsBtn = document.getElementById('set-dimensions-btn'); const labelPreview = document.getElementById('label-preview'); if (setDimensionsBtn) { setDimensionsBtn.addEventListener('click', () => { const widthInput = document.getElementById('label-width').value; const heightInput = document.getElementById('label-height').value; if (!widthInput || !heightInput) { alert('Please enter valid dimensions for width and height.'); return; } // Convert mm to pixels (1 mm = 3.779528 pixels) const widthPixels = parseFloat(widthInput) * 3.779528; const heightPixels = parseFloat(heightInput) * 3.779528; // Set the size of the label container labelPreview.style.width = `${widthPixels}px`; labelPreview.style.height = `${heightPixels}px`; alert(`Label dimensions set to ${widthPixels.toFixed(2)}px x ${heightPixels.toFixed(2)}px.`); }); } }); document.addEventListener('DOMContentLoaded', () => { const labelPreview = document.getElementById('label-preview'); const addFieldButtons = document.querySelectorAll('.add-field-btn'); // Add fields dynamically addFieldButtons.forEach(button => { button.addEventListener('click', () => { const fieldType = button.getAttribute('data-type'); addFieldToPreview(fieldType); }); }); // Function to add a field to the preview function addFieldToPreview(type) { const field = document.createElement('div'); field.classList.add('draggable-field'); field.setAttribute('draggable', 'true'); field.style.position = 'absolute'; field.style.top = '10px'; field.style.left = '10px'; switch (type) { case 'text-label': field.textContent = 'Text Label'; field.style.fontSize = '14px'; break; case 'text-input': field.innerHTML = ''; break; case 'barcode': field.textContent = 'Barcode Box'; field.style.border = '1px dashed #000'; field.style.width = '100px'; field.style.height = '50px'; break; case 'qrcode': field.textContent = 'QR Code Box'; field.style.border = '1px dashed #000'; field.style.width = '50px'; field.style.height = '50px'; break; } labelPreview.appendChild(field); // Make the field draggable makeFieldDraggable(field); } // Function to make a field draggable function makeFieldDraggable(field) { field.addEventListener('dragstart', (e) => { e.dataTransfer.setData('text/plain', null); field.classList.add('dragging'); }); field.addEventListener('dragend', () => { field.classList.remove('dragging'); }); labelPreview.addEventListener('dragover', (e) => { e.preventDefault(); const draggingField = document.querySelector('.dragging'); const rect = labelPreview.getBoundingClientRect(); draggingField.style.left = `${e.clientX - rect.left}px`; draggingField.style.top = `${e.clientY - rect.top}px`; }); } // Calendar functionality for date selection const selectDayReportBtn = document.getElementById('select-day-report'); const calendarModal = document.getElementById('calendar-modal'); const closeModal = document.querySelector('.close-modal'); const cancelDate = document.getElementById('cancel-date'); const confirmDate = document.getElementById('confirm-date'); const calendarDays = document.getElementById('calendar-days'); const calendarMonthYear = document.getElementById('calendar-month-year'); const prevMonth = document.getElementById('prev-month'); const nextMonth = document.getElementById('next-month'); let currentDate = new Date(); let selectedDate = null; // Show calendar modal if (selectDayReportBtn) { selectDayReportBtn.addEventListener('click', () => { calendarModal.style.display = 'block'; generateCalendar(currentDate); }); } // Show calendar modal for quality defects report const selectDayDefectsReportBtn = document.getElementById('select-day-defects-report'); if (selectDayDefectsReportBtn) { selectDayDefectsReportBtn.addEventListener('click', () => { console.log('DEBUG: Select Day Quality Defects Report button clicked!'); calendarModal.style.display = 'block'; generateCalendar(currentDate); // Mark this as a defects report by setting a flag calendarModal.setAttribute('data-report-type', 'defects'); }); } // Close modal events if (closeModal) { closeModal.addEventListener('click', closeCalendarModal); } if (cancelDate) { cancelDate.addEventListener('click', closeCalendarModal); } // Click outside modal to close window.addEventListener('click', (e) => { if (e.target === calendarModal) { closeCalendarModal(); } }); // Navigation buttons if (prevMonth) { prevMonth.addEventListener('click', () => { currentDate.setMonth(currentDate.getMonth() - 1); generateCalendar(currentDate); }); } if (nextMonth) { nextMonth.addEventListener('click', () => { currentDate.setMonth(currentDate.getMonth() + 1); generateCalendar(currentDate); }); } // Confirm date selection if (confirmDate) { confirmDate.addEventListener('click', () => { console.log('DEBUG: Calendar Generate Report button clicked!'); if (selectedDate) { // Format date as YYYY-MM-DD (timezone-safe) const year = selectedDate.getFullYear(); const month = String(selectedDate.getMonth() + 1).padStart(2, '0'); const day = String(selectedDate.getDate()).padStart(2, '0'); const formattedDate = `${year}-${month}-${day}`; console.log(`DEBUG: Selected date object:`, selectedDate); console.log(`DEBUG: Selected date formatted as: ${formattedDate}`); // Check if this is a defects report or regular report const reportType = calendarModal.getAttribute('data-report-type'); console.log(`DEBUG: Report type: ${reportType}`); closeCalendarModal(); // Fetch appropriate report data for the selected date if (reportType === 'defects') { console.log('DEBUG: About to call fetchCustomDefectsReport'); fetchCustomDefectsReport(formattedDate); } else { console.log('DEBUG: About to call fetchCustomDateReport'); fetchCustomDateReport(formattedDate); } } else { console.log('DEBUG: No date selected when Generate Report clicked'); } }); } function closeCalendarModal() { calendarModal.style.display = 'none'; selectedDate = null; confirmDate.disabled = true; // Clear report type calendarModal.removeAttribute('data-report-type'); // Remove selected class from all days const selectedDays = document.querySelectorAll('.calendar-day.selected'); selectedDays.forEach(day => day.classList.remove('selected')); } function generateCalendar(date) { const year = date.getFullYear(); const month = date.getMonth(); // Update header const monthNames = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']; calendarMonthYear.textContent = `${monthNames[month]} ${year}`; // Clear previous days calendarDays.innerHTML = ''; // Get first day of month and number of days const firstDay = new Date(year, month, 1).getDay(); const daysInMonth = new Date(year, month + 1, 0).getDate(); const today = new Date(); // Add empty cells for days before month starts for (let i = 0; i < firstDay; i++) { const emptyDay = document.createElement('div'); emptyDay.classList.add('calendar-day', 'other-month'); calendarDays.appendChild(emptyDay); } // Add days of the month for (let day = 1; day <= daysInMonth; day++) { const dayElement = document.createElement('div'); dayElement.classList.add('calendar-day'); dayElement.textContent = day; const dayDate = new Date(year, month, day); // Highlight today if (dayDate.toDateString() === today.toDateString()) { dayElement.classList.add('today'); } // Add click event dayElement.addEventListener('click', () => { // Remove previous selection const previousSelected = document.querySelector('.calendar-day.selected'); if (previousSelected) { previousSelected.classList.remove('selected'); } // Select this day dayElement.classList.add('selected'); selectedDate = new Date(year, month, day); confirmDate.disabled = false; }); calendarDays.appendChild(dayElement); } } function fetchCustomDateReport(dateString) { console.log(`DEBUG: fetchCustomDateReport called with date: ${dateString}`); // Get elements directly to avoid scope issues const reportTitleElement = document.getElementById('report-title'); const reportTableElement = document.getElementById('report-table'); console.log(`DEBUG: reportTitle element:`, reportTitleElement); console.log(`DEBUG: reportTable element:`, reportTableElement); if (!reportTitleElement) { console.error('ERROR: report-title element not found!'); return; } reportTitleElement.textContent = `Loading report for ${dateString}...`; // Local function to populate table to avoid scope issues function localPopulateTable(data) { const tableHead = reportTableElement.querySelector('thead tr'); const tableBody = reportTableElement.querySelector('tbody'); // Clear existing table content tableHead.innerHTML = ''; tableBody.innerHTML = ''; if (data.headers && data.rows && data.rows.length > 0) { // Populate table headers data.headers.forEach((header) => { const th = document.createElement('th'); th.textContent = header; tableHead.appendChild(th); }); // Populate table rows data.rows.forEach((row) => { const tr = document.createElement('tr'); row.forEach((cell, index) => { const td = document.createElement('td'); // Format dates properly if (data.headers[index].toLowerCase() === 'date' && cell) { td.textContent = cell; // Use as-is since backend already formats it } else { td.textContent = cell; } tr.appendChild(td); }); tableBody.appendChild(tr); }); } else { // Handle no data scenarios const tr = document.createElement('tr'); const td = document.createElement('td'); td.colSpan = 10; // Span all columns td.textContent = 'No data available.'; td.style.textAlign = 'center'; tr.appendChild(td); tableBody.appendChild(tr); } } const url = `/generate_report?report=6&date=${dateString}`; console.log(`DEBUG: Making request to URL: ${url}`); fetch(url) .then(response => { console.log(`DEBUG: Response status: ${response.status}`); return response.json(); }) .then(data => { console.log('DEBUG: Response data:', data); if (data.error) { reportTitleElement.textContent = `Error: ${data.error}`; localPopulateTable({ headers: [], rows: [] }); } else if (data.message) { reportTitleElement.textContent = data.message; localPopulateTable({ headers: [], rows: [] }); } else if (data.rows && data.rows.length === 0) { reportTitleElement.textContent = `No data found for ${dateString}`; localPopulateTable(data); } else { reportTitleElement.textContent = `Daily Report for ${dateString} (${data.rows ? data.rows.length : 0} records)`; localPopulateTable(data); } }) .catch(error => { console.error('Error fetching custom date report:', error); reportTitleElement.textContent = 'Error loading report'; localPopulateTable({ headers: [], rows: [] }); }); } // Function to fetch quality defects report for specific date function fetchCustomDefectsReport(dateString) { console.log(`DEBUG: fetchCustomDefectsReport called with date: ${dateString}`); // Get elements directly to avoid scope issues const reportTitleElement = document.getElementById('report-title'); const reportTableElement = document.getElementById('report-table'); console.log(`DEBUG: reportTitle element:`, reportTitleElement); console.log(`DEBUG: reportTable element:`, reportTableElement); if (!reportTitleElement) { console.error('ERROR: report-title element not found!'); return; } reportTitleElement.textContent = `Loading quality defects report for ${dateString}...`; // Local function to populate table to avoid scope issues function localPopulateTable(data) { const tableHead = reportTableElement.querySelector('thead tr'); const tableBody = reportTableElement.querySelector('tbody'); // Clear existing table content tableHead.innerHTML = ''; tableBody.innerHTML = ''; if (data.headers && data.rows && data.rows.length > 0) { // Populate table headers data.headers.forEach((header) => { const th = document.createElement('th'); th.textContent = header; tableHead.appendChild(th); }); // Populate table rows data.rows.forEach((row) => { const tr = document.createElement('tr'); row.forEach((cell, index) => { const td = document.createElement('td'); // Highlight quality code column for defects if (data.headers[index] === 'Quality Code' && cell != '0') { td.style.backgroundColor = '#ffebee'; // Light red background td.style.fontWeight = 'bold'; } td.textContent = cell; tr.appendChild(td); }); tableBody.appendChild(tr); }); } else { // Handle no data scenarios const tr = document.createElement('tr'); const td = document.createElement('td'); td.colSpan = 10; // Span all columns td.textContent = 'No quality defects found for this date.'; td.style.textAlign = 'center'; tr.appendChild(td); tableBody.appendChild(tr); } } const url = `/generate_report?report=8&date=${dateString}`; console.log(`DEBUG: Making request to URL: ${url}`); fetch(url) .then(response => { console.log(`DEBUG: Response status: ${response.status}`); return response.json(); }) .then(data => { console.log('DEBUG: Quality defects response data:', data); if (data.error) { reportTitleElement.textContent = `Error: ${data.error}`; localPopulateTable({ headers: [], rows: [] }); } else if (data.message) { reportTitleElement.textContent = data.message; localPopulateTable({ headers: [], rows: [] }); } else if (data.rows && data.rows.length === 0) { reportTitleElement.textContent = `No quality defects found for ${dateString}`; localPopulateTable(data); } else { let titleText = `Quality Defects Report for ${dateString} (${data.rows ? data.rows.length : 0} defective items)`; // Add defects summary info if available if (data.defects_summary) { const summary = data.defects_summary; titleText += ` | ${summary.unique_defect_types} defect types, ${summary.total_rejected_quantity} rejected items`; } reportTitleElement.textContent = titleText; localPopulateTable(data); } }) .catch(error => { console.error('Error fetching quality defects report:', error); reportTitleElement.textContent = 'Error loading quality defects report'; localPopulateTable({ headers: [], rows: [] }); }); } // ===== DATE RANGE MODAL FUNCTIONALITY ===== const dateRangeReportBtn = document.getElementById('date-range-report'); const dateRangeDefectsBtn = document.getElementById('date-range-defects-report'); const dateRangeModal = document.getElementById('date-range-modal'); const closeDateRange = document.getElementById('close-date-range'); const cancelDateRange = document.getElementById('cancel-date-range'); // Track which date range report type was requested let currentDateRangeReportType = 'standard'; // 'standard' or 'defects' const confirmDateRange = document.getElementById('confirm-date-range'); const startDateInput = document.getElementById('start-date'); const endDateInput = document.getElementById('end-date'); if (dateRangeReportBtn && dateRangeModal) { // Open date range modal dateRangeReportBtn.addEventListener('click', () => { console.log('DEBUG: Date Range Report button clicked!'); currentDateRangeReportType = 'standard'; // Set default dates (last 7 days to today) const today = new Date(); const weekAgo = new Date(); weekAgo.setDate(today.getDate() - 6); // Last 7 days including today const todayStr = formatDateForInput(today); const weekAgoStr = formatDateForInput(weekAgo); startDateInput.value = weekAgoStr; endDateInput.value = todayStr; console.log(`DEBUG: Default date range set to ${weekAgoStr} - ${todayStr}`); dateRangeModal.style.display = 'block'; validateDateRange(); // Enable/disable confirm button based on inputs }); // Add handler for date range defects report if (dateRangeDefectsBtn) { dateRangeDefectsBtn.addEventListener('click', () => { console.log('DEBUG: Date Range Quality Defects Report button clicked!'); currentDateRangeReportType = 'defects'; // Set default dates (last 7 days to today) const today = new Date(); const weekAgo = new Date(); weekAgo.setDate(today.getDate() - 6); // Last 7 days including today const todayStr = formatDateForInput(today); const weekAgoStr = formatDateForInput(weekAgo); startDateInput.value = weekAgoStr; endDateInput.value = todayStr; console.log(`DEBUG: Default date range for defects report set to ${weekAgoStr} - ${todayStr}`); dateRangeModal.style.display = 'block'; validateDateRange(); // Enable/disable confirm button based on inputs }); } // Close modal functions function closeDateRangeModal() { dateRangeModal.style.display = 'none'; startDateInput.value = ''; endDateInput.value = ''; confirmDateRange.disabled = true; } closeDateRange.addEventListener('click', closeDateRangeModal); cancelDateRange.addEventListener('click', closeDateRangeModal); // Close modal when clicking outside window.addEventListener('click', (e) => { if (e.target === dateRangeModal) { closeDateRangeModal(); } }); // Validate date range and enable/disable confirm button function validateDateRange() { const startDate = startDateInput.value; const endDate = endDateInput.value; if (startDate && endDate) { const start = new Date(startDate); const end = new Date(endDate); if (start <= end) { confirmDateRange.disabled = false; console.log(`DEBUG: Valid date range: ${startDate} to ${endDate}`); } else { confirmDateRange.disabled = true; console.log('DEBUG: Invalid date range: start date is after end date'); } } else { confirmDateRange.disabled = true; console.log('DEBUG: Missing start or end date'); } } // Validate when dates change startDateInput.addEventListener('change', validateDateRange); endDateInput.addEventListener('change', validateDateRange); // Confirm date range selection confirmDateRange.addEventListener('click', () => { const startDate = startDateInput.value; const endDate = endDateInput.value; console.log(`DEBUG: Generating ${currentDateRangeReportType} date range report from ${startDate} to ${endDate}`); closeDateRangeModal(); // Fetch report data for the selected date range based on report type if (currentDateRangeReportType === 'defects') { fetchDateRangeDefectsReport(startDate, endDate); } else { fetchDateRangeReport(startDate, endDate); } }); } // Helper function to format date for input field function formatDateForInput(date) { const year = date.getFullYear(); const month = String(date.getMonth() + 1).padStart(2, '0'); const day = String(date.getDate()).padStart(2, '0'); return `${year}-${month}-${day}`; } // Function to fetch date range report function fetchDateRangeReport(startDate, endDate) { console.log(`DEBUG: Fetching date range report from ${startDate} to ${endDate}`); // Get elements directly to avoid scope issues const reportTitleElement = document.getElementById('report-title'); const reportTableElement = document.getElementById('report-table'); if (!reportTitleElement) { console.error('ERROR: report-title element not found!'); return; } reportTitleElement.textContent = `Loading report for ${startDate} to ${endDate}...`; // Local function to populate table to avoid scope issues function localPopulateTable(data) { const tableHead = reportTableElement.querySelector('thead tr'); const tableBody = reportTableElement.querySelector('tbody'); // Clear existing table content tableHead.innerHTML = ''; tableBody.innerHTML = ''; if (data.headers && data.rows && data.rows.length > 0) { // Populate table headers data.headers.forEach((header) => { const th = document.createElement('th'); th.textContent = header; tableHead.appendChild(th); }); // Populate table rows data.rows.forEach((row) => { const tr = document.createElement('tr'); row.forEach((cell, index) => { const td = document.createElement('td'); td.textContent = cell; tr.appendChild(td); }); tableBody.appendChild(tr); }); } else { // Handle no data scenarios const tr = document.createElement('tr'); const td = document.createElement('td'); td.colSpan = 10; // Span all columns td.textContent = 'No data available for the selected date range.'; td.style.textAlign = 'center'; tr.appendChild(td); tableBody.appendChild(tr); } } const url = `/generate_report?report=7&start_date=${startDate}&end_date=${endDate}`; console.log(`DEBUG: Making date range request to URL: ${url}`); fetch(url) .then(response => { console.log(`DEBUG: Response status: ${response.status}`); return response.json(); }) .then(data => { console.log('DEBUG: Date range response data:', data); if (data.error) { reportTitleElement.textContent = `Error: ${data.error}`; localPopulateTable({ headers: [], rows: [] }); } else if (data.message) { reportTitleElement.textContent = data.message; localPopulateTable({ headers: [], rows: [] }); } else if (data.rows && data.rows.length === 0) { reportTitleElement.textContent = `No data found for ${startDate} to ${endDate}`; localPopulateTable(data); } else { const recordCount = data.rows ? data.rows.length : 0; let titleText = `Date Range Report: ${startDate} to ${endDate} (${recordCount} records)`; // Add summary info if available if (data.summary) { titleText += ` | Approved: ${data.summary.total_approved}, Rejected: ${data.summary.total_rejected}`; } reportTitleElement.textContent = titleText; localPopulateTable(data); } }) .catch(error => { console.error('Error fetching date range report:', error); reportTitleElement.textContent = 'Error loading date range report'; localPopulateTable({ headers: [], rows: [] }); }); } // Function to fetch date range quality defects report function fetchDateRangeDefectsReport(startDate, endDate) { console.log(`DEBUG: Fetching date range quality defects report from ${startDate} to ${endDate}`); // Get elements directly to avoid scope issues const reportTitleElement = document.getElementById('report-title'); const reportTableElement = document.getElementById('report-table'); if (!reportTitleElement) { console.error('ERROR: report-title element not found!'); return; } reportTitleElement.textContent = `Loading quality defects report for ${startDate} to ${endDate}...`; // Local function to populate table to avoid scope issues function localPopulateTable(data) { const tableHead = reportTableElement.querySelector('thead tr'); const tableBody = reportTableElement.querySelector('tbody'); // Clear existing table content tableHead.innerHTML = ''; tableBody.innerHTML = ''; if (data.headers && data.rows && data.rows.length > 0) { // Populate table headers data.headers.forEach((header) => { const th = document.createElement('th'); th.textContent = header; tableHead.appendChild(th); }); // Populate table rows data.rows.forEach((row) => { const tr = document.createElement('tr'); row.forEach((cell, index) => { const td = document.createElement('td'); td.textContent = cell; tr.appendChild(td); }); tableBody.appendChild(tr); }); } else { // Handle no data scenarios const tr = document.createElement('tr'); const td = document.createElement('td'); td.colSpan = 10; // Span all columns td.textContent = 'No quality defects found for the selected date range.'; td.style.textAlign = 'center'; tr.appendChild(td); tableBody.appendChild(tr); } } const url = `/generate_report?report=9&start_date=${startDate}&end_date=${endDate}`; console.log(`DEBUG: Making date range defects request to URL: ${url}`); fetch(url) .then(response => { console.log(`DEBUG: Response status: ${response.status}`); return response.json(); }) .then(data => { console.log('DEBUG: Date range defects response data:', data); if (data.error) { reportTitleElement.textContent = `Error: ${data.error}`; localPopulateTable({ headers: [], rows: [] }); } else if (data.message) { reportTitleElement.textContent = data.message; localPopulateTable({ headers: [], rows: [] }); } else if (data.rows && data.rows.length === 0) { reportTitleElement.textContent = `No quality defects found for ${startDate} to ${endDate}`; localPopulateTable(data); } else { const recordCount = data.rows ? data.rows.length : 0; let titleText = `Quality Defects Report: ${startDate} to ${endDate} (${recordCount} defective items)`; // Add defects summary info if available if (data.defects_summary) { const summary = data.defects_summary; titleText += ` | Rejected Qty: ${summary.total_rejected_quantity || 0}, Defect Types: ${summary.unique_defect_types || 0}`; if (summary.days_with_defects) { titleText += `, Days: ${summary.days_with_defects}`; } } reportTitleElement.textContent = titleText; localPopulateTable(data); } }) .catch(error => { console.error('Error fetching date range defects report:', error); reportTitleElement.textContent = 'Error loading date range quality defects report'; localPopulateTable({ headers: [], rows: [] }); }); } });