package domain import ( "nearle/db" "nearle/models" "nearle/utils" "strconv" "strings" ) func Getuserbyid(uid int) models.UserInfo { var user models.UserInfo q1 := `SELECT a.userid,a.authname,a.email,a.configid,a.roleid,a.authmode,a.contactno, a.firstname,a.lastname,concat(a.firstname,' ',a.lastname) as fullname,a.password,a.address,a.suburb,a.city,a.state,a.postcode, a.userfcmtoken,a.pin,a.deviceid,a.devicetype,a.tenantid,a.shiftid, a.applocationid,b.locationname as applocation,b.latitude as applatitude,b.longitude as applongitude, b.radius as appradius , concat(c.starttime, ' - ', c.endtime) as shiftname from app_users a INNER JOIN app_location b on a.applocationid=b.applocationid LEFT JOIN ridershifts c ON a.shiftid = c.shiftid WHERE a.userid= ` + strconv.Itoa(uid) // print(q1) db.DB.Raw(q1).Find(&user) return user } func GetAllUsers( roleID, configID, tenantID, pageno, pagesize int, status, keyword string, ) []models.UserInfo { var users []models.UserInfo var params []interface{} var queryBuilder strings.Builder offset := (pageno - 1) * pagesize queryBuilder.WriteString(` SELECT a.userid, a.authname, a.email, a.configid, a.roleid, a.authmode, a.contactno, a.firstname, a.lastname, CONCAT(a.firstname, ' ', a.lastname) AS fullname, a.address, a.suburb, a.city, a.state, a.postcode, a.userfcmtoken, a.pin, a.deviceid, a.devicetype, a.tenantid, a.status, a.shiftid, a.latitude, a.longitude,d.rolename, STRING_AGG( CONCAT( ac.applocationid, '::', al.locationname, '::', ac.status )::text, ',' ) AS applocations_raw FROM app_users a LEFT JOIN app_locationconfig ac ON ac.userid = a.userid LEFT JOIN app_location al ON al.applocationid = ac.applocationid LEFT JOIN app_roles d ON a.roleid = d.roleid WHERE 1=1 `) if roleID != 0 { queryBuilder.WriteString(" AND a.roleid = ?") params = append(params, roleID) } if configID != 0 { queryBuilder.WriteString(" AND a.configid = ?") params = append(params, configID) } if tenantID != 0 { queryBuilder.WriteString(" AND a.tenantid = ?") params = append(params, tenantID) } if status != "" { queryBuilder.WriteString(" AND a.status = ?") params = append(params, status) } if keyword != "" { queryBuilder.WriteString(` AND ( LOWER(a.firstname) LIKE ? OR LOWER(a.contactno) LIKE ? OR LOWER(a.suburb) LIKE ? ) `) search := "%" + strings.ToLower(keyword) + "%" params = append(params, search, search, search) } queryBuilder.WriteString(` GROUP BY a.userid, d.rolename ORDER BY a.userid DESC LIMIT ? OFFSET ? `) params = append(params, pagesize, offset) // ---------- TEMP STRUCT ---------- type tempUser struct { models.UserInfo ApplocationsRaw string `gorm:"column:applocations_raw"` } var temp []tempUser db.DB.Raw(queryBuilder.String(), params...).Scan(&temp) // ---------- MAP RESULT ---------- for _, t := range temp { t.UserInfo.Applocations = []models.AppLocation{} if t.ApplocationsRaw != "" { items := strings.Split(t.ApplocationsRaw, ",") for _, item := range items { parts := strings.Split(item, "::") if len(parts) == 3 { id, err := strconv.Atoi(parts[0]) if err == nil { t.UserInfo.Applocations = append( t.UserInfo.Applocations, models.AppLocation{ Applocationid: id, Applocationname: parts[1], Status: parts[2], }, ) } } } } users = append(users, t.UserInfo) } return users } func GetTenantUserbyId(uid int) models.TenantUserInfo { var user models.TenantUserInfo q1 := `SELECT a.userid,a.authname,a.email,a.configid,a.roleid,a.authmode,a.contactno, a.firstname,a.lastname,concat(a.firstname,' ',a.lastname) as fullname, a.userfcmtoken,a.pin,a.deviceid,a.devicetype,a.tenantid,a.locationid,a.applocationid, b.partnerid,b.moduleid,b.categoryid as categoryid,b.subcategoryid as subcategoryid, b.applocationid,b.tenantname,b.address as tenantaddress,b.state as tenantstate,b.city as tenantcity, b.postcode as tenantpostcode,b.latitude as tenantlat,b.longitude as tenantlong,c.locationname AS applocation, c.latitude as applatitude,c.longitude as applongitude,c.radius as appradius, d.categoryname, e.locationname from app_users a LEFT JOIN tenants b ON a.tenantid=b.tenantid INNER JOIN app_location c on c.applocationid=b.applocationid LEFT JOIN app_category d ON b.categoryid=d.categoryid LEFT JOIN tenantlocations e ON a.locationid=e.locationid WHERE a.userid= ` + strconv.Itoa(uid) // print(q1) db.DB.Raw(q1).Find(&user) return user } func GetTenantId(uid int, contactno string) int { var tid int var q1 string if contactno != "" { q1 = `select tenantid from tenants WHERE primarycontact='` + contactno + `'` } else { q1 = `select primarycontact from tenants WHERE primarycontact='` + contactno + `'` } db.DB.Raw(q1).Find(&tid) return tid } func Getuserbyno(cno string) models.UserInfo { var user models.UserInfo q1 := `SELECT a.userid,a.authname,a.email,a.configid,a.roleid,a.authmode,a.contactno, a.firstname,a.lastname,concat(a.firstname,' ',a.lastname) as fullname, a.userfcmtoken,a.pin,a.deviceid,a.devicetype,a.tenantid,a.locationid, b.partnerid,b.moduleid,b.categoryid as categoryid,b.subcategoryid as subcategoryid, b.applocationid,b.tenantname,b.address as tenantaddress,b.state as tenantstate,b.city as tenantcity, b.postcode as tenantpostcode,b.latitude as tenantlat,b.longitude as tenantlong from app_users a LEFT JOIN tenants b ON a.tenantid=b.tenantid WHERE a.contactno= '` + cno + `'` db.DB.Raw(q1).Find(&user) return user } func GetPartnerUserbyid(uid int) models.UserInfo { var user models.UserInfo q1 := `SELECT a.userid,a.authname,a.email,a.configid,a.roleid,a.authmode,a.contactno,a.firstname,a.lastname,concat(a.firstname,' ',a.lastname) as fullname, a.userfcmtoken,a.pin,a.deviceid,a.devicetype,a.tenantid,a.applocationid,a.partnerid, b.locationname AS applocation,b.latitude AS applatitude,b.longitude AS applongitude,b.radius AS appradius, b.deliveryradius, c.partnername from app_users a INNER JOIN app_location b ON a.applocationid=b.applocationid LEFT JOIN partnerinfo c ON a.partnerid=c.partnerid WHERE a.userid= ` + strconv.Itoa(uid) db.DB.Raw(q1).Find(&user) return user } func GetRiderUserbyid(uid int) models.RiderInfo { var user models.RiderInfo q1 := `SELECT a.userid,a.authname,a.email,a.configid,a.roleid,a.authmode,a.contactno, a.address,a.state,a.city,a.postcode,a.latitude,a.longitude, a.firstname,a.lastname,concat(a.firstname,' ',a.lastname) as username,a.userfcmtoken,a.pin,a.deviceid,a.devicetype,a.partnerid,a.applocationid, a.tenantid, a.locationid, a.shiftid, b.starttime, b.endtime, b.shifthours, b.firstmilecharge, b.fuelcharge, c.logid, d.onduty, e.logseconds, e.deliveryradius from app_users a LEFT JOIN ridershifts b ON a.shiftid=b.shiftid LEFT JOIN riderlogs c ON a.userid=c.userid LEFT JOIN app_userpools d on a.userid=d.userid LEFT JOIN app_location e on a.applocationid=e.applocationid WHERE a.userid= ` + strconv.Itoa(uid) db.DB.Raw(q1).Find(&user) utils.Logger.Debugf("Query: %s", q1) return user } func GetAdminUserbyid(uid int) models.User { var user models.User q1 := `SELECT a.*,b.rolename from app_users a LEFT JOIN app_roles b ON a.roleid=b.roleid where a.userid= ` + strconv.Itoa(uid) db.DB.Raw(q1).Find(&user) return user } func UpdatUser(user models.User) { db.DB.Table("app_users").Where("userid=?", user.Userid).Updates(&user) if user.Tenantid != 0 { db.DB.Table("tenants").Where("tenantid=?", user.Tenantid).Update("tenanttoken", user.Userfcmtoken) } } func GetUserIDByContact(contact string, configID int) int { var uid int query := `SELECT userid FROM app_users WHERE contactno = ? AND configid = ?` db.DB.Raw(query, contact, configID).Scan(&uid) return uid } func GetUserIDByAuth(authname string, configID int) int { var uid int query := `SELECT userid FROM app_users WHERE authname = ? AND configid = ?` db.DB.Raw(query, authname, configID).Scan(&uid) return uid } func GetUserStatus(userid int) string { var status string db.DB.Raw("SELECT status FROM app_users WHERE userid = ?", userid).Scan(&status) return status } func GetStoredPin(uid int) int { var pin int db.DB.Raw(`SELECT COALESCE(pin, 0) FROM app_users WHERE userid = ?`, uid).Scan(&pin) return pin } func GetAuthMode(uid int) int { var mode int db.DB.Raw(`SELECT COALESCE(authmode, 1) FROM app_users WHERE userid = ?`, uid).Scan(&mode) return mode } func UpdateUserFcmToken(uid int, token string) error { query := `UPDATE app_users SET userfcmtoken = ? WHERE userid = ?` return db.DB.Exec(query, token, uid).Error } // Check if device already exists for user func IsDeviceLinked(userid int, deviceid string) bool { var count int64 db.DB.Table("user_devices"). Where("userid = ? AND deviceid = ?", userid, deviceid). Count(&count) return count > 0 } func GetStoredDeviceID(uid int) (string, error) { var deviceID string query := `SELECT deviceid FROM app_users WHERE userid = ? LIMIT 1` result := db.DB.Raw(query, uid).Scan(&deviceID) if result.Error != nil { utils.Error("Error fetching deviceid", "error", result.Error) return "", result.Error } // If nothing found if result.RowsAffected == 0 { return "", nil } return deviceID, nil } func CheckUserExists(contactno, email string, configid int) (bool, error) { var count int64 err := db.DB.Table("app_users"). Where("configid = ?", configid). Where( db.DB. Where("contactno = ? AND ? != ''", contactno, contactno). Or("email = ? AND ? != ''", email, email), ). Count(&count).Error if err != nil { return false, err } return count > 0, nil } func GetAllUsersv2(roleID, configID, tenantID, pageno, pagesize int, keyword string) []models.UserInfov2 { var users []models.UserInfov2 var params []interface{} var queryBuilder strings.Builder offset := (pageno - 1) * pagesize queryBuilder.WriteString(` SELECT a.userid,a.authname,a.email,a.configid,a.roleid,a.authmode,a.contactno,a.firstname, a.lastname,CONCAT(a.firstname, ' ', a.lastname) AS fullname,a.address,a.suburb, a.city,a.state,a.postcode,a.userfcmtoken,a.pin,a.deviceid,a.devicetype,a.tenantid, a.status,a.shiftid, STRING_AGG(DISTINCT alc.applocationid::text, ',') AS applocationids_raw, STRING_AGG(DISTINCT d.locationname, ',') AS applocationnames_raw, CONCAT(c.starttime, ' - ', c.endtime) AS shiftname FROM app_users a LEFT JOIN app_locationconfig alc ON alc.userid = a.userid AND alc.configid = a.configid AND alc.status = 'Active' LEFT JOIN app_location d ON d.applocationid = alc.applocationid LEFT JOIN ridershifts c ON a.shiftid = c.shiftid WHERE 1=1 `) if roleID != 0 { queryBuilder.WriteString(" AND a.roleid = ?") params = append(params, roleID) } if configID != 0 { queryBuilder.WriteString(" AND a.configid = ?") params = append(params, configID) } if tenantID != 0 { queryBuilder.WriteString(" AND a.tenantid = ?") params = append(params, tenantID) } if keyword != "" { queryBuilder.WriteString(` AND ( LOWER(a.firstname) LIKE ? OR LOWER(a.contactno) LIKE ? OR LOWER(a.suburb) LIKE ? ) `) search := "%" + strings.ToLower(keyword) + "%" params = append(params, search, search, search) } queryBuilder.WriteString(` GROUP BY a.userid, c.starttime, c.endtime ORDER BY a.userid DESC LIMIT ? OFFSET ? `) params = append(params, pagesize, offset) // 🔹 Execute query db.DB.Raw(queryBuilder.String(), params...).Scan(&users) // 🔹 Convert RAW → API arrays for i := range users { // ✅ always initialize → [] not null users[i].Applocationids = []int{} users[i].Applocationnames = []string{} // IDs if users[i].ApplocationidsRaw != "" { ids := strings.Split(users[i].ApplocationidsRaw, ",") for _, id := range ids { if v, err := strconv.Atoi(id); err == nil { users[i].Applocationids = append(users[i].Applocationids, v) } } } // Names if users[i].ApplocationnamesRaw != "" { names := strings.Split(users[i].ApplocationnamesRaw, ",") for _, name := range names { users[i].Applocationnames = append( users[i].Applocationnames, strings.TrimSpace(name), ) } } } return users }