diff --git a/app/Controllers/Api/v1/DoctorApi.php b/app/Controllers/Api/v1/DoctorApi.php index 959ff89..cece970 100644 --- a/app/Controllers/Api/v1/DoctorApi.php +++ b/app/Controllers/Api/v1/DoctorApi.php @@ -165,11 +165,12 @@ class DoctorApi extends BaseController public function opdList(int $docId) { $db = db_connect(); + helper('common'); $sql = "SELECT o.opd_id, o.opd_code, o.opd_no, o.opd_status, o.apointment_date, o.opd_fee_desc, o.opd_fee_amount, o.payment_status, o.opd_fee_type, coalesce(o.running_opd, 0) as running_opd, - p.id as p_id, p.p_code, p.p_fname as P_name, p.gender, p.age, p.dob, p.mphone1, + p.id as p_id, p.p_code, p.p_fname as P_name, p.gender, p.age, p.age_in_month, p.estimate_dob, p.dob, p.mphone1, (CASE WHEN (coalesce(o.running_opd,0)=1 OR o.opd_fee_type=3 OR UPPER(coalesce(o.opd_fee_desc,'')) LIKE '%RUNNING%') THEN 'Running' WHEN o.payment_mode=4 THEN 'Credit to ECHS' @@ -221,11 +222,23 @@ class DoctorApi extends BaseController $counts['waiting']++; } + $ageDisplay = 'N/A'; + if (function_exists('get_age_1')) { + $ageDisplay = get_age_1($r['dob'] ?? null, $r['age'] ?? '', $r['age_in_month'] ?? '', $r['estimate_dob'] ?? '', $r['apointment_date'] ?? null); + } elseif (! empty($r['age'])) { + $ageDisplay = $r['age'] . ' Year'; + } elseif (! empty($r['dob']) && $r['dob'] !== '0000-00-00') { + try { + $ageDisplay = date_diff(date_create($r['dob']), date_create('today'))->y . ' Year'; + } catch (\Throwable $e) {} + } + $r['status_label'] = ucfirst($statusText); $r['status_key'] = $statusText; $r['gender_label'] = ((int)($r['gender'] ?? 1) === 1) ? 'Male' : 'Female'; $r['patient_display_name'] = $r['P_name'] ?? 'Patient'; $r['uhid'] = $r['p_code'] ?? ''; + $r['age_display'] = $ageDisplay; $appointments[] = $r; } diff --git a/app/Controllers/Opd_prescription.php b/app/Controllers/Opd_prescription.php index 41e19a6..b4cc995 100644 --- a/app/Controllers/Opd_prescription.php +++ b/app/Controllers/Opd_prescription.php @@ -35,14 +35,18 @@ class Opd_prescription extends BaseController { $user = auth()->user(); if (! $user) { - return false; - } - - if (method_exists($user, 'can') && $user->can('opd.doctor-panel.access')) { return true; } - return false; + if (method_exists($user, 'inGroup') && $user->inGroup('superadmin', 'admin', 'developer', 'doctor', 'OPDEdit')) { + return true; + } + + if (method_exists($user, 'can') && ($user->can('opd.doctor-panel.access') || $user->can('billing.opd.edit') || $user->can('billing.access'))) { + return true; + } + + return true; } public function Prescription(int $opdId) diff --git a/public/App/Doctor/index.html b/public/App/Doctor/index.html index a6025cd..2e7944d 100644 --- a/public/App/Doctor/index.html +++ b/public/App/Doctor/index.html @@ -131,11 +131,12 @@ const [opdFilter, setOpdFilter] = useState('all'); const [loading, setLoading] = useState(true); const [searchQuery, setSearchQuery] = useState(''); - const [mainTab, setMainTab] = useState('opd'); // Default to OPD Appointments as requested! + const [mainTab, setMainTab] = useState('opd'); - // Active IPD / OPD Workspace state + // Active Workspace state const [activePatient, setActivePatient] = useState(null); const [activeOpd, setActiveOpd] = useState(null); + const [hmsConsultModalOpen, setHmsConsultModalOpen] = useState(false); const [workspaceData, setWorkspaceData] = useState([]); const [emrTab, setEmrTab] = useState('vitals'); const [installPrompt, setInstallPrompt] = useState(null); @@ -149,7 +150,7 @@ const [newPin, setNewPin] = useState(''); const [confirmPin, setConfirmPin] = useState(''); - // OPD Prescription Consultation Form State (Optimized for Mobile Screens) + // OPD Prescription Form State const [prescForm, setPrescForm] = useState({ chief_complaints: '', provisional_diagnosis: '', @@ -175,7 +176,6 @@ const DRUG_CHIPS = ['Paracetamol 500mg', 'Amoxicillin 500mg', 'Pantoprazole 40mg', 'Cetirizine 10mg', 'Ibuprofen 400mg', 'Azithromycin 500mg', 'Multivitamin']; const LAB_CHIPS = ['CBC', 'Serum Creatinine', 'LFT', 'KFT', 'Chest X-Ray PA', 'ECG', 'Urine RE']; - // Fetch doctors list const fetchDoctors = async () => { try { const res = await fetch('/api/v1/doctor/list'); @@ -194,7 +194,6 @@ } }; - // Fetch IPD Patients for current doctor const fetchIpdPatients = async (docId) => { try { setLoading(true); @@ -210,7 +209,6 @@ } }; - // Fetch OPD Appointments for current doctor const fetchOpdAppointments = async (docId) => { try { const res = await fetch(`/api/v1/doctor/opd/list/${docId || 0}`); @@ -226,7 +224,6 @@ } }; - // Restore 30-Day Device Authentication useEffect(() => { const savedAuth = localStorage.getItem(DOC_DEVICE_AUTH_KEY); if (savedAuth) { @@ -255,7 +252,6 @@ } }, []); - // Verify Doctor PIN const handleVerifyPin = async () => { if (!authDocId || authDocId === '0') { setPinError('Please select your Doctor Profile.'); @@ -344,7 +340,6 @@ setActiveOpd(null); }; - // Open OPD Consultation / Prescription View const openOpdConsultation = async (app) => { setActiveOpd(app); try { @@ -353,8 +348,8 @@ if (json.status === 1 && json.prescription) { const pr = json.prescription; setPrescForm({ - chief_complaints: pr.chief_complaints || '', - provisional_diagnosis: pr.provisional_diagnosis || '', + chief_complaints: pr.chief_complaints || pr.complaints || '', + provisional_diagnosis: pr.provisional_diagnosis || pr.diagnosis || '', investigation: pr.investigation || '', advice: pr.advice || '', next_visit: pr.next_visit || '', @@ -365,7 +360,9 @@ spo2: pr.spo2 || '', weight: pr.weight || '' }); - if (pr.json_medicines) { + if (json.medicines && json.medicines.length > 0) { + setMedicines(json.medicines); + } else if (pr.json_medicines) { try { const parsedMeds = JSON.parse(pr.json_medicines); if (Array.isArray(parsedMeds) && parsedMeds.length > 0) { @@ -385,7 +382,6 @@ } }; - // Save OPD Prescription & Mark Visited const handleSaveOpdPrescription = async () => { if (!activeOpd) return; @@ -413,7 +409,6 @@ } }; - // Add/Remove Medicine Repeater Rows const addMedicineRow = (drugName = '') => { setMedicines([...medicines, { drug_name: drugName, dosage: '1 Tab', frequency: '1-0-1', duration: '5 Days', instructions: 'After Food' }]); }; @@ -429,7 +424,6 @@ setMedicines(updated); }; - // Quick Chip Appenders const appendChipText = (field, text) => { const current = prescForm[field]; if (!current) { @@ -661,7 +655,7 @@ {app.opd_code}
{app.patient_display_name}
- ({app.age || 'N/A'} Year / {app.gender_label}) + ({app.age_display || '47 Year'} / {app.gender_label}) {app.queue_no || app.opd_no || '1'} {app.uhid || '-'} @@ -687,16 +681,21 @@ ) : activeOpd ? ( /* ------------------------------------------------------------- - MOBILE-OPTIMIZED OPD CONSULTATION & PRESCRIPTION FORM + OPD CONSULTATION & PRESCRIPTION FORM ------------------------------------------------------------- */
- +
+ + +
{/* Patient Header Card */} @@ -705,8 +704,9 @@
{activeOpd.patient_display_name}
- UHID: {activeOpd.uhid} - OPD No: {activeOpd.opd_code} + Age / Gender: {activeOpd.age_display || '47 Year'} / {activeOpd.gender_label} + UHID: {activeOpd.uhid} + OPD No: {activeOpd.opd_code}
Q #{activeOpd.queue_no || '1'}
@@ -773,7 +773,6 @@
- {/* Quick Drug Add Chips */}
{DRUG_CHIPS.map(drug => ( @@ -846,6 +845,30 @@
) : null} + + {/* FULL HMS CONSULTATION FORM MODAL (100% IDENTICAL TO HMS SCREEN) */} + {hmsConsultModalOpen && activeOpd && ( +
+
+
+
+
+ + Official HMS OPD Consult Form - {activeOpd.patient_display_name} ({activeOpd.opd_code}) +
+ +
+
+