get prices for single entity

This commit is contained in:
nquidox 2025-09-26 20:16:21 +03:00
parent b434c4172f
commit 77c678dd7a
3 changed files with 105 additions and 14 deletions

View file

@ -32,6 +32,7 @@ func (h *Handler) RegisterRoutes(r *gin.RouterGroup, authMW gin.HandlerFunc, ref
chartsGroup := r.Group("/prices", authMW)
chartsGroup.GET("", h.controller.getChartsPrices)
chartsGroup.GET("/:uuid", h.controller.getDistinctPrices)
}
@ -196,7 +197,7 @@ func (co *controller) deleteMerch(c *gin.Context) {
// @Description Получить цены мерча за период
// @Tags Merch
// @Security BearerAuth
// @Param days query string false "merch_uuid"
// @Param days query string false "period in days"
// @Success 200 {array} PricesResponse
// @Failure 400 {object} responses.ErrorResponse400
// @Failure 500 {object} responses.ErrorResponse500
@ -220,3 +221,39 @@ func (co *controller) getChartsPrices(c *gin.Context) {
c.JSON(http.StatusOK, response)
}
// @Summary Получить перепады цен мерча за период по его merch_uuid
// @Description Получить перепады цен мерча за период по его merch_uuid
// @Tags Merch
// @Security BearerAuth
// @Param uuid path string true "merch_uuid"
// @Param days query string false "period in days"
// @Success 200 {object} PricesResponse
// @Failure 400 {object} responses.ErrorResponse400
// @Failure 500 {object} responses.ErrorResponse500
// @Router /prices/{uuid} [get]
func (co *controller) getDistinctPrices(c *gin.Context) {
daysQuery := strings.ToLower(c.DefaultQuery("days", ""))
userUuid, err := co.utils.GetUserUuidFromContext(c)
if err != nil {
c.JSON(http.StatusInternalServerError, responses.ErrorResponse500{Error: err.Error()})
log.WithError(err).Error("Merch | Failed to get user uuid from context")
return
}
merchUuid := c.Param("uuid")
if merchUuid == "" {
c.JSON(http.StatusBadRequest, responses.ErrorResponse400{Error: "MerchUuid is empty"})
return
}
response, err := co.service.getDistinctPrices(userUuid, merchUuid, daysQuery)
if err != nil {
c.JSON(http.StatusBadRequest, responses.ErrorResponse500{Error: err.Error()})
log.WithError(err).Error("Merch | Failed to get single merch")
return
}
c.JSON(http.StatusOK, response)
}

View file

@ -34,6 +34,7 @@ type repository interface {
type prices interface {
getPricesWithDays(userUuid string, period time.Time) ([]Price, error)
getDistinctPrices(userUuid, merchUuid string, period time.Time) (prices []Price, err error)
}
func (r *Repo) addMerch(bundle merchBundle) error {
@ -198,3 +199,27 @@ func (r *Repo) getPricesWithDays(userUuid string, period time.Time) (prices []Pr
}
return prices, nil
}
func (r *Repo) getDistinctPrices(userUuid, merchUuid string, period time.Time) (prices []Price, err error) {
err = r.db.Raw(`
SELECT price, created_at, origin
FROM (
SELECT DISTINCT ON (price) price, created_at, origin
FROM prices
WHERE merch_uuid = ?
AND created_at > ?
AND deleted_at IS NULL
AND EXISTS (
SELECT 1
FROM merch
WHERE merch_uuid = ?
AND user_uuid = ?
)
) AS up
ORDER BY created_at;`, merchUuid, period, merchUuid, userUuid).Scan(&prices).Error
if err != nil {
return nil, err
}
return prices, nil
}

View file

@ -4,7 +4,6 @@ import (
"database/sql"
"errors"
"github.com/google/uuid"
"strconv"
"time"
)
@ -98,18 +97,7 @@ func (s *service) getPrices(userUuid string, days string) ([]PricesResponse, err
})
}
daysInt, err := strconv.Atoi(days)
if err != nil {
daysInt = 7
}
if daysInt > 365 {
daysInt = 7
}
period := time.Now().UTC().Add(-(time.Duration(daysInt) * time.Hour * 24))
pricesList, err := s.repo.getPricesWithDays(userUuid, period)
pricesList, err := s.repo.getPricesWithDays(userUuid, getPeriod(days))
if err != nil {
return nil, err
}
@ -142,3 +130,44 @@ func (s *service) getPrices(userUuid string, days string) ([]PricesResponse, err
return response, nil
}
func (s *service) getDistinctPrices(userUuid, merchUuid, days string) (PricesResponse, error) {
result, err := s.repo.getDistinctPrices(userUuid, merchUuid, getPeriod(days))
if err != nil {
return PricesResponse{}, err
}
if result == nil {
return PricesResponse{}, errors.New("no prices found")
}
originSurugaya := OriginWithPrices{
Origin: surugaya,
Prices: []PriceEntry{},
}
originMandarake := OriginWithPrices{
Origin: mandarake,
Prices: []PriceEntry{},
}
for _, item := range result {
switch item.Origin {
case surugaya:
originSurugaya.Prices = append(originSurugaya.Prices, PriceEntry{
CreatedAt: item.CreatedAt.Unix(),
Value: item.Price,
})
case mandarake:
originMandarake.Prices = append(originMandarake.Prices, PriceEntry{
CreatedAt: item.CreatedAt.Unix(),
Value: item.Price,
})
}
}
return PricesResponse{
MerchUuid: merchUuid,
Origins: []OriginWithPrices{originSurugaya, originMandarake},
}, nil
}