package bitrix 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" "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/pj_errors" "time" ) type BitrixRepository struct { queries *sqlcgen.Queries pool *sql.DB } type Deps struct { Queries *sqlcgen.Queries Pool *sql.DB } func NewBitrixRepository(deps Deps) *BitrixRepository { return &BitrixRepository{ queries: deps.Queries, pool: deps.Pool, } } // методы компании func (r *BitrixRepository) GettingUserWithPagination(ctx context.Context, req *model.PaginationReq, accountID string) (*model.UserListBitrixResp, error) { rows, err := r.queries.GetUsersBitrixWithPagination(ctx, sqlcgen.GetUsersBitrixWithPaginationParams{ Accountid: accountID, Column2: req.Page, Limit: req.Size, }) if err != nil { return nil, err } var users []model.BitrixAccountUser var count int64 for _, row := range rows { users = append(users, model.BitrixAccountUser{ ID: row.ID, AccountID: row.Accountid, BitrixIDUserID: row.Bitrixiduserid, Name: row.Name, LastName: row.Lastname, SecondName: row.Secondname, Title: row.Title, Email: row.Email, UFDepartment: row.Ufdepartment, WorkPosition: row.Workposition, CreatedAt: row.Createdat, }) count = row.TotalCount } resp := model.UserListBitrixResp{ Count: count, Items: users, } return &resp, nil } func (r *BitrixRepository) SoftDeleteAccount(ctx context.Context, accountID string) error { err := r.queries.SoftDeleteBitrixAccount(ctx, accountID) if err != nil { return err } return nil } func (r *BitrixRepository) GetCurrentAccount(ctx context.Context, accountID string) (*model.BitrixAccount, error) { row, err := r.queries.GetCurrentBitrixCompany(ctx, accountID) if err != nil { return nil, err } user := model.BitrixAccount{ ID: row.ID, AccountID: row.Accountid, BitrixID: row.Bitrixid, CreatedAt: row.Createdat, Subdomain: row.Subdomain, } _, err = r.queries.CheckExpiredBitrixToken(ctx, accountID) if err != nil { if err == sql.ErrNoRows { user.Stale = false return &user, nil } return nil, err } user.Stale = true return &user, nil } func (r *BitrixRepository) UpdateCurrentAccount(ctx context.Context, user model.BitrixAccount) error { err := r.queries.UpdateBitrixAccount(ctx, sqlcgen.UpdateBitrixAccountParams{ Accountid: user.AccountID, Subdomain: user.Subdomain, }) if err != nil { return err } return nil } func (r *BitrixRepository) CreateAccount(ctx context.Context, userInfo model.BitrixAccount) error { err := r.queries.CreateBitrixAccount(ctx, sqlcgen.CreateBitrixAccountParams{ Accountid: userInfo.AccountID, Subdomain: userInfo.Subdomain, Bitrixid: userInfo.BitrixID, }) if err != nil { return err } return nil } // методы пользователей func (r *BitrixRepository) AddBitrixAccountUser(ctx context.Context, user model.BitrixAccountUser) error { err := r.queries.AddBitrixAccountUser(ctx, sqlcgen.AddBitrixAccountUserParams{ Accountid: user.AccountID, Bitrixiduserid: user.BitrixIDUserID, Name: user.Name, Lastname: user.LastName, Secondname: user.SecondName, Title: user.Title, Email: user.Email, Ufdepartment: user.UFDepartment, Workposition: user.WorkPosition, }) if err != nil { return err } return nil } func (r *BitrixRepository) UpdateBitrixAccountUser(ctx context.Context, user model.BitrixAccountUser) error { err := r.queries.UpdateBitrixAccountUser(ctx, sqlcgen.UpdateBitrixAccountUserParams{ Accountid: user.AccountID, Bitrixiduserid: user.BitrixIDUserID, Name: user.Name, Lastname: user.LastName, Secondname: user.SecondName, Title: user.Title, Email: user.Email, Ufdepartment: user.UFDepartment, Workposition: user.WorkPosition, }) if err != nil { return err } return nil } func (r *BitrixRepository) GetTokenByID(ctx context.Context, accountID string) (*model.Token, error) { row, err := r.queries.GetBitrixTokenById(ctx, accountID) if err != nil { return nil, err } return &model.Token{ AccountID: row.Accountid, RefreshToken: row.Refreshtoken, AccessToken: row.Accesstoken, AuthCode: row.Authcode, Expiration: row.Expiration.Unix(), CreatedAt: row.Createdat.Unix(), }, nil } func (r *BitrixRepository) DeleteUsers(ctx context.Context, ids []int64) error { err := r.queries.DeleteBitrixUsers(ctx, ids) if err != nil { return err } return nil } func (r *BitrixRepository) GetUserUsersByID(ctx context.Context, bitrixCompanyID string) ([]model.BitrixAccountUser, error) { rows, err := r.queries.GetUserUsersByIDBitrix(ctx, bitrixCompanyID) if err != nil { return nil, err } var users []model.BitrixAccountUser for _, row := range rows { users = append(users, model.BitrixAccountUser{ ID: row.ID, AccountID: row.Accountid, BitrixIDUserID: row.Bitrixiduserid, Name: row.Name, LastName: row.Lastname, SecondName: row.Secondname, Title: row.Title, Email: row.Email, UFDepartment: row.Ufdepartment, WorkPosition: row.Workposition, CreatedAt: row.Createdat, }) } return users, nil } // методы webhook func (r *BitrixRepository) WebhookCreate(ctx context.Context, tokens model.Token) error { err := r.queries.CreateBitrixWebHook(ctx, sqlcgen.CreateBitrixWebHookParams{ 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: time.Unix(tokens.CreatedAt, 0), }) if err != nil { return err } return nil } func (r *BitrixRepository) WebhookUpdate(ctx context.Context, token model.Token) error { err := r.queries.WebhookBitrixUpdate(ctx, sqlcgen.WebhookBitrixUpdateParams{ Accesstoken: token.AccessToken, Refreshtoken: token.RefreshToken, Accountid: token.AccountID, Column3: token.Expiration, Column4: token.CreatedAt, }) if err != nil { return err } return nil } func (r *BitrixRepository) GetAllTokens(ctx context.Context) ([]model.Token, error) { rows, err := r.queries.GetAllBitrixTokens(ctx) if err != nil { return nil, err } var tokens []model.Token for _, row := range rows { tokens = append(tokens, model.Token{ AccountID: row.Accountid, AccessToken: row.Accesstoken, RefreshToken: row.Refreshtoken, AuthCode: row.Authcode, Expiration: row.Expiration.Unix(), CreatedAt: row.Createdat.Unix(), }) } return tokens, nil } func (r *BitrixRepository) WebhookDelete(ctx context.Context, bitrixID string) error { err := r.queries.WebhookBitrixDelete(ctx, bitrixID) if err != nil { return err } return nil } // методы pipelines func (r *BitrixRepository) GetPipelinesWithPagination(ctx context.Context, req *model.PaginationReq, accountID string) (*model.UserBitrixListPipelinesResp, error) { rows, err := r.queries.GetBitrixPipelinesWithPagination(ctx, sqlcgen.GetBitrixPipelinesWithPaginationParams{ Accountid: accountID, Column2: req.Page, Limit: req.Size, }) if err != nil { return nil, err } var count int64 var pipelines []model.PipelineBitrix for _, row := range rows { count = row.TotalCount pipelines = append(pipelines, model.PipelineBitrix{ ID: row.ID, BitrixID: row.Bitrixid, AccountID: row.Accountid, Name: row.Name, EntityTypeId: model.IntegerEntityType(row.Entitytypeid), Createdat: row.Createdat.Unix(), }) } resp := model.UserBitrixListPipelinesResp{ Count: count, Items: pipelines, } return &resp, nil } func (r *BitrixRepository) CheckPipelines(ctx context.Context, pipelines []model.PipelineBitrix) error { dollar1, err := json.Marshal(pipelines) if err != nil { return err } rows, err := r.queries.CheckBitrixPipelines(ctx, dollar1) if err != nil { return err } if rows != nil { var toUpdate []model.PipelineBitrix for _, row := range rows { to := model.PipelineBitrix{ BitrixID: row.Bitrixid, AccountID: row.Accountid, Name: row.Name, EntityTypeId: model.IntegerEntityType(row.Entitytypeid), } toUpdate = append(toUpdate, to) } dollar1, err := json.Marshal(toUpdate) if err != nil { return err } err = r.queries.UpdateBitrixPipelines(ctx, dollar1) if err != nil { return err } } return nil } func (r *BitrixRepository) DeletePipelines(ctx context.Context, ids []int64) error { err := r.queries.DeleteBitrixPipelines(ctx, ids) if err != nil { return err } return nil } func (r *BitrixRepository) GetUserPipelinesByID(ctx context.Context, bitrixID string) ([]model.PipelineBitrix, error) { rows, err := r.queries.GetUserBitrixPipelinesByID(ctx, bitrixID) if err != nil { return nil, err } var pipelines []model.PipelineBitrix for _, row := range rows { pipeline := model.PipelineBitrix{ ID: row.ID, BitrixID: row.Bitrixid, AccountID: row.Accountid, Name: row.Name, EntityTypeId: model.IntegerEntityType(row.Entitytypeid), } pipelines = append(pipelines, pipeline) } return pipelines, nil } // методы steps func (r *BitrixRepository) GetStepsWithPagination(ctx context.Context, req *model.PaginationReq, bitrixID string) (*model.UserListBitrixStepsResp, error) { rows, err := r.queries.GetBitrixStepsWithPagination(ctx, sqlcgen.GetBitrixStepsWithPaginationParams{ Accountid: bitrixID, Column2: req.Page, Limit: req.Size, }) if err != nil { return nil, err } var count int64 var steps []model.StepBitrix for _, row := range rows { count = row.TotalCount steps = append(steps, model.StepBitrix{ ID: row.ID, AccountID: row.Accountid, BitrixID: row.Bitrixid, EntityID: row.Entityid, StatusID: row.Statusid, Name: row.Name, NameInit: row.Nameinit, Color: row.Color, PipelineID: row.Pipelineid, Createdat: row.Createdat.Unix(), }) } resp := model.UserListBitrixStepsResp{ Count: count, Items: steps, } return &resp, nil } // todo func (r *BitrixRepository) CheckSteps(ctx context.Context, steps []model.StepBitrix) error { dollar1, err := json.Marshal(steps) if err != nil { return err } rows, err := r.queries.CheckBitrixSteps(ctx, dollar1) if err != nil { return err } if rows != nil { var toUpdate []model.StepBitrix for _, row := range rows { to := model.StepBitrix{ AccountID: row.Accountid, BitrixID: row.Bitrixid, Name: row.Name, EntityID: row.Entityid, StatusID: row.Statusid, NameInit: row.Nameinit, Color: row.Color, PipelineID: row.Pipelineid, } toUpdate = append(toUpdate, to) } dollar1, err := json.Marshal(toUpdate) if err != nil { return err } err = r.queries.UpdateBitrixSteps(ctx, dollar1) if err != nil { return err } } return nil } func (r *BitrixRepository) DeleteSteps(ctx context.Context, ids []int64) error { err := r.queries.DeleteBitrixSteps(ctx, ids) if err != nil { return err } return nil } func (r *BitrixRepository) GetUserStepsByID(ctx context.Context, bitrixID string) ([]model.StepBitrix, error) { rows, err := r.queries.GetUserBitrixStepsByID(ctx, bitrixID) if err != nil { return nil, err } var steps []model.StepBitrix for _, row := range rows { steps = append(steps, model.StepBitrix{ ID: row.ID, AccountID: row.Accountid, BitrixID: row.Bitrixid, StatusID: row.Statusid, EntityID: row.Entityid, Name: row.Name, NameInit: row.Nameinit, Color: row.Color, PipelineID: row.Pipelineid, }) } return steps, nil } // методы tags todo // методы fields func (r *BitrixRepository) GetFieldsWithPagination(ctx context.Context, req *model.PaginationReq, accountID string) (*model.UserListBitrixFieldsResp, error) { rows, err := r.queries.GetBitrixFieldsWithPagination(ctx, sqlcgen.GetBitrixFieldsWithPaginationParams{ Accountid: accountID, Column2: req.Page, Limit: req.Size, }) if err != nil { return nil, err } var count int64 var fields []model.BitrixField for _, row := range rows { count = row.TotalCount var entityID model.FieldsType v := string(row.Entityid.([]byte)) entityID = model.FieldsType(v) var fieldType model.CustomFieldsType f := string(row.Fieldtype.([]byte)) fieldType = model.CustomFieldsType(f) fields = append(fields, model.BitrixField{ ID: row.ID, AccountID: row.Accountid, EntityID: entityID, FieldName: row.Fieldname, EditFromLabel: row.Editfromlabel, FieldType: fieldType, Createdat: row.Createdat.Unix(), BitrixID: row.Bitrixid, }) } resp := model.UserListBitrixFieldsResp{ Count: count, Items: fields, } return &resp, nil } func (r *BitrixRepository) CheckFields(ctx context.Context, fields []model.BitrixField, accountID string) error { column2, err := json.Marshal(fields) if err != nil { return err } rows, err := r.queries.CheckBitrixFields(ctx, sqlcgen.CheckBitrixFieldsParams{ Accountid: accountID, Column2: column2, }) if err != nil { return err } if rows != nil { var toUpdate []model.BitrixField for _, row := range rows { var entityID model.FieldsType v := string(row.Entityid.([]byte)) entityID = model.FieldsType(v) var fieldType model.CustomFieldsType f := string(row.Fieldtype.([]byte)) fieldType = model.CustomFieldsType(f) toUpdate = append(toUpdate, model.BitrixField{ AccountID: row.Accountid, EntityID: entityID, FieldName: row.Fieldname, EditFromLabel: row.Editfromlabel, FieldType: fieldType, BitrixID: row.Bitrixid, }) } dollar1, err := json.Marshal(toUpdate) if err != nil { return err } err = r.queries.UpdateBitrixFields(ctx, dollar1) if err != nil { return err } } return nil } func (r *BitrixRepository) GetUserFieldsByID(ctx context.Context, bitrixID string) ([]model.BitrixField, error) { rows, err := r.queries.GetUserBitrixFieldsByID(ctx, bitrixID) if err != nil { return nil, err } var fields []model.BitrixField for _, row := range rows { var entityID model.FieldsType v := string(row.Entityid.([]byte)) entityID = model.FieldsType(v) var fieldType model.CustomFieldsType f := string(row.Fieldtype.([]byte)) fieldType = model.CustomFieldsType(f) fields = append(fields, model.BitrixField{ ID: row.ID, AccountID: row.Accountid, FieldName: row.Fieldname, EditFromLabel: row.Editfromlabel, Createdat: row.Createdat.Unix(), EntityID: entityID, FieldType: fieldType, BitrixID: row.Bitrixid, }) } return fields, err } func (r *BitrixRepository) DeleteFields(ctx context.Context, ids []int64) error { err := r.queries.DeleteBitrixFields(ctx, ids) if err != nil { return err } return nil } // todo mb by name? bec in create field return int id, but getting list return string )) func (r *BitrixRepository) GetFieldByID(ctx context.Context, bitrixID string) (*model.BitrixField, error) { row, err := r.queries.GetBitrixFieldByID(ctx, bitrixID) if err != nil { return nil, err } var entityID model.FieldsType v := string(row.Entityid.([]byte)) entityID = model.FieldsType(v) var fieldType model.CustomFieldsType f := string(row.Fieldtype.([]byte)) fieldType = model.CustomFieldsType(f) return &model.BitrixField{ ID: row.ID, AccountID: row.Accountid, FieldName: row.Fieldname, EditFromLabel: row.Editfromlabel, Createdat: row.Createdat.Unix(), EntityID: entityID, FieldType: fieldType, BitrixID: row.Bitrixid, }, nil } // методы rules func (r *BitrixRepository) ChangeQuizSettings(ctx context.Context, request *model.BitrixRulesReq, accountID string, quizID int) error { jsonFieldRule, err := json.Marshal(request.FieldsRule) if err != nil { return err } jsonTagsToAdd, err := json.Marshal(request.TagsToAdd) if err != nil { return err } _, err = r.queries.ChangeBitrixQuizSettings(ctx, sqlcgen.ChangeBitrixQuizSettingsParams{ Performerid: request.PerformerID, Pipelineid: request.PipelineID, Typeid: request.TypeID, Stageid: request.StageID, Sourceid: request.SourceID, Fieldsrule: jsonFieldRule, Tagstoadd: jsonTagsToAdd, Leadflag: request.LeadFlag, Accountid: accountID, Quizid: int32(quizID), Statusid: request.StatusID, }) if err != nil { return err } return nil } func (r *BitrixRepository) SetQuizSettings(ctx context.Context, request *model.BitrixRulesReq, accountID string, quizID int) error { jsonFieldRule, err := json.Marshal(request.FieldsRule) if err != nil { return err } jsonTagsToAdd, err := json.Marshal(request.TagsToAdd) if err != nil { return err } _, err = r.queries.SetBitrixQuizSettings(ctx, sqlcgen.SetBitrixQuizSettingsParams{ Performerid: request.PerformerID, Pipelineid: request.PipelineID, Typeid: request.TypeID, Stageid: request.StageID, Sourceid: request.SourceID, Fieldsrule: jsonFieldRule, Tagstoadd: jsonTagsToAdd, Accountid: accountID, Quizid: int32(quizID), Leadflag: request.LeadFlag, Statusid: request.StatusID, }) if err != nil { return err } return nil } func (r *BitrixRepository) GettingQuizRules(ctx context.Context, quizID int) (*model.BitrixRule, error) { row, err := r.queries.GetBitrixQuizRule(ctx, int32(quizID)) if err != nil { return nil, err } var fieldsRule model.BitrixFieldRules err = json.Unmarshal(row.Fieldsrule, &fieldsRule) if err != nil { return nil, err } var tagsToAdd model.TagsToAdd err = json.Unmarshal(row.Tagstoadd, &tagsToAdd) if err != nil { return nil, err } return &model.BitrixRule{ ID: row.ID, AccountID: row.Accountid, QuizID: row.Quizid, PerformerID: row.Performerid, PipelineID: row.Pipelineid, TypeID: row.Typeid, StageID: row.Stageid, SourceID: row.Sourceid, FieldsRule: fieldsRule, TagsToAdd: tagsToAdd, LeadFlag: row.Leadflag, StatusID: row.Statusid, }, nil } func (r *BitrixRepository) UpdateFieldRules(ctx context.Context, fieldRules model.BitrixFieldRules, accountID string, quizID int32) error { jsonFieldsRule, err := json.Marshal(fieldRules) if err != nil { return err } err = r.queries.UpdateBitrixFieldRules(ctx, sqlcgen.UpdateBitrixFieldRulesParams{ Fieldsrule: jsonFieldsRule, Accountid: accountID, Quizid: quizID, }) if err != nil { return err } return nil } // todo need check func (r *BitrixRepository) GettingBitrixUsersTrueResults(ctx context.Context) ([]model.BitrixUsersTrueResults, error) { rows, err := r.queries.GettingBitrixUsersTrueResults(ctx) if err != nil { return nil, err } var results []model.BitrixUsersTrueResults for _, row := range rows { var fieldsRule model.BitrixFieldRules err = json.Unmarshal(row.Fieldsrule, &fieldsRule) if err != nil { return nil, err } var utm model.UTMSavingMap err = json.Unmarshal(row.Utm.([]byte), &utm) if err != nil { return nil, err } var tagsToAdd model.TagsToAdd err = json.Unmarshal(row.Tagstoadd, &tagsToAdd) if err != nil { return nil, err } result := model.BitrixUsersTrueResults{ QuizID: row.QuizID, AnswerID: row.ID, Result: row.Result.Bool, QuestionID: row.QuestionID, Content: row.Content.String, Session: row.Session.String, AccessToken: row.Accesstoken, AmoAccountID: row.Accountid, UTMs: utm, FieldsRule: fieldsRule, TagsToAdd: tagsToAdd, PerformerID: row.Performerid, TypeID: row.Typeid, StageID: row.Stageid, SourceID: row.Sourceid, PipelineID: row.Pipelineid, PerformerName: row.PerformerName, SubDomain: row.Subdomain, QuizAccountID: row.Accountid_2, LeadFlag: row.Leadflag, StatusID: row.Statusid, } results = append(results, result) } return results, nil } // методы bitrixCRMStatuses todo type SaveDealBitrixDeps struct { DealID int32 AnswerID int64 Status string AccessToken string } func (r *BitrixRepository) SaveDealBitrixStatus(ctx context.Context, deps SaveDealBitrixDeps) error { err := r.queries.SettingDealBitrixStatus(ctx, sqlcgen.SettingDealBitrixStatusParams{ Dealid: deps.DealID, Answerid: deps.AnswerID, Status: deps.Status, Accesstoken: deps.AccessToken, }) if err != nil { return err } return nil } // методы для contact в амо func (r *BitrixRepository) GetExistingContactBitrix(ctx context.Context, accountID string, fields []string) (map[int32][]model.ContactBitrix, error) { rows, err := r.queries.GetExistingContactBitrix(ctx, sqlcgen.GetExistingContactBitrixParams{ Accountid: accountID, Column2: fields, }) if err != nil { if err == sql.ErrNoRows { return nil, pj_errors.ErrNotFound } return nil, err } result := make(map[int32][]model.ContactBitrix) for _, row := range rows { result[row.Bitrixid] = append(result[row.Bitrixid], model.ContactBitrix{ ID: row.ID, BitrixID: row.Bitrixid, AccountID: row.Accountid, Field: row.Field, }) } return result, nil } func (r *BitrixRepository) InsertContactBitrix(ctx context.Context, val model.ContactBitrix) (int32, error) { amoID, err := r.queries.InsertContactBitrix(ctx, sqlcgen.InsertContactBitrixParams{ Accountid: val.AccountID, Bitrixid: val.BitrixID, Field: val.Field, }) if err != nil { return 0, err } return amoID, err } func (r *BitrixRepository) UpdateBitrixContact(ctx context.Context, id int64, field string, newBitrixID int32) error { err := r.queries.UpdateBitrixContact(ctx, sqlcgen.UpdateBitrixContactParams{ Field: field, ID: id, Bitrixid: newBitrixID, }) if err != nil { return err } return nil }