Marwan Alwali 35be20ae4c update
2025-09-06 19:07:14 +03:00

634 lines
23 KiB
HTML

{% extends 'base.html' %}
{% load static %}
{% block title %}Blood Bank Reports{% endblock %}
{% block css %}
<link href="{% static 'plugins/chart.js/dist/Chart.min.css' %}" rel="stylesheet" />
<link href="{% static 'plugins/bootstrap-datepicker/dist/css/bootstrap-datepicker.min.css' %}" rel="stylesheet" />
<style>
.report-card {
border-radius: 10px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
transition: transform 0.3s ease;
cursor: pointer;
}
.report-card:hover {
transform: translateY(-5px);
}
.report-icon {
font-size: 3rem;
margin-bottom: 1rem;
}
.chart-container {
position: relative;
height: 400px;
}
.kpi-card {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border-radius: 10px;
padding: 20px;
margin-bottom: 20px;
}
.metric-value {
font-size: 2.5rem;
font-weight: bold;
margin-bottom: 0.5rem;
}
.metric-label {
font-size: 0.9rem;
opacity: 0.9;
}
.trend-up {
color: #28a745;
}
.trend-down {
color: #dc3545;
}
.trend-stable {
color: #6c757d;
}
</style>
{% endblock %}
{% block content %}
<!-- BEGIN breadcrumb -->
<ol class="breadcrumb float-xl-end">
<li class="breadcrumb-item"><a href="{% url 'core:dashboard' %}">Home</a></li>
<li class="breadcrumb-item"><a href="{% url 'blood_bank:dashboard' %}">Blood Bank</a></li>
<li class="breadcrumb-item active">Reports</li>
</ol>
<!-- END breadcrumb -->
<!-- BEGIN page-header -->
<h1 class="page-header">Blood Bank Reports <small>comprehensive analytics and reporting</small></h1>
<!-- END page-header -->
<!-- BEGIN KPI overview -->
<div class="row mb-4">
<div class="col-xl-3 col-md-6">
<div class="kpi-card">
<div class="d-flex justify-content-between align-items-center">
<div>
<div class="metric-value">{{ total_donations_month }}</div>
<div class="metric-label">Donations This Month</div>
<div class="mt-2">
<i class="fa fa-arrow-up trend-up"></i>
<span class="trend-up">+12% vs last month</span>
</div>
</div>
<div>
<i class="fa fa-tint fa-3x opacity-75"></i>
</div>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6">
<div class="kpi-card">
<div class="d-flex justify-content-between align-items-center">
<div>
<div class="metric-value">{{ total_transfusions_month }}</div>
<div class="metric-label">Transfusions This Month</div>
<div class="mt-2">
<i class="fa fa-arrow-up trend-up"></i>
<span class="trend-up">+8% vs last month</span>
</div>
</div>
<div>
<i class="fa fa-heartbeat fa-3x opacity-75"></i>
</div>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6">
<div class="kpi-card">
<div class="d-flex justify-content-between align-items-center">
<div>
<div class="metric-value">{{ inventory_turnover }}%</div>
<div class="metric-label">Inventory Turnover</div>
<div class="mt-2">
<i class="fa fa-minus trend-stable"></i>
<span class="trend-stable">Stable</span>
</div>
</div>
<div>
<i class="fa fa-sync-alt fa-3x opacity-75"></i>
</div>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6">
<div class="kpi-card">
<div class="d-flex justify-content-between align-items-center">
<div>
<div class="metric-value">{{ wastage_rate }}%</div>
<div class="metric-label">Wastage Rate</div>
<div class="mt-2">
<i class="fa fa-arrow-down trend-up"></i>
<span class="trend-up">-3% vs last month</span>
</div>
</div>
<div>
<i class="fa fa-exclamation-triangle fa-3x opacity-75"></i>
</div>
</div>
</div>
</div>
</div>
<!-- END KPI overview -->
<!-- BEGIN report categories -->
<div class="row mb-4">
<div class="col-12">
<div class="panel panel-inverse">
<div class="panel-heading">
<h4 class="panel-title">Report Categories</h4>
</div>
<div class="panel-body">
<div class="row">
<div class="col-xl-3 col-md-6 mb-3">
<div class="report-card card text-center p-4" onclick="generateReport('inventory')">
<div class="report-icon text-primary">
<i class="fa fa-boxes"></i>
</div>
<h5>Inventory Reports</h5>
<p class="text-muted">Stock levels, expiry tracking, location analysis</p>
</div>
</div>
<div class="col-xl-3 col-md-6 mb-3">
<div class="report-card card text-center p-4" onclick="generateReport('donation')">
<div class="report-icon text-success">
<i class="fa fa-user-plus"></i>
</div>
<h5>Donation Reports</h5>
<p class="text-muted">Donor statistics, collection trends, demographics</p>
</div>
</div>
<div class="col-xl-3 col-md-6 mb-3">
<div class="report-card card text-center p-4" onclick="generateReport('transfusion')">
<div class="report-icon text-info">
<i class="fa fa-heartbeat"></i>
</div>
<h5>Transfusion Reports</h5>
<p class="text-muted">Usage patterns, patient outcomes, safety metrics</p>
</div>
</div>
<div class="col-xl-3 col-md-6 mb-3">
<div class="report-card card text-center p-4" onclick="generateReport('quality')">
<div class="report-icon text-warning">
<i class="fa fa-shield-alt"></i>
</div>
<h5>Quality Reports</h5>
<p class="text-muted">QC results, compliance metrics, CAPA tracking</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- END report categories -->
<!-- BEGIN analytics dashboard -->
<div class="row">
<!-- BEGIN col-8 -->
<div class="col-xl-8">
<!-- BEGIN donation trends -->
<div class="panel panel-inverse">
<div class="panel-heading">
<h4 class="panel-title">Donation Trends</h4>
<div class="panel-heading-btn">
<select class="form-select form-select-sm" id="donationPeriod" onchange="updateDonationChart()">
<option value="7">Last 7 Days</option>
<option value="30">Last 30 Days</option>
<option value="90">Last 3 Months</option>
<option value="365">Last Year</option>
</select>
</div>
</div>
<div class="panel-body">
<div class="chart-container">
<canvas id="donationTrendChart"></canvas>
</div>
</div>
</div>
<!-- END donation trends -->
<!-- BEGIN blood group distribution -->
<div class="panel panel-inverse">
<div class="panel-heading">
<h4 class="panel-title">Blood Group Distribution</h4>
</div>
<div class="panel-body">
<div class="row">
<div class="col-md-6">
<h6 class="text-center">Donations</h6>
<div class="chart-container" style="height: 300px;">
<canvas id="donationBloodGroupChart"></canvas>
</div>
</div>
<div class="col-md-6">
<h6 class="text-center">Transfusions</h6>
<div class="chart-container" style="height: 300px;">
<canvas id="transfusionBloodGroupChart"></canvas>
</div>
</div>
</div>
</div>
</div>
<!-- END blood group distribution -->
<!-- BEGIN utilization metrics -->
<div class="panel panel-inverse">
<div class="panel-heading">
<h4 class="panel-title">Utilization Metrics</h4>
</div>
<div class="panel-body">
<div class="chart-container">
<canvas id="utilizationChart"></canvas>
</div>
</div>
</div>
<!-- END utilization metrics -->
</div>
<!-- END col-8 -->
<!-- BEGIN col-4 -->
<div class="col-xl-4">
<!-- BEGIN quick reports -->
<div class="panel panel-inverse">
<div class="panel-heading">
<h4 class="panel-title">Quick Reports</h4>
</div>
<div class="panel-body">
<div class="d-grid gap-2">
<button type="button" class="btn btn-outline-primary" onclick="generateQuickReport('daily')">
<i class="fa fa-calendar-day"></i> Daily Summary
</button>
<button type="button" class="btn btn-outline-success" onclick="generateQuickReport('weekly')">
<i class="fa fa-calendar-week"></i> Weekly Report
</button>
<button type="button" class="btn btn-outline-info" onclick="generateQuickReport('monthly')">
<i class="fa fa-calendar-alt"></i> Monthly Report
</button>
<button type="button" class="btn btn-outline-warning" onclick="generateQuickReport('expiry')">
<i class="fa fa-exclamation-triangle"></i> Expiry Alert
</button>
<button type="button" class="btn btn-outline-danger" onclick="generateQuickReport('critical')">
<i class="fa fa-exclamation-circle"></i> Critical Levels
</button>
</div>
</div>
</div>
<!-- END quick reports -->
<!-- BEGIN top donors -->
<div class="panel panel-inverse">
<div class="panel-heading">
<h4 class="panel-title">Top Donors This Month</h4>
</div>
<div class="panel-body">
{% for donor in top_donors %}
<div class="d-flex justify-content-between align-items-center mb-3">
<div>
<strong>{{ donor.full_name }}</strong>
<br><small class="text-muted">{{ donor.donor_id }}</small>
</div>
<div class="text-end">
<span class="badge bg-primary">{{ donor.donations_this_month }}</span>
<br><small class="text-muted">donations</small>
</div>
</div>
{% empty %}
<div class="text-center py-3">
<i class="fa fa-users fa-2x text-muted mb-2"></i>
<p class="text-muted mb-0">No donations this month</p>
</div>
{% endfor %}
</div>
</div>
<!-- END top donors -->
<!-- BEGIN recent alerts -->
<div class="panel panel-inverse">
<div class="panel-heading">
<h4 class="panel-title">Recent Alerts</h4>
</div>
<div class="panel-body">
{% for alert in recent_alerts %}
<div class="alert alert-{{ alert.severity }} d-flex justify-content-between align-items-center">
<div>
<i class="fa {{ alert.icon }}"></i>
{{ alert.message }}
</div>
<small class="text-muted">{{ alert.timestamp|date:"H:i" }}</small>
</div>
{% empty %}
<div class="text-center py-3">
<i class="fa fa-check-circle fa-2x text-success mb-2"></i>
<p class="text-muted mb-0">No recent alerts</p>
</div>
{% endfor %}
</div>
</div>
<!-- END recent alerts -->
<!-- BEGIN custom report builder -->
<div class="panel panel-inverse">
<div class="panel-heading">
<h4 class="panel-title">Custom Report Builder</h4>
</div>
<div class="panel-body">
<form id="customReportForm">
<div class="mb-3">
<label class="form-label">Report Type</label>
<select class="form-select" id="customReportType">
<option value="inventory">Inventory Analysis</option>
<option value="donor">Donor Analysis</option>
<option value="usage">Usage Analysis</option>
<option value="quality">Quality Metrics</option>
<option value="financial">Financial Report</option>
</select>
</div>
<div class="mb-3">
<label class="form-label">Date Range</label>
<div class="input-group">
<input type="text" class="form-control" id="startDate" placeholder="Start Date">
<input type="text" class="form-control" id="endDate" placeholder="End Date">
</div>
</div>
<div class="mb-3">
<label class="form-label">Filters</label>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="includeExpired">
<label class="form-check-label" for="includeExpired">
Include Expired Units
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="groupByBloodType">
<label class="form-check-label" for="groupByBloodType">
Group by Blood Type
</label>
</div>
</div>
<div class="d-grid">
<button type="button" class="btn btn-primary" onclick="generateCustomReport()">
<i class="fa fa-chart-bar"></i> Generate Report
</button>
</div>
</form>
</div>
</div>
<!-- END custom report builder -->
</div>
<!-- END col-4 -->
</div>
<!-- END analytics dashboard -->
{% endblock %}
{% block js %}
<script src="{% static 'plugins/chart.js/dist/chart.umd.js' %}"></script>
<script src="{% static 'plugins/bootstrap-datepicker/dist/js/bootstrap-datepicker.min.js' %}"></script>
<script>
$(document).ready(function() {
initializeCharts();
initializeDatePickers();
});
function initializeCharts() {
// Donation Trend Chart
var donationCtx = document.getElementById('donationTrendChart').getContext('2d');
var donationChart = new Chart(donationCtx, {
type: 'line',
data: {
labels: {{ donation_trend_labels|safe }},
datasets: [{
label: 'Donations',
data: {{ donation_trend_data|safe }},
borderColor: '#28a745',
backgroundColor: 'rgba(40, 167, 69, 0.1)',
tension: 0.4
}, {
label: 'Transfusions',
data: {{ transfusion_trend_data|safe }},
borderColor: '#007bff',
backgroundColor: 'rgba(0, 123, 255, 0.1)',
tension: 0.4
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true
}
}
}
});
// Blood Group Distribution Charts
var donationBGCtx = document.getElementById('donationBloodGroupChart').getContext('2d');
var donationBGChart = new Chart(donationBGCtx, {
type: 'doughnut',
data: {
labels: {{ blood_group_labels|safe }},
datasets: [{
data: {{ donation_blood_group_data|safe }},
backgroundColor: ['#dc3545', '#007bff', '#28a745', '#ffc107']
}]
},
options: {
responsive: true,
maintainAspectRatio: false
}
});
var transfusionBGCtx = document.getElementById('transfusionBloodGroupChart').getContext('2d');
var transfusionBGChart = new Chart(transfusionBGCtx, {
type: 'doughnut',
data: {
labels: {{ blood_group_labels|safe }},
datasets: [{
data: {{ transfusion_blood_group_data|safe }},
backgroundColor: ['#dc3545', '#007bff', '#28a745', '#ffc107']
}]
},
options: {
responsive: true,
maintainAspectRatio: false
}
});
// Utilization Chart
var utilizationCtx = document.getElementById('utilizationChart').getContext('2d');
var utilizationChart = new Chart(utilizationCtx, {
type: 'bar',
data: {
labels: {{ utilization_labels|safe }},
datasets: [{
label: 'Collected',
data: {{ collected_data|safe }},
backgroundColor: '#28a745'
}, {
label: 'Used',
data: {{ used_data|safe }},
backgroundColor: '#007bff'
}, {
label: 'Expired',
data: {{ expired_data|safe }},
backgroundColor: '#dc3545'
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true
}
}
}
});
}
function initializeDatePickers() {
$('#startDate, #endDate').datepicker({
format: 'yyyy-mm-dd',
autoclose: true,
todayHighlight: true
});
}
function generateReport(category) {
Swal.fire({
title: `Generate ${category.charAt(0).toUpperCase() + category.slice(1)} Report`,
html: `
<div class="text-start">
<div class="mb-3">
<label class="form-label">Report Period</label>
<select class="form-select" id="reportPeriod">
<option value="week">Last Week</option>
<option value="month">Last Month</option>
<option value="quarter">Last Quarter</option>
<option value="year">Last Year</option>
<option value="custom">Custom Range</option>
</select>
</div>
<div class="mb-3">
<label class="form-label">Format</label>
<select class="form-select" id="reportFormat">
<option value="pdf">PDF</option>
<option value="excel">Excel</option>
<option value="csv">CSV</option>
</select>
</div>
<div class="mb-3">
<label class="form-label">Include Charts</label>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="includeCharts" checked>
<label class="form-check-label" for="includeCharts">
Include visual charts and graphs
</label>
</div>
</div>
</div>
`,
showCancelButton: true,
confirmButtonText: 'Generate Report',
cancelButtonText: 'Cancel'
}).then((result) => {
if (result.isConfirmed) {
Swal.fire({
icon: 'success',
title: 'Report Generated',
text: `${category} report is being prepared and will be available for download shortly.`,
confirmButtonText: 'OK'
});
}
});
}
function generateQuickReport(type) {
var reportNames = {
'daily': 'Daily Summary Report',
'weekly': 'Weekly Activity Report',
'monthly': 'Monthly Statistics Report',
'expiry': 'Expiry Alert Report',
'critical': 'Critical Inventory Levels Report'
};
Swal.fire({
title: 'Generating Report...',
text: `Preparing ${reportNames[type]}`,
allowOutsideClick: false,
didOpen: () => {
Swal.showLoading();
}
});
// Simulate report generation
setTimeout(function() {
Swal.fire({
icon: 'success',
title: 'Report Ready',
text: `${reportNames[type]} has been generated successfully.`,
showCancelButton: true,
confirmButtonText: 'Download',
cancelButtonText: 'Close'
});
}, 2000);
}
function generateCustomReport() {
var reportType = document.getElementById('customReportType').value;
var startDate = document.getElementById('startDate').value;
var endDate = document.getElementById('endDate').value;
if (!startDate || !endDate) {
Swal.fire({
icon: 'error',
title: 'Missing Information',
text: 'Please select both start and end dates.',
confirmButtonText: 'OK'
});
return;
}
Swal.fire({
icon: 'success',
title: 'Custom Report Generated',
text: `${reportType} report for ${startDate} to ${endDate} is being prepared.`,
confirmButtonText: 'OK'
});
}
function updateDonationChart() {
var period = document.getElementById('donationPeriod').value;
Swal.fire({
title: 'Updating Chart...',
text: `Loading data for last ${period} days`,
timer: 1500,
showConfirmButton: false,
didOpen: () => {
Swal.showLoading();
}
});
}
</script>
{% endblock %}