initial commit

This commit is contained in:
2026-05-25 11:52:26 +05:30
commit 0d42ac84e1
53 changed files with 11222 additions and 0 deletions

View File

@@ -0,0 +1,359 @@
package repositories
import (
"fmt"
"nearle/models"
"strings"
"gorm.io/gorm"
)
type CustomerRepository interface {
GetCustomer(cid int, cno string) (*models.CustomerInfo, error)
UpdateCustomer(input models.Customers) error
GetCustomerLocations(cid int) ([]models.Customerlocations, error)
CreateCustomerLocation(input models.Customerlocations) (int, error)
CreateCustomerRequest(req *models.CustomerRequest) error
GetCustomerRequests(customerID int, pageNo, pageSize int) ([]models.CustomerRequest, int64, error)
GetTenantCustomers(tid, lid, pageno, pagesize int, keyword string) []models.CustomerInfo
SearchCustomer(keyword string, tid int) []models.CustomerInfo
CheckCustomer(contactno string) int
CheckTenantCustomer(cid, tid int) int
CreateTenantCustomer(input models.Customers) int
CreateCustomer(input models.Customers) int
GetCustomerByContactNo(contactNo string) (*models.Customers, error)
}
type customerRepository struct {
db *gorm.DB
}
func NewCustomerRepository(db *gorm.DB) CustomerRepository {
return &customerRepository{db: db}
}
func (r *customerRepository) GetCustomer(cid int, cno string) (*models.CustomerInfo, error) {
var data models.CustomerInfo
q := `
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 AND b.primaryaddress=1
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 %s LIMIT 1
`
var err error
if cid != 0 {
err = r.db.Raw(fmt.Sprintf(q, "a.customerid = ?"), cid).Scan(&data).Error
} else {
err = r.db.Raw(fmt.Sprintf(q, "a.contactno = ?"), cno).Scan(&data).Error
}
if err != nil {
return nil, err
}
return &data, nil
}
func (r *customerRepository) UpdateCustomer(input models.Customers) error {
var custloc models.Customerlocations
tx := r.db.Begin()
if err := tx.Where("customerid=?", input.Customerid).Updates(&input).Error; err != nil {
tx.Rollback()
return err
}
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
if err := tx.Table("customerlocations").
Where("customerid=? and primaryaddress=?", input.Customerid, 1).
Updates(&custloc).Error; err != nil {
tx.Rollback()
return err
}
if err := tx.Commit().Error; err != nil {
fmt.Println("Commit failed:", err)
return err
}
return nil
}
func (r *customerRepository) GetCustomerLocations(cid int) ([]models.Customerlocations, error) {
var data []models.Customerlocations
if cid == 0 {
return data, nil
}
query := `SELECT a.locationid, a.customerid, b.applocationid, 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
LEFT JOIN customers b ON a.customerid = b.customerid
WHERE a.customerid = ?`
if err := r.db.Raw(query, cid).Scan(&data).Error; err != nil {
return nil, err
}
return data, nil
}
func (r *customerRepository) CreateCustomerLocation(input models.Customerlocations) (int, error) {
// Duplicate address checking
var count int
err := r.db.Raw(`
SELECT COUNT(*) FROM customerlocations
WHERE customerid = ?
AND address = ?
AND suburb = ?
AND city = ?
AND state = ?
AND postcode = ?
AND landmark = ?
AND doorno = ?
`, input.Customerid, input.Address, input.Suburb, input.City, input.State,
input.Postcode, input.Landmark, input.Doorno).
Scan(&count).Error
if err != nil {
return 0, err
}
if count > 0 {
// Duplicate found
return -1, nil
}
// Insert new address
if err := r.db.Create(&input).Error; err != nil {
return 0, err
}
return input.Customerid, nil
}
func (r *customerRepository) CreateCustomerRequest(req *models.CustomerRequest) error {
return r.db.Table("customerrequest").Create(req).Error
}
func (r *customerRepository) GetCustomerRequests(customerID, pageNo, pageSize int) ([]models.CustomerRequest, int64, error) {
var requests []models.CustomerRequest
var total int64
query := r.db.Table("customerrequest")
if customerID != 0 {
query = query.Where("customerid = ?", customerID)
}
query.Count(&total)
offset := (pageNo - 1) * pageSize
if err := query.Order("created desc").Offset(offset).Limit(pageSize).Find(&requests).Error; err != nil {
return nil, 0, err
}
return requests, total, nil
}
func (r *customerRepository) GetTenantCustomers(tid, lid, pageno, pagesize int, keyword string) []models.CustomerInfo {
var data []models.CustomerInfo
offset := (pageno - 1) * pagesize
var q1 string
var args []interface{}
searchLike := "%" + keyword + "%"
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
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 keyword != "" {
q1 += ` AND (a.firstname LIKE ? OR a.contactno LIKE ? OR b.suburb LIKE ?)`
args = append(args, searchLike, searchLike, searchLike)
}
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.locationid as tenantlocationid,a.status
FROM customers a
INNER JOIN tenantcustomers c ON a.customerid=c.customerid
WHERE c.tenantid = ?`
args = append(args, tid)
if keyword != "" {
searchLike := "%" + strings.ToLower(keyword) + "%"
q1 += ` AND (LOWER(a.firstname) LIKE ? OR LOWER(a.contactno) LIKE ? OR LOWER(a.suburb) LIKE ?)`
args = append(args, searchLike, searchLike, searchLike)
}
q1 += ` ORDER BY a.customerid DESC LIMIT ? OFFSET ?`
args = append(args, pagesize, offset)
}
print(q1)
r.db.Raw(q1, args...).Find(&data)
return data
}
func (r *customerRepository) SearchCustomer(keyword string, tid int) []models.CustomerInfo {
var data []models.CustomerInfo
searchLike := strings.ToLower(keyword) + "%"
var q1 string
var args []interface{}
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 = ? AND (LOWER(a.firstname) LIKE ? OR LOWER(a.contactno) LIKE ?)`
args = append(args, tid, searchLike, searchLike)
} 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.locationid as tenantlocationid,a.status
FROM customers a
INNER JOIN tenantcustomers c ON a.customerid=c.customerid
WHERE (LOWER(a.firstname) LIKE ? OR LOWER(a.contactno) LIKE ?)`
args = append(args, searchLike, searchLike)
}
r.db.Raw(q1, args...).Find(&data)
return data
}
func (r *customerRepository) CheckCustomer(contactno string) int {
var data models.Customers
q1 := `SELECT a.customerid FROM customers a WHERE a.contactno = ?`
r.db.Raw(q1, contactno).Find(&data)
return data.Customerid
}
func (r *customerRepository) CheckTenantCustomer(cid, tid int) int {
var data models.Customers
q1 := `SELECT a.customerid FROM tenantcustomers a WHERE a.customerid = ? AND a.tenantid = ?`
r.db.Raw(q1, cid, tid).Find(&data)
return data.Customerid
}
func (r *customerRepository) CreateTenantCustomer(input models.Customers) int {
var tcust models.Tenantcustomers
tcust.Customerid = input.Customerid
tcust.Tenantid = input.Tenantid
tx := r.db.Begin()
if err := tx.Table("tenantcustomers").Create(&tcust).Error; err != nil {
fmt.Println(err)
tx.Rollback()
return 0
}
tx.Commit()
return input.Customerid
}
func (r *customerRepository) CreateCustomer(input models.Customers) int {
var custloc models.Customerlocations
var tcust models.Tenantcustomers
tx := r.db.Begin()
if err := tx.Create(&input).Error; err != nil {
fmt.Println(err)
tx.Rollback()
return 0
}
custloc = models.Customerlocations{
Customerid: input.Customerid,
Address: input.Address,
Suburb: input.Suburb,
City: input.City,
State: input.State,
Postcode: input.Postcode,
Latitude: input.Latitude,
Longitude: input.Longitude,
Doorno: input.Doorno,
Landmark: input.Landmark,
Primaryaddress: 1,
}
if err := tx.Table("customerlocations").Create(&custloc).Error; err != nil {
fmt.Println(err)
tx.Rollback()
return 0
}
tcust = models.Tenantcustomers{
Customerid: input.Customerid,
Tenantid: input.Tenantid,
}
if err := tx.Table("tenantcustomers").Create(&tcust).Error; err != nil {
fmt.Println(err)
tx.Rollback()
return 0
}
tx.Commit()
return input.Customerid
}
func (r *customerRepository) GetCustomerByContactNo(contactNo string) (*models.Customers, error) {
var customer models.Customers
query := `
SELECT a.customerid, a.authmode, a.configid, a.deviceid, a.devicetype, a.customertoken,
a.firstname, a.lastname, a.contactno, a.profileimage, a.address, a.suburb,
a.city, a.state, a.landmark, a.doorno, a.postcode, a.latitude, a.longitude,
a.applocationid, a.status, a.profileimage, a.dialcode, a.intro,
b.tenantid, b.locationid,
c.qrmode
FROM customers a
INNER JOIN tenantcustomers b ON a.customerid = b.customerid
LEFT JOIN app_location c ON a.applocationid = c.applocationid
WHERE a.configid = 2 AND a.contactno = ?
`
if err := r.db.Raw(query, contactNo).Scan(&customer).Error; err != nil {
return nil, err
}
return &customer, nil
}

View File

@@ -0,0 +1,922 @@
package repositories
import (
"fmt"
"log"
"nearle/models"
"strconv"
"strings"
"github.com/jinzhu/copier"
"gorm.io/gorm"
)
type DeliveriesRepository interface {
CreateDeliveries(data []models.Deliveries) error
UpdateDelivery(data models.UpdateDeliveryStatus) error
GetDeliverySummary(tid, pid, uid, aid, lid int, fdate, tdate string) (models.DeliverySummary, error)
GetDeliveryInsight(tid int) ([]models.OrderInsightv1, error)
GetLocationDeliverySummary(tenantID int) ([]models.Ordersummarylocation, error)
GetReportSummary(tid, pid, uid, aid int, fdate, tdate string) ([]models.ReportSummary, error)
GetRiderSummary(aid, pid, tid int, fdate, tdate string) ([]models.Ridersummary, error)
GetTenantDeliveries(input models.DeliveryQuery) []models.Deliveryinfo
GetPartnerDeliveries(input models.DeliveryQuery) []models.Deliveryinfo
GetCustomerDeliveries(input models.DeliveryQuery) []models.Deliveryinfo
GetAdminDeliveries(input models.DeliveryQuery) []models.Deliveryinfo
GetUserDeliveries(input models.DeliveryQuery) []models.Deliveryinfo
GetAppUserDeliveries(input models.DeliveryQuery) []models.Deliveryinfo
GetDeliveries(input models.DeliveryQuery) []models.Deliveryinfo
GetDeliveryQueues(uid int, fdate, tdate string) ([]models.Deliveryinfo, error)
GetTenantLocationDeliveries(input models.DeliveryQuery) []models.Deliveryinfo
}
type deliveriesRepository struct {
db *gorm.DB
}
func NewDeliveriesRepository(db *gorm.DB) DeliveriesRepository {
return &deliveriesRepository{db: db}
}
const (
core = `SELECT COUNT(*) AS total,
SUM(CASE WHEN orderstatus = 'pending' THEN 1 ELSE 0 END) AS pending,
SUM(CASE WHEN orderstatus = 'accepted' THEN 1 ELSE 0 END) AS accepted,
SUM(CASE WHEN orderstatus = 'arrived' THEN 1 ELSE 0 END) AS arrived,
SUM(CASE WHEN orderstatus = 'picked' THEN 1 ELSE 0 END) AS picked,
SUM(CASE WHEN orderstatus = 'active' THEN 1 ELSE 0 END) AS active,
SUM(CASE WHEN orderstatus = 'delivered' THEN 1 ELSE 0 END) AS delivered,
SUM(CASE WHEN orderstatus = 'cancelled' THEN 1 ELSE 0 END) AS cancelled`
reports = `SELECT b.tenantid,b.tenantname,
COUNT(*) AS totalorders,
SUM(CASE WHEN a.orderstatus = 'created' THEN 1 ELSE 0 END) AS orderscreated,
SUM(CASE WHEN a.orderstatus = 'pending' THEN 1 ELSE 0 END) AS orderspending,
SUM(CASE WHEN a.orderstatus = 'cancelled' THEN 1 ELSE 0 END) AS orderscancelled,
SUM(CASE WHEN a.orderstatus = 'delivered' THEN 1 ELSE 0 END) AS orderscompleted,
SUM(CASE WHEN c.orderstatus = 'pending' THEN 1 ELSE 0 END) AS deliveriespending,
SUM(CASE WHEN c.orderstatus = 'delivered' THEN 1 ELSE 0 END) AS deliveriescompleted,
SUM(CASE WHEN c.orderstatus = 'cancelled' THEN 1 ELSE 0 END) AS deliveriescancelled,
SUM(CASE WHEN c.paymenttype = 64 THEN c.deliveryamt ELSE 0 END) AS paylater,
SUM(CASE WHEN c.paymenttype = 43 THEN c.deliveryamt ELSE 0 END) AS payondelivery,
ROUND(SUM(c.kms), 2) AS kms,
ROUND(SUM(c.actualkms), 2) AS actualkms,
SUM(c.deliveryamt) AS charges
FROM
tenants b
right JOIN orders a ON b.tenantid = a.tenantid
right JOIN deliveries c ON a.orderheaderid = c.orderheaderid `
Ridersummary = `SELECT a.userid, a.firstname, a.lastname,
CONCAT(a.firstname, ' ', a.lastname) AS fullname,a.status,
SUM(CASE WHEN b.orderstatus = 'pending' THEN 1 ELSE 0 END) AS deliveries,
SUM(CASE WHEN b.orderstatus = 'assigned' THEN 1 ELSE 0 END) AS assigned,
SUM(CASE WHEN b.orderstatus = 'accepted' THEN 1 ELSE 0 END) AS accepted,
SUM(CASE WHEN b.orderstatus = 'arrived' THEN 1 ELSE 0 END) AS arrived,
SUM(CASE WHEN b.orderstatus = 'picked' THEN 1 ELSE 0 END) AS picked,
SUM(CASE WHEN b.orderstatus = 'delivered' THEN 1 ELSE 0 END) AS delivered,
SUM(CASE WHEN b.orderstatus = 'delivered' THEN b.actualkms ELSE 0 END) AS actualkms,
SUM(CASE WHEN b.orderstatus = 'delivered' THEN b.kms ELSE 0 END) AS kms,
SUM(CASE WHEN b.paymenttype = 64 THEN b.deliveryamt ELSE 0 END) AS paylater,
SUM(CASE WHEN b.paymenttype = 43 THEN b.deliveryamt ELSE 0 END) AS payondelivery,
SUM(CASE WHEN b.orderstatus = 'delivered' THEN b.deliveryamt ELSE 0 END) AS deliveryamt
FROM app_users a
LEFT JOIN deliveries b ON a.userid = b.userid`
)
const (
deliveries = `SELECT distinct a.deliveryid,a.applocationid,f.locationname AS applocation,a.orderheaderid,a.configid,a.tenantid,a.partnerid,a.locationid,a.userid,a.categoryid,a.subcategoryid,a.moduleid,
a.orderid,a.deliverydate,a.orderstatus,a.assigntime,a.starttime,a.arrivaltime,a.pickuptime,a.deliverytime,a.canceltime,
a.customerid,a.pickupcustomer,a.pickupcontactno,a.pickuplocationid,a.pickupaddress,a.pickuplocation,a.pickuplat,a.pickuplon,
a.deliverycustomerid,a.deliverycustomer,a.deliverycontactno,a.deliverylocationid,a.deliveryaddress,a.deliverylocation,
a.droplat,a.droplon,a.deliverylat,a.deliverylong,
a.riderslat,a.riderslon,a.deliveryamt,a.kms,a.actualkms,a.riderkms,a.deliverycharges,a.deliverytype,a.paymenttype,a.smsdelivery,
a.expecteddeliverytime,a.profit,a.transitminutes,a.calculationdistancekm,
a.notes,a.ordernotes,b.tenantname,b.primarycontact as tenantcontactno,b.tenanttoken,b.suburb as tenantsuburb,b.city as tenantcity,
c.firstname AS ridername,c.userfcmtoken,e.locationname,e.suburb AS locationsuburb,e.contactno AS locationcontactno
FROM deliveries a
INNER JOIN tenants b ON a.tenantid=b.tenantid
INNER JOIN app_users c ON a.userid=c.userid
INNER JOIN tenantlocations e ON a.locationid=e.locationid
INNER JOIN app_location f ON a.applocationid = f.applocationid
INNER JOIN app_locationconfig g ON f.applocationid = g.applocationid`
)
func (r *deliveriesRepository) CreateDeliveries(data []models.Deliveries) error {
var que []models.Deliveryqueues
var ord models.Updateorderstatus
tx := r.db.Begin()
for i := range data {
if err := tx.Create(&data[i]).Error; err != nil {
tx.Rollback()
return err
}
if err := copier.Copy(&que, &data[i]); err != nil {
tx.Rollback()
return err
}
if err := tx.Create(&que).Error; err != nil {
tx.Rollback()
return err
}
ord.Orderstatus = data[i].Orderstatus
ord.Pending = data[i].Deliverydate
if err := tx.Table("orders").
Where("orderheaderid=?", data[i].Orderheaderid).
Updates(&ord).Error; err != nil {
tx.Rollback()
return err
}
}
if err := tx.Commit().Error; err != nil {
return err
}
return nil
}
func (r *deliveriesRepository) UpdateDelivery(data models.UpdateDeliveryStatus) error {
var ord models.Updateorderstatus
var cloc models.Customerlocations
tx := r.db.Begin()
if err := tx.Table("deliveries").Where("deliveryid = ?", data.Deliveryid).Updates(&data).Error; err != nil {
tx.Rollback()
return err
}
switch data.Orderstatus {
case "pending":
ord.Orderstatus = data.Orderstatus
ord.Pending = data.Assigntime
if err := tx.Table("orders").Where("orderheaderid = ?", data.Orderheaderid).Updates(&ord).Error; err != nil {
tx.Rollback()
return err
}
case "picked":
if data.Pickuplocationid != 0 && data.Deliverytype != "B" {
cloc.Latitude = data.Riderslat
cloc.Longitude = data.Riderslon
cloc.Address = data.Address
cloc.Suburb = data.Suburb
cloc.City = data.City
cloc.State = data.State
cloc.Postcode = data.Postcode
if err := tx.Table("customerlocations").Where("locationid = ?", data.Pickuplocationid).Updates(&cloc).Error; err != nil {
tx.Rollback()
return err
}
}
case "delivered":
ord.Orderstatus = data.Orderstatus
ord.Delivered = data.Deliverytime
if err := tx.Table("orders").Where("orderheaderid = ?", data.Orderheaderid).Updates(&ord).Error; err != nil {
tx.Rollback()
return err
}
if data.Deliverylocationid != 0 && data.Deliverytype != "B" {
cloc.Latitude = data.Deliverylat
cloc.Longitude = data.Deliverylong
cloc.Address = data.Address
cloc.Suburb = data.Suburb
cloc.City = data.City
cloc.State = data.State
cloc.Postcode = data.Postcode
if err := tx.Table("customerlocations").Where("locationid = ?", data.Deliverylocationid).Updates(&cloc).Error; err != nil {
tx.Rollback()
return err
}
}
case "cancelled":
ord.Orderstatus = data.Orderstatus
ord.Cancelled = data.Canceltime
if err := tx.Table("orders").Where("orderheaderid = ?", data.Orderheaderid).Updates(&ord).Error; err != nil {
tx.Rollback()
return err
}
}
if err := tx.Commit().Error; err != nil {
return err
}
return nil
}
func (r *deliveriesRepository) GetDeliverySummary(tid, pid, uid, aid, lid int, fdate, tdate string) (models.DeliverySummary, error) {
var data models.DeliverySummary
var q1 string
var params []interface{}
// Base query
q1 = core + " FROM deliveries WHERE configid = 1"
// Filters (allow multiple together)
if tid != 0 {
q1 += " AND tenantid = ?"
params = append(params, tid)
}
if pid != 0 {
q1 += " AND partnerid = ?"
params = append(params, pid)
}
if uid != 0 {
q1 += " AND userid = ?"
params = append(params, uid)
}
if aid != 0 {
q1 += " AND applocationid = ?"
params = append(params, aid)
}
if lid != 0 {
q1 += " AND locationid = ?"
params = append(params, lid)
}
// Date filter
if fdate != "" && tdate != "" {
q1 += " AND deliverydate::date BETWEEN ? AND ?"
params = append(params, fdate, tdate)
}
// Execute query
if err := r.db.Raw(q1, params...).Scan(&data).Error; err != nil {
return data, err
}
print(q1)
return data, nil
}
func (r *deliveriesRepository) GetDeliveryInsight(tenantID int) ([]models.OrderInsightv1, error) {
var locations []models.OrderInsightv1
var params []interface{}
// Base query for fetching active locations
q1 := `
SELECT DISTINCT l.locationid, l.locationname
FROM tenantlocations l
LEFT JOIN deliveries d ON l.locationid = d.locationid
WHERE l.status = 'Active'
`
// Add tenant filter if provided
if tenantID != 0 {
q1 += " AND l.tenantid = ?"
params = append(params, tenantID)
}
if err := r.db.Raw(q1, params...).Scan(&locations).Error; err != nil {
return nil, err
}
// Query for monthly deliveries
q2 := `
SELECT
COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM d.deliverydate) = 1 THEN 1 ELSE 0 END), 0) AS jan,
COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM d.deliverydate) = 2 THEN 1 ELSE 0 END), 0) AS feb,
COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM d.deliverydate) = 3 THEN 1 ELSE 0 END), 0) AS mar,
COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM d.deliverydate) = 4 THEN 1 ELSE 0 END), 0) AS apr,
COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM d.deliverydate) = 5 THEN 1 ELSE 0 END), 0) AS may,
COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM d.deliverydate) = 6 THEN 1 ELSE 0 END), 0) AS jun,
COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM d.deliverydate) = 7 THEN 1 ELSE 0 END), 0) AS jul,
COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM d.deliverydate) = 8 THEN 1 ELSE 0 END), 0) AS aug,
COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM d.deliverydate) = 9 THEN 1 ELSE 0 END), 0) AS sep,
COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM d.deliverydate) = 10 THEN 1 ELSE 0 END), 0) AS oct,
COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM d.deliverydate) = 11 THEN 1 ELSE 0 END), 0) AS nov,
COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM d.deliverydate) = 12 THEN 1 ELSE 0 END), 0) AS dece
FROM deliveries d
WHERE d.locationid = ?
AND EXTRACT(YEAR FROM d.deliverydate) = EXTRACT(YEAR FROM CURRENT_DATE)
`
if tenantID != 0 {
q2 += " AND d.tenantid = ?"
}
// Attach month-wise insights for each location
for i := range locations {
var orderMonths models.Ordermonths
var err error
if tenantID != 0 {
err = r.db.Raw(q2, locations[i].Locationid, tenantID).Scan(&orderMonths).Error
} else {
err = r.db.Raw(q2, locations[i].Locationid).Scan(&orderMonths).Error
}
if err != nil {
return nil, err
}
locations[i].Ordermonths = &orderMonths
}
return locations, nil
}
func (r *deliveriesRepository) GetLocationDeliverySummary(tenantID int) ([]models.Ordersummarylocation, error) {
var data []models.Ordersummarylocation
var params []interface{}
q1 := `
SELECT
b.locationid,
b.locationname,
COALESCE(COUNT(a.orderid), 0) AS total,
COALESCE(SUM(CASE WHEN a.orderstatus = 'created' THEN 1 ELSE 0 END), 0) AS created,
COALESCE(SUM(CASE WHEN a.orderstatus = 'pending' THEN 1 ELSE 0 END), 0) AS pending,
COALESCE(SUM(CASE WHEN a.orderstatus = 'processing' THEN 1 ELSE 0 END), 0) AS processing,
COALESCE(SUM(CASE WHEN a.orderstatus = 'delivered' THEN 1 ELSE 0 END), 0) AS delivered,
COALESCE(SUM(CASE WHEN a.orderstatus = 'cancelled' THEN 1 ELSE 0 END), 0) AS cancelled
FROM tenantlocations b
LEFT JOIN deliveries a
ON a.locationid = b.locationid
AND a.configid = 1
`
// ✅ Only filter tenant locations in WHERE
if tenantID != 0 {
q1 += " WHERE b.tenantid = ?"
params = append(params, tenantID)
}
q1 += " GROUP BY b.locationid, b.locationname ORDER BY b.locationid"
if err := r.db.Raw(q1, params...).Scan(&data).Error; err != nil {
return nil, err
}
return data, nil
}
func (r *deliveriesRepository) GetReportSummary(tid, pid, uid, aid int, fdate, tdate string) ([]models.ReportSummary, error) {
var data []models.ReportSummary
var q1 string
switch {
case tid != 0:
if fdate != "" && tdate != "" {
q1 = reports + ` WHERE a.tenantid=` + strconv.Itoa(tid) +
` AND a.orderdate::date BETWEEN '` + fdate + `' AND '` + tdate + `' GROUP BY a.tenantid, b.tenantname`
} else {
q1 = reports + ` WHERE a.tenantid=` + strconv.Itoa(tid) + ` GROUP BY a.tenantid, b.tenantname`
}
case pid != 0:
if fdate != "" && tdate != "" {
q1 = reports + ` WHERE a.partnerid=` + strconv.Itoa(pid) +
` AND a.orderdate::date BETWEEN '` + fdate + `' AND '` + tdate + `' GROUP BY a.tenantid, b.tenantname`
} else {
q1 = reports + ` WHERE a.partnerid=` + strconv.Itoa(pid) + ` GROUP BY a.tenantid, b.tenantname`
}
case uid != 0:
if fdate != "" && tdate != "" {
q1 = reports + ` WHERE c.userid=` + strconv.Itoa(uid) +
` AND a.orderdate::date BETWEEN '` + fdate + `' AND '` + tdate + `' GROUP BY a.tenantid, b.tenantname`
} else {
q1 = reports + ` WHERE c.userid=` + strconv.Itoa(uid) + ` GROUP BY a.tenantid, b.tenantname`
}
case aid != 0:
if fdate != "" && tdate != "" {
q1 = reports + ` WHERE c.applocationid=` + strconv.Itoa(aid) +
` AND a.orderdate::date BETWEEN '` + fdate + `' AND '` + tdate + `' GROUP BY a.tenantid, b.tenantname`
} else {
q1 = reports + ` WHERE c.applocationid=` + strconv.Itoa(aid) + ` GROUP BY a.tenantid, b.tenantname`
}
default:
if fdate != "" && tdate != "" {
q1 = reports + ` WHERE a.orderdate::date BETWEEN '` + fdate + `' AND '` + tdate + `' GROUP BY a.tenantid, b.tenantname`
} else {
q1 = reports + ` GROUP BY a.tenantid, b.tenantname`
}
}
if err := r.db.Raw(q1).Scan(&data).Error; err != nil {
return nil, err
}
return data, nil
}
func (r *deliveriesRepository) GetRiderSummary(aid, pid, tid int, fdate, tdate string) ([]models.Ridersummary, error) {
var data []models.Ridersummary
var q1 string
switch {
case aid != 0:
if fdate != "" && tdate != "" {
q1 = Ridersummary + ` WHERE a.configid=6 AND a.applocationid=` + strconv.Itoa(aid) +
` AND b.deliverydate::date BETWEEN '` + fdate + `' AND '` + tdate + `' GROUP BY a.userid, a.firstname, a.lastname`
} else {
q1 = Ridersummary + ` WHERE a.configid=6 AND a.applocationid=` + strconv.Itoa(aid) +
` GROUP BY a.userid, a.firstname, a.lastname`
}
case pid != 0:
if fdate != "" && tdate != "" {
q1 = Ridersummary + ` WHERE a.configid=6 AND a.partnerid=` + strconv.Itoa(pid) +
` AND b.deliverydate::date BETWEEN '` + fdate + `' AND '` + tdate + `' GROUP BY a.userid, a.firstname, a.lastname`
} else {
q1 = Ridersummary + ` WHERE a.configid=6 AND a.partnerid=` + strconv.Itoa(pid) +
` GROUP BY a.userid, a.firstname, a.lastname`
}
case tid != 0:
if fdate != "" && tdate != "" {
q1 = Ridersummary + ` WHERE a.configid=6 AND b.tenantid=` + strconv.Itoa(tid) +
` AND b.deliverydate::date BETWEEN '` + fdate + `' AND '` + tdate + `' GROUP BY a.userid, a.firstname, a.lastname`
} else {
q1 = Ridersummary + ` WHERE a.configid=6 AND b.tenantid=` + strconv.Itoa(tid) +
` GROUP BY a.userid, a.firstname, a.lastname`
}
default:
if fdate != "" && tdate != "" {
q1 = Ridersummary + ` WHERE a.configid=6 AND b.deliverydate::date BETWEEN '` + fdate + `' AND '` + tdate + `' GROUP BY a.userid, a.firstname, a.lastname`
} else {
q1 = Ridersummary + ` WHERE a.configid=6 GROUP BY a.userid, a.firstname, a.lastname`
}
}
if err := r.db.Raw(q1).Scan(&data).Error; err != nil {
return nil, err
}
return data, nil
}
func (r *deliveriesRepository) GetTenantDeliveries(input models.DeliveryQuery) []models.Deliveryinfo {
fmt.Println("🔍 Fetching Tenant Deliveries")
var data []models.Deliveryinfo
var queryBuilder strings.Builder
var params []interface{}
offset := (input.Pageno - 1) * input.Pagesize
baseQuery := `
SELECT a.*, b.tenantname, c.firstname AS ridername, c.contactno AS ridercontact
FROM deliveries a
JOIN tenants b ON a.tenantid = b.tenantid
JOIN app_users c ON a.userid = c.userid
WHERE a.tenantid = ?
`
queryBuilder.WriteString(baseQuery)
params = append(params, input.Tenantid)
if input.Status != "" {
queryBuilder.WriteString(" AND a.orderstatus = ?")
params = append(params, input.Status)
}
if input.Fromdate != "" && input.ToDate != "" {
queryBuilder.WriteString(" AND a.deliverydate::date BETWEEN ? AND ?")
params = append(params, input.Fromdate, input.ToDate)
}
if input.Keyword != "" {
k := "%" + input.Keyword + "%"
queryBuilder.WriteString(`
AND (
a.pickupcustomer LIKE ? OR
a.deliverycustomer LIKE ? OR
a.pickupcontactno LIKE ? OR
a.deliverycontactno LIKE ? OR
a.orderid LIKE ?
)
`)
for i := 0; i < 5; i++ {
params = append(params, k)
}
}
queryBuilder.WriteString(" ORDER BY a.deliveryid DESC")
if input.Pagesize != 0 {
queryBuilder.WriteString(" LIMIT ? OFFSET ?")
params = append(params, input.Pagesize, offset)
}
query := queryBuilder.String()
fmt.Println("Final query:", query)
fmt.Println("Params:", params)
r.db.Raw(query, params...).Scan(&data)
return data
}
func (r *deliveriesRepository) GetPartnerDeliveries(input models.DeliveryQuery) []models.Deliveryinfo {
fmt.Println("🔍 Fetching Partner Deliveries")
var data []models.Deliveryinfo
var queryBuilder strings.Builder
var params []interface{}
offset := (input.Pageno - 1) * input.Pagesize
queryBuilder.WriteString(deliveries + ` WHERE a.partnerid = ?`)
params = append(params, input.Partnerid)
if input.Status != "" {
queryBuilder.WriteString(" AND a.orderstatus = ?")
params = append(params, input.Status)
}
if input.Fromdate != "" && input.ToDate != "" {
queryBuilder.WriteString(" AND a.deliverydate::date BETWEEN ? AND ?")
params = append(params, input.Fromdate, input.ToDate)
}
queryBuilder.WriteString(" ORDER BY a.deliveryid DESC")
if input.Pagesize > 0 {
queryBuilder.WriteString(" LIMIT ? OFFSET ?")
params = append(params, input.Pagesize, offset)
}
finalQuery := queryBuilder.String()
log.Println("Final Partner Query:", finalQuery, "Params:", params)
r.db.Raw(finalQuery, params...).Scan(&data)
return data
}
func (r *deliveriesRepository) GetCustomerDeliveries(input models.DeliveryQuery) []models.Deliveryinfo {
fmt.Println("🔍 Fetching Customer Deliveries")
var data []models.Deliveryinfo
var queryBuilder strings.Builder
var params []interface{}
offset := (input.Pageno - 1) * input.Pagesize
queryBuilder.WriteString(deliveries + ` WHERE a.customerid = ?`)
params = append(params, input.Customerid)
if input.Partnerid != 0 {
queryBuilder.WriteString(" AND a.partnerid = ?")
params = append(params, input.Partnerid)
}
if input.Status != "" {
queryBuilder.WriteString(" AND a.orderstatus = ?")
params = append(params, input.Status)
}
if input.Fromdate != "" && input.ToDate != "" {
queryBuilder.WriteString(" AND a.deliverydate::date BETWEEN ? AND ?")
params = append(params, input.Fromdate, input.ToDate)
}
if input.Keyword != "" {
k := "%" + input.Keyword + "%"
queryBuilder.WriteString(` AND (
a.pickupcustomer LIKE ? OR
a.deliverycustomer LIKE ? OR
a.pickupcontactno LIKE ? OR
a.deliverycontactno LIKE ? OR
a.orderid LIKE ?
)`)
for i := 0; i < 5; i++ {
params = append(params, k)
}
}
queryBuilder.WriteString(" ORDER BY a.deliveryid DESC")
if input.Pagesize != 0 {
queryBuilder.WriteString(" LIMIT ? OFFSET ?")
params = append(params, input.Pagesize, offset)
}
query := queryBuilder.String()
fmt.Println("Final query:", query)
fmt.Println("Params:", params)
r.db.Raw(query, params...).Scan(&data)
return data
}
func (r *deliveriesRepository) GetAdminDeliveries(input models.DeliveryQuery) []models.Deliveryinfo {
fmt.Println("Admin Deliveries")
var data []models.Deliveryinfo
var queryBuilder strings.Builder
var params []interface{}
offset := (input.Pageno - 1) * input.Pagesize
queryBuilder.WriteString(`
SELECT a.*, b.tenantname, c.firstname as ridername
FROM deliveries a
JOIN tenants b ON a.tenantid = b.tenantid
JOIN app_users c ON c.userid = a.userid
WHERE a.applocationid = ?
`)
params = append(params, input.Applocationid)
if input.Status != "" {
queryBuilder.WriteString(" AND a.orderstatus = ?")
params = append(params, input.Status)
}
if input.Fromdate != "" && input.ToDate != "" {
queryBuilder.WriteString(" AND a.deliverydate::date BETWEEN ? AND ?")
params = append(params, input.Fromdate, input.ToDate)
}
if input.Keyword != "" {
k := "%" + input.Keyword + "%"
queryBuilder.WriteString(`
AND (
a.pickupcustomer LIKE ? OR
b.tenantname LIKE ? OR
a.deliverycustomer LIKE ? OR
a.pickupcontactno LIKE ? OR
a.deliverycontactno LIKE ? OR
a.orderid LIKE ?
)
`)
for i := 0; i < 6; i++ {
params = append(params, k)
}
}
queryBuilder.WriteString(" ORDER BY a.deliveryid DESC")
if input.Pagesize > 0 {
queryBuilder.WriteString(" LIMIT ? OFFSET ?")
params = append(params, input.Pagesize, offset)
}
finalQuery := queryBuilder.String()
log.Println("AdminDeliveries query:", finalQuery)
log.Println("Params:", params)
r.db.Raw(finalQuery, params...).Scan(&data)
return data
}
func (r *deliveriesRepository) GetUserDeliveries(input models.DeliveryQuery) []models.Deliveryinfo {
var q1 string
offset := (input.Pageno - 1) * input.Pagesize
var data []models.Deliveryinfo
if input.Status != "" {
if input.Pagesize != 0 {
fmt.Println("Rider Deliveriesv2")
q1 = deliveries + ` where a.userid=` + strconv.Itoa(input.UserID) + ` and a.orderstatus='` + input.Status + `'
and a.deliverydate::date between '` + input.Fromdate + `' and '` + input.ToDate + `' order by deliveryid
desc LIMIT ` + strconv.Itoa(input.Pagesize) + ` OFFSET ` + strconv.Itoa(offset)
} else {
fmt.Println("Rider Deliveriesv1")
q1 = deliveries + ` where a.userid=` + strconv.Itoa(input.UserID) + ` and a.orderstatus='` + input.Status + `'
and a.deliverydate::date between '` + input.Fromdate + `' and '` + input.ToDate + `' order by deliveryid asc`
}
} else {
if input.Pagesize != 0 {
fmt.Println("Rider Deliveriesv2")
q1 = deliveries + ` where a.orderstatus in ('accepted','arrived','picked') and a.userid=` + strconv.Itoa(input.UserID) + ` and
a.deliverydate::date between '` + input.Fromdate + `' and '` + input.ToDate + `' order by deliveryid
desc LIMIT ` + strconv.Itoa(input.Pagesize) + ` OFFSET ` + strconv.Itoa(offset)
} else {
fmt.Println("Rider Deliveriesv1")
q1 = deliveries + ` where a.orderstatus in ('accepted','arrived','picked') and a.userid=` + strconv.Itoa(input.UserID) + ` and
a.deliverydate::date between '` + input.Fromdate + `' and '` + input.ToDate + `' order by deliveryid desc`
}
}
r.db.Raw(q1).Find(&data)
return data
}
func (r *deliveriesRepository) GetAppUserDeliveries(input models.DeliveryQuery) []models.Deliveryinfo {
var data []models.Deliveryinfo
fmt.Println("Appsuser Deliveries -new")
var q1 string
offset := (input.Pageno - 1) * input.Pagesize
q1 = deliveries + ` WHERE g.status = 'Active' AND g.userid=` + strconv.Itoa(input.Appuserid)
if input.Status != "" {
q1 += ` AND a.orderstatus='` + input.Status + `'`
}
if input.Fromdate != "" && input.ToDate != "" {
q1 += ` AND a.deliverydate::date BETWEEN '` + input.Fromdate + `' AND '` + input.ToDate + `'`
}
if input.Keyword != "" {
k := "%" + input.Keyword + "%"
q1 += ` AND (
a.pickupcustomer LIKE '` + k + `' OR
b.tenantname LIKE '` + k + `' OR
a.deliverycustomer LIKE '` + k + `' OR
a.pickupcontactno LIKE '` + k + `' OR
a.deliverycontactno LIKE '` + k + `' OR
CAST(a.orderid AS TEXT) LIKE '` + k + `'
)`
}
q1 += ` ORDER BY a.deliveryid DESC`
if input.Pagesize != 0 {
q1 += ` LIMIT ` + strconv.Itoa(input.Pagesize) + ` OFFSET ` + strconv.Itoa(offset)
}
log.Println("Final Query:", q1)
r.db.Raw(q1).Find(&data)
return data
}
func (r *deliveriesRepository) GetDeliveries(input models.DeliveryQuery) []models.Deliveryinfo {
var data []models.Deliveryinfo
var queryBuilder strings.Builder
var params []interface{}
offset := (input.Pageno - 1) * input.Pagesize
baseQuery := `
SELECT a.*, b.tenantname, c.firstname as ridername, c.contactno as ridercontact, d.customertoken
FROM deliveries a
JOIN tenants b ON a.tenantid = b.tenantid
Join app_users c ON a.userid = c.userid
JOIN customer d ON a.deliverycustomerid = d.customerid
WHERE 1=1
`
queryBuilder.WriteString(baseQuery)
if input.Fromdate != "" && input.ToDate != "" {
queryBuilder.WriteString(" AND a.deliverydate::date BETWEEN ? AND ?")
params = append(params, input.Fromdate, input.ToDate)
}
if input.Status != "" {
queryBuilder.WriteString(" AND a.orderstatus = ?")
params = append(params, input.Status)
}
if input.Keyword != "" {
k := "%" + input.Keyword + "%"
queryBuilder.WriteString(`
AND (
a.pickupcustomer LIKE ? OR
b.tenantname LIKE ? OR
a.deliverycustomer LIKE ? OR
a.pickupcontactno LIKE ? OR
a.deliverycontactno LIKE ? OR
a.orderid LIKE ?
)
`)
for i := 0; i < 6; i++ {
params = append(params, k)
}
}
queryBuilder.WriteString(" ORDER BY a.deliveryid DESC")
if input.Pagesize != 0 {
queryBuilder.WriteString(" LIMIT ? OFFSET ?")
params = append(params, input.Pagesize, offset)
}
query := queryBuilder.String()
log.Println("Final query:", query)
log.Println("With params:", params)
r.db.Raw(query, params...).Scan(&data)
return data
}
func (r *deliveriesRepository) GetDeliveryQueues(uid int, fdate, tdate string) ([]models.Deliveryinfo, error) {
var data []models.Deliveryinfo
var q1 string
if fdate != "" && tdate != "" {
q1 = deliveries + `
WHERE a.orderstatus='pending'
AND a.userid=?
AND DATE(a.deliverydate) BETWEEN ? AND ?
ORDER BY a.deliveryid ASC`
if err := r.db.Raw(q1, uid, fdate, tdate).Find(&data).Error; err != nil {
return nil, err
}
} else {
q1 = deliveries + `
WHERE a.orderstatus='pending'
AND a.userid=?
AND DATE(a.deliverydate)=CURDATE()
ORDER BY a.deliveryid ASC`
if err := r.db.Raw(q1, uid).Find(&data).Error; err != nil {
return nil, err
}
}
return data, nil
}
func (r *deliveriesRepository) GetTenantLocationDeliveries(input models.DeliveryQuery) []models.Deliveryinfo {
var data []models.Deliveryinfo
var params []interface{}
var qb strings.Builder
offset := (input.Pageno - 1) * input.Pagesize
qb.WriteString(`
SELECT a.*, b.tenantname, c.firstname AS ridername,
c.contactno AS ridercontact, d.customertoken
FROM deliveries a
JOIN tenants b ON a.tenantid = b.tenantid
JOIN app_users c ON a.userid = c.userid
JOIN customers d ON a.deliverycustomerid = d.customerid
WHERE a.tenantid = ? AND a.locationid = ?
`)
params = append(params, input.Tenantid, input.Locationid)
if input.Fromdate != "" && input.ToDate != "" {
qb.WriteString(" AND DATE(a.deliverydate) BETWEEN ? AND ?")
params = append(params, input.Fromdate, input.ToDate)
}
if input.Status != "" {
qb.WriteString(" AND a.orderstatus = ?")
params = append(params, input.Status)
}
if input.Keyword != "" {
like := "%" + input.Keyword + "%"
qb.WriteString(`
AND (
a.pickupcustomer LIKE ? OR
b.tenantname LIKE ? OR
a.deliverycustomer LIKE ? OR m
a.pickupcontactno LIKE ? OR
a.deliverycontactno LIKE ? OR
a.orderid LIKE ?
)
`)
for i := 0; i < 6; i++ {
params = append(params, like)
}
}
qb.WriteString(" ORDER BY a.deliveryid DESC")
if input.Pagesize != 0 {
qb.WriteString(" LIMIT ? OFFSET ?")
params = append(params, input.Pagesize, offset)
}
query := qb.String()
log.Println("Tenant+Location Query:", query)
log.Println("Params:", params)
r.db.Raw(query, params...).Scan(&data)
return data
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,199 @@
package repositories
import (
"fmt"
"nearle/models"
"strconv"
"gorm.io/gorm"
)
type PartnerRepository interface {
GetActiveRiders(partnerid, aid, uid, tid int) ([]models.RiderInfo, error)
GetPartners(aid, pid, uid int) ([]models.Partnerinfo, error)
GetRiderShifts(aid int) ([]models.Ridershifts, error)
GetLocationConfig(uid, cid int) ([]models.Locationconfigs, error)
GetRiderLogs(pid, aid int, fdate, tdate string) ([]models.RiderlogDetails, error)
GetRiderInfo(userid int) (models.RiderInfo, error)
}
type partnerRepository struct {
db *gorm.DB
}
func NewPartnerRepository(db *gorm.DB) PartnerRepository {
return &partnerRepository{db: db}
}
func (r *partnerRepository) GetActiveRiders(partnerid, aid, uid, tid int) ([]models.RiderInfo, error) {
var data []models.RiderInfo
var q1 string
const riders = `SELECT DISTINCT b.poolid, a.userid, a.firstname, a.lastname,CONCAT(a.firstname, ' ', a.lastname) AS fullname,a.contactno, a.userfcmtoken, a.partnerid, a.applocationid,
c.identificationno, c.registrationno, c.licenseno, c.vehiclename, c.vehicleno,d.shiftid, d.starttime, d.endtime, d.shifthours, d.basefare, d.fuelcharge,e.logdate,
e.login, e.logout, e.workhours, e.shorthours, e.logstatus, a.status,f.locationname AS applocation
FROM app_users a
INNER JOIN app_userpools b ON a.userid = b.userid
INNER JOIN ridersettings c ON a.userid = c.userid
INNER JOIN ridershifts d ON c.shiftid = d.shiftid
INNER JOIN (
SELECT r1.*
FROM riderlogs r1
INNER JOIN (
SELECT userid, MAX(logdate) AS max_logdate
FROM riderlogs
WHERE logdate::date = CURRENT_DATE
GROUP BY userid
) r2 ON r1.userid = r2.userid AND r1.logdate = r2.max_logdate
) e ON a.userid = e.userid
INNER JOIN app_location f ON a.applocationid = f.applocationid
INNER JOIN app_locationconfig g ON g.applocationid = f.applocationid`
if aid != 0 {
q1 = riders + ` WHERE a.configid = 6 AND a.status = 'Active' AND b.onduty = 1
AND e.logdate::date = CURRENT_DATE AND e.logstatus = 0 AND a.applocationid = ` + strconv.Itoa(aid)
} else if partnerid != 0 {
q1 = riders + ` WHERE a.configid = 6 AND a.status = 'Active' AND b.onduty = 1
AND e.logdate::date = CURRENT_DATE AND e.logstatus = 0 AND a.partnerid = ` + strconv.Itoa(partnerid)
} else if tid != 0 {
q1 = riders + ` WHERE a.configid = 6 AND a.status = 'Active' AND b.onduty = 1
AND e.logdate::date = CURRENT_DATE AND e.logstatus = 0 AND a.tenantid = ` + strconv.Itoa(tid)
} else {
q1 = riders + ` WHERE g.status = 'Active' AND a.configid = 6 AND a.status = 'Active'
AND b.onduty = 1 AND e.logdate::date = CURRENT_DATE AND e.logstatus = 0 AND g.userid = ` + strconv.Itoa(uid)
}
err := r.db.Raw(q1).Find(&data).Error
if err != nil {
return nil, err
}
return data, nil
}
func (r *partnerRepository) GetPartners(aid, pid, uid int) ([]models.Partnerinfo, error) {
var data []models.Partnerinfo
var q1 string
var args []interface{}
if pid != 0 {
q1 = `select partnerid,applocationid,partnertypeid,partnername,primarycontact,primaryemail,
contactno,address,suburb,state,city,partnerimage
from partnerinfo where status='Active' and partnerid=?`
args = append(args, pid)
} else if aid != 0 {
q1 = `select partnerid,applocationid,partnertypeid,partnername,primarycontact,primaryemail,
contactno,address,suburb,state,city,partnerimage
from partnerinfo where status='Active' and applocationid=?`
args = append(args, aid)
} else {
q1 = `select partnerid,applocationid,partnertypeid,partnername,primarycontact,primaryemail,
contactno,address,suburb,state,city,partnerimage
from partnerinfo where status='Active'`
}
err := r.db.Raw(q1, args...).Find(&data).Error
if err != nil {
return nil, err
}
print(q1)
return data, nil
}
func (r *partnerRepository) GetRiderShifts(aid int) ([]models.Ridershifts, error) {
var data []models.Ridershifts
q1 := `Select a.*,concat(a.starttime,'-',a.endtime) as shiftname from ridershifts a where a.applocationid=` + strconv.Itoa(aid)
err := r.db.Raw(q1).Find(&data).Error
if err != nil {
return nil, err
}
print(q1)
return data, nil
}
func (r *partnerRepository) GetLocationConfig(uid, cid int) ([]models.Locationconfigs, error) {
var data []models.Locationconfigs
q1 := fmt.Sprintf(`SELECT a.applocationid,a.locationname FROM app_location a
inner join app_locationconfig b ON a.applocationid=b.applocationid
WHERE b.status='Active' and b.userid=%d`, uid)
err := r.db.Raw(q1).Find(&data).Error
if err != nil {
return nil, err
}
print(q1)
return data, nil
}
func (r *partnerRepository) GetRiderLogs(pid, aid int, fdate, tdate string) ([]models.RiderlogDetails, error) {
var data []models.RiderlogDetails
var args []interface{}
baseQuery := `
SELECT a.*, b.*, CONCAT(b.firstname,' ',b.lastname) AS username,
COALESCE(SUM(c.breakhours),0) AS breakhours
FROM riderlogs a
INNER JOIN app_users b ON a.userid = b.userid
LEFT JOIN riderbreaks c ON a.logid = c.logid AND a.userid = c.userid
WHERE 1=1
`
if pid != 0 {
baseQuery += " AND a.partnerid = ?"
args = append(args, pid)
}
if aid != 0 {
baseQuery += " AND b.applocationid = ?"
args = append(args, aid)
}
if fdate != "" && tdate != "" {
baseQuery += " AND logdate::date BETWEEN ? AND ?"
args = append(args, fdate, tdate)
} else {
baseQuery += " AND a.logdate::date = CURRENT_DATE"
}
baseQuery += " GROUP BY a.userid ORDER BY logid ASC"
if err := r.db.Raw(baseQuery, args...).Find(&data).Error; err != nil {
return nil, err
}
return data, nil
}
func (r *partnerRepository) GetRiderInfo(userid int) (models.RiderInfo, error) {
var data models.RiderInfo
q1 := `SELECT a.userid,a.firstname,a.lastname, CONCAT(a.firstname,' ',a.lastname) as fullname,
a.partnerid,a.configid,a.contactno,
a.address,a.suburb,a.city,a.state,a.postcode,a.latitude,a.longitude,
b.identificationno,b.vehicleno,b.vehiclename,b.licenseno,b.insuranceno,b.insurancedate,
c.shiftid,c.starttime,c.endtime,c.shifthours,c.basefare,c.additionalcharges,c.orders,c.fuelcharge,a.status,
a.applocationid,d.locationname as applocation,d.logseconds
FROM app_users a
INNER JOIN ridersettings b ON a.userid=b.userid
INNER JOIN ridershifts c ON b.shiftid=c.shiftid
INNER JOIN app_location d ON a.applocationid=d.applocationid
WHERE a.userid = ?`
if err := r.db.Raw(q1, userid).Scan(&data).Error; err != nil {
return models.RiderInfo{}, err
}
return data, nil
}

View File

@@ -0,0 +1,747 @@
package repositories
import (
"fmt"
"strconv"
"strings"
"time"
"nearle/models"
"gorm.io/gorm"
"gorm.io/gorm/clause"
)
type ProductRepository interface {
GetProductSubCategory(categoryID, tenantID int) ([]models.ProductSubCategory, error)
GetProductCount(tenantID, categoryID, subcategoryID int, approve string) ([]models.Productcount, error)
GetProductCategory() ([]models.ProductCategory, error)
GetProductVariants(tenantID, subcategoryID int) ([]models.Productvariant, error)
GetCatalougeProducts(tenantID, locationID, subcategoryID, pageno, pagesize int, keyword string) ([]models.Products, error)
GetProductStocks(tenantID, locationID string) ([]models.Productstocks, error)
CreateProductStock(stocks []models.Productstock) error
UpdateProductStatus(productIDs []int, status string) error
CreateProduct(product models.Products) error
UpdateProduct(product models.Products) error
DeleteProduct(productID int) error
GetStockStatement(tenantID, locationID, subcategoryID, pageno, pagesize int, keyword string) ([]models.Productstockstatement, error)
GetLocationProducts(tenantID, locationID, subcategoryID, pageno, pagesize int, keyword string) ([]models.Locationproducts, error)
GetLocationProductSummary(tenantID, locationID int) ([]models.ProductSummary, error)
FetchFilteredProducts(categoryID, subcategoryID, productID, applocationID, tenantID, locationID int, keyword, productStatus, approve string, pageno, pagesize int) ([]models.Tenantproducts, error)
GetProductByVariant(tenantid, variantid int) ([]models.Products, error)
GetSubcategories(categoryID int) ([]models.Subcategory, error)
GetProducts(params models.ProductFilter) ([]models.Products, error)
GetTenantInfo(tenantID, applocationID int) (map[string]interface{}, error)
UpdateProductLocation(input models.Productlocations) error
CreateProductLocation(input []models.Productlocations) error
CreateProductVariant(input models.Productvariant) error
}
type productRepository struct {
db *gorm.DB
}
func NewProductRepository(db *gorm.DB) ProductRepository {
return &productRepository{db: db}
}
func (r *productRepository) GetProductSubCategory(categoryID, tenantID int) ([]models.ProductSubCategory, error) {
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)
}
if err := r.db.Raw(query.String(), args...).Scan(&data).Error; err != nil {
return nil, err
}
// print()
return data, nil
}
func (r *productRepository) 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 := r.db.Raw(baseQuery, params...).Scan(&data).Error; err != nil {
return nil, err
}
print(baseQuery)
return data, nil
}
func (r *productRepository) GetProductCategory() ([]models.ProductCategory, error) {
var data []models.ProductCategory
q1 := `SELECT * FROM productcategories WHERE moduleid = 2 AND status = 'Active'`
r.db.Raw(q1).Scan(&data)
print(q1)
return data, nil
}
func (r *productRepository) GetProductVariants(tenantID int, subcategoryID int) ([]models.Productvariant, error) {
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)
}
r.db.Raw(query, params...).Scan(&data)
//print(query)
return data, nil
}
func (r *productRepository) GetCatalougeProducts(tenantID, locationID, subcategoryID, pageno, pagesize int, keyword string) ([]models.Products, error) {
var data []models.Products
if pageno < 1 {
pageno = 1
}
if pagesize < 1 {
pagesize = 10
}
offset := (pageno - 1) * pagesize
params := []interface{}{locationID, tenantID}
// Base query
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
`
// Optional filters
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)+"%")
}
// Pagination
query += " ORDER BY a.productid DESC LIMIT " + strconv.Itoa(pagesize) + " OFFSET " + strconv.Itoa(offset)
// Debug logs
fmt.Println("Executing query:", query)
fmt.Println("Params:", params)
// Execute query
if err := r.db.Raw(query, params...).Scan(&data).Error; err != nil {
return nil, err
}
return data, nil
}
func (r *productRepository) 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 := r.db.Raw(query, params...).Scan(&stocks).Error; err != nil {
return nil, err
}
return stocks, nil
}
func (r *productRepository) CreateProductStock(stocks []models.Productstock) error {
return r.db.Table("productstocks").Create(&stocks).Error
}
func (r *productRepository) UpdateProductStatus(productIDs []int, status string) error {
return r.db.Table("products").
Where("productid IN ?", productIDs).
Update("productstatus", status).Error
}
func (r *productRepository) CreateProduct(product models.Products) error {
tx := r.db.Begin()
if err := tx.Create(&product).Error; err != nil {
tx.Rollback()
return err
}
if err := tx.Commit().Error; err != nil {
return err
}
return nil
}
func (r *productRepository) UpdateProduct(product models.Products) error {
tx := r.db.Begin()
if err := tx.Table("productlocations").
Where("productid = ?", product.Productid).
Select("status"). // only update 'approve' field
Updates(product).Error; err != nil {
tx.Rollback()
return err
}
return tx.Commit().Error
}
func (r *productRepository) DeleteProduct(productID int) error {
tx := r.db.Begin()
if err := tx.Table("products").Where("productid = ?", productID).Delete(&models.Products{}).Error; err != nil {
tx.Rollback()
return err
}
if err := tx.Commit().Error; err != nil {
return err
}
return nil
}
func (r *productRepository) GetStockStatement(tenantID, locationID, subcategoryID, pageno, pagesize int, keyword string) ([]models.Productstockstatement, error) {
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 TEXT) 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)
if err := r.db.Raw(query, params...).Scan(&data).Error; err != nil {
return nil, err
}
print(query)
return data, nil
}
func (r *productRepository) GetLocationProducts(tenantID, locationID, subcategoryID, pageno, pagesize int, keyword string) ([]models.Locationproducts, error) {
var data []models.Locationproducts
if pageno < 1 {
pageno = 1
}
if pagesize < 1 {
pagesize = 10
}
offset := (pageno - 1) * pagesize
params := []interface{}{tenantID, locationID}
query := `SELECT a.*, b.productlocationid, b.status,
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, b.productlocationid, b.status
ORDER BY a.productid DESC LIMIT ? OFFSET ?`
params = append(params, pagesize, offset)
if err := r.db.Raw(query, params...).Scan(&data).Error; err != nil {
return nil, err
}
print(query)
return data, nil
}
func (r *productRepository) GetLocationProductSummary(tenantID, locationID int) ([]models.ProductSummary, error) {
data := make([]models.ProductSummary, 0)
query := `
SELECT
a.subcatid AS subcategoryid,
a.subcatname AS subcategroyname,
a.image,
COUNT(DISTINCT c.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 c.tenantid = ?
AND c.locationid = ?
WHERE a.categoryid = 2
GROUP BY a.subcatid, a.subcatname, a.image
ORDER BY a.subcatid;
`
// Only 3 params: tenantID for products, tenantID for locations, locationID
params := []interface{}{tenantID, tenantID, locationID}
if err := r.db.Raw(query, params...).Scan(&data).Error; err != nil {
return nil, err
}
// Correct "All" count: sum of only products that exist in this location
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, nil
}
func (r *productRepository) 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
}
// Fetch tenant info
var tenant models.TenantInfo
if err := r.db.Table("tenants").Where("tenantid = ?", tenantID).First(&tenant).Error; err != nil {
return nil, err
}
// Build product query
var products []models.Products
query := r.db.
Table("products a").
Select(`
a.*,
b.status,
c.categoryname,
d.subcatname AS subcategoryname,
ps.locationid,
COALESCE(ps.quantity, 0) AS quantity
`).
Joins("LEFT JOIN productlocations b ON a.productid = b.productid").
Joins("LEFT JOIN productcategories c ON a.categoryid = c.categoryid").
Joins("LEFT JOIN productsubcategories d ON a.subcategoryid = d.subcatid").
Joins(`
LEFT JOIN (
SELECT
productid,
locationid,
SUM(CASE WHEN stocktype = 'in' THEN quantity ELSE 0 END) -
SUM(CASE WHEN stocktype = 'out' THEN quantity ELSE 0 END) AS quantity
FROM productstocks
GROUP BY productid, locationid
) ps ON ps.productid = a.productid
`).
Where("a.tenantid = ?", tenantID).
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(
r.db.Where("LOWER(a.productname) LIKE ?", like).
Or("LOWER(a.unitvalue) LIKE ?", like).
Or("LOWER(CAST(a.productcost AS TEXT)) LIKE ?", like),
)
}
if pagesize > 0 && offset >= 0 {
query = query.Limit(pagesize).Offset(offset)
}
if err := query.Scan(&products).Error; err != nil {
return nil, err
}
if products == nil {
products = []models.Products{}
}
results = append(results, models.Tenantproducts{
Tenant: tenant,
Products: products,
})
print(query)
return results, nil
}
func (r *productRepository) GetProductByVariant(tenantid, variantid int) ([]models.Products, error) {
var data []models.Products
err := r.db.
Table("products p").
Select(`
p.*,
c.categoryname,
d.subcatname AS subcategoryname,
COALESCE(pd.discountvalue, 0) AS discountvalue,
pd.discountid
`).
Joins("LEFT JOIN productcategories c ON p.categoryid = c.categoryid").
Joins("LEFT JOIN productsubcategories d ON p.subcategoryid = d.subcatid").
Joins("LEFT JOIN productdiscounts pd ON pd.productid = p.productid").
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 (r *productRepository) GetSubcategories(categoryID int) ([]models.Subcategory, error) {
var subcats []models.Subcategory
err := r.db.Table("productsubcategories").
Where("categoryid = ?", categoryID).
Find(&subcats).Error
return subcats, err
}
func (r *productRepository) GetProducts(params models.ProductFilter) ([]models.Products, error) {
var products []models.Products
q := r.db.Table("products a").
Joins("LEFT JOIN productlocations pl ON pl.productid = a.productid").
Joins("LEFT JOIN productdiscounts pd ON pd.productid = a.productid").
Joins("LEFT JOIN productcategories c ON a.categoryid = c.categoryid").
Where("a.categoryid = ?", params.CategoryID)
if params.TenantID > 0 {
q = q.Where("a.tenantid = ?", params.TenantID)
}
if params.LocationID > 0 {
q = q.Where("pl.locationid = ?", params.LocationID)
}
if params.AppLocationID > 0 {
q = q.Where("a.applocationid = ?", params.AppLocationID)
}
if params.ProductID > 0 {
q = q.Where("a.productid = ?", params.ProductID)
}
if params.Keyword != "" {
like := "%" + strings.ToLower(params.Keyword) + "%"
q = q.Where(
r.db.Where("LOWER(a.productname) LIKE ?", like).
Or("LOWER(a.unitvalue) LIKE ?", like).
Or("LOWER(CAST(a.productcost AS TEXT)) LIKE ?", like),
)
}
err := q.Select(`
a.*,
COALESCE(pd.discountvalue, 0) AS discountvalue
`).Find(&products).Error
return products, err
}
func (r *productRepository) GetTenantInfo(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 := r.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 {
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 (r *productRepository) UpdateProductLocation(input models.Productlocations) error {
tx := r.db.Begin()
t1 := tx.Where("productlocationid = ?", input.Productlocationid).Updates(&input)
if t1.Error != nil {
tx.Rollback()
return t1.Error
}
if err := tx.Commit().Error; err != nil {
return err
}
return nil
}
func (r *productRepository) CreateProductLocation(input []models.Productlocations) error {
var stk []models.Productstock
tx := r.db.Begin()
// Insert or update product location
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
}
// Prepare product stock entries
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,
})
}
}
// Insert stock records if available
if len(stk) > 0 {
if err := tx.Create(&stk).Error; err != nil {
tx.Rollback()
return err
}
}
// Commit transaction
if err := tx.Commit().Error; err != nil {
return err
}
return nil
}
func (r *productRepository) CreateProductVariant(input models.Productvariant) error {
tx := r.db.Begin()
if err := tx.Create(&input).Error; err != nil {
tx.Rollback()
return err
}
if err := tx.Commit().Error; err != nil {
return err
}
return nil
}

View File

@@ -0,0 +1,737 @@
package repositories
import (
"errors"
"fmt"
"nearle/models"
"strconv"
"strings"
"github.com/jinzhu/copier"
"gorm.io/gorm"
)
type TenantRepository interface {
SearchTenant(status, searchstr string) ([]models.Tenantinfo, error)
GetAllTenants(pageno, pagesize, aid int, status, tenanttype, keyword string) ([]models.Tenantinfo, error)
GetTenantLocations(tid int) ([]models.Tenantlocations, error)
GetTenantSlot() (models.Tenantslot, error)
CreateTenantCustomer(customer models.Tenantcustomer) (*models.Tenantcustomer, error)
GetCustomerTenants(customerID int, categoryID int, tenantFlag int) ([]models.TenantInfo, error)
GetTenantPricing(tid, aid int) (*models.Tenantpricing, error)
UpdateLocation(input models.Tenantlocations) error
CreateLocation(data models.Tenantlocations) error
GetStaffs(tid int) ([]models.StaffInfo, error)
CreateStaff(user models.User) error
UpdateStaff(user models.User) error
CreateTenantLocation(data models.Tenantlocations) error
UpdateTenantLocation(data models.Tenantlocations) error
CheckTenantByNo(cno string) int
CreateTenantUser(data models.Tenants) (bool, error)
GetUserByNo(cno string) models.UserInfo
GetTenantByID(tid int, locationid int) (models.Tenantinfo, error)
GetTenantByKeyword(keyword string) ([]models.TenantSearch, error)
}
type tenantRepository struct {
db *gorm.DB
}
func NewTenantRepository(db *gorm.DB) TenantRepository {
return &tenantRepository{db: db}
}
func (r *tenantRepository) SearchTenant(status, keyword string) ([]models.Tenantinfo, error) {
var data []models.Tenantinfo
var query string
searchStr := strings.ToLower(keyword)
if strings.ToLower(status) != "pending" {
query = `
SELECT a.*, b.subcategoryname, c.firstname, c.lastname,
CONCAT(c.firstname, ' ', c.lastname) AS accountname
FROM tenants a
INNER JOIN app_subcategory b ON a.subcategoryid = b.subcategoryid
LEFT JOIN app_users c ON c.userid = a.partneruserid
WHERE a.approved = 1
AND LOWER(a.status) = ?
AND LOWER(a.tenantname) LIKE ?
`
r.db.Raw(query, strings.ToLower(status), searchStr+"%").Scan(&data)
} else {
query = `
SELECT a.*, b.subcategoryname, c.firstname, c.lastname,
CONCAT(c.firstname, ' ', c.lastname) AS accountname
FROM tenants a
INNER JOIN app_subcategory b ON a.subcategoryid = b.subcategoryid
LEFT JOIN app_users c ON c.userid = a.partneruserid
WHERE a.approved = 0
AND LOWER(a.tenantname) LIKE ?
`
r.db.Raw(query, searchStr+"%").Scan(&data)
}
return data, nil
}
func (r *tenantRepository) GetAllTenants(pageno, pagesize, aid int, status, tenanttype, keyword string) ([]models.Tenantinfo, error) {
offset := (pageno - 1) * pagesize
var data []models.Tenantinfo
base := `SELECT * FROM tenants a 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 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)
err := r.db.Raw(base, params...).Scan(&data).Error
if err != nil {
return nil, err
}
return data, nil
}
func (r *tenantRepository) GetTenantLocations(tid int) ([]models.Tenantlocations, error) {
var data []models.Tenantlocations
q1 := `SELECT a.*, b.roleid FROM tenantlocations a
LEFT JOIN app_users b ON a.locationid = b.locationid
AND a.tenantid = b.tenantid
WHERE a.tenantid = ?`
if err := r.db.Raw(q1, tid).Find(&data).Error; err != nil {
return nil, err
}
print(q1)
return data, nil
}
func (r *tenantRepository) GetTenantSlot() (models.Tenantslot, error) {
var data models.Tenantslot
err := r.db.Raw(`SELECT * FROM tenantslot`).Find(&data).Error
if err != nil {
return models.Tenantslot{}, err
}
return data, nil
}
func (r *tenantRepository) CreateTenantCustomer(customer models.Tenantcustomer) (*models.Tenantcustomer, error) {
var existing models.Tenantcustomer
// 🔍 Step 1: Check if a record already exists with same customerid and locationid
err := r.db.
Where("customerid = ? AND locationid = ?", customer.CustomerID, customer.LocationID).
First(&existing).Error
// If record found, prevent insertion
if err == nil {
return nil, fmt.Errorf("customer already exists for this location")
}
// If error other than record not found, return it
if !errors.Is(err, gorm.ErrRecordNotFound) {
return nil, err
}
// ✅ Step 2: Insert new record if no duplicate found
if err := r.db.Create(&customer).Error; err != nil {
return nil, err
}
return &customer, nil
}
func (r *tenantRepository) GetCustomerTenants(customerID int, categoryID int, tenantFlag int) ([]models.TenantInfo, error) {
var tenants []models.TenantInfo
query := `
SELECT a.customerid, a.locationid, b.tenantid,b.tenantname,b.address,b.licenseno,
b.primaryemail,b.primarycontact,b.applocationid,b.suburb,b.city,
b.latitude,b.longitude,b.postcode,b.tenantimage,b.subcategoryid,
b.categoryid,b.registrationno,d.userfcmtoken,c.locationname,
COALESCE(o.orderscount, 0) AS orderscount
FROM tenantcustomers a
LEFT JOIN tenants b ON a.tenantid = b.tenantid
INNER JOIN tenantlocations c ON a.locationid = c.locationid
LEFT JOIN (
SELECT tenantid, customerid, COUNT(*) AS orderscount
FROM orders
GROUP BY tenantid, customerid
) o ON b.tenantid = o.tenantid AND o.customerid = a.customerid
LEFT JOIN (
SELECT locationid,
MAX(userfcmtoken) AS userfcmtoken
FROM app_users
GROUP BY locationid
) d ON d.locationid = a.locationid
WHERE a.customerid = ?
AND b.tenantid IS NOT NULL
`
args := []interface{}{customerID}
if categoryID != 0 {
query += " AND b.categoryid = ?"
args = append(args, categoryID)
}
if tenantFlag == 1 {
query += " AND COALESCE(o.orderscount,0) > 0"
}
if err := r.db.Raw(query, args...).Scan(&tenants).Error; err != nil {
return nil, err
}
if tenants == nil {
return []models.TenantInfo{}, nil
}
// Attach top 5 subcategories
if len(tenants) > 0 {
var subcategories []models.ProductSubcategory
if err := r.db.Table("productsubcategories").
Order("subcatid ASC").
Limit(5).
Find(&subcategories).Error; err != nil {
return nil, err
}
for i := range tenants {
tenants[i].ProductSubcategory = subcategories
}
}
print(tenants)
return tenants, nil
}
func (r *tenantRepository) GetTenantPricing(tid, aid int) (*models.Tenantpricing, error) {
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`
}
if err := r.db.Raw(q1, tid).Find(&data).Error; err != nil {
return nil, err
}
return &data, nil
}
func (r *tenantRepository) UpdateLocation(input models.Tenantlocations) error {
tx := r.db.Begin()
if err := tx.Where("locationid=?", input.Locationid).Updates(&input).Error; err != nil {
tx.Rollback()
return err
}
if err := tx.Commit().Error; err != nil {
return err
}
return nil
}
func (r *tenantRepository) CreateLocation(data models.Tenantlocations) error {
var cust models.Customers
var tcust models.Tenantcustomers
var custloc models.Customerlocations
tx := r.db.Begin()
if err := tx.Create(&data).Error; err != nil {
tx.Rollback()
return err
}
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
if err := tx.Table("customers").Create(&cust).Error; err != nil {
tx.Rollback()
return err
}
if err := copier.Copy(&custloc, &cust); err != nil {
tx.Rollback()
return err
}
if err := tx.Table("customerlocations").Create(&custloc).Error; err != nil {
tx.Rollback()
return err
}
tcust.Customerid = cust.Customerid
tcust.Tenantid = data.Tenantid
tcust.Locationid = data.Locationid
tcust.Moduleid = data.Moduleid
if err := tx.Table("tenantcustomers").Create(&tcust).Error; err != nil {
tx.Rollback()
return err
}
if err := tx.Commit().Error; err != nil {
return err
}
return nil
}
func (r *tenantRepository) GetStaffs(tid int) ([]models.StaffInfo, error) {
var data []models.StaffInfo
q1 := `SELECT a.userid,a.firstname,a.lastname,
CONCAT(a.firstname,' ',a.lastname) AS fullname,
a.email,a.contactno,a.address,a.suburb,a.city,
a.state,a.postcode,a.userfcmtoken,a.pin,a.applocationid,
a.roleid,a.partnerid,a.tenantid,a.locationid,
b.locationname
FROM app_users a
INNER JOIN tenantlocations b ON a.locationid = b.locationid
WHERE a.tenantid = ?`
if err := r.db.Raw(q1, tid).Scan(&data).Error; err != nil {
return nil, err
}
return data, nil
}
func (r *tenantRepository) CreateStaff(user models.User) error {
if err := r.db.Table("app_users").Create(&user).Error; err != nil {
return err
}
return nil
}
func (r *tenantRepository) UpdateStaff(user models.User) error {
if err := r.db.Table("app_users").Where("userid = ?", user.Userid).Updates(&user).Error; err != nil {
return err
}
return nil
}
func (r *tenantRepository) CreateTenantLocation(data models.Tenantlocations) error {
var user models.Tenantuser
tx := r.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 (r *tenantRepository) UpdateTenantLocation(input models.Tenantlocations) error {
tx := r.db.Begin()
// ✅ Step 1: Prepare map for tenantlocations update
locationUpdate := make(map[string]interface{})
if input.Locationname != "" {
locationUpdate["locationname"] = input.Locationname
}
if input.Email != "" {
locationUpdate["email"] = input.Email
}
if input.Contactno != "" {
locationUpdate["contactno"] = input.Contactno
}
if input.Address != "" {
locationUpdate["address"] = input.Address
}
if input.Suburb != "" {
locationUpdate["suburb"] = input.Suburb
}
if input.City != "" {
locationUpdate["city"] = input.City
}
if input.State != "" {
locationUpdate["state"] = input.State
}
if input.Postcode != "" {
locationUpdate["postcode"] = input.Postcode
}
if input.Partnerid != 0 {
locationUpdate["partnerid"] = input.Partnerid
}
if input.Tenantid != 0 {
locationUpdate["tenantid"] = input.Tenantid
}
if input.Applocationid != 0 {
locationUpdate["applocationid"] = input.Applocationid
}
if input.Status != "" {
locationUpdate["status"] = input.Status
}
// ✅ Step 2: Update tenantlocations (only provided fields)
if len(locationUpdate) > 0 {
if err := tx.Table("tenantlocations").
Where("locationid = ?", input.Locationid).
Updates(locationUpdate).Error; err != nil {
tx.Rollback()
return err
}
}
// ✅ Step 3: Prepare map for app_users update (only matching fields)
userUpdate := make(map[string]interface{})
if input.Locationname != "" {
userUpdate["firstname"] = input.Locationname
}
if input.Email != "" {
userUpdate["email"] = input.Email
}
if input.Contactno != "" {
userUpdate["contactno"] = input.Contactno
}
if input.Address != "" {
userUpdate["address"] = input.Address
}
if input.Suburb != "" {
userUpdate["suburb"] = input.Suburb
}
if input.City != "" {
userUpdate["city"] = input.City
}
if input.State != "" {
userUpdate["state"] = input.State
}
if input.Postcode != "" {
userUpdate["postcode"] = input.Postcode
}
if input.Tenantid != 0 {
userUpdate["tenantid"] = input.Tenantid
}
if input.Partnerid != 0 {
userUpdate["partnerid"] = input.Partnerid
}
if input.Applocationid != 0 {
userUpdate["applocationid"] = input.Applocationid
}
if input.Status != "" {
userUpdate["status"] = input.Status
}
// ✅ Step 4: Update app_users (only provided fields)
if len(userUpdate) > 0 {
if err := tx.Table("app_users").
Where("locationid = ?", input.Locationid).
Updates(userUpdate).Error; err != nil {
tx.Rollback()
return err
}
}
// ✅ Commit transaction
if err := tx.Commit().Error; err != nil {
return err
}
return nil
}
// ✅ Check if tenant exists
func (r *tenantRepository) CheckTenantByNo(cno string) int {
var id int
q1 := "SELECT tenantid FROM tenants WHERE primarycontact = '" + cno + `'`
r.db.Raw(q1).Find(&id)
return id
}
// ✅ Create tenant + user + customer records
func (r *tenantRepository) 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 := r.db.Begin()
// Step 1: Insert into tenants
if err := tx.Create(&data).Error; err != nil {
tx.Rollback()
return false, errors.New("error in tenant creation")
}
// Step 2: Create order sequence
seq.Tenantid = data.Tenantid
if err := tx.Table("ordersequences").Create(&seq).Error; err != nil {
tx.Rollback()
return false, errors.New("error in sequence")
}
// Step 3: Create app_user
if err := copier.Copy(&user, &data); err != nil {
tx.Rollback()
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
if err := tx.Table("app_users").Create(&user).Error; err != nil {
tx.Rollback()
return false, errors.New("error in user creation")
}
// Step 4: Create / Update customers
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 := r.CheckCustomer(data.Primarycontact)
if cid == 0 {
if err := tx.Table("customers").Create(&cust).Error; err != nil {
tx.Rollback()
return false, errors.New("error in customer creation")
}
if err := copier.Copy(&custloc, &cust); err != nil {
tx.Rollback()
return false, err
}
if err := tx.Table("customerlocations").Create(&custloc).Error; err != nil {
tx.Rollback()
return false, errors.New("error in customer location")
}
} else {
if err := tx.Table("customers").Where("customerid=?", cid).Updates(&cust).Error; err != nil {
tx.Rollback()
return false, errors.New("error updating customer")
}
if err := copier.Copy(&custloc, &cust); err != nil {
tx.Rollback()
return false, err
}
if err := tx.Table("customerlocations").Where("customerid=?", cid).Updates(&custloc).Error; err != nil {
tx.Rollback()
return false, errors.New("error updating customer location")
}
}
// Step 5: Create tenant-customer link
tcust.Customerid = cust.Customerid
tcust.Tenantid = data.Tenantid
tcust.Locationid = data.Tenantlocations.Locationid
if err := tx.Table("tenantcustomers").Create(&tcust).Error; err != nil {
tx.Rollback()
return false, errors.New("error in tenant customer")
}
// ✅ Commit transaction
if err := tx.Commit().Error; err != nil {
return false, errors.New("error in tenant creation")
}
return true, nil
}
// ✅ Check if customer exists
func (r *tenantRepository) CheckCustomer(cno string) int {
var id int
q := "SELECT customerid FROM customers WHERE contactno = '" + cno + `'`
r.db.Raw(q).Find(&id)
return id
}
// ✅ Get user by contact number
func (r *tenantRepository) 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,b.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 + `'`
r.db.Raw(q1).Find(&user)
return user
}
func (r *tenantRepository) GetTenantByID(tid int, locationid int) (models.Tenantinfo, error) {
var data models.Tenantinfo
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, f.contactno as locationcontact
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
WHERE a.tenantid = ?
`
var args []interface{}
args = append(args, tid)
if locationid != 0 {
q1 += " AND f.locationid = ?"
args = append(args, locationid)
}
if err := r.db.Raw(q1, args...).Find(&data).Error; err != nil {
return data, err
}
return data, nil
}
func (r *tenantRepository) GetTenantByKeyword(keyword string) ([]models.TenantSearch, error) {
var data []models.TenantSearch
kw := "%" + strings.ToLower(keyword) + "%"
query := `
SELECT a.tenantname, b.productname, c.subcatname
FROM tenants a
LEFT JOIN products b ON a.tenantid = b.tenantid
LEFT JOIN productsubcategories c ON b.subcategoryid = c.subcatid
WHERE c.categoryid = 2
AND (LOWER(a.tenantname) LIKE ? OR LOWER(b.productname) LIKE ? OR LOWER(c.subcatname) LIKE ?)
`
if err := r.db.Raw(query, kw, kw, kw).Scan(&data).Error; err != nil {
return nil, err
}
return data, nil
}

View File

@@ -0,0 +1,279 @@
package repositories
import (
"fmt"
"strings"
"nearle/models"
"gorm.io/gorm"
)
type UserRepository interface {
GetAllUsers(roleID, tenantID, pageno, pagesize int, keyword string) ([]models.UserInfo, error)
GetUserByID(uid int) (models.UserInfo, error)
Login(user models.User) (models.UserInfo, error)
FindUserID(authname, contactno string, configid int) (int, error)
GetTenantUserByID(userid int) (models.TenantUserInfo, error)
UpdateStaff(user models.User) error
GetUserByAuthname(authname string, configid int) (int, string, string)
GetUserByContactNo(contactno string, configid int) (int, string, string)
UpdateFCMToken(userid int, token string) error
GetTenantUserById(userid int) models.TenantUserInfo
CreateUser(user models.User) (int, error)
GetUserById(uid int) (models.UserInfo, error)
GetUserLogin(field, value string, configid int) (int, string, string, int)
UpdateUserFcmToken(uid int, token string) error
}
type userRepository struct {
db *gorm.DB
}
func NewUserRepository(db *gorm.DB) UserRepository {
return &userRepository{db: db}
}
func (r *userRepository) GetAllUsers(roleID, tenantID, pageno, pagesize int, keyword string) ([]models.UserInfo, error) {
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.applocationid, b.locationname AS applocation, b.latitude AS applatitude, concat(c.starttime, ' - ', c.endtime) as shiftname,
b.longitude AS applongitude, b.radius AS appradius
FROM app_users a
LEFT JOIN app_location b ON a.applocationid = b.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 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(" ORDER BY a.userid DESC LIMIT ? OFFSET ?")
params = append(params, pagesize, offset)
print(queryBuilder.String())
if err := r.db.Raw(queryBuilder.String(), params...).Scan(&users).Error; err != nil {
return nil, err
}
return users, nil
}
func (r *userRepository) GetUserByID(uid int) (models.UserInfo, error) {
var user models.UserInfo
q := `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.locationid,
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 = ?`
if err := r.db.Raw(q, uid).Scan(&user).Error; err != nil {
return models.UserInfo{}, err
}
return user, nil
}
func (r *userRepository) Login(user models.User) (models.UserInfo, error) {
var uid int
var userInfo models.UserInfo
var q string
if user.Authname != "" {
q = `SELECT a.userid FROM app_users a
WHERE a.authname = ? AND a.configid = ?`
if err := r.db.Raw(q, user.Authname, user.Configid).Scan(&uid).Error; err != nil {
return models.UserInfo{}, err
}
} else {
q = `SELECT a.userid FROM app_users a
WHERE a.contactno = ? AND a.configid = ?`
if err := r.db.Raw(q, user.Contactno, user.Configid).Scan(&uid).Error; err != nil {
return models.UserInfo{}, err
}
}
if uid == 0 {
return models.UserInfo{}, gorm.ErrRecordNotFound
}
// ✅ Update FCM token in app_users table if provided
if user.Userfcmtoken != "" {
if err := r.db.Table("app_users").
Where("userid = ?", uid).
Update("userfcmtoken", user.Userfcmtoken).Error; err != nil {
return models.UserInfo{}, err
}
}
userInfo, err := r.GetUserByID(uid)
if err != nil {
return models.UserInfo{}, err
}
return userInfo, nil
}
func (r *userRepository) FindUserID(authname, contactno string, configid int) (int, error) {
var uid int
var query string
if authname != "" {
query = `SELECT a.userid FROM app_users a WHERE a.authname = ? AND a.configid = ?`
if err := r.db.Raw(query, authname, configid).Scan(&uid).Error; err != nil {
return 0, err
}
} else {
query = `SELECT a.userid FROM app_users a WHERE a.contactno = ? AND a.configid = ?`
if err := r.db.Raw(query, contactno, configid).Scan(&uid).Error; err != nil {
return 0, err
}
}
return uid, nil
}
func (r *userRepository) GetTenantUserByID(userid int) (models.TenantUserInfo, error) {
var info models.TenantUserInfo
query := `SELECT a.userid, a.authname, a.contactno, a.tenantid, t.tenantname
FROM app_users a
LEFT JOIN tenants t ON a.tenantid = t.tenantid
WHERE a.userid = ?`
if err := r.db.Raw(query, userid).Scan(&info).Error; err != nil {
return info, err
}
return info, nil
}
func (r *userRepository) UpdateStaff(user models.User) error {
return r.db.Table("app_users").Where("userid = ?", user.Userid).Updates(&user).Error
}
func (r *userRepository) GetUserByAuthname(authname string, configid int) (int, string, string) {
var uid int
var password, status string
query := `SELECT userid, password, status FROM app_users WHERE authname = ? AND configid = ?`
r.db.Raw(query, authname, configid).Row().Scan(&uid, &password, &status)
return uid, password, status
}
func (r *userRepository) GetUserByContactNo(contactno string, configid int) (int, string, string) {
var uid int
var password, status string
query := `SELECT userid, password, status FROM app_users WHERE contactno = ? AND configid = ?`
r.db.Raw(query, contactno, configid).Row().Scan(&uid, &password, &status)
return uid, password, status
}
func (r *userRepository) UpdateFCMToken(userid int, token string) error {
query := `UPDATE app_users SET userfcmtoken = ? WHERE userid = ?`
return r.db.Exec(query, token, userid).Error
}
func (r *userRepository) GetTenantUserById(userid int) models.TenantUserInfo {
var info models.TenantUserInfo
query := `
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 = ?
`
r.db.Raw(query, userid).Scan(&info)
print(query)
return info
}
func (r *userRepository) CreateUser(user models.User) (int, error) {
tx := r.db.Begin()
if err := tx.Table("app_users").Create(&user).Error; err != nil {
tx.Rollback()
return 0, err
}
if err := tx.Commit().Error; err != nil {
return 0, err
}
return user.Userid, nil
}
func (r *userRepository) GetUserById(uid int) (models.UserInfo, error) {
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= ?`
if err := r.db.Raw(q1, uid).Scan(&user).Error; err != nil {
return models.UserInfo{}, err
}
return user, nil
}
func (r *userRepository) GetUserLogin(field, value string, configid int) (int, string, string, int) {
var uid, roleid int
var password, status string
query := fmt.Sprintf(`
SELECT userid, password, status, roleid
FROM app_users
WHERE %s = ? AND configid = ?`, field)
r.db.Raw(query, value, configid).Row().Scan(&uid, &password, &status, &roleid)
return uid, password, status, roleid
}
func (r *userRepository) UpdateUserFcmToken(userid int, fcmToken string) error {
query := `UPDATE app_users SET userfcmtoken = ? WHERE userid = ?`
return r.db.Exec(query, fcmToken, userid).Error
}

View File

@@ -0,0 +1,203 @@
package repositories
import (
"context"
"fmt"
"nearle/models"
"strconv"
firebase "firebase.google.com/go"
"firebase.google.com/go/messaging"
"google.golang.org/api/option"
"gorm.io/gorm"
)
type UtilsRepository interface {
GetApptypes(tag string) ([]models.Apptypes, error)
SendNotification(token string, notification models.FcmNotification, data map[string]string) error
GetSubcategories(moduleid int, categoryid int) ([]models.Appsubcategories, error)
GetApplocations(aid int) ([]models.Applocations, error)
GetApplocationConfig(aid int) ([]models.Applocations, error)
GetAppConfig(configID int) (models.Appconfig, error)
GetAppCategory() ([]models.AppCategory, error)
}
type utilsRepository struct {
db *gorm.DB
}
func NewUtilsRepository(db *gorm.DB) UtilsRepository {
return &utilsRepository{db: db}
}
func (r *utilsRepository) GetApptypes(tag string) ([]models.Apptypes, error) {
var data []models.Apptypes
q1 := `Select * from app_types where status ='Active' and tag='` + tag + `'`
print(q1)
err := r.db.Raw(q1).Find(&data).Error
if err != nil {
return nil, err
}
return data, nil
}
func (r *utilsRepository) SendNotification(token string, notification models.FcmNotification, data map[string]string) error {
opt := option.WithCredentialsFile("nearle-gear-firebase-adminsdk-l9oha-23ca3b3609.json")
app, err := firebase.NewApp(context.Background(), nil, opt)
if err != nil {
return fmt.Errorf("error initializing Firebase app: %v", err)
}
client, err := app.Messaging(context.Background())
if err != nil {
return fmt.Errorf("error getting Messaging client: %v", err)
}
message := &messaging.Message{
Token: token,
Notification: &messaging.Notification{
Title: notification.Title,
Body: notification.Body,
},
Android: &messaging.AndroidConfig{
Priority: "high",
Notification: &messaging.AndroidNotification{
Sound: "ring",
},
},
Data: data,
}
_, err = client.Send(context.Background(), message)
if err != nil {
return fmt.Errorf("error sending FCM message: %v", err)
}
return nil
}
func (r *utilsRepository) GetSubcategories(moduleid int, categoryid int) ([]models.Appsubcategories, error) {
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)
}
if err := r.db.Raw(query, params...).Scan(&data).Error; err != nil {
return nil, err
}
print(query)
return data, nil
}
func (r *utilsRepository) GetApplocations(aid int) ([]models.Applocations, error) {
var data []models.Applocations
q1 := `Select * from app_location where status='Active'`
if aid != 0 {
q1 += ` and applocationid = ?`
params := []interface{}{aid}
err := r.db.Raw(q1, params...).Scan(&data).Error
if err != nil {
return nil, err
}
} else {
err := r.db.Raw(q1).Scan(&data).Error
if err != nil {
return nil, err
}
}
print(q1)
return data, nil
}
func (r *utilsRepository) GetApplocationConfig(aid int) ([]models.Applocations, error) {
var data []models.Applocations
var q1, q2 string
if aid != 0 {
q1 = `SELECT * FROM app_location WHERE status='Active' AND applocationid=` + strconv.Itoa(aid)
} else {
q1 = `SELECT * FROM app_location WHERE status='Active'`
}
if err := r.db.Raw(q1).Scan(&data).Error; err != nil {
return nil, err
}
for i := range data {
q2 = `
SELECT a.userid, a.userfcmtoken, b.notify, b.applocationid
FROM app_users a
INNER JOIN app_locationconfig b ON a.userid = b.userid
WHERE b.notify='true' AND b.applocationid=` + strconv.Itoa(data[i].Applocationid)
var users []models.Applocationadmins
if err := r.db.Raw(q2).Scan(&users).Error; err != nil {
return nil, err
}
data[i].Applocationadmins = users
}
print(q1)
return data, nil
}
func (r *utilsRepository) GetAppConfig(configID int) (models.Appconfig, error) {
var data models.Appconfig
var q1 string
if configID != 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=` + strconv.Itoa(configID)
} 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`
}
fmt.Println(q1)
if err := r.db.Raw(q1).Find(&data).Error; err != nil {
return data, err
}
return data, nil
}
func (r *utilsRepository) GetAppCategory() ([]models.AppCategory, error) {
var data []models.AppCategory
query := `SELECT * FROM app_category WHERE status = 'Active' ORDER BY sortorder ASC`
if err := r.db.Raw(query).Scan(&data).Error; err != nil {
return nil, err
}
return data, nil
}