package helper import ( "fmt" "github.com/gshopify/service-wrapper/fun" "github.com/gshopify/service-wrapper/model" "gshopper.com/gshopify/products/graphql/generated" "sort" ) func NewProductConnection(src []*generated.Product, after *string, before *string, first *int, last *int, reverse *bool) (*generated.ProductConnection, error) { var ( connection = &generated.ProductConnection{} err error ) if len(src) == 0 { return connection, nil } if reverse != nil && *reverse { src = fun.Reverse(src) } connection.Nodes = src[:] connection.Nodes = fun.First(connection.Nodes, first) connection.Nodes = fun.Last(connection.Nodes, last) connection.Nodes, err = fun.WithCursor(connection.Nodes, after, model.GidProduct, true) if err != nil { return nil, fmt.Errorf("illegal cursor: %s", *after) } connection.Nodes, err = fun.WithCursor(connection.Nodes, before, model.GidProduct, false) if err != nil { return nil, fmt.Errorf("illegal cursor: %s", *before) } connection.PageInfo = model.NewPageInfo(connection.Nodes, model.GidProduct, src[0], src[len(src)-1]) // Edges for i := range connection.Nodes { e := &generated.ProductEdge{ Node: connection.Nodes[i], } if c, err := model.NewSimpleCursor(e.Node.ID, model.GidProduct); err == nil { e.Cursor = *c.String() } connection.Edges = append(connection.Edges, e) } return connection, nil } func SortProducts(src []*generated.Product, k fmt.Stringer) []*generated.Product { if k == nil { return src[:] } sortBy := k.String() if !generated.ProductSortKeys(sortBy).IsValid() && !generated.ProductCollectionSortKeys(sortBy).IsValid() { return src[:] } return internalSortProducts(src[:], sortBy) } // internalSortProducts TODO: generated.ProductCollectionSortKeysBestSelling // internalSortProducts TODO: generated.ProductCollectionSortKeysCollectionDefault // internalSortProducts TODO: generated.ProductCollectionSortKeysManual // internalSortProducts TODO: generated.ProductCollectionSortKeysRelevance // internalSortProducts TODO: generated.ProductSortKeysBestSelling // internalSortProducts TODO: generated.ProductSortKeysRelevance func internalSortProducts(src []*generated.Product, key string) []*generated.Product { sort.Slice(src[:], func(i, j int) bool { switch key { case "ID": return src[i].ID < src[j].ID case "TITLE": return src[i].Title < src[j].Title case "PRODUCT_TYPE": return src[i].ProductType < src[j].ProductType case "VENDOR": return src[i].Vendor < src[j].Vendor case "CREATED": return src[i].CreatedAt < src[j].CreatedAt case "CREATED_AT": return src[i].CreatedAt < src[j].CreatedAt case "UPDATED_AT": return src[i].UpdatedAt < src[j].UpdatedAt case "PRICE": 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 }