Files
backend_jupiter/controllers/deliveryController.go
2026-05-25 11:45:56 +05:30

1486 lines
40 KiB
Go

package controllers
import (
"nearle/db"
"nearle/domain"
"nearle/models"
"nearle/utils"
"net/http"
"strconv"
"strings"
"github.com/gofiber/fiber/v2"
)
const (
core = `SELECT COUNT(DISTINCT a.deliveryid) AS total,
COUNT(DISTINCT CASE WHEN a.orderstatus = 'pending' THEN a.deliveryid END) AS pending,
COUNT(DISTINCT CASE WHEN a.orderstatus = 'accepted' THEN a.deliveryid END) AS accepted,
COUNT(DISTINCT CASE WHEN a.orderstatus = 'arrived' THEN a.deliveryid END) AS arrived,
COUNT(DISTINCT CASE WHEN a.orderstatus = 'picked' THEN a.deliveryid END) AS picked,
COUNT(DISTINCT CASE WHEN a.orderstatus = 'active' THEN a.deliveryid END) AS active,
COUNT(DISTINCT CASE WHEN a.orderstatus = 'delivered' THEN a.deliveryid END) AS delivered,
COUNT(DISTINCT CASE WHEN a.orderstatus = 'cancelled' THEN a.deliveryid END) AS cancelled,
COUNT(DISTINCT CASE WHEN a.orderstatus = 'skipped' THEN a.deliveryid END) AS skipped`
reports = `SELECT
c.userid,e.firstname,e.lastname,e.contactno AS ridercontact,b.tenantid,b.tenantname,a.locationid, d.locationname,
COUNT(*) AS totalorders,
SUM(CASE WHEN a.orderstatus = 'created' THEN 1 ELSE 0 END) AS orderscreated,
SUM(CASE WHEN a.orderstatus = 'pending' THEN 1 ELSE 0 END) AS orderspending,
SUM(CASE WHEN a.orderstatus = 'cancelled' THEN 1 ELSE 0 END) AS orderscancelled,
SUM(CASE WHEN a.orderstatus = 'delivered' THEN 1 ELSE 0 END) AS orderscompleted,
SUM(CASE WHEN c.orderstatus = 'pending' THEN 1 ELSE 0 END) AS deliveriespending,
SUM(CASE WHEN c.orderstatus = 'delivered' THEN 1 ELSE 0 END) AS deliveriescompleted,
SUM(CASE WHEN c.orderstatus = 'cancelled' THEN 1 ELSE 0 END) AS deliveriescancelled,
SUM(CASE WHEN c.paymenttype = 64 THEN c.deliveryamt ELSE 0 END) AS paylater,
SUM(CASE WHEN c.paymenttype = 43 THEN c.deliveryamt ELSE 0 END) AS payondelivery,
ROUND(SUM(CAST(COALESCE(NULLIF(c.kms, ''), '0') AS NUMERIC)), 2) AS kms,
ROUND(SUM(CAST(COALESCE(NULLIF(c.actualkms, ''), '0') AS NUMERIC)), 2) AS actualkms,
SUM(c.deliveryamt) AS charges,
SUM(CASE WHEN c.orderstatus = 'delivered' THEN c.cumulativekms ELSE 0 END) AS cumulativekms,
SUM(CASE WHEN c.orderstatus = 'delivered' THEN c.deliveryamt ELSE 0 END) AS deliveryamt,
SUM(c.previouskms) AS previouskms,
SUM(c.previouskms) AS previouskms,
SUM(CAST(COALESCE(NULLIF(c.riderkms, ''), '0') AS NUMERIC)) AS riderkms,
SUM(c.quantity) AS quantity, SUM(c.collectionamt) AS collectionamt, SUM(c.collectedamt) AS collectedamt, c.collectionstatus
FROM
tenants b
right JOIN orders a ON b.tenantid = a.tenantid
right JOIN deliveries c ON a.orderheaderid = c.orderheaderid
LEFT JOIN tenantlocations d ON a.locationid = d.locationid
LEFT JOIN app_users e ON e.userid = c.userid`
Ridersummary = `SELECT a.userid, a.firstname, a.lastname, a.contactno AS ridercontact, MAX(b.tenantid) AS tenantid, MAX(c.tenantname) AS tenantname, MAX(b.locationid) AS locationid, MAX(d.locationname) AS locationname,
CONCAT(a.firstname, ' ', a.lastname) AS fullname, a.status, SUM(COALESCE(b.quantity,0)) AS quantity, SUM(COALESCE(b.collectionamt,0)) AS collectionamt, SUM(COALESCE(b.collectedamt,0)) AS collectedamt, COALESCE(MAX(b.collectionstatus),0) AS collectionstatus,
COUNT(b.orderid) AS totalorders,
SUM(CASE WHEN b.orderstatus = 'pending' THEN 1 ELSE 0 END) AS pending,
SUM(CASE WHEN b.orderstatus = 'assigned' THEN 1 ELSE 0 END) AS assigned,
SUM(CASE WHEN b.orderstatus = 'accepted' THEN 1 ELSE 0 END) AS accepted,
SUM(CASE WHEN b.orderstatus = 'arrived' THEN 1 ELSE 0 END) AS arrived,
SUM(CASE WHEN b.orderstatus = 'picked' THEN 1 ELSE 0 END) AS picked,
SUM(CASE WHEN b.orderstatus = 'active' THEN 1 ELSE 0 END) AS active,
SUM(CASE WHEN b.orderstatus = 'skipped' THEN 1 ELSE 0 END) AS skipped,
SUM(CASE WHEN b.orderstatus = 'delivered' THEN 1 ELSE 0 END) AS delivered,
SUM(CASE WHEN b.orderstatus = 'cancelled' THEN 1 ELSE 0 END) AS cancelled,
SUM(CASE WHEN b.orderstatus = 'delivered' THEN CAST(COALESCE(NULLIF(b.actualkms, ''), '0') AS NUMERIC) ELSE 0 END) AS actualkms,
SUM(CASE WHEN b.orderstatus = 'delivered' THEN CAST(COALESCE(NULLIF(b.kms, ''), '0') AS NUMERIC) ELSE 0 END) AS kms,
SUM(CASE WHEN b.paymenttype = 64 THEN b.deliveryamt ELSE 0 END) AS paylater,
SUM(CASE WHEN b.paymenttype = 43 THEN b.deliveryamt ELSE 0 END) AS payondelivery,
SUM(CASE WHEN b.orderstatus = 'delivered' THEN b.cumulativekms ELSE 0 END) AS cumulativekms,
SUM(CASE WHEN b.orderstatus = 'delivered' THEN b.deliveryamt ELSE 0 END) AS deliveryamt,
SUM(b.previouskms) AS previouskms
FROM app_users a
LEFT JOIN deliveries b ON a.userid = b.userid
LEFT JOIN tenants c ON b.tenantid = c.tenantid
LEFT JOIN tenantlocations d ON b.locationid = d.locationid`
)
func PublishLog(c *fiber.Ctx) error {
var data []models.Deliverylogs
if err := c.BodyParser(&data); err != nil {
return err
}
err := domain.PublishLog(data)
if err != nil {
return c.JSON(fiber.Map{
"status": false,
"code": http.StatusConflict,
"message": err,
})
}
return c.JSON(fiber.Map{
"status": true,
"code": http.StatusOK,
"message": "successful",
})
}
func GetDeliverylogs(c *fiber.Ctx) error {
did, _ := strconv.Atoi(c.Query("deliveryid"))
result := domain.GetDeliverylogs(did)
return c.JSON(fiber.Map{
"code": http.StatusOK,
"message": "Success",
"status": true,
"details": result,
})
}
func GetDeliveriesV1(c *fiber.Ctx) error {
var result []models.Deliveryinfo
pid, _ := strconv.Atoi(c.Query("partnerid"))
tid, _ := strconv.Atoi(c.Query("tenantid"))
uid, _ := strconv.Atoi(c.Query("userid"))
cid, _ := strconv.Atoi(c.Query("customerid"))
aid, _ := strconv.Atoi(c.Query("applocationid"))
aud, _ := strconv.Atoi(c.Query("appuserid"))
fdate := c.Query("fromdate")
tdate := c.Query("todate")
stat := c.Query("status")
var info models.DeliveryQuery
info.Partnerid = pid
info.Tenantid = tid
info.UserID = uid
info.Appuserid = aud
info.Applocationid = aid
info.Fromdate = fdate
info.ToDate = tdate
info.Status = stat
if tid != 0 {
result = domain.GetTenantDeliveries(info)
} else if pid != 0 {
result = domain.GetPartnerDeliveries(info)
} else if cid != 0 {
result = domain.GetCustomerDeliveries(info)
} else if aid != 0 {
result = domain.GetAdminDeliveries(info)
} else if uid != 0 {
result = domain.GetUserDeliveries(info)
} else if aud != 0 {
result = domain.GetAppUserDeliveries(info)
}
return c.JSON(fiber.Map{
"code": http.StatusOK,
"message": "Success",
"status": true,
"details": result,
})
}
func GetDeliveriesV2(c *fiber.Ctx) error {
var result []models.Deliveryinfo
pid, _ := strconv.Atoi(c.Query("partnerid"))
tid, _ := strconv.Atoi(c.Query("tenantid"))
lid, _ := strconv.Atoi(c.Query("locationid"))
uid, _ := strconv.Atoi(c.Query("userid"))
cid, _ := strconv.Atoi(c.Query("customerid"))
aid, _ := strconv.Atoi(c.Query("applocationid"))
aud, _ := strconv.Atoi(c.Query("appuserid"))
fdate := c.Query("fromdate")
tdate := c.Query("todate")
stat := c.Query("status")
keyword := c.Query("keyword")
pagenoStr := c.Query("pageno")
pagesizeStr := c.Query("pagesize")
var pageno, pagesize int
var err error
if pagenoStr != "" {
pageno, err = strconv.Atoi(pagenoStr)
if err != nil || pageno <= 0 {
pageno = 1
}
}
if pagesizeStr != "" {
pagesize, err = strconv.Atoi(pagesizeStr)
if err != nil || pagesize <= 0 {
pagesize = 10
}
}
info := models.DeliveryQuery{
Partnerid: pid,
Tenantid: tid,
Locationid: lid,
UserID: uid,
Appuserid: aud,
Applocationid: aid,
Fromdate: fdate,
ToDate: tdate,
Status: stat,
Pageno: pageno,
Pagesize: pagesize,
Keyword: keyword,
}
utils.Logger.Infow("Searching Delivery", "keyword", keyword)
switch {
case tid != 0 && lid != 0:
result = domain.GetTenantLocationDeliveries(info)
case tid != 0:
result = domain.GetTenantDeliveries(info)
case lid != 0:
result = domain.GetLocationDeliveries(info)
case pid != 0:
result = domain.GetPartnerDeliveries(info)
case cid != 0:
result = domain.GetCustomerDeliveries(info)
case aid != 0:
result = domain.GetAdminDeliveries(info)
case uid != 0:
result = domain.GetUserDeliveries(info)
case aud != 0:
result = domain.GetAppUserDeliveries(info)
default:
result = domain.GetDeliveries(info)
}
if result == nil {
result = []models.Deliveryinfo{}
}
return c.JSON(fiber.Map{
"code": http.StatusOK,
"message": "Success",
"status": true,
"details": result,
})
}
func GetDeliveriesV3(c *fiber.Ctx) error {
var result []models.Deliveryinfo
pid, _ := strconv.Atoi(c.Query("partnerid"))
tid, _ := strconv.Atoi(c.Query("tenantid"))
uid, _ := strconv.Atoi(c.Query("userid"))
cid, _ := strconv.Atoi(c.Query("customerid"))
aid, _ := strconv.Atoi(c.Query("applocationid"))
aud, _ := strconv.Atoi(c.Query("appuserid"))
pageno, _ := strconv.Atoi(c.Query("pageno", "1"))
pagesize, _ := strconv.Atoi(c.Query("pagesize", ""))
fdate := c.Query("fromdate")
tdate := c.Query("todate")
stat := c.Query("status")
keyword := c.Query("keyword")
var info models.DeliveryQuery
info.Partnerid = pid
info.Tenantid = tid
info.UserID = uid
info.Appuserid = aud
info.Applocationid = aid
info.Fromdate = fdate
info.ToDate = tdate
info.Status = stat
info.Pageno = pageno
info.Pagesize = pagesize
info.Keyword = keyword
utils.Logger.Infow("Searching Delivery", "keyword", keyword)
// Choose which delivery function to call
switch {
case tid != 0:
result = domain.GetTenantDeliveries(info)
case pid != 0:
result = domain.GetPartnerDeliveries(info)
case cid != 0:
result = domain.GetCustomerDeliveries(info)
case aid != 0:
result = domain.GetAdminDeliveries(info)
case uid != 0:
result = domain.GetUserDeliveriesv1(info)
case aud != 0:
result = domain.GetAppUserDeliveries(info)
default:
result = domain.GetDeliveries(info)
}
// Ensure result is not nil (avoid "null" in JSON)
if result == nil {
result = []models.Deliveryinfo{}
}
return c.JSON(fiber.Map{
"code": http.StatusOK,
"message": "Success",
"status": true,
"details": result,
})
}
func GetDeliveries(c *fiber.Ctx) error {
pid, _ := strconv.Atoi(c.Query("partnerid"))
tid, _ := strconv.Atoi(c.Query("tenantid"))
uid, _ := strconv.Atoi(c.Query("userid"))
aid, _ := strconv.Atoi(c.Query("applocationid"))
aud, _ := strconv.Atoi(c.Query("appuserid"))
fdate := c.Query("fromdate")
tdate := c.Query("todate")
stat := c.Query("status")
var info models.DeliveryQuery
info.Partnerid = pid
info.Tenantid = tid
info.UserID = uid
info.Appuserid = aud
info.Applocationid = aid
info.Fromdate = fdate
info.ToDate = tdate
info.Status = stat
data := domain.GetDeliveries(info)
return c.JSON(fiber.Map{
"code": http.StatusOK,
"message": "Success",
"status": true,
"details": data,
})
}
func GetReportSummary(c *fiber.Ctx) error {
tid, _ := strconv.Atoi(c.Query("tenantid"))
pid, _ := strconv.Atoi(c.Query("partnerid"))
uid, _ := strconv.Atoi(c.Query("userid"))
aid, _ := strconv.Atoi(c.Query("applocationid"))
fdate := c.Query("fromdate")
tdate := c.Query("todate")
var data []models.ReportSummary
var q1 string
var params []interface{}
q1 = reports
if tid != 0 {
q1 += " WHERE a.tenantid=? "
params = append(params, tid)
} else if pid != 0 {
q1 += " WHERE a.partnerid=? "
params = append(params, pid)
} else if uid != 0 {
q1 += " WHERE c.userid=? "
params = append(params, uid)
} else if aid != 0 {
q1 += " WHERE c.applocationid=? "
params = append(params, aid)
} else {
q1 += " WHERE 1=1 "
}
if fdate != "" && tdate != "" {
q1 += " AND a.orderdate::date between ?::date and ?::date "
params = append(params, fdate, tdate)
}
q1 += " GROUP BY a.tenantid, b.tenantname, c.userid, e.firstname, e.lastname, e.contactno, a.locationid, d.locationname, c.collectionstatus"
utils.Logger.Debugw("ReportSummary SQL generated", "query", q1)
db.DB.Raw(q1, params...).Find(&data)
return c.JSON(fiber.Map{
"code": http.StatusOK,
"message": "Success",
"status": true,
"details": data,
})
}
func GetReportLocationSummary(c *fiber.Ctx) error {
tid, _ := strconv.Atoi(c.Query("tenantid"))
lid, _ := strconv.Atoi(c.Query("locationid"))
pid, _ := strconv.Atoi(c.Query("partnerid"))
uid, _ := strconv.Atoi(c.Query("userid"))
aid, _ := strconv.Atoi(c.Query("applocationid"))
fdate := c.Query("fromdate")
tdate := c.Query("todate")
keyword := c.Query("keyword")
var data []models.ReportSummary
var q1 string
var params []interface{}
q1 = reports + " WHERE 1=1 "
if tid != 0 {
q1 += " AND a.tenantid=? "
params = append(params, tid)
}
if lid != 0 {
q1 += " AND a.locationid=? "
params = append(params, lid)
}
if pid != 0 {
q1 += " AND a.partnerid=? "
params = append(params, pid)
}
if uid != 0 {
q1 += " AND c.userid=? "
params = append(params, uid)
}
if aid != 0 {
q1 += " AND c.applocationid=? "
params = append(params, aid)
}
if keyword != "" {
q1 += " AND LOWER(d.locationname) LIKE LOWER(?) "
params = append(params, "%"+keyword+"%")
}
if fdate != "" && tdate != "" {
q1 += " AND a.orderdate::date BETWEEN ?::date AND ?::date "
params = append(params, fdate, tdate)
}
q1 += " GROUP BY a.locationid, b.tenantid, b.tenantname, c.userid, e.firstname, e.lastname, e.contactno, d.locationname, c.collectionstatus"
utils.Logger.Debugw("ReportLocationSummary SQL generated", "query", q1)
db.DB.Raw(q1, params...).Scan(&data)
return c.JSON(fiber.Map{
"code": http.StatusOK,
"message": "Success",
"status": true,
"details": data,
})
}
func GetRiderLocationReportSummary(c *fiber.Ctx) error {
tid, _ := strconv.Atoi(c.Query("tenantid"))
pid, _ := strconv.Atoi(c.Query("partnerid"))
uid, _ := strconv.Atoi(c.Query("userid"))
aid, _ := strconv.Atoi(c.Query("applocationid"))
fdate := c.Query("fromdate")
tdate := c.Query("todate")
var data []models.ReportSummary
var q1 string
base := `
SELECT b.tenantid,b.tenantname,a.locationid,d.locationname,e.userid,e.firstname,e.lastname,
COUNT(*) AS totalorders,
SUM(CASE WHEN a.orderstatus = 'created' THEN 1 ELSE 0 END) AS orderscreated,
SUM(CASE WHEN a.orderstatus = 'pending' THEN 1 ELSE 0 END) AS orderspending,
SUM(CASE WHEN a.orderstatus = 'cancelled' THEN 1 ELSE 0 END) AS orderscancelled,
SUM(CASE WHEN a.orderstatus = 'delivered' THEN 1 ELSE 0 END) AS orderscompleted,
SUM(CASE WHEN c.orderstatus = 'pending' THEN 1 ELSE 0 END) AS deliveriespending,
SUM(CASE WHEN c.orderstatus = 'delivered' THEN 1 ELSE 0 END) AS deliveriescompleted,
SUM(CASE WHEN c.orderstatus = 'cancelled' THEN 1 ELSE 0 END) AS deliveriescancelled,
SUM(CASE WHEN c.paymenttype = 64 THEN c.deliveryamt ELSE 0 END) AS paylater,
SUM(CASE WHEN c.paymenttype = 43 THEN c.deliveryamt ELSE 0 END) AS payondelivery,
ROUND(SUM(CAST(COALESCE(NULLIF(c.kms, ''), '0') AS NUMERIC)), 2) AS kms,
ROUND(SUM(CAST(COALESCE(NULLIF(c.actualkms, ''), '0') AS NUMERIC)), 2) AS actualkms,
SUM(c.deliveryamt) AS charges
FROM tenants b
RIGHT JOIN orders a ON b.tenantid = a.tenantid
RIGHT JOIN deliveries c ON a.orderheaderid = c.orderheaderid
LEFT JOIN tenantlocations d ON a.locationid = d.locationid
LEFT JOIN app_users e ON e.userid = c.userid
`
// WHERE conditions
var where []string
var params []interface{}
// Tenant filter
if tid != 0 {
where = append(where, "a.tenantid=?")
params = append(params, tid)
}
// Partner filter
if pid != 0 {
where = append(where, "a.partnerid=?")
params = append(params, pid)
}
// Rider (userid) filter
if uid != 0 {
where = append(where, "c.userid=?")
params = append(params, uid)
}
// Location filter
if aid != 0 {
where = append(where, "a.locationid=?")
params = append(params, aid)
}
// Date filter
if fdate != "" && tdate != "" {
where = append(where, "a.orderdate::date BETWEEN ?::date AND ?::date")
where = append(where, "c.deliverydate::date BETWEEN ?::date AND ?::date")
params = append(params, fdate, tdate, fdate, tdate)
}
// Build WHERE clause
if len(where) > 0 {
q1 = base + " WHERE " + strings.Join(where, " AND ")
} else {
q1 = base
}
// GROUP BY
q1 += " GROUP BY a.locationid, b.tenantid, b.tenantname, d.locationname, e.userid, e.firstname, e.lastname"
utils.Logger.Debugw("RiderLocationReportSummary SQL generated", "query", q1)
db.DB.Raw(q1, params...).Find(&data)
return c.JSON(fiber.Map{
"code": http.StatusOK,
"message": "Success",
"status": true,
"details": data,
})
}
func GetRiderSummary(c *fiber.Ctx) error {
aid, _ := strconv.Atoi(c.Query("applocationid"))
pid, _ := strconv.Atoi(c.Query("partnerid"))
tid, _ := strconv.Atoi(c.Query("tenantid"))
lid, _ := strconv.Atoi(c.Query("locationid"))
uid, _ := strconv.Atoi(c.Query("userid"))
fdate := c.Query("fromdate")
tdate := c.Query("todate")
keyword := c.Query("keyword")
var data []models.Ridersummary
var params []interface{}
q1 := Ridersummary + " WHERE a.configid = 6"
if uid != 0 {
q1 += " AND a.userid=?"
params = append(params, uid)
}
if tid != 0 {
q1 += " AND b.tenantid=?"
params = append(params, tid)
}
if lid != 0 {
q1 += " AND b.locationid=?"
params = append(params, lid)
}
if aid != 0 {
q1 += " AND a.applocationid=?"
params = append(params, aid)
}
if pid != 0 {
q1 += " AND a.partnerid=?"
params = append(params, pid)
}
if fdate != "" && tdate != "" {
q1 += " AND b.deliverydate::date BETWEEN ?::date AND ?::date"
params = append(params, fdate, tdate)
}
if keyword != "" {
k := "%" + strings.ToLower(keyword) + "%"
q1 += " AND (LOWER(a.firstname) LIKE ? OR LOWER(a.lastname) LIKE ? OR LOWER(CONCAT(a.firstname, ' ', a.lastname)) LIKE ?)"
params = append(params, k, k, k)
}
q1 += " GROUP BY a.userid, a.firstname, a.lastname, a.contactno, a.status"
utils.Logger.Debugw("RiderSummary SQL generated", "query", q1)
db.DB.Raw(q1, params...).Scan(&data)
return c.JSON(fiber.Map{
"code": http.StatusOK,
"message": "Success",
"status": true,
"details": data,
})
}
func GetRiderLocationSummary(c *fiber.Ctx) error {
aid, _ := strconv.Atoi(c.Query("applocationid"))
pid, _ := strconv.Atoi(c.Query("partnerid"))
tid, _ := strconv.Atoi(c.Query("tenantid"))
lid, _ := strconv.Atoi(c.Query("locationid"))
fdate := c.Query("fromdate")
tdate := c.Query("todate")
var data []models.Ridersummary
var q1 string
var params []interface{}
q1 = Ridersummary + " WHERE a.configid=6 "
if tid != 0 {
q1 += " AND b.tenantid=? "
params = append(params, tid)
}
if lid != 0 {
q1 += " AND b.locationid=? "
params = append(params, lid)
}
if aid != 0 {
q1 += " AND a.applocationid=? "
params = append(params, aid)
}
if pid != 0 {
q1 += " AND a.partnerid=? "
params = append(params, pid)
}
if fdate != "" && tdate != "" {
q1 += " AND b.deliverydate::date BETWEEN ?::date AND ?::date "
params = append(params, fdate, tdate)
}
q1 += " GROUP BY a.userid, b.locationid, a.firstname, a.lastname, a.contactno, b.tenantid, c.tenantname, d.locationname, a.status"
db.DB.Raw(q1, params...).Scan(&data)
utils.Logger.Debugw("RiderLocationSummary SQL generated", "query", q1)
return c.JSON(fiber.Map{
"code": 200,
"message": "Success",
"status": true,
"details": data,
})
}
func GetDeliverySummary(c *fiber.Ctx) error {
// 🔹 Query params
appuid, _ := strconv.Atoi(c.Query("appuserid"))
tid, _ := strconv.Atoi(c.Query("tenantid"))
lid, _ := strconv.Atoi(c.Query("locationid"))
aid, _ := strconv.Atoi(c.Query("applocationid"))
uid, _ := strconv.Atoi(c.Query("userid"))
status := c.Query("status")
fdate := c.Query("fromdate")
tdate := c.Query("todate")
var data models.DeliverySummary
var qb strings.Builder
var params []interface{}
qb.WriteString(core + `
FROM deliveries a
INNER JOIN tenants b ON a.tenantid = b.tenantid
INNER JOIN app_users c ON a.userid = c.userid
INNER JOIN tenantlocations e ON a.locationid = e.locationid
INNER JOIN app_location f ON a.applocationid = f.applocationid
INNER JOIN app_locationconfig g ON f.applocationid = g.applocationid
WHERE b.moduleid = 6
AND g.status = 'Active'
`)
if appuid != 0 {
qb.WriteString(" AND g.userid = ?")
params = append(params, appuid)
}
if tid != 0 {
qb.WriteString(" AND a.tenantid = ?")
params = append(params, tid)
}
if lid != 0 {
qb.WriteString(" AND a.locationid = ?")
params = append(params, lid)
}
if aid != 0 {
qb.WriteString(" AND a.applocationid = ?")
params = append(params, aid)
}
if uid != 0 {
qb.WriteString(" AND a.userid = ?")
params = append(params, uid)
}
if status != "" && strings.ToLower(status) != "all" {
qb.WriteString(" AND a.orderstatus = ?")
params = append(params, status)
}
// 🔹 DATE FILTER (INDEX-FRIENDLY)
if fdate != "" && tdate != "" {
qb.WriteString(`
AND a.deliverydate >= (CONCAT(?::text, ' 00:00:00'))::timestamp
AND a.deliverydate <= (CONCAT(?::text, ' 23:59:59'))::timestamp
`)
params = append(params, fdate, tdate)
}
finalQuery := qb.String()
utils.Logger.Infow("DeliverySummary SQL generated", "query", finalQuery, "params", params)
db.DB.Raw(finalQuery, params...).Scan(&data)
return c.JSON(fiber.Map{
"code": http.StatusOK,
"status": true,
"message": "Success",
"details": data,
})
}
func GetlocationdeliverySummary(c *fiber.Ctx) error {
tenantIDStr := c.Query("tenantid")
tenantID, _ := strconv.Atoi(tenantIDStr)
var data []models.Ordersummary
var q1 string
var params []interface{}
q1 = `SELECT b.locationname, a.applocationid, COUNT(*) AS total,
SUM(CASE WHEN orderstatus = 'created' THEN 1 ELSE 0 END) AS created,
SUM(CASE WHEN orderstatus = 'pending' THEN 1 ELSE 0 END) AS pending,
SUM(CASE WHEN orderstatus = 'processing' THEN 1 ELSE 0 END) AS processing,
SUM(CASE WHEN orderstatus = 'delivered' THEN 1 ELSE 0 END) AS delivered,
SUM(CASE WHEN orderstatus = 'cancelled' THEN 1 ELSE 0 END) AS cancelled
FROM orders a
INNER JOIN app_location b ON a.applocationid = b.applocationid`
// Apply tenant filter only if tenantID != 0
if tenantID != 0 {
q1 += " WHERE a.tenantid = ?"
params = append(params, tenantID)
}
q1 += " GROUP BY a.applocationid, b.locationname"
if err := db.DB.Raw(q1, params...).Scan(&data).Error; err != nil {
return c.Status(http.StatusInternalServerError).JSON(fiber.Map{
"status": false,
"code": http.StatusInternalServerError,
"message": err.Error(),
})
}
return c.JSON(fiber.Map{
"code": http.StatusOK,
"message": "Success",
"status": true,
"details": data,
})
}
func GetDeliveryInsight(c *fiber.Ctx) error {
tenantIDStr := c.Query("tenantid")
tenantID, _ := strconv.Atoi(tenantIDStr)
var locations []models.OrderInsight
var params []interface{}
// Query 1: Get distinct locations
q1 := `SELECT DISTINCT a.applocationid, b.locationname
FROM deliveries a
INNER JOIN app_location b ON a.applocationid = b.applocationid
WHERE b.status = 'Active'`
if tenantID != 0 {
q1 += " AND a.tenantid = ?"
params = append(params, tenantID)
}
if err := db.DB.Raw(q1, params...).Scan(&locations).Error; err != nil {
return c.JSON(fiber.Map{
"code": http.StatusConflict,
"message": err.Error(),
"status": false,
})
}
// Query 2: Fetch delivery insights for each location
q2 := `SELECT
COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM a.deliverydate) = 1 THEN 1 ELSE 0 END), 0) AS jan,
COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM a.deliverydate) = 2 THEN 1 ELSE 0 END), 0) AS feb,
COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM a.deliverydate) = 3 THEN 1 ELSE 0 END), 0) AS mar,
COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM a.deliverydate) = 4 THEN 1 ELSE 0 END), 0) AS apr,
COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM a.deliverydate) = 5 THEN 1 ELSE 0 END), 0) AS may,
COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM a.deliverydate) = 6 THEN 1 ELSE 0 END), 0) AS jun,
COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM a.deliverydate) = 7 THEN 1 ELSE 0 END), 0) AS jul,
COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM a.deliverydate) = 8 THEN 1 ELSE 0 END), 0) AS aug,
COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM a.deliverydate) = 9 THEN 1 ELSE 0 END), 0) AS sep,
COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM a.deliverydate) = 10 THEN 1 ELSE 0 END), 0) AS oct,
COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM a.deliverydate) = 11 THEN 1 ELSE 0 END), 0) AS nov,
COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM a.deliverydate) = 12 THEN 1 ELSE 0 END), 0) AS dece
FROM deliveries a
WHERE a.applocationid = ? AND EXTRACT(YEAR FROM a.deliverydate) = EXTRACT(YEAR FROM CURRENT_DATE)`
if tenantID != 0 {
q2 += " AND a.tenantid = ?"
}
// Fetch monthly delivery counts for each location
for i := range locations {
var orderMonths models.Ordermonths
if tenantID != 0 {
if err := db.DB.Raw(q2, locations[i].Applocationid, tenantID).Scan(&orderMonths).Error; err != nil {
return c.JSON(fiber.Map{
"code": http.StatusConflict,
"message": err.Error(),
"status": false,
})
}
} else {
if err := db.DB.Raw(q2, locations[i].Applocationid).Scan(&orderMonths).Error; err != nil {
return c.JSON(fiber.Map{
"code": http.StatusConflict,
"message": err.Error(),
"status": false,
})
}
}
locations[i].Ordermonths = &orderMonths
}
return c.JSON(fiber.Map{
"code": http.StatusOK,
"message": "Success",
"status": true,
"details": locations,
})
}
func DeliverySummary(c *fiber.Ctx) error {
pid, _ := strconv.Atoi(c.Query("partnerid"))
var data models.DeliverySummary
q1 := `SELECT
COUNT(*) AS deliveries,
SUM(CASE WHEN orderstatus = 'cancelled' THEN 1 ELSE 0 END) AS cancelled,
SUM(round(kms, 2)) AS kms,
SUM(deliveryamt) AS amount
FROM
deliveries
WHERE
partnerid =?`
db.DB.Raw(q1, pid).Find(&data)
return c.JSON(fiber.Map{
"code": http.StatusOK,
"message": "Success",
"status": true,
"details": data,
})
}
func CreateDelivery(c *fiber.Ctx) error {
var data models.Deliveries
if err := c.BodyParser(&data); err != nil {
return err
}
err := domain.CreateDelivery(data)
if err != nil {
return c.JSON(fiber.Map{
"code": http.StatusConflict,
"message": err,
"status": false,
})
} else {
return c.JSON(fiber.Map{
"code": http.StatusCreated,
"message": "Success",
"status": true,
})
}
}
func CreateDeliveries(c *fiber.Ctx) error {
var data []models.Deliveries
if err := c.BodyParser(&data); err != nil {
return err
}
err := domain.CreateDeliveries(data)
if err != nil {
return c.JSON(fiber.Map{
"code": http.StatusConflict,
"message": err.Error(),
"status": false,
})
}
return c.JSON(fiber.Map{
"code": http.StatusCreated,
"message": "Success",
"status": true,
})
}
func CreateDeliveriesV2(c *fiber.Ctx) error {
var data []models.Deliveries
if err := c.BodyParser(&data); err != nil {
return c.Status(400).JSON(fiber.Map{
"status": false,
"code": 400,
"message": "Invalid JSON body",
})
}
utils.Logger.Infow("CreateDeliveriesV2 Call", "records", len(data))
ids, err := domain.CreateDeliveriesV2(data)
if err != nil {
return c.Status(409).JSON(fiber.Map{
"status": false,
"code": 409,
"message": err.Error(),
})
}
return c.JSON(fiber.Map{
"status": true,
"code": 201,
"message": "Deliveries created successfully",
"deliveryids": ids,
})
}
func UpdateDelivery(c *fiber.Ctx) error {
var data models.UpdateDeliveryStatus
if err := c.BodyParser(&data); err != nil {
return err
}
err := domain.UpdateDelivery(data)
if err != nil {
return c.JSON(fiber.Map{
"code": http.StatusConflict,
"message": err.Error(),
"status": false,
})
}
return c.JSON(fiber.Map{
"code": http.StatusCreated,
"message": "Success",
"status": true,
})
}
func GetDeliveryQueues(c *fiber.Ctx) error {
fdate := c.Query("fromdate")
tdate := c.Query("todate")
uid, _ := strconv.Atoi(c.Query("userid"))
result := domain.GetDeliveryQueues(uid, fdate, tdate)
return c.JSON(fiber.Map{
"code": http.StatusOK,
"message": "Success",
"status": true,
"details": result,
})
}
func GetDeliveryQueuesV1(c *fiber.Ctx) error {
fdate := c.Query("fromdate")
tdate := c.Query("todate")
uid, _ := strconv.Atoi(c.Query("userid"))
result := domain.GetDeliveryQueuesV1(uid, fdate, tdate)
return c.JSON(fiber.Map{
"code": http.StatusOK,
"message": "Success",
"status": true,
"details": result,
})
}
func GetDeliveryQueuesPicked(c *fiber.Ctx) error {
fdate := c.Query("fromdate")
tdate := c.Query("todate")
uid, _ := strconv.Atoi(c.Query("userid"))
result := domain.GetDeliveryQueuesPicked(uid, fdate, tdate)
return c.JSON(fiber.Map{
"code": http.StatusOK,
"message": "Success",
"status": true,
"details": result,
})
}
func GetlocationdeliverySummaryDaily(c *fiber.Ctx) error {
tenantIDStr := c.Query("tenantid")
tenantID, _ := strconv.Atoi(tenantIDStr)
var data []models.Ordersummarylocation
var q1 string
var params []interface{}
q1 = `
SELECT
b.locationid,
b.locationname,
COALESCE(COUNT(a.orderid), 0) AS total,
COALESCE(SUM(CASE WHEN a.orderstatus = 'created' THEN 1 ELSE 0 END), 0) AS created,
COALESCE(SUM(CASE WHEN a.orderstatus = 'pending' THEN 1 ELSE 0 END), 0) AS pending,
COALESCE(SUM(CASE WHEN a.orderstatus = 'processing' THEN 1 ELSE 0 END), 0) AS processing,
COALESCE(SUM(CASE WHEN a.orderstatus = 'delivered' THEN 1 ELSE 0 END), 0) AS delivered,
COALESCE(SUM(CASE WHEN a.orderstatus = 'cancelled' THEN 1 ELSE 0 END), 0) AS cancelled
FROM tenantlocations b
LEFT JOIN orders a ON a.locationid = b.locationid
`
// ✅ Apply tenant filter on tenantlocations (not orders only)
if tenantID != 0 {
q1 += " WHERE b.tenantid = ?"
params = append(params, tenantID)
}
q1 += " GROUP BY b.locationid, b.locationname"
if err := db.DB.Raw(q1, params...).Scan(&data).Error; err != nil {
return c.Status(http.StatusInternalServerError).JSON(fiber.Map{
"status": false,
"code": http.StatusInternalServerError,
"message": err.Error(),
})
}
return c.JSON(fiber.Map{
"code": http.StatusOK,
"message": "Success",
"status": true,
"details": data,
})
}
func GetDeliveryInsightDaily(c *fiber.Ctx) error {
tenantIDStr := c.Query("tenantid")
tenantID, _ := strconv.Atoi(tenantIDStr)
var locations []models.OrderInsightv1
var params []interface{}
q1 := `SELECT DISTINCT l.locationid, l.locationname
FROM tenantlocations l
LEFT JOIN deliveries d ON l.locationid = d.locationid
WHERE l.status = 'Active'`
if tenantID != 0 {
q1 += " AND l.tenantid = ?"
params = append(params, tenantID)
}
if err := db.DB.Raw(q1, params...).Scan(&locations).Error; err != nil {
return c.JSON(fiber.Map{
"code": http.StatusConflict,
"message": err.Error(),
"status": false,
})
}
q2 := `SELECT
COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM d.deliverydate) = 1 THEN 1 ELSE 0 END), 0) AS jan,
COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM d.deliverydate) = 2 THEN 1 ELSE 0 END), 0) AS feb,
COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM d.deliverydate) = 3 THEN 1 ELSE 0 END), 0) AS mar,
COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM d.deliverydate) = 4 THEN 1 ELSE 0 END), 0) AS apr,
COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM d.deliverydate) = 5 THEN 1 ELSE 0 END), 0) AS may,
COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM d.deliverydate) = 6 THEN 1 ELSE 0 END), 0) AS jun,
COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM d.deliverydate) = 7 THEN 1 ELSE 0 END), 0) AS jul,
COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM d.deliverydate) = 8 THEN 1 ELSE 0 END), 0) AS aug,
COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM d.deliverydate) = 9 THEN 1 ELSE 0 END), 0) AS sep,
COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM d.deliverydate) = 10 THEN 1 ELSE 0 END), 0) AS oct,
COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM d.deliverydate) = 11 THEN 1 ELSE 0 END), 0) AS nov,
COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM d.deliverydate) = 12 THEN 1 ELSE 0 END), 0) AS dece
FROM deliveries d
WHERE d.locationid = ? AND EXTRACT(YEAR FROM d.deliverydate) = EXTRACT(YEAR FROM CURRENT_DATE)`
if tenantID != 0 {
q2 += " AND d.tenantid = ?"
}
for i := range locations {
var orderMonths models.Ordermonths
if tenantID != 0 {
if err := db.DB.Raw(q2, locations[i].Locationid, tenantID).Scan(&orderMonths).Error; err != nil {
return c.JSON(fiber.Map{
"code": http.StatusConflict,
"message": err.Error(),
"status": false,
})
}
} else {
if err := db.DB.Raw(q2, locations[i].Locationid).Scan(&orderMonths).Error; err != nil {
return c.JSON(fiber.Map{
"code": http.StatusConflict,
"message": err.Error(),
"status": false,
})
}
}
locations[i].Ordermonths = &orderMonths
}
return c.JSON(fiber.Map{
"code": http.StatusOK,
"message": "Success",
"status": true,
"details": locations,
})
}
func PublishLogv1(c *fiber.Ctx) error {
var data []models.Deliverylogs
if err := c.BodyParser(&data); err != nil {
return c.Status(http.StatusBadRequest).JSON(fiber.Map{
"status": false,
"code": http.StatusBadRequest,
"message": "Invalid JSON body",
})
}
err := domain.PublishLogv1(data)
if err != nil {
return c.Status(http.StatusConflict).JSON(fiber.Map{
"status": false,
"code": http.StatusConflict,
"message": err.Error(),
})
}
return c.JSON(fiber.Map{
"status": true,
"code": http.StatusOK,
"message": "Successfully saved logs to Redis",
})
}
func GetDeliverylogsv1(c *fiber.Ctx) error {
did, _ := strconv.Atoi(c.Query("deliveryid"))
result, err := domain.GetDeliverylogsv1(did)
if err != nil {
return c.JSON(fiber.Map{
"code": http.StatusConflict,
"message": err.Error(),
"status": false,
"details": []models.Deliverylogs{},
})
}
return c.JSON(fiber.Map{
"code": http.StatusOK,
"message": "Success",
"status": true,
"details": result,
})
}
func GetDeliveryLogsv1(c *fiber.Ctx) error {
deliveryID := c.Query("deliveryid")
if deliveryID == "" {
return c.Status(http.StatusBadRequest).JSON(fiber.Map{
"code": http.StatusBadRequest,
"message": "deliveryid is required",
"status": false,
})
}
logs, err := domain.GetDeliveryLogsv1(deliveryID)
if err != nil {
return c.Status(http.StatusInternalServerError).JSON(fiber.Map{
"code": http.StatusInternalServerError,
"message": err.Error(),
"status": false,
})
}
return c.JSON(fiber.Map{
"code": 200,
"details": logs,
"status": true,
})
}
func GetRiderByDelivery(c *fiber.Ctx) error {
fromdate := strings.TrimSpace(c.Query("fromdate"))
todate := strings.TrimSpace(c.Query("todate"))
keyword := strings.TrimSpace(c.Query("keyword"))
if fromdate == "" || todate == "" {
return c.Status(400).JSON(fiber.Map{
"code": 400,
"status": false,
"message": "fromdate and todate are required",
})
}
applocationidStr := strings.TrimSpace(c.Query("applocationid"))
tenantidStr := strings.TrimSpace(c.Query("tenantid"))
locationidStr := strings.TrimSpace(c.Query("locationid"))
applocationid, _ := strconv.Atoi(applocationidStr)
tenantid, _ := strconv.Atoi(tenantidStr)
locationid, _ := strconv.Atoi(locationidStr)
var users []models.User
var params []interface{}
query := `
SELECT b.userid,b.authname,b.firstname,b.lastname,b.password,b.email,b.dialcode,b.contactno,b.configid,b.authmode,b.roleid,b.pin,b.deviceid,b.devicetype,b.userfcmtoken,
b.address,b.suburb,b.city,b.state,b.postcode,b.partnerid,a.tenantid,a.locationid,a.applocationid,b.status,b.shiftid,b.hashsalt
FROM deliveries a
LEFT JOIN app_users b ON a.userid = b.userid
WHERE a.deliverydate::date BETWEEN ?::date AND ?::date
`
params = append(params, fromdate, todate)
if tenantid != 0 {
query += " AND a.tenantid = ?"
params = append(params, tenantid)
}
if locationid != 0 {
query += " AND a.locationid = ?"
params = append(params, locationid)
}
if applocationid != 0 {
query += " AND a.applocationid = ?"
params = append(params, applocationid)
}
if keyword != "" {
k := "%" + strings.ToLower(keyword) + "%"
query += `
AND (
LOWER(b.firstname) LIKE ? OR
LOWER(b.lastname) LIKE ? OR
LOWER(b.contactno) LIKE ?
)
`
params = append(params, k, k, k)
}
query += " GROUP BY b.userid ORDER BY b.userid DESC"
if err := db.DB.Raw(query, params...).Scan(&users).Error; err != nil {
return c.Status(500).JSON(fiber.Map{
"code": 500,
"status": false,
"message": "Database error: " + err.Error(),
})
}
return c.JSON(fiber.Map{
"code": 200,
"status": true,
"details": users,
})
}
func GetLastDeliveryByContact(c *fiber.Ctx) error {
deliverycontactno := c.Query("deliverycontactno")
fromdate := c.Query("fromdate")
todate := c.Query("todate")
var data []models.Deliveries
var query string
var args []interface{}
dateCondition := ""
if fromdate != "" && todate != "" {
dateCondition = " AND deliverydate::date BETWEEN ?::date AND ?::date "
args = append(args, fromdate, todate)
} else if fromdate != "" {
dateCondition = " AND deliverydate::date >= ?::date "
args = append(args, fromdate)
} else if todate != "" {
dateCondition = " AND deliverydate::date <= ?::date "
args = append(args, todate)
}
if deliverycontactno == "" {
query = `
SELECT d.*
FROM deliveries d
INNER JOIN (
SELECT deliverycontactno, MAX(deliveryid) AS maxid
FROM deliveries
WHERE 1=1 ` + dateCondition + `
GROUP BY deliverycontactno
) t ON d.deliveryid = t.maxid
ORDER BY d.deliveryid DESC;
`
} else {
query = `
SELECT *
FROM deliveries
WHERE deliverycontactno = ? ` + dateCondition + `
ORDER BY deliveryid DESC
LIMIT 1;
`
args = append([]interface{}{deliverycontactno}, args...)
}
if err := db.DB.Raw(query, args...).Scan(&data).Error; err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"code": 500,
"message": err.Error(),
"status": false,
})
}
return c.Status(200).JSON(fiber.Map{
"code": 200,
"message": "Success",
"details": data,
"status": true,
})
}
func GetUserReportSummary(c *fiber.Ctx) error {
tid, _ := strconv.Atoi(c.Query("tenantid"))
// pid, _ := strconv.Atoi(c.Query("partnerid"))
uid, _ := strconv.Atoi(c.Query("userid"))
// aid, _ := strconv.Atoi(c.Query("applocationid"))
fdate := c.Query("fromdate")
tdate := c.Query("todate")
var data []models.UserReportSummary
var q1 string
var params []interface{}
q1 = reports
if tid != 0 {
q1 += " WHERE a.tenantid = ?"
params = append(params, tid)
} else if uid != 0 {
q1 += " WHERE c.userid = ?"
params = append(params, uid)
} else {
q1 += " WHERE 1=1"
}
if fdate != "" && tdate != "" {
q1 += " AND a.orderdate::date BETWEEN ?::date AND ?::date"
params = append(params, fdate, tdate)
}
q1 += ` GROUP BY
c.userid, e.firstname, e.lastname, e.contactno,
b.tenantid, b.tenantname`
utils.Logger.Debugw("RiderLocationReportSummary SQL generated", "query", q1)
db.DB.Raw(q1, params...).Scan(&data)
return c.JSON(fiber.Map{
"code": http.StatusOK,
"message": "Success",
"status": true,
"details": data,
})
}
func GetUserDeliveryLogs(c *fiber.Ctx) error {
userid, err := strconv.Atoi(c.Query("userid"))
if err != nil || userid == 0 {
return c.Status(400).JSON(fiber.Map{
"code": 400,
"message": "Invalid userid",
"status": false,
"details": []models.Deliverylogs{},
})
}
fromdate := strings.TrimSpace(c.Query("fromdate"))
todate := strings.TrimSpace(c.Query("todate"))
result, err := domain.GetUserDeliveryLogs(userid, fromdate, todate)
if err != nil {
return c.JSON(fiber.Map{
"code": 409,
"message": err.Error(),
"status": false,
"details": []models.Deliverylogs{},
})
}
return c.JSON(fiber.Map{
"code": 200,
"message": "Success",
"status": true,
"details": result,
})
}