Технічне завдання: передача документів для звітності в податкову через Птах для Python
23.; Етапи реалізації
def download_receipts(self, document_id: str) -> list [bytes]:
event_type="STATUS_SYNC_FAILED",
1.; Мета
services/
10.; Мапінг статусів ПТАХ
- xml
| - | Rejected | Отримати офіційну документацію та тестовий доступ.; |- | waiting_receipt | WaitingForReceipt | - | КЕП | Кваліфікований електронний підпис.; характеристика | }
7.; # Які endpoint-и використовуються для відправки?; "taxpayer_id": "1234567890", 11.8.; Отримання журналу8.1.; Створення документаPOST /api/v1/tax-reports/{report_id}/download-receipts | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Python | Зафіксувати помилку, повідомити адміністратора.; |- | Failed | - | Зміна API | - | AC-10 | Документ підписано.;=== 8.4.; Підписання документа ===
11.7.; Отримання документа |
; repositories/
event_type="SIGNED_IN_PTAH", | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Draft | Опційно.; Перевірити, що документ не був відправлений раніше.; |- | AC-2 | - | AC-11 | }
integration/
* доступ до платформи ПТАХ;
* активований доступ до API.ПТАХ;
* базовий URL API;
* спосіб авторизації;
* API key / token / client credentials;
* технічну документацію endpoint-ів;
* перелік доступних типів документів;
* підтвердження функціональні можливості передачі звітності до ДПС через ПТАХ;
* формат передачі файлів;
* формат метаданих документа;
* правила створення документа в ПТАХ;
* правила підписання документа;
* правила відправки документа;
* правила отримання статусів;
* правила отримання квитанцій;
* тестове середовище, якщо доступне;
* технічний контакт з боку постачальника ПТАХ.; Оновити статус на Signed або Failed.; |-
| waiting_signature
| WaitingForSignature
| Очікується підпис.; |-
| Квитанція
| Підтвердження прийняття, відхилення або обробки звіту.; | платформа надає можливість ініціювати підписання, якщо це підтримується API.; | платформа не створює дубль без окремого підтвердження.; |-
| accepted
| Accepted
| Документ прийнято.; # Чи Python-сервіс має сам формувати XML, чи отримує готовий XML з ERP?; |-
| document_number
| varchar
| Номер документа.; Інтервал перевірки
)
{| class="wikitable"
"status": "Generated",
POST /api/v1/tax-reports/{report_id}/validate
=== 11.5.; Відправка документа ===
}
verify_ssl: bool = True
ERP / Accounting System
== 11.; API Python-сервісу ==
ДПС або інший отримувач
{
!; |-
| Помилка API
| HTTP-код, тіло відповіді, correlation ID.; |-
| old_status
| varchar
| Попередній статус.; Викликати PtahClient.upload_tax_report().; |-
| WaitingForSignature
| Документ очікує підписання.; характеристика
платформа повинна мати background worker, який періодично оновлює статуси документів.; |-
| AC-14
| ПТАХ повертає невідомий статус.; "period": "2026-Q1",
* реалізувати авторизацію;
* реалізувати upload_tax_report;
* реалізувати create_document;
* реалізувати get_document_status;
* реалізувати download_document;
* реалізувати download_receipts;
* реалізувати обробку помилок;
* реалізувати retry.; | платформа надає можливість відправку документа.; | Виконати retry.; щоб оперативно знаходити причину помилок інтеграції.; |-
| XSD
| Схема перевірки XML-документа.; |-
| payload
| jsonb
| Технічні інформаційні дані події.; # Записати подію в журнал.; |-
| status
| varchar
| Внутрішній статус.; | Зберегти raw-статус, створити подію UnknownStatus.; |-
| file_type
| varchar
| original, signed, pdf, receipt_1, receipt_2, error_protocol.; |-
| file_format
| varchar
| XML, PDF, ZIP тощо.; |-
| Недоступність ПТАХ
| Платформа або мережа можуть бути тимчасово недоступні.; |-
| HTTP client
| httpx.; Спосіб
</pre>
"taxpayer_name": "ФОП Іваненко Іван Іванович",
!; | Він бачить всі пов'язані файли та статуси.; |-
| Validation Layer
| Перевіряє реквізити, структуру та статус документа.; | платформа надає можливість передачу в ПТАХ.;=== 11.10.; Повторна відправка ===
report.status = TaxReportStatus.SIGNED
|
; event_type="SENT_TO_PTAH",
Якщо API.ПТАХ підтримує роботу відповідний метод, Python-сервіс повинен ініціювати відправку документа отримувачу.; | Статуси документів оновлюються автономно.; Отримати результат підписання.; |- |
created_at | timestamp | - | AC-17 | Отримати офіційну API-документацію та підтвердження від постачальника.; !; Метою задачі є собою створення Python-сервісу для передачі документів звітності через платформу ПТАХ.; reports = tax_report_repository.get_reports_for_sync()
) entity_id=report.id, allowed_formats: |
- | uploaded | SentToPtah | - | Python-сервіс | - | source_system | varchar | - | Підписання в Python-сервісі | - | ReadyToSend | Документ готовий до передачі.;
"status": "Sent", "new_status": "WaitingForSignature", Етап 5.; Підписання та відправка"report_type": "single_tax_declaration", </syntaxhighlight> |
Внутрішній статус документа змінюється.; Очікуваний результат | ; Внутрішній статус
"old_status": "SentToPtah", POST /api/v1/tax-reports/{report_id}/sign платформа повинна забезпечити:
payload = DocumentPayload(
"ptah_status": "waiting_signature"
retry_backoff_seconds: int = 5
models.py
report = tax_report_repository.get_by_id(db, report_id)
Фінальний мапінг статусів потрібно побудувати після отримання офіційного довідника статусів API.ПТАХ.; | Основна платформа для передачі документів.; # Оновити статус на Sent.; - zip
- xml
POST /api/v1/tax-reports/{report_id}/send-to-ptah
details={
"status": "ReadyToSend",
Сервіс повинен забезпечити:
{| class="wikitable"
!; # Записати подію в журнал.; | Raw-статус зберігається, створюється подія UnknownStatus.; |-
| Невідомі статуси
| ПТАХ має змогу повертати статуси, яких немає в системі.; Перевірити, що документ підписано.; характеристика
entity_id=report.id,
file_repository.py
== 14.; Підписання та відправка через ПТАХ ==
<pre>
main.py
Очікувана відповідь:
"message": "Document sent via Ptah"
=== 14.1.; Логічний бізнес-процес підписання ===
event_repository.py
!; Окремо варто відзначити який формує, перевіряє, передає і контролює документи звітності через інтеграцію з платформою ПТАХ / API.ПТАХ.; # Перевірити, що документ підписано або готовий до підписання.; TaxReportStatus.SENT_TO_PTAH,
=== 11.2.; Перевірка документа ===
def create_document(self, document: "DocumentPayload") -> "PtahDocumentResponse":
4.; } tax_report_service.py GET /api/v1/tax-reports/{report_id}/events requires_receipt: true PTAH_RETRY_BACKOFF_SECONDS=5 title: "Об'єднана формування звітів" </syntaxhighlight> pass
storage/
<pre>
[[Категорія:K2 ERP]]
=== 11.9.; Завантаження квитанцій ===
report_id=report.id,
unified_report:
README.md
requires_signature: true
from pydantic_settings import BaseSettings
</pre>
Мінімальний набір вхідних даних:
{| class="wikitable"
try:
return report
"errors": []
)
PTAH_TIMEOUT_SECONDS=30
Повторна відправка дозволена тільки для документів у статусах:
tests/
4.; Передача документа через API.ПТАХ
!; Очікувана відповідь:
POST /api/v1/tax-reports/{report_id}/send-to-ptah
ptah/
{{DISPLAYTITLE:Технічне завдання: Передача документів для звітності в податкову через ПТАХ для Python}}
== 12. Ptah Integration Client ==
!; |}
db/
report.ptah_document_id = response.id
* timeout;
* тимчасової недоступності API.ПТАХ;
* HTTP 429;
* HTTP 500;
* HTTP 502;
* HTTP 503;
* HTTP 504;
* тимчасових мережевих помилок.; !; | Статус документа змінюється на Signed.; {| class="wikitable"
!; date=report.document_date,
== 6.; технічна архітектура рішення для бізнесу ==
class PtahClient:
=== 12.3.; Конфігурація клієнта ===
"id": "9ddaa913-03a3-4e11-a90a-582adf8a05ff",
!; | Резервний режим.; |-
| event_type
| varchar
| Тип події.; Рекомендація
|-
| AC-8
| Документ створено в ПТАХ.; Оновити статус на SentToPtah.; №
</pre>
PTAH_TIMEOUT_SECONDS=30
* прийом даних звітності з ERP / облікової системи;
* формування або прийом готового XML-документа;
* перевірку документа перед передачею;
* передачу документа в ПТАХ;
* запуск підписання документа, якщо це підтримується API;
* запуск відправки документа, якщо це підтримується API;
* отримання зовнішнього ID документа;
* синхронізацію статусів;
* отримання квитанцій або результатів обробки;
* збереження історії передачі;
* обробку помилок;
* повторну відправку;
* журналювання всіх технічних і бізнес-подій.; |-
| Помилки КЕП
| Можливі проблеми з ключами, паролями або сертифікатами.; # Які endpoint-и використовуються для створення документа?; # Чи підтримуються webhook-и?; |-
| PtahUnavailableError
| Платформа ПТАХ недоступна.; |}
exceptions.py
=== 14.3.; Приклад Python-логіки ===
* квитанцію про отримання;
* квитанцію про прийняття;
* квитанцію про відхилення;
* підписаний документ;
* PDF-візуалізацію, якщо доступна;
* технічний протокол обробки, якщо доступний;
* raw-відповідь ПТАХ.; Очікуваний результат
!; | Заборонити повтор без підтвердження.; |-
| Validation
| Pydantic.; Валідація та збереження документа
title: "Декларація платника єдиного податку"
)
|
| 3.; щоб мати підтвердження результату передачі документа.; | Не відправляти документ, показати список помилок.; Критерій
FILE_STORAGE_PATH=/data/tax-reports
sync_statuses.py
1.; def sync_pending_reports() -> None:
!; status_mapper.py
!; |-
| Завантаження квитанції
| Тип файлу, назва, дата.; # Які типи звітів підтримуються першими?; |-
| Polling
| Періодичне опитування зовнішнього API.; |-
| ДПС
| Державна податкова служба України.; |-
| Webhook
| Механізм отримання подій від зовнішньої системи.; Ризик
== 22. MVP ==
},
=== 16.2. tax_report_events ===
=== 21.5.; Квитанції та файли ===
}
Python Tax Reporting Service
logging.py
== 17.; Обробка помилок ==
{| class="wikitable"
PTAH_CLIENT_SECRET=********
POST /api/v1/tax-reports
"ptah_status": ptah_status.raw_status,
pass
=== 12.2.; Основні методи ===
db.commit()
<pre>
!;<pre>
* Accepted;
* Sent;
* WaitingForReceipt;
* SentToPtah;
* WaitingForSignature.; |}
Очікувана відповідь:
<pre>
if report.status not in {
!; # Оновити статус документа.; |}
details={"error": str(exc)},
# Який саме програмний продукт застосовується: ПТАХ, API.ПТАХ або інтеграційні функціональні можливості через інший програмний продукт Linkos Group?; |-
| created_at
| timestamp
| Дата створення.; # Який SLA по оновленню статусів?; №
функціональні можливості застосовують, коли потрібно для автоматизації передачі документів звітності з ERP або облікової системи до ПТАХ.; | Відображати зрозумілу помилку та дозволяти повторне підписання.; |-
| AC-3
| Передано некоректні інформаційні дані.; |-
| ptah_raw_status
| varchar
| Останній raw-статус ПТАХ.; | Зберігати raw-статус та мати UnknownStatus.; |-
| last_sync_at
| timestamp
| Дата останньої синхронізації.; |-
| Generated
| Файл документа сформовано.; Записати подію в журнал.; new_status=new_status,
!; |-
| rejected
| Rejected
| Документ відхилено.; |}
POST /api/v1/tax-reports/{report_id}/sync-status
details={
"ptah_document_id": "external-document-id",
{| class="wikitable"
{
},
)
Для реалізації задачі необхідно отримати:
ptah_status = ptah_client.get_document_status(
"source_system": "K2 ERP",
return report
6.; Пріоритет
!; # Чи підтримує роботу ПТАХ сценарій подання податкової звітності до ДПС?; Перевірити, що документ має статус ReadyToSend.; # Які endpoint-и використовуються для підписання?; |-
| Sending
| Документ передається в ПТАХ.; |-
| SentToPtah
| Документ успішно передано в ПТАХ.; |-
| file_name
| varchar
| Назва файлу.; Призначення
1.; POST /api/v1/tax-reports/{report_id}/send
v
* створення Python API для прийому документів;
* створення клієнта інтеграції з API.ПТАХ;
* формування XML або прийом готового XML;
* збереження документа;
* перевірка обов'язкових реквізитів;
* передача документа в ПТАХ;
* запуск підписання / відправки через ПТАХ, якщо підтримується API;
* отримання статусів;
* отримання квитанцій або результатів обробки;
* журнал подій;
* retry-механізм;
* захист API-ключів і службових доступів;
* інтеграційні функціональні можливості з ERP.; | Перевіряти ptah_document_id перед відправкою.; requires_signature: true
== 13.; Передача документа в ПТАХ ==
{| class="wikitable"
from uuid import UUID
{| class="wikitable"
unit/
)
я хочу ініціювати підписання та відправку документа через ПТАХ,
download_receipts.py
<syntaxhighlight lang="python">
audit_logger.log(
GET /api/v1/tax-reports/{report_id}
"old_status": old_status,
</div>
=== 12.1.; Призначення ===
!; |-
| Передача в ПТАХ
| Endpoint, час, статус відповіді, зовнішній ID.; Запустити очікування квитанцій.; |-
| ptah_document_id
| varchar
| ID документа у ПТАХ.; Зберегти ID у локальній БД.; |-
| file_path
| varchar
| Шлях до файлу у сховищі.; # Який формат документа підтримується: XML, PDF, ZIP, JSON?; | Додати healthcheck інтеграції та повідомлення адміністратору.; |-
| error_message
| text
| Остання помилка.; |-
| StatusMappingError
| Невідомий статус від ПТАХ.; характеристика
raise InvalidStatusError(
</pre>
)
</pre>
<pre>
allowed_formats:
client.py
PTAH_CLIENT_ID=********
5.; document_types:
routes/
* ValidationError;
* Failed;
* Rejected;
* DeliveryError;
* NeedResend.; |-
| Дублювання документів
| Повторна відправка має змогу створити дубль.;<pre>
* додати Dockerfile;
* додати docker-compose;
* додати structured logging;
* додати metrics;
* додати alerting;
* додати rate limiting;
* додати security review.; |-
| sent_at
| timestamp
| Дата передачі в ПТАХ.; Тип
PTAH_COMPANY_CODE=12345678 платформа повинна підтримувати два способи актуалізація статусів: pass "created_by": "user@example.com" "source_system": report.source_system,
timeout_seconds: int = 30
f"Report {report_id} cannot be signed from status {report.status}"
old_status = report.status
|
; "id": "9ddaa913-03a3-4e11-a90a-582adf8a05ff",
client_id: str | None = None |
- | accepted_at | timestamp | Дата прийняття.; validation_service.py | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| id | uuid | ID події.; характеристика
STATUS_SYNC_INTERVAL_SECONDS=300 я хочу повторно відправити документ після технічної помилки, session.py event_type="STATUS_CHANGED", raw_status=ptah_status.raw_status, "file_content_base64": "BASE64_XML_CONTENT", ) STATUS_SYNC_ENABLED=true allowed_formats: entity_id=report.id, file_storage.py 4.; Синхронізація статусів report = tax_report_repository.get_by_id(db, report_id)
|