539 lines
20 KiB
JavaScript
539 lines
20 KiB
JavaScript
// FG Quality specific JavaScript - Standalone version
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// Prevent conflicts with main script.js by removing existing listeners
|
|
console.log('FG Quality JavaScript loaded');
|
|
|
|
const reportButtons = document.querySelectorAll('.report-btn');
|
|
const reportTable = document.getElementById('report-table');
|
|
const reportTitle = document.getElementById('report-title');
|
|
const exportCsvButton = document.getElementById('export-csv');
|
|
|
|
// Calendar elements
|
|
const calendarModal = document.getElementById('calendar-modal');
|
|
const dateRangeModal = document.getElementById('date-range-modal');
|
|
const selectDayReport = document.getElementById('select-day-report');
|
|
const selectDayDefectsReport = document.getElementById('select-day-defects-report');
|
|
const dateRangeReport = document.getElementById('date-range-report');
|
|
const dateRangeDefectsReport = document.getElementById('date-range-defects-report');
|
|
|
|
let currentReportType = null;
|
|
let currentDate = new Date();
|
|
let selectedDate = null;
|
|
|
|
// Clear any existing event listeners by cloning elements
|
|
function clearExistingListeners() {
|
|
if (selectDayReport) {
|
|
const newSelectDayReport = selectDayReport.cloneNode(true);
|
|
selectDayReport.parentNode.replaceChild(newSelectDayReport, selectDayReport);
|
|
}
|
|
if (selectDayDefectsReport) {
|
|
const newSelectDayDefectsReport = selectDayDefectsReport.cloneNode(true);
|
|
selectDayDefectsReport.parentNode.replaceChild(newSelectDayDefectsReport, selectDayDefectsReport);
|
|
}
|
|
if (dateRangeReport) {
|
|
const newDateRangeReport = dateRangeReport.cloneNode(true);
|
|
dateRangeReport.parentNode.replaceChild(newDateRangeReport, dateRangeReport);
|
|
}
|
|
if (dateRangeDefectsReport) {
|
|
const newDateRangeDefectsReport = dateRangeDefectsReport.cloneNode(true);
|
|
dateRangeDefectsReport.parentNode.replaceChild(newDateRangeDefectsReport, dateRangeDefectsReport);
|
|
}
|
|
}
|
|
|
|
// Clear existing listeners first
|
|
clearExistingListeners();
|
|
|
|
// Re-get elements after cloning
|
|
const newSelectDayReport = document.getElementById('select-day-report');
|
|
const newSelectDayDefectsReport = document.getElementById('select-day-defects-report');
|
|
const newDateRangeReport = document.getElementById('date-range-report');
|
|
const newDateRangeDefectsReport = document.getElementById('date-range-defects-report');
|
|
|
|
// Add event listeners to report buttons
|
|
reportButtons.forEach(button => {
|
|
const reportType = button.getAttribute('data-report');
|
|
if (reportType) {
|
|
// Clone to remove existing listeners
|
|
const newButton = button.cloneNode(true);
|
|
button.parentNode.replaceChild(newButton, button);
|
|
|
|
newButton.addEventListener('click', function(e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
console.log('FG Report button clicked:', reportType);
|
|
fetchFGReportData(reportType);
|
|
});
|
|
}
|
|
});
|
|
|
|
// Calendar-based report buttons with FG-specific handlers
|
|
if (newSelectDayReport) {
|
|
newSelectDayReport.addEventListener('click', (e) => {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
console.log('FG Select Day Report clicked');
|
|
currentReportType = '6';
|
|
showCalendarModal();
|
|
});
|
|
}
|
|
|
|
if (newSelectDayDefectsReport) {
|
|
newSelectDayDefectsReport.addEventListener('click', (e) => {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
console.log('FG Select Day Defects Report clicked');
|
|
currentReportType = '8';
|
|
showCalendarModal();
|
|
});
|
|
}
|
|
|
|
if (newDateRangeReport) {
|
|
newDateRangeReport.addEventListener('click', (e) => {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
console.log('FG Date Range Report clicked');
|
|
currentReportType = '7';
|
|
showDateRangeModal();
|
|
});
|
|
}
|
|
|
|
if (newDateRangeDefectsReport) {
|
|
newDateRangeDefectsReport.addEventListener('click', (e) => {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
console.log('FG Date Range Defects Report clicked');
|
|
currentReportType = '9';
|
|
showDateRangeModal();
|
|
});
|
|
}
|
|
|
|
// Function to fetch FG report data
|
|
function fetchFGReportData(reportType) {
|
|
const url = `/get_fg_report_data?report=${reportType}`;
|
|
console.log('Fetching FG data from:', url);
|
|
reportTitle.textContent = 'Loading FG data...';
|
|
|
|
fetch(url)
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
console.log('FG Report data received:', data);
|
|
if (data.error) {
|
|
reportTitle.textContent = data.error;
|
|
return;
|
|
}
|
|
|
|
populateFGTable(data);
|
|
updateReportTitle(reportType);
|
|
})
|
|
.catch(error => {
|
|
console.error('Error fetching FG report data:', error);
|
|
reportTitle.textContent = 'Error loading FG data.';
|
|
});
|
|
}
|
|
|
|
// Function to fetch FG report data for specific dates
|
|
function fetchFGDateReportData(reportType, date, startDate = null, endDate = null) {
|
|
let url = `/generate_fg_report?report=${reportType}`;
|
|
if (date) {
|
|
url += `&date=${date}`;
|
|
}
|
|
if (startDate && endDate) {
|
|
url += `&start_date=${startDate}&end_date=${endDate}`;
|
|
}
|
|
|
|
console.log('Fetching FG date report from:', url);
|
|
reportTitle.textContent = 'Loading FG data...';
|
|
|
|
fetch(url)
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
console.log('FG Date report data received:', data);
|
|
if (data.error) {
|
|
reportTitle.textContent = data.error;
|
|
return;
|
|
}
|
|
|
|
populateFGTable(data);
|
|
updateDateReportTitle(reportType, date, startDate, endDate);
|
|
})
|
|
.catch(error => {
|
|
console.error('Error fetching FG date report data:', error);
|
|
reportTitle.textContent = 'Error loading FG data.';
|
|
});
|
|
}
|
|
|
|
// Function to populate the table with FG data
|
|
function populateFGTable(data) {
|
|
const thead = reportTable.querySelector('thead tr');
|
|
const tbody = reportTable.querySelector('tbody');
|
|
|
|
// Clear existing content
|
|
thead.innerHTML = '';
|
|
tbody.innerHTML = '';
|
|
|
|
// Add headers
|
|
if (data.headers && data.headers.length > 0) {
|
|
data.headers.forEach(header => {
|
|
const th = document.createElement('th');
|
|
th.textContent = header;
|
|
thead.appendChild(th);
|
|
});
|
|
}
|
|
|
|
// Add rows
|
|
if (data.rows && data.rows.length > 0) {
|
|
data.rows.forEach(row => {
|
|
const tr = document.createElement('tr');
|
|
row.forEach(cell => {
|
|
const td = document.createElement('td');
|
|
td.textContent = cell || '';
|
|
tr.appendChild(td);
|
|
});
|
|
tbody.appendChild(tr);
|
|
});
|
|
} else {
|
|
// Show no data message
|
|
const tr = document.createElement('tr');
|
|
const td = document.createElement('td');
|
|
td.colSpan = data.headers ? data.headers.length : 1;
|
|
td.textContent = data.message || 'No FG data found for the selected criteria.';
|
|
td.style.textAlign = 'center';
|
|
td.style.fontStyle = 'italic';
|
|
td.style.padding = '20px';
|
|
tr.appendChild(td);
|
|
tbody.appendChild(tr);
|
|
}
|
|
}
|
|
|
|
// Function to update report title based on type
|
|
function updateReportTitle(reportType) {
|
|
const titles = {
|
|
'1': 'Daily Complete FG Orders Report',
|
|
'2': '5-Day Complete FG Orders Report',
|
|
'3': 'FG Items with Defects for Current Day',
|
|
'4': 'FG Items with Defects for Last 5 Days',
|
|
'5': 'Complete FG Database Report'
|
|
};
|
|
|
|
reportTitle.textContent = titles[reportType] || 'FG Quality Report';
|
|
}
|
|
|
|
// Function to update report title for date-based reports
|
|
function updateDateReportTitle(reportType, date, startDate, endDate) {
|
|
const titles = {
|
|
'6': `FG Daily Report for ${date}`,
|
|
'7': `FG Date Range Report (${startDate} to ${endDate})`,
|
|
'8': `FG Quality Defects Report for ${date}`,
|
|
'9': `FG Quality Defects Range Report (${startDate} to ${endDate})`
|
|
};
|
|
|
|
reportTitle.textContent = titles[reportType] || 'FG Quality Report';
|
|
}
|
|
|
|
// Calendar functionality
|
|
function showCalendarModal() {
|
|
if (calendarModal) {
|
|
calendarModal.style.display = 'block';
|
|
generateCalendar();
|
|
}
|
|
}
|
|
|
|
function hideCalendarModal() {
|
|
if (calendarModal) {
|
|
calendarModal.style.display = 'none';
|
|
selectedDate = null;
|
|
updateConfirmButton();
|
|
}
|
|
}
|
|
|
|
function showDateRangeModal() {
|
|
if (dateRangeModal) {
|
|
dateRangeModal.style.display = 'block';
|
|
const today = new Date().toISOString().split('T')[0];
|
|
document.getElementById('start-date').value = today;
|
|
document.getElementById('end-date').value = today;
|
|
}
|
|
}
|
|
|
|
function hideDataRangeModal() {
|
|
if (dateRangeModal) {
|
|
dateRangeModal.style.display = 'none';
|
|
}
|
|
}
|
|
|
|
function generateCalendar() {
|
|
const calendarDays = document.getElementById('calendar-days');
|
|
const monthYear = document.getElementById('calendar-month-year');
|
|
|
|
if (!calendarDays || !monthYear) return;
|
|
|
|
const year = currentDate.getFullYear();
|
|
const month = currentDate.getMonth();
|
|
|
|
monthYear.textContent = `${currentDate.toLocaleString('default', { month: 'long' })} ${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();
|
|
|
|
// Add empty cells for previous month
|
|
for (let i = 0; i < firstDay; i++) {
|
|
const emptyDay = document.createElement('div');
|
|
emptyDay.className = 'calendar-day empty';
|
|
calendarDays.appendChild(emptyDay);
|
|
}
|
|
|
|
// Add days of current month
|
|
for (let day = 1; day <= daysInMonth; day++) {
|
|
const dayElement = document.createElement('div');
|
|
dayElement.className = 'calendar-day';
|
|
dayElement.textContent = day;
|
|
|
|
// Check if it's today
|
|
const today = new Date();
|
|
if (year === today.getFullYear() && month === today.getMonth() && day === today.getDate()) {
|
|
dayElement.classList.add('today');
|
|
}
|
|
|
|
dayElement.addEventListener('click', () => {
|
|
// Remove previous selection
|
|
document.querySelectorAll('.calendar-day.selected').forEach(el => {
|
|
el.classList.remove('selected');
|
|
});
|
|
|
|
// Add selection to clicked day
|
|
dayElement.classList.add('selected');
|
|
|
|
// Set selected date
|
|
selectedDate = `${year}-${String(month + 1).padStart(2, '0')}-${String(day).padStart(2, '0')}`;
|
|
console.log('FG Calendar date selected:', selectedDate);
|
|
updateConfirmButton();
|
|
});
|
|
|
|
calendarDays.appendChild(dayElement);
|
|
}
|
|
}
|
|
|
|
function updateConfirmButton() {
|
|
const confirmButton = document.getElementById('confirm-date');
|
|
if (confirmButton) {
|
|
confirmButton.disabled = !selectedDate;
|
|
}
|
|
}
|
|
|
|
// Calendar navigation
|
|
const prevMonthBtn = document.getElementById('prev-month');
|
|
const nextMonthBtn = document.getElementById('next-month');
|
|
|
|
if (prevMonthBtn) {
|
|
// Clone to remove existing listeners
|
|
const newPrevBtn = prevMonthBtn.cloneNode(true);
|
|
prevMonthBtn.parentNode.replaceChild(newPrevBtn, prevMonthBtn);
|
|
|
|
newPrevBtn.addEventListener('click', (e) => {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
currentDate.setMonth(currentDate.getMonth() - 1);
|
|
generateCalendar();
|
|
});
|
|
}
|
|
|
|
if (nextMonthBtn) {
|
|
// Clone to remove existing listeners
|
|
const newNextBtn = nextMonthBtn.cloneNode(true);
|
|
nextMonthBtn.parentNode.replaceChild(newNextBtn, nextMonthBtn);
|
|
|
|
newNextBtn.addEventListener('click', (e) => {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
currentDate.setMonth(currentDate.getMonth() + 1);
|
|
generateCalendar();
|
|
});
|
|
}
|
|
|
|
// Calendar modal buttons
|
|
const cancelDateBtn = document.getElementById('cancel-date');
|
|
const confirmDateBtn = document.getElementById('confirm-date');
|
|
|
|
if (cancelDateBtn) {
|
|
// Clone to remove existing listeners
|
|
const newCancelBtn = cancelDateBtn.cloneNode(true);
|
|
cancelDateBtn.parentNode.replaceChild(newCancelBtn, cancelDateBtn);
|
|
|
|
newCancelBtn.addEventListener('click', (e) => {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
hideCalendarModal();
|
|
});
|
|
}
|
|
|
|
if (confirmDateBtn) {
|
|
// Clone to remove existing listeners
|
|
const newConfirmBtn = confirmDateBtn.cloneNode(true);
|
|
confirmDateBtn.parentNode.replaceChild(newConfirmBtn, confirmDateBtn);
|
|
|
|
newConfirmBtn.addEventListener('click', (e) => {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
console.log('FG Calendar confirm clicked with date:', selectedDate, 'report type:', currentReportType);
|
|
if (selectedDate && currentReportType) {
|
|
fetchFGDateReportData(currentReportType, selectedDate);
|
|
hideCalendarModal();
|
|
}
|
|
});
|
|
}
|
|
|
|
// Date range modal buttons
|
|
const cancelDateRangeBtn = document.getElementById('cancel-date-range');
|
|
const confirmDateRangeBtn = document.getElementById('confirm-date-range');
|
|
|
|
if (cancelDateRangeBtn) {
|
|
// Clone to remove existing listeners
|
|
const newCancelRangeBtn = cancelDateRangeBtn.cloneNode(true);
|
|
cancelDateRangeBtn.parentNode.replaceChild(newCancelRangeBtn, cancelDateRangeBtn);
|
|
|
|
newCancelRangeBtn.addEventListener('click', (e) => {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
hideDataRangeModal();
|
|
});
|
|
}
|
|
|
|
if (confirmDateRangeBtn) {
|
|
// Clone to remove existing listeners
|
|
const newConfirmRangeBtn = confirmDateRangeBtn.cloneNode(true);
|
|
confirmDateRangeBtn.parentNode.replaceChild(newConfirmRangeBtn, confirmDateRangeBtn);
|
|
|
|
newConfirmRangeBtn.addEventListener('click', (e) => {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
const startDate = document.getElementById('start-date').value;
|
|
const endDate = document.getElementById('end-date').value;
|
|
|
|
console.log('FG Date range confirm clicked:', startDate, 'to', endDate, 'report type:', currentReportType);
|
|
if (startDate && endDate && currentReportType) {
|
|
fetchFGDateReportData(currentReportType, null, startDate, endDate);
|
|
hideDataRangeModal();
|
|
}
|
|
});
|
|
}
|
|
|
|
// Enable/disable date range confirm button
|
|
const startDateInput = document.getElementById('start-date');
|
|
const endDateInput = document.getElementById('end-date');
|
|
|
|
function updateDateRangeConfirmButton() {
|
|
const confirmBtn = document.getElementById('confirm-date-range');
|
|
if (confirmBtn && startDateInput && endDateInput) {
|
|
confirmBtn.disabled = !startDateInput.value || !endDateInput.value;
|
|
}
|
|
}
|
|
|
|
if (startDateInput) {
|
|
startDateInput.addEventListener('change', updateDateRangeConfirmButton);
|
|
}
|
|
|
|
if (endDateInput) {
|
|
endDateInput.addEventListener('change', updateDateRangeConfirmButton);
|
|
}
|
|
|
|
// Close modals when clicking outside
|
|
window.addEventListener('click', (event) => {
|
|
if (event.target === calendarModal) {
|
|
hideCalendarModal();
|
|
}
|
|
if (event.target === dateRangeModal) {
|
|
hideDataRangeModal();
|
|
}
|
|
});
|
|
|
|
// Close modals with X button
|
|
document.querySelectorAll('.close-modal').forEach(closeBtn => {
|
|
// Clone to remove existing listeners
|
|
const newCloseBtn = closeBtn.cloneNode(true);
|
|
closeBtn.parentNode.replaceChild(newCloseBtn, closeBtn);
|
|
|
|
newCloseBtn.addEventListener('click', (event) => {
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
const modal = event.target.closest('.modal');
|
|
if (modal) {
|
|
modal.style.display = 'none';
|
|
}
|
|
});
|
|
});
|
|
|
|
// Export functionality
|
|
if (exportCsvButton) {
|
|
exportCsvButton.addEventListener('click', () => {
|
|
const rows = reportTable.querySelectorAll('tr');
|
|
if (rows.length === 0) {
|
|
alert('No FG data available to export.');
|
|
return;
|
|
}
|
|
const reportTitleText = reportTitle.textContent.trim();
|
|
const filename = `${reportTitleText.replace(/\s+/g, '_')}.csv`;
|
|
exportTableToCSV(filename);
|
|
});
|
|
}
|
|
|
|
// Export to CSV function
|
|
function exportTableToCSV(filename) {
|
|
const table = reportTable;
|
|
const rows = Array.from(table.querySelectorAll('tr'));
|
|
|
|
const csvContent = rows.map(row => {
|
|
const cells = Array.from(row.querySelectorAll('th, td'));
|
|
return cells.map(cell => {
|
|
let text = cell.textContent.trim();
|
|
// Escape quotes and wrap in quotes if necessary
|
|
if (text.includes(',') || text.includes('"') || text.includes('\n')) {
|
|
text = '"' + text.replace(/"/g, '""') + '"';
|
|
}
|
|
return text;
|
|
}).join(',');
|
|
}).join('\n');
|
|
|
|
const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
|
|
const link = document.createElement('a');
|
|
const url = URL.createObjectURL(blob);
|
|
link.setAttribute('href', url);
|
|
link.setAttribute('download', filename);
|
|
link.style.visibility = 'hidden';
|
|
document.body.appendChild(link);
|
|
link.click();
|
|
document.body.removeChild(link);
|
|
}
|
|
|
|
// Test Database Button
|
|
const testDatabaseBtn = document.getElementById('test-database');
|
|
if (testDatabaseBtn) {
|
|
testDatabaseBtn.addEventListener('click', () => {
|
|
console.log('Testing FG database connection...');
|
|
reportTitle.textContent = 'Testing FG Database Connection...';
|
|
fetch('/test_fg_database')
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
console.log('FG Database test results:', data);
|
|
if (data.success) {
|
|
reportTitle.textContent = `FG Database Test Results - ${data.total_records} records found`;
|
|
// Show alert with summary
|
|
alert(`FG Database Test Complete!\n\nConnection: ${data.database_connection}\nTable exists: ${data.table_exists}\nTotal records: ${data.total_records}\nMessage: ${data.message}`);
|
|
} else {
|
|
reportTitle.textContent = 'FG Database Test Failed';
|
|
alert(`FG Database test failed: ${data.message}`);
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('FG Database test error:', error);
|
|
reportTitle.textContent = 'Error testing FG database.';
|
|
alert('Error testing FG database connection.');
|
|
});
|
|
});
|
|
}
|
|
|
|
console.log('FG Quality JavaScript setup complete');
|
|
}); |