+
-
-
+
+
+
diff --git a/patch.php b/patch.php
new file mode 100644
index 0000000..3e36e38
--- /dev/null
+++ b/patch.php
@@ -0,0 +1,117 @@
+ ['class' => 'warning', 'en' => 'Waiting for vitals', 'ar' => 'بانتظار العلامات الحيوية'],
+EOD;
+
+$replace1 = <<<'EOD'
+'waiting_vitals' => ['class' => 'warning', 'en' => 'Waiting for vitals', 'ar' => 'بانتظار العلامات الحيوية'],
+ 'nursing_called' => ['class' => 'primary', 'en' => 'Nursing Call', 'ar' => 'نداء التمريض'],
+EOD;
+$content = str_replace($search1, $replace1, $content);
+
+$search2 = <<<'EOD'
+SUM(CASE WHEN t.status = 'waiting_vitals' THEN 1 ELSE 0 END) AS vitals_waiting,
+EOD;
+
+$replace2 = <<<'EOD'
+SUM(CASE WHEN t.status IN ('waiting_vitals', 'nursing_called') THEN 1 ELSE 0 END) AS vitals_waiting,
+EOD;
+$content = str_replace($search2, $replace2, $content);
+
+$search3 = <<<'EOD'
+'waiting_vitals' => (int) $pdo->query("SELECT COUNT(*) FROM hospital_queue_records WHERE item_type = 'ticket' AND DATE(created_at) = CURDATE() AND status = 'waiting_vitals'")->fetchColumn(),
+EOD;
+
+$replace3 = <<<'EOD'
+'waiting_vitals' => (int) $pdo->query("SELECT COUNT(*) FROM hospital_queue_records WHERE item_type = 'ticket' AND DATE(created_at) = CURDATE() AND status IN ('waiting_vitals', 'nursing_called')")->fetchColumn(),
+EOD;
+$content = str_replace($search3, $replace3, $content);
+
+$search4 = <<<'EOD'
+function qh_call_message(array $ticket): array
+{
+ $ticketNumber = $ticket['ticket_number'] ?? '---';
+ $doctorNameEn = $ticket['doctor_name_en'] ?? 'Doctor';
+EOD;
+
+$replace4 = <<<'EOD'
+function qh_call_message(array $ticket): array
+{
+ $ticketNumber = $ticket['ticket_number'] ?? '---';
+
+ if (("ticket['status']" ?? '') === 'nursing_called') {
+ return [
+ 'en' => sprintf('Ticket %s, please proceed to Nursing Station.', $ticketNumber),
+ 'ar' => sprintf('رقم التذكرة %s، يرجى التوجه إلى محطة التمريض.', $ticketNumber),
+ ];
+ }
+
+ $doctorNameEn = $ticket['doctor_name_en'] ?? 'Doctor';
+EOD;
+$content = str_replace($search4, $replace4, $content);
+
+$searchHandler = <<<'EOD'
+ $ticketId = (int) ($_POST['ticket_id'] ?? 0);
+ $vitalsNotes = trim((string) ($_POST['vitals_notes'] ?? ''));
+ if ($ticketId <= 0 || $vitalsNotes === '') {
+ throw new InvalidArgumentException(qh_t('Please add a short vitals note before sending the patient forward.', 'يرجى إضافة ملاحظة قصيرة للعلامات الحيوية قبل إرسال المريض.'));
+ }
+
+ $stmt = db()->prepare(
+ "UPDATE hospital_queue_records
+ SET vitals_notes = :vitals_notes,
+ status = 'ready_for_doctor',
+ display_note = 'Vitals completed. Wait for doctor call.'
+ WHERE item_type = 'ticket' AND id = :ticket_id AND status = 'waiting_vitals'"
+ );
+ $stmt->execute([
+ 'vitals_notes' => $vitalsNotes,
+ 'ticket_id' => $ticketId,
+ ]);
+ qh_set_flash('success', qh_t('Vitals captured and patient moved to the doctor queue.', 'تم حفظ العلامات الحيوية ونقل المريض إلى طابور الطبيب.'));
+EOD;
+
+$replaceHandler = <<<'EOD'
+ $ticketId = (int) ($_POST['ticket_id'] ?? 0);
+ $action = trim((string) ($_POST['action'] ?? 'send'));
+
+ $ticket = qh_fetch_ticket($ticketId);
+ if (!$ticket) throw new InvalidArgumentException(qh_t('Invalid ticket.', 'تذكرة غير صالحة.'));
+
+ if ($action === 'call_ticket') {
+ $stmt = db()->prepare(
+ "UPDATE hospital_queue_records
+ SET status = 'nursing_called', called_at = NOW(), display_note = :display_note
+ WHERE item_type = 'ticket' AND id = :ticket_id"
+ );
+ $stmt->execute([
+ 'display_note' => sprintf('Ticket %s, proceed to Nursing Station.', $ticket['ticket_number']),
+ 'ticket_id' => $ticketId
+ ]);
+ qh_set_flash('success', qh_t('Patient call was sent to the public display.', 'تم إرسال نداء المريض إلى الشاشة العامة.'));
+ } else {
+ $vitalsNotes = trim((string) ($_POST['vitals_notes'] ?? ''));
+ if ($vitalsNotes === '') throw new InvalidArgumentException(qh_t('Please add a short vitals note before sending the patient forward.', 'يرجى إضافة ملاحظة قصيرة للعلامات الحيوية قبل إرسال المريض.'));
+
+ $stmt = db()->prepare(
+ "UPDATE hospital_queue_records
+ SET vitals_notes = :vitals_notes,
+ status = 'ready_for_doctor',
+ display_note = 'Vitals completed. Wait for doctor call.'
+ WHERE item_type = 'ticket' AND id = :ticket_id AND status IN ('waiting_vitals', 'nursing_called')"
+ );
+ $stmt->execute([
+ 'vitals_notes' => $vitalsNotes,
+ 'ticket_id' => $ticketId,
+ ]);
+ qh_set_flash('success', qh_t('Vitals captured and patient moved to the doctor queue.', 'تم حفظ العلامات الحيوية ونقل المريض إلى طابور الطبيب.'));
+ }
+EOD;
+$content = str_replace($searchHandler, $replaceHandler, $content);
+
+file_put_contents('queue_bootstrap.php', $content);
+echo "SUCCESS!\n";
+
+?>
\ No newline at end of file
diff --git a/queue_bootstrap.php b/queue_bootstrap.php
index 90d0e20..231887c 100644
--- a/queue_bootstrap.php
+++ b/queue_bootstrap.php
@@ -851,7 +851,7 @@ function qh_fetch_tickets(array $statuses = [], ?int $doctorId = null, ?int $lim
function qh_queue_overview(): array
{
$sql = "SELECT c.id, c.name_en, c.name_ar, c.code,
- SUM(CASE WHEN t.status = 'waiting_vitals' THEN 1 ELSE 0 END) AS vitals_waiting,
+ SUM(CASE WHEN t.status IN ('waiting_vitals', 'nursing_called') THEN 1 ELSE 0 END) AS vitals_waiting,
SUM(CASE WHEN t.status = 'ready_for_doctor' THEN 1 ELSE 0 END) AS doctor_waiting,
SUM(CASE WHEN t.status IN ('called', 'in_progress') THEN 1 ELSE 0 END) AS active_calls,
COUNT(t.id) AS total_today
@@ -872,7 +872,7 @@ function qh_dashboard_stats(): array
$pdo = db();
return [
'issued_today' => (int) $pdo->query("SELECT COUNT(*) FROM hospital_queue_records WHERE item_type = 'ticket' AND DATE(created_at) = CURDATE()")->fetchColumn(),
- 'waiting_vitals' => (int) $pdo->query("SELECT COUNT(*) FROM hospital_queue_records WHERE item_type = 'ticket' AND DATE(created_at) = CURDATE() AND status = 'waiting_vitals'")->fetchColumn(),
+ 'waiting_vitals' => (int) $pdo->query("SELECT COUNT(*) FROM hospital_queue_records WHERE item_type = 'ticket' AND DATE(created_at) = CURDATE() AND status IN ('waiting_vitals', 'nursing_called')")->fetchColumn(),
'ready_for_doctor' => (int) $pdo->query("SELECT COUNT(*) FROM hospital_queue_records WHERE item_type = 'ticket' AND DATE(created_at) = CURDATE() AND status = 'ready_for_doctor'")->fetchColumn(),
'active_rooms' => (int) $pdo->query("SELECT COUNT(DISTINCT doctor_id) FROM hospital_queue_records WHERE item_type = 'ticket' AND DATE(created_at) = CURDATE() AND status IN ('called', 'in_progress') AND doctor_id IS NOT NULL")->fetchColumn(),
];
@@ -950,6 +950,7 @@ function qh_status_meta(string $status): array
{
$map = [
'waiting_vitals' => ['class' => 'warning', 'en' => 'Waiting for vitals', 'ar' => 'بانتظار العلامات الحيوية'],
+ 'nursing_called' => ['class' => 'primary', 'en' => 'Nursing Call', 'ar' => 'نداء التمريض'],
'ready_for_doctor' => ['class' => 'info', 'en' => 'Ready for doctor', 'ar' => 'جاهز للطبيب'],
'called' => ['class' => 'primary', 'en' => 'Called', 'ar' => 'تم النداء'],
'in_progress' => ['class' => 'secondary', 'en' => 'In consultation', 'ar' => 'داخل العيادة'],
@@ -971,6 +972,14 @@ function qh_status_badge(string $status): string
function qh_call_message(array $ticket): array
{
$ticketNumber = $ticket['ticket_number'] ?? '---';
+
+ if (("ticket['status']" ?? '') === 'nursing_called') {
+ return [
+ 'en' => sprintf('Ticket %s, please proceed to Nursing Station.', $ticketNumber),
+ 'ar' => sprintf('رقم التذكرة %s، يرجى التوجه إلى محطة التمريض.', $ticketNumber),
+ ];
+ }
+
$doctorNameEn = $ticket['doctor_name_en'] ?? 'Doctor';
$doctorNameAr = $ticket['doctor_name_ar'] ?? 'الطبيب';
$room = $ticket['doctor_room'] ?? '--';
@@ -1324,23 +1333,39 @@ function qh_nursing_handle_request(): void
try {
$ticketId = (int) ($_POST['ticket_id'] ?? 0);
- $vitalsNotes = trim((string) ($_POST['vitals_notes'] ?? ''));
- if ($ticketId <= 0 || $vitalsNotes === '') {
- throw new InvalidArgumentException(qh_t('Please add a short vitals note before sending the patient forward.', 'يرجى إضافة ملاحظة قصيرة للعلامات الحيوية قبل إرسال المريض.'));
- }
+ $action = trim((string) ($_POST['action'] ?? 'send'));
+
+ $ticket = qh_fetch_ticket($ticketId);
+ if (!$ticket) throw new InvalidArgumentException(qh_t('Invalid ticket.', 'تذكرة غير صالحة.'));
- $stmt = db()->prepare(
- "UPDATE hospital_queue_records
- SET vitals_notes = :vitals_notes,
- status = 'ready_for_doctor',
- display_note = 'Vitals completed. Wait for doctor call.'
- WHERE item_type = 'ticket' AND id = :ticket_id AND status = 'waiting_vitals'"
- );
- $stmt->execute([
- 'vitals_notes' => $vitalsNotes,
- 'ticket_id' => $ticketId,
- ]);
- qh_set_flash('success', qh_t('Vitals captured and patient moved to the doctor queue.', 'تم حفظ العلامات الحيوية ونقل المريض إلى طابور الطبيب.'));
+ if ($action === 'call_ticket') {
+ $stmt = db()->prepare(
+ "UPDATE hospital_queue_records
+ SET status = 'nursing_called', called_at = NOW(), display_note = :display_note
+ WHERE item_type = 'ticket' AND id = :ticket_id"
+ );
+ $stmt->execute([
+ 'display_note' => sprintf('Ticket %s, proceed to Nursing Station.', $ticket['ticket_number']),
+ 'ticket_id' => $ticketId
+ ]);
+ qh_set_flash('success', qh_t('Patient call was sent to the public display.', 'تم إرسال نداء المريض إلى الشاشة العامة.'));
+ } else {
+ $vitalsNotes = trim((string) ($_POST['vitals_notes'] ?? ''));
+ if ($vitalsNotes === '') throw new InvalidArgumentException(qh_t('Please add a short vitals note before sending the patient forward.', 'يرجى إضافة ملاحظة قصيرة للعلامات الحيوية قبل إرسال المريض.'));
+
+ $stmt = db()->prepare(
+ "UPDATE hospital_queue_records
+ SET vitals_notes = :vitals_notes,
+ status = 'ready_for_doctor',
+ display_note = 'Vitals completed. Wait for doctor call.'
+ WHERE item_type = 'ticket' AND id = :ticket_id AND status IN ('waiting_vitals', 'nursing_called')"
+ );
+ $stmt->execute([
+ 'vitals_notes' => $vitalsNotes,
+ 'ticket_id' => $ticketId,
+ ]);
+ qh_set_flash('success', qh_t('Vitals captured and patient moved to the doctor queue.', 'تم حفظ العلامات الحيوية ونقل المريض إلى طابور الطبيب.'));
+ }
} catch (Throwable $exception) {
qh_set_flash('danger', $exception->getMessage());
}