Files
api_antrean/internal/handlers/master/dokter.go
T
2026-02-13 15:57:28 +07:00

229 lines
6.3 KiB
Go

package master
import (
"api-service/internal/config"
"api-service/internal/database"
"api-service/internal/models"
modelsMaster "api-service/internal/models/master"
"api-service/pkg/logger"
"context"
"fmt"
"github.com/gin-gonic/gin"
"github.com/go-playground/validator/v10"
"github.com/jmoiron/sqlx"
"net/http"
"strconv"
"strings"
"time"
)
func init() {
once.Do(func() {
db = database.New(config.LoadConfig())
validate = validator.New()
// Register custom validations if needed
validate.RegisterValidation("retribusi_status", validateRetribusiStatus)
if db == nil {
logger.Fatal("Failed to initialize database connection")
}
})
}
func validateRetribusiStatus(fl validator.FieldLevel) bool {
return models.IsValidStatus(fl.Field().String())
}
type DokterHandler struct {
db database.Service
}
func NewDokterHandler() *DokterHandler {
return &DokterHandler{
db: db,
}
}
func (h *DokterHandler) GetDokterbyspesialis(c *gin.Context) {
ctx, cancel := context.WithTimeout(c.Request.Context(), 120*time.Second)
defer cancel()
klinikIDStr := c.Param("idklinik")
klinikID, err := strconv.Atoi(klinikIDStr)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid klinik ID"})
return
}
dbAntrean, err := h.db.GetSQLXDB("postgres_antrean")
if err != nil {
logger.Error("Failed to connect postgres_antrean", map[string]interface{}{"error": err.Error()})
c.JSON(http.StatusInternalServerError, gin.H{"error": "Database connection failed"})
return
}
spesialisIDs, err := h.GetSpesialisIDsByKlinik(ctx, dbAntrean, klinikID)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Database connection failed"})
return
}
if len(spesialisIDs) == 0 {
c.JSON(http.StatusOK, modelsMaster.DokterResponse{
Message: "Tidak ada dokter untuk klinik ini",
Data: []*modelsMaster.DokterFormatted{},
Meta: map[string]interface{}{"total": 0},
})
return
}
logger.Info("Spesialis IDs found", map[string]interface{}{
"klinikID": klinikID,
"spesialisIDs": spesialisIDs,
"count": len(spesialisIDs),
})
dbConn, err := h.db.GetSQLXDB("postgres_satudata")
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Database connection failed"})
return
}
dokterList, err := h.GetDokterBySpesialisIDs(ctx, dbConn, spesialisIDs)
if err != nil {
logger.Error("Failed to get dokter data", map[string]interface{}{"error": err.Error()})
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get dokter data"})
return
}
formattedData := h.FormatDokterData(dokterList)
c.JSON(http.StatusOK, modelsMaster.DokterResponse{
Message: "Data dokter berhasil diambil",
Data: formattedData,
Meta: map[string]interface{}{
"total": len(formattedData),
"klinikID": klinikID,
"jumlahSpesialis": len(spesialisIDs),
},
})
}
func (h *DokterHandler) GetSpesialisIDsByKlinik(ctx context.Context, dbConn *sqlx.DB, klinikID int) ([]int, error) {
query := `
SELECT fk_sd_spesialis_id
FROM master.ms_healthcare_service_spesialis
WHERE fk_ms_healthcare_service_id = $1
`
var spesialisIDs []int
err := dbConn.SelectContext(ctx, &spesialisIDs, query, klinikID)
if err != nil {
return nil, fmt.Errorf("failed to get spesialis IDs: %w", err)
}
return spesialisIDs, nil
}
func (h *DokterHandler) FormatDokterData(data []*modelsMaster.ListDokter) []*modelsMaster.DokterFormatted {
result := make([]*modelsMaster.DokterFormatted, 0, len(data))
for _, dokter := range data {
namaLengkap := ""
if dokter.GelarDepan != "" {
gelarDepanList := strings.Split(dokter.GelarDepan, "|")
var formattedGelar []string
for _, gelar := range gelarDepanList {
gelar = strings.TrimSpace(gelar)
if gelar != "" && !strings.HasSuffix(gelar, ".") {
gelar += "."
}
if gelar != "" {
formattedGelar = append(formattedGelar, gelar)
}
}
if len(formattedGelar) > 0 {
namaLengkap = strings.Join(formattedGelar, " ") + " "
}
}
namaLengkap += strings.TrimSpace(dokter.NamaLengkap)
if dokter.GelarBelakang != "" {
gelarBelakangList := strings.Split(dokter.GelarBelakang, "|")
var formattedGelar []string
for _, gelar := range gelarBelakangList {
gelar = strings.TrimSpace(gelar)
if gelar != "" {
formattedGelar = append(formattedGelar, gelar)
}
}
if len(formattedGelar) > 0 {
namaLengkap += ", " + strings.Join(formattedGelar, ", ")
}
}
formatted := &modelsMaster.DokterFormatted{
NamaLengkapFormatted: strings.TrimSpace(namaLengkap),
Spesialis: strings.TrimSpace(dokter.Spesialis),
Subspesialis: strings.TrimSpace(dokter.Subspesialis),
}
result = append(result, formatted)
}
return result
}
func (h *DokterHandler) GetDokterBySpesialisIDs(ctx context.Context, dbConn *sqlx.DB, spesialisIDs []int) ([]*modelsMaster.ListDokter, error) {
query, args, err := sqlx.In(`
SELECT
ARRAY_TO_STRING(
ARRAY(
SELECT dgd."Gelar_depan"
FROM data_pegawai_daftar_gelar_depan dpdgd
LEFT JOIN daftar_gelar_depan dgd ON dpdgd.daftar_gelar_depan_id = dgd.id
WHERE dpdgd.data_pegawai_id = dp.id
), '|'
) AS gelardepan,
COALESCE(dk."Nama_lengkap", '') AS namalengkap,
ARRAY_TO_STRING(
ARRAY(
SELECT dgb."Gelar_belakang"
FROM data_pegawai_daftar_gelar_belakang dpdgb
LEFT JOIN daftar_gelar_belakang dgb ON dpdgb.daftar_gelar_belakang_id = dgb.id
WHERE dpdgb.data_pegawai_id = dp.id
), '|'
) AS gelarbelakang,
ds."Subspesialis",
dss."Spesialis"
FROM "data_pegawai" dp
LEFT JOIN data_ktp dk ON dp."KTP" = dk.id
LEFT JOIN daftar_subspesialis ds ON dp."Subspesialis" = ds.id
LEFT JOIN daftar_spesialis dss ON ds."FK_daftar_spesialis_ID" = dss.id
WHERE dss.id IN (?)
ORDER BY dk."Nama_lengkap" ASC
`, spesialisIDs)
if err != nil {
return nil, fmt.Errorf("failed to build query: %w", err)
}
query = dbConn.Rebind(query)
var dokterList []*modelsMaster.ListDokter
err = dbConn.SelectContext(ctx, &dokterList, query, args...)
if err != nil {
return nil, fmt.Errorf("failed to execute query: %w", err)
}
return dokterList, nil
}