codeword/internal/repository/promocode_repository.go
2024-01-11 22:47:54 +03:00

101 lines
2.4 KiB
Go

package repository
import (
"codeword/internal/models"
"context"
"errors"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"time"
)
var (
ErrDuplicateCodeword = errors.New("duplicate codeword")
ErrPromoCodeNotFound = errors.New("promo code not found")
)
type PromoCodeRepository struct {
mdb *mongo.Collection
}
func NewPromoCodeRepository(mdb *mongo.Collection) *PromoCodeRepository {
indexModel := mongo.IndexModel{
Keys: bson.D{
{"codeword", 1},
{"delete", 1},
},
Options: options.Index().SetUnique(true).SetPartialFilterExpression(bson.M{"delete": false}),
}
_, err := mdb.Indexes().CreateOne(context.Background(), indexModel)
if err != nil {
panic(err)
}
return &PromoCodeRepository{mdb: mdb}
}
func (r *PromoCodeRepository) CreatePromoCode(ctx context.Context, promoCode *models.PromoCode) (*models.PromoCode, error) {
promoCode.CreatedAt = time.Now()
promoCode.ID = primitive.NewObjectID()
_, err := r.mdb.InsertOne(ctx, promoCode)
if err != nil {
if writeErr, ok := err.(mongo.WriteException); ok {
for _, writeError := range writeErr.WriteErrors {
if writeError.Code == 11000 {
return nil, ErrDuplicateCodeword
}
}
}
return nil, err
}
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
}