feat: add CPONE package endpoints
This commit is contained in:
181
internal/http/paket.go
Normal file
181
internal/http/paket.go
Normal file
@@ -0,0 +1,181 @@
|
||||
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.paketRepo.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.paketRepo.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,
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user