Files
quality_recticel/py_app/app/static/script.js
2025-09-24 22:04:34 +03:00

1074 lines
45 KiB
JavaScript

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 = '<th>Error</th>';
tbody.innerHTML = `<tr><td>${data.message}</td></tr>`;
}
})
.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 = '<input type="text" placeholder="Input Field" style="width: 100px;">';
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: [] });
});
}
});