15 KiB
Вопросы и Ответы - Отправка инвойсов в 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, там вроде бы уже созданы поля для этих целей, вот код из этого файла:
"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: Вот список всех единиц измерений и их кодов из сайта:
{
"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:
-
Generate Serial Number:
https://new.e-taxes.gov.az/api/po/invoice/public/v1/generateSerialNumber/defaultInvoice- Response:
{"serialNumber":"MT25121128****"}
- Response:
-
Create Invoice:
https://new.e-taxes.gov.az/api/po/invoice/public/v2/invoice- Response:
{"id":"b7bd1f20-4bdb-4e7b-bf18-c1f9bd******"}
- Response:
-
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"}
- Request:
Примеры находятся в:
/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 процесса отправки:
- Пользователь нажимает "Send to E-Taxes" на submitted Sales Invoice
- Первый диалог подтверждения: 'Send this invoice to E-Taxes?'
- Второй диалог подтверждения: 'Are you sure?'
- Показать простой loading индикатор
- Валидация данных:
- Проверка TIN клиента (tax_id)
- Проверка product_group_code у всех товаров
- Проверка что инвойс еще не отправлен (блокировка повтора)
- Получение serial number от API
- Формирование 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
- Отправка на создание инвойса
- Автоматическое подписание инвойса
- Создание E-Taxes Sales Outbox tracking document
- Сохранение результатов в Sales Invoice:
- Invoice ID
- Serial Number
- Verification Code (если успешно)
- Статус отправки ('Sent and Signed' или 'Created, not signed')
- Заменить кнопку на индикатор статуса
- Показать успешное сообщение пользователю