github.com/shoshinnikita/budget-manager@v0.7.1-0.20220131195411-8c46ff1c6778/internal/web/api/search.go (about) 1 package api 2 3 import ( 4 "context" 5 "net/http" 6 "strings" 7 8 "github.com/ShoshinNikita/budget-manager/internal/db" 9 "github.com/ShoshinNikita/budget-manager/internal/logger" 10 "github.com/ShoshinNikita/budget-manager/internal/pkg/money" 11 "github.com/ShoshinNikita/budget-manager/internal/pkg/reqid" 12 "github.com/ShoshinNikita/budget-manager/internal/web/api/models" 13 "github.com/ShoshinNikita/budget-manager/internal/web/utils" 14 ) 15 16 type SearchHandlers struct { 17 db SearchDB 18 log logger.Logger 19 } 20 21 type SearchDB interface { 22 SearchSpends(ctx context.Context, args db.SearchSpendsArgs) ([]db.Spend, error) 23 } 24 25 // @Summary Search Spends 26 // @Tags Search 27 // @Router /api/search/spends [get] 28 // @Param params query models.SearchSpendsReq true "Search args" 29 // @Produce json 30 // @Success 200 {object} models.SearchSpendsResp 31 // @Failure 400 {object} models.Response "Invalid request" 32 // @Failure 500 {object} models.Response "Internal error" 33 // 34 func (h SearchHandlers) SearchSpends(w http.ResponseWriter, r *http.Request) { 35 ctx := r.Context() 36 log := reqid.FromContextToLogger(ctx, h.log) 37 38 // Decode 39 req := &models.SearchSpendsReq{} 40 if ok := utils.DecodeRequest(w, r, log, req); !ok { 41 return 42 } 43 log = log.WithRequest(req) 44 45 // Process 46 args := db.SearchSpendsArgs{ 47 Title: strings.ToLower(req.Title), 48 Notes: strings.ToLower(req.Notes), 49 TitleExactly: req.TitleExactly, 50 NotesExactly: req.NotesExactly, 51 After: req.After, 52 Before: req.Before, 53 MinCost: money.FromFloat(req.MinCost), 54 MaxCost: money.FromFloat(req.MaxCost), 55 TypeIDs: req.TypeIDs, 56 } 57 switch req.Sort { 58 case "title": 59 args.Sort = db.SortSpendsByTitle 60 case "cost": 61 args.Sort = db.SortSpendsByCost 62 default: 63 args.Sort = db.SortSpendsByDate 64 } 65 switch req.Order { 66 case "desc": 67 args.Order = db.OrderByDesc 68 default: 69 args.Order = db.OrderByAsc 70 } 71 72 spends, err := h.db.SearchSpends(ctx, args) 73 if err != nil { 74 utils.EncodeInternalError(ctx, w, log, "couldn't search for Spends", err) 75 return 76 } 77 log.WithField("spend_number", len(spends)).Debug("finish Spend search") 78 79 resp := &models.SearchSpendsResp{ 80 Spends: spends, 81 } 82 utils.Encode(ctx, w, log, utils.EncodeResponse(resp)) 83 }