feat: add endpoints and logic for retrieving warehouse space usage and status distribution, including SQL queries, models, and service integration

This commit is contained in:
Tran Anh Tuan
2026-05-14 11:44:39 +07:00
parent cee0186225
commit 84ef7d446e
11 changed files with 612 additions and 0 deletions

View File

@@ -76,3 +76,20 @@ func ToDomainTopExportedComponent(r db.GetTopExportedComponentsRow) models.TopEx
TotalExported: r.TotalExported,
}
}
func ToDomainStatusDistribution(r db.GetStatusDistributionRow) models.StatusDistributionItem {
return models.StatusDistributionItem{
Status: string(r.Status),
Count: r.Count,
TotalQuantity: r.TotalQuantity,
}
}
func ToDomainSpaceUsage(r db.GetSpaceUsageRow) models.SpaceUsageItem {
return models.SpaceUsageItem{
Warehouse: r.Warehouse,
Room: r.Room,
TotalContainers: r.TotalContainers,
UsedContainers: r.UsedContainers,
}
}

View File

@@ -76,3 +76,16 @@ type TopExportedComponent struct {
ComponentTypeName string `json:"componentTypeName"`
TotalExported int64 `json:"totalExported"`
}
type StatusDistributionItem struct {
Status string `json:"status"`
Count int64 `json:"count"`
TotalQuantity int64 `json:"totalQuantity"`
}
type SpaceUsageItem struct {
Warehouse string `json:"warehouse"`
Room string `json:"room"`
TotalContainers int64 `json:"totalContainers"`
UsedContainers int64 `json:"usedContainers"`
}

View File

@@ -142,3 +142,27 @@ func GetTopExportedComponents(ctx context.Context, queries *db.Queries, startDat
}
return items, nil
}
func GetStatusDistribution(ctx context.Context, queries *db.Queries, warehouseID pgtype.Int8) ([]models.StatusDistributionItem, error) {
results, err := queries.GetStatusDistribution(ctx, warehouseID)
if err != nil {
return nil, err
}
items := make([]models.StatusDistributionItem, 0, len(results))
for _, r := range results {
items = append(items, mapper.ToDomainStatusDistribution(r))
}
return items, nil
}
func GetSpaceUsage(ctx context.Context, queries *db.Queries, warehouseID pgtype.Int8) ([]models.SpaceUsageItem, error) {
results, err := queries.GetSpaceUsage(ctx, warehouseID)
if err != nil {
return nil, err
}
items := make([]models.SpaceUsageItem, 0, len(results))
for _, r := range results {
items = append(items, mapper.ToDomainSpaceUsage(r))
}
return items, nil
}

View File

@@ -160,6 +160,8 @@ func NewRouter() *gin.Engine {
dashboard.GET("/anomalies", utils.AsyncHandler(services.DashboardAnomalies))
dashboard.GET("/transactions-chart", utils.AsyncHandler(services.DashboardTransactionsChart))
dashboard.GET("/top-components", utils.AsyncHandler(services.DashboardTopComponents))
dashboard.GET("/status-distribution", utils.AsyncHandler(services.DashboardStatusDistribution))
dashboard.GET("/space-usage", utils.AsyncHandler(services.DashboardSpaceUsage))
}
}
}

View File

@@ -211,3 +211,65 @@ func DashboardTopComponents(c *gin.Context) error {
response.Ok(c, "Success", data)
return nil
}
// @Summary Get status distribution
// @Description Retrieve component items count grouped by status (normal, damaged, expired, etc.)
// @Tags dashboard
// @Accept json
// @Produce json
// @Param warehouse_id query int false "Filter by warehouse ID"
// @Success 200 {object} response.SuccessResponse{data=[]models.StatusDistributionItem}
// @Failure 400 {object} response.ErrorResponse
// @Failure 500 {object} response.ErrorResponse
// @Router /v1/dashboard/status-distribution [get]
func DashboardStatusDistribution(c *gin.Context) error {
var warehouseID pgtype.Int8
if raw := c.Query("warehouse_id"); raw != "" {
id, err := strconv.ParseInt(raw, 10, 64)
if err != nil {
response.BadRequestError(c, http.StatusBadRequest, "Invalid warehouse_id")
return nil
}
warehouseID = pgtype.Int8{Int64: id, Valid: true}
}
data, err := repositories.GetStatusDistribution(c.Request.Context(), global.Queries, warehouseID)
if err != nil {
log.Err(err).Msg("Error when Get Status Distribution")
response.InternalServerError(c, http.StatusInternalServerError, "Failed to get status distribution")
return nil
}
response.Ok(c, "Success", data)
return nil
}
// @Summary Get space usage
// @Description Retrieve warehouse space usage statistics showing total vs used containers per room
// @Tags dashboard
// @Accept json
// @Produce json
// @Param warehouse_id query int false "Filter by warehouse ID"
// @Success 200 {object} response.SuccessResponse{data=[]models.SpaceUsageItem}
// @Failure 400 {object} response.ErrorResponse
// @Failure 500 {object} response.ErrorResponse
// @Router /v1/dashboard/space-usage [get]
func DashboardSpaceUsage(c *gin.Context) error {
var warehouseID pgtype.Int8
if raw := c.Query("warehouse_id"); raw != "" {
id, err := strconv.ParseInt(raw, 10, 64)
if err != nil {
response.BadRequestError(c, http.StatusBadRequest, "Invalid warehouse_id")
return nil
}
warehouseID = pgtype.Int8{Int64: id, Valid: true}
}
data, err := repositories.GetSpaceUsage(c.Request.Context(), global.Queries, warehouseID)
if err != nil {
log.Err(err).Msg("Error when Get Space Usage")
response.InternalServerError(c, http.StatusInternalServerError, "Failed to get space usage")
return nil
}
response.Ok(c, "Success", data)
return nil
}