invoice_az/QA_SEND_INVOICE.md

15 KiB
Raw Permalink Blame History

Вопросы и Ответы - Отправка инвойсов в 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:

  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')
  1. Заменить кнопку на индикатор статуса
  2. Показать успешное сообщение пользователю