stock request table created
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
56
repositories/stockrequest.go
Normal file
56
repositories/stockrequest.go
Normal 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
|
||||
}
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user