| Підходить для
|
-
|
Помилка передачі
|
-
|
Attachment
|
Список документів, dashboard, картка документа.; |}
},
- акаунт EDIN;
- доступ до EDIN API або EDIN DocFlow API;
- тестове середовище або тестову компанію, якщо доступно;
- логін / пароль або API token;
- інформаційні дані компанії-відправника;
- інформаційні дані контрагентів;
- перелік типів документів, які потрібно передавати;
- XML / JSON-специфікації документів;
- правила підписання;
- КЕП / ЕЦП або сценарій делегованого підписання;
- вимоги до вкладень;
- правила отримання статусів;
- правила отримання квитанцій;
- правила повторної відправки;
- контакт технічної підтримки EDIN.; KPI
def sync_edin_document_status(document_id: str, db: "Session") -> None:
K2 ERP передає різні типи документів через різні API EDIN.; |-
| file_size
|
integer
|
-
|
status
|
varchar
|
-
|
Document Queue
|
-
|
Підписано
|
SIGNED
|
Зелений
|
-
|
AC-12
|
-
|
document_id
|
uuid
|
-
|
CounterpartyError
|
Він бачить кількість створених, підписаних, відправлених, прийнятих і відхилених документів.; |-
|
Основні операції
|
Підготовка документа, підписання, передача, статуси, квитанції.; v
- реалізувати сценарій WAITING_SIGNATURE;
- реалізувати інтеграцію з Signature Service, якщо є собою;
- реалізувати перевірку підпису;
- реалізувати журнал підписання.; | Зберігається EDIN document ID.; |-
|
Document Type
|
style="background:#eeeeee;" | Сірий
|
| Готовий до перевірки
|
READY_FOR_REVIEW
|
Документ сформований і очікує перевірки.; характеристика
|
е-ТТН, нестандартні документи, ручні сценарії.; |-
|
Signature
|
Підпис КЕП / ЕЦП.; Поле
|
| id
|
uuid
|
-
|
file_id
|
uuid
|
-
|
status
|
varchar
|
-
|
Дублювання документів
|
}
|
; from pydantic_settings import BaseSettings
document = edin_document_repository.create(
document.status = "SENDING"
|
| EDIN не підтримує роботу потрібний тип звітності
|
-
|
Завантаження квитанцій
|
Середній
|
Не блокує первинну відправку.;== 28.; Ризики ==
document.status = "NEEDS_RETRY"
integration_mode: str = "docflow"
Критично істотно: перед початком розробки потрібно підтвердити у EDIN, які саме типи документів можуть передаватись через API у конкретному акаунті: податкові накладні, первинні документи, структуровані документи DocFlow, EDI-документи, е-ТТН або саме податкова формування звітів до ДПС.; |-
|
document_type_id
|
uuid
|
Тип документа.; * створення інтеграції EDIN;
- перевірка підключення;
- довідник типів документів;
- створення документа;
- валідація документа;
- завантаження вкладень;
- базовий сценарій підписання або статус «очікує підпису»;
- передача документа в EDIN;
- збереження EDIN document ID;
- синхронізація статусу;
- отримання квитанцій, якщо доступно через API;
- дедублікація;
- retry-механізм;
- журнал подій;
- dashboard API;
- базові unit-тести;
- mock EDIN API для інтеграційних тестів.; |-
|
company_id
|
varchar
|
ID компанії в EDIN.; EDIN повертає ID документа або технічну відповідь.; характеристика
- реалізувати dashboard API;
- реалізувати список проблемних документів;
- реалізувати фільтри;
- реалізувати експорт, якщо потрібно.; | style="background:#bbdefb;" | Блакитний
|
| Потребує виправлення
|
NEEDS_CORRECTION
|
}
13.6.; Завантаження вкладення
11.1.; Загальна схемаЕтап 4.; Документи та валідація
| id
|
uuid
|
-
|
external_receipt_id
|
varchar
|
Повторна відправка блокується.; |-
|
received_at
|
timestamp
|
Дата отримання.; Коментар
21.; Обробка помилок
7.2.; Підписання
|
; Компонент
|
style="background:#e3f2fd;" | відомості
|
| Очікують підпису
|
Документи без підпису.; Колір
Python-сервіс формує або передає документи, пов'язані з електронною податковою накладною.; !; |-
|
counterparty_id
|
uuid
|
Контрагент.; характеристика
Етап 6.; Черга та статуси
|
|
style="background:#bbdefb;" | Блакитний
|
| Доставлено
|
DELIVERED
|
Документ доставлений отримувачу або системі.; Доставка / обробка / статуси
POST /api/v1/edin/documents/{document_id}/attachments
|
|
-
|
K2 ERP / ERP / CRM
|
-
|
AC-7
|
Потрібно перевірити конкретний API та тип документа.; |-
|
EDIN Tax Invoice / Податкова накладна
|
платформа показує AuthError і не відправляє документи.; |-
|
name
|
varchar
|
Назва інтеграції.; Signature Service / KEP Module
- додати rate limiting;
- додати моніторинг;
- додати alerting;
- додати dead letter queue;
- додати резервне копіювання;
- додати безпечне зберігання секретів.; |}
щоб підписати їх КЕП перед відправкою.; # Чи потрібна інтеграційні функціональні можливості з хмарним КЕП?; |-
|
api_token_encrypted
|
text
|
-
|
Organization
|
Статус підписання змінюється на SIGNED.; "organization_id": command.organization_id,
13.8.; Повторна відправка
|
-
|
Податкові декларації
|
Окремо підтверджується; за потреби застосовують, коли потрібно інший канал.; Показник
Варіант 4.; 5.4.; Гібридна схема
Як бухгалтер,
Як адміністратор,
document.status = "SENT_TO_EDIN"
25.3.; Статуси та квитанції
}
old_status="SENDING",
EDIN_COMPANY_ID=company-001
12.1.; Призначення
|
Статус підсвічується зеленим.; Дія
"attachments": [
def get_document_status(self, edin_document_id: str) -> "DocumentStatusResponse":
До MVP входить:
Критично істотно: для кожного типу документа потрібно окремо зберігати схему, канал передачі, правила підписання, допустимі вкладення та правила отримання статусу.; |-
| document_number + document_date + organization_id + counterparty_id
|
-
|
requires_signature
|
boolean
|
style="background:#ffcc80;" | Помаранчевий
|
| Скасовано
|
CANCELLED
|
Документ скасовано користувачем.; Очікуваний результат
sha256(document_type + document_number + document_date + total_amount + organization_tax_id + counterparty_tax_id)
|
| Документів створено
|
Загальна кількість документів за період.; №
платформа повинна не допускати дублювання документів.; | style="background:#fff9c4;" | Жовтий
|
| Відправляється
|
SENDING
|
Виконується API-запит до EDIN.; Тип
|
Вони підсвічуються червоним.; |-
|
Отримання статусу
|
-
|
created_at
|
timestamp
|
Дата створення.; характеристика
25. Acceptance Criteria
|
}
- Який саме програмний продукт EDIN застосовується: DocFlow, EDI Network, Tax Invoice, ETTN чи гібрид?; | style="background:#c8e6c9;" | Зелений
| Очікує відправки
|
PENDING_SEND
|
Документ у черзі передачі.; Коментар
|
; характеристика
Python-сервіс створює або передає структуровані документи через DocFlow API.; K2 ERP отримує фінальний статус.; характеристика
document_validator.validate(command)
|
; Очікуваний результат
</syntaxhighlight>
[[Категорія:Python]]
=== 8.1.; Основні типи документів для MVP ===
== 24.; Логування та аудит ==
</pre>
<pre>
!; |-
| total_amount
| numeric
| Загальна сума.; |-
| style="background:#fff9c4;" | Жовтий
| #fff9c4
| Очікування дії: підпис, відправка, перевірка.; {| class="wikitable"
== 5.; Варіанти інтеграції ==
== 16.; Підписання КЕП ==
"idempotency_key": "K2-TAX-INVOICE-2026-000123-v1",
!; |-
| Python Integration Service
| Інтеграційний шар між K2 ERP та EDIN.; |}
'''істотно:''' EDIN не слід автономно вважати універсальним каналом подання всіх декларацій до ДПС.; |-
| name
| varchar
| Назва типу документа.; |-
| SignatureError
| Помилка підписання.; |-
| Неправильний формат XML
| Документ має змогу бути відхилено.; | Валідація за схемою до відправки.; K2 ERP створює документ.; Тип
=== 11.2.; Основні компоненти Python-сервісу ===
db=db,
|-
| id
| uuid
| ID вкладення.; EDIN застосовується для ЕДО та первинних документів, а податкова формування звітів подається через інший канал виступає ключовою рисою '''істотно:''' якщо бізнес-процес передбачає саме подання декларацій до ДПС, потрібно окремо підтвердити, що EDIN API підтримує роботу цей тип звітності.; |}
<pre>
"filename": "tax_invoice_123.pdf",
'''Заборонено:''' зберігати логін, пароль, API token, КЕП, пароль до КЕП або інші секрети у коді, Git-репозиторії, відкритих логах або frontend-змінних.; |-
| AC-16
| Документ уже прийнятий.; характеристика
=== 18.1.; Логіка черги ===
=== 19.4. edin_attachments ===
</pre>
|
| 1.; Реальні EDIN API endpoint-и потрібно підставити з офіційної документації EDIN для конкретного продукту: DocFlow, EDI Network, ETTN або податкові накладні.; №
!; Тип
!; |-
| style="background:#ef9a9a;" | Червоний
| #ef9a9a
| Відхилено або критична помилка.; | style="background:#ef9a9a;" | Критично
|-
| Потребують повтору
| Технічні помилки, які можна повторити.; Формування документа
!; |}
== 4.; Передумови ==
!; |-
| edin_attachment_id
| varchar
| ID вкладення в EDIN.; |-
| Signature Adapter
| Підписує документ або передає його на підписання.; document_id=document.id,
=== Етап 3.; EDIN Client ===
=== 22.3.; Проблемні документи ===
щоб документ із K2 ERP був сформований, перевірений, підписаний і переданий в EDIN.; # Які типи документів потрібно передавати в MVP?; | Документ переходить у NEEDS_RETRY.; return existing
old_status=old_status,
def upload_attachment(self, edin_document_id: str, file: bytes, filename: str) -> "AttachmentResponse":
new_status=new_status,
7.; Стан
!; характеристика
!; |-
| SendError
| API EDIN повернув помилку.; # Чи потрібен dashboard у K2 ERP?; pass
"status": "DRAFT",
}
"vat_amount": 2000.00,
!; |-
| Валідація
| Результат, список помилок.; |-
| Document
| Внутрішній документ K2 ERP.; Пріоритет
{| class="wikitable"
"send_after_signing": true
try:
api_password: str | None = None
pass
pass
=== Етап 5.; Підписання ===
v
db=db,
== 27.; Етапи реалізації ==
"document_date": "2026-05-07",
!; |-
| storage_path
| varchar
| Шлях у сховищі.; |-
| new_status
| varchar
| Новий статус.; Статус
{
== 1.; Мета ==
if old_status != new_status:
if existing:
!; |-
| Підписання
| Хто підписав, коли, результат.;=== 13.1.; Створення інтеграції ===
"total_amount": command.total_amount,
"currency": "UAH",
!; | Повернути існуючий документ.; Значення
)
=== 22.2.; Приклад dashboard ===
|-
| Створення документа
| Тип, номер, дата, організація, контрагент.; | style="background:#ef9a9a;" | Червоний
|-
| Потребує повтору
| NEEDS_RETRY
| Документ можна передати повторно.; |-
| code
| varchar
| TAX_INVOICE, ACT, INVOICE, ETTN тощо.; | style="background:#ef9a9a;" | Червоний
|-
| Помилка передачі
| SEND_ERROR
| Технічна помилка передачі.; Критерій
!; | Вони підсвічуються помаранчевим.; | style="background:#c8e6c9;" | Зелений
|-
| Прийнято
| ACCEPTED
| Документ прийнятий.; |-
| raw_request
| jsonb
| Запит до EDIN.; |-
| AC-3
| Облікові інформаційні дані неправильні.; | платформа повертає успішний або помилковий статус.; |-
| EDI-документи
| EDI Network.; | Не відправляти документ, показати список помилок.; |-
| ReceiptError
| Помилка отримання квитанції.; |-
| sent_at
| timestamp
| Дата передачі.; |-
| Receipt Collector
| Завантажує квитанції, підтвердження, службові повідомлення.; |-
| AC-5
| Документ проходить валідацію.; Тип задачі
verify_ssl: bool = True
== 7. User Story ==
'''Критично істотно:''' без офіційної API-документації EDIN для конкретного продукту не можна фіксувати production endpoint-и, назви методів і формати payload як остаточні.; Статус
!; Окремо варто відзначити який інтегрує K2 ERP або іншу облікову систему з платформою EDIN; додатково реалізовано податкових накладних, первинних документів, супровідних файлів і документів, пов'язаних із податковою звітністю.; Валідація, мапінг, підготовка файлів
!; |-
| Document Validator
| Перевіряє обов'язкові поля, суми, контрагентів, формати.; Python-сервіс зберігає EDIN ID.; Дія системи
Python EDIN Integration Service
=== 21.2.; Retry-логіка ===
payload_hash = document_hash_service.calculate(command.payload)
EDIN_BASE_URL=https://api.example.edin
== 22.; Dashboard керівника ==
event_type="DOCUMENT_STATUS_SYNCED",
|-
| Підходить для
| Юридично значущих документів, актів, рахунків, договорів, первинних документів.; Помилка
=== 13.4.; Передача документа в EDIN ===
Retry заборонений для:
* формування електронного документа у внутрішній системі;
* валідацію документа перед передачею;
* підготовку XML / JSON / PDF / XLSX / вкладень;
* підписання КЕП або передачу документа на підписання;
* відправку документа в EDIN;
* отримання статусу документа;
* отримання підтверджень, квитанцій або службових повідомлень, якщо доступні;
* збереження ID документа EDIN;
* збереження історії зміни статусів;
* повторну передачу документа після технічної помилки;
* захист від дублювання;
* передачу статусу назад у K2 ERP;
* формування dashboard для контролю.; !; |-
| provider
| varchar
| edin.; | платформа повторює передачу без дублювання.;<div style="border-left: 6px solid #c62828; background: #ffebee; padding: 12px 16px; margin: 16px 0;">
!; №
{| class="wikitable"
!; |-
| document_id
| uuid
| ID документа.; |-
| Status
| Статус документа в K2 ERP та EDIN.; |-
| created_at
| timestamp
| Дата створення.; |-
| AC-6
| Документ потребує підпису.; |-
| AC-18
| є собою відхилені документи.; Тип помилки
document.raw_response = response.raw_payload
Python EDIN Client
щоб знати, чи документ прийнятий, відхилений, доставлений або очікує дії.; |-
| filename
| varchar
| Назва файлу.; | Другий документ не створюється.; |-
| Делеговане підписання
| Підписує відповідальна особа після отримання задачі.; |-
| base_url
| varchar
| URL API.;=== 13.10. Dashboard ===
!; |-
| Підписання в EDIN
| Документ передається в EDIN і підписується користувачем на платформі.; Поле
idempotency_key=command.idempotency_key,
</pre>
POST /api/v1/edin/documents
'''Управлінський результат:''' керівник або бухгалтер повинен бачити, які документи сформовано, які підписано, які передано в EDIN, які прийнято, які відхилено, які очікують підпису або дії користувача.; !; |-
| accepted_at
| timestamp
| Дата прийняття.; Призначення
"payload": {
=== 13.7.; Синхронізація статусу ===
=== 7.3.; Контроль статусів ===
EDIN
{| class="wikitable"
event_type="DOCUMENT_SENT_TO_EDIN",
{| class="wikitable"
def refresh_token(self) -> "AuthResult":
=== 7.4.; Повторна передача ===
EDIN_RETRY_BACKOFF_SECONDS=5
retry_count: int = 3
db.commit()
!; Якщо не підтримує роботу.; |-
| Повторна відправка
| Хто запустив, причина, результат.; | Не змінювати фінальний статус без перевірки.; | Реалізується в межах цього ТЗ.; |-
| event_type
| varchar
| Тип події.; | Dashboard, проблемні документи.; Значення
return
!; |-
| Counterparty
| Контрагент.; Контрагент
document = edin_document_repository.get_by_id(db, document_id)
|-
| Документів за місяць
| 1840
| style="background:#e3f2fd;" | відомості
|-
| Очікують підпису
| 43
| style="background:#fff9c4;" | Увага
|-
| Передано в EDIN
| 1290
| style="background:#bbdefb;" | В роботі
|-
| Прийнято
| 1218
| style="background:#c8e6c9;" | Норма
|-
| Відхилено
| 12
| style="background:#ef9a9a;" | Критично
|-
| Потребують повтору
| 18
| style="background:#ffcc80;" | Потрібна дія
|}
</pre>
я хочу повторити передачу після технічної помилки,
=== 13.9.; Отримання квитанцій ===
[[Категорія:K2 ERP]]
== 15.; Валідація документа ==
!; Компонент
api_token: str | None = None
new_status = status_mapper.from_edin(status_response.status)
=== Етап 8.; Production hardening ===
!; | Потрібен workflow задач.; Статус
|-
| AC-13
| Повторний запит має той самий idempotency_key.; !; |-
| Відправка в EDIN
| Час, endpoint, request_id, EDIN document ID.; |}
!; Очікуваний результат
я хочу натиснути кнопку «Передати через EDIN»,
new_status=document.status,
{| class="wikitable"
<pre>
return
"raw_request": command.model_dump(),
[[Категорія:Податкова звітність]]
POST /api/v1/edin/integrations
POST /api/v1/edin/documents/{document_id}/send
def cancel_document(self, edin_document_id: str, reason: str) -> "CancelDocumentResponse":
Як відповідальна особа,
"document_number": "123",
pass
Приклад `.env`:
!; |-
| Розрахунок коригування
| Критичний
| Впливає на ПДВ та реєстрацію.; '''Критично істотно:''' документ зі статусом ACCEPTED або DELIVERED не можна автономно відправляти повторно.; |-
| AC-19
| є собою документи без підпису.; |-
| payload
| jsonb
| Технічні інформаційні дані.; | Зупинити інтеграцію, повідомити адміністратора.; |-
| е-ТТН
| EDIN ETTN API, якщо підключено.; |-
| Document Mapper
| Перетворює документ K2 ERP у формат EDIN.; API EDIN / DocFlow / EDI Network
== Див.; 31.; додатково ==
<div style="border-left: 6px solid #f57c00; background: #fff3e0; padding: 12px 16px; margin: 16px 0;">
|
| 5.; def create_edin_document(command: "CreateEdinDocumentCommand", db: "Session") -> "EdinDocument":
return document
* передачі податкових накладних;
* передачі розрахунків коригування;
* передачі первинних документів;
* передачі актів, рахунків, видаткових накладних;
* передачі структурованих документів через EDIN DocFlow;
* передачі EDI-документів;
* передачі е-ТТН, якщо застосовується відповідний API EDIN;
* передачі документів між контрагентами;
* підготовки пакета документів, які потрібні бухгалтеру для податкової звітності;
* контролю статусів підписання та доставки документів.; | Перевести в NEEDS_CORRECTION.; |-
| API Event
| Подія інтеграції.; |-
| переважні аспекти
| Можливість працювати з податковими документами в одному ЕДО-середовищі.; |-
| integration_mode
| varchar
| Через який канал передається.; | style="background:#fff9c4;" | Жовтий
|-
| Підписано
| SIGNED
| Документ підписано КЕП.; | Перевести в SIGN_ERROR.; {| class="wikitable"
"file_id": "file-001"
{| class="wikitable"
"vat_amount": command.vat_amount,
audit_logger.log(
payload={"external_document_id": command.external_document_id},
class EdinSettings(BaseSettings):
old_status = document.status
document.accepted_at = datetime.now(timezone.utc)
=== 19.1. edin_integrations ===
pass
"document_type_id": command.document_type_id,
<pre>
EDIN Client — це Python-клас або пакет, який інкапсулює роботу з EDIN API.; # Чи потрібно підтримувати декілька акаунтів EDIN?; |}
new_status="SENT_TO_EDIN",
existing = edin_document_repository.get_by_idempotency_key(
=== 21.1.; Типи помилок ===
{| class="wikitable"
db.commit()
|-
| id
| uuid
| Внутрішній ID документа.; |-
| EDIN Document
| Документ, створений або переданий в EDIN.; Канал
pass
</pre>
!; Після підпису документ переходить у PENDING_SEND.; K2 ERP / ERP / CRM
|-
| style="background:#c8e6c9;" | Зелений
| #c8e6c9
| Успішно: підписано, доставлено, прийнято.; | Внутрішня платформа замовника.; |}
!; | Перевести в NEEDS_RETRY.; |-
| переважні аспекти
| Стандартизований обмін документами з контрагентами.; Канал
<pre>
!; |-
| vat_amount
| numeric
| Сума ПДВ.; характеристика
def check_connection(self) -> "ConnectionStatus":
інтеграційні функціональні можливості має змогу використовуватись для:
document.status = new_status
!; | Окремий статус SIGN_ERROR і журнал підписання.; Поле
* отримати офіційну документацію EDIN;
* визначити програмний продукт: DocFlow, EDI Network, Tax Invoice, ETTN або гібрид;
* визначити авторизацію;
* визначити формати документів;
* визначити статуси;
* визначити правила підписання;
* визначити квитанції та підтвердження.; Коментар
</div>
Ключі дедублікації:
<div style="border-left: 6px solid #c62828; background: #ffebee; padding: 12px 16px; margin: 16px 0;">
</pre>
<pre>
</pre>
!; # Як часто синхронізувати статуси?; |-
| content_type
| varchar
| MIME type.; Параметр
{| class="wikitable"
|-
| EDIN
| Платформа електронного документообігу.; |-
| Довільний файл
| Середній
| Супровідний документ.; | Статус підсвічується червоним.; |-
| AC-14
| EDIN API тимчасово недоступний.; |-
| е-ТТН
| Високий
| Важливий для логістики.; | Помилки валідації, retry.; | інтеграційні функціональні можливості зберігається в системі.; |-
| AC-15
| користувач системи запускає retry.; |-
| payload_format
| varchar
| XML, JSON, PDF.; {| class="wikitable"
* автоматичне подання всіх декларацій до ДПС без підтвердження EDIN API;
* повна супровід всіх документів EDIN;
* повна супровід всіх EDI-мереж;
* повна супровід е-ТТН, якщо не підключено ETTN API;
* власний компонент КЕП без окремого ТЗ;
* складний UI підписання;
* автоматичне виправлення XML-помилок;
* юридична перевірка змісту документа.; Призначення
Python Status Sync Worker
я хочу бачити загальну картину по документах EDIN,
!; |}
<syntaxhighlight lang="python">
</pre>
18.2.; Пріоритети задач
event_type="DOCUMENT_CREATED",
def create_document(self, payload: "EdinDocumentPayload") -> "EdinDocumentResponse":
"idempotency_key": command.idempotency_key,
Метою задачі є собою створення Python-сервісу для інтеграції з EDIN з метою передачі електронних документів, які використовуються у процесах податкового, бухгалтерського та юридично значущого документообігу.;== 18.; Черга передачі ==
|
| API Layer
|
-
|
Помилка КЕП
|
Документ не буде підписано.; status_response = edin_client.get_document_status(document.edin_document_id)
audit_logger.log(
Технічний стек: Python 3.11+, FastAPI, PostgreSQL, SQLAlchemy, Alembic, httpx, Pydantic, Celery/RQ/APScheduler, Redis, Docker.; |-
|
Первинний документ
|
Високий
|
Важливий для бухгалтерії.; except Exception as exc:
|
| Податкова накладна
|
Критичний
|
-
|
idempotency_key
|
varchar
|
-
|
EDIN EDI Network
|
}
if new_status == "ACCEPTED":
POST /api/v1/edin/integrations/{integration_id}/check-connection
"counterparty_id": command.counterparty_id,
def download_receipt(self, edin_document_id: str, receipt_id: str) -> bytes:
POST /api/v1/edin/documents/{document_id}/sync-status
|
| id
|
uuid
|
-
|
Receipt / Confirmation
|
-
|
Отримання квитанції
|
Тип квитанції, час, файл.;</syntaxhighlight>
!; |-
| Обмеження
| Потрібно підтвердити формат API, підписання, статуси та квитанції.; {| class="wikitable"
K2 ERP / Dashboard / Задачі відповідальних
!; |-
| is_active
| boolean
| Активність.; характеристика
9.; |-
| payload_format
| varchar
| XML, JSON, PDF, mixed.;== 20.; Приклад Python-логіки ==
* помилок валідації;
* неправильного логіна / пароля / token;
* помилки КЕП;
* невідповідності схемі документа;
* документа, який уже прийнято;
* документа, який явно відхилено через бізнес-помилки.; # Чи потрібно надсилати документи пакетно?; Документ
=== Варіант 2.; 5.2.; EDI Network API ===
=== Етап 2.; Базовий Python-сервіс ===
3.; Критерій
</div>
!; # Чи потрібно зберігати КЕП у системі?; Очікуваний результат
|
-
|
AC-11
|
-
|
SchemaError
|
Документ не відповідає XML/JSON-схемі.; "content_type": "application/pdf",
},
def get_document(self, edin_document_id: str) -> "EdinDocumentResponse":
|
-
|
Блакитний
|
#bbdefb
|
-
|
raw_response
|
jsonb
|
Відповідь EDIN.; Поле
19.2. edin_document_types
<syntaxhighlight lang="python">
"content_type": "application/xml",
{| class="wikitable"
8.; У цьому ТЗ endpoint-и Python-сервісу є собою внутрішніми, а EDIN endpoint-и мають уточнюватись за документацією EDIN.; Тип документа
"signing_status": "WAITING_SIGNATURE" if command.signing_required else "SIGN_NOT_REQUIRED",
!; |}
EDIN_API_TOKEN=********
!; Колір
=== Варіант 3.; 5.3.; Податкові накладні через EDIN ===
!; характеристика
"document_type": "TAX_INVOICE",
| Не потребує підпису
|
SIGN_NOT_REQUIRED
|
Сірий
|
}
data={
raise BusinessError("Document must be signed before sending")
def authenticate(self) -> "AuthResult":
<syntaxhighlight lang="python">
company_id: str
|-
| AC-1
| Адміністратор створює інтеграцію EDIN.; |-
| is_active
| boolean
| Активність.; Сервіс повинен забезпечити:
</div>
!; |-
| Немає квитанції
| Документ передано, але підтвердження не отримано.; Для реалізації задачі необхідно отримати:
{| class="wikitable"
!; |-
| Помилка підпису
| SIGN_ERROR
| style="background:#ef9a9a;" | Червоний
| Підписання не виконано.; |-
| updated_at
| timestamp
| Дата актуалізація.; | ключовий зовнішній сервіс.; | style="background:#c8e6c9;" | Норма
|-
| Відхилено
| Документи з негативним статусом.; | Квитанція зберігається в картці документа.; Що зберігати
|-
| Чернетка
| DRAFT
| Документ створено в K2 ERP, але ще не готовий до передачі.; Для класичної податкової звітності потрібно окремо перевіряти, чи підтримує роботу EDIN потрібний сценарій передачі, підписання, отримання квитанцій та статусів.; |-
| document_date
| date
| Дата документа.; |}
[[Категорія:API]]
!; |-
| api_password_encrypted
| text
| Зашифрований пароль.; |-
| payload_hash
| varchar
| Hash документа.; |-
| переважні аспекти
| Робота зі статусами, компаніями, документами, структурованими даними.; |-
| style="background:#f3e5f5;" | Фіолетовий
| #f3e5f5
| Спеціальний або індивідуальний документ.; |}
!; |-
| style="background:#ffcc80;" | Помаранчевий
| #ffcc80
| Потрібна дія користувача або повтор.; |-
| Синхронізація статусів
| Середній
| Фоновий бізнес-процес.; | застосовується, якщо підключено DocFlow.; |-
| Status Sync Worker
| Періодично синхронізує статуси з EDIN.; |-
| DuplicateDocumentError
| Документ уже існує.; | Потрібно безпечно зберігати ключі або використовувати HSM/хмарний КЕП.; Worker відправляє документ у EDIN.; |-
| file_hash
| varchar
| Hash файлу.; |-
| AC-2
| Адміністратор перевіряє підключення.; | Потрібен компонент КЕП у K2 ERP.; retry_backoff_seconds: int = 5
document_id=document.id,
|-
| AC-4
| K2 ERP створює документ.; Сутність
|-
| Integration Account
| Обліковий запис інтеграції EDIN.; document.status = "SEND_ERROR"
* реалізувати чергу передачі;
* реалізувати worker відправки;
* реалізувати worker синхронізації статусів;
* реалізувати retry;
* реалізувати збереження квитанцій.; Поле
v
"external_document_id": command.external_document_id,
payload = edin_mapper.to_edin_payload(document)
EDIN_API_PASSWORD=********
!; |-
| external_document_id
| varchar
| ID документа в K2 ERP.; |-
| integration_mode
| varchar
| docflow, edi_network, tax_invoice, ettn, hybrid.; |-
| organization_id
| uuid
| Організація-відправник.; # Чи потрібна валідація XML за XSD?; характеристика
document.sent_at = datetime.now(timezone.utc)
GET /api/v1/edin/documents/{document_id}/receipts
|-
| ValidationError
| Некоректні інформаційні дані документа.; |-
| created_at
| timestamp
| Дата події.; характеристика
== 23.; Безпека ==
!; # Чи потрібне підписання в K2 ERP, Python-сервісі або на стороні EDIN?; auth_url: str | None = None
* створити FastAPI-проєкт;
* налаштувати PostgreSQL;
* створити моделі інтеграції, документів, вкладень, подій;
* налаштувати Alembic;
* реалізувати healthcheck.; Формат
)
pass
<pre>
|-
| Підходить для
| Податкових накладних, розрахунків коригування, пов'язаних документів.; Повторна відправка дозволена тільки для технічних помилок або спеціальних статусів, визначених бізнес-правилами.; |}
db.commit()
</div>
=== 20.2.; Відправка документа ===
POST /api/v1/edin/documents/{document_id}/sign
document.error_message = str(exc)
=== 22.1.; Основні KPI ===
=== 25.4.; Дедублікація та повтор ===
!; | Підтвердити API та типи документів до розробки.; # Чи потрібно експортувати журнал передачі в Excel?; Критерій
<div style="border-left: 6px solid #f57c00; background: #fff3e0; padding: 12px 16px; margin: 16px 0;">
!; |}
)
payload=status_response.raw_payload,
!; | Idempotency key і document_hash.; Параметр
audit_logger.log(
document_id=document.id,
|-
| external_document_id
| ID документа у K2 ERP.; характеристика
GET /api/v1/edin/dashboard?date_from=2026-05-01&date_to=2026-05-31
=== 13.2.; Перевірка підключення ===
== 14.; Приклад запиту на створення документа ==
5.; |-
| Основні операції
| Формування XML, передача, отримання статусу, отримання відповіді контрагента.; характеристика
"payload_hash": payload_hash,
!; |-
| Очікує підпису
| WAITING_SIGNATURE
| style="background:#fff9c4;" | Жовтий
| Документ очікує підписання.; Код
<div style="border-left: 6px solid #c62828; background: #ffebee; padding: 12px 16px; margin: 16px 0;">
def update_document(self, edin_document_id: str, payload: "EdinDocumentPayload") -> "EdinDocumentResponse":
платформа повинна забезпечити:
if document.status in ["ACCEPTED", "DELIVERED"]:
=== 25.5. Dashboard ===
v
== 2.; Область сфера застосування ==
},
"document_number": command.document_number,
<pre>
{| class="wikitable"
document.error_message = str(exc)
v
EDIN_AUTH_URL=https://api.example.edin/auth
</syntaxhighlight>
== 11.; технічна архітектура рішення для бізнесу ==
Для надійності передача документів повинна виконуватись через чергу.; Поле
{{SEO
|title=Технічне завдання: Передача документів для звітності в податкову через EDIN для Python
|description=Технічне завдання на реалізацію Python-сервісу для передачі документів, податкових накладних, первинних документів та супровідних документів через EDIN / EDIN DocFlow / EDI Network з контролем статусів, підписанням, квитанціями, журналюванням та інтеграцією з K2 ERP.
|keywords=Python, EDIN, EDIN API, EDIN DocFlow, EDI Network, електронний документообіг, податкова накладна, КЕП, електронні документи, K2 ERP, податкова звітність, технічне завдання
}}
{| class="wikitable"
document = edin_document_repository.get_by_id(db, document_id)
== 3.; Джерела інтеграції ==
!; |-
| api_login_encrypted
| text
| Зашифрований логін.; Параметр
=== 25.1.; інтеграційні функціональні можливості ===
|-
| 07.05.2026
| Податкова накладна №123
| ТОВ «Альфа»
| ТОВ «Бета»
| style="background:#ef9a9a;" | Відхилено
| Помилка схеми XML
| Виправити
|-
| 07.05.2026
| Акт №45
| ТОВ «Альфа»
| ТОВ «Гамма»
| style="background:#fff9c4;" | Очікує підпису
| Немає КЕП відповідального
| Підписати
|-
| 07.05.2026
| е-ТТН №77
| ТОВ «Логістика»
| ТОВ «Покупець»
| style="background:#ffcc80;" | Потребує повтору
| Timeout EDIN API
| Повторити
|}
<div style="border-left: 6px solid #c62828; background: #ffebee; padding: 12px 16px; margin: 16px 0;">
{| class="wikitable"
* зберігання EDIN credentials тільки у secret storage або в зашифрованому вигляді;
* заборону логування паролів, token, ключів КЕП;
* маскування персональних даних;
* HTTPS для всіх API-запитів;
* перевірку SSL;
* рольову модель доступу;
* окремі права на підписання;
* окремі права на повторну відправку;
* окремі права на скасування документа;
* журнал усіх дій;
* захист від дублювання документів;
* контроль доступу до вкладень;
* обмеження розміру файлів;
* антивірусну перевірку вкладень, якщо потрібно.; | Фоновий retry отримання квитанцій.; |-
| edin_document_id
| varchar
| ID документа в EDIN.; |}
== 13.; API Python-сервісу ==
=== 5.1.; Варіант 1.; EDIN DocFlow API ===
<syntaxhighlight lang="python">
EDIN_INTEGRATION_MODE=docflow
)
|-
| id
| uuid
| ID квитанції.; |-
| signing_status
| varchar
| Статус підписання.; # Чи потрібно підтримувати декілька юридичних осіб?; |}
</syntaxhighlight>
4.; | Python-сервіс створює запис зі статусом DRAFT.; |}
v
!; Код
timeout_seconds: int = 30
== 26. MVP ==
|
; Колір
finally:
10.; Єдина логіка кольорів
13.3.; Створення документа
8.; Типи документів
|
; |
; Сценарій
- наявність external_document_id;
- наявність idempotency_key;
- тип документа;
- організацію-відправника;
- контрагента;
- ЄДРПОУ / ІПН / податковий номер сторін;
- дату документа;
- номер документа;
- валюту;
- суму;
- ПДВ, якщо застосовується;
- формат XML / JSON / PDF;
- відповідність схемі документа;
- наявність обов'язкових вкладень;
- наявність КЕП або сценарію підписання;
- чи не був документ уже відправлений;
- чи дозволений повтор для поточного статусу.; | Python-сервіс оновлює статус у K2 ERP.; актуалізація статусів
Python-сервіс передає EDI-документи між компаніями та торговельними мережами.; характеристика
],
"signing_required": true,
!; Status Sync Worker періодично оновлює статус.; |}
== 30.; Джерела ==
== 9.; Статуси документів ==
{| class="wikitable"
!; Квитанції та підтвердження зберігаються в картці документа.; | style="background:#ffcc80;" | Помаранчевий
|-
| Очікує підпису
| WAITING_SIGNATURE
| Документ готовий, але ще не підписаний.; | Версіонування клієнта і contract-тести.; # Чи потрібно отримувати квитанції автономно?; Де застосовується
=== 7.1.; Передача документа ===
|-
| Підписання в K2 ERP
| Документ підписується до передачі в EDIN.; |-
| document_id
| uuid
| ID документа.; | style="background:#eeeeee;" | Сірий
|}
from datetime import datetime, timezone
=== 16.2.; Статуси підписання ===
передачі електронних документів забезпечується через '''Головна ідея:''' розробити Python-сервіс.; | Списки, архів.; Підписання або передача на підпис
"external_document_id": "K2-TAX-INVOICE-2026-000123",
|
|
4.; "payload_format": command.payload_format,
- реалізувати створення документа;
- реалізувати мапінг K2 ERP → EDIN;
- реалізувати валідацію;
- реалізувати hash документа;
- реалізувати дедублікацію.; | style="background:#bbdefb;" | В роботі
|
| Прийнято
|
-
|
requires_attachments
|
boolean
|
None = None
- реалізувати авторизацію;
- реалізувати check_connection;
- реалізувати create_document;
- реалізувати upload_attachment;
- реалізувати send_document;
- реалізувати get_document_status;
- реалізувати get_document_list;
- реалізувати download_receipt;
- реалізувати обробку помилок.; | style="background:#ffcc80;" | Потрібна дія
|
| Без квитанції
|
-
|
Підписання в Python-сервісі
|
-
|
Обмеження
|
Потрібно перевірити доступність конкретних типів документів.;=== Етап 1.; Аналіз EDIN API ===
29.; Відкриті питання
"filename": "tax_invoice_123.xml",
|
; !; Тип
|
|
Черга, статус API.; |-
|
AuthError
|
}
response = edin_client.create_document(payload)
20.3.; Синхронізація статусів
pass
|
Без підпису він не відправляється.; |-
|
Обмеження
|
Статус змінюється на READY_FOR_REVIEW або WAITING_SIGNATURE.; | Вони підсвічуються жовтим.; №
|
| AC-17
|
-
|
Основні операції
|
Створення документа, редагування, зміна статусу, отримання списку документів.; характеристика
12.2.; Основні методи
17.; Дедублікація
"document_date": command.document_date,
"payload_format": "xml",
19.6. edin_events
|
style="background:#fff9c4;" | Контроль
|
|
-
|
Зміна API
|
Перевести в NEEDS_CORRECTION.; Retry дозволений для:
10.; |-
|
EDIN DocFlow API
|
API для роботи зі структурованими документами, компаніями, статусами та списками документів.; Тип
"counterparty_id": "counterparty-001",
db.commit()
"organization_id": "org-001",
|
; Критерій
|
; Важливість
if not document.edin_document_id:
pass
def send_document(self, edin_document_id: str) -> "SendDocumentResponse":
19.; Модель даних
|
Потрібно підтвердити підтримку цього сценарію для типу документа.; | Таблиця status_mapping і статус UNKNOWN.; |-
|
AC-8
|
Документ відправлено в EDIN.; Як зменшити
|
Зберегти raw-відповідь.; !; Дата
щоб не створювати документ вручну повторно.; |-
|
error_message
|
text
|
Остання помилка.;
|
Черга підпису, календар задач.; |-
|
document_number
|
varchar
|
-
|
Підписується
|
SIGNING
|
Блакитний
|
Виконується підписання.; Подія
EDIN_API_LOGIN=********
|
-
|
created_at
|
timestamp
|
style="background:#fff9c4;" | Увага
|
| Передано в EDIN
|
style="background:#c8e6c9;" | Зелений
|
| Відхилено
|
REJECTED
|
Документ відхилено.; HTML
12. EDIN Client
Як керівник бухгалтерської компанії,
|
style="background:#bbdefb;" | Блакитний
|
| Передано в EDIN
|
SENT_TO_EDIN
|
-
|
old_status
|
varchar
|
-
|
Скасування
|
Хто скасував, причина.; Код
def send_edin_document(document_id: str, db: "Session") -> None:
|
; payload={"edin_document_id": response.document_id},
До MVP не входить:
|
; Критерій
|
; Ключ
16.1.; Сценарії підписання
|
-
|
source
|
varchar
|
-
|
Сірий
|
#eeeeee
|
застосовується для ORDER, DESADV, INVOICE та інших EDI-документів.;=== 12.3.; Конфігурація клієнта ===
* https://edin.ua/
* https://edin.ua/edi-network/
* https://edin.ua/integraciya/
* https://edin.ua/integracijni-rishennya-edin/
* https://wiki.edin.ua/
* https://wiki-df.edin.ua/
* https://wiki.edin.ua/uk/latest/retail_2.0/Formuvannya_Podatkovoyi_Nakladnyy_na_pidstavi_Prybutkovoyi_nakladnoyi.html
* https://wiki.edin.ua/uk/latest/API_ETTNv3_1/API_ETTNv3_1_list.html
"xml_file_id": "file-001"
* Python
* FastAPI
* K2 ERP
* EDIN
* EDIN DocFlow
* EDI Network
* Електронний документообіг
* КЕП
* Податкова накладна
* Розрахунок коригування
* Первинні документи
* е-ТТН
* API інтеграція
{
25.2.; Документи
pass
if document.signing_status == "WAITING_SIGNATURE":
"total_amount": 12000.00,
"file_id": "file-002"
|
|
|
| |
|
|
|