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 }