Browse Source

Sort & Filters

Alexey Kim 2 years ago
parent
commit
91595ba8ce
2 changed files with 81 additions and 25 deletions
  1. 78 22
      graphql/helper/product.go
  2. 3 3
      graphql/query_product.go

+ 78 - 22
graphql/helper/product.go

@@ -9,7 +9,7 @@ import (
 )
 
 func NewProductConnection(src []*generated.Product,
-	after *string, before *string, first *int, last *int, reverse *bool, sortKey *generated.ProductCollectionSortKeys) (*generated.ProductConnection, error) {
+	after *string, before *string, first *int, last *int, reverse *bool) (*generated.ProductConnection, error) {
 	var (
 		connection = &generated.ProductConnection{}
 		err        error
@@ -23,27 +23,6 @@ func NewProductConnection(src []*generated.Product,
 		src = fun.Reverse(src)
 	}
 
-	//TODO: ProductCollectionSortKeysBestSelling
-	//TODO: ProductCollectionSortKeysCollectionDefault
-	//TODO: ProductCollectionSortKeysManual
-	//TODO: ProductCollectionSortKeysRelevance
-	if sortKey != nil && sortKey.IsValid() {
-		sort.Slice(src[:], func(i, j int) bool {
-			switch *sortKey {
-			case generated.ProductCollectionSortKeysID:
-				return src[i].ID < src[j].ID
-			case generated.ProductCollectionSortKeysTitle:
-				return src[i].Title < src[j].Title
-			case generated.ProductCollectionSortKeysCreated:
-				return src[i].CreatedAt < src[j].CreatedAt
-			case generated.ProductCollectionSortKeysPrice:
-				return src[i].PriceRange.MinVariantPrice.Amount < src[j].PriceRange.MinVariantPrice.Amount
-			}
-
-			return false
-		})
-	}
-
 	connection.Nodes = src[:]
 	connection.Nodes = fun.First(connection.Nodes, first)
 	connection.Nodes = fun.Last(connection.Nodes, last)
@@ -75,3 +54,80 @@ func NewProductConnection(src []*generated.Product,
 
 	return connection, nil
 }
+
+// SortProducts TODO: ProductCollectionSortKeysBestSelling
+// SortProducts TODO: ProductCollectionSortKeysCollectionDefault
+// SortProducts TODO: ProductCollectionSortKeysManual
+// SortProducts TODO: ProductCollectionSortKeysRelevance
+func SortProducts(src []*generated.Product, sortKey *generated.ProductCollectionSortKeys) []*generated.Product {
+	if sortKey == nil || !sortKey.IsValid() {
+		return src[:]
+	}
+
+	sort.Slice(src[:], func(i, j int) bool {
+		switch *sortKey {
+		case generated.ProductCollectionSortKeysID:
+			return src[i].ID < src[j].ID
+		case generated.ProductCollectionSortKeysTitle:
+			return src[i].Title < src[j].Title
+		case generated.ProductCollectionSortKeysCreated:
+			return src[i].CreatedAt < src[j].CreatedAt
+		case generated.ProductCollectionSortKeysPrice:
+			return src[i].PriceRange.MinVariantPrice.Amount < src[j].PriceRange.MinVariantPrice.Amount
+		}
+
+		return false
+	})
+
+	return src[:]
+}
+
+// FilterProducts TODO: VariantOptionFilter
+// FilterProducts TODO: ProductMetafield
+// FilterProducts TODO: VariantMetafield
+func FilterProducts(src []*generated.Product, filters []*generated.ProductFilter) []*generated.Product {
+	if len(src) < 1 {
+		return src
+	}
+
+	var f = func(src []*generated.Product, filter *generated.ProductFilter) []*generated.Product {
+		if filter == nil || len(src) < 1 {
+			return src
+		}
+
+		var products = make([]*generated.Product, 0)
+		for i := range src {
+			if filter.Available != nil && src[i].AvailableForSale != *filter.Available {
+				continue
+			}
+
+			if filter.ProductType != nil && src[i].ProductType != *filter.ProductType {
+				continue
+			}
+
+			if filter.ProductVendor != nil && src[i].Vendor != *filter.ProductVendor {
+				continue
+			}
+
+			if filter.Price != nil {
+				if filter.Price.Min != nil && src[i].PriceRange.MinVariantPrice.Amount.Float() < *filter.Price.Min {
+					continue
+				}
+
+				if filter.Price.Max != nil && src[i].PriceRange.MaxVariantPrice.Amount.Float() > *filter.Price.Max {
+					continue
+				}
+			}
+
+			products = append(products, src[i])
+		}
+
+		return products
+	}
+
+	for _, filter := range filters {
+		src = f(src, filter)
+	}
+
+	return src
+}

+ 3 - 3
graphql/query_product.go

@@ -49,8 +49,6 @@ func (r *productResolver) Description(_ context.Context, product *generated.Prod
 }
 
 // Products retrieves Product list by collection
-// TODO: implement filters
-// TODO: implement sort
 func (r *collectionResolver) Products(ctx context.Context, collection *generated.Collection,
 	after *string, before *string, filters []*generated.ProductFilter, first *int, last *int, reverse *bool, sort *generated.ProductCollectionSortKeys) (*generated.ProductConnection, error) {
 	var (
@@ -72,7 +70,9 @@ func (r *collectionResolver) Products(ctx context.Context, collection *generated
 		return nil, err
 	}
 
-	return helper.NewProductConnection(products, after, before, first, last, reverse, sort)
+	products = helper.FilterProducts(products, filters)
+	products = helper.SortProducts(products, sort)
+	return helper.NewProductConnection(products, after, before, first, last, reverse)
 }
 
 func (r *productResolver) Options(ctx context.Context, product *generated.Product, first *int) ([]*generated.ProductOption, error) {