bugs fixed

This commit is contained in:
2026-08-28 18:19:52 +05:30
parent 40500f936a
commit 7c5be9b5cf
4 changed files with 96 additions and 39 deletions

View File

@@ -350,12 +350,41 @@ func (ctl *OrderController) CreateOrderv3(c *fiber.Ctx) error {
data.Deliverytime = time.Now().Format("2006-01-02 15:04:05") 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) order, err := ctl.orderService.CreateOrder(data)
if err != nil { if err != nil {
log.Println("CreateOrder service error:", err) 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 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 statusCode = http.StatusConflict
case strings.Contains(lowered, "names no outlet"):
statusCode = http.StatusBadRequest
} }
return c.Status(statusCode).JSON(fiber.Map{ return c.Status(statusCode).JSON(fiber.Map{
"code": statusCode, "code": statusCode,

View File

@@ -70,39 +70,45 @@ func (fs FlexibleString) String() string {
} }
type OrderInfo struct { type OrderInfo struct {
Orderheaderid int `json:"orderheaderid"` Orderheaderid int `json:"orderheaderid"`
Applocationid int `json:"applocationid"` Applocationid int `json:"applocationid"`
Applocation string `json:"applocation"` Applocation string `json:"applocation"`
Tenantid int `json:"tenantid"` Tenantid int `json:"tenantid"`
Partnerid int `json:"partnerid"` Partnerid int `json:"partnerid"`
Locationid int `json:"locationid"` Locationid int `json:"locationid"`
Categoryid int `json:"categoryid"` Categoryid int `json:"categoryid"`
Subcategoryid int `json:"subcategoryid"` Subcategoryid int `json:"subcategoryid"`
Moduleid int `json:"moduleid"` Moduleid int `json:"moduleid"`
Configid int `json:"configid"` Configid int `json:"configid"`
Orderid string `json:"orderid"` Orderid string `json:"orderid"`
Orderdate string `json:"orderdate"` Orderdate string `json:"orderdate"`
Deliverydate string `json:"deliverydate"` Deliverydate string `json:"deliverydate"`
Orderstatus string `json:"orderstatus"` Orderstatus string `json:"orderstatus"`
Deliverystatus string `json:"deliverystatus"` Deliverystatus string `json:"deliverystatus"`
Deliveryamt float64 `json:"deliveryamt"` Deliveryamt float64 `json:"deliveryamt"`
Itemcount int `json:"itemcount"` Itemcount int `json:"itemcount"`
Ordernotes string `json:"ordernotes"` Ordernotes string `json:"ordernotes"`
Kms FlexibleString `json:"kms"` Kms FlexibleString `json:"kms"`
Actualkms FlexibleString `json:"actualkms"` Actualkms FlexibleString `json:"actualkms"`
Pending string `json:"Pending"` Pending string `json:"Pending"`
Processing string `json:"processing"` Processing string `json:"processing"`
Ready string `json:"ready"` Ready string `json:"ready"`
Cancelled string `json:"cancelled"` Cancelled string `json:"cancelled"`
Delivered string `json:"delivered"` Delivered string `json:"delivered"`
Assigntime string `json:"assigntime"` Assigntime string `json:"assigntime"`
Starttime string `json:"starttime"` Starttime string `json:"starttime"`
Arrivaltime string `json:"arrivaltime"` Arrivaltime string `json:"arrivaltime"`
Pickuptime string `json:"pickuptime"` Pickuptime string `json:"pickuptime"`
Deliverytime string `json:"deliverytime"` Deliverytime string `json:"deliverytime"`
Canceltime string `json:"canceltime"` Canceltime string `json:"canceltime"`
Deliverycharge float32 `json:"deliverycharge"` Deliverycharge float32 `json:"deliverycharge"`
Orderamount float32 `json:"orderamount"` 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"` Customerid int `json:"customerid"`
Pickupcustomer string `json:"pickupcustomer"` Pickupcustomer string `json:"pickupcustomer"`
Pickupcontactno string `json:"pickupcontactno"` Pickupcontactno string `json:"pickupcontactno"`

View File

@@ -42,11 +42,24 @@ func NewOrderRepository(db *gorm.DB) OrderRepository {
return &orderRepository{db: db} 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 ( 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, 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.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.deliverycharge, a.kms,
a.orderamount, a.ordervalue, a.taxamount, a.ordercharges,
a.customerid, a.pickuplocationid, a.pickupaddress, a.pickuplat, a.pickuplong, a.customerid, a.pickuplocationid, a.pickupaddress, a.pickuplat, a.pickuplong,
a.pickupcustomer, a.pickupcontactno, a.pickuplocation as pickupsuburb, a.pickupcity, a.pickupcustomer, a.pickupcontactno, a.pickuplocation as pickupsuburb, a.pickupcity,
a.deliveryid AS deliverycustomerid, a.deliveryaddress, a.deliverylat, a.deliverylong, a.deliverytype, 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(` totalsQuery := fmt.Sprintf(`
SELECT 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 COUNT(orderheaderid) AS total_orders
FROM orders FROM orders
WHERE %s`, whereClause) WHERE %s`, whereClause)
@@ -1016,7 +1029,7 @@ func (r *orderRepository) GetSalesSummary(tid, lid int, fdate, tdate string) (*m
chartQuery := fmt.Sprintf(` chartQuery := fmt.Sprintf(`
SELECT SELECT
CAST(orderdate AS DATE) AS date, 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 COUNT(orderheaderid) AS orders
FROM orders FROM orders
WHERE %s WHERE %s
@@ -1050,7 +1063,7 @@ func (r *orderRepository) GetSalesSummary(tid, lid int, fdate, tdate string) (*m
cleanTopLocQuery := fmt.Sprintf(` cleanTopLocQuery := fmt.Sprintf(`
SELECT SELECT
COALESCE(l.locationname, 'Unknown') AS locationname, 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 FROM orders o
LEFT JOIN tenantlocations l ON o.locationid = l.locationid LEFT JOIN tenantlocations l ON o.locationid = l.locationid
WHERE %s WHERE %s

View File

@@ -281,6 +281,15 @@ func (r *userRepository) CreateUser(user models.User) (int, error) {
return user.Userid, nil 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) { func (r *userRepository) GetUserById(uid int) (models.UserInfo, error) {
var user models.UserInfo 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.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 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 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 LEFT JOIN ridershifts c ON a.shiftid = c.shiftid
WHERE a.userid= ?` WHERE a.userid= ?`