add import patients

This commit is contained in:
Flatlogic Bot 2026-03-29 15:09:40 +00:00
parent 83aa809d57
commit b19e996e1e
9 changed files with 233 additions and 2 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

View File

@ -0,0 +1,35 @@
<?php
session_start();
if (!isset($_SESSION['user_id'])) {
header("Location: login.php");
exit;
}
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename="patients_import_template.csv"');
// Output UTF-8 BOM for Excel
echo "\xEF\xBB\xBF";
$output = fopen('php://output', 'w');
// Header row
fputcsv($output, [
'Patient Name',
'DOB',
'Nationality',
'Telephone',
'City'
]);
// Sample row
fputcsv($output, [
'John Doe',
'1990-01-01',
'Omani',
'96812345678',
'Muscat'
]);
fclose($output);
exit;

View File

@ -904,7 +904,54 @@ $sick_leave_start_date = !empty($_POST['sick_leave_start_date']) ? $_POST['sick_
$_SESSION['flash_message'] = __('delete') . ' ' . __('successfully');
$redirect = true;
}
} elseif ($_POST['action'] === 'import_drugs_groups') {
} elseif ($_POST['action'] === 'import_patients') {
if (isset($_FILES['file'])) {
try {
$rows = parse_import_file($_FILES['file']);
if ($rows) {
$db->beginTransaction();
$stmt = $db->prepare("INSERT INTO patients (name, dob, nationality, phone, city) VALUES (?, ?, ?, ?, ?)");
foreach ($rows as $row) {
$name = trim($row[0] ?? '');
if (empty($name)) continue;
$dob = trim($row[1] ?? '');
if (!empty($dob)) {
$parsed_date = strtotime(str_replace('/', '-', $dob));
if ($parsed_date) {
$dob = date('Y-m-d', $parsed_date);
} else {
$dob = null;
}
} else {
$dob = null;
}
$nationality = trim($row[2] ?? '');
$phone = trim($row[3] ?? '');
$city = trim($row[4] ?? '');
$stmt->execute([$name, $dob, $nationality, $phone, $city]);
}
$db->commit();
$_SESSION['flash_message'] = __('patients').' '.__('imported_successfully') ?? 'Import successful';
} else {
$_SESSION['flash_message'] = $_SESSION['import_error'] ?? 'Failed to parse file or empty.'; unset($_SESSION['import_error']);
}
} catch (Exception $e) {
if ($db->inTransaction()) {
$db->rollBack();
}
$_SESSION['flash_message'] = "Error importing data: " . $e->getMessage();
}
} else {
$_SESSION['flash_message'] = "No file selected.";
}
header('Location: ../patients.php');
exit;
} elseif ($_POST['action'] === 'import_drugs_groups') {
if (isset($_FILES['csv_file'])) {
try {
$rows = parse_import_file($_FILES['csv_file']);

View File

@ -51,6 +51,40 @@
</div>
</div>
<!-- Import Patients Modal -->
<div class="modal fade" id="importPatientsModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<form method="POST" action="includes/actions.php" enctype="multipart/form-data">
<input type="hidden" name="action" value="import_patients">
<div class="modal-content border-0 shadow">
<div class="modal-header bg-success text-white">
<h5 class="modal-title"><i class="bi bi-file-earmark-excel me-2"></i> <?php echo __("import_excel"); ?></h5>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body p-4">
<div class="mb-3">
<label class="form-label"><?php echo __("select_file"); ?></label>
<input type="file" name="file" class="form-control" accept=".csv,.xls,.xlsx" required>
<div class="form-text mt-2 text-muted">
<i class="bi bi-info-circle me-1"></i> <?php echo __("excel_format_info"); ?>
</div>
</div>
<div class="mt-3 text-center">
<a href="download_patient_template.php" class="btn btn-outline-success btn-sm">
<i class="bi bi-download me-1"></i> <?php echo __("download_sample_template") ?? "Download Sample Template"; ?>
</a>
</div>
</div>
<div class="modal-footer bg-light">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal"><?php echo __("cancel"); ?></button>
<button type="submit" class="btn btn-success px-4"><?php echo __("import"); ?></button>
</div>
</div>
</form>
</div>
</div>
<!-- Add Patient Modal -->
<div class="modal fade" id="addPatientModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-lg">

View File

@ -153,9 +153,14 @@ if (isset($_GET['ajax_search'])) {
<div class="d-flex justify-content-between align-items-center mb-4">
<h3 class="fw-bold text-secondary"><?php echo __('patients'); ?></h3>
<button class="btn btn-primary shadow-sm" data-bs-toggle="modal" data-bs-target="#addPatientModal">
<div class="d-flex gap-2">
<button class="btn btn-success shadow-sm" data-bs-toggle="modal" data-bs-target="#importPatientsModal">
<i class="bi bi-file-earmark-excel me-1"></i> <?php echo __("import_excel"); ?>
</button>
<button class="btn btn-primary shadow-sm" data-bs-toggle="modal" data-bs-target="#addPatientModal">
<i class="bi bi-person-plus me-1"></i> <?php echo __('add_patient'); ?>
</button>
</div>
</div>
<!-- Search Bar -->

View File

@ -231,6 +231,12 @@ $translations = array (
'today' => 'Today',
'revenue' => 'Revenue',
'pending' => 'Pending',
'import_excel' => 'Import Excel',
'select_file' => 'Select File',
'import' => 'Import',
'excel_format_info' => 'Excel Format: Patient Name | DOB (YYYY-MM-DD) | Nationality | Telephone | City',
'download_sample_template' => 'Download Sample Template',
'imported_successfully' => 'imported successfully',
'add_patient' => 'Add Patient',
'book_appointment' => 'Book Appointment',
'add_visit' => 'Add Visit',
@ -747,6 +753,12 @@ $translations = array (
'today' => 'اليوم',
'revenue' => 'الإيرادات',
'pending' => 'معلق',
'import_excel' => 'استيراد إكسيل',
'select_file' => 'اختر الملف',
'import' => 'استيراد',
'excel_format_info' => 'تنسيق إكسيل: اسم المريض | تاريخ الميلاد | الجنسية | رقم الهاتف | المدينة',
'download_sample_template' => 'تنزيل نموذج تجريبي',
'imported_successfully' => 'تم الاستيراد بنجاح',
'add_patient' => 'إضافة مريض',
'book_appointment' => 'حجز موعد',
'add_visit' => 'إضافة زيارة',

72
patch_actions.py Normal file
View File

@ -0,0 +1,72 @@
import sys
with open('includes/actions.php', 'r', encoding='utf-8') as f:
content = f.read()
# First remove the previously injected block
if "} elseif ($_POST['action'] === 'import_patients') {" in content:
import re
# We will use string manipulation to remove the whole block.
# It starts with "} elseif ($_POST['action'] === 'import_patients') {"
# and ends right before "} elseif ($_POST['action'] === 'import_drugs_groups') {"
start_idx = content.find("} elseif ($_POST['action'] === 'import_patients') {")
end_idx = content.find("} elseif ($_POST['action'] === 'import_drugs_groups') {", start_idx + 1)
if start_idx != -1 and end_idx != -1:
content = content[:start_idx] + content[end_idx:]
inject_code = """ } elseif ($_POST['action'] === 'import_patients') {
if (isset($_FILES['file'])) {
try {
$rows = parse_import_file($_FILES['file']);
if ($rows) {
$db->beginTransaction();
$stmt = $db->prepare("INSERT INTO patients (name, dob, nationality, phone, city) VALUES (?, ?, ?, ?, ?)");
foreach ($rows as $row) {
$name = trim($row[0] ?? '');
if (empty($name)) continue;
$dob = trim($row[1] ?? '');
if (!empty($dob)) {
$parsed_date = strtotime(str_replace('/', '-', $dob));
if ($parsed_date) {
$dob = date('Y-m-d', $parsed_date);
} else {
$dob = null;
}
} else {
$dob = null;
}
$nationality = trim($row[2] ?? '');
$phone = trim($row[3] ?? '');
$city = trim($row[4] ?? '');
$stmt->execute([$name, $dob, $nationality, $phone, $city]);
}
$db->commit();
$_SESSION['flash_message'] = __('patients').' '.__('imported_successfully') ?? 'Import successful';
} else {
$_SESSION['flash_message'] = $_SESSION['import_error'] ?? 'Failed to parse file or empty.'; unset($_SESSION['import_error']);
}
} catch (Exception $e) {
if ($db->inTransaction()) {
$db->rollBack();
}
$_SESSION['flash_message'] = "Error importing data: " . $e->getMessage();
}
} else {
$_SESSION['flash_message'] = "No file selected.";
}
header('Location: ../patients.php');
exit;
"""
if "} elseif ($_POST['action'] === 'import_drugs_groups') {" in content:
content = content.replace("} elseif ($_POST['action'] === 'import_drugs_groups') {", inject_code + "} elseif ($_POST['action'] === 'import_drugs_groups') {")
with open('includes/actions.php', 'w', encoding='utf-8') as f:
f.write(content)
print("Injected successfully")
else:
print("Could not find the hook in actions.php")

26
patch_footer.py Normal file
View File

@ -0,0 +1,26 @@
import re
with open("includes/layout/footer.php", "r") as f:
content = f.read()
new_body = """<div class="mb-3">
<label class="form-label"><?php echo __("select_file"); ?></label>
<input type="file" name="file" class="form-control" accept=".csv,.xls,.xlsx" required>
<div class="form-text mt-2 text-muted">
<i class="bi bi-info-circle me-1"></i> <?php echo __("excel_format_info"); ?>
</div>
</div>
<div class="mt-3 text-center">
<a href="download_patient_template.php" class="btn btn-outline-success btn-sm">
<i class="bi bi-download me-1"></i> <?php echo __("download_sample_template") ?? "Download Sample Template"; ?>
</a>
</div>"""
content = re.sub(
r'<div class="mb-3">\s*<label class="form-label"><\?php echo __\("select_file"\); \?></label>\s*<input type="file" name="file" class="form-control" accept="\.xls,\.xlsx" required>\s*<div class="form-text mt-2 text-muted">\s*<i class="bi bi-info-circle me-1"></i> <\?php echo __\("excel_format_info"\); \?>\s*</div>\s*</div>',
new_body,
content
)
with open("includes/layout/footer.php", "w") as f:
f.write(content)