package privilege import ( "context" "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" "go.uber.org/zap" "gitea.pena/PenaSide/tariffs/internal/errors" "gitea.pena/PenaSide/tariffs/internal/models" "time" ) type Deps struct { Mdb *mongo.Collection Logger *zap.Logger } type Privilege struct { mdb *mongo.Collection logger *zap.Logger } func NewPrivilegeRepo(deps Deps) *Privilege { return &Privilege{ mdb: deps.Mdb, logger: deps.Logger, } } func (p *Privilege) GetAllPrivileges(ctx context.Context) ([]models.Privilege, error) { filter := bson.M{"isDeleted": false} opts := options.Find() cursor, err := p.mdb.Find(ctx, filter, opts) if err != nil { if err == mongo.ErrNoDocuments { return nil, errors.ErrNotFound } p.logger.Error("failed to find privileges", zap.Error(err)) return nil, err } defer cursor.Close(ctx) var privileges []models.Privilege if err = cursor.All(ctx, &privileges); err != nil { p.logger.Error("failed to decode privileges", zap.Error(err)) return nil, err } return privileges, nil } func (p *Privilege) Create(ctx context.Context, req models.CreateUpdateReq) (models.Privilege, error) { exist := models.Privilege{} err := p.mdb.FindOne(ctx, bson.M{"privilegeId": req.PrivilegeId}).Decode(&exist) if err == nil { return models.Privilege{}, errors.ErrAlreadyExist } else if err != mongo.ErrNoDocuments { p.logger.Error("Failed to check existing privilege", zap.Error(err)) return models.Privilege{}, err } privilege := models.Privilege{ ID: primitive.NewObjectID(), Name: req.Name, PrivilegeID: req.PrivilegeId, ServiceKey: req.ServiceKey, Description: req.Description, Type: req.Type, Value: req.Value, Price: req.Price, CreatedAt: time.Now(), IsDeleted: false, } _, err = p.mdb.InsertOne(ctx, privilege) if err != nil { p.logger.Error("Failed to create privilege", zap.Error(err)) return models.Privilege{}, err } return privilege, nil } func (p *Privilege) Update(ctx context.Context, req models.CreateUpdateReq) (models.Privilege, error) { exist := models.Privilege{} err := p.mdb.FindOne(ctx, bson.M{"privilegeId": req.PrivilegeId}).Decode(&exist) if err != nil { if err == mongo.ErrNoDocuments { return models.Privilege{}, errors.ErrNotFound } p.logger.Error("Failed to find privilege", zap.Error(err)) return models.Privilege{}, err } currTime := time.Now() update := bson.M{ "$set": bson.M{ "name": req.Name, "serviceKey": req.ServiceKey, "description": req.Description, "type": req.Type, "value": req.Value, "price": req.Price, "updatedAt": currTime, }, } _, err = p.mdb.UpdateOne(ctx, bson.M{"privilegeId": req.PrivilegeId}, update) if err != nil { p.logger.Error("Failed to update privilege", zap.Error(err)) return models.Privilege{}, err } exist.Name = req.Name exist.ServiceKey = req.ServiceKey exist.Description = req.Description exist.Type = req.Type exist.Value = req.Value exist.Price = req.Price exist.UpdatedAt = currTime return exist, nil } func (p *Privilege) Delete(ctx context.Context, id string) (models.Privilege, error) { var privilege models.Privilege filter := bson.M{"privilegeId": id} update := bson.M{ "$set": bson.M{ "isDeleted": true, "deletedAt": time.Now(), }, } opts := options.FindOneAndUpdate().SetReturnDocument(options.After) err := p.mdb.FindOneAndUpdate(ctx, filter, update, opts).Decode(&privilege) if err != nil { if err == mongo.ErrNoDocuments { return models.Privilege{}, errors.ErrNotFound } p.logger.Error("failed to delete privilege", zap.Error(err)) return models.Privilege{}, err } return privilege, nil } func (p *Privilege) GetByID(ctx context.Context, id string) (models.Privilege, error) { var privilege models.Privilege filter := bson.M{ "privilegeId": id, "isDeleted": false, } err := p.mdb.FindOne(ctx, filter).Decode(&privilege) if err != nil { if err == mongo.ErrNoDocuments { return models.Privilege{}, errors.ErrNotFound } p.logger.Error("failed to get privilege by privilege id", zap.Error(err)) return models.Privilege{}, err } return privilege, nil } func (p *Privilege) GetByServiceKey(ctx context.Context, serviceKey string) ([]models.Privilege, error) { filter := bson.M{ "serviceKey": serviceKey, "isDeleted": false, } opts := options.Find() cursor, err := p.mdb.Find(ctx, filter, opts) if err != nil { if err == mongo.ErrNoDocuments { return nil, errors.ErrNotFound } p.logger.Error("failed to find privileges by service key", zap.Error(err)) return nil, err } defer cursor.Close(ctx) var privileges []models.Privilege if err = cursor.All(ctx, &privileges); err != nil { p.logger.Error("failed to decode privileges", zap.Error(err)) return nil, err } return privileges, nil } func (p *Privilege) PostMany(ctx context.Context, req models.ManyCreateUpdate) ([]models.Privilege, error) { var privileges []models.Privilege for _, r := range req.Privileges { exist := models.Privilege{} err := p.mdb.FindOne(ctx, bson.M{"privilegeId": r.PrivilegeId}).Decode(&exist) if err == nil { p.logger.Error("privilege already exists", zap.String("privilegeId", r.PrivilegeId)) return nil, errors.ErrAlreadyExist } else if err != mongo.ErrNoDocuments { p.logger.Error("failed to check existing privilege", zap.Error(err)) return nil, err } privileges = append(privileges, models.Privilege{ ID: primitive.NewObjectID(), Name: r.Name, PrivilegeID: r.PrivilegeId, ServiceKey: r.ServiceKey, Description: r.Description, Type: r.Type, Value: r.Value, Price: r.Price, CreatedAt: time.Now(), IsDeleted: false, }) } noneType := make([]interface{}, len(privileges)) for i, v := range privileges { noneType[i] = v } _, err := p.mdb.InsertMany(ctx, noneType) if err != nil { p.logger.Error("failed to insert privileges", zap.Error(err)) return nil, err } return privileges, nil } func (p *Privilege) UpdateMany(ctx context.Context, req models.ManyCreateUpdate) ([]models.Privilege, error) { var updated []models.Privilege for _, r := range req.Privileges { filter := bson.M{"privilegeId": r.PrivilegeId} update := bson.M{ "$set": bson.M{ "name": r.Name, "serviceKey": r.ServiceKey, "description": r.Description, "type": r.Type, "value": r.Value, "price": r.Price, "updatedAt": time.Now(), }, } var updatedPrivilege models.Privilege opts := options.FindOneAndUpdate().SetReturnDocument(options.After) err := p.mdb.FindOneAndUpdate(ctx, filter, update, opts).Decode(&updatedPrivilege) if err != nil { if err == mongo.ErrNoDocuments { return nil, errors.ErrNotFound } p.logger.Error("failed to update privilege", zap.Error(err)) return nil, err } updated = append(updated, updatedPrivilege) } return updated, nil } func (p *Privilege) RestorePrivilege(ctx context.Context, id string) (models.Privilege, error) { exist := models.Privilege{} err := p.mdb.FindOne(ctx, bson.M{"privilegeId": id}).Decode(&exist) if err != nil { if err == mongo.ErrNoDocuments { return models.Privilege{}, errors.ErrNotFound } p.logger.Error("Failed to find privilege", zap.Error(err)) return models.Privilege{}, err } currTime := time.Now() update := bson.M{ "$set": bson.M{ "isDeleted": false, "updatedAt": currTime, }, } _, err = p.mdb.UpdateOne(ctx, bson.M{"privilegeId": id}, update) if err != nil { p.logger.Error("Failed to restore privilege", zap.Error(err)) return models.Privilege{}, err } exist.IsDeleted = false exist.UpdatedAt = currTime return exist, nil }