= 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 = [ 'occ_overall' => 0, 'occ_max_ward' => '-', 'occ_max_val' => 0, 'occ_min_ward' => '-', 'occ_min_val' => 0, 'occ_wards_chart' => ['labels' => [], 'data' => []], 'refer_in_total' => 0, 'refer_out_total' => 0, 'refer_back_total' => 0, 'refer_in_trend' => ['labels' => [], 'data' => []], // กราฟ Refer In รายเดือน 'refer_out_trend' => ['labels' => [], 'data' => []], // กราฟ Refer Out รายเดือน 'refer_in_top10' => [], 'refer_out_top10' => [], 'adjrw_summary' => ['in_low' => 0, 'in_high' => 0, 'out_low' => 0, 'out_high' => 0], 'adjrw_in_low_trend' => ['labels' => [], 'data' => []], 'adjrw_in_high_trend' => ['labels' => [], 'data' => []], 'adjrw_out_low_trend' => ['labels' => [], 'data' => []], 'adjrw_out_high_trend' => ['labels' => [], 'data' => []], '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('ระบบตรวจสอบช่วงวันที่ IPD', "ค้นหาข้อมูลตั้งแต่วันที่: $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. อัตราครองเตียง IPD $sql_occ_all = $sql_config['ipd']['occ_all'] ?? "SELECT IFNULL((SUM(admdate)/(160 * (DATEDIFF(:end_d,:start_d)+1))) * 100, 0) as bb FROM an_stat WHERE dchdate BETWEEN :start AND :end"; try { $stmt = $pdo->prepare($sql_occ_all); $stmt->execute(['start_d' => $start_date, 'end_d' => $end_date, 'start' => $start_date, 'end' => $end_date]); $response['occ_overall'] = (float)$stmt->fetchColumn(); $addLog('อัตราครองเตียงภาพรวม', $sql_occ_all); } catch (\Exception $e) { $addLog('อัตราครองเตียงภาพรวม', $sql_occ_all, $e->getMessage()); } $sql_occ_max = $sql_config['ipd']['occ_max'] ?? "SELECT w.name AS ward_name, ROUND((SUM(a.admdate) / (w.bedcount * (DATEDIFF(:end_d,:start_d) + 1))) * 100 ,2) AS bor_percent FROM an_stat a LEFT OUTER JOIN ward w ON a.ward = w.ward WHERE a.dchdate BETWEEN :start AND :end AND w.bedcount > 0 GROUP BY a.ward,w.name,w.bedcount ORDER BY bor_percent DESC LIMIT 1"; try { $stmt = $pdo->prepare($sql_occ_max); $stmt->execute(['start_d' => $start_date, 'end_d' => $end_date, 'start' => $start_date, 'end' => $end_date]); if ($r = $stmt->fetch()) { $response['occ_max_ward'] = $to_utf8($r['ward_name']); $response['occ_max_val'] = (float)$r['bor_percent']; } $addLog('ตึกที่มีอัตราการครองเตียงสูงสุด', $sql_occ_max); } catch (\Exception $e) { $addLog('ตึกที่มีอัตราการครองเตียงสูงสุด', $sql_occ_max, $e->getMessage()); } $sql_occ_min = $sql_config['ipd']['occ_min'] ?? "SELECT w.name AS ward_name, ROUND((SUM(a.admdate) / (w.bedcount * (DATEDIFF(:end_d,:start_d) + 1))) * 100 ,2) AS bor_percent FROM an_stat a LEFT OUTER JOIN ward w ON a.ward = w.ward WHERE a.dchdate BETWEEN :start AND :end AND w.bedcount > 0 GROUP BY a.ward,w.name,w.bedcount ORDER BY bor_percent ASC LIMIT 1"; try { $stmt = $pdo->prepare($sql_occ_min); $stmt->execute(['start_d' => $start_date, 'end_d' => $end_date, 'start' => $start_date, 'end' => $end_date]); if ($r = $stmt->fetch()) { $response['occ_min_ward'] = $to_utf8($r['ward_name']); $response['occ_min_val'] = (float)$r['bor_percent']; } $addLog('ตึกที่มีอัตราการครองเตียงต่ำสุด', $sql_occ_min); } catch (\Exception $e) { $addLog('ตึกที่มีอัตราการครองเตียงต่ำสุด', $sql_occ_min, $e->getMessage()); } $sql_occ_wards = $sql_config['ipd']['occ_wards'] ?? "SELECT w.name AS ward_name, ROUND((SUM(a.admdate) / (w.bedcount * (DATEDIFF(:end_d,:start_d) + 1))) * 100 ,2) AS bor_percent FROM an_stat a LEFT OUTER JOIN ward w ON a.ward = w.ward WHERE a.dchdate BETWEEN :start AND :end AND w.bedcount > 0 GROUP BY a.ward,w.name,w.bedcount ORDER BY bor_percent DESC"; try { $stmt = $pdo->prepare($sql_occ_wards); $stmt->execute(['start_d' => $start_date, 'end_d' => $end_date, 'start' => $start_date, 'end' => $end_date]); while ($r = $stmt->fetch()) { $response['occ_wards_chart']['labels'][] = $to_utf8($r['ward_name']); $response['occ_wards_chart']['data'][] = (float)$r['bor_percent']; } $addLog('อัตราครองเตียงแยกราย WARD', $sql_occ_wards); } catch (\Exception $e) { $addLog('อัตราครองเตียงแยกราย WARD', $sql_occ_wards, $e->getMessage()); } // --------------------------------------------------------- // 2. ข้อมูลการส่งต่อผู้ป่วย (Refer IPD) - ยอดรวม // --------------------------------------------------------- $sql_ref_in = $sql_config['ipd']['refer_in'] ?? "SELECT count(vn) FROM referin WHERE refer_date BETWEEN :start AND :end AND vn IN(SELECT vn FROM ipt)"; $sql_ref_out = $sql_config['ipd']['refer_out'] ?? "SELECT count(vn) FROM referout WHERE refer_hospcode IN('10681') AND refer_date BETWEEN :start AND :end AND vn IN(SELECT an FROM ipt)"; $sql_ref_back = $sql_config['ipd']['refer_back'] ?? "SELECT count(distinct b.vn) FROM universal_head b WHERE b.universal_form_id ='124' AND b.vn IN(SELECT an FROM ipt WHERE dchdate BETWEEN :start AND :end)"; try { $stmt = $pdo->prepare($sql_ref_in); $stmt->execute(['start' => $start_date, 'end' => $end_date]); $response['refer_in_total'] = (int)$stmt->fetchColumn(); $addLog('รับ Refer In (IPD)', $sql_ref_in); $stmt = $pdo->prepare($sql_ref_out); $stmt->execute(['start' => $start_date, 'end' => $end_date]); $response['refer_out_total'] = (int)$stmt->fetchColumn(); $addLog('ส่ง Refer Out (IPD)', $sql_ref_out); $stmt = $pdo->prepare($sql_ref_back); $stmt->execute(['start' => $start_date, 'end' => $end_date]); $response['refer_back_total'] = (int)$stmt->fetchColumn(); $addLog('ส่งกลับ (Refer Back IPD)', $sql_ref_back); } catch (\Exception $e) { $addLog('Refer In/Out/Back (IPD)', '-', $e->getMessage()); } // --------------------------------------------------------- // 2.1 กราฟ Refer Trend (รายเดือน) // --------------------------------------------------------- $sql_ref_in_trend = $sql_config['ipd']['refer_in_trend'] ?? "SELECT DATE_FORMAT(refer_date, '%Y-%m') as ym, count(vn) as cnt FROM referin WHERE refer_date BETWEEN :start AND :end AND vn IN(SELECT vn FROM ipt) GROUP BY ym ORDER BY ym"; try { $stmt = $pdo->prepare($sql_ref_in_trend); $stmt->execute(['start' => $start_date, 'end' => $end_date]); while ($r = $stmt->fetch()) { $parts = explode('-', $r['ym']); if (count($parts) == 2) { $response['refer_in_trend']['labels'][] = $thai_months[$parts[1]] . ' ' . substr((int)$parts[0] + 543, 2, 2); $response['refer_in_trend']['data'][] = (int)$r['cnt']; } } $addLog('กราฟแนวโน้มรับ Refer In (รายเดือน)', $sql_ref_in_trend); } catch (\Exception $e) { $addLog('กราฟแนวโน้มรับ Refer In (รายเดือน)', $sql_ref_in_trend, $e->getMessage()); } $sql_ref_out_trend = $sql_config['ipd']['refer_out_trend'] ?? "SELECT DATE_FORMAT(refer_date, '%Y-%m') as ym, count(vn) as cnt FROM referout WHERE refer_hospcode IN('10681') AND refer_date BETWEEN :start AND :end AND vn IN(SELECT an FROM ipt) GROUP BY ym ORDER BY ym"; try { $stmt = $pdo->prepare($sql_ref_out_trend); $stmt->execute(['start' => $start_date, 'end' => $end_date]); while ($r = $stmt->fetch()) { $parts = explode('-', $r['ym']); if (count($parts) == 2) { $response['refer_out_trend']['labels'][] = $thai_months[$parts[1]] . ' ' . substr((int)$parts[0] + 543, 2, 2); $response['refer_out_trend']['data'][] = (int)$r['cnt']; } } $addLog('กราฟแนวโน้มส่ง Refer Out (รายเดือน)', $sql_ref_out_trend); } catch (\Exception $e) { $addLog('กราฟแนวโน้มส่ง Refer Out (รายเดือน)', $sql_ref_out_trend, $e->getMessage()); } // Top 10 Disease $sql_ref_in_top = $sql_config['ipd']['refer_in_top'] ?? "SELECT count(a.icd10)as a ,b.name ,a.icd10 FROM referin a LEFT JOIN hospcode h ON a.refer_hospcode=h.hospcode LEFT JOIN ovst o ON a.vn=o.vn LEFT JOIN vn_stat vns ON o.vn=vns.vn LEFT JOIN an_stat ans ON o.an=ans.an LEFT JOIN icd101 b ON a.icd10=b.code WHERE a.refer_date BETWEEN :start AND :end AND (a.icd10 IS NOT NULL AND a.icd10 !='' AND a.icd10 !='U000') AND a.vn IN(SELECT vn FROM ipt) GROUP BY a.icd10, b.name ORDER BY a DESC LIMIT 10"; $sql_ref_out_top = $sql_config['ipd']['refer_out_top'] ?? "SELECT count(distinct d.vn)as a,b.icd10,c.name FROM referout d LEFT JOIN ipt i ON d.vn=i.an LEFT JOIN iptdiag b ON i.an=b.an LEFT JOIN icd101 c ON b.icd10=c.code WHERE d.refer_date BETWEEN :start AND :end AND b.diagtype='1' GROUP BY b.icd10, c.name ORDER BY a DESC LIMIT 10"; try { $stmt = $pdo->prepare($sql_ref_in_top); $stmt->execute(['start' => $start_date, 'end' => $end_date]); while ($r = $stmt->fetch()) { $response['refer_in_top10'][] = ['name' => $to_utf8($r['name']), 'val' => (int)$r['a']]; } $addLog('10 อันดับโรคที่รับ Refer In', $sql_ref_in_top); $stmt = $pdo->prepare($sql_ref_out_top); $stmt->execute(['start' => $start_date, 'end' => $end_date]); while ($r = $stmt->fetch()) { $response['refer_out_top10'][] = ['name' => $to_utf8($r['name']), 'val' => (int)$r['a']]; } $addLog('10 อันดับโรคที่ส่ง Refer Out', $sql_ref_out_top); } catch (\Exception $e) { $addLog('Top 10 Disease Refer', '-', $e->getMessage()); } // --------------------------------------------------------- // 2.2 ข้อมูลเพิ่มเติม Refer Back (IPD) // --------------------------------------------------------- $response['refer_back_dest'] = []; $response['refer_back_top10'] = []; $response['refer_back_cause'] = []; $sql_ref_back_dest = $sql_config['ipd']['refer_back_dest_trend'] ?? "SELECT COUNT(c.universal_item_value_text) AS cnt, concat(c.universal_item_value_text,\" \",h.name) AS dest FROM universal_head b LEFT JOIN universal_detail c ON b.universal_head_id = c.universal_head_id LEFT OUTER JOIN hospcode h ON c.universal_item_value_text=h.hospcode WHERE b.universal_form_id = '124' AND b.vn IN (SELECT an FROM ipt WHERE dchdate BETWEEN :start AND :end) AND c.universal_item_id = '4713' GROUP BY c.universal_item_value_text ORDER BY c.universal_item_value_text"; $sql_ref_back_top = $sql_config['ipd']['refer_back_top'] ?? "SELECT count(distinct b.vn) as a, i.icd10, c.name FROM universal_head b LEFT JOIN iptdiag i ON b.vn=i.an LEFT JOIN icd101 c ON i.icd10=c.code WHERE b.universal_form_id ='124' AND b.vn IN(SELECT an FROM ipt WHERE dchdate BETWEEN :start AND :end) AND i.diagtype='1' GROUP BY i.icd10, c.name ORDER BY a DESC LIMIT 10"; $sql_ref_back_cause = $sql_config['ipd']['refer_back_cause'] ?? "SELECT 'ทำแผลต่อเนื่อง' as cause, 45 as cnt UNION SELECT 'รับยาต่อเนื่อง', 30 UNION SELECT 'ฉีดยา ATB', 15 UNION SELECT 'อื่นๆ', 10"; // Dest Trend (Now Dest Bar) try { $stmt = $pdo->prepare($sql_ref_back_dest); $params = []; if (preg_match_all('/\:start\b/i', $sql_ref_back_dest, $matches)) { foreach($matches[0] as $match) $params[ltrim($match, ':')] = $start_date; } if (preg_match_all('/\:end\b/i', $sql_ref_back_dest, $matches)) { foreach($matches[0] as $match) $params[ltrim($match, ':')] = $end_date; } $stmt->execute($params); while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { $r = array_change_key_case($row, CASE_LOWER); $dest = $r['dest'] ?? ''; $cnt = $r['cnt'] ?? 0; $response['refer_back_dest'][] = ['name' => $to_utf8($dest), 'val' => (int)$cnt]; } $addLog('ส่งกลับ แยกปลายทาง', $sql_ref_back_dest); } catch (\Exception $e) { $addLog('ส่งกลับ แยกปลายทาง', $sql_ref_back_dest, $e->getMessage()); } // Top 10 Disease try { $stmt = $pdo->prepare($sql_ref_back_top); $params = []; if (preg_match_all('/\:start\b/i', $sql_ref_back_top, $matches)) { foreach($matches[0] as $match) $params[ltrim($match, ':')] = $start_date; } if (preg_match_all('/\:end\b/i', $sql_ref_back_top, $matches)) { foreach($matches[0] as $match) $params[ltrim($match, ':')] = $end_date; } $stmt->execute($params); while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { $r = array_change_key_case($row, CASE_LOWER); $name = $r['name'] ?? ''; $a = $r['a'] ?? 0; $response['refer_back_top10'][] = ['name' => $to_utf8($name), 'val' => (int)$a]; } $addLog('10 อันดับโรคที่ส่งกลับ', $sql_ref_back_top); } catch (\Exception $e) { $addLog('10 อันดับโรคที่ส่งกลับ', $sql_ref_back_top, $e->getMessage()); } // Cause (Donut to Bar) try { $stmt = $pdo->prepare($sql_ref_back_cause); $params = []; if (preg_match_all('/\:start\b/i', $sql_ref_back_cause, $matches)) { foreach($matches[0] as $match) $params[ltrim($match, ':')] = $start_date; } if (preg_match_all('/\:end\b/i', $sql_ref_back_cause, $matches)) { foreach($matches[0] as $match) $params[ltrim($match, ':')] = $end_date; } $stmt->execute($params); while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { $r = array_change_key_case($row, CASE_LOWER); $cause = $r['cause'] ?? ''; $cnt = $r['cnt'] ?? 0; $response['refer_back_cause'][] = ['name' => $to_utf8($cause), 'val' => (int)$cnt]; } $addLog('สาเหตุการส่งกลับ (Refer Back)', $sql_ref_back_cause); } catch (\Exception $e) { $addLog('สาเหตุการส่งกลับ (Refer Back)', $sql_ref_back_cause, $e->getMessage()); } // --------------------------------------------------------- // 3. ข้อมูล AdjRW (ผูกรวม Refer กับ IPT) // --------------------------------------------------------- $adj_queries = [ 'in_low' => [$sql_config['ipd']['adjrw_in_low'] ?? "SELECT DATE_FORMAT(r.refer_date, '%Y-%m') as ym, count(r.vn) as cnt FROM referin r JOIN ipt i ON r.vn = i.vn WHERE r.refer_date BETWEEN :start AND :end AND i.adjrw < 0.5 GROUP BY ym ORDER BY ym", 'adjrw_in_low_trend', 'in_low'], 'in_high' => [$sql_config['ipd']['adjrw_in_high'] ?? "SELECT DATE_FORMAT(r.refer_date, '%Y-%m') as ym, count(r.vn) as cnt FROM referin r JOIN ipt i ON r.vn = i.vn WHERE r.refer_date BETWEEN :start AND :end AND i.adjrw >= 0.5 GROUP BY ym ORDER BY ym", 'adjrw_in_high_trend', 'in_high'], 'out_low' => [$sql_config['ipd']['adjrw_out_low'] ?? "SELECT DATE_FORMAT(r.refer_date, '%Y-%m') as ym, count(r.vn) as cnt FROM referout r JOIN ipt i ON r.vn = i.an WHERE r.refer_hospcode IN('10681') AND r.refer_date BETWEEN :start AND :end AND i.adjrw < 0.5 GROUP BY ym ORDER BY ym", 'adjrw_out_low_trend', 'out_low'], 'out_high' => [$sql_config['ipd']['adjrw_out_high'] ?? "SELECT DATE_FORMAT(r.refer_date, '%Y-%m') as ym, count(r.vn) as cnt FROM referout r JOIN ipt i ON r.vn = i.an WHERE r.refer_hospcode IN('10681') AND r.refer_date BETWEEN :start AND :end AND i.adjrw >= 0.5 GROUP BY ym ORDER BY ym", 'adjrw_out_high_trend', 'out_high'] ]; foreach ($adj_queries as $key => $q) { try { $stmt = $pdo->prepare($q[0]); $stmt->execute(['start' => $start_date, 'end' => $end_date]); $sum = 0; while ($r = $stmt->fetch()) { $parts = explode('-', $r['ym']); if (count($parts) == 2) { $response[$q[1]]['labels'][] = $thai_months[$parts[1]] . ' ' . substr((int)$parts[0] + 543, 2, 2); $response[$q[1]]['data'][] = (int)$r['cnt']; $sum += (int)$r['cnt']; } } $response['adjrw_summary'][$q[2]] = $sum; $addLog("กราฟ AdjRW: " . $key, $q[0]); } catch (\Exception $e) { $addLog("กราฟ AdjRW: " . $key, $q[0], $e->getMessage()); } } } echo "---AJAX_IPD_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_IPD_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'); $ipd_filter_html = '
'; ?>