stock request table created

This commit is contained in:
2026-07-04 17:49:54 +05:30
parent f220c24c17
commit abe2cb997b
24 changed files with 648 additions and 61 deletions

View File

@@ -26,6 +26,7 @@ type OrderRepository interface {
CreateOrder(order models.Orders) (models.Orders, error)
GetCustomerOrdersv3(customerID, tenantID, moduleID, fromDate, toDate, orderStatus, keyword string, pageSize, offset int) ([]models.CustomerOrder, error)
GetRevenueSummary(tid, lid int, fdate, tdate string) (*models.TenantRevenueSummary, error)
GetSalesSummary(tid, lid int, fdate, tdate string) (*models.SalesSummaryResponse, error)
}
type orderRepository struct {
@@ -793,6 +794,100 @@ func (r *orderRepository) GetDistinctLocations() ([]models.OrderInsight, error)
return locations, nil
}
func (r *orderRepository) GetSalesSummary(tid, lid int, fdate, tdate string) (*models.SalesSummaryResponse, error) {
var summary models.SalesSummaryResponse
whereClause := "tenantid = ? AND orderstatus IN ('delivered', 'completed') AND configid = 1"
var params []interface{}
params = append(params, tid)
if lid != 0 {
whereClause += " AND locationid = ?"
params = append(params, lid)
}
if fdate != "" && tdate != "" {
whereClause += " AND orderdate::date BETWEEN ? AND ?"
params = append(params, fdate, tdate)
}
totalsQuery := fmt.Sprintf(`
SELECT
COALESCE(SUM(COALESCE(ordervalue, 0) + COALESCE(orderamount, 0) + COALESCE(deliveryamt, 0)), 0) AS total_revenue,
COUNT(orderheaderid) AS total_orders
FROM orders
WHERE %s`, whereClause)
var result struct {
TotalRevenue float64
TotalOrders int
}
if err := r.db.Raw(totalsQuery, params...).Scan(&result).Error; err != nil {
return nil, err
}
summary.TotalRevenue = result.TotalRevenue
summary.TotalOrders = result.TotalOrders
if summary.TotalOrders > 0 {
summary.AverageOrderValue = summary.TotalRevenue / float64(summary.TotalOrders)
}
chartQuery := fmt.Sprintf(`
SELECT
CAST(orderdate AS DATE) AS date,
COALESCE(SUM(COALESCE(ordervalue, 0) + COALESCE(orderamount, 0) + COALESCE(deliveryamt, 0)), 0) AS revenue,
COUNT(orderheaderid) AS orders
FROM orders
WHERE %s
GROUP BY CAST(orderdate AS DATE)
ORDER BY date ASC`, whereClause)
var chartData []models.SalesSummaryChartData
if err := r.db.Raw(chartQuery, params...).Scan(&chartData).Error; err != nil {
return nil, err
}
if chartData == nil {
chartData = []models.SalesSummaryChartData{}
}
summary.ChartData = chartData
var topLocations []models.SalesSummaryTopLocation
if lid == 0 {
topWhere := "o.tenantid = ? AND o.orderstatus IN ('delivered', 'completed') AND o.configid = 1"
var topParams []interface{}
topParams = append(topParams, tid)
if fdate != "" && tdate != "" {
topWhere += " AND o.orderdate::date BETWEEN ? AND ?"
topParams = append(topParams, fdate, tdate)
}
cleanTopLocQuery := fmt.Sprintf(`
SELECT
COALESCE(l.locationname, 'Unknown') AS locationname,
COALESCE(SUM(COALESCE(o.ordervalue, 0) + COALESCE(o.orderamount, 0) + COALESCE(o.deliveryamt, 0)), 0) AS revenue
FROM orders o
LEFT JOIN tenantlocations l ON o.locationid = l.locationid
WHERE %s
GROUP BY l.locationid, l.locationname
ORDER BY revenue DESC
LIMIT 5`, topWhere)
if err := r.db.Raw(cleanTopLocQuery, topParams...).Scan(&topLocations).Error; err != nil {
return nil, err
}
}
if topLocations == nil {
topLocations = []models.SalesSummaryTopLocation{}
}
summary.TopLocations = topLocations
return &summary, nil
}
func (r *orderRepository) GetMonthlyOrders(applocationid string) (*models.Ordermonths, error) {
var orderMonths models.Ordermonths
@@ -920,13 +1015,14 @@ func (r *orderRepository) getSequenceno(tid int, prefix string) string {
var q1 string
// Formats the ID as tenantid-subprefix+seqno (e.g., 908-20245189)
if prefix == "ORD" {
switch prefix {
case "ORD":
q1 = `SELECT CONCAT(tenantid, '-',
CASE WHEN subprefix IS NULL OR CAST(subprefix AS TEXT) IN ('0', '0.0', '') THEN '' ELSE CAST(subprefix AS TEXT) END,
COALESCE(MAX(orderseqno) + 1, 1)) AS orderseqno
FROM ordersequences WHERE tenantid = ?
GROUP BY tenantid, subprefix`
} else if prefix == "INV" {
case "INV":
q1 = `SELECT CONCAT(tenantid, '-',
CASE WHEN subprefix IS NULL OR CAST(subprefix AS TEXT) IN ('0', '0.0', '') THEN '' ELSE CAST(subprefix AS TEXT) END,
COALESCE(MAX(invoiceseqno) + 1, 1)) AS orderseqno
@@ -947,11 +1043,12 @@ func (r *orderRepository) getSequenceno(tid int, prefix string) string {
func (r *orderRepository) updateSeqno(tid int, prefix string) error {
var field string
if prefix == "ORD" {
switch prefix {
case "ORD":
field = "orderseqno"
} else if prefix == "INV" {
case "INV":
field = "invoiceseqno"
} else {
default:
return fmt.Errorf("invalid prefix: %s", prefix)
}

View File

@@ -15,6 +15,7 @@ type PartnerRepository interface {
GetLocationConfig(uid, cid int) ([]models.Locationconfigs, error)
GetRiderLogs(pid, aid int, fdate, tdate string) ([]models.RiderlogDetails, error)
GetRiderInfo(userid int) (models.RiderInfo, error)
GetFleetSummary(aid, tid int, fdate, tdate string) (models.FleetSummary, error)
}
type partnerRepository struct {
@@ -197,3 +198,100 @@ func (r *partnerRepository) GetRiderInfo(userid int) (models.RiderInfo, error) {
return data, nil
}
func (r *partnerRepository) GetFleetSummary(aid, tid int, fdate, tdate string) (models.FleetSummary, error) {
var summary models.FleetSummary
// --- Fleet membership filter (app_users aliased as a) ---
memberWhere := "a.configid = 6"
var memberArgs []interface{}
if aid != 0 {
memberWhere += " AND a.applocationid = ?"
memberArgs = append(memberArgs, aid)
}
if tid != 0 {
memberWhere += " AND a.tenantid = ?"
memberArgs = append(memberArgs, tid)
}
countsQuery := `
SELECT
COUNT(*) AS totalriders,
COUNT(*) FILTER (WHERE a.status = 'Active') AS activeriders
FROM app_users a
WHERE ` + memberWhere
if err := r.db.Raw(countsQuery, memberArgs...).Scan(&summary.Counts).Error; err != nil {
return models.FleetSummary{}, err
}
// --- Log-range filter (app_users aliased as b, riderlogs as a) ---
logWhere := "b.configid = 6"
var logArgs []interface{}
if aid != 0 {
logWhere += " AND b.applocationid = ?"
logArgs = append(logArgs, aid)
}
if tid != 0 {
logWhere += " AND b.tenantid = ?"
logArgs = append(logArgs, tid)
}
if fdate != "" && tdate != "" {
logWhere += " AND a.logdate::date BETWEEN ? AND ?"
logArgs = append(logArgs, fdate, tdate)
} else {
logWhere += " AND a.logdate::date = CURRENT_DATE"
}
var worked struct {
Ridersworked int `json:"ridersworked"`
Totallogins int `json:"totallogins"`
}
workedQuery := `
SELECT
COUNT(DISTINCT a.userid) AS ridersworked,
COUNT(*) AS totallogins
FROM riderlogs a
INNER JOIN app_users b ON a.userid = b.userid
WHERE ` + logWhere
if err := r.db.Raw(workedQuery, logArgs...).Scan(&worked).Error; err != nil {
return models.FleetSummary{}, err
}
summary.Counts.Ridersworked = worked.Ridersworked
summary.Counts.Totallogins = worked.Totallogins
// --- Per-rider breakdown over the range ---
// Breaks are pre-aggregated per log so the join cannot inflate the work/short-hour sums.
ridersQuery := `
SELECT
b.userid,
CONCAT(b.firstname, ' ', b.lastname) AS fullname,
b.contactno,
b.partnerid,
b.status,
rs.vehicleno,
rs.vehiclename,
COUNT(DISTINCT a.logdate::date) AS dayslogged,
COALESCE(SUM(a.workhours), 0) AS totalworkhours,
COALESCE(SUM(a.shorthours), 0) AS totalshorthours,
COALESCE(SUM(bk.breakhours), 0) AS totalbreakhours
FROM riderlogs a
INNER JOIN app_users b ON a.userid = b.userid
LEFT JOIN ridersettings rs ON b.userid = rs.userid
LEFT JOIN (
SELECT logid, userid, SUM(breakhours) AS breakhours
FROM riderbreaks
GROUP BY logid, userid
) bk ON a.logid = bk.logid AND a.userid = bk.userid
WHERE ` + logWhere + `
GROUP BY b.userid, b.firstname, b.lastname, b.contactno, b.partnerid, b.status, rs.vehicleno, rs.vehiclename
ORDER BY fullname ASC`
if err := r.db.Raw(ridersQuery, logArgs...).Find(&summary.Riders).Error; err != nil {
return models.FleetSummary{}, err
}
return summary, nil
}

View File

@@ -0,0 +1,56 @@
package repositories
import (
"nearle/models"
"gorm.io/gorm"
)
type StockRequestRepository interface {
CreateStockRequest(req *models.StockRequest) error
GetStockRequests(tenantID int, locationID int, status string, pageNo int, pageSize int) ([]models.StockRequest, error)
GetStockRequestByID(requestID int) (*models.StockRequest, error)
UpdateStockRequest(requestID int, status string) error
}
type stockRequestRepository struct {
db *gorm.DB
}
func NewStockRequestRepository(db *gorm.DB) StockRequestRepository {
return &stockRequestRepository{db: db}
}
func (r *stockRequestRepository) CreateStockRequest(req *models.StockRequest) error {
return r.db.Create(req).Error
}
func (r *stockRequestRepository) GetStockRequests(tenantID int, locationID int, status string, pageNo int, pageSize int) ([]models.StockRequest, error) {
var requests []models.StockRequest
query := r.db.Table("stockrequests").
Select("stockrequests.*, products.productname, products.productimage").
Joins("left join products on products.productid = stockrequests.productid").
Where("stockrequests.tenantid = ?", tenantID)
if locationID > 0 {
query = query.Where("stockrequests.locationid = ?", locationID)
}
if status != "" {
query = query.Where("stockrequests.status = ?", status)
}
offset := (pageNo - 1) * pageSize
err := query.Order("stockrequests.created DESC").Offset(offset).Limit(pageSize).Find(&requests).Error
return requests, err
}
func (r *stockRequestRepository) GetStockRequestByID(requestID int) (*models.StockRequest, error) {
var req models.StockRequest
err := r.db.Table("stockrequests").Where("requestid = ?", requestID).First(&req).Error
return &req, err
}
func (r *stockRequestRepository) UpdateStockRequest(requestID int, status string) error {
return r.db.Model(&models.StockRequest{}).Where("requestid = ?", requestID).Update("status", status).Error
}

View File

@@ -21,6 +21,7 @@ type TenantRepository interface {
GetTenantPricing(tid, aid int) (*models.Tenantpricing, error)
UpdateLocation(input models.Tenantlocations) error
CreateLocation(data models.Tenantlocations) error
DeleteLocation(locationid int, tenantid int) error
GetStaffs(tid int) ([]models.StaffInfo, error)
CreateStaff(user models.User) error
UpdateStaff(user models.User) error
@@ -290,52 +291,10 @@ func (r *tenantRepository) UpdateLocation(input models.Tenantlocations) error {
return nil
}
func (r *tenantRepository) CreateLocation(data models.Tenantlocations) error {
var cust models.Customers
var tcust models.Tenantcustomers
var custloc models.Customerlocations
func (r *tenantRepository) DeleteLocation(locationid int, tenantid int) error {
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 {
if err := tx.Where("locationid=? AND tenantid=?", locationid, tenantid).Delete(&models.Tenantlocations{}).Error; err != nil {
tx.Rollback()
return err
}
@@ -347,6 +306,13 @@ func (r *tenantRepository) CreateLocation(data models.Tenantlocations) error {
return nil
}
func (r *tenantRepository) CreateLocation(data models.Tenantlocations) error {
if err := r.db.Create(&data).Error; err != nil {
return err
}
return nil
}
func (r *tenantRepository) GetStaffs(tid int) ([]models.StaffInfo, error) {
var data []models.StaffInfo

View File

@@ -24,6 +24,7 @@ type UserRepository interface {
GetUserById(uid int) (models.UserInfo, error)
GetUserLogin(field, value string, configid int) (int, string, string, int)
UpdateUserFcmToken(uid int, token string) error
GetLocationStatus(locationid int) string
}
type userRepository struct {
@@ -277,3 +278,12 @@ 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
}
func (r *userRepository) GetLocationStatus(locationid int) string {
var status string
query := `SELECT status FROM tenantlocations WHERE locationid = ?`
r.db.Raw(query, locationid).Row().Scan(&status)
return status
}