feat: add search and pagination to tariff period services

This commit is contained in:
2026-09-02 09:27:23 +07:00
parent 1d5bc309c0
commit 181d53af45
8 changed files with 560 additions and 8 deletions

View File

@@ -0,0 +1,176 @@
package repository
import (
"context"
"database/sql"
"fmt"
"strconv"
)
type PeriodeTarif struct {
PeriodeTarifID int64 `json:"PeriodeTarifID"`
Keterangan *string `json:"Keterangan"`
TanggalBerlaku string `json:"TanggalBerlaku"`
TanggalBerakhir string `json:"TanggalBerakhir"`
}
func (r MySQLLayananRepository) ListPeriodeTarif(ctx context.Context) ([]PeriodeTarif, error) {
rows, err := r.db.QueryContext(ctx, `
SELECT PeriodeTarifID, Keterangan,
CAST(TanggalBerlaku AS CHAR), CAST(TanggalBerakhir AS CHAR)
FROM periode_tarif
WHERE NA = 'N'
ORDER BY Keterangan ASC, PeriodeTarifID ASC
`)
if err != nil {
return nil, err
}
defer rows.Close()
result := make([]PeriodeTarif, 0)
for rows.Next() {
var item PeriodeTarif
var keterangan sql.NullString
if err := rows.Scan(&item.PeriodeTarifID, &keterangan,
&item.TanggalBerlaku, &item.TanggalBerakhir); err != nil {
return nil, err
}
item.Keterangan = nullStringPtr(keterangan)
result = append(result, item)
}
if err := rows.Err(); err != nil {
return nil, err
}
return result, nil
}
type PeriodeTarifLayanan struct {
TarifLayananID int64 `json:"TarifLayananID"`
LayananID *string `json:"LayananID"`
NamaLayanan *string `json:"NamaLayanan"`
LayananDepartemenID int64 `json:"LayananDepartemenID"`
Departemen *string `json:"Departemen"`
Kelas string `json:"Kelas"`
NamaKelas *string `json:"NamaKelas"`
Harga *string `json:"Harga"`
TipeShare *string `json:"TipeShare"`
ShareDokter *string `json:"ShareDokter"`
ShareRS *string `json:"ShareRS"`
ShareExternal *string `json:"ShareExternal"`
ShareLain *string `json:"ShareLain"`
}
type PeriodeTarifLayananListParams struct {
PeriodeTarifID int64
Page int
PerPage int
Search string
}
type PeriodeTarifLayananPage struct {
Items []PeriodeTarifLayanan
Total int
}
func (r MySQLLayananRepository) ListPeriodeTarifLayanan(ctx context.Context, params PeriodeTarifLayananListParams) (PeriodeTarifLayananPage, error) {
tableName := "harga_layanan_" + strconv.FormatInt(params.PeriodeTarifID, 10)
exists, err := r.tableExists(ctx, tableName)
if err != nil {
return PeriodeTarifLayananPage{}, err
}
if !exists {
return PeriodeTarifLayananPage{}, ErrTarifTableNotFound
}
where := `
WHERE tarif.NA = 'N'
AND layanan_dept.NA = 'N'`
args := make([]any, 0, 4)
if params.Search != "" {
where += `
AND (layanan_dept.LayananID LIKE ? OR layanan.Nama LIKE ?)`
like := "%" + params.Search + "%"
args = append(args, like, like)
}
countQuery := fmt.Sprintf(`
SELECT COUNT(*)
FROM %s AS tarif
INNER JOIN layanandepartemen AS layanan_dept
ON layanan_dept.LayananDepartemenID = tarif.LayananDepartemenID
LEFT JOIN masterlayanan AS layanan
ON layanan.LayananID = layanan_dept.LayananID
%s
`, tableName, where)
var total int
if err := r.db.QueryRowContext(ctx, countQuery, args...).Scan(&total); err != nil {
return PeriodeTarifLayananPage{}, err
}
query := fmt.Sprintf(`
SELECT
tarif.HargaLayananID,
layanan_dept.LayananID,
layanan.Nama,
tarif.LayananDepartemenID,
departemen.Nama,
tarif.KelasID,
kelas.Nama,
CAST(tarif.Harga AS CHAR),
tarif.ShareTipe,
CAST(tarif.ShareDokter AS CHAR),
CAST(tarif.ShareRS AS CHAR),
CAST(tarif.ShareExternal AS CHAR),
CAST(tarif.ShareLain AS CHAR)
FROM %s AS tarif
INNER JOIN layanandepartemen AS layanan_dept
ON layanan_dept.LayananDepartemenID = tarif.LayananDepartemenID
LEFT JOIN masterlayanan AS layanan
ON layanan.LayananID = layanan_dept.LayananID
LEFT JOIN departemen AS departemen
ON departemen.DepartemenID = layanan_dept.DepartemenID
LEFT JOIN kelas AS kelas
ON kelas.KelasID = tarif.KelasID
%s
ORDER BY layanan.Nama, layanan_dept.LayananID, tarif.KelasID, tarif.HargaLayananID
LIMIT ? OFFSET ?
`, tableName, where)
args = append(args, params.PerPage, (params.Page-1)*params.PerPage)
rows, err := r.db.QueryContext(ctx, query, args...)
if err != nil {
return PeriodeTarifLayananPage{}, err
}
defer rows.Close()
result := make([]PeriodeTarifLayanan, 0)
for rows.Next() {
var item PeriodeTarifLayanan
var layananID, namaLayanan, departemen, namaKelas, harga sql.NullString
var tipeShare, shareDokter, shareRS, shareExternal, shareLain sql.NullString
if err := rows.Scan(
&item.TarifLayananID, &layananID, &namaLayanan,
&item.LayananDepartemenID, &departemen, &item.Kelas, &namaKelas,
&harga, &tipeShare, &shareDokter, &shareRS, &shareExternal, &shareLain,
); err != nil {
return PeriodeTarifLayananPage{}, err
}
item.LayananID = nullStringPtr(layananID)
item.NamaLayanan = nullStringPtr(namaLayanan)
item.Departemen = nullStringPtr(departemen)
item.NamaKelas = nullStringPtr(namaKelas)
item.Harga = nullStringPtr(harga)
item.TipeShare = nullStringPtr(tipeShare)
item.ShareDokter = nullStringPtr(shareDokter)
item.ShareRS = nullStringPtr(shareRS)
item.ShareExternal = nullStringPtr(shareExternal)
item.ShareLain = nullStringPtr(shareLain)
result = append(result, item)
}
if err := rows.Err(); err != nil {
return PeriodeTarifLayananPage{}, err
}
return PeriodeTarifLayananPage{Items: result, Total: total}, nil
}