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
import (
"encoding/json"
"fmt"
)
type DealReq struct {
Name string `json:"name"` // название сделки
Price int `json:"price"` // бюджет сделки
@ -18,9 +23,11 @@ type DealReq struct {
RequestID string `json:"request_id"`
}
type ValueInterface interface{}
type FieldsValues struct {
FieldID int `json:"field_id"`
Values []interface{} `json:"values"`
FieldID int `json:"field_id"`
Values []ValueInterface `json:"values"`
}
type Values struct {
@ -37,6 +44,52 @@ type ValueFile struct {
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 {
Tags []Tag `json:"tags"` // Данные тегов, добавляемых к сделке
Contact []Contact `json:"contacts"` // Данные контактов, которые будет прикреплены к сделке

@ -4,6 +4,7 @@ import (
"amocrm/internal/models"
"context"
"encoding/json"
"fmt"
"github.com/go-redis/redis/v8"
"go.uber.org/zap"
"strconv"
@ -49,6 +50,7 @@ func (r *Repository) CachingLeadFieldsToRedis(ctx context.Context, answerID int6
return err
}
fmt.Println(string(leadFieldsJson), "CHECK CACHING LEAD FIELDS")
err = r.redisClient.Set(ctx, key, leadFieldsJson, 0).Err()
if err != nil {
return err
@ -104,6 +106,14 @@ func (r *Repository) FetchingDeals(ctx context.Context) (map[string][]models.Map
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()
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 {
if fieldValue != "" {
values := make([]interface{}, 0)
values := make([]models.ValueInterface, 0)
values = append(values, models.Values{Value: fieldValue})
contactFields = append(contactFields, models.FieldsValues{
@ -129,7 +129,7 @@ func ConstructUTMFields(utmMap model.UTMSavingMap, currentFields []model.Field)
var fields []models.FieldsValues
for _, field := range currentFields {
if data, ok := utmMap[field.Name]; ok {
val := []interface{}{
val := []models.ValueInterface{
models.Values{
Value: data,
},

@ -142,9 +142,11 @@ func (wc *PostDeals) sendingDealsReq(ctx context.Context, mapDealReq map[string]
for accessToken, deal := range mapDealReq {
resp, err := wc.amoClient.CreatingDeal(deal, accessToken)
if err != nil {
// todo логирование в тг
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 {
wc.logger.Error("error saving resp data to db", zap.Error(err))
return err
@ -153,11 +155,8 @@ func (wc *PostDeals) sendingDealsReq(ctx context.Context, mapDealReq map[string]
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"
if errResp != nil {
status = errResp.Error()
}
for _, dealResp := range resp {
requestID := strings.Join(dealResp.RequestID, ",")
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) {
dateCreating := time.Now().Unix()
entityFieldsMap := make(map[model.EntityType]map[int][]interface{})
entityFieldsMap[model.LeadsType] = make(map[int][]interface{})
entityFieldsMap[model.CompaniesType] = make(map[int][]interface{})
entityFieldsMap[model.CustomersType] = make(map[int][]interface{})
entityFieldsMap := make(map[model.EntityType]map[int][]models.ValueInterface)
entityFieldsMap[model.LeadsType] = make(map[int][]models.ValueInterface)
entityFieldsMap[model.CompaniesType] = make(map[int][]models.ValueInterface)
entityFieldsMap[model.CustomersType] = make(map[int][]models.ValueInterface)
entityRules := make(map[model.EntityType][]model.FieldRule)
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)
if errResp != nil {
// todo также логирование ошибки в тг
wc.logger.Error("error sendig request for update deal fields", zap.Error(errResp))
for _, data := range reqToUpdate {
errorCheckerMap[data.DealID] = struct{}{}
@ -101,7 +102,6 @@ func (wc *PostFields) sendForUpdate(ctx context.Context, token string, dealsData
err := wc.updateDealStatus(ctx, DealStatus{
Resp: resp,
AccessToken: token,
ErrResp: errResp,
})
if err != nil {
@ -115,7 +115,6 @@ func (wc *PostFields) sendForUpdate(ctx context.Context, token string, dealsData
type DealStatus struct {
Resp *models.UpdateDealResp
AccessToken string
ErrResp 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)
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 {
for _, err = range errs {
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)
}
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
}
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))
}