Initial CPONE middleware implementation
This commit is contained in:
134
internal/http/handler.go
Normal file
134
internal/http/handler.go
Normal file
@@ -0,0 +1,134 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"primaya-api/cpone-middleware/internal/repository"
|
||||
)
|
||||
|
||||
var digitsOnly = regexp.MustCompile(`^\d+$`)
|
||||
|
||||
type LayananRepository interface {
|
||||
MappingHarga(ctx context.Context, params repository.MappingHargaParams) ([]repository.TarifLayanan, error)
|
||||
}
|
||||
|
||||
type Handler struct {
|
||||
repo LayananRepository
|
||||
}
|
||||
|
||||
func NewHandler(repo LayananRepository) Handler {
|
||||
return Handler{repo: repo}
|
||||
}
|
||||
|
||||
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.repo.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
|
||||
}
|
||||
Reference in New Issue
Block a user