new changes
This commit is contained in:
@@ -354,3 +354,35 @@ func (ctl *OrderController) GetCustomerOrders(c *fiber.Ctx) error {
|
|||||||
"data": orders,
|
"data": orders,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ctl *OrderController) GetRevenueSummary(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 && lid == 0 {
|
||||||
|
return c.Status(http.StatusBadRequest).JSON(fiber.Map{
|
||||||
|
"code": http.StatusBadRequest,
|
||||||
|
"message": "Either tenantid or locationid query parameter is required",
|
||||||
|
"status": false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := ctl.orderService.GetRevenueSummary(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,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -438,3 +438,17 @@ type Ordersequences struct {
|
|||||||
Receiptprefix string `json:"receiptprefix" gorm:"default:REC"`
|
Receiptprefix string `json:"receiptprefix" gorm:"default:REC"`
|
||||||
Paymentprefix string `json:"paymentprefix" gorm:"default:PAY"`
|
Paymentprefix string `json:"paymentprefix" gorm:"default:PAY"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TenantRevenueSummary struct {
|
||||||
|
Tenantid int `json:"tenantid"`
|
||||||
|
Tenantname string `json:"tenantname"`
|
||||||
|
OverallRevenue float64 `json:"overallrevenue"`
|
||||||
|
LocationRevenue []LocationRevenueDetails `json:"locationrevenue"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type LocationRevenueDetails struct {
|
||||||
|
Locationid int `json:"locationid"`
|
||||||
|
Locationname string `json:"locationname"`
|
||||||
|
Revenue float64 `json:"revenue"`
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ type OrderRepository interface {
|
|||||||
UpdateOrder(order *models.Orders) error
|
UpdateOrder(order *models.Orders) error
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
type orderRepository struct {
|
type orderRepository struct {
|
||||||
@@ -681,6 +682,102 @@ func (r *orderRepository) GetLocationOrderSummary(tenantID int) ([]models.Orders
|
|||||||
return data, nil
|
return data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *orderRepository) GetRevenueSummary(tid, lid int, fdate, tdate string) (*models.TenantRevenueSummary, error) {
|
||||||
|
var summary models.TenantRevenueSummary
|
||||||
|
|
||||||
|
// 1. If tid is 0 and lid is not 0, lookup the tenantid from tenantlocations
|
||||||
|
if tid == 0 && lid != 0 {
|
||||||
|
var tenantLoc struct {
|
||||||
|
Tenantid int
|
||||||
|
}
|
||||||
|
if err := r.db.Table("tenantlocations").Select("tenantid").Where("locationid = ?", lid).Scan(&tenantLoc).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
tid = tenantLoc.Tenantid
|
||||||
|
}
|
||||||
|
|
||||||
|
if tid == 0 {
|
||||||
|
return nil, fmt.Errorf("tenant ID is required or could not be determined")
|
||||||
|
}
|
||||||
|
|
||||||
|
summary.Tenantid = tid
|
||||||
|
|
||||||
|
// 2. Fetch the tenant name
|
||||||
|
var tenant struct {
|
||||||
|
Tenantname string
|
||||||
|
}
|
||||||
|
if err := r.db.Table("tenants").Select("tenantname").Where("tenantid = ?", tid).Scan(&tenant).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
summary.Tenantname = tenant.Tenantname
|
||||||
|
|
||||||
|
// 3. Fetch overall revenue for this tenant
|
||||||
|
overallQuery := `
|
||||||
|
SELECT COALESCE(SUM(orderamount), 0) AS overall_revenue
|
||||||
|
FROM orders
|
||||||
|
WHERE tenantid = ? AND orderstatus = 'delivered' AND configid = 1
|
||||||
|
`
|
||||||
|
var overallParams []interface{}
|
||||||
|
overallParams = append(overallParams, tid)
|
||||||
|
|
||||||
|
if lid != 0 {
|
||||||
|
overallQuery += " AND locationid = ?"
|
||||||
|
overallParams = append(overallParams, lid)
|
||||||
|
}
|
||||||
|
|
||||||
|
if fdate != "" && tdate != "" {
|
||||||
|
overallQuery += " AND orderdate::date BETWEEN ? AND ?"
|
||||||
|
overallParams = append(overallParams, fdate, tdate)
|
||||||
|
}
|
||||||
|
|
||||||
|
var overallRev float64
|
||||||
|
if err := r.db.Raw(overallQuery, overallParams...).Scan(&overallRev).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
summary.OverallRevenue = overallRev
|
||||||
|
|
||||||
|
// 4. Fetch revenue details by location
|
||||||
|
locationQuery := `
|
||||||
|
SELECT
|
||||||
|
l.locationid,
|
||||||
|
l.locationname,
|
||||||
|
COALESCE(SUM(o.orderamount), 0) AS revenue
|
||||||
|
FROM tenantlocations l
|
||||||
|
LEFT JOIN orders o
|
||||||
|
ON l.locationid = o.locationid
|
||||||
|
AND o.orderstatus = 'delivered'
|
||||||
|
AND o.configid = 1
|
||||||
|
`
|
||||||
|
var locParams []interface{}
|
||||||
|
|
||||||
|
if fdate != "" && tdate != "" {
|
||||||
|
locationQuery += " AND o.orderdate::date BETWEEN ? AND ?"
|
||||||
|
locParams = append(locParams, fdate, tdate)
|
||||||
|
}
|
||||||
|
|
||||||
|
locationQuery += " WHERE l.tenantid = ?"
|
||||||
|
locParams = append(locParams, tid)
|
||||||
|
|
||||||
|
if lid != 0 {
|
||||||
|
locationQuery += " AND l.locationid = ?"
|
||||||
|
locParams = append(locParams, lid)
|
||||||
|
}
|
||||||
|
|
||||||
|
locationQuery += " GROUP BY l.locationid, l.locationname ORDER BY l.locationid"
|
||||||
|
|
||||||
|
var locRevenues []models.LocationRevenueDetails
|
||||||
|
if err := r.db.Raw(locationQuery, locParams...).Scan(&locRevenues).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if locRevenues == nil {
|
||||||
|
locRevenues = []models.LocationRevenueDetails{}
|
||||||
|
}
|
||||||
|
summary.LocationRevenue = locRevenues
|
||||||
|
|
||||||
|
return &summary, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (r *orderRepository) GetDistinctLocations() ([]models.OrderInsight, error) {
|
func (r *orderRepository) GetDistinctLocations() ([]models.OrderInsight, error) {
|
||||||
var locations []models.OrderInsight
|
var locations []models.OrderInsight
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ func RegisterOrderRoutes(api fiber.Router, f *facade.Facade) {
|
|||||||
orders.Get("/getordersummary", f.OrderController.GetOrderSummary)
|
orders.Get("/getordersummary", f.OrderController.GetOrderSummary)
|
||||||
orders.Get("/getlocationsummary", f.OrderController.GetlocationOrderSummary)
|
orders.Get("/getlocationsummary", f.OrderController.GetlocationOrderSummary)
|
||||||
orders.Get("/getorderinsight", f.OrderController.GetOrderInsights)
|
orders.Get("/getorderinsight", f.OrderController.GetOrderInsights)
|
||||||
|
orders.Get("/getrevenuesummary", f.OrderController.GetRevenueSummary)
|
||||||
orders.Get("/getorderdetails", f.OrderController.GetOrderDetails)
|
orders.Get("/getorderdetails", f.OrderController.GetOrderDetails)
|
||||||
orders.Put("/updateorder", f.OrderController.UpdateOrder)
|
orders.Put("/updateorder", f.OrderController.UpdateOrder)
|
||||||
orders.Post("/createorder", f.OrderController.CreateOrderv3)
|
orders.Post("/createorder", f.OrderController.CreateOrderv3)
|
||||||
|
|||||||
82
scratch/check_db.js
Normal file
82
scratch/check_db.js
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
const { Client } = require('pg');
|
||||||
|
|
||||||
|
const client = new Client({
|
||||||
|
host: '66.116.207.225',
|
||||||
|
port: 5433,
|
||||||
|
database: 'nearledb',
|
||||||
|
user: 'admin',
|
||||||
|
password: 'Package@123#',
|
||||||
|
ssl: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
try {
|
||||||
|
await client.connect();
|
||||||
|
console.log('Connected to PostgreSQL successfully!');
|
||||||
|
|
||||||
|
// Let's execute a transaction test to insert the tenant and see the DB error
|
||||||
|
await client.query('BEGIN');
|
||||||
|
try {
|
||||||
|
const query = `
|
||||||
|
INSERT INTO tenants (
|
||||||
|
tenantid, tenantname, configid, partnerid, moduleid, tenanttype,
|
||||||
|
registrationno, tenanttoken, companyname, devicetype, deviceid,
|
||||||
|
firstname, primaryemail, primarycontact, categoryid, subcategoryid,
|
||||||
|
address, suburb, city, state, postcode, latitude, longitude,
|
||||||
|
tenantimage, tenantinfo, paymode1, paymode2, promotion, minorder,
|
||||||
|
applocationid, approved, status, partneruserid
|
||||||
|
) VALUES (
|
||||||
|
$1, $2, $3, $4, $5, $6,
|
||||||
|
$7, $8, $9, $10, $11,
|
||||||
|
$12, $13, $14, $15, $16,
|
||||||
|
$17, $18, $19, $20, $21, $22, $23,
|
||||||
|
$24, $25, $26, $27, $28, $29,
|
||||||
|
$30, $31, $32, $33
|
||||||
|
)
|
||||||
|
`;
|
||||||
|
const values = [
|
||||||
|
273, "Suriya Store", 1, 1, 2, "Retail",
|
||||||
|
"REG-SURIYA-273", "fcm_token_suriya_273", "Suriya Enterprises", "Android", "device-uuid-9876543210",
|
||||||
|
"Suriya", "suriya@example.com", "9876543212", 1, 2,
|
||||||
|
"12, DB Road, RS Puram", "RS Puram", "Coimbatore", "Tamil Nadu", "641002", "11.0118", "76.9456",
|
||||||
|
"https://example.com/suriya_store.jpg", "Groceries and essentials in RS Puram, Coimbatore", 1, 1, 0, 10,
|
||||||
|
1, 0, "Active", 0
|
||||||
|
];
|
||||||
|
|
||||||
|
await client.query(query, values);
|
||||||
|
console.log('Tenant insert succeeded!');
|
||||||
|
|
||||||
|
// Let's also try to insert the tenantlocation
|
||||||
|
const locQuery = `
|
||||||
|
INSERT INTO tenantlocations (
|
||||||
|
tenantid, applocationid, moduleid, locationname, email, contactno,
|
||||||
|
latitude, longitude, address, suburb, city, state, postcode,
|
||||||
|
opentime, closetime, partnerid, deliveryradius, deliverymins, cancelsecs, status
|
||||||
|
) VALUES (
|
||||||
|
$1, $2, $3, $4, $5, $6,
|
||||||
|
$7, $8, $9, $10, $11, $12, $13,
|
||||||
|
$14, $15, $16, $17, $18, $19, $20
|
||||||
|
)
|
||||||
|
`;
|
||||||
|
const locValues = [
|
||||||
|
273, 1, 2, "Suriya Store RS Puram", "rspuram@suriya.com", "9876543210",
|
||||||
|
"11.0118", "76.9456", "12, DB Road, RS Puram", "RS Puram", "Coimbatore", "Tamil Nadu", "641002",
|
||||||
|
"08:00", "22:00", 1, 5, 30, 120, "Active"
|
||||||
|
];
|
||||||
|
await client.query(locQuery, locValues);
|
||||||
|
console.log('Location insert succeeded!');
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
console.error('SQL Error during insert:', e.message, e.detail || '');
|
||||||
|
} finally {
|
||||||
|
await client.query('ROLLBACK');
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Error connecting:', err);
|
||||||
|
} finally {
|
||||||
|
await client.end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main();
|
||||||
92
scratch/check_db_schema.go
Normal file
92
scratch/check_db_schema.go
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
_ "github.com/jackc/pgx/v5/stdlib"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
dsn := "host=66.116.207.225 port=5433 user=admin password=Package@123# dbname=nearledb sslmode=disable"
|
||||||
|
db, err := sql.Open("pgx", dsn)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Error opening db connection: %v", err)
|
||||||
|
}
|
||||||
|
defer db.Close()
|
||||||
|
|
||||||
|
err = db.Ping()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Error pinging db: %v", err)
|
||||||
|
}
|
||||||
|
fmt.Println("Connected successfully to PostgreSQL!")
|
||||||
|
|
||||||
|
// 1. Group users by roleid
|
||||||
|
query1 := `
|
||||||
|
SELECT roleid, COUNT(*), MIN(authname) AS sample_user
|
||||||
|
FROM app_users
|
||||||
|
GROUP BY roleid
|
||||||
|
ORDER BY roleid;
|
||||||
|
`
|
||||||
|
rows1, err := db.Query(query1)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Query1 error: %v", err)
|
||||||
|
}
|
||||||
|
defer rows1.Close()
|
||||||
|
|
||||||
|
fmt.Println("\n--- USER COUNTS BY ROLEID ---")
|
||||||
|
for rows1.Next() {
|
||||||
|
var roleid sql.NullInt64
|
||||||
|
var count int
|
||||||
|
var sampleUser sql.NullString
|
||||||
|
if err := rows1.Scan(&roleid, &count, &sampleUser); err != nil {
|
||||||
|
log.Fatalf("Row scan error: %v", err)
|
||||||
|
}
|
||||||
|
fmt.Printf("Role ID: %5d | Count: %5d | Sample User: %s\n", roleid.Int64, count, sampleUser.String)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Fetch list of tables matching 'rider' or 'pool'
|
||||||
|
query2 := `
|
||||||
|
SELECT table_name
|
||||||
|
FROM information_schema.tables
|
||||||
|
WHERE table_name LIKE '%rider%' OR table_name LIKE '%pool%' OR table_name LIKE '%staff%';
|
||||||
|
`
|
||||||
|
rows2, err := db.Query(query2)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Query2 error: %v", err)
|
||||||
|
}
|
||||||
|
defer rows2.Close()
|
||||||
|
|
||||||
|
fmt.Println("\n--- RIDER/POOL/STAFF TABLES ---")
|
||||||
|
for rows2.Next() {
|
||||||
|
var tableName string
|
||||||
|
if err := rows2.Scan(&tableName); err != nil {
|
||||||
|
log.Fatalf("Row scan error: %v", err)
|
||||||
|
}
|
||||||
|
fmt.Println("Table Name:", tableName)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Check triggers on app_users
|
||||||
|
query3 := `
|
||||||
|
SELECT tgname, tgtype, pg_get_triggerdef(pg_trigger.oid)
|
||||||
|
FROM pg_trigger
|
||||||
|
JOIN pg_class ON pg_class.oid = tgrelid
|
||||||
|
WHERE relname = 'app_users';
|
||||||
|
`
|
||||||
|
rows3, err := db.Query(query3)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Query3 error: %v", err)
|
||||||
|
}
|
||||||
|
defer rows3.Close()
|
||||||
|
|
||||||
|
fmt.Println("\n--- TRIGGERS ON app_users ---")
|
||||||
|
for rows3.Next() {
|
||||||
|
var tgname, tgdef string
|
||||||
|
var tgtype int
|
||||||
|
if err := rows3.Scan(&tgname, &tgtype, &tgdef); err != nil {
|
||||||
|
log.Fatalf("Row scan error: %v", err)
|
||||||
|
}
|
||||||
|
fmt.Printf("Trigger: %s | Type: %d | Def: %s\n", tgname, tgtype, tgdef)
|
||||||
|
}
|
||||||
|
}
|
||||||
45
scratch/check_user_schema.js
Normal file
45
scratch/check_user_schema.js
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
const { Client } = require('pg');
|
||||||
|
|
||||||
|
const client = new Client({
|
||||||
|
host: '66.116.207.225',
|
||||||
|
port: 5433,
|
||||||
|
database: 'nearledb',
|
||||||
|
user: 'admin',
|
||||||
|
password: 'Package@123#',
|
||||||
|
ssl: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
try {
|
||||||
|
await client.connect();
|
||||||
|
console.log('Connected to PostgreSQL successfully!');
|
||||||
|
|
||||||
|
// Get information about columns in app_users
|
||||||
|
const colsRes = await client.query(`
|
||||||
|
SELECT column_name, data_type, is_nullable, column_default
|
||||||
|
FROM information_schema.columns
|
||||||
|
WHERE table_name = 'app_users'
|
||||||
|
ORDER BY ordinal_position;
|
||||||
|
`);
|
||||||
|
|
||||||
|
console.log('\n--- COLUMN SCHEMA FOR app_users ---');
|
||||||
|
console.table(colsRes.rows);
|
||||||
|
|
||||||
|
// Also get indices / constraints
|
||||||
|
const constraintsRes = await client.query(`
|
||||||
|
SELECT conname, pg_get_constraintdef(c.oid)
|
||||||
|
FROM pg_constraint c
|
||||||
|
JOIN pg_namespace n ON n.oid = c.connamespace
|
||||||
|
WHERE conrelid = 'app_users'::regclass;
|
||||||
|
`);
|
||||||
|
console.log('\n--- CONSTRAINTS FOR app_users ---');
|
||||||
|
console.table(constraintsRes.rows);
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Error:', err);
|
||||||
|
} finally {
|
||||||
|
await client.end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main();
|
||||||
@@ -20,7 +20,7 @@ type OrderService 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)
|
||||||
GetTenantLocationOrders(input models.DeliveryQuery) ([]models.OrderInfo, error)
|
GetTenantLocationOrders(input models.DeliveryQuery) ([]models.OrderInfo, error)
|
||||||
|
GetRevenueSummary(tid, lid int, fdate, tdate string) (*models.TenantRevenueSummary, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type orderService struct {
|
type orderService struct {
|
||||||
@@ -86,3 +86,8 @@ func (s *orderService) GetCustomerOrdersv3(customerID, tenantID, moduleID, fromD
|
|||||||
func (s *orderService) GetTenantLocationOrders(input models.DeliveryQuery) ([]models.OrderInfo, error) {
|
func (s *orderService) GetTenantLocationOrders(input models.DeliveryQuery) ([]models.OrderInfo, error) {
|
||||||
return s.repo.GetTenantLocationOrders(input)
|
return s.repo.GetTenantLocationOrders(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *orderService) GetRevenueSummary(tid, lid int, fdate, tdate string) (*models.TenantRevenueSummary, error) {
|
||||||
|
return s.repo.GetRevenueSummary(tid, lid, fdate, tdate)
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user