refactor logic for posting deals
This commit is contained in:
parent
f21dadfd01
commit
02263b0ed0
2
go.mod
2
go.mod
@ -12,7 +12,7 @@ require (
|
|||||||
github.com/twmb/franz-go v1.16.1
|
github.com/twmb/franz-go v1.16.1
|
||||||
go.uber.org/zap v1.27.0
|
go.uber.org/zap v1.27.0
|
||||||
google.golang.org/protobuf v1.33.0
|
google.golang.org/protobuf v1.33.0
|
||||||
penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240504123552-f1d3073dc9f1
|
penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240505074742-07895eccdd07
|
||||||
penahub.gitlab.yandexcloud.net/backend/quiz/core.git v0.0.0-20240219174804-d78fd38511af
|
penahub.gitlab.yandexcloud.net/backend/quiz/core.git v0.0.0-20240219174804-d78fd38511af
|
||||||
)
|
)
|
||||||
|
|
||||||
|
4
go.sum
4
go.sum
@ -151,7 +151,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
|||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
penahub.gitlab.yandexcloud.net/backend/penahub_common v0.0.0-20240223054633-6cb3d5ce45b6 h1:oV+/HNX+JPoQ3/GUx08hio7d45WpY0AMGrFs7j70QlA=
|
penahub.gitlab.yandexcloud.net/backend/penahub_common v0.0.0-20240223054633-6cb3d5ce45b6 h1:oV+/HNX+JPoQ3/GUx08hio7d45WpY0AMGrFs7j70QlA=
|
||||||
penahub.gitlab.yandexcloud.net/backend/penahub_common v0.0.0-20240223054633-6cb3d5ce45b6/go.mod h1:lTmpjry+8evVkXWbEC+WMOELcFkRD1lFMc7J09mOndM=
|
penahub.gitlab.yandexcloud.net/backend/penahub_common v0.0.0-20240223054633-6cb3d5ce45b6/go.mod h1:lTmpjry+8evVkXWbEC+WMOELcFkRD1lFMc7J09mOndM=
|
||||||
penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240504123552-f1d3073dc9f1 h1:H+2MgBImU5ab8vIFLQCUw0Az85BHKNXi2yPqKtX8sR0=
|
penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240505074742-07895eccdd07 h1:ttTQdCfoOj5L/C6xv9GEVDd23LWGkvgZCCEXvSXzjEo=
|
||||||
penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240504123552-f1d3073dc9f1/go.mod h1:oRyhT55ctjqp/7ZxIzkR7OsQ7T/NLibsfrbb7Ytns64=
|
penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240505074742-07895eccdd07/go.mod h1:oRyhT55ctjqp/7ZxIzkR7OsQ7T/NLibsfrbb7Ytns64=
|
||||||
penahub.gitlab.yandexcloud.net/backend/quiz/core.git v0.0.0-20240219174804-d78fd38511af h1:jQ7HaXSutDX5iepU7VRImxhikK7lV/lBKkiloOZ4Emo=
|
penahub.gitlab.yandexcloud.net/backend/quiz/core.git v0.0.0-20240219174804-d78fd38511af h1:jQ7HaXSutDX5iepU7VRImxhikK7lV/lBKkiloOZ4Emo=
|
||||||
penahub.gitlab.yandexcloud.net/backend/quiz/core.git v0.0.0-20240219174804-d78fd38511af/go.mod h1:5S5YwjSXWmnEKjBjG6MtyGtFmljjukDRS8CwHk/CF/I=
|
penahub.gitlab.yandexcloud.net/backend/quiz/core.git v0.0.0-20240219174804-d78fd38511af/go.mod h1:5S5YwjSXWmnEKjBjG6MtyGtFmljjukDRS8CwHk/CF/I=
|
||||||
|
@ -29,7 +29,7 @@ func (c *Controller) UpdateListCustom(ctx *fiber.Ctx) error {
|
|||||||
return ctx.Status(fiber.StatusUnauthorized).SendString("account id is required")
|
return ctx.Status(fiber.StatusUnauthorized).SendString("account id is required")
|
||||||
}
|
}
|
||||||
|
|
||||||
//accountID := "64f2cd7a7047f28fdabf6d9e"
|
//accountID := "654a8909725f47e926f0bebc"
|
||||||
|
|
||||||
err := c.service.UpdateListCustom(ctx.Context(), accountID)
|
err := c.service.UpdateListCustom(ctx.Context(), accountID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -12,7 +12,7 @@ func (c *Controller) UpdateListUsers(ctx *fiber.Ctx) error {
|
|||||||
return ctx.Status(fiber.StatusUnauthorized).SendString("account id is required")
|
return ctx.Status(fiber.StatusUnauthorized).SendString("account id is required")
|
||||||
}
|
}
|
||||||
|
|
||||||
//accountID := "64f2cd7a7047f28fdabf6d9e"
|
//accountID := "654a8909725f47e926f0bebc"
|
||||||
|
|
||||||
err := c.service.UpdateListUsers(ctx.Context(), accountID)
|
err := c.service.UpdateListUsers(ctx.Context(), accountID)
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ type DealReq struct {
|
|||||||
CustomFieldsValues []FieldsValues `json:"custom_fields_values"` // Массив полей которые заполняются значениями
|
CustomFieldsValues []FieldsValues `json:"custom_fields_values"` // Массив полей которые заполняются значениями
|
||||||
TagsToAdd []Tag `json:"tags_to_add"` // Массив тегов для добавления
|
TagsToAdd []Tag `json:"tags_to_add"` // Массив тегов для добавления
|
||||||
Embed Embedd `json:"_embedded"`
|
Embed Embedd `json:"_embedded"`
|
||||||
|
RequestID string `json:"request_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type FieldsValues struct {
|
type FieldsValues struct {
|
||||||
@ -34,17 +35,24 @@ type Embedd struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Contact struct {
|
type Contact struct {
|
||||||
//ID int32 `json:"id"` // ID контакта
|
//ID int32 `json:"id"` // ID контакта
|
||||||
//IsMain bool `json:"is_main"` // Флаг, показывающий, является контакт главным или нет
|
IsMain bool `json:"is_main"` // Флаг, показывающий, является контакт главным или нет
|
||||||
Name string `json:"first_name"`
|
Name string `json:"first_name"`
|
||||||
CreatedAT int64 `json:"created_at"`
|
CreatedAt int64 `json:"created_at"`
|
||||||
UpdatedBy int `json:"updated_by"`
|
UpdatedBy int `json:"updated_by"`
|
||||||
ResponsibleUserID int32 `json:"responsible_user_id"` // ID пользователя, ответственного за сделку, в нашем случае PerformerID
|
ResponsibleUserID int32 `json:"responsible_user_id"` // ID пользователя, ответственного за сделку, в нашем случае PerformerID
|
||||||
CustomFieldsValues []FieldsValues `json:"custom_fields_values"` // Массив полей которые заполняются значениями
|
CustomFieldsValues []FieldsValues `json:"custom_fields_values"` // Массив полей которые заполняются значениями
|
||||||
}
|
}
|
||||||
|
|
||||||
type Company struct {
|
type Company struct {
|
||||||
ID int `json:"id"` // ID компании
|
//ID int32 `json:"id"` // ID компании
|
||||||
|
Name string `json:"name"` // Название компании
|
||||||
|
ResponsibleUserID int32 `json:"responsible_user_id"` // ID пользователя, ответственного за сделку, в нашем случае PerformerID
|
||||||
|
CreatedBy int32 `json:"created_by"` // id пользователя amoid который создает сделку (тот кто подключил интеграцию)
|
||||||
|
UpdatedBy int `json:"updated_by"`
|
||||||
|
CreatedAt int64 `json:"created_at"`
|
||||||
|
UpdatedAt int64 `json:"updated_at"` // Дата изменения сделки, передается в Unix Timestamp
|
||||||
|
CustomFieldsValues []FieldsValues `json:"custom_fields_values"` // Массив полей которые заполняются значениями
|
||||||
}
|
}
|
||||||
|
|
||||||
type Source struct {
|
type Source struct {
|
||||||
@ -53,16 +61,9 @@ type Source struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type DealResp struct {
|
type DealResp struct {
|
||||||
Link struct {
|
DealID int `json:"id"` // ID сделки
|
||||||
SelfLink `json:"self"`
|
ContactID int `json:"contact_id"` // ID контакта
|
||||||
} `json:"_links"`
|
CompanyID int `json:"company_id"` // ID компании
|
||||||
Embed struct {
|
Merged bool `json:"merged"` // Флаг, который показывает, найден дубль подходящий под условия поиска дублей и произведено объединение или нет
|
||||||
Leads []struct {
|
RequestID []string `json:"request_id"` // Массив строк с пользовательскими идентификаторами, которые были переданы с каждой сущностью
|
||||||
ID int `json:"id"`
|
|
||||||
RequestID string `json:"request_id"`
|
|
||||||
Links struct {
|
|
||||||
SelfLink `json:"self"`
|
|
||||||
} `json:"_links"`
|
|
||||||
}
|
|
||||||
} `json:"_embedded"`
|
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package tools
|
|||||||
import (
|
import (
|
||||||
"amocrm/internal/models"
|
"amocrm/internal/models"
|
||||||
"penahub.gitlab.yandexcloud.net/backend/quiz/common.git/model"
|
"penahub.gitlab.yandexcloud.net/backend/quiz/common.git/model"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ToPipeline(amoPipelines []models.Pipeline) []model.Pipeline {
|
func ToPipeline(amoPipelines []models.Pipeline) []model.Pipeline {
|
||||||
@ -64,66 +65,72 @@ func ToField(amoField []models.CustomField, entity model.EntityType) []model.Fie
|
|||||||
return fields
|
return fields
|
||||||
}
|
}
|
||||||
|
|
||||||
func ConstructField(allAnswers []model.ResultAnswer, fieldsRule model.Fieldsrule) []models.FieldsValues {
|
// todo Для добавляемых сущностей (сделка, контакт, компания), можно передать не более 40 значений дополнительных полей.
|
||||||
fieldsMap := make(map[int][]models.Values)
|
func ConstructField(allAnswers []model.ResultAnswer, result model.AmoUsersTrueResults) ([]models.FieldsValues, []models.Contact, []models.Company) {
|
||||||
|
entityFieldsMap := make(map[model.EntityType]map[int][]models.Values)
|
||||||
|
entityFieldsMap[model.LeadsType] = make(map[int][]models.Values)
|
||||||
|
entityFieldsMap[model.ContactsType] = make(map[int][]models.Values)
|
||||||
|
entityFieldsMap[model.CompaniesType] = make(map[int][]models.Values)
|
||||||
|
entityFieldsMap[model.CustomersType] = make(map[int][]models.Values)
|
||||||
|
|
||||||
if fieldsRule.Lead != nil {
|
entityRules := make(map[model.EntityType][]model.FieldRule)
|
||||||
for _, rule := range fieldsRule.Lead {
|
entityRules[model.LeadsType] = result.FieldsRule.Lead
|
||||||
|
entityRules[model.ContactsType] = result.FieldsRule.Contact
|
||||||
|
entityRules[model.CompaniesType] = result.FieldsRule.Company
|
||||||
|
entityRules[model.CustomersType] = result.FieldsRule.Customer
|
||||||
|
|
||||||
|
for entityType, ruleList := range entityRules {
|
||||||
|
for _, rule := range ruleList {
|
||||||
for _, data := range allAnswers {
|
for _, data := range allAnswers {
|
||||||
if fieldID, ok := rule.Questionid[int(data.QuestionID)]; ok {
|
if fieldID, ok := rule.Questionid[int(data.QuestionID)]; ok {
|
||||||
values := fieldsMap[fieldID]
|
values := entityFieldsMap[entityType][fieldID]
|
||||||
values = append(values, models.Values{Value: data.Content})
|
values = append(values, models.Values{Value: data.Content})
|
||||||
fieldsMap[fieldID] = values
|
entityFieldsMap[entityType][fieldID] = values
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if fieldsRule.Contact != nil {
|
var leadFields []models.FieldsValues
|
||||||
for _, rule := range fieldsRule.Contact {
|
var contactFields []models.FieldsValues
|
||||||
for _, data := range allAnswers {
|
var companyFields []models.FieldsValues
|
||||||
if fieldID, ok := rule.Questionid[int(data.QuestionID)]; ok {
|
var customerFields []models.FieldsValues
|
||||||
values := fieldsMap[fieldID]
|
|
||||||
values = append(values, models.Values{Value: data.Content})
|
for entityType, fieldMap := range entityFieldsMap {
|
||||||
fieldsMap[fieldID] = values
|
for fieldID, values := range fieldMap {
|
||||||
}
|
field := models.FieldsValues{
|
||||||
|
FieldID: fieldID,
|
||||||
|
Values: values,
|
||||||
|
}
|
||||||
|
switch entityType {
|
||||||
|
case model.LeadsType:
|
||||||
|
leadFields = append(leadFields, field)
|
||||||
|
case model.ContactsType:
|
||||||
|
contactFields = append(contactFields, field)
|
||||||
|
case model.CompaniesType:
|
||||||
|
companyFields = append(companyFields, field)
|
||||||
|
case model.CustomersType:
|
||||||
|
customerFields = append(customerFields, field)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if fieldsRule.Company != nil {
|
return leadFields, []models.Contact{
|
||||||
for _, rule := range fieldsRule.Company {
|
{
|
||||||
for _, data := range allAnswers {
|
Name: result.PerformerName,
|
||||||
if fieldID, ok := rule.Questionid[int(data.QuestionID)]; ok {
|
CreatedAt: time.Now().Unix(),
|
||||||
values := fieldsMap[fieldID]
|
UpdatedBy: 0,
|
||||||
values = append(values, models.Values{Value: data.Content})
|
ResponsibleUserID: result.PerformerID,
|
||||||
fieldsMap[fieldID] = values
|
CustomFieldsValues: contactFields,
|
||||||
}
|
},
|
||||||
}
|
}, []models.Company{
|
||||||
|
{
|
||||||
|
Name: "OOO PENA CO",
|
||||||
|
ResponsibleUserID: result.PerformerID,
|
||||||
|
CreatedBy: 0,
|
||||||
|
UpdatedBy: 0,
|
||||||
|
CreatedAt: time.Now().Unix(),
|
||||||
|
CustomFieldsValues: companyFields,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if fieldsRule.Customer != nil {
|
|
||||||
for _, rule := range fieldsRule.Customer {
|
|
||||||
for _, data := range allAnswers {
|
|
||||||
if fieldID, ok := rule.Questionid[int(data.QuestionID)]; ok {
|
|
||||||
values := fieldsMap[fieldID]
|
|
||||||
values = append(values, models.Values{Value: data.Content})
|
|
||||||
fieldsMap[fieldID] = values
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var fields []models.FieldsValues
|
|
||||||
for fieldID, values := range fieldsMap {
|
|
||||||
field := models.FieldsValues{
|
|
||||||
FieldID: fieldID,
|
|
||||||
Values: values,
|
|
||||||
}
|
|
||||||
|
|
||||||
fields = append(fields, field)
|
|
||||||
}
|
|
||||||
|
|
||||||
return fields
|
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,7 @@ func ToCreatedUpdateQuestionRules(questionsTypeMap map[model.EntityType][]model.
|
|||||||
for _, question := range questions {
|
for _, question := range questions {
|
||||||
matched := false
|
matched := false
|
||||||
for _, field := range currentFields {
|
for _, field := range currentFields {
|
||||||
if question.Title == field.Name {
|
if question.Title == field.Name && entity == field.Entity {
|
||||||
toUpdate[int(question.Id)] = int(field.Amoid)
|
toUpdate[int(question.Id)] = int(field.Amoid)
|
||||||
matched = true
|
matched = true
|
||||||
break
|
break
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
"penahub.gitlab.yandexcloud.net/backend/quiz/common.git/dal"
|
"penahub.gitlab.yandexcloud.net/backend/quiz/common.git/dal"
|
||||||
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -32,7 +33,7 @@ func NewPostFieldsWC(deps Deps) *PostFields {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (wc *PostFields) Start(ctx context.Context) {
|
func (wc *PostFields) Start(ctx context.Context) {
|
||||||
ticker := time.NewTicker(10 * time.Second)
|
ticker := time.NewTicker(30 * time.Second)
|
||||||
defer ticker.Stop()
|
defer ticker.Stop()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
@ -61,41 +62,30 @@ func (wc *PostFields) startFetching(ctx context.Context) {
|
|||||||
wc.logger.Error("error getting all user answers by result session", zap.Error(err))
|
wc.logger.Error("error getting all user answers by result session", zap.Error(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
//todo За один запрос можно передать не более 50 сделок.
|
||||||
deal := models.DealReq{
|
deal := models.DealReq{
|
||||||
Name: fmt.Sprintf("deal quiz number %d", result.QuizID),
|
Name: fmt.Sprintf("deal quiz number %d", result.QuizID),
|
||||||
StatusID: 48703678, //result.StepID,
|
StatusID: result.StepID,
|
||||||
PipelineID: 5505076, //result.PipelineID,
|
PipelineID: result.PipelineID,
|
||||||
CreatedBy: 0, //result.AmoAccountID,
|
CreatedBy: 0, //result.AmoAccountID,
|
||||||
UpdatedBy: 0,
|
UpdatedBy: 0,
|
||||||
CreatedAt: time.Now().Unix(),
|
CreatedAt: time.Now().Unix(),
|
||||||
ResponsibleUserID: result.PerformerID,
|
ResponsibleUserID: result.PerformerID,
|
||||||
Embed: models.Embedd{
|
Embed: models.Embedd{
|
||||||
Contact: []models.Contact{
|
Company: []models.Company{},
|
||||||
{
|
|
||||||
Name: "Дмитрий",
|
|
||||||
CreatedAT: time.Now().Unix(),
|
|
||||||
UpdatedBy: 0,
|
|
||||||
ResponsibleUserID: result.PerformerID,
|
|
||||||
CustomFieldsValues: []models.FieldsValues{
|
|
||||||
{
|
|
||||||
FieldID: 1153687,
|
|
||||||
Values: []models.Values{
|
|
||||||
{
|
|
||||||
Value: "Saint_Petersburg",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Source: models.Source{
|
Source: models.Source{
|
||||||
Type: "widget",
|
Type: "widget",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
// строка которая будет возвращенна в респонсе чтоб понимать кто есть что
|
||||||
|
RequestID: strconv.Itoa(int(result.AnswerID)),
|
||||||
}
|
}
|
||||||
fields := tools.ConstructField(allAnswers, result.FieldsRule)
|
|
||||||
|
|
||||||
deal.CustomFieldsValues = fields
|
leadFields, contactData, companyData := tools.ConstructField(allAnswers, result)
|
||||||
|
|
||||||
|
deal.CustomFieldsValues = leadFields
|
||||||
|
deal.Embed.Contact = contactData
|
||||||
|
deal.Embed.Company = companyData
|
||||||
|
|
||||||
mapDealReq[result.AccessToken] = append(mapDealReq[result.AccessToken], deal)
|
mapDealReq[result.AccessToken] = append(mapDealReq[result.AccessToken], deal)
|
||||||
}
|
}
|
||||||
|
@ -428,7 +428,7 @@ func (a *Amo) AddFields(req []models.AddLeadsFields, entity model.EntityType, ac
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Amo) CreatingDeal(req []models.DealReq, accessToken string) (*models.DealResp, error) {
|
func (a *Amo) CreatingDeal(req []models.DealReq, accessToken string) ([]models.DealResp, error) {
|
||||||
for {
|
for {
|
||||||
if a.rateLimiter.Check() {
|
if a.rateLimiter.Check() {
|
||||||
uri := fmt.Sprintf("%s/api/v4/leads/complex", a.baseApiURL)
|
uri := fmt.Sprintf("%s/api/v4/leads/complex", a.baseApiURL)
|
||||||
@ -456,14 +456,14 @@ func (a *Amo) CreatingDeal(req []models.DealReq, accessToken string) (*models.De
|
|||||||
return nil, fmt.Errorf(errorMessage)
|
return nil, fmt.Errorf(errorMessage)
|
||||||
}
|
}
|
||||||
|
|
||||||
var resp models.DealResp
|
var resp []models.DealResp
|
||||||
err = json.Unmarshal(resBody, &resp)
|
err = json.Unmarshal(resBody, &resp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
a.logger.Error("error unmarshal response body in Creating Deal:", zap.Error(err))
|
a.logger.Error("error unmarshal response body in Creating Deal:", zap.Error(err))
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
time.Sleep(a.rateLimiter.Interval)
|
time.Sleep(a.rateLimiter.Interval)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user