codeword/internal/controller/promocode/promocode_controller.go

319 lines
10 KiB
Go
Raw Normal View History

2024-01-11 18:20:33 +00:00
package promocode
2024-01-11 16:29:53 +00:00
import (
"codeword/internal/models"
2024-01-11 18:20:33 +00:00
"codeword/internal/repository"
2024-01-11 16:29:53 +00:00
"codeword/internal/services"
2024-05-28 11:05:31 +00:00
"codeword/internal/utils/middleware"
2024-01-11 18:20:33 +00:00
"errors"
2024-03-21 14:49:35 +00:00
"fmt"
2024-01-11 16:29:53 +00:00
"github.com/gofiber/fiber/v2"
"go.uber.org/zap"
"penahub.gitlab.yandexcloud.net/backend/penahub_common/log_mw"
2024-01-11 16:29:53 +00:00
)
2024-03-03 10:13:13 +00:00
type Deps struct {
Logger *zap.Logger
PromoCodeService *services.PromoCodeService
}
2024-01-11 16:29:53 +00:00
type PromoCodeController struct {
logger *zap.Logger
promoCodeService *services.PromoCodeService
}
2024-03-03 10:13:13 +00:00
func NewPromoCodeController(deps Deps) *PromoCodeController {
2024-01-11 16:29:53 +00:00
return &PromoCodeController{
2024-03-03 10:13:13 +00:00
logger: deps.Logger,
promoCodeService: deps.PromoCodeService,
2024-01-11 16:29:53 +00:00
}
}
func (p *PromoCodeController) CreatePromoCode(c *fiber.Ctx) error {
2024-05-28 11:05:31 +00:00
userID := middleware.ExtractUserID(c)
hlogger := log_mw.ExtractLogger(c)
2024-01-12 11:28:22 +00:00
var req models.PromoCode
if err := c.BodyParser(&req); err != nil {
2024-01-11 16:29:53 +00:00
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid request payload"})
}
2024-01-26 11:47:44 +00:00
if req.Codeword == "" {
2024-01-26 11:50:47 +00:00
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "codeword is required"})
2024-01-26 11:47:44 +00:00
}
2024-04-08 22:07:43 +00:00
req.ActivationLimit = req.ActivationCount
2024-01-12 11:28:22 +00:00
createdPromoCode, err := p.promoCodeService.CreatePromoCode(c.Context(), &req)
2024-01-11 16:29:53 +00:00
if err != nil {
p.logger.Error("Failed to create promocode", zap.Error(err))
2024-01-11 18:20:33 +00:00
if errors.Is(err, repository.ErrDuplicateCodeword) {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Duplicate Codeword"})
}
2024-01-11 16:29:53 +00:00
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Internal Server Error"})
}
2024-05-28 11:05:31 +00:00
var keyType string
var ctxFactor float64
var keyTargetType string
var ctxTarget string
var ctxAmount int64
2024-05-28 11:08:40 +00:00
if createdPromoCode.Bonus.Privilege.PrivilegeID != "" && createdPromoCode.Bonus.Discount.Factor != 0 && createdPromoCode.Bonus.Discount.Factor != 1 {
2024-05-28 11:05:31 +00:00
keyType = "privilege,discount"
keyTargetType = "privilege,service"
ctxTarget = fmt.Sprintf("%s,%s", createdPromoCode.Bonus.Privilege.PrivilegeID, createdPromoCode.Bonus.Discount.Target)
ctxAmount = int64(createdPromoCode.Bonus.Privilege.Amount)
ctxFactor = createdPromoCode.Bonus.Discount.Factor
} else if createdPromoCode.Bonus.Privilege.PrivilegeID != "" {
keyType = "privilege"
keyTargetType = "privilege"
ctxTarget = createdPromoCode.Bonus.Privilege.PrivilegeID
ctxAmount = int64(createdPromoCode.Bonus.Privilege.Amount)
2024-05-28 11:08:40 +00:00
} else if createdPromoCode.Bonus.Discount.Factor != 0 && createdPromoCode.Bonus.Discount.Factor != 1 {
2024-05-28 11:05:31 +00:00
keyType = "discount"
keyTargetType = "service"
ctxFactor = createdPromoCode.Bonus.Discount.Factor
ctxTarget = createdPromoCode.Bonus.Discount.Target
}
hlogger.Emit(models.InfoPromocodeCreated{
CtxID: createdPromoCode.ID.String(),
CtxUserID: userID,
KeyType: keyType,
CtxFactor: ctxFactor,
KeyTargetType: keyTargetType,
CtxTarget: ctxTarget,
CtxAmount: ctxAmount,
CtxCode: createdPromoCode.Codeword,
})
2024-03-03 19:31:40 +00:00
return c.Status(fiber.StatusOK).JSON(createdPromoCode)
2024-01-11 16:29:53 +00:00
}
2024-01-11 19:47:54 +00:00
func (p *PromoCodeController) EditPromoCode(c *fiber.Ctx) error {
2024-05-28 11:05:31 +00:00
userID := middleware.ExtractUserID(c)
hlogger := log_mw.ExtractLogger(c)
2024-05-28 11:05:31 +00:00
2024-01-12 11:28:22 +00:00
var req models.ReqEditPromoCode
if err := c.BodyParser(&req); err != nil {
2024-01-11 19:47:54 +00:00
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid request payload"})
}
2024-01-12 11:28:22 +00:00
if req.ID == "" {
2024-01-12 09:42:56 +00:00
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "promocode ID is required"})
}
2024-04-08 22:07:43 +00:00
req.ActivationLimit = req.ActivationCount
2024-01-12 11:28:22 +00:00
editedPromoCode, err := p.promoCodeService.EditPromoCode(c.Context(), &req)
2024-01-11 19:47:54 +00:00
if err != nil {
p.logger.Error("Failed to edit promocode", zap.Error(err))
if errors.Is(err, repository.ErrPromoCodeNotFound) {
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "PromoCode not found"})
}
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Internal Server Error"})
}
2024-05-28 11:05:31 +00:00
var keyType string
var ctxFactor float64
var keyTargetType string
var ctxTarget string
var ctxAmount int64
2024-05-28 11:08:40 +00:00
if editedPromoCode.Bonus.Privilege.PrivilegeID != "" && editedPromoCode.Bonus.Discount.Factor != 0 && editedPromoCode.Bonus.Discount.Factor != 1 {
2024-05-28 11:05:31 +00:00
keyType = "privilege,discount"
keyTargetType = "privilege,service"
ctxTarget = fmt.Sprintf("%s,%s", editedPromoCode.Bonus.Privilege.PrivilegeID, editedPromoCode.Bonus.Discount.Target)
ctxAmount = int64(editedPromoCode.Bonus.Privilege.Amount)
ctxFactor = editedPromoCode.Bonus.Discount.Factor
} else if editedPromoCode.Bonus.Privilege.PrivilegeID != "" {
keyType = "privilege"
keyTargetType = "privilege"
ctxTarget = editedPromoCode.Bonus.Privilege.PrivilegeID
ctxAmount = int64(editedPromoCode.Bonus.Privilege.Amount)
2024-05-28 11:08:40 +00:00
} else if editedPromoCode.Bonus.Discount.Factor != 0 && editedPromoCode.Bonus.Discount.Factor != 1 {
2024-05-28 11:05:31 +00:00
keyType = "discount"
keyTargetType = "service"
ctxFactor = editedPromoCode.Bonus.Discount.Factor
ctxTarget = editedPromoCode.Bonus.Discount.Target
}
hlogger.Emit(models.InfoPromocodeUpdated{
CtxID: editedPromoCode.ID.String(),
CtxUserID: userID,
KeyType: keyType,
CtxFactor: ctxFactor,
KeyTargetType: keyTargetType,
CtxTarget: ctxTarget,
CtxAmount: ctxAmount,
CtxCode: editedPromoCode.Codeword,
})
2024-01-11 19:47:54 +00:00
return c.Status(fiber.StatusOK).JSON(editedPromoCode)
}
2024-01-12 11:28:22 +00:00
func (p *PromoCodeController) GetList(c *fiber.Ctx) error {
var req models.GetPromoCodesListReq
if err := c.BodyParser(&req); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid request payload"})
}
promoCodes, count, err := p.promoCodeService.GetPromoCodesList(c.Context(), &req)
if err != nil {
p.logger.Error("Failed to retrieve promocode list", zap.Error(err))
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Internal Server Error"})
}
2024-02-22 09:18:24 +00:00
return c.Status(fiber.StatusOK).JSON(models.GetPromoCodesListResp{
2024-01-12 11:28:22 +00:00
Count: count,
Items: promoCodes,
2024-02-22 09:18:24 +00:00
})
2024-01-12 11:28:22 +00:00
}
2024-01-12 13:46:36 +00:00
func (p *PromoCodeController) Activate(c *fiber.Ctx) error {
2024-05-28 11:05:31 +00:00
userID := middleware.ExtractUserID(c)
hlogger := log_mw.ExtractLogger(c)
fmt.Println("SKER1", userID)
2024-03-03 10:13:13 +00:00
if userID == "" {
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "failed to get jwt payload"})
}
2024-01-12 13:46:36 +00:00
var req models.ActivateReq
if err := c.BodyParser(&req); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid request payload"})
}
2024-01-14 14:18:36 +00:00
if req.Codeword == "" && req.FastLink == "" {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "codeword or fastlink is required"})
2024-01-12 13:46:36 +00:00
}
fmt.Println("SKER2", req)
2024-01-12 13:46:36 +00:00
2024-05-28 11:05:31 +00:00
promocode, err := p.promoCodeService.ActivatePromo(c.Context(), &req, userID)
fmt.Println("SKER3", err)
2024-01-12 13:46:36 +00:00
if err != nil {
p.logger.Error("Failed to activate promocode", zap.Error(err))
switch {
case errors.Is(err, repository.ErrPromoCodeNotFound):
2024-01-12 13:46:36 +00:00
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "PromoCode not found"})
case errors.Is(err, repository.ErrPromoCodeAlreadyActivated):
return c.Status(fiber.StatusForbidden).JSON(fiber.Map{"error": "PromoCode already activated"})
case errors.Is(err, repository.ErrPromoCodeExpired):
2024-05-28 11:05:31 +00:00
hlogger.Emit(models.InfoPromocodeDeadlined{
CtxID: promocode.ID.String(),
2024-05-28 11:05:31 +00:00
})
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": err.Error()})
case errors.Is(err, repository.ErrPromoCodeExhausted):
2024-05-28 11:05:31 +00:00
hlogger.Emit(models.InfoPromocodeExhausted{
CtxID: promocode.ID.String(),
2024-05-28 11:05:31 +00:00
})
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "PromoCode exhausted"})
default:
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Internal Server Error"})
2024-01-12 13:46:36 +00:00
}
}
2024-05-28 11:05:31 +00:00
if req.Codeword != "" {
hlogger.Emit(models.InfoPromocodeActivated{
CtxID: promocode.ID.String(),
CtxUserID: userID,
CtxCode: req.Codeword,
2024-05-28 11:05:31 +00:00
})
} else if req.FastLink != "" {
hlogger.Emit(models.InfoFastlinkActivated{
CtxID: promocode.ID.String(),
CtxUserID: userID,
CtxPromocodeID: req.FastLink,
})
}
return c.Status(fiber.StatusOK).JSON(models.ActivateResp{Greetings: promocode.Greetings})
2024-01-12 13:46:36 +00:00
}
2024-01-12 14:50:53 +00:00
func (p *PromoCodeController) Delete(c *fiber.Ctx) error {
2024-05-28 11:05:31 +00:00
userID := middleware.ExtractUserID(c)
hlogger := log_mw.ExtractLogger(c)
2024-01-12 14:50:53 +00:00
2024-05-28 11:05:31 +00:00
promoCodeID := c.Params("promocodeID")
2024-01-12 14:50:53 +00:00
if promoCodeID == "" {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "PromoCode ID is required"})
}
err := p.promoCodeService.DeletePromoCode(c.Context(), promoCodeID)
if err != nil {
p.logger.Error("Failed to delete promocode", zap.Error(err))
if errors.Is(err, repository.ErrPromoCodeNotFound) {
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "PromoCode not found"})
}
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Internal Server Error"})
}
2024-05-28 11:05:31 +00:00
hlogger.Emit(models.InfoPromocodeDeleted{
CtxID: promoCodeID,
CtxUserID: userID,
2024-05-28 11:05:31 +00:00
})
2024-01-12 14:50:53 +00:00
return c.SendStatus(fiber.StatusOK)
}
2024-01-14 14:18:36 +00:00
func (p *PromoCodeController) CreateFastLink(c *fiber.Ctx) error {
2024-05-28 11:05:31 +00:00
userID := middleware.ExtractUserID(c)
hlogger := log_mw.ExtractLogger(c)
2024-05-28 11:05:31 +00:00
2024-01-14 14:18:36 +00:00
var req struct {
2024-01-15 13:32:46 +00:00
PromoCodeID string `json:"id"`
2024-01-14 14:18:36 +00:00
}
if err := c.BodyParser(&req); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid request payload"})
}
2024-01-26 15:37:07 +00:00
if req.PromoCodeID == "" {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "PromoCode ID is required"})
}
2024-01-14 14:18:36 +00:00
fastLink, err := p.promoCodeService.CreateFastLink(c.Context(), req.PromoCodeID)
if err != nil {
p.logger.Error("Failed to create fastlink", zap.Error(err))
if errors.Is(err, repository.ErrPromoCodeNotFound) {
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "PromoCode not found"})
}
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Internal Server Error"})
}
2024-05-28 11:05:31 +00:00
hlogger.Emit(models.InfoFastlinkCreated{
CtxID: fastLink,
CtxPromocodeID: req.PromoCodeID,
CtxUserID: userID,
})
2024-01-14 14:18:36 +00:00
return c.Status(fiber.StatusCreated).JSON(fiber.Map{"fastlink": fastLink})
}
2024-01-27 12:51:32 +00:00
2024-03-03 18:24:28 +00:00
func (p *PromoCodeController) GetStats(c *fiber.Ctx) error {
2024-03-27 12:29:49 +00:00
var req models.PromoStatReq
2024-03-03 18:24:28 +00:00
if err := c.BodyParser(&req); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid request payload"})
}
2024-03-03 19:31:40 +00:00
if req.PromoCodeID == "" {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "PromoCode ID is required"})
}
2024-03-27 12:29:49 +00:00
promoStats, err := p.promoCodeService.GetStats(c.Context(), req)
2024-01-27 12:51:32 +00:00
if err != nil {
p.logger.Error("Failed getting promo stats", zap.Error(err))
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Internal Server Error: " + err.Error()})
2024-01-27 12:51:32 +00:00
}
return c.Status(fiber.StatusOK).JSON(promoStats)
}