package amo import ( "context" "database/sql" "encoding/json" "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/dal/sqlcgen" "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/model" "strings" "time" ) type AmoRepository struct { queries *sqlcgen.Queries pool *sql.DB } type Deps struct { Queries *sqlcgen.Queries Pool *sql.DB } func NewAmoRepository(deps Deps) *AmoRepository { return &AmoRepository{ queries: deps.Queries, pool: deps.Pool, } } // методы пользователя func (r *AmoRepository) GettingUserWithPagination(ctx context.Context, req *model.PaginationReq, accountID string) (*model.UserListResp, error) { rows, err := r.queries.GetUsersWithPagination(ctx, sqlcgen.GetUsersWithPaginationParams{ Column2: req.Page, Limit: req.Size, Accountid: accountID, }) if err != nil { return nil, err } var count int64 var users []model.User for _, row := range rows { user := model.User{ ID: row.ID, Accountid: row.Accountid, AmoID: row.Amoid, Name: row.Name, Email: row.Email, Group: row.Group, Role: row.Role, Createdat: row.Createdat.Time.Unix(), Subdomain: row.Subdomain, Amouserid: row.Amouserid, Country: row.Country, } count = row.TotalCount users = append(users, user) } resp := model.UserListResp{ Count: count, Items: users, } return &resp, nil } func (r *AmoRepository) SoftDeleteAccount(ctx context.Context, accountID string) error { err := r.queries.SoftDeleteAccount(ctx, accountID) if err != nil { return err } return nil } func (r *AmoRepository) GetCurrentAccount(ctx context.Context, accountID string) (*model.User, error) { row, err := r.queries.GetCurrentAccount(ctx, accountID) if err != nil { return nil, err } user := model.User{ ID: row.ID, Accountid: row.Accountid, AmoID: row.Amoid, Name: row.Name, Email: row.Email, Role: row.Role, Group: row.Group, Createdat: row.Createdat.Time.Unix(), Subdomain: row.Subdomain, Amouserid: row.Amouserid, Country: row.Country, } return &user, nil } func (r *AmoRepository) CreateAccount(ctx context.Context, accountID string, userInfo model.User) error { err := r.queries.CreateAmoAccount(ctx, sqlcgen.CreateAmoAccountParams{ Accountid: accountID, Amoid: userInfo.AmoID, Name: userInfo.Name, Email: userInfo.Email, Role: userInfo.Role, Group: userInfo.Group, Createdat: sql.NullTime{Time: time.Now(), Valid: true}, Subdomain: userInfo.Subdomain, Amouserid: userInfo.Amouserid, Country: userInfo.Country, }) if err != nil { return err } return nil } func (r *AmoRepository) CheckMainUser(ctx context.Context, user model.User) error { err := r.queries.CheckMainUser(ctx, sqlcgen.CheckMainUserParams{ Name: user.Name, Group: user.Group, Email: user.Email, Role: user.Role, Amoid: user.AmoID, }) if err != nil { return err } return nil } func (r *AmoRepository) CheckAndUpdateUsers(ctx context.Context, user model.User) error { err := r.queries.CheckUsers(ctx, sqlcgen.CheckUsersParams{ Amoid: user.AmoID, Name: user.Name, Email: user.Email, Role: user.Role, Group: user.Group, Amouserid: user.Amouserid, }) // чекаем на конфликт if err != nil && strings.Contains(err.Error(), "duplicate key value violates unique constraint") { err = r.queries.UpdateUsers(ctx, sqlcgen.UpdateUsersParams{ Amoid: user.AmoID, Name: user.Name, Email: user.Email, Role: user.Role, Group: user.Group, Amouserid: user.Amouserid, }) if err != nil { return err } return nil } return err } func (r *AmoRepository) GetTokenByID(ctx context.Context, accountID string) (*model.Token, error) { row, err := r.queries.GetTokenById(ctx, accountID) if err != nil { return nil, err } return &model.Token{ AccountID: row.Accountid, RefreshToken: row.Refreshtoken, AccessToken: row.Accesstoken, }, nil } // методы webhook func (r *AmoRepository) WebhookCreate(ctx context.Context, tokens model.Token) error { err := r.queries.CreateWebHook(ctx, sqlcgen.CreateWebHookParams{ Accountid: tokens.AccountID, Refreshtoken: tokens.RefreshToken, Accesstoken: tokens.AccessToken, Authcode: tokens.AuthCode, Expiration: time.Unix(tokens.Expiration, 0).In(time.Unix(tokens.CreatedAt, 0).Location()), Createdat: sql.NullTime{Time: time.Unix(tokens.CreatedAt, 0), Valid: true}, }) if err != nil { return err } return nil } func (r *AmoRepository) WebhookUpdate(ctx context.Context, tokens []model.Token) error { dollar1, err := json.Marshal(tokens) if err != nil { return err } err = r.queries.WebhookUpdate(ctx, dollar1) if err != nil { return err } return nil } // воркер запускается каждые 5 минут, поэтомму ищем токены котторые исекают менее чем через 10 минут отдаем их на обноление func (r *AmoRepository) CheckExpired(ctx context.Context) ([]model.Token, error) { rows, err := r.queries.CheckExpired(ctx) if err != nil { return nil, err } var tokens []model.Token for _, row := range rows { token := model.Token{ AccountID: row.Accountid, AccessToken: row.Accesstoken, RefreshToken: row.Refreshtoken, AuthCode: row.Authcode, Expiration: row.Expiration.Unix(), CreatedAt: row.Createdat.Time.Unix(), } tokens = append(tokens, token) } return tokens, nil } func (r *AmoRepository) GetAllTokens(ctx context.Context) ([]model.Token, error) { rows, err := r.queries.GetAllTokens(ctx) if err != nil { return nil, err } var tokens []model.Token for _, row := range rows { token := model.Token{ AccountID: row.Accountid, AccessToken: row.Accesstoken, RefreshToken: row.Refreshtoken, AuthCode: row.Authcode, Expiration: row.Expiration.Unix(), CreatedAt: row.Createdat.Time.Unix(), } tokens = append(tokens, token) } return tokens, nil } func (r *AmoRepository) WebhookDelete(ctx context.Context, amoID int) error { return nil } // методы pipelines func (r *AmoRepository) GetPipelinesWithPagination(ctx context.Context, req *model.PaginationReq, accountID string) (*model.UserListPipelinesResp, error) { rows, err := r.queries.GetPipelinesWithPagination(ctx, sqlcgen.GetPipelinesWithPaginationParams{ Accountid: accountID, Column2: req.Page, Limit: req.Size, }) if err != nil { return nil, err } var count int64 var pipelines []model.Pipeline for _, row := range rows { count = row.TotalCount pipeline := model.Pipeline{ ID: row.ID, Amoid: row.Amoid, AccountID: row.Accountid, Name: row.Name, Isarchive: row.Isarchive, Createdat: row.Createdat.Time.Unix(), } pipelines = append(pipelines, pipeline) } resp := model.UserListPipelinesResp{ Count: count, Items: pipelines, } return &resp, nil } func (r *AmoRepository) CheckPipelines(ctx context.Context, pipelines []model.Pipeline) error { dollar1, err := json.Marshal(pipelines) if err != nil { return err } rows, err := r.queries.CheckPipelines(ctx, dollar1) if err != nil { return err } if rows != nil { var toUpdate []model.Pipeline for _, row := range rows { to := model.Pipeline{ Amoid: row.Amoid, AccountID: row.Accountid, Name: row.Name, Isarchive: row.Isarchive, } toUpdate = append(toUpdate, to) } dollar1, err := json.Marshal(toUpdate) if err != nil { return err } err = r.queries.UpdatePipelines(ctx, dollar1) if err != nil { return err } } return nil } // методы steps func (r *AmoRepository) GetStepsWithPagination(ctx context.Context, req *model.PaginationReq, accountID string) (*model.UserListStepsResp, error) { rows, err := r.queries.GetStepsWithPagination(ctx, sqlcgen.GetStepsWithPaginationParams{ Accountid: accountID, Column2: req.Page, Limit: req.Size, }) if err != nil { return nil, err } var count int64 var steps []model.Step for _, row := range rows { count = row.TotalCount step := model.Step{ ID: row.ID, Amoid: row.Amoid, Pipelineid: row.Pipelineid, Accountid: row.Accountid, Name: row.Name, Color: row.Color, Createdat: row.Createdat.Time.Unix(), } steps = append(steps, step) } resp := model.UserListStepsResp{ Count: count, Items: steps, } return &resp, nil } func (r *AmoRepository) CheckSteps(ctx context.Context, steps []model.Step) error { dollar1, err := json.Marshal(steps) if err != nil { return err } rows, err := r.queries.CheckSteps(ctx, dollar1) if err != nil { return err } if rows != nil { var toUpdate []model.Step for _, row := range rows { to := model.Step{ Amoid: row.Amoid, Pipelineid: row.Pipelineid, Accountid: row.Accountid, Name: row.Name, Color: row.Color, } toUpdate = append(toUpdate, to) } dollar1, err := json.Marshal(toUpdate) if err != nil { return err } err = r.queries.UpdateSteps(ctx, dollar1) if err != nil { return err } } return nil } // методы tags func (r *AmoRepository) GetTagsWithPagination(ctx context.Context, req *model.PaginationReq, accountID string) (*model.UserListTagsResp, error) { rows, err := r.queries.GetTagsWithPagination(ctx, sqlcgen.GetTagsWithPaginationParams{ Accountid: accountID, Column2: req.Page, Limit: req.Size, }) if err != nil { return nil, err } var count int64 var tags []model.Tag for _, row := range rows { count = row.TotalCount var entity model.EntityType v := string(row.Entity.([]byte)) entity = model.EntityType(v) tag := model.Tag{ ID: row.ID, Amoid: row.Amoid, Accountid: row.Accountid, Entity: entity, Name: row.Name, Color: &row.Color, Createdat: row.Createdat.Time.Unix(), } tags = append(tags, tag) } resp := model.UserListTagsResp{ Count: count, Items: tags, } return &resp, nil } func (r *AmoRepository) CheckTags(ctx context.Context, tags []model.Tag, tokenID string) error { column2, err := json.Marshal(tags) if err != nil { return err } rows, err := r.queries.CheckTags(ctx, sqlcgen.CheckTagsParams{ Accountid: tokenID, Column2: column2, }) if rows != nil { var toUpdate []model.Tag for _, row := range rows { var entity model.EntityType v := string(row.Entity.([]byte)) entity = model.EntityType(v) to := model.Tag{ Amoid: row.Amoid, Accountid: row.Amoid_2, Entity: entity, Name: row.Name, Color: &row.Color, } toUpdate = append(toUpdate, to) } dollar1, err := json.Marshal(toUpdate) if err != nil { return err } err = r.queries.UpdateTags(ctx, dollar1) if err != nil { return err } } if err != nil { return err } return nil } // методы fields func (r *AmoRepository) GetFieldsWithPagination(ctx context.Context, req *model.PaginationReq, accountID string) (*model.UserListFieldsResp, error) { rows, err := r.queries.GetFieldsWithPagination(ctx, sqlcgen.GetFieldsWithPaginationParams{ Accountid: accountID, Column2: req.Page, Limit: req.Size, }) if err != nil { return nil, err } var count int64 var fields []model.Field for _, row := range rows { count = row.TotalCount var entity model.EntityType v := string(row.Entity.([]byte)) entity = model.EntityType(v) field := model.Field{ ID: row.ID, Amoid: row.Amoid, Code: row.Code, Accountid: row.Accountid, Name: row.Name, Entity: entity, Type: row.Type, Createdat: row.Createdat.Time.Unix(), } fields = append(fields, field) } resp := model.UserListFieldsResp{ Count: count, Items: fields, } return &resp, nil } func (r *AmoRepository) CheckFields(ctx context.Context, fields []model.Field, tokenID string) error { column2, err := json.Marshal(fields) if err != nil { return err } rows, err := r.queries.CheckFields(ctx, sqlcgen.CheckFieldsParams{ Accountid: tokenID, Column2: column2, }) if err != nil { return err } if rows != nil { var toUpdate []model.Field for _, row := range rows { var entity model.EntityType v := string(row.Entity.([]byte)) entity = model.EntityType(v) to := model.Field{ Amoid: row.Amoid, Code: row.Code, Accountid: row.Amoid_2, Entity: entity, Type: row.Type, } toUpdate = append(toUpdate, to) } dollar1, err := json.Marshal(toUpdate) if err != nil { return err } err = r.queries.UpdateFields(ctx, dollar1) if err != nil { return err } } return nil } // методы rules func (r *AmoRepository) ChangeQuizSettings(ctx context.Context, request *model.RulesReq, accountID string, quizID int) (*model.Rule, error) { jsonFieldRule, err := json.Marshal(request.Fieldsrule) if err != nil { return nil, err } row, err := r.queries.ChangeQuizSettings(ctx, sqlcgen.ChangeQuizSettingsParams{ Performerid: request.PerformerID, Pipelineid: request.PipelineID, Stepid: request.StepID, Utms: request.Utms, Fieldsrule: jsonFieldRule, Accountid: accountID, Quizid: int32(quizID), }) var fieldsRule model.Fieldsrule err = json.Unmarshal(row.Fieldsrule, &fieldsRule) if err != nil { return nil, err } return &model.Rule{ ID: row.ID, Accountid: row.Accountid, Quizid: row.Quizid, Performerid: row.Performerid, Pipelineid: row.Pipelineid, Stepid: row.Stepid, Utms: row.Utms, Fieldsrule: fieldsRule, }, nil } func (r *AmoRepository) SetQuizSettings(ctx context.Context, request *model.RulesReq, accountID string, quizID int) (*model.Rule, error) { jsonFieldRule, err := json.Marshal(request.Fieldsrule) if err != nil { return nil, err } row, err := r.queries.SetQuizSettings(ctx, sqlcgen.SetQuizSettingsParams{ Performerid: request.PerformerID, Pipelineid: request.PipelineID, Stepid: request.StepID, Utms: request.Utms, Fieldsrule: jsonFieldRule, Accountid: accountID, Quizid: int32(quizID), }) var fieldsRule model.Fieldsrule err = json.Unmarshal(row.Fieldsrule, &fieldsRule) if err != nil { return nil, err } return &model.Rule{ ID: row.ID, Accountid: row.Accountid, Quizid: row.Quizid, Performerid: row.Performerid, Pipelineid: row.Pipelineid, Stepid: row.Stepid, Utms: row.Utms, Fieldsrule: fieldsRule, }, nil } func (r *AmoRepository) GettingQuizRules(ctx context.Context, quizID int) (*model.Rule, error) { row, err := r.queries.GetQuizRule(ctx, int32(quizID)) if err != nil { return nil, err } var fieldsRule model.Fieldsrule err = json.Unmarshal(row.Fieldsrule, &fieldsRule) if err != nil { return nil, err } return &model.Rule{ ID: row.ID, Accountid: row.Accountid, Quizid: row.Quizid, Performerid: row.Performerid, Pipelineid: row.Pipelineid, Stepid: row.Stepid, Utms: row.Utms, Fieldsrule: fieldsRule, }, nil } // методы UTMs func (r *AmoRepository) DeletingUserUtm(ctx context.Context, request *model.ListDeleteUTMIDsReq) error { err := r.queries.DeletingUTM(ctx, request.Utms) if err != nil { return err } return nil } // todo нужно ли тут ограничивать индексом что то func (r *AmoRepository) SavingUserUtm(ctx context.Context, utms []model.UTM, accountID string) (*model.ListSavedIDUTMResp, error) { column2, err := json.Marshal(utms) if err != nil { return nil, err } rows, err := r.queries.SaveUTMs(ctx, sqlcgen.SaveUTMsParams{ Accountid: accountID, Column2: column2, }) var ids []int64 for _, row := range rows { ids = append(ids, row.ID) } return &model.ListSavedIDUTMResp{ Ids: ids, }, nil } func (r *AmoRepository) GettingUserUtm(ctx context.Context, request *model.PaginationReq, accountID string, quizID int) (*model.GetListUserUTMResp, error) { rows, err := r.queries.GetUTMsWithPagination(ctx, sqlcgen.GetUTMsWithPaginationParams{ Accountid: accountID, Column2: request.Page, Limit: request.Size, Quizid: int32(quizID), }) if err != nil { return nil, err } var count int64 var utmS []model.UTM for _, row := range rows { count = row.TotalCount utm := model.UTM{ ID: row.ID, Amofieldid: row.Amofieldid, Quizid: row.Quizid, Accountid: row.Accountid, Name: row.Name, Deleted: row.Deleted, Createdat: row.Createdat.Time.Unix(), } utmS = append(utmS, utm) } return &model.GetListUserUTMResp{ Count: count, Items: utmS, }, nil }