add check update/insert fields

This commit is contained in:
Pavel 2024-04-12 14:52:38 +03:00
parent 8b1bd1a892
commit 1d7f794068
8 changed files with 196 additions and 16 deletions

@ -65,6 +65,7 @@ func Run(ctx context.Context, config initialize.Config, logger *zap.Logger) erro
Pipelines: mdb.Collection("pipelines"),
Steps: mdb.Collection("steps"),
Tags: mdb.Collection("tags"),
Fields: mdb.Collection("fields"),
Logger: logger,
})

@ -4,6 +4,7 @@ type GetListFieldsReq struct {
Page int `json:"page"`
Limit int `json:"limit"`
//Filter []string `json:"filter"` // пока не понял что это может быть
EntityType EntityType `json:"entityType"`
}
type ResponseGetListFields struct {
@ -28,6 +29,7 @@ type CustomField struct {
ID int `json:"id"`
Name string `json:"name"`
Sort int `json:"sort"`
Code string `json:"code"`
Type string `json:"type"`
Entity_type string `json:"entity_type"`
IsComputed bool `json:"is_computed"`

@ -1,22 +1,26 @@
package models
import "amocrm/internal/models/amo"
type Field struct {
/* - таймштамп создания воронки в нашей системе*/
Createdat int `json:"CreatedAt"`
Createdat int64 `json:"CreatedAt" bson:"createdat"`
// время обновления
UpdateAt int64 `json:"UpdateAt" bson:"updateAt"`
/* - флаг мягкого удаления*/
Deleted bool `json:"Deleted"`
Deleted bool `json:"Deleted" bson:"deleted"`
/* - тип сущности в амо, для которой это кастомное поле*/
Entitytype string `json:"EntityType"`
Entity amo.EntityType `json:"Entity" bson:"entity"`
/* - айдишник в нашей системе*/
ID int `json:"ID"`
ID string `json:"ID" bson:"id"`
/* - название воронки в амо*/
Name string `json:"Name"`
Name string `json:"Name" bson:"name"`
/* - тип поля https://www.amocrm.ru/developers/content/crm_platform/custom-fields#%D0%94%D0%BE%D1%81%D1%82%D1%83%D0%BF%D0%BD%D1%8B%D0%B5-%D1%82%D0%B8%D0%BF%D1%8B-%D0%BF%D0%BE%D0%BB%D0%B5%D0%B9*/
Type string `json:"Type"`
Type string `json:"Type" bson:"type"`
/* - связь с аккаунтом в интеграции амо*/
Accountid string `json:"AccountID"`
Accountid int `json:"AccountID" bson:"accountid"`
/* - айдишник кастомного поля в амо*/
Amoid int `json:"AmoID"`
Amoid int `json:"AmoID" bson:"amoid"`
/* - кодовое слово в амо*/
Code string `json:"Code"`
Code string `json:"Code" bson:"code"`
}

@ -2,7 +2,11 @@ package repository
import (
"amocrm/internal/models"
"amocrm/internal/models/amo"
"context"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"time"
)
func (r *Repository) GettingFieldsFromCash(ctx context.Context) (*models.UserListFieldsResp, error) {
@ -17,3 +21,77 @@ func (r *Repository) UpdateListCustom(ctx context.Context) error {
return nil
}
type CheckFieldsDeps struct {
AccountID string // id quiz
ID int // id amo
EntityType amo.EntityType
Fields []amo.CustomField
}
func (r *Repository) CheckFields(ctx context.Context, deps CheckFieldsDeps) error {
for _, f := range deps.Fields {
field := models.Field{
ID: deps.AccountID,
Accountid: deps.ID,
Amoid: f.ID,
Name: f.Name,
Type: f.Type,
Code: f.Code,
Entity: deps.EntityType,
}
existingField, err := r.GetFieldByID(ctx, deps.AccountID, f.ID)
if err != nil {
return err
}
if existingField != nil {
field.UpdateAt = time.Now().Unix()
err = r.UpdateField(ctx, &field)
if err != nil {
return err
}
} else {
field.Createdat = time.Now().Unix()
err = r.InsertField(ctx, &field)
if err != nil {
return err
}
}
}
return nil
}
func (r *Repository) GetFieldByID(ctx context.Context, accountID string, amoid int) (*models.Field, error) {
var field models.Field
filter := bson.M{"id": accountID, "amoid": amoid}
err := r.fields.FindOne(ctx, filter).Decode(&field)
if err == mongo.ErrNoDocuments {
return nil, nil
}
if err != nil {
return nil, err
}
return &field, nil
}
func (r *Repository) UpdateField(ctx context.Context, field *models.Field) error {
filter := bson.M{"id": field.ID, "amoid": field.Amoid}
update := bson.M{"$set": bson.M{
"accountid": field.Accountid,
"name": field.Name,
"updateAt": field.UpdateAt,
"type": field.Type,
"entity": field.Entity,
"code": field.Code,
}}
_, err := r.fields.UpdateOne(ctx, filter, update)
return err
}
func (r *Repository) InsertField(ctx context.Context, field *models.Field) error {
_, err := r.fields.InsertOne(ctx, field)
return err
}

@ -11,6 +11,7 @@ type Deps struct {
Pipelines *mongo.Collection
Steps *mongo.Collection
Tags *mongo.Collection
Fields *mongo.Collection
Logger *zap.Logger
}
@ -20,6 +21,7 @@ type Repository struct {
pipelines *mongo.Collection
steps *mongo.Collection
tags *mongo.Collection
fields *mongo.Collection
logger *zap.Logger
}
@ -30,6 +32,7 @@ func NewRepository(deps Deps) *Repository {
pipelines: deps.Pipelines,
steps: deps.Steps,
tags: deps.Tags,
fields: deps.Fields,
logger: deps.Logger,
}
}

@ -54,7 +54,8 @@ func (wc *DataUpdater) processTasks(ctx context.Context) {
return
}
for _, token := range allTokens {
accountID := 0
accountID := 0 // id аккаунта в амо для тегов и кастомных полей так как там не приходит
// pipelines
pipelines, err := wc.amoClient.GetListPipelines(token.AccessToken)
if err != nil {
wc.logger.Error("error getting list pipelines:", zap.Error(err))
@ -64,6 +65,7 @@ func (wc *DataUpdater) processTasks(ctx context.Context) {
wc.logger.Error("error update pipelines in mongo:", zap.Error(err))
}
// steps
for _, pipeline := range pipelines.Embedded.Pipelines {
accountID = pipeline.AccountID
steps, err := wc.amoClient.GetListSteps(pipeline.ID, token.AccessToken)
@ -78,6 +80,7 @@ func (wc *DataUpdater) processTasks(ctx context.Context) {
}
}
// tags
var leadsTags []amo.Tag
var contactsTags []amo.Tag
var companiesTags []amo.Tag
@ -168,7 +171,94 @@ func (wc *DataUpdater) processTasks(ctx context.Context) {
}
}
// todo fields
// fields
var leadsFields []amo.CustomField
var contactsFields []amo.CustomField
var companiesFields []amo.CustomField
var customersFields []amo.CustomField
for _, entityType := range entityTypes {
page := 1
limit := 50
for {
req := amo.GetListFieldsReq{
Page: page,
Limit: limit,
EntityType: entityType,
}
tags, err := wc.amoClient.GetListFields(req, token.AccessToken)
if err != nil {
wc.logger.Error("error getting list of fields", zap.Error(err))
break
}
switch entityType {
case amo.LeadsTags:
leadsFields = append(leadsFields, tags.Embedded.CustomFields...)
case amo.ContactsTags:
contactsFields = append(contactsFields, tags.Embedded.CustomFields...)
case amo.CompaniesTags:
companiesFields = append(companiesFields, tags.Embedded.CustomFields...)
case amo.CustomersTags:
customersFields = append(customersFields, tags.Embedded.CustomFields...)
}
if len(tags.Embedded.CustomFields) == 0 {
break
}
page++
}
}
for _, entityType := range entityTypes {
switch entityType {
case amo.LeadsTags:
err := wc.repo.CheckFields(ctx, repository.CheckFieldsDeps{
Fields: leadsFields,
AccountID: token.AccountID,
ID: accountID,
EntityType: entityType,
})
if err != nil {
wc.logger.Error("error update leads fields")
continue
}
case amo.ContactsTags:
err := wc.repo.CheckFields(ctx, repository.CheckFieldsDeps{
Fields: contactsFields,
AccountID: token.AccountID,
ID: accountID,
EntityType: entityType,
})
if err != nil {
wc.logger.Error("error update contacts fields")
continue
}
case amo.CompaniesTags:
err := wc.repo.CheckFields(ctx, repository.CheckFieldsDeps{
Fields: companiesFields,
AccountID: token.AccountID,
ID: accountID,
EntityType: entityType,
})
if err != nil {
wc.logger.Error("error update companies fields")
continue
}
case amo.CustomersTags:
err := wc.repo.CheckFields(ctx, repository.CheckFieldsDeps{
Fields: companiesFields,
AccountID: token.AccountID,
ID: accountID,
EntityType: entityType,
})
if err != nil {
wc.logger.Error("error update customer fields")
continue
}
}
}
}
}

@ -539,7 +539,7 @@ components:
description: объект кастомного поля амо
properties:
ID:
type: integer
type: string
description: айдишник в нашей системе
AmoID:
type: integer
@ -548,7 +548,7 @@ components:
type: string
description: кодовое слово в амо
AccountID:
type: string
type: integer
description: связь с аккаунтом в интеграции амо
Name:
type: string

@ -193,15 +193,17 @@ func (a *Amo) GetListSteps(pipelineID int, accessToken string) (*amo2.ResponseGe
// GET /api/v4/contacts/custom_fields
// GET /api/v4/companies/custom_fields
// GET /api/v4/customers/custom_fields
// пока без этих двух
// GET /api/v4/customers/segments/custom_fields
// GET /api/v4/catalogs/{catalog_id}/custom_fields
// эти методы все относятся к одному и тому же, поэтому на вход будет урл и рек стуктура, выход у них один и тот же
func (a *Amo) GetListFields(req amo2.GetListFieldsReq, url string) (*amo2.ResponseGetListFields, error) {
func (a *Amo) GetListFields(req amo2.GetListFieldsReq, accessToken string) (*amo2.ResponseGetListFields, error) {
for {
if a.rateLimiter.Check() {
fullURL := fmt.Sprintf("%s?limit=%d&page=%d", url, req.Limit, req.Page)
fullURL := fmt.Sprintf("%s/api/v4/%s/custom_fields?limit=%d&page=%d", a.baseApiURL, req.EntityType, req.Limit, req.Page)
agent := a.fiberClient.Get(fullURL)
agent.Set("Authorization", "Bearer "+accessToken)
statusCode, resBody, errs := agent.Bytes()
if len(errs) > 0 {
for _, err := range errs {