package mongos import ( "context" "errors" "github.com/Pena-Co-Ltd/amocrm_templategen_back/dal/model" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/mongo" "go.uber.org/zap" "time" ) type Amo struct { coll *mongo.Collection logger *zap.Logger } func InitAmo(db *mongo.Database, logger *zap.Logger) *Amo { return &Amo{coll: db.Collection("amo"), logger: logger} } func (d *Amo) InsertOrUpdate(ctx context.Context, record *model.Amo) (string, error) { if record.AccountID == "" { err := errors.New("got empty account_id") d.logger.Error("ErrorInsertOrUpdateAmo", zap.Error(err)) return "", err } record.CreatedAt = time.Now() record.UpdatedAt = time.Now() found, err := d.GetByAccountID(ctx, record.AccountID) if err != nil { return "", err } if found == nil { result, err := d.coll.InsertOne(ctx, record) if err != nil { d.logger.Error("ErrorInsertOrUpdateAmo", zap.Error(err)) return "", err } id := result.InsertedID.(primitive.ObjectID).Hex() d.logger.Info("InfoInserteAmo", zap.String("id", id)) return id, nil } err = d.Update(ctx, record) if err != nil { d.logger.Error("ErrorInsertOrUpdateAmo", zap.Error(err)) return "", err } return found.ID, nil } func (d *Amo) GetByID(ctx context.Context, id string) (*model.Amo, error) { objID, err := primitive.ObjectIDFromHex(id) if err != nil { d.logger.Error("ErrorGetAmo", zap.Error(err)) return nil, err } filter := bson.M{"_id": objID, "is_deleted": false} var result model.Amo err = d.coll.FindOne(ctx, filter).Decode(&result) if err == mongo.ErrNoDocuments { return nil, nil } else { if err != nil { d.logger.Error("ErrorGetAmo", zap.Error(err)) return nil, err } } d.logger.Info("InfoGetAmo", zap.String("id", result.ID)) return &result, nil } func (d *Amo) GetListByUserID(ctx context.Context, userID string) ([]model.Amo, error) { filter := bson.M{"user_id": userID, "is_deleted": false} var result []model.Amo cur, err := d.coll.Find(ctx, filter) if err == mongo.ErrNoDocuments { return nil, nil } else { if err != nil { d.logger.Error("ErrorGetListAmo", zap.Error(err)) return nil, err } } err = cur.All(ctx, &result) if err != nil { d.logger.Error("ErrorGetListAmo", zap.Error(err)) return nil, err } d.logger.Info("InfoGetListAmo") return result, nil } func (d *Amo) GetByAccountID(ctx context.Context, accId string) (*model.Amo, error) { filter := bson.M{"account_id": accId, "is_deleted": false} var result model.Amo err := d.coll.FindOne(ctx, filter).Decode(&result) if err == mongo.ErrNoDocuments { return nil, nil } else { if err != nil { d.logger.Error("ErrorGetAmo", zap.Error(err)) return nil, err } } d.logger.Info("InfoGetAmo", zap.String("id", result.ID)) return &result, nil } // Update - обновляет запись по id или accountID func (d *Amo) Update(ctx context.Context, record *model.Amo) error { filter := bson.M{"is_deleted": false} if record.ID != "" { objID, err := primitive.ObjectIDFromHex(record.ID) if err != nil { d.logger.Error("ErrorUpdateAmo", zap.Error(err)) return err } filter["_id"] = objID } else if record.AccountID != "" { filter["account_id"] = record.AccountID } else { err := errors.New("got empty id and account id") d.logger.Error("ErrorUpdateAmo", zap.Error(err)) return err } update := bson.M{"updated_at": time.Now()} // Token if record.AccessToken != "" { update["access_token"] = record.AccessToken } if record.RefreshToken != "" { update["refresh_token"] = record.RefreshToken } if !record.ExpiresIn.IsZero() { update["expires_in"] = record.ExpiresIn } if record.TokenType != "" { update["token_type"] = record.TokenType } // AccessRules if record.AccessRules.Visibility != nil || len(record.AccessRules.Visibility) > 0 { update["access_rules.visibility"] = record.AccessRules.Visibility } if record.AccessRules.Creation != nil || len(record.AccessRules.Creation) > 0 { update["access_rules.creation"] = record.AccessRules.Creation } if record.AccessRules.Delete != nil || len(record.AccessRules.Delete) > 0 { update["access_rules.delete"] = record.AccessRules.Delete } updated, err := d.coll.UpdateOne(ctx, filter, bson.D{{"$set", update}}) if err != nil { d.logger.Error("ErrorUpdateAmo", zap.Error(err)) return err } var id string _, ok := updated.UpsertedID.(primitive.ObjectID) if ok { id = updated.UpsertedID.(primitive.ObjectID).Hex() } d.logger.Info("InfoUpdateAmo", zap.String("_id", id)) return nil } func (d *Amo) DeleteByUserID(ctx context.Context, userID string) error { if userID == "" { err := errors.New("got empty user id") d.logger.Error("ErrorDeleteAmo", zap.Error(err)) return err } filter := bson.M{"user_id": userID, "is_deleted": false} update := bson.M{"updated_at": time.Now(), "is_deleted": true} _, err := d.coll.UpdateMany(ctx, filter, bson.D{{"$set", update}}) if err != nil { d.logger.Error("ErrorDeleteAmo", zap.Error(err)) return err } return nil } func (d *Amo) UpdateAccessRules(ctx context.Context, id string, record *model.AmoAccessRules) error { objID, err := primitive.ObjectIDFromHex(id) if err != nil { d.logger.Error("ErrorUpdateAmoAccessRules", zap.Error(err)) return err } filter := bson.M{"_id": objID, "is_deleted": false} update := bson.M{"updated_at": time.Now()} if record.Visibility != nil || len(record.Visibility) > 0 { update["access_rules.visibility"] = record.Visibility } if record.Creation != nil || len(record.Creation) > 0 { update["access_rules.creation"] = record.Creation } if record.Delete != nil || len(record.Delete) > 0 { update["access_rules.delete"] = record.Delete } _, err = d.coll.UpdateOne(ctx, filter, bson.D{{"$set", update}}) if err != nil { d.logger.Error("ErrorUpdateAmoAccessRules", zap.Error(err)) return err } return nil }