447 lines
18 KiB
HTML
447 lines
18 KiB
HTML
{% extends "base.html" %}
|
|
|
|
{% block title %}Daily Mirror - Quality Recticel{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="container-fluid">
|
|
<!-- Page Header -->
|
|
<div class="row mb-4">
|
|
<div class="col-12">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<h1 class="h3 mb-0">📈 Daily Mirror</h1>
|
|
<p class="text-muted">Generate comprehensive daily production reports</p>
|
|
</div>
|
|
<div>
|
|
<a href="{{ url_for('daily_mirror.daily_mirror_history_route') }}" class="btn btn-outline-primary">
|
|
<i class="fas fa-history"></i> View History
|
|
</a>
|
|
<a href="{{ url_for('main.dashboard') }}" class="btn btn-secondary">
|
|
<i class="fas fa-arrow-left"></i> Back to Dashboard
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Date Selection Card -->
|
|
<div class="row mb-4">
|
|
<div class="col-12">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="card-title mb-0">
|
|
<i class="fas fa-calendar-alt"></i> Select Report Date
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="row">
|
|
<div class="col-md-4">
|
|
<label for="reportDate" class="form-label">Report Date:</label>
|
|
<input type="date" class="form-control" id="reportDate" value="{{ today }}">
|
|
</div>
|
|
<div class="col-md-4 d-flex align-items-end">
|
|
<button type="button" class="btn btn-primary" onclick="generateDailyReport()">
|
|
<i class="fas fa-chart-line"></i> Generate Report
|
|
</button>
|
|
</div>
|
|
<div class="col-md-4 d-flex align-items-end">
|
|
<button type="button" class="btn btn-success" onclick="setTodayDate()">
|
|
<i class="fas fa-calendar-day"></i> Today's Report
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Loading Indicator -->
|
|
<div id="loadingIndicator" class="row mb-4" style="display: none;">
|
|
<div class="col-12">
|
|
<div class="card">
|
|
<div class="card-body text-center">
|
|
<div class="spinner-border text-primary" role="status">
|
|
<span class="visually-hidden">Loading...</span>
|
|
</div>
|
|
<p class="mt-2 mb-0">Generating daily report...</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Daily Report Results -->
|
|
<div id="reportResults" style="display: none;">
|
|
<!-- Key Metrics Overview -->
|
|
<div class="row mb-4">
|
|
<div class="col-12">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="card-title mb-0">
|
|
<i class="fas fa-tachometer-alt"></i> Daily Production Overview
|
|
<span id="reportDateDisplay" class="badge bg-primary ms-2"></span>
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="row">
|
|
<div class="col-md-3">
|
|
<div class="metric-card orders-quantity">
|
|
<div class="metric-icon">
|
|
<i class="fas fa-clipboard-list"></i>
|
|
</div>
|
|
<div class="metric-content">
|
|
<h3 id="ordersQuantity">-</h3>
|
|
<p>Orders Quantity</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<div class="metric-card production-launched">
|
|
<div class="metric-icon">
|
|
<i class="fas fa-play-circle"></i>
|
|
</div>
|
|
<div class="metric-content">
|
|
<h3 id="productionLaunched">-</h3>
|
|
<p>Production Launched</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<div class="metric-card production-finished">
|
|
<div class="metric-icon">
|
|
<i class="fas fa-check-circle"></i>
|
|
</div>
|
|
<div class="metric-content">
|
|
<h3 id="productionFinished">-</h3>
|
|
<p>Production Finished</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<div class="metric-card orders-delivered">
|
|
<div class="metric-icon">
|
|
<i class="fas fa-truck"></i>
|
|
</div>
|
|
<div class="metric-content">
|
|
<h3 id="ordersDelivered">-</h3>
|
|
<p>Orders Delivered</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Quality Control Metrics -->
|
|
<div class="row mb-4">
|
|
<div class="col-md-6">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="card-title mb-0">
|
|
<i class="fas fa-search"></i> Quality Control Scans
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="quality-stats">
|
|
<div class="row">
|
|
<div class="col-4">
|
|
<div class="stat-item">
|
|
<h4 id="qualityTotalScans">-</h4>
|
|
<p>Total Scans</p>
|
|
</div>
|
|
</div>
|
|
<div class="col-4">
|
|
<div class="stat-item approved">
|
|
<h4 id="qualityApprovedScans">-</h4>
|
|
<p>Approved</p>
|
|
</div>
|
|
</div>
|
|
<div class="col-4">
|
|
<div class="stat-item rejected">
|
|
<h4 id="qualityRejectedScans">-</h4>
|
|
<p>Rejected</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="mt-3">
|
|
<div class="progress">
|
|
<div id="qualityApprovalBar" class="progress-bar bg-success" role="progressbar" style="width: 0%"></div>
|
|
</div>
|
|
<p class="text-center mt-2 mb-0">
|
|
Approval Rate: <span id="qualityApprovalRate" class="fw-bold">0%</span>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="card-title mb-0">
|
|
<i class="fas fa-clipboard-check"></i> Finish Goods Quality
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="quality-stats">
|
|
<div class="row">
|
|
<div class="col-4">
|
|
<div class="stat-item">
|
|
<h4 id="fgQualityTotalScans">-</h4>
|
|
<p>Total Scans</p>
|
|
</div>
|
|
</div>
|
|
<div class="col-4">
|
|
<div class="stat-item approved">
|
|
<h4 id="fgQualityApprovedScans">-</h4>
|
|
<p>Approved</p>
|
|
</div>
|
|
</div>
|
|
<div class="col-4">
|
|
<div class="stat-item rejected">
|
|
<h4 id="fgQualityRejectedScans">-</h4>
|
|
<p>Rejected</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="mt-3">
|
|
<div class="progress">
|
|
<div id="fgQualityApprovalBar" class="progress-bar bg-success" role="progressbar" style="width: 0%"></div>
|
|
</div>
|
|
<p class="text-center mt-2 mb-0">
|
|
Approval Rate: <span id="fgQualityApprovalRate" class="fw-bold">0%</span>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Export and Actions -->
|
|
<div class="row mb-4">
|
|
<div class="col-12">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="card-title mb-0">
|
|
<i class="fas fa-download"></i> Export Options
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="btn-group" role="group">
|
|
<button type="button" class="btn btn-outline-success" onclick="exportReportPDF()">
|
|
<i class="fas fa-file-pdf"></i> Export PDF
|
|
</button>
|
|
<button type="button" class="btn btn-outline-primary" onclick="exportReportExcel()">
|
|
<i class="fas fa-file-excel"></i> Export Excel
|
|
</button>
|
|
<button type="button" class="btn btn-outline-info" onclick="printReport()">
|
|
<i class="fas fa-print"></i> Print Report
|
|
</button>
|
|
<button type="button" class="btn btn-outline-secondary" onclick="shareReport()">
|
|
<i class="fas fa-share"></i> Share Report
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Error Message -->
|
|
<div id="errorMessage" class="row mb-4" style="display: none;">
|
|
<div class="col-12">
|
|
<div class="alert alert-danger" role="alert">
|
|
<i class="fas fa-exclamation-triangle"></i>
|
|
<strong>Error:</strong> <span id="errorText"></span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<style>
|
|
.metric-card {
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 1.5rem;
|
|
background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
|
|
border-radius: 10px;
|
|
margin-bottom: 1rem;
|
|
transition: transform 0.2s ease;
|
|
}
|
|
|
|
.metric-card:hover {
|
|
transform: translateY(-2px);
|
|
}
|
|
|
|
.metric-card.orders-quantity {
|
|
background: linear-gradient(135deg, #e3f2fd 0%, #bbdefb 100%);
|
|
}
|
|
|
|
.metric-card.production-launched {
|
|
background: linear-gradient(135deg, #f3e5f5 0%, #ce93d8 100%);
|
|
}
|
|
|
|
.metric-card.production-finished {
|
|
background: linear-gradient(135deg, #e8f5e8 0%, #a5d6a7 100%);
|
|
}
|
|
|
|
.metric-card.orders-delivered {
|
|
background: linear-gradient(135deg, #fff3e0 0%, #ffcc02 100%);
|
|
}
|
|
|
|
.metric-icon {
|
|
font-size: 2.5rem;
|
|
margin-right: 1rem;
|
|
opacity: 0.8;
|
|
}
|
|
|
|
.metric-content h3 {
|
|
font-size: 2rem;
|
|
font-weight: bold;
|
|
margin: 0;
|
|
color: #2c3e50;
|
|
}
|
|
|
|
.metric-content p {
|
|
margin: 0;
|
|
color: #6c757d;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.quality-stats .stat-item {
|
|
text-align: center;
|
|
padding: 1rem 0;
|
|
}
|
|
|
|
.quality-stats .stat-item h4 {
|
|
font-size: 1.5rem;
|
|
font-weight: bold;
|
|
margin: 0;
|
|
color: #2c3e50;
|
|
}
|
|
|
|
.quality-stats .stat-item.approved h4 {
|
|
color: #28a745;
|
|
}
|
|
|
|
.quality-stats .stat-item.rejected h4 {
|
|
color: #dc3545;
|
|
}
|
|
|
|
.quality-stats .stat-item p {
|
|
margin: 0;
|
|
color: #6c757d;
|
|
font-size: 0.9rem;
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.metric-card {
|
|
flex-direction: column;
|
|
text-align: center;
|
|
}
|
|
|
|
.metric-icon {
|
|
margin-right: 0;
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
}
|
|
</style>
|
|
|
|
<script>
|
|
function setTodayDate() {
|
|
const today = new Date().toISOString().split('T')[0];
|
|
document.getElementById('reportDate').value = today;
|
|
generateDailyReport();
|
|
}
|
|
|
|
function generateDailyReport() {
|
|
const reportDate = document.getElementById('reportDate').value;
|
|
|
|
if (!reportDate) {
|
|
showError('Please select a report date');
|
|
return;
|
|
}
|
|
|
|
// Show loading indicator
|
|
document.getElementById('loadingIndicator').style.display = 'block';
|
|
document.getElementById('reportResults').style.display = 'none';
|
|
document.getElementById('errorMessage').style.display = 'none';
|
|
|
|
// Make API call to get daily data
|
|
fetch(`/daily_mirror/api/data?date=${reportDate}`)
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.error) {
|
|
showError(data.error);
|
|
return;
|
|
}
|
|
|
|
// Update display with data
|
|
updateDailyReport(data);
|
|
|
|
// Hide loading and show results
|
|
document.getElementById('loadingIndicator').style.display = 'none';
|
|
document.getElementById('reportResults').style.display = 'block';
|
|
})
|
|
.catch(error => {
|
|
console.error('Error generating daily report:', error);
|
|
showError('Failed to generate daily report. Please try again.');
|
|
});
|
|
}
|
|
|
|
function updateDailyReport(data) {
|
|
// Update date display
|
|
document.getElementById('reportDateDisplay').textContent = data.date;
|
|
|
|
// Update key metrics
|
|
document.getElementById('ordersQuantity').textContent = data.orders_quantity.toLocaleString();
|
|
document.getElementById('productionLaunched').textContent = data.production_launched.toLocaleString();
|
|
document.getElementById('productionFinished').textContent = data.production_finished.toLocaleString();
|
|
document.getElementById('ordersDelivered').textContent = data.orders_delivered.toLocaleString();
|
|
|
|
// Update quality control data
|
|
document.getElementById('qualityTotalScans').textContent = data.quality_scans.total_scans.toLocaleString();
|
|
document.getElementById('qualityApprovedScans').textContent = data.quality_scans.approved_scans.toLocaleString();
|
|
document.getElementById('qualityRejectedScans').textContent = data.quality_scans.rejected_scans.toLocaleString();
|
|
document.getElementById('qualityApprovalRate').textContent = data.quality_scans.approval_rate + '%';
|
|
document.getElementById('qualityApprovalBar').style.width = data.quality_scans.approval_rate + '%';
|
|
|
|
// Update FG quality data
|
|
document.getElementById('fgQualityTotalScans').textContent = data.fg_quality_scans.total_scans.toLocaleString();
|
|
document.getElementById('fgQualityApprovedScans').textContent = data.fg_quality_scans.approved_scans.toLocaleString();
|
|
document.getElementById('fgQualityRejectedScans').textContent = data.fg_quality_scans.rejected_scans.toLocaleString();
|
|
document.getElementById('fgQualityApprovalRate').textContent = data.fg_quality_scans.approval_rate + '%';
|
|
document.getElementById('fgQualityApprovalBar').style.width = data.fg_quality_scans.approval_rate + '%';
|
|
}
|
|
|
|
function showError(message) {
|
|
document.getElementById('errorText').textContent = message;
|
|
document.getElementById('errorMessage').style.display = 'block';
|
|
document.getElementById('loadingIndicator').style.display = 'none';
|
|
document.getElementById('reportResults').style.display = 'none';
|
|
}
|
|
|
|
function exportReportPDF() {
|
|
alert('PDF export functionality will be implemented soon.');
|
|
}
|
|
|
|
function exportReportExcel() {
|
|
alert('Excel export functionality will be implemented soon.');
|
|
}
|
|
|
|
function printReport() {
|
|
window.print();
|
|
}
|
|
|
|
function shareReport() {
|
|
alert('Share functionality will be implemented soon.');
|
|
}
|
|
|
|
// Auto-generate today's report on page load
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
generateDailyReport();
|
|
});
|
|
</script>
|
|
{% endblock %} |