updating report print

This commit is contained in:
Flatlogic Bot 2026-03-30 02:50:26 +00:00
parent c26368f032
commit 559fedf5a0
3 changed files with 288 additions and 21 deletions

View File

@ -115,6 +115,95 @@ foreach ($patients_by_nationality_raw as $key => $val) {
$chart_nationality_labels = array_keys($patients_by_nationality);
$chart_nationality_data = array_values($patients_by_nationality);
// 11. Visits with Lab Tests by Nationality
$stmt = $db->prepare("
SELECT
CASE
WHEN p.nationality = 'Oman' THEN 'omani'
WHEN p.nationality IS NULL OR p.nationality = '' THEN 'unknown_nationality'
ELSE 'non_omani'
END as nat_group,
COUNT(DISTINCT v.id) as count
FROM visits v
JOIN patients p ON v.patient_id = p.id
JOIN laboratory_inquiries l ON l.visit_id = v.id
WHERE DATE(v.visit_date) BETWEEN ? AND ?
GROUP BY nat_group");
$stmt->execute([$start_date, $end_date]);
$lab_by_nationality_raw = $stmt->fetchAll(PDO::FETCH_KEY_PAIR);
$lab_by_nationality = [];
foreach ($lab_by_nationality_raw as $key => $val) {
$lab_by_nationality[__($key)] = $val;
}
$chart_lab_nat_labels = array_keys($lab_by_nationality);
$chart_lab_nat_data = array_values($lab_by_nationality);
// 12. Visits with X-Ray by Nationality
$stmt = $db->prepare("
SELECT
CASE
WHEN p.nationality = 'Oman' THEN 'omani'
WHEN p.nationality IS NULL OR p.nationality = '' THEN 'unknown_nationality'
ELSE 'non_omani'
END as nat_group,
COUNT(DISTINCT v.id) as count
FROM visits v
JOIN patients p ON v.patient_id = p.id
JOIN xray_inquiries x ON x.visit_id = v.id
WHERE DATE(v.visit_date) BETWEEN ? AND ?
GROUP BY nat_group");
$stmt->execute([$start_date, $end_date]);
$xray_by_nationality_raw = $stmt->fetchAll(PDO::FETCH_KEY_PAIR);
$xray_by_nationality = [];
foreach ($xray_by_nationality_raw as $key => $val) {
$xray_by_nationality[__($key)] = $val;
}
$chart_xray_nat_labels = array_keys($xray_by_nationality);
$chart_xray_nat_data = array_values($xray_by_nationality);
// 13. Visits by Department and Nationality
$stmt = $db->prepare("
SELECT
d.name_$lang as dept_name,
SUM(CASE WHEN p.nationality = 'Oman' THEN 1 ELSE 0 END) as omani_count,
SUM(CASE WHEN p.nationality != 'Oman' AND p.nationality IS NOT NULL AND p.nationality != '' THEN 1 ELSE 0 END) as non_omani_count,
SUM(CASE WHEN p.nationality IS NULL OR p.nationality = '' THEN 1 ELSE 0 END) as unknown_count
FROM visits v
JOIN patients p ON v.patient_id = p.id
JOIN employees e ON v.doctor_id = e.id
JOIN departments d ON e.department_id = d.id
WHERE DATE(v.visit_date) BETWEEN ? AND ?
GROUP BY d.id");
$stmt->execute([$start_date, $end_date]);
$dept_nat_data = $stmt->fetchAll(PDO::FETCH_ASSOC);
$chart_dept_nat_labels = array_column($dept_nat_data, 'dept_name');
$chart_dept_nat_omani = array_column($dept_nat_data, 'omani_count');
$chart_dept_nat_non_omani = array_column($dept_nat_data, 'non_omani_count');
$chart_dept_nat_unknown = array_column($dept_nat_data, 'unknown_count');
// 14. Visits by Doctor and Nationality
$stmt = $db->prepare("
SELECT
e.name_$lang as doctor_name,
SUM(CASE WHEN p.nationality = 'Oman' THEN 1 ELSE 0 END) as omani_count,
SUM(CASE WHEN p.nationality != 'Oman' AND p.nationality IS NOT NULL AND p.nationality != '' THEN 1 ELSE 0 END) as non_omani_count,
SUM(CASE WHEN p.nationality IS NULL OR p.nationality = '' THEN 1 ELSE 0 END) as unknown_count
FROM visits v
JOIN patients p ON v.patient_id = p.id
JOIN employees e ON v.doctor_id = e.id
WHERE DATE(v.visit_date) BETWEEN ? AND ?
GROUP BY e.id");
$stmt->execute([$start_date, $end_date]);
$doc_nat_data = $stmt->fetchAll(PDO::FETCH_ASSOC);
$chart_doc_nat_labels = array_column($doc_nat_data, 'doctor_name');
$chart_doc_nat_omani = array_column($doc_nat_data, 'omani_count');
$chart_doc_nat_non_omani = array_column($doc_nat_data, 'non_omani_count');
$chart_doc_nat_unknown = array_column($doc_nat_data, 'unknown_count');
// --- PREPARE DATA FOR JS ---
$chart_dept_revenue_labels = array_column($dept_revenue, 'name');
$chart_dept_revenue_data = array_column($dept_revenue, 'revenue');
@ -164,6 +253,11 @@ $chart_gender_data = array_values($patients_by_gender);
}
/* Ensure Charts are Visible */
.g-4, .gy-4 { --bs-gutter-y: 0.5rem !important; --bs-gutter-x: 0.5rem !important; }
.mb-5, .mb-4 { margin-bottom: 0.5rem !important; }
.card-body { min-height: auto !important; padding: 0.5rem !important; }
.card-body > div { height: 250px !important; max-height: 250px !important; }
h5 { font-size: 14pt !important; margin-bottom: 5px !important; }
canvas {
max-width: 100% !important;
height: auto !important;
@ -182,7 +276,7 @@ $chart_gender_data = array_values($patients_by_gender);
/* Page Break */
.page-break {
page-break-before: always;
page-break-inside: avoid; margin-bottom: 20px !important;
}
/* Header for Print */
@ -233,7 +327,7 @@ $chart_gender_data = array_values($patients_by_gender);
<!-- Summary Cards -->
<div class="row g-4 mb-4">
<div class="col-md-3">
<div class="col-6 col-md-3">
<div class="card border-0 shadow-sm h-100">
<div class="card-body d-flex align-items-center">
<div class="rounded-circle p-3 bg-primary bg-opacity-10 text-primary me-3">
@ -246,7 +340,7 @@ $chart_gender_data = array_values($patients_by_gender);
</div>
</div>
</div>
<div class="col-md-3">
<div class="col-6 col-md-3">
<div class="card border-0 shadow-sm h-100">
<div class="card-body d-flex align-items-center">
<div class="rounded-circle p-3 bg-success bg-opacity-10 text-success me-3">
@ -259,7 +353,7 @@ $chart_gender_data = array_values($patients_by_gender);
</div>
</div>
</div>
<div class="col-md-3">
<div class="col-6 col-md-3">
<div class="card border-0 shadow-sm h-100">
<div class="card-body d-flex align-items-center">
<div class="rounded-circle p-3 bg-info bg-opacity-10 text-info me-3">
@ -272,7 +366,7 @@ $chart_gender_data = array_values($patients_by_gender);
</div>
</div>
</div>
<div class="col-md-3">
<div class="col-6 col-md-3">
<div class="card border-0 shadow-sm h-100">
<div class="card-body d-flex align-items-center">
<div class="rounded-circle p-3 bg-warning bg-opacity-10 text-warning me-3">
@ -289,19 +383,19 @@ $chart_gender_data = array_values($patients_by_gender);
<!-- Charts Row 1 -->
<div class="row g-4 mb-4 page-break">
<div class="col-md-6">
<div class="col-6 col-md-6">
<div class="card border-0 shadow-sm h-100">
<div class="card-header bg-white border-bottom-0 pt-4 px-4">
<h5 class="fw-bold text-dark mb-0"><?php echo __('department_revenue'); ?></h5>
</div>
<div class="card-body d-flex justify-content-center align-items-center" style="min-height: 350px;">
<div style="position: relative; width: 300px; height: 300px;">
<div style="position: relative; width: 100%; height: 300px;">
<canvas id="deptRevenueChart"></canvas>
</div>
</div>
</div>
</div>
<div class="col-md-6">
<div class="col-6 col-md-6">
<div class="card border-0 shadow-sm h-100">
<div class="card-header bg-white border-bottom-0 pt-4 px-4">
<h5 class="fw-bold text-dark mb-0"><?php echo __('revenue_trend'); ?></h5>
@ -317,7 +411,7 @@ $chart_gender_data = array_values($patients_by_gender);
<!-- Charts Row 2 -->
<div class="row g-4 mb-5 page-break">
<div class="col-md-6">
<div class="col-6 col-md-6">
<div class="card border-0 shadow-sm h-100">
<div class="card-header bg-white border-bottom-0 pt-4 px-4">
<h5 class="fw-bold text-dark mb-0"><?php echo __('top_doctors'); ?></h5>
@ -329,13 +423,13 @@ $chart_gender_data = array_values($patients_by_gender);
</div>
</div>
</div>
<div class="col-md-6">
<div class="col-6 col-md-6">
<div class="card border-0 shadow-sm h-100">
<div class="card-header bg-white border-bottom-0 pt-4 px-4">
<h5 class="fw-bold text-dark mb-0"><?php echo __('new_patients'); ?> (<?php echo __('gender'); ?>)</h5>
</div>
<div class="card-body d-flex justify-content-center align-items-center" style="min-height: 350px;">
<div style="position: relative; width: 300px; height: 300px;">
<div style="position: relative; width: 100%; height: 300px;">
<canvas id="genderChart"></canvas>
</div>
</div>
@ -346,24 +440,76 @@ $chart_gender_data = array_values($patients_by_gender);
<!-- Charts Row 3 -->
<div class="row g-4 mb-5 page-break">
<div class="col-md-6 offset-md-3">
<div class="col-4 col-md-4">
<div class="card border-0 shadow-sm h-100">
<div class="card-header bg-white border-bottom-0 pt-4 px-4">
<h5 class="fw-bold text-dark mb-0"><?php echo __('patients_by_nationality'); ?></h5>
</div>
<div class="card-body d-flex justify-content-center align-items-center" style="min-height: 350px;">
<div style="position: relative; width: 300px; height: 300px;">
<div style="position: relative; width: 100%; height: 300px;">
<canvas id="nationalityChart"></canvas>
</div>
</div>
</div>
</div>
<div class="col-4 col-md-4">
<div class="card border-0 shadow-sm h-100">
<div class="card-header bg-white border-bottom-0 pt-4 px-4">
<h5 class="fw-bold text-dark mb-0"><?php echo __('visits_with_lab_tests_by_nationality'); ?></h5>
</div>
<div class="card-body d-flex justify-content-center align-items-center" style="min-height: 350px;">
<div style="position: relative; width: 100%; height: 300px;">
<canvas id="labNatChart"></canvas>
</div>
</div>
</div>
</div>
<div class="col-4 col-md-4">
<div class="card border-0 shadow-sm h-100">
<div class="card-header bg-white border-bottom-0 pt-4 px-4">
<h5 class="fw-bold text-dark mb-0"><?php echo __('visits_with_xray_by_nationality'); ?></h5>
</div>
<div class="card-body d-flex justify-content-center align-items-center" style="min-height: 350px;">
<div style="position: relative; width: 100%; height: 300px;">
<canvas id="xrayNatChart"></canvas>
</div>
</div>
</div>
</div>
</div>
<!-- Charts Row 4 (Stacked Bars) -->
<div class="row g-4 mb-5 page-break">
<div class="col-6 col-md-6">
<div class="card border-0 shadow-sm h-100">
<div class="card-header bg-white border-bottom-0 pt-4 px-4">
<h5 class="fw-bold text-dark mb-0"><?php echo __('visits_by_dept_nationality'); ?></h5>
</div>
<div class="card-body" style="min-height: 350px;">
<div style="position: relative; height: 300px; width: 100%;">
<canvas id="deptNatChart"></canvas>
</div>
</div>
</div>
</div>
<div class="col-6 col-md-6">
<div class="card border-0 shadow-sm h-100">
<div class="card-header bg-white border-bottom-0 pt-4 px-4">
<h5 class="fw-bold text-dark mb-0"><?php echo __('visits_by_doctor_nationality'); ?></h5>
</div>
<div class="card-body" style="min-height: 350px;">
<div style="position: relative; height: 300px; width: 100%;">
<canvas id="doctorNatChart"></canvas>
</div>
</div>
</div>
</div>
</div>
<!-- Detailed Tables -->
<div class="row g-4 mb-4 page-break">
<!-- Department Revenue -->
<div class="col-md-6">
<div class="col-6 col-md-6">
<div class="card border-0 shadow-sm h-100">
<div class="card-header bg-white border-bottom-0 pt-4 px-4 d-flex justify-content-between align-items-center">
<h5 class="fw-bold text-dark mb-0"><?php echo __('department_revenue'); ?></h5>
@ -398,7 +544,7 @@ $chart_gender_data = array_values($patients_by_gender);
</div>
<!-- Doctor Revenue -->
<div class="col-md-6">
<div class="col-6 col-md-6">
<div class="card border-0 shadow-sm h-100">
<div class="card-header bg-white border-bottom-0 pt-4 px-4 d-flex justify-content-between align-items-center">
<h5 class="fw-bold text-dark mb-0"><?php echo __('doctor_revenue'); ?></h5>
@ -592,5 +738,120 @@ document.addEventListener('DOMContentLoaded', function() {
}
});
// 6. Lab by Nationality (Doughnut)
const ctxLabNat = document.getElementById('labNatChart').getContext('2d');
new Chart(ctxLabNat, {
type: 'doughnut',
data: {
labels: <?php echo json_encode($chart_lab_nat_labels); ?>,
datasets: [{
data: <?php echo json_encode($chart_lab_nat_data); ?>,
backgroundColor: [colors.teal, colors.warning, colors.secondary],
borderWidth: 0
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: { position: 'bottom' }
}
}
});
// 7. X-Ray by Nationality (Doughnut)
const ctxXrayNat = document.getElementById('xrayNatChart').getContext('2d');
new Chart(ctxXrayNat, {
type: 'doughnut',
data: {
labels: <?php echo json_encode($chart_xray_nat_labels); ?>,
datasets: [{
data: <?php echo json_encode($chart_xray_nat_data); ?>,
backgroundColor: [colors.teal, colors.warning, colors.secondary],
borderWidth: 0
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: { position: 'bottom' }
}
}
});
// 8. Dept by Nationality (Stacked Bar)
const ctxDeptNat = document.getElementById('deptNatChart').getContext('2d');
new Chart(ctxDeptNat, {
type: 'bar',
data: {
labels: <?php echo json_encode($chart_dept_nat_labels); ?>,
datasets: [
{
label: '<?php echo __('omani'); ?>',
data: <?php echo json_encode($chart_dept_nat_omani); ?>,
backgroundColor: colors.teal
},
{
label: '<?php echo __('non_omani'); ?>',
data: <?php echo json_encode($chart_dept_nat_non_omani); ?>,
backgroundColor: colors.warning
},
{
label: '<?php echo __('unknown_nationality'); ?>',
data: <?php echo json_encode($chart_dept_nat_unknown); ?>,
backgroundColor: colors.secondary
}
]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
x: { stacked: true },
y: { stacked: true }
},
plugins: {
legend: { position: 'bottom' }
}
}
});
// 9. Doctor by Nationality (Stacked Bar)
const ctxDoctorNat = document.getElementById('doctorNatChart').getContext('2d');
new Chart(ctxDoctorNat, {
type: 'bar',
data: {
labels: <?php echo json_encode($chart_doc_nat_labels); ?>,
datasets: [
{
label: '<?php echo __('omani'); ?>',
data: <?php echo json_encode($chart_doc_nat_omani); ?>,
backgroundColor: colors.teal
},
{
label: '<?php echo __('non_omani'); ?>',
data: <?php echo json_encode($chart_doc_nat_non_omani); ?>,
backgroundColor: colors.warning
},
{
label: '<?php echo __('unknown_nationality'); ?>',
data: <?php echo json_encode($chart_doc_nat_unknown); ?>,
backgroundColor: colors.secondary
}
]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
x: { stacked: true },
y: { stacked: true }
},
plugins: {
legend: { position: 'bottom' }
}
}
});
});
</script>

View File

@ -23,7 +23,7 @@ $query = "
e.name_$lang as doctor_name
FROM visits v
JOIN patients p ON v.patient_id = p.id
JOIN employees e ON v.doctor_id = e.id
LEFT JOIN employees e ON v.doctor_id = e.id
WHERE v.sick_leave_days IS NOT NULL AND v.sick_leave_days > 0
";
$params = [];
@ -166,7 +166,7 @@ $doctors = $stmt->fetchAll(PDO::FETCH_ASSOC);
</span>
</td>
<td class="px-4 text-end">
<span class="text-dark"><i class="bi bi-person-badge text-muted me-1"></i> <?php echo htmlspecialchars($leave['doctor_name']); ?></span>
<span class="text-dark"><i class="bi bi-person-badge text-muted me-1"></i> <?php echo htmlspecialchars($leave['doctor_name'] ?? '-'); ?></span>
</td>
</tr>
<?php endforeach; ?>

View File

@ -1,14 +1,17 @@
<?php
$translations = array (
'en' =>
array
array (
'nationality' => 'Nationality',
'omani' => 'Omani',
'non_omani' => 'Non-Omani',
'unknown_nationality' => 'Unknown Nationality',
'patients_by_nationality' => 'Patients by Nationality',
(
'visits_with_lab_tests_by_nationality' => 'Visits with Lab Tests by Nationality',
'visits_with_xray_by_nationality' => 'Visits with X-Ray by Nationality',
'visits_by_dept_nationality' => 'Visits by Department (Nationality)',
'visits_by_doctor_nationality' => 'Visits by Doctor (Nationality)',
'sick_leave_report' => 'Patient Sick Leave',
'date_issued' => 'Date Issued',
'number_of_days' => 'Number of Days',
@ -538,14 +541,17 @@ $translations = array (
'confirm_delete_request' => 'Are you sure you want to delete this request?'
),
'ar' =>
array
array (
'nationality' => 'الجنسية',
'omani' => 'عماني',
'non_omani' => 'غير عماني',
'unknown_nationality' => 'جنسية غير معروفة',
'patients_by_nationality' => 'المرضى حسب الجنسية',
(
'visits_with_lab_tests_by_nationality' => 'الزيارات مع الفحوصات المخبرية حسب الجنسية',
'visits_with_xray_by_nationality' => 'الزيارات مع الأشعة حسب الجنسية',
'visits_by_dept_nationality' => 'الزيارات حسب القسم (الجنسية)',
'visits_by_doctor_nationality' => 'الزيارات حسب الطبيب (الجنسية)',
'sick_leave_report' => 'إجازات المرضى',
'date_issued' => 'تاريخ الإصدار',
'number_of_days' => 'عدد الأيام',