diff --git a/controllers/hubController.go b/controllers/hubController.go index 0069eb3..18c9c22 100644 --- a/controllers/hubController.go +++ b/controllers/hubController.go @@ -100,6 +100,36 @@ func todayMidnight() time.Time { return time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location()) } +// parseHubDashboardRange parses optional from/to (YYYY-MM-DD) query params +// for GetHubDashboardStats, defaulting to "today so far" when both are +// omitted. Mirrors GetHubReport's range semantics: to is inclusive of the +// whole day. +func parseHubDashboardRange(c *fiber.Ctx) (time.Time, time.Time, error) { + fromStr := c.Query("from") + toStr := c.Query("to") + + if fromStr == "" && toStr == "" { + return todayMidnight(), time.Now(), nil + } + if fromStr == "" || toStr == "" { + return time.Time{}, time.Time{}, fmt.Errorf("both from and to query params are required (YYYY-MM-DD)") + } + + from, err := time.ParseInLocation("2006-01-02", fromStr, time.Local) + if err != nil { + return time.Time{}, time.Time{}, fmt.Errorf("invalid from date, expected YYYY-MM-DD") + } + toDate, err := time.ParseInLocation("2006-01-02", toStr, time.Local) + if err != nil { + return time.Time{}, time.Time{}, fmt.Errorf("invalid to date, expected YYYY-MM-DD") + } + to := toDate.Add(24*time.Hour - time.Nanosecond) + if to.Before(from) { + return time.Time{}, time.Time{}, fmt.Errorf("to date must not be before from date") + } + return from, to, nil +} + // hubPincodePrefix returns the first 3 digits of a hub's pincode, following // the same zone-prefix convention used in pricing_helpers.go and city_gate.go. func hubPincodePrefix(hubID int) string { @@ -183,12 +213,16 @@ func isDoormileStaff(staff *models.HubStaffAccount) bool { func GetHubDashboardStats(c *fiber.Ctx) error { hubID := c.Locals("hubid").(int) - midnight := todayMidnight() prefix := hubPincodePrefix(hubID) + from, to, err := parseHubDashboardRange(c) + if err != nil { + return utils.BadRequest(c, err.Error()) + } + var parcelsReceivedToday int64 db.DB.Model(&models.Consignment{}). - Where("currenthubid = ? AND status = ? AND updatedat >= ?", hubID, constants.ConsignmentInwardedAtHub, midnight). + Where("currenthubid = ? AND status = ? AND updatedat BETWEEN ? AND ?", hubID, constants.ConsignmentInwardedAtHub, from, to). Count(&parcelsReceivedToday) var milersAvailable int64 @@ -210,12 +244,12 @@ func GetHubDashboardStats(c *fiber.Ctx) error { var batchesSentToday int64 db.DB.Model(&models.Tripsheet{}). - Where("sourcehubid = ? AND dispatchtime >= ?", hubID, midnight). + Where("sourcehubid = ? AND dispatchtime BETWEEN ? AND ?", hubID, from, to). Count(&batchesSentToday) var exceptions int64 db.DB.Model(&models.ConsignmentException{}). - Where("hubid = ? AND createdat >= ?", hubID, midnight). + Where("hubid = ? AND createdat BETWEEN ? AND ?", hubID, from, to). Count(&exceptions) // Sorting happens at inbound scan (CreateInboundScan assigns a shelf), so