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")
}
// 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,

View File

@@ -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"`

View File

@@ -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

View File

@@ -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= ?`