bugs fixed
This commit is contained in:
@@ -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,
|
||||||
|
|||||||
@@ -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"`
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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= ?`
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user