add custom encoder (need testing with amo) and delete double logic for save status deals, for future connect to tg trashlog

This commit is contained in:
Pavel 2024-06-08 14:40:47 +03:00
parent 4b1d689fd7
commit a4e90a79d7
7 changed files with 135 additions and 23 deletions

@ -1,5 +1,10 @@
package models package models
import (
"encoding/json"
"fmt"
)
type DealReq struct { type DealReq struct {
Name string `json:"name"` // название сделки Name string `json:"name"` // название сделки
Price int `json:"price"` // бюджет сделки Price int `json:"price"` // бюджет сделки
@ -18,9 +23,11 @@ type DealReq struct {
RequestID string `json:"request_id"` RequestID string `json:"request_id"`
} }
type ValueInterface interface{}
type FieldsValues struct { type FieldsValues struct {
FieldID int `json:"field_id"` FieldID int `json:"field_id"`
Values []interface{} `json:"values"` Values []ValueInterface `json:"values"`
} }
type Values struct { type Values struct {
@ -37,6 +44,52 @@ type ValueFile struct {
FileSize int64 `json:"file_size"` FileSize int64 `json:"file_size"`
} }
func (fv *FieldsValues) UnmarshalJSON(data []byte) error {
type Alias FieldsValues
aux := struct {
Alias
FieldID int `json:"field_id"`
Values []json.RawMessage `json:"values"`
}{}
if err := json.Unmarshal(data, &aux); err != nil {
return err
}
fv.FieldID = aux.FieldID
fv.Values = make([]ValueInterface, len(aux.Values))
for i, rawVal := range aux.Values {
var v map[string]interface{}
if err := json.Unmarshal(rawVal, &v); err != nil {
return err
}
if _, ok := v["value"]; !ok {
return fmt.Errorf("missing value in JSON")
}
var value ValueInterface
if _, ok := v["value"].(map[string]interface{}); ok {
var fileStruct ValuesFile
if err := json.Unmarshal(rawVal, &fileStruct); err != nil {
return err
}
value = fileStruct
} else {
var valValue Values
if err := json.Unmarshal(rawVal, &valValue); err != nil {
return err
}
value = valValue
}
fv.Values[i] = value
}
return nil
}
type Embedd struct { type Embedd struct {
Tags []Tag `json:"tags"` // Данные тегов, добавляемых к сделке Tags []Tag `json:"tags"` // Данные тегов, добавляемых к сделке
Contact []Contact `json:"contacts"` // Данные контактов, которые будет прикреплены к сделке Contact []Contact `json:"contacts"` // Данные контактов, которые будет прикреплены к сделке

@ -4,6 +4,7 @@ import (
"amocrm/internal/models" "amocrm/internal/models"
"context" "context"
"encoding/json" "encoding/json"
"fmt"
"github.com/go-redis/redis/v8" "github.com/go-redis/redis/v8"
"go.uber.org/zap" "go.uber.org/zap"
"strconv" "strconv"
@ -49,6 +50,7 @@ func (r *Repository) CachingLeadFieldsToRedis(ctx context.Context, answerID int6
return err return err
} }
fmt.Println(string(leadFieldsJson), "CHECK CACHING LEAD FIELDS")
err = r.redisClient.Set(ctx, key, leadFieldsJson, 0).Err() err = r.redisClient.Set(ctx, key, leadFieldsJson, 0).Err()
if err != nil { if err != nil {
return err return err
@ -104,6 +106,14 @@ func (r *Repository) FetchingDeals(ctx context.Context) (map[string][]models.Map
return return
} }
fmt.Println("CUSTOM ENCODER", leadFields)
for _, f := range leadFields {
fmt.Println(f.FieldID)
fmt.Println(f.Values[0])
fmt.Println(f.Values[1])
}
mu.Lock() mu.Lock()
defer mu.Unlock() defer mu.Unlock()

@ -114,7 +114,7 @@ func EmojiUnicode(text string) string {
func AddContactFields(contactFields []models.FieldsValues, fieldValue string, fieldType model.ContactQuizConfig, fieldMap map[string]int) []models.FieldsValues { func AddContactFields(contactFields []models.FieldsValues, fieldValue string, fieldType model.ContactQuizConfig, fieldMap map[string]int) []models.FieldsValues {
if fieldValue != "" { if fieldValue != "" {
values := make([]interface{}, 0) values := make([]models.ValueInterface, 0)
values = append(values, models.Values{Value: fieldValue}) values = append(values, models.Values{Value: fieldValue})
contactFields = append(contactFields, models.FieldsValues{ contactFields = append(contactFields, models.FieldsValues{
@ -129,7 +129,7 @@ func ConstructUTMFields(utmMap model.UTMSavingMap, currentFields []model.Field)
var fields []models.FieldsValues var fields []models.FieldsValues
for _, field := range currentFields { for _, field := range currentFields {
if data, ok := utmMap[field.Name]; ok { if data, ok := utmMap[field.Name]; ok {
val := []interface{}{ val := []models.ValueInterface{
models.Values{ models.Values{
Value: data, Value: data,
}, },

@ -142,9 +142,11 @@ func (wc *PostDeals) sendingDealsReq(ctx context.Context, mapDealReq map[string]
for accessToken, deal := range mapDealReq { for accessToken, deal := range mapDealReq {
resp, err := wc.amoClient.CreatingDeal(deal, accessToken) resp, err := wc.amoClient.CreatingDeal(deal, accessToken)
if err != nil { if err != nil {
// todo логирование в тг
wc.logger.Error("error creating deal in amo", zap.Error(err)) wc.logger.Error("error creating deal in amo", zap.Error(err))
return err
} }
err = wc.saveDealToDB(ctx, resp, accessToken, err) err = wc.saveDealToDB(ctx, resp, accessToken)
if err != nil { if err != nil {
wc.logger.Error("error saving resp data to db", zap.Error(err)) wc.logger.Error("error saving resp data to db", zap.Error(err))
return err return err
@ -153,11 +155,8 @@ func (wc *PostDeals) sendingDealsReq(ctx context.Context, mapDealReq map[string]
return nil return nil
} }
func (wc *PostDeals) saveDealToDB(ctx context.Context, resp []models.DealResp, accessToken string, errResp error) error { func (wc *PostDeals) saveDealToDB(ctx context.Context, resp []models.DealResp, accessToken string) error {
status := "pending" status := "pending"
if errResp != nil {
status = errResp.Error()
}
for _, dealResp := range resp { for _, dealResp := range resp {
requestID := strings.Join(dealResp.RequestID, ",") requestID := strings.Join(dealResp.RequestID, ",")
answerID, err := strconv.ParseInt(requestID, 10, 64) answerID, err := strconv.ParseInt(requestID, 10, 64)
@ -189,10 +188,10 @@ func (wc *PostDeals) saveDealToDB(ctx context.Context, resp []models.DealResp, a
func (wc *PostDeals) constructField(ctx context.Context, allAnswers []model.ResultAnswer, result model.AmoUsersTrueResults) ([]models.FieldsValues, []models.Contact, []models.Company, []models.Customer, error) { func (wc *PostDeals) constructField(ctx context.Context, allAnswers []model.ResultAnswer, result model.AmoUsersTrueResults) ([]models.FieldsValues, []models.Contact, []models.Company, []models.Customer, error) {
dateCreating := time.Now().Unix() dateCreating := time.Now().Unix()
entityFieldsMap := make(map[model.EntityType]map[int][]interface{}) entityFieldsMap := make(map[model.EntityType]map[int][]models.ValueInterface)
entityFieldsMap[model.LeadsType] = make(map[int][]interface{}) entityFieldsMap[model.LeadsType] = make(map[int][]models.ValueInterface)
entityFieldsMap[model.CompaniesType] = make(map[int][]interface{}) entityFieldsMap[model.CompaniesType] = make(map[int][]models.ValueInterface)
entityFieldsMap[model.CustomersType] = make(map[int][]interface{}) entityFieldsMap[model.CustomersType] = make(map[int][]models.ValueInterface)
entityRules := make(map[model.EntityType][]model.FieldRule) entityRules := make(map[model.EntityType][]model.FieldRule)
entityRules[model.LeadsType] = result.FieldsRule.Lead entityRules[model.LeadsType] = result.FieldsRule.Lead

@ -91,6 +91,7 @@ func (wc *PostFields) sendForUpdate(ctx context.Context, token string, dealsData
resp, errResp := wc.amoClient.UpdatingDeal(reqToUpdate, token) resp, errResp := wc.amoClient.UpdatingDeal(reqToUpdate, token)
if errResp != nil { if errResp != nil {
// todo также логирование ошибки в тг
wc.logger.Error("error sendig request for update deal fields", zap.Error(errResp)) wc.logger.Error("error sendig request for update deal fields", zap.Error(errResp))
for _, data := range reqToUpdate { for _, data := range reqToUpdate {
errorCheckerMap[data.DealID] = struct{}{} errorCheckerMap[data.DealID] = struct{}{}
@ -101,7 +102,6 @@ func (wc *PostFields) sendForUpdate(ctx context.Context, token string, dealsData
err := wc.updateDealStatus(ctx, DealStatus{ err := wc.updateDealStatus(ctx, DealStatus{
Resp: resp, Resp: resp,
AccessToken: token, AccessToken: token,
ErrResp: errResp,
}) })
if err != nil { if err != nil {
@ -115,7 +115,6 @@ func (wc *PostFields) sendForUpdate(ctx context.Context, token string, dealsData
type DealStatus struct { type DealStatus struct {
Resp *models.UpdateDealResp Resp *models.UpdateDealResp
AccessToken string AccessToken string
ErrResp error
} }
func (wc *PostFields) updateDealStatus(ctx context.Context, deps DealStatus) error { func (wc *PostFields) updateDealStatus(ctx context.Context, deps DealStatus) error {

@ -440,14 +440,6 @@ func (a *Amo) CreatingDeal(req []models.DealReq, accessToken string) ([]models.D
agent.Set("Authorization", "Bearer "+accessToken) agent.Set("Authorization", "Bearer "+accessToken)
statusCode, resBody, errs := agent.Bytes() statusCode, resBody, errs := agent.Bytes()
var resp []models.DealResp
err = json.Unmarshal(resBody, &resp)
if err != nil {
a.logger.Error("error unmarshal response body in Creating Deal:", zap.Error(err))
return nil, err
}
if len(errs) > 0 { if len(errs) > 0 {
for _, err = range errs { for _, err = range errs {
a.logger.Error("error sending request in Creating Deal for creating deals", zap.Error(err)) a.logger.Error("error sending request in Creating Deal for creating deals", zap.Error(err))
@ -461,6 +453,13 @@ func (a *Amo) CreatingDeal(req []models.DealReq, accessToken string) ([]models.D
return nil, fmt.Errorf(errorMessage) return nil, fmt.Errorf(errorMessage)
} }
var resp []models.DealResp
err = json.Unmarshal(resBody, &resp)
if err != nil {
a.logger.Error("error unmarshal response body in Creating Deal:", zap.Error(err))
return nil, err
}
return resp, nil return resp, nil
} }
time.Sleep(a.rateLimiter.Interval) time.Sleep(a.rateLimiter.Interval)

52
tests/json/json_test.go Normal file

@ -0,0 +1,52 @@
package json
import (
"amocrm/internal/models"
"encoding/json"
"fmt"
"github.com/stretchr/testify/assert"
"testing"
)
func TestUnmarshalJSON(t *testing.T) {
jsonData := []byte(`[
{
"field_id": 1,
"values": [
{"value": "Value1"},
{"value": {"file_uuid": "123e4567file_uuid", "version_uuid": "123e4567version_uuid", "file_name": "file.pdf", "file_size": 1}}
]
},
{
"field_id": 2,
"values": [
{"value": "Value2"},
{"value": {"file_uuid": "98765432file_uuid", "version_uuid": "98765432version_uuid", "file_name": "file.wc", "file_size": 2}}
]
},
{
"field_id": 3,
"values": [
{"value": "Value3"},
{"value": {"file_uuid": "abcdeffile_uuid", "version_uuid": "abcdefversion_uuid", "file_name": "file.txt", "file_size": 3}}
]
}
]
`)
var fv []models.FieldsValues
err := json.Unmarshal(jsonData, &fv)
if err != nil {
t.Errorf("UnmarshalJSON failed: %v", err)
}
for _, f := range fv {
fmt.Println(f)
}
assert.Equal(t, 3, len(fv))
jsonAgain, err := json.Marshal(fv)
assert.NoError(t, err)
fmt.Println(string(jsonAgain))
}