Files
cpone_midleware/internal/http/handler.go

298 lines
8.5 KiB
Go

package http
import (
"context"
"errors"
"net/http"
"regexp"
"strings"
"primaya-api/cpone-middleware/internal/repository"
)
var digitsOnly = regexp.MustCompile(`^\d+$`)
type LayananRepository interface {
ListLayanan(ctx context.Context, params repository.LayananListParams) (repository.LayananPage, error)
MappingHarga(ctx context.Context, params repository.MappingHargaParams) ([]repository.TarifLayanan, error)
}
type LabRegistrationRepository interface {
RegisterLab(ctx context.Context, params repository.LabRegistrationParams) (repository.LabRegistrationOutcome, error)
AddLabServices(ctx context.Context, regID string, params repository.AddLabServicesParams) (repository.LabRegistrationOutcome, error)
AddLabPackage(ctx context.Context, regID string, params repository.AddLabPackageParams) (repository.LabRegistrationOutcome, error)
}
type PatientRepository interface {
StoreMedrec(ctx context.Context, params repository.MedrecParams) (repository.MedrecOutcome, error)
}
type RegistrationRepository interface {
RegisterPatient(ctx context.Context, params repository.RegistrationParams) (repository.RegistrationOutcome, error)
}
type LabResultRepository interface {
GetLabResult(ctx context.Context, labNumber string) (repository.LabResultOutcome, error)
}
type PaketRepository interface {
ListPaket(ctx context.Context, params repository.PaketListParams) (repository.PaketPage, error)
GetPaket(ctx context.Context, id string) (*repository.PaketDetail, error)
CreatePaket(ctx context.Context, params repository.CreatePaketParams) (repository.CreatePaketResult, error)
}
type TarifKerjasamaRepository interface {
ListTarifKerjasama(ctx context.Context, params repository.TarifKerjasamaListParams) (repository.TarifKerjasamaPage, error)
GetTarifKerjasama(ctx context.Context, id int64, params repository.TarifKerjasamaDetailParams) (*repository.TarifKerjasamaDetail, error)
}
type PeriodeTarifRepository interface {
ListPeriodeTarif(ctx context.Context) ([]repository.PeriodeTarif, error)
}
type PeriodeTarifDetailRepository interface {
ListPeriodeTarifLayanan(ctx context.Context, params repository.PeriodeTarifLayananListParams) (repository.PeriodeTarifLayananPage, error)
}
type PerusahaanRepository interface {
ListPerusahaan(ctx context.Context, params repository.PerusahaanListParams) (repository.PerusahaanPage, error)
GetPerusahaan(ctx context.Context, id string) (*repository.PerusahaanDetail, error)
GetPerusahaanGroupTarif(ctx context.Context, id, groupTarifID string) (*repository.PerusahaanGroupTarifDetail, error)
}
type DokterRepository interface {
ListDokter(ctx context.Context, params repository.DokterListParams) (repository.DokterPage, error)
}
type Handler struct {
layananRepo LayananRepository
labRepo LabRegistrationRepository
patientRepo PatientRepository
registrationRepo RegistrationRepository
labResultRepo LabResultRepository
paketRepo PaketRepository
tarifRepo TarifKerjasamaRepository
periodeTarifRepo PeriodeTarifRepository
periodeTarifDetailRepo PeriodeTarifDetailRepository
perusahaanRepo PerusahaanRepository
dokterRepo DokterRepository
hospitalCode string
departmentID string
}
type CPONERepository interface {
LayananRepository
LabRegistrationRepository
PatientRepository
RegistrationRepository
LabResultRepository
PaketRepository
TarifKerjasamaRepository
PeriodeTarifRepository
PeriodeTarifDetailRepository
PerusahaanRepository
DokterRepository
}
func NewHandler(repo CPONERepository) Handler {
return Handler{
layananRepo: repo, labRepo: repo, patientRepo: repo, registrationRepo: repo,
labResultRepo: repo, paketRepo: repo, tarifRepo: repo,
periodeTarifRepo: repo, periodeTarifDetailRepo: repo, perusahaanRepo: repo,
dokterRepo: repo,
}
}
func NewDynamicHandler(hospitalCode string, departmentID string) Handler {
return Handler{
hospitalCode: strings.ToUpper(strings.TrimSpace(hospitalCode)),
departmentID: strings.TrimSpace(departmentID),
}
}
func (h Handler) layananRepository(ctx context.Context) LayananRepository {
if repo, ok := selectedRepository(ctx); ok {
return repo
}
return h.layananRepo
}
func (h Handler) labRepository(ctx context.Context) LabRegistrationRepository {
if repo, ok := selectedRepository(ctx); ok {
return repo
}
return h.labRepo
}
func (h Handler) patientRepository(ctx context.Context) PatientRepository {
if repo, ok := selectedRepository(ctx); ok {
return repo
}
return h.patientRepo
}
func (h Handler) registrationRepository(ctx context.Context) RegistrationRepository {
if repo, ok := selectedRepository(ctx); ok {
return repo
}
return h.registrationRepo
}
func (h Handler) labResultRepository(ctx context.Context) LabResultRepository {
if repo, ok := selectedRepository(ctx); ok {
return repo
}
return h.labResultRepo
}
func (h Handler) paketRepository(ctx context.Context) PaketRepository {
if repo, ok := selectedRepository(ctx); ok {
return repo
}
return h.paketRepo
}
func (h Handler) tarifRepository(ctx context.Context) TarifKerjasamaRepository {
if repo, ok := selectedRepository(ctx); ok {
return repo
}
return h.tarifRepo
}
func (h Handler) periodeTarifRepository(ctx context.Context) PeriodeTarifRepository {
if repo, ok := selectedRepository(ctx); ok {
return repo
}
return h.periodeTarifRepo
}
func (h Handler) periodeTarifDetailRepository(ctx context.Context) PeriodeTarifDetailRepository {
if repo, ok := selectedRepository(ctx); ok {
return repo
}
return h.periodeTarifDetailRepo
}
func (h Handler) perusahaanRepository(ctx context.Context) PerusahaanRepository {
if repo, ok := selectedRepository(ctx); ok {
return repo
}
return h.perusahaanRepo
}
func (h Handler) dokterRepository(ctx context.Context) DokterRepository {
if repo, ok := selectedRepository(ctx); ok {
return repo
}
return h.dokterRepo
}
func (h Handler) MappingHarga(w http.ResponseWriter, r *http.Request) {
layananIDs := parseLayananIDs(r)
if len(layananIDs) == 0 {
WriteJSON(w, http.StatusUnprocessableEntity, Response{
Success: false,
Message: "Parameter layananID wajib diisi dan dapat berupa satu atau beberapa LayananID",
Data: nil,
})
return
}
periodeTarifID, ok := firstQueryValue(r, "periodeTarifID", "periode_tarif_id")
if !ok || strings.TrimSpace(periodeTarifID) == "" {
WriteJSON(w, http.StatusUnprocessableEntity, Response{
Success: false,
Message: "Parameter periodeTarifID wajib diisi",
Data: nil,
})
return
}
periodeTarifID = strings.TrimSpace(periodeTarifID)
if !digitsOnly.MatchString(periodeTarifID) {
WriteJSON(w, http.StatusUnprocessableEntity, Response{
Success: false,
Message: "Parameter periodeTarifID harus berupa angka",
Data: nil,
})
return
}
rows, err := h.layananRepository(r.Context()).MappingHarga(r.Context(), repository.MappingHargaParams{
PeriodeTarifID: periodeTarifID,
LayananIDs: layananIDs,
Search: strings.TrimSpace(r.URL.Query().Get("search")),
})
if err != nil {
if errors.Is(err, repository.ErrTarifTableNotFound) {
WriteJSON(w, http.StatusNotFound, Response{
Success: false,
Message: "Tabel tarif dasar tidak ditemukan: harga_layanan_" + periodeTarifID,
Data: nil,
})
return
}
WriteJSON(w, http.StatusInternalServerError, Response{
Success: false,
Message: "internal server error",
Data: nil,
})
return
}
WriteJSON(w, http.StatusOK, Response{
Success: true,
Message: "ok",
Data: MappingHargaData{
PeriodeTarifID: periodeTarifID,
DetailLayanan: rows,
},
})
}
func parseLayananIDs(r *http.Request) []string {
values := queryValues(r, "layananID", "layananID[]")
if len(values) == 0 {
values = queryValues(r, "layanan_id", "layanan_id[]")
}
seen := make(map[string]struct{}, len(values))
ids := make([]string, 0, len(values))
for _, value := range values {
for _, part := range strings.Split(value, ",") {
id := strings.TrimSpace(part)
if id == "" {
continue
}
if _, exists := seen[id]; exists {
continue
}
seen[id] = struct{}{}
ids = append(ids, id)
}
}
return ids
}
func queryValues(r *http.Request, keys ...string) []string {
query := r.URL.Query()
values := make([]string, 0)
for _, key := range keys {
values = append(values, query[key]...)
}
return values
}
func firstQueryValue(r *http.Request, keys ...string) (string, bool) {
query := r.URL.Query()
for _, key := range keys {
if values, exists := query[key]; exists && len(values) > 0 {
return values[0], true
}
}
return "", false
}