Add read endpoints for counter sales
The ingest only ever wrote. A bill that reached pos_orders was safe and completely unreachable — no screen in the product could show it, and the only way to see a day's counter takings was to query the database by hand. Three endpoints: a paged bill list, one bill with its lines, and a summary split the three ways somebody actually asks for — by tender for reconciling a drawer, by day for a chart, by till for an outlet running several counters. locationid is required on all of them and is the authorisation boundary, so a caller cannot page through another shop's takings by omitting a parameter. Fetching a bill under the wrong outlet returns 404 even when the reference is a real one. Dates match businessdate rather than arrival, because a till that was offline overnight uploads yesterday's bills this morning and they belong to yesterday. The list is ordered by billedat for the same reason — sorting by arrival would interleave a recovered backlog through today. Unlike the ingest handlers these answer in the usual envelope: they are read by the web app, not by a terminal, and nothing about them is bound to the till's contract. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -136,3 +136,74 @@ type PosOrderItems struct {
|
||||
func (PosOrderItems) TableName() string {
|
||||
return "pos_order_items"
|
||||
}
|
||||
|
||||
// PosSalesFilter scopes a query over counter sales.
|
||||
//
|
||||
// Locationid is required and is the authorisation boundary — every read is
|
||||
// scoped to one outlet, so a caller cannot page through another shop's takings
|
||||
// by omitting a parameter.
|
||||
type PosSalesFilter struct {
|
||||
Locationid int
|
||||
Fromdate string // YYYY-MM-DD, matched against businessdate
|
||||
Todate string
|
||||
Terminalid string
|
||||
Cashiername string
|
||||
Paymentmode string
|
||||
Pageno int
|
||||
Pagesize int
|
||||
}
|
||||
|
||||
// PosSalesPage is one page of bills, with the total so a caller can paginate
|
||||
// without a second request.
|
||||
type PosSalesPage struct {
|
||||
Total int64 `json:"total"`
|
||||
Pageno int `json:"pageno"`
|
||||
Pagesize int `json:"pagesize"`
|
||||
Bills []PosOrders `json:"bills"`
|
||||
}
|
||||
|
||||
// PosSalesSummary totals a range of counter sales.
|
||||
//
|
||||
// Deliberately separate from the bill list: a shop settling a till wants the
|
||||
// figures, not five hundred rows, and computing them client-side would mean
|
||||
// fetching every page first.
|
||||
type PosSalesSummary struct {
|
||||
Locationid int `json:"locationid"`
|
||||
Fromdate string `json:"fromdate"`
|
||||
Todate string `json:"todate"`
|
||||
Billcount int `json:"billcount"`
|
||||
Itemcount int `json:"itemcount"`
|
||||
Grosssales float64 `json:"grosssales"`
|
||||
Taxcollected float64 `json:"taxcollected"`
|
||||
Discount float64 `json:"discountgiven"`
|
||||
Roundoff float64 `json:"roundoff"`
|
||||
Averagebill float64 `json:"averagebill"`
|
||||
|
||||
// What a cashier reconciles the drawer against.
|
||||
Bypaymentmode []PosPaymentTotal `json:"bypaymentmode"`
|
||||
|
||||
// One row per trading day, for a chart.
|
||||
Byday []PosDayTotal `json:"byday"`
|
||||
|
||||
// Which tills contributed, so an outlet with several counters can see them
|
||||
// apart without a second query.
|
||||
Byterminal []PosTerminalTotal `json:"byterminal"`
|
||||
}
|
||||
|
||||
type PosPaymentTotal struct {
|
||||
Paymentmode string `json:"paymentmode"`
|
||||
Billcount int `json:"billcount"`
|
||||
Amount float64 `json:"amount"`
|
||||
}
|
||||
|
||||
type PosDayTotal struct {
|
||||
Businessdate string `json:"businessdate"`
|
||||
Billcount int `json:"billcount"`
|
||||
Amount float64 `json:"amount"`
|
||||
}
|
||||
|
||||
type PosTerminalTotal struct {
|
||||
Terminalid string `json:"terminalid"`
|
||||
Billcount int `json:"billcount"`
|
||||
Amount float64 `json:"amount"`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user