182 lines
5.2 KiB
Go
182 lines
5.2 KiB
Go
package http
|
|
|
|
import (
|
|
"net/http"
|
|
"net/url"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"primaya-api/cpone-middleware/internal/repository"
|
|
)
|
|
|
|
type PaketValidationResponse struct {
|
|
Success bool `json:"success"`
|
|
Status string `json:"status"`
|
|
Message string `json:"message"`
|
|
Data any `json:"data"`
|
|
}
|
|
|
|
type PaketPaginationResponse struct {
|
|
CurrentPage int `json:"current_page"`
|
|
Data []repository.PaketSummary `json:"data"`
|
|
FirstPageURL string `json:"first_page_url"`
|
|
From *int `json:"from"`
|
|
LastPage int `json:"last_page"`
|
|
LastPageURL string `json:"last_page_url"`
|
|
Links map[string]any `json:"links"`
|
|
NextPageURL *string `json:"next_page_url"`
|
|
Total int `json:"total"`
|
|
PerPage int `json:"per_page"`
|
|
}
|
|
|
|
func (h Handler) ListPaket(w http.ResponseWriter, r *http.Request) {
|
|
params, message := parsePaketListParams(r)
|
|
if message != "" {
|
|
writePaketValidationError(w, message)
|
|
return
|
|
}
|
|
|
|
page, err := h.paketRepository(r.Context()).ListPaket(r.Context(), params)
|
|
if err != nil {
|
|
WriteJSON(w, http.StatusInternalServerError, Response{
|
|
Success: false, Message: "internal server error", Data: nil,
|
|
})
|
|
return
|
|
}
|
|
|
|
lastPage := (page.Total + params.PerPage - 1) / params.PerPage
|
|
if lastPage < 1 {
|
|
lastPage = 1
|
|
}
|
|
var from *int
|
|
if len(page.Items) > 0 {
|
|
value := (params.Page-1)*params.PerPage + 1
|
|
from = &value
|
|
}
|
|
var nextPageURL *string
|
|
if params.Page < lastPage {
|
|
value := currentRequestURL(r, params.Page+1)
|
|
nextPageURL = &value
|
|
}
|
|
|
|
WriteJSON(w, http.StatusOK, PaketPaginationResponse{
|
|
CurrentPage: params.Page,
|
|
Data: page.Items,
|
|
FirstPageURL: "",
|
|
From: from,
|
|
LastPage: lastPage,
|
|
LastPageURL: "",
|
|
Links: map[string]any{},
|
|
NextPageURL: nextPageURL,
|
|
Total: page.Total,
|
|
PerPage: params.PerPage,
|
|
})
|
|
}
|
|
|
|
func (h Handler) GetPaket(w http.ResponseWriter, r *http.Request) {
|
|
id := strings.TrimSpace(r.PathValue("id"))
|
|
paket, err := h.paketRepository(r.Context()).GetPaket(r.Context(), id)
|
|
if err != nil {
|
|
WriteJSON(w, http.StatusInternalServerError, Response{
|
|
Success: false, Message: "internal server error", Data: nil,
|
|
})
|
|
return
|
|
}
|
|
if paket == nil {
|
|
WriteJSON(w, http.StatusNotFound, Response{
|
|
Success: false, Message: "Data tidak ditemukan", Data: nil,
|
|
})
|
|
return
|
|
}
|
|
|
|
WriteJSON(w, http.StatusOK, Response{Success: true, Message: "ok", Data: paket})
|
|
}
|
|
|
|
func parsePaketListParams(r *http.Request) (repository.PaketListParams, string) {
|
|
query := r.URL.Query()
|
|
params := repository.PaketListParams{
|
|
Search: query.Get("search"), Code: query.Get("code"),
|
|
CareType: query.Get("care_type"), Active: query.Get("active"),
|
|
StartDate: query.Get("start_date"), EndDate: query.Get("end_date"),
|
|
Status: 2, Page: 1, PerPage: 15,
|
|
}
|
|
|
|
if params.CareType != "" && params.CareType != "RI" && params.CareType != "RJ" {
|
|
return params, "The selected care type is invalid."
|
|
}
|
|
if raw, exists := firstQueryValue(r, "status"); exists && raw != "" {
|
|
value, err := strconv.Atoi(raw)
|
|
if err != nil {
|
|
return params, "The status must be an integer."
|
|
}
|
|
if value < -1 || value > 2 {
|
|
return params, "The selected status is invalid."
|
|
}
|
|
params.Status = value
|
|
}
|
|
if params.Active != "" && params.Active != "N" && params.Active != "Y" {
|
|
return params, "The selected active is invalid."
|
|
}
|
|
if params.StartDate != "" {
|
|
if _, err := time.Parse("2006-01-02", params.StartDate); err != nil {
|
|
return params, "The start date does not match the format Y-m-d."
|
|
}
|
|
}
|
|
if params.EndDate != "" {
|
|
end, err := time.Parse("2006-01-02", params.EndDate)
|
|
if err != nil {
|
|
return params, "The end date does not match the format Y-m-d."
|
|
}
|
|
if params.StartDate != "" {
|
|
start, _ := time.Parse("2006-01-02", params.StartDate)
|
|
if end.Before(start) {
|
|
return params, "The end date must be a date after or equal to start date."
|
|
}
|
|
}
|
|
}
|
|
if raw, exists := firstQueryValue(r, "page"); exists && raw != "" {
|
|
value, err := strconv.Atoi(raw)
|
|
if err != nil {
|
|
return params, "The page must be an integer."
|
|
}
|
|
if value < 1 {
|
|
return params, "The page must be at least 1."
|
|
}
|
|
params.Page = value
|
|
}
|
|
if raw, exists := firstQueryValue(r, "per_page"); exists && raw != "" {
|
|
value, err := strconv.Atoi(raw)
|
|
if err != nil {
|
|
return params, "The per page must be an integer."
|
|
}
|
|
if value < 1 || value > 100 {
|
|
return params, "The per page must be between 1 and 100."
|
|
}
|
|
params.PerPage = value
|
|
}
|
|
|
|
return params, ""
|
|
}
|
|
|
|
func currentRequestURL(r *http.Request, page int) string {
|
|
scheme := "http"
|
|
if r.TLS != nil {
|
|
scheme = "https"
|
|
}
|
|
if forwarded := r.Header.Get("X-Forwarded-Proto"); forwarded != "" {
|
|
scheme = strings.TrimSpace(strings.Split(forwarded, ",")[0])
|
|
}
|
|
host := r.Host
|
|
if host == "" {
|
|
host = "localhost"
|
|
}
|
|
return (&url.URL{Scheme: scheme, Host: host, Path: r.URL.Path, RawQuery: "page=" + strconv.Itoa(page)}).String()
|
|
}
|
|
|
|
func writePaketValidationError(w http.ResponseWriter, message string) {
|
|
WriteJSON(w, http.StatusUnprocessableEntity, PaketValidationResponse{
|
|
Success: false, Status: "validation_error", Message: message, Data: nil,
|
|
})
|
|
}
|