stock request table created
This commit is contained in:
@@ -377,7 +377,6 @@ func (ctl *OrderController) GetRevenueSummary(c *fiber.Ctx) error {
|
|||||||
"status": false,
|
"status": false,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.Status(http.StatusOK).JSON(fiber.Map{
|
return c.Status(http.StatusOK).JSON(fiber.Map{
|
||||||
"code": http.StatusOK,
|
"code": http.StatusOK,
|
||||||
"message": "Success",
|
"message": "Success",
|
||||||
@@ -386,3 +385,33 @@ func (ctl *OrderController) GetRevenueSummary(c *fiber.Ctx) error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ctl *OrderController) GetSalesSummary(c *fiber.Ctx) error {
|
||||||
|
tid, _ := strconv.Atoi(c.Query("tenantid"))
|
||||||
|
lid, _ := strconv.Atoi(c.Query("locationid"))
|
||||||
|
fdate := c.Query("fromdate")
|
||||||
|
tdate := c.Query("todate")
|
||||||
|
|
||||||
|
if tid == 0 {
|
||||||
|
return c.Status(http.StatusBadRequest).JSON(fiber.Map{
|
||||||
|
"code": http.StatusBadRequest,
|
||||||
|
"message": "tenantid query parameter is required",
|
||||||
|
"status": false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := ctl.orderService.GetSalesSummary(tid, lid, fdate, tdate)
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(http.StatusInternalServerError).JSON(fiber.Map{
|
||||||
|
"code": http.StatusInternalServerError,
|
||||||
|
"message": err.Error(),
|
||||||
|
"status": false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.Status(http.StatusOK).JSON(fiber.Map{
|
||||||
|
"code": http.StatusOK,
|
||||||
|
"message": "Success",
|
||||||
|
"status": true,
|
||||||
|
"details": data,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ func (ctl *PartnerController) GetActiveRiders(c *fiber.Ctx) error {
|
|||||||
pid, _ := strconv.Atoi(c.Query("partnerid"))
|
pid, _ := strconv.Atoi(c.Query("partnerid"))
|
||||||
aid, _ := strconv.Atoi(c.Query("applocationid"))
|
aid, _ := strconv.Atoi(c.Query("applocationid"))
|
||||||
uid, _ := strconv.Atoi(c.Query("userid"))
|
uid, _ := strconv.Atoi(c.Query("userid"))
|
||||||
tid,_ := strconv.Atoi(c.Query("tenantid"))
|
tid, _ := strconv.Atoi(c.Query("tenantid"))
|
||||||
result, err := ctl.partnerService.GetActiveRiders(pid, aid, uid, tid)
|
result, err := ctl.partnerService.GetActiveRiders(pid, aid, uid, tid)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -109,7 +109,6 @@ func (ctl *PartnerController) GetLocationConfig(c *fiber.Ctx) error {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (ctl *PartnerController) GetRiderLogs(c *fiber.Ctx) error {
|
func (ctl *PartnerController) GetRiderLogs(c *fiber.Ctx) error {
|
||||||
pid, _ := strconv.Atoi(c.Query("partnerid"))
|
pid, _ := strconv.Atoi(c.Query("partnerid"))
|
||||||
aid, _ := strconv.Atoi(c.Query("applocationid"))
|
aid, _ := strconv.Atoi(c.Query("applocationid"))
|
||||||
@@ -134,6 +133,29 @@ func (ctl *PartnerController) GetRiderLogs(c *fiber.Ctx) error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ctl *PartnerController) GetFleetSummary(c *fiber.Ctx) error {
|
||||||
|
aid, _ := strconv.Atoi(c.Query("applocationid"))
|
||||||
|
tid, _ := strconv.Atoi(c.Query("tenantid"))
|
||||||
|
fdate := c.Query("fromdate")
|
||||||
|
tdate := c.Query("todate")
|
||||||
|
|
||||||
|
result, err := ctl.partnerService.GetFleetSummary(aid, tid, fdate, tdate)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return c.JSON(fiber.Map{
|
||||||
|
"status": false,
|
||||||
|
"code": http.StatusInternalServerError,
|
||||||
|
"message": err.Error(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(fiber.Map{
|
||||||
|
"status": true,
|
||||||
|
"code": http.StatusOK,
|
||||||
|
"message": "Successful",
|
||||||
|
"details": result,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (ctl *PartnerController) GetRiderInfo(c *fiber.Ctx) error {
|
func (ctl *PartnerController) GetRiderInfo(c *fiber.Ctx) error {
|
||||||
uid, _ := strconv.Atoi(c.Query("userid"))
|
uid, _ := strconv.Atoi(c.Query("userid"))
|
||||||
|
|||||||
69
controllers/stockrequestController.go
Normal file
69
controllers/stockrequestController.go
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
package controllers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"nearle/models"
|
||||||
|
"nearle/services"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
type StockRequestController struct {
|
||||||
|
stockRequestService services.StockRequestService
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewStockRequestController(stockRequestService services.StockRequestService) *StockRequestController {
|
||||||
|
return &StockRequestController{stockRequestService: stockRequestService}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctl *StockRequestController) CreateStockRequest(c *fiber.Ctx) error {
|
||||||
|
var input models.StockRequest
|
||||||
|
if err := c.BodyParser(&input); err != nil {
|
||||||
|
return c.JSON(fiber.Map{"code": http.StatusBadRequest, "message": "Invalid input", "status": false})
|
||||||
|
}
|
||||||
|
|
||||||
|
if input.Status == "" {
|
||||||
|
input.Status = "Pending"
|
||||||
|
}
|
||||||
|
|
||||||
|
err := ctl.stockRequestService.CreateStockRequest(&input)
|
||||||
|
if err != nil {
|
||||||
|
return c.JSON(fiber.Map{"code": http.StatusInternalServerError, "message": err.Error(), "status": false})
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(fiber.Map{"code": 200, "message": "Stock request created", "status": true, "details": input})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctl *StockRequestController) GetStockRequests(c *fiber.Ctx) error {
|
||||||
|
tenantID, _ := strconv.Atoi(c.Query("tenantid", "0"))
|
||||||
|
locationID, _ := strconv.Atoi(c.Query("locationid", "0"))
|
||||||
|
status := c.Query("status", "")
|
||||||
|
pageNo, _ := strconv.Atoi(c.Query("pageno", "1"))
|
||||||
|
pageSize, _ := strconv.Atoi(c.Query("pagesize", "50"))
|
||||||
|
|
||||||
|
data, err := ctl.stockRequestService.GetStockRequests(tenantID, locationID, status, pageNo, pageSize)
|
||||||
|
if err != nil {
|
||||||
|
return c.JSON(fiber.Map{"code": http.StatusInternalServerError, "message": err.Error(), "status": false})
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(fiber.Map{"code": 200, "message": "Success", "status": true, "details": data})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctl *StockRequestController) UpdateStockRequest(c *fiber.Ctx) error {
|
||||||
|
var input struct {
|
||||||
|
RequestID int `json:"requestid"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
}
|
||||||
|
if err := c.BodyParser(&input); err != nil {
|
||||||
|
return c.JSON(fiber.Map{"code": http.StatusBadRequest, "message": "Invalid input", "status": false})
|
||||||
|
}
|
||||||
|
|
||||||
|
err := ctl.stockRequestService.UpdateStockRequest(input.RequestID, input.Status)
|
||||||
|
if err != nil {
|
||||||
|
return c.JSON(fiber.Map{"code": http.StatusInternalServerError, "message": err.Error(), "status": false})
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(fiber.Map{"code": 200, "message": "Stock request updated", "status": true})
|
||||||
|
}
|
||||||
@@ -252,6 +252,40 @@ func (ctl *TenantController) CreateLocation(c *fiber.Ctx) error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ctl *TenantController) DeleteLocation(c *fiber.Ctx) error {
|
||||||
|
locationid, err := strconv.Atoi(c.Query("locationid"))
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(http.StatusBadRequest).JSON(fiber.Map{
|
||||||
|
"code": http.StatusBadRequest,
|
||||||
|
"message": "Invalid location ID",
|
||||||
|
"status": false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
tenantid, err := strconv.Atoi(c.Query("tenantid"))
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(http.StatusBadRequest).JSON(fiber.Map{
|
||||||
|
"code": http.StatusBadRequest,
|
||||||
|
"message": "Invalid tenant ID",
|
||||||
|
"status": false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := ctl.tenantService.DeleteLocation(locationid, tenantid); err != nil {
|
||||||
|
return c.Status(http.StatusInternalServerError).JSON(fiber.Map{
|
||||||
|
"code": http.StatusInternalServerError,
|
||||||
|
"message": err.Error(),
|
||||||
|
"status": false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(fiber.Map{
|
||||||
|
"code": http.StatusOK,
|
||||||
|
"message": "Location Successfully Deleted",
|
||||||
|
"status": true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (ctl *TenantController) GetStaffs(c *fiber.Ctx) error {
|
func (ctl *TenantController) GetStaffs(c *fiber.Ctx) error {
|
||||||
tid, _ := strconv.Atoi(c.Query("tenantid"))
|
tid, _ := strconv.Atoi(c.Query("tenantid"))
|
||||||
|
|
||||||
|
|||||||
32
create_table.go
Normal file
32
create_table.go
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"gorm.io/driver/postgres"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
func CreateStockRequestsTable() {
|
||||||
|
dsn := "host=66.116.207.225 user=admin password=Package@123# dbname=nearledb port=5433 sslmode=disable TimeZone=Asia/Kolkata"
|
||||||
|
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("failed to connect database: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
query := `CREATE TABLE IF NOT EXISTS stockrequests (
|
||||||
|
requestid SERIAL PRIMARY KEY,
|
||||||
|
tenantid INT NOT NULL,
|
||||||
|
locationid INT NOT NULL,
|
||||||
|
productid INT NOT NULL,
|
||||||
|
qty INT NOT NULL,
|
||||||
|
status VARCHAR(50) DEFAULT 'Pending',
|
||||||
|
created TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);`
|
||||||
|
|
||||||
|
if err := db.Exec(query).Error; err != nil {
|
||||||
|
log.Fatalf("failed to create table: %v", err)
|
||||||
|
}
|
||||||
|
fmt.Println("Table stockrequests created successfully")
|
||||||
|
}
|
||||||
@@ -17,6 +17,7 @@ type Facade struct {
|
|||||||
TenantController *controllers.TenantController
|
TenantController *controllers.TenantController
|
||||||
PartnerController *controllers.PartnerController
|
PartnerController *controllers.PartnerController
|
||||||
CustomerController *controllers.CustomerController
|
CustomerController *controllers.CustomerController
|
||||||
|
StockRequestController *controllers.StockRequestController
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewFacade(db *gorm.DB) *Facade {
|
func NewFacade(db *gorm.DB) *Facade {
|
||||||
@@ -61,6 +62,11 @@ func NewFacade(db *gorm.DB) *Facade {
|
|||||||
customerService := services.NewCustomerService(customerRepo)
|
customerService := services.NewCustomerService(customerRepo)
|
||||||
customerController := controllers.NewCustomerController(customerService)
|
customerController := controllers.NewCustomerController(customerService)
|
||||||
|
|
||||||
|
// Stock Request Module
|
||||||
|
stockRequestRepo := repositories.NewStockRequestRepository(db)
|
||||||
|
stockRequestService := services.NewStockRequestService(stockRequestRepo, productService)
|
||||||
|
stockRequestController := controllers.NewStockRequestController(stockRequestService)
|
||||||
|
|
||||||
return &Facade{
|
return &Facade{
|
||||||
UserController: userController,
|
UserController: userController,
|
||||||
ProductController: productController,
|
ProductController: productController,
|
||||||
@@ -70,5 +76,6 @@ func NewFacade(db *gorm.DB) *Facade {
|
|||||||
TenantController: tenantController,
|
TenantController: tenantController,
|
||||||
PartnerController: partnerController,
|
PartnerController: partnerController,
|
||||||
CustomerController: customerController,
|
CustomerController: customerController,
|
||||||
|
StockRequestController: stockRequestController,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
5
main.go
5
main.go
@@ -62,9 +62,8 @@ func selectDBMiddleware(c *fiber.Ctx) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var currentDB *gorm.DB
|
var currentDB *gorm.DB
|
||||||
if flavour == "dev" {
|
switch flavour {
|
||||||
currentDB = db.DB
|
case "dev", "live":
|
||||||
} else if flavour == "live" {
|
|
||||||
currentDB = db.DB
|
currentDB = db.DB
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -452,3 +452,21 @@ type LocationRevenueDetails struct {
|
|||||||
Revenue float64 `json:"revenue"`
|
Revenue float64 `json:"revenue"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SalesSummaryChartData struct {
|
||||||
|
Date string `json:"date"`
|
||||||
|
Revenue float64 `json:"revenue"`
|
||||||
|
Orders int `json:"orders"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SalesSummaryTopLocation struct {
|
||||||
|
Locationname string `json:"locationname"`
|
||||||
|
Revenue float64 `json:"revenue"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SalesSummaryResponse struct {
|
||||||
|
TotalRevenue float64 `json:"totalRevenue"`
|
||||||
|
TotalOrders int `json:"totalOrders"`
|
||||||
|
AverageOrderValue float64 `json:"averageOrderValue"`
|
||||||
|
ChartData []SalesSummaryChartData `json:"chartData"`
|
||||||
|
TopLocations []SalesSummaryTopLocation `json:"topLocations"`
|
||||||
|
}
|
||||||
|
|||||||
@@ -86,6 +86,31 @@ type Locationconfigs struct {
|
|||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type FleetCounts struct {
|
||||||
|
Totalriders int `json:"totalriders"`
|
||||||
|
Activeriders int `json:"activeriders"`
|
||||||
|
Ridersworked int `json:"ridersworked"`
|
||||||
|
Totallogins int `json:"totallogins"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FleetRiderSummary struct {
|
||||||
|
Userid int `json:"userid"`
|
||||||
|
Fullname string `json:"fullname"`
|
||||||
|
Contactno string `json:"contactno"`
|
||||||
|
Partnerid int `json:"partnerid"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Vehicleno string `json:"vehicleno"`
|
||||||
|
Vehiclename string `json:"vehiclename"`
|
||||||
|
Dayslogged int `json:"dayslogged"`
|
||||||
|
Totalworkhours float32 `json:"totalworkhours"`
|
||||||
|
Totalshorthours float32 `json:"totalshorthours"`
|
||||||
|
Totalbreakhours float32 `json:"totalbreakhours"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FleetSummary struct {
|
||||||
|
Counts FleetCounts `json:"counts"`
|
||||||
|
Riders []FleetRiderSummary `json:"riders"`
|
||||||
|
}
|
||||||
|
|
||||||
type RiderlogDetails struct {
|
type RiderlogDetails struct {
|
||||||
Logid int `json:"logid"`
|
Logid int `json:"logid"`
|
||||||
|
|||||||
20
models/stockrequest.go
Normal file
20
models/stockrequest.go
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type StockRequest struct {
|
||||||
|
Requestid int `json:"requestid" gorm:"primaryKey;autoIncrement;column:requestid"`
|
||||||
|
Tenantid int `json:"tenantid" gorm:"column:tenantid"`
|
||||||
|
Locationid int `json:"locationid" gorm:"column:locationid"`
|
||||||
|
Productid int `json:"productid" gorm:"column:productid"`
|
||||||
|
Productname string `json:"productname" gorm:"->"`
|
||||||
|
Productimage string `json:"productimage" gorm:"->"`
|
||||||
|
Qty int `json:"qty" gorm:"column:qty"`
|
||||||
|
Status string `json:"status" gorm:"column:status;default:Pending"`
|
||||||
|
Created time.Time `json:"created" gorm:"column:created;autoCreateTime"`
|
||||||
|
Updated time.Time `json:"updated" gorm:"column:updated;autoUpdateTime"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (StockRequest) TableName() string {
|
||||||
|
return "stockrequests"
|
||||||
|
}
|
||||||
@@ -26,6 +26,7 @@ type OrderRepository interface {
|
|||||||
CreateOrder(order models.Orders) (models.Orders, error)
|
CreateOrder(order models.Orders) (models.Orders, error)
|
||||||
GetCustomerOrdersv3(customerID, tenantID, moduleID, fromDate, toDate, orderStatus, keyword string, pageSize, offset int) ([]models.CustomerOrder, 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)
|
GetRevenueSummary(tid, lid int, fdate, tdate string) (*models.TenantRevenueSummary, error)
|
||||||
|
GetSalesSummary(tid, lid int, fdate, tdate string) (*models.SalesSummaryResponse, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type orderRepository struct {
|
type orderRepository struct {
|
||||||
@@ -793,6 +794,100 @@ func (r *orderRepository) GetDistinctLocations() ([]models.OrderInsight, error)
|
|||||||
return locations, nil
|
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) {
|
func (r *orderRepository) GetMonthlyOrders(applocationid string) (*models.Ordermonths, error) {
|
||||||
var orderMonths models.Ordermonths
|
var orderMonths models.Ordermonths
|
||||||
|
|
||||||
@@ -920,13 +1015,14 @@ func (r *orderRepository) getSequenceno(tid int, prefix string) string {
|
|||||||
|
|
||||||
var q1 string
|
var q1 string
|
||||||
// Formats the ID as tenantid-subprefix+seqno (e.g., 908-20245189)
|
// Formats the ID as tenantid-subprefix+seqno (e.g., 908-20245189)
|
||||||
if prefix == "ORD" {
|
switch prefix {
|
||||||
|
case "ORD":
|
||||||
q1 = `SELECT CONCAT(tenantid, '-',
|
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,
|
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
|
COALESCE(MAX(orderseqno) + 1, 1)) AS orderseqno
|
||||||
FROM ordersequences WHERE tenantid = ?
|
FROM ordersequences WHERE tenantid = ?
|
||||||
GROUP BY tenantid, subprefix`
|
GROUP BY tenantid, subprefix`
|
||||||
} else if prefix == "INV" {
|
case "INV":
|
||||||
q1 = `SELECT CONCAT(tenantid, '-',
|
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,
|
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
|
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 {
|
func (r *orderRepository) updateSeqno(tid int, prefix string) error {
|
||||||
var field string
|
var field string
|
||||||
if prefix == "ORD" {
|
switch prefix {
|
||||||
|
case "ORD":
|
||||||
field = "orderseqno"
|
field = "orderseqno"
|
||||||
} else if prefix == "INV" {
|
case "INV":
|
||||||
field = "invoiceseqno"
|
field = "invoiceseqno"
|
||||||
} else {
|
default:
|
||||||
return fmt.Errorf("invalid prefix: %s", prefix)
|
return fmt.Errorf("invalid prefix: %s", prefix)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ type PartnerRepository interface {
|
|||||||
GetLocationConfig(uid, cid int) ([]models.Locationconfigs, error)
|
GetLocationConfig(uid, cid int) ([]models.Locationconfigs, error)
|
||||||
GetRiderLogs(pid, aid int, fdate, tdate string) ([]models.RiderlogDetails, error)
|
GetRiderLogs(pid, aid int, fdate, tdate string) ([]models.RiderlogDetails, error)
|
||||||
GetRiderInfo(userid int) (models.RiderInfo, error)
|
GetRiderInfo(userid int) (models.RiderInfo, error)
|
||||||
|
GetFleetSummary(aid, tid int, fdate, tdate string) (models.FleetSummary, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type partnerRepository struct {
|
type partnerRepository struct {
|
||||||
@@ -197,3 +198,100 @@ func (r *partnerRepository) GetRiderInfo(userid int) (models.RiderInfo, error) {
|
|||||||
|
|
||||||
return data, nil
|
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)
|
GetTenantPricing(tid, aid int) (*models.Tenantpricing, error)
|
||||||
UpdateLocation(input models.Tenantlocations) error
|
UpdateLocation(input models.Tenantlocations) error
|
||||||
CreateLocation(data models.Tenantlocations) error
|
CreateLocation(data models.Tenantlocations) error
|
||||||
|
DeleteLocation(locationid int, tenantid int) error
|
||||||
GetStaffs(tid int) ([]models.StaffInfo, error)
|
GetStaffs(tid int) ([]models.StaffInfo, error)
|
||||||
CreateStaff(user models.User) error
|
CreateStaff(user models.User) error
|
||||||
UpdateStaff(user models.User) error
|
UpdateStaff(user models.User) error
|
||||||
@@ -290,52 +291,10 @@ func (r *tenantRepository) UpdateLocation(input models.Tenantlocations) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *tenantRepository) CreateLocation(data models.Tenantlocations) error {
|
func (r *tenantRepository) DeleteLocation(locationid int, tenantid int) error {
|
||||||
var cust models.Customers
|
|
||||||
var tcust models.Tenantcustomers
|
|
||||||
var custloc models.Customerlocations
|
|
||||||
|
|
||||||
tx := r.db.Begin()
|
tx := r.db.Begin()
|
||||||
|
|
||||||
if err := tx.Create(&data).Error; err != nil {
|
if err := tx.Where("locationid=? AND tenantid=?", locationid, tenantid).Delete(&models.Tenantlocations{}).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()
|
tx.Rollback()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -347,6 +306,13 @@ func (r *tenantRepository) CreateLocation(data models.Tenantlocations) error {
|
|||||||
return nil
|
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) {
|
func (r *tenantRepository) GetStaffs(tid int) ([]models.StaffInfo, error) {
|
||||||
var data []models.StaffInfo
|
var data []models.StaffInfo
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ type UserRepository interface {
|
|||||||
GetUserById(uid int) (models.UserInfo, error)
|
GetUserById(uid int) (models.UserInfo, error)
|
||||||
GetUserLogin(field, value string, configid int) (int, string, string, int)
|
GetUserLogin(field, value string, configid int) (int, string, string, int)
|
||||||
UpdateUserFcmToken(uid int, token string) error
|
UpdateUserFcmToken(uid int, token string) error
|
||||||
|
GetLocationStatus(locationid int) string
|
||||||
}
|
}
|
||||||
|
|
||||||
type userRepository struct {
|
type userRepository struct {
|
||||||
@@ -277,3 +278,12 @@ func (r *userRepository) UpdateUserFcmToken(userid int, fcmToken string) error {
|
|||||||
query := `UPDATE app_users SET userfcmtoken = ? WHERE userid = ?`
|
query := `UPDATE app_users SET userfcmtoken = ? WHERE userid = ?`
|
||||||
return r.db.Exec(query, fcmToken, userid).Error
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,9 @@ func RegisterOrderRoutes(api fiber.Router, f *facade.Facade) {
|
|||||||
orders.Put("/updateorder", f.OrderController.UpdateOrder)
|
orders.Put("/updateorder", f.OrderController.UpdateOrder)
|
||||||
orders.Post("/createorder", f.OrderController.CreateOrderv3)
|
orders.Post("/createorder", f.OrderController.CreateOrderv3)
|
||||||
|
|
||||||
|
reports := api.Group("/v1/web/reports")
|
||||||
|
reports.Get("/sales-summary", f.OrderController.GetSalesSummary)
|
||||||
|
|
||||||
orders = api.Group("/v1/mob/orders")
|
orders = api.Group("/v1/mob/orders")
|
||||||
|
|
||||||
orders.Post("/createorder", f.OrderController.CreateOrderv3)
|
orders.Post("/createorder", f.OrderController.CreateOrderv3)
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ func RegisterPartnerRoutes(api fiber.Router, f *facade.Facade) {
|
|||||||
partner.Get("/getridershifts", f.PartnerController.GetRiderShifts)
|
partner.Get("/getridershifts", f.PartnerController.GetRiderShifts)
|
||||||
partner.Get("/getlocations", f.PartnerController.GetLocationConfig)
|
partner.Get("/getlocations", f.PartnerController.GetLocationConfig)
|
||||||
partner.Get("/getriderlogs", f.PartnerController.GetRiderLogs)
|
partner.Get("/getriderlogs", f.PartnerController.GetRiderLogs)
|
||||||
|
partner.Get("/getfleetsummary", f.PartnerController.GetFleetSummary)
|
||||||
|
|
||||||
partner = api.Group("/v1/mob/partners")
|
partner = api.Group("/v1/mob/partners")
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,10 @@ func RegisterProductRoutes(api fiber.Router, f *facade.Facade) {
|
|||||||
products.Post("/createproductlocation", f.ProductController.CreateProductLocation)
|
products.Post("/createproductlocation", f.ProductController.CreateProductLocation)
|
||||||
products.Post("/createproductvariant", f.ProductController.CreateProductVariant)
|
products.Post("/createproductvariant", f.ProductController.CreateProductVariant)
|
||||||
|
|
||||||
|
products.Post("/createstockrequest", f.StockRequestController.CreateStockRequest)
|
||||||
|
products.Get("/getstockrequests", f.StockRequestController.GetStockRequests)
|
||||||
|
products.Put("/updatestockrequest", f.StockRequestController.UpdateStockRequest)
|
||||||
|
|
||||||
products = api.Group("/v1/mob/products")
|
products = api.Group("/v1/mob/products")
|
||||||
|
|
||||||
products.Get("/getproductbyvariant", f.ProductController.GetProductByVariant)
|
products.Get("/getproductbyvariant", f.ProductController.GetProductByVariant)
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ func RegisterTenantRoutes(api fiber.Router, f *facade.Facade) {
|
|||||||
tenant.Post("/createtenantcustomer", f.TenantController.CreateTenantCustomer)
|
tenant.Post("/createtenantcustomer", f.TenantController.CreateTenantCustomer)
|
||||||
tenant.Put("/updatelocation", f.TenantController.UpdateLocation)
|
tenant.Put("/updatelocation", f.TenantController.UpdateLocation)
|
||||||
tenant.Post("/createlocation", f.TenantController.CreateLocation)
|
tenant.Post("/createlocation", f.TenantController.CreateLocation)
|
||||||
|
tenant.Delete("/deletelocation", f.TenantController.DeleteLocation)
|
||||||
tenant.Post("/createtenantlocation", f.TenantController.CreateTenantLocation)
|
tenant.Post("/createtenantlocation", f.TenantController.CreateTenantLocation)
|
||||||
tenant.Put("/updatetenantlocation", f.TenantController.UpdateTenantLocation)
|
tenant.Put("/updatetenantlocation", f.TenantController.UpdateTenantLocation)
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ type OrderService interface {
|
|||||||
GetCustomerOrdersv3(customerID, tenantID, moduleID, fromDate, toDate, orderStatus, keyword string, pageSize, offset int) ([]models.CustomerOrder, error)
|
GetCustomerOrdersv3(customerID, tenantID, moduleID, fromDate, toDate, orderStatus, keyword string, pageSize, offset int) ([]models.CustomerOrder, error)
|
||||||
GetTenantLocationOrders(input models.DeliveryQuery) ([]models.OrderInfo, error)
|
GetTenantLocationOrders(input models.DeliveryQuery) ([]models.OrderInfo, error)
|
||||||
GetRevenueSummary(tid, lid int, fdate, tdate string) (*models.TenantRevenueSummary, error)
|
GetRevenueSummary(tid, lid int, fdate, tdate string) (*models.TenantRevenueSummary, error)
|
||||||
|
GetSalesSummary(tid, lid int, fdate, tdate string) (*models.SalesSummaryResponse, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type orderService struct {
|
type orderService struct {
|
||||||
@@ -91,3 +92,7 @@ func (s *orderService) GetRevenueSummary(tid, lid int, fdate, tdate string) (*mo
|
|||||||
return s.repo.GetRevenueSummary(tid, lid, fdate, tdate)
|
return s.repo.GetRevenueSummary(tid, lid, fdate, tdate)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *orderService) GetSalesSummary(tid, lid int, fdate, tdate string) (*models.SalesSummaryResponse, error) {
|
||||||
|
return s.repo.GetSalesSummary(tid, lid, fdate, tdate)
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ type PartnerService interface {
|
|||||||
GetLocationConfig(uid, cid int) ([]models.Locationconfigs, error)
|
GetLocationConfig(uid, cid int) ([]models.Locationconfigs, error)
|
||||||
GetRiderLogs(pid, aid int, fdate, tdate string) ([]models.RiderlogDetails, error)
|
GetRiderLogs(pid, aid int, fdate, tdate string) ([]models.RiderlogDetails, error)
|
||||||
GetRiderInfo(userid int) (models.RiderInfo, error)
|
GetRiderInfo(userid int) (models.RiderInfo, error)
|
||||||
|
GetFleetSummary(aid, tid int, fdate, tdate string) (models.FleetSummary, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type partnerService struct {
|
type partnerService struct {
|
||||||
@@ -53,3 +54,7 @@ func (s *partnerService) GetRiderLogs(pid, aid int, fdate, tdate string) ([]mode
|
|||||||
func (s *partnerService) GetRiderInfo(userid int) (models.RiderInfo, error) {
|
func (s *partnerService) GetRiderInfo(userid int) (models.RiderInfo, error) {
|
||||||
return s.repo.GetRiderInfo(userid)
|
return s.repo.GetRiderInfo(userid)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *partnerService) GetFleetSummary(aid, tid int, fdate, tdate string) (models.FleetSummary, error) {
|
||||||
|
return s.repo.GetFleetSummary(aid, tid, fdate, tdate)
|
||||||
|
}
|
||||||
|
|||||||
58
services/stockrequestService.go
Normal file
58
services/stockrequestService.go
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
package services
|
||||||
|
|
||||||
|
import (
|
||||||
|
"nearle/models"
|
||||||
|
"nearle/repositories"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type StockRequestService interface {
|
||||||
|
CreateStockRequest(req *models.StockRequest) error
|
||||||
|
GetStockRequests(tenantID int, locationID int, status string, pageNo int, pageSize int) ([]models.StockRequest, error)
|
||||||
|
UpdateStockRequest(requestID int, status string) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type stockRequestService struct {
|
||||||
|
repo repositories.StockRequestRepository
|
||||||
|
productService ProductService
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewStockRequestService(repo repositories.StockRequestRepository, productService ProductService) StockRequestService {
|
||||||
|
return &stockRequestService{repo: repo, productService: productService}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stockRequestService) CreateStockRequest(req *models.StockRequest) error {
|
||||||
|
return s.repo.CreateStockRequest(req)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stockRequestService) GetStockRequests(tenantID int, locationID int, status string, pageNo int, pageSize int) ([]models.StockRequest, error) {
|
||||||
|
return s.repo.GetStockRequests(tenantID, locationID, status, pageNo, pageSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stockRequestService) UpdateStockRequest(requestID int, status string) error {
|
||||||
|
// If the request is being marked as Received, we need to update the actual store inventory
|
||||||
|
if status == "Received" {
|
||||||
|
req, err := s.repo.GetStockRequestByID(requestID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if req.Status != "Received" { // prevent double receiving
|
||||||
|
stk := models.Productstock{
|
||||||
|
Tenantid: req.Tenantid,
|
||||||
|
Locationid: req.Locationid,
|
||||||
|
Productid: req.Productid,
|
||||||
|
Quantity: req.Qty,
|
||||||
|
Stocktype: "Credit",
|
||||||
|
Stockdate: time.Now(),
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.productService.CreateProductStock([]models.Productstock{stk})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.repo.UpdateStockRequest(requestID, status)
|
||||||
|
}
|
||||||
@@ -17,6 +17,7 @@ type TenantService interface {
|
|||||||
GetTenantPricing(tid, aid int) (models.Tenantpricing, error)
|
GetTenantPricing(tid, aid int) (models.Tenantpricing, error)
|
||||||
UpdateLocation(input models.Tenantlocations) error
|
UpdateLocation(input models.Tenantlocations) error
|
||||||
CreateLocation(data models.Tenantlocations) error
|
CreateLocation(data models.Tenantlocations) error
|
||||||
|
DeleteLocation(locationid int, tenantid int) error
|
||||||
GetStaffs(tid int) ([]models.StaffInfo, error)
|
GetStaffs(tid int) ([]models.StaffInfo, error)
|
||||||
CreateStaff(user models.User) error
|
CreateStaff(user models.User) error
|
||||||
UpdateStaff(user models.User) error
|
UpdateStaff(user models.User) error
|
||||||
@@ -89,6 +90,10 @@ func (s *tenantService) CreateLocation(data models.Tenantlocations) error {
|
|||||||
return s.repo.CreateLocation(data)
|
return s.repo.CreateLocation(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *tenantService) DeleteLocation(locationid int, tenantid int) error {
|
||||||
|
return s.repo.DeleteLocation(locationid, tenantid)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *tenantService) GetStaffs(tid int) ([]models.StaffInfo, error) {
|
func (s *tenantService) GetStaffs(tid int) ([]models.StaffInfo, error) {
|
||||||
return s.repo.GetStaffs(tid)
|
return s.repo.GetStaffs(tid)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -143,6 +143,19 @@ func (s *userService) AppLogin(user models.User) (models.TenantUserInfo, fiber.M
|
|||||||
// ✅ Fetch tenant user info
|
// ✅ Fetch tenant user info
|
||||||
info := s.repo.GetTenantUserById(uid)
|
info := s.repo.GetTenantUserById(uid)
|
||||||
|
|
||||||
|
// ✅ Check if assigned store is inactive
|
||||||
|
if info.Locationid > 0 {
|
||||||
|
storeStatus := s.repo.GetLocationStatus(info.Locationid)
|
||||||
|
if storeStatus == "InActive" {
|
||||||
|
resp := fiber.Map{
|
||||||
|
"status": false,
|
||||||
|
"code": 403,
|
||||||
|
"message": "Assigned store is inactive. Contact admin.",
|
||||||
|
}
|
||||||
|
return models.TenantUserInfo{}, resp, errors.New("inactive store")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ✅ Return success response
|
// ✅ Return success response
|
||||||
resp := fiber.Map{
|
resp := fiber.Map{
|
||||||
"status": true,
|
"status": true,
|
||||||
@@ -247,8 +260,6 @@ func (s *userService) TenantWebLogin(user models.User) (models.TenantUserInfo, m
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
user.Userid = uid
|
|
||||||
|
|
||||||
// Step 4: Update FCM if provided
|
// Step 4: Update FCM if provided
|
||||||
if user.Userfcmtoken != "" {
|
if user.Userfcmtoken != "" {
|
||||||
_ = s.repo.UpdateUserFcmToken(uid, user.Userfcmtoken)
|
_ = s.repo.UpdateUserFcmToken(uid, user.Userfcmtoken)
|
||||||
@@ -257,6 +268,18 @@ func (s *userService) TenantWebLogin(user models.User) (models.TenantUserInfo, m
|
|||||||
// Step 5: Get full tenant info
|
// Step 5: Get full tenant info
|
||||||
info := s.repo.GetTenantUserById(uid)
|
info := s.repo.GetTenantUserById(uid)
|
||||||
|
|
||||||
|
// Step 6: Check if assigned store is inactive
|
||||||
|
if info.Locationid > 0 {
|
||||||
|
storeStatus := s.repo.GetLocationStatus(info.Locationid)
|
||||||
|
if storeStatus == "InActive" {
|
||||||
|
return models.TenantUserInfo{}, map[string]interface{}{
|
||||||
|
"status": false,
|
||||||
|
"code": 403,
|
||||||
|
"message": "Assigned store is inactive. Contact admin.",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return info, map[string]interface{}{
|
return info, map[string]interface{}{
|
||||||
"status": true,
|
"status": true,
|
||||||
"code": 200,
|
"code": 200,
|
||||||
|
|||||||
Reference in New Issue
Block a user