From 5ff557c2c2907ddab54c514258425fe2a70012f1 Mon Sep 17 00:00:00 2001 From: Pavel Date: Thu, 11 Jan 2024 22:47:54 +0300 Subject: [PATCH] add edit promo route --- docs/openapi.yaml | 73 ++++++++++++++++++- .../promocode/promocode_controller.go | 20 +++++ internal/models/bonus.go | 11 +++ internal/repository/promocode_repository.go | 48 +++++++++++- internal/server/http/http_server.go | 1 + internal/services/promocode_service.go | 11 +++ 6 files changed, 162 insertions(+), 2 deletions(-) diff --git a/docs/openapi.yaml b/docs/openapi.yaml index f8ce1bf..8769379 100644 --- a/docs/openapi.yaml +++ b/docs/openapi.yaml @@ -121,6 +121,51 @@ paths: error: type: string + /promocode/edit: + put: + summary: Обновить существующий промокод + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ReqEditPromoCode' + responses: + '200': + description: Промокод успешно обновлен + content: + application/json: + schema: + $ref: '#/components/schemas/PromoCodeResponse' + '400': + description: Неверный формат запроса + content: + application/json: + schema: + type: object + properties: + error: + type: string + '404': + description: Промокод не найден + content: + application/json: + schema: + type: object + properties: + error: + type: string + '500': + description: Внутренняя ошибка сервера + content: + application/json: + schema: + type: object + properties: + error: + type: string + + components: schemas: PromoCodeRequest: @@ -232,4 +277,30 @@ components: createdAt: type: string format: date-time - description: Время создания промокода \ No newline at end of file + description: Время создания промокода + + ReqEditPromoCode: + type: object + properties: + id: + type: string + description: ID промокода, который обновляем + description: + type: string + description: Описание, необходимое менеджеру в админке + greetings: + type: string + description: Текст, выдаваемый пользователю в ответ на активацию промокода + dueTo: + type: integer + format: int64 + description: Временная метка окончания активации кода + activationCount: + type: integer + format: int64 + description: Предел количества активаций промокода + delete: + type: boolean + description: Флаг удаления промокода + required: + - id diff --git a/internal/controller/promocode/promocode_controller.go b/internal/controller/promocode/promocode_controller.go index 6bd5d29..7bd0014 100644 --- a/internal/controller/promocode/promocode_controller.go +++ b/internal/controller/promocode/promocode_controller.go @@ -40,3 +40,23 @@ func (p *PromoCodeController) CreatePromoCode(c *fiber.Ctx) error { return c.Status(fiber.StatusCreated).JSON(createdPromoCode) } + +func (p *PromoCodeController) EditPromoCode(c *fiber.Ctx) error { + var reqEditPromoCode models.ReqEditPromoCode + if err := c.BodyParser(&reqEditPromoCode); err != nil { + return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid request payload"}) + } + + editedPromoCode, err := p.promoCodeService.EditPromoCode(c.Context(), &reqEditPromoCode) + 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"}) + } + + return c.Status(fiber.StatusOK).JSON(editedPromoCode) +} diff --git a/internal/models/bonus.go b/internal/models/bonus.go index da48c38..ff7cf8e 100644 --- a/internal/models/bonus.go +++ b/internal/models/bonus.go @@ -29,3 +29,14 @@ type PromoCode struct { Delete bool `json:"delete" bson:"delete"` CreatedAt time.Time `json:"createdAt" bson:"createdAt"` } + +type ReqEditPromoCode struct { + ID string `json:"id" bson:"_id"` //айдишник промокода, который обновляем + Description string `json:"description" bson:"description"` // описание, необходимое менеджеру в админке + Greetings string `json:"greetings" bson:"greetings"` // текст, выдаваемый пользователю в ответ на активацию промокода + + DueTo int64 `json:"dueTo" bson:"dueTo"` // таймштамп времени окончания работы активации промокода + ActivationCount int64 `json:"activationCount" bson:"activationCount"` // предел количества активаций промокода + + Delete bool `json:"delete" bson:"delete"` +} diff --git a/internal/repository/promocode_repository.go b/internal/repository/promocode_repository.go index 8e5a6dc..11a209f 100644 --- a/internal/repository/promocode_repository.go +++ b/internal/repository/promocode_repository.go @@ -11,7 +11,10 @@ import ( "time" ) -var ErrDuplicateCodeword = errors.New("duplicate codeword") +var ( + ErrDuplicateCodeword = errors.New("duplicate codeword") + ErrPromoCodeNotFound = errors.New("promo code not found") +) type PromoCodeRepository struct { mdb *mongo.Collection @@ -52,3 +55,46 @@ func (r *PromoCodeRepository) CreatePromoCode(ctx context.Context, promoCode *mo return promoCode, nil } + +func (r *PromoCodeRepository) EditPromoCode(ctx context.Context, EditPromoCode *models.ReqEditPromoCode) (*models.PromoCode, error) { + promoCodeID, err := primitive.ObjectIDFromHex(EditPromoCode.ID) + if err != nil { + return nil, err + } + + filter := bson.M{"_id": promoCodeID} + update := bson.M{ + "$set": bson.M{ + "description": EditPromoCode.Description, + "greetings": EditPromoCode.Greetings, + "dueTo": EditPromoCode.DueTo, + "activationCount": EditPromoCode.ActivationCount, + "delete": EditPromoCode.Delete, + }, + } + + result, err := r.mdb.UpdateOne(ctx, filter, update) + if err != nil { + return nil, err + } + + if result.MatchedCount == 0 { + return nil, ErrPromoCodeNotFound + } + + return r.GetPromoCodeByID(ctx, promoCodeID) +} + +func (r *PromoCodeRepository) GetPromoCodeByID(ctx context.Context, promoCodeID primitive.ObjectID) (*models.PromoCode, error) { + var promoCode models.PromoCode + err := r.mdb.FindOne(ctx, bson.M{"_id": promoCodeID}).Decode(&promoCode) + if err != nil { + if err == mongo.ErrNoDocuments { + return nil, ErrPromoCodeNotFound + } + + return nil, err + } + + return &promoCode, nil +} diff --git a/internal/server/http/http_server.go b/internal/server/http/http_server.go index cf118b8..9c70564 100644 --- a/internal/server/http/http_server.go +++ b/internal/server/http/http_server.go @@ -58,6 +58,7 @@ func (s *Server) registerRoutes() { s.app.Get("/recover/:sign", s.RecoveryController.HandleRecoveryLink) s.app.Post("/promocode/create", s.PromoCodeController.CreatePromoCode) + s.app.Put("/promocode/edit", s.PromoCodeController.EditPromoCode) //... other } diff --git a/internal/services/promocode_service.go b/internal/services/promocode_service.go index 20af7b1..e8f92cf 100644 --- a/internal/services/promocode_service.go +++ b/internal/services/promocode_service.go @@ -8,6 +8,7 @@ import ( type PromoCodeRepository interface { CreatePromoCode(ctx context.Context, promoCode *models.PromoCode) (*models.PromoCode, error) + EditPromoCode(ctx context.Context, reqEditPromoCode *models.ReqEditPromoCode) (*models.PromoCode, error) } type PromoDeps struct { @@ -36,3 +37,13 @@ func (s *PromoCodeService) CreatePromoCode(ctx context.Context, req *models.Prom return promoCode, nil } + +func (s *PromoCodeService) EditPromoCode(ctx context.Context, req *models.ReqEditPromoCode) (*models.PromoCode, error) { + editedPromoCode, err := s.promoCodeRepo.EditPromoCode(ctx, req) + if err != nil { + s.logger.Error("Failed to edit promocode in database", zap.Error(err)) + return nil, err + } + + return editedPromoCode, nil +}