= 10) ? $current_year + 1 : $current_year; $filter_type = $_GET['filter_type'] ?? 'fiscal'; $selected_fy = isset($_GET['fiscal_year']) ? (int)$_GET['fiscal_year'] : $current_fy; if ($selected_fy > 2500) { $selected_fy -= 543; } if ($filter_type === 'fiscal') { $start_date = ($selected_fy - 1) . '-10-01'; $end_date = $selected_fy . '-09-30'; } else { $start_date = $_GET['start_date'] ?? date('Y-m-01'); $end_date = $_GET['end_date'] ?? date('Y-m-d'); $s_parts = explode('-', $start_date); if (count($s_parts) === 3 && (int)$s_parts[0] > 2500) { $s_parts[0] = (int)$s_parts[0] - 543; $start_date = implode('-', $s_parts); } $e_parts = explode('-', $end_date); if (count($e_parts) === 3 && (int)$e_parts[0] > 2500) { $e_parts[0] = (int)$e_parts[0] - 543; $end_date = implode('-', $e_parts); } } $response = [ 'disease_opd' => [], 'disease_ipd' => [], 'disease_ipd_death' => [], 'disease_er_death' => [], 'refer_overview' => [], 'refer_ambulance' => [], 'refer_ship' => [], 'refer_air' => [], 'service_totals' => ['opd' => 0, 'ipd' => 0, 'er' => 0, 'ipd_death' => 0, 'er_death' => 0, 'doa' => 0], 'service_rights' => ['labels' => [], 'data' => []], 'nationality' => ['thai' => ['opd' => 0, 'ipd' => 0], 'foreign' => ['opd' => 0, 'ipd' => 0], 'alien' => ['opd' => 0, 'ipd' => 0]], 'cmi_avg' => 0, 'adjrw_sum' => 0, 'trend_cmi' => ['labels' => [], 'data' => []], 'trend_adjrw' => ['labels' => [], 'data' => []], 'display_start' => date('d/m/Y', strtotime($start_date)), 'display_end' => date('d/m/Y', strtotime($end_date)), 'sql_logs' => [], 'debug_enabled' => ($show_sql_log_btn === 'Y') ]; $addLog = function ($name, $sql, $error = null) use (&$response) { $response['sql_logs'][] = ['name' => $name, 'sql' => trim(preg_replace('/\s+/', ' ', $sql)), 'status' => $error ? 'Error' : 'Success', 'error' => $error]; }; $addLog('ระบบตรวจสอบช่วงวันที่ Stats', "ค้นหาข้อมูลตั้งแต่วันที่: $start_date ถึง $end_date"); $to_utf8 = function ($str) { if (empty($str)) return 'ไม่ระบุ'; if (!mb_check_encoding($str, 'UTF-8')) return @iconv('TIS-620', 'UTF-8//IGNORE', $str); return $str; }; $thai_months = ['01' => 'ม.ค.', '02' => 'ก.พ.', '03' => 'มี.ค.', '04' => 'เม.ย.', '05' => 'พ.ค.', '06' => 'มิ.ย.', '07' => 'ก.ค.', '08' => 'ส.ค.', '09' => 'ก.ย.', '10' => 'ต.ค.', '11' => 'พ.ย.', '12' => 'ธ.ค.']; if ($pdo) { // --- 1. สถิติโรค (10 อันดับโรค) --- $queries_disease = [ 'disease_opd' => [$sql_config['stats']['disease_opd'] ?? "SELECT v.icd10, i.name, count(v.vn) as a FROM ovstdiag v LEFT JOIN icd101 i ON v.icd10=i.code WHERE v.vstdate BETWEEN :start AND :end AND v.diagtype='1' GROUP BY v.icd10, i.name ORDER BY a DESC LIMIT 10", "10 อันดับโรคผู้ป่วยนอก (OPD)"], 'disease_ipd' => [$sql_config['stats']['disease_ipd'] ?? "SELECT v.icd10, i.name, count(v.an) as a FROM iptdiag v LEFT JOIN ipt ip ON v.an=ip.an LEFT JOIN icd101 i ON v.icd10=i.code WHERE ip.dchdate BETWEEN :start AND :end AND v.diagtype='1' GROUP BY v.icd10, i.name ORDER BY a DESC LIMIT 10", "10 อันดับโรคผู้ป่วยใน (IPD)"], 'disease_ipd_death' => [$sql_config['stats']['disease_ipd_death'] ?? "SELECT v.icd10, i.name, count(v.an) as a FROM iptdiag v LEFT JOIN ipt ip ON v.an=ip.an LEFT JOIN icd101 i ON v.icd10=i.code WHERE ip.dchdate BETWEEN :start AND :end AND v.diagtype='1' AND ip.dchtype IN ('08','09') GROUP BY v.icd10, i.name ORDER BY a DESC LIMIT 10", "10 อันดับเสียชีวิต IPD"], 'disease_er_death' => [$sql_config['stats']['disease_er_death'] ?? "SELECT v.icd10, i.name, count(v.vn) as a FROM ovstdiag v LEFT JOIN icd101 i ON v.icd10=i.code WHERE v.vstdate BETWEEN :start AND :end AND v.diagtype='1' AND v.vn IN(SELECT vn FROM er_regist WHERE er_dch_type='4') GROUP BY v.icd10, i.name ORDER BY a DESC LIMIT 10", "10 อันดับเสียชีวิตที่ ER"] ]; foreach ($queries_disease as $key => $q) { try { $stmt = $pdo->prepare($q[0]); $stmt->execute(['start' => $start_date, 'end' => $end_date]); while ($r = $stmt->fetch()) { $response[$key][] = ['name' => $to_utf8($r['name']) . " ({$r['icd10']})", 'val' => (int)$r['a']]; } $addLog($q[1], $q[0]); } catch (\Exception $e) { $addLog($q[1], $q[0], $e->getMessage()); } } // --- 2. 10 อันดับโรคส่งต่อ (Refer) --- $queries_refer = [ 'refer_overview' => [$sql_config['stats']['refer_overview'] ?? "SELECT a.pdx, ic.name as icd10, count(a.pdx) as pdxcount FROM referout a LEFT JOIN icd101 ic ON a.pdx=ic.code WHERE a.refer_date BETWEEN :start AND :end AND ic.name IS NOT NULL AND a.pdx !='U000' GROUP BY a.pdx ORDER BY pdxcount DESC LIMIT 10", "ภาพรวมโรคส่งต่อ (Refer Out)"], 'refer_ambulance' => [$sql_config['stats']['refer_ambulance'] ?? "SELECT a.pdx, ic.name as icd10, count(a.pdx) as pdxcount FROM referout a LEFT JOIN icd101 ic ON a.pdx=ic.code WHERE a.refer_date BETWEEN :start AND :end AND ic.name IS NOT NULL AND a.with_ambulance='Y' AND a.pdx !='U000' GROUP BY a.pdx ORDER BY pdxcount DESC LIMIT 10", "10 อันดับโรคส่งต่อด้วยรถพยาบาล"], 'refer_ship' => [$sql_config['stats']['refer_ship'] ?? "SELECT a.pdx, ic.name as icd10, count(a.pdx) as pdxcount FROM referout a LEFT JOIN opitemrece op ON a.vn=op.vn LEFT JOIN icd101 ic ON a.pdx=ic.code WHERE a.refer_date BETWEEN :start AND :end AND ic.name IS NOT NULL AND a.pdx !='U000' AND op.icode IN ('3162878','3162879','3162880','3162881','3162882','3162883','3162884','3162885') GROUP BY a.pdx ORDER BY pdxcount DESC LIMIT 10", "10 อันดับโรคส่งต่อทางเรือ"], 'refer_air' => [$sql_config['stats']['refer_air'] ?? "SELECT a.pdx, ic.name as icd10, count(a.pdx) as pdxcount FROM referout a LEFT JOIN opitemrece op ON a.vn=op.vn LEFT JOIN icd101 ic ON a.pdx=ic.code WHERE a.refer_date BETWEEN :start AND :end AND ic.name IS NOT NULL AND a.pdx !='U000' AND op.icode IN ('3162862','3162863','3162864','3162865','3162866','3162867','3162868','3162869','3162870','3162871','3162872','3162873','3162874','3162875','3162876','3162877','3163699','3163891') GROUP BY a.pdx ORDER BY pdxcount DESC LIMIT 10", "10 อันดับโรคส่งต่อทางอากาศ"] ]; foreach ($queries_refer as $key => $q) { try { $stmt = $pdo->prepare($q[0]); $stmt->execute(['start' => $start_date, 'end' => $end_date]); while ($r = $stmt->fetch()) { $response[$key][] = ['name' => $to_utf8($r['icd10']), 'val' => (int)$r['pdxcount']]; } $addLog($q[1], $q[0]); } catch (\Exception $e) { $addLog($q[1], $q[0], $e->getMessage()); } } // --- 3. สถิติรับบริการรวม (Totals) --- $queries_totals = [ 'opd' => [$sql_config['stats']['total_opd'] ?? "SELECT count(distinct vn) FROM ovst WHERE vstdate BETWEEN :start AND :end AND an IS NULL", "ยอดรวมผู้ป่วยนอก (OPD)"], 'ipd' => [$sql_config['stats']['total_ipd'] ?? "SELECT count(distinct an) FROM ipt WHERE dchdate BETWEEN :start AND :end", "ยอดรวมผู้ป่วยใน (IPD)"], 'er' => [$sql_config['stats']['total_er'] ?? "SELECT count(distinct vn) FROM ovst WHERE vstdate BETWEEN :start AND :end AND vn IN(SELECT vn FROM er_regist)", "ยอดรวมอุบัติเหตุ (ER)"], 'ipd_death' => [$sql_config['stats']['total_ipd_death'] ?? "SELECT count(distinct an) FROM ipt WHERE dchdate BETWEEN :start AND :end AND dchtype IN('08','09')", "จำนวนการเสียชีวิตผู้ป่วยใน"], 'er_death' => [$sql_config['stats']['total_er_death'] ?? "SELECT count(distinct vn) FROM ovst WHERE vstdate BETWEEN :start AND :end AND vn IN(SELECT vn FROM er_regist WHERE er_dch_type='4')", "จำนวนการเสียชีวิตที่ ER"], 'doa' => [$sql_config['stats']['total_doa'] ?? "SELECT count(distinct vn) FROM ovst WHERE vstdate BETWEEN :start AND :end AND vn IN(SELECT vn FROM er_regist WHERE dba='Y')", "เสียชีวิตก่อนถึง รพ. (DOA/DBA)"] ]; foreach ($queries_totals as $key => $q) { try { $stmt = $pdo->prepare($q[0]); $stmt->execute(['start' => $start_date, 'end' => $end_date]); $response['service_totals'][$key] = (int)$stmt->fetchColumn(); $addLog($q[1], $q[0]); } catch (\Exception $e) { $addLog($q[1], $q[0], $e->getMessage()); } } // --- 4. สัดส่วนสิทธิการรักษา --- $sql_rights = $sql_config['stats']['service_rights'] ?? "SELECT count(distinct a.vn) as a, c.pttype_spp_name FROM ovst a LEFT JOIN pttype b ON a.pttype=b.pttype LEFT JOIN pttype_spp c ON b.pttype_spp_id=c.pttype_spp_id WHERE a.vstdate BETWEEN :start AND :end GROUP BY b.pttype_spp_id"; try { $stmt = $pdo->prepare($sql_rights); $stmt->execute(['start' => $start_date, 'end' => $end_date]); while ($r = $stmt->fetch()) { $response['service_rights']['labels'][] = $to_utf8($r['pttype_spp_name']); $response['service_rights']['data'][] = (int)$r['a']; } $addLog('สัดส่วนสิทธิการรักษา', $sql_rights); } catch (\Exception $e) { $addLog('สัดส่วนสิทธิการรักษา', $sql_rights, $e->getMessage()); } // --- 5. สัญชาติ --- $queries_nat = [ 'thai_opd' => [$sql_config['stats']['thai_opd'] ?? "SELECT count(distinct a.vn) as a ,AEC_SAMUI FROM ovst a LEFT OUTER JOIN patient p ON a.hn=p.hn LEFT OUTER JOIN nationality n ON p.nationality=n.nationality WHERE a.vstdate BETWEEN :start AND :end AND AEC_SAMUI IN('N','P','T') AND p.nationality IS NOT NULL AND AEC_SAMUI IS NOT NULL GROUP BY AEC_SAMUI", "สัญชาติไทย OPD"], 'thai_ipd' => [$sql_config['stats']['thai_ipd'] ?? "SELECT count(distinct a.an) as a ,AEC_SAMUI FROM ipt a LEFT OUTER JOIN patient p ON a.hn=p.hn LEFT OUTER JOIN nationality n ON p.nationality=n.nationality WHERE a.dchdate BETWEEN :start AND :end AND AEC_SAMUI IN('N','P','T') AND p.nationality IS NOT NULL AND AEC_SAMUI IS NOT NULL GROUP BY AEC_SAMUI", "สัญชาติไทย IPD"], 'foreign_opd' => [$sql_config['stats']['foreign_opd'] ?? "SELECT count(distinct a.vn) as a ,AEC_SAMUI FROM ovst a LEFT OUTER JOIN patient p ON a.hn=p.hn LEFT OUTER JOIN nationality n ON p.nationality=n.nationality WHERE a.vstdate BETWEEN :start AND :end AND AEC_SAMUI IN('F') AND p.nationality IS NOT NULL AND AEC_SAMUI IS NOT NULL GROUP BY AEC_SAMUI", "ต่างชาติ OPD"], 'foreign_ipd' => [$sql_config['stats']['foreign_ipd'] ?? "SELECT count(distinct a.an) as a ,AEC_SAMUI FROM ipt a LEFT OUTER JOIN patient p ON a.hn=p.hn LEFT OUTER JOIN nationality n ON p.nationality=n.nationality WHERE a.dchdate BETWEEN :start AND :end AND AEC_SAMUI IN('F') AND p.nationality IS NOT NULL AND AEC_SAMUI IS NOT NULL GROUP BY AEC_SAMUI", "ต่างชาติ IPD"], 'alien_opd' => [$sql_config['stats']['alien_opd'] ?? "SELECT count(distinct a.vn) as a ,AEC_SAMUI FROM ovst a LEFT OUTER JOIN patient p ON a.hn=p.hn LEFT OUTER JOIN nationality n ON p.nationality=n.nationality WHERE a.vstdate BETWEEN :start AND :end AND AEC_SAMUI IN('ํY','Y') AND p.nationality IS NOT NULL AND AEC_SAMUI IS NOT NULL GROUP BY AEC_SAMUI", "ต่างด้าว OPD"], 'alien_ipd' => [$sql_config['stats']['alien_ipd'] ?? "SELECT count(distinct a.an) as a ,AEC_SAMUI FROM ipt a LEFT OUTER JOIN patient p ON a.hn=p.hn LEFT OUTER JOIN nationality n ON p.nationality=n.nationality WHERE a.dchdate BETWEEN :start AND :end AND AEC_SAMUI IN('Y','ํY') AND p.nationality IS NOT NULL AND AEC_SAMUI IS NOT NULL GROUP BY AEC_SAMUI", "ต่างด้าว IPD"] ]; foreach ($queries_nat as $key => $q) { try { $stmt = $pdo->prepare($q[0]); $stmt->execute(['start' => $start_date, 'end' => $end_date]); $sum = 0; while ($r = $stmt->fetch()) { $sum += (int)$r['a']; } $parts = explode('_', $key); $response['nationality'][$parts[0]][$parts[1]] = $sum; $addLog($q[1], $q[0]); } catch (\Exception $e) { $addLog($q[1], $q[0], $e->getMessage()); } } // --- 6. CMI และ AdjRW (ภาพรวม + กราฟรายเดือน) --- try { $sql_cmi_avg = $sql_config['stats']['cmi_avg'] ?? "SELECT IFNULL((SUM(adjrw)/count(an)),0) FROM ipt WHERE dchdate BETWEEN :start AND :end"; $stmt = $pdo->prepare($sql_cmi_avg); $stmt->execute(['start' => $start_date, 'end' => $end_date]); $response['cmi_avg'] = (float)$stmt->fetchColumn(); $sql_adjrw_sum = $sql_config['stats']['adjrw_sum'] ?? "SELECT IFNULL(SUM(adjrw),0) FROM ipt WHERE dchdate BETWEEN :start AND :end"; $stmt = $pdo->prepare($sql_adjrw_sum); $stmt->execute(['start' => $start_date, 'end' => $end_date]); $response['adjrw_sum'] = (float)$stmt->fetchColumn(); $addLog('ค่า CMI และ Sum AdjRW ภาพรวม', $sql_cmi_avg . " | " . $sql_adjrw_sum); // กราฟรายเดือน $sql_trend_cmi = $sql_config['stats']['trend_cmi'] ?? "SELECT DATE_FORMAT(dchdate, '%Y-%m') as ym, IFNULL((SUM(adjrw)/count(an)),0) as cmi, IFNULL(SUM(adjrw),0) as adjrw FROM ipt WHERE dchdate BETWEEN :start AND :end GROUP BY ym ORDER BY ym"; $stmt = $pdo->prepare($sql_trend_cmi); $stmt->execute(['start' => $start_date, 'end' => $end_date]); while ($r = $stmt->fetch()) { $parts = explode('-', $r['ym']); if (count($parts) == 2) { $lb = $thai_months[$parts[1]] . ' ' . substr((int)$parts[0] + 543, 2, 2); $response['trend_cmi']['labels'][] = $lb; $response['trend_cmi']['data'][] = (float)$r['cmi']; $response['trend_adjrw']['labels'][] = $lb; $response['trend_adjrw']['data'][] = (float)$r['adjrw']; } } $addLog('กราฟ CMI / AdjRW รายเดือน', "SELECT DATE_FORMAT(dchdate), SUM(adjrw)..."); } catch (\Exception $e) { $addLog('CMI / AdjRW', '-', $e->getMessage()); } } echo "---AJAX_STATS_START---"; $json_output = @json_encode($response, JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE); if (!$json_output) { echo json_encode(['error' => 'JSON Encode Error']); } else { echo $json_output; } echo "---AJAX_STATS_END---"; exit; } // ------------------------------------------------------------------------- // ฟอร์มการกรอง // ------------------------------------------------------------------------- $c_m = (int)date('m'); $c_y = (int)date('Y'); $c_fy = ($c_m >= 10) ? $c_y + 1 : $c_y; $options_html = ''; for ($i = 0; $i <= 5; $i++) { $y = $c_fy - $i; $yth = $y + 543; $options_html .= ""; } $start_d = date('Y-m-01'); $end_d = date('Y-m-d'); $stats_filter_html = '
'; ?>