Krukov / amocrm_api

Python amocrm API wrapper
MIT License
104 stars 55 forks source link

ValidationError, FieldNotExpected при сохранении кастомных полей #68

Closed alex-msk closed 1 year ago

alex-msk commented 2 years ago

Есть такое поле

class Contact(_Contact):
    class LANG_ENUMS:
        ru = custom_field.SelectValue(id=1227515, value='Рус')
        en = custom_field.SelectValue(id=1227517, value='Англ')
    lang = custom_field.SelectCustomField("Язык", field_id=1152165, enums=LANG_ENUMS)

Делаю так:

lang_enum_ru = crm_inst.LANG_ENUMS.ru
crm_inst.lang = lang_enum_ru

или

crm_inst.lang = 'Рус'

затем

crm_inst.save()

и получаю Exception:

ValidationError({'validation-errors': [{'request_id': '0', 'errors': [{'code': 'FieldNotExpected', 'path': 'custom_fields_values.5.values.0.enum_code', 'detail': 'This field was not expected.'}]}], 'title': 'Bad Request', 'type': 'https://httpstatus.es/400', 'status': 400, 'detail': 'Request validation failed'})

Причем такое почти при любом сохранении полей кроме стандартных(в смысле при сохранении custom_fields). в чем может быть проблема?

celeryworker_1  | Traceback (most recent call last):
celeryworker_1  |   File "/usr/local/lib/python3.9/site-packages/celery/app/trace.py", line 451, in trace_task
celeryworker_1  |     R = retval = fun(*args, **kwargs)
celeryworker_1  |   File "/usr/local/lib/python3.9/site-packages/celery/app/trace.py", line 734, in __protected_call__
celeryworker_1  |     return self.run(*args, **kwargs)
celeryworker_1  |   File "/app/amo/tasks.py", line 246, in validate_person
celeryworker_1  |     raise self.retry(exc=e)
celeryworker_1  |   File "/usr/local/lib/python3.9/site-packages/celery/app/task.py", line 717, in retry
celeryworker_1  |     raise_with_context(exc)
celeryworker_1  |   File "/app/amo/tasks.py", line 242, in validate_person
celeryworker_1  |     crm_inst.save()
celeryworker_1  |   File "/usr/local/lib/python3.9/site-packages/amocrm/v2/model.py", line 49, in save
celeryworker_1  |     self.update()
celeryworker_1  |   File "/usr/local/lib/python3.9/site-packages/amocrm/v2/model.py", line 63, in update
celeryworker_1  |     self._manager.update(self.id, self._get_updated_data())
celeryworker_1  |   File "/usr/local/lib/python3.9/site-packages/amocrm/v2/manager.py", line 19, in update
celeryworker_1  |     return self._interaction.update(object_id=object_id, data=data or kwargs)
celeryworker_1  |   File "/usr/local/lib/python3.9/site-packages/amocrm/v2/interaction.py", line 132, in update
celeryworker_1  |     raise exceptions.ValidationError(response)
celeryworker_1  | amocrm.v2.exceptions.ValidationError: {'validation-errors': [{'request_id': '0', 'errors': [{'code': 'FieldNotExpected', 'path': 'custom_fields_values.5.values.0.enum_code', 'detail': 'This field was not expected.'}]}], 'title': 'Bad Request', 'type': 'https://httpstatus.es/400', 'status': 400, 'detail': 'Request validation failed'}
alex-msk commented 2 years ago

Вообщем то ли API AmoCRM не воспринимает 'field_code' и 'enum_code', то ли не воспринимает их вместе c ID полей и значений, то ли ему требуется строго ID, но временно удалось обойти проблему таким вот адовым костылём :)

        for c in crm_inst._data['custom_fields_values']:
            if 'field_code' in c:
                del c['field_code']
            if 'values' in c:
                for v in c['values']:
                    if 'enum_code' in v:
                        del v['enum_code']

crm_inst - это экземпляр Contact

Krukov commented 2 years ago

честно скажу я с Енумами потому так и не работал или не разобрался - надо смотреть: может тут кривая реализация )

Krukov commented 2 years ago

Да судя по коду они и не будут работать https://github.com/Krukov/amocrm_api/blame/426f4582e3c6b15a4bd68315b7ea40946fb6d736/amocrm/v2/entity/custom_field.py#L196

alex-msk commented 2 years ago

Ну, мой грязный хак выше вполне себе работает. Так что здесь им то ли не нравится наличие field_code/enum_code, то ли field_code вместе с field_id(нужно что то одно). Судя по всему, нужно убрать field_code/enum_code, если это не противоречит ничему другому в проекте.

LennyLip commented 2 years ago

Подскажите, где спросить про api (интересуют обновление enums в кастомных полях так, чтобы не слетали со сделок. В ТП послали в тематические сообщества (или к ведущему партнеру - я не знаю кто это), где эти сообщества искать? Или может тут кто знает?

from_field = Manager(
        GenericInteraction(
            path=f"leads/custom_fields",
            field="custom_fields",
        ),
        model=custom_field.CustomFieldModel,
    )
  data = {
        "enums":  enums_list
    }
 from_field.update(object_id=123, data=data)

обновляю так, но он вроде создает новый список.

Krukov commented 2 years ago

@LennyLip привет не понял что такое "ТП" )

Проблема с енумами есть да и она еще не решена. У меня не хватает мотивации поддерживать библиотеку. Может @alex-msk что то сможет подсказать?

LennyLip commented 2 years ago

@LennyLip привет не понял что такое "ТП" )

ТП - это ТехПоддержка. К библиотеке вопросов нет, код выше работает отлично. С обновлением тоже разобрался, если значение передать с id, то оно остается, если id нет - то создается новый, если значения в амо есть, но id не передали - то оно удаляется соответсвенно при апдейте.

Для примера:

data = {"enums": [{'id': 1291669, 'value': 'Тест 1', 'sort': 1},
                      {'id': 1291671, 'value': 'Тест 2', 'sort': 2},
                      {'value': 'Тест 3', 'sort': 3}
                      ]}

первые два останутся как были, тест 3 - создаст новый.