From 7c5be9b5cfdc6f26c38ec51b6f76d624f1a25e18 Mon Sep 17 00:00:00 2001 From: abhishek Date: Fri, 28 Aug 2026 18:19:52 +0530 Subject: [PATCH] bugs fixed --- controllers/orderController.go | 31 +++++++++++++- models/order.go | 72 ++++++++++++++++++--------------- repositories/orderRepository.go | 21 ++++++++-- repositories/userRepository.go | 11 ++++- 4 files changed, 96 insertions(+), 39 deletions(-) diff --git a/controllers/orderController.go b/controllers/orderController.go index e4ce87a..ccd4be7 100644 --- a/controllers/orderController.go +++ b/controllers/orderController.go @@ -350,12 +350,41 @@ func (ctl *OrderController) CreateOrderv3(c *fiber.Ctx) error { data.Deliverytime = time.Now().Format("2006-01-02 15:04:05") } + // An order that does not state its config is an APP order, because that is + // the only kind this endpoint takes. + // + // Every revenue figure in the product filters on `configid = 1` — the + // per-branch summary, the tenant revenue summary, the sales summary and the + // top-locations list all carry it. An order created with configid 0 is + // therefore accepted, deducts stock, appears in the order LIST, and counts + // for nothing in any total: the branch reads zero orders and zero revenue + // while the stock has genuinely moved. + // + // Confirmed against live data before defaulting it: every real order across + // every tenant carries configid 1. Nothing legitimately arrives here as 0, + // so this only ever rescues a caller that forgot the field rather than + // relabelling an order that meant something else. + if data.Configid == 0 { + data.Configid = 1 + } + order, err := ctl.orderService.CreateOrder(data) if err != nil { log.Println("CreateOrder service error:", err) + // A rejected order is not a server fault, and the status code has to say + // so: a client that retries on 5xx will hammer a request that can never + // succeed, while a 4xx tells it to fix the request and stop trying. + // + // "names no outlet" is the caller having omitted locationid, which is + // squarely a bad request. It was falling through to the 500 default — + // right message, wrong class — because only the stock case was mapped. statusCode := http.StatusInternalServerError - if strings.Contains(strings.ToLower(err.Error()), "insufficient stock") { + lowered := strings.ToLower(err.Error()) + switch { + case strings.Contains(lowered, "insufficient stock"): statusCode = http.StatusConflict + case strings.Contains(lowered, "names no outlet"): + statusCode = http.StatusBadRequest } return c.Status(statusCode).JSON(fiber.Map{ "code": statusCode, diff --git a/models/order.go b/models/order.go index 566eecb..777112d 100644 --- a/models/order.go +++ b/models/order.go @@ -70,39 +70,45 @@ func (fs FlexibleString) String() string { } type OrderInfo struct { - Orderheaderid int `json:"orderheaderid"` - Applocationid int `json:"applocationid"` - Applocation string `json:"applocation"` - Tenantid int `json:"tenantid"` - Partnerid int `json:"partnerid"` - Locationid int `json:"locationid"` - Categoryid int `json:"categoryid"` - Subcategoryid int `json:"subcategoryid"` - Moduleid int `json:"moduleid"` - Configid int `json:"configid"` - Orderid string `json:"orderid"` - Orderdate string `json:"orderdate"` - Deliverydate string `json:"deliverydate"` - Orderstatus string `json:"orderstatus"` - Deliverystatus string `json:"deliverystatus"` - Deliveryamt float64 `json:"deliveryamt"` - Itemcount int `json:"itemcount"` - Ordernotes string `json:"ordernotes"` - Kms FlexibleString `json:"kms"` - Actualkms FlexibleString `json:"actualkms"` - Pending string `json:"Pending"` - Processing string `json:"processing"` - Ready string `json:"ready"` - Cancelled string `json:"cancelled"` - Delivered string `json:"delivered"` - Assigntime string `json:"assigntime"` - Starttime string `json:"starttime"` - Arrivaltime string `json:"arrivaltime"` - Pickuptime string `json:"pickuptime"` - Deliverytime string `json:"deliverytime"` - Canceltime string `json:"canceltime"` - Deliverycharge float32 `json:"deliverycharge"` - Orderamount float32 `json:"orderamount"` + Orderheaderid int `json:"orderheaderid"` + Applocationid int `json:"applocationid"` + Applocation string `json:"applocation"` + Tenantid int `json:"tenantid"` + Partnerid int `json:"partnerid"` + Locationid int `json:"locationid"` + Categoryid int `json:"categoryid"` + Subcategoryid int `json:"subcategoryid"` + Moduleid int `json:"moduleid"` + Configid int `json:"configid"` + Orderid string `json:"orderid"` + Orderdate string `json:"orderdate"` + Deliverydate string `json:"deliverydate"` + Orderstatus string `json:"orderstatus"` + Deliverystatus string `json:"deliverystatus"` + Deliveryamt float64 `json:"deliveryamt"` + Itemcount int `json:"itemcount"` + Ordernotes string `json:"ordernotes"` + Kms FlexibleString `json:"kms"` + Actualkms FlexibleString `json:"actualkms"` + Pending string `json:"Pending"` + Processing string `json:"processing"` + Ready string `json:"ready"` + Cancelled string `json:"cancelled"` + Delivered string `json:"delivered"` + Assigntime string `json:"assigntime"` + Starttime string `json:"starttime"` + Arrivaltime string `json:"arrivaltime"` + Pickuptime string `json:"pickuptime"` + Deliverytime string `json:"deliverytime"` + Canceltime string `json:"canceltime"` + Deliverycharge float32 `json:"deliverycharge"` + Orderamount float32 `json:"orderamount"` + // Ordervalue and Taxamount were absent from this struct, so even once the + // query selected them there was nowhere for GORM to put the values. The + // console reads `ordervalue || orderamount || deliveryamt` in that order, + // which means the field it prefers was the one it could never receive. + Ordervalue float32 `json:"ordervalue"` + Taxamount float32 `json:"taxamount"` Customerid int `json:"customerid"` Pickupcustomer string `json:"pickupcustomer"` Pickupcontactno string `json:"pickupcontactno"` diff --git a/repositories/orderRepository.go b/repositories/orderRepository.go index 63d32ff..0a1c7b9 100644 --- a/repositories/orderRepository.go +++ b/repositories/orderRepository.go @@ -42,11 +42,24 @@ func NewOrderRepository(db *gorm.DB) OrderRepository { return &orderRepository{db: db} } +// base backs the tenant and location order lists. +// +// It now selects the MONEY columns, and their absence is why every order in +// the console Sales list read as worth nothing. The values were always stored +// correctly - an order for 3 x 45 carries landingamount 135 on its line and +// orderamount 135 on its header, and the orderdetails query below has always +// selected it. This query simply never asked, so the columns scanned as zero +// and the screen reported that faithfully. +// +// It made a real revenue figure indistinguishable from an order that genuinely +// booked nothing, which is why the historic orders on several tenants all look +// worthless. const ( base = `SELECT DISTINCT a.orderheaderid, a.applocationid, h.locationname AS applocation, a.tenantid, a.locationid, a.partnerid, a.configid, a.categoryid, a.subcategoryid, a.moduleid, a.orderid, a.orderstatus, a.orderdate, a.ordernotes, a.itemcount, a.deliverytime AS deliverydate, - a.pending, a.processing, a.ready, a.delivered AS completed, a.cancelled, + a.pending, a.processing, a.ready, a.delivered AS completed, a.cancelled, a.deliverycharge, a.kms, + a.orderamount, a.ordervalue, a.taxamount, a.ordercharges, a.customerid, a.pickuplocationid, a.pickupaddress, a.pickuplat, a.pickuplong, a.pickupcustomer, a.pickupcontactno, a.pickuplocation as pickupsuburb, a.pickupcity, a.deliveryid AS deliverycustomerid, a.deliveryaddress, a.deliverylat, a.deliverylong, a.deliverytype, @@ -984,7 +997,7 @@ func (r *orderRepository) GetSalesSummary(tid, lid int, fdate, tdate string) (*m totalsQuery := fmt.Sprintf(` SELECT - COALESCE(SUM(COALESCE(ordervalue, 0) + COALESCE(orderamount, 0) + COALESCE(deliveryamt, 0)), 0) AS total_revenue, + COALESCE(SUM(COALESCE(ordervalue, 0) + COALESCE(orderamount, 0)), 0) AS total_revenue, COUNT(orderheaderid) AS total_orders FROM orders WHERE %s`, whereClause) @@ -1016,7 +1029,7 @@ func (r *orderRepository) GetSalesSummary(tid, lid int, fdate, tdate string) (*m chartQuery := fmt.Sprintf(` SELECT CAST(orderdate AS DATE) AS date, - COALESCE(SUM(COALESCE(ordervalue, 0) + COALESCE(orderamount, 0) + COALESCE(deliveryamt, 0)), 0) AS revenue, + COALESCE(SUM(COALESCE(ordervalue, 0) + COALESCE(orderamount, 0)), 0) AS revenue, COUNT(orderheaderid) AS orders FROM orders WHERE %s @@ -1050,7 +1063,7 @@ func (r *orderRepository) GetSalesSummary(tid, lid int, fdate, tdate string) (*m 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 + COALESCE(SUM(COALESCE(o.ordervalue, 0) + COALESCE(o.orderamount, 0)), 0) AS revenue FROM orders o LEFT JOIN tenantlocations l ON o.locationid = l.locationid WHERE %s diff --git a/repositories/userRepository.go b/repositories/userRepository.go index 952f297..4af398a 100644 --- a/repositories/userRepository.go +++ b/repositories/userRepository.go @@ -281,6 +281,15 @@ func (r *userRepository) CreateUser(user models.User) (int, error) { return user.Userid, nil } +// GetUserById reads one person back. +// +// The app_location join is LEFT, not INNER, and that is the whole fix. A user is +// not required to belong to an app location, and an INNER JOIN did not "filter" +// those users — it made them unreadable. CreateUser looks the new row up through +// here to return it, so creating a store user with no applocationid answered 201 +// with userid 0 and every field blank. The user existed and every listing showed +// it; only the response meant to confirm the creation came back empty, which +// reads as a failure that silently succeeded. func (r *userRepository) GetUserById(uid int) (models.UserInfo, error) { var user models.UserInfo @@ -289,7 +298,7 @@ func (r *userRepository) GetUserById(uid int) (models.UserInfo, error) { a.userfcmtoken,a.pin,a.deviceid,a.devicetype,a.tenantid,a.shiftid, a.applocationid,b.locationname as applocation,b.latitude as applatitude,b.longitude as applongitude, b.radius as appradius , concat(c.starttime, ' - ', c.endtime) as shiftname, a.status FROM app_users a - INNER JOIN app_location b on a.applocationid=b.applocationid + LEFT JOIN app_location b on a.applocationid=b.applocationid LEFT JOIN ridershifts c ON a.shiftid = c.shiftid WHERE a.userid= ?`