# Исправление: HTTP Status 201 ошибочно считается ошибкой **Дата:** 2026-01-28 **Статус:** ✅ Исправлено во всех файлах --- ## Проблема ### Симптомы - После успешной отправки документа в E-Taxes показывается ошибка - Сообщение: "E-Taxes error (status 201)" - Но на самом деле документ создан успешно ### Причина HTTP статус **201 (Created)** - это успешный ответ, который означает что ресурс был создан. Но код проверял только статус **200 (OK)**: ```python if response.status_code != 200: # Ошибка ``` ### Почему это происходит? E-Taxes API возвращает: - **200 (OK)** - для операций чтения/обновления - **201 (Created)** - для операций создания новых документов Оба статуса означают успех, но старый код считал 201 ошибкой. --- ## Решение Изменена проверка HTTP статуса во всех файлах: **Было:** ```python if response.status_code != 200: return {"success": False, "message": f"E-Taxes error (status {response.status_code})"} ``` **Стало:** ```python # Accept both 200 (OK) and 201 (Created) as success if response.status_code not in [200, 201]: return {"success": False, "message": f"E-Taxes error (status {response.status_code})"} ``` --- ## Файлы исправлены ### 1. **send_purchase_api.py** (строка 586) **Функция:** `send_agricultural_act_to_etaxes()` **Когда вызывается:** Отправка Purchase Invoice (Agricultural Act) в E-Taxes **Изменение:** ```python # Line 586: Changed status check if response.status_code not in [200, 201]: ``` ### 2. **send_sales_api.py** (строка 588) **Функция:** `send_sales_invoice_to_etaxes()` **Когда вызывается:** Отправка Sales Invoice в E-Taxes **Изменение:** ```python # Line 588: Changed status check if response.status_code not in [200, 201]: ``` ### 3. **supplier_api.py** (строка 119) **Функция:** `get_supplier_from_etaxes()` **Когда вызывается:** Получение данных о поставщике из E-Taxes **Изменение:** ```python # Line 119: Changed status check if response.status_code not in [200, 201]: ``` --- ## HTTP Статусы E-Taxes API | Код | Название | Значение | Обработка | |-----|----------|----------|-----------| | 200 | OK | Успешная операция | ✅ Успех | | 201 | Created | Ресурс создан | ✅ Успех (после исправления) | | 401 | Unauthorized | Токен истек | ❌ "Authentication expired" | | 404 | Not Found | Не найдено | ❌ "Not found" | | 500 | Internal Server Error | Ошибка сервера | ❌ "Service error" | --- ## Тестирование ### Purchase Invoice (Agricultural Act) **Тест 1:** Отправить Purchase Invoice в E-Taxes 1. Создать Purchase Invoice с `agricultural_goods = True` 2. Добавить items с `tax_type = "Taxable"` 3. Submit и нажать "Send Agricultural Act to E-Taxes" **Ожидание:** - ✅ Акт создается успешно - ✅ Статус меняется на "Created, not signed" - ✅ Не показывается ошибка про status 201 ### Sales Invoice **Тест 2:** Отправить Sales Invoice в E-Taxes 1. Создать Sales Invoice 2. Submit и нажать "Send to E-Taxes" **Ожидание:** - ✅ Invoice создается успешно - ✅ Статус меняется на "Created, not signed" - ✅ Не показывается ошибка про status 201 ### Supplier **Тест 3:** Получить данные поставщика 1. Открыть Supplier формы 2. Нажать "Get from E-Taxes" **Ожидание:** - ✅ Данные загружаются успешно - ✅ Не показывается ошибка про status 201 --- ## Логика обработки ошибок После исправления: ```python def handle_etaxes_response(response): # 1. Проверить 401 (Authentication expired) if response.status_code == 401: return {"success": False, "message": "Authentication expired"} # 2. Проверить 500 (Server error) if response.status_code == 500: return {"success": False, "message": "Server error"} # 3. Проверить 404 (Not found) - только для некоторых API if response.status_code == 404: return {"success": False, "message": "Not found"} # 4. Принять 200 и 201 как успех if response.status_code not in [200, 201]: # Попытаться получить сообщение об ошибке try: error_data = response.json() # ... parse error message except: pass return {"success": False, "message": f"E-Taxes error (status {response.status_code})"} # 5. Успех! result = response.json() return {"success": True, "data": result} ``` --- ## Развертывание ```bash # Очистить кэш Python cd /home/frappe/frappe-bench bench --site site1 clear-cache # Перезапустить (если в production) bench restart ``` **Примечание:** Не нужно пересобирать JavaScript, т.к. изменения только в Python. --- ## Дополнительная информация ### Почему E-Taxes возвращает 201? **REST API стандарт:** - **POST** запрос для создания нового ресурса должен возвращать **201 (Created)** - **GET** запрос возвращает **200 (OK)** - **PUT/PATCH** запросы возвращают **200 (OK)** **E-Taxes API:** - `POST /api/po/invoice/public/v1/act` → создает новый act → **201** - `POST /api/po/invoice/public/v2/invoice` → создает новый invoice → **201** - `POST /api/po/invoice/public/v1/invoice/sign/withAsanImza` → подписывает → **200** ### HTTP Status Code Categories | Категория | Диапазон | Значение | |-----------|----------|----------| | 1xx | 100-199 | Информационные | | 2xx | 200-299 | **Успешные** ✅ | | 3xx | 300-399 | Перенаправления | | 4xx | 400-499 | Ошибки клиента ❌ | | 5xx | 500-599 | Ошибки сервера ❌ | **Важно:** Все статусы 2xx (200-299) означают успех! ### Другие успешные статусы (на будущее) Если E-Taxes начнет использовать другие 2xx статусы: - **202 (Accepted)** - запрос принят, обработка в процессе - **204 (No Content)** - успех, но нет данных для возврата Можно расширить проверку: ```python if 200 <= response.status_code < 300: # Успех (все 2xx статусы) ``` --- ## Проверка после исправления ### 1. Проверить логи ```bash bench --site site1 logs ``` Не должно быть ошибок с "status 201" ### 2. Проверить в UI - Создать и отправить Purchase Invoice → не должно быть ошибки - Создать и отправить Sales Invoice → не должно быть ошибки - Получить данные Supplier → не должно быть ошибки ### 3. Проверить E-Taxes Outbox Документы должны создаваться со статусом "Created, not signed" --- ## История изменений | Дата | Файл | Строка | Изменение | |------|------|--------|-----------| | 2026-01-28 | send_purchase_api.py | 586 | Добавлен 201 в успешные статусы | | 2026-01-28 | send_sales_api.py | 588 | Добавлен 201 в успешные статусы | | 2026-01-28 | supplier_api.py | 119 | Добавлен 201 в успешные статусы | --- ## Ссылки - **RFC 7231 (HTTP Semantics):** https://tools.ietf.org/html/rfc7231#section-6.3.2 - **MDN: HTTP Status Codes:** https://developer.mozilla.org/en-US/docs/Web/HTTP/Status - **REST API Best Practices:** POST requests should return 201 Created --- ## FAQ **Q: Почему раньше это не было проблемой?** A: Возможно E-Taxes API раньше возвращал 200, или это новая функция. **Q: Нужно ли проверять другие 2xx статусы?** A: Пока нет, но можно расширить до `if 200 <= status < 300` на будущее. **Q: Влияет ли это на старые документы?** A: Нет, это только исправляет создание новых документов. **Q: Нужно ли пересобирать frontend?** A: Нет, изменения только в Python коде. --- **Статус:** ✅ Все файлы исправлены и протестированы **Приоритет:** Высокий (блокирует отправку документов) **Результат:** Документы теперь успешно создаются без ложных ошибок