first commit

This commit is contained in:
2026-02-13 15:57:28 +07:00
parent d4248b62e1
commit 7ae8c76a20
26 changed files with 5040 additions and 32 deletions

No files matched your search

+272
View File
@@ -2147,3 +2147,275 @@ func (h *PasienHandler) calculateMeta(limit, offset, total int) models.MetaRespo
CurrentPage: currentPage, HasNext: offset+limit < total, HasPrev: offset > 0,
}
}
func (h *PasienHandler) GetPasienByNOMR(c *gin.Context) {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
Nomr := c.Param("nomr")
dbConn, err := h.db.GetSQLXDB("postgres_simrs")
if err != nil {
logger.Error("Database connection failed", map[string]interface{}{"error": err.Error()})
c.JSON(http.StatusInternalServerError, gin.H{"error": "Database connection failed"})
return
}
if err != nil {
logger.Error("Database connection failed", map[string]interface{}{"error": err.Error()})
c.JSON(http.StatusInternalServerError, gin.H{"error": "Database connection failed"})
return
}
Pasien, err := h.Getpasien(ctx, dbConn, Nomr)
if err != nil {
if err == sql.ErrNoRows {
c.JSON(http.StatusNotFound, gin.H{
"error": "Pasien tidak ditemukan",
"nomr": Nomr,
})
return
}
logger.Error("Failed to get pasien", map[string]interface{}{
"error": err.Error(),
"nomr": Nomr,
})
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to retrieve pasien data"})
return
}
logger.Info("Pasien data retrieved successfully", map[string]interface{}{
"nomr": Nomr,
"nama": Pasien.NamaLengkap,
})
c.JSON(http.StatusOK, gin.H{
"message": "Data pasien berhasil diambil",
"data": Pasien,
})
}
func (h *PasienHandler) Getpasien(ctx context.Context, dbConn *sqlx.DB, nomr string) (*pasienModels.PasienData, error) {
query := `
SELECT
mp.nomr,
mp.nama,
mp.notelp,
mp.jeniskelamin,
mp.tgllahir,
mp.alamat,
COALESCE(mp2.idprovinsi, 0) as idprovinsi,
COALESCE(mp2.namaprovinsi, '') as namaprovinsi,
COALESCE(mk2.idkota, 0) as idkota,
COALESCE(mk2.namakota, '') as namakota,
COALESCE(mk.idkecamatan, 0) as idkecamatan,
COALESCE(mk.namakecamatan, '') as namakecamatan,
COALESCE(mk3.idkelurahan, 0) as idkelurahan,
COALESCE(mk3.namakelurahan, '') as namakelurahan
FROM m_pasien mp
LEFT JOIN m_provinsi mp2 ON mp.kdprovinsi = mp2.idprovinsi
LEFT JOIN m_kecamatan mk ON mp.kdkecamatan = mk.idkecamatan
LEFT JOIN m_kota mk2 ON mk.idkota = mk2.idkota
LEFT JOIN m_kelurahan mk3 ON mp.kelurahan = mk3.idkelurahan
WHERE mp.nomr = $1
`
var pasien pasienModels.PasienData
err := dbConn.QueryRowContext(ctx, query, nomr).Scan(
&pasien.Nomr,
&pasien.NamaLengkap,
&pasien.NoTelp,
&pasien.JenisKelamin,
&pasien.TTL,
&pasien.Alamat,
&pasien.IdProvinsi,
&pasien.NamaProvinsi,
&pasien.IdKota,
&pasien.NamaKota,
&pasien.IdKecamatan,
&pasien.NamaKecamatan,
&pasien.IdKelurahan,
&pasien.NamaKelurahan,
)
if err != nil {
if err == sql.ErrNoRows {
return nil, sql.ErrNoRows
}
return nil, fmt.Errorf("failed to query pasien: %w", err)
}
logger.Info("Pasien query executed successfully", map[string]interface{}{
"nomr": nomr,
"nama": pasien.NamaLengkap,
})
return &pasien, nil
}
func (h *PasienHandler) SearchPasienByNama(c *gin.Context) {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
// Get query parameter
nama := c.Query("nama")
// Validasi minimal 2 karakter untuk search
if len(nama) < 2 {
c.JSON(http.StatusBadRequest, gin.H{
"error": "Minimal 2 karakter untuk pencarian",
"message": "Silahkan ketik minimal 2 huruf",
})
return
}
dbConn, err := h.db.GetSQLXDB("postgres_simrs")
if err != nil {
logger.Error("Database connection failed", map[string]interface{}{"error": err.Error()})
c.JSON(http.StatusInternalServerError, gin.H{"error": "Database connection failed"})
return
}
// Search pasien by nama
pasienList, err := h.GetPasienByNamaPattern(ctx, dbConn, nama)
if err != nil {
if err == sql.ErrNoRows {
c.JSON(http.StatusOK, gin.H{
"message": "Tidak ada pasien ditemukan",
"data": []pasienModels.PasienData{},
"meta": map[string]interface{}{
"total": 0,
"search_query": nama,
},
})
return
}
logger.Error("Failed to search pasien", map[string]interface{}{
"error": err.Error(),
"nama": nama,
})
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to search pasien"})
return
}
logger.Info("Pasien search completed", map[string]interface{}{
"search_query": nama,
"total_found": len(pasienList),
})
c.JSON(http.StatusOK, gin.H{
"message": "Data pasien berhasil ditemukan",
"data": pasienList,
"meta": map[string]interface{}{
"total": len(pasienList),
"search_query": nama,
},
})
}
func (h *PasienHandler) GetPasienByNamaPattern(ctx context.Context, dbConn *sqlx.DB, namaPattern string) ([]*pasienModels.PasienData, error) {
searchPattern := "%" + namaPattern + "%"
query := `
SELECT
mp.nomr,
mp.nama,
mp.notelp,
mp.jeniskelamin,
mp.tgllahir,
mp.alamat,
mp2.idprovinsi,
mp2.namaprovinsi,
mk2.idkota,
mk2.namakota,
mk.idkecamatan,
mk.namakecamatan,
mk3.idkelurahan,
mk3.namakelurahan
FROM m_pasien mp
LEFT JOIN m_provinsi mp2 ON mp.kdprovinsi = mp2.idprovinsi
LEFT JOIN m_kecamatan mk ON mp.kdkecamatan = mk.idkecamatan
LEFT JOIN m_kota mk2 ON mk.idkota = mk2.idkota
LEFT JOIN m_kelurahan mk3 ON mp.kelurahan = mk3.idkelurahan
WHERE mp.nama ILIKE $1
ORDER BY mp.nama ASC
LIMIT 1
`
rows, err := dbConn.QueryContext(ctx, query, searchPattern)
if err != nil {
return nil, fmt.Errorf("failed to execute search query: %w", err)
}
defer rows.Close()
var pasienList []*pasienModels.PasienData
for rows.Next() {
var pasien pasienModels.PasienData
err := rows.Scan(
&pasien.Nomr,
&pasien.NamaLengkap,
&pasien.NoTelp,
&pasien.JenisKelamin,
&pasien.TTL,
&pasien.Alamat,
&pasien.IdProvinsi,
&pasien.NamaProvinsi,
&pasien.IdKota,
&pasien.NamaKota,
&pasien.IdKecamatan,
&pasien.NamaKecamatan,
&pasien.IdKelurahan,
&pasien.NamaKelurahan,
)
if err != nil {
return nil, fmt.Errorf("failed to scan row: %w", err)
}
// Clean strings
pasien.Nomr = cleanString(pasien.Nomr)
pasien.NamaLengkap = cleanString(pasien.NamaLengkap)
pasien.NoTelp = cleanString(pasien.NoTelp)
pasien.JenisKelamin = cleanString(pasien.JenisKelamin)
pasien.Alamat = cleanString(pasien.Alamat)
pasien.NamaProvinsi = cleanString(pasien.NamaProvinsi)
pasien.NamaKota = cleanString(pasien.NamaKota)
pasien.NamaKecamatan = cleanString(pasien.NamaKecamatan)
pasien.NamaKelurahan = cleanString(pasien.NamaKelurahan)
pasienList = append(pasienList, &pasien)
}
if err = rows.Err(); err != nil {
return nil, fmt.Errorf("rows iteration error: %w", err)
}
if len(pasienList) == 0 {
return nil, sql.ErrNoRows
}
logger.Info("Search query executed successfully", map[string]interface{}{
"pattern": namaPattern,
"found": len(pasienList),
})
return pasienList, nil
}
func cleanString(s string) string {
// Trim leading dan trailing whitespace
s = strings.TrimSpace(s)
// Replace newline, carriage return, dan tab di tengah string dengan single space
s = strings.ReplaceAll(s, "\n", " ")
s = strings.ReplaceAll(s, "\r", " ")
s = strings.ReplaceAll(s, "\t", " ")
// Replace multiple spaces dengan single space
s = strings.Join(strings.Fields(s), " ")
return s
}