zero prices methods

This commit is contained in:
nquidox 2026-03-11 20:17:30 +03:00
parent 33327eaa2c
commit 756b5c126f
3 changed files with 235 additions and 112 deletions

View file

@ -42,20 +42,26 @@ func (h *Handler) RegisterRoutes(r *gin.RouterGroup) {
chartsGroup.GET("", h.controller.getChartsPrices) chartsGroup.GET("", h.controller.getChartsPrices)
chartsGroup.GET("/:uuid", h.controller.getDistinctPrices) chartsGroup.GET("/:uuid", h.controller.getDistinctPrices)
zeroPricesGroup := merchGroup.Group("/zeroprices")
zeroPricesGroup.GET("", h.controller.getZeroPrices)
zeroPricesGroup.DELETE("", h.controller.deleteZeroPrices)
zeroPricesGroup.DELETE("/period", h.controller.deleteZeroPricesPeriod)
} }
// create godoc // create godoc
// //
// @Summary Create new merch // @Summary Create new merch
// @Description Create new merch // @Description Create new merch
// @Tags Merch // @Tags Merch
// @Accept json // @Accept json
// @Param merch body newMerchDTO true "merch body" // @Param merch body newMerchDTO true "merch body"
// @Success 201 // @Success 201
// @Failure 400 {object} responses.BadRequest // @Failure 400 {object} responses.BadRequest
// @Failure 401 {object} responses.Unauthorized // @Failure 401 {object} responses.Unauthorized
// @Failure 500 {object} responses.InternalServerError // @Failure 500 {object} responses.InternalServerError
// @Router /merch/create [POST] // @Router /merch/create [POST]
func (co *controller) create(c *gin.Context) { func (co *controller) create(c *gin.Context) {
var newMerch newMerchDTO var newMerch newMerchDTO
if err := c.ShouldBindJSON(&newMerch); err != nil { if err := c.ShouldBindJSON(&newMerch); err != nil {
@ -77,16 +83,16 @@ func (co *controller) getOne(c *gin.Context) {}
// getMany godoc // getMany godoc
// //
// @Summary Get all merch // @Summary Get all merch
// @Description Get all merch without origins // @Description Get all merch without origins
// @Tags Merch // @Tags Merch
// @Produce json // @Produce json
// @Success 200 {array} merchDTO // @Success 200 {array} merchDTO
// @Success 204 // @Success 204
// @Failure 400 {object} responses.BadRequest // @Failure 400 {object} responses.BadRequest
// @Failure 401 {object} responses.Unauthorized // @Failure 401 {object} responses.Unauthorized
// @Failure 500 {object} responses.InternalServerError // @Failure 500 {object} responses.InternalServerError
// @Router /merch/list [GET] // @Router /merch/list [GET]
func (co *controller) getMany(c *gin.Context) { func (co *controller) getMany(c *gin.Context) {
response, err := co.service.getMany(c, getUserId(c)) response, err := co.service.getMany(c, getUserId(c))
if err != nil { if err != nil {
@ -105,18 +111,18 @@ func (co *controller) getMany(c *gin.Context) {
// updateMerch godoc // updateMerch godoc
// //
// @Summary Update merch // @Summary Update merch
// @Description Update merch general info (except extra data) // @Description Update merch general info (except extra data)
// @Tags Merch // @Tags Merch
// @Accept json // @Accept json
// @Param uuid path string true "merch uuid" // @Param uuid path string true "merch uuid"
// @Param payload body updateMerchDTO true "payload" // @Param payload body updateMerchDTO true "payload"
// @Produce json // @Produce json
// @Success 200 {object} merchDTO // @Success 200 {object} merchDTO
// @Failure 400 {object} responses.BadRequest // @Failure 400 {object} responses.BadRequest
// @Failure 401 {object} responses.Unauthorized // @Failure 401 {object} responses.Unauthorized
// @Failure 500 {object} responses.InternalServerError // @Failure 500 {object} responses.InternalServerError
// @Router /merch/{uuid} [PUT] // @Router /merch/{uuid} [PUT]
func (co *controller) updateMerch(c *gin.Context) { func (co *controller) updateMerch(c *gin.Context) {
merchUuid := c.Param("id") merchUuid := c.Param("id")
if err := uuid.Validate(merchUuid); err != nil { if err := uuid.Validate(merchUuid); err != nil {
@ -150,18 +156,18 @@ func (co *controller) updateMerch(c *gin.Context) {
// updateMerch godoc // updateMerch godoc
// //
// @Summary Update merch extra data // @Summary Update merch extra data
// @Description Update ONLY merch extra data // @Description Update ONLY merch extra data
// @Tags Merch // @Tags Merch
// @Accept json // @Accept json
// @Param uuid path string true "merch uuid" // @Param uuid path string true "merch uuid"
// @Param payload body extraDataDTO true "payload" // @Param payload body extraDataDTO true "payload"
// @Produce json // @Produce json
// @Success 200 {object} extraDataDTO // @Success 200 {object} extraDataDTO
// @Failure 400 {object} responses.BadRequest // @Failure 400 {object} responses.BadRequest
// @Failure 401 {object} responses.Unauthorized // @Failure 401 {object} responses.Unauthorized
// @Failure 500 {object} responses.InternalServerError // @Failure 500 {object} responses.InternalServerError
// @Router /merch/extra/{uuid} [PUT] // @Router /merch/extra/{uuid} [PUT]
func (co *controller) updateExtraData(c *gin.Context) { func (co *controller) updateExtraData(c *gin.Context) {
merchUuid := c.Param("id") merchUuid := c.Param("id")
if err := uuid.Validate(merchUuid); err != nil { if err := uuid.Validate(merchUuid); err != nil {
@ -195,16 +201,16 @@ func (co *controller) updateExtraData(c *gin.Context) {
// deleteMerch godoc // deleteMerch godoc
// //
// @Summary Delete merch // @Summary Delete merch
// @Description Marks merch and all its extra data as deleted by uuid. // @Description Marks merch and all its extra data as deleted by uuid.
// @Tags Merch // @Tags Merch
// @Accept json // @Accept json
// @Param uuid path string true "merch uuid" // @Param uuid path string true "merch uuid"
// @Success 204 // @Success 204
// @Failure 400 {object} responses.BadRequest // @Failure 400 {object} responses.BadRequest
// @Failure 401 {object} responses.Unauthorized // @Failure 401 {object} responses.Unauthorized
// @Failure 500 {object} responses.InternalServerError // @Failure 500 {object} responses.InternalServerError
// @Router /merch/{uuid} [DELETE] // @Router /merch/{uuid} [DELETE]
func (co *controller) deleteMerch(c *gin.Context) { func (co *controller) deleteMerch(c *gin.Context) {
merchUuid := c.Param("id") merchUuid := c.Param("id")
if err := uuid.Validate(merchUuid); err != nil { if err := uuid.Validate(merchUuid); err != nil {
@ -224,16 +230,16 @@ func (co *controller) deleteMerch(c *gin.Context) {
// createOrigin godoc // createOrigin godoc
// //
// @Summary Create new origin // @Summary Create new origin
// @Description Create new origin with name // @Description Create new origin with name
// @Tags Origins // @Tags Origins
// @Accept json // @Accept json
// @Param origin body newOriginDTO true "origin body" // @Param origin body newOriginDTO true "origin body"
// @Success 201 // @Success 201
// @Failure 400 {object} responses.BadRequest // @Failure 400 {object} responses.BadRequest
// @Failure 401 {object} responses.Unauthorized // @Failure 401 {object} responses.Unauthorized
// @Failure 500 {object} responses.InternalServerError // @Failure 500 {object} responses.InternalServerError
// @Router /merch/origins [POST] // @Router /merch/origins [POST]
func (co *controller) createOrigin(c *gin.Context) { func (co *controller) createOrigin(c *gin.Context) {
var origin *newOriginDTO var origin *newOriginDTO
@ -255,16 +261,16 @@ func (co *controller) createOrigin(c *gin.Context) {
// getOrigins godoc // getOrigins godoc
// //
// @Summary Get all origins // @Summary Get all origins
// @Description Get all origins // @Description Get all origins
// @Tags Origins // @Tags Origins
// @Produce json // @Produce json
// @Success 200 {object} originsDTO // @Success 200 {object} originsDTO
// @Success 204 // @Success 204
// @Failure 400 {object} responses.BadRequest // @Failure 400 {object} responses.BadRequest
// @Failure 401 {object} responses.Unauthorized // @Failure 401 {object} responses.Unauthorized
// @Failure 500 {object} responses.InternalServerError // @Failure 500 {object} responses.InternalServerError
// @Router /merch/origins [GET] // @Router /merch/origins [GET]
func (co *controller) getOrigins(c *gin.Context) { func (co *controller) getOrigins(c *gin.Context) {
response, err := co.service.getOrigins(c) response, err := co.service.getOrigins(c)
if err != nil { if err != nil {
@ -279,16 +285,16 @@ func (co *controller) getOrigins(c *gin.Context) {
// deleteOrigin godoc // deleteOrigin godoc
// //
// @Summary Delete origin // @Summary Delete origin
// @Description Marks origin as deleted by name. // @Description Marks origin as deleted by name.
// @Tags Origins // @Tags Origins
// @Accept json // @Accept json
// @Param origin body deleteOriginDTO true "origin body" // @Param origin body deleteOriginDTO true "origin body"
// @Success 204 // @Success 204
// @Failure 400 {object} responses.BadRequest // @Failure 400 {object} responses.BadRequest
// @Failure 401 {object} responses.Unauthorized // @Failure 401 {object} responses.Unauthorized
// @Failure 500 {object} responses.InternalServerError // @Failure 500 {object} responses.InternalServerError
// @Router /merch/origins [DELETE] // @Router /merch/origins [DELETE]
func (co *controller) deleteOrigin(c *gin.Context) { func (co *controller) deleteOrigin(c *gin.Context) {
var origin *deleteOriginDTO var origin *deleteOriginDTO
@ -310,17 +316,16 @@ func (co *controller) deleteOrigin(c *gin.Context) {
// getChartsPrices godoc // getChartsPrices godoc
// //
// @Summary Получить цены мерча за период // @Summary Получить цены мерча за период
// @Description Получить цены мерча за период // @Description Получить цены мерча за период
// @Tags Merch // @Tags Merch
// @Security BearerAuth // @Produce json
// @Produce json // @Param days query string false "period in days"
// @Param days query string false "period in days" // @Success 200 {array} PricesResponse
// @Success 200 {array} PricesResponse // @Failure 400 {object} responses.BadRequest
// @Failure 400 {object} responses.BadRequest // @Failure 401 {object} responses.Unauthorized
// @Failure 401 {object} responses.Unauthorized // @Failure 500 {object} responses.InternalServerError
// @Failure 500 {object} responses.InternalServerError // @Router /prices [get]
// @Router /prices [get]
func (co *controller) getChartsPrices(c *gin.Context) { func (co *controller) getChartsPrices(c *gin.Context) {
response, err := co.service.getPrices(c, getUserId(c), getDays(c)) response, err := co.service.getPrices(c, getUserId(c), getDays(c))
if err != nil { if err != nil {
@ -334,19 +339,18 @@ func (co *controller) getChartsPrices(c *gin.Context) {
// getDistinctPrices godoc // getDistinctPrices godoc
// //
// @Summary Получить перепады цен мерча за период по его merch_uuid // @Summary Получить перепады цен мерча за период по его merch_uuid
// @Description Получить перепады цен мерча за период по его merch_uuid // @Description Получить перепады цен мерча за период по его merch_uuid
// @Tags Merch // @Tags Merch
// @Security BearerAuth // @Produce json
// @Produce json // @Param uuid path string true "merch_uuid"
// @Param uuid path string true "merch_uuid" // @Param days query string false "period in days"
// @Param days query string false "period in days" // @Success 200 {object} PricesResponse
// @Success 200 {object} PricesResponse // @Success 204
// @Success 204 // @Failure 400 {object} responses.BadRequest
// @Failure 400 {object} responses.BadRequest // @Failure 401 {object} responses.Unauthorized
// @Failure 401 {object} responses.Unauthorized // @Failure 500 {object} responses.InternalServerError
// @Failure 500 {object} responses.InternalServerError // @Router /prices/{uuid} [get]
// @Router /prices/{uuid} [get]
func (co *controller) getDistinctPrices(c *gin.Context) { func (co *controller) getDistinctPrices(c *gin.Context) {
merchUuid := c.Param("uuid") merchUuid := c.Param("uuid")
if merchUuid == "" { if merchUuid == "" {
@ -370,3 +374,98 @@ func (co *controller) getDistinctPrices(c *gin.Context) {
c.JSON(http.StatusOK, response) c.JSON(http.StatusOK, response)
} }
// getZeroPrices godoc
//
// @Summary Получить нулевые цены
// @Description Получить нулевые цены
// @Tags Merch zero prices
// @Produce json
// @Success 200 {array} ZeroPrice
// @Success 204
// @Failure 401 {object} responses.Unauthorized
// @Failure 500 {object} responses.InternalServerError
// @Router /merch/zeroprices [get]
func (co *controller) getZeroPrices(c *gin.Context) {
response, err := co.service.getZeroPrices(c, getUserId(c))
if err != nil {
c.JSON(http.StatusInternalServerError, responses.InternalServerError{Error: err.Error()})
logErr(controllerLogHeader, err)
return
}
if response == nil {
c.Status(http.StatusNoContent)
}
c.JSON(http.StatusOK, response)
}
// deleteZeroPrices godoc
//
// @Summary Пометить нулевые цены как удаленные
// @Description Пометить нулевые цены как удаленные
// @Tags Merch zero prices
// @Security BearerAuth
// @Accept json
// @Param payload body DeleteZeroPrices true "payload"
// @Success 204
// @Failure 400 {object} responses.BadRequest
// @Failure 401 {object} responses.Unauthorized
// @Failure 500 {object} responses.InternalServerError
// @Router /merch/zeroprices [delete]
func (co *controller) deleteZeroPrices(c *gin.Context) {
var payload []DeleteZeroPrices
if err := c.ShouldBindJSON(&payload); err != nil {
c.JSON(http.StatusBadRequest, responses.BadRequest{Error: err.Error()})
logErr(controllerLogHeader, err)
return
}
if len(payload) < 1 || payload == nil {
c.Status(http.StatusNoContent)
return
}
if err := co.service.deleteZeroPrices(c, getUserId(c), payload); err != nil {
c.JSON(http.StatusInternalServerError, responses.InternalServerError{Error: err.Error()})
logErr(controllerLogHeader, err)
return
}
c.Status(http.StatusNoContent)
}
// @Summary Пометить нулевые цены как удаленные за указанный период
// @Description Пометить нулевые цены как удаленные за указанный период
// @Tags Merch zero prices
// @Security BearerAuth
// @Param start query string true "start"
// @Param end query string true "end"
// @Success 204
// @Failure 400 {object} responses.BadRequest
// @Failure 401 {object} responses.Unauthorized
// @Failure 500 {object} responses.InternalServerError
// @Router /merch/zeroprices/period [delete]
func (co *controller) deleteZeroPricesPeriod(c *gin.Context) {
start, err := co.utils.ParseTime(c.Query("start"))
if err != nil {
c.JSON(http.StatusBadRequest, responses.BadRequest{Error: err.Error()})
logErr(controllerLogHeader, err)
return
}
end, err := co.utils.ParseTime(c.Query("end"))
if err != nil {
c.JSON(http.StatusBadRequest, responses.BadRequest{Error: err.Error()})
logErr(controllerLogHeader, err)
return
}
if err = co.service.deleteZeroPricesPeriod(c, getUserId(c), start, end); err != nil {
c.JSON(http.StatusInternalServerError, responses.InternalServerError{Error: err.Error()})
logErr(controllerLogHeader, err)
return
}
c.Status(http.StatusOK)
}

View file

@ -14,7 +14,7 @@ type Prices interface {
getZeroPrices(ctx context.Context, userId int64) ([]ZeroPrice, error) getZeroPrices(ctx context.Context, userId int64) ([]ZeroPrice, error)
deleteZeroPricesPeriod(ctx context.Context, userId int64, start, end time.Time, now sql.NullTime) error deleteZeroPricesPeriod(ctx context.Context, userId int64, start, end time.Time, now sql.NullTime) error
deleteZeroPrices(ctx context.Context, now sql.NullTime, list []int64) error deleteZeroPrices(ctx context.Context, userId int64, now sql.NullTime, list []int64) error
} }
func (r *repo) insertPrices(ctx context.Context, prices []Price) error { func (r *repo) insertPrices(ctx context.Context, prices []Price) error {
@ -192,10 +192,17 @@ func (r *repo) deleteZeroPricesPeriod(ctx context.Context, userId int64, start,
return nil return nil
} }
func (r *repo) deleteZeroPrices(ctx context.Context, now sql.NullTime, list []int64) error { func (r *repo) deleteZeroPrices(ctx context.Context, userId int64, now sql.NullTime, list []int64) error {
q := `UPDATE merch_prices SET deleted_at = $1 WHERE id IN $2` q := `
UPDATE merch_prices mp
SET deleted_at = $1
FROM merch m
WHERE mp.id = ANY($2)
AND mp.merch_id = m.id
AND m.user_id = $3
`
_, err := r.db.Exec(ctx, q, now, list) _, err := r.db.Exec(ctx, q, now, list, userId)
if err != nil { if err != nil {
return err return err
} }

View file

@ -4,6 +4,7 @@ import (
"context" "context"
"errors" "errors"
"fmt" "fmt"
"time"
) )
func (s *service) getPrices(ctx context.Context, userId int64, days int) ([]PricesResponse, error) { func (s *service) getPrices(ctx context.Context, userId int64, days int) ([]PricesResponse, error) {
@ -123,3 +124,19 @@ func (s *service) getDistinctPrices(ctx context.Context, userId int64, merchUuid
return &response, nil return &response, nil
} }
func (s *service) getZeroPrices(ctx context.Context, userId int64) ([]ZeroPrice, error) {
return s.repo.getZeroPrices(ctx, userId)
}
func (s *service) deleteZeroPricesPeriod(ctx context.Context, userId int64, start, end time.Time) error {
return s.repo.deleteZeroPricesPeriod(ctx, userId, start, end, s.utils.NullTimeNowUTC())
}
func (s *service) deleteZeroPrices(ctx context.Context, userId int64, list []DeleteZeroPrices) error {
var l []int64
for _, item := range list {
l = append(l, item.Id)
}
return s.repo.deleteZeroPrices(ctx, userId, s.utils.NullTimeNowUTC(), l)
}