123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- 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.NewCursor(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
- }
|