diff --git a/db/migrations/20260305_add_details_to_patients.sql b/db/migrations/20260305_add_details_to_patients.sql new file mode 100644 index 0000000..3c87490 --- /dev/null +++ b/db/migrations/20260305_add_details_to_patients.sql @@ -0,0 +1,5 @@ +-- Add civil_id, nationality, city to patients +ALTER TABLE patients +ADD COLUMN civil_id VARCHAR(50) DEFAULT NULL, +ADD COLUMN nationality VARCHAR(100) DEFAULT NULL, +ADD COLUMN city VARCHAR(100) DEFAULT NULL; diff --git a/includes/actions.php b/includes/actions.php index cca04ec..a4a745f 100644 --- a/includes/actions.php +++ b/includes/actions.php @@ -83,10 +83,13 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { $insurance_company_id = $_POST['insurance_company_id'] ?: null; $policy_number = $_POST['policy_number'] ?? ''; $address = $_POST['address'] ?? ''; + $civil_id = $_POST['civil_id'] ?? ''; + $nationality = $_POST['nationality'] ?? ''; + $city = $_POST['city'] ?? ''; if ($name) { - $stmt = $db->prepare("INSERT INTO patients (name, phone, dob, gender, blood_group, insurance_company_id, policy_number, address) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"); - $stmt->execute([$name, $phone, $dob, $gender, $blood_group, $insurance_company_id, $policy_number, $address]); + $stmt = $db->prepare("INSERT INTO patients (name, phone, dob, gender, blood_group, insurance_company_id, policy_number, address, civil_id, nationality, city) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); + $stmt->execute([$name, $phone, $dob, $gender, $blood_group, $insurance_company_id, $policy_number, $address, $civil_id, $nationality, $city]); $_SESSION['flash_message'] = __('add_patient') . ' ' . __('successfully'); $redirect = true; } @@ -100,10 +103,13 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { $insurance_company_id = $_POST['insurance_company_id'] ?: null; $policy_number = $_POST['policy_number'] ?? ''; $address = $_POST['address'] ?? ''; + $civil_id = $_POST['civil_id'] ?? ''; + $nationality = $_POST['nationality'] ?? ''; + $city = $_POST['city'] ?? ''; if ($id && $name) { - $stmt = $db->prepare("UPDATE patients SET name = ?, phone = ?, dob = ?, gender = ?, blood_group = ?, insurance_company_id = ?, policy_number = ?, address = ? WHERE id = ?"); - $stmt->execute([$name, $phone, $dob, $gender, $blood_group, $insurance_company_id, $policy_number, $address, $id]); + $stmt = $db->prepare("UPDATE patients SET name = ?, phone = ?, dob = ?, gender = ?, blood_group = ?, insurance_company_id = ?, policy_number = ?, address = ?, civil_id = ?, nationality = ?, city = ? WHERE id = ?"); + $stmt->execute([$name, $phone, $dob, $gender, $blood_group, $insurance_company_id, $policy_number, $address, $civil_id, $nationality, $city, $id]); $_SESSION['flash_message'] = __('edit_patient') . ' ' . __('successfully'); $redirect = true; } @@ -758,6 +764,9 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { $phone = $_POST['phone'] ?? ''; $email = $_POST['email'] ?? ''; $address = $_POST['address'] ?? ''; + $civil_id = $_POST['civil_id'] ?? ''; + $nationality = $_POST['nationality'] ?? ''; + $city = $_POST['city'] ?? ''; if ($name_en && $name_ar) { $stmt = $db->prepare("INSERT INTO suppliers (name_en, name_ar, contact_person, phone, email, address) VALUES (?, ?, ?, ?, ?, ?)"); @@ -773,6 +782,9 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { $phone = $_POST['phone'] ?? ''; $email = $_POST['email'] ?? ''; $address = $_POST['address'] ?? ''; + $civil_id = $_POST['civil_id'] ?? ''; + $nationality = $_POST['nationality'] ?? ''; + $city = $_POST['city'] ?? ''; if ($id && $name_en && $name_ar) { $stmt = $db->prepare("UPDATE suppliers SET name_en = ?, name_ar = ?, contact_person = ?, phone = ?, email = ?, address = ? WHERE id = ?"); diff --git a/includes/common_data.php b/includes/common_data.php index 68011b5..4bbc484 100644 --- a/includes/common_data.php +++ b/includes/common_data.php @@ -19,4 +19,4 @@ $scheduled_appointments = $db->query(" FROM appointments a JOIN patients p ON a.patient_id = p.id WHERE a.status = 'Scheduled' - ORDER BY a.start_time ASC")->fetchAll(); \ No newline at end of file + ORDER BY a.start_time ASC")->fetchAll();$all_countries = require __DIR__ . "/countries.php"; diff --git a/includes/countries.php b/includes/countries.php new file mode 100644 index 0000000..afce9d3 --- /dev/null +++ b/includes/countries.php @@ -0,0 +1,28 @@ + + \1\n
+
+ + +
+
+ + +
+
+
+ +
@@ -90,6 +108,25 @@
+
+
+ + +
+
+ + +
+
+
+ + +
@@ -2159,6 +2196,10 @@ var fields = { 'edit_patient_id': patient.id, 'edit_patient_name': patient.name, + 'edit_patient_civil_id': patient.civil_id || '', + 'edit_patient_nationality': patient.nationality || '', + 'edit_patient_city': patient.city || '', + 'edit_patient_phone': patient.phone, 'edit_patient_dob': patient.dob, 'edit_patient_gender': patient.gender, @@ -2169,7 +2210,12 @@ }; for (var id in fields) { var field = document.getElementById(id); - if (field) field.value = fields[id]; + if (field) { + field.value = fields[id]; + if (id === 'edit_patient_nationality') { + $(field).val(fields[id]).trigger('change'); + } + } } bootstrap.Modal.getOrCreateInstance(el).show(); } diff --git a/lang.php b/lang.php index 2d7f49e..3066b35 100644 --- a/lang.php +++ b/lang.php @@ -250,6 +250,9 @@ $translations = [ 'save_visit_to_add_inquiries' => 'Please save the visit first to add inquiries.', 'or' => 'or', 'no_patients_found' => 'No patients found', + 'civil_id' => 'Civil ID', + 'nationality' => 'Nationality', + 'city' => 'City', ], 'ar' => [ 'attachment' => 'المرفق', @@ -503,5 +506,8 @@ $translations = [ 'save_visit_to_add_inquiries' => 'يرجى حفظ الزيارة أولاً لإضافة الاستفسارات.', 'or' => 'أو', 'no_patients_found' => 'لم يتم العثور على مرضى', + 'civil_id' => 'الرقم المدني', + 'nationality' => 'الجنسية', + 'city' => 'المدينة', ] ]; \ No newline at end of file diff --git a/print_prescription.php b/print_prescription.php index 6e8aea2..3eee0b5 100644 --- a/print_prescription.php +++ b/print_prescription.php @@ -63,12 +63,18 @@ try { .prescription-header { border-bottom: 2px solid #000; padding-bottom: 20px; margin-bottom: 30px; } .prescription-footer { border-top: 2px solid #000; padding-top: 20px; margin-top: 50px; } .rx-symbol { font-size: 40px; font-weight: bold; font-family: cursive; margin-bottom: 10px; } - .drug-item { margin-bottom: 15px; border-bottom: 1px dashed #ccc; padding-bottom: 10px; } - .drug-name { font-weight: bold; font-size: 18px; } - .drug-dose { font-style: italic; } + + /* Grid Table Styles */ + .drug-grid { width: 100%; border-collapse: collapse; table-layout: fixed; } + .drug-grid td { border: 1px solid #000; padding: 8px; vertical-align: top; } + .drug-name { font-weight: bold; font-size: 15px; margin-bottom: 4px; display: block; } + .drug-meta { font-size: 13px; line-height: 1.4; } + .drug-meta strong { color: #555; } + @media print { .no-print { display: none; } body { padding: 20px; } + .drug-grid td { page-break-inside: avoid; } } @@ -116,26 +122,32 @@ try {

No medications prescribed.

-
- $p): ?> -
-
-
.
-
-
-
-
- Dose: -
-
- Instructions: -
-
+ + + + + + + + + + + - +
+
+
+
Dose:
+
Instr:
- - +
 
diff --git a/update_actions.py b/update_actions.py index 21c0af6..948f9bd 100644 --- a/update_actions.py +++ b/update_actions.py @@ -2,109 +2,37 @@ import re file_path = 'includes/actions.php' -try: - with open(file_path, 'r') as f: - content = f.read() -except FileNotFoundError: - print(f"Error: {file_path} not found.") - exit(1) +with open(file_path, 'r') as f: + content = f.read() -# New function implementation -new_function = r""" function parse_import_file($file_input) { - if (!isset($file_input['error']) || $file_input['error'] !== UPLOAD_ERR_OK) { - $_SESSION['import_error'] = 'Upload error code: ' . ($file_input['error'] ?? 'unknown'); - return false; - } - $ext = strtolower(pathinfo($file_input['name'], PATHINFO_EXTENSION)); - $rows = []; - - if ($ext === 'csv') { - $handle = fopen($file_input['tmp_name'], 'r'); - if ($handle === false) { - $_SESSION['import_error'] = 'Failed to open CSV file.'; - return false; - } - # Skip header - fgetcsv($handle); - while (($row = fgetcsv($handle)) !== false) { - if (array_filter($row)) { - $rows[] = $row; - } - } - fclose($handle); - if (empty($rows)) { - $_SESSION['import_error'] = 'CSV file is empty or could not be parsed.'; - } - } elseif ($ext === 'xlsx' || $ext === 'xls') { - require_once __DIR__ . '/SimpleXLSX.php'; - if ($xlsx = \Shuchkin\SimpleXLSX::parse($file_input['tmp_name'])) { - $rows = $xlsx->rows(); - array_shift($rows); # Skip header - if (empty($rows)) { - $_SESSION['import_error'] = 'Excel file is empty.'; - } - } else { - $_SESSION['import_error'] = 'SimpleXLSX Error: ' . \Shuchkin\SimpleXLSX::parseError(); - return false; - } - } else { - $_SESSION['import_error'] = "Unsupported file extension: $ext. Please upload .csv or .xlsx"; - return false; - } - return $rows; - }""" +# 1. Update variable assignments +# This is safe to replace globally as it adds variables where address is defined. +content = content.replace( + "$address = $_POST['address'] ?? '';", + "$address = $_POST['address'] ?? '';\n $civil_id = $_POST['civil_id'] ?? '';\n $nationality = $_POST['nationality'] ?? '';\n $city = $_POST['city'] ?? '';" +) -# Escape specific regex characters in the new function if we used it in regex, but here we use it as replacement string. -# We need to escape backslashes in the replacement string if we use re.sub, because \1, \g<1> etc have meaning. -# However, our replacement string doesn't have those. But PHP has backslashes (namespaces). -# So we need to escape backslashes for python string, and then for re.sub. +# 2. Update INSERT query (Add Patient) +old_insert = '"INSERT INTO patients (name, phone, dob, gender, blood_group, insurance_company_id, policy_number, address) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"' +new_insert = '"INSERT INTO patients (name, phone, dob, gender, blood_group, insurance_company_id, policy_number, address, civil_id, nationality, city) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"' +content = content.replace(old_insert, new_insert) -# Actually, let's use string.replace() if possible, but we don't know the exact content of the old function to replace it exactly if it varies. -# But we know the structure. -# Let's try to identify the start and end of the function. +# Update INSERT execution array +old_exec_insert = '[$name, $phone, $dob, $gender, $blood_group, $insurance_company_id, $policy_number, $address]' +new_exec_insert = '[$name, $phone, $dob, $gender, $blood_group, $insurance_company_id, $policy_number, $address, $civil_id, $nationality, $city]' +content = content.replace(old_exec_insert, new_exec_insert) -start_marker = "function parse_import_file($file_input) {" -end_marker = "return $rows;\n }" +# 3. Update UPDATE query (Edit Patient) +old_update = '"UPDATE patients SET name = ?, phone = ?, dob = ?, gender = ?, blood_group = ?, insurance_company_id = ?, policy_number = ?, address = ? WHERE id = ?"' +new_update = '"UPDATE patients SET name = ?, phone = ?, dob = ?, gender = ?, blood_group = ?, insurance_company_id = ?, policy_number = ?, address = ?, civil_id = ?, nationality = ?, city = ? WHERE id = ?"' +content = content.replace(old_update, new_update) -start_pos = content.find(start_marker) -if start_pos != -1: - end_pos = content.find(end_marker, start_pos) - if end_pos != -1: - end_pos += len(end_marker) - # Replace the function - content = content[:start_pos] + new_function.strip() + "\n" + content[end_pos:] - print("Replaced function parse_import_file.") - else: - print("Could not find end of function parse_import_file.") - # Fallback to regex if simple find fails (e.g. whitespace diff) - pattern = r"function parse_import_file\(\$file_input\) \{[\s\S]+?return \$rows;\s+\}" - if re.search(pattern, content): - content = re.sub(pattern, new_function, content, count=1) - print("Replaced function parse_import_file using regex.") - else: - print("Could not find function parse_import_file using regex.") -else: - print("Could not find start of function parse_import_file.") - # Fallback to regex - pattern = r"function parse_import_file\(\$file_input\) \{[\s\S]+?return \$rows;\s+\}" - if re.search(pattern, content): - content = re.sub(pattern, new_function, content, count=1) - print("Replaced function parse_import_file using regex (fallback).") - else: - print("Could not find function parse_import_file using regex (fallback).") - - -# Update the calling logic -old_msg = "$_SESSION['flash_message'] = 'Failed to parse file or empty.';" -new_msg = "$_SESSION['flash_message'] = $_SESSION['import_error'] ?? 'Failed to parse file or empty.'; unset($_SESSION['import_error']);" - -if old_msg in content: - content = content.replace(old_msg, new_msg) - print("Updated error message logic.") -else: - print("Could not find old error message logic.") +# Update UPDATE execution array +old_exec_update = '[$name, $phone, $dob, $gender, $blood_group, $insurance_company_id, $policy_number, $address, $id]' +new_exec_update = '[$name, $phone, $dob, $gender, $blood_group, $insurance_company_id, $policy_number, $address, $civil_id, $nationality, $city, $id]' +content = content.replace(old_exec_update, new_exec_update) with open(file_path, 'w') as f: f.write(content) -print("Finished updating includes/actions.php") \ No newline at end of file +print("Updated actions.php") \ No newline at end of file diff --git a/update_footer.py b/update_footer.py index 2cc2ab8..311635e 100644 --- a/update_footer.py +++ b/update_footer.py @@ -1,308 +1,114 @@ + + import re file_path = 'includes/layout/footer.php' -with open(file_path, 'r', encoding='utf-8') as f: +with open(file_path, 'r') as f: content = f.read() -# Define the new content for Record Visit Modal -record_visit_modal = """ -