Merge remote-tracking branch 'origin/main'
This commit is contained in:
@@ -460,9 +460,18 @@ type OfflineSaleItem struct {
|
||||
}
|
||||
|
||||
// OfflineSaleBill is one counter bill — the rows of a spreadsheet grouped by
|
||||
// their billno. Billno is what makes a re-upload of the same file safe: it is
|
||||
// recorded on the order and refused if it is already present for this outlet.
|
||||
// their branch and bill number.
|
||||
//
|
||||
// Locationid is the branch the bill was rung up at, taken from the spreadsheet
|
||||
// row rather than from a store the operator picked in the UI. One workbook can
|
||||
// therefore carry sales for every branch a merchant runs, and each bill's stock
|
||||
// comes out of its own outlet. Bills are grouped per branch, so the same bill
|
||||
// number at two outlets is two separate sales, not a duplicate.
|
||||
//
|
||||
// Billno is what makes a re-upload of the same file safe: it is recorded on the
|
||||
// order and refused if already present for that branch.
|
||||
type OfflineSaleBill struct {
|
||||
Locationid int `json:"locationid"`
|
||||
Billno string `json:"billno"`
|
||||
Saledate string `json:"saledate"`
|
||||
Paymentmode string `json:"paymentmode"`
|
||||
@@ -472,9 +481,16 @@ type OfflineSaleBill struct {
|
||||
Items []OfflineSaleItem `json:"items"`
|
||||
}
|
||||
|
||||
// OfflineSalesUpload is the request body. Locationid is the outlet the sales
|
||||
// belong to and is authorised server-side against Tenantid — a store user
|
||||
// editing the spreadsheet cannot post sales into another branch.
|
||||
// OfflineSalesUpload is the request body.
|
||||
//
|
||||
// Locationid here is a scope constraint, not the destination. Left at 0 the
|
||||
// bills go to whichever branch each one names, which is what a multi-branch
|
||||
// owner uploads. Set to a branch it pins the whole upload to that outlet and
|
||||
// any bill naming a different one is refused — that is how a store user is
|
||||
// held to their own store no matter what the spreadsheet says.
|
||||
//
|
||||
// Every branch referenced is checked against Tenantid regardless, so no upload
|
||||
// can reach an outlet the merchant does not own.
|
||||
type OfflineSalesUpload struct {
|
||||
Tenantid int `json:"tenantid"`
|
||||
Locationid int `json:"locationid"`
|
||||
@@ -492,7 +508,11 @@ const (
|
||||
|
||||
// OfflineSaleResult reports one bill's fate. Bills are independent, so a file
|
||||
// with one bad bill still imports the rest and names exactly what it skipped.
|
||||
// The branch is echoed back because a single upload spans several, and "bill 7
|
||||
// failed" is not actionable without knowing which store it belonged to.
|
||||
type OfflineSaleResult struct {
|
||||
Locationid int `json:"locationid"`
|
||||
Locationname string `json:"locationname"`
|
||||
Billno string `json:"billno"`
|
||||
Status string `json:"status"`
|
||||
Orderid string `json:"orderid"`
|
||||
|
||||
@@ -327,19 +327,27 @@ type ProductLocationRef struct {
|
||||
Productid int
|
||||
}
|
||||
|
||||
// SaleTemplateRow is one line of the downloadable offline-sales spreadsheet:
|
||||
// a product actually stocked at one outlet, with the numbers the person at the
|
||||
// till needs to see before they type a sold quantity against it.
|
||||
// SaleTemplateRow is one line of the downloadable offline-sales spreadsheet: a
|
||||
// product stocked at one branch, with the numbers the person at the till needs
|
||||
// to see before typing a sold quantity against it.
|
||||
//
|
||||
// Tenantid and Locationid ride on every row because one workbook covers every
|
||||
// branch a merchant runs. The row's own Locationid decides which branch's stock
|
||||
// its sale comes out of — a tenant-level import would be wrong, since the same
|
||||
// product is held separately at each outlet.
|
||||
//
|
||||
// Productid is the only field that identifies the product. It cannot be
|
||||
// productsku: across the live catalogue 6,245 products share just 93 distinct
|
||||
// sku values (one tenant has 463 products all carrying sku "1"), and 154 are
|
||||
// blank, so a sku is not a key. Productname is nearly unique per tenant but
|
||||
// not reliably ("rice" appears 6 times for one tenant), so it travels as a
|
||||
// blank, so a sku is not a key. Productname is nearly unique per tenant but not
|
||||
// reliably ("rice" appears 6 times for one tenant), so it travels as a
|
||||
// human-readable confirmation only and is never matched on. That is why the
|
||||
// spreadsheet has to be generated from this endpoint rather than typed from
|
||||
// scratch — the productid column is filled in for the user.
|
||||
// scratch — productid and locationid are filled in for the user.
|
||||
type SaleTemplateRow struct {
|
||||
Tenantid int `json:"tenantid"`
|
||||
Locationid int `json:"locationid"`
|
||||
Locationname string `json:"locationname"`
|
||||
Productid int `json:"productid"`
|
||||
Productname string `json:"productname"`
|
||||
Productunit string `json:"productunit"`
|
||||
@@ -350,15 +358,24 @@ type SaleTemplateRow struct {
|
||||
Taxpercent float64 `json:"taxpercent"`
|
||||
}
|
||||
|
||||
// SaleTemplate is the payload the web app turns into an .xlsx workbook. The
|
||||
// tenant/location identity travels with it so the generated file records which
|
||||
// outlet it belongs to, and the upload can be checked against the file it came
|
||||
// from instead of trusting a hand-typed location.
|
||||
// SaleTemplateLocation is one branch covered by the workbook, so the sheet can
|
||||
// list what it spans and the UI can summarise it without walking every row.
|
||||
type SaleTemplateLocation struct {
|
||||
Locationid int `json:"locationid"`
|
||||
Locationname string `json:"locationname"`
|
||||
Productcount int `json:"productcount"`
|
||||
}
|
||||
|
||||
// SaleTemplate is the payload the web app turns into an .xlsx workbook.
|
||||
//
|
||||
// Locationid is 0 when the template spans every branch of the tenant, which is
|
||||
// the normal case for an owner or admin. A store user gets a template for their
|
||||
// own branch only, and it is then the single entry in Locations.
|
||||
type SaleTemplate struct {
|
||||
Tenantid int `json:"tenantid"`
|
||||
Locationid int `json:"locationid"`
|
||||
Locationname string `json:"locationname"`
|
||||
Products []SaleTemplateRow `json:"products"`
|
||||
Tenantid int `json:"tenantid"`
|
||||
Locationid int `json:"locationid"`
|
||||
Locations []SaleTemplateLocation `json:"locations"`
|
||||
Products []SaleTemplateRow `json:"products"`
|
||||
}
|
||||
|
||||
type ProductSubcategory struct {
|
||||
|
||||
Reference in New Issue
Block a user