starting daily mirror

This commit is contained in:
Quality System Admin
2025-10-25 02:15:54 +03:00
parent 1afd09b88b
commit 87469ecb8e
23 changed files with 5849 additions and 14 deletions

View File

@@ -0,0 +1,447 @@
{% 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 %}