440 lines
20 KiB
HTML
440 lines
20 KiB
HTML
{% extends "base.html" %}
|
|
{% block title %}FG Quality Module{% endblock %}
|
|
{% block content %}
|
|
<div class="scan-container">
|
|
<!-- Reports Card -->
|
|
<div class="card report-form-card">
|
|
<h3>FG Quality Reports</h3>
|
|
|
|
<!-- Reports List with Label-Button Layout -->
|
|
<div class="reports-grid">
|
|
<div class="form-centered">
|
|
<label class="report-description">Daily report will export all FG orders scanned at quality scanning points</label>
|
|
<button class="btn report-btn" data-report="1">Daily Complete FG Orders Report</button>
|
|
</div>
|
|
<div class="form-centered">
|
|
<label class="report-description">Select day for daily FG report will export all orders scanned at quality scanning points</label>
|
|
<button class="btn report-btn" id="select-day-report">Select Day Daily FG Report</button>
|
|
</div>
|
|
<div class="form-centered">
|
|
<label class="report-description">Select date range for custom FG report - from start date 00:00 to end date 23:59</label>
|
|
<button class="btn report-btn" id="date-range-report">Date Range FG Report</button>
|
|
</div>
|
|
<div class="form-centered">
|
|
<label class="report-description">5-day report will export all FG orders scanned at quality scanning points</label>
|
|
<button class="btn report-btn" data-report="2">5-Day Complete FG Orders Report</button>
|
|
</div>
|
|
<div class="form-centered">
|
|
<label class="report-description">Report on FG items with quality issues for the current day</label>
|
|
<button class="btn report-btn" data-report="3">Report on FG Items with Defects for the Current Day</button>
|
|
</div>
|
|
<div class="form-centered">
|
|
<label class="report-description">Select specific day for FG quality defects report - items with quality issues</label>
|
|
<button class="btn report-btn" id="select-day-defects-report">Select Day FG Quality Defects Report</button>
|
|
</div>
|
|
<div class="form-centered">
|
|
<label class="report-description">Select date range for FG quality defects report - items with quality issues between two dates</label>
|
|
<button class="btn report-btn" id="date-range-defects-report">Date Range FG Quality Defects Report</button>
|
|
</div>
|
|
<div class="form-centered">
|
|
<label class="report-description">Report on FG items with quality issues for the last 5 days</label>
|
|
<button class="btn report-btn" data-report="4">Report on FG Items with Defects for the Last 5 Days</button>
|
|
</div>
|
|
<div class="form-centered">
|
|
<label class="report-description">Report all FG entries from the database</label>
|
|
<button class="btn report-btn" data-report="5">Report FG Database</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Separator -->
|
|
<div class="report-separator"></div>
|
|
|
|
<!-- Export Section -->
|
|
<div class="export-section">
|
|
<div class="form-centered last-buttons">
|
|
<label class="export-description">Export current report as:</label>
|
|
<div class="button-row">
|
|
<button class="btn export-btn" id="export-csv">Export CSV</button>
|
|
<!-- <button class="btn export-btn" id="export-excel">Export excell</button> -->
|
|
{% if session.get('role') == 'superadmin' %}
|
|
<button class="btn export-btn test-db-btn" id="test-database">Test FG Database</button>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Data Display Card -->
|
|
<div class="card report-table-card">
|
|
<h3 id="report-title">No data to display, please select a report.</h3>
|
|
<div class="report-table-container">
|
|
<table class="scan-table" id="report-table">
|
|
<thead>
|
|
<tr>
|
|
<!-- Table headers will be dynamically populated -->
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<!-- Table data will be dynamically populated -->
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Calendar Popup Modal -->
|
|
<div id="calendar-modal" class="modal">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h4>Select Date for Daily FG Report</h4>
|
|
<span class="close-modal">×</span>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div class="calendar-container">
|
|
<div class="calendar-header">
|
|
<button id="prev-month" class="calendar-nav"><</button>
|
|
<h3 id="calendar-month-year"></h3>
|
|
<button id="next-month" class="calendar-nav">></button>
|
|
</div>
|
|
<div class="calendar-grid">
|
|
<div class="calendar-weekdays">
|
|
<div>Sun</div>
|
|
<div>Mon</div>
|
|
<div>Tue</div>
|
|
<div>Wed</div>
|
|
<div>Thu</div>
|
|
<div>Fri</div>
|
|
<div>Sat</div>
|
|
</div>
|
|
<div class="calendar-days" id="calendar-days">
|
|
<!-- Days will be populated by JavaScript -->
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button class="btn btn-secondary" id="cancel-date">Cancel</button>
|
|
<button class="btn btn-primary" id="confirm-date" disabled>Generate Report</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Date Range Popup Modal -->
|
|
<div id="date-range-modal" class="modal">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h4>Select Date Range for FG Report</h4>
|
|
<span class="close-modal" id="close-date-range">×</span>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div class="date-range-container">
|
|
<div class="date-input-group">
|
|
<label for="start-date">Start Date:</label>
|
|
<input type="date" id="start-date" class="date-input" />
|
|
<small class="date-help">Report will include data from 00:00:00</small>
|
|
</div>
|
|
<div class="date-input-group">
|
|
<label for="end-date">End Date:</label>
|
|
<input type="date" id="end-date" class="date-input" />
|
|
<small class="date-help">Report will include data until 23:59:59</small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button class="btn btn-secondary" id="cancel-date-range">Cancel</button>
|
|
<button class="btn btn-primary" id="confirm-date-range" disabled>Generate Report</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{% endblock %}
|
|
|
|
{% block head %}
|
|
<script>
|
|
// Debug check - this will run immediately when the page loads
|
|
console.log('FG Quality page loaded - checking script conflicts');
|
|
window.addEventListener('DOMContentLoaded', function() {
|
|
console.log('FG Quality DOM loaded');
|
|
// Add a visible indicator that our script loaded
|
|
setTimeout(() => {
|
|
const titleElement = document.getElementById('report-title');
|
|
if (titleElement && titleElement.textContent === 'No data to display, please select a report.') {
|
|
titleElement.textContent = '🟢 FG Quality Module Ready - Select a report';
|
|
}
|
|
}, 100);
|
|
});
|
|
</script>
|
|
<script src="{{ url_for('static', filename='fg_quality.js') }}"></script>
|
|
<script>
|
|
// Theme functionality for FG Quality page
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
const body = document.body;
|
|
const themeToggleButton = document.getElementById('theme-toggle');
|
|
|
|
// 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
|
|
if (themeToggleButton) {
|
|
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
|
|
});
|
|
}
|
|
});
|
|
|
|
// Override script - runs after both script.js and fg_quality.js
|
|
window.addEventListener('DOMContentLoaded', function() {
|
|
// Wait a bit to ensure all scripts have loaded
|
|
setTimeout(() => {
|
|
console.log('🔧 FG Quality Override Script - Fixing event handlers');
|
|
|
|
// Override the problematic calendar functionality
|
|
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 currentFGReportType = null;
|
|
let selectedFGDate = null;
|
|
|
|
// Clear and re-add event listeners with FG-specific functionality
|
|
if (selectDayReport) {
|
|
// Remove all existing listeners by cloning
|
|
const newSelectDayReport = selectDayReport.cloneNode(true);
|
|
selectDayReport.parentNode.replaceChild(newSelectDayReport, selectDayReport);
|
|
|
|
newSelectDayReport.addEventListener('click', function(e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
console.log('🎯 FG Select Day Report clicked');
|
|
currentFGReportType = '6';
|
|
showFGCalendarModal();
|
|
});
|
|
}
|
|
|
|
if (dateRangeReport) {
|
|
const newDateRangeReport = dateRangeReport.cloneNode(true);
|
|
dateRangeReport.parentNode.replaceChild(newDateRangeReport, dateRangeReport);
|
|
|
|
newDateRangeReport.addEventListener('click', function(e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
console.log('🎯 FG Date Range Report clicked');
|
|
currentFGReportType = '7';
|
|
showFGDateRangeModal();
|
|
});
|
|
}
|
|
|
|
// FG-specific calendar modal functionality
|
|
function showFGCalendarModal() {
|
|
const calendarModal = document.getElementById('calendar-modal');
|
|
if (calendarModal) {
|
|
calendarModal.style.display = 'block';
|
|
generateFGCalendar();
|
|
}
|
|
}
|
|
|
|
function showFGDateRangeModal() {
|
|
const dateRangeModal = document.getElementById('date-range-modal');
|
|
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 generateFGCalendar() {
|
|
const calendarDays = document.getElementById('calendar-days');
|
|
const monthYear = document.getElementById('calendar-month-year');
|
|
|
|
if (!calendarDays || !monthYear) return;
|
|
|
|
const currentDate = new Date();
|
|
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;
|
|
|
|
// Highlight October 15 as it has FG data
|
|
if (month === 9 && day === 15) { // October is month 9
|
|
dayElement.style.backgroundColor = '#e3f2fd';
|
|
dayElement.style.border = '2px solid #2196f3';
|
|
dayElement.title = 'FG data available';
|
|
}
|
|
|
|
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
|
|
selectedFGDate = `${year}-${String(month + 1).padStart(2, '0')}-${String(day).padStart(2, '0')}`;
|
|
console.log('🗓️ FG Calendar date selected:', selectedFGDate);
|
|
|
|
// Enable confirm button
|
|
const confirmButton = document.getElementById('confirm-date');
|
|
if (confirmButton) {
|
|
confirmButton.disabled = false;
|
|
}
|
|
});
|
|
|
|
calendarDays.appendChild(dayElement);
|
|
}
|
|
}
|
|
|
|
// Override confirm button
|
|
const confirmDateBtn = document.getElementById('confirm-date');
|
|
if (confirmDateBtn) {
|
|
const newConfirmBtn = confirmDateBtn.cloneNode(true);
|
|
confirmDateBtn.parentNode.replaceChild(newConfirmBtn, confirmDateBtn);
|
|
|
|
newConfirmBtn.addEventListener('click', function(e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
console.log('✅ FG Calendar confirm clicked:', selectedFGDate, 'Report type:', currentFGReportType);
|
|
|
|
if (selectedFGDate && currentFGReportType) {
|
|
const url = `/generate_fg_report?report=${currentFGReportType}&date=${selectedFGDate}`;
|
|
console.log('🚀 Calling FG endpoint:', url);
|
|
|
|
document.getElementById('report-title').textContent = 'Loading FG data...';
|
|
|
|
fetch(url)
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
console.log('📊 FG Data received:', data);
|
|
|
|
const table = document.getElementById('report-table');
|
|
const thead = table.querySelector('thead tr');
|
|
const tbody = table.querySelector('tbody');
|
|
|
|
// Clear existing content
|
|
thead.innerHTML = '';
|
|
tbody.innerHTML = '';
|
|
|
|
// Add headers
|
|
if (data.headers) {
|
|
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);
|
|
});
|
|
document.getElementById('report-title').textContent = `FG Daily Report for ${selectedFGDate} (${data.rows.length} records)`;
|
|
} else {
|
|
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';
|
|
td.style.textAlign = 'center';
|
|
tr.appendChild(td);
|
|
tbody.appendChild(tr);
|
|
document.getElementById('report-title').textContent = `FG Daily Report for ${selectedFGDate} - No data`;
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('❌ Error fetching FG data:', error);
|
|
document.getElementById('report-title').textContent = 'Error loading FG data';
|
|
});
|
|
|
|
// Hide modal
|
|
document.getElementById('calendar-modal').style.display = 'none';
|
|
}
|
|
});
|
|
}
|
|
|
|
// Override date range confirm button
|
|
const confirmDateRangeBtn = document.getElementById('confirm-date-range');
|
|
if (confirmDateRangeBtn) {
|
|
const newConfirmRangeBtn = confirmDateRangeBtn.cloneNode(true);
|
|
confirmDateRangeBtn.parentNode.replaceChild(newConfirmRangeBtn, confirmDateRangeBtn);
|
|
|
|
newConfirmRangeBtn.addEventListener('click', function(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:', startDate, 'to', endDate);
|
|
|
|
if (startDate && endDate && currentFGReportType) {
|
|
const url = `/generate_fg_report?report=${currentFGReportType}&start_date=${startDate}&end_date=${endDate}`;
|
|
console.log('🚀 Calling FG range endpoint:', url);
|
|
|
|
fetch(url)
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
console.log('📊 FG Range data received:', data);
|
|
// Handle response similar to above
|
|
document.getElementById('report-title').textContent = `FG Date Range Report (${startDate} to ${endDate})`;
|
|
})
|
|
.catch(error => {
|
|
console.error('❌ Error fetching FG range data:', error);
|
|
});
|
|
|
|
// Hide modal
|
|
document.getElementById('date-range-modal').style.display = 'none';
|
|
}
|
|
});
|
|
}
|
|
|
|
console.log('✅ FG Quality Override Script - Event handlers fixed');
|
|
}, 500); // Wait 500ms to ensure all other scripts are loaded
|
|
});
|
|
</script>
|
|
{% endblock %} |