Autosave: 20260305-064557

This commit is contained in:
Flatlogic Bot 2026-03-05 06:45:57 +00:00
parent c8679068a9
commit c3784f3565
11 changed files with 801 additions and 2 deletions

18
apply_migrations.php Normal file
View File

@ -0,0 +1,18 @@
<?php
require 'db/config.php';
$db = db();
$files = glob('db/migrations/*.sql');
sort($files);
foreach ($files as $file) {
echo "Processing $file...\n";
$sql = file_get_contents($file);
try {
$db->exec($sql);
echo "Done.\n";
} catch (PDOException $e) {
echo "Error: " . $e->getMessage() . "\n";
}
}

View File

@ -0,0 +1,20 @@
CREATE TABLE IF NOT EXISTS drugs_groups (
id INT AUTO_INCREMENT PRIMARY KEY,
name_en VARCHAR(255) NOT NULL,
name_ar VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS drugs (
id INT AUTO_INCREMENT PRIMARY KEY,
group_id INT,
name_en VARCHAR(255) NOT NULL,
name_ar VARCHAR(255) NOT NULL,
description_en TEXT,
description_ar TEXT,
default_dosage VARCHAR(255),
default_instructions TEXT,
price DECIMAL(10, 2) DEFAULT 0.00,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (group_id) REFERENCES drugs_groups(id) ON DELETE SET NULL
);

View File

@ -0,0 +1,9 @@
CREATE TABLE IF NOT EXISTS visit_prescriptions (
id INT AUTO_INCREMENT PRIMARY KEY,
visit_id INT NOT NULL,
drug_name VARCHAR(255) NOT NULL,
dosage VARCHAR(100),
instructions TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (visit_id) REFERENCES visits(id) ON DELETE CASCADE
);

View File

@ -191,6 +191,18 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$db->beginTransaction(); $db->beginTransaction();
$stmt = $db->prepare("INSERT INTO visits (patient_id, doctor_id, appointment_id, weight, blood_pressure, heart_rate, temperature, symptoms, diagnosis, treatment_plan) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); $stmt = $db->prepare("INSERT INTO visits (patient_id, doctor_id, appointment_id, weight, blood_pressure, heart_rate, temperature, symptoms, diagnosis, treatment_plan) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
$stmt->execute([$patient_id, $doctor_id, $appointment_id, $weight, $bp, $hr, $temp, $symptoms, $diagnosis, $treatment]); $stmt->execute([$patient_id, $doctor_id, $appointment_id, $weight, $bp, $hr, $temp, $symptoms, $diagnosis, $treatment]);
$visit_id = $db->lastInsertId();
if (isset($_POST['prescriptions']) && is_array($_POST['prescriptions'])) {
$drug_names = $_POST['prescriptions']['drug_name'] ?? [];
$dosages = $_POST['prescriptions']['dosage'] ?? [];
$instructions = $_POST['prescriptions']['instructions'] ?? [];
$pStmt = $db->prepare("INSERT INTO visit_prescriptions (visit_id, drug_name, dosage, instructions) VALUES (?, ?, ?, ?)");
foreach ($drug_names as $i => $drug) {
if (!empty($drug)) {
$pStmt->execute([$visit_id, $drug, $dosages[$i] ?? '', $instructions[$i] ?? '']);
}
}
}
if ($appointment_id) { if ($appointment_id) {
$stmt = $db->prepare("UPDATE appointments SET status = 'Completed' WHERE id = ?"); $stmt = $db->prepare("UPDATE appointments SET status = 'Completed' WHERE id = ?");
@ -215,6 +227,19 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if ($id && $patient_id && $doctor_id) { if ($id && $patient_id && $doctor_id) {
$stmt = $db->prepare("UPDATE visits SET patient_id = ?, doctor_id = ?, weight = ?, blood_pressure = ?, heart_rate = ?, temperature = ?, symptoms = ?, diagnosis = ?, treatment_plan = ? WHERE id = ?"); $stmt = $db->prepare("UPDATE visits SET patient_id = ?, doctor_id = ?, weight = ?, blood_pressure = ?, heart_rate = ?, temperature = ?, symptoms = ?, diagnosis = ?, treatment_plan = ? WHERE id = ?");
$stmt->execute([$patient_id, $doctor_id, $weight, $bp, $hr, $temp, $symptoms, $diagnosis, $treatment, $id]); $stmt->execute([$patient_id, $doctor_id, $weight, $bp, $hr, $temp, $symptoms, $diagnosis, $treatment, $id]);
$stmt = $db->prepare("DELETE FROM visit_prescriptions WHERE visit_id = ?");
$stmt->execute([$id]);
if (isset($_POST['prescriptions']) && is_array($_POST['prescriptions'])) {
$drug_names = $_POST['prescriptions']['drug_name'] ?? [];
$dosages = $_POST['prescriptions']['dosage'] ?? [];
$instructions = $_POST['prescriptions']['instructions'] ?? [];
$pStmt = $db->prepare("INSERT INTO visit_prescriptions (visit_id, drug_name, dosage, instructions) VALUES (?, ?, ?, ?)");
foreach ($drug_names as $i => $drug) {
if (!empty($drug)) {
$pStmt->execute([$id, $drug, $dosages[$i] ?? '', $instructions[$i] ?? '']);
}
}
}
$_SESSION['flash_message'] = __('edit_visit') . ' ' . __('successfully'); $_SESSION['flash_message'] = __('edit_visit') . ' ' . __('successfully');
$redirect = true; $redirect = true;
} }
@ -602,6 +627,75 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$redirect = true; $redirect = true;
} }
} }
} elseif ($_POST['action'] === 'add_drug_group') {
$name_en = $_POST['name_en'] ?? '';
$name_ar = $_POST['name_ar'] ?? '';
if ($name_en && $name_ar) {
$stmt = $db->prepare("INSERT INTO drugs_groups (name_en, name_ar) VALUES (?, ?)");
$stmt->execute([$name_en, $name_ar]);
$_SESSION['flash_message'] = __('add_drug_group') . ' ' . __('successfully');
$redirect = true;
}
} elseif ($_POST['action'] === 'edit_drug_group') {
$id = $_POST['id'] ?? '';
$name_en = $_POST['name_en'] ?? '';
$name_ar = $_POST['name_ar'] ?? '';
if ($id && $name_en && $name_ar) {
$stmt = $db->prepare("UPDATE drugs_groups SET name_en = ?, name_ar = ? WHERE id = ?");
$stmt->execute([$name_en, $name_ar, $id]);
$_SESSION['flash_message'] = __('edit_drug_group') . ' ' . __('successfully');
$redirect = true;
}
} elseif ($_POST['action'] === 'delete_drug_group') {
$id = $_POST['id'] ?? '';
if ($id) {
$stmt = $db->prepare("DELETE FROM drugs_groups WHERE id = ?");
$stmt->execute([$id]);
$_SESSION['flash_message'] = __('delete') . ' ' . __('successfully');
$redirect = true;
}
} elseif ($_POST['action'] === 'add_drug') {
$name_en = $_POST['name_en'] ?? '';
$name_ar = $_POST['name_ar'] ?? '';
$group_id = $_POST['group_id'] ?: null;
$desc_en = $_POST['description_en'] ?? '';
$desc_ar = $_POST['description_ar'] ?? '';
$dosage = $_POST['default_dosage'] ?? '';
$instructions = $_POST['default_instructions'] ?? '';
$price = $_POST['price'] ?? 0;
if ($name_en && $name_ar) {
$stmt = $db->prepare("INSERT INTO drugs (name_en, name_ar, group_id, description_en, description_ar, default_dosage, default_instructions, price) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
$stmt->execute([$name_en, $name_ar, $group_id, $desc_en, $desc_ar, $dosage, $instructions, $price]);
$_SESSION['flash_message'] = __('add_drug') . ' ' . __('successfully');
$redirect = true;
}
} elseif ($_POST['action'] === 'edit_drug') {
$id = $_POST['id'] ?? '';
$name_en = $_POST['name_en'] ?? '';
$name_ar = $_POST['name_ar'] ?? '';
$group_id = $_POST['group_id'] ?: null;
$desc_en = $_POST['description_en'] ?? '';
$desc_ar = $_POST['description_ar'] ?? '';
$dosage = $_POST['default_dosage'] ?? '';
$instructions = $_POST['default_instructions'] ?? '';
$price = $_POST['price'] ?? 0;
if ($id && $name_en && $name_ar) {
$stmt = $db->prepare("UPDATE drugs SET name_en = ?, name_ar = ?, group_id = ?, description_en = ?, description_ar = ?, default_dosage = ?, default_instructions = ?, price = ? WHERE id = ?");
$stmt->execute([$name_en, $name_ar, $group_id, $desc_en, $desc_ar, $dosage, $instructions, $price, $id]);
$_SESSION['flash_message'] = __('edit_drug') . ' ' . __('successfully');
$redirect = true;
}
} elseif ($_POST['action'] === 'delete_drug') {
$id = $_POST['id'] ?? '';
if ($id) {
$stmt = $db->prepare("DELETE FROM drugs WHERE id = ?");
$stmt->execute([$id]);
$_SESSION['flash_message'] = __('delete') . ' ' . __('successfully');
$redirect = true;
}
} }
if ($redirect) { if ($redirect) {

View File

@ -1295,6 +1295,16 @@
</div> </div>
<textarea name="treatment_plan" class="form-control rich-editor" rows="2"></textarea> <textarea name="treatment_plan" class="form-control rich-editor" rows="2"></textarea>
</div> </div>
<hr>
<div class="mb-3">
<div class="d-flex justify-content-between align-items-center mb-2">
<label class="form-label mb-0 fw-bold"><?php echo __('prescriptions'); ?></label>
<button type="button" class="btn btn-sm btn-outline-primary" onclick="addPrescriptionRow('visit_prescriptions_container')">
<i class="bi bi-plus-circle"></i> <?php echo __('add_drug'); ?>
</button>
</div>
<div id="visit_prescriptions_container"></div>
</div>
</div> </div>
<div class="modal-footer bg-light"> <div class="modal-footer bg-light">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal"><?php echo __('cancel'); ?></button> <button type="button" class="btn btn-secondary" data-bs-dismiss="modal"><?php echo __('cancel'); ?></button>
@ -1385,6 +1395,16 @@
</div> </div>
<textarea name="treatment_plan" id="edit_visit_treatment_plan" class="form-control rich-editor" rows="2"></textarea> <textarea name="treatment_plan" id="edit_visit_treatment_plan" class="form-control rich-editor" rows="2"></textarea>
</div> </div>
<hr>
<div class="mb-3">
<div class="d-flex justify-content-between align-items-center mb-2">
<label class="form-label mb-0 fw-bold"><?php echo __('prescriptions'); ?></label>
<button type="button" class="btn btn-sm btn-outline-primary" onclick="addPrescriptionRow('edit_visit_prescriptions_container')">
<i class="bi bi-plus-circle"></i> <?php echo __('add_drug'); ?>
</button>
</div>
<div id="edit_visit_prescriptions_container"></div>
</div>
</div> </div>
<div class="modal-footer bg-light"> <div class="modal-footer bg-light">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal"><?php echo __('cancel'); ?></button> <button type="button" class="btn btn-secondary" data-bs-dismiss="modal"><?php echo __('cancel'); ?></button>
@ -2531,6 +2551,18 @@
} }
} }
} }
// Populate prescriptions
const pContainer = document.getElementById('edit_visit_prescriptions_container');
if (pContainer) {
pContainer.innerHTML = '';
if (visit.prescriptions && visit.prescriptions.length > 0) {
visit.prescriptions.forEach(p => {
addPrescriptionRow('edit_visit_prescriptions_container', p);
});
}
}
bootstrap.Modal.getOrCreateInstance(el).show(); bootstrap.Modal.getOrCreateInstance(el).show();
} }
} }
@ -2653,5 +2685,218 @@
} }
</script> </script>
<script src="assets/js/ai_helper.js?v=1772645929"></script> <script src="assets/js/ai_helper.js?v=1772645929"></script>
<script>
function addPrescriptionRow(containerId, data = null) {
const container = document.getElementById(containerId);
if (!container) return;
const row = document.createElement('div');
row.className = 'prescription-row card bg-light border-0 mb-2 p-2';
row.innerHTML = `
<div class="row g-2 align-items-end">
<div class="col-md-4">
<label class="small text-muted mb-1"><?php echo __('drug_name'); ?></label>
<input type="text" name="prescriptions[drug_name][]" class="form-control form-control-sm" required value="${data ? (data.drug_name || '') : ''}">
</div>
<div class="col-md-3">
<label class="small text-muted mb-1"><?php echo __('dosage'); ?></label>
<input type="text" name="prescriptions[dosage][]" class="form-control form-control-sm" value="${data ? (data.dosage || '') : ''}">
</div>
<div class="col-md-4">
<label class="small text-muted mb-1"><?php echo __('instructions'); ?></label>
<input type="text" name="prescriptions[instructions][]" class="form-control form-control-sm" value="${data ? (data.instructions || '') : ''}">
</div>
<div class="col-md-1 text-center">
<button type="button" class="btn btn-link text-danger p-0" onclick="this.closest('.prescription-row').remove()">
<i class="bi bi-x-circle"></i>
</button>
</div>
</div>
`;
container.appendChild(row);
}
</script>
<?php
// Fetch Drugs for JS
$drug_query = $db->query("SELECT d.*, g.name_$lang as group_name FROM drugs d LEFT JOIN drugs_groups g ON d.group_id = g.id ORDER BY d.name_$lang");
$all_drugs_js = $drug_query->fetchAll(PDO::FETCH_ASSOC);
$drug_groups_js = $db->query("SELECT * FROM drugs_groups ORDER BY name_$lang")->fetchAll(PDO::FETCH_ASSOC);
?>
<script>
window.ALL_DRUGS = <?php echo json_encode($all_drugs_js, JSON_UNESCAPED_UNICODE); ?>;
window.DRUG_GROUPS = <?php echo json_encode($drug_groups_js, JSON_UNESCAPED_UNICODE); ?>;
</script>
<!-- Select Drug Modal -->
<div class="modal fade" id="selectDrugModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content border-0 shadow">
<div class="modal-header bg-primary text-white">
<h5 class="modal-title fw-bold"><?php echo __('select_drug'); ?></h5>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="row mb-3">
<div class="col-md-6">
<input type="text" id="drug_search_input" class="form-control" placeholder="<?php echo __('search'); ?>..." onkeyup="filterDrugs()">
</div>
<div class="col-md-6">
<select id="drug_group_filter" class="form-select" onchange="filterDrugs()">
<option value=""><?php echo __('all'); ?> <?php echo __('groups'); ?></option>
<!-- Populated by JS -->
</select>
</div>
</div>
<div class="list-group list-group-flush" id="drug_list_container" style="max-height: 400px; overflow-y: auto;">
<!-- Populated by JS -->
</div>
</div>
</div>
</div>
</div>
<script>
let currentPrescriptionRowTarget = null;
// Populate Groups Filter
$(document).ready(function() {
const groupSelect = document.getElementById('drug_group_filter');
if (groupSelect && window.DRUG_GROUPS) {
window.DRUG_GROUPS.forEach(g => {
const opt = document.createElement('option');
opt.value = g.id;
opt.text = g.name_<?php echo $lang; ?>;
groupSelect.appendChild(opt);
});
}
});
// Redefine addPrescriptionRow to use the modal
window.addPrescriptionRow = function(containerId, data = null) {
const container = document.getElementById(containerId);
if (!container) return;
const rowId = 'rx_row_' + Date.now() + '_' + Math.floor(Math.random() * 1000);
const row = document.createElement('div');
row.className = 'prescription-row card bg-light border-0 mb-2 p-2';
row.id = rowId;
const drugName = data ? (data.drug_name || '') : '';
const dosage = data ? (data.dosage || '') : '';
const instr = data ? (data.instructions || '') : '';
row.innerHTML = `
<div class="row g-2 align-items-end">
<div class="col-md-4">
<label class="small text-muted mb-1"><?php echo __('drug_name'); ?></label>
<div class="input-group input-group-sm">
<input type="text" name="prescriptions[drug_name][]" id="${rowId}_name" class="form-control" required value="${drugName}" readonly>
<button class="btn btn-outline-secondary" type="button" onclick="openSelectDrugModal('${rowId}')">
<i class="bi bi-search"></i>
</button>
</div>
</div>
<div class="col-md-3">
<label class="small text-muted mb-1"><?php echo __('dosage'); ?></label>
<input type="text" name="prescriptions[dosage][]" id="${rowId}_dosage" class="form-control form-control-sm" value="${dosage}">
</div>
<div class="col-md-4">
<label class="small text-muted mb-1"><?php echo __('instructions'); ?></label>
<input type="text" name="prescriptions[instructions][]" id="${rowId}_instr" class="form-control form-control-sm" value="${instr}">
</div>
<div class="col-md-1 text-center">
<button type="button" class="btn btn-link text-danger p-0" onclick="this.closest('.prescription-row').remove()">
<i class="bi bi-x-circle"></i>
</button>
</div>
</div>
`;
container.appendChild(row);
};
function openSelectDrugModal(rowId) {
currentPrescriptionRowTarget = rowId;
const modalEl = document.getElementById('selectDrugModal');
if (modalEl) {
document.getElementById('drug_search_input').value = '';
document.getElementById('drug_group_filter').value = '';
filterDrugs();
bootstrap.Modal.getOrCreateInstance(modalEl).show();
}
}
function filterDrugs() {
const search = document.getElementById('drug_search_input').value.toLowerCase();
const groupId = document.getElementById('drug_group_filter').value;
const list = document.getElementById('drug_list_container');
if (!list) return;
list.innerHTML = '';
if (!window.ALL_DRUGS) return;
const filtered = window.ALL_DRUGS.filter(d => {
const nameEn = d.name_en ? d.name_en.toLowerCase() : '';
const nameAr = d.name_ar ? d.name_ar.toLowerCase() : '';
const nameMatch = nameEn.includes(search) || nameAr.includes(search);
const groupMatch = groupId ? d.group_id == groupId : true;
return nameMatch && groupMatch;
});
if (filtered.length === 0) {
list.innerHTML = '<div class="text-center p-3 text-muted"><?php echo __('no_drugs_found'); ?></div>';
return;
}
filtered.forEach(d => {
const item = document.createElement('a');
item.href = '#';
item.className = 'list-group-item list-group-item-action';
item.addEventListener('click', function(e) {
e.preventDefault();
selectDrug(d);
});
const name = d.name_<?php echo $lang; ?> || d.name_en;
const desc = d.description_<?php echo $lang; ?> || '';
const dosage = d.default_dosage || '';
const price = parseFloat(d.price).toFixed(2);
item.innerHTML = `
<div class="d-flex w-100 justify-content-between">
<h6 class="mb-1 fw-bold text-primary">${name}</h6>
<small class="text-muted">$${price}</small>
</div>
<p class="mb-1 small text-dark">${desc}</p>
<small class="text-muted">Dose: ${dosage}</small>
`;
list.appendChild(item);
});
}
function selectDrug(drug) {
if (currentPrescriptionRowTarget) {
const nameInput = document.getElementById(currentPrescriptionRowTarget + '_name');
const doseInput = document.getElementById(currentPrescriptionRowTarget + '_dosage');
const instrInput = document.getElementById(currentPrescriptionRowTarget + '_instr');
if (nameInput) nameInput.value = drug.name_<?php echo $lang; ?> || drug.name_en;
if (doseInput && !doseInput.value) doseInput.value = drug.default_dosage || '';
if (instrInput && !instrInput.value) instrInput.value = drug.default_instructions || '';
}
const modalEl = document.getElementById('selectDrugModal');
if (modalEl) {
const modalInstance = bootstrap.Modal.getInstance(modalEl);
if (modalInstance) modalInstance.hide();
}
currentPrescriptionRowTarget = null;
}
</script>
</body> </body>
</html> </html>

View File

@ -119,6 +119,18 @@ $site_favicon = !empty($site_settings['company_favicon']) ? $site_settings['comp
<a href="xray_inquiries.php" class="sidebar-link py-2 <?php echo $section === 'xray_inquiries' ? 'active' : ''; ?>"><i class="bi bi-question-circle me-2"></i> <?php echo __('inquiries'); ?></a> <a href="xray_inquiries.php" class="sidebar-link py-2 <?php echo $section === 'xray_inquiries' ? 'active' : ''; ?>"><i class="bi bi-question-circle me-2"></i> <?php echo __('inquiries'); ?></a>
</div> </div>
</div> </div>
<!-- Drugs Module -->
<a href="#drugsSubmenu" data-bs-toggle="collapse" class="sidebar-link <?php echo in_array($section, ['drugs', 'drugs_groups']) ? 'active' : ''; ?> d-flex justify-content-between align-items-center">
<span><i class="bi bi-capsule me-2"></i> <?php echo __('drugs'); ?></span>
<i class="bi bi-chevron-down small"></i>
</a>
<div class="collapse <?php echo in_array($section, ['drugs', 'drugs_groups']) ? 'show' : ''; ?>" id="drugsSubmenu">
<div class="sidebar-submenu">
<a href="drugs.php" class="sidebar-link py-2 <?php echo $section === 'drugs' ? 'active' : ''; ?>"><i class="bi bi-list-check me-2"></i> <?php echo __('drugs'); ?></a>
<a href="drugs_groups.php" class="sidebar-link py-2 <?php echo $section === 'drugs_groups' ? 'active' : ''; ?>"><i class="bi bi-collection me-2"></i> <?php echo __('groups'); ?></a>
</div>
</div>
<a href="billing.php" class="sidebar-link <?php echo $section === 'billing' ? 'active' : ''; ?>"><i class="bi bi-receipt me-2"></i> <?php echo __('billing'); ?></a> <a href="billing.php" class="sidebar-link <?php echo $section === 'billing' ? 'active' : ''; ?>"><i class="bi bi-receipt me-2"></i> <?php echo __('billing'); ?></a>
<a href="insurance.php" class="sidebar-link <?php echo $section === 'insurance' ? 'active' : ''; ?>"><i class="bi bi-shield-check me-2"></i> <?php echo __('insurance'); ?></a> <a href="insurance.php" class="sidebar-link <?php echo $section === 'insurance' ? 'active' : ''; ?>"><i class="bi bi-shield-check me-2"></i> <?php echo __('insurance'); ?></a>

135
includes/pages/drugs.php Normal file
View File

@ -0,0 +1,135 @@
<?php
$search_name = $_GET['name'] ?? '';
$search_group = $_GET['group_id'] ?? '';
$query = "
SELECT d.*, g.name_$lang as group_name
FROM drugs d
LEFT JOIN drugs_groups g ON d.group_id = g.id
WHERE 1=1";
$params = [];
if ($search_name) {
$query .= " AND (d.name_en LIKE ? OR d.name_ar LIKE ?)";
$params[] = "%$search_name%";
$params[] = "%$search_name%";
}
if ($search_group) {
$query .= " AND d.group_id = ?";
$params[] = $search_group;
}
$query .= " ORDER BY d.id DESC";
$stmt = $db->prepare($query);
$stmt->execute($params);
$drugs = $stmt->fetchAll();
// Fetch all groups for filter dropdown
$gStmt = $db->query("SELECT * FROM drugs_groups ORDER BY name_$lang");
$all_drug_groups = $gStmt->fetchAll();
?>
<div class="d-flex justify-content-between align-items-center mb-4">
<h3 class="fw-bold text-secondary"><?php echo __('drugs'); ?></h3>
<button class="btn btn-primary shadow-sm" data-bs-toggle="modal" data-bs-target="#addDrugModal">
<i class="bi bi-plus-circle me-1"></i> <?php echo __('add_drug'); ?>
</button>
</div>
<!-- Search Bar -->
<div class="card shadow-sm border-0 mb-4">
<div class="card-body">
<form method="GET" action="" class="row g-3">
<div class="col-md-6">
<div class="input-group">
<span class="input-group-text bg-light border-end-0 text-muted"><i class="bi bi-search"></i></span>
<input type="text" name="name" class="form-control bg-light border-start-0" placeholder="<?php echo __('drug_name'); ?>" value="<?php echo htmlspecialchars($search_name); ?>">
</div>
</div>
<div class="col-md-4">
<select name="group_id" class="form-select bg-light">
<option value=""><?php echo __('drug_group'); ?> (<?php echo __('all'); ?>)</option>
<?php foreach ($all_drug_groups as $group): ?>
<option value="<?php echo $group['id']; ?>" <?php echo $search_group == $group['id'] ? 'selected' : ''; ?>>
<?php echo htmlspecialchars($group['name_' . $lang]); ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="col-md-2">
<button type="submit" class="btn btn-secondary w-100"><?php echo __('search'); ?></button>
</div>
</form>
</div>
</div>
<div class="card shadow-sm border-0">
<div class="card-body p-0">
<div class="table-responsive">
<table class="table table-hover align-middle mb-0">
<thead class="table-light text-secondary">
<tr>
<th class="px-4 py-3">#</th>
<th class="py-3"><?php echo __('drug_name'); ?></th>
<th class="py-3"><?php echo __('drug_group'); ?></th>
<th class="py-3"><?php echo __('default_dosage'); ?></th>
<th class="py-3"><?php echo __('price'); ?></th>
<th class="py-3 text-end px-4"><?php echo __('actions'); ?></th>
</tr>
</thead>
<tbody>
<?php if (empty($drugs)): ?>
<tr>
<td colspan="6" class="text-center py-5 text-muted">
<i class="bi bi-capsule display-4 d-block mb-3"></i>
<?php echo __('no_drugs_found'); ?>
</td>
</tr>
<?php else: ?>
<?php foreach ($drugs as $drug): ?>
<tr>
<td class="px-4 fw-medium text-secondary"><?php echo $drug['id']; ?></td>
<td>
<div class="d-flex align-items-center">
<div class="bg-primary bg-opacity-10 text-primary p-2 rounded-circle me-3">
<i class="bi bi-capsule fs-5"></i>
</div>
<div>
<div class="fw-semibold text-dark"><?php echo htmlspecialchars($drug['name_'.$lang]); ?></div>
<small class="text-muted"><?php echo htmlspecialchars($drug['name_'.($lang == 'en' ? 'ar' : 'en')]); ?></small>
</div>
</div>
</td>
<td>
<span class="badge bg-info bg-opacity-10 text-info border border-info border-opacity-25 px-2 py-1">
<?php echo htmlspecialchars($drug['group_name'] ?? '-'); ?>
</span>
</td>
<td>
<span class="text-muted small italic">
<?php echo htmlspecialchars($drug['default_dosage'] ?? '-'); ?>
</span>
</td>
<td class="text-secondary fw-bold"><?php echo number_format($drug['price'], 2); ?></td>
<td class="text-end px-4">
<div class="btn-group shadow-sm border rounded bg-white">
<button class="btn btn-link text-primary py-1 px-2 border-end"
onclick="showEditDrugModal(<?php echo htmlspecialchars(json_encode($drug, JSON_UNESCAPED_UNICODE)); ?>)"
data-bs-toggle="tooltip" title="<?php echo __('edit'); ?>">
<i class="bi bi-pencil-square"></i>
</button>
<button class="btn btn-link text-danger py-1 px-2"
onclick="showDeleteDrugModal(<?php echo $drug['id']; ?>)"
data-bs-toggle="tooltip" title="<?php echo __('delete'); ?>">
<i class="bi bi-trash3"></i>
</button>
</div>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</div>

View File

@ -0,0 +1,61 @@
<?php
$query = "SELECT * FROM drugs_groups ORDER BY id DESC";
$stmt = $db->query($query);
$groups = $stmt->fetchAll();
?>
<div class="d-flex justify-content-between align-items-center mb-4">
<h3 class="fw-bold text-secondary"><?php echo __('drugs_groups'); ?></h3>
<button class="btn btn-primary shadow-sm" data-bs-toggle="modal" data-bs-target="#addDrugGroupModal">
<i class="bi bi-plus-lg me-1"></i> <?php echo __('add_drug_group'); ?>
</button>
</div>
<div class="card shadow-sm border-0">
<div class="card-body p-0">
<div class="table-responsive">
<table class="table table-hover align-middle mb-0">
<thead class="table-light text-secondary">
<tr>
<th class="px-4 py-3">#</th>
<th class="py-3"><?php echo __('name_en'); ?></th>
<th class="py-3"><?php echo __('name_ar'); ?></th>
<th class="py-3 text-end px-4"><?php echo __('actions'); ?></th>
</tr>
</thead>
<tbody>
<?php if (empty($groups)): ?>
<tr>
<td colspan="4" class="text-center py-5 text-muted">
<i class="bi bi-collection display-4 d-block mb-3"></i>
<?php echo __('no_data_found'); ?>
</td>
</tr>
<?php else: ?>
<?php foreach ($groups as $group): ?>
<tr>
<td class="px-4 text-secondary"><?php echo $group['id']; ?></td>
<td class="fw-semibold text-dark"><?php echo htmlspecialchars($group['name_en']); ?></td>
<td class="text-secondary"><?php echo htmlspecialchars($group['name_ar']); ?></td>
<td class="text-end px-4">
<div class="btn-group shadow-sm border rounded bg-white">
<button class="btn btn-link text-primary py-1 px-2 border-end"
onclick="showEditDrugGroupModal(<?php echo htmlspecialchars(json_encode($group, JSON_UNESCAPED_UNICODE)); ?>)"
data-bs-toggle="tooltip" title="<?php echo __('edit'); ?>">
<i class="bi bi-pencil-square"></i>
</button>
<button class="btn btn-link text-danger py-1 px-2"
onclick="showDeleteDrugGroupModal(<?php echo $group['id']; ?>)"
data-bs-toggle="tooltip" title="<?php echo __('delete'); ?>">
<i class="bi bi-trash3"></i>
</button>
</div>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</div>

View File

@ -43,6 +43,10 @@ foreach ($raw_visits as $v) {
foreach($v['xray_inquiries'] as &$xi) { foreach($v['xray_inquiries'] as &$xi) {
$xi['items'] = $db->query("SELECT xit.*, xt.name_$lang as xray_name FROM xray_inquiry_items xit JOIN xray_tests xt ON xit.xray_id = xt.id WHERE xit.inquiry_id = " . (int)$xi['id'])->fetchAll(); $xi['items'] = $db->query("SELECT xit.*, xt.name_$lang as xray_name FROM xray_inquiry_items xit JOIN xray_tests xt ON xit.xray_id = xt.id WHERE xit.inquiry_id = " . (int)$xi['id'])->fetchAll();
} }
// Fetch Prescriptions
$v['prescriptions'] = $db->query("SELECT * FROM visit_prescriptions WHERE visit_id = " . (int)$v['id'])->fetchAll();
$visits[] = $v; $visits[] = $v;
} }
?> ?>
@ -191,6 +195,11 @@ foreach ($raw_visits as $v) {
data-bs-toggle="tooltip" title="<?php echo __('create_bill'); ?>"> data-bs-toggle="tooltip" title="<?php echo __('create_bill'); ?>">
<i class="bi bi-receipt"></i> <i class="bi bi-receipt"></i>
</button> </button>
<a href="print_prescription.php?visit_id=<?php echo $v['id']; ?>" target="_blank"
class="btn btn-sm btn-outline-dark"
data-bs-toggle="tooltip" title="<?php echo __('print_prescription'); ?>">
<i class="bi bi-printer"></i>
</a>
</div> </div>
</td> </td>
</tr> </tr>

View File

@ -208,7 +208,27 @@ $translations = [
'close' => 'Close', 'close' => 'Close',
'results' => 'Results', 'results' => 'Results',
'laboratory_inquiries' => 'Laboratory Inquiries', 'laboratory_inquiries' => 'Laboratory Inquiries',
'xray_inquiries' => 'X-Ray Inquiries' 'xray_inquiries' => 'X-Ray Inquiries',
'prescriptions' => 'Prescriptions',
'add_drug' => 'Add Drug',
'drug_name' => 'Drug Name',
'dosage' => 'Dosage',
'instructions' => 'Instructions',
'print_prescription' => 'Print Prescription',
'drugs_groups' => 'Drugs Groups',
'add_drug_group' => 'Add Drug Group',
'edit_drug_group' => 'Edit Drug Group',
'delete_drug_group' => 'Delete Drug Group',
'drugs' => 'Drugs',
'edit_drug' => 'Edit Drug',
'delete_drug' => 'Delete Drug',
'drug_group' => 'Drug Group',
'default_dosage' => 'Default Dosage',
'default_instructions' => 'Default Instructions',
'no_drugs_found' => 'No drugs found',
'select_drug' => 'Select Drug',
'select' => 'Select',
], ],
'ar' => [ 'ar' => [
'attachment' => 'المرفق', 'attachment' => 'المرفق',
@ -420,6 +440,26 @@ $translations = [
'company_logo' => 'شعار الشركة', 'company_logo' => 'شعار الشركة',
'company_favicon' => 'أيقونة الشركة', 'company_favicon' => 'أيقونة الشركة',
'save_changes' => 'حفظ التغييرات', 'save_changes' => 'حفظ التغييرات',
'settings_updated_successfully' => 'تم تحديث الإعدادات بنجاح' 'settings_updated_successfully' => 'تم تحديث الإعدادات بنجاح',
'prescriptions' => 'الوصفات الطبية',
'add_drug' => 'إضافة دواء',
'drug_name' => 'اسم الدواء',
'dosage' => 'الجرعة',
'instructions' => 'التعليمات',
'print_prescription' => 'طباعة الوصفة',
'drugs_groups' => 'مجموعات الأدوية',
'add_drug_group' => 'إضافة مجموعة أدوية',
'edit_drug_group' => 'تعديل مجموعة أدوية',
'delete_drug_group' => 'حذف مجموعة أدوية',
'drugs' => 'الأدوية',
'edit_drug' => 'تعديل دواء',
'delete_drug' => 'حذف دواء',
'drug_group' => 'مجموعة الدواء',
'default_dosage' => 'الجرعة الافتراضية',
'default_instructions' => 'التعليمات الافتراضية',
'no_drugs_found' => 'لم يتم العثور على أدوية',
'select_drug' => 'اختر الدواء',
'select' => 'اختيار',
] ]
]; ];

156
print_prescription.php Normal file
View File

@ -0,0 +1,156 @@
<?php
require 'db/config.php';
require 'helpers.php';
// Enable error reporting for debugging (remove in production if sensitive)
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
try {
$db = db();
$visit_id = $_GET['visit_id'] ?? 0;
if (!$visit_id) {
throw new Exception("Invalid Visit ID");
}
// Fetch visit details
// Ensure all joined columns exist or use COALESCE/Check schema
// We select specific columns to avoid 'ambiguous column' errors or fetching too much
$stmt = $db->prepare("
SELECT
v.*,
p.name as patient_name,
p.age,
p.gender,
d.name_en as doctor_name_en,
d.name_ar as doctor_name_ar,
d.specialization_en,
d.specialization_ar
FROM visits v
JOIN patients p ON v.patient_id = p.id
JOIN doctors d ON v.doctor_id = d.id
WHERE v.id = ?
");
$stmt->execute([$visit_id]);
$visit = $stmt->fetch();
if (!$visit) {
throw new Exception("Visit not found");
}
// Fetch prescriptions
// Check if table exists implicitly by try-catch
$stmt = $db->prepare("SELECT * FROM visit_prescriptions WHERE visit_id = ?");
$stmt->execute([$visit_id]);
$prescriptions = $stmt->fetchAll();
$lang = $_SESSION['lang'] ?? 'en';
} catch (Exception $e) {
die("Error: " . $e->getMessage());
}
?>
<!DOCTYPE html>
<html lang="<?php echo $lang; ?>" dir="<?php echo $lang == 'ar' ? 'rtl' : 'ltr'; ?>">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Prescription #<?php echo $visit_id; ?></title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
body { font-family: 'Times New Roman', Times, serif; }
.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; }
@media print {
.no-print { display: none; }
body { padding: 20px; }
}
</style>
</head>
<body onload="window.print()">
<div class="container">
<div class="no-print mb-3 text-end">
<button onclick="window.print()" class="btn btn-primary">Print</button>
<button onclick="window.close()" class="btn btn-secondary">Close</button>
</div>
<div class="prescription-header text-center">
<h2>Hospital Management System</h2>
<p>123 Medical Center Street, City, Country</p>
<p>Phone: +123 456 7890 | Email: info@hospital.com</p>
</div>
<div class="row mb-4">
<div class="col-6">
<h5 class="fw-bold">Doctor:</h5>
<p class="mb-0"><?php echo $visit['doctor_name_' . $lang] ?? $visit['doctor_name_en']; ?></p>
<p class="text-muted small"><?php echo $visit['specialization_' . $lang] ?? $visit['specialization_en']; ?></p>
</div>
<div class="col-6 text-end">
<h5 class="fw-bold">Date:</h5>
<p><?php echo date('d M Y', strtotime($visit['visit_date'] ?? 'now')); ?></p>
</div>
</div>
<div class="row mb-5 border p-3 rounded">
<div class="col-md-6">
<strong>Patient Name:</strong> <?php echo htmlspecialchars($visit['patient_name']); ?>
</div>
<div class="col-md-3">
<strong>Age:</strong> <?php echo $visit['age'] ?? 'N/A'; ?>
</div>
<div class="col-md-3">
<strong>Gender:</strong> <?php echo $visit['gender']; ?>
</div>
</div>
<div class="rx-symbol">Rx</div>
<div class="prescription-body mb-5">
<?php if (empty($prescriptions)): ?>
<p class="text-muted text-center py-5">No medications prescribed.</p>
<?php else: ?>
<div class="list-group list-group-flush">
<?php foreach ($prescriptions as $index => $p): ?>
<div class="drug-item">
<div class="row">
<div class="col-1 text-muted fw-bold"><?php echo $index + 1; ?>.</div>
<div class="col-11">
<div class="drug-name"><?php echo htmlspecialchars($p['drug_name']); ?></div>
<div class="row mt-1">
<div class="col-md-6">
<span class="text-muted">Dose:</span> <span class="drug-dose"><?php echo htmlspecialchars($p['dosage']); ?></span>
</div>
<div class="col-md-6">
<span class="text-muted">Instructions:</span> <span><?php echo htmlspecialchars($p['instructions']); ?></span>
</div>
</div>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
</div>
<div class="prescription-footer">
<div class="row">
<div class="col-8">
<p class="small text-muted">This prescription is valid for 30 days from the date of issue.</p>
</div>
<div class="col-4 text-center">
<div class="border-bottom border-dark mb-2" style="height: 50px;"></div>
<p class="fw-bold">Doctor's Signature</p>
</div>
</div>
</div>
</div>
</body>
</html>