product variant id
This commit is contained in:
@@ -36,14 +36,48 @@ type ProductCategory struct {
|
||||
Updated time.Time `json:"updated"`
|
||||
}
|
||||
|
||||
// One size of one product — "500ml" hanging under the parent "Coke".
|
||||
//
|
||||
// The table always had the two columns that make this a relationship rather
|
||||
// than a list of words: `productid` names the PARENT, `variantproductid` names
|
||||
// the product a shopper actually orders when they pick this size. Neither was
|
||||
// mapped here, so nothing could read or write them: `createproductvariant`
|
||||
// wrote rows with no parent, and `getproductvariants` returned a flat
|
||||
// per-tenant list of names. Measured 2026-09-02 across ten tenants: two rows
|
||||
// existed on the whole platform, named "testing" and "demo", attached to
|
||||
// nothing.
|
||||
//
|
||||
// The consequence is the ordering bug. With no way to attach a variant to a
|
||||
// product, the app had only `products.variants` — a bare group number, 0 on
|
||||
// every product — to go on.
|
||||
type Productvariant struct {
|
||||
Variantid int `json:"variantid" gorm:"Primary_Key"`
|
||||
Tenantid int `json:"tenantid"`
|
||||
Variantname string `json:"variantname"`
|
||||
Variantid int `json:"variantid" gorm:"primaryKey;autoIncrement"`
|
||||
Tenantid int `json:"tenantid"`
|
||||
|
||||
// The parent. A variant is meaningless without one, so this is what
|
||||
// AddProductVariant refuses to accept as zero.
|
||||
Productid int `json:"productid"`
|
||||
|
||||
// The product to actually put in the basket for this size. It is a real
|
||||
// product row, so it carries its own price, stock and barcode — which is
|
||||
// why a variant does not need to duplicate any of them.
|
||||
Variantproductid int `json:"variantproductid"`
|
||||
|
||||
Variantname string `json:"variantname"`
|
||||
Varianttype string `json:"varianttype,omitempty"`
|
||||
Price float64 `json:"price,omitempty"`
|
||||
|
||||
Categoryid int `json:"categoryid" gorm:"default:0"`
|
||||
Categoryname string `json:"categoryname" gorm:"-"`
|
||||
Subcategoryid int `json:"subcategoryid"`
|
||||
Status string `json:"status" gorm:"default:active"`
|
||||
Status string `json:"status" gorm:"default:Active"`
|
||||
|
||||
// Read-only, from the variant's own product row. The app needs a name and a
|
||||
// price to draw a size picker; without these it would have to fetch each
|
||||
// variant separately to render one screen.
|
||||
Variantproductname string `json:"variantproductname" gorm:"->"`
|
||||
Variantprice float64 `json:"variantprice" gorm:"->"`
|
||||
Variantstock int `json:"variantstock" gorm:"->"`
|
||||
}
|
||||
|
||||
type Products struct {
|
||||
@@ -107,7 +141,20 @@ type Products struct {
|
||||
Productstock int `json:"productstock" gorm:"default:0"`
|
||||
Productcombo int `json:"productcombo" gorm:"default:0"`
|
||||
Variants int `json:"variants" gorm:"default:0"`
|
||||
Quantity int `json:"quantity"`
|
||||
|
||||
// The sizes hanging under this product, so one call draws the whole screen.
|
||||
//
|
||||
// A separate field from `Variants` above, which is the legacy group NUMBER
|
||||
// and stays exactly as it was — renaming it would break every caller, and it
|
||||
// is still what an old client reads. This is the list.
|
||||
//
|
||||
// Always present, and EMPTY for a product with no sizes. That is the case
|
||||
// that matters: an empty list is a complete answer meaning "order this one
|
||||
// directly", which is what lets the app proceed instead of stalling on a
|
||||
// choice that does not exist.
|
||||
Variantoptions []Productvariant `json:"variantoptions" gorm:"-"`
|
||||
|
||||
Quantity int `json:"quantity"`
|
||||
// Price is the EFFECTIVE selling price at the location a query was scoped
|
||||
// to: productlocations.price when the store has set one, otherwise the
|
||||
// master Retailprice below. Read-only — it is computed by the query, never
|
||||
|
||||
Reference in New Issue
Block a user