Files
cpone_dashboard/cpone-dashboard/menu/result/query.go
2026-07-17 14:53:23 +07:00

178 lines
4.8 KiB
Go

package result
import (
"cpone-dashboard/db"
"strings"
)
type ResultRow struct {
NIP string
Name string
Posisi string
PacketCode string
PacketName string
Tests string
FileUrl string
ReportDate string
ReportVersion string
}
type ResultSummary struct {
Total int
HasPDF int
}
func GetResultRows(mcuID int) ([]ResultRow, error) {
rows, err := db.DB.Query(`
SELECT
COALESCE(NULLIF(TRIM(mp.Mcu_PatientNIP), ''), '-') AS nip,
COALESCE(NULLIF(TRIM(mp.Mcu_PatientName), ''), '-') AS name,
COALESCE(
NULLIF(TRIM(mp.Mcu_PatientDepartment), ''),
NULLIF(TRIM(mp.Mcu_PatientDivision), ''),
NULLIF(TRIM(mp.Mcu_PatientPosisi), ''),
'-'
) AS posisi,
COALESCE((
SELECT GROUP_CONCAT(DISTINCT COALESCE(NULLIF(TRIM(pp.Mcu_PatientPacketCode), ''), pp.Mcu_PatientPacketName) ORDER BY COALESCE(NULLIF(TRIM(pp.Mcu_PatientPacketCode), ''), pp.Mcu_PatientPacketName) SEPARATOR ',')
FROM mcu_patient_packet pp
WHERE pp.Mcu_PatientPacketPreregisterID = mp.Mcu_PatientPreregisterID
), '') AS packet_code,
COALESCE((
SELECT GROUP_CONCAT(DISTINCT pp.Mcu_PatientPacketName ORDER BY pp.Mcu_PatientPacketName SEPARATOR ', ')
FROM mcu_patient_packet pp
WHERE pp.Mcu_PatientPacketPreregisterID = mp.Mcu_PatientPreregisterID
), '') AS packet_name,
COALESCE(NULLIF(TRIM(mp.Mcu_PatientPemeriksaan), ''), '') AS tests,
COALESCE(p.Published_McuDasboardFileUrl, '') AS file_url,
CASE
WHEN p.Published_McuDasboardFileUrl IS NOT NULL
AND p.Published_McuDasboardFileUrl != ''
THEN COALESCE(CAST(p.Published_McuDasboardLastUpdated AS CHAR), '')
ELSE ''
END AS report_date,
CASE
WHEN p.Published_McuDasboardFileUrl IS NOT NULL
AND p.Published_McuDasboardFileUrl != ''
THEN COALESCE(CAST(UNIX_TIMESTAMP(p.Published_McuDasboardLastUpdated) AS CHAR), '')
ELSE ''
END AS report_version
FROM mcu_patient mp
LEFT JOIN published_mcu_dashboard_sync p
ON p.Published_McuDasboardT_OrderHeaderID = mp.Mcu_PatientOrderID
WHERE mp.Mcu_PatientMcuID = ?
AND mp.Mcu_PatientIsActive = 'Y'
ORDER BY
(p.Published_McuDasboardFileUrl IS NOT NULL AND p.Published_McuDasboardFileUrl != '') DESC,
mp.Mcu_PatientName ASC
`, mcuID)
if err != nil {
return nil, err
}
defer rows.Close()
var result []ResultRow
for rows.Next() {
var r ResultRow
if err := rows.Scan(&r.NIP, &r.Name, &r.Posisi, &r.PacketCode, &r.PacketName, &r.Tests, &r.FileUrl, &r.ReportDate, &r.ReportVersion); err != nil {
continue
}
result = append(result, r)
}
return result, rows.Err()
}
func BuildResultSummary(rows []ResultRow) ResultSummary {
s := ResultSummary{Total: len(rows)}
for _, r := range rows {
if r.FileUrl != "" {
s.HasPDF++
}
}
return s
}
func FilterResultRows(rows []ResultRow, search, filter, packetCode string) []ResultRow {
search = strings.ToLower(strings.TrimSpace(search))
filter = strings.TrimSpace(filter)
packetCode = strings.TrimSpace(packetCode)
if search == "" && filter == "" && packetCode == "" {
return rows
}
out := make([]ResultRow, 0, len(rows))
for _, r := range rows {
if packetCode != "" && r.PacketCode != packetCode {
continue
}
switch filter {
case "has_pdf":
if r.FileUrl == "" {
continue
}
case "no_pdf":
if r.FileUrl != "" {
continue
}
}
if search != "" {
hay := strings.ToLower(r.Name + " " + r.NIP + " " + r.Posisi + " " + r.PacketCode + " " + r.PacketName + " " + r.Tests)
if !strings.Contains(hay, search) {
continue
}
}
out = append(out, r)
}
return out
}
type PacketOption struct {
Code string
Name string
}
func UniquePackets(rows []ResultRow) []PacketOption {
seen := map[string]struct{}{}
out := []PacketOption{}
for _, r := range rows {
code := strings.TrimSpace(r.PacketCode)
if code == "" {
continue
}
if _, ok := seen[code]; ok {
continue
}
seen[code] = struct{}{}
name := strings.TrimSpace(r.PacketName)
if name == "" {
name = code
}
out = append(out, PacketOption{Code: code, Name: name})
}
for i := 0; i < len(out); i++ {
for j := i + 1; j < len(out); j++ {
if out[j].Code < out[i].Code {
out[i], out[j] = out[j], out[i]
}
}
}
return out
}
func PaginateResultRows(rows []ResultRow, page, pageSize int) ([]ResultRow, bool) {
if page < 1 {
page = 1
}
if pageSize < 1 {
pageSize = 30
}
start := (page - 1) * pageSize
if start >= len(rows) {
return []ResultRow{}, false
}
end := start + pageSize
if end > len(rows) {
end = len(rows)
}
return rows[start:end], end < len(rows)
}