Browse Source

refactoring: ProductVariant

Alexey Kim 2 năm trước cách đây
mục cha
commit
f50b5a907d
2 tập tin đã thay đổi với 79 bổ sung80 xóa
  1. 35 18
      db/clickhouse.go
  2. 44 62
      relation/product_variant.go

+ 35 - 18
db/clickhouse.go

@@ -184,29 +184,46 @@ func (db *clickhouse) ProductOptions(ln model.LanguageCode, id string) ([]*gener
 
 func (db *clickhouse) ProductVariants(ctx *middleware.GShopifyContext, id string) ([]*generated.ProductVariant, error) {
 	var (
-		variants []*generated.ProductVariant
-		key      = productVariantKey("product_id=?", id)
-		l        = ttlcache.LoaderFunc[string, any](
+		variants  []*generated.ProductVariant
+		selection = []string{
+			"any(t.id) as id",
+			"any(t.product_id) as product_id",
+			"any(t.inventory_item_id) as inventory_item_id",
+			fmt.Sprintf("any(t.price['%s']) as price", defaultCurrency),
+			fmt.Sprintf("any(t.compare_at_price['%s']) as compare_at_price", defaultCurrency),
+			"any(t.position) as position",
+			"any(t.image) as image",
+			"any(t.inventory_management) as inventory_management",
+			"any(t.inventory_policy) as inventory_policy",
+			"any(t.options) as options",
+			"any(t.grams) as grams",
+			"any(t.weight) as weight",
+			"any(t.weight_unit) as weight_unit",
+			"any(t.created_at) as created_at",
+			"any(t.updated_at) as updated_at",
+			"any(t.published_at) as published_at",
+			"any(t.deleted_at) as deleted_at",
+			"sum(inventory_level.available) as available",
+			fmt.Sprintf("any(product.title['%s']) as title", ctx.Language),
+			"any(inventory_item.sku) as sku",
+			"any(inventory_item.barcode) as barcode",
+			"any(inventory_item.requires_shipping) as requires_shipping",
+			"any(inventory_item.tracked) as tracked",
+			"if(tracked, if(available > 0, true, if(inventory_policy == 'continue', true, false)), false) as for_sale",
+		}
+		key = productVariantKey("t.product_id=?", id)
+		l   = ttlcache.LoaderFunc[string, any](
 			func(ttl *ttlcache.Cache[string, any], _ string) *ttlcache.Item[string, any] {
 				var o []relation.ProductVariant
 				rows, err := db.session.
-					Select(
-						"t.id as id", "t.product_id as product_id", "t.options as options",
-						fmt.Sprintf("t.price['%s'] as price", defaultCurrency),
-						fmt.Sprintf("t.unit_price['%s'] as unit_price", defaultCurrency),
-						fmt.Sprintf("t.compare_at_price['%s'] as compare_at_price", defaultCurrency),
-						"t.barcode as barcode", "t.sku as sku", "t.hs_code as hs_code", "t.origin_country as origin_country",
-						"t.allow_backorder as allow_backorder", "t.manage_inventory as manage_inventory", "t.unit_price_measurement as unit_price_measurement",
-						"t.weight as weight", "t.wight_unit as weight_unit",
-						"t.created_at as created_at", "t.updated_at as updated_at", "t.deleted_at as deleted_at",
-						"shopping_profile.type as type",
-						ctx.Language.SqlFieldSelection("title", "t"),
-					).
+					Select(selection...).
 					From(fmt.Sprintf("%s as t", key.Table())).
-					Where(key.Clause(), key.Args()...).
 					LeftJoin("product", "product.id = t.product_id").
-					LeftJoin("shopping_profile", "product.profile_id = shopping_profile.id").
-					OrderBy("t.created_at").
+					LeftJoin("inventory_item", "inventory_item.id = t.inventory_item_id").
+					LeftJoin("inventory_level", "inventory_level.inventory_item_id = t.inventory_item_id").
+					Where(key.Clause(), key.Args()...).
+					OrderBy("position").
+					GroupBy("t.id").
 					Load(&o)
 				if rows < 1 || err != nil {
 					return nil

+ 44 - 62
relation/product_variant.go

@@ -9,86 +9,68 @@ import (
 )
 
 type ProductVariant struct {
-	Id        string `db:"id"`
-	ProductId string `db:"product_id"`
-	Title     string `db:"title"`
-	Options   []struct {
+	Id                  string          `db:"id"`
+	ProductId           string          `db:"product_id"`
+	InventoryItemId     string          `db:"inventory_item_id"`
+	Price               float64         `db:"price"`
+	CompareAtPrice      float64         `db:"compare_at_price"`
+	Position            int8            `db:"position"`
+	Image               dbr.NullString  `db:"image"`
+	InventoryManagement string          `db:"inventory_management"`
+	InventoryPolicy     string          `db:"inventory_policy"`
+	Grams               dbr.NullFloat64 `db:"grams"`
+	Weight              dbr.NullFloat64 `db:"weight"`
+	WeightUnit          string          `db:"weight_unit"`
+	CreatedAt           time.Time       `db:"created_at"`
+	UpdatedAt           time.Time       `db:"updated_at"`
+	PublishedAt         *time.Time      `db:"published_at"`
+	DeletedAt           *time.Time      `db:"deleted_at"`
+	Options             []struct {
 		Field0 string
 		Field1 int32
 	} `db:"options"`
-	Price                float64        `db:"price"`
-	UnitPrice            float64        `db:"unit_price"`
-	CompareAtPrice       float64        `db:"compare_at_price"`
-	Barcode              dbr.NullString `db:"barcode"`
-	Sku                  dbr.NullString `db:"sku"`
-	HarmonizedSystemCode dbr.NullString `db:"hs_code"`
-	AllowBackorder       bool           `db:"allow_backorder"`
-	ManageInventory      bool           `db:"manage_inventory"`
-	OriginCountry        dbr.NullString `db:"origin_country"`
-	UnitPriceMeasurement struct {
-		Field0 string
-		Field1 string
-		Field2 float64
-		Field3 string
-		Field4 int32
-	} `db:"unit_price_measurement"`
-	Weight     dbr.NullFloat64 `db:"weight"`
-	WeightUnit string          `db:"weight_unit"`
-	CreatedAt  time.Time       `db:"created_at"`
-	UpdatedAt  time.Time       `db:"updated_at"`
-	DeletedAt  *time.Time      `db:"deleted_at"`
 
-	ShoppingProfileType dbr.NullString `db:"type"`
+	Title             string         `db:"title"`
+	Sku               dbr.NullString `db:"sku"`
+	Barcode           dbr.NullString `db:"barcode"`
+	RequiresShipping  bool           `db:"requires_shipping"`
+	QuantityAvailable int            `db:"available"`
+	ForSale           bool           `db:"for_sale"`
 }
 
 func (v *ProductVariant) As() *generated.ProductVariant {
 	variant := generated.ProductVariant{
-		AvailableForSale:    false,
-		CurrentlyNotInStock: false,
-		QuantityAvailable:   nil,
-		Image:               nil,
-		SelectedOptions:     nil,
+		AvailableForSale:    v.ForSale,
+		CurrentlyNotInStock: v.QuantityAvailable <= 0,
 
-		ID:               model.NewId(model.GidVariant, v.Id),
-		Title:            v.Title,
-		Product:          &generated.Product{ID: model.NewId(model.GidProduct, v.ProductId)},
-		RequiresShipping: true,
+		Image:                nil,
+		SelectedOptions:      nil,
+		UnitPrice:            nil,
+		UnitPriceMeasurement: nil,
 
-		Price: &generated.MoneyV2{
-			Amount:       scalar.NewDecimal(v.Price),
-			CurrencyCode: generated.CurrencyCodeUsd,
-		},
 		CompareAtPrice: &generated.MoneyV2{
 			Amount:       scalar.NewDecimal(v.CompareAtPrice),
 			CurrencyCode: generated.CurrencyCodeUsd,
 		},
-		UnitPrice: &generated.MoneyV2{
-			Amount:       scalar.NewDecimal(v.UnitPrice),
-			CurrencyCode: generated.CurrencyCodeUsd,
-		},
 
-		UnitPriceMeasurement: &generated.UnitPriceMeasurement{
-			QuantityValue:  v.UnitPriceMeasurement.Field2,
-			ReferenceValue: int(v.UnitPriceMeasurement.Field4),
+		ID: model.NewId(model.GidVariant, v.Id),
+		Price: &generated.MoneyV2{
+			Amount:       scalar.NewDecimal(v.Price),
+			CurrencyCode: generated.CurrencyCodeUsd,
 		},
-		WeightUnit: generated.WeightUnit(v.WeightUnit),
-	}
-
-	if enum := model.ShoppingProfileType(v.ShoppingProfileType.String); enum.IsValid() {
-		variant.RequiresShipping = model.ShoppingProfileTypeDefault == enum
-	}
-
-	if enum := generated.UnitPriceMeasurementMeasuredType(v.UnitPriceMeasurement.Field0); enum.IsValid() {
-		variant.UnitPriceMeasurement.MeasuredType = &enum
-	}
-
-	if enum := generated.UnitPriceMeasurementMeasuredUnit(v.UnitPriceMeasurement.Field1); enum.IsValid() {
-		variant.UnitPriceMeasurement.QuantityUnit = &enum
+		Product:           &generated.Product{ID: model.NewId(model.GidProduct, v.ProductId)},
+		QuantityAvailable: &v.QuantityAvailable,
+		RequiresShipping:  v.RequiresShipping,
+		Title:             v.Title,
+		WeightUnit:        generated.WeightUnit(v.WeightUnit),
 	}
 
-	if enum := generated.UnitPriceMeasurementMeasuredUnit(v.UnitPriceMeasurement.Field3); enum.IsValid() {
-		variant.UnitPriceMeasurement.ReferenceUnit = &enum
-	}
+	variant.Metafields = append(variant.Metafields, &generated.Metafield{
+		Namespace: model.GidVariant.String(),
+		Key:       "position",
+		Type:      model.MetaFieldTypeNumberInteger.String(),
+		Value:     model.MetaFieldValue(model.MetaFieldTypeNumberInteger, v.Position),
+	})
 
 	if v.Weight.Valid {
 		s := v.Weight.Float64