mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-20 13:31:56 +00:00
194 lines
5.7 KiB
Go
194 lines
5.7 KiB
Go
package controller
|
|
|
|
import (
|
|
"math"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"gitlab.com/mbugroup/lti-api.git/internal/modules/dashboards/dto"
|
|
service "gitlab.com/mbugroup/lti-api.git/internal/modules/dashboards/services"
|
|
validation "gitlab.com/mbugroup/lti-api.git/internal/modules/dashboards/validations"
|
|
"gitlab.com/mbugroup/lti-api.git/internal/response"
|
|
|
|
"github.com/gofiber/fiber/v2"
|
|
)
|
|
|
|
type DashboardController struct {
|
|
DashboardService service.DashboardService
|
|
}
|
|
|
|
func NewDashboardController(dashboardService service.DashboardService) *DashboardController {
|
|
return &DashboardController{
|
|
DashboardService: dashboardService,
|
|
}
|
|
}
|
|
|
|
func (u *DashboardController) GetAll(c *fiber.Ctx) error {
|
|
parseStringListParam := func(param string) ([]string, error) {
|
|
if param == "" {
|
|
return nil, nil
|
|
}
|
|
parts := strings.Split(param, ",")
|
|
result := make([]string, 0, len(parts))
|
|
for _, part := range parts {
|
|
trimmed := strings.TrimSpace(part)
|
|
if trimmed == "" {
|
|
return nil, strconv.ErrSyntax
|
|
}
|
|
result = append(result, trimmed)
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
parseUintListParam := func(param string) ([]uint, error) {
|
|
if param == "" {
|
|
return nil, nil
|
|
}
|
|
parts := strings.Split(param, ",")
|
|
ids := make([]uint, 0, len(parts))
|
|
for _, part := range parts {
|
|
trimmed := strings.TrimSpace(part)
|
|
if trimmed == "" {
|
|
return nil, strconv.ErrSyntax
|
|
}
|
|
parsed, err := strconv.ParseUint(trimmed, 10, 64)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
ids = append(ids, uint(parsed))
|
|
}
|
|
return ids, nil
|
|
}
|
|
|
|
lokasiIds, err := parseUintListParam(c.Query("lokasi_ids", ""))
|
|
if err != nil {
|
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid lokasi_ids")
|
|
}
|
|
|
|
flockIds, err := parseUintListParam(c.Query("flock_ids", ""))
|
|
if err != nil {
|
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid flock_ids")
|
|
}
|
|
|
|
kandangIds, err := parseUintListParam(c.Query("kandang_ids", ""))
|
|
if err != nil {
|
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid kandang_ids")
|
|
}
|
|
|
|
include, err := parseStringListParam(strings.ToLower(c.Query("include", "")))
|
|
if err != nil {
|
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid include")
|
|
}
|
|
|
|
analysisMode := strings.ToUpper(strings.TrimSpace(c.Query("analysis_mode", validation.AnalysisModeOverview)))
|
|
metric := strings.ToLower(strings.TrimSpace(c.Query("metric", "")))
|
|
|
|
query := &validation.Query{
|
|
Page: c.QueryInt("page", 1),
|
|
Limit: c.QueryInt("limit", 10),
|
|
Search: strings.TrimSpace(c.Query("search", "")),
|
|
PerformanceOverviewFilter: validation.PerformanceOverviewFilter{
|
|
StartDate: c.Query("start_date", ""),
|
|
EndDate: c.Query("end_date", ""),
|
|
AnalysisMode: analysisMode,
|
|
ComparisonType: strings.ToUpper(strings.TrimSpace(c.Query("comparison_type", ""))),
|
|
Metric: metric,
|
|
LokasiIds: lokasiIds,
|
|
FlockIds: flockIds,
|
|
KandangIds: kandangIds,
|
|
Include: include,
|
|
},
|
|
}
|
|
|
|
if query.Page < 1 || query.Limit < 1 {
|
|
return fiber.NewError(fiber.StatusBadRequest, "page and limit must be greater than 0")
|
|
}
|
|
|
|
if query.AnalysisMode == validation.AnalysisModeComparison && query.ComparisonType == "" {
|
|
return fiber.NewError(fiber.StatusBadRequest, "comparison_type is required for comparison mode")
|
|
}
|
|
|
|
location, err := time.LoadLocation("Asia/Jakarta")
|
|
if err != nil {
|
|
return fiber.NewError(fiber.StatusInternalServerError, "failed to load timezone configuration")
|
|
}
|
|
|
|
startDate, endDate, endExclusive, err := parsePeriodDates(query.StartDate, query.EndDate, location)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
query.PeriodStart = startDate
|
|
query.PeriodEnd = endDate
|
|
query.PeriodEndExclusive = endExclusive
|
|
|
|
result, totalResults, err := u.DashboardService.GetAll(c.Context(), query)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
filters := dto.DashboardFiltersDTO{
|
|
StartDate: query.StartDate,
|
|
EndDate: query.EndDate,
|
|
AnalysisMode: query.AnalysisMode,
|
|
ComparisonType: query.ComparisonType,
|
|
Metric: query.Metric,
|
|
LokasiIds: defaultUintSlice(query.LokasiIds),
|
|
FlockIds: defaultUintSlice(query.FlockIds),
|
|
KandangIds: defaultUintSlice(query.KandangIds),
|
|
Include: query.Include,
|
|
}
|
|
|
|
return c.Status(fiber.StatusOK).
|
|
JSON(response.SuccessWithMeta{
|
|
Code: fiber.StatusOK,
|
|
Status: "success",
|
|
Message: "Get dashboard successfully",
|
|
Meta: response.Meta{
|
|
Page: query.Page,
|
|
Limit: query.Limit,
|
|
TotalPages: int64(math.Ceil(float64(totalResults) / float64(query.Limit))),
|
|
TotalResults: totalResults,
|
|
Filters: filters,
|
|
},
|
|
Data: result,
|
|
})
|
|
}
|
|
|
|
func defaultUintSlice(values []uint) []uint {
|
|
if values == nil {
|
|
return []uint{}
|
|
}
|
|
return values
|
|
}
|
|
|
|
func parsePeriodDates(startDateRaw, endDateRaw string, location *time.Location) (time.Time, time.Time, time.Time, error) {
|
|
now := time.Now().In(location)
|
|
startDate := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, location)
|
|
endDate := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, location)
|
|
|
|
if startDateRaw != "" {
|
|
parsed, err := time.ParseInLocation("2006-01-02", startDateRaw, location)
|
|
if err != nil {
|
|
return time.Time{}, time.Time{}, time.Time{}, fiber.NewError(fiber.StatusBadRequest, "start_date must follow format YYYY-MM-DD")
|
|
}
|
|
startDate = parsed
|
|
}
|
|
|
|
if endDateRaw != "" {
|
|
parsed, err := time.ParseInLocation("2006-01-02", endDateRaw, location)
|
|
if err != nil {
|
|
return time.Time{}, time.Time{}, time.Time{}, fiber.NewError(fiber.StatusBadRequest, "end_date must follow format YYYY-MM-DD")
|
|
}
|
|
endDate = parsed
|
|
}
|
|
|
|
if endDate.Before(startDate) {
|
|
return time.Time{}, time.Time{}, time.Time{}, fiber.NewError(fiber.StatusBadRequest, "end_date must be greater than or equal to start_date")
|
|
}
|
|
|
|
endExclusive := endDate.AddDate(0, 0, 1)
|
|
return startDate, endDate, endExclusive, nil
|
|
}
|