Files
api-antrian-operasi/internal/domain/reference/dokter/repository.go
T
2026-03-03 12:07:44 +07:00

283 lines
7.3 KiB
Go

package dokter
import (
"antrian-operasi/internal/database"
"errors"
"log"
queryUtils "antrian-operasi/internal/utils/query"
"context"
"github.com/jmoiron/sqlx"
)
const DB_NAME = "db_antrian"
const TBL_NAME = "data_pegawai"
const TBL_GELAR_DEPAN = "daftar_gelar_depan"
const TBL_GELAR_BELAKANG = "daftar_gelar_belakang"
const TBL_RELASI_GELAR_DEPAN = "data_pegawai_daftar_gelar_depan"
const TBL_RELASI_GELAR_BLKG = "data_pegawai_daftar_gelar_belakang"
type IDokterRepository interface {
SearchableListDokter(c context.Context, search string, limit int, offset int) (ListDokterModelPaginate, error)
GetDokterById(c context.Context, id string) (DokterModel, error)
}
type dokterRepo struct {
queryBuilder *queryUtils.QueryBuilder
db database.Service
}
func NewRepository(dbService database.Service) IDokterRepository {
queryBuilder := queryUtils.NewQueryBuilder(queryUtils.DBTypePostgreSQL).
SetAllowedColumns([]string{
"id",
"nip",
"nama_depan",
"nama_belakang",
"hfis_code",
"nama_ksm",
})
queryBuilder.SetSecurityOptions(false, 100)
return dokterRepo{
queryBuilder: queryBuilder,
db: dbService,
}
}
func baseSelectQuery() queryUtils.DynamicQuery {
query := queryUtils.DynamicQuery{
From: TBL_NAME,
Aliases: "dp",
Fields: []queryUtils.SelectField{
{Expression: "dp.id", Alias: "id"},
{Expression: "dp.NIP", Alias: "nip"},
{Expression: "dp.Nama_depan", Alias: "nama_depan"},
{Expression: "dp.Nama_belakang", Alias: "nama_belakang"},
{Expression: "HFIS_code", Alias: "hfis_code"},
{Expression: "dk.Nama_ksm", Alias: "nama_ksm"},
},
}
query.Joins = []queryUtils.Join{
{
Type: "LEFT",
Table: "daftar_ksm",
Alias: "dk",
OnConditions: queryUtils.FilterGroup{
Filters: []queryUtils.DynamicFilter{
{
Column: "dk.id", Operator: queryUtils.OpEqual, Value: "dp.KSM",
},
},
},
},
}
return query
}
func FetchGelar(c context.Context, qb *queryUtils.QueryBuilder, dbconn *sqlx.DB, listDokter []DokterModel) []DokterModel {
var listGelarDepan []GelarModel
var listGelarBelakang []GelarModel
dokterIds := make([]string, 0, len(listDokter))
for _, dokter := range listDokter {
dokterIds = append(dokterIds, dokter.ID)
}
queryGelarDepan := queryUtils.DynamicQuery{
Fields: []queryUtils.SelectField{
{Expression: "rgd.data_pegawai_id", Alias: "id_dokter"},
{Expression: "gd.Gelar_depan", Alias: "gelar"},
},
From: TBL_RELASI_GELAR_DEPAN,
Aliases: "rgd",
Joins: []queryUtils.Join{
{
Type: "LEFT",
Table: TBL_GELAR_DEPAN,
Alias: "gd",
OnConditions: queryUtils.FilterGroup{
Filters: []queryUtils.DynamicFilter{
{
Column: "gd.id", Operator: queryUtils.OpEqual, Value: "rgd.daftar_gelar_depan_id",
},
},
},
},
},
Filters: []queryUtils.FilterGroup{
{
Filters: []queryUtils.DynamicFilter{
{
Column: "rgd.data_pegawai_id", Operator: queryUtils.OpIn, Value: dokterIds,
},
},
},
},
}
queryGelarBelakang := queryUtils.DynamicQuery{
Fields: []queryUtils.SelectField{
{Expression: "rgb.data_pegawai_id", Alias: "id_dokter"},
{Expression: "gb.Gelar_belakang", Alias: "gelar"},
},
From: TBL_RELASI_GELAR_BLKG,
Aliases: "rgb",
Joins: []queryUtils.Join{
{
Type: "LEFT",
Table: TBL_GELAR_BELAKANG,
Alias: "gb",
OnConditions: queryUtils.FilterGroup{
Filters: []queryUtils.DynamicFilter{
{
Column: "gb.id", Operator: queryUtils.OpEqual, Value: "rgb.daftar_gelar_belakang_id",
},
},
},
},
},
Filters: []queryUtils.FilterGroup{
{
Filters: []queryUtils.DynamicFilter{
{
Column: "rgb.data_pegawai_id", Operator: queryUtils.OpIn, Value: dokterIds,
},
},
},
},
}
err := qb.ExecuteQuery(c, dbconn, queryGelarDepan, &listGelarDepan)
if err != nil {
return listDokter
}
err = qb.ExecuteQuery(c, dbconn, queryGelarBelakang, &listGelarBelakang)
if err != nil {
return listDokter
}
mapGelarDepan := make(map[string][]string)
mapGelarBelakang := make(map[string][]string)
for _, g := range listGelarDepan {
mapGelarDepan[g.IDDokter] = append(mapGelarDepan[g.IDDokter], g.Gelar)
}
for _, g := range listGelarBelakang {
mapGelarBelakang[g.IDDokter] = append(mapGelarBelakang[g.IDDokter], g.Gelar)
}
for idx := range listDokter {
listDokter[idx].GelarDepan = mapGelarDepan[listDokter[idx].ID]
listDokter[idx].GelarBelakang = mapGelarBelakang[listDokter[idx].ID]
}
return listDokter
}
func (r dokterRepo) SearchableListDokter(c context.Context, search string, limit int, offset int) (ListDokterModelPaginate, error) {
var result ListDokterModelPaginate
// base query
query := baseSelectQuery()
// base filtering
var baseFilter []queryUtils.DynamicFilter
baseFilter = append(baseFilter, queryUtils.DynamicFilter{Column: "dp.KSM", Operator: queryUtils.OpNotNull})
// filtering search results
if search != "" {
searchFilters := []queryUtils.DynamicFilter{
{Column: "dp.Nama_depan", Operator: queryUtils.OpILike, Value: "%" + search + "%"},
{Column: "dp.NIP", Operator: queryUtils.OpILike, Value: "%" + search + "%"},
{Column: "dp.Nama_belakang", Operator: queryUtils.OpILike, Value: "%" + search + "%"},
{Column: "dk.Nama_ksm", Operator: queryUtils.OpILike, Value: "%" + search + "%"},
}
query.Filters = append(query.Filters, queryUtils.FilterGroup{Filters: searchFilters, LogicOp: "OR"})
}
if len(baseFilter) > 0 {
query.Filters = append(query.Filters, queryUtils.FilterGroup{Filters: baseFilter, LogicOp: "AND"})
}
dbconn, err := r.db.GetSQLXDB(DB_NAME)
if err != nil {
// log.Fatalf("unable to connect db %s", err)
return result, err
}
// query count
countData, err := r.queryBuilder.ExecuteCount(c, dbconn, query)
if err != nil {
log.Printf("Unable to execute query count : %s ", err)
return result, err
}
result.Paging.Limit = limit
result.Paging.Offset = offset
result.Paging.Total = int(countData)
result.Paging.CalculatePagingInfo()
// query data
queryData := query
queryData.Limit = limit
queryData.Offset = offset
err = r.queryBuilder.ExecuteQuery(
c, dbconn, queryData, &result.Data)
if err != nil {
// log.Fatalf("unable to execute query %s", err)
return result, err
}
result.Data = FetchGelar(c, r.queryBuilder, dbconn, result.Data)
return result, nil
}
func (r dokterRepo) GetDokterById(c context.Context, id string) (DokterModel, error) {
var resultQuery []DokterModel
var result DokterModel
// base query
query := baseSelectQuery()
// LIMIT 1
query.Limit = 1
// base filtering
var baseFilter []queryUtils.DynamicFilter
baseFilter = append(baseFilter, queryUtils.DynamicFilter{Column: "dp.KSM", Operator: queryUtils.OpNotNull})
// filter by id
baseFilter = append(baseFilter, queryUtils.DynamicFilter{Column: "dp.id", Operator: queryUtils.OpEqual, Value: id})
query.Filters = append(query.Filters, queryUtils.FilterGroup{Filters: baseFilter, LogicOp: "AND"})
dbconn, err := r.db.GetSQLXDB(DB_NAME)
if err != nil {
// log.Fatalf("unable to connect db %s", err) // TODO : handling error
return result, err
}
err = r.queryBuilder.ExecuteQuery(
c, dbconn, query, &resultQuery)
if err != nil {
// log.Fatalf("unable to execute query %s", err)
return result, err
}
if len(resultQuery) == 0 {
notFoundError := errors.New("doctor not found")
return result, notFoundError
}
return resultQuery[0], nil
}