156 lines
4.4 KiB
Go
156 lines
4.4 KiB
Go
package aplicare
|
|
|
|
import (
|
|
"api-service/internal/database"
|
|
"context"
|
|
"database/sql"
|
|
"fmt"
|
|
)
|
|
|
|
type Ruangan struct {
|
|
No int `db:"no"`
|
|
Nama string `db:"nama"`
|
|
JumlahTT int `db:"jumlah_tt"`
|
|
KodeRuang sql.NullString `db:"kode_aplicare"` // diisi manual, dikirim ke BPJS
|
|
NamaRuang sql.NullString `db:"nama_ruang"` // diisi manual, dikirim ke BPJS
|
|
KelasRuang sql.NullString `db:"kode_kelas"` // diisi manual, dikirim ke BPJS
|
|
}
|
|
|
|
// BedDetail adalah data dari tabel m_detail_tempat_tidur
|
|
// Setiap row = 1 bed yang sedang terisi
|
|
// idxruang bertipe varchar di DB, relasi ke m_ruang.no (integer)
|
|
type BedDetail struct {
|
|
IdxRuang string `db:"idxruang"`
|
|
}
|
|
|
|
// =============================================
|
|
// SIMRS READER
|
|
// =============================================
|
|
|
|
type SimrsDB struct {
|
|
db database.Service
|
|
}
|
|
|
|
func NewSimrsDB(db database.Service) *SimrsDB {
|
|
return &SimrsDB{db: db}
|
|
}
|
|
|
|
// GetRuangan membaca semua ruangan aktif dari m_ruang
|
|
// Hanya ruangan yang sudah di-mapping manual (kode_ruang + kode_kelas tidak kosong)
|
|
func (s *SimrsDB) GetRuangan(ctx context.Context) ([]Ruangan, error) {
|
|
db, err := s.db.GetDB("simrs")
|
|
if err != nil {
|
|
return nil, fmt.Errorf("koneksi simrs gagal: %w", err)
|
|
}
|
|
|
|
query := `
|
|
SELECT no, nama, jumlah_tt,kode_aplicare, nama_ruang, kode_kelas
|
|
FROM m_ruang
|
|
where st_aktif = 1 AND kode_aplicare IS NOT NULL
|
|
ORDER BY no
|
|
`
|
|
|
|
rows, err := db.QueryContext(ctx, query)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("query m_ruang gagal: %w", err)
|
|
}
|
|
defer rows.Close()
|
|
|
|
var result []Ruangan
|
|
for rows.Next() {
|
|
var r Ruangan
|
|
if err := rows.Scan(
|
|
&r.No, &r.Nama, &r.JumlahTT,
|
|
&r.KodeRuang, &r.NamaRuang, &r.KelasRuang,
|
|
); err != nil {
|
|
return nil, fmt.Errorf("scan m_ruang gagal: %w", err)
|
|
}
|
|
result = append(result, r)
|
|
}
|
|
return result, rows.Err()
|
|
}
|
|
|
|
// GetBedDetails membaca semua bed yang terisi dari m_detail_tempat_tidur
|
|
// Return map[idxruang][]BedDetail — dikelompokkan per ruangan
|
|
// Setiap row = 1 bed terisi, COUNT per idxruang = total terisi
|
|
func (s *SimrsDB) GetBedDetails(ctx context.Context) (map[string][]BedDetail, error) {
|
|
db, err := s.db.GetDB("simrs")
|
|
if err != nil {
|
|
return nil, fmt.Errorf("koneksi simrs gagal: %w", err)
|
|
}
|
|
|
|
query := `
|
|
SELECT idxruang
|
|
FROM m_detail_tempat_tidur
|
|
WHERE status IN (1, 5)
|
|
ORDER BY idxruang
|
|
`
|
|
|
|
rows, err := db.QueryContext(ctx, query)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("query m_detail_tempat_tidur gagal: %w", err)
|
|
}
|
|
defer rows.Close()
|
|
|
|
result := make(map[string][]BedDetail)
|
|
for rows.Next() {
|
|
var d BedDetail
|
|
if err := rows.Scan(&d.IdxRuang); err != nil {
|
|
return nil, fmt.Errorf("scan m_detail_tempat_tidur gagal: %w", err)
|
|
}
|
|
result[d.IdxRuang] = append(result[d.IdxRuang], d)
|
|
}
|
|
return result, rows.Err()
|
|
}
|
|
|
|
// =============================================
|
|
// TRANSFORM
|
|
// =============================================
|
|
|
|
// BedData adalah hasil agregasi per ruangan — siap kirim ke BPJS
|
|
type BedData struct {
|
|
No int `json:"no"`
|
|
KodeKelas string `json:"kodekelas"`
|
|
KodeRuang string `json:"koderuang"`
|
|
NamaRuang string `json:"namaruang"`
|
|
Kapasitas int `json:"kapasitas"`
|
|
Tersedia int `json:"tersedia"`
|
|
TersediaPria int `json:"tersediapria"`
|
|
TersediaWanita int `json:"tersediawanita"`
|
|
TersediaPriaWanita int `json:"tersediapriawanita"`
|
|
}
|
|
|
|
// buildBedData mengubah data SIMRS menjadi BedData siap kirim ke BPJS
|
|
// tersedia = jumlah_tt - COUNT(row di m_detail per ruangan)
|
|
// karena setiap row di m_detail = 1 bed yang terisi
|
|
func buildBedData(ruangans []Ruangan, detailMap map[string][]BedDetail) []BedData {
|
|
var result []BedData
|
|
for _, r := range ruangans {
|
|
// detailMap berisi semua bed yang tidak tersedia (status != 0)
|
|
// tersedia = jumlah_tt - jumlah yang tidak tersedia
|
|
terisi := len(detailMap[fmt.Sprintf("%d", r.No)])
|
|
tersedia := r.JumlahTT - terisi
|
|
if tersedia < 0 {
|
|
tersedia = 0
|
|
}
|
|
|
|
// Skip ruangan dengan kapasitas 0 — tidak valid untuk dikirim ke BPJS
|
|
if r.JumlahTT == 0 {
|
|
continue
|
|
}
|
|
|
|
result = append(result, BedData{
|
|
No: r.No,
|
|
KodeKelas: r.KelasRuang.String,
|
|
KodeRuang: r.KodeRuang.String,
|
|
NamaRuang: r.NamaRuang.String,
|
|
Kapasitas: r.JumlahTT,
|
|
Tersedia: tersedia,
|
|
TersediaPria: 0,
|
|
TersediaWanita: 0,
|
|
TersediaPriaWanita: tersedia,
|
|
})
|
|
}
|
|
return result
|
|
}
|