1296 lines
35 KiB
Go
1296 lines
35 KiB
Go
package domain
|
||
|
||
import (
|
||
"context"
|
||
"encoding/json"
|
||
"errors"
|
||
"nearle/db"
|
||
"nearle/models"
|
||
"nearle/utils"
|
||
"strconv"
|
||
"strings"
|
||
"time"
|
||
|
||
"github.com/jinzhu/copier"
|
||
"github.com/redis/go-redis/v9"
|
||
)
|
||
|
||
const (
|
||
deliveries = `SELECT distinct a.deliveryid,a.applocationid,f.locationname AS applocation,a.orderheaderid,a.configid,a.tenantid,a.partnerid,a.locationid,a.userid,a.categoryid,a.subcategoryid,a.moduleid,
|
||
a.orderid,a.deliverydate,a.orderstatus,a.assigntime,a.starttime,a.arrivaltime,a.pickuptime,a.deliverytime,a.canceltime,a.acceptedtime,
|
||
a.customerid,a.pickupcustomer,a.pickupcontactno,a.pickuplocationid,a.pickupaddress,a.pickuplocation,a.pickuplat,a.pickuplon,
|
||
a.deliverycustomerid,a.deliverycustomer,a.deliverycontactno,a.deliverylocationid,a.deliveryaddress,a.deliverylocation,
|
||
a.droplat,a.droplon,a.deliverylat,a.deliverylong,
|
||
a.riderslat,a.riderslon,a.deliveryamt,a.kms,a.actualkms,a.riderkms,a.deliverycharges,a.deliverytype,a.paymenttype,a.smsdelivery,a.quantity,a.collectionamt,a.collectedamt,a.collectionstatus,
|
||
a.notes,a.ordernotes,a.step,a.eta,a.previouskms,a.cumulativekms,a.ridertime,b.tenantname,b.primarycontact as tenantcontactno,b.tenanttoken,b.suburb as tenantsuburb,b.city as tenantcity,
|
||
b.address AS tenantaddress, CONCAT(c.firstname, ' ', c.lastname) AS ridername,c.userfcmtoken,c.contactno as ridercontact,e.locationname,e.suburb AS locationsuburb,e.contactno AS locationcontactno,e.address AS locationaddress,
|
||
h.slab, h.pricingdate, h.baseprice, h.minkm, h.priceperkm, h.maxkm, h.orders, h.othercharges, h.surgecharges,
|
||
a.expecteddeliverytime, a.profit, a.transitminutes, a.calculationdistancekm
|
||
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
|
||
LEFT JOIN tenantpricing h ON a.tenantid = h.tenantid`
|
||
)
|
||
|
||
func PublishLog(input []models.Deliverylogs) error {
|
||
|
||
logInfo("PublishLog", "records", len(input))
|
||
|
||
tx := db.DB.Begin()
|
||
|
||
for i := range input {
|
||
|
||
t1 := tx.Create(&input[i])
|
||
if t1.Error != nil {
|
||
logError("PublishLog failed", "error", tx.Error)
|
||
tx.Rollback()
|
||
return t1.Error
|
||
}
|
||
|
||
}
|
||
|
||
err := tx.Commit().Error
|
||
if err != nil {
|
||
|
||
return err
|
||
}
|
||
|
||
return nil
|
||
|
||
}
|
||
|
||
func CreateDeliveries(data []models.Deliveries) error {
|
||
logInfo("CreateDeliveries", "records", len(data))
|
||
|
||
var que []models.Deliveryqueues
|
||
|
||
var ord models.Updateorderstatus
|
||
|
||
tx := db.DB.Begin()
|
||
|
||
for i := range data {
|
||
|
||
t1 := tx.Create(&data[i])
|
||
if t1.Error != nil {
|
||
logError("CreateDeliveries failed", "error", tx.Error)
|
||
tx.Rollback()
|
||
return t1.Error
|
||
}
|
||
|
||
if err := copier.Copy(&que, &data[i]); err != nil {
|
||
return err
|
||
}
|
||
|
||
t2 := tx.Create(&que)
|
||
if t2.Error != nil {
|
||
logError("CreateDeliveries queue failed", "error", tx.Error)
|
||
tx.Rollback()
|
||
return t2.Error
|
||
}
|
||
ord.Orderstatus = data[i].Orderstatus
|
||
ord.Pending = data[i].Deliverydate
|
||
|
||
t3 := tx.Table("orders").Where("orderheaderid=?", data[i].Orderheaderid).Updates(&ord)
|
||
if t3.Error != nil {
|
||
|
||
logError("CreateDeliveries order update failed", "error", tx.Error)
|
||
tx.Rollback()
|
||
return t3.Error
|
||
|
||
}
|
||
|
||
}
|
||
|
||
err := tx.Commit().Error
|
||
if err != nil {
|
||
|
||
return err
|
||
}
|
||
|
||
return nil
|
||
|
||
}
|
||
|
||
func CreateDeliveriesV2(data []models.Deliveries) ([]int64, error) {
|
||
|
||
ctx := db.Ctx
|
||
var deliveryIDs []int64
|
||
|
||
logInfo("🔥 CreateDeliveriesV2 DOMAIN CALLED")
|
||
|
||
for _, d := range data {
|
||
|
||
// 🔒 Rider guard key
|
||
riderKey := "rider:" + strconv.Itoa(d.Userid) + ":active_delivery"
|
||
|
||
// ⏱ delivery TTL (example: 2 hours)
|
||
ttl := 2 * time.Hour
|
||
|
||
// 🔒 PREVENT DOUBLE ASSIGN (CREATE ONLY IF NOT EXISTS)
|
||
ok, err := db.Rdb.SetNX(ctx, riderKey, "LOCK", ttl).Result()
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
if !ok {
|
||
return nil, errors.New("rider " + strconv.Itoa(d.Userid) + " already has active delivery")
|
||
}
|
||
|
||
// 🔥 Generate delivery ID
|
||
deliveryID, err := db.Rdb.Incr(ctx, "counter:deliveryid").Result()
|
||
if err != nil {
|
||
db.Rdb.Del(ctx, riderKey)
|
||
return nil, err
|
||
}
|
||
|
||
deliveryIDs = append(deliveryIDs, deliveryID)
|
||
|
||
// 🔑 Redis keys
|
||
deliveryKey := "delivery:active:" + strconv.FormatInt(deliveryID, 10)
|
||
cityKey := "city:" + strconv.Itoa(d.Tenantid) + ":active_deliveries"
|
||
|
||
pipe := db.Rdb.TxPipeline()
|
||
|
||
// 🔥 ACTIVE DELIVERY HASH (AUTO-CREATES)
|
||
pipe.HSet(ctx, deliveryKey, map[string]interface{}{
|
||
"delivery_id": deliveryID,
|
||
"orderheaderid": d.Orderheaderid,
|
||
"orderid": d.Orderid,
|
||
"tenantid": d.Tenantid, // city
|
||
"partnerid": d.Partnerid,
|
||
"rider_id": d.Userid,
|
||
"status": "ASSIGNED",
|
||
"pickupaddress": d.Pickupaddress,
|
||
"deliveryaddress": d.Deliveryaddress,
|
||
"pickuplat": d.Pickuplat,
|
||
"pickuplon": d.Pickuplon,
|
||
"deliverylat": d.Deliverylat,
|
||
"deliverylong": d.Deliverylong,
|
||
"eta": d.Eta,
|
||
"expecteddeliverytime": d.Expecteddeliverytime,
|
||
"profit": d.Profit,
|
||
"transitminutes": d.Transitminutes,
|
||
"calculationdistancekm": d.Calculationdistancekm,
|
||
"created_at": time.Now().Unix(),
|
||
"last_updated": time.Now().Unix(),
|
||
})
|
||
|
||
// 🔥 CITY → ACTIVE DELIVERIES INDEX (AUTO-CREATES)
|
||
pipe.SAdd(ctx, cityKey, deliveryID)
|
||
|
||
// 🔥 SET RIDER VALUE (REPLACE LOCK)
|
||
pipe.Set(ctx, riderKey, deliveryID, ttl)
|
||
|
||
// 🔥 TTL ONLY ON DELIVERY & RIDER (NEVER CITY)
|
||
pipe.Expire(ctx, deliveryKey, ttl)
|
||
|
||
cmds, err := pipe.Exec(ctx)
|
||
if err != nil {
|
||
db.Rdb.Del(ctx, riderKey)
|
||
return nil, err
|
||
}
|
||
|
||
// 🔍 Per-command safety check
|
||
for _, cmd := range cmds {
|
||
if cmd.Err() != nil {
|
||
db.Rdb.Del(ctx, riderKey)
|
||
return nil, cmd.Err()
|
||
}
|
||
}
|
||
|
||
logInfo("✅ Delivery created", "deliveryID", deliveryID)
|
||
}
|
||
|
||
logInfo("✅ CreateDeliveriesV2 COMPLETED")
|
||
return deliveryIDs, nil
|
||
}
|
||
|
||
func CreateDelivery(data models.Deliveries) error {
|
||
logInfo("CreateDelivery", "orderheaderid", data.Orderheaderid)
|
||
|
||
var que models.Deliveryqueues
|
||
var ord models.Updateorderstatus
|
||
|
||
tx := db.DB.Begin()
|
||
|
||
t1 := tx.Table("deliveries").Create(&data)
|
||
if t1.Error != nil {
|
||
|
||
tx.Rollback()
|
||
return t1.Error
|
||
}
|
||
|
||
if err := copier.Copy(&que, &data); err != nil {
|
||
|
||
return err
|
||
}
|
||
|
||
t2 := tx.Table("deliveryqueues").Create(&que)
|
||
if t2.Error != nil {
|
||
|
||
logError("CreateDelivery queue failed", "error", tx.Error)
|
||
tx.Rollback()
|
||
return t2.Error
|
||
}
|
||
|
||
ord.Orderstatus = data.Orderstatus
|
||
ord.Pending = data.Assigntime
|
||
|
||
t3 := tx.Table("orders").Where("orderheaderid=?", data.Orderheaderid).Updates(&ord)
|
||
if t3.Error != nil {
|
||
|
||
logError("CreateDelivery order update failed", "error", tx.Error)
|
||
tx.Rollback()
|
||
return t3.Error
|
||
}
|
||
|
||
err := tx.Commit().Error
|
||
if err != nil {
|
||
|
||
return err
|
||
|
||
}
|
||
return nil
|
||
|
||
}
|
||
|
||
func UpdateDelivery(data models.UpdateDeliveryStatus) error {
|
||
logInfo("UpdateDelivery", "deliveryid", data.Deliveryid, "status", data.Orderstatus)
|
||
|
||
var ord models.Updateorderstatus
|
||
var cloc models.Customerlocations
|
||
|
||
tx := db.DB.Begin()
|
||
|
||
t1 := tx.Table("deliveries").Where("deliveryid=?", data.Deliveryid).Updates(&data)
|
||
if t1.Error != nil {
|
||
|
||
logError("UpdateDelivery failed", "error", tx.Error)
|
||
tx.Rollback()
|
||
}
|
||
|
||
if data.Orderstatus == "pending" {
|
||
|
||
ord.Orderstatus = data.Orderstatus
|
||
ord.Pending = data.Assigntime
|
||
|
||
t2 := tx.Table("orders").Where("orderheaderid=?", data.Orderheaderid).Updates(&ord)
|
||
if t2.Error != nil {
|
||
|
||
logError("UpdateDelivery pending update failed", "error", tx.Error)
|
||
tx.Rollback()
|
||
}
|
||
|
||
}
|
||
|
||
if data.Orderstatus == "picked" {
|
||
|
||
if data.Pickuplocationid != 0 && data.Deliverytype != "B" {
|
||
|
||
cloc.Latitude = data.Riderslat
|
||
cloc.Longitude = data.Riderslon
|
||
cloc.Address = data.Address
|
||
cloc.Suburb = data.Suburb
|
||
cloc.City = data.City
|
||
cloc.State = data.State
|
||
cloc.Postcode = data.Postcode
|
||
|
||
t5 := tx.Table("customerlocations").Where("locationid=?", data.Pickuplocationid).Updates(&cloc)
|
||
if t5.Error != nil {
|
||
|
||
logError("UpdateDelivery customer location update failed", "error", tx.Error)
|
||
tx.Rollback()
|
||
}
|
||
|
||
}
|
||
|
||
}
|
||
|
||
if data.Orderstatus == "delivered" {
|
||
|
||
ord.Orderstatus = data.Orderstatus
|
||
ord.Delivered = data.Deliverytime
|
||
|
||
t2 := tx.Table("orders").Where("orderheaderid=?", data.Orderheaderid).Updates(&ord)
|
||
if t2.Error != nil {
|
||
|
||
logError("UpdateDelivery delivered update failed", "error", tx.Error)
|
||
tx.Rollback()
|
||
}
|
||
|
||
if data.Deliverylocationid != 0 && data.Deliverytype != "B" {
|
||
|
||
cloc.Latitude = data.Deliverylat
|
||
cloc.Longitude = data.Deliverylong
|
||
cloc.Address = data.Address
|
||
cloc.Suburb = data.Suburb
|
||
cloc.City = data.City
|
||
cloc.State = data.State
|
||
cloc.Postcode = data.Postcode
|
||
|
||
t5 := tx.Table("customerlocations").Where("locationid=?", data.Deliverylocationid).Updates(&cloc)
|
||
if t5.Error != nil {
|
||
|
||
logError("UpdateDelivery delivery location update failed", "error", tx.Error)
|
||
tx.Rollback()
|
||
}
|
||
|
||
}
|
||
|
||
}
|
||
|
||
if data.Orderstatus == "cancelled" {
|
||
|
||
ord.Orderstatus = data.Orderstatus
|
||
ord.Cancelled = data.Canceltime
|
||
|
||
t2 := tx.Table("orders").Where("orderheaderid=?", data.Orderheaderid).Updates(&ord)
|
||
if t2.Error != nil {
|
||
|
||
logError("UpdateDelivery cancelled update failed", "error", tx.Error)
|
||
tx.Rollback()
|
||
}
|
||
|
||
}
|
||
|
||
err := tx.Commit().Error
|
||
|
||
if err != nil {
|
||
|
||
return err
|
||
|
||
}
|
||
|
||
return err
|
||
|
||
}
|
||
|
||
func GetDeliveryQueues(uid int, fdate, tdate string) []models.Deliveryinfo {
|
||
logInfo("GetDeliveryQueues", "userid", uid)
|
||
|
||
var data []models.Deliveryinfo
|
||
|
||
var q1 string
|
||
|
||
if fdate != "" && tdate != "" {
|
||
|
||
q1 = deliveries + " where a.orderstatus='pending' and a.userid= ? and a.deliverydate::date between ? and ? order by a.deliveryid asc"
|
||
db.DB.Raw(q1, uid, fdate, tdate).Find(&data)
|
||
|
||
} else {
|
||
|
||
q1 = deliveries + " where a.orderstatus='pending' and a.userid= ? and a.deliverydate::date = CURRENT_DATE order by a.deliveryid asc"
|
||
db.DB.Raw(q1, uid).Find(&data)
|
||
}
|
||
|
||
logInfo("GetDeliveryQueues Query executed", "userid", uid)
|
||
|
||
return data
|
||
|
||
}
|
||
|
||
func GetDeliveryQueuesV1(uid int, fdate, tdate string) []models.Deliveryinfo {
|
||
logInfo("GetDeliveryQueuesV1", "userid", uid)
|
||
var data []models.Deliveryinfo
|
||
var q1 string
|
||
|
||
statusFilter := `a.orderstatus IN ('pending', 'accepted', 'arrived')`
|
||
|
||
if fdate != "" && tdate != "" {
|
||
q1 = deliveries + " WHERE " + statusFilter + " AND a.userid = ? AND a.deliverydate::date BETWEEN ? AND ? ORDER BY a.deliveryid ASC"
|
||
db.DB.Raw(q1, uid, fdate, tdate).Find(&data)
|
||
} else {
|
||
q1 = deliveries + " WHERE " + statusFilter + " AND a.userid = ? AND a.deliverydate::date = CURRENT_DATE ORDER BY a.deliveryid ASC"
|
||
db.DB.Raw(q1, uid).Find(&data)
|
||
}
|
||
|
||
return data
|
||
}
|
||
|
||
func GetDeliveryQueuesPicked(uid int, fdate, tdate string) []models.Deliveryinfo {
|
||
logInfo("GetDeliveryQueuesPicked", "userid", uid)
|
||
|
||
var data []models.Deliveryinfo
|
||
|
||
var q1 string
|
||
|
||
if fdate != "" && tdate != "" {
|
||
|
||
q1 = deliveries + " where a.orderstatus='picked' and a.userid=? and a.deliverydate::date between ? and ? order by a.deliveryid asc"
|
||
db.DB.Raw(q1, uid, fdate, tdate).Find(&data)
|
||
|
||
} else {
|
||
|
||
q1 = deliveries + " where a.orderstatus='picked' and a.userid=? and a.deliverydate::date = CURRENT_DATE order by a.deliveryid asc"
|
||
db.DB.Raw(q1, uid).Find(&data)
|
||
}
|
||
|
||
return data
|
||
|
||
}
|
||
|
||
func GetDeliverylogs(did int) []models.Deliverylogs {
|
||
logInfo("GetDeliverylogs", "deliveryid", did)
|
||
|
||
var data []models.Deliverylogs
|
||
|
||
q1 := "select * from deliverylogs where deliveryid=? order by logid asc"
|
||
db.DB.Raw(q1, did).Find(&data)
|
||
|
||
return data
|
||
|
||
}
|
||
|
||
func GetTenantDeliveries(input models.DeliveryQuery) []models.Deliveryinfo {
|
||
logInfo("🔍 Fetching Tenant Deliveries", "tenantid", input.Tenantid)
|
||
|
||
var data []models.Deliveryinfo
|
||
var queryBuilder strings.Builder
|
||
var params []interface{}
|
||
|
||
offset := (input.Pageno - 1) * input.Pagesize
|
||
|
||
baseQuery := `
|
||
SELECT a.*, b.tenantname,
|
||
CONCAT(c.firstname, ' ', c.lastname) AS ridername,
|
||
c.contactno AS ridercontact, c.userfcmtoken,
|
||
d.locationname, d.contactno AS locationcontactno,
|
||
d.suburb AS locationsuburb, d.address AS locationaddress,
|
||
e.slab, e.pricingdate, e.baseprice, e.minkm,
|
||
e.priceperkm, e.maxkm, e.orders,
|
||
e.othercharges, e.surgecharges
|
||
FROM deliveries a
|
||
JOIN tenants b ON a.tenantid = b.tenantid
|
||
JOIN app_users c ON a.userid = c.userid
|
||
JOIN tenantlocations d ON a.locationid = d.locationid
|
||
JOIN tenantpricing e ON a.tenantid = e.tenantid
|
||
WHERE b.moduleid = 6
|
||
AND a.tenantid = ?
|
||
`
|
||
queryBuilder.WriteString(baseQuery)
|
||
params = append(params, input.Tenantid)
|
||
|
||
// ✅ USERID FILTER (FIX)
|
||
if input.UserID > 0 {
|
||
queryBuilder.WriteString(" AND a.userid = ?")
|
||
params = append(params, input.UserID)
|
||
}
|
||
|
||
// ✅ STATUS FILTER (ignore "all")
|
||
if input.Status != "" && strings.ToLower(input.Status) != "all" {
|
||
queryBuilder.WriteString(" AND LOWER(a.orderstatus) = LOWER(?)")
|
||
params = append(params, input.Status)
|
||
}
|
||
|
||
// ✅ DATE FILTER
|
||
if input.Fromdate != "" && input.ToDate != "" {
|
||
queryBuilder.WriteString(" AND a.deliverydate::date BETWEEN ? AND ?")
|
||
params = append(params, input.Fromdate, input.ToDate)
|
||
}
|
||
|
||
// ✅ KEYWORD FILTER
|
||
if input.Keyword != "" {
|
||
k := "%" + strings.ToLower(input.Keyword) + "%"
|
||
|
||
queryBuilder.WriteString(`
|
||
AND (
|
||
LOWER(a.pickupcustomer) LIKE ? OR
|
||
LOWER(a.deliverycustomer) LIKE ? OR
|
||
LOWER(a.pickupcontactno) LIKE ? OR
|
||
LOWER(a.deliverycontactno) LIKE ? OR
|
||
LOWER(CAST(a.orderid AS CHAR)) LIKE ? OR
|
||
LOWER(c.firstname) LIKE ? OR
|
||
LOWER(c.lastname) LIKE ? OR
|
||
LOWER(c.contactno) LIKE ?
|
||
)
|
||
`)
|
||
|
||
for i := 0; i < 8; i++ {
|
||
params = append(params, k)
|
||
}
|
||
}
|
||
|
||
queryBuilder.WriteString(" ORDER BY a.deliveryid DESC")
|
||
|
||
if input.Pagesize > 0 {
|
||
queryBuilder.WriteString(" LIMIT ? OFFSET ?")
|
||
params = append(params, input.Pagesize, offset)
|
||
}
|
||
|
||
query := queryBuilder.String()
|
||
// print("Final Query:", query)
|
||
db.DB.Raw(query, params...).Scan(&data)
|
||
return data
|
||
}
|
||
|
||
func GetPartnerDeliveries(input models.DeliveryQuery) []models.Deliveryinfo {
|
||
|
||
logInfo("Partner Deliveries", "partnerid", input.Partnerid)
|
||
|
||
var data []models.Deliveryinfo
|
||
var qb strings.Builder
|
||
var params []interface{}
|
||
|
||
offset := (input.Pageno - 1) * input.Pagesize
|
||
|
||
// 🔹 Base query
|
||
qb.WriteString(deliveries)
|
||
qb.WriteString(` WHERE b.moduleid = 6 AND a.partnerid = ?`)
|
||
params = append(params, input.Partnerid)
|
||
|
||
// 🔹 STATUS FILTER (ignore "all")
|
||
if input.Status != "" && strings.ToLower(input.Status) != "all" {
|
||
qb.WriteString(` AND LOWER(a.orderstatus) = LOWER(?)`)
|
||
params = append(params, input.Status)
|
||
}
|
||
|
||
// 🔹 DATE FILTER
|
||
if input.Fromdate != "" && input.ToDate != "" {
|
||
qb.WriteString(` AND a.deliverydate::date BETWEEN ? AND ?`)
|
||
params = append(params, input.Fromdate, input.ToDate)
|
||
}
|
||
|
||
// 🔹 ORDER
|
||
qb.WriteString(` ORDER BY a.deliveryid DESC`)
|
||
|
||
// 🔹 PAGINATION
|
||
if input.Pagesize > 0 {
|
||
qb.WriteString(` LIMIT ? OFFSET ?`)
|
||
params = append(params, input.Pagesize, offset)
|
||
}
|
||
|
||
finalQuery := qb.String()
|
||
logInfo("Final Query", "query", finalQuery)
|
||
logInfo("Params", "params", params)
|
||
|
||
db.DB.Raw(finalQuery, params...).Scan(&data)
|
||
return data
|
||
}
|
||
|
||
func GetCustomerDeliveries(input models.DeliveryQuery) []models.Deliveryinfo {
|
||
|
||
logInfo("Customer Deliveries", "partnerid", input.Partnerid)
|
||
|
||
var q1 string
|
||
offset := (input.Pageno - 1) * input.Pagesize
|
||
var data []models.Deliveryinfo
|
||
|
||
// ✅ Apply status filter ONLY if status != "" AND status != "all"
|
||
if input.Status != "" && strings.ToLower(input.Status) != "all" {
|
||
|
||
if input.Fromdate != "" && input.ToDate != "" {
|
||
|
||
if input.Pagesize != 0 {
|
||
|
||
q1 = deliveries + " where b.moduleid=6 and a.partnerid=? and a.orderstatus=? and a.deliverydate::date between ? and ? order by deliveryid desc LIMIT ? OFFSET ?"
|
||
db.DB.Raw(q1, input.Partnerid, input.Status, input.Fromdate, input.ToDate, input.Pagesize, offset).Find(&data)
|
||
|
||
} else {
|
||
|
||
q1 = deliveries + " where b.moduleid=6 and a.partnerid=? and a.orderstatus=? and a.deliverydate::date between ? and ? order by deliveryid desc"
|
||
db.DB.Raw(q1, input.Partnerid, input.Status, input.Fromdate, input.ToDate).Find(&data)
|
||
}
|
||
|
||
} else {
|
||
|
||
if input.Pagesize != 0 {
|
||
|
||
q1 = deliveries + " where b.moduleid=6 and a.partnerid=? and a.orderstatus=? order by deliveryid desc LIMIT ? OFFSET ?"
|
||
db.DB.Raw(q1, input.Partnerid, input.Status, input.Pagesize, offset).Find(&data)
|
||
|
||
} else {
|
||
|
||
q1 = deliveries + " where b.moduleid=6 and a.partnerid=? and a.orderstatus=? order by deliveryid desc"
|
||
db.DB.Raw(q1, input.Partnerid, input.Status).Find(&data)
|
||
}
|
||
}
|
||
|
||
} else {
|
||
// ✅ status = "" OR status = "all" → NO STATUS FILTER
|
||
|
||
if input.Pagesize != 0 {
|
||
|
||
q1 = deliveries + " where b.moduleid=6 and a.partnerid=? and a.deliverydate::date between ? and ? order by deliveryid desc LIMIT ? OFFSET ?"
|
||
db.DB.Raw(q1, input.Partnerid, input.Fromdate, input.ToDate, input.Pagesize, offset).Find(&data)
|
||
|
||
} else {
|
||
|
||
q1 = deliveries + " where b.moduleid=6 and a.partnerid=? and a.deliverydate::date between ? and ? order by deliveryid desc"
|
||
db.DB.Raw(q1, input.Partnerid, input.Fromdate, input.ToDate).Find(&data)
|
||
}
|
||
}
|
||
return data
|
||
}
|
||
|
||
func GetAdminDeliveries(input models.DeliveryQuery) []models.Deliveryinfo {
|
||
logInfo("Admin Deliveries", "applocationid", input.Applocationid)
|
||
|
||
var data []models.Deliveryinfo
|
||
var qb strings.Builder
|
||
var params []interface{}
|
||
|
||
offset := (input.Pageno - 1) * input.Pagesize
|
||
|
||
qb.WriteString(`
|
||
SELECT a.*,
|
||
b.tenantname,b.primarycontact as tenantcontactno,b.tenanttoken,b.suburb as tenantsuburb,b.city as tenantcity, b.address AS tenantaddress,
|
||
CONCAT(c.firstname, ' ', c.lastname) AS ridername,c.userfcmtoken,c.contactno as ridercontact,
|
||
d.locationname,d.suburb AS locationsuburb,d.contactno AS locationcontactno,d.address AS locationaddress,
|
||
e.locationname AS applocation, f.slab, f.pricingdate, f.baseprice, f.minkm, f.priceperkm, f.maxkm, f.orders, f.othercharges, f.surgecharges
|
||
FROM deliveries a
|
||
JOIN tenants b ON a.tenantid = b.tenantid
|
||
JOIN app_users c ON a.userid = c.userid
|
||
JOIN tenantlocations d ON a.locationid = d.locationid
|
||
JOIN app_location e ON a.applocationid = e.applocationid
|
||
JOIN tenantpricing f ON a.tenantid = f.tenantid
|
||
WHERE b.moduleid = 6
|
||
AND a.applocationid = ?
|
||
`)
|
||
params = append(params, input.Applocationid)
|
||
|
||
// ✅ TENANT FILTER
|
||
if input.Tenantid != 0 {
|
||
qb.WriteString(" AND a.tenantid = ?")
|
||
params = append(params, input.Tenantid)
|
||
}
|
||
|
||
// ✅ LOCATION FILTER
|
||
if input.Locationid != 0 {
|
||
qb.WriteString(" AND a.locationid = ?")
|
||
params = append(params, input.Locationid)
|
||
}
|
||
|
||
// ✅ USER / RIDER FILTER
|
||
if input.UserID != 0 {
|
||
qb.WriteString(" AND a.userid = ?")
|
||
params = append(params, input.UserID)
|
||
}
|
||
|
||
// ✅ STATUS FILTER
|
||
if input.Status != "" && strings.ToLower(input.Status) != "all" {
|
||
qb.WriteString(" AND LOWER(a.orderstatus) = LOWER(?)")
|
||
params = append(params, input.Status)
|
||
}
|
||
|
||
// ✅ DATE RANGE FILTER
|
||
if input.Fromdate != "" && input.ToDate != "" {
|
||
qb.WriteString(`
|
||
AND a.deliverydate >= (CONCAT(?::text, ' 00:00:00'))::timestamp
|
||
AND a.deliverydate <= (CONCAT(?::text, ' 23:59:59'))::timestamp
|
||
`)
|
||
params = append(params, input.Fromdate, input.ToDate)
|
||
}
|
||
|
||
qb.WriteString(" ORDER BY a.deliveryid DESC")
|
||
|
||
// ✅ PAGINATION
|
||
if input.Pagesize > 0 {
|
||
qb.WriteString(" LIMIT ? OFFSET ?")
|
||
params = append(params, input.Pagesize, offset)
|
||
}
|
||
|
||
finalQuery := qb.String()
|
||
|
||
db.DB.Raw(finalQuery, params...).Scan(&data)
|
||
return data
|
||
}
|
||
|
||
func GetUserDeliveries(input models.DeliveryQuery) []models.Deliveryinfo {
|
||
|
||
var q1 string
|
||
logInfo("User Deliveries", "userid", input.UserID)
|
||
|
||
offset := (input.Pageno - 1) * input.Pagesize
|
||
var data []models.Deliveryinfo
|
||
var params []interface{}
|
||
|
||
q1 = deliveries + " where b.moduleid=6 and a.userid=?"
|
||
params = append(params, input.UserID)
|
||
|
||
// CASE 1: status = all → show all statuses
|
||
if input.Status == "all" {
|
||
|
||
q1 += " and a.deliverydate::date between ? and ? order by deliveryid desc"
|
||
params = append(params, input.Fromdate, input.ToDate)
|
||
|
||
// CASE 2: Specific status (picked, active, delivered…)
|
||
} else if input.Status != "" {
|
||
|
||
q1 += " and a.orderstatus=? and a.deliverydate::date between ? and ? order by deliveryid desc"
|
||
params = append(params, input.Status, input.Fromdate, input.ToDate)
|
||
|
||
// CASE 3: No status passed → default statuses
|
||
} else {
|
||
|
||
q1 += " and a.orderstatus in ('picked','active','skipped') and a.deliverydate::date between ? and ? order by deliveryid desc"
|
||
params = append(params, input.Fromdate, input.ToDate)
|
||
}
|
||
|
||
if input.Pagesize != 0 {
|
||
q1 += " LIMIT ? OFFSET ?"
|
||
params = append(params, input.Pagesize, offset)
|
||
}
|
||
|
||
db.DB.Raw(q1, params...).Find(&data)
|
||
|
||
return data
|
||
}
|
||
|
||
func GetUserDeliveriesv1(input models.DeliveryQuery) []models.Deliveryinfo {
|
||
|
||
var q1 string
|
||
|
||
logInfo("User Deliveriesv1", "userid", input.UserID)
|
||
|
||
offset := (input.Pageno - 1) * input.Pagesize
|
||
|
||
var data []models.Deliveryinfo
|
||
|
||
if input.Status != "" {
|
||
|
||
if input.Pagesize != 0 {
|
||
|
||
logInfo("Rider Deliveriesv2")
|
||
|
||
q1 = deliveries + " where a.userid=? and a.orderstatus=? and a.deliverydate::date between ? and ? order by deliveryid desc LIMIT ? OFFSET ?"
|
||
db.DB.Raw(q1, input.UserID, input.Status, input.Fromdate, input.ToDate, input.Pagesize, offset).Find(&data)
|
||
|
||
} else {
|
||
|
||
logInfo("Rider Deliveriesv1")
|
||
|
||
q1 = deliveries + " where a.userid=? and a.orderstatus=? and a.deliverydate::date between ? and ? order by deliveryid asc"
|
||
db.DB.Raw(q1, input.UserID, input.Status, input.Fromdate, input.ToDate).Find(&data)
|
||
|
||
}
|
||
|
||
} else {
|
||
|
||
if input.Pagesize != 0 {
|
||
logInfo("Rider Deliveriesv2")
|
||
|
||
q1 = deliveries + " where a.orderstatus in ('picked') and a.userid=? and a.deliverydate::date between ? and ? order by deliveryid desc LIMIT ? OFFSET ?"
|
||
db.DB.Raw(q1, input.UserID, input.Fromdate, input.ToDate, input.Pagesize, offset).Find(&data)
|
||
|
||
} else {
|
||
|
||
logInfo("Rider Deliveriesv1")
|
||
|
||
q1 = deliveries + " where a.orderstatus in ('picked') and a.userid=? and a.deliverydate::date between ? and ? order by deliveryid desc"
|
||
db.DB.Raw(q1, input.UserID, input.Fromdate, input.ToDate).Find(&data)
|
||
|
||
}
|
||
|
||
}
|
||
|
||
return data
|
||
|
||
}
|
||
|
||
func GetAppUserDeliveries(input models.DeliveryQuery) []models.Deliveryinfo {
|
||
var data []models.Deliveryinfo
|
||
|
||
logInfo("App User Deliveries", "appuserid", input.UserID)
|
||
|
||
var (
|
||
q1 strings.Builder
|
||
params []interface{}
|
||
)
|
||
|
||
offset := (input.Pageno - 1) * input.Pagesize
|
||
|
||
// 🔹 Base query
|
||
q1.WriteString(deliveries)
|
||
q1.WriteString(" WHERE b.moduleid = 6 AND g.status = 'Active' ")
|
||
|
||
// 🔹 Apply userid filter ONLY if userid > 0
|
||
if input.UserID > 0 {
|
||
q1.WriteString(" AND g.userid = ? ")
|
||
params = append(params, input.UserID)
|
||
}
|
||
|
||
// 🔹 Status filter (IGNORE if status = all)
|
||
if input.Status != "" && strings.ToLower(input.Status) != "all" {
|
||
q1.WriteString(" AND a.orderstatus = ? ")
|
||
params = append(params, input.Status)
|
||
}
|
||
|
||
// 🔹 Date filter
|
||
if input.Fromdate != "" && input.ToDate != "" {
|
||
q1.WriteString(" AND a.deliverydate::date BETWEEN ? AND ? ")
|
||
params = append(params, input.Fromdate, input.ToDate)
|
||
}
|
||
|
||
// 🔹 Keyword filter (case-insensitive)
|
||
if input.Keyword != "" {
|
||
k := "%" + strings.ToLower(input.Keyword) + "%"
|
||
|
||
q1.WriteString(`
|
||
AND (
|
||
LOWER(a.pickupcustomer) LIKE ? OR
|
||
LOWER(b.tenantname) LIKE ? OR
|
||
LOWER(a.deliverycustomer) LIKE ? OR
|
||
LOWER(a.pickupcontactno) LIKE ? OR
|
||
LOWER(a.deliverycontactno) LIKE ? OR
|
||
LOWER(CAST(a.orderid AS CHAR)) LIKE ? OR
|
||
LOWER(CAST(a.deliveryid AS CHAR)) LIKE ? OR
|
||
LOWER(c.firstname) LIKE ? OR
|
||
LOWER(c.contactno) LIKE ?
|
||
)
|
||
`)
|
||
|
||
for i := 0; i < 9; i++ {
|
||
params = append(params, k)
|
||
}
|
||
}
|
||
|
||
q1.WriteString(" ORDER BY a.deliveryid DESC ")
|
||
|
||
if input.Pagesize > 0 {
|
||
q1.WriteString(" LIMIT ? OFFSET ? ")
|
||
params = append(params, input.Pagesize, offset)
|
||
}
|
||
|
||
db.DB.Raw(q1.String(), params...).Scan(&data)
|
||
|
||
return data
|
||
}
|
||
|
||
func GetDeliveries(input models.DeliveryQuery) []models.Deliveryinfo {
|
||
var data []models.Deliveryinfo
|
||
var queryBuilder strings.Builder
|
||
var params []interface{}
|
||
|
||
logInfo("Get All Deliveries -new")
|
||
|
||
offset := (input.Pageno - 1) * input.Pagesize
|
||
|
||
baseQuery := `
|
||
SELECT a.*, b.tenantname, c.userid,
|
||
CONCAT(c.firstname, ' ', c.lastname) AS ridername,
|
||
c.contactno AS ridercontact,
|
||
d.slab, d.pricingdate, d.baseprice, d.minkm,
|
||
d.priceperkm, d.maxkm, d.orders,
|
||
d.othercharges, d.surgecharges
|
||
FROM deliveries a
|
||
JOIN tenants b ON a.tenantid = b.tenantid
|
||
JOIN app_users c ON a.userid = c.userid
|
||
JOIN tenantpricing d ON a.tenantid = d.tenantid
|
||
WHERE 1=1
|
||
`
|
||
|
||
queryBuilder.WriteString(baseQuery)
|
||
|
||
// ✅ DATE FILTER
|
||
if input.Fromdate != "" && input.ToDate != "" {
|
||
queryBuilder.WriteString(" AND b.moduleid=6 AND a.deliverydate::date BETWEEN ? AND ?")
|
||
params = append(params, input.Fromdate, input.ToDate)
|
||
}
|
||
|
||
// ✅ STATUS FILTER (ignore "all")
|
||
if input.Status != "" && strings.ToLower(input.Status) != "all" {
|
||
queryBuilder.WriteString(" AND b.moduleid=6 AND LOWER(a.orderstatus) = LOWER(?)")
|
||
params = append(params, input.Status)
|
||
}
|
||
|
||
// ✅ KEYWORD FILTER
|
||
if input.Keyword != "" {
|
||
k := "%" + strings.ToLower(input.Keyword) + "%"
|
||
|
||
queryBuilder.WriteString(`
|
||
AND (
|
||
LOWER(a.pickupcustomer) LIKE ? OR
|
||
LOWER(b.tenantname) LIKE ? OR
|
||
LOWER(a.deliverycustomer) LIKE ? OR
|
||
LOWER(a.pickupcontactno) LIKE ? OR
|
||
LOWER(a.deliverycontactno) LIKE ? OR
|
||
LOWER(CAST(a.orderid AS CHAR)) LIKE ?
|
||
)
|
||
`)
|
||
|
||
for i := 0; i < 6; i++ {
|
||
params = append(params, k)
|
||
}
|
||
}
|
||
|
||
queryBuilder.WriteString(" ORDER BY a.deliveryid DESC")
|
||
|
||
if input.Pagesize > 0 {
|
||
queryBuilder.WriteString(" LIMIT ? OFFSET ?")
|
||
params = append(params, input.Pagesize, offset)
|
||
}
|
||
|
||
query := queryBuilder.String()
|
||
|
||
db.DB.Raw(query, params...).Scan(&data)
|
||
return data
|
||
}
|
||
|
||
func GetTenantLocationDeliveries(input models.DeliveryQuery) []models.Deliveryinfo {
|
||
|
||
logInfo("Tenant Location Deliveries", "tenantid", input.Tenantid, "locationid", input.Locationid)
|
||
|
||
var data []models.Deliveryinfo
|
||
var queryBuilder strings.Builder
|
||
var params []interface{}
|
||
|
||
offset := (input.Pageno - 1) * input.Pagesize
|
||
|
||
// 🔹 Base query
|
||
queryBuilder.WriteString(deliveries)
|
||
queryBuilder.WriteString(` WHERE b.moduleid = 6 AND a.tenantid = ? AND a.locationid = ?`)
|
||
params = append(params, input.Tenantid, input.Locationid)
|
||
|
||
// 🔹 USER FILTER (apply only if userid > 0)
|
||
if input.UserID > 0 {
|
||
queryBuilder.WriteString(` AND a.userid = ?`)
|
||
params = append(params, input.UserID)
|
||
}
|
||
|
||
// 🔹 STATUS FILTER (ignore "all", case-insensitive)
|
||
if input.Status != "" && strings.ToLower(input.Status) != "all" {
|
||
queryBuilder.WriteString(` AND LOWER(a.orderstatus) = LOWER(?)`)
|
||
params = append(params, input.Status)
|
||
}
|
||
|
||
// 🔹 DATE FILTER
|
||
if input.Fromdate != "" && input.ToDate != "" {
|
||
queryBuilder.WriteString(` AND a.deliverydate::date BETWEEN ? AND ?`)
|
||
params = append(params, input.Fromdate, input.ToDate)
|
||
}
|
||
|
||
// 🔹 KEYWORD FILTER (case-insensitive)
|
||
if input.Keyword != "" {
|
||
k := "%" + strings.ToLower(input.Keyword) + "%"
|
||
|
||
queryBuilder.WriteString(`
|
||
AND (
|
||
LOWER(a.pickupcustomer) LIKE ? OR
|
||
LOWER(b.tenantname) LIKE ? OR
|
||
LOWER(a.deliverycustomer) LIKE ? OR
|
||
LOWER(a.pickupcontactno) LIKE ? OR
|
||
LOWER(a.deliverycontactno) LIKE ? OR
|
||
LOWER(CAST(a.orderid AS CHAR)) LIKE ?
|
||
)
|
||
`)
|
||
|
||
// ✔ exactly 6 placeholders
|
||
for i := 0; i < 6; i++ {
|
||
params = append(params, k)
|
||
}
|
||
}
|
||
|
||
// 🔹 ORDER + PAGINATION
|
||
queryBuilder.WriteString(` ORDER BY a.deliveryid DESC`)
|
||
|
||
if input.Pagesize > 0 {
|
||
queryBuilder.WriteString(` LIMIT ? OFFSET ?`)
|
||
params = append(params, input.Pagesize, offset)
|
||
}
|
||
|
||
finalQuery := queryBuilder.String()
|
||
logInfo("Final Query", "query", finalQuery)
|
||
logInfo("Params", "params", params)
|
||
|
||
db.DB.Raw(finalQuery, params...).Scan(&data)
|
||
return data
|
||
}
|
||
|
||
func GetLocationDeliveries(input models.DeliveryQuery) []models.Deliveryinfo {
|
||
|
||
logInfo("Location Deliveries", "locationid", input.Locationid)
|
||
|
||
var q1 string
|
||
var data []models.Deliveryinfo
|
||
offset := (input.Pageno - 1) * input.Pagesize
|
||
|
||
if input.Status != "" {
|
||
|
||
if input.Fromdate != "" && input.ToDate != "" {
|
||
|
||
if input.Pagesize != 0 {
|
||
|
||
q1 = deliveries + " WHERE b.moduleid=6 and a.locationid=? AND a.orderstatus=? AND a.deliverydate::date BETWEEN ? AND ? ORDER BY a.deliveryid DESC LIMIT ? OFFSET ?"
|
||
db.DB.Raw(q1, input.Locationid, input.Status, input.Fromdate, input.ToDate, input.Pagesize, offset).Find(&data)
|
||
|
||
} else {
|
||
|
||
q1 = deliveries + " WHERE b.moduleid=6 and a.locationid=? AND a.orderstatus=? AND a.deliverydate::date BETWEEN ? AND ? ORDER BY a.deliveryid DESC"
|
||
db.DB.Raw(q1, input.Locationid, input.Status, input.Fromdate, input.ToDate).Find(&data)
|
||
}
|
||
|
||
} else {
|
||
|
||
if input.Pagesize != 0 {
|
||
|
||
q1 = deliveries + " WHERE b.moduleid=6 and a.locationid=? AND a.orderstatus=? ORDER BY a.deliveryid DESC LIMIT ? OFFSET ?"
|
||
db.DB.Raw(q1, input.Locationid, input.Status, input.Pagesize, offset).Find(&data)
|
||
|
||
} else {
|
||
|
||
q1 = deliveries + " WHERE b.moduleid=6 and a.locationid=? AND a.orderstatus=? ORDER BY a.deliveryid DESC"
|
||
db.DB.Raw(q1, input.Locationid, input.Status).Find(&data)
|
||
}
|
||
}
|
||
|
||
} else {
|
||
|
||
if input.Pagesize != 0 {
|
||
|
||
q1 = deliveries + " WHERE b.moduleid=6 and a.locationid=? AND a.deliverydate::date BETWEEN ? AND ? ORDER BY a.deliveryid DESC LIMIT ? OFFSET ?"
|
||
db.DB.Raw(q1, input.Locationid, input.Fromdate, input.ToDate, input.Pagesize, offset).Find(&data)
|
||
|
||
} else {
|
||
|
||
q1 = deliveries + " WHERE b.moduleid=6 and a.locationid=? AND a.deliverydate::date BETWEEN ? AND ? ORDER BY a.deliveryid DESC"
|
||
db.DB.Raw(q1, input.Locationid, input.Fromdate, input.ToDate).Find(&data)
|
||
}
|
||
}
|
||
return data
|
||
}
|
||
|
||
// func PublishLogv1(input []models.Deliverylogs) error {
|
||
// key := "Deliverylogs"
|
||
|
||
// for _, item := range input {
|
||
// // Convert each item to JSON
|
||
// jsonData, err := json.Marshal(item)
|
||
// if err != nil {
|
||
// return fmt.Errorf("failed to marshal delivery log: %v", err)
|
||
// }
|
||
|
||
// // Push each record into Redis list
|
||
// if err := db.Rdb.RPush(db.Ctx, key, jsonData).Err(); err != nil {
|
||
// return fmt.Errorf("failed to push to Redis: %v", err)
|
||
// }
|
||
// }
|
||
|
||
// return nil
|
||
// }
|
||
|
||
// func PublishLogv1(input []models.Deliverylogs) error {
|
||
|
||
// for _, item := range input {
|
||
|
||
// // key per delivery
|
||
// key := fmt.Sprintf("Deliverylogs:%d", item.Deliveryid)
|
||
|
||
// // Convert to JSON
|
||
// jsonData, err := json.Marshal(item)
|
||
// if err != nil {
|
||
// return fmt.Errorf("marshal error: %v", err)
|
||
// }
|
||
|
||
// // Write to delivery-specific list
|
||
// if err := db.Rdb.RPush(db.Ctx, key, jsonData).Err(); err != nil {
|
||
// return fmt.Errorf("redis push error: %v", err)
|
||
// }
|
||
// }
|
||
|
||
// return nil
|
||
// }
|
||
|
||
func PublishLogv1(input []models.Deliverylogs) error {
|
||
logInfo("PublishLogv1", "records", len(input))
|
||
|
||
pipe := db.Rdb.TxPipeline()
|
||
|
||
for _, item := range input {
|
||
|
||
logInfo("DELIVERY LOG RECEIVED",
|
||
"deliveryid", item.Deliveryid,
|
||
"userid", item.Userid,
|
||
"logdate", item.Logdate,
|
||
)
|
||
|
||
logTime, err := time.Parse("2006-01-02 15:04:05", item.Logdate)
|
||
if err != nil {
|
||
logError("❌ TIME PARSE FAILED", "error", err)
|
||
continue
|
||
}
|
||
|
||
ts := logTime.Unix()
|
||
|
||
logKey := "Deliverylogs:" + strconv.Itoa(item.Deliveryid)
|
||
userIndexKey := "user:deliverylogs:" + strconv.Itoa(item.Userid)
|
||
|
||
jsonData, _ := json.Marshal(item)
|
||
|
||
pipe.RPush(db.Ctx, logKey, jsonData)
|
||
pipe.ZAdd(db.Ctx, userIndexKey, redis.Z{
|
||
Score: float64(ts),
|
||
Member: item.Deliveryid,
|
||
})
|
||
|
||
logInfo("✅ ZADD PREPARED", "key", userIndexKey, "deliveryid", item.Deliveryid)
|
||
}
|
||
|
||
_, err := pipe.Exec(db.Ctx)
|
||
if err != nil {
|
||
logError("❌ PIPELINE EXEC FAILED", "error", err)
|
||
}
|
||
|
||
return err
|
||
}
|
||
|
||
func GetDeliverylogsv1(did int) ([]models.Deliverylogs, error) {
|
||
logInfo("GetDeliverylogsv1", "deliveryid", did)
|
||
var result []models.Deliverylogs
|
||
|
||
key := "Deliverylogs"
|
||
|
||
// Get all elements from the Redis list
|
||
values, err := db.Rdb.LRange(db.Ctx, key, 0, -1).Result()
|
||
if err != nil {
|
||
return nil, errors.New("failed to read from Redis: " + err.Error())
|
||
}
|
||
|
||
for _, v := range values {
|
||
var log models.Deliverylogs
|
||
if err := json.Unmarshal([]byte(v), &log); err != nil {
|
||
continue // skip invalid JSON entries
|
||
}
|
||
|
||
// filter only the deliveryid we need
|
||
if log.Deliveryid == did {
|
||
result = append(result, log)
|
||
}
|
||
}
|
||
|
||
return result, nil
|
||
}
|
||
|
||
func GetDeliveryLogsv1(deliveryID string) ([]models.Deliverylogs, error) {
|
||
logInfo("GetDeliveryLogsv1", "deliveryid", deliveryID)
|
||
ctx := context.Background()
|
||
var results []models.Deliverylogs
|
||
|
||
key := "Deliverylogs:" + deliveryID
|
||
|
||
// Fetch logs ONLY for this delivery
|
||
listItems, err := db.Rdb.LRange(ctx, key, 0, -1).Result()
|
||
if err != nil {
|
||
return nil, errors.New("redis lrange error: " + err.Error())
|
||
}
|
||
|
||
for _, item := range listItems {
|
||
|
||
var log models.Deliverylogs
|
||
if err := json.Unmarshal([]byte(item), &log); err != nil {
|
||
continue
|
||
}
|
||
|
||
// Fetch username using redis cached function
|
||
if log.Userid != 0 {
|
||
user, err := GetUserCached(log.Userid)
|
||
if err == nil {
|
||
log.Firstname = user.Firstname
|
||
log.Lastname = user.Lastname
|
||
}
|
||
}
|
||
|
||
results = append(results, log)
|
||
}
|
||
|
||
return results, nil
|
||
}
|
||
|
||
// func GetDeliveryCached(deliveryID int) (models.Delivery, error) {
|
||
// ctx := context.Background()
|
||
// var data models.Delivery
|
||
|
||
// key := fmt.Sprintf("delivery:info:%d", deliveryID)
|
||
|
||
// // Check in Redis
|
||
// cached, err := db.Rdb.Get(ctx, key).Result()
|
||
// if err == nil {
|
||
// json.Unmarshal([]byte(cached), &data)
|
||
// return data, nil
|
||
// }
|
||
|
||
// // Fetch from DB if not cached
|
||
// q := `
|
||
// SELECT deliveryid, pickupcustomer, deliverycustomer,
|
||
// pickupcontactno, deliverycontactno
|
||
// FROM deliveries
|
||
// WHERE deliveryid=? LIMIT 1
|
||
// `
|
||
// if err := db.DB.Raw(q, deliveryID).Scan(&data).Error; err != nil {
|
||
// return data, err
|
||
// }
|
||
|
||
// // Store back to Redis for 6 hours
|
||
// b, _ := json.Marshal(data)
|
||
// db.Rdb.Set(ctx, key, b, 6*time.Hour)
|
||
|
||
// return data, nil
|
||
// }
|
||
|
||
func GetUserDeliveryLogs(userid int, fromdate, todate string) ([]models.Deliverylogs, error) {
|
||
logInfo("GetUserDeliveryLogs", "userid", userid)
|
||
|
||
var fromTS int64 = 0
|
||
var toTS int64 = time.Now().Unix()
|
||
|
||
if fromdate != "" {
|
||
t, err := time.Parse("2006-01-02", fromdate)
|
||
if err != nil {
|
||
return nil, errors.New("invalid fromdate")
|
||
}
|
||
fromTS = t.Unix()
|
||
}
|
||
|
||
if todate != "" {
|
||
t, err := time.Parse("2006-01-02", todate)
|
||
if err != nil {
|
||
return nil, errors.New("invalid todate")
|
||
}
|
||
toTS = t.Add(23*time.Hour + 59*time.Minute + 59*time.Second).Unix()
|
||
}
|
||
|
||
// 1️⃣ Get delivery IDs for user (O(logN))
|
||
deliveryIDs, err := db.Rdb.ZRangeByScore(
|
||
db.Ctx,
|
||
"user:deliverylogs:"+strconv.Itoa(userid),
|
||
&redis.ZRangeBy{
|
||
Min: strconv.FormatInt(fromTS, 10),
|
||
Max: strconv.FormatInt(toTS, 10),
|
||
},
|
||
).Result()
|
||
|
||
if err != nil || len(deliveryIDs) == 0 {
|
||
return []models.Deliverylogs{}, nil
|
||
}
|
||
|
||
// 2️⃣ Batch fetch logs
|
||
var result []models.Deliverylogs
|
||
|
||
for _, id := range deliveryIDs {
|
||
key := "Deliverylogs:" + id
|
||
|
||
values, err := db.Rdb.LRange(db.Ctx, key, 0, -1).Result()
|
||
if err != nil {
|
||
continue
|
||
}
|
||
|
||
for _, v := range values {
|
||
var log models.Deliverylogs
|
||
if err := json.Unmarshal([]byte(v), &log); err == nil {
|
||
result = append(result, log)
|
||
}
|
||
}
|
||
}
|
||
|
||
return result, nil
|
||
}
|
||
|
||
func logInfo(msg string, props ...interface{}) {
|
||
utils.Logger.Infow(msg, props...)
|
||
}
|
||
|
||
func logError(msg string, props ...interface{}) {
|
||
utils.Logger.Errorw(msg, props...)
|
||
}
|