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:
@@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"`
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user