2024-01-11 16:29:53 +00:00
|
|
|
package repository
|
|
|
|
|
|
|
|
import (
|
|
|
|
"codeword/internal/models"
|
|
|
|
"context"
|
2024-01-11 18:20:33 +00:00
|
|
|
"errors"
|
|
|
|
"go.mongodb.org/mongo-driver/bson"
|
|
|
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
2024-01-11 16:29:53 +00:00
|
|
|
"go.mongodb.org/mongo-driver/mongo"
|
2024-01-11 18:20:33 +00:00
|
|
|
"go.mongodb.org/mongo-driver/mongo/options"
|
2024-01-11 16:29:53 +00:00
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
2024-01-11 19:47:54 +00:00
|
|
|
var (
|
|
|
|
ErrDuplicateCodeword = errors.New("duplicate codeword")
|
|
|
|
ErrPromoCodeNotFound = errors.New("promo code not found")
|
|
|
|
)
|
2024-01-11 18:20:33 +00:00
|
|
|
|
2024-01-11 16:29:53 +00:00
|
|
|
type PromoCodeRepository struct {
|
|
|
|
mdb *mongo.Collection
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewPromoCodeRepository(mdb *mongo.Collection) *PromoCodeRepository {
|
2024-01-11 18:20:33 +00:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
|
2024-01-11 16:29:53 +00:00
|
|
|
return &PromoCodeRepository{mdb: mdb}
|
|
|
|
}
|
|
|
|
|
2024-01-11 18:23:15 +00:00
|
|
|
func (r *PromoCodeRepository) CreatePromoCode(ctx context.Context, promoCode *models.PromoCode) (*models.PromoCode, error) {
|
2024-01-11 16:29:53 +00:00
|
|
|
promoCode.CreatedAt = time.Now()
|
2024-01-11 18:20:33 +00:00
|
|
|
promoCode.ID = primitive.NewObjectID()
|
|
|
|
|
2024-01-11 16:29:53 +00:00
|
|
|
_, err := r.mdb.InsertOne(ctx, promoCode)
|
|
|
|
if err != nil {
|
2024-01-11 18:20:33 +00:00
|
|
|
if writeErr, ok := err.(mongo.WriteException); ok {
|
|
|
|
for _, writeError := range writeErr.WriteErrors {
|
|
|
|
if writeError.Code == 11000 {
|
|
|
|
return nil, ErrDuplicateCodeword
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-01-11 16:29:53 +00:00
|
|
|
return nil, err
|
|
|
|
}
|
2024-01-11 18:20:33 +00:00
|
|
|
|
2024-01-11 16:29:53 +00:00
|
|
|
return promoCode, nil
|
|
|
|
}
|
2024-01-11 19:47:54 +00:00
|
|
|
|
2024-01-12 09:42:56 +00:00
|
|
|
func (r *PromoCodeRepository) EditPromoCode(ctx context.Context, editPromoCode *models.ReqEditPromoCode) (*models.PromoCode, error) {
|
|
|
|
promoCodeID, err := primitive.ObjectIDFromHex(editPromoCode.ID)
|
2024-01-11 19:47:54 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2024-01-12 09:42:56 +00:00
|
|
|
updateFields := bson.M{}
|
|
|
|
if editPromoCode.Description != nil {
|
|
|
|
updateFields["description"] = *editPromoCode.Description
|
|
|
|
}
|
|
|
|
if editPromoCode.Greetings != nil {
|
|
|
|
updateFields["greetings"] = *editPromoCode.Greetings
|
|
|
|
}
|
|
|
|
if editPromoCode.DueTo != nil {
|
|
|
|
updateFields["dueTo"] = *editPromoCode.DueTo
|
|
|
|
}
|
|
|
|
if editPromoCode.ActivationCount != nil {
|
|
|
|
updateFields["activationCount"] = *editPromoCode.ActivationCount
|
|
|
|
}
|
|
|
|
if editPromoCode.Delete != nil {
|
|
|
|
updateFields["delete"] = *editPromoCode.Delete
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(updateFields) == 0 {
|
|
|
|
return r.GetPromoCodeByID(ctx, promoCodeID)
|
2024-01-11 19:47:54 +00:00
|
|
|
}
|
|
|
|
|
2024-01-12 09:42:56 +00:00
|
|
|
update := bson.M{"$set": updateFields}
|
|
|
|
result, err := r.mdb.UpdateOne(ctx, bson.M{"_id": promoCodeID}, update)
|
2024-01-11 19:47:54 +00:00
|
|
|
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
|
|
|
|
}
|