product.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. package helper
  2. import (
  3. "fmt"
  4. "github.com/gshopify/service-wrapper/fun"
  5. "github.com/gshopify/service-wrapper/model"
  6. "gshopper.com/gshopify/products/graphql/generated"
  7. "sort"
  8. )
  9. func NewProductConnection(src []*generated.Product,
  10. after *string, before *string, first *int, last *int, reverse *bool) (*generated.ProductConnection, error) {
  11. var (
  12. connection = &generated.ProductConnection{}
  13. err error
  14. )
  15. if len(src) == 0 {
  16. return connection, nil
  17. }
  18. if reverse != nil && *reverse {
  19. src = fun.Reverse(src)
  20. }
  21. connection.Nodes = src[:]
  22. connection.Nodes = fun.First(connection.Nodes, first)
  23. connection.Nodes = fun.Last(connection.Nodes, last)
  24. connection.Nodes, err = fun.WithCursor(connection.Nodes, after, model.GidProduct, true)
  25. if err != nil {
  26. return nil, fmt.Errorf("illegal cursor: %s", *after)
  27. }
  28. connection.Nodes, err = fun.WithCursor(connection.Nodes, before, model.GidProduct, false)
  29. if err != nil {
  30. return nil, fmt.Errorf("illegal cursor: %s", *before)
  31. }
  32. connection.PageInfo = model.NewPageInfo(connection.Nodes, model.GidProduct, src[0], src[len(src)-1])
  33. // Edges
  34. for i := range connection.Nodes {
  35. e := &generated.ProductEdge{
  36. Node: connection.Nodes[i],
  37. }
  38. if c, err := model.NewCursor(e.Node.ID, model.GidProduct); err == nil {
  39. e.Cursor = *c.String()
  40. }
  41. connection.Edges = append(connection.Edges, e)
  42. }
  43. return connection, nil
  44. }
  45. func SortProducts(src []*generated.Product, k fmt.Stringer) []*generated.Product {
  46. if k == nil {
  47. return src[:]
  48. }
  49. sortBy := k.String()
  50. if !generated.ProductSortKeys(sortBy).IsValid() &&
  51. !generated.ProductCollectionSortKeys(sortBy).IsValid() {
  52. return src[:]
  53. }
  54. return internalSortProducts(src[:], sortBy)
  55. }
  56. // internalSortProducts TODO: generated.ProductCollectionSortKeysBestSelling
  57. // internalSortProducts TODO: generated.ProductCollectionSortKeysCollectionDefault
  58. // internalSortProducts TODO: generated.ProductCollectionSortKeysManual
  59. // internalSortProducts TODO: generated.ProductCollectionSortKeysRelevance
  60. // internalSortProducts TODO: generated.ProductSortKeysBestSelling
  61. // internalSortProducts TODO: generated.ProductSortKeysRelevance
  62. func internalSortProducts(src []*generated.Product, key string) []*generated.Product {
  63. sort.Slice(src[:], func(i, j int) bool {
  64. switch key {
  65. case "ID":
  66. return src[i].ID < src[j].ID
  67. case "TITLE":
  68. return src[i].Title < src[j].Title
  69. case "PRODUCT_TYPE":
  70. return src[i].ProductType < src[j].ProductType
  71. case "VENDOR":
  72. return src[i].Vendor < src[j].Vendor
  73. case "CREATED":
  74. return src[i].CreatedAt < src[j].CreatedAt
  75. case "CREATED_AT":
  76. return src[i].CreatedAt < src[j].CreatedAt
  77. case "UPDATED_AT":
  78. return src[i].UpdatedAt < src[j].UpdatedAt
  79. case "PRICE":
  80. return src[i].PriceRange.MinVariantPrice.Amount < src[j].PriceRange.MinVariantPrice.Amount
  81. }
  82. return false
  83. })
  84. return src[:]
  85. }
  86. // FilterProducts TODO: VariantOptionFilter
  87. // FilterProducts TODO: ProductMetafield
  88. // FilterProducts TODO: VariantMetafield
  89. func FilterProducts(src []*generated.Product, filters []*generated.ProductFilter) []*generated.Product {
  90. if len(src) < 1 {
  91. return src
  92. }
  93. var f = func(src []*generated.Product, filter *generated.ProductFilter) []*generated.Product {
  94. if filter == nil || len(src) < 1 {
  95. return src
  96. }
  97. var products = make([]*generated.Product, 0)
  98. for i := range src {
  99. if filter.Available != nil && src[i].AvailableForSale != *filter.Available {
  100. continue
  101. }
  102. if filter.ProductType != nil && src[i].ProductType != *filter.ProductType {
  103. continue
  104. }
  105. if filter.ProductVendor != nil && src[i].Vendor != *filter.ProductVendor {
  106. continue
  107. }
  108. if filter.Price != nil {
  109. if filter.Price.Min != nil && src[i].PriceRange.MinVariantPrice.Amount.Float() < *filter.Price.Min {
  110. continue
  111. }
  112. if filter.Price.Max != nil && src[i].PriceRange.MaxVariantPrice.Amount.Float() > *filter.Price.Max {
  113. continue
  114. }
  115. }
  116. products = append(products, src[i])
  117. }
  118. return products
  119. }
  120. for _, filter := range filters {
  121. src = f(src, filter)
  122. }
  123. return src
  124. }