updated control access
This commit is contained in:
539
py_app/app/static/fg_quality.js
Normal file
539
py_app/app/static/fg_quality.js
Normal file
@@ -0,0 +1,539 @@
|
||||
// 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');
|
||||
});
|
||||
Reference in New Issue
Block a user