From f220c24c172b39306d9857468773bcba3135be62 Mon Sep 17 00:00:00 2001 From: Suriya Date: Wed, 1 Jul 2026 10:53:57 +0530 Subject: [PATCH] new changes --- controllers/orderController.go | 32 +++++++++++ models/order.go | 14 +++++ repositories/orderRepository.go | 97 +++++++++++++++++++++++++++++++++ routes/orderroutes.go | 1 + scratch/check_db.js | 82 ++++++++++++++++++++++++++++ scratch/check_db_schema.go | 92 +++++++++++++++++++++++++++++++ scratch/check_user_schema.js | 45 +++++++++++++++ services/orderService.go | 7 ++- 8 files changed, 369 insertions(+), 1 deletion(-) create mode 100644 scratch/check_db.js create mode 100644 scratch/check_db_schema.go create mode 100644 scratch/check_user_schema.js diff --git a/controllers/orderController.go b/controllers/orderController.go index ec987cf..f1b4824 100644 --- a/controllers/orderController.go +++ b/controllers/orderController.go @@ -354,3 +354,35 @@ func (ctl *OrderController) GetCustomerOrders(c *fiber.Ctx) error { "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, + }) +} + diff --git a/models/order.go b/models/order.go index 7f54691..f54d803 100644 --- a/models/order.go +++ b/models/order.go @@ -438,3 +438,17 @@ type Ordersequences struct { Receiptprefix string `json:"receiptprefix" gorm:"default:REC"` 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"` +} + diff --git a/repositories/orderRepository.go b/repositories/orderRepository.go index d884279..2675ed8 100644 --- a/repositories/orderRepository.go +++ b/repositories/orderRepository.go @@ -25,6 +25,7 @@ type OrderRepository interface { UpdateOrder(order *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) + GetRevenueSummary(tid, lid int, fdate, tdate string) (*models.TenantRevenueSummary, error) } type orderRepository struct { @@ -681,6 +682,102 @@ func (r *orderRepository) GetLocationOrderSummary(tenantID int) ([]models.Orders 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) { var locations []models.OrderInsight diff --git a/routes/orderroutes.go b/routes/orderroutes.go index 9e08bfe..9a06f2e 100644 --- a/routes/orderroutes.go +++ b/routes/orderroutes.go @@ -19,6 +19,7 @@ func RegisterOrderRoutes(api fiber.Router, f *facade.Facade) { orders.Get("/getordersummary", f.OrderController.GetOrderSummary) orders.Get("/getlocationsummary", f.OrderController.GetlocationOrderSummary) orders.Get("/getorderinsight", f.OrderController.GetOrderInsights) + orders.Get("/getrevenuesummary", f.OrderController.GetRevenueSummary) orders.Get("/getorderdetails", f.OrderController.GetOrderDetails) orders.Put("/updateorder", f.OrderController.UpdateOrder) orders.Post("/createorder", f.OrderController.CreateOrderv3) diff --git a/scratch/check_db.js b/scratch/check_db.js new file mode 100644 index 0000000..08c642b --- /dev/null +++ b/scratch/check_db.js @@ -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(); diff --git a/scratch/check_db_schema.go b/scratch/check_db_schema.go new file mode 100644 index 0000000..6802f56 --- /dev/null +++ b/scratch/check_db_schema.go @@ -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) + } +} diff --git a/scratch/check_user_schema.js b/scratch/check_user_schema.js new file mode 100644 index 0000000..dde378a --- /dev/null +++ b/scratch/check_user_schema.js @@ -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(); diff --git a/services/orderService.go b/services/orderService.go index c4f6ab1..7ea3e38 100644 --- a/services/orderService.go +++ b/services/orderService.go @@ -20,7 +20,7 @@ type OrderService interface { CreateOrder(order models.Orders) (models.Orders, error) GetCustomerOrdersv3(customerID, tenantID, moduleID, fromDate, toDate, orderStatus, keyword string, pageSize, offset int) ([]models.CustomerOrder, error) GetTenantLocationOrders(input models.DeliveryQuery) ([]models.OrderInfo, error) - + GetRevenueSummary(tid, lid int, fdate, tdate string) (*models.TenantRevenueSummary, error) } 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) { 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) +} +