package tariff 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" "math" "time" ) type Deps struct { Mdb *mongo.Collection Logger *zap.Logger PrivilegeDB *mongo.Collection } type Tariff struct { mdb *mongo.Collection logger *zap.Logger privilegeDB *mongo.Collection } func NewTariffRepo(deps Deps) *Tariff { return &Tariff{ mdb: deps.Mdb, logger: deps.Logger, privilegeDB: deps.PrivilegeDB, } } func (t *Tariff) GetByID(ctx context.Context, id primitive.ObjectID) (models.Tariff, error) { var tariff models.Tariff filter := bson.M{ "_id": id, "isDeleted": false, } err := t.mdb.FindOne(ctx, filter).Decode(&tariff) if err != nil { if err == mongo.ErrNoDocuments { return tariff, errors.ErrNotFound } t.logger.Error("failed to get tariff by object id", zap.Error(err)) return tariff, err } return tariff, nil } func (t *Tariff) Create(ctx context.Context, req models.Tariff) (models.Tariff, error) { req.ID = primitive.NewObjectID() req.CreatedAt = time.Now() req.IsDeleted = false req.UpdatedAt = time.Now() _, err := t.mdb.InsertOne(ctx, req) if err != nil { t.logger.Error("failed insert tariff", zap.Error(err)) return req, err } return req, nil } func (t *Tariff) GetList(ctx context.Context, page, limit int64, userID string) (models.TariffPagination, error) { var result models.TariffPagination filter := bson.M{ "$or": []bson.M{ {"isCustom": false, "isDeleted": false}, }, } if userID != "" { filter["$or"] = append(filter["$or"].([]bson.M), bson.M{"isCustom": true, "userID": userID}) } count, err := t.mdb.CountDocuments(ctx, filter) if err != nil { t.logger.Error("failed count tariffs", zap.Error(err)) return result, err } totalPages := int(math.Ceil(float64(count) / float64(limit))) offset := (page - 1) * limit findOptions := options.Find().SetSort(bson.D{{"order", 1}}).SetSkip(offset).SetLimit(limit) cursor, err := t.mdb.Find(ctx, filter, findOptions) if err != nil { t.logger.Error("failed find tariffs", zap.Error(err)) return result, err } defer cursor.Close(ctx) var tariffs []models.Tariff if err = cursor.All(ctx, &tariffs); err != nil { t.logger.Error("failed decode tariffs", zap.Error(err)) return result, err } result.TotalPages = totalPages result.Tariffs = tariffs return result, nil } func (t *Tariff) SoftDelete(ctx context.Context, tariffID primitive.ObjectID) (models.Tariff, error) { var tariff models.Tariff filter := bson.M{"_id": tariffID} update := bson.M{"$set": bson.M{"isDeleted": true, "deletedAt": time.Now()}} err := t.mdb.FindOneAndUpdate(ctx, filter, update, options.FindOneAndUpdate().SetReturnDocument(options.After)).Decode(&tariff) if err != nil { if err == mongo.ErrNoDocuments { return tariff, errors.ErrNotFound } t.logger.Error("failed soft delete tariff", zap.Error(err)) return tariff, err } return tariff, nil } func (t *Tariff) Update(ctx context.Context, tariffID primitive.ObjectID, req models.Tariff) (models.Tariff, error) { var tariff models.Tariff err := t.mdb.FindOne(ctx, bson.M{"_id": tariffID}).Decode(&tariff) if err != nil { if err == mongo.ErrNoDocuments { return tariff, errors.ErrNotFound } t.logger.Error("failed find tariff", zap.Error(err)) return tariff, err } privilegeIDs := make([]string, len(req.Privileges)) for i, privilege := range req.Privileges { privilegeIDs[i] = privilege.PrivilegeID } cursor, err := t.privilegeDB.Find(ctx, bson.M{"privilegeId": bson.M{"$in": privilegeIDs}}) if err != nil { t.logger.Error("failed find privileges", zap.Error(err)) return tariff, err } defer cursor.Close(ctx) privilegeMap := make(map[string]models.Privilege) for cursor.Next(ctx) { var privilege models.Privilege if err := cursor.Decode(&privilege); err != nil { t.logger.Error("failed decode privilege", zap.Error(err)) return tariff, err } privilegeMap[privilege.PrivilegeID] = privilege } clean := make([]models.Privilege, len(req.Privileges)) for i, privilege := range req.Privileges { origPrivilege := privilegeMap[privilege.PrivilegeID] clean[i] = models.Privilege{ ID: origPrivilege.ID, Name: origPrivilege.Name, PrivilegeID: origPrivilege.PrivilegeID, ServiceKey: origPrivilege.ServiceKey, Description: origPrivilege.Description, Type: origPrivilege.Type, Value: origPrivilege.Value, Amount: origPrivilege.Amount, Price: origPrivilege.Price, } } update := bson.M{ "$set": bson.M{ "description": req.Description, "order": req.Order, "name": req.Name, "price": req.Price, "isCustom": req.IsCustom, "privileges": clean, }, } err = t.mdb.FindOneAndUpdate(ctx, bson.M{"_id": tariffID}, update).Decode(&tariff) if err != nil { if err == mongo.ErrNoDocuments { return tariff, errors.ErrNotFound } t.logger.Error("failed update tariff", zap.Error(err)) return tariff, err } return tariff, nil } func (t *Tariff) Restore(ctx context.Context, tariffID primitive.ObjectID) (models.Tariff, error) { var tariff models.Tariff filter := bson.M{"_id": tariffID} update := bson.M{"$set": bson.M{"isDeleted": false}} err := t.mdb.FindOneAndUpdate(ctx, filter, update, options.FindOneAndUpdate().SetReturnDocument(options.After)).Decode(&tariff) if err != nil { if err == mongo.ErrNoDocuments { return tariff, errors.ErrNotFound } t.logger.Error("failed restore tariff", zap.Error(err)) return tariff, err } return tariff, nil }