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

@@ -153,6 +153,89 @@ func (q *Queries) GetContainerStats(ctx context.Context, warehouseID pgtype.Int8
return i, err
}
const getSpaceUsage = `-- name: GetSpaceUsage :many
SELECT w.name AS warehouse, r.name AS room,
COUNT(DISTINCT c.id)::bigint AS total_containers,
COUNT(DISTINCT ci.container_id)::bigint AS used_containers
FROM warehouses w
JOIN rooms r ON r.warehouse_id = w.id
JOIN cabinets cb ON cb.room_id = r.id
JOIN shelves s ON s.cabinet_id = cb.id
JOIN containers c ON c.shelf_id = s.id
LEFT JOIN component_items ci ON ci.container_id = c.id
WHERE ($1::bigint IS NULL OR w.id = $1::bigint)
GROUP BY w.name, r.name
`
type GetSpaceUsageRow struct {
Warehouse string `db:"warehouse" json:"warehouse"`
Room string `db:"room" json:"room"`
TotalContainers int64 `db:"total_containers" json:"totalContainers"`
UsedContainers int64 `db:"used_containers" json:"usedContainers"`
}
func (q *Queries) GetSpaceUsage(ctx context.Context, warehouseID pgtype.Int8) ([]GetSpaceUsageRow, error) {
rows, err := q.db.Query(ctx, getSpaceUsage, warehouseID)
if err != nil {
return nil, err
}
defer rows.Close()
var items []GetSpaceUsageRow
for rows.Next() {
var i GetSpaceUsageRow
if err := rows.Scan(
&i.Warehouse,
&i.Room,
&i.TotalContainers,
&i.UsedContainers,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getStatusDistribution = `-- name: GetStatusDistribution :many
SELECT status, COUNT(*) AS count, COALESCE(SUM(quantity), 0)::bigint AS total_quantity
FROM component_items ci
JOIN containers con ON ci.container_id = con.id
JOIN shelves s ON con.shelf_id = s.id
JOIN cabinets cab ON s.cabinet_id = cab.id
JOIN rooms r ON cab.room_id = r.id
WHERE ($1::bigint IS NULL OR r.warehouse_id = $1::bigint)
GROUP BY ci.status
`
type GetStatusDistributionRow struct {
Status ComponentItemStatusEnum `db:"status" json:"status"`
Count int64 `db:"count" json:"count"`
TotalQuantity int64 `db:"total_quantity" json:"totalQuantity"`
}
func (q *Queries) GetStatusDistribution(ctx context.Context, warehouseID pgtype.Int8) ([]GetStatusDistributionRow, error) {
rows, err := q.db.Query(ctx, getStatusDistribution, warehouseID)
if err != nil {
return nil, err
}
defer rows.Close()
var items []GetStatusDistributionRow
for rows.Next() {
var i GetStatusDistributionRow
if err := rows.Scan(&i.Status, &i.Count, &i.TotalQuantity); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getStockAlerts = `-- name: GetStockAlerts :many
SELECT c.id, c.name, c.unit, c.total_quantity, c.min_quantity, c.component_type_id,
ct.name AS component_type_name

View File

@@ -68,6 +68,8 @@ type Querier interface {
GetRoleByID(ctx context.Context, id uuid.UUID) (Role, error)
GetRoomByID(ctx context.Context, id int64) (Room, error)
GetShelveByID(ctx context.Context, id int64) (Shelf, error)
GetSpaceUsage(ctx context.Context, warehouseID pgtype.Int8) ([]GetSpaceUsageRow, error)
GetStatusDistribution(ctx context.Context, warehouseID pgtype.Int8) ([]GetStatusDistributionRow, error)
GetStockAlerts(ctx context.Context) ([]GetStockAlertsRow, error)
GetTodayInvoiceCounts(ctx context.Context) ([]GetTodayInvoiceCountsRow, error)
GetTopExportedComponents(ctx context.Context, arg GetTopExportedComponentsParams) ([]GetTopExportedComponentsRow, error)