# Вопросы и Ответы - Отправка инвойсов в E-Taxes Дата: 2025-12-15 Задача: Добавить функционал отправки Sales Invoice в E-Taxes ## Технические Вопросы и Ответы ### 1. Аутентификация **Q:** Должны ли мы использовать существующую систему аутентификации ASAN Login (которая уже есть в приложении для импорта инвойсов), или нужны отдельные credentials для отправки? **A:** Использовать существующий ASAN Login --- ### 2. Доступность кнопки **Q:** Когда кнопка 'Отправить в E-Taxes' должна быть доступна? **A:** После Submit (рекомендуется) - кнопка доступна только после того, как Sales Invoice в статусе Submitted --- ### 3. Процесс подписания **Q:** Должен ли процесс подписания (sign/withAsanImza) происходить автоматически после создания инвойса, или это должна быть отдельная кнопка? **A:** Да, автоматически после создания. Если у тебя есть еще вопросы - не стесняйся их задавать. Например где создавать кастомные поля, которые могут понадобится? Ответ - в приложении jey_erp, там файл custom_fields. --- ### 4. Данные клиента (TIN и Object Name) **Q:** Где хранится информация о клиенте для отправки в E-Taxes (TIN, objectName)? **A:** Так, поле TIN это tax_id а вот поля object_name не существует. ПОКА ЧТО пусть создастся тестовое поле с типом текст, потом что нибудь придумаем на замену. --- ### 5. Product Group Code для товаров **Q:** Как определять productGroupCode для товаров (items)? **A:** Есть поле в item называется product_group_code, текстового типа. --- ### 6. Сохранение данных после отправки **Q:** Какие данные нужно сохранить после успешной отправки? **A:** - Invoice ID - Serial Number - Verification Code - Статус отправки --- ### 7. Обработка ошибок API **Q:** Как обрабатывать ошибки API? **A:** Показать ошибку и остановить. Если есть еще какие то вопросы - не стесняйся задавать, чем большое понимания задачи - тем лучше исполнение. --- ### 8. Тип НДС для товаров **Q:** Как определять тип НДС для товаров (vat18, vat0, vatFree, exempt)? **A:** Проанализируй файл custom_fields.py, там вроде бы уже созданы поля для этих целей, вот код из этого файла: ```python "Sales Invoice Item": [ dict( fieldname='vat_18_percent_with_amount', label='VAT 18% with amount', fieldtype='Currency', insert_after='amount', in_list_view=1, read_only=1, columns=2, precision=2 ), dict( fieldname='vat_amount', label='VAT Amount', fieldtype='Currency', insert_after='vat_18_percent_with_amount', in_list_view=1, columns=2, precision=2, read_only=1, description='Calculated as: VAT 18% with amount - Amount' ), dict( fieldname='vat_0_percent_with_amount', label='VAT 0% with amount', fieldtype='Currency', insert_after='vat_amount', in_list_view=1, read_only=1, columns=2, precision=2 ), dict( fieldname='amount_without_vat', label='Amount without VAT', fieldtype='Currency', insert_after='vat_0_percent_with_amount', in_list_view=1, read_only=1, columns=2, precision=2 ), dict( fieldname='vat_free_amount', label='VAT free amount', fieldtype='Currency', insert_after='amount_without_vat', in_list_view=1, read_only=1, columns=2, precision=2 ), dict( fieldname='tax_article', label='Tax Article', fieldtype='Link', options='Tax Article', insert_after='vat_free_amount', in_list_view=1, columns=2, description='Tax Article field for VAT purposes' ) ] ``` --- ### 9. Unit Code для единиц измерения **Q:** Откуда брать unitCode для единиц измерения? **A:** Вот список всех единиц измерений и их кодов из сайта: ```json { "items": [ {"code": "666", "name": {"az": "ədəd", "ru": "штук", "en": "piece"}}, {"code": "391836", "name": {"az": "km", "ru": "км", "en": "km"}}, {"code": "529937", "name": {"az": "kq", "ru": "кг", "en": "kg"}}, {"code": "581879", "name": {"az": "l", "ru": "л", "en": "l"}}, {"code": "207201", "name": {"az": "m", "ru": "м", "en": "m"}}, {"code": "6666", "name": {"az": "m2", "ru": "м2", "en": "m2"}}, {"code": "839111", "name": {"az": "m3", "ru": "м3", "en": "m3"}}, {"code": "525166", "name": {"az": "q", "ru": "г", "en": "g"}}, {"code": "116094", "name": {"az": "sm", "ru": "см", "en": "cm"}}, {"code": "864211", "name": {"az": "sm3", "ru": "см3", "en": "cm3"}}, {"code": "544580", "name": {"az": "t", "ru": "т", "en": "t"}} ] } ``` --- ### 10. Дополнительные поля (senderObjectCode, vehicleRegistrationNumber) **Q:** Что делать с полями senderObjectCode и vehicleRegistrationNumber? **A:** Оставить пустыми --- ### 11. Предотвращение повторной отправки **Q:** Должны ли мы предотвращать повторную отправку? **A:** Да, блокировать повтор --- ### 12. Текст кнопки **Q:** Какой текст должен быть на кнопке отправки? **A:** Send to E-Taxes --- ### 13. Комментарии в инвойсе **Q:** Что делать с полями invoiceComment и invoiceComment2? **A:** Есть буквально поля который называются comment и additional_comment. --- ### 14. Диалог подтверждения **Q:** Показывать ли диалог подтверждения перед отправкой? **A:** Да, аж два, типа "вы точно уверены?" "точно при точно??" (ну не дословно так, но будет 2 вопроса). --- ### 15. Кнопка в списке инвойсов **Q:** Нужна ли кнопка в list view (списке инвойсов)? **A:** Вообще нужно, но давай пока что без этого. Если есть еще вопросы - задавай. Кстати, на всякий случай, если я захочу продолжить в другом чате - ответы на вопросы и план основанный на ответах создай в корневой папке приложения. --- ### 16. Генерация ID для товаров **Q:** Как генерировать ID для товаров (item id в формате '44f5986a-2d3c-45d6-bb14-79a899******')? **A:** Случайный UUID --- ### 17. Фиксированные поля JSON **Q:** Какие значения использовать для полей type, kind, sourceSystem? **A:** Как в примере (type='current', kind='defaultInvoice', sourceSystem='lk') --- ### 18. Валидация данных **Q:** Нужно ли валидировать данные перед отправкой? **A:** - Проверить TIN клиента - Проверить product codes - Проверить unit codes --- ## Техническая Информация ### API Endpoints: 1. **Generate Serial Number**: `https://new.e-taxes.gov.az/api/po/invoice/public/v1/generateSerialNumber/defaultInvoice` - Response: `{"serialNumber":"MT25121128****"}` 2. **Create Invoice**: `https://new.e-taxes.gov.az/api/po/invoice/public/v2/invoice` - Response: `{"id":"b7bd1f20-4bdb-4e7b-bf18-c1f9bd******"}` 3. **Sign Invoice**: `https://new.e-taxes.gov.az/api/po/invoice/public/v1/invoice/sign/withAsanImza` - Request: `{"type": "send", "invoiceIds": ["invoice-id-here"]}` - Response: `{"status":"ok","error":null,"verificationCode":"4147"}` ### Примеры находятся в: - `/home/frappe/frappe-bench/apps/invoice_az/invoice.txt` - пример создания инвойса - `/home/frappe/frappe-bench/apps/invoice_az/invoice asan.txt` - пример подписания ### Кастомные поля создаются в: - `/home/frappe/frappe-bench/apps/jey_erp/jey_erp/custom_fields.py` ### Существующие поля в Sales Invoice Item: - vat_18_percent_with_amount - vat_amount - vat_0_percent_with_amount - amount_without_vat - vat_free_amount - tax_article ### Существующие поля в Sales Invoice: - comment - additional_comment - tax_id (в Customer) ### Существующие поля в Item: - product_group_code --- ### 19. Маппинг единиц измерения (UOM) **Q:** Как маппить единицы измерения из ERPNext UOM в коды E-Taxes? Например, если в Sales Invoice Item указано 'Nos' или 'Unit' - какой код использовать? **A:** Короче, я только что путем эксперементов узнал что оказвыается поле unit_code необязательно, и вообще тот список ед. измерений который я тебе скинул - это просто шаблоны из сайта, то есть можно просто текстом написать ədəd, и сайт пропустит это, даже без кода, или вообще написать test123, и сайт всеравно пропустит. ПОэтому просто бери имя единицы измерений из табличной части и все. --- ### 20. Pricing поля для товаров **Q:** Что использовать для pricePerUnit и cost в items? В примере оба = 1, но у нас есть rate, amount и т.д. **A:** rate -> pricePerUnit, amount -> cost --- ### 21. Кнопка после отправки **Q:** Что делать с кнопкой после успешной отправки (ты говорил блокировать повтор)? **A:** Показать статус (заменить кнопку на индикатор статуса с информацией об отправке) --- ### 22. Язык сообщений **Q:** На каком языке показывать сообщения об ошибках и подтверждения? **A:** English --- ### 23. Receiver Name (юридическое название) **Q:** Про receiver.name - нужно искать клиента в E-Taxes Customer Mappings, найти соответствующий E-Taxes Customers и оттуда брать name? **A:** Да, из E-Taxes Customers. Короче ищи соответствие в e-taxes-settings (в том, который помечен как default), и там будет 100% название из сайта. --- ### 24. Частичная ошибка (создание успешно, подписание failed) **Q:** Если создание инвойса (invoice create) прошло успешно, но подписание (signing) провалилось - что делать? **A:** Сохранить ID, показать ошибку. Сохранить invoice ID и serial number, но показать ошибку подписания. Статус = 'Created, not signed' --- ### 25. Progress dialog **Q:** Нужно ли показывать progress dialog во время отправки (как в существующей функции импорта)? **A:** Простой loading (простой frappe.show_alert с loading индикатором) --- ### 26. Тексты подтверждения **Q:** Тексты для двух диалогов подтверждения - какие должны быть? **A:** Простые - 1) 'Send this invoice to E-Taxes?' 2) 'Are you sure?' --- ### 27. Tracking doctype **Q:** Нужно ли создавать tracking doctype (типа E-Taxes Sales) для отправленных инвойсов? **A:** Да, создать. (Создать E-Taxes Sales Outbox для отслеживания отправленных инвойсов) --- ## Workflow процесса отправки: 1. Пользователь нажимает "Send to E-Taxes" на submitted Sales Invoice 2. Первый диалог подтверждения: 'Send this invoice to E-Taxes?' 3. Второй диалог подтверждения: 'Are you sure?' 4. Показать простой loading индикатор 5. Валидация данных: - Проверка TIN клиента (tax_id) - Проверка product_group_code у всех товаров - Проверка что инвойс еще не отправлен (блокировка повтора) 6. Получение serial number от API 7. Формирование JSON с данными инвойса: - receiver.name - из E-Taxes Customers (через mapping) - receiver.tin - из tax_id - receiver.objectName - из custom field в Sales Invoice - items: pricePerUnit = rate, cost = amount, unit = UOM name (текст) - VAT: vat_18_percent_with_amount -> vat18, vat_0_percent_with_amount -> vat0, etc. - comments: comment и additional_comment 8. Отправка на создание инвойса 9. Автоматическое подписание инвойса 10. Создание E-Taxes Sales Outbox tracking document 11. Сохранение результатов в Sales Invoice: - Invoice ID - Serial Number - Verification Code (если успешно) - Статус отправки ('Sent and Signed' или 'Created, not signed') 12. Заменить кнопку на индикатор статуса 13. Показать успешное сообщение пользователю