intial commit

This commit is contained in:
2026-05-25 11:45:56 +05:30
commit 6ab508560f
73 changed files with 23713 additions and 0 deletions

668
domain/customerDomain.go Normal file
View File

@@ -0,0 +1,668 @@
package domain
import (
"nearle/db"
"nearle/models"
"nearle/utils"
"net/http"
"strconv"
"strings"
)
func CreateCustomer(input models.Customers) int {
var custloc models.Customerlocations
var tcust models.Tenantcustomers
tx := db.DB.Begin()
t1 := tx.Create(&input)
if t1.Error != nil {
utils.Error("CreateCustomer t1 error", "error", t1.Error)
tx.Rollback()
}
custloc.Customerid = input.Customerid
custloc.Address = input.Address
custloc.Suburb = input.Suburb
custloc.City = input.City
custloc.State = input.State
custloc.Postcode = input.Postcode
custloc.Latitude = input.Latitude
custloc.Longitude = input.Longitude
custloc.Doorno = input.Doorno
custloc.Landmark = input.Landmark
custloc.Primaryaddress = 1
t2 := tx.Table("customerlocations").Create(&custloc)
if t2.Error != nil {
utils.Error("CreateCustomer t2 error", "error", t2.Error)
tx.Rollback()
}
tcust.Customerid = input.Customerid
tcust.Tenantid = input.Tenantid
t3 := tx.Table("tenantcustomers").Create(&tcust)
if t3.Error != nil {
utils.Error("CreateCustomer t3 error", "error", t3.Error)
tx.Rollback()
}
tx.Commit()
return input.Customerid
}
func CreateCustomerv1(input models.Customers) (int, error) {
var tcust models.Tenantcustomers
tx := db.DB.Begin()
t1 := tx.Create(&input)
if t1.Error != nil {
utils.Error("CreateCustomerv1 t1 error", "error", t1.Error)
tx.Rollback()
return 0, t1.Error
}
tcust.Customerid = input.Customerid
tcust.Tenantid = input.Tenantid
t3 := tx.Table("tenantcustomers").Create(&tcust)
if t3.Error != nil {
utils.Error("CreateCustomerv1 t3 error", "error", t3.Error)
tx.Rollback()
return 0, t3.Error
}
err := tx.Commit().Error
if err != nil {
return 0, err
}
return input.Customerid, nil
}
func CreateCustomerv2(input models.Customers) (*models.CustomersId, error) {
var custloc models.Customerlocations
var tcust models.Tenantcustomers
var cid models.CustomersId
tx := db.DB.Begin()
t1 := tx.Create(&input)
if t1.Error != nil {
utils.Error("CreateCustomerv2 t1 error", "error", t1.Error)
tx.Rollback()
return nil, t1.Error
}
custloc.Customerid = input.Customerid
custloc.Address = input.Address
custloc.Suburb = input.Suburb
custloc.City = input.City
custloc.State = input.State
custloc.Postcode = input.Postcode
custloc.Latitude = input.Latitude
custloc.Longitude = input.Longitude
custloc.Doorno = input.Doorno
custloc.Landmark = input.Landmark
custloc.Primaryaddress = 1
t2 := tx.Table("customerlocations").Create(&custloc)
if t2.Error != nil {
utils.Error("CreateCustomerv2 t2 error", "error", t2.Error)
tx.Rollback()
return nil, t2.Error
}
tcust.Customerid = input.Customerid
tcust.Tenantid = input.Tenantid
t3 := tx.Table("tenantcustomers").Create(&tcust)
if t3.Error != nil {
utils.Error("CreateCustomerv2 t3 error", "error", t3.Error)
tx.Rollback()
return nil, t3.Error
}
cid.Customerid = input.Customerid
cid.Locationid = custloc.Locationid
err := tx.Commit().Error
if err != nil {
return nil, err
}
return &cid, nil
}
func UpdateCustomerv2(input models.Customers) (int, error) {
var custloc models.Customerlocations
var tcust models.Tenantcustomers
var data models.CustomersId
tx := db.DB.Begin()
t1 := tx.Where("customerid=?", input.Customerid).Updates(&input)
if t1.Error != nil {
utils.Error("UpdateCustomerv2 t1 error", "error", t1.Error)
tx.Rollback()
return 0, t1.Error
}
custloc.Customerid = input.Customerid
custloc.Address = input.Address
custloc.Suburb = input.Suburb
custloc.City = input.City
custloc.State = input.State
custloc.Postcode = input.Postcode
custloc.Latitude = input.Latitude
custloc.Longitude = input.Longitude
custloc.Doorno = input.Doorno
custloc.Landmark = input.Landmark
custloc.Primaryaddress = 1
custlocid, err := CheckLocation(input.Customerid)
if err != nil {
tx.Rollback()
return 0, err
}
if custlocid != 0 {
utils.Logger.Infof("entering location update: %d", custlocid)
custloc.Locationid = custlocid
t2 := tx.Table("customerlocations").Where("locationid=?", custlocid).Updates(&custloc)
if t2.Error != nil {
utils.Error("UpdateCustomerv2 t2 update error", "error", t2.Error)
tx.Rollback()
return 0, t2.Error
}
} else {
utils.Logger.Infof("entering location create for customer: %d", input.Customerid)
t2 := tx.Table("customerlocations").Create(&custloc)
if t2.Error != nil {
utils.Error("UpdateCustomerv2 t2 create error", "error", t2.Error)
tx.Rollback()
return 0, t2.Error
}
}
cid := CheckTenantCustomer(input.Customerid, input.Tenantid)
if cid == 0 {
tcust.Customerid = input.Customerid
tcust.Tenantid = input.Tenantid
t3 := tx.Table("tenantcustomers").Create(&tcust)
if t3.Error != nil {
utils.Error("UpdateCustomerv2 t3 error", "error", t3.Error)
tx.Rollback()
return 0, t3.Error
}
}
data.Locationid = custloc.Locationid
utils.Logger.Infof("customerid for the customer is %d", input.Customerid)
utils.Logger.Infof("The created Location for the customer is %d", data.Locationid)
utils.Logger.Infof("the Location for the customer is %d", custloc.Locationid)
err = tx.Commit().Error
if err != nil {
return 0, err
}
return data.Locationid, nil
}
func UpdateCustomerv1(input models.Customers) error {
var tcust models.Tenantcustomers
tx := db.DB.Begin()
t1 := tx.Where("customerid=?", input.Customerid).Updates(&input)
if t1.Error != nil {
utils.Error("UpdateCustomerv1 t1 error", "error", t1.Error)
tx.Rollback()
return t1.Error
}
cid := CheckTenantCustomer(input.Customerid, input.Tenantid)
if cid == 0 {
tcust.Customerid = input.Customerid
tcust.Tenantid = input.Tenantid
t3 := tx.Table("tenantcustomers").Create(&tcust)
if t3.Error != nil {
utils.Error("UpdateCustomerv1 t3 error", "error", t3.Error)
tx.Rollback()
return t3.Error
}
}
err := tx.Commit().Error
if err != nil {
return err
}
return nil
}
func CreateTenantCustomer(input models.Customers) int {
var tcust models.Tenantcustomers
tcust.Customerid = input.Customerid
tcust.Tenantid = input.Tenantid
tx := db.DB.Begin()
t3 := tx.Table("tenantcustomers").Create(&tcust)
if t3.Error != nil {
utils.Error("CreateTenantCustomer t3 error", "error", t3.Error)
tx.Rollback()
}
tx.Commit()
return input.Customerid
}
func UpdateCustomer(input models.Customers) models.Result {
var custloc models.Customerlocations
var result models.Result
tx := db.DB.Begin()
t1 := tx.Where("customerid=?", input.Customerid).Updates(&input)
if t1.Error != nil {
utils.Error("UpdateCustomer t1 error", "error", t1.Error)
tx.Rollback()
}
custloc.Customerid = input.Customerid
custloc.Address = input.Address
custloc.Suburb = input.Suburb
custloc.City = input.City
custloc.State = input.State
custloc.Postcode = input.Postcode
custloc.Latitude = input.Latitude
custloc.Longitude = input.Longitude
custloc.Doorno = input.Doorno
custloc.Landmark = input.Landmark
t2 := tx.Table("customerlocations").Where("customerid=? and primaryaddress=?", input.Customerid, 1).Updates(&custloc)
if t2.Error != nil {
utils.Error("UpdateCustomer t2 error", "error", t2.Error)
tx.Rollback()
}
err := tx.Commit().Error
if err != nil {
result.Code = http.StatusConflict
result.Status = false
result.Message = "Update Customer Failed"
return result
}
result.Code = http.StatusAccepted
result.Status = true
result.Message = "Customer customer successful"
return result
}
func GetCustomer(cid int, cno string) models.CustomerInfo {
var data models.CustomerInfo
var q1 string
if cid != 0 {
// q1 = `select a.customerid,a.authmode,a.configid,a.deviceid,a.devicetype,a.customertoken,a.firstname,a.lastname,
// a.contactno,a.email,a.profileimage,a.address,a.suburb,a.city,a.state,a.landmark,a.doorno,a.postcode,
// a.latitude,a.longitude,a.applocationid,a.status from customers a where a.customerid= ` + strconv.Itoa(cid)
q1 = `SELECT a.customerid,a.firstname,a.lastname,a.contactno,a.email, a.profileimage, a.dialcode, a.deviceid, a.devicetype, a.authmode, a.configid, a.customertoken, a.intro, a.gender, a.dob,
b.locationid as deliverylocationid,b.address,b.suburb,b.city,b.state,b.landmark,b.doorno,b.postcode,
b.latitude,b.longitude,a.applocationid,c.locationid as tenantlocationid, c.tenantid, a.status,d.qrmode,d.latitude as selectedlatitude, d.longitude as selectedlongitude, d.radius, d.applocationid, e.allocationid
from customers a
INNER JOIN customerlocations b ON a.customerid=b.customerid
INNER JOIN tenantcustomers c ON a.customerid=c.customerid
LEFT JOIN app_location d ON a.applocationid=d.applocationid
LEFT JOIN tenants e ON e.tenantid=c.tenantid
WHERE b.primaryaddress=1 and a.customerid= ` + strconv.Itoa(cid) + ` order by customerid desc`
} else {
q1 = `SELECT a.customerid,a.firstname,a.lastname,a.contactno,a.email,a.profileimage, a.dialcode, a.deviceid, a.devicetype, a.authmode, a.configid, a.customertoken, a.intro,a.gender, a.dob,
b.locationid as deliverylocationid,b.address,b.suburb,b.city,b.state,b.landmark,b.doorno,b.postcode,
b.latitude,b.longitude,a.applocationid,c.locationid as tenantlocationid, c.tenantid, a.status, d.qrmode, d.latitude as selectedlatitude, d.longitude as selectedlongitude,d.radius, d.applocationid, e.allocationid
from customers a
INNER JOIN customerlocations b ON a.customerid=b.customerid
INNER JOIN tenantcustomers c ON a.customerid=c.customerid
LEFT JOIN app_location d ON a.applocationid=d.applocationid
LEFT JOIN tenants e ON e.tenantid=c.tenantid
WHERE b.primaryaddress=1 and a.contactno= '` + cno + `' order by customerid desc`
}
utils.Logger.Debugf("Query: %s", q1)
db.DB.Raw(q1).Find(&data)
return data
}
func GetTenantCustomers(tid, lid, aid, pageno, pagesize int, keyword string) []models.CustomerInfo {
var data []models.CustomerInfo
offset := (pageno - 1) * pagesize
var q1 string
var args []interface{}
if lid != 0 {
q1 = `
SELECT a.customerid,a.firstname,a.lastname,a.contactno,
a.email,b.locationid AS deliverylocationid,b.address,b.suburb,b.city,b.state,b.landmark,b.doorno,b.postcode,b.latitude,b.longitude,a.applocationid,c.tenantid,
c.locationid AS tenantlocationid,a.status,1 AS quantity,0.0 AS collectionamt
FROM customers a
LEFT JOIN customerlocations b ON a.customerid = b.customerid
INNER JOIN tenantcustomers c ON a.customerid = c.customerid
WHERE c.locationid = ? AND c.tenantid = ?
`
args = append(args, lid, tid)
if aid != 0 {
q1 += ` AND a.applocationid = ?`
args = append(args, aid)
}
if keyword != "" {
search := "%" + keyword + "%"
q1 += ` AND (a.firstname LIKE ? OR a.contactno LIKE ? OR b.suburb LIKE ?)`
args = append(args, search, search, search)
}
q1 += ` ORDER BY a.customerid DESC LIMIT ? OFFSET ?`
args = append(args, pagesize, offset)
} else {
q1 = `
SELECT a.customerid, a.firstname, a.lastname, a.contactno, a.email, a.address, a.suburb, a.city, a.state, a.landmark, a.doorno, a.postcode, a.latitude,
a.longitude, a.applocationid, c.tenantid, c.locationid AS tenantlocationid, a.status, 1 AS quantity, 0.0 AS collectionamt
FROM customers a
INNER JOIN tenantcustomers c ON a.customerid = c.customerid WHERE c.tenantid = ? `
args = append(args, tid)
if aid != 0 {
q1 += ` AND a.applocationid = ?`
args = append(args, aid)
}
if keyword != "" {
search := "%" + strings.ToLower(keyword) + "%"
q1 += ` AND (LOWER(a.firstname) LIKE ? OR LOWER(a.contactno) LIKE ? OR LOWER(a.suburb) LIKE ?)`
args = append(args, search, search, search)
}
q1 += ` ORDER BY a.customerid DESC LIMIT ? OFFSET ?`
args = append(args, pagesize, offset)
}
// 🔹 Execute query
db.DB.Raw(q1, args...).Scan(&data)
return data
}
func GetCustomerbytenant(tid, lid int) []models.CustomerInfo {
var data []models.CustomerInfo
var q1 string
if lid != 0 {
q1 = `SELECT a.customerid,a.firstname,a.lastname,a.contactno,a.email,
b.locationid as deliverylocationid,b.address,b.suburb,b.city,b.state,b.landmark,b.doorno,b.postcode,
b.latitude,b.longitude,a.applocationid,c.locationid as tenantlocationid,a.status
from customers a
INNER JOIN customerlocations b ON a.customerid=b.customerid
INNER JOIN tenantcustomers c ON a.customerid=c.customerid
WHERE c.locationid > 0 and c.tenantid=? order by customerid desc`
} else {
q1 = `SELECT a.customerid,a.firstname,a.lastname,a.contactno,a.email,
b.locationid as deliverylocationid,b.address,b.suburb,b.city,b.state,b.landmark,b.doorno,b.postcode,
b.latitude,b.longitude,a.applocationid,c.locationid as tenantlocationid,a.status
from customers a
INNER JOIN customerlocations b ON a.customerid=b.customerid
INNER JOIN tenantcustomers c ON a.customerid=c.customerid
WHERE c.tenantid=? and c.locationid = 0 order by customerid desc`
//and c.locationid = 0
}
db.DB.Raw(q1, tid).Find(&data)
return data
}
func GetallCustomers(aid, pageno, pagesize int, keyword string) []models.CustomerInfo {
var data []models.CustomerInfo
offset := (pageno - 1) * pagesize
var q1 string
baseQuery := `SELECT a.customerid,a.firstname,a.lastname,a.contactno,a.email,
b.locationid as deliverylocationid,b.address,b.suburb,b.city,b.state,b.landmark,b.doorno,b.postcode,
b.latitude,b.longitude,a.applocationid,a.status,b.primaryaddress
FROM customers a
INNER JOIN customerlocations b ON a.customerid=b.customerid
WHERE b.primaryaddress=1`
// filter by applocationid
if aid != 0 {
baseQuery += " AND a.applocationid=" + strconv.Itoa(aid)
}
// keyword search filter (case-insensitive)
if keyword != "" {
like := "'%" + strings.ToLower(keyword) + "%'"
baseQuery += " AND (LOWER(a.firstname) LIKE " + like +
" OR LOWER(a.lastname) LIKE " + like +
" OR LOWER(a.contactno) LIKE " + like + ")"
}
// order + pagination
q1 = baseQuery + " ORDER BY a.customerid DESC LIMIT " + strconv.Itoa(pagesize) + " OFFSET " + strconv.Itoa(offset)
db.DB.Raw(q1).Find(&data)
return data
}
func SearchCustomer(str string, tid int) []models.CustomerInfo {
var data []models.CustomerInfo
var q1 string
if tid != 0 {
q1 = `SELECT a.customerid,a.firstname,a.lastname,a.contactno,a.email,
a.address,a.suburb,a.city,a.state,a.landmark,a.doorno,a.postcode,
a.latitude,a.longitude,a.applocationid,c.locationid as tenantlocationid,a.status
from customers a
INNER JOIN tenantcustomers c ON a.customerid=c.customerid
WHERE c.tenantid=` + strconv.Itoa(tid) + ` and lower(a.firstname) like '` + strings.ToLower(str) + `%' or contactno like '` + strings.ToLower(str) + `%'`
} else {
// q1 = `SELECT a.customerid,a.firstname,a.lastname,a.contactno,a.email,
// b.locationid as deliverylocationid,b.address,b.suburb,b.city,b.state,b.landmark,b.doorno,b.postcode,
// b.latitude,b.longitude,a.applocationid,a.status,c.locationid as tenantlocationid
// from customers a
// INNER JOIN customerlocations b ON a.customerid=b.customerid
// INNER JOIN tenantcustomers c ON a.customerid=c.customerid
// WHERE lower(a.firstname) like '` + strings.ToLower(str) + `%' or contactno like '` + strings.ToLower(str) + `%'`
q1 = `SELECT a.customerid,a.firstname,a.lastname,a.contactno,a.email,
a.address,a.suburb,a.city,a.state,a.landmark,a.doorno,a.postcode,
a.latitude,a.longitude,a.applocationid,c.locationid as tenantlocationid,a.status
from customers a
INNER JOIN tenantcustomers c ON a.customerid=c.customerid
WHERE lower(a.firstname) like '` + strings.ToLower(str) + `%' or contactno like '` + strings.ToLower(str) + `%'`
}
db.DB.Raw(q1).Find(&data)
return data
}
func GetCustomerbyApplocation(aid int) []models.CustomerInfo {
var data []models.CustomerInfo
var q1 string
if aid != 0 {
q1 = `SELECT a.customerid,a.firstname,a.lastname,a.contactno,a.email,
b.locationid as deliverylocationid,b.address,b.suburb,b.city,b.state,b.landmark,b.doorno,b.postcode,
b.latitude,b.longitude,a.applocationid,a.status
from customers a
INNER JOIN customerlocations b ON a.customerid=b.customerid
INNER JOIN tenantcustomers c ON a.customerid=c.customerid
WHERE b.primaryaddress=1 and a.applocationid=? order by customerid desc`
}
db.DB.Raw(q1, aid).Find(&data)
return data
}
func CheckCustomer(contactno string) int {
var data models.Customers
q1 := `select a.customerid,a.authmode,a.configid,a.deviceid,a.devicetype,a.customertoken,a.firstname,a.lastname,
a.contactno,a.email,a.profileimage,a.address,a.suburb,a.city,a.state,a.landmark,a.doorno,a.postcode,
a.latitude,a.longitude,a.status from customers a where a.contactno= '` + contactno + `'`
db.DB.Raw(q1).Find(&data)
return data.Customerid
}
func CheckLocation(cid int) (int, error) {
var data int
q1 := `select a.locationid from customerlocations a where a.customerid= ` + strconv.Itoa(cid)
db.DB.Raw(q1).Find(&data)
return data, nil
}
func CheckTenantCustomer(cid, tid int) int {
var data models.Customers
q1 := `select a.customerid from tenantcustomers a where a.customerid=` + strconv.Itoa(cid) + ` and a.tenantid=` + strconv.Itoa(tid)
db.DB.Raw(q1).Find(&data)
return data.Customerid
}
func CreateCustomerLocation(input models.Customerlocations) int {
err := db.DB.Create(&input).Error
if err != nil {
return 0
}
return input.Customerid
}
func GetCustomerLocation(cid int) models.CustomerLocationResult {
var result models.CustomerLocationResult
var data []models.Customerlocations
var q1 string
if cid != 0 {
q1 = `SELECT a.locationid, a.customerid, a.address, a.suburb, a.city, a.state, a.landmark, a.doorno, a.postcode,
a.latitude, a.longitude, a.defaultaddress, a.primaryaddress, a.status
FROM customerlocations a WHERE a.customerid = ` + strconv.Itoa(cid)
}
db.DB.Raw(q1).Find(&data)
result.Code = http.StatusOK
result.Status = true
result.Message = "Successful"
result.Details = data
return result
}

1295
domain/delivery.go Normal file

File diff suppressed because it is too large Load Diff

207
domain/invoice.go Normal file
View File

@@ -0,0 +1,207 @@
package domain
import (
"nearle/db"
"nearle/models"
"nearle/utils"
"strconv"
)
func GetAllInvoice(stat, tid int) []models.Tenantsales {
var q1 string
var data []models.Tenantsales
const (
base = `select a.* from tenantsales a`
)
if stat == 1 {
if tid != 0 {
q1 = base + ` where a.billstatus=0 and a.tenantid=` + strconv.Itoa(tid) + ` and a.duedate::date > CURRENT_DATE order by salesid desc `
} else {
q1 = base + ` where a.billstatus=0 and a.duedate::date > CURRENT_DATE order by salesid desc `
}
} else if stat == 2 {
if tid != 0 {
q1 = base + ` where a.billstatus=0 and a.tenantid=` + strconv.Itoa(tid) + ` and a.duedate::date < CURRENT_DATE order by salesid desc `
} else {
q1 = base + ` where a.billstatus=0 and a.duedate::date < CURRENT_DATE order by salesid desc `
}
} else if stat == 3 {
if tid != 0 {
q1 = base + ` where a.billstatus=2 and a.tenantid=` + strconv.Itoa(tid) + ` order by salesid desc `
} else {
q1 = base + ` where a.billstatus=2 order by salesid desc `
}
} else {
if tid != 0 {
q1 = base + ` where a.tenantid=` + strconv.Itoa(tid) + ` order by salesid desc `
} else {
q1 = base + ` order by salesid desc `
}
}
// print(q1)
db.DB.Raw(q1).Preload("Tenantsalesdetails").Find(&data)
return data
}
func GetInvoiceOrders(tid int, fdate, tdate string) models.InvoiceOrders {
var q1 string
var data models.InvoiceOrders
q1 = `SELECT round(SUM(actualkms),0) AS actualkms,round(SUM(kms),0) AS kms,count(*) as deliveries FROM deliveries
WHERE orderstatus='delivered' and tenantid=` + strconv.Itoa(tid) + ` and date(deliverydate) between '` + fdate + `' and '` + tdate + `'`
utils.Logger.Debugf("Query: %s", q1)
db.DB.Raw(q1).Find(&data)
return data
}
func GetInvoiceInsight(tid int) models.InvoiceInsight {
var q1 string
var data models.InvoiceInsight
if tid != 0 {
q1 = `Select COUNT(*) AS totalcount,
SUM(totalamount) AS total,
SUM(CASE WHEN billstatus=0 and status='pending' AND duedate > CURRENT_DATE THEN 1 ELSE 0 END) AS pendingcount,
SUM(CASE WHEN billstatus IN (0) and status='pending' AND duedate > CURRENT_DATE THEN totalamount ELSE 0 END) AS pending,
(SUM(CASE WHEN billstatus IN (0) and status='pending' AND duedate > CURRENT_DATE THEN totalamount ELSE 0 END) / SUM(totalamount) * 100) AS pendingpercent,
SUM(CASE WHEN billstatus = 1 THEN 1 ELSE 0 END) AS confirmedcount,
SUM(CASE WHEN billstatus = 1 THEN totalamount ELSE 0 END) AS confirmed,
(SUM(CASE WHEN billstatus = 1 THEN totalamount ELSE 0 END) / SUM(totalamount) * 100) AS confrimedpercent,
SUM(CASE WHEN billstatus = 2 THEN 1 ELSE 0 END) AS paidcount,
SUM(CASE WHEN billstatus = 2 THEN totalamount ELSE 0 END) AS paid,
(SUM(CASE WHEN billstatus = 2 THEN totalamount ELSE 0 END) / SUM(totalamount) * 100) AS paidpercent,
SUM(CASE WHEN billstatus IN (0) and status='pending' AND duedate <= CURRENT_DATE THEN 1 ELSE 0 END) AS overduecount,
SUM(CASE WHEN billstatus IN(0) and status='pending' AND duedate <= CURRENT_DATE THEN totalamount ELSE 0 END) AS overdue,
(SUM(CASE WHEN billstatus IN(0) and status='pending' AND duedate <= CURRENT_DATE THEN totalamount ELSE 0 END) / SUM(totalamount) * 100) AS overduepercent
FROM tenantsales where tenantid=` + strconv.Itoa(tid)
} else {
q1 = `Select COUNT(*) AS totalcount,
SUM(totalamount) AS total,
SUM(CASE WHEN billstatus=0 and status='pending' AND duedate > CURRENT_DATE THEN 1 ELSE 0 END) AS pendingcount,
SUM(CASE WHEN billstatus IN (0) and status='pending' AND duedate > CURRENT_DATE THEN totalamount ELSE 0 END) AS pending,
(SUM(CASE WHEN billstatus IN (0) and status='pending' AND duedate > CURRENT_DATE THEN totalamount ELSE 0 END) / SUM(totalamount) * 100) AS pendingpercent,
SUM(CASE WHEN billstatus = 1 THEN 1 ELSE 0 END) AS confirmedcount,
SUM(CASE WHEN billstatus = 1 THEN totalamount ELSE 0 END) AS confirmed,
(SUM(CASE WHEN billstatus = 1 THEN totalamount ELSE 0 END) / SUM(totalamount) * 100) AS confrimedpercent,
SUM(CASE WHEN billstatus = 2 THEN 1 ELSE 0 END) AS paidcount,
SUM(CASE WHEN billstatus = 2 THEN totalamount ELSE 0 END) AS paid,
(SUM(CASE WHEN billstatus = 2 THEN totalamount ELSE 0 END) / SUM(totalamount) * 100) AS paidpercent,
SUM(CASE WHEN billstatus IN (0) and status='pending' AND duedate <= CURRENT_DATE THEN 1 ELSE 0 END) AS overduecount,
SUM(CASE WHEN billstatus IN(0) and status='pending' AND duedate <= CURRENT_DATE THEN totalamount ELSE 0 END) AS overdue,
(SUM(CASE WHEN billstatus IN(0) and status='pending' AND duedate <= CURRENT_DATE THEN totalamount ELSE 0 END) / SUM(totalamount) * 100) AS overduepercent
FROM tenantsales`
}
// print(q1)
db.DB.Raw(q1).Find(&data)
return data
}
func CreateInvoice(data models.Tenantsales) error {
tx := db.DB.Begin()
t1 := tx.Create(&data)
if t1.Error != nil {
utils.Error("CreateInvoice error", "error", t1.Error)
tx.Rollback()
return t1.Error
}
t2 := tx.Table("deliveries").Where("deliverydate>=? and deliverydate<=?", data.Tenantsalesdetails[0].Fromdate, data.Tenantsalesdetails[0].Todate).Update("settlementid", data.Salesid)
if t2.Error != nil {
utils.Error("CreateInvoice deliveries update error", "error", t2.Error)
tx.Rollback()
return t2.Error
}
UpdateSeqno(data.Tenantid, "INV")
err := tx.Commit().Error
if err != nil {
return err
}
return nil
}
func UpdateInvoice(data models.Tenantsales) error {
tx := db.DB.Begin()
t1 := tx.Where("salesid=?", data.Salesid).Updates(&data)
if t1.Error != nil {
utils.Error("UpdateInvoice error", "error", t1.Error)
tx.Rollback()
}
err := tx.Commit().Error
if err != nil {
return err
}
return nil
}
func UpdateInvoiceStatus(data models.InvoiceStatus) error {
tx := db.DB.Begin()
t1 := tx.Table("tenantsales").Where("salesid=?", data.Salesid).Updates(&data)
if t1.Error != nil {
utils.Error("UpdateInvoiceStatus error", "error", t1.Error)
tx.Rollback()
}
err := tx.Commit().Error
if err != nil {
return err
}
return nil
}

1072
domain/order.go Normal file

File diff suppressed because it is too large Load Diff

1388
domain/partner.go Normal file

File diff suppressed because it is too large Load Diff

34
domain/platform.go Normal file
View File

@@ -0,0 +1,34 @@
package domain
import (
"nearle/db"
"nearle/models"
"nearle/utils"
"strconv"
)
func GetModules(mid int) []models.AppModules {
var data []models.AppModules
q1 := `SELECT a.moduleid,a.modulename,a.logourl,
(SELECT COUNT(*) FROM tenants WHERE moduleid=a.moduleid) AS business,
(SELECT COUNT(*) FROM deliveries WHERE moduleid=a.moduleid) as orders from app_module a where a.status='Active' order by sortorder asc`
db.DB.Raw(q1).Find(&data)
return data
}
func GetSmsprovider(tid int) models.Smsproviders {
var data models.Smsproviders
q1 := `select * from smsproviders where status='Active' and templatetypeid=` + strconv.Itoa(tid)
db.DB.Raw(q1).Find(&data)
utils.Logger.Debugf("Query: %s", q1)
return data
}

847
domain/product.go Normal file
View File

@@ -0,0 +1,847 @@
package domain
import (
"errors"
"nearle/db"
"nearle/models"
"nearle/utils"
"strconv"
"strings"
"time"
"gorm.io/gorm"
"gorm.io/gorm/clause"
)
func GetProductCategory() []models.ProductCategory {
var data []models.ProductCategory
q1 := `SELECT * FROM productcategories WHERE moduleid = 2 and status = "Active"`
db.DB.Raw(q1).Scan(&data)
return data
}
func GetProductSubCategory(categoryID, tenantID int) []models.ProductSubCategory {
var data []models.ProductSubCategory
var query strings.Builder
var args []interface{}
query.WriteString("SELECT * FROM productsubcategories WHERE 1=1")
if tenantID != 0 {
query.WriteString(" AND tenantid = ?")
args = append(args, tenantID)
}
if categoryID != 0 {
query.WriteString(" AND categoryid = ?")
args = append(args, categoryID)
}
db.DB.Raw(query.String(), args...).Scan(&data)
return data
}
func CreateProduct(product *models.Products) error {
tx := db.DB.Begin()
t1 := tx.Create(&product)
if t1.Error != nil {
utils.Error("CreateProduct error", "error", t1.Error)
tx.Rollback()
return t1.Error
}
err := tx.Commit().Error
if err != nil {
return err
}
return nil
}
func CreateProductVariant(input models.Productvariant) error {
tx := db.DB.Begin()
t1 := tx.Create(&input)
if t1.Error != nil {
utils.Error("CreateProductVariant error", "error", t1.Error)
tx.Rollback()
return t1.Error
}
err := tx.Commit().Error
if err != nil {
return err
}
return nil
}
func FetchFilteredProducts(categoryID, subcategoryID, productID, applocationID, tenantID, locationID int, keyword, productStatus, approve string, pageno, pagesize int) ([]models.Tenantproducts, error) {
offset := (pageno - 1) * pagesize
results := make([]models.Tenantproducts, 0)
if tenantID == 0 {
return results, nil
}
var tenant models.TenantInfo
err := db.DB.Table("tenants").Where("tenantid = ?", tenantID).First(&tenant).Error
if err != nil {
return nil, err
}
var products []models.Products
query := db.DB.
Debug().
Table("products a").
Select(`
a.*,
c.categoryname,
d.subcatname AS subcategoryname,
e.locationid,
COALESCE(
SUM(CASE WHEN e.stocktype = 'in' THEN e.quantity ELSE 0 END) -
SUM(CASE WHEN e.stocktype = 'out' THEN e.quantity ELSE 0 END),
0
) AS quantity
`).
Joins("LEFT JOIN productcategories c ON a.categoryid = c.categoryid").
Joins("LEFT JOIN productsubcategories d ON a.subcategoryid = d.subcatid").
Joins("LEFT JOIN productstocks e ON e.productid = a.productid").
Where("a.tenantid = ?", tenantID).
Group("a.productid"). // Important for SUM
Order("a.productid DESC")
if categoryID != 0 {
query = query.Where("a.categoryid = ?", categoryID)
}
if subcategoryID != 0 {
query = query.Where("a.subcategoryid = ?", subcategoryID)
}
if productID != 0 {
query = query.Where("a.productid = ?", productID)
}
if productStatus != "" {
query = query.Where("a.productstatus = ?", productStatus)
}
if locationID != 0 {
query = query.Where("e.locationid = ?", locationID)
}
if approve != "" {
query = query.Where("a.approve = ?", approve)
}
if keyword != "" {
like := "%" + strings.ToLower(keyword) + "%"
query = query.Where(
db.DB.Where("LOWER(a.productname) LIKE ?", like).
Or("LOWER(a.unitvalue) LIKE ?", like).
Or("LOWER(CAST(a.productcost AS CHAR)) LIKE ?", like),
)
}
if pagesize > 0 && offset >= 0 {
query = query.Limit(pagesize).Offset(offset)
}
err = query.Scan(&products).Error
if err != nil {
return nil, err
}
if products == nil {
products = []models.Products{}
}
results = append(results, models.Tenantproducts{
Tenant: tenant,
Products: products,
})
return results, nil
}
func UpdateProduct(input models.Products) error {
tx := db.DB.Begin()
t1 := tx.Where("productid=?", input.Productid).Updates(&input)
if t1.Error != nil {
tx.Rollback()
return t1.Error
}
err := tx.Commit().Error
if err != nil {
return err
}
return nil
}
func Getproductcount(tenantid, categoryid, subcategory int, approve string) ([]models.Productcount, error) {
var data []models.Productcount
baseQuery := `
SELECT
COUNT(*) AS total,
SUM(CASE WHEN a.productstatus = 'available' THEN 1 ELSE 0 END) AS available,
SUM(CASE WHEN a.productstatus = 'outofstock' THEN 1 ELSE 0 END) AS outofstock
FROM products a
WHERE 1 = 1
`
var conditions []string
var params []interface{}
if tenantid != 0 {
conditions = append(conditions, "a.tenantid = ?")
params = append(params, tenantid)
}
if categoryid != 0 {
conditions = append(conditions, "a.categoryid = ?")
params = append(params, categoryid)
}
if subcategory != 0 {
conditions = append(conditions, "a.subcategoryid = ?")
params = append(params, subcategory)
}
if approve != "" {
conditions = append(conditions, "a.approve = ?")
params = append(params, approve)
}
if len(conditions) > 0 {
baseQuery += " AND " + strings.Join(conditions, " AND ")
}
if err := db.DB.Raw(baseQuery, params...).Scan(&data).Error; err != nil {
return nil, err
}
return data, nil
}
func GetproductbyVariant(tenantid, variantid int) ([]models.Products, error) {
var data []models.Products
err := db.DB.
Table("products p").
Select("p.*, c.categoryname, d.subcatname as subcategoryname").
Joins("LEFT JOIN productcategories c ON p.categoryid = c.categoryid").
Joins("LEFT JOIN productsubcategories d ON p.subcategoryid = d.subcatid").
Where("p.tenantid = ? and p.variants = ?", tenantid, variantid).
Order("p.productid desc").Scan(&data).Error
if err != nil {
return nil, err
}
return data, nil
}
func GetProductVariants(tenantId int, subcategoryId int) []models.Productvariant {
var data []models.Productvariant
var query string
var params []interface{}
query = `
SELECT a.*, b.categoryname
FROM productvariants a
JOIN app_category b ON a.categoryid = b.categoryid
WHERE a.tenantid = ?
`
params = append(params, tenantId)
if subcategoryId != 0 {
query += " AND a.subcategoryid = ?"
params = append(params, subcategoryId)
}
db.DB.Raw(query, params...).Scan(&data)
return data
}
func GetCatalougeProducts(tenantId, locationid, subcategoryid, pageno, pagesize int, keyword string) []models.Products {
var data []models.Products
var query string
if pageno < 1 {
pageno = 1
}
if pagesize < 1 {
pagesize = 10
}
offset := (pageno - 1) * pagesize
params := []interface{}{locationid, tenantId}
query = `SELECT a.* FROM products a
LEFT JOIN productlocations b ON a.productid = b.productid
AND b.locationid =? AND b.tenantid = a.tenantid
WHERE a.approve=1 and a.tenantid = ? AND b.productid IS NULL order by a.productid desc LIMIT ` + strconv.Itoa(pagesize) + ` OFFSET ` + strconv.Itoa(offset)
if subcategoryid != 0 {
query += " AND a.subcategoryid = ?"
params = append(params, subcategoryid)
}
if keyword != "" {
query += " AND LOWER(a.productname) LIKE ?"
params = append(params, "%"+strings.ToLower(keyword)+"%")
}
db.DB.Raw(query, params...).Scan(&data)
utils.Logger.Debugf("Query: %s", query)
return data
}
func GetLocationProducts(tenantid, locationid, subcategoryid, pageno, pagesize int, keyword string) []models.Products {
var data []models.Products
if pageno < 1 {
pageno = 1
}
if pagesize < 1 {
pagesize = 10
}
offset := (pageno - 1) * pagesize
params := []interface{}{tenantid, locationid}
query := `SELECT a.*,
COALESCE(SUM(CASE WHEN UPPER(c.stocktype) = 'IN' THEN c.quantity ELSE 0 END), 0) AS total_in,
COALESCE(SUM(CASE WHEN UPPER(c.stocktype) = 'OUT' THEN c.quantity ELSE 0 END), 0) AS total_out,
COALESCE(SUM(CASE WHEN UPPER(c.stocktype) = 'IN' THEN c.quantity ELSE 0 END) -
SUM(CASE WHEN UPPER(c.stocktype) = 'OUT' THEN c.quantity ELSE 0 END), 0) AS productstock
FROM products a
INNER JOIN productlocations b
ON a.productid = b.productid AND a.tenantid = b.tenantid
LEFT JOIN productstocks c
ON a.productid = c.productid
AND b.locationid = c.locationid
AND a.tenantid = c.tenantid
WHERE a.approve=1 AND a.tenantid = ?
AND b.locationid = ?`
if subcategoryid != 0 {
query += " AND a.subcategoryid = ?"
params = append(params, subcategoryid)
}
if keyword != "" {
query += " AND LOWER(a.productname) LIKE ?"
params = append(params, "%"+strings.ToLower(keyword)+"%")
}
query += ` GROUP BY a.productid, a.productname, a.productimage, a.categoryid, a.subcategoryid,
a.productunit, a.productcost, a.taxpercent, a.taxamount, a.retailprice,
b.tenantid, b.locationid`
query += " ORDER BY a.productid DESC LIMIT ? OFFSET ?"
params = append(params, pagesize, offset)
db.DB.Raw(query, params...).Scan(&data)
return data
}
func GetStockStatement(tenantid, locationid, subcategoryid, pageno, pagesize int, keyword string) []models.Productstockstatement {
data := make([]models.Productstockstatement, 0)
if pageno < 1 {
pageno = 1
}
if pagesize < 1 {
pagesize = 10
}
offset := (pageno - 1) * pagesize
params := []interface{}{tenantid, locationid}
query := `SELECT a.productid,a.productname,a.productimage,a.categoryid,a.subcategoryid,a.productunit,a.unitvalue,a.productcost,a.taxpercent,a.taxamount,a.retailprice,b.tenantid,b.locationid,
COALESCE( SUM(CASE WHEN UPPER(c.stocktype) = 'IN' AND c.stockdate::date <= CURRENT_DATE THEN c.quantity ELSE 0 END) -
SUM(CASE WHEN UPPER(c.stocktype) = 'OUT' AND c.stockdate::date <= CURRENT_DATE THEN c.quantity ELSE 0 END),0 )
AS opening,
COALESCE(SUM(CASE WHEN UPPER(c.stocktype) = 'IN' AND c.stockdate::date = CURRENT_DATE THEN c.quantity ELSE 0 END), 0) AS credit,
COALESCE(SUM(CASE WHEN UPPER(c.stocktype) = 'OUT' AND c.stockdate::date= CURRENT_DATE THEN c.quantity ELSE 0 END), 0) AS debit,
COALESCE(
( SUM(CASE WHEN UPPER(c.stocktype) = 'IN' AND c.stockdate::date < CURRENT_DATE THEN c.quantity ELSE 0 END) -
SUM(CASE WHEN UPPER(c.stocktype) = 'OUT' AND c.stockdate::date < CURRENT_DATE THEN c.quantity ELSE 0 END)
) +
SUM(CASE WHEN UPPER(c.stocktype) = 'IN' AND c.stockdate::date = CURRENT_DATE THEN c.quantity ELSE 0 END) -
SUM(CASE WHEN UPPER(c.stocktype) = 'OUT' AND c.stockdate::date = CURRENT_DATE THEN c.quantity ELSE 0 END),
0
) AS closing
FROM products a
JOIN productlocations b ON a.productid = b.productid AND a.tenantid = b.tenantid
LEFT JOIN productstocks c ON a.productid = c.productid AND b.locationid = c.locationid AND b.tenantid = c.tenantid
WHERE b.tenantid = ? AND b.locationid = ?`
if subcategoryid != 0 {
query += " AND a.subcategoryid = ?"
params = append(params, subcategoryid)
}
if keyword != "" {
query += " AND (CAST(a.productid AS CHAR) LIKE ? OR LOWER(a.productname) LIKE ?)"
likeParam := "%" + strings.ToLower(keyword) + "%"
params = append(params, likeParam, likeParam)
}
query += `
GROUP BY
a.productid, a.productname, a.productimage,
a.categoryid, a.subcategoryid, a.productunit,
a.productcost, a.taxpercent, a.taxamount,
a.retailprice, b.tenantid, b.locationid
ORDER BY a.productid DESC LIMIT ` + strconv.Itoa(pagesize) + ` OFFSET ` + strconv.Itoa(offset)
db.DB.Raw(query, params...).Scan(&data)
utils.Logger.Debugf("Query: %s", query)
return data
}
func CreateProductLocation(input []models.Productlocations) error {
var stk []models.Productstock
tx := db.DB.Begin()
if err := tx.Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "tenantid"}, {Name: "locationid"}, {Name: "productid"}},
DoUpdates: clause.AssignmentColumns([]string{"price", "minquantity", "maxquantity"}),
}).Create(&input).Error; err != nil {
tx.Rollback()
return err
}
for _, loc := range input {
if loc.Quantity > 0 {
stk = append(stk, models.Productstock{
Tenantid: loc.Tenantid,
Stockdate: time.Now(),
Locationid: loc.Locationid,
Productid: loc.Productid,
Quantity: loc.Quantity,
Stocktype: loc.Stocktype,
})
}
}
if len(stk) > 0 {
t2 := tx.Create(&stk)
if t2.Error != nil {
tx.Rollback()
return t2.Error
}
}
err := tx.Commit().Error
if err != nil {
return err
}
return nil
}
func UpdateProductLocation(input models.Productlocations) error {
tx := db.DB.Begin()
t1 := tx.Where("productlocationid=?", input.Productlocationid).Updates(&input)
if t1.Error != nil {
tx.Rollback()
return t1.Error
}
err := tx.Commit().Error
if err != nil {
return err
}
return nil
}
func FetchProductsBySubcategory(categoryID, tenantID, applocationID, locationID, productID int, keyword string) (map[string]interface{}, error) {
utils.Logger.Infof("Domain: Fetching products for categoryID=%d, tenantID=%d", categoryID, tenantID)
// Step 1: Fetch subcategories
var subcategories []models.Subcategory
err := db.DB.Table("productsubcategories").
Where("categoryid = ?", categoryID).
Find(&subcategories).Error
if err != nil {
utils.Error("Error fetching subcategories", "error", err)
return nil, err
}
// Step 2: Build product query
var products []models.Products
query := db.DB.Table("products a").
Joins("LEFT JOIN productlocations pl ON pl.productid = a.productid").
Where("a.categoryid = ? AND a.tenantid = ?", categoryID, tenantID)
if locationID > 0 {
query = query.Where("pl.locationid = ?", locationID)
}
if applocationID > 0 {
query = query.Where("a.applocationid = ?", applocationID)
}
if productID > 0 {
query = query.Where("a.productid = ?", productID)
}
if keyword != "" {
like := "%" + strings.ToLower(keyword) + "%"
query = query.Where(
db.DB.Where("LOWER(a.productname) LIKE ?", like).
Or("LOWER(a.unitvalue) LIKE ?", like).
Or("LOWER(CAST(a.productcost AS CHAR)) LIKE ?", like),
)
}
if err := query.Select("a.*").Find(&products).Error; err != nil {
utils.Error("Error fetching products", "error", err)
return nil, err
}
// Step 3: Grouping
var grouped []models.SubcategoryProductResponse
var uncategorized []models.Products
for _, subcat := range subcategories {
var matched []models.Products
for _, prod := range products {
if prod.Subcategoryid != nil && *prod.Subcategoryid == subcat.Subcategoryid {
matched = append(matched, prod)
}
}
if len(matched) > 0 {
grouped = append(grouped, models.SubcategoryProductResponse{
SubcategoryID: subcat.Subcategoryid,
SubcategoryName: subcat.Subcategoryname,
Products: matched,
})
}
}
// Add uncategorized
for _, p := range products {
if p.Subcategoryid == nil {
uncategorized = append(uncategorized, p)
}
}
if len(uncategorized) > 0 {
grouped = append(grouped, models.SubcategoryProductResponse{
SubcategoryID: 0,
SubcategoryName: "Uncategorized",
Products: uncategorized,
})
}
// Step 4: Tenant info
var tenantInfo map[string]interface{}
for _, p := range products {
if p.Tenantid != nil {
tenantInfo, err = fetchTenantDetails(*p.Tenantid, applocationID)
if err != nil {
utils.Error("Error fetching tenant details", "error", err)
}
break
}
}
if tenantInfo == nil {
return map[string]interface{}{}, nil
}
tenantInfo["details"] = grouped
return tenantInfo, nil
}
func fetchTenantDetails(tenantID, applocationID int) (map[string]interface{}, error) {
var tenant struct {
Tenantname string
Address string
Licenseno string
Primaryemail string
Primarycontact string
Locationname string
Pickuplocationid int
Suburb string
City string
Latitude string
Longitude string
Postcode string
}
err := db.DB.Raw(`
SELECT t.tenantname,t.address,t.licenseno,t.primaryemail,t.primarycontact,l.locationid AS pickuplocationid,l.suburb,l.city,l.latitude,l.longitude,l.postcode,a.locationname
FROM tenants t
LEFT JOIN tenantlocations l ON t.tenantid = l.tenantid
LEFT JOIN app_location a ON l.applocationid = a.applocationid
WHERE t.tenantid = ? AND t.applocationid = ?
LIMIT 1
`, tenantID, applocationID).Scan(&tenant).Error
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
return nil, err
}
return map[string]interface{}{
"tenantname": tenant.Tenantname,
"address": tenant.Address,
"licenseno": tenant.Licenseno,
"primaryemail": tenant.Primaryemail,
"primarycontact": tenant.Primarycontact,
"locationname": tenant.Locationname,
"pickuplocationid": tenant.Pickuplocationid,
"suburb": tenant.Suburb,
"city": tenant.City,
"pickuplat": tenant.Latitude,
"pickuplong": tenant.Longitude,
"postcode": tenant.Postcode,
}, nil
}
func UpdateProductStock(stock *models.Productstock) error {
// Ensure the record exists
var existing models.Productstock
if err := db.DB.First(&existing, "productstockid = ?", stock.Productstockid).Error; err != nil {
return err
}
// Update fields
return db.DB.Model(&existing).Updates(models.Productstock{
Tenantid: stock.Tenantid,
Stockdate: stock.Stockdate,
Locationid: stock.Locationid,
Productid: stock.Productid,
Quantity: stock.Quantity,
Stocktype: stock.Stocktype,
Status: stock.Status,
}).Error
}
func GetProductStocks(tenantID, locationID string) ([]models.Productstocks, error) {
var stocks []models.Productstocks
var params []interface{}
var conditions []string
query := `
SELECT
a.productid, a.tenantid, MAX(a.stockdate) AS stockdate, a.locationid, a.stocktype, a.maxquantity, a.minquantity, a.status,
b.applocationid, b.categoryid, b.subcategoryid, b.catalogueid, b.addonid, b.discountid, b.pricingid,
b.productname, b.productimage, b.productdesc, b.productsku, b.brandid, b.productbrand, b.productunit,
b.unitvalue, b.toppicks, b.productcost, b.taxamount, b.taxpercent, b.producttax, b.productstock,
b.productcombo, b.variants, b.retailprice, b.diffprice, b.diffpercent, b.othercost, b.approve,
b.productstatus, b.created, b.updated, c.subcatname AS subcategoryname,
SUM(CASE WHEN a.stocktype = 'in' THEN a.quantity ELSE 0 END) -
SUM(CASE WHEN a.stocktype = 'out' THEN a.quantity ELSE 0 END) AS quantity
FROM productstocks a
JOIN products b ON a.productid = b.productid
INNER JOIN productsubcategories c ON c.subcatid = b.subcategoryid
`
if tenantID != "" {
conditions = append(conditions, "a.tenantid = ?")
params = append(params, tenantID)
}
if locationID != "" {
conditions = append(conditions, "a.locationid = ?")
params = append(params, locationID)
}
if len(conditions) > 0 {
query += " WHERE " + strings.Join(conditions, " AND ")
}
query += " GROUP BY a.productid"
if err := db.DB.Raw(query, params...).Scan(&stocks).Error; err != nil {
return nil, err
}
return stocks, nil
}
func GetSubCategoryWiseSummary(tenantId, locationid, subcategoryid int) ([]models.SubCategorySummary, error) {
var data []models.SubCategorySummary
query := `
SELECT a.subcategoryid AS subcategoryid, c.subcatname AS subcatname, COUNT(a.productid) AS productcount
FROM products a
LEFT JOIN productlocations b ON a.productid = b.productid AND b.locationid = ? AND b.tenantid = a.tenantid
LEFT JOIN productsubcategories c ON a.subcategoryid = c.subcatid
WHERE a.approve = 1 AND a.tenantid = ? AND b.productid IS NULL
`
var params []interface{}
params = append(params, locationid, tenantId)
if subcategoryid > 0 {
query += " AND a.subcategoryid = ?"
params = append(params, subcategoryid)
}
query += `
GROUP BY a.subcategoryid, c.subcatname
ORDER BY a.subcategoryid ASC
`
if err := db.DB.Raw(query, params...).Scan(&data).Error; err != nil {
return nil, err
}
return data, nil
}
func GetLocationProductSummary(tenantid, locationid int) []models.ProductSummary {
data := make([]models.ProductSummary, 0)
params := []interface{}{tenantid, locationid}
query := `
SELECT a.subcatid AS subcategoryid, a.subcatname AS subcategroyname, a.image, COUNT(DISTINCT b.productid) AS productcount
FROM productsubcategories a
LEFT JOIN products b ON a.subcatid = b.subcategoryid AND b.approve = 1 AND b.tenantid = ?
LEFT JOIN productlocations c ON b.productid = c.productid AND b.tenantid = c.tenantid AND c.locationid = ?
WHERE a.categoryid = 2
GROUP BY a.subcatid, a.subcatname
ORDER BY a.subcatid;
`
db.DB.Raw(query, params...).Scan(&data)
total := 0
for _, d := range data {
total += d.Productcount
}
all := models.ProductSummary{
Subcategoryid: 0,
Subcategroyname: "All",
Productcount: total,
}
data = append([]models.ProductSummary{all}, data...)
return data
}
func GetStockStatementSummary(tenantid, locationid int) []models.ProductSummary {
data := make([]models.ProductSummary, 0)
params := []interface{}{tenantid, locationid}
query := `
SELECT a.subcatid AS subcategoryid, a.subcatname AS subcategroyname, a.image, COUNT(DISTINCT b.productid) AS productcount
FROM productsubcategories a
LEFT JOIN products b ON a.subcatid = b.subcategoryid AND b.tenantid = ?
LEFT JOIN productlocations c ON b.productid = c.productid AND b.tenantid = c.tenantid AND c.locationid = ?
WHERE a.categoryid = 2
GROUP BY a.subcatid, a.subcatname
ORDER BY a.subcatid;
`
db.DB.Raw(query, params...).Scan(&data)
utils.Logger.Debugf("Query: %s", query)
// Add "All" row
total := models.ProductSummary{
Subcategoryid: 0,
Subcategroyname: "All",
}
for _, d := range data {
total.Productcount += d.Productcount
}
data = append([]models.ProductSummary{total}, data...)
return data
}
func CreateProductDiscount(discount *models.ProductDiscount) error {
// convert []string to comma-separated string
if len(discount.Locationid) > 0 {
discount.LocationidStr = strings.Join(discount.Locationid, ",")
}
tx := db.DB.Begin()
if err := tx.Table("productdiscounts").Create(discount).Error; err != nil {
tx.Rollback()
return err
}
return tx.Commit().Error
}
func GetProductDiscounts(tid int, lid string) []models.ProductDiscount {
var result []models.ProductDiscount
query := `
SELECT
discountid, discounttypeid, tenantid, productid, moduleid,
locationid, discountname, discountcode,
discountterms, discountvalue, startdate, enddate, status
FROM productdiscounts
WHERE tenantid = ?
AND moduleid = 2
AND FIND_IN_SET(?, locationid)
`
db.DB.Raw(query, tid, lid).Scan(&result)
// convert comma separated location ids to []string
for i := range result {
if result[i].LocationidStr != "" {
result[i].Locationid = strings.Split(result[i].LocationidStr, ",")
} else {
result[i].Locationid = []string{}
}
}
return result
}

591
domain/tenant.go Normal file
View File

@@ -0,0 +1,591 @@
package domain
import (
"errors"
"nearle/db"
"nearle/models"
"nearle/utils"
"strconv"
"strings"
"github.com/jinzhu/copier"
)
func CreateTenantUser(data models.Tenants) (bool, error) {
var seq models.Ordersequences
var user models.User
var cust models.Customers
var custloc models.Customerlocations
var tcust models.Tenantcustomers
tx := db.DB.Begin()
t1 := tx.Create(&data)
if t1.Error != nil {
tx.Rollback()
return false, errors.New("error in tenant creation")
}
seq.Tenantid = data.Tenantid
t2 := tx.Table("ordersequences").Create(&seq)
if t2.Error != nil {
tx.Rollback()
return false, errors.New("error in sequence")
}
if err := copier.Copy(&user, &data); err != nil {
return false, err
}
user.Userfcmtoken = data.Tenanttoken
user.Contactno = data.Primarycontact
user.Email = data.Primaryemail
user.Authname = data.Primaryemail
user.Deviceid = data.Deviceid
user.Tenantid = data.Tenantid
user.Locationid = data.Tenantlocations.Locationid
user.Roleid = 1
t3 := tx.Table("app_users").Create(&user)
if t3.Error != nil {
tx.Rollback()
return false, errors.New("error in user creation")
}
cust.Configid = data.Configid
cust.Firstname = data.Tenantname
cust.Email = data.Primaryemail
cust.Contactno = data.Primarycontact
cust.Deviceid = data.Deviceid
cust.Devicetype = data.Devicetype
cust.Customertoken = data.Tenanttoken
cust.Profileimage = data.Tenantimage
cust.Address = data.Address
cust.Suburb = data.Suburb
cust.City = data.City
cust.State = data.State
cust.Postcode = data.Postcode
cust.Applocationid = data.Applocationid
cust.Latitude = data.Latitude
cust.Longitude = data.Longitude
cust.Primaryaddress = 1
cid := CheckCustomer(data.Primarycontact)
if cid == 0 {
t4 := tx.Table("customers").Create(&cust)
if t4.Error != nil {
tx.Rollback()
return false, errors.New("error in customer creation")
}
if err := copier.Copy(&custloc, &cust); err != nil {
return false, err
}
t5 := tx.Table("customerlocations").Create(&custloc)
if t5.Error != nil {
tx.Rollback()
return false, errors.New("error in customer location")
}
} else {
t1 := tx.Table("customers").Where("customerid=?", cid).Updates(&cust)
if t1.Error != nil {
tx.Rollback()
return false, errors.New("error in customer creation")
}
if err := copier.Copy(&custloc, &cust); err != nil {
return false, err
}
t2 := tx.Table("customerlocations").Where("customerid=?", cid).Updates(&custloc)
if t2.Error != nil {
tx.Rollback()
return false, errors.New("error in customer location")
}
}
tcust.Customerid = cust.Customerid
tcust.Tenantid = data.Tenantid
tcust.Locationid = data.Tenantlocations.Locationid
t6 := tx.Table("tenantcustomers").Create(&tcust)
if t6.Error != nil {
tx.Rollback()
return false, errors.New("error in tenant customer")
}
err := tx.Commit().Error
if err != nil {
return false, errors.New("error in tenant creation")
}
return true, nil
}
func UpdateTenant(input models.Tenants) error {
tx := db.DB.Begin()
t1 := tx.Where("tenantid=?", input.Tenantid).Updates(&input)
if t1.Error != nil {
tx.Rollback()
return t1.Error
}
err := tx.Commit().Error
if err != nil {
return err
}
return nil
}
func UpdateLocation(input models.Tenantlocations) error {
tx := db.DB.Begin()
t1 := tx.Where("locationid=?", input.Locationid).Updates(&input)
if t1.Error != nil {
tx.Rollback()
return t1.Error
}
err := tx.Commit().Error
if err != nil {
return err
}
return nil
}
func CreateLocation(data models.Tenantlocations) error {
var cust models.Customers
var tcust models.Tenantcustomers
var custloc models.Customerlocations
tx := db.DB.Begin()
t1 := tx.Create(&data)
if t1.Error != nil {
tx.Rollback()
return t1.Error
}
cust.Firstname = data.Locationname
cust.Email = data.Email
cust.Contactno = data.Contactno
cust.Address = data.Address
cust.Suburb = data.Suburb
cust.City = data.City
cust.State = data.State
cust.Postcode = data.Postcode
cust.Applocationid = data.Applocationid
cust.Latitude = data.Latitude
cust.Longitude = data.Longitude
cust.Primaryaddress = 0
t2 := tx.Table("customers").Create(&cust)
if t2.Error != nil {
tx.Rollback()
return t2.Error
}
if err := copier.Copy(&custloc, &cust); err != nil {
return err
}
t3 := tx.Table("customerlocations").Create(&custloc)
if t3.Error != nil {
tx.Rollback()
return t3.Error
}
tcust.Customerid = cust.Customerid
tcust.Tenantid = data.Tenantid
tcust.Locationid = data.Locationid
tcust.Moduleid = data.Moduleid
t4 := tx.Table("tenantcustomers").Create(&tcust)
if t4.Error != nil {
tx.Rollback()
return t4.Error
}
err := tx.Commit().Error
if err != nil {
return err
}
return nil
}
func Checktenantbyno(cno string) int {
var id int
q1 := "select tenantid from tenants where primarycontact='" + cno + `'`
db.DB.Raw(q1).Find(&id)
return id
}
func GetTeanantById(tid int) models.Tenantinfo {
var data models.Tenantinfo
// q1 := `SELECT a.*,b.categoryid,b.subcategoryid,c.subcategoryname,b.moduleid,d.locationid,d.locationname FROM
// tenants a
// INNER JOIN tenantsubscriptions b ON a.tenantid=b.tenantid
// INNER JOIN app_subcategory c ON c.subcategoryid=b.subcategoryid
// INNER JOIN tenantlocations d ON d.tenantid=a.tenantid
// where a.tenantid=?`
q1 := `SELECT a.*,b.categoryname,c.locationname as applocation,d.allocationid as allocationmode,e.typename AS allocationtype,e.mapid as allocationid,f.locationid,
f.locationname, g.slab, g.pricingdate, g.baseprice, g.minkm, g.priceperkm, g.maxkm, g.orders, g.othercharges, g.surgecharges
FROM tenants a
INNER JOIN app_category b ON a.categoryid=b.categoryid
INNER JOIN app_location c ON a.applocationid=c.applocationid
LEFT JOIN partnerinfo d ON a.partnerid=d.partnerid
LEFT JOIN app_types e ON d.allocationid=e.apptypeid
LEFT JOIN tenantlocations f ON a.tenantid=f.tenantid
LEFT JOIN tenantpricing g ON a.tenantid=g.tenantid
where a.tenantid=?`
utils.Logger.Debugf("Query: %s", q1)
db.DB.Raw(q1, tid).Find(&data)
return data
}
func GetTeanantPricing(tid, aid int) models.Tenantpricing {
var data models.Tenantpricing
var q1 string
if tid != 0 {
q1 = `SELECT * FROM tenantpricing WHERE pricingdate = (SELECT MAX(pricingdate) FROM tenantpricing where tenantid=` + strconv.Itoa(tid) + `) AND tenantid=? order by tenantpricingid desc`
}
utils.Logger.Debugf("Query: %s", q1)
db.DB.Raw(q1, tid).Find(&data)
return data
}
func GetPricinglist(tid int) []models.Tenantpricing {
var data []models.Tenantpricing
q1 := `SELECT *
FROM tenantpricing
WHERE tenantid=? order by pricingdate desc`
db.DB.Raw(q1, tid).Find(&data)
return data
}
func Getalltenants(pageno, pagesize, aid, moduleid int, status, tenanttype, keyword string) []models.Tenantinfo {
offset := (pageno - 1) * pagesize
var data []models.Tenantinfo
base := `
SELECT a.*, b.categoryname, c.slab, c.pricingdate, c.baseprice, c.minkm,
c.priceperkm, c.maxkm, c.orders,
c.othercharges, c.surgecharges
FROM tenants a
LEFT JOIN app_category b ON a.categoryid = b.categoryid
LEFT JOIN (
SELECT DISTINCT ON (tenantid) *
FROM tenantpricing
ORDER BY tenantid, pricingdate DESC
) c ON a.tenantid = c.tenantid
WHERE 1 = 1
`
var (
conds []string
params []interface{}
)
switch strings.ToLower(status) {
case "active":
conds = append(conds, "a.approved = 1 AND a.status = 'Active'")
case "inactive":
conds = append(conds, "a.approved = 1 AND a.status = 'InActive'")
case "pending":
conds = append(conds, "a.approved = 0")
}
if aid != 0 {
conds = append(conds, "a.applocationid = ?")
params = append(params, aid)
}
if moduleid != 0 {
conds = append(conds, "a.moduleid = ?")
params = append(params, moduleid)
}
if tenanttype != "" {
conds = append(conds, "a.tenanttype = ?")
params = append(params, tenanttype)
}
if keyword != "" {
kw := "%" + strings.ToLower(keyword) + "%"
conds = append(conds,
"(LOWER(a.tenantname) LIKE ? OR LOWER(a.primarycontact) LIKE ?)")
params = append(params, kw, kw)
}
if len(conds) > 0 {
base += " AND " + strings.Join(conds, " AND ")
}
base += " ORDER BY a.tenantid DESC LIMIT ? OFFSET ?"
params = append(params, pagesize, offset)
print(base, params)
db.DB.Raw(base, params...).Find(&data)
return data
}
func GetCustomerLocations(customerID int) models.CustomerTenantResponse {
var customer models.Customers
// get customer
db.DB.Table("customers").
Where("customerid = ?", customerID).
First(&customer)
// get locations
locations := []models.LocationDetails{}
query := `
SELECT
c.locationid,c.locationname,c.tenantid,b.tenantname,c.address,c.email,c.contactno,c.applocationid,c.suburb,c.city,c.latitude,c.longitude,c.postcode
FROM tenantcustomers a
Left join tenants b ON a.tenantid = b.tenantid
LEFT JOIN tenantlocations c ON a.locationid = c.locationid
WHERE a.customerid = ?
`
db.DB.Raw(query, customerID).Scan(&locations)
// print(customer, locations)
return models.CustomerTenantResponse{
Customer: customer,
Tenantlocations: locations,
}
}
func CreateTenantLocation(data models.Tenantlocations) error {
var user models.Tenantuser
tx := db.DB.Begin()
// 🔧 Set status BEFORE insert
data.Status = "InActive"
// Step 1: Insert into tenantlocations
if err := tx.Create(&data).Error; err != nil {
tx.Rollback()
return err
}
// Step 2: Insert into app_users
user.Authname = data.Email
user.Firstname = data.Locationname
user.Email = data.Email
user.Contactno = data.Contactno
user.Address = data.Address
user.Suburb = data.Suburb
user.City = data.City
user.State = data.State
user.Postcode = data.Postcode
user.Partnerid = data.Partnerid
user.Tenantid = data.Tenantid
user.Locationid = data.Locationid
user.Applocationid = data.Applocationid
user.Configid = 1
user.Status = "InActive"
user.Roleid = 0
user.Authmode = 0
user.Password = ""
user.Dialcode = "+91"
if err := tx.Table("app_users").Create(&user).Error; err != nil {
tx.Rollback()
return err
}
// Commit
if err := tx.Commit().Error; err != nil {
return err
}
return nil
}
func UpdateTenantLocation(input models.Tenantlocations) error {
tx := db.DB.Begin()
t1 := tx.Where("locationid=?", input.Locationid).Updates(&input)
if t1.Error != nil {
tx.Rollback()
return t1.Error
}
err := tx.Commit().Error
if err != nil {
return err
}
return nil
}
func FetchLocationSummary(tenantID int) models.LocationSummary {
var summary models.LocationSummary
db.DB.Raw(`
SELECT
SUM(CASE WHEN status = 'Active' THEN 1 ELSE 0 END) AS active_count,
SUM(CASE WHEN status = 'InActive' THEN 1 ELSE 0 END) AS inactive_count,
COUNT(*) AS total_count
FROM tenantlocations
WHERE tenantid = ?
`, tenantID).Scan(&summary)
return summary
}
func FetchTenantStaffSummary(tenantID int) models.TenantUserSummary {
var summary models.TenantUserSummary
query := `
SELECT
SUM(CASE WHEN a.status = 'Active' THEN 1 ELSE 0 END) AS active_count,
SUM(CASE WHEN b.status = 'InActive' THEN 1 ELSE 0 END) AS inactive_count,
COUNT(*) AS total_count
FROM tenantstaffs a
JOIN app_users b ON a.userid = b.userid
WHERE a.tenantid = ? AND b.roleid = 2
`
db.DB.Raw(query, tenantID).Scan(&summary)
return summary
}
func FetchTenantRiderSummary(tenantID int) models.TenantUserSummary {
var summary models.TenantUserSummary
query := `
SELECT
SUM(CASE WHEN a.status = 'Active' THEN 1 ELSE 0 END) AS active_count,
SUM(CASE WHEN a.status = 'InActive' THEN 1 ELSE 0 END) AS inactive_count,
COUNT(*) AS total_count
FROM tenantstaffs a
JOIN app_users b ON a.userid = b.userid
WHERE a.tenantid = ? AND b.roleid = 3
`
db.DB.Raw(query, tenantID).Scan(&summary)
return summary
}
func CreateTenantPromotion(promo *models.Tenantpromotions) error {
// convert []string to comma-separated string
if len(promo.Locationid) > 0 {
promo.LocationidStr = strings.Join(promo.Locationid, ",")
}
tx := db.DB.Begin()
if err := tx.Table("tenantpromotions").Create(promo).Error; err != nil {
tx.Rollback()
return err
}
return tx.Commit().Error
}
func GetTenantPromotions(tid int, lid string) []models.Tenantpromotions {
var result []models.Tenantpromotions
query := `
SELECT
promotionid, promotiontypeid, tenantid,
locationid, applocationid, moduleid, categoryid,
promoname, promocode, description, product, productimage,
promoamount, promovalue, purchasevalue, startdate, enddate
FROM tenantpromotions
WHERE tenantid = ?
AND moduleid = 2
AND FIND_IN_SET(?, locationid)
`
db.DB.Raw(query, tid, lid).Scan(&result)
// Convert location string → slice
for i := range result {
if result[i].LocationidStr != "" {
result[i].Locationid = strings.Split(result[i].LocationidStr, ",")
} else {
result[i].Locationid = []string{}
}
}
return result
}

457
domain/userDomain.go Normal file
View File

@@ -0,0 +1,457 @@
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
}

727
domain/utilsDomain.go Normal file
View File

@@ -0,0 +1,727 @@
package domain
import (
"context"
"errors"
"nearle/db"
"nearle/models"
"nearle/utils"
"net/http"
"strconv"
firebase "firebase.google.com/go"
"firebase.google.com/go/messaging"
"google.golang.org/api/option"
"gorm.io/gorm"
)
var (
firebaseApp *firebase.App
fcmClient *messaging.Client
)
func getFCMClient() (*messaging.Client, error) {
if fcmClient != nil {
return fcmClient, nil
}
opt := option.WithCredentialsFile("nearle-gear-firebase-adminsdk-l9oha-23ca3b3609.json")
app, err := firebase.NewApp(context.Background(), nil, opt)
if err != nil {
return nil, errors.New("error initializing firebase app: " + err.Error())
}
firebaseApp = app
client, err := app.Messaging(context.Background())
if err != nil {
return nil, errors.New("error getting messaging client: " + err.Error())
}
fcmClient = client
return fcmClient, nil
}
func GetApplocations(aid int) []models.Applocations {
var data []models.Applocations
var q1 string
if aid != 0 {
q1 = "Select * from app_location where status='Active' and applocationid=?"
db.DB.Raw(q1, aid).Find(&data)
} else {
q1 = "Select * from app_location where status='Active'"
db.DB.Raw(q1).Find(&data)
}
utils.Logger.Debugf("Query executed for aid: %d", aid)
return data
}
func GetApplocationsv2(userid int) []models.Applocations {
var data []models.Applocations
var q1 string
if userid != 0 {
q1 = `
SELECT b.*
FROM app_locationconfig a
INNER JOIN app_location b
ON a.applocationid = b.applocationid
WHERE b.status = 'Active'
AND a.userid = ?`
db.DB.Raw(q1, userid).Find(&data)
} else {
q1 = `
SELECT *
FROM app_location
WHERE status = 'Active'
`
db.DB.Raw(q1).Find(&data)
}
utils.Logger.Debugf("Query executed for userid: %d", userid)
return data
}
func GetApplocationConfig(aid int) models.Applocations {
var data models.Applocations
var q1, q2 string
if aid != 0 {
q1 = `Select * from app_location where status='Active' and applocationid=` + strconv.Itoa(aid)
q2 = `SELECT distinct a.userid,a.userfcmtoken,b.notify,b.applocationid,c.opentime,c.closetime
FROM app_users a
INNER JOIN app_locationconfig b ON a.userid=b.userid
INNER JOiN app_location c on a.applocationid= c.applocationid
WHERE b.notify='true' AND b.applocationid=` + strconv.Itoa(aid)
} else {
q1 = `Select * from app_location where status='Active'`
}
// print(q1)
// db.DB.Raw(q1).Preload("Applocationadmins").Find(&data)
db.DB.Raw(q1).Preload("Applocationadmins", func(db *gorm.DB) *gorm.DB {
return db.Raw(q2)
}).Find(&data)
return data
}
func GetAppPricing(aid, cid, pid int) []models.Apppricing {
var data []models.Apppricing
var q1 string
if aid != 0 {
q1 = `SELECT a.* FROM app_pricing a
JOIN (
SELECT pricingtypeid, MAX(pricingdate) AS maxpricingdate
FROM app_pricing
WHERE applocationid = ?
GROUP BY pricingtypeid
) AS maxpricing ON a.pricingtypeid = maxpricing.pricingtypeid AND a.pricingdate = maxpricing.maxpricingdate WHERE a.applocationid = ?`
db.DB.Raw(q1, aid, aid).Find(&data)
} else if cid != 0 {
q1 = `SELECT * FROM app_pricing WHERE pricingdate = (SELECT MAX(pricingdate) FROM app_pricing where configid= ?)`
db.DB.Raw(q1, cid).Find(&data)
}
// print(q1)
db.DB.Raw(q1).Find(&data)
return data
}
func CreateAppProcing(input models.Apppricing) bool {
err := db.DB.Table("app_pricing").Create(&input).Error
return err == nil
}
func GetAllAppPricing(aid int) []models.Apppricing {
var data []models.Apppricing
var q1 string
if aid != 0 {
q1 = `SELECT a.*,b.locationname as applocation, d.appname FROM app_pricing a
inner join app_location b on a.applocationid=b.applocationid
Inner Join app_types c on a.pricingtypeid=c.apptypeid
INNER JOIN app_config d ON a.configid=d.configid
where a.applocationid=? ORDER BY b.locationname ASC`
db.DB.Raw(q1, aid).Find(&data)
} else {
q1 = `SELECT a.*,b.locationname as applocation, d.appname FROM app_pricing a
inner join app_location b on a.applocationid=b.applocationid
Inner Join app_types c on a.pricingtypeid=c.apptypeid
INNER JOIN app_config d ON a.configid=d.configid ORDER BY b.locationname ASC`
db.DB.Raw(q1).Find(&data)
}
utils.Logger.Debugf("Query executed for aid: %d", aid)
return data
}
func GetApplocationadmins(aid int) []models.Applocationadmins {
var data []models.Applocationadmins
var q1 string
if aid != 0 {
q1 = `SELECT distinct a.userid,a.userfcmtoken,b.notify,b.applocationid,c.opentime,c.closetime
FROM app_users a
INNER JOIN app_locationconfig b ON a.userid=b.userid
INNER JOiN app_location c on a.applocationid= c.applocationid
WHERE b.notify='true' AND b.applocationid=?`
db.DB.Raw(q1, aid).Find(&data)
}
return data
}
func GetAppconfig(cid int) models.Appconfig {
var data models.Appconfig
var q1 string
if cid != 0 {
q1 = `SELECT a.configid,a.Appname,a.paymentdevkey,a.paymentlivekey,a.fcmkey,a.googleapikey,a.applocationradius,
b.providerid,b.providerapi,b.providerkey
FROM app_config a
LEFT JOIN smsproviders b ON a.smsproviderid=b.providerid
WHERE a.configid=?`
db.DB.Raw(q1, cid).Find(&data)
} else {
q1 = `SELECT a.configid,a.Appname,a.paymentdevkey,a.paymentlivekey,a.fcmkey,a.googleapikey,a.applocationradius,
b.providerid,b.providerapi,b.providerkey FROM app_config a
LEFT JOIN smsproviders b ON a.smsproviderid=b.providerid order by configid asc`
db.DB.Raw(q1).Find(&data)
}
utils.Logger.Debugf("Query executed for cid: %d", cid)
return data
}
func GetAllAppconfig() []models.Appconfig {
var data []models.Appconfig
q1 := `SELECT a.configid,a.Appname,a.paymentdevkey,a.paymentlivekey,a.fcmkey,a.googleapikey,a.applocationradius,
b.providerid,b.providerapi,b.providerkey FROM app_config a
LEFT JOIN smsproviders b ON a.smsproviderid=b.providerid order by configid asc`
db.DB.Raw(q1).Find(&data)
return data
}
func GetAppModule() []models.AppModule {
var data []models.AppModule
q1 := `SELECT * FROM app_module where status='Active'`
db.DB.Raw(q1).Find(&data)
return data
}
func GetApptypes(tag string) []models.Apptypes {
var data []models.Apptypes
q1 := "Select * from app_types where status ='Active' and tag=?"
db.DB.Raw(q1, tag).Find(&data)
return data
}
func GetSubcategories(moduleid int, categoryid int) []models.Appsubcategories {
var data []models.Appsubcategories
query := `
SELECT a.subcategoryid,a.categoryid,a.subcategoryname,b.categoryname,a.status,c.moduleid
FROM app_subcategory a
INNER JOIN app_category b ON a.categoryid = b.categoryid
INNER JOIN app_module c ON a.categoryid = c.categoryid
WHERE 1=1`
var params []interface{}
if moduleid != 0 {
query += " AND c.moduleid = ?"
params = append(params, moduleid)
}
if categoryid != 0 {
query += " AND a.categoryid = ?"
params = append(params, categoryid)
}
db.DB.Raw(query, params...).Scan(&data)
return data
}
func GetCategories(mid int) []models.AppCategory {
var data []models.AppCategory
if mid == 0 {
// No moduleid filter → return all categories
q := `
SELECT a.*, b.moduleid
FROM app_category a
INNER JOIN app_module b ON a.categoryid = b.categoryid
`
db.DB.Raw(q).Scan(&data)
} else {
// Filter by moduleid
q := `
SELECT a.*, b.moduleid
FROM app_category a
INNER JOIN app_module b ON a.categoryid = b.categoryid
WHERE b.moduleid = ?
`
db.DB.Raw(q, mid).Scan(&data)
}
return data
}
func Insertnotification(input models.Data) bool {
db.DB.Table("tenantnotifications").Create(&input)
return true
}
func SendLoginNotification(regid, accessid string, pin int) error {
if regid == "" {
return errors.New("no FCM token provided")
}
client, err := getFCMClient()
if err != nil {
return err
}
// Construct the notification payload
body := "Your passcode to Nearle app is: " + strconv.Itoa(pin) + "."
title := "Nearle Code"
// Prepare FCM message
message := &messaging.Message{
Notification: &messaging.Notification{
Title: title,
Body: body,
},
Token: regid,
Android: &messaging.AndroidConfig{
Priority: "high",
Notification: &messaging.AndroidNotification{
Sound: "ring",
},
},
}
// Send the FCM notification
response, err := client.Send(context.Background(), message)
if err != nil {
utils.Logger.Errorf("FCM send error: %v", err)
return errors.New("failed to send FCM: " + err.Error())
}
utils.Logger.Infof("Successfully sent message: %v", response)
return nil
}
func SendSingleNotification(regid, accessid string, Partner string) bool {
client, err := getFCMClient()
if err != nil {
utils.Logger.Errorf("getFCMClient error: %v", err)
return false
}
title := "Nearle Admin"
body := "Orders had been placed for delivery by " + Partner
message := &messaging.Message{
Notification: &messaging.Notification{
Title: title,
Body: body,
},
Token: regid,
Android: &messaging.AndroidConfig{
Priority: "high",
Notification: &messaging.AndroidNotification{
Sound: "ring",
},
},
}
response, err := client.Send(context.Background(), message)
if err != nil {
utils.Logger.Errorf("Error sending single notification: %v", err)
return false
}
utils.Logger.Infof("Successfully sent single message: %v", response)
return true
}
func NotifyUser(fcm models.NotifyUser) bool {
client, err := getFCMClient()
if err != nil {
utils.Logger.Errorf("getFCMClient error: %v", err)
return false
}
message := &messaging.Message{
Notification: &messaging.Notification{
Title: fcm.Notification.Notify.Title,
Body: fcm.Notification.Notify.Body,
},
Token: fcm.Notification.To,
Android: &messaging.AndroidConfig{
Priority: fcm.Notification.Priority,
Notification: &messaging.AndroidNotification{
Sound: fcm.Notification.Notify.Sound,
},
},
}
response, err := client.Send(context.Background(), message)
if err != nil {
utils.Logger.Errorf("Error notifying user: %v", err)
return false
}
utils.Logger.Infof("Successfully notified user: %v", response)
return true
}
func SendNotifications(fcm models.Notifications) bool {
client, err := getFCMClient()
if err != nil {
utils.Logger.Errorf("getFCMClient error: %v", err)
return false
}
successCount := 0
for _, token := range fcm.Registrationids {
if token == "" {
continue
}
message := &messaging.Message{
Notification: &messaging.Notification{
Title: fcm.Notify.Title,
Body: fcm.Notify.Body,
},
Token: token,
Android: &messaging.AndroidConfig{
Priority: fcm.Priority,
Notification: &messaging.AndroidNotification{
Sound: fcm.Notify.Sound,
},
},
}
_, err := client.Send(context.Background(), message)
if err != nil {
utils.Logger.Errorf("Error sending notification to token %s: %v", token, err)
continue
}
successCount++
}
utils.Logger.Infof("Successfully sent %d notifications out of %d", successCount, len(fcm.Registrationids))
return successCount > 0
}
func SendNotification(fcm models.Notifications, accessid string) models.Result {
var result models.Result
client, err := getFCMClient()
if err != nil {
utils.Logger.Errorf("getFCMClient error: %v", err)
result.Code = http.StatusInternalServerError
result.Message = "Error initializing FCM client"
result.Status = false
return result
}
// Assuming we send to the first registration ID if multiple provided
if len(fcm.Registrationids) == 0 {
result.Code = http.StatusBadRequest
result.Message = "No registration IDs provided"
result.Status = false
return result
}
message := &messaging.Message{
Notification: &messaging.Notification{
Title: fcm.Notify.Title,
Body: fcm.Notify.Body,
},
Token: fcm.Registrationids[0],
Android: &messaging.AndroidConfig{
Priority: fcm.Priority,
Notification: &messaging.AndroidNotification{
Sound: fcm.Notify.Sound,
},
},
}
response, err := client.Send(context.Background(), message)
if err != nil {
utils.Logger.Errorf("Error sending single notification: %v", err)
result.Code = http.StatusInternalServerError
result.Message = "Error sending notification: " + err.Error()
result.Status = false
return result
}
utils.Logger.Infof("Successfully sent notification: %v", response)
status := Insertnotification(fcm.Data)
if !status {
result.Code = http.StatusConflict
result.Message = "Notification sent but Insert UnSuccessfully"
result.Status = false
return result
}
result.Code = http.StatusCreated
result.Message = "Notification Sent and Inserted Successfully"
result.Status = true
return result
}
func Getconfigs(categoryid int) models.Appconfig {
var q1 string
var data models.Appconfig
q1 = `SELECT a.configid,a.appname,a.smsproviderid,COALESCE(a.fcmkey,'') AS fcmkey,COALESCE(a.clientid,'') AS clientid,COALESCE(a.googleapikey,'') AS googleapikey,COALESCE(a.paymentdevkey,'') AS paymentdevkey,COALESCE(a.paymentlivekey,'') AS paymentlivekey,a.applocationradius,COALESCE(b.providername,'') AS providername,COALESCE(b.providerapi,'') AS providerapi,COALESCE(b.providerkey,'') AS providerkey, COALESCE(b.username,'') AS username,COALESCE(b.passcode,'') AS passcode,COALESCE(b.defaultprovider,false) AS defaultprovider
FROM app_config a LEFT OUTER JOIN smsproviders b ON a.smsproviderid = b.providerid AND b.status='Active' WHERE a.configid=?`
db.DB.Raw(q1, categoryid).Find(&data)
return data
}
func UpdateSeqno(tid int, prefix string) error {
var field string
if prefix == "ORD" {
field = "orderseqno"
} else if prefix == "INV" {
field = "invoiceseqno"
} else {
return errors.New("invalid prefix: " + prefix)
}
result := db.DB.
Table("ordersequences").
Where("tenantid = ?", tid).
Update(field, gorm.Expr(field+" + 1"))
if result.Error != nil {
utils.Logger.Errorf("UpdateSeqno failed for tenantid %d, prefix %s: %v", tid, prefix, result.Error)
return result.Error
}
if result.RowsAffected == 0 {
utils.Logger.Infof("No rows updated for tenantid %d with prefix %s", tid, prefix)
return errors.New("no rows updated for tenantid " + strconv.Itoa(tid))
}
return nil
}
func GetSequenceno(tid int, prefix string) string {
type SeqResult struct {
Orderseqno string
}
var q1 string
if prefix == "ORD" {
q1 = `
SELECT COALESCE(CONCAT(tenantid, '-', subprefix, COALESCE(MAX(orderseqno) + 1, 1)), '') AS orderseqno
FROM ordersequences
WHERE tenantid = ?
GROUP BY tenantid, subprefix
`
} else if prefix == "INV" {
q1 = `
SELECT COALESCE(CONCAT(tenantid, '-', subprefix, COALESCE(MAX(invoiceseqno) + 1, 1)), '') AS orderseqno
FROM ordersequences
WHERE tenantid = ?
GROUP BY tenantid, subprefix
`
}
var result SeqResult
db.DB.Raw(q1, tid).Scan(&result)
return result.Orderseqno
}
func GetTenantNotifications(tenantid, locationid, customerid, moduleid, pageno, pagesize int) ([]models.TenantNotification, int) {
var data []models.TenantNotification
var total int
offset := (pageno - 1) * pagesize
baseQuery := db.DB.Table("tenantnotifications").
Select("*").
Where("tenantid = ?", tenantid)
if locationid != 0 {
baseQuery = baseQuery.Where("locationid = ?", locationid)
}
if customerid != 0 {
baseQuery = baseQuery.Where("customerid = ?", customerid)
}
if moduleid != 0 {
baseQuery = baseQuery.Where("moduleid = ?", moduleid)
}
err := baseQuery.
Order("notificationdate DESC").
Limit(pagesize).
Offset(offset).
Find(&data).Error
if err != nil {
utils.Logger.Errorf("DB Error GetTenantNotifications: %v", err)
}
return data, total
}
func GetUserBonusSummary(userid int) (models.Riderinfo, error) {
var user models.Riderinfo
query := `
SELECT COALESCE(SUM(a.bonuspts), 0) AS bonuspts,b.*
FROM deliveries a
LEFT JOIN app_users b ON a.userid = b.userid
WHERE a.userid = ?
GROUP BY b.userid
`
err := db.DB.Raw(query, userid).Scan(&user).Error
if err != nil {
return user, err
}
return user, nil
}
func CreateAppLocationConfig(input models.AppLocationConfigRequest) bool {
if input.Notify == "" {
input.Notify = "true"
}
if input.Status == "" {
input.Status = "Active"
}
for _, locID := range input.Applocationids {
data := models.AppLocationConfig{
Applocationid: locID,
Configid: input.Configid,
Userid: input.Userid,
Partnerid: input.Partnerid,
Notify: input.Notify,
Status: input.Status,
}
if err := db.DB.Table("app_locationconfig").Create(&data).Error; err != nil {
return false
}
}
return true
}
func UpdateAppLocationConfig(input models.AppLocationConfigRequest) bool {
if input.Status == "" {
input.Status = "Active"
}
for _, locID := range input.Applocationids {
if err := db.DB.Table("app_locationconfig").
Where("userid = ? AND applocationid = ?", input.Userid, locID).
Update("status", input.Status).Error; err != nil {
utils.Logger.Errorf("Error updating app_locationconfig: %v", err)
return false
}
}
return true
}
func GetUserRoles() ([]models.UserRoles, error) {
var roles []models.UserRoles
query := `SELECT * FROM app_roles
`
err := db.DB.Raw(query).Scan(&roles).Error
if err != nil {
return roles, err
}
return roles, nil
}