github.com/timoth-y/kicksware-api/order-service@v0.0.0-20201002192818-87b546a7ae5a/usecase/business/orderService.go (about) 1 package business 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "fmt" 7 "io/ioutil" 8 "net/http" 9 "strings" 10 "time" 11 12 "github.com/pkg/errors" 13 "github.com/rs/xid" 14 "github.com/thoas/go-funk" 15 "github.com/timoth-y/kicksware-api/search-service/core/pipe" 16 "gopkg.in/dealancer/validate.v2" 17 18 "github.com/timoth-y/kicksware-api/service-common/core/meta" 19 "github.com/timoth-y/kicksware-api/order-service/core/model" 20 "github.com/timoth-y/kicksware-api/order-service/core/repo" 21 "github.com/timoth-y/kicksware-api/order-service/core/service" 22 "github.com/timoth-y/kicksware-api/order-service/env" 23 ) 24 25 var ( 26 ErrOrderNotFound = errors.New("order Not Found") 27 ErrOrderNotValid = errors.New("order Not Valid") 28 ) 29 30 type orderService struct { 31 repo repo.OrderRepository 32 serviceConfig env.CommonConfig 33 pipe pipe.SneakerReferencePipe 34 } 35 36 func NewOrderService(orderRepo repo.OrderRepository, pipe pipe.SneakerReferencePipe, serviceConfig env.CommonConfig) service.OrderService { 37 return &orderService{ 38 orderRepo, 39 serviceConfig, 40 pipe, 41 } 42 } 43 44 func (s *orderService) FetchOne(code string, params *meta.RequestParams) (*model.Order, error) { 45 return s.repo.FetchOne(code, params) 46 } 47 48 func (s *orderService) Fetch(codes []string, params *meta.RequestParams) ([]*model.Order, error) { 49 return s.repo.Fetch(codes, params) 50 } 51 52 func (s *orderService) FetchAll(params *meta.RequestParams) ([]*model.Order, error) { 53 return s.repo.FetchAll(params) 54 } 55 56 func (s *orderService) FetchQuery(query meta.RequestQuery, params *meta.RequestParams) (refs []*model.Order, err error) { 57 foreignKeys, is := s.handleForeignSubquery(query) 58 refs, err = s.repo.FetchQuery(query, params) 59 if err == nil && is { 60 refs = funk.Filter(refs, func(ref *model.Order) bool { 61 return funk.Contains(foreignKeys, ref.UniqueID) 62 }).([]*model.Order) 63 } 64 return 65 } 66 67 func (s *orderService) StoreOne(order *model.Order) error { 68 if err := validate.Validate(order); err != nil { 69 return errors.Wrap(ErrOrderNotValid, "service.repo.Store") 70 } 71 order.UniqueID = xid.New().String() 72 if ref, err := s.pipe.FetchOne(order.ReferenceID); err == nil { 73 order.Price = ref.Price 74 if url := ref.StadiumUrl; len(url) != 0 { 75 order.SourceURL = url 76 } else if url := ref.GoatUrl; len(url) != 0 { 77 order.SourceURL = url 78 } else { 79 order.SourceURL = fmt.Sprintf("http://kicksware.com/shop/references/%v", ref.UniqueId) 80 } 81 order.Price = ref.Price 82 } 83 order.Status = model.Draft 84 order.AddedAt = time.Now() 85 return s.repo.StoreOne(order) 86 } 87 88 func (s *orderService) Modify(order *model.Order) error { 89 return s.repo.Modify(order) 90 } 91 92 func (s *orderService) Remove(code string) error { 93 return s.repo.Remove(code) 94 } 95 96 func (s *orderService) CountAll() (int, error) { 97 return s.repo.CountAll() 98 } 99 100 func (s *orderService) Count(query meta.RequestQuery, params *meta.RequestParams) (int, error) { 101 foreignKeys, is := s.handleForeignSubquery(query); if is { 102 refs, err := s.repo.FetchQuery(query, params) 103 if err == nil && is { 104 refs = funk.Filter(refs, func(ref *model.Order) bool { 105 return funk.Contains(foreignKeys, ref.UniqueID) 106 }).([]*model.Order) 107 } 108 return len(refs), nil 109 } 110 return s.repo.Count(query, params) 111 } 112 113 func (s *orderService) handleForeignSubquery(query map[string]interface{}) (foreignKeys []string, is bool) { 114 foreignKeys = make([]string, 0) 115 for key := range query { 116 if strings.Contains(key, "*/") { 117 is = true 118 res := strings.TrimLeft(key, "*/"); 119 host := fmt.Sprintf("%s-service", strings.Split(res, "/")[0]); 120 service := fmt.Sprintf(s.serviceConfig.InnerServiceFormat, host, res) 121 if keys, err := s.postOnForeignService(service, query[key]); err == nil { 122 foreignKeys = append(foreignKeys, keys...) 123 } 124 delete(query, key) 125 } 126 } 127 return 128 } 129 130 func (s *orderService) postOnForeignService(service string, query interface{}) (keys []string, err error) { 131 body, err := json.Marshal(query); if err != nil { 132 return 133 } 134 resp, err := http.Post(service, s.serviceConfig.ContentType, bytes.NewBuffer(body)) 135 if err != nil { 136 return 137 } 138 defer resp.Body.Close() 139 140 bytes, err := ioutil.ReadAll(resp.Body); if err != nil { 141 return 142 } 143 144 subs := make([]map[string]interface{}, 0) 145 err = json.Unmarshal(bytes, &subs); if err != nil { 146 return 147 } 148 149 keys = make([]string, 0) 150 for _, doc := range subs { 151 if key, ok := doc["OrderId"]; ok { 152 keys = append(keys, key.(string)) 153 } 154 } 155 return 156 }