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  }